Index: pro-bachkim-filespace/sourcecode/api.violet.vn/apps/platform/config/app.yml
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/apps/platform/config/app.yml	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/apps/platform/config/app.yml	(revision 19)
@@ -0,0 +1,11 @@
+# default values
+all:
+  basehost:       api.violet.vn
+
+  convert_exe:    /usr/bin/convert
+  identify_exe:   /usr/bin/identify
+  mplayer_exe:    /usr/bin/mplayer
+  flvtool2_exe:   /usr/bin/flvtool2
+  ffmpeg_exe:     /usr/local/bin/ffmpeg
+  swfdump_exe:    /usr/local/bin/swfdump
+  7z_exe:         /usr/local/bin/7z
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/apps/platform/config/cache.yml
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/apps/platform/config/cache.yml	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/apps/platform/config/cache.yml	(revision 19)
@@ -0,0 +1,4 @@
+default:
+  enabled:     off
+  with_layout: false
+  lifetime:    86400
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/apps/platform/config/config.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/apps/platform/config/config.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/apps/platform/config/config.php	(revision 19)
@@ -0,0 +1,8 @@
+<?php
+
+// include project configuration
+include(SF_ROOT_DIR.DIRECTORY_SEPARATOR.'config'.DIRECTORY_SEPARATOR.'config.php');
+
+// symfony bootstraping
+require_once($sf_symfony_lib_dir.'/util/sfCore.class.php');
+sfCore::bootstrap($sf_symfony_lib_dir, $sf_symfony_data_dir);
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/apps/platform/config/factories.yml
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/apps/platform/config/factories.yml	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/apps/platform/config/factories.yml	(revision 19)
@@ -0,0 +1,35 @@
+cli:
+  controller:
+    class: sfConsoleController
+  request:
+    class: sfConsoleRequest
+  response:
+    class: sfConsoleResponse
+
+test:
+  storage:
+    class: sfSessionTestStorage
+
+#all:
+#  controller:
+#    class: sfFrontWebController
+#
+#  request:
+#    class: sfWebRequest
+#
+#  response:
+#    class: sfWebResponse
+#
+#  user:
+#    class: myUser
+#
+#  storage:
+#    class: sfSessionStorage
+#    param:
+#      session_name: symfony
+#
+#  view_cache:
+#    class: sfFileCache
+#    param:
+#      automaticCleaningFactor: 0
+#      cacheDir:                %SF_TEMPLATE_CACHE_DIR%
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/apps/platform/config/filters.yml
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/apps/platform/config/filters.yml	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/apps/platform/config/filters.yml	(revision 19)
@@ -0,0 +1,10 @@
+rendering: ~
+web_debug: ~
+security:  ~
+
+# generally, you will want to insert your own filters here
+
+cache:     ~
+common:    ~
+flash:     ~
+execution: ~
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/apps/platform/config/i18n.yml
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/apps/platform/config/i18n.yml	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/apps/platform/config/i18n.yml	(revision 19)
@@ -0,0 +1,7 @@
+#all:
+#  default_culture:     en
+#  source:              XLIFF
+#  debug:               off
+#  cache:               on
+#  untranslated_prefix: "[T]"
+#  untranslated_suffix: "[/T]"
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/apps/platform/config/logging.yml
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/apps/platform/config/logging.yml	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/apps/platform/config/logging.yml	(revision 19)
@@ -0,0 +1,22 @@
+prod:
+  enabled: off
+  level:   err
+  rotate:  on
+  purge:   off
+
+#all:
+#  enabled: on
+#  level:   debug
+#  rotate:  off
+#  period:  7
+#  history: 10
+#  purge:   on
+#  loggers:
+#    sf_web_debug:
+#      class: sfWebDebugLogger
+#      param:
+#        condition: %SF_WEB_DEBUG%
+#    sf_file_debug:
+#      class: sfFileLogger
+#      param:
+#        file: %SF_LOG_DIR%/%SF_APP%_%SF_ENVIRONMENT%.log
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/apps/platform/config/routing.yml
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/apps/platform/config/routing.yml	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/apps/platform/config/routing.yml	(revision 19)
@@ -0,0 +1,15 @@
+# default rules
+homepage:
+  url:   /
+  param: { module: default, action: index }
+
+default_symfony:
+  url:   /symfony/:action/*
+  param: { module: default }
+
+default_index:
+  url:   /:module
+  param: { action: index }
+
+default:
+  url:   /:module/:action/*
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/apps/platform/config/security.yml
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/apps/platform/config/security.yml	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/apps/platform/config/security.yml	(revision 19)
@@ -0,0 +1,2 @@
+default:
+  is_secure: off
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/apps/platform/config/settings.yml
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/apps/platform/config/settings.yml	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/apps/platform/config/settings.yml	(revision 19)
@@ -0,0 +1,108 @@
+prod:
+  .settings:
+    no_script_name:           off
+
+dev:
+  .settings:
+    error_reporting:        <?php echo (E_ALL | E_STRICT)."\n" ?>
+    web_debug:              on
+    cache:                  off
+    no_script_name:         off
+    etag:                   off
+
+test:
+  .settings:
+    error_reporting:        <?php echo (E_ALL | E_STRICT & ~E_NOTICE)."\n" ?>
+    cache:                  off
+    web_debug:              off
+    no_script_name:         off
+    etag:                   off
+
+all:
+  .settings:
+    # Cache settings
+    lazy_cache_key:         on        # Delays creation of a cache key until after checking whether an action or partial is cacheable
+
+#all:
+#  .actions:
+#    default_module:         default   # Default module and action to be called when
+#    default_action:         index     # A routing rule doesn't set it
+#
+#    error_404_module:       default   # To be called when a 404 error is raised
+#    error_404_action:       error404  # Or when the requested URL doesn't match any route
+#
+#    login_module:           default   # To be called when a non-authenticated user
+#    login_action:           login     # Tries to access a secure page
+#
+#    secure_module:          default   # To be called when a user doesn't have
+#    secure_action:          secure    # The credentials required for an action
+#
+#    module_disabled_module: default   # To be called when a user requests 
+#    module_disabled_action: disabled  # A module disabled in the module.yml
+#
+#    unavailable_module:     default   # To be called when a user requests a page
+#    unavailable_action:  unavailable  # From an application disabled via the available setting below
+#
+#  .settings:
+#    available:              on        # Enable the whole application. Switch to off to redirect all requests to the unavailable module and action.
+#
+#    # Optional features. Deactivating unused features boots performance a bit.
+#    use_database:           on        # Enable database manager. Set to off if you don't use a database.
+#    use_security:           on        # Enable security features (login and credentials). Set to off for public applications.
+#    use_flash:              on        # Enable flash parameter feature. Set to off if you never use the set_flash() method in actions.
+#    i18n:                   off       # Enable interface translation. Set to off if your application should not be translated.
+#    check_symfony_version:  off       # Enable check of symfony version for every request. Set to on to have symfony clear the cache automatically when the framework is upgraded. Set to off if you always clear the cache after an upgrade.
+#    use_process_cache:      on        # Enable symfony optimizations based on PHP accelerators. Set to off for tests or when you have enabled a PHP accelerator in your server but don't want symfony to use it internally.
+#    compressed:             off       # Enable PHP response compression. Set to on to compress the outgoing HTML via the PHP handler.
+#    check_lock:             off       # Enable the application lock system triggered by the clear-cache and disable tasks. Set to on to have all requests to disabled applications redirected to the $sf_symfony_data_dir/web/arrors/unavailable.php page.
+#
+#    # Output escaping settings
+#    escaping_strategy:      bc        # Determines how variables are made available to templates. Accepted values: bc, both, on, off. The value off deactivates escaping completely and gives a slight boost.
+#    escaping_method:   ESC_ENTITIES   # Function or helper used for escaping. Accepted values: ESC_RAW, ESC_ENTITIES, ESC_JS, ESC_JS_NO_ENTITIES.
+#
+#    # Routing settings
+#    suffix:                 .         # Default suffix for generated URLs. If set to a single dot (.), no suffix is added. Possible values: .html, .php, and so on.
+#    no_script_name:         off       # Enable the front controller name in generated URLs
+#
+#    # Validation settings, used for error generation by the Validation helper
+#    validation_error_prefix:    ' &darr;&nbsp;'
+#    validation_error_suffix:    ' &nbsp;&darr;'
+#    validation_error_class:     form_error
+#    validation_error_id_prefix: error_for_
+#
+#    # Cache settings
+#    cache:                  off       # Enable the template cache
+#    etag:                   on        # Enable etag handling
+#    lazy_cache_key:         off       # Delays creation of a cache key until after checking whether an action or partial is cacheable (defaults to false for backward compatibility)
+#
+#    # Logging and debugging settings
+#    web_debug:              off       # Enable the web debug toolbar
+#    error_reporting:        <?php echo (E_PARSE | E_COMPILE_ERROR | E_ERROR | E_CORE_ERROR | E_USER_ERROR)."\n" ?> # Determines which events are logged. The default value is E_PARSE | E_COMPILE_ERROR | E_ERROR | E_CORE_ERROR | E_USER_ERROR = 341
+#
+#    # Assets paths
+#    rich_text_js_dir:       js/tiny_mce
+#    prototype_web_dir:      /sf/prototype
+#    admin_web_dir:          /sf/sf_admin
+#    web_debug_web_dir:      /sf/sf_web_debug
+#    calendar_web_dir:       /sf/calendar
+#
+#    # Helpers included in all templates by default
+#    standard_helpers:       [Partial, Cache, Form]
+#
+#    # Activated modules from plugins or from the symfony core
+#    enabled_modules:        [default]
+#
+#    # Charset used for the response
+#    charset:                utf-8
+#
+#    # Miscellaneous
+#    strip_comments:         on         # Remove comments in core framework classes as defined in the core_compile.yml
+#    autoloading_functions:  ~          # Functions called when a class is requested and this it is not already loaded. Expects an array of callables. Used by the framework bridges.
+#    timeout:                1800       # Session timeout, in seconds
+#    max_forwards:           5
+#    path_info_array:        SERVER
+#    path_info_key:          PATH_INFO
+#    url_format:             PATH
+#
+#    # ORM
+#    orm:                    propel
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/apps/platform/config/view.yml
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/apps/platform/config/view.yml	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/apps/platform/config/view.yml	(revision 19)
@@ -0,0 +1,17 @@
+default:
+  http_metas:
+    content-type: text/html
+
+  metas:
+    title:        symfony project
+    robots:       index, follow
+    description:  symfony project
+    keywords:     symfony, project
+    language:     en
+
+  stylesheets:    [main]
+
+  javascripts:    []
+
+  has_layout:     off
+  layout:         layout
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/apps/platform/lib/myUser.class.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/apps/platform/lib/myUser.class.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/apps/platform/lib/myUser.class.php	(revision 19)
@@ -0,0 +1,5 @@
+<?php
+
+class myUser extends sfBasicSecurityUser
+{
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/apps/platform/lib/violetUtil.class.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/apps/platform/lib/violetUtil.class.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/apps/platform/lib/violetUtil.class.php	(revision 19)
@@ -0,0 +1,40 @@
+<?php
+
+/**
+ * Utility functions for violet application
+ *
+ */
+class violetUtil {
+
+  public static function getSpacePath($absolute = true) {
+    if ($absolute) {
+      return sfConfig::get('sf_upload_dir') . '/space/';
+    } else {
+      return sfConfig::get('sf_upload_dir_name') . '/space/';
+    }
+  }
+
+  public static function getTempPath($subDir = '', $create = false) {
+    $tempPath = sfConfig::get('sf_upload_dir') . '/copying/' . $subDir;
+    if ($create && !file_exists($tempPath)) mkdir($tempPath, 0777, true);
+    return $tempPath;
+  }
+
+  public static function getContentType($fileType) {
+    switch (strtolower($fileType)) {
+      case 'xml':
+      case 'xvl': return 'text/xml';
+
+      case 'jpe':
+      case 'jpg':
+      case 'jpeg': return 'image/jpeg';
+      case 'gif': return 'image/gif';
+      case 'png': return 'image/png';
+
+      case 'flv': return 'video/x-flv';
+      case 'mp4': return 'video/mp4';
+      case 'mp3': return 'audio/mpeg';
+      case 'swf': return 'application/x-shockwave-flash';
+    }
+  }
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/apps/platform/modules/space/actions/actions.class.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/apps/platform/modules/space/actions/actions.class.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/apps/platform/modules/space/actions/actions.class.php	(revision 19)
@@ -0,0 +1,255 @@
+<?php
+
+/**
+ * space actions.
+ *
+ * @package    violetspace
+ * @subpackage space
+ * @author     Your name here
+ * @version    SVN: $Id: actions.class.php 2692 2006-11-15 21:03:55Z fabien $
+ */
+class spaceActions extends sfActions
+{
+  /**
+   * Executes index action
+   *
+   */
+  public function executeIndex()
+  {
+    //$this->forward('default', 'module');
+  }
+
+  private function CreateSpaceDir($folderName, $parentId, $userId) {
+    $c = new Criteria();
+    $c->add(TblspacecategoryPeer::CAT_PARENT, $parentId);
+    $c->add(TblspacecategoryPeer::CAT_USER, $userId);
+    $c->add(TblspacecategoryPeer::CAT_NAME, $folderName);
+    $category = TblspacecategoryPeer::doSelectOne($c);
+    if ($category == null) {
+      $category = new Tblspacecategory();
+      $category->setCatName($folderName);
+      $category->setCatParent($parentId);
+      $category->setCatUser($userId);
+      $category->setCatDate(date('Y-m-d H:i:s'));
+      $category->save();
+    }
+    return $category->getCatId();
+  }
+
+  private function CreateSpaceFile($file, $fileName, $fileSize, $catId, $userId) {
+    $tblres = new Tblspaceresource();
+    $tblres->setResFilename($fileName);
+    $tblres->setResFilesize($fileSize);
+    $tblres->setResFilecrc(crc32(file_get_contents($file)));
+    $tblres->save();
+    rename($file, $tblres->getFullFilename(true));
+
+    $tblfile = new Tblspacefile();
+    $tblfile->setFileResource($tblres->getResId());
+    $tblfile->setFileCategory($catId);
+    $tblfile->setFileUser($userId);
+    $tblfile->setFileName($fileName);
+    $tblfile->setFileDate(date('Y-m-d H:i:s'));
+    $tblfile->save();
+
+    $type = $tblfile->getFileType();
+    $filePath = $tblres->getFullFilename();
+    if (in_array($type, array('avi', 'mpg', 'mpeg', 'mpe', 'mpa', 'wmv', 'asf', 'mov', 'qt', '3gp'))) {
+      $flvName = myUtility::getFileName($filePath).'.flv';
+      myUtility::MovieToFlv($filePath, $flvName);
+    }
+    if (in_array($type, array('bmp', 'ico', 'wmf', 'emf'))) {
+      $jpgName = myUtility::getFileName($filePath).'.jpg';
+      myUtility::ImageToJpg($filePath, $jpgName);
+    }
+  }
+
+  private function MoveDirToSpace($path, $catId, $userId) {
+    foreach (scandir($path) as $dir) {
+      if ($dir=='.' || $dir=='..') continue;
+      $dname = $path.'/'.$dir;
+      if (is_dir($dname)) {
+        $subCatId = $this->CreateSpaceDir($dir, $catId, $userId);
+        $this->MoveDirToSpace($dname, $subCatId, $userId);
+      } else {
+        $this->CreateSpaceFile($dname, $dir, filesize($dname), $catId, $userId);
+      }
+    }
+    rmdir($path);
+  }
+
+  public function executeDir() {
+    $this->catId = $this->getRequestParameter('id', -1);
+    $userId = $this->getRequestParameter('userid');
+    $filter = $this->getRequestParameter('filter');
+    
+    // find parent ID of this category
+    if ($this->catId != -1) {
+      $c = new Criteria();
+      $c->add(TblspacecategoryPeer::CAT_ID, $this->catId);
+      $c->add(TblspacecategoryPeer::CAT_USER, $userId);
+      $thisCat = TblspacecategoryPeer::doSelectOne($c);
+      $this->parentId = $thisCat? $thisCat->getCatParent(): '-1';
+    }
+    else $this->parentId = '';
+
+    // find subcategory of this category
+    $c = new Criteria();
+    $c->add(TblspacecategoryPeer::CAT_PARENT, $this->catId);
+    $c->add(TblspacecategoryPeer::CAT_USER, $userId);
+    $c->addAscendingOrderByColumn(TblspacecategoryPeer::CAT_NAME);
+    $this->tblcategories = TblspacecategoryPeer::doSelect($c);
+
+    // find files in this category folder
+    $c = new Criteria();
+    $c->add(TblspacefilePeer::FILE_CATEGORY, $this->catId);
+    $c->add(TblspacefilePeer::FILE_USER, $userId);
+    if ($filter) $c->add(TblspacefilePeer::FILE_TYPE, explode(';', $filter), Criteria::IN);
+    $c->addAscendingOrderByColumn(TblspacefilePeer::FILE_NAME);
+    $this->tblfiles = TblspacefilePeer::doSelect($c);
+    
+    $this->errMsg = '';
+    $this->errCode = '';
+  }
+  
+  public function executeMkdir() {
+    $userId = $this->getRequestParameter('userid');
+    $parentId = $this->getRequestParameter('parent_id');
+    $folderName = $this->getRequestParameter('name');
+    $this->catId = $this->CreateSpaceDir($folderName, $parentId, $userId);
+    $this->errCode = '';
+    $this->errMsg = '';
+  }
+
+  public function executeDelete() {
+    //if (!$this->checkAuthentication()) return sfView::NONE;
+    $userId = $this->getRequestParameter('userid');
+    $type = $this->getRequestParameter('type');
+    $id = $this->getRequestParameter('id');
+
+    switch ($type) {
+      case 'folder': 
+        $c1 = new Criteria();
+        $c2 = new Criteria();
+        $c1->add(TblspacecategoryPeer::CAT_USER, $userId);
+        $c1->add(TblspacecategoryPeer::CAT_PARENT, $id);
+        $c2->add(TblspacefilePeer::FILE_USER, $userId);
+        $c2->add(TblspacefilePeer::FILE_CATEGORY, $id);
+        if (TblspacecategoryPeer::doCount($c1) > 0 || TblspacefilePeer::doCount($c2) > 0) {
+          $this->errMsg = 'Folder is not empty!';
+          $this->errCode = 'errFolderNotEmpty';
+          return;
+        }
+        $c = new Criteria();
+        $c->add(TblspacecategoryPeer::CAT_ID, $id);
+        $c->add(TblspacecategoryPeer::CAT_USER, $userId);
+        TblspacecategoryPeer::doDelete($c);
+        break;
+
+      case 'file':
+        $c = new Criteria();
+        $c->add(TblspacefilePeer::FILE_ID, $id);
+        $c->add(TblspacefilePeer::FILE_USER, $userId);
+        $tblfile = TblspacefilePeer::doSelectOne($c);
+        if ($tblfile) $tblfile->delete();
+        break;
+    }
+    $this->errMsg = '';
+    $this->errCode = '';
+  }
+
+  public function executeUpload() {
+    //if (!$this->checkAuthentication()) return sfView::NONE;
+    $userId = $this->getRequestParameter('userid');
+    $catId = $this->getRequestParameter('dir');
+
+    if ($this->getRequest()->hasErrors()) return false;
+    if (!$this->getRequest()->hasFiles()) return true;
+
+    $file = reset($this->getRequest()->getFileNames());
+    $fileName = $this->getRequest()->getFileName($file);
+    $fileType = $this->getRequest()->getFileType($file);
+    $fileSize = $this->getRequest()->getFileSize($file);
+    $fileError = $this->getRequest()->hasFileError($file);
+    $fileErrorNum = $this->getRequest()->getFileError($file);
+    if ($fileErrorNum || $fileError) return false;
+
+    $tempFile = violetUtil::getTempPath().$userId.'_'.$fileName;
+    $this->getRequest()->moveFile($file, $tempFile);
+    if ($this->getRequestParameter('unpack') == 'true') {
+      $tempPath = violetUtil::getTempPath($userId.'_'.date("YmdHis"), true);
+      myZip::Unzip($tempFile, $tempPath);
+      $this->MoveDirToSpace($tempPath, $catId, $userId);
+      unlink($tempFile);
+    } else {
+      $this->CreateSpaceFile($tempFile, $fileName, $fileSize, $catId, $userId);
+    }
+
+    return sfView::NONE;
+  }
+
+  public function executeSave() {
+    $content = file_get_contents('php://input');
+    if ($content == '') {
+      $this->errMsg = 'Error when saving file';
+      $this->errCode = 'errSave6'; // khong tim thay noi dung bai giang
+      return;
+    }
+    $this->fileId = $this->getRequestParameter('fileid', '');
+    if ($this->fileId == '') {
+      $userId = $this->getRequestParameter('userid');
+      $fileName = $this->getRequestParameter('name');
+      $catId = $this->getRequestParameter('dir', -1);
+
+      $tblres = new Tblspaceresource();
+      $tblres->setResFilename($fileName);
+      $tblres->setResFilesize(strlen($content));
+      $tblres->setResFilecrc(crc32($content));
+      $tblres->save();
+      file_put_contents($tblres->getFullFilename(true), $content);
+
+      $tblfile = new Tblspacefile();
+      $tblfile->setFileResource($tblres->getResId());
+      $tblfile->setFileCategory($catId);
+      $tblfile->setFileUser($userId);
+      $tblfile->setFileName($fileName);
+      $tblfile->setFileDate(date('Y-m-d H:i:s'));
+      $tblfile->save();
+      $this->fileId = $tblfile->getFileId();
+    } else {
+      $tblfile = TblspacefilePeer::retrieveByPk($this->fileId);
+      $tblfile->setFileDate(date('Y-m-d H:i:s'));
+      $tblfile->save();
+
+      $tblres = $tblfile->getTblspaceresource();
+      $tblres->setResFilesize(strlen($content));
+      $tblres->setResFilecrc(crc32($content));
+      $tblres->save();
+      file_put_contents($tblres->getFullFilename(), $content);
+    }
+
+    $this->fileName = $fileName;
+    $this->errCode = '';
+    $this->errMsg = '';
+  }
+
+  public function executeFile() {
+    $fileId = $this->getRequestParameter('id');
+    $tblres = TblspacefilePeer::retrieveByPk($fileId)->getTblspaceresource();
+    $fileName = $tblres->getFullFilename();
+    $ext = strtolower(substr($fileName, strrpos($fileName, '.') + 1));
+
+    $userFileName = $this->getRequestParameter('filename');
+    if ($userFileName != null) {
+      $userExt = strtolower(substr($userFileName, strrpos($userFileName, '.') + 1));
+      if ($userExt != $ext) {
+        $fileName = substr($fileName, 0, strrpos($fileName, '.')) . ".$userExt";
+        $ext = $userExt;
+      }
+    }
+    header('Content-Type: '.violetUtil::getContentType($ext));
+    header('Content-Length: '.filesize($fileName));
+    fpassthru(fopen($fileName, 'rb'));
+    return sfView::NONE;
+  }
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/apps/platform/modules/space/templates/deleteSuccess.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/apps/platform/modules/space/templates/deleteSuccess.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/apps/platform/modules/space/templates/deleteSuccess.php	(revision 19)
@@ -0,0 +1,1 @@
+<status err="<?php echo $errMsg; ?>" errCode="<?php echo $errCode; ?>" />
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/apps/platform/modules/space/templates/dirSuccess.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/apps/platform/modules/space/templates/dirSuccess.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/apps/platform/modules/space/templates/dirSuccess.php	(revision 19)
@@ -0,0 +1,10 @@
+<list parent_id="<?php echo $parentId; ?>" err="<?php echo $errMsg; ?>" errCode="<?php echo $errCode; ?>">
+  <!-- folders in current folder -->
+  <?php foreach ($tblcategories as $tblcategory): ?>
+    <folder id="<?php echo $tblcategory->getCatId() ?>" name="<?php echo $tblcategory->getCatName() ?>" filetype="" />
+  <?php endforeach; ?>
+  <!-- files in current folder -->
+  <?php foreach ($tblfiles as $tblfile): ?>
+    <file id="<?php echo $tblfile->getFileId() ?>" name="<?php echo $tblfile->getFileName() ?>" filetype="<?php echo $tblfile->getFileType() ?>" />
+  <?php endforeach; ?>
+</list>
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/apps/platform/modules/space/templates/mkdirSuccess.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/apps/platform/modules/space/templates/mkdirSuccess.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/apps/platform/modules/space/templates/mkdirSuccess.php	(revision 19)
@@ -0,0 +1,1 @@
+<status id="<?php echo $catId; ?>" err="<?php echo $errMsg; ?>" errCode="<?php echo $errCode; ?>" />
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/apps/platform/modules/space/templates/saveSuccess.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/apps/platform/modules/space/templates/saveSuccess.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/apps/platform/modules/space/templates/saveSuccess.php	(revision 19)
@@ -0,0 +1,3 @@
+<?php
+  echo "<status id='$fileId' name='$fileName' err='$errMsg' errCode='$errCode' />";
+?>
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/apps/platform/modules/space/templates/unpackSuccess.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/apps/platform/modules/space/templates/unpackSuccess.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/apps/platform/modules/space/templates/unpackSuccess.php	(revision 19)
@@ -0,0 +1,1 @@
+<status err="<?php echo $errMsg; ?>" errCode="<?php echo $errCode; ?>" />
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/apps/platform/modules/user/actions/actions.class.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/apps/platform/modules/user/actions/actions.class.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/apps/platform/modules/user/actions/actions.class.php	(revision 19)
@@ -0,0 +1,245 @@
+<?php
+
+/**
+ * user actions.
+ *
+ * @package    violetspace
+ * @subpackage user
+ * @author     Your name here
+ * @version    SVN: $Id: actions.class.php 2692 2006-11-15 21:03:55Z fabien $
+ */
+class userActions extends sfActions
+{
+  const TOKENPW = 'violet';
+
+  /**
+   * Executes index action
+   *
+   */
+  public function executeIndex()
+  {
+    $this->forward('default', 'module');
+  }
+
+  private function getUserField($fieldName, $value) {
+    $c = new Criteria();
+    $c->add($fieldName, $value);
+    return TbluserPeer::doSelectOne($c);
+  }
+
+  private function validateData($name, $email, $phone, &$error) {
+    return
+    ($name != null && !myUtility::validate('sfFilterValidator', $name, $error)) ||
+    ($name != null && !myUtility::validate('sfFullnameValidator', $name, $error)) ||
+    ($email != null && !myUtility::validate('sfEmailValidator', $email, $error)) ||
+    ($phone != null && !myUtility::validate('sfPhoneValidator', $phone, $error));
+  }
+
+  private function getUserInfo($tbluser) {
+    $result  = 'us_id='.$tbluser->getUsId();
+    $result .= '&username='.$tbluser->getUsUsername();
+    $result .= '&fullname='.$tbluser->getUsFullname();
+    $result .= '&gender='.($tbluser->getUsSex()==1? 'male': 'female');
+    $result .= '&email='.$tbluser->getUsEmail();
+    $result .= '&phone='.$tbluser->getUSPhone();
+    $result .= '&school='.$tbluser->getUsSchool();
+    $result .= '&province='.$tbluser->getUsProvince();
+    return $result;
+  }
+
+  private function getLicenseLevel($tbluser) {
+    $productId = $this->getRequestParameter('product');
+    $version = $this->getRequestParameter('version');
+    if ($productId == null) return 0;
+
+    $c = new Criteria();
+    $c->add(TblprolicensePeer::LI_TYPE, 1);
+    $c->add(TblprolicensePeer::LI_CUSTOMER, $tbluser->getUsId());
+    $c->add(TblprolicensePeer::LI_PRODUCT, $productId);
+    $c->add(TblprolicensePeer::LI_VERSION, $version, Criteria::GREATER_EQUAL);
+    $c->add(TblprolicensePeer::LI_EXPIREDATE, date('Y-m-d H:i:s'), Criteria::GREATER_EQUAL);
+    $license = TblprolicensePeer::doSelectOne($c);
+    $userdetail = TblblogcheckinfoPeer::retrieveByPk($tbluser->getUsId());
+    if ($license == null && $userdetail != null) {
+      $c = new Criteria();
+      $c->add(TblprolicensePeer::LI_TYPE, 2);
+      $c->add(TblprolicensePeer::LI_CUSTOMER, $userdetail->getCiSchool());
+      $c->add(TblprolicensePeer::LI_PRODUCT, $productId);
+      $c->add(TblprolicensePeer::LI_VERSION, $version, Criteria::GREATER_EQUAL);
+      $c->add(TblprolicensePeer::LI_EXPIREDATE, date('Y-m-d H:i:s'), Criteria::GREATER_EQUAL);
+      $license = TblprolicensePeer::doSelectOne($c);
+    }
+    if ($license == null) return 0;
+    return $license->getLiLevel();
+  }
+
+  public function executeLogin() {
+    $src = $this->getRequestParameter('src');
+    $token = $this->getRequestParameter('token');
+    $account = $this->getRequestParameter('username');
+    $password = $this->getRequestParameter('password');
+    if ($account == null || $password == null) return $this->renderText('status=1&errMsg=Not enough data');
+    if ($src == null || $token != md5($account.self::TOKENPW)) return $this->renderText('status=10');
+
+    $tbluser = $this->getUserField(TbluserPeer::US_USERNAME, $account);
+    if (!$tbluser) $tbluser = $this->getUserField(TbluserPeer::US_EMAIL, $account);
+    if (!$tbluser) $tbluser = $this->getUserField(TbluserPeer::US_PHONE, $account);
+    if (!$tbluser) return $this->renderText('status=2&errMsg=User not found');
+    if ($tbluser->getUsPassword() != md5($password)) return $this->renderText('status=3&errMsg=Incorrect password');
+
+    $loginResult = $this->getUserInfo($tbluser);
+    if ($tbluser->getUsStatus() == 0) return $this->renderText($loginResult.'&status=4&errMsg=Account is not activated');
+    $loginResult .= '&level='.$this->getLicenseLevel($tbluser);
+    $loginResult .= '&status=0';
+
+    try {
+      $this->getUser()->signIn($tbluser);
+    } catch (Exception $e) {
+      return $this->renderText('&status=5&errMsg='.$e->getMessage());
+    }
+    $ip = myUtility::getRealIpAddr();
+    myUtility::log("$ip login from $src, account: $account", 'apiuser.log');
+    return $this->renderText($loginResult);
+  }
+
+  public function executeLogout() {
+    $this->getUser()->signOut();
+    return sfView::NONE;
+  }
+
+  public function executeGetinfo() {
+    $src = $this->getRequestParameter('src');
+    $us_id = $this->getRequestParameter('us_id');
+    $uname = $this->getRequestParameter('username');
+    $email = $this->getRequestParameter('email');
+    $phone = $this->getRequestParameter('phone');
+    $token = $this->getRequestParameter('token');
+    if ($src == null) return sfView::NONE;
+
+    if ($us_id && $token==md5($us_id.self::TOKENPW)) $tbluser = $this->getUserField(TbluserPeer::US_ID, $us_id);
+    if ($uname && $token==md5($uname.self::TOKENPW)) $tbluser = $this->getUserField(TbluserPeer::US_USERNAME, $uname);
+    if ($email && $token==md5($email.self::TOKENPW)) $tbluser = $this->getUserField(TbluserPeer::US_EMAIL, $email);
+    if ($phone && $token==md5($phone.self::TOKENPW)) $tbluser = $this->getUserField(TbluserPeer::US_PHONE, $phone);
+
+    if ($tbluser) $result = $this->getUserInfo($tbluser);
+    else return sfView::NONE;
+
+    $ip = myUtility::getRealIpAddr();
+    myUtility::log("$ip get from $src".($tbluser? '': ' failed'), 'apiuser.log');
+    return $this->renderText($result);
+  }
+
+  public function executeUpdate() {
+    $src = $this->getRequestParameter('src');
+    $us_id = $this->getRequestParameter('us_id');
+    $username = $this->getRequestParameter('username');
+    $password = $this->getRequestParameter('password');
+    $fullname = $this->getRequestParameter('fullname'); 
+    $gender = $this->getRequestParameter('gender'); 
+    $email = $this->getRequestParameter('email');
+    $phone = $this->getRequestParameter('phone');
+    $school = $this->getRequestParameter('school');
+    $province = $this->getRequestParameter('province');
+    $token = $this->getRequestParameter('token');
+    $sendmail = $this->getRequestParameter('sendmail');
+    $oldpass = $this->getRequestParameter('oldpass');
+
+    if ($src == null) return $this->renderText('status=10');
+    if ($this->validateData($fullname, $email, $phone, $error)) return $this->renderText('status=7&errMsg='.$error);
+
+    if ($us_id == null) {
+      if ($token != md5($username.self::TOKENPW)) return $this->renderText('status=10');
+      if (!$username || !$password || !$fullname) return $this->renderText('status=1&errMsg=Not enough data');
+      if ($this->getUserField(TbluserPeer::US_USERNAME, $username)) return $this->renderText('status=2&errMsg=Username has existed');
+      if ($this->getUserField(TbluserPeer::US_EMAIL, $email)) return $this->renderText('status=3&errMsg=Email has existed');
+      if ($this->getUserField(TbluserPeer::US_PHONE, $phone)) return $this->renderText('status=4&errMsg=Phone number has existed');
+      $tbluser = new Tbluser();
+    } else {
+      if ($token != md5($us_id.self::TOKENPW)) return $this->renderText('status=10');
+      $tbluser = TbluserPeer::retrieveByPK($us_id);
+      if ($tbluser == null) return $this->renderText('status=5&errMsg=User not found');
+      if (($username != null || $password != null) && md5($oldpass) != $tbluser->getUsPassword()) return $this->renderText('status=6&errMsg=Incorrect old password');
+      if ($email != null && $email != $tbluser->getUsEmail()) $tbluser->setEmailConfirm(0);
+      if ($phone != null && $phone != $tbluser->getUsPhone()) $tbluser->setMobileConfirm(0);
+    }
+
+    if ($username != null) $tbluser->setUsUsername($username);
+    if ($password != null) $tbluser->setUsPassword(md5($password));
+    if ($fullname != null) $tbluser->setUsFullname($fullname);
+    if ($gender != null) $tbluser->setUsSex($gender=='male'? 1: 2);
+    if ($email != null) $tbluser->setUsEmail($email);
+    if ($phone != null) $tbluser->setUsPhone($phone);
+    if ($school != null) $tbluser->setUsSchool($school);
+    if ($province != null) $tbluser->setUsProvince($province);
+    $tbluser->save();
+
+    if ($sendmail == 'true') userMessage::sendConfirmEmail($this->tbluser, $password);
+    $ip = myUtility::getRealIpAddr();
+    $act = ($us_id == null? 'create': 'update');
+    myUtility::log("$ip $act from $src".($tbluser? '': ' failed'), 'apiuser.log');
+    return $this->renderText('status=0&id='.$tbluser->getUsId());
+  }
+
+  public function executeForgotpassword() {
+    $src = $this->getRequestParameter('src');
+    $email = $this->getRequestParameter('email');
+    $token = $this->getRequestParameter('token');
+    if ($src != null && $email != null && $token == md5($email.self::TOKENPW)) {
+      $c = new Criteria();
+      $c->add(TbluserPeer::US_EMAIL, trim($email));
+      $tbluser = TbluserPeer::doSelectOne($c);
+      if ($tbluser != null) {
+        $res = userMessage::sendForgotPassEmail($tbluser);
+        $ip = myUtility::getRealIpAddr();
+        $acc = $tbluser->getUsUsername();
+        myUtility::log("$ip from $src get password for $acc".($res?'':' failed'), 'apiuser.log');
+        return $this->renderText('status=0');
+      }
+      return $this->renderText('status=1&errMsg=Email not found');
+    }
+    return $this->renderText('status=10');
+  }
+
+  public function executeGetonlineuser() {
+    return sfView::NONE;
+  }
+
+  public function executeActivate() {
+    $arParams['access_key']   = $this->getRequestParameter('access_key', 'no_access_key');
+    $arParams['command']      = $this->getRequestParameter('command', 'no_command');
+    $arParams['mo_message']   = $this->getRequestParameter('mo_message', 'no_mo_message');
+    $arParams['msisdn']       = $this->getRequestParameter('msisdn', 'no_msisdn');
+    $arParams['request_id']   = $this->getRequestParameter('request_id', 'no_request_id');
+    $arParams['request_time'] = $this->getRequestParameter('request_time', 'no_request_time');
+    $arParams['short_code']   = $this->getRequestParameter('short_code', 'no_short_code');
+    $arParams['signature']    = $this->getRequestParameter('signature', 'no_signature');
+
+    $data  = "access_key=" . $arParams['access_key'] . "&command=" . $arParams['command'] . "&mo_message=" . $arParams['mo_message'] . "&msisdn=" . $arParams['msisdn'];
+    $data .= "&request_id=" . $arParams['request_id'] . "&request_time=" . $arParams['request_time'] . "&short_code=" . $arParams['short_code'];
+    $secret = 'evvx931itxysfnp9m94rf2vxd101zegr';
+    $signature = hash_hmac("sha256", $data, $secret);
+
+    if ($arParams['signature'] == $signature) {
+      $phone = preg_replace('/^84/', '0', $arParams['msisdn']);
+      $tbluser = $tbluser = $this->getUserField(TbluserPeer::US_PHONE, $phone);
+      if ($tbluser != null) {
+        if ($tbluser->getMobileConfirm() == 0) {
+          $tbluser->setMobileConfirm(1);
+          $tbluser->save();
+          $arResponse['sms'] = 'Kich hoat thanh cong tai khoan '.$tbluser->getUsUsername();
+        } else {
+          $arResponse['sms'] = 'Tai khoan '.$tbluser->getUsUsername().' da duoc kich hoat';
+        }
+      } else {
+        $arResponse['sms'] = 'Khong tim thay so dien thoai tren Violet.vn';
+      }
+    } else {
+      $arResponse['sms'] = 'Sai chu ky';
+    }
+
+    $arResponse['status'] = 1;
+    $arResponse['type'] = 'text';
+    myUtility::log($arParams['msisdn'].': '.$arParams['mo_message'].' -> '.$arParams['short_code'].' | '.$arResponse['sms'], 'sms.log');
+    return $this->renderText(json_encode($arResponse));
+  }
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/apps/platform/templates/layout.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/apps/platform/templates/layout.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/apps/platform/templates/layout.php	(revision 19)
@@ -0,0 +1,18 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+
+<?php include_http_metas() ?>
+<?php include_metas() ?>
+
+<?php include_title() ?>
+
+<link rel="shortcut icon" href="/favicon.ico" />
+
+</head>
+<body>
+
+<?php echo $sf_data->getRaw('sf_content') ?>
+
+</body>
+</html>
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/cache/platform/prod/config/VERSION
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/cache/platform/prod/config/VERSION	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/cache/platform/prod/config/VERSION	(revision 19)
@@ -0,0 +1,1 @@
+1.0.22
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/cache/platform/prod/config/config_app.yml.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/cache/platform/prod/config/config_app.yml.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/cache/platform/prod/config/config_app.yml.php	(revision 19)
@@ -0,0 +1,13 @@
+<?php
+// auto-generated by sfDefineEnvironmentConfigHandler
+// date: 2014/05/07 16:15:25
+sfConfig::add(array(
+  'app_basehost' => 'api.violet.vn',
+  'app_convert_exe' => '/usr/bin/convert',
+  'app_identify_exe' => '/usr/bin/identify',
+  'app_mplayer_exe' => '/usr/bin/mplayer',
+  'app_flvtool2_exe' => '/usr/bin/flvtool2',
+  'app_ffmpeg_exe' => '/usr/local/bin/ffmpeg',
+  'app_swfdump_exe' => '/usr/local/bin/swfdump',
+  'app_7z_exe' => '/usr/local/bin/7z',
+));
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/cache/platform/prod/config/config_autoload.yml.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/cache/platform/prod/config/config_autoload.yml.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/cache/platform/prod/config/config_autoload.yml.php	(revision 19)
@@ -0,0 +1,874 @@
+<?php
+// auto-generated by sfAutoloadConfigHandler
+// date: 2014/05/07 16:15:25
+return array(
+
+// symfony
+'sfWebRequest' => '/usr/local/src/symfony/lib/request/sfWebRequest.class.php',
+'sfRequest' => '/usr/local/src/symfony/lib/request/sfRequest.class.php',
+'sfConsoleRequest' => '/usr/local/src/symfony/lib/request/sfConsoleRequest.class.php',
+'sfRichTextEditorTinyMCE' => '/usr/local/src/symfony/lib/helper/sfRichTextEditorTinyMCE.class.php',
+'sfRichTextEditorFCK' => '/usr/local/src/symfony/lib/helper/sfRichTextEditorFCK.class.php',
+'sfRichTextEditor' => '/usr/local/src/symfony/lib/helper/sfRichTextEditor.class.php',
+'sfAction' => '/usr/local/src/symfony/lib/action/sfAction.class.php',
+'sfActionStackEntry' => '/usr/local/src/symfony/lib/action/sfActionStackEntry.class.php',
+'sfActionStack' => '/usr/local/src/symfony/lib/action/sfActionStack.class.php',
+'sfActions' => '/usr/local/src/symfony/lib/action/sfActions.class.php',
+'sfComponent' => '/usr/local/src/symfony/lib/action/sfComponent.class.php',
+'sfComponents' => '/usr/local/src/symfony/lib/action/sfComponents.class.php',
+'sfSecurityUser' => '/usr/local/src/symfony/lib/user/sfSecurityUser.class.php',
+'sfUser' => '/usr/local/src/symfony/lib/user/sfUser.class.php',
+'sfBasicSecurityUser' => '/usr/local/src/symfony/lib/user/sfBasicSecurityUser.class.php',
+'sfPropelDatabaseSchema' => '/usr/local/src/symfony/lib/addon/propel/sfPropelDatabaseSchema.class.php',
+'sfPropelUniqueValidator' => '/usr/local/src/symfony/lib/addon/propel/validator/sfPropelUniqueValidator.class.php',
+'sfPropelManyToMany' => '/usr/local/src/symfony/lib/addon/propel/sfPropelManyToMany.class.php',
+'sfPropelDatabase' => '/usr/local/src/symfony/lib/addon/propel/database/sfPropelDatabase.class.php',
+'sfPropelDataRetriever' => '/usr/local/src/symfony/lib/addon/propel/database/sfPropelDataRetriever.class.php',
+'sfPropelData' => '/usr/local/src/symfony/lib/addon/propel/sfPropelData.class.php',
+'sfPropelBehavior' => '/usr/local/src/symfony/lib/addon/propel/sfPropelBehavior.class.php',
+'sfPropelAdminGenerator' => '/usr/local/src/symfony/lib/addon/propel/generator/sfPropelAdminGenerator.class.php',
+'sfPropelCrudGenerator' => '/usr/local/src/symfony/lib/addon/propel/generator/sfPropelCrudGenerator.class.php',
+'sfPropelPager' => '/usr/local/src/symfony/lib/addon/propel/sfPropelPager.class.php',
+'SfExtensionPeerBuilder' => '/usr/local/src/symfony/lib/addon/propel/builder/SfExtensionPeerBuilder.php',
+'SfMapBuilderBuilder' => '/usr/local/src/symfony/lib/addon/propel/builder/SfMapBuilderBuilder.php',
+'SfExtensionObjectBuilder' => '/usr/local/src/symfony/lib/addon/propel/builder/SfExtensionObjectBuilder.php',
+'SfObjectBuilder' => '/usr/local/src/symfony/lib/addon/propel/builder/SfObjectBuilder.php',
+'SfMultiExtendObjectBuilder' => '/usr/local/src/symfony/lib/addon/propel/builder/SfMultiExtendObjectBuilder.php',
+'SfPeerBuilder' => '/usr/local/src/symfony/lib/addon/propel/builder/SfPeerBuilder.php',
+'sfData' => '/usr/local/src/symfony/lib/addon/sfData.class.php',
+'sfPager' => '/usr/local/src/symfony/lib/addon/sfPager.class.php',
+'sfMail' => '/usr/local/src/symfony/lib/addon/sfMail.class.php',
+'sfDebugConnection' => '/usr/local/src/symfony/lib/addon/creole/drivers/sfDebugConnection.php',
+'sfCreoleSessionStorage' => '/usr/local/src/symfony/lib/addon/creole/storage/sfCreoleSessionStorage.class.php',
+'sfCreoleDatabase' => '/usr/local/src/symfony/lib/addon/creole/database/sfCreoleDatabase.class.php',
+'sfMessageSource_Creole' => '/usr/local/src/symfony/lib/addon/creole/i18n/sfMessageSource_Creole.class.php',
+'sfEzComponentsBridge' => '/usr/local/src/symfony/lib/addon/bridge/sfEzComponentsBridge.class.php',
+'sfZendFrameworkBridge' => '/usr/local/src/symfony/lib/addon/bridge/sfZendFrameworkBridge.class.php',
+'sfActionException' => '/usr/local/src/symfony/lib/exception/sfActionException.class.php',
+'sfCacheException' => '/usr/local/src/symfony/lib/exception/sfCacheException.class.php',
+'sfRenderException' => '/usr/local/src/symfony/lib/exception/sfRenderException.class.php',
+'sfParseException' => '/usr/local/src/symfony/lib/exception/sfParseException.class.php',
+'sfViewException' => '/usr/local/src/symfony/lib/exception/sfViewException.class.php',
+'sfAutoloadException' => '/usr/local/src/symfony/lib/exception/sfAutoloadException.class.php',
+'sfFilterException' => '/usr/local/src/symfony/lib/exception/sfFilterException.class.php',
+'sfFileException' => '/usr/local/src/symfony/lib/exception/sfFileException.class.php',
+'sfSecurityException' => '/usr/local/src/symfony/lib/exception/sfSecurityException.class.php',
+'sfFactoryException' => '/usr/local/src/symfony/lib/exception/sfFactoryException.class.php',
+'sfValidatorException' => '/usr/local/src/symfony/lib/exception/sfValidatorException.class.php',
+'sfForwardException' => '/usr/local/src/symfony/lib/exception/sfForwardException.class.php',
+'sfConfigurationException' => '/usr/local/src/symfony/lib/exception/sfConfigurationException.class.php',
+'sfException' => '/usr/local/src/symfony/lib/exception/sfException.class.php',
+'sfContextException' => '/usr/local/src/symfony/lib/exception/sfContextException.class.php',
+'sfStorageException' => '/usr/local/src/symfony/lib/exception/sfStorageException.class.php',
+'sfStopException' => '/usr/local/src/symfony/lib/exception/sfStopException.class.php',
+'sfControllerException' => '/usr/local/src/symfony/lib/exception/sfControllerException.class.php',
+'sfDatabaseException' => '/usr/local/src/symfony/lib/exception/sfDatabaseException.class.php',
+'sfInitializationException' => '/usr/local/src/symfony/lib/exception/sfInitializationException.class.php',
+'sfError404Exception' => '/usr/local/src/symfony/lib/exception/sfError404Exception.class.php',
+'sfSessionTestStorage' => '/usr/local/src/symfony/lib/storage/sfSessionTestStorage.class.php',
+'sfPostgreSQLSessionStorage' => '/usr/local/src/symfony/lib/storage/sfPostgreSQLSessionStorage.class.php',
+'sfStorage' => '/usr/local/src/symfony/lib/storage/sfStorage.class.php',
+'sfMySQLSessionStorage' => '/usr/local/src/symfony/lib/storage/sfMySQLSessionStorage.class.php',
+'sfPDOSessionStorage' => '/usr/local/src/symfony/lib/storage/sfPDOSessionStorage.class.php',
+'sfSessionStorage' => '/usr/local/src/symfony/lib/storage/sfSessionStorage.class.php',
+'sfCompareValidator' => '/usr/local/src/symfony/lib/validator/sfCompareValidator.class.php',
+'sfValidator' => '/usr/local/src/symfony/lib/validator/sfValidator.class.php',
+'sfUrlValidator' => '/usr/local/src/symfony/lib/validator/sfUrlValidator.class.php',
+'sfNumberValidator' => '/usr/local/src/symfony/lib/validator/sfNumberValidator.class.php',
+'sfCallbackValidator' => '/usr/local/src/symfony/lib/validator/sfCallbackValidator.class.php',
+'sfValidatorManager' => '/usr/local/src/symfony/lib/validator/sfValidatorManager.class.php',
+'sfRegexValidator' => '/usr/local/src/symfony/lib/validator/sfRegexValidator.class.php',
+'sfDateValidator' => '/usr/local/src/symfony/lib/validator/sfDateValidator.class.php',
+'sfEmailValidator' => '/usr/local/src/symfony/lib/validator/sfEmailValidator.class.php',
+'sfStringValidator' => '/usr/local/src/symfony/lib/validator/sfStringValidator.class.php',
+'sfHtmlValidator' => '/usr/local/src/symfony/lib/validator/sfHtmlValidator.class.php',
+'sfFileValidator' => '/usr/local/src/symfony/lib/validator/sfFileValidator.class.php',
+'sfRouting' => '/usr/local/src/symfony/lib/controller/sfRouting.class.php',
+'sfController' => '/usr/local/src/symfony/lib/controller/sfController.class.php',
+'sfFrontWebController' => '/usr/local/src/symfony/lib/controller/sfFrontWebController.class.php',
+'sfConsoleController' => '/usr/local/src/symfony/lib/controller/sfConsoleController.class.php',
+'sfWebController' => '/usr/local/src/symfony/lib/controller/sfWebController.class.php',
+'sfPDODatabase' => '/usr/local/src/symfony/lib/database/sfPDODatabase.class.php',
+'sfDatabaseManager' => '/usr/local/src/symfony/lib/database/sfDatabaseManager.class.php',
+'sfPostgreSQLDatabase' => '/usr/local/src/symfony/lib/database/sfPostgreSQLDatabase.class.php',
+'sfDatabase' => '/usr/local/src/symfony/lib/database/sfDatabase.class.php',
+'sfMySQLDatabase' => '/usr/local/src/symfony/lib/database/sfMySQLDatabase.class.php',
+'sfCommonFilter' => '/usr/local/src/symfony/lib/filter/sfCommonFilter.class.php',
+'sfBasicSecurityFilter' => '/usr/local/src/symfony/lib/filter/sfBasicSecurityFilter.class.php',
+'sfSecurityFilter' => '/usr/local/src/symfony/lib/filter/sfSecurityFilter.class.php',
+'sfFilterChain' => '/usr/local/src/symfony/lib/filter/sfFilterChain.class.php',
+'sfCacheFilter' => '/usr/local/src/symfony/lib/filter/sfCacheFilter.class.php',
+'sfWebDebugFilter' => '/usr/local/src/symfony/lib/filter/sfWebDebugFilter.class.php',
+'sfExecutionFilter' => '/usr/local/src/symfony/lib/filter/sfExecutionFilter.class.php',
+'sfRenderingFilter' => '/usr/local/src/symfony/lib/filter/sfRenderingFilter.class.php',
+'sfFlashFilter' => '/usr/local/src/symfony/lib/filter/sfFlashFilter.class.php',
+'sfFilter' => '/usr/local/src/symfony/lib/filter/sfFilter.class.php',
+'sfFillInFormFilter' => '/usr/local/src/symfony/lib/filter/sfFillInFormFilter.class.php',
+'sfI18N' => '/usr/local/src/symfony/lib/i18n/sfI18N.class.php',
+'sfMessageSource_SQLite' => '/usr/local/src/symfony/lib/i18n/sfMessageSource_SQLite.class.php',
+'sfChoiceFormat' => '/usr/local/src/symfony/lib/i18n/sfChoiceFormat.class.php',
+'sfMessageSource' => '/usr/local/src/symfony/lib/i18n/sfMessageSource.class.php',
+'sfDateFormat' => '/usr/local/src/symfony/lib/i18n/sfDateFormat.class.php',
+'sfNumberFormatInfo' => '/usr/local/src/symfony/lib/i18n/sfNumberFormatInfo.class.php',
+'sfNumberFormat' => '/usr/local/src/symfony/lib/i18n/sfNumberFormat.class.php',
+'sfMessageSource_gettext' => '/usr/local/src/symfony/lib/i18n/sfMessageSource_gettext.class.php',
+'sfMessageCache' => '/usr/local/src/symfony/lib/i18n/sfMessageCache.class.php',
+'sfIMessageSource' => '/usr/local/src/symfony/lib/i18n/sfIMessageSource.class.php',
+'sfCultureInfo' => '/usr/local/src/symfony/lib/i18n/sfCultureInfo.class.php',
+'TGettext_MO' => '/usr/local/src/symfony/lib/i18n/Gettext/MO.php',
+'TGettext' => '/usr/local/src/symfony/lib/i18n/Gettext/TGettext.class.php',
+'TGettext_PO' => '/usr/local/src/symfony/lib/i18n/Gettext/PO.php',
+'sfDateTimeFormatInfo' => '/usr/local/src/symfony/lib/i18n/sfDateTimeFormatInfo.class.php',
+'sfMessageSource_XLIFF' => '/usr/local/src/symfony/lib/i18n/sfMessageSource_XLIFF.class.php',
+'sfMessageSource_MySQL' => '/usr/local/src/symfony/lib/i18n/sfMessageSource_MySQL.class.php',
+'sfMessageFormat' => '/usr/local/src/symfony/lib/i18n/sfMessageFormat.class.php',
+'sfTimer' => '/usr/local/src/symfony/lib/debug/sfTimer.class.php',
+'sfTimerManager' => '/usr/local/src/symfony/lib/debug/sfTimerManager.class.php',
+'sfDebug' => '/usr/local/src/symfony/lib/debug/sfDebug.class.php',
+'sfWebDebug' => '/usr/local/src/symfony/lib/debug/sfWebDebug.class.php',
+'sfCore' => '/usr/local/src/symfony/lib/util/sfCore.class.php',
+'sfDomCssSelector' => '/usr/local/src/symfony/lib/util/sfDomCssSelector.class.php',
+'sfInflector' => '/usr/local/src/symfony/lib/util/sfInflector.class.php',
+'sfYaml' => '/usr/local/src/symfony/lib/util/sfYaml.class.php',
+'sfParameterHolder' => '/usr/local/src/symfony/lib/util/sfParameterHolder.class.php',
+'sfContext' => '/usr/local/src/symfony/lib/util/sfContext.class.php',
+'sfMixer' => '/usr/local/src/symfony/lib/util/sfMixer.class.php',
+'YAMLNode' => '/usr/local/src/symfony/lib/util/Spyc.class.php',
+'Spyc' => '/usr/local/src/symfony/lib/util/Spyc.class.php',
+'sfBrowser' => '/usr/local/src/symfony/lib/util/sfBrowser.class.php',
+'sfFakeRenderingFilter' => '/usr/local/src/symfony/lib/util/sfBrowser.class.php',
+'sfToolkit' => '/usr/local/src/symfony/lib/util/sfToolkit.class.php',
+'sfFinder' => '/usr/local/src/symfony/lib/util/sfFinder.class.php',
+'sfGlobToRegex' => '/usr/local/src/symfony/lib/util/sfFinder.class.php',
+'sfNumberCompare' => '/usr/local/src/symfony/lib/util/sfFinder.class.php',
+'sfFillInForm' => '/usr/local/src/symfony/lib/util/sfFillInForm.class.php',
+'sfAdminGenerator' => '/usr/local/src/symfony/lib/generator/sfAdminGenerator.class.php',
+'sfAdminColumn' => '/usr/local/src/symfony/lib/generator/sfAdminGenerator.class.php',
+'sfGeneratorManager' => '/usr/local/src/symfony/lib/generator/sfGeneratorManager.class.php',
+'sfCrudGenerator' => '/usr/local/src/symfony/lib/generator/sfCrudGenerator.class.php',
+'sfGenerator' => '/usr/local/src/symfony/lib/generator/sfGenerator.class.php',
+'sfTestBrowser' => '/usr/local/src/symfony/lib/test/sfTestBrowser.class.php',
+'sfRoutingConfigHandler' => '/usr/local/src/symfony/lib/config/sfRoutingConfigHandler.class.php',
+'sfCacheConfigHandler' => '/usr/local/src/symfony/lib/config/sfCacheConfigHandler.class.php',
+'sfViewConfigHandler' => '/usr/local/src/symfony/lib/config/sfViewConfigHandler.class.php',
+'sfYamlConfigHandler' => '/usr/local/src/symfony/lib/config/sfYamlConfigHandler.class.php',
+'sfCompileConfigHandler' => '/usr/local/src/symfony/lib/config/sfCompileConfigHandler.class.php',
+'sfValidatorConfigHandler' => '/usr/local/src/symfony/lib/config/sfValidatorConfigHandler.class.php',
+'sfDatabaseConfigHandler' => '/usr/local/src/symfony/lib/config/sfDatabaseConfigHandler.class.php',
+'sfFilterConfigHandler' => '/usr/local/src/symfony/lib/config/sfFilterConfigHandler.class.php',
+'sfGeneratorConfigHandler' => '/usr/local/src/symfony/lib/config/sfGeneratorConfigHandler.class.php',
+'sfPhpConfigHandler' => '/usr/local/src/symfony/lib/config/sfPhpConfigHandler.class.php',
+'sfConfigCache' => '/usr/local/src/symfony/lib/config/sfConfigCache.class.php',
+'sfRootConfigHandler' => '/usr/local/src/symfony/lib/config/sfRootConfigHandler.class.php',
+'sfDefineEnvironmentConfigHandler' => '/usr/local/src/symfony/lib/config/sfDefineEnvironmentConfigHandler.class.php',
+'sfSimpleYamlConfigHandler' => '/usr/local/src/symfony/lib/config/sfSimpleYamlConfigHandler.class.php',
+'sfSecurityConfigHandler' => '/usr/local/src/symfony/lib/config/sfSecurityConfigHandler.class.php',
+'sfConfigHandler' => '/usr/local/src/symfony/lib/config/sfConfigHandler.class.php',
+'sfFactoryConfigHandler' => '/usr/local/src/symfony/lib/config/sfFactoryConfigHandler.class.php',
+'sfLoader' => '/usr/local/src/symfony/lib/config/sfLoader.class.php',
+'sfConfig' => '/usr/local/src/symfony/lib/config/sfConfig.class.php',
+'sfLoggingConfigHandler' => '/usr/local/src/symfony/lib/config/sfLoggingConfigHandler.class.php',
+'sfAutoloadConfigHandler' => '/usr/local/src/symfony/lib/config/sfAutoloadConfigHandler.class.php',
+'sfFileCache' => '/usr/local/src/symfony/lib/cache/sfFileCache.class.php',
+'sfFunctionCache' => '/usr/local/src/symfony/lib/cache/sfFunctionCache.class.php',
+'sfProcessCache' => '/usr/local/src/symfony/lib/cache/sfProcessCache.class.php',
+'sfSQLiteCache' => '/usr/local/src/symfony/lib/cache/sfSQLiteCache.class.php',
+'sfCache' => '/usr/local/src/symfony/lib/cache/sfCache.class.php',
+'sfPHPView' => '/usr/local/src/symfony/lib/view/sfPHPView.class.php',
+'sfViewCacheManager' => '/usr/local/src/symfony/lib/view/sfViewCacheManager.class.php',
+'sfPartialView' => '/usr/local/src/symfony/lib/view/sfPartialView.class.php',
+'sfOutputEscaperGetterDecorator' => '/usr/local/src/symfony/lib/view/escaper/sfOutputEscaperGetterDecorator.class.php',
+'sfOutputEscaperIteratorDecorator' => '/usr/local/src/symfony/lib/view/escaper/sfOutputEscaperIteratorDecorator.class.php',
+'sfOutputEscaperObjectDecorator' => '/usr/local/src/symfony/lib/view/escaper/sfOutputEscaperObjectDecorator.class.php',
+'Countable' => '/usr/local/src/symfony/lib/view/escaper/sfOutputEscaperArrayDecorator.class.php',
+'sfOutputEscaperArrayDecorator' => '/usr/local/src/symfony/lib/view/escaper/sfOutputEscaperArrayDecorator.class.php',
+'sfOutputEscaper' => '/usr/local/src/symfony/lib/view/escaper/sfOutputEscaper.class.php',
+'sfMailView' => '/usr/local/src/symfony/lib/view/sfMailView.class.php',
+'sfView' => '/usr/local/src/symfony/lib/view/sfView.class.php',
+'sfWebResponse' => '/usr/local/src/symfony/lib/response/sfWebResponse.class.php',
+'sfConsoleResponse' => '/usr/local/src/symfony/lib/response/sfConsoleResponse.class.php',
+'sfResponse' => '/usr/local/src/symfony/lib/response/sfResponse.class.php',
+'sfLogManager' => '/usr/local/src/symfony/lib/log/sfLogManager.class.php',
+'sfFileLogger' => '/usr/local/src/symfony/lib/log/sfLogger/sfFileLogger.class.php',
+'sfWebDebugLogger' => '/usr/local/src/symfony/lib/log/sfLogger/sfWebDebugLogger.class.php',
+'sfLogger' => '/usr/local/src/symfony/lib/log/sfLogger.class.php',
+
+// propel
+'BaseObject' => '/usr/local/src/symfony/lib/vendor/propel/om/BaseObject.php',
+'Persistent' => '/usr/local/src/symfony/lib/vendor/propel/om/Persistent.php',
+'PreOrderNodeIterator' => '/usr/local/src/symfony/lib/vendor/propel/om/PreOrderNodeIterator.php',
+'PropelException' => '/usr/local/src/symfony/lib/vendor/propel/PropelException.php',
+'BasicLogger' => '/usr/local/src/symfony/lib/vendor/propel/logger/BasicLogger.php',
+'MojaviLogAdapter' => '/usr/local/src/symfony/lib/vendor/propel/logger/MojaviLogAdapter.php',
+'Propel' => '/usr/local/src/symfony/lib/vendor/propel/Propel.php',
+'UniqueValidator' => '/usr/local/src/symfony/lib/vendor/propel/validator/UniqueValidator.php',
+'MinValueValidator' => '/usr/local/src/symfony/lib/vendor/propel/validator/MinValueValidator.php',
+'MatchValidator' => '/usr/local/src/symfony/lib/vendor/propel/validator/MatchValidator.php',
+'NotMatchValidator' => '/usr/local/src/symfony/lib/vendor/propel/validator/NotMatchValidator.php',
+'MaxValueValidator' => '/usr/local/src/symfony/lib/vendor/propel/validator/MaxValueValidator.php',
+'ValidationFailed' => '/usr/local/src/symfony/lib/vendor/propel/validator/ValidationFailed.php',
+'RequiredValidator' => '/usr/local/src/symfony/lib/vendor/propel/validator/RequiredValidator.php',
+'ValidValuesValidator' => '/usr/local/src/symfony/lib/vendor/propel/validator/ValidValuesValidator.php',
+'BasicValidator' => '/usr/local/src/symfony/lib/vendor/propel/validator/BasicValidator.php',
+'MaxLengthValidator' => '/usr/local/src/symfony/lib/vendor/propel/validator/MaxLengthValidator.php',
+'MinLengthValidator' => '/usr/local/src/symfony/lib/vendor/propel/validator/MinLengthValidator.php',
+'Transaction' => '/usr/local/src/symfony/lib/vendor/propel/util/Transaction.php',
+'PropelPager' => '/usr/local/src/symfony/lib/vendor/propel/util/PropelPager.php',
+'BasePeer' => '/usr/local/src/symfony/lib/vendor/propel/util/BasePeer.php',
+'PeerInfo' => '/usr/local/src/symfony/lib/vendor/propel/util/PeerInfo.php',
+'Criteria' => '/usr/local/src/symfony/lib/vendor/propel/util/Criteria.php',
+'CriterionIterator' => '/usr/local/src/symfony/lib/vendor/propel/util/Criteria.php',
+'Criterion' => '/usr/local/src/symfony/lib/vendor/propel/util/Criteria.php',
+'Join' => '/usr/local/src/symfony/lib/vendor/propel/util/Criteria.php',
+'MapBuilder' => '/usr/local/src/symfony/lib/vendor/propel/map/MapBuilder.php',
+'TableMap' => '/usr/local/src/symfony/lib/vendor/propel/map/TableMap.php',
+'DatabaseMap' => '/usr/local/src/symfony/lib/vendor/propel/map/DatabaseMap.php',
+'ValidatorMap' => '/usr/local/src/symfony/lib/vendor/propel/map/ValidatorMap.php',
+'ColumnMap' => '/usr/local/src/symfony/lib/vendor/propel/map/ColumnMap.php',
+'DBMSSQL' => '/usr/local/src/symfony/lib/vendor/propel/adapter/DBMSSQL.php',
+'DBPostgres' => '/usr/local/src/symfony/lib/vendor/propel/adapter/DBPostgres.php',
+'DBMySQL' => '/usr/local/src/symfony/lib/vendor/propel/adapter/DBMySQL.php',
+'DBSQLite' => '/usr/local/src/symfony/lib/vendor/propel/adapter/DBSQLite.php',
+'DBSybase' => '/usr/local/src/symfony/lib/vendor/propel/adapter/DBSybase.php',
+'DBNone' => '/usr/local/src/symfony/lib/vendor/propel/adapter/DBNone.php',
+'DBAdapter' => '/usr/local/src/symfony/lib/vendor/propel/adapter/DBAdapter.php',
+'DBMySQLi' => '/usr/local/src/symfony/lib/vendor/propel/adapter/DBMySQLi.php',
+'DBOracle' => '/usr/local/src/symfony/lib/vendor/propel/adapter/DBOracle.php',
+
+// creole
+'SQLiteTypes' => '/usr/local/src/symfony/lib/vendor/creole/drivers/sqlite/SQLiteTypes.php',
+'SQLiteIdGenerator' => '/usr/local/src/symfony/lib/vendor/creole/drivers/sqlite/SQLiteIdGenerator.php',
+'SQLiteResultSet' => '/usr/local/src/symfony/lib/vendor/creole/drivers/sqlite/SQLiteResultSet.php',
+'SQLitePreparedStatement' => '/usr/local/src/symfony/lib/vendor/creole/drivers/sqlite/SQLitePreparedStatement.php',
+'SQLiteConnection' => '/usr/local/src/symfony/lib/vendor/creole/drivers/sqlite/SQLiteConnection.php',
+'SQLiteTableInfo' => '/usr/local/src/symfony/lib/vendor/creole/drivers/sqlite/metadata/SQLiteTableInfo.php',
+'SQLiteDatabaseInfo' => '/usr/local/src/symfony/lib/vendor/creole/drivers/sqlite/metadata/SQLiteDatabaseInfo.php',
+'SQLiteResultSetIterator' => '/usr/local/src/symfony/lib/vendor/creole/drivers/sqlite/SQLiteResultSetIterator.php',
+'SQLiteStatement' => '/usr/local/src/symfony/lib/vendor/creole/drivers/sqlite/SQLiteStatement.php',
+'MySQLStatement' => '/usr/local/src/symfony/lib/vendor/creole/drivers/mysql/MySQLStatement.php',
+'MySQLResultSet' => '/usr/local/src/symfony/lib/vendor/creole/drivers/mysql/MySQLResultSet.php',
+'MySQLConnection' => '/usr/local/src/symfony/lib/vendor/creole/drivers/mysql/MySQLConnection.php',
+'MySQLDatabaseInfo' => '/usr/local/src/symfony/lib/vendor/creole/drivers/mysql/metadata/MySQLDatabaseInfo.php',
+'MySQLTableInfo' => '/usr/local/src/symfony/lib/vendor/creole/drivers/mysql/metadata/MySQLTableInfo.php',
+'MySQLPreparedStatement' => '/usr/local/src/symfony/lib/vendor/creole/drivers/mysql/MySQLPreparedStatement.php',
+'MySQLIdGenerator' => '/usr/local/src/symfony/lib/vendor/creole/drivers/mysql/MySQLIdGenerator.php',
+'MySQLTypes' => '/usr/local/src/symfony/lib/vendor/creole/drivers/mysql/MySQLTypes.php',
+'MySQLiIdGenerator' => '/usr/local/src/symfony/lib/vendor/creole/drivers/mysqli/MySQLiIdGenerator.php',
+'MySQLiResultSet' => '/usr/local/src/symfony/lib/vendor/creole/drivers/mysqli/MySQLiResultSet.php',
+'MySQLiStatement' => '/usr/local/src/symfony/lib/vendor/creole/drivers/mysqli/MySQLiStatement.php',
+'MySQLiConnection' => '/usr/local/src/symfony/lib/vendor/creole/drivers/mysqli/MySQLiConnection.php',
+'MySQLiTableInfo' => '/usr/local/src/symfony/lib/vendor/creole/drivers/mysqli/metadata/MySQLiTableInfo.php',
+'MySQLiDatabaseInfo' => '/usr/local/src/symfony/lib/vendor/creole/drivers/mysqli/metadata/MySQLiDatabaseInfo.php',
+'MySQLiPreparedStatement' => '/usr/local/src/symfony/lib/vendor/creole/drivers/mysqli/MySQLiPreparedStatement.php',
+'MSSQLConnection' => '/usr/local/src/symfony/lib/vendor/creole/drivers/mssql/MSSQLConnection.php',
+'MSSQLCallableStatement' => '/usr/local/src/symfony/lib/vendor/creole/drivers/mssql/MSSQLCallableStatement.php',
+'MSSQLPreparedStatement' => '/usr/local/src/symfony/lib/vendor/creole/drivers/mssql/MSSQLPreparedStatement.php',
+'MSSQLIdGenerator' => '/usr/local/src/symfony/lib/vendor/creole/drivers/mssql/MSSQLIdGenerator.php',
+'MSSQLTypes' => '/usr/local/src/symfony/lib/vendor/creole/drivers/mssql/MSSQLTypes.php',
+'MSSQLResultSet' => '/usr/local/src/symfony/lib/vendor/creole/drivers/mssql/MSSQLResultSet.php',
+'MSSQLTableInfo' => '/usr/local/src/symfony/lib/vendor/creole/drivers/mssql/metadata/MSSQLTableInfo.php',
+'MSSQLDatabaseInfo' => '/usr/local/src/symfony/lib/vendor/creole/drivers/mssql/metadata/MSSQLDatabaseInfo.php',
+'MSSQLStatement' => '/usr/local/src/symfony/lib/vendor/creole/drivers/mssql/MSSQLStatement.php',
+'OCI8Connection' => '/usr/local/src/symfony/lib/vendor/creole/drivers/oracle/OCI8Connection.php',
+'OCI8PreparedStatement' => '/usr/local/src/symfony/lib/vendor/creole/drivers/oracle/OCI8PreparedStatement.php',
+'OCI8Statement' => '/usr/local/src/symfony/lib/vendor/creole/drivers/oracle/OCI8Statement.php',
+'OCI8DatabaseInfo' => '/usr/local/src/symfony/lib/vendor/creole/drivers/oracle/metadata/OCI8DatabaseInfo.php',
+'OCI8TableInfo' => '/usr/local/src/symfony/lib/vendor/creole/drivers/oracle/metadata/OCI8TableInfo.php',
+'OCI8IdGenerator' => '/usr/local/src/symfony/lib/vendor/creole/drivers/oracle/OCI8IdGenerator.php',
+'OCI8Types' => '/usr/local/src/symfony/lib/vendor/creole/drivers/oracle/OCI8Types.php',
+'OCI8ResultSet' => '/usr/local/src/symfony/lib/vendor/creole/drivers/oracle/OCI8ResultSet.php',
+'PgSQLResultSet' => '/usr/local/src/symfony/lib/vendor/creole/drivers/pgsql/PgSQLResultSet.php',
+'PgSQLStatement' => '/usr/local/src/symfony/lib/vendor/creole/drivers/pgsql/PgSQLStatement.php',
+'PgSQLPreparedStatement' => '/usr/local/src/symfony/lib/vendor/creole/drivers/pgsql/PgSQLPreparedStatement.php',
+'PgSQLTypes' => '/usr/local/src/symfony/lib/vendor/creole/drivers/pgsql/PgSQLTypes.php',
+'PgSQLConnection' => '/usr/local/src/symfony/lib/vendor/creole/drivers/pgsql/PgSQLConnection.php',
+'PgSQLResultSetIterator' => '/usr/local/src/symfony/lib/vendor/creole/drivers/pgsql/PgSQLResultSetIterator.php',
+'PgSQLTableInfo' => '/usr/local/src/symfony/lib/vendor/creole/drivers/pgsql/metadata/PgSQLTableInfo.php',
+'PgSQLDatabaseInfo' => '/usr/local/src/symfony/lib/vendor/creole/drivers/pgsql/metadata/PgSQLDatabaseInfo.php',
+'PgSQLIdGenerator' => '/usr/local/src/symfony/lib/vendor/creole/drivers/pgsql/PgSQLIdGenerator.php',
+'ODBCStatement' => '/usr/local/src/symfony/lib/vendor/creole/drivers/odbc/ODBCStatement.php',
+'ODBCResultSetCommon' => '/usr/local/src/symfony/lib/vendor/creole/drivers/odbc/ODBCResultSetCommon.php',
+'ODBCPreparedStatement' => '/usr/local/src/symfony/lib/vendor/creole/drivers/odbc/ODBCPreparedStatement.php',
+'ODBCDatabaseInfo' => '/usr/local/src/symfony/lib/vendor/creole/drivers/odbc/metadata/ODBCDatabaseInfo.php',
+'ODBCTableInfo' => '/usr/local/src/symfony/lib/vendor/creole/drivers/odbc/metadata/ODBCTableInfo.php',
+'ODBCConnection' => '/usr/local/src/symfony/lib/vendor/creole/drivers/odbc/ODBCConnection.php',
+'ODBCResultResource' => '/usr/local/src/symfony/lib/vendor/creole/drivers/odbc/ODBCConnection.php',
+'MySQLAdapter' => '/usr/local/src/symfony/lib/vendor/creole/drivers/odbc/adapters/MySQLAdapter.php',
+'ODBCAdapter' => '/usr/local/src/symfony/lib/vendor/creole/drivers/odbc/adapters/ODBCAdapter.php',
+'CodeBaseAdapter' => '/usr/local/src/symfony/lib/vendor/creole/drivers/odbc/adapters/CodeBaseAdapter.php',
+'ODBCCachedResultSet' => '/usr/local/src/symfony/lib/vendor/creole/drivers/odbc/ODBCCachedResultSet.php',
+'ODBCResultSet' => '/usr/local/src/symfony/lib/vendor/creole/drivers/odbc/ODBCResultSet.php',
+'ODBCIdGenerator' => '/usr/local/src/symfony/lib/vendor/creole/drivers/odbc/ODBCIdGenerator.php',
+'ODBCTypes' => '/usr/local/src/symfony/lib/vendor/creole/drivers/odbc/ODBCTypes.php',
+'ConnectionCommon' => '/usr/local/src/symfony/lib/vendor/creole/common/ConnectionCommon.php',
+'PreparedStatementCommon' => '/usr/local/src/symfony/lib/vendor/creole/common/PreparedStatementCommon.php',
+'StatementCommon' => '/usr/local/src/symfony/lib/vendor/creole/common/StatementCommon.php',
+'ResultSetCommon' => '/usr/local/src/symfony/lib/vendor/creole/common/ResultSetCommon.php',
+'CreoleTypes' => '/usr/local/src/symfony/lib/vendor/creole/CreoleTypes.php',
+'PreparedStatement' => '/usr/local/src/symfony/lib/vendor/creole/PreparedStatement.php',
+'ResultSetIterator' => '/usr/local/src/symfony/lib/vendor/creole/ResultSetIterator.php',
+'IdGenerator' => '/usr/local/src/symfony/lib/vendor/creole/IdGenerator.php',
+'Creole' => '/usr/local/src/symfony/lib/vendor/creole/Creole.php',
+'ResultSet' => '/usr/local/src/symfony/lib/vendor/creole/ResultSet.php',
+'DebugConnection' => '/usr/local/src/symfony/lib/vendor/creole/contrib/DebugConnection.php',
+'ForeignKeyInfo' => '/usr/local/src/symfony/lib/vendor/creole/metadata/ForeignKeyInfo.php',
+'DatabaseInfo' => '/usr/local/src/symfony/lib/vendor/creole/metadata/DatabaseInfo.php',
+'TableInfo' => '/usr/local/src/symfony/lib/vendor/creole/metadata/TableInfo.php',
+'ColumnInfo' => '/usr/local/src/symfony/lib/vendor/creole/metadata/ColumnInfo.php',
+'PrimaryKeyInfo' => '/usr/local/src/symfony/lib/vendor/creole/metadata/PrimaryKeyInfo.php',
+'IndexInfo' => '/usr/local/src/symfony/lib/vendor/creole/metadata/IndexInfo.php',
+'SQLStatementExtractor' => '/usr/local/src/symfony/lib/vendor/creole/util/sql/SQLStatementExtractor.php',
+'Blob' => '/usr/local/src/symfony/lib/vendor/creole/util/Blob.php',
+'Clob' => '/usr/local/src/symfony/lib/vendor/creole/util/Clob.php',
+'Lob' => '/usr/local/src/symfony/lib/vendor/creole/util/Lob.php',
+'CallableStatement' => '/usr/local/src/symfony/lib/vendor/creole/CallableStatement.php',
+'Connection' => '/usr/local/src/symfony/lib/vendor/creole/Connection.php',
+'Statement' => '/usr/local/src/symfony/lib/vendor/creole/Statement.php',
+'SQLException' => '/usr/local/src/symfony/lib/vendor/creole/SQLException.php',
+
+// propel addon
+'Propel' => '/usr/local/src/symfony/lib/addon/propel/sfPropelAutoload.php',
+
+// plugins lib
+'sfPropel13LogWrapper' => '/home/www/plugins/sfPropel13Plugin/lib/propel/sfPropel13LogWrapper.class.php',
+'sfPropel13Database' => '/home/www/plugins/sfPropel13Plugin/lib/propel/database/sfPropel13Database.class.php',
+'sfPropel13AdminGenerator' => '/home/www/plugins/sfPropel13Plugin/lib/propel/generator/sfPropel13AdminGenerator.class.php',
+'sfPropel13AdminColumn' => '/home/www/plugins/sfPropel13Plugin/lib/propel/generator/sfPropel13AdminGenerator.class.php',
+'sfPropel13CrudGenerator' => '/home/www/plugins/sfPropel13Plugin/lib/propel/generator/sfPropel13CrudGenerator.class.php',
+'sfPropel13Data' => '/home/www/plugins/sfPropel13Plugin/lib/propel/sfPropel13Data.class.php',
+'SfObjectBuilder' => '/home/www/plugins/sfPropel13Plugin/lib/propel/builder/SfObjectBuilder.php',
+'SfPeerBuilder' => '/home/www/plugins/sfPropel13Plugin/lib/propel/builder/SfPeerBuilder.php',
+'BaseObject' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/propel/om/BaseObject.php',
+'NestedSetRecursiveIterator' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/propel/om/NestedSetRecursiveIterator.php',
+'Persistent' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/propel/om/Persistent.php',
+'PreOrderNodeIterator' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/propel/om/PreOrderNodeIterator.php',
+'NodeObject' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/propel/om/NodeObject.php',
+'PropelException' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/propel/PropelException.php',
+'BasicLogger' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/propel/logger/BasicLogger.php',
+'MojaviLogAdapter' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/propel/logger/MojaviLogAdapter.php',
+'Propel' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/propel/Propel.php',
+'UniqueValidator' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/propel/validator/UniqueValidator.php',
+'MinValueValidator' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/propel/validator/MinValueValidator.php',
+'MatchValidator' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/propel/validator/MatchValidator.php',
+'NotMatchValidator' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/propel/validator/NotMatchValidator.php',
+'MaxValueValidator' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/propel/validator/MaxValueValidator.php',
+'ValidationFailed' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/propel/validator/ValidationFailed.php',
+'RequiredValidator' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/propel/validator/RequiredValidator.php',
+'TypeValidator' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/propel/validator/TypeValidator.php',
+'ValidValuesValidator' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/propel/validator/ValidValuesValidator.php',
+'BasicValidator' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/propel/validator/BasicValidator.php',
+'MaxLengthValidator' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/propel/validator/MaxLengthValidator.php',
+'MinLengthValidator' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/propel/validator/MinLengthValidator.php',
+'DebugPDO' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/propel/util/DebugPDO.php',
+'PropelPager' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/propel/util/PropelPager.php',
+'BasePeer' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/propel/util/BasePeer.php',
+'PropelColumnTypes' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/propel/util/PropelColumnTypes.php',
+'PropelDateTime' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/propel/util/PropelDateTime.php',
+'NodePeer' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/propel/util/NodePeer.php',
+'DebugPDOStatement' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/propel/util/DebugPDOStatement.php',
+'PropelPDO' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/propel/util/PropelPDO.php',
+'Criteria' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/propel/util/Criteria.php',
+'CriterionIterator' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/propel/util/Criteria.php',
+'Criterion' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/propel/util/Criteria.php',
+'Join' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/propel/util/Criteria.php',
+'MapBuilder' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/propel/map/MapBuilder.php',
+'TableMap' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/propel/map/TableMap.php',
+'DatabaseMap' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/propel/map/DatabaseMap.php',
+'ValidatorMap' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/propel/map/ValidatorMap.php',
+'ColumnMap' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/propel/map/ColumnMap.php',
+'DBMSSQL' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/propel/adapter/DBMSSQL.php',
+'DBPostgres' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/propel/adapter/DBPostgres.php',
+'DBMySQL' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/propel/adapter/DBMySQL.php',
+'DBSQLite' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/propel/adapter/DBSQLite.php',
+'DBNone' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/propel/adapter/DBNone.php',
+'DBAdapter' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/propel/adapter/DBAdapter.php',
+'DBOracle' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/propel/adapter/DBOracle.php',
+'HelloWorldTest' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/docs/example/src/HelloWorldTest.php',
+'HelloWorld' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/docs/example/src/HelloWorld.php',
+'TypedefTestType' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/test/classes/example/types/TypedefTestType.php',
+'TaskdefTestSimpleTask' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/test/classes/example/tasks/TaskdefTestSimpleTask.php',
+'TestEcho' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/test/classes/example/tasks/TaskdefTestSimpleTask.php',
+'BuildFileTest' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/test/classes/phing/BuildFileTest.php',
+'PhingTestListener' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/test/classes/phing/BuildFileTest.php',
+'LineContainsTest' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/test/classes/phing/filters/LineContainsTest.php',
+'MapperTest' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/test/classes/phing/types/MapperTest.php',
+'TaskdefForCopyTest' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/test/classes/phing/types/MapperTest.php',
+'AbstractFileSetTest' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/test/classes/phing/types/AbstractFileSetTest.php',
+'FileSetTest' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/test/classes/phing/types/FileSetTest.php',
+'CommandlineTest' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/test/classes/phing/types/CommandlineTest.php',
+'FileOutputStreamTest' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/test/classes/phing/system/FileOutputStreamTest.php',
+'PropertyTaskTest' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/test/classes/phing/tasks/PropertyTaskTest.php',
+'ContainsConditionTest' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/test/classes/phing/tasks/condition/ContainsConditionTest.php',
+'EqualsConditionTest' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/test/classes/phing/tasks/condition/EqualsConditionTest.php',
+'TypedefTaskTest' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/test/classes/phing/tasks/TypedefTaskTest.php',
+'IntrospectionHelperTest' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/test/classes/phing/IntrospectionHelperTest.php',
+'expect' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/test/classes/phing/IntrospectionHelperTest.php',
+'expect' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/test/classes/phing/IntrospectionHelperTest.php',
+'IHProjectComponent' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/test/classes/phing/IntrospectionHelperTest.php',
+'IHCreatorFail1' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/test/classes/phing/IntrospectionHelperTest.php',
+'IHCreatorFail2' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/test/classes/phing/IntrospectionHelperTest.php',
+'IHCreatorFail3' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/test/classes/phing/IntrospectionHelperTest.php',
+'IHFail4' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/test/classes/phing/IntrospectionHelperTest.php',
+'IHFail5' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/test/classes/phing/IntrospectionHelperTest.php',
+'BuildPhingPEARPackageTask' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/pear/BuildPhingPEARPackageTask.php',
+'Task' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/Task.php',
+'Project' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/Project.php',
+'BuildLogger' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/BuildLogger.php',
+'XmlLogger' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/listener/XmlLogger.php',
+'AnsiColorLogger' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/listener/AnsiColorLogger.php',
+'StreamRequiredBuildLogger' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/listener/StreamRequiredBuildLogger.php',
+'DefaultLogger' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/listener/DefaultLogger.php',
+'NoBannerLogger' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/listener/NoBannerLogger.php',
+'PearLogListener' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/listener/PearLogListener.php',
+'BuildListener' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/BuildListener.php',
+'ProjectComponent' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/ProjectComponent.php',
+'UnknownElement' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/UnknownElement.php',
+'LineContainsRegexp' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/filters/LineContainsRegexp.php',
+'StripWhitespace' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/filters/StripWhitespace.php',
+'TabToSpaces' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/filters/TabToSpaces.php',
+'PrefixLines' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/filters/PrefixLines.php',
+'ReplaceRegexp' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/filters/ReplaceRegexp.php',
+'TidyFilter' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/filters/TidyFilter.php',
+'StripLineComments' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/filters/StripLineComments.php',
+'Comment' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/filters/StripLineComments.php',
+'BaseFilterReader' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/filters/BaseFilterReader.php',
+'StripLineBreaks' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/filters/StripLineBreaks.php',
+'IniFileTokenReader' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/filters/util/IniFileTokenReader.php',
+'ChainReaderHelper' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/filters/util/ChainReaderHelper.php',
+'XsltFilter' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/filters/XsltFilter.php',
+'XSLTParam' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/filters/XsltFilter.php',
+'ChainableReader' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/filters/ChainableReader.php',
+'ReplaceTokens' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/filters/ReplaceTokens.php',
+'Token' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/filters/ReplaceTokens.php',
+'HeadFilter' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/filters/HeadFilter.php',
+'StripPhpComments' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/filters/StripPhpComments.php',
+'XincludeFilter' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/filters/XincludeFilter.php',
+'TranslateGettext' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/filters/TranslateGettext.php',
+'TailFilter' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/filters/TailFilter.php',
+'LineContains' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/filters/LineContains.php',
+'Contains' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/filters/LineContains.php',
+'ExpandProperties' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/filters/ExpandProperties.php',
+'BaseParamFilterReader' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/filters/BaseParamFilterReader.php',
+'Capsule' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/lib/Capsule.php',
+'Archive_Zip' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/lib/Zip.php',
+'ProjectHandler' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/parser/ProjectHandler.php',
+'TargetHandler' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/parser/TargetHandler.php',
+'ExpatParser' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/parser/ExpatParser.php',
+'ExpatParseException' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/parser/ExpatParseException.php',
+'NestedElementHandler' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/parser/NestedElementHandler.php',
+'DataTypeHandler' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/parser/DataTypeHandler.php',
+'RootHandler' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/parser/RootHandler.php',
+'ProjectConfigurator' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/parser/ProjectConfigurator.php',
+'Location' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/parser/Location.php',
+'AbstractSAXParser' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/parser/AbstractSAXParser.php',
+'TaskHandler' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/parser/TaskHandler.php',
+'AbstractHandler' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/parser/AbstractHandler.php',
+'RuntimeConfigurable' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/RuntimeConfigurable.php',
+'Parameter' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/types/Parameter.php',
+'DataType' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/types/DataType.php',
+'Description' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/types/Description.php',
+'DirSet' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/types/DirSet.php',
+'Parameterizable' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/types/Parameterizable.php',
+'FileList' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/types/FileList.php',
+'Mapper' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/types/Mapper.php',
+'TokenSource' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/types/TokenSource.php',
+'TokenReader' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/types/TokenReader.php',
+'FileSet' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/types/FileSet.php',
+'RegularExpression' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/types/RegularExpression.php',
+'PhingFilterReader' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/types/PhingFilterReader.php',
+'PatternSet' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/types/PatternSet.php',
+'PatternSetNameEntry' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/types/PatternSet.php',
+'Path' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/types/Path.php',
+'PathElement' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/types/Path.php',
+'SelectorUtils' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/types/selectors/SelectorUtils.php',
+'BaseExtendSelector' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/types/selectors/BaseExtendSelector.php',
+'TypeSelector' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/types/selectors/TypeSelector.php',
+'BaseSelectorContainer' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/types/selectors/BaseSelectorContainer.php',
+'SelectorContainer' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/types/selectors/SelectorContainer.php',
+'FilenameSelector' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/types/selectors/FilenameSelector.php',
+'PresentSelector' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/types/selectors/PresentSelector.php',
+'ContainsSelector' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/types/selectors/ContainsSelector.php',
+'DepthSelector' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/types/selectors/DepthSelector.php',
+'SizeSelector' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/types/selectors/SizeSelector.php',
+'SelectorScanner' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/types/selectors/SelectorScanner.php',
+'BaseSelector' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/types/selectors/BaseSelector.php',
+'ExtendSelector' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/types/selectors/ExtendSelector.php',
+'NotSelector' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/types/selectors/NotSelector.php',
+'DateSelector' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/types/selectors/DateSelector.php',
+'ContainsRegexpSelector' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/types/selectors/ContainsRegexpSelector.php',
+'MajoritySelector' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/types/selectors/MajoritySelector.php',
+'ExtendFileSelector' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/types/selectors/ExtendFileSelector.php',
+'SelectSelector' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/types/selectors/SelectSelector.php',
+'AndSelector' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/types/selectors/AndSelector.php',
+'FileSelector' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/types/selectors/FileSelector.php',
+'DependSelector' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/types/selectors/DependSelector.php',
+'OrSelector' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/types/selectors/OrSelector.php',
+'NoneSelector' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/types/selectors/NoneSelector.php',
+'Commandline' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/types/Commandline.php',
+'CommandlineArgument' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/types/Commandline.php',
+'CommandlineMarker' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/types/Commandline.php',
+'AbstractFileSet' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/types/AbstractFileSet.php',
+'FilterChain' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/types/FilterChain.php',
+'Reference' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/types/Reference.php',
+'TaskContainer' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/TaskContainer.php',
+'FileSystem' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/system/io/FileSystem.php',
+'FilterReader' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/system/io/FilterReader.php',
+'FileInputStream' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/system/io/FileInputStream.php',
+'Reader' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/system/io/Reader.php',
+'OutputStreamWriter' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/system/io/OutputStreamWriter.php',
+'PhingFile' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/system/io/PhingFile.php',
+'WinNTFileSystem' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/system/io/WinNTFileSystem.php',
+'StringReader' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/system/io/StringReader.php',
+'InputStreamReader' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/system/io/InputStreamReader.php',
+'BufferedWriter' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/system/io/BufferedWriter.php',
+'UnixFileSystem' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/system/io/UnixFileSystem.php',
+'Writer' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/system/io/Writer.php',
+'IOException' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/system/io/IOException.php',
+'ConsoleReader' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/system/io/ConsoleReader.php',
+'InputStream' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/system/io/InputStream.php',
+'BufferedReader' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/system/io/BufferedReader.php',
+'FileWriter' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/system/io/FileWriter.php',
+'OutputStream' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/system/io/OutputStream.php',
+'FileOutputStream' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/system/io/FileOutputStream.php',
+'FileReader' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/system/io/FileReader.php',
+'Win32FileSystem' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/system/io/Win32FileSystem.php',
+'Register' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/system/util/Register.php',
+'RegisterSlot' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/system/util/Register.php',
+'Timer' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/system/util/Timer.php',
+'Properties' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/system/util/Properties.php',
+'NullPointerException' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/system/lang/NullPointerException.php',
+'Character' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/system/lang/Character.php',
+'SecurityException' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/system/lang/SecurityException.php',
+'FileNotFoundException' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/system/lang/FileNotFoundException.php',
+'EventObject' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/system/lang/EventObject.php',
+'BuildEvent' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/BuildEvent.php',
+'IdentityMapper' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/mappers/IdentityMapper.php',
+'MergeMapper' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/mappers/MergeMapper.php',
+'FlattenMapper' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/mappers/FlattenMapper.php',
+'FileNameMapper' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/mappers/FileNameMapper.php',
+'RegexpMapper' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/mappers/RegexpMapper.php',
+'GlobMapper' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/mappers/GlobMapper.php',
+'SourceFileScanner' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/util/SourceFileScanner.php',
+'ExtendedFileStream' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/util/ExtendedFileStream.php',
+'Regexp' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/util/regexp/Regexp.php',
+'RegexpEngine' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/util/regexp/RegexpEngine.php',
+'PregEngine' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/util/regexp/PregEngine.php',
+'DirectoryScanner' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/util/DirectoryScanner.php',
+'FileUtils' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/util/FileUtils.php',
+'LogWriter' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/util/LogWriter.php',
+'PathTokenizer' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/util/PathTokenizer.php',
+'StringHelper' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/util/StringHelper.php',
+'Target' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/Target.php',
+'IntrospectionHelper' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/IntrospectionHelper.php',
+'TaskAdapter' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/TaskAdapter.php',
+'BuildException' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/BuildException.php',
+'DefaultInputHandler' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/input/DefaultInputHandler.php',
+'InputRequest' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/input/InputRequest.php',
+'MultipleChoiceInputRequest' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/input/MultipleChoiceInputRequest.php',
+'InputHandler' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/input/InputHandler.php',
+'YesNoInputRequest' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/input/YesNoInputRequest.php',
+'PDOSQLExecTask' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/pdo/PDOSQLExecTask.php',
+'PDOSQLExecTransaction' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/pdo/PDOSQLExecTask.php',
+'XMLPDOResultFormatter' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/pdo/XMLPDOResultFormatter.php',
+'PlainPDOResultFormatter' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/pdo/PlainPDOResultFormatter.php',
+'PDOResultFormatter' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/pdo/PDOResultFormatter.php',
+'PDOTask' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/pdo/PDOTask.php',
+'PDOSQLExecFormatterElement' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/pdo/PDOSQLExecFormatterElement.php',
+'UntarTask' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/UntarTask.php',
+'ZipTask' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/ZipTask.php',
+'ZipFileSet' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/ZipTask.php',
+'PearPackage2Task' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/PearPackage2Task.php',
+'SmartyTask' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/SmartyTask.php',
+'MailTask' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/MailTask.php',
+'CapsuleTask' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/CapsuleTask.php',
+'AssignedVar' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/CapsuleTask.php',
+'ScpSendTask' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/ScpSendTask.php',
+'PHPUnitTask' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/phpunit/PHPUnitTask.php',
+'PHPUnitReportTask' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/phpunit/PHPUnitReportTask.php',
+'PHPUnitTestRunner' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/phpunit/PHPUnitTestRunner.php',
+'PHPUnitUtil' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/phpunit/PHPUnitUtil.php',
+'FormatterElement' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/phpunit/FormatterElement.php',
+'SummaryPHPUnit3ResultFormatter' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/phpunit/phpunit3/SummaryPHPUnit3ResultFormatter.php',
+'PHPUnit3ResultFormatter' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/phpunit/phpunit3/PHPUnit3ResultFormatter.php',
+'PlainPHPUnit3ResultFormatter' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/phpunit/phpunit3/PlainPHPUnit3ResultFormatter.php',
+'XMLPHPUnit3ResultFormatter' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/phpunit/phpunit3/XMLPHPUnit3ResultFormatter.php',
+'PHPUnit2ResultFormatter' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/phpunit/phpunit2/PHPUnit2ResultFormatter.php',
+'PlainPHPUnit2ResultFormatter' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/phpunit/phpunit2/PlainPHPUnit2ResultFormatter.php',
+'XMLPHPUnit2ResultFormatter' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/phpunit/phpunit2/XMLPHPUnit2ResultFormatter.php',
+'SummaryPHPUnit2ResultFormatter' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/phpunit/phpunit2/SummaryPHPUnit2ResultFormatter.php',
+'BatchTest' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/phpunit/BatchTest.php',
+'PhpCodeSnifferTask' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/PhpCodeSnifferTask.php',
+'ZendCodeAnalyzerTask' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/ZendCodeAnalyzerTask.php',
+'UnzipTask' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/UnzipTask.php',
+'JslLintTask' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/JslLintTask.php',
+'DbDeployTask' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/dbdeploy/DbDeployTask.php',
+'DbmsSyntaxSQLite' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/dbdeploy/DbmsSyntaxSQLite.php',
+'DbmsSyntaxMysql' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/dbdeploy/DbmsSyntaxMysql.php',
+'DbmsSyntaxFactory' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/dbdeploy/DbmsSyntaxFactory.php',
+'DbmsSyntax' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/dbdeploy/DbmsSyntax.php',
+'DbmsSyntaxMsSql' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/dbdeploy/DbmsSyntaxMsSql.php',
+'FtpDeployTask' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/FtpDeployTask.php',
+'CoverageMergerTask' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/coverage/CoverageMergerTask.php',
+'CoverageReportTransformer' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/coverage/CoverageReportTransformer.php',
+'CoverageMerger' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/coverage/CoverageMerger.php',
+'CoverageSetupTask' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/coverage/CoverageSetupTask.php',
+'CoverageReportTask' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/coverage/CoverageReportTask.php',
+'IoncubeComment' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/ioncube/IoncubeComment.php',
+'IoncubeLicenseTask' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/ioncube/IoncubeLicenseTask.php',
+'IoncubeEncoderTask' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/ioncube/IoncubeEncoderTask.php',
+'XmlLintTask' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/XmlLintTask.php',
+'SimpleTestTask' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/simpletest/SimpleTestTask.php',
+'SimpleTestFormatterElement' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/simpletest/SimpleTestFormatterElement.php',
+'SimpleTestPlainResultFormatter' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/simpletest/SimpleTestPlainResultFormatter.php',
+'SimpleTestResultFormatter' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/simpletest/SimpleTestResultFormatter.php',
+'SimpleTestCountResultFormatter' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/simpletest/SimpleTestCountResultFormatter.php',
+'SimpleTestSummaryResultFormatter' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/simpletest/SimpleTestSummaryResultFormatter.php',
+'PearPackageTask' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/PearPackageTask.php',
+'PearPkgOption' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/PearPackageTask.php',
+'PearPkgMapping' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/PearPackageTask.php',
+'PearPkgMappingElement' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/PearPackageTask.php',
+'PackageAsPathTask' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/PackageAsPathTask.php',
+'ExtractBaseTask' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/ExtractBaseTask.php',
+'PhpDocumentorTask' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/phpdoc/PhpDocumentorTask.php',
+'PhingPhpDocumentorSetup' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/phpdoc/PhingPhpDocumentorSetup.php',
+'PhpDocumentorExternalTask' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/phpdoc/PhpDocumentorExternalTask.php',
+'ManifestTask' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/ManifestTask.php',
+'SvnExportTask' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/svn/SvnExportTask.php',
+'SvnCheckoutTask' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/svn/SvnCheckoutTask.php',
+'SvnLastRevisionTask' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/svn/SvnLastRevisionTask.php',
+'SvnBaseTask' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/svn/SvnBaseTask.php',
+'SvnUpdateTask' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/svn/SvnUpdateTask.php',
+'PEAR_PackageFileManager_Fileset' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/pearpackage/Fileset.php',
+'CreoleSQLExecTask' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/creole/CreoleSQLExecTask.php',
+'SQLExecTransaction' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/creole/CreoleSQLExecTask.php',
+'CreoleTask' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/creole/CreoleTask.php',
+'PhpLintTask' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/PhpLintTask.php',
+'TarTask' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/TarTask.php',
+'TarFileSet' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/TarTask.php',
+'IncludePathTask' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/system/IncludePathTask.php',
+'XsltTask' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/system/XsltTask.php',
+'MoveTask' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/system/MoveTask.php',
+'AdhocTypedefTask' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/system/AdhocTypedefTask.php',
+'ForeachTask' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/system/ForeachTask.php',
+'AdhocTask' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/system/AdhocTask.php',
+'InputTask' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/system/InputTask.php',
+'CVSPassTask' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/system/CvsPassTask.php',
+'TypedefTask' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/system/TypedefTask.php',
+'MatchingTask' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/system/MatchingTask.php',
+'ConditionBase' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/system/condition/ConditionBase.php',
+'ConditionEnumeration' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/system/condition/ConditionBase.php',
+'OsCondition' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/system/condition/OsCondition.php',
+'IsFalseCondition' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/system/condition/IsFalseCondition.php',
+'ContainsCondition' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/system/condition/ContainsCondition.php',
+'IsTrueCondition' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/system/condition/IsTrueCondition.php',
+'NotCondition' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/system/condition/NotCondition.php',
+'EqualsCondition' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/system/condition/EqualsCondition.php',
+'ReferenceExistsCondition' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/system/condition/ReferenceExistsCondition.php',
+'Condition' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/system/condition/Condition.php',
+'AndCondition' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/system/condition/AndCondition.php',
+'OrCondition' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/system/condition/OrCondition.php',
+'IsSetCondition' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/system/condition/IsSetCondition.php',
+'DeleteTask' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/system/DeleteTask.php',
+'ChmodTask' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/system/ChmodTask.php',
+'TaskdefTask' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/system/TaskdefTask.php',
+'AppendTask' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/system/AppendTask.php',
+'PropertyPromptTask' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/system/PropertyPromptTask.php',
+'ReflexiveTask' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/system/ReflexiveTask.php',
+'MkdirTask' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/system/MkdirTask.php',
+'WarnTask' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/system/WarnTask.php',
+'ExecTask' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/system/ExecTask.php',
+'TstampTask' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/system/TstampTask.php',
+'TstampCustomFormat' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/system/TstampTask.php',
+'ExitTask' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/system/ExitTask.php',
+'PhingTask' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/system/PhingTask.php',
+'PhingReference' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/system/PhingTask.php',
+'PropertyTask' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/system/PropertyTask.php',
+'ConditionTask' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/system/ConditionTask.php',
+'PhingCallTask' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/system/PhingCallTask.php',
+'EchoTask' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/system/EchoTask.php',
+'TouchTask' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/system/TouchTask.php',
+'ResolvePathTask' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/system/ResolvePathTask.php',
+'CvsTask' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/system/CvsTask.php',
+'SequentialTask' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/system/SequentialTask.php',
+'IfTask' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/system/IfTask.php',
+'ElseIfTask' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/system/IfTask.php',
+'AdhocTaskdefTask' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/system/AdhocTaskdefTask.php',
+'CopyTask' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/system/CopyTask.php',
+'UpToDateTask' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/system/UpToDateTask.php',
+'ChownTask' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/system/ChownTask.php',
+'PhpEvalTask' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/system/PhpEvalTask.php',
+'FunctionParam' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/system/PhpEvalTask.php',
+'AvailableTask' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/system/AvailableTask.php',
+'Phing' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/Phing.php',
+'ConfigurationException' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/ConfigurationException.php',
+'GeneratedPeerTest' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/propel-generator/test/classes/propel/GeneratedPeerTest.php',
+'GeneratedNestedSetTest' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/propel-generator/test/classes/propel/GeneratedNestedSetTest.php',
+'Ticket520Test' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/propel-generator/test/classes/propel/Ticket520Test.php',
+'FieldnameRelatedTest' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/propel-generator/test/classes/propel/FieldnameRelatedTest.php',
+'GeneratedNestedSetObjectTest' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/propel-generator/test/classes/propel/GeneratedNestedSetObjectTest.php',
+'ValidatorTest' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/propel-generator/test/classes/propel/validator/ValidatorTest.php',
+'GeneratedObjectTest' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/propel-generator/test/classes/propel/GeneratedObjectTest.php',
+'PropelDateTimeTest' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/propel-generator/test/classes/propel/util/PropelDateTimeTest.php',
+'CriteriaTest' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/propel-generator/test/classes/propel/util/CriteriaTest.php',
+'PropelPDOTest' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/propel-generator/test/classes/propel/util/PropelPDOTest.php',
+'BasePeerTest' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/propel-generator/test/classes/propel/util/BasePeerTest.php',
+'CharacterEncodingTest' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/propel-generator/test/classes/propel/CharacterEncodingTest.php',
+'TableTest' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/propel-generator/test/classes/propel/engine/database/model/TableTest.php',
+'NameFactoryTest' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/propel-generator/test/classes/propel/engine/database/model/NameFactoryTest.php',
+'ColumnTest' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/propel-generator/test/classes/propel/engine/database/model/ColumnTest.php',
+'PlatformTestBase' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/propel-generator/test/classes/propel/engine/platform/PlatformTestBase.php',
+'SqlitePlatformTest' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/propel-generator/test/classes/propel/engine/platform/SqlitePlatformTest.php',
+'DefaultPlatformTest' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/propel-generator/test/classes/propel/engine/platform/DefaultPlatformTest.php',
+'GeneratedObjectRelTest' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/propel-generator/test/classes/propel/GeneratedObjectRelTest.php',
+'GeneratedNestedSetPeerTest' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/propel-generator/test/classes/propel/GeneratedNestedSetPeerTest.php',
+'GeneratedObjectLobTest' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/propel-generator/test/classes/propel/GeneratedObjectLobTest.php',
+'BaseTestCase' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/propel-generator/test/classes/propel/BaseTestCase.php',
+'CmsTestBase' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/propel-generator/test/classes/cms/CmsTestBase.php',
+'CmsDataPopulator' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/propel-generator/test/classes/cms/CmsDataPopulator.php',
+'ISBNValidator' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/propel-generator/test/classes/bookstore/validator/ISBNValidator.php',
+'BookstoreDataPopulator' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/propel-generator/test/classes/bookstore/BookstoreDataPopulator.php',
+'BookstoreTestBase' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/propel-generator/test/classes/bookstore/BookstoreTestBase.php',
+'DefineTask' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/propel-generator/test/tools/phing/DefineTask.php',
+'BuildPropelGenPEARPackageTask' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/propel-generator/pear/BuildPropelGenPEARPackageTask.php',
+'PropelConvertConfTask' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/phing/PropelConvertConfTask.php',
+'AbstractPropelDataModelTask' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/phing/AbstractPropelDataModelTask.php',
+'PropelDataDTDTask' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/phing/PropelDataDTDTask.php',
+'PropelOMTask' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/phing/PropelOMTask.php',
+'PropelDataModelTemplateTask' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/phing/PropelDataModelTemplateTask.php',
+'PropelSchemaReverseTask' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/phing/PropelSchemaReverseTask.php',
+'PropelSchemaReverse_ValidatorSet' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/phing/PropelSchemaReverseTask.php',
+'PropelSQLExec' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/phing/PropelSQLExec.php',
+'PropelSQLExecTransaction' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/phing/PropelSQLExec.php',
+'PropelSQLTask' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/phing/PropelSQLTask.php',
+'PropelDataSQLTask' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/phing/PropelDataSQLTask.php',
+'PropelDataDumpTask' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/phing/PropelDataDumpTask.php',
+'PropelGraphvizTask' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/phing/PropelGraphvizTask.php',
+'PropelCreoleTransformTask' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/phing/PropelCreoleTransformTask.php',
+'NameGenerator' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/database/model/NameGenerator.php',
+'Validator' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/database/model/Validator.php',
+'IdMethodParameter' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/database/model/IdMethodParameter.php',
+'VendorInfo' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/database/model/VendorInfo.php',
+'Database' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/database/model/Database.php',
+'XMLElement' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/database/model/XMLElement.php',
+'ColumnDefaultValue' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/database/model/ColumnDefaultValue.php',
+'Rule' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/database/model/Rule.php',
+'Domain' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/database/model/Domain.php',
+'NameFactory' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/database/model/NameFactory.php',
+'ForeignKey' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/database/model/ForeignKey.php',
+'PropelTypes' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/database/model/PropelTypes.php',
+'Table' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/database/model/Table.php',
+'Unique' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/database/model/Unique.php',
+'Index' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/database/model/Index.php',
+'AppData' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/database/model/AppData.php',
+'Column' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/database/model/Column.php',
+'ConstraintNameGenerator' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/database/model/ConstraintNameGenerator.php',
+'Inheritance' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/database/model/Inheritance.php',
+'IDMethod' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/database/model/IDMethod.php',
+'PhpNameGenerator' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/database/model/PhpNameGenerator.php',
+'XmlToAppData' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/database/transform/XmlToAppData.php',
+'SqliteSchemaParser' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/database/reverse/sqlite/SqliteSchemaParser.php',
+'MysqlSchemaParser' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/database/reverse/mysql/MysqlSchemaParser.php',
+'BaseSchemaParser' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/database/reverse/BaseSchemaParser.php',
+'MssqlSchemaParser' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/database/reverse/mssql/MssqlSchemaParser.php',
+'PgsqlSchemaParser' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/database/reverse/pgsql/PgsqlSchemaParser.php',
+'SchemaParser' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/database/reverse/SchemaParser.php',
+'PgsqlPlatform' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/platform/PgsqlPlatform.php',
+'MysqlPlatform' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/platform/MysqlPlatform.php',
+'DefaultPlatform' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/platform/DefaultPlatform.php',
+'OraclePlatform' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/platform/OraclePlatform.php',
+'MssqlPlatform' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/platform/MssqlPlatform.php',
+'SqlitePlatform' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/platform/SqlitePlatform.php',
+'Platform' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/platform/Platform.php',
+'GeneratorConfig' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/GeneratorConfig.php',
+'OMBuilder' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/builder/om/OMBuilder.php',
+'PHP5PeerBuilder' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/builder/om/php5/PHP5PeerBuilder.php',
+'PHP5NodeBuilder' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/builder/om/php5/PHP5NodeBuilder.php',
+'PHP5NestedSetBuilder' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/builder/om/php5/PHP5NestedSetBuilder.php',
+'PHP5ExtensionNodePeerBuilder' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/builder/om/php5/PHP5ExtensionNodePeerBuilder.php',
+'PHP5ExtensionPeerBuilder' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/builder/om/php5/PHP5ExtensionPeerBuilder.php',
+'PHP5InterfaceBuilder' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/builder/om/php5/PHP5InterfaceBuilder.php',
+'PHP5ObjectBuilder' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/builder/om/php5/PHP5ObjectBuilder.php',
+'PHP5ExtensionNodeBuilder' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/builder/om/php5/PHP5ExtensionNodeBuilder.php',
+'PHP5ExtensionObjectBuilder' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/builder/om/php5/PHP5ExtensionObjectBuilder.php',
+'PHP5MapBuilderBuilder' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/builder/om/php5/PHP5MapBuilderBuilder.php',
+'PHP5NodePeerBuilder' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/builder/om/php5/PHP5NodePeerBuilder.php',
+'PHP5MultiExtendObjectBuilder' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/builder/om/php5/PHP5MultiExtendObjectBuilder.php',
+'PHP5NestedSetPeerBuilder' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/builder/om/php5/PHP5NestedSetPeerBuilder.php',
+'ObjectBuilder' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/builder/om/ObjectBuilder.php',
+'PeerBuilder' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/builder/om/PeerBuilder.php',
+'ClassTools' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/builder/om/ClassTools.php',
+'DDLBuilder' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/builder/sql/DDLBuilder.php',
+'SqliteDataSQLBuilder' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/builder/sql/sqlite/SqliteDataSQLBuilder.php',
+'SqliteDDLBuilder' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/builder/sql/sqlite/SqliteDDLBuilder.php',
+'MysqlDDLBuilder' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/builder/sql/mysql/MysqlDDLBuilder.php',
+'MysqlDataSQLBuilder' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/builder/sql/mysql/MysqlDataSQLBuilder.php',
+'MssqlDDLBuilder' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/builder/sql/mssql/MssqlDDLBuilder.php',
+'MssqlDataSQLBuilder' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/builder/sql/mssql/MssqlDataSQLBuilder.php',
+'OracleDDLBuilder' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/builder/sql/oracle/OracleDDLBuilder.php',
+'OracleDataSQLBuilder' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/builder/sql/oracle/OracleDataSQLBuilder.php',
+'DataSQLBuilder' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/builder/sql/DataSQLBuilder.php',
+'PgsqlDataSQLBuilder' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/builder/sql/pgsql/PgsqlDataSQLBuilder.php',
+'PgsqlDDLBuilder' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/builder/sql/pgsql/PgsqlDDLBuilder.php',
+'XmlToDataSQL' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/builder/util/transform/XmlToDataSQL.php',
+'DataRow' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/builder/util/transform/XmlToDataSQL.php',
+'ColumnValue' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/builder/util/transform/XmlToDataSQL.php',
+'Pluralizer' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/builder/util/Pluralizer.php',
+'DefaultEnglishPluralizer' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/builder/util/DefaultEnglishPluralizer.php',
+'DataModelBuilder' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/builder/DataModelBuilder.php',
+'EngineException' => '/home/www/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/EngineException.php',
+
+// plugins module lib
+
+// project
+'userMessage' => '/home/www/lib/common/userMessage.class.php',
+'sfIdnumberValidator' => '/home/www/lib/common/sfIdnumberValidator.class.php',
+'onlineUser' => '/home/www/lib/common/onlineUser.class.php',
+'sfMyUser' => '/home/www/lib/common/sfMyUser.class.php',
+'myFolder' => '/home/www/lib/common/myZip.class.php',
+'myListFile' => '/home/www/lib/common/myZip.class.php',
+'myZip' => '/home/www/lib/common/myZip.class.php',
+'sfEntryException' => '/home/www/lib/common/sfEntryException.class.php',
+'sfPhoneValidator' => '/home/www/lib/common/sfPhoneValidator.class.php',
+'sfDatabaseSessionStorage' => '/home/www/lib/common/sfDatabaseSessionStorage.class.php',
+'sfFullnameValidator' => '/home/www/lib/common/sfFullnameValidator.class.php',
+'userBase' => '/home/www/lib/common/userBase.class.php',
+'sfFilterValidator' => '/home/www/lib/common/sfFilterValidator.class.php',
+'myMail' => '/home/www/lib/common/myMail.class.php',
+'htmlFilter' => '/home/www/lib/common/htmlFilter.class.php',
+'html2text' => '/home/www/lib/common/html2text.php',
+'myUtility' => '/home/www/lib/common/myUtility.class.php',
+'userTeacher' => '/home/www/lib/common/userTeacher.class.php',
+
+// project model
+'BaseTbluserPeer' => '/home/www/lib/model/om/BaseTbluserPeer.php',
+'BaseTbluser' => '/home/www/lib/model/om/BaseTbluser.php',
+'BaseTblspacefilePeer' => '/home/www/lib/model/om/BaseTblspacefilePeer.php',
+'BaseTblspaceresourcePeer' => '/home/www/lib/model/om/BaseTblspaceresourcePeer.php',
+'BaseTblblogcheckinfoPeer' => '/home/www/lib/model/om/BaseTblblogcheckinfoPeer.php',
+'BaseTblspacecategoryPeer' => '/home/www/lib/model/om/BaseTblspacecategoryPeer.php',
+'BaseTblspacecategory' => '/home/www/lib/model/om/BaseTblspacecategory.php',
+'BaseTblspaceresource' => '/home/www/lib/model/om/BaseTblspaceresource.php',
+'BaseTblblogcheckinfo' => '/home/www/lib/model/om/BaseTblblogcheckinfo.php',
+'BaseTblspacefile' => '/home/www/lib/model/om/BaseTblspacefile.php',
+'TblspacecategoryPeer' => '/home/www/lib/model/TblspacecategoryPeer.php',
+'TblspacefilePeer' => '/home/www/lib/model/TblspacefilePeer.php',
+'Tblblogcheckinfo' => '/home/www/lib/model/Tblblogcheckinfo.php',
+'Tblspacecategory' => '/home/www/lib/model/Tblspacecategory.php',
+'TblspaceresourcePeer' => '/home/www/lib/model/TblspaceresourcePeer.php',
+'TblblogcheckinfoPeer' => '/home/www/lib/model/TblblogcheckinfoPeer.php',
+'TblspacefileMapBuilder' => '/home/www/lib/model/map/TblspacefileMapBuilder.php',
+'TbluserMapBuilder' => '/home/www/lib/model/map/TbluserMapBuilder.php',
+'TblblogcheckinfoMapBuilder' => '/home/www/lib/model/map/TblblogcheckinfoMapBuilder.php',
+'TblspacecategoryMapBuilder' => '/home/www/lib/model/map/TblspacecategoryMapBuilder.php',
+'TblspaceresourceMapBuilder' => '/home/www/lib/model/map/TblspaceresourceMapBuilder.php',
+'TbluserPeer' => '/home/www/lib/model/TbluserPeer.php',
+'Tblspaceresource' => '/home/www/lib/model/Tblspaceresource.php',
+'Tblspacefile' => '/home/www/lib/model/Tblspacefile.php',
+'Tbluser' => '/home/www/lib/model/Tbluser.php',
+
+// application
+'violetUtil' => '/home/www/apps/platform/lib/violetUtil.class.php',
+'myUser' => '/home/www/apps/platform/lib/myUser.class.php',
+
+// module
+);
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/cache/platform/prod/config/config_bootstrap_compile.yml.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/cache/platform/prod/config/config_bootstrap_compile.yml.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/cache/platform/prod/config/config_bootstrap_compile.yml.php	(revision 19)
@@ -0,0 +1,292 @@
+<?php
+// auto-generated by sfCompileConfigHandler
+// date: 2014/05/07 16:15:25
+
+
+$sf_symfony_lib_dir = sfConfig::get('sf_symfony_lib_dir');
+if (!sfConfig::get('sf_in_bootstrap'))
+{
+    require_once($sf_symfony_lib_dir.'/util/sfYaml.class.php');
+    require_once($sf_symfony_lib_dir.'/cache/sfCache.class.php');
+  require_once($sf_symfony_lib_dir.'/cache/sfFileCache.class.php');
+    require_once($sf_symfony_lib_dir.'/config/sfConfigCache.class.php');
+  require_once($sf_symfony_lib_dir.'/config/sfConfigHandler.class.php');
+  require_once($sf_symfony_lib_dir.'/config/sfYamlConfigHandler.class.php');
+  require_once($sf_symfony_lib_dir.'/config/sfAutoloadConfigHandler.class.php');
+  require_once($sf_symfony_lib_dir.'/config/sfRootConfigHandler.class.php');
+  require_once($sf_symfony_lib_dir.'/config/sfLoader.class.php');
+    require_once($sf_symfony_lib_dir.'/exception/sfException.class.php');
+  require_once($sf_symfony_lib_dir.'/exception/sfAutoloadException.class.php');
+  require_once($sf_symfony_lib_dir.'/exception/sfCacheException.class.php');
+  require_once($sf_symfony_lib_dir.'/exception/sfConfigurationException.class.php');
+  require_once($sf_symfony_lib_dir.'/exception/sfParseException.class.php');
+    require_once($sf_symfony_lib_dir.'/util/sfParameterHolder.class.php');
+}
+else
+{
+  require_once($sf_symfony_lib_dir.'/config/sfConfigCache.class.php');
+}
+sfCore::initAutoload();
+try
+{
+  $configCache = sfConfigCache::getInstance();
+    if (function_exists('date_default_timezone_get'))
+  {
+    if ($default_timezone = sfConfig::get('sf_default_timezone'))
+    {
+      date_default_timezone_set($default_timezone);
+    }
+    else if (sfConfig::get('sf_force_default_timezone', true))
+    {
+      date_default_timezone_set(@date_default_timezone_get());
+    }
+  }
+    $sf_app_config_dir_name = sfConfig::get('sf_app_config_dir_name');
+  $sf_debug = sfConfig::get('sf_debug');
+    if ($sf_debug)
+  {
+    require_once($sf_symfony_lib_dir.'/debug/sfTimerManager.class.php');
+    require_once($sf_symfony_lib_dir.'/debug/sfTimer.class.php');
+  }
+    // 'config/settings.yml' config file
+// auto-generated by sfDefineEnvironmentConfigHandler
+// date: 2014/05/07 16:15:25
+sfConfig::add(array(
+  'sf_default_module' => 'default',
+  'sf_default_action' => 'index',
+  'sf_error_404_module' => 'default',
+  'sf_error_404_action' => 'error404',
+  'sf_login_module' => 'default',
+  'sf_login_action' => 'login',
+  'sf_secure_module' => 'default',
+  'sf_secure_action' => 'secure',
+  'sf_module_disabled_module' => 'default',
+  'sf_module_disabled_action' => 'disabled',
+  'sf_unavailable_module' => 'default',
+  'sf_unavailable_action' => 'unavailable',
+  'sf_available' => true,
+  'sf_use_database' => true,
+  'sf_use_security' => true,
+  'sf_use_flash' => true,
+  'sf_i18n' => false,
+  'sf_check_symfony_version' => false,
+  'sf_use_process_cache' => true,
+  'sf_compressed' => false,
+  'sf_check_lock' => false,
+  'sf_escaping_strategy' => 'bc',
+  'sf_escaping_method' => 'ESC_ENTITIES',
+  'sf_suffix' => '.',
+  'sf_no_script_name' => false,
+  'sf_validation_error_prefix' => ' &darr;&nbsp;',
+  'sf_validation_error_suffix' => ' &nbsp;&darr;',
+  'sf_validation_error_class' => 'form_error',
+  'sf_validation_error_id_prefix' => 'error_for_',
+  'sf_cache' => false,
+  'sf_etag' => true,
+  'sf_lazy_cache_key' => true,
+  'sf_web_debug' => false,
+  'sf_error_reporting' => 341,
+  'sf_rich_text_js_dir' => 'js/tiny_mce',
+  'sf_prototype_web_dir' => '/sf/prototype',
+  'sf_admin_web_dir' => '/sf/sf_admin',
+  'sf_web_debug_web_dir' => '/sf/sf_web_debug',
+  'sf_calendar_web_dir' => '/sf/calendar',
+  'sf_standard_helpers' => array (
+  0 => 'Partial',
+  1 => 'Cache',
+  2 => 'Form',
+),
+  'sf_enabled_modules' => array (
+  0 => 'default',
+),
+  'sf_charset' => 'utf-8',
+  'sf_strip_comments' => true,
+  'sf_autoloading_functions' => NULL,
+  'sf_timeout' => 1800,
+  'sf_max_forwards' => 5,
+  'sf_path_info_array' => 'SERVER',
+  'sf_path_info_key' => 'PATH_INFO',
+  'sf_url_format' => 'PATH',
+  'sf_orm' => 'propel',
+));
+  if (sfConfig::get('sf_logging_enabled', true))
+  {
+    // 'config/logging.yml' config file
+// auto-generated by sfDefineEnvironmentConfigHandler
+// date: 2014/05/07 16:15:25
+sfConfig::add(array(
+  'sf_logging_enabled' => false,
+  'sf_logging_level' => 'err',
+  'sf_logging_rotate' => true,
+  'sf_logging_period' => 7,
+  'sf_logging_history' => 10,
+  'sf_logging_purge' => false,
+));
+  }
+  if ($file = $configCache->checkConfig($sf_app_config_dir_name.'/app.yml', true))
+  {
+    include($file);
+  }
+  if (sfConfig::get('sf_i18n'))
+  {
+    // 'config/i18n.yml' config file
+// auto-generated by sfDefineEnvironmentConfigHandler
+// date: 2014/05/07 16:15:25
+sfConfig::add(array(
+  'sf_i18n_default_culture' => 'en',
+  'sf_i18n_source' => 'XLIFF',
+  'sf_i18n_debug' => false,
+  'sf_i18n_cache' => true,
+  'sf_i18n_untranslated_prefix' => '[T]',
+  'sf_i18n_untranslated_suffix' => '[/T]',
+));
+  }
+    foreach ((array) sfConfig::get('sf_autoloading_functions', array()) as $callable)
+  {
+    sfCore::addAutoloadCallable($callable);
+  }
+    ini_set('display_errors', $sf_debug ? 'on' : 'off');
+  error_reporting(sfConfig::get('sf_error_reporting'));
+    if (!sfConfig::get('sf_in_bootstrap') && !$sf_debug && !sfConfig::get('sf_test'))
+  {
+    $configCache->checkConfig($sf_app_config_dir_name.'/bootstrap_compile.yml');
+  }
+      if (!$sf_debug && !sfConfig::get('sf_test'))
+  {
+    $core_classes = $sf_app_config_dir_name.'/core_compile.yml';
+    $configCache->import($core_classes, false);
+  }
+  // 'config/php.yml' config file
+// auto-generated by sfPhpConfigHandler
+// date: 2014/05/07 16:15:25
+ini_set('magic_quotes_runtime', '');
+ini_set('log_errors', '1');
+ini_set('arg_separator.output', '&amp;');
+if (ini_get('magic_quotes_gpc') != false)
+{
+  sfLogger::getInstance()->warning('{sfPhpConfigHandler} php.ini "magic_quotes_gpc" key is better set to "false" (current value is "\'\'" - php.ini location: "/etc/php.ini").');
+}
+if (ini_get('register_globals') != false)
+{
+  sfLogger::getInstance()->warning('{sfPhpConfigHandler} php.ini "register_globals" key is better set to "false" (current value is "\'\'" - php.ini location: "/etc/php.ini").');
+}
+if (ini_get('session.auto_start') != false)
+{
+  sfLogger::getInstance()->warning('{sfPhpConfigHandler} php.ini "session.auto_start" key is better set to "false" (current value is "\'0\'" - php.ini location: "/etc/php.ini").');
+}
+  // 'config/routing.yml' config file
+// auto-generated by sfRoutingConfigHandler
+// date: 2014/05/07 16:15:25
+$routes = sfRouting::getInstance();
+$routes->setRoutes(
+array (
+  'homepage' =>
+  array (
+    0 => '/',
+    1 => '/^[\\/]*$/',
+    2 =>
+    array (
+    ),
+    3 =>
+    array (
+    ),
+    4 =>
+    array (
+      'module' => 'default',
+      'action' => 'index',
+    ),
+    5 =>
+    array (
+    ),
+    6 => '',
+  ),
+  'default_symfony' =>
+  array (
+    0 => '/symfony/:action/*',
+    1 => '#^/symfony(?:\\/([^\\/]+))?(?:\\/(.*))?$#',
+    2 =>
+    array (
+      0 => 'action',
+    ),
+    3 =>
+    array (
+      'action' => 1,
+    ),
+    4 =>
+    array (
+      'module' => 'default',
+    ),
+    5 =>
+    array (
+    ),
+    6 => '',
+  ),
+  'default_index' =>
+  array (
+    0 => '/:module',
+    1 => '#^(?:\\/([^\\/]+))?$#',
+    2 =>
+    array (
+      0 => 'module',
+    ),
+    3 =>
+    array (
+      'module' => 1,
+    ),
+    4 =>
+    array (
+      'action' => 'index',
+    ),
+    5 =>
+    array (
+    ),
+    6 => '',
+  ),
+  'default' =>
+  array (
+    0 => '/:module/:action/*',
+    1 => '#^(?:\\/([^\\/]+))?(?:\\/([^\\/]+))?(?:\\/(.*))?$#',
+    2 =>
+    array (
+      0 => 'module',
+      1 => 'action',
+    ),
+    3 =>
+    array (
+      'module' => 1,
+      'action' => 1,
+    ),
+    4 =>
+    array (
+    ),
+    5 =>
+    array (
+    ),
+    6 => '',
+  ),
+)
+);
+    sfLoader::loadPluginConfig();
+    ob_start(sfConfig::get('sf_compressed') ? 'ob_gzhandler' : '');
+}
+catch (sfException $e)
+{
+  $e->printStackTrace();
+}
+catch (Exception $e)
+{
+  if (sfConfig::get('sf_test'))
+  {
+    throw $e;
+  }
+  try
+  {
+        $sfException = new sfException();
+    $sfException->printStackTrace($e);
+  }
+  catch (Exception $e)
+  {
+    header('HTTP/1.0 500 Internal Server Error');
+  }
+}
+
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/cache/platform/prod/config/config_config_handlers.yml.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/cache/platform/prod/config/config_config_handlers.yml.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/cache/platform/prod/config/config_config_handlers.yml.php	(revision 19)
@@ -0,0 +1,56 @@
+<?php
+// auto-generated by sfRootConfigHandler
+// date: 2014/05/07 16:15:25
+
+$this->handlers['config/autoload.yml'] = new sfAutoloadConfigHandler();
+$this->handlers['config/autoload.yml']->initialize();
+$this->handlers['config/php.yml'] = new sfPhpConfigHandler();
+$this->handlers['config/php.yml']->initialize();
+$this->handlers['config/databases.yml'] = new sfDatabaseConfigHandler();
+$this->handlers['config/databases.yml']->initialize();
+$this->handlers['config/settings.yml'] = new sfDefineEnvironmentConfigHandler();
+$this->handlers['config/settings.yml']->initialize(array (
+  'prefix' => 'sf_',
+));
+$this->handlers['config/app.yml'] = new sfDefineEnvironmentConfigHandler();
+$this->handlers['config/app.yml']->initialize(array (
+  'prefix' => 'app_',
+));
+$this->handlers['config/factories.yml'] = new sfFactoryConfigHandler();
+$this->handlers['config/factories.yml']->initialize();
+$this->handlers['config/bootstrap_compile.yml'] = new sfCompileConfigHandler();
+$this->handlers['config/bootstrap_compile.yml']->initialize();
+$this->handlers['config/core_compile.yml'] = new sfCompileConfigHandler();
+$this->handlers['config/core_compile.yml']->initialize();
+$this->handlers['config/filters.yml'] = new sfFilterConfigHandler();
+$this->handlers['config/filters.yml']->initialize();
+$this->handlers['config/logging.yml'] = new sfLoggingConfigHandler();
+$this->handlers['config/logging.yml']->initialize(array (
+  'prefix' => 'sf_logging_',
+));
+$this->handlers['config/routing.yml'] = new sfRoutingConfigHandler();
+$this->handlers['config/routing.yml']->initialize();
+$this->handlers['config/i18n.yml'] = new sfDefineEnvironmentConfigHandler();
+$this->handlers['config/i18n.yml']->initialize(array (
+  'prefix' => 'sf_i18n_',
+));
+$this->handlers['modules/*/config/generator.yml'] = new sfGeneratorConfigHandler();
+$this->handlers['modules/*/config/generator.yml']->initialize();
+$this->handlers['modules/*/config/view.yml'] = new sfViewConfigHandler();
+$this->handlers['modules/*/config/view.yml']->initialize();
+$this->handlers['modules/*/config/mailer.yml'] = new sfDefineEnvironmentConfigHandler();
+$this->handlers['modules/*/config/mailer.yml']->initialize(array (
+  'prefix' => 'sf_mailer_',
+  'module' => true,
+));
+$this->handlers['modules/*/config/security.yml'] = new sfSecurityConfigHandler();
+$this->handlers['modules/*/config/security.yml']->initialize();
+$this->handlers['modules/*/config/cache.yml'] = new sfCacheConfigHandler();
+$this->handlers['modules/*/config/cache.yml']->initialize();
+$this->handlers['modules/*/validate/*.yml'] = new sfValidatorConfigHandler();
+$this->handlers['modules/*/validate/*.yml']->initialize();
+$this->handlers['modules/*/config/module.yml'] = new sfDefineEnvironmentConfigHandler();
+$this->handlers['modules/*/config/module.yml']->initialize(array (
+  'prefix' => 'mod_',
+  'module' => true,
+));
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/cache/platform/prod/config/config_core_compile.yml.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/cache/platform/prod/config/config_core_compile.yml.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/cache/platform/prod/config/config_core_compile.yml.php	(revision 19)
@@ -0,0 +1,3663 @@
+<?php
+// auto-generated by sfCompileConfigHandler
+// date: 2014/05/07 16:15:25
+
+
+abstract class sfComponent
+{
+  protected
+    $context                = null,
+    $request                = null,
+    $response               = null,
+    $varHolder              = null,
+    $requestParameterHolder = null;
+  abstract function execute();
+  public function getModuleName()
+  {
+    return $this->getContext()->getModuleName();
+  }
+  public function getActionName()
+  {
+    return $this->getContext()->getActionName();
+  }
+  public function initialize($context)
+  {
+    $this->context                = $context;
+    $this->varHolder              = new sfParameterHolder();
+    $this->request                = $context->getRequest();
+    $this->response               = $context->getResponse();
+    $this->requestParameterHolder = $this->request->getParameterHolder();
+    return true;
+  }
+  public final function getContext()
+  {
+    return $this->context;
+  }
+  public final function getLogger()
+  {
+    return $this->context->getLogger();
+  }
+  public function logMessage($message, $priority = 'info')
+  {
+    if (sfConfig::get('sf_logging_enabled'))
+    {
+      $this->context->getLogger()->log($message, constant('SF_LOG_'.strtoupper($priority)));
+    }
+  }
+  public function debugMessage($message)
+  {
+    if (sfConfig::get('sf_web_debug'))
+    {
+      sfWebDebug::getInstance()->logShortMessage($message);
+    }
+  }
+  public function getRequestParameter($name, $default = null)
+  {
+    return $this->requestParameterHolder->get($name, $default);
+  }
+  public function hasRequestParameter($name)
+  {
+    return $this->requestParameterHolder->has($name);
+  }
+  public function getRequest()
+  {
+    return $this->request;
+  }
+  public function getResponse()
+  {
+    return $this->response;
+  }
+  public function getController()
+  {
+    return $this->getContext()->getController();
+  }
+  public function getUser()
+  {
+    return $this->getContext()->getUser();
+  }
+  public function setVar($name, $value)
+  {
+    $this->varHolder->set($name, $value);
+  }
+  public function getVar($name)
+  {
+    return $this->varHolder->get($name);
+  }
+  public function getVarHolder()
+  {
+    return $this->varHolder;
+  }
+  public function __set($key, $value)
+  {
+    return $this->varHolder->setByRef($key, $value);
+  }
+  public function & __get($key)
+  {
+    return $this->varHolder->get($key);
+  }
+  public function __isset($name)
+  {
+    return $this->varHolder->has($name);
+  }
+  public function __unset($name)
+  {
+    $this->varHolder->remove($name);
+  }
+  public function setFlash($name, $value, $persist = true)
+  {
+    $this->getUser()->setAttribute($name, $value, 'symfony/flash');
+    if ($persist)
+    {
+            $this->getUser()->getAttributeHolder()->remove($name, 'symfony/flash/remove');
+    }
+    else
+    {
+      $this->getUser()->setAttribute($name, true, 'symfony/flash/remove');
+    }
+  }
+  public function getFlash($name)
+  {
+    return $this->getUser()->getAttribute($name, null, 'symfony/flash');
+  }
+  public function hasFlash($name)
+  {
+    return $this->getUser()->hasAttribute($name, 'symfony/flash');
+  }
+  public function sendEmail($module, $action)
+  {
+    return $this->getController()->getPresentationFor($module, $action, 'sfMail');
+  }
+  public function getPresentationFor($module, $action, $viewName = null)
+  {
+    return $this->getController()->getPresentationFor($module, $action, $viewName);
+  }
+  public function __call($method, $arguments)
+  {
+    if (!$callable = sfMixer::getCallable('sfComponent:'.$method))
+    {
+      throw new sfException(sprintf('Call to undefined method sfComponent::%s', $method));
+    }
+    array_unshift($arguments, $this);
+    return call_user_func_array($callable, $arguments);
+  }
+}
+
+
+abstract class sfAction extends sfComponent
+{
+  protected
+    $security = array();
+  public function initialize($context)
+  {
+    parent::initialize($context);
+        if ($file = sfConfigCache::getInstance()->checkConfig(sfConfig::get('sf_app_module_dir_name').'/'.$this->getModuleName().'/'.sfConfig::get('sf_app_module_config_dir_name').'/security.yml', true))
+    {
+      require $file;
+    }
+    return true;
+  }
+  public function preExecute()
+  {
+  }
+  public function postExecute()
+  {
+  }
+  public function forward404($message = '')
+  {
+    throw new sfError404Exception($message);
+  }
+  public function forward404Unless($condition, $message = '')
+  {
+    if (!$condition)
+    {
+      throw new sfError404Exception($message);
+    }
+  }
+  public function forward404If($condition, $message = '')
+  {
+    if ($condition)
+    {
+      throw new sfError404Exception($message);
+    }
+  }
+  public function redirect404()
+  {
+    return $this->redirect('/'.sfConfig::get('sf_error_404_module').'/'.sfConfig::get('sf_error_404_action'));
+  }
+  public function forward($module, $action)
+  {
+    if (sfConfig::get('sf_logging_enabled'))
+    {
+      $this->getContext()->getLogger()->info('{sfAction} forward to action "'.$module.'/'.$action.'"');
+    }
+    $this->getController()->forward($module, $action);
+    throw new sfStopException();
+  }
+  public function forwardIf($condition, $module, $action)
+  {
+    if ($condition)
+    {
+      $this->forward($module, $action);
+    }
+  }
+  public function forwardUnless($condition, $module, $action)
+  {
+    if (!$condition)
+    {
+      $this->forward($module, $action);
+    }
+  }
+  public function redirect($url, $statusCode = 302)
+  {
+    $url = $this->getController()->genUrl($url, true);
+    if (sfConfig::get('sf_logging_enabled'))
+    {
+      $this->getContext()->getLogger()->info('{sfAction} redirect to "'.$url.'"');
+    }
+    $this->getController()->redirect($url, 0, $statusCode);
+    throw new sfStopException();
+  }
+  public function redirectIf($condition, $url)
+  {
+    if ($condition)
+    {
+      $this->redirect($url);
+    }
+  }
+  public function redirectUnless($condition, $url)
+  {
+    if (!$condition)
+    {
+      $this->redirect($url);
+    }
+  }
+  public function renderText($text)
+  {
+    $this->getResponse()->setContent($this->getResponse()->getContent().$text);
+    return sfView::NONE;
+  }
+  public function getDefaultView()
+  {
+    return sfView::INPUT;
+  }
+  public function getRequestMethods()
+  {
+    return sfRequest::GET
+           | sfRequest::POST
+           | sfRequest::PUT
+           | sfRequest::DELETE
+           | sfRequest::HEAD
+           | sfRequest::NONE;
+  }
+  public function handleError()
+  {
+    return sfView::ERROR;
+  }
+  public function validate()
+  {
+    return true;
+  }
+  public function getSecurityConfiguration()
+  {
+    return $this->security;
+  }
+  public function setSecurityConfiguration($security)
+  {
+    $this->security = $security;
+  }
+  public function isSecure()
+  {
+    $actionName = strtolower($this->getActionName());
+    if (isset($this->security[$actionName]['is_secure']))
+    {
+      return $this->security[$actionName]['is_secure'];
+    }
+    if (isset($this->security['all']['is_secure']))
+    {
+      return $this->security['all']['is_secure'];
+    }
+    return false;
+  }
+  public function getCredential()
+  {
+    $actionName = strtolower($this->getActionName());
+    if (isset($this->security[$actionName]['credentials']))
+    {
+      $credentials = $this->security[$actionName]['credentials'];
+    }
+    else if (isset($this->security['all']['credentials']))
+    {
+      $credentials = $this->security['all']['credentials'];
+    }
+    else
+    {
+      $credentials = null;
+    }
+    return $credentials;
+  }
+  public function setTemplate($name)
+  {
+    if (sfConfig::get('sf_logging_enabled'))
+    {
+      $this->getContext()->getLogger()->info('{sfAction} change template to "'.$name.'"');
+    }
+    $this->getResponse()->setParameter($this->getModuleName().'_'.$this->getActionName().'_template', $name, 'symfony/action/view');
+  }
+  public function getTemplate()
+  {
+    return $this->getResponse()->getParameter($this->getModuleName().'_'.$this->getActionName().'_template', null, 'symfony/action/view');
+  }
+  public function setLayout($name)
+  {
+    if (sfConfig::get('sf_logging_enabled'))
+    {
+      $this->getContext()->getLogger()->info('{sfAction} change layout to "'.$name.'"');
+    }
+    $this->getResponse()->setParameter($this->getModuleName().'_'.$this->getActionName().'_layout', $name, 'symfony/action/view');
+  }
+  public function getLayout()
+  {
+    return $this->getResponse()->getParameter($this->getModuleName().'_'.$this->getActionName().'_layout', null, 'symfony/action/view');
+  }
+  public function setViewClass($class)
+  {
+    sfConfig::set('mod_'.strtolower($this->getModuleName()).'_view_class', $class);
+  }
+}
+
+
+abstract class sfActions extends sfAction
+{
+  public function execute()
+  {
+        $actionToRun = 'execute'.ucfirst($this->getActionName());
+    if ($actionToRun === 'execute')
+    {
+            $error = 'sfAction initialization failed for module "%s". There was no action given.';
+      $error = sprintf($error, $this->getModuleName());
+      throw new sfInitializationException($error);
+    }
+    if (!is_callable(array($this, $actionToRun)))
+    {
+            $error = 'sfAction initialization failed for module "%s", action "%s". You must create a "%s" method.';
+      $error = sprintf($error, $this->getModuleName(), $this->getActionName(), $actionToRun);
+      throw new sfInitializationException($error);
+    }
+    if (sfConfig::get('sf_logging_enabled'))
+    {
+      $this->getContext()->getLogger()->info('{sfAction} call "'.get_class($this).'->'.$actionToRun.'()'.'"');
+    }
+        $ret = $this->$actionToRun();
+    return $ret;
+  }
+}
+
+
+class sfActionStack
+{
+  protected
+    $stack = array();
+  public function addEntry($moduleName, $actionName, $actionInstance)
+  {
+        $actionEntry = new sfActionStackEntry($moduleName, $actionName, $actionInstance);
+    $this->stack[] = $actionEntry;
+    return $actionEntry;
+  }
+  public function getEntry($index)
+  {
+    $retval = null;
+    if ($index > -1 && $index < count($this->stack))
+    {
+      $retval = $this->stack[$index];
+    }
+    return $retval;
+  }
+  public function popEntry()
+  {
+    return array_pop($this->stack);
+  }
+  public function getFirstEntry()
+  {
+    $retval = null;
+    if (isset($this->stack[0]))
+    {
+      $retval = $this->stack[0];
+    }
+    return $retval;
+  }
+  public function getLastEntry()
+  {
+    $count  = count($this->stack);
+    $retval = null;
+    if (isset($this->stack[0]))
+    {
+      $retval = $this->stack[$count - 1];
+    }
+    return $retval;
+  }
+  public function getSize()
+  {
+    return count($this->stack);
+  }
+}
+
+
+class sfActionStackEntry
+{
+  protected
+    $actionInstance = null,
+    $actionName     = null,
+    $moduleName     = null,
+    $presentation   = null,
+    $viewInstance   = null;
+  public function __construct($moduleName, $actionName, $actionInstance)
+  {
+    $this->actionName     = $actionName;
+    $this->actionInstance = $actionInstance;
+    $this->moduleName     = $moduleName;
+  }
+  public function getActionName()
+  {
+    return $this->actionName;
+  }
+  public function getActionInstance()
+  {
+    return $this->actionInstance;
+  }
+  public function getViewInstance()
+  {
+    return $this->viewInstance;
+  }
+  public function setViewInstance($viewInstance)
+  {
+    $this->viewInstance = $viewInstance;
+  }
+  public function getModuleName()
+  {
+    return $this->moduleName;
+  }
+  public function & getPresentation()
+  {
+    return $this->presentation;
+  }
+  public function setPresentation(&$presentation)
+  {
+    $this->presentation =& $presentation;
+  }
+}
+
+
+abstract class sfController
+{
+  protected
+    $context                  = null,
+    $controllerClasses        = array(),
+    $maxForwards              = 5,
+    $renderMode               = sfView::RENDER_CLIENT,
+    $viewCacheClassName       = null;
+  public function componentExists($moduleName, $componentName)
+  {
+    return $this->controllerExists($moduleName, $componentName, 'component', false);
+  }
+  public function actionExists($moduleName, $actionName)
+  {
+    return $this->controllerExists($moduleName, $actionName, 'action', false);
+  }
+  protected function controllerExists($moduleName, $controllerName, $extension, $throwExceptions)
+  {
+    $dirs = sfLoader::getControllerDirs($moduleName);
+    foreach ($dirs as $dir => $checkEnabled)
+    {
+            if ($checkEnabled && !in_array($moduleName, sfConfig::get('sf_enabled_modules')) && is_readable($dir))
+      {
+        $error = 'The module "%s" is not enabled.';
+        $error = sprintf($error, $moduleName);
+        throw new sfConfigurationException($error);
+      }
+            $classFile   = strtolower($extension);
+      $classSuffix = ucfirst(strtolower($extension));
+      $file        = $dir.'/'.$controllerName.$classSuffix.'.class.php';
+      if (is_readable($file))
+      {
+                require_once($file);
+        $this->controllerClasses[$moduleName.'_'.$controllerName.'_'.$classSuffix] = $controllerName.$classSuffix;
+        return true;
+      }
+      $module_file = $dir.'/'.$classFile.'s.class.php';
+      if (is_readable($module_file))
+      {
+                require_once($module_file);
+        if (!class_exists($moduleName.$classSuffix.'s', false))
+        {
+          if ($throwExceptions)
+          {
+            throw new sfControllerException(sprintf('There is no "%s" class in your action file "%s".', $moduleName.$classSuffix.'s', $module_file));
+          }
+          return false;
+        }
+                if (!in_array('execute'.ucfirst($controllerName), get_class_methods($moduleName.$classSuffix.'s')))
+        {
+          if ($throwExceptions)
+          {
+            throw new sfControllerException(sprintf('There is no "%s" method in your action class "%s"', 'execute'.ucfirst($controllerName), $moduleName.$classSuffix.'s'));
+          }
+          return false;
+        }
+        $this->controllerClasses[$moduleName.'_'.$controllerName.'_'.$classSuffix] = $moduleName.$classSuffix.'s';
+        return true;
+      }
+    }
+        if ($throwExceptions && sfConfig::get('sf_debug'))
+    {
+      $dirs = array_keys($dirs);
+            foreach ($dirs as &$dir)
+      {
+        $dir = str_replace(sfConfig::get('sf_root_dir'), '%SF_ROOT_DIR%', $dir);
+      }
+      throw new sfControllerException(sprintf('{sfController} controller "%s/%s" does not exist in: %s', $moduleName, $controllerName, implode(', ', $dirs)));
+    }
+    return false;
+  }
+  public function forward($moduleName, $actionName)
+  {
+        $moduleName = preg_replace('/[^a-z0-9\-_]+/i', '', $moduleName);
+    $actionName = preg_replace('/[^a-z0-9\-_]+/i', '', $actionName);
+    if ($this->getActionStack()->getSize() >= $this->maxForwards)
+    {
+            $error = 'Too many forwards have been detected for this request (> %d)';
+      $error = sprintf($error, $this->maxForwards);
+      throw new sfForwardException($error);
+    }
+    $rootDir = sfConfig::get('sf_root_dir');
+    $app     = sfConfig::get('sf_app');
+    $env     = sfConfig::get('sf_environment');
+    if (!sfConfig::get('sf_available') || sfToolkit::hasLockFile($rootDir.'/'.$app.'_'.$env.'.lck'))
+    {
+            $moduleName = sfConfig::get('sf_unavailable_module');
+      $actionName = sfConfig::get('sf_unavailable_action');
+      if (!$this->actionExists($moduleName, $actionName))
+      {
+                $error = 'Invalid configuration settings: [sf_unavailable_module] "%s", [sf_unavailable_action] "%s"';
+        $error = sprintf($error, $moduleName, $actionName);
+        throw new sfConfigurationException($error);
+      }
+    }
+        sfConfigCache::getInstance()->import(sfConfig::get('sf_app_module_dir_name').'/'.$moduleName.'/'.sfConfig::get('sf_app_module_config_dir_name').'/generator.yml', true, true);
+    if (!$this->actionExists($moduleName, $actionName))
+    {
+            if (sfConfig::get('sf_logging_enabled'))
+      {
+        $this->getContext()->getLogger()->info(sprintf('{sfController} action "%s/%s" does not exist', $moduleName, $actionName));
+      }
+            $this->context->getRequest()->setAttribute('requested_action', $actionName);
+      $this->context->getRequest()->setAttribute('requested_module', $moduleName);
+            $moduleName = sfConfig::get('sf_error_404_module');
+      $actionName = sfConfig::get('sf_error_404_action');
+      if (!$this->actionExists($moduleName, $actionName))
+      {
+                $error = 'Invalid configuration settings: [sf_error_404_module] "%s", [sf_error_404_action] "%s"';
+        $error = sprintf($error, $moduleName, $actionName);
+        throw new sfConfigurationException($error);
+      }
+    }
+        $actionInstance = $this->getAction($moduleName, $actionName);
+        $this->getActionStack()->addEntry($moduleName, $actionName, $actionInstance);
+        require(sfConfigCache::getInstance()->checkConfig(sfConfig::get('sf_app_module_dir_name').'/'.$moduleName.'/'.sfConfig::get('sf_app_module_config_dir_name').'/module.yml'));
+        if ($this->getActionStack()->getSize() == 1 && sfConfig::get('mod_'.strtolower($moduleName).'_is_internal') && !sfConfig::get('sf_test'))
+    {
+      $error = 'Action "%s" from module "%s" cannot be called directly';
+      $error = sprintf($error, $actionName, $moduleName);
+      throw new sfConfigurationException($error);
+    }
+    if (sfConfig::get('mod_'.strtolower($moduleName).'_enabled'))
+    {
+            $moduleConfig = sfConfig::get('sf_app_module_dir').'/'.$moduleName.'/'.sfConfig::get('sf_app_module_config_dir_name').'/config.php';
+      if (is_readable($moduleConfig))
+      {
+        require_once($moduleConfig);
+      }
+            if ($actionInstance->initialize($this->context))
+      {
+                $filterChain = new sfFilterChain();
+        $this->loadFilters($filterChain, $actionInstance);
+        if ($moduleName == sfConfig::get('sf_error_404_module') && $actionName == sfConfig::get('sf_error_404_action'))
+        {
+          $this->getContext()->getResponse()->setStatusCode(404);
+          $this->getContext()->getResponse()->setHttpHeader('Status', '404 Not Found');
+          foreach (sfMixer::getCallables('sfController:forward:error404') as $callable)
+          {
+            call_user_func($callable, $this, $moduleName, $actionName);
+          }
+        }
+                if (sfConfig::get('sf_i18n'))
+        {
+          if (sfLoader::getI18NDir($moduleName))
+          {
+            $this->context->getI18N()->setMessageSourceDir(sfLoader::getI18NDir($moduleName), $this->context->getUser()->getCulture());
+          }
+          else
+          {
+            $this->context->getI18N()->setMessageSourceDir(sfConfig::get('sf_app_i18n_dir'), $this->context->getUser()->getCulture());
+          }
+        }
+                $filterChain->execute();
+      }
+      else
+      {
+                $error = 'Action initialization failed for module "%s", action "%s"';
+        $error = sprintf($error, $moduleName, $actionName);
+        throw new sfInitializationException($error);
+      }
+    }
+    else
+    {
+            $moduleName = sfConfig::get('sf_module_disabled_module');
+      $actionName = sfConfig::get('sf_module_disabled_action');
+      if (!$this->actionExists($moduleName, $actionName))
+      {
+                $error = 'Invalid configuration settings: [sf_module_disabled_module] "%s", [sf_module_disabled_action] "%s"';
+        $error = sprintf($error, $moduleName, $actionName);
+        throw new sfConfigurationException($error);
+      }
+      $this->forward($moduleName, $actionName);
+    }
+  }
+  public function getAction($moduleName, $actionName)
+  {
+    return $this->getController($moduleName, $actionName, 'action');
+  }
+  public function getComponent($moduleName, $componentName)
+  {
+    return $this->getController($moduleName, $componentName, 'component');
+  }
+  protected function getController($moduleName, $controllerName, $extension)
+  {
+    $classSuffix = ucfirst(strtolower($extension));
+    if (!isset($this->controllerClasses[$moduleName.'_'.$controllerName.'_'.$classSuffix]))
+    {
+      $this->controllerExists($moduleName, $controllerName, $extension, true);
+    }
+    $class = $this->controllerClasses[$moduleName.'_'.$controllerName.'_'.$classSuffix];
+        $moduleClass = $moduleName.'_'.$class;
+    if (class_exists($moduleClass, false))
+    {
+      $class = $moduleClass;
+    }
+    return new $class();
+  }
+  public function getActionStack()
+  {
+    return $this->context->getActionStack();
+  }
+  public function getContext()
+  {
+    return $this->context;
+  }
+  public function getRenderMode()
+  {
+    return $this->renderMode;
+  }
+  public function getView($moduleName, $actionName, $viewName)
+  {
+        $file = sfConfig::get('sf_app_module_dir').'/'.$moduleName.'/'.sfConfig::get('sf_app_module_view_dir_name').'/'.$actionName.$viewName.'View.class.php';
+    if (is_readable($file))
+    {
+      require_once($file);
+      $class = $actionName.$viewName.'View';
+            $moduleClass = $moduleName.'_'.$class;
+      if (class_exists($moduleClass, false))
+      {
+        $class = $moduleClass;
+      }
+    }
+    else
+    {
+            $viewName = $this->getContext()->getRequest()->getAttribute($moduleName.'_'.$actionName.'_view_name', sfConfig::get('mod_'.strtolower($moduleName).'_view_class'), 'symfony/action/view');
+      $class    = sfCore::getClassPath($viewName.'View') ? $viewName.'View' : 'sfPHPView';
+    }
+    return new $class();
+  }
+  public function initialize($context)
+  {
+    $this->context = $context;
+    if (sfConfig::get('sf_logging_enabled'))
+    {
+      $this->context->getLogger()->info('{sfController} initialization');
+    }
+        $this->maxForwards = sfConfig::get('sf_max_forwards');
+  }
+  public static function newInstance($class)
+  {
+    try
+    {
+            $object = new $class();
+      if (!($object instanceof sfController))
+      {
+                    $error = 'Class "%s" is not of the type sfController';
+          $error = sprintf($error, $class);
+          throw new sfFactoryException($error);
+      }
+      return $object;
+    }
+    catch (sfException $e)
+    {
+      $e->printStackTrace();
+    }
+  }
+  public function sendEmail($module, $action)
+  {
+    return $this->getPresentationFor($module, $action, 'sfMail');
+  }
+  public function getPresentationFor($module, $action, $viewName = null)
+  {
+    if (sfConfig::get('sf_logging_enabled'))
+    {
+      $this->getContext()->getLogger()->info('{sfController} get presentation for action "'.$module.'/'.$action.'" (view class: "'.$viewName.'")');
+    }
+        $renderMode = $this->getRenderMode();
+        $this->setRenderMode(sfView::RENDER_VAR);
+        $actionStack = $this->getActionStack();
+        $index = $actionStack->getSize();
+        if ($viewName)
+    {
+      $this->getContext()->getRequest()->setAttribute($module.'_'.$action.'_view_name', $viewName, 'symfony/action/view');
+    }
+    try
+    {
+            $this->forward($module, $action);
+    }
+    catch (Exception $e)
+    {
+            $this->setRenderMode($renderMode);
+            if ($viewName)
+      {
+        $this->getContext()->getRequest()->getAttributeHolder()->remove($module.'_'.$action.'_view_name', 'symfony/action/view');
+      }
+      throw $e;
+    }
+        $actionEntry = $actionStack->getEntry($index);
+        $presentation =& $actionEntry->getPresentation();
+        $this->setRenderMode($renderMode);
+        $nb = $actionStack->getSize() - $index;
+    while ($nb-- > 0)
+    {
+      $actionEntry = $actionStack->popEntry();
+      if ($actionEntry->getModuleName() == sfConfig::get('sf_login_module') && $actionEntry->getActionName() == sfConfig::get('sf_login_action'))
+      {
+        throw new sfException('Your action is secured, but the user is not authenticated.');
+      }
+      else if ($actionEntry->getModuleName() == sfConfig::get('sf_secure_module') && $actionEntry->getActionName() == sfConfig::get('sf_secure_action'))
+      {
+        throw new sfException('Your action is secured, but the user does not have access.');
+      }
+    }
+        if ($viewName)
+    {
+      $this->getContext()->getRequest()->getAttributeHolder()->remove($module.'_'.$action.'_view_name', 'symfony/action/view');
+    }
+    return $presentation;
+  }
+  public function setRenderMode($mode)
+  {
+    if ($mode == sfView::RENDER_CLIENT || $mode == sfView::RENDER_VAR || $mode == sfView::RENDER_NONE)
+    {
+      $this->renderMode = $mode;
+      return;
+    }
+        $error = 'Invalid rendering mode: %s';
+    $error = sprintf($error, $mode);
+    throw new sfRenderException($error);
+  }
+  public function inCLI()
+  {
+    return 0 == strncasecmp(PHP_SAPI, 'cli', 3);
+  }
+  public function loadFilters($filterChain, $actionInstance)
+  {
+    $moduleName = $this->context->getModuleName();
+    require(sfConfigCache::getInstance()->checkConfig(sfConfig::get('sf_app_module_dir_name').'/'.$moduleName.'/'.sfConfig::get('sf_app_module_config_dir_name').'/filters.yml'));
+  }
+  public function __call($method, $arguments)
+  {
+    if (!$callable = sfMixer::getCallable('sfController:'.$method))
+    {
+      throw new sfException(sprintf('Call to undefined method sfController::%s', $method));
+    }
+    array_unshift($arguments, $this);
+    return call_user_func_array($callable, $arguments);
+  }
+}
+
+
+class sfDatabaseManager
+{
+  protected
+    $databases = array();
+  public function getDatabase($name = 'default')
+  {
+    if (isset($this->databases[$name]))
+    {
+      return $this->databases[$name];
+    }
+        $error = 'Database "%s" does not exist';
+    $error = sprintf($error, $name);
+    throw new sfDatabaseException($error);
+  }
+  public function initialize()
+  {
+        // 'config/databases.yml' config file
+// auto-generated by sfDatabaseConfigHandler
+// date: 2014/05/07 16:15:25
+$database = new sfPropel13Database();
+$database->initialize(array (
+  'dsn' => 'mysql:dbname=tvtl;host=127.0.0.1',
+  'username' => 'root',
+  'password' => 123456,
+), 'propel');
+$this->databases['propel'] = $database;
+  }
+  public function shutdown()
+  {
+        foreach ($this->databases as $database)
+    {
+      $database->shutdown();
+    }
+  }
+}
+
+
+abstract class sfFilter
+{
+  protected
+    $parameterHolder = null,
+    $context         = null;
+  public static
+    $filterCalled    = array();
+  protected function isFirstCall()
+  {
+    $class = get_class($this);
+    if (isset(self::$filterCalled[$class]))
+    {
+      return false;
+    }
+    else
+    {
+      self::$filterCalled[$class] = true;
+      return true;
+    }
+  }
+  public final function getContext()
+  {
+    return $this->context;
+  }
+  public function initialize($context, $parameters = array())
+  {
+    $this->context = $context;
+    $this->parameterHolder = new sfParameterHolder();
+    $this->parameterHolder->add($parameters);
+    return true;
+  }
+  public function getParameterHolder()
+  {
+    return $this->parameterHolder;
+  }
+  public function getParameter($name, $default = null, $ns = null)
+  {
+    return $this->parameterHolder->get($name, $default, $ns);
+  }
+  public function hasParameter($name, $ns = null)
+  {
+    return $this->parameterHolder->has($name, $ns);
+  }
+  public function setParameter($name, $value, $ns = null)
+  {
+    return $this->parameterHolder->set($name, $value, $ns);
+  }
+}
+
+
+class sfCommonFilter extends sfFilter
+{
+  public function execute($filterChain)
+  {
+        $filterChain->execute();
+        $response = $this->getContext()->getResponse();
+        $content = $response->getContent();
+    if (false !== ($pos = strpos($content, '</head>')))
+    {
+      sfLoader::loadHelpers(array('Tag', 'Asset'));
+      $html = '';
+      if (!$response->getParameter('javascripts_included', false, 'symfony/view/asset'))
+      {
+        $html .= get_javascripts($response);
+      }
+      if (!$response->getParameter('stylesheets_included', false, 'symfony/view/asset'))
+      {
+        $html .= get_stylesheets($response);
+      }
+      if ($html)
+      {
+        $response->setContent(substr($content, 0, $pos).$html.substr($content, $pos));
+      }
+    }
+    $response->setParameter('javascripts_included', false, 'symfony/view/asset');
+    $response->setParameter('stylesheets_included', false, 'symfony/view/asset');
+  }
+}
+
+
+class sfExecutionFilter extends sfFilter
+{
+  public function execute($filterChain)
+  {
+        $context    = $this->getContext();
+    $controller = $context->getController();
+        $actionEntry    = $controller->getActionStack()->getLastEntry();
+    $actionInstance = $actionEntry->getActionInstance();
+        $moduleName = $context->getModuleName();
+    $actionName = $context->getActionName();
+        $method = $context->getRequest()->getMethod();
+    $viewName = null;
+    if (sfConfig::get('sf_cache'))
+    {
+      $uri = sfRouting::getInstance()->getCurrentInternalUri();
+      if (null !== $context->getResponse()->getParameter($uri.'_action', null, 'symfony/cache'))
+      {
+                $viewName = sfView::SUCCESS;
+      }
+    }
+    if (!$viewName)
+    {
+      if (($actionInstance->getRequestMethods() & $method) != $method)
+      {
+                        $viewName = $actionInstance->getDefaultView();
+      }
+      else
+      {
+                $validated = true;
+                        $validationConfigWithFirstLetterLower = $moduleName.'/'.sfConfig::get('sf_app_module_validate_dir_name').'/'.strtolower(substr($actionName, 0, 1)).substr($actionName, 1).'.yml';
+        $validationConfigWithFirstLetterUpper = $moduleName.'/'.sfConfig::get('sf_app_module_validate_dir_name').'/'.ucfirst($actionName).'.yml';
+                        $validateFile = null;
+        if (!is_null($testValidateFile = sfConfigCache::getInstance()->checkConfig(sfConfig::get('sf_app_module_dir_name').'/'.$validationConfigWithFirstLetterLower, true)))
+        {
+          $validateFile = $testValidateFile;
+        }
+        else if (!is_null($testValidateFile = sfConfigCache::getInstance()->checkConfig(sfConfig::get('sf_app_module_dir_name').'/'.$validationConfigWithFirstLetterUpper, true)))
+        {
+          $validateFile = $testValidateFile;
+        }
+                        if (!is_null($validateFile))
+        {
+                    $validatorManager = new sfValidatorManager();
+          $validatorManager->initialize($context);
+          require($validateFile);
+                    $validated = $validatorManager->execute();
+        }
+                $validateToRun = 'validate'.ucfirst($actionName);
+        $manualValidated = method_exists($actionInstance, $validateToRun) ? $actionInstance->$validateToRun() : $actionInstance->validate();
+                                $validated = ($manualValidated && $validated) || ($manualValidated && !$validated && !$context->getRequest()->hasErrors());
+                if (null !== ($parameters = $context->getRequest()->getAttribute('fillin', null, 'symfony/filter')))
+        {
+          $this->registerFillInFilter($filterChain, $parameters);
+        }
+        if ($validated)
+        {
+          if (sfConfig::get('sf_debug') && sfConfig::get('sf_logging_enabled'))
+          {
+            $timer = sfTimerManager::getTimer(sprintf('Action "%s/%s"', $moduleName, $actionName));
+          }
+                    $actionInstance->preExecute();
+          $viewName = $actionInstance->execute();
+          if ($viewName == '')
+          {
+            $viewName = sfView::SUCCESS;
+          }
+          $actionInstance->postExecute();
+          if (sfConfig::get('sf_debug') && sfConfig::get('sf_logging_enabled'))
+          {
+            $timer->addTime();
+          }
+        }
+        else
+        {
+          if (sfConfig::get('sf_logging_enabled'))
+          {
+            $this->context->getLogger()->info('{sfFilter} action validation failed');
+          }
+                    $handleErrorToRun = 'handleError'.ucfirst($actionName);
+          $viewName = method_exists($actionInstance, $handleErrorToRun) ? $actionInstance->$handleErrorToRun() : $actionInstance->handleError();
+          if ($viewName == '')
+          {
+            $viewName = sfView::ERROR;
+          }
+        }
+      }
+    }
+    if ($viewName == sfView::HEADER_ONLY)
+    {
+      $context->getResponse()->setHeaderOnly(true);
+            $filterChain->execute();
+    }
+    else if ($viewName != sfView::NONE)
+    {
+      if (sfConfig::get('sf_debug') && sfConfig::get('sf_logging_enabled'))
+      {
+        $timer = sfTimerManager::getTimer(sprintf('View "%s" for "%s/%s"', $viewName, $moduleName, $actionName));
+      }
+            $viewInstance = $controller->getView($moduleName, $actionName, $viewName);
+      $viewInstance->initialize($context, $moduleName, $actionName, $viewName);
+      $viewInstance->execute();
+                  $viewData = $viewInstance->render();
+      if (sfConfig::get('sf_debug') && sfConfig::get('sf_logging_enabled'))
+      {
+        $timer->addTime();
+      }
+      if ($controller->getRenderMode() == sfView::RENDER_VAR)
+      {
+        $actionEntry->setPresentation($viewData);
+      }
+      else
+      {
+                $filterChain->execute();
+      }
+    }
+  }
+  protected function registerFillInFilter($filterChain, $parameters)
+  {
+        if (isset($parameters['enabled']) && $parameters['enabled'] && !$filterChain->hasFilter('sfFillInFormFilter'))
+    {
+            $fillInFormFilter = new sfFillInFormFilter();
+      $fillInFormFilter->initialize($this->context, isset($parameters['param']) ? $parameters['param'] : array());
+      $filterChain->register($fillInFormFilter);
+    }
+  }
+}
+
+
+class sfRenderingFilter extends sfFilter
+{
+  public function execute($filterChain)
+  {
+        $filterChain->execute();
+    if (sfConfig::get('sf_logging_enabled'))
+    {
+      $this->getContext()->getLogger()->info('{sfFilter} render to client');
+    }
+        $response = $this->getContext()->getResponse();
+        if (method_exists($response, 'sendHttpHeaders'))
+    {
+      $response->sendHttpHeaders();
+    }
+        $response->sendContent();
+        if (sfConfig::get('sf_debug') && sfConfig::get('sf_logging_enabled'))
+    {
+      $logger = $this->getContext()->getLogger();
+      foreach (sfTimerManager::getTimers() as $name => $timer)
+      {
+        $logger->info(sprintf('{sfTimerManager} %s %.2f ms (%d)', $name, $timer->getElapsedTime() * 1000, $timer->getCalls()));
+      }
+    }
+  }
+}
+
+
+class sfFilterChain
+{
+  protected
+    $chain = array(),
+    $index = -1;
+  public function execute()
+  {
+        ++$this->index;
+    if ($this->index < count($this->chain))
+    {
+      if (sfConfig::get('sf_logging_enabled'))
+      {
+        sfContext::getInstance()->getLogger()->info(sprintf('{sfFilter} executing filter "%s"', get_class($this->chain[$this->index])));
+      }
+            $this->chain[$this->index]->execute($this);
+    }
+  }
+  public function hasFilter($class)
+  {
+    foreach ($this->chain as $filter)
+    {
+      if ($filter instanceof $class)
+      {
+        return true;
+      }
+    }
+    return false;
+  }
+  public function register($filter)
+  {
+    $this->chain[] = $filter;
+  }
+}
+
+
+abstract class sfRequest
+{
+  const GET = 2;
+  const NONE = 1;
+  const POST = 4;
+  const PUT = 5;
+  const DELETE = 6;
+  const HEAD = 7;
+  protected
+    $errors          = array(),
+    $context         = null,
+    $method          = null,
+    $parameterHolder = null,
+    $config          = null,
+    $attributeHolder = null;
+  public function & extractParameters($names)
+  {
+    $array = array();
+    $parameters =& $this->parameterHolder->getAll();
+    foreach ($parameters as $key => &$value)
+    {
+      if (in_array($key, $names))
+      {
+        $array[$key] =& $value;
+      }
+    }
+    return $array;
+  }
+  public function getError($name, $catalogue = 'messages')
+  {
+    $retval = null;
+    if (isset($this->errors[$name]))
+    {
+      $retval = $this->errors[$name];
+            if (sfConfig::get('sf_i18n'))
+      {
+        $retval = $this->context->getI18N()->__($retval, null, $catalogue);
+      }
+    }
+    return $retval;
+  }
+  public function getErrorNames()
+  {
+    return array_keys($this->errors);
+  }
+  public function getErrors()
+  {
+    return $this->errors;
+  }
+  public function getMethod()
+  {
+    return $this->method;
+  }
+  public function hasError($name)
+  {
+    return array_key_exists($name, $this->errors);
+  }
+  public function hasErrors()
+  {
+    return (count($this->errors) > 0);
+  }
+  public function initialize($context, $parameters = array(), $attributes = array())
+  {
+    $this->context = $context;
+        $this->parameterHolder = new sfParameterHolder();
+    $this->attributeHolder = new sfParameterHolder();
+    $this->parameterHolder->add($parameters);
+    $this->attributeHolder->add($attributes);
+  }
+  public function getContext()
+  {
+    return $this->context;
+  }
+  public static function newInstance($class)
+  {
+        $object = new $class();
+    if (!($object instanceof sfRequest))
+    {
+            $error = 'Class "%s" is not of the type sfRequest';
+      $error = sprintf($error, $class);
+      throw new sfFactoryException($error);
+    }
+    return $object;
+  }
+  public function & removeError($name)
+  {
+    $retval = null;
+    if (isset($this->errors[$name]))
+    {
+      $retval =& $this->errors[$name];
+      unset($this->errors[$name]);
+    }
+    return $retval;
+  }
+  public function setError($name, $message)
+  {
+    if (sfConfig::get('sf_logging_enabled'))
+    {
+      $this->getContext()->getLogger()->info('{sfRequest} error in form for parameter "'.$name.'" (with message "'.$message.'")');
+    }
+    $this->errors[$name] = $message;
+  }
+  public function setErrors($errors)
+  {
+    $this->errors = array_merge($this->errors, $errors);
+  }
+  public function setMethod($methodCode)
+  {
+    $available_methods = array(self::GET, self::POST, self::PUT, self::DELETE, self::HEAD, self::NONE);
+    if (in_array($methodCode, $available_methods))
+    {
+      $this->method = $methodCode;
+      return;
+    }
+        $error = 'Invalid request method: %s';
+    $error = sprintf($error, $methodCode);
+    throw new sfException($error);
+  }
+  public function getParameterHolder()
+  {
+    return $this->parameterHolder;
+  }
+  public function getAttributeHolder()
+  {
+    return $this->attributeHolder;
+  }
+  public function getAttribute($name, $default = null, $ns = null)
+  {
+    return $this->attributeHolder->get($name, $default, $ns);
+  }
+  public function hasAttribute($name, $ns = null)
+  {
+    return $this->attributeHolder->has($name, $ns);
+  }
+  public function setAttribute($name, $value, $ns = null)
+  {
+    $this->attributeHolder->set($name, $value, $ns);
+  }
+  public function getParameter($name, $default = null, $ns = null)
+  {
+    return $this->parameterHolder->get($name, $default, $ns);
+  }
+  public function hasParameter($name, $ns = null)
+  {
+    return $this->parameterHolder->has($name, $ns);
+  }
+  public function setParameter($name, $value, $ns = null)
+  {
+    $this->parameterHolder->set($name, $value, $ns);
+  }
+  abstract function shutdown();
+  public function __call($method, $arguments)
+  {
+    if (!$callable = sfMixer::getCallable('sfRequest:'.$method))
+    {
+      throw new sfException(sprintf('Call to undefined method sfRequest::%s', $method));
+    }
+    array_unshift($arguments, $this);
+    return call_user_func_array($callable, $arguments);
+  }
+}
+
+
+abstract class sfResponse
+{
+  protected
+    $parameterHolder = null,
+    $context         = null,
+    $content         = '';
+  public function initialize($context, $parameters = array())
+  {
+    $this->context = $context;
+    $this->parameterHolder = new sfParameterHolder();
+    $this->parameterHolder->add($parameters);
+  }
+  public function setContext($context)
+  {
+    $this->context = $context;
+  }
+  public function getContext()
+  {
+    return $this->context;
+  }
+  public static function newInstance($class)
+  {
+        $object = new $class();
+    if (!($object instanceof sfResponse))
+    {
+            $error = 'Class "%s" is not of the type sfResponse';
+      $error = sprintf($error, $class);
+      throw new sfFactoryException($error);
+    }
+    return $object;
+  }
+  public function setContent($content)
+  {
+    $this->content = $content;
+  }
+  public function getContent()
+  {
+    return $this->content;
+  }
+  public function sendContent()
+  {
+    if (sfConfig::get('sf_logging_enabled'))
+    {
+      $this->getContext()->getLogger()->info('{sfResponse} send content ('.strlen($this->content).' o)');
+    }
+    echo $this->content;
+  }
+  public function getParameterHolder()
+  {
+    return $this->parameterHolder;
+  }
+  public function getParameter($name, $default = null, $ns = null)
+  {
+    return $this->parameterHolder->get($name, $default, $ns);
+  }
+  public function hasParameter($name, $ns = null)
+  {
+    return $this->parameterHolder->has($name, $ns);
+  }
+  public function setParameter($name, $value, $ns = null)
+  {
+    $this->parameterHolder->set($name, $value, $ns);
+  }
+  abstract function shutdown();
+  public function __call($method, $arguments)
+  {
+    if (!$callable = sfMixer::getCallable('sfResponse:'.$method))
+    {
+      throw new sfException(sprintf('Call to undefined method sfResponse::%s', $method));
+    }
+    array_unshift($arguments, $this);
+    return call_user_func_array($callable, $arguments);
+  }
+}
+
+
+abstract class sfStorage
+{
+  protected
+    $parameterHolder = null,
+    $context         = null;
+  public function getContext()
+  {
+    return $this->context;
+  }
+  public function initialize($context, $parameters = array())
+  {
+    $this->context = $context;
+    $this->parameterHolder = new sfParameterHolder();
+    $this->getParameterHolder()->add($parameters);
+  }
+  public static function newInstance($class)
+  {
+        $object = new $class();
+    if (!($object instanceof sfStorage))
+    {
+            $error = 'Class "%s" is not of the type sfStorage';
+      $error = sprintf($error, $class);
+      throw new sfFactoryException($error);
+    }
+    return $object;
+  }
+  abstract function & read($key);
+  abstract function & remove($key);
+  abstract function shutdown();
+  abstract function write($key, &$data);
+  public function getParameterHolder()
+  {
+    return $this->parameterHolder;
+  }
+  public function getParameter($name, $default = null, $ns = null)
+  {
+    return $this->parameterHolder->get($name, $default, $ns);
+  }
+  public function hasParameter($name, $ns = null)
+  {
+    return $this->parameterHolder->has($name, $ns);
+  }
+  public function setParameter($name, $value, $ns = null)
+  {
+    return $this->parameterHolder->set($name, $value, $ns);
+  }
+}
+
+
+class sfUser
+{
+  const ATTRIBUTE_NAMESPACE = 'symfony/user/sfUser/attributes';
+  const CULTURE_NAMESPACE = 'symfony/user/sfUser/culture';
+  protected
+    $parameterHolder = null,
+    $attributeHolder = null,
+    $culture         = null,
+    $context         = null;
+  public function getContext()
+  {
+    return $this->context;
+  }
+  public function initialize($context, $parameters = array())
+  {
+    $this->context = $context;
+    $this->parameterHolder = new sfParameterHolder();
+    $this->parameterHolder->add($parameters);
+    $this->attributeHolder = new sfParameterHolder(self::ATTRIBUTE_NAMESPACE);
+        $attributes = $context->getStorage()->read(self::ATTRIBUTE_NAMESPACE);
+    if (is_array($attributes))
+    {
+      foreach ($attributes as $namespace => $values)
+      {
+        $this->attributeHolder->add($values, $namespace);
+      }
+    }
+                    if (!($culture = $context->getRequest()->getParameter('sf_culture')))
+    {
+      if (null === ($culture = $context->getStorage()->read(self::CULTURE_NAMESPACE)))
+      {
+        $culture = sfConfig::get('sf_i18n_default_culture', 'en');
+      }
+    }
+    $this->setCulture($culture);
+  }
+  public static function newInstance($class)
+  {
+        $object = new $class();
+    if (!($object instanceof sfUser))
+    {
+            $error = 'Class "%s" is not of the type sfUser';
+      $error = sprintf($error, $class);
+      throw new sfFactoryException($error);
+    }
+    return $object;
+  }
+  public function setCulture($culture)
+  {
+    if ($this->culture != $culture)
+    {
+      $this->culture = $culture;
+            if (sfConfig::get('sf_i18n'))
+      {
+        $this->context->getI18N()->setCulture($culture);
+      }
+            sfConfig::set('sf_routing_defaults', array_merge((array) sfConfig::get('sf_routing_defaults'), array('sf_culture' => $culture)));
+    }
+  }
+  public function getCulture()
+  {
+    return $this->culture;
+  }
+  public function getParameterHolder()
+  {
+    return $this->parameterHolder;
+  }
+  public function getAttributeHolder()
+  {
+    return $this->attributeHolder;
+  }
+  public function getAttribute($name, $default = null, $ns = null)
+  {
+    return $this->attributeHolder->get($name, $default, $ns);
+  }
+  public function hasAttribute($name, $ns = null)
+  {
+    return $this->attributeHolder->has($name, $ns);
+  }
+  public function setAttribute($name, $value, $ns = null)
+  {
+    return $this->attributeHolder->set($name, $value, $ns);
+  }
+  public function getParameter($name, $default = null, $ns = null)
+  {
+    return $this->parameterHolder->get($name, $default, $ns);
+  }
+  public function hasParameter($name, $ns = null)
+  {
+    return $this->parameterHolder->has($name, $ns);
+  }
+  public function setParameter($name, $value, $ns = null)
+  {
+    return $this->parameterHolder->set($name, $value, $ns);
+  }
+  public function shutdown()
+  {
+    $storage = $this->getContext()->getStorage();
+    $attributes = array();
+    foreach ($this->attributeHolder->getNamespaces() as $namespace)
+    {
+      $attributes[$namespace] = $this->attributeHolder->getAll($namespace);
+    }
+        $storage->write(self::ATTRIBUTE_NAMESPACE, $attributes);
+        $storage->write(self::CULTURE_NAMESPACE, $this->culture);
+    session_write_close();
+  }
+  public function __call($method, $arguments)
+  {
+    if (!$callable = sfMixer::getCallable('sfUser:'.$method))
+    {
+      throw new sfException(sprintf('Call to undefined method sfUser::%s', $method));
+    }
+    array_unshift($arguments, $this);
+    return call_user_func_array($callable, $arguments);
+  }
+}
+
+
+class sfContext
+{
+  protected
+    $actionStack       = null,
+    $controller        = null,
+    $databaseManager   = null,
+    $request           = null,
+    $response          = null,
+    $storage           = null,
+    $viewCacheManager  = null,
+    $i18n              = null,
+    $logger            = null,
+    $user              = null;
+  protected static
+    $instance          = null;
+  public static function removeInstance()
+  {
+    self::$instance = null;
+  }
+  protected function initialize()
+  {
+    $this->logger = sfLogger::getInstance();
+    if (sfConfig::get('sf_logging_enabled'))
+    {
+      $this->logger->info('{sfContext} initialization');
+    }
+    if (sfConfig::get('sf_use_database'))
+    {
+            $this->databaseManager = new sfDatabaseManager();
+      $this->databaseManager->initialize();
+    }
+        $this->actionStack = new sfActionStack();
+        // 'config/factories.yml' config file
+// auto-generated by sfFactoryConfigHandler
+// date: 2014/05/07 16:15:25
+  $this->controller = sfController::newInstance(sfConfig::get('sf_factory_controller', 'sfFrontWebController'));
+  $this->request = sfRequest::newInstance(sfConfig::get('sf_factory_request', 'sfWebRequest'));
+  $this->response = sfResponse::newInstance(sfConfig::get('sf_factory_response', 'sfWebResponse'));
+  $this->storage = sfStorage::newInstance(sfConfig::get('sf_factory_storage', 'sfDatabaseSessionStorage'));
+  $this->user = sfUser::newInstance(sfConfig::get('sf_factory_user', 'sfMyUser'));
+  $this->controller->initialize($this);
+  $this->request->initialize($this, sfConfig::get('sf_factory_request_parameters', NULL), sfConfig::get('sf_factory_request_attributes', array()));
+  $this->response->initialize($this, sfConfig::get('sf_factory_response_parameters', NULL));
+  $this->storage->initialize($this, sfConfig::get('sf_factory_storage_parameters', array (
+  'session_name' => 'symfony',
+  'session_dsn' => 'mysql:dbname=sessions;host=127.0.0.1',
+  'session_user' => 'sessionuser',
+  'session_password' => 'sessionpassword',
+)));
+  $this->user->initialize($this, sfConfig::get('sf_factory_user_parameters', NULL));
+  if (sfConfig::get('sf_cache'))
+  {
+    $this->viewCacheManager = new sfViewCacheManager();
+    $this->viewCacheManager->initialize($this, sfConfig::get('sf_factory_view_cache', 'sfFileCache'), sfConfig::get('sf_factory_view_cache_parameters', array (
+  'automaticCleaningFactor' => 0,
+  'cacheDir' => '/home/www/cache/platform/prod/template',
+)));
+ }
+        register_shutdown_function(array($this, 'shutdown'));
+  }
+  public static function getInstance()
+  {
+    if (!isset(self::$instance))
+    {
+      $class = __CLASS__;
+      self::$instance = new $class();
+      self::$instance->initialize();
+    }
+    return self::$instance;
+  }
+  public static function hasInstance()
+  {
+    return isset(self::$instance);
+  }
+  public function getActionName()
+  {
+        if ($this->actionStack && $lastEntry = $this->actionStack->getLastEntry())
+    {
+      return $lastEntry->getActionName();
+    }
+  }
+  public function getActionStack()
+  {
+    return $this->actionStack;
+  }
+   public function getController()
+   {
+     return $this->controller;
+   }
+   public function getLogger()
+   {
+     return $this->logger;
+   }
+  public function getDatabaseConnection($name = 'default')
+  {
+    if ($this->databaseManager != null)
+    {
+      return $this->databaseManager->getDatabase($name)->getConnection();
+    }
+    return null;
+  }
+  public function retrieveObjects($class, $peerMethod)
+  {
+    $retrievingClass = 'sf'.ucfirst(sfConfig::get('sf_orm', 'propel')).'DataRetriever';
+    return call_user_func(array($retrievingClass, 'retrieveObjects'), $class, $peerMethod);
+  }
+  public function getDatabaseManager()
+  {
+    return $this->databaseManager;
+  }
+  public function getModuleDirectory()
+  {
+        if ($this->actionStack && $lastEntry = $this->actionStack->getLastEntry())
+    {
+      return sfConfig::get('sf_app_module_dir').'/'.$lastEntry->getModuleName();
+    }
+  }
+  public function getModuleName()
+  {
+        if ($this->actionStack && $lastEntry = $this->actionStack->getLastEntry())
+    {
+      return $lastEntry->getModuleName();
+    }
+  }
+  public function getCurrentViewInstance()
+  {
+        if ($this->actionStack && $lastEntry = $this->actionStack->getLastEntry())
+    {
+      return $lastEntry->getViewInstance();
+    }
+  }
+  public function getRequest()
+  {
+    return $this->request;
+  }
+  public function getResponse()
+  {
+    return $this->response;
+  }
+  public function setResponse($response)
+  {
+    $this->response = $response;
+  }
+  public function getStorage()
+  {
+    return $this->storage;
+  }
+  public function getViewCacheManager()
+  {
+    return $this->viewCacheManager;
+  }
+  public function getI18N()
+  {
+    if (!$this->i18n && sfConfig::get('sf_i18n'))
+    {
+      $this->i18n = sfI18N::getInstance();
+      $this->i18n->initialize($this);
+    }
+    return $this->i18n;
+  }
+  public function getUser()
+  {
+    return $this->user;
+  }
+  public function shutdown()
+  {
+        $this->getUser()->shutdown();
+    $this->getStorage()->shutdown();
+    $this->getRequest()->shutdown();
+    $this->getResponse()->shutdown();
+    if (sfConfig::get('sf_logging_enabled'))
+    {
+      $this->getLogger()->shutdown();
+    }
+    if (sfConfig::get('sf_use_database'))
+    {
+      $this->getDatabaseManager()->shutdown();
+    }
+    if (sfConfig::get('sf_cache'))
+    {
+      $this->getViewCacheManager()->shutdown();
+    }
+  }
+}
+
+
+class sfValidatorManager
+{
+  protected
+    $groups  = array(),
+    $names   = array(),
+    $request = null;
+  public function clear()
+  {
+    $this->groups = null;
+    $this->groups = array();
+    $this->names  = null;
+    $this->names  = array();
+  }
+  public function execute()
+  {
+    if (sfConfig::get('sf_logging_enabled'))
+    {
+      sfContext::getInstance()->getLogger()->info('{sfValidator} validation execution');
+    }
+    $retval = true;
+            $pass = 1;
+    while (true)
+    {
+      foreach ($this->names as $name => &$data)
+      {
+        if (isset($data['_is_parent']))
+        {
+                    foreach ($data as $subname => &$subdata)
+          {
+            if ($subname == '_is_parent')
+            {
+                            continue;
+            }
+            if ($subdata['validation_status'] == true && !$this->validate($subname, $subdata, $name))
+            {
+                            $retval = false;
+            }
+          }
+        }
+        else
+        {
+                    if ($data['validation_status'] == true && !$this->validate($name, $data, null))
+          {
+                        $retval = false;
+          }
+        }
+      }
+      if (count($this->groups) == 0 || $pass == 2)
+      {
+        break;
+      }
+            ++$pass;
+    }
+    return $retval;
+  }
+  public function initialize($context)
+  {
+    $this->request = $context->getRequest();
+  }
+  public function registerName($name, $required = true, $message = 'Required', $parent = null, $group = null, $isFile = false)
+  {
+        $entry                      = array();
+    $entry['group']             = null;
+    $entry['is_file']           = $isFile;
+    $entry['required']          = $required;
+    $entry['required_msg']      = $message;
+    $entry['validation_status'] = true;
+    $entry['validators']        = array();
+    if ($parent != null)
+    {
+            if (!isset($this->names[$parent]))
+      {
+                $this->names[$parent] = array('_is_parent' => true);
+      }
+            $this->names[$parent][$name] =& $entry;
+    }
+    else
+    {
+            $this->names[$name] =& $entry;
+    }
+    if ($group != null)
+    {
+            if (!isset($this->groups[$group]))
+      {
+                $this->groups[$group] = array('_force' => false);
+      }
+            $this->groups[$group][] = $name;
+            $entry['group'] =& $this->groups[$group];
+    }
+  }
+  public function registerValidator($name, $validator, $parent = null)
+  {
+    if ($parent != null)
+    {
+            $this->names[$parent][$name]['validators'][] = $validator;
+    }
+    else
+    {
+            $this->names[$name]['validators'][] = $validator;
+    }
+  }
+  protected function validate(&$name, &$data, $parent)
+  {
+        $error     = null;
+    $errorName = null;
+    $force     = null !== $data['group'] ? $data['group']['_force'] : false;
+    $retval    = true;
+    $value     = null;
+        if ($parent == null)
+    {
+            $errorName = $name;
+      if ($data['is_file'])
+      {
+                $value = $this->request->getFile($name);
+      }
+      else
+      {
+                $value = $this->request->getParameterHolder()->get($name);
+      }
+    }
+    else
+    {
+            $errorName = $parent.'{'.$name.'}';
+      if ($data['is_file'])
+      {
+                $parent = $this->request->getFile($parent.'['.$name.']');
+        if ($parent != null)
+        {
+          $value = $parent;
+        }
+      }
+      else
+      {
+                $parent = $this->request->getParameterHolder()->get($parent);
+        if ($parent != null && isset($parent[$name]))
+        {
+          $value = $parent[$name];
+        }
+      }
+    }
+        if (
+      ($data['is_file'] && !$value['name'])
+      ||
+      (!$data['is_file'] && (is_array($value) ? sfToolkit::isArrayValuesEmpty($value) : ($value === null || strlen($value) == 0)))
+    )
+    {
+      if ($data['required'] || $force)
+      {
+                $error  = $data['required_msg'];
+        $retval = false;
+      }
+      else
+      {
+                $retval = true;
+      }
+    }
+    else
+    {
+            $error = null;
+            if ($data['group'] != null)
+      {
+                $data['group']['_force'] = true;
+      }
+      if (count($data['validators']) > 0)
+      {
+                foreach ($data['validators'] as $validator)
+        {
+          if (!$validator->execute($value, $error))
+          {
+            $retval = false;
+            break;
+          }
+        }
+      }
+    }
+    if (!$retval)
+    {
+            $data['validation_status'] = false;
+            $this->request->setError($errorName, $error);
+    }
+    return $retval;
+  }
+}
+
+
+abstract class sfView
+{
+  const ALERT = 'Alert';
+  const ERROR = 'Error';
+  const INPUT = 'Input';
+  const NONE = 'None';
+  const SUCCESS = 'Success';
+  const HEADER_ONLY = 'Headers';
+  const RENDER_CLIENT = 2;
+  const RENDER_NONE = 1;
+  const RENDER_VAR = 4;
+  protected
+    $context            = null,
+    $decorator          = false,
+    $decoratorDirectory = null,
+    $decoratorTemplate  = null,
+    $directory          = null,
+    $componentSlots     = array(),
+    $template           = null,
+    $escaping           = null,
+    $escapingMethod     = null,
+    $attributeHolder    = null,
+    $parameterHolder    = null,
+    $moduleName         = '',
+    $actionName         = '',
+    $viewName           = '',
+    $extension          = '.php';
+  abstract function execute();
+  abstract function configure();
+  public final function getContext()
+  {
+    return $this->context;
+  }
+  public function getDecoratorDirectory()
+  {
+    return $this->decoratorDirectory;
+  }
+  public function getDecoratorTemplate()
+  {
+    return $this->decoratorTemplate;
+  }
+  public function getDirectory()
+  {
+    return $this->directory;
+  }
+  abstract function getEngine();
+  public function getTemplate()
+  {
+    return $this->template;
+  }
+  public function getEscaping()
+  {
+    return null === $this->escaping ? sfConfig::get('sf_escaping_strategy') : $this->escaping;
+  }
+  public function getEscapingMethod()
+  {
+    $method = null === $this->escapingMethod ? sfConfig::get('sf_escaping_method') : $this->escapingMethod;
+    if (empty($method))
+    {
+      return $method;
+    }
+    if (!defined($method))
+    {
+      throw new sfException(sprintf('Escaping method "%s" is not available; perhaps another helper needs to be loaded in?', $method));
+    }
+    return constant($method);
+  }
+  public function importAttributes($names, $files = false, $errors = true, $stripTags = true, $specialChars = true)
+  {
+        $request = $this->context->getRequest();
+        if ($files)
+    {
+            $array =& $request->getFiles();
+    }
+    else
+    {
+            $array =& $request->getParameterHolder()->getAll();
+    }
+        foreach ($names as &$name)
+    {
+        if (preg_match('/^([a-z0-9\-_]+)\{([a-z0-9\s\-_]+)\}$/i', $name, $match))
+        {
+                    $parent  = $match[1];
+          $subname = $match[2];
+                    if (isset($array[$parent]) && isset($array[$parent][$subname]))
+          {
+            $value = $array[$parent][$subname];
+            if ($stripTags)
+              $value = strip_tags($value);
+            if ($specialChars)
+              $value = htmlspecialchars($value);
+            $this->setAttribute($name, $value);
+          }
+          else
+          {
+                        $this->setAttribute($name, '');
+          }
+        }
+        else
+        {
+                    if (isset($array[$name]))
+          {
+            $value = $array[$name];
+            if ($stripTags)
+              $value = strip_tags($value);
+            if ($specialChars)
+              $value = htmlspecialchars($value);
+            $this->setAttribute($name, $value);
+          }
+          else
+          {
+                        $this->setAttribute($name, '');
+          }
+        }
+        if ($errors)
+        {
+          if ($request->hasError($name))
+          {
+            $this->setAttribute($name.'_error', $request->getError($name));
+          }
+          else
+          {
+                        $this->setAttribute($name.'_error', '');
+          }
+        }
+    }
+  }
+  public function initialize($context, $moduleName, $actionName, $viewName)
+  {
+    if (sfConfig::get('sf_logging_enabled'))
+    {
+      $context->getLogger()->info(sprintf('{sfView} initialize view for "%s/%s"', $moduleName, $actionName));
+    }
+    $this->moduleName = $moduleName;
+    $this->actionName = $actionName;
+    $this->viewName   = $viewName;
+    $this->context = $context;
+    $this->attributeHolder = new sfParameterHolder();
+    $this->parameterHolder = new sfParameterHolder();
+    $this->parameterHolder->add(sfConfig::get('mod_'.strtolower($moduleName).'_view_param', array()));
+    $this->decoratorDirectory = sfConfig::get('sf_app_template_dir');
+        $this->configure();
+    return true;
+  }
+  public function getAttributeHolder()
+  {
+    return $this->attributeHolder;
+  }
+  public function getAttribute($name, $default = null, $ns = null)
+  {
+    return $this->attributeHolder->get($name, $default, $ns);
+  }
+  public function hasAttribute($name, $ns = null)
+  {
+    return $this->attributeHolder->has($name, $ns);
+  }
+  public function setAttribute($name, $value, $ns = null)
+  {
+    $this->attributeHolder->set($name, $value, $ns);
+  }
+  public function getParameterHolder()
+  {
+    return $this->parameterHolder;
+  }
+  public function getParameter($name, $default = null, $ns = null)
+  {
+    return $this->parameterHolder->get($name, $default, $ns);
+  }
+  public function hasParameter($name, $ns = null)
+  {
+    return $this->parameterHolder->has($name, $ns);
+  }
+  public function setParameter($name, $value, $ns = null)
+  {
+    $this->parameterHolder->set($name, $value, $ns);
+  }
+  public function isDecorator()
+  {
+    return $this->decorator;
+  }
+  public function setDecorator($boolean)
+  {
+    $this->decorator = (boolean) $boolean;
+  }
+  protected function preRenderCheck()
+  {
+    if ($this->template == null)
+    {
+            $error = 'A template has not been set';
+      throw new sfRenderException($error);
+    }
+    $template = $this->directory.'/'.$this->template;
+    if (!is_readable($template))
+    {
+            throw new sfRenderException(sprintf('The template "%s" does not exist in: %s', $template, $this->directory));
+    }
+        if ($this->decorator)
+    {
+      $template = $this->decoratorDirectory.'/'.$this->decoratorTemplate;
+      if (!is_readable($template))
+      {
+                $error = 'The decorator template "%s" does not exist or is unreadable';
+        $error = sprintf($error, $template);
+        throw new sfRenderException($error);
+      }
+    }
+  }
+  abstract function render($templateVars = null);
+  public function setDecoratorDirectory($directory)
+  {
+    $this->decoratorDirectory = $directory;
+  }
+  public function setEscaping($escaping)
+  {
+    $this->escaping = $escaping;
+  }
+  public function setEscapingMethod($method)
+  {
+    $this->escapingMethod = $method;
+  }
+  public function setDecoratorTemplate($template)
+  {
+    if (sfToolkit::isPathAbsolute($template))
+    {
+      $this->decoratorDirectory = dirname($template);
+      $this->decoratorTemplate  = basename($template);
+    }
+    else
+    {
+      $this->decoratorTemplate = $template;
+    }
+    if (!strpos($this->decoratorTemplate, '.'))
+    {
+      $this->decoratorTemplate .= $this->getExtension();
+    }
+        $this->decorator = true;
+  }
+  public function setDirectory($directory)
+  {
+    $this->directory = $directory;
+  }
+  public function setComponentSlot($attributeName, $moduleName, $componentName)
+  {
+    $this->componentSlots[$attributeName]                   = array();
+    $this->componentSlots[$attributeName]['module_name']    = $moduleName;
+    $this->componentSlots[$attributeName]['component_name'] = $componentName;
+  }
+  public function hasComponentSlot($name)
+  {
+    return isset($this->componentSlots[$name]);
+  }
+  public function getComponentSlot($name)
+  {
+    if (isset($this->componentSlots[$name]) && $this->componentSlots[$name]['module_name'] && $this->componentSlots[$name]['component_name'])
+    {
+      return array($this->componentSlots[$name]['module_name'], $this->componentSlots[$name]['component_name']);
+    }
+    return null;
+  }
+  public function setTemplate($template)
+  {
+    if (sfToolkit::isPathAbsolute($template))
+    {
+      $this->directory = dirname($template);
+      $this->template  = basename($template);
+    }
+    else
+    {
+      $this->template = $template;
+    }
+  }
+  public function getExtension()
+  {
+    return $this->extension;
+  }
+  public function setExtension($ext)
+  {
+    $this->extension = $ext;
+  }
+  public function __call($method, $arguments)
+  {
+    if (!$callable = sfMixer::getCallable('sfView:'.$method))
+    {
+      throw new sfException(sprintf('Call to undefined method sfView::%s', $method));
+    }
+    array_unshift($arguments, $this);
+    return call_user_func_array($callable, $arguments);
+  }
+}
+
+
+abstract class sfWebController extends sfController
+{
+  public function genUrl($parameters = array(), $absolute = false)
+  {
+        if (!is_array($parameters) && preg_match('#^[a-z]+\://#', $parameters))
+    {
+      return $parameters;
+    }
+    if (!is_array($parameters) && $parameters == '#')
+    {
+      return $parameters;
+    }
+    $url = '';
+    if (!sfConfig::get('sf_no_script_name'))
+    {
+      $url = $this->getContext()->getRequest()->getScriptName();
+    }
+    else if ($sf_relative_url_root = $this->getContext()->getRequest()->getRelativeUrlRoot())
+    {
+      $url = $sf_relative_url_root;
+    }
+    $route_name = '';
+    $fragment = '';
+    if (!is_array($parameters))
+    {
+            if (false !== ($pos = strpos($parameters, '#')))
+      {
+        $fragment = substr($parameters, $pos + 1);
+        $parameters = substr($parameters, 0, $pos);
+      }
+      list($route_name, $parameters) = $this->convertUrlStringToParameters($parameters);
+    }
+    if (sfConfig::get('sf_url_format') == 'PATH')
+    {
+            $divider = '/';
+      $equals  = '/';
+      $querydiv = '/';
+    }
+    else
+    {
+            $divider = '&';
+      $equals  = '=';
+      $querydiv = '?';
+    }
+        if (!isset($parameters['module']))
+    {
+      $parameters['module'] = sfConfig::get('sf_default_module');
+    }
+        if (!isset($parameters['action']))
+    {
+      $parameters['action'] = sfConfig::get('sf_default_action');
+    }
+    $r = sfRouting::getInstance();
+    if ($r->hasRoutes() && $generated_url = $r->generate($route_name, $parameters, $querydiv, $divider, $equals))
+    {
+      $url .= $generated_url;
+    }
+    else
+    {
+      $query = http_build_query($parameters);
+      if (sfConfig::get('sf_url_format') == 'PATH')
+      {
+        $query = strtr($query, ini_get('arg_separator.output').'=', '/');
+      }
+      $url .= $query;
+    }
+    if ($absolute)
+    {
+      $request = $this->getContext()->getRequest();
+      $url = 'http'.($request->isSecure() ? 's' : '').'://'.$request->getHost().$url;
+    }
+    if ($fragment)
+    {
+      $url .= '#'.$fragment;
+    }
+    return $url;
+  }
+  public function convertUrlStringToParameters($url)
+  {
+    $params       = array();
+    $query_string = '';
+    $route_name   = '';
+        if (!$url)
+    {
+      $url = '/';
+    }
+        if ($pos = strpos($url, '?'))
+    {
+      $query_string = substr($url, $pos + 1);
+      $url = substr($url, 0, $pos);
+    }
+        if ($url[0] == '/')
+    {
+      $url = substr($url, 1);
+    }
+        if ($url[0] == '@')
+    {
+      $route_name = substr($url, 1);
+    }
+    else
+    {
+      $tmp = explode('/', $url);
+      $params['module'] = $tmp[0];
+      $params['action'] = isset($tmp[1]) ? $tmp[1] : sfConfig::get('sf_default_action');
+    }
+        if ($query_string)
+    {
+      $matched = preg_match_all('/
+        ([^&=]+)            # key
+        =                   # =
+        (.*?)               # value
+        (?:
+          (?=&[^&=]+=) | $   # followed by another key= or the end of the string
+        )
+      /x', $query_string, $matches, PREG_SET_ORDER | PREG_OFFSET_CAPTURE);
+      foreach ($matches as $match)
+      {
+        $params[urldecode($match[1][0])] = urldecode($match[2][0]);
+      }
+            if (!$matched)
+      {
+        throw new sfParseException(sprintf('Unable to parse query string "%s".', $query_string));
+      }
+    }
+    return array($route_name, $params);
+  }
+  public function redirect($url, $delay = 0, $statusCode = 302)
+  {
+    $response = $this->getContext()->getResponse();
+        $response->clearHttpHeaders();
+    $response->setStatusCode($statusCode);
+    $response->setHttpHeader('Location', $url);
+    $response->setContent(sprintf('<html><head><meta http-equiv="refresh" content="%d;url=%s"/></head></html>', $delay, htmlentities($url, ENT_QUOTES, sfConfig::get('sf_charset'))));
+    if (!sfConfig::get('sf_test'))
+    {
+      $response->sendHttpHeaders();
+    }
+    $response->sendContent();
+  }
+}
+
+
+class sfFrontWebController extends sfWebController
+{
+  public function dispatch()
+  {
+    try
+    {
+      if (sfConfig::get('sf_logging_enabled'))
+      {
+        $this->getContext()->getLogger()->info('{sfController} dispatch request');
+      }
+            sfFilter::$filterCalled = array();
+            $request    = $this->getContext()->getRequest();
+      $moduleName = $request->getParameter('module');
+      $actionName = $request->getParameter('action');
+            $this->forward($moduleName, $actionName);
+    }
+    catch (sfException $e)
+    {
+      if (sfConfig::get('sf_test'))
+      {
+        throw $e;
+      }
+      $e->printStackTrace();
+    }
+    catch (Exception $e)
+    {
+      if (sfConfig::get('sf_test'))
+      {
+        throw $e;
+      }
+      try
+      {
+                $sfException = new sfException($e->getMessage().' in '.$e->getFile().' line '.$e->getLine());
+        $sfException->printStackTrace($e);
+      }
+      catch (Exception $e)
+      {
+        header('HTTP/1.0 500 Internal Server Error');
+      }
+    }
+  }
+}
+
+
+class sfWebRequest extends sfRequest
+{
+  protected $languages = null;
+  protected $charsets = null;
+  protected $acceptableContentTypes = null;
+  protected $pathInfoArray = null;
+  protected $relativeUrlRoot = null;
+  protected $filesInfos;
+  public function getFile($name)
+  {
+    return ($this->hasFile($name) ? $this->getFileValues($name) : null);
+  }
+  public function getFileError($name)
+  {
+    return ($this->hasFile($name) ? $this->getFileValue($name, 'error') : UPLOAD_ERR_NO_FILE);
+  }
+  public function getFileName($name)
+  {
+    return ($this->hasFile($name) ? $this->getFileValue($name, 'name') : null);
+  }
+  public function getFileNames()
+  {
+    return array_keys($_FILES);
+  }
+  public function getFiles()
+  {
+    return $_FILES;
+  }
+  public function getFilePath($name)
+  {
+    return ($this->hasFile($name) ? $this->getFileValue($name, 'tmp_name') : null);
+  }
+  public function getFileSize($name)
+  {
+    return ($this->hasFile($name) ? $this->getFileValue($name, 'size') : null);
+  }
+  public function getFileType($name)
+  {
+    return ($this->hasFile($name) ? $this->getFileValue($name, 'type') : null);
+  }
+  public function hasFile($name)
+  {
+    if (strpos($name, '['))
+    {
+      return !is_null(sfToolkit::getArrayValueForPath($this->filesInfos, $name));
+    }
+    else
+    {
+      return isset($this->filesInfos[$name]);
+    }
+  }
+  public function hasFileError($name)
+  {
+    return ($this->hasFile($name) ? ($this->getFileValue($name, 'error') != UPLOAD_ERR_OK) : false);
+  }
+  public function hasFileErrors()
+  {
+    foreach ($this->getFileNames() as $name)
+    {
+      if ($this->hasFileError($name) === true)
+      {
+        return true;
+      }
+    }
+    return false;
+  }
+  public function hasFiles()
+  {
+    return (count($_FILES) > 0);
+  }
+  public function getFileValue($name, $key)
+  {
+    $fileInfos = $this->getFileValues($name);
+    return isset($fileInfos[$key]) ? $fileInfos[$key] : null;
+  }
+  public function getFileValues($name)
+  {
+    if (strpos($name, '['))
+    {
+      return sfToolkit::getArrayValueForPath($this->filesInfos, $name);
+    }
+    else
+    {
+      return isset($this->filesInfos[$name]) ? $this->filesInfos[$name] : null;
+    }
+  }
+  protected function convertFileInformation($taintedFiles)
+  {
+    return $this->pathsToArray(preg_replace('#^(/[^/]+)?(/name|/type|/tmp_name|/error|/size)([^\s]*)( = [^\n]*)#m', '$1$3$2$4', $this->arrayToPaths($taintedFiles)));
+  }
+  public function getFileExtension($name)
+  {
+    static $mimeTypes = null;
+    $fileType = $this->getFileType($name);
+    if (!$fileType)
+    {
+      return '.bin';
+    }
+    if (is_null($mimeTypes))
+    {
+      $mimeTypes = unserialize(file_get_contents(sfConfig::get('sf_symfony_data_dir').'/data/mime_types.dat'));
+    }
+    return isset($mimeTypes[$fileType]) ? '.'.$mimeTypes[$fileType] : '.bin';
+  }
+  public function initialize($context, $parameters = array(), $attributes = array())
+  {
+    parent::initialize($context, $parameters, $attributes);
+    if (isset($_SERVER['REQUEST_METHOD']))
+    {
+      switch ($_SERVER['REQUEST_METHOD'])
+      {
+        case 'GET':
+          $this->setMethod(self::GET);
+          break;
+        case 'POST':
+          $this->setMethod(self::POST);
+          break;
+        case 'PUT':
+          $this->setMethod(self::PUT);
+          break;
+        case 'DELETE':
+          $this->setMethod(self::DELETE);
+          break;
+        case 'HEAD':
+          $this->setMethod(self::HEAD);
+          break;
+        default:
+          $this->setMethod(self::GET);
+      }
+    }
+    else
+    {
+            $this->setMethod(self::GET);
+    }
+        $this->loadParameters();
+  }
+  protected function getPathInfoArray()
+  {
+    if (!$this->pathInfoArray)
+    {
+            switch (sfConfig::get('sf_path_info_array'))
+      {
+        case 'SERVER':
+          $this->pathInfoArray =& $_SERVER;
+          break;
+        case 'ENV':
+        default:
+          $this->pathInfoArray =& $_ENV;
+      }
+    }
+    return $this->pathInfoArray;
+  }
+  public function getUri()
+  {
+    $pathArray = $this->getPathInfoArray();
+        if ('HTTP_X_REWRITE_URL' == sfConfig::get('sf_path_info_key'))
+    {
+      $uri = isset($pathArray['HTTP_X_REWRITE_URL']) ? $pathArray['HTTP_X_REWRITE_URL'] : '';
+    }
+    else
+    {
+      $uri = isset($pathArray['REQUEST_URI']) ? $pathArray['REQUEST_URI'] : '';
+    }
+    return $this->isAbsUri() ? $uri : $this->getUriPrefix().$uri;
+  }
+  public function isAbsUri()
+  {
+    $pathArray = $this->getPathInfoArray();
+    return preg_match('/^http/', $pathArray['REQUEST_URI']);
+  }
+  public function getUriPrefix()
+  {
+    $pathArray = $this->getPathInfoArray();
+    if ($this->isSecure())
+    {
+      $standardPort = '443';
+      $protocol = 'https';
+    }
+    else
+    {
+      $standardPort = '80';
+      $protocol = 'http';
+    }
+    $host = explode(":", $this->getHost());
+    if (count($host) == 1)
+    {
+      $host[] = isset($pathArray['SERVER_PORT']) ? $pathArray['SERVER_PORT'] : '';
+    }
+    if ($host[1] == $standardPort || empty($host[1]))
+    {
+      unset($host[1]);
+    }
+    return $protocol.'://'.implode(':', $host);;
+  }
+  public function getPathInfo()
+  {
+    $pathInfo = '';
+    $pathArray = $this->getPathInfoArray();
+        $sf_path_info_key = sfConfig::get('sf_path_info_key');
+    if (!isset($pathArray[$sf_path_info_key]) || !$pathArray[$sf_path_info_key])
+    {
+      if (isset($pathArray['REQUEST_URI']))
+      {
+        $script_name = $this->getScriptName();
+        $uri_prefix = $this->isAbsUri() ? $this->getUriPrefix() : '';
+        $pathInfo = preg_replace('/^'.preg_quote($uri_prefix, '/').'/','',$pathArray['REQUEST_URI']);
+        $pathInfo = preg_replace('/^'.preg_quote($script_name, '/').'/', '', $pathInfo);
+        $prefix_name = preg_replace('#/[^/]+$#', '', $script_name);
+        $pathInfo = preg_replace('/^'.preg_quote($prefix_name, '/').'/', '', $pathInfo);
+        $pathInfo = preg_replace('/\??'.preg_quote($pathArray['QUERY_STRING'], '/').'$/', '', $pathInfo);
+      }
+    }
+    else
+    {
+      $pathInfo = $pathArray[$sf_path_info_key];
+      if ($sf_relative_url_root = $this->getRelativeUrlRoot())
+      {
+        $pathInfo = preg_replace('/^'.str_replace('/', '\\/', $sf_relative_url_root).'\//', '', $pathInfo);
+      }
+    }
+        if (isset($_SERVER['SERVER_SOFTWARE']) && false !== stripos($_SERVER['SERVER_SOFTWARE'], 'iis') && $pos = stripos($pathInfo, '.php'))
+    {
+      $pathInfo = substr($pathInfo, $pos + 4);
+    }
+    if (!$pathInfo)
+    {
+      $pathInfo = '/';
+    }
+    return $pathInfo;
+  }
+  protected function loadParameters()
+  {
+        if (get_magic_quotes_gpc())
+    {
+      $_GET = sfToolkit::stripslashesDeep($_GET);
+    }
+    $this->getParameterHolder()->addByRef($_GET);
+    $pathInfo = $this->getPathInfo();
+    if ($pathInfo)
+    {
+            $r = sfRouting::getInstance();
+      if ($r->hasRoutes())
+      {
+        $results = $r->parse($pathInfo);
+        if ($results !== null)
+        {
+          $this->getParameterHolder()->addByRef($results);
+        }
+        else
+        {
+          $this->setParameter('module', sfConfig::get('sf_error_404_module'));
+          $this->setParameter('action', sfConfig::get('sf_error_404_action'));
+        }
+      }
+      else
+      {
+        $array = explode('/', trim($pathInfo, '/'));
+        $count = count($array);
+        for ($i = 0; $i < $count; $i++)
+        {
+                              if ($count > ($i + 1))
+          {
+            $this->getParameterHolder()->setByRef($array[$i], $array[++$i]);
+          }
+        }
+      }
+    }
+    $this->filesInfos = $this->convertFileInformation($_FILES);
+        if (get_magic_quotes_gpc())
+    {
+      $_POST = sfToolkit::stripslashesDeep((array) $_POST);
+    }
+    $this->getParameterHolder()->addByRef($_POST);
+        foreach ($this->getParameterHolder()->getAll() as $key => $value)
+    {
+      if (0 === stripos($key, '_sf_'))
+      {
+        $this->getParameterHolder()->remove($key);
+        $this->setParameter($key, $value, 'symfony/request/sfWebRequest');
+        unset($_GET[$key]);
+      }
+    }
+    if (sfConfig::get('sf_logging_enabled'))
+    {
+      $this->getContext()->getLogger()->info(sprintf('{sfRequest} request parameters %s', str_replace("\n", '', var_export($this->getParameterHolder()->getAll(), true))));
+    }
+  }
+  public function moveFile($name, $file, $fileMode = 0666, $create = true, $dirMode = 0777)
+  {
+    if ($this->hasFile($name) && $this->getFileValue($name, 'error') == UPLOAD_ERR_OK && $this->getFileValue($name, 'size') > 0)
+    {
+            $directory = dirname($file);
+      if (!is_readable($directory))
+      {
+        $fmode = 0777;
+        if ($create && !@mkdir($directory, $dirMode, true))
+        {
+                    $error = 'Failed to create file upload directory "%s"';
+          $error = sprintf($error, $directory);
+          throw new sfFileException($error);
+        }
+                        @chmod($directory, $dirMode);
+      }
+      else if (!is_dir($directory))
+      {
+                $error = 'File upload path "%s" exists, but is not a directory';
+        $error = sprintf($error, $directory);
+        throw new sfFileException($error);
+      }
+      else if (!is_writable($directory))
+      {
+                $error = 'File upload path "%s" is not writable';
+        $error = sprintf($error, $directory);
+        throw new sfFileException($error);
+      }
+      if (@move_uploaded_file($this->getFileValue($name, 'tmp_name'), $file))
+      {
+                @chmod($file, $fileMode);
+        return true;
+      }
+    }
+    return false;
+  }
+  public function getReferer()
+  {
+    $pathArray = $this->getPathInfoArray();
+    return isset($pathArray['HTTP_REFERER']) ? $pathArray['HTTP_REFERER'] : '';
+  }
+  public function getHost()
+  {
+    $pathArray = $this->getPathInfoArray();
+    return isset($pathArray['HTTP_X_FORWARDED_HOST']) ? $pathArray['HTTP_X_FORWARDED_HOST'] : (isset($pathArray['HTTP_HOST']) ? $pathArray['HTTP_HOST'] : '');
+  }
+  public function getScriptName()
+  {
+    $pathArray = $this->getPathInfoArray();
+    return isset($pathArray['SCRIPT_NAME']) ? $pathArray['SCRIPT_NAME'] : (isset($pathArray['ORIG_SCRIPT_NAME']) ? $pathArray['ORIG_SCRIPT_NAME'] : '');
+  }
+  public function getMethodName()
+  {
+    $pathArray = $this->getPathInfoArray();
+    return isset($pathArray['REQUEST_METHOD']) ? $pathArray['REQUEST_METHOD'] : 'GET';
+  }
+  public function getLanguages()
+  {
+    if ($this->languages)
+    {
+      return $this->languages;
+    }
+    if (!isset($_SERVER['HTTP_ACCEPT_LANGUAGE']))
+    {
+      return array();
+    }
+    $languages = $this->splitHttpAcceptHeader($_SERVER['HTTP_ACCEPT_LANGUAGE']);
+    foreach ($languages as $lang)
+    {
+      if (strstr($lang, '-'))
+      {
+        $codes = explode('-', $lang);
+        if ($codes[0] == 'i')
+        {
+                                        if (count($codes) > 1)
+          {
+            $lang = $codes[1];
+          }
+        }
+        else
+        {
+          for ($i = 0, $max = count($codes); $i < $max; $i++)
+          {
+            if ($i == 0)
+            {
+              $lang = strtolower($codes[0]);
+            }
+            else
+            {
+              $lang .= '_'.strtoupper($codes[$i]);
+            }
+          }
+        }
+      }
+      $this->languages[] = $lang;
+    }
+    return $this->languages;
+  }
+  public function getCharsets()
+  {
+    if ($this->charsets)
+    {
+      return $this->charsets;
+    }
+    if (!isset($_SERVER['HTTP_ACCEPT_CHARSET']))
+    {
+      return array();
+    }
+    $this->charsets = $this->splitHttpAcceptHeader($_SERVER['HTTP_ACCEPT_CHARSET']);
+    return $this->charsets;
+  }
+  public function getAcceptableContentTypes()
+  {
+    if ($this->acceptableContentTypes)
+    {
+      return $this->acceptableContentTypes;
+    }
+    if (!isset($_SERVER['HTTP_ACCEPT']))
+    {
+      return array();
+    }
+    $this->acceptableContentTypes = $this->splitHttpAcceptHeader($_SERVER['HTTP_ACCEPT']);
+    return $this->acceptableContentTypes;
+  }
+  public function isXmlHttpRequest()
+  {
+    return ($this->getHttpHeader('X_REQUESTED_WITH') == 'XMLHttpRequest');
+  }
+  public function getHttpHeader($name, $prefix = 'http')
+  {
+    if ($prefix)
+    {
+      $prefix = strtoupper($prefix).'_';
+    }
+    $name = $prefix.strtoupper(strtr($name, '-', '_'));
+    $pathArray = $this->getPathInfoArray();
+    return isset($pathArray[$name]) ? sfToolkit::stripslashesDeep($pathArray[$name]) : null;
+  }
+  public function getCookie($name, $defaultValue = null)
+  {
+    $retval = $defaultValue;
+    if (isset($_COOKIE[$name]))
+    {
+      $retval = get_magic_quotes_gpc() ? sfToolkit::stripslashesDeep($_COOKIE[$name]) : $_COOKIE[$name];
+    }
+    return $retval;
+  }
+  public function isSecure()
+  {
+    $pathArray = $this->getPathInfoArray();
+    return (
+      (isset($pathArray['HTTPS']) && (strtolower($pathArray['HTTPS']) == 'on' || strtolower($pathArray['HTTPS']) == 1))
+      ||
+      (isset($pathArray['HTTP_X_FORWARDED_PROTO']) && strtolower($pathArray['HTTP_X_FORWARDED_PROTO']) == 'https')
+    );
+  }
+  public function getRelativeUrlRoot()
+  {
+    if ($this->relativeUrlRoot === null)
+    {
+      $this->relativeUrlRoot = sfConfig::get('sf_relative_url_root', preg_replace('#/[^/]+\.php5?$#', '', $this->getScriptName()));
+    }
+    return $this->relativeUrlRoot;
+  }
+  public function setRelativeUrlRoot($value)
+  {
+    $this->relativeUrlRoot = $value;
+  }
+  public function shutdown()
+  {
+  }
+  public function splitHttpAcceptHeader($header)
+  {
+    $values = array();
+    foreach (array_filter(explode(',', $header)) as $value)
+    {
+            if ($pos = strpos($value, ';'))
+      {
+        $q     = (float) trim(substr($value, $pos + 3));
+        $value = trim(substr($value, 0, $pos));
+      }
+      else
+      {
+        $q = 1;
+      }
+      $values[$value] = $q;
+    }
+    arsort($values);
+    return array_keys($values);
+  }
+  protected function pathsToArray($str)
+  {
+    $array = array();
+    $lines = explode("\n", trim($str));
+    if (!empty($lines[0]))
+    {
+      foreach ($lines as $line)
+      {
+        list($path, $value) = explode(' = ', $line);
+        $steps = explode('/', $path);
+        array_shift($steps);
+        $insertion =& $array;
+        foreach ($steps as $step)
+        {
+          if (!isset($insertion[$step]))
+          {
+            $insertion[$step] = array();
+          }
+          $insertion =& $insertion[$step];
+        }
+        $insertion = ctype_digit($value) ? (int) $value : $value;
+      }
+    }
+    return $array;
+  }
+  protected function arrayToPaths($array = array(), $prefix = '')
+  {
+    $str = '';
+    $freshPrefix = $prefix;
+    foreach ($array as $key => $value)
+    {
+      $freshPrefix .= "/{$key}";
+      if (is_array($value))
+      {
+        $str .= $this->arrayToPaths($value, $freshPrefix);
+        $freshPrefix = $prefix;
+      }
+      else
+      {
+        $str .= "{$prefix}/{$key} = {$value}\n";
+      }
+    }
+    return $str;
+  }
+}
+
+
+class sfWebResponse extends sfResponse
+{
+  protected
+    $cookies     = array(),
+    $statusCode  = 200,
+    $statusText  = 'OK',
+    $statusTexts = array(),
+    $headerOnly  = false;
+  public function initialize($context, $parameters = array())
+  {
+    parent::initialize($context, $parameters);
+    if ('HEAD' == $context->getRequest()->getMethodName())
+    {
+      $this->setHeaderOnly(true);
+    }
+    $this->statusTexts = array(
+      '100' => 'Continue',
+      '101' => 'Switching Protocols',
+      '200' => 'OK',
+      '201' => 'Created',
+      '202' => 'Accepted',
+      '203' => 'Non-Authoritative Information',
+      '204' => 'No Content',
+      '205' => 'Reset Content',
+      '206' => 'Partial Content',
+      '300' => 'Multiple Choices',
+      '301' => 'Moved Permanently',
+      '302' => 'Found',
+      '303' => 'See Other',
+      '304' => 'Not Modified',
+      '305' => 'Use Proxy',
+      '306' => '(Unused)',
+      '307' => 'Temporary Redirect',
+      '400' => 'Bad Request',
+      '401' => 'Unauthorized',
+      '402' => 'Payment Required',
+      '403' => 'Forbidden',
+      '404' => 'Not Found',
+      '405' => 'Method Not Allowed',
+      '406' => 'Not Acceptable',
+      '407' => 'Proxy Authentication Required',
+      '408' => 'Request Timeout',
+      '409' => 'Conflict',
+      '410' => 'Gone',
+      '411' => 'Length Required',
+      '412' => 'Precondition Failed',
+      '413' => 'Request Entity Too Large',
+      '414' => 'Request-URI Too Long',
+      '415' => 'Unsupported Media Type',
+      '416' => 'Requested Range Not Satisfiable',
+      '417' => 'Expectation Failed',
+      '500' => 'Internal Server Error',
+      '501' => 'Not Implemented',
+      '502' => 'Bad Gateway',
+      '503' => 'Service Unavailable',
+      '504' => 'Gateway Timeout',
+      '505' => 'HTTP Version Not Supported',
+    );
+  }
+  public function setHeaderOnly($value = true)
+  {
+    $this->headerOnly = (boolean) $value;
+  }
+  public function isHeaderOnly()
+  {
+    return $this->headerOnly;
+  }
+  public function setCookie($name, $value, $expire = null, $path = '/', $domain = '', $secure = false, $httpOnly = false)
+  {
+    if ($expire !== null)
+    {
+      if (is_numeric($expire))
+      {
+        $expire = (int) $expire;
+      }
+      else
+      {
+        $expire = strtotime($expire);
+        if ($expire === false || $expire == -1)
+        {
+          throw new sfException('Your expire parameter is not valid.');
+        }
+      }
+    }
+    $this->cookies[] = array(
+      'name'     => $name,
+      'value'    => $value,
+      'expire'   => $expire,
+      'path'     => $path,
+      'domain'   => $domain,
+      'secure'   => $secure ? true : false,
+      'httpOnly' => $httpOnly,
+    );
+  }
+  public function setStatusCode($code, $name = null)
+  {
+    $this->statusCode = $code;
+    $this->statusText = null !== $name ? $name : $this->statusTexts[$code];
+  }
+  public function getStatusCode()
+  {
+    return $this->statusCode;
+  }
+  public function setHttpHeader($name, $value, $replace = true)
+  {
+    $name = $this->normalizeHeaderName($name);
+    if ('Content-Type' == $name)
+    {
+      if ($replace || !$this->getHttpHeader('Content-Type', null))
+      {
+        $this->setContentType($value);
+      }
+      return;
+    }
+    if (!$replace)
+    {
+      $current = $this->getParameter($name, '', 'symfony/response/http/headers');
+      $value = ($current ? $current.', ' : '').$value;
+    }
+    $this->setParameter($name, $value, 'symfony/response/http/headers');
+  }
+  public function getHttpHeader($name, $default = null)
+  {
+    return $this->getParameter($this->normalizeHeaderName($name), $default, 'symfony/response/http/headers');
+  }
+  public function hasHttpHeader($name)
+  {
+    return $this->hasParameter($this->normalizeHeaderName($name), 'symfony/response/http/headers');
+  }
+  public function setContentType($value)
+  {
+        if (false === stripos($value, 'charset') && (0 === stripos($value, 'text/') || strlen($value) - 3 === strripos($value, 'xml')))
+    {
+      $value .= '; charset='.sfConfig::get('sf_charset');
+    }
+    $this->setParameter('Content-Type', $value, 'symfony/response/http/headers');
+  }
+  public function getContentType()
+  {
+    return $this->getHttpHeader('Content-Type', 'text/html; charset='.sfConfig::get('sf_charset'));
+  }
+  public function sendHttpHeaders()
+  {
+    $headers = $this->getParameterHolder()->getAll('symfony/response/http/headers');
+        $status = 'HTTP/1.0 '.$this->statusCode.' '.$this->statusText;
+    header($status);
+    if (substr(php_sapi_name(), 0, 3) == 'cgi')
+    {
+                  unset($headers['Status']);
+    }
+    if (sfConfig::get('sf_logging_enabled'))
+    {
+      $this->getContext()->getLogger()->info('{sfResponse} send status "'.$status.'"');
+    }
+        foreach ($headers as $name => $value)
+    {
+      header($name.': '.$value);
+      if (sfConfig::get('sf_logging_enabled') && $value != '')
+      {
+        $this->getContext()->getLogger()->info('{sfResponse} send header "'.$name.'": "'.$value.'"');
+      }
+    }
+        foreach ($this->cookies as $cookie)
+    {
+      if (version_compare(phpversion(), '5.2', '>='))
+      {
+        setrawcookie($cookie['name'], $cookie['value'], $cookie['expire'], $cookie['path'], $cookie['domain'], $cookie['secure'], $cookie['httpOnly']);
+      }
+      else
+      {
+        setrawcookie($cookie['name'], $cookie['value'], $cookie['expire'], $cookie['path'], $cookie['domain'], $cookie['secure']);
+      }
+      if (sfConfig::get('sf_logging_enabled'))
+      {
+        $this->getContext()->getLogger()->info('{sfResponse} send cookie "'.$cookie['name'].'": "'.$cookie['value'].'"');
+      }
+    }
+  }
+  public function sendContent()
+  {
+    if (!$this->headerOnly)
+    {
+      parent::sendContent();
+    }
+  }
+  protected function normalizeHeaderName($name)
+  {
+    return preg_replace('/\-(.)/e', "'-'.strtoupper('\\1')", strtr(ucfirst(strtolower($name)), '_', '-'));
+  }
+  public function getDate($timestamp, $type = 'rfc1123')
+  {
+    $type = strtolower($type);
+    if ($type == 'rfc1123')
+    {
+      return substr(gmdate('r', $timestamp), 0, -5).'GMT';
+    }
+    else if ($type == 'rfc1036')
+    {
+      return gmdate('l, d-M-y H:i:s ', $timestamp).'GMT';
+    }
+    else if ($type == 'asctime')
+    {
+      return gmdate('D M j H:i:s', $timestamp);
+    }
+    else
+    {
+      $error = 'The second getDate() method parameter must be one of: rfc1123, rfc1036 or asctime';
+      throw new sfParameterException($error);
+    }
+  }
+  public function addVaryHttpHeader($header)
+  {
+    $vary = $this->getHttpHeader('Vary');
+    $currentHeaders = array();
+    if ($vary)
+    {
+      $currentHeaders = preg_split('/\s*,\s*/', $vary);
+    }
+    $header = $this->normalizeHeaderName($header);
+    if (!in_array($header, $currentHeaders))
+    {
+      $currentHeaders[] = $header;
+      $this->setHttpHeader('Vary', implode(', ', $currentHeaders));
+    }
+  }
+  public function addCacheControlHttpHeader($name, $value = null)
+  {
+    $cacheControl = $this->getHttpHeader('Cache-Control');
+    $currentHeaders = array();
+    if ($cacheControl)
+    {
+      foreach (preg_split('/\s*,\s*/', $cacheControl) as $tmp)
+      {
+        $tmp = explode('=', $tmp);
+        $currentHeaders[$tmp[0]] = isset($tmp[1]) ? $tmp[1] : null;
+      }
+    }
+    $currentHeaders[strtr(strtolower($name), '_', '-')] = $value;
+    $headers = array();
+    foreach ($currentHeaders as $key => $value)
+    {
+      $headers[] = $key.(null !== $value ? '='.$value : '');
+    }
+    $this->setHttpHeader('Cache-Control', implode(', ', $headers));
+  }
+  public function getHttpMetas()
+  {
+    return $this->getParameterHolder()->getAll('helper/asset/auto/httpmeta');
+  }
+  public function addHttpMeta($key, $value, $replace = true)
+  {
+    $key = $this->normalizeHeaderName($key);
+        $this->setHttpHeader($key, $value, $replace);
+    if ('Content-Type' == $key)
+    {
+      $value = $this->getContentType();
+    }
+    else if (!$replace)
+    {
+      $current = $this->getParameter($key, '', 'helper/asset/auto/httpmeta');
+      $value = ($current ? $current.', ' : '').$value;
+    }
+    $this->setParameter($key, $value, 'helper/asset/auto/httpmeta');
+  }
+  public function getMetas()
+  {
+    return $this->getParameterHolder()->getAll('helper/asset/auto/meta');
+  }
+  public function addMeta($key, $value, $replace = true, $escape = true)
+  {
+    $key = strtolower($key);
+    if (sfConfig::get('sf_i18n'))
+    {
+      $value = $this->getContext()->getI18N()->__($value);
+    }
+    if ($escape)
+    {
+      $value = htmlspecialchars($value, ENT_QUOTES, sfConfig::get('sf_charset'));
+    }
+    if ($replace || !$this->getParameter($key, null, 'helper/asset/auto/meta'))
+    {
+      $this->setParameter($key, $value, 'helper/asset/auto/meta');
+    }
+  }
+  public function getTitle()
+  {
+    return $this->getParameter('title', '', 'helper/asset/auto/meta');
+  }
+  public function setTitle($title, $escape = true)
+  {
+    $this->addMeta('title', $title, true, $escape);
+  }
+  public function getStylesheets($position = '')
+  {
+    return $this->getParameterHolder()->getAll('helper/asset/auto/stylesheet'.($position ? '/'.$position : ''));
+  }
+  public function addStylesheet($css, $position = '', $options = array())
+  {
+    $this->setParameter($css, $options, 'helper/asset/auto/stylesheet'.($position ? '/'.$position : ''));
+  }
+  public function getJavascripts($position = '')
+  {
+    return $this->getParameterHolder()->getAll('helper/asset/auto/javascript'.($position ? '/'.$position : ''));
+  }
+  public function addJavascript($js, $position = '')
+  {
+    $this->setParameter($js, $js, 'helper/asset/auto/javascript'.($position ? '/'.$position : ''));
+  }
+  public function getCookies()
+  {
+    $cookies = array();
+    foreach ($this->cookies as $cookie)
+    {
+      $cookies[$cookie['name']] = $cookie;
+    }
+    return $cookies;
+  }
+  public function getHttpHeaders()
+  {
+    return $this->getParameterHolder()->getAll('symfony/response/http/headers');
+  }
+  public function clearHttpHeaders()
+  {
+    $this->getParameterHolder()->removeNamespace('symfony/response/http/headers');
+  }
+  public function mergeProperties($response)
+  {
+    $this->parameterHolder = clone $response->getParameterHolder();
+  }
+  public function __sleep()
+  {
+    return array('content', 'statusCode', 'statusText', 'parameterHolder');
+  }
+  public function __wakeup()
+  {
+  }
+  public function shutdown()
+  {
+  }
+}
+
+
+class sfSessionStorage extends sfStorage
+{
+  public function initialize($context, $parameters = null)
+  {
+        parent::initialize($context, $parameters);
+        $sessionName = $this->getParameterHolder()->get('session_name', 'symfony');
+    session_name($sessionName);
+    $use_cookies = (boolean) ini_get('session.use_cookies');
+    if (!$use_cookies)
+    {
+      $sessionId = $context->getRequest()->getParameter($sessionName, '');
+      if ($sessionId != '')
+      {
+        session_id($sessionId);
+      }
+    }
+    $cookieDefaults = session_get_cookie_params();
+    $lifetime = $this->getParameter('session_cookie_lifetime', $cookieDefaults['lifetime']);
+    $path     = $this->getParameter('session_cookie_path',     $cookieDefaults['path']);
+    $domain   = $this->getParameter('session_cookie_domain',   $cookieDefaults['domain']);
+    $secure   = $this->getParameter('session_cookie_secure',   $cookieDefaults['secure']);
+    $httpOnly = $this->getParameter('session_cookie_httponly', isset($cookieDefaults['httponly']) ? $cookieDefaults['httponly'] : false);
+    if (version_compare(phpversion(), '5.2', '>='))
+    {
+      session_set_cookie_params($lifetime, $path, $domain, $secure, $httpOnly);
+    }
+    else
+    {
+      session_set_cookie_params($lifetime, $path, $domain, $secure);
+    }
+    if ($this->getParameter('auto_start', true))
+    {
+            session_start();
+    }
+  }
+  public function & read($key)
+  {
+    $retval = null;
+    if (isset($_SESSION[$key]))
+    {
+      $retval =& $_SESSION[$key];
+    }
+    return $retval;
+  }
+  public function & remove($key)
+  {
+    $retval = null;
+    if (isset($_SESSION[$key]))
+    {
+      $retval =& $_SESSION[$key];
+      unset($_SESSION[$key]);
+    }
+    return $retval;
+  }
+  public function write($key, &$data)
+  {
+    $_SESSION[$key] =& $data;
+  }
+  public function shutdown()
+  {
+      }
+}
+
+
+class sfPHPView extends sfView
+{
+  public function execute()
+  {
+  }
+  protected function getGlobalVars()
+  {
+    $context = $this->getContext();
+    $shortcuts = array(
+      'sf_context' => $context,
+      'sf_params'  => $context->getRequest()->getParameterHolder(),
+      'sf_request' => $context->getRequest(),
+      'sf_user'    => $context->getUser(),
+      'sf_view'    => $this,
+    );
+    if (sfConfig::get('sf_use_flash'))
+    {
+      $sf_flash = new sfParameterHolder();
+      $sf_flash->add($context->getUser()->getAttributeHolder()->getAll('symfony/flash'));
+      $shortcuts['sf_flash'] = $sf_flash;
+    }
+    return $shortcuts;
+  }
+  protected function loadCoreAndStandardHelpers()
+  {
+    static $coreHelpersLoaded = 0;
+    if ($coreHelpersLoaded)
+    {
+      return;
+    }
+    $coreHelpersLoaded = 1;
+    $core_helpers = array('Helper', 'Url', 'Asset', 'Tag', 'Escaping');
+    $standard_helpers = sfConfig::get('sf_standard_helpers');
+    $helpers = array_unique(array_merge($core_helpers, $standard_helpers));
+    sfLoader::loadHelpers($helpers);
+  }
+  protected function renderFile($_sfFile)
+  {
+    if (sfConfig::get('sf_logging_enabled'))
+    {
+      $this->getContext()->getLogger()->info('{sfView} render "'.$_sfFile.'"');
+    }
+    $this->loadCoreAndStandardHelpers();
+    $_escaping = $this->getEscaping();
+    if ($_escaping === false || $_escaping === 'bc')
+    {
+      $vars = $this->attributeHolder->getAll();
+      extract($vars);
+    }
+    if ($_escaping !== false)
+    {
+      $sf_data = sfOutputEscaper::escape($this->getEscapingMethod(), $this->attributeHolder->getAll());
+      if ($_escaping === 'both')
+      {
+        foreach ($sf_data as $_key => $_value)
+        {
+          ${$_key} = $_value;
+        }
+      }
+    }
+        ob_start();
+    ob_implicit_flush(0);
+    require($_sfFile);
+    return ob_get_clean();
+  }
+  public function getEngine()
+  {
+    return null;
+  }
+  public function configure()
+  {
+        $actionStackEntry = $this->getContext()->getActionStack()->getLastEntry();
+    if (!$actionStackEntry->getViewInstance())
+    {
+      $actionStackEntry->setViewInstance($this);
+    }
+        $viewConfigFile = $this->moduleName.'/'.sfConfig::get('sf_app_module_config_dir_name').'/view.yml';
+    require(sfConfigCache::getInstance()->checkConfig(sfConfig::get('sf_app_module_dir_name').'/'.$viewConfigFile));
+        if (!$this->directory)
+    {
+      $this->setDirectory(sfLoader::getTemplateDir($this->moduleName, $this->getTemplate()));
+    }
+  }
+  protected function decorate($content)
+  {
+    $template = $this->getDecoratorDirectory().'/'.$this->getDecoratorTemplate();
+    if (sfConfig::get('sf_logging_enabled'))
+    {
+      $this->getContext()->getLogger()->info('{sfView} decorate content with "'.$template.'"');
+    }
+        $this->attributeHolder->set('sf_content', $content);
+        $this->attributeHolder->set('content', $content);
+        $retval = $this->renderFile($template);
+    return $retval;
+  }
+  public function render($templateVars = null)
+  {
+    $context = $this->getContext();
+        $mode = $context->getController()->getRenderMode();
+    if ($mode == sfView::RENDER_NONE)
+    {
+      return null;
+    }
+    $retval = null;
+    $response = $context->getResponse();
+    if (sfConfig::get('sf_cache'))
+    {
+      $key   = $response->getParameterHolder()->remove('current_key', 'symfony/cache/current');
+      $cache = $response->getParameter($key, null, 'symfony/cache');
+      if ($cache !== null)
+      {
+        $cache  = unserialize($cache);
+        $retval = $cache['content'];
+        $vars   = $cache['vars'];
+        $response->mergeProperties($cache['response']);
+      }
+    }
+        $layout = $response->getParameter($this->moduleName.'_'.$this->actionName.'_layout', null, 'symfony/action/view');
+    if (false === $layout)
+    {
+      $this->setDecorator(false);
+    }
+    else if (null !== $layout)
+    {
+      $this->setDecoratorTemplate($layout.$this->getExtension());
+    }
+        if ($templateVars === null)
+    {
+      $actionInstance   = $context->getActionStack()->getLastEntry()->getActionInstance();
+      $templateVars     = $actionInstance->getVarHolder()->getAll();
+    }
+        $this->attributeHolder->add($this->getGlobalVars());
+    $this->attributeHolder->add($retval !== null ? $vars : $templateVars);
+        if ($retval === null)
+    {
+            $this->preRenderCheck();
+            $template = $this->getDirectory().'/'.$this->getTemplate();
+      $retval = $this->renderFile($template);
+      if (sfConfig::get('sf_cache') && $key !== null)
+      {
+        $cache = array(
+          'content'   => $retval,
+          'vars'      => $templateVars,
+          'view_name' => $this->viewName,
+          'response'  => $context->getResponse(),
+        );
+        $response->setParameter($key, serialize($cache), 'symfony/cache');
+        if (sfConfig::get('sf_web_debug'))
+        {
+          $retval = sfWebDebug::getInstance()->decorateContentWithDebug($key, $retval, true);
+        }
+      }
+    }
+        if ($this->isDecorator())
+    {
+      $retval = $this->decorate($retval);
+    }
+        if ($mode == sfView::RENDER_CLIENT)
+    {
+      $context->getResponse()->setContent($retval);
+    }
+    return $retval;
+  }
+}
+
+
+abstract class sfOutputEscaper
+{
+  protected $value;
+  protected $escapingMethod;
+  public function __construct($escapingMethod, $value)
+  {
+    $this->value          = $value;
+    $this->escapingMethod = $escapingMethod;
+  }
+  public static function escape($escapingMethod, $value)
+  {
+    if (is_null($value) || ($value === false) || ($escapingMethod === 'esc_raw'))
+    {
+      return $value;
+    }
+        if (is_scalar($value))
+    {
+      return call_user_func($escapingMethod, $value);
+    }
+    if (is_array($value))
+    {
+      return new sfOutputEscaperArrayDecorator($escapingMethod, $value);
+    }
+    if (is_object($value))
+    {
+      if ($value instanceof sfOutputEscaper)
+      {
+                $copy = clone $value;
+        $copy->escapingMethod = $escapingMethod;
+        return $copy;
+      }
+      elseif ($value instanceof Traversable)
+      {
+        return new sfOutputEscaperIteratorDecorator($escapingMethod, $value);
+      }
+      else
+      {
+        return new sfOutputEscaperObjectDecorator($escapingMethod, $value);
+      }
+    }
+        throw new sfException(sprintf('Unable to escape value "%s"', print_r($value, true)));
+  }
+  public function getRawValue()
+  {
+    return $this->value;
+  }
+  public function __get($var)
+  {
+    return $this->escape($this->escapingMethod, $this->value->$var);
+  }
+}
+
+
+if (!interface_exists('Countable', false))
+{
+  interface Countable
+  {
+    public function count();
+  }
+}
+class sfOutputEscaperArrayDecorator extends sfOutputEscaperGetterDecorator implements Iterator, ArrayAccess, Countable
+{
+  private $count;
+  public function rewind()
+  {
+    reset($this->value);
+    $this->count = count($this->value);
+  }
+  public function key()
+  {
+    return key($this->value);
+  }
+  public function current()
+  {
+    return sfOutputEscaper::escape($this->escapingMethod, current($this->value));
+  }
+  public function next()
+  {
+    next($this->value);
+    $this->count --;
+  }
+  public function valid()
+  {
+    return $this->count > 0;
+  }
+  public function offsetExists($offset)
+  {
+    return array_key_exists($offset, $this->value);
+  }
+  public function offsetGet($offset)
+  {
+    return sfOutputEscaper::escape($this->escapingMethod, $this->value[$offset]);
+  }
+  public function offsetSet($offset, $value)
+  {
+    throw new sfException('Cannot set values.');
+  }
+  public function offsetUnset($offset)
+  {
+    throw new sfException('Cannot unset values.');
+  }
+  public function count()
+  {
+    return count($this->value);
+  }
+  public function getRaw($key)
+  {
+    return $this->value[$key];
+  }
+}
+
+
+abstract class sfOutputEscaperGetterDecorator extends sfOutputEscaper
+{
+  public abstract function getRaw($key);
+  public function get($key, $escapingMethod = null)
+  {
+    if (!$escapingMethod)
+    {
+      $escapingMethod = $this->escapingMethod;
+    }
+    return sfOutputEscaper::escape($escapingMethod, $this->getRaw($key));
+  }
+}
+
+
+class sfOutputEscaperIteratorDecorator extends sfOutputEscaperObjectDecorator implements Iterator, Countable, ArrayAccess
+{
+  private $iterator;
+  public function __construct($escapingMethod, Traversable $value)
+  {
+    parent::__construct($escapingMethod, $value);
+    $this->iterator = new IteratorIterator($value);
+  }
+  public function rewind()
+  {
+    return $this->iterator->rewind();
+  }
+  public function current()
+  {
+    return sfOutputEscaper::escape($this->escapingMethod, $this->iterator->current());
+  }
+  public function key()
+  {
+    return $this->iterator->key();
+  }
+  public function next()
+  {
+    return $this->iterator->next();
+  }
+  public function valid()
+  {
+    return $this->iterator->valid();
+  }
+  public function offsetExists($offset)
+  {
+    return array_key_exists($offset, $this->value);
+  }
+  public function offsetGet($offset)
+  {
+    return sfOutputEscaper::escape($this->escapingMethod, $this->value[$offset]);
+  }
+  public function offsetSet($offset, $value)
+  {
+    throw new sfException('Cannot set values.');
+  }
+  public function offsetUnset($offset)
+  {
+    throw new sfException('Cannot unset values.');
+  }
+  public function count()
+  {
+    return count($this->value);
+  }
+}
+
+
+class sfOutputEscaperObjectDecorator extends sfOutputEscaperGetterDecorator
+{
+  public function __call($method, $args)
+  {
+    if (count($args) > 0)
+    {
+      $escapingMethod = $args[count($args) - 1];
+      if (is_string($escapingMethod) && substr($escapingMethod, 0, 4) === 'esc_')
+      {
+        array_pop($args);
+      }
+      else
+      {
+        $escapingMethod = $this->escapingMethod;
+      }
+    }
+    else
+    {
+      $escapingMethod = $this->escapingMethod;
+    }
+    $value = call_user_func_array(array($this->value, $method), $args);
+    return sfOutputEscaper::escape($escapingMethod, $value);
+  }
+  public function getRaw($key)
+  {
+    if (!is_callable(array($this->value, 'get')))
+    {
+      throw new sfException('Object does not have a callable get() method.');
+    }
+    return $this->value->get($key);
+  }
+  public function __toString()
+  {
+    return $this->escape($this->escapingMethod, $this->value->__toString());
+  }
+}
+
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/cache/platform/prod/config/config_databases.yml.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/cache/platform/prod/config/config_databases.yml.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/cache/platform/prod/config/config_databases.yml.php	(revision 19)
@@ -0,0 +1,11 @@
+<?php
+// auto-generated by sfDatabaseConfigHandler
+// date: 2014/05/07 16:15:25
+
+$database = new sfPropel13Database();
+$database->initialize(array (
+  'dsn' => 'mysql:dbname=tvtl;host=127.0.0.1',
+  'username' => 'root',
+  'password' => 123456,
+), 'propel');
+$this->databases['propel'] = $database;
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/cache/platform/prod/config/config_factories.yml.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/cache/platform/prod/config/config_factories.yml.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/cache/platform/prod/config/config_factories.yml.php	(revision 19)
@@ -0,0 +1,29 @@
+<?php
+// auto-generated by sfFactoryConfigHandler
+// date: 2014/05/07 16:15:25
+
+  $this->controller = sfController::newInstance(sfConfig::get('sf_factory_controller', 'sfFrontWebController'));
+  $this->request = sfRequest::newInstance(sfConfig::get('sf_factory_request', 'sfWebRequest'));
+  $this->response = sfResponse::newInstance(sfConfig::get('sf_factory_response', 'sfWebResponse'));
+  $this->storage = sfStorage::newInstance(sfConfig::get('sf_factory_storage', 'sfDatabaseSessionStorage'));
+  $this->user = sfUser::newInstance(sfConfig::get('sf_factory_user', 'sfMyUser'));
+  $this->controller->initialize($this);
+  $this->request->initialize($this, sfConfig::get('sf_factory_request_parameters', NULL), sfConfig::get('sf_factory_request_attributes', array()));
+  $this->response->initialize($this, sfConfig::get('sf_factory_response_parameters', NULL));
+  $this->storage->initialize($this, sfConfig::get('sf_factory_storage_parameters', array (
+  'session_name' => 'symfony',
+  'session_dsn' => 'mysql:dbname=sessions;host=127.0.0.1',
+  'session_user' => 'sessionuser',
+  'session_password' => 'sessionpassword',
+)));
+  $this->user->initialize($this, sfConfig::get('sf_factory_user_parameters', NULL));
+
+  if (sfConfig::get('sf_cache'))
+  {
+    $this->viewCacheManager = new sfViewCacheManager();
+    $this->viewCacheManager->initialize($this, sfConfig::get('sf_factory_view_cache', 'sfFileCache'), sfConfig::get('sf_factory_view_cache_parameters', array (
+  'automaticCleaningFactor' => 0,
+  'cacheDir' => '/home/www/cache/platform/prod/template',
+)));
+ }
+
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/cache/platform/prod/config/config_i18n.yml.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/cache/platform/prod/config/config_i18n.yml.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/cache/platform/prod/config/config_i18n.yml.php	(revision 19)
@@ -0,0 +1,11 @@
+<?php
+// auto-generated by sfDefineEnvironmentConfigHandler
+// date: 2014/05/07 16:15:25
+sfConfig::add(array(
+  'sf_i18n_default_culture' => 'en',
+  'sf_i18n_source' => 'XLIFF',
+  'sf_i18n_debug' => false,
+  'sf_i18n_cache' => true,
+  'sf_i18n_untranslated_prefix' => '[T]',
+  'sf_i18n_untranslated_suffix' => '[/T]',
+));
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/cache/platform/prod/config/config_logging.yml.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/cache/platform/prod/config/config_logging.yml.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/cache/platform/prod/config/config_logging.yml.php	(revision 19)
@@ -0,0 +1,11 @@
+<?php
+// auto-generated by sfDefineEnvironmentConfigHandler
+// date: 2014/05/07 16:15:25
+sfConfig::add(array(
+  'sf_logging_enabled' => false,
+  'sf_logging_level' => 'err',
+  'sf_logging_rotate' => true,
+  'sf_logging_period' => 7,
+  'sf_logging_history' => 10,
+  'sf_logging_purge' => false,
+));
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/cache/platform/prod/config/config_php.yml.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/cache/platform/prod/config/config_php.yml.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/cache/platform/prod/config/config_php.yml.php	(revision 19)
@@ -0,0 +1,21 @@
+<?php
+// auto-generated by sfPhpConfigHandler
+// date: 2014/05/07 16:15:25
+ini_set('magic_quotes_runtime', '');
+ini_set('log_errors', '1');
+ini_set('arg_separator.output', '&amp;');
+if (ini_get('magic_quotes_gpc') != false)
+{
+  sfLogger::getInstance()->warning('{sfPhpConfigHandler} php.ini "magic_quotes_gpc" key is better set to "false" (current value is "\'\'" - php.ini location: "/etc/php.ini").');
+}
+
+if (ini_get('register_globals') != false)
+{
+  sfLogger::getInstance()->warning('{sfPhpConfigHandler} php.ini "register_globals" key is better set to "false" (current value is "\'\'" - php.ini location: "/etc/php.ini").');
+}
+
+if (ini_get('session.auto_start') != false)
+{
+  sfLogger::getInstance()->warning('{sfPhpConfigHandler} php.ini "session.auto_start" key is better set to "false" (current value is "\'0\'" - php.ini location: "/etc/php.ini").');
+}
+
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/cache/platform/prod/config/config_routing.yml.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/cache/platform/prod/config/config_routing.yml.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/cache/platform/prod/config/config_routing.yml.php	(revision 19)
@@ -0,0 +1,92 @@
+<?php
+// auto-generated by sfRoutingConfigHandler
+// date: 2014/05/07 16:15:25
+$routes = sfRouting::getInstance();
+$routes->setRoutes(
+array (
+  'homepage' => 
+  array (
+    0 => '/',
+    1 => '/^[\\/]*$/',
+    2 => 
+    array (
+    ),
+    3 => 
+    array (
+    ),
+    4 => 
+    array (
+      'module' => 'default',
+      'action' => 'index',
+    ),
+    5 => 
+    array (
+    ),
+    6 => '',
+  ),
+  'default_symfony' => 
+  array (
+    0 => '/symfony/:action/*',
+    1 => '#^/symfony(?:\\/([^\\/]+))?(?:\\/(.*))?$#',
+    2 => 
+    array (
+      0 => 'action',
+    ),
+    3 => 
+    array (
+      'action' => 1,
+    ),
+    4 => 
+    array (
+      'module' => 'default',
+    ),
+    5 => 
+    array (
+    ),
+    6 => '',
+  ),
+  'default_index' => 
+  array (
+    0 => '/:module',
+    1 => '#^(?:\\/([^\\/]+))?$#',
+    2 => 
+    array (
+      0 => 'module',
+    ),
+    3 => 
+    array (
+      'module' => 1,
+    ),
+    4 => 
+    array (
+      'action' => 'index',
+    ),
+    5 => 
+    array (
+    ),
+    6 => '',
+  ),
+  'default' => 
+  array (
+    0 => '/:module/:action/*',
+    1 => '#^(?:\\/([^\\/]+))?(?:\\/([^\\/]+))?(?:\\/(.*))?$#',
+    2 => 
+    array (
+      0 => 'module',
+      1 => 'action',
+    ),
+    3 => 
+    array (
+      'module' => 1,
+      'action' => 1,
+    ),
+    4 => 
+    array (
+    ),
+    5 => 
+    array (
+    ),
+    6 => '',
+  ),
+)
+);
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/cache/platform/prod/config/config_settings.yml.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/cache/platform/prod/config/config_settings.yml.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/cache/platform/prod/config/config_settings.yml.php	(revision 19)
@@ -0,0 +1,61 @@
+<?php
+// auto-generated by sfDefineEnvironmentConfigHandler
+// date: 2014/05/07 16:15:25
+sfConfig::add(array(
+  'sf_default_module' => 'default',
+  'sf_default_action' => 'index',
+  'sf_error_404_module' => 'default',
+  'sf_error_404_action' => 'error404',
+  'sf_login_module' => 'default',
+  'sf_login_action' => 'login',
+  'sf_secure_module' => 'default',
+  'sf_secure_action' => 'secure',
+  'sf_module_disabled_module' => 'default',
+  'sf_module_disabled_action' => 'disabled',
+  'sf_unavailable_module' => 'default',
+  'sf_unavailable_action' => 'unavailable',
+  'sf_available' => true,
+  'sf_use_database' => true,
+  'sf_use_security' => true,
+  'sf_use_flash' => true,
+  'sf_i18n' => false,
+  'sf_check_symfony_version' => false,
+  'sf_use_process_cache' => true,
+  'sf_compressed' => false,
+  'sf_check_lock' => false,
+  'sf_escaping_strategy' => 'bc',
+  'sf_escaping_method' => 'ESC_ENTITIES',
+  'sf_suffix' => '.',
+  'sf_no_script_name' => false,
+  'sf_validation_error_prefix' => ' &darr;&nbsp;',
+  'sf_validation_error_suffix' => ' &nbsp;&darr;',
+  'sf_validation_error_class' => 'form_error',
+  'sf_validation_error_id_prefix' => 'error_for_',
+  'sf_cache' => false,
+  'sf_etag' => true,
+  'sf_lazy_cache_key' => true,
+  'sf_web_debug' => false,
+  'sf_error_reporting' => 341,
+  'sf_rich_text_js_dir' => 'js/tiny_mce',
+  'sf_prototype_web_dir' => '/sf/prototype',
+  'sf_admin_web_dir' => '/sf/sf_admin',
+  'sf_web_debug_web_dir' => '/sf/sf_web_debug',
+  'sf_calendar_web_dir' => '/sf/calendar',
+  'sf_standard_helpers' => array (
+  0 => 'Partial',
+  1 => 'Cache',
+  2 => 'Form',
+),
+  'sf_enabled_modules' => array (
+  0 => 'default',
+),
+  'sf_charset' => 'utf-8',
+  'sf_strip_comments' => true,
+  'sf_autoloading_functions' => NULL,
+  'sf_timeout' => 1800,
+  'sf_max_forwards' => 5,
+  'sf_path_info_array' => 'SERVER',
+  'sf_path_info_key' => 'PATH_INFO',
+  'sf_url_format' => 'PATH',
+  'sf_orm' => 'propel',
+));
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/cache/platform/prod/config/modules_default_config_filters.yml.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/cache/platform/prod/config/modules_default_config_filters.yml.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/cache/platform/prod/config/modules_default_config_filters.yml.php	(revision 19)
@@ -0,0 +1,43 @@
+<?php
+// auto-generated by sfFilterConfigHandler
+// date: 2014/05/07 16:26:20
+
+list($class, $parameters) = (array) sfConfig::get('sf_rendering_filter', array('sfRenderingFilter', array (
+)));
+$filter = new $class();
+$filter->initialize($this->context, $parameters);
+$filterChain->register($filter);
+
+// does this action require security?
+if ($actionInstance->isSecure())
+{
+  if (!in_array('sfSecurityUser', class_implements($this->context->getUser())))
+  {
+    $error = 'Security is enabled, but your sfUser implementation does not implement sfSecurityUser interface';
+    throw new sfSecurityException($error);
+  }
+  
+list($class, $parameters) = (array) sfConfig::get('sf_security_filter', array('sfBasicSecurityFilter', array (
+)));
+$filter = new $class();
+$filter->initialize($this->context, $parameters);
+$filterChain->register($filter);
+}
+
+list($class, $parameters) = (array) sfConfig::get('sf_common_filter', array('sfCommonFilter', null));
+$filter = new $class();
+$filter->initialize($this->context, $parameters);
+$filterChain->register($filter);
+
+list($class, $parameters) = (array) sfConfig::get('sf_flash_filter', array('sfFlashFilter', array (
+)));
+$filter = new $class();
+$filter->initialize($this->context, $parameters);
+$filterChain->register($filter);
+
+list($class, $parameters) = (array) sfConfig::get('sf_execution_filter', array('sfExecutionFilter', array (
+)));
+$filter = new $class();
+$filter->initialize($this->context, $parameters);
+$filterChain->register($filter);
+
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/cache/platform/prod/config/modules_default_config_module.yml.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/cache/platform/prod/config/modules_default_config_module.yml.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/cache/platform/prod/config/modules_default_config_module.yml.php	(revision 19)
@@ -0,0 +1,8 @@
+<?php
+// auto-generated by sfDefineEnvironmentConfigHandler
+// date: 2014/05/07 16:26:20
+sfConfig::add(array(
+  'mod_'.strtolower($moduleName).'_enabled' => true,
+  'mod_'.strtolower($moduleName).'_view_class' => 'sfPHP',
+  'mod_'.strtolower($moduleName).'_is_internal' => false,
+));
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/cache/platform/prod/config/modules_default_config_security.yml.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/cache/platform/prod/config/modules_default_config_security.yml.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/cache/platform/prod/config/modules_default_config_security.yml.php	(revision 19)
@@ -0,0 +1,9 @@
+<?php
+// auto-generated by sfSecurityConfigHandler
+// date: 2014/05/07 16:26:20
+$this->security = array (
+  'all' => 
+  array (
+    'is_secure' => false,
+  ),
+);
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/cache/platform/prod/config/modules_default_config_view.yml.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/cache/platform/prod/config/modules_default_config_view.yml.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/cache/platform/prod/config/modules_default_config_view.yml.php	(revision 19)
@@ -0,0 +1,22 @@
+<?php
+// auto-generated by sfViewConfigHandler
+// date: 2014/05/07 16:26:20
+$context  = $this->getContext();
+$response = $context->getResponse();
+
+
+  $templateName = $response->getParameter($this->moduleName.'_'.$this->actionName.'_template', $this->actionName, 'symfony/action/view');
+  $this->setTemplate($templateName.$this->viewName.$this->getExtension());
+
+
+
+  $response->addHttpMeta('content-type', 'text/html', false);
+  $response->addMeta('title', 'symfony project', false, false);
+  $response->addMeta('robots', 'index, follow', false, false);
+  $response->addMeta('description', 'symfony project', false, false);
+  $response->addMeta('keywords', 'symfony, project', false, false);
+  $response->addMeta('language', 'en', false, false);
+
+  $response->addStylesheet('main', '', array ());
+
+
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/cache/platform/prod/config/modules_space_config_filters.yml.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/cache/platform/prod/config/modules_space_config_filters.yml.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/cache/platform/prod/config/modules_space_config_filters.yml.php	(revision 19)
@@ -0,0 +1,43 @@
+<?php
+// auto-generated by sfFilterConfigHandler
+// date: 2014/05/07 16:15:25
+
+list($class, $parameters) = (array) sfConfig::get('sf_rendering_filter', array('sfRenderingFilter', array (
+)));
+$filter = new $class();
+$filter->initialize($this->context, $parameters);
+$filterChain->register($filter);
+
+// does this action require security?
+if ($actionInstance->isSecure())
+{
+  if (!in_array('sfSecurityUser', class_implements($this->context->getUser())))
+  {
+    $error = 'Security is enabled, but your sfUser implementation does not implement sfSecurityUser interface';
+    throw new sfSecurityException($error);
+  }
+  
+list($class, $parameters) = (array) sfConfig::get('sf_security_filter', array('sfBasicSecurityFilter', array (
+)));
+$filter = new $class();
+$filter->initialize($this->context, $parameters);
+$filterChain->register($filter);
+}
+
+list($class, $parameters) = (array) sfConfig::get('sf_common_filter', array('sfCommonFilter', null));
+$filter = new $class();
+$filter->initialize($this->context, $parameters);
+$filterChain->register($filter);
+
+list($class, $parameters) = (array) sfConfig::get('sf_flash_filter', array('sfFlashFilter', array (
+)));
+$filter = new $class();
+$filter->initialize($this->context, $parameters);
+$filterChain->register($filter);
+
+list($class, $parameters) = (array) sfConfig::get('sf_execution_filter', array('sfExecutionFilter', array (
+)));
+$filter = new $class();
+$filter->initialize($this->context, $parameters);
+$filterChain->register($filter);
+
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/cache/platform/prod/config/modules_space_config_module.yml.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/cache/platform/prod/config/modules_space_config_module.yml.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/cache/platform/prod/config/modules_space_config_module.yml.php	(revision 19)
@@ -0,0 +1,8 @@
+<?php
+// auto-generated by sfDefineEnvironmentConfigHandler
+// date: 2014/05/07 16:15:25
+sfConfig::add(array(
+  'mod_'.strtolower($moduleName).'_enabled' => true,
+  'mod_'.strtolower($moduleName).'_view_class' => 'sfPHP',
+  'mod_'.strtolower($moduleName).'_is_internal' => false,
+));
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/cache/platform/prod/config/modules_space_config_security.yml.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/cache/platform/prod/config/modules_space_config_security.yml.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/cache/platform/prod/config/modules_space_config_security.yml.php	(revision 19)
@@ -0,0 +1,9 @@
+<?php
+// auto-generated by sfSecurityConfigHandler
+// date: 2014/05/07 16:15:25
+$this->security = array (
+  'all' => 
+  array (
+    'is_secure' => false,
+  ),
+);
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/cache/platform/prod/config/modules_space_config_view.yml.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/cache/platform/prod/config/modules_space_config_view.yml.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/cache/platform/prod/config/modules_space_config_view.yml.php	(revision 19)
@@ -0,0 +1,22 @@
+<?php
+// auto-generated by sfViewConfigHandler
+// date: 2014/05/07 16:15:25
+$context  = $this->getContext();
+$response = $context->getResponse();
+
+
+  $templateName = $response->getParameter($this->moduleName.'_'.$this->actionName.'_template', $this->actionName, 'symfony/action/view');
+  $this->setTemplate($templateName.$this->viewName.$this->getExtension());
+
+
+
+  $response->addHttpMeta('content-type', 'text/html', false);
+  $response->addMeta('title', 'symfony project', false, false);
+  $response->addMeta('robots', 'index, follow', false, false);
+  $response->addMeta('description', 'symfony project', false, false);
+  $response->addMeta('keywords', 'symfony, project', false, false);
+  $response->addMeta('language', 'en', false, false);
+
+  $response->addStylesheet('main', '', array ());
+
+
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/cache/platform/prod/config/modules_user_config_filters.yml.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/cache/platform/prod/config/modules_user_config_filters.yml.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/cache/platform/prod/config/modules_user_config_filters.yml.php	(revision 19)
@@ -0,0 +1,43 @@
+<?php
+// auto-generated by sfFilterConfigHandler
+// date: 2014/05/07 16:26:26
+
+list($class, $parameters) = (array) sfConfig::get('sf_rendering_filter', array('sfRenderingFilter', array (
+)));
+$filter = new $class();
+$filter->initialize($this->context, $parameters);
+$filterChain->register($filter);
+
+// does this action require security?
+if ($actionInstance->isSecure())
+{
+  if (!in_array('sfSecurityUser', class_implements($this->context->getUser())))
+  {
+    $error = 'Security is enabled, but your sfUser implementation does not implement sfSecurityUser interface';
+    throw new sfSecurityException($error);
+  }
+  
+list($class, $parameters) = (array) sfConfig::get('sf_security_filter', array('sfBasicSecurityFilter', array (
+)));
+$filter = new $class();
+$filter->initialize($this->context, $parameters);
+$filterChain->register($filter);
+}
+
+list($class, $parameters) = (array) sfConfig::get('sf_common_filter', array('sfCommonFilter', null));
+$filter = new $class();
+$filter->initialize($this->context, $parameters);
+$filterChain->register($filter);
+
+list($class, $parameters) = (array) sfConfig::get('sf_flash_filter', array('sfFlashFilter', array (
+)));
+$filter = new $class();
+$filter->initialize($this->context, $parameters);
+$filterChain->register($filter);
+
+list($class, $parameters) = (array) sfConfig::get('sf_execution_filter', array('sfExecutionFilter', array (
+)));
+$filter = new $class();
+$filter->initialize($this->context, $parameters);
+$filterChain->register($filter);
+
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/cache/platform/prod/config/modules_user_config_module.yml.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/cache/platform/prod/config/modules_user_config_module.yml.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/cache/platform/prod/config/modules_user_config_module.yml.php	(revision 19)
@@ -0,0 +1,8 @@
+<?php
+// auto-generated by sfDefineEnvironmentConfigHandler
+// date: 2014/05/07 16:26:26
+sfConfig::add(array(
+  'mod_'.strtolower($moduleName).'_enabled' => true,
+  'mod_'.strtolower($moduleName).'_view_class' => 'sfPHP',
+  'mod_'.strtolower($moduleName).'_is_internal' => false,
+));
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/cache/platform/prod/config/modules_user_config_security.yml.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/cache/platform/prod/config/modules_user_config_security.yml.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/cache/platform/prod/config/modules_user_config_security.yml.php	(revision 19)
@@ -0,0 +1,9 @@
+<?php
+// auto-generated by sfSecurityConfigHandler
+// date: 2014/05/07 16:26:26
+$this->security = array (
+  'all' => 
+  array (
+    'is_secure' => false,
+  ),
+);
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/check_configuration.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/check_configuration.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/check_configuration.php	(revision 19)
@@ -0,0 +1,107 @@
+<?php
+
+function is_cli()
+{
+  return !isset($_SERVER['HTTP_HOST']);
+}
+
+/**
+ * Checks a configuration.
+ */
+function check($boolean, $message, $help = '', $fatal = false)
+{
+  echo $boolean ? "  OK        " : sprintf("[[%s]] ", $fatal ? ' ERROR ' : 'WARNING');
+  echo sprintf("$message%s\n", $boolean ? '' : ': FAILED');
+
+  if (!$boolean)
+  {
+    echo "            *** $help ***\n";
+    if ($fatal)
+    {
+      die("You must fix this problem before resuming the check.\n");
+    }
+  }
+}
+
+/**
+ * Gets the php.ini path used by the current PHP interpretor.
+ *
+ * @return string the php.ini path
+ */
+function get_ini_path()
+{
+  if ($path = get_cfg_var('cfg_file_path'))
+  {
+    return $path;
+  }
+
+  return 'WARNING: not using a php.ini file';
+}
+
+if (!is_cli())
+{
+  echo '<html><body><pre>';
+}
+
+echo "********************************\n";
+echo "*                              *\n";
+echo "*  symfony requirements check  *\n";
+echo "*                              *\n";
+echo "********************************\n\n";
+
+echo sprintf("php.ini used by PHP: %s\n\n", get_ini_path());
+
+if (is_cli())
+{
+  echo "** WARNING **\n";
+  echo "*  The PHP CLI can use a different php.ini file\n";
+  echo "*  than the one used with your web server.\n";
+  if ('\\' == DIRECTORY_SEPARATOR)
+  {
+    echo "*  (especially on the Windows platform)\n";
+  }
+  echo "*  If this is the case, please launch this\n";
+  echo "*  utility from your web server.\n";
+  echo "** WARNING **\n";
+}
+
+// mandatory
+echo "\n** Mandatory requirements **\n\n";
+check(version_compare(phpversion(), '5.2.4', '>='), sprintf('PHP version is at least 5.2.4 (%s)', phpversion()), 'Current version is '.phpversion(), true);
+
+// warnings
+echo "\n** Optional checks **\n\n";
+check(class_exists('PDO'), 'PDO is installed', 'Install PDO (mandatory for Propel and Doctrine)', false);
+if (class_exists('PDO'))
+{
+  $drivers = PDO::getAvailableDrivers();
+  check(count($drivers), 'PDO has some drivers installed: '.implode(', ', $drivers), 'Install PDO drivers (mandatory for Propel and Doctrine)');
+}
+check(class_exists('DomDocument'), 'PHP-XML module is installed', 'Install and enable the php-xml module (required by Propel)', false);
+check(class_exists('XSLTProcessor'), 'XSL module is installed', 'Install and enable the XSL module (recommended for Propel)', false);
+check(function_exists('token_get_all'), 'The token_get_all() function is available', 'Install and enable the Tokenizer extension (highly recommended)', false);
+check(function_exists('mb_strlen'), 'The mb_strlen() function is available', 'Install and enable the mbstring extension', false);
+check(function_exists('iconv'), 'The iconv() function is available', 'Install and enable the iconv extension', false);
+check(function_exists('utf8_decode'), 'The utf8_decode() is available', 'Install and enable the XML extension', false);
+check(function_exists('posix_isatty'), 'The posix_isatty() is available', 'Install and enable the php_posix extension (used to colorized the CLI output)', false);
+
+$accelerator = 
+  (function_exists('apc_store') && ini_get('apc.enabled'))
+  ||
+  function_exists('eaccelerator_put') && ini_get('eaccelerator.enable')
+  ||
+  function_exists('xcache_set')
+;
+check($accelerator, 'A PHP accelerator is installed', 'Install a PHP accelerator like APC (highly recommended)', false);
+
+check(!ini_get('short_open_tag'), 'php.ini has short_open_tag set to off', 'Set it to off in php.ini', false);
+check(!ini_get('magic_quotes_gpc'), 'php.ini has magic_quotes_gpc set to off', 'Set it to off in php.ini', false);
+check(!ini_get('register_globals'), 'php.ini has register_globals set to off', 'Set it to off in php.ini', false);
+check(!ini_get('session.auto_start'), 'php.ini has session.auto_start set to off', 'Set it to off in php.ini', false);
+
+check(version_compare(phpversion(), '5.2.9', '!='), 'PHP version is not 5.2.9', 'PHP 5.2.9 broke array_unique() and sfToolkit::arrayDeepMerge(). Use 5.2.10 instead [Ticket #6211]', false);
+
+if (!is_cli())
+{
+  echo '</pre></body></html>';
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/config/1.ini
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/config/1.ini	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/config/1.ini	(revision 19)
@@ -0,0 +1,44 @@
+propel.targetPackage       = lib.model
+propel.packageObjectModel  = true
+propel.project             = tvtl
+propel.database            = mysql
+propel.database.createUrl  = mysql://localhost/
+propel.database.url        = mysql://localhost/tvtl
+
+propel.addGenericAccessors = true
+propel.addGenericMutators  = true
+propel.addTimeStamp        = false
+
+propel.schema.validate     = false
+
+; directories
+propel.home                    = .
+propel.output.dir              = /srv/www/tvtl
+propel.schema.dir              = ${propel.output.dir}/config
+propel.conf.dir                = ${propel.output.dir}/config
+propel.phpconf.dir             = ${propel.output.dir}/config
+propel.sql.dir                 = ${propel.output.dir}/data/sql
+propel.runtime.conf.file       = runtime-conf.xml
+propel.php.dir                 = ${propel.output.dir}
+propel.default.schema.basename = schema
+propel.datadump.mapper.from    = *schema.xml
+propel.datadump.mapper.to      = *data.xml
+
+; builder settings
+propel.builder.peer.class              = plugins.sfPropel13Plugin.lib.propel.builder.SfPeerBuilder
+propel.builder.object.class            = plugins.sfPropel13Plugin.lib.propel.builder.SfObjectBuilder
+
+propel.builder.objectstub.class        = addon.propel.builder.SfExtensionObjectBuilder
+propel.builder.peerstub.class          = addon.propel.builder.SfExtensionPeerBuilder
+propel.builder.objectmultiextend.class = addon.propel.builder.SfMultiExtendObjectBuilder
+propel.builder.mapbuilder.class        = addon.propel.builder.SfMapBuilderBuilder
+propel.builder.interface.class         = propel.engine.builder.om.php5.PHP5InterfaceBuilder
+propel.builder.node.class              = propel.engine.builder.om.php5.PHP5NodeBuilder
+propel.builder.nodepeer.class          = propel.engine.builder.om.php5.PHP5NodePeerBuilder
+propel.builder.nodestub.class          = propel.engine.builder.om.php5.PHP5ExtensionNodeBuilder
+propel.builder.nodepeerstub.class      = propel.engine.builder.om.php5.PHP5ExtensionNodePeerBuilder
+
+propel.builder.addIncludes = false
+propel.builder.addComments = false
+
+propel.builder.addBehaviors = false 
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/config/1.xml
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/config/1.xml	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/config/1.xml	(revision 19)
@@ -0,0 +1,488 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<database defaultPhpNamingMethod="underscore" heavyIndexing="false" name="propel" defaultIdMethod="native" noXsd="true" package="lib.model">
+
+  <!-- 1. tblblog -->
+  <table skipSql="false" abstract="false" name="tblblog">
+    <column required="true"  name="bl_id" type="integer" autoIncrement="true" primaryKey="true"/>
+    <column required="true"  name="bl_shortname" type="varchar" size="255"/>
+    <column required="true"  name="bl_title" type="varchar" size="255"/>
+    <column required="true"  name="bl_user" type="integer"/>
+    <column required="true"  name="bl_module_config" type="longvarchar" lazyLoad="true"/>
+    <column required="true"  name="bl_category" type="longvarchar"/>
+    <column required="true"  name="bl_hit" type="integer" default="0"/>
+    <column required="true"  name="bl_type" type="tinyint" default="1"/>
+    <column required="true"  name="bl_active" type="tinyint" default="1"/>
+    <column required="true"  name="bl_lastupdate" type="timestamp"/>
+    <column required="false" name="bl_school" type="integer"/>
+    <column required="false" name="bl_pageviews" type="integer" default="0"/>
+    <column required="false" name="bl_host" type="varchar" size="255"/>
+    <column required="false" name="bl_commercial" type="tinyint" size="1"/>
+    <foreign-key foreignTable="tbluser">
+       <reference local="bl_user" foreign="us_id"/>
+    </foreign-key>
+  </table>
+
+  <!-- 2. tblblogcategory -->
+  <table skipSql="false" abstract="false" name="tblblogcategory">
+    <column required="true" name="cat_id" type="integer" autoIncrement="true" primaryKey="true" />
+    <column required="true" name="cat_blog" type="integer"/>
+    <column required="true" name="cat_parent" type="integer" />
+    <column required="true" name="cat_path" type="varchar" size="255"/>
+    <column required="true" name="cat_name" type="varchar" size="255"/>
+    <column required="true" name="cat_type" type="tinyint"/>
+    <column required="true" name="cat_public" type="integer" default="2"/>
+    <column required="true" name="cat_base" type="integer" default="0"/>
+    <column required="true" name="cat_config" type="longvarchar" lazyLoad="true"/>
+    <column required="true" name="cat_order" type="integer" default="0"/>
+    <foreign-key foreignTable="tblcategory">
+       <reference local="cat_base" foreign="cg_id"/>
+    </foreign-key>
+  </table>
+
+  <!-- 3. tblblogcategoryentry -->
+  <table skipSql="false" abstract="false" name="tblblogcategoryentry">
+    <column required="true"  name="ce_category" type="integer" primaryKey="true" />
+    <column required="true"  name="ce_entry" type="integer" primaryKey="true" />
+    <column required="true"  name="ce_modifydate" type="timestamp" />
+    <column required="true"  name="ce_hit" type="integer" default="0" />
+    <column required="true"  name="ce_score" type="double" default="0.0" />
+    <column required="true"  name="ce_status" type="tinyint" default="0" />
+    <column required="true"  name="ce_type" type="tinyint" default="2" />
+    <column required="false" name="ce_link" type="integer"/>
+    <column required="false" name="ce_creator" type="integer" default="0" />
+    <column required="false" name="ce_sender" type="integer" default="0" />
+    <column required="false" name="ce_title" type="varchar" size="255" default="0" />
+    <column required="false" name="ce_thumbnail" type="varchar" size="255" default="0" />
+    <foreign-key foreignTable="tblblogentry">
+       <reference local="ce_entry" foreign="entry_id"/>
+    </foreign-key>
+    <foreign-key foreignTable="tbluser">
+       <reference local="ce_sender" foreign="us_id"/>
+    </foreign-key>
+    <foreign-key foreignTable="tbldocument">
+       <reference local="ce_link" foreign="doc_id"/>
+    </foreign-key>
+    <foreign-key foreignTable="tblpresentation">
+       <reference local="ce_link" foreign="pr_id"/>
+    </foreign-key>
+  </table>
+
+  <!-- 4. tblblogcheckinfo -->
+  <table skipSql="false" abstract="false" name="tblblogcheckinfo">
+    <column required="true" name="ci_userid" type="integer" primaryKey="true"/>
+    <column required="true" name="ci_birthday" type="date"/>
+    <column required="true" name="ci_phone" type="varchar" size="30"/>
+    <column required="true" name="ci_pr" type="longvarchar"/>
+    <column required="true" name="ci_numberid" type="varchar" size="30"/>
+    <column required="true" name="ci_position" type="integer"/>
+    <column required="true" name="ci_school" type="integer"/>
+    <column required="true" name="ci_district" type="integer"/>
+    <column required="true" name="ci_province" type="integer"/>
+    <column required="true" name="ci_badge" type="varchar" size="30"/>
+    <column required="true" name="ci_subject" type="varchar" size="30"/>
+    <column required="true" name="ci_score" type="integer"/>
+    <foreign-key foreignTable="tbluser">
+       <reference local="ci_userid" foreign="us_id"/>
+    </foreign-key>
+  </table>
+
+   <!--tblblogdepends-->
+  <table skipSql="false" abstract="false" name="tblblogdepends">
+    <column primaryKey="true" name="dp_blog" type="integer" required="true"/>
+    <column primaryKey="true" name="dp_parent" type="integer" required="true"/>
+    <foreign-key foreignTable="tblblog">
+       <reference local="dp_blog" foreign="bl_id"/>
+    </foreign-key>
+  </table>
+
+  <!-- 6. tblblogentry -->
+  <table skipSql="false" abstract="false" name="tblblogentry">
+    <column required="true"  name="entry_id" type="integer" autoIncrement="true" primaryKey="true" />
+    <column required="true"  name="entry_user" type="integer" />
+    <column required="false" name="entry_link" type="integer" />
+    <column required="false" name="entry_title" type="varchar" size="255" />
+    <column required="false" name="entry_content" type="longvarchar" lazyLoad="true" />
+    <column required="true"  name="entry_createdate" type="timestamp" />
+    <column required="true"  name="entry_modifydate" type="timestamp" />
+    <column required="true"  name="entry_hit" type="integer" default="0" />
+    <column required="true"  name="entry_score" type="double" default="0.0" />
+    <column required="true"  name="entry_status" type="tinyint" default="0" />
+    <column required="true"  name="entry_category" type="integer" />
+    <column required="true"  name="entry_type" type="tinyint" default="2"/>
+    <column required="true"  name="entry_blog" type="integer" default="0"/>
+    <column required="false" name="entry_thumb" type="integer"/>
+    <column required="false" name="entry_like" type="integer" default="0" />
+    <column required="false" name="entry_likeinfo" type="varchar" size="255" />
+    <foreign-key foreignTable="tblpresentation">
+       <reference local="entry_link" foreign="pr_id"/>
+    </foreign-key>
+    <foreign-key foreignTable="tbldocument">
+       <reference local="entry_link" foreign="doc_id"/>
+    </foreign-key>
+    <foreign-key foreignTable="tblblogcategory">
+       <reference local="entry_category" foreign="cat_id"/>
+    </foreign-key>
+    <foreign-key foreignTable="tblblog">
+       <reference local="entry_blog" foreign="bl_id"/>
+    </foreign-key>
+    <foreign-key foreignTable="tbluser">
+       <reference local="entry_user" foreign="us_id"/>
+    </foreign-key>
+  </table>
+
+  <!-- 7. tblblogentrycomment -->
+  <table skipSql="false" abstract="false" name="tblblogentrycomment">
+    <column required="true"  name="cm_id" type="integer" autoIncrement="true" primaryKey="true" />
+    <column required="true"  name="cm_entry" type="integer" />
+    <column required="true"  name="cm_user" type="integer" />
+    <column required="true"  name="cm_date" type="timestamp" />
+    <column required="true"  name="cm_content" type="longvarchar" />
+    <column required="true"  name="cm_blog" type="integer" default="0" />
+    <column required="false" name="cm_user_info" type="varchar" size="255" />
+    <foreign-key foreignTable="tbluser">
+       <reference local="cm_user" foreign="us_id"/>
+    </foreign-key>
+    <foreign-key foreignTable="tblblogentry">
+       <reference local="cm_entry" foreign="entry_id"/>
+    </foreign-key>
+    <foreign-key foreignTable="tblblog">
+       <reference local="cm_blog" foreign="bl_id"/>
+    </foreign-key>
+  </table>
+
+  <!-- 8. tblblogentryinvalid -->
+  <table skipSql="false" abstract="false" name="tblblogentryinvalid">
+    <column required="false" name="ei_from" type="integer" />
+    <column required="false" name="ei_to" type="integer" />
+    <column required="true"  name="ei_entry" type="integer" primaryKey="true" />
+    <column required="false" name="ei_content" type="longvarchar" />
+    <column required="false" name="ei_blog" type="integer"/>
+    <column required="true"  name="ei_datesent" type="timestamp"/>
+  </table>
+
+  <!-- 9. tblblogentryscore -->
+  <table skipSql="false" abstract="false" name="tblblogentryscore">
+    <column required="true" name="score_entry" type="integer" primaryKey="true"/>
+    <column required="true" name="score_user" type="integer" primaryKey="true"/>
+    <column required="true" name="score_value" type="integer"/>
+  </table>
+
+  <!-- 10. tblbloghost -->
+  <table skipSql="false" abstract="false" name="tblbloghost">
+    <column name="bh_host" type="varchar" size="255" primaryKey="true"/>
+    <column name="bh_blogname" type="varchar" size="255"/>
+    <column name="bh_hostcode" type="char" size="2"/>
+  </table>
+
+  <!-- 11. tblblogpoll -->
+  <table skipSql="false" abstract="false" name="tblblogpoll">
+    <column required="true" name="poll_id" type="integer" autoIncrement="true" primaryKey="true"/>
+    <column required="true" name="poll_name" type="varchar"/>
+    <column required="true" name="poll_questions" type="longvarchar"/>
+    <column required="true" name="poll_type" type="tinyint"/>
+    <column required="true" name="poll_blog" type="integer"/>
+    <column required="true" name="poll_createdate" type="timestamp"/>
+    <column required="true" name="poll_active" type="tinyint"/>
+    <foreign-key foreignTable="tblblog">
+       <reference local="poll_blog" foreign="bl_id"/>
+    </foreign-key>
+   </table>
+
+  <!-- 12. tblblogpolldata -->
+  <table skipSql="false" abstract="false" name="tblblogpolldata">
+    <column required="true" name="pd_id" type="integer" autoIncrement="true" primaryKey="true"/>
+    <column required="true" name="pd_choice" type="integer"/>
+    <column required="true" name="pd_user" type="integer"/>
+    <column required="true" name="pd_ip" type="varchar"/>
+    <column required="true" name="pd_poll" type="integer"/>
+    <column required="true" name="pd_createdate" type="timestamp"/>
+    <foreign-key foreignTable="tblblogpoll">
+       <reference local="pd_poll" foreign="poll_id"/>
+    </foreign-key>
+   </table>
+
+  <!-- 13. tblblogschools -->
+  <table skipSql="false" abstract="false" name="tblblogschools">
+    <column required="true" name="sc_id" type="integer" autoIncrement="true" primaryKey="true"/>
+    <column required="true" name="sc_name" type="varchar"/>
+    <column required="true" name="sc_type" type="tinyint" size="1" default="2"/>
+    <column required="true" name="sc_parent" type="integer"/>
+    <column required="true" name="sc_approve" type="tinyint" default="0"/>
+    <column required="true" name="sc_phone" type="varchar" size="30"/>
+    <column required="true" name="sc_email" type="varchar" size="50"/>
+    <column required="true" name="sc_headmaster" type="varchar" size="50"/>
+    <column required="true" name="sc_taxcode" type="varchar" size="50"/>
+    <column required="true" name="sc_user" type="integer" default="0"/>
+  </table>
+
+  <!-- 14. tblblogstatday -->
+  <table skipSql="false" abstract="false" name="tblblogstatday">
+    <column name="std_blog" type="integer" required="true" primaryKey="true"/>
+    <column name="std_date" type="timestamp" required="true" primaryKey="true"/>
+    <column name="std_pageviews" type="integer" required="true"/>
+    <column name="std_visitors" type="integer" required="true"/>
+    <column name="std_blogtype" type="tinyint" required="false"/>
+    <column name="std_blogadmin" type="integer" required="false"/>
+  </table>
+
+  <!-- 15. tblbloguser -->
+  <table skipSql="false" abstract="false" name="tblbloguser">
+    <column required="true"  name="us_blog" type="integer" primaryKey="true" />
+    <column required="true"  name="us_user" type="integer" primaryKey="true" />
+    <column required="true"  name="us_role" type="integer" />
+    <column required="false" name="us_categories" type="varchar" size="255" />
+    <column required="true"  name="us_picture" type="varchar" size="255" />
+    <column required="true"  name="us_lastvisit" type="timestamp" />
+    <column required="true"  name="us_joindate" type="timestamp" />
+    <column required="false" name="us_fullname" type="varchar" size="255"/>
+    <column required="false" name="us_nickname" type="varchar" size="255"/>
+    <column required="false" name="us_email" type="varchar" size="255"/>
+    <column required="false" name="us_managecat" type="varchar" size="255" />
+    <foreign-key foreignTable="tbluser">
+       <reference local="us_user" foreign="us_id"/>
+    </foreign-key>
+  </table>
+
+  <!-- 16. tblblogusercheck -->
+  <table skipSql="false" abstract="false" name="tblblogusercheck">
+    <column required="true" name="uc_user" type="integer" primaryKey="true"/>
+    <column required="true" name="uc_checker" type="integer" primaryKey="true"/>
+    <column required="true" name="uc_approve" type="tinyint" default="0"/>
+    <column required="true" name="uc_checkdate" type="timestamp"/>
+    <foreign-key foreignTable="tbluser">
+       <reference local="uc_user" foreign="us_id"/>
+    </foreign-key>
+  </table>
+
+  <!-- 17. tblcategory -->
+  <table skipSql="false" abstract="false" name="tblcategory">
+    <column required="true"  name="cg_id" type="integer" autoIncrement="true" primaryKey="true"/>
+    <column required="true"  name="cg_name" type="varchar" size="30"/>
+    <column required="false" name="cg_parentid" type="integer"/>
+    <column required="false" name="cg_child" type="varchar" size="255"/>
+    <column required="false" name="cg_family" type="varchar" size="255"/>
+    <column required="false" name="cg_desc" type="varchar" size="255"/>
+    <column required="true"  name="cg_visited" type="integer" default="0"/>
+    <column required="false" name="cg_image" type="varchar" size="255"/>
+    <column required="false" name="cg_path" type="varchar" size="255"/>
+    <column required="false" name="cg_public" type="integer" default="null"/>
+    <column required="false" name="cg_sort" type="integer" default="null"/>
+  </table>
+
+  <!-- 18. tblcomplain -->
+  <table skipSql="false" abstract="false" name="tblcomplain">
+    <column required="true"  name="cp_id" type="integer" autoIncrement="true" primaryKey="true"/>
+    <column required="false" name="cp_user" type="integer"/>
+    <column required="false" name="cp_note" type="longvarchar"/>
+    <column required="false" name="cp_date" type="timestamp"/>
+    <column required="false" name="cp_solveduser" type="integer"/>
+    <column required="false" name="cp_solveddate" type="timestamp"/>
+    <column required="false" name="cp_category" type="integer"/>
+    <column required="false" name="cp_blog" type="integer"/>
+    <column required="false" name="cp_entry" type="integer"/>
+    <column required="false" name="cp_type" type="tinyint"/>
+    <column required="false" name="cp_solvedtype" type="tinyint"/>
+    <foreign-key foreignTable="tbluser">
+       <reference local="cp_user" foreign="us_id"/>
+    </foreign-key>
+  </table>
+
+  <!-- 19. tbldocument -->
+  <table skipSql="false" abstract="false" name="tbldocument">
+    <column required="true"  name="doc_id" type="integer" autoIncrement="true" primaryKey="true"/>
+    <column required="false" name="doc_category" type="integer"/>
+    <column required="false" name="doc_name" type="varchar" size="255"/>
+    <column required="false" name="doc_desc" type="longvarchar" lazyLoad="true"/>
+    <column required="true"  name="doc_source" type="varchar" size="255"/>
+    <column required="fasle" name="doc_keyword" type="varchar" size="255"/>
+    <column required="true"  name="doc_type" type="varchar" size="3"/>
+    <column required="true"  name="doc_filename" type="varchar" size="255"/>
+    <column required="false" name="doc_user" type="integer"/>
+    <column required="false" name="doc_date" type="timestamp"/>
+    <column required="true"  name="doc_hit" type="integer" default="0"/>
+    <column required="true"  name="doc_rating" type="integer" default="0"/>
+    <column required="false" name="doc_status" type="integer" default="0"/>
+    <column required="false" name="doc_width" type="integer" default="0"/>
+    <column required="false" name="doc_height" type="integer" default="0"/>
+    <column required="true"  name="doc_view" type="integer" default="0"/>
+    <column required="false" name="doc_manager" type="integer" default="0"/>
+    <column required="false" name="doc_report" type="integer" default="0"/>
+    <column required="false" name="doc_filesize" type="integer"/>
+    <column required="false" name="doc_thumbnail" type="tinyint" default="0"/>
+    <foreign-key foreignTable="tbluser">
+       <reference local="doc_user" foreign="us_id"/>
+    </foreign-key>
+  </table>
+
+  <!-- 20. tblpresentation -->
+  <table skipSql="false" abstract="false" name="tblpresentation">
+    <column required="true"  name="pr_id" type="integer" autoIncrement="true" primaryKey="true"/>
+    <column required="false" name="pr_category" type="integer"/>
+    <column required="false" name="pr_name" type="varchar" size="255"/>
+    <column required="true"  name="pr_source" type="varchar" size="255"/>
+    <column required="false" name="pr_keyword" type="varchar" size="255"/>
+    <column required="true"  name="pr_type" type="varchar" size="3"/>
+    <column required="true"  name="pr_filename" type="varchar" size="255"/>
+    <column required="false" name="pr_user" type="integer"/>
+    <column required="false" name="pr_slides" type="integer" default="0"/>
+    <column required="false" name="pr_date" type="timestamp"/>
+    <column required="true"  name="pr_hit" type="integer" default="0"/>
+    <column required="true"  name="pr_rating" type="integer" default="0"/>
+    <column required="false" name="pr_status" type="integer" default="0"/>
+    <column required="false" name="pr_playername" type="longvarchar"/>
+    <column required="false" name="pr_content" type="longvarchar" lazyLoad="true"/>
+    <column required="false" name="pr_view" type="integer" default="0"/>
+    <column required="false" name="pr_manager" type="integer" default="0"/>
+    <column required="false" name="pr_report" type="integer" default="0"/>
+    <column required="false" name="pr_filesize" type="integer" default="0"/>
+    <column required="false" name="pr_thumbnail" type="tinyint" default="0"/>
+    <foreign-key foreignTable="tbluser">
+      <reference local="pr_user" foreign="us_id"/>
+    </foreign-key>
+  </table>
+
+  <!-- 21. tbluser -->
+  <table skipSql="false" abstract="false" name="tbluser">
+    <column required="true"  name="us_id" type="integer" autoIncrement="true" primaryKey="true"/>
+    <column required="false" name="us_username" type="varchar" size="30"/>
+    <column required="false" name="us_password" type="varchar" size="50"/>
+    <column required="true"  name="us_firstname" type="varchar" size="50"/>
+    <column required="true"  name="us_lastname" type="varchar" size="50"/>
+    <column required="false" name="us_sex" type="tinyint" default="0"/>
+    <column required="true"  name="us_email" type="varchar" size="100"/>
+    <column required="false" name="us_aclgroup" type="integer"/>
+    <column required="false" name="us_school" type="varchar" size="100"/>
+    <column required="false" name="us_province" type="varchar" size="50"/>
+    <column required="false" name="us_lastvisited" type="timestamp"/>
+    <column required="false" name="us_registerdate" type="timestamp" />
+    <column required="true"  name="us_rating" type="integer"  default="0"/>
+    <column required="false" name="us_download" type="integer" default="0" />
+    <column required="false" name="us_avatar" type="varchar" size="255"/>
+    <column required="false" name="us_status" type="integer" default="null"/>
+    <column required="false" name="us_key" type="integer" default="null"/>
+    <column required="false" name="us_company" type="integer" default="0"/>
+    <column required="false" name="us_score" type="integer" default="0"/>
+    <column required="false" name="us_pointplus" type="integer" default="5"/>
+    <column required="false" name="us_checked" type="tinyint" default="0"/>
+    <column required="false" name="us_checkinfo" type="integer"/>
+    <column required="false" name="us_idmd5" type="varchar" size="32"/>
+    <column required="false" name="us_homepage" type="varchar" size="255"/>
+  </table>
+
+  <!-- 22. tbluserdayscore -->
+  <table skipSql="false" abstract="false" name="tbluserdayscore">
+    <column required="true"  name="udsc_user" type="integer" primaryKey="true"/>
+    <column required="true"  name="udsc_date" type="timestamp" primaryKey="true"/>
+    <column required="false" name="udsc_score" type="integer"/>
+    <foreign-key foreignTable="tbluser">
+       <reference local="udsc_user" foreign="us_id"/>
+    </foreign-key>
+  </table>
+
+  <!-- 23. tbluserdocument -->
+  <table skipSql="false" abstract="false" name="tbluserdocument">
+    <column required="true"  name="usdoc_user" type="integer" primaryKey="true"/>
+    <column required="true"  name="usdoc_document" type="integer" primaryKey="true"/>
+    <column required="false" name="usdoc_date" type="timestamp"/>
+    <foreign-key foreignTable="tbldocument">
+       <reference local="usdoc_document" foreign="doc_id"/>
+    </foreign-key>
+  </table>
+
+  <!-- 24. tbluserpresentation -->
+  <table skipSql="false" abstract="false" name="tbluserpresentation">
+    <column required="true"  name="uspre_user" type="integer" primaryKey="true"/>
+    <column required="true"  name="uspre_presentation" type="integer" primaryKey="true"/>
+    <column required="false" name="uspre_date" type="timestamp"/>
+    <foreign-key foreignTable="tblpresentation">
+       <reference local="uspre_presentation" foreign="pr_id"/>
+    </foreign-key>
+  </table>
+
+  <!-- 25. tblusertempscore -->
+  <table skipSql="false" abstract="false" name="tblusertempscore">
+    <column required="true"  name="utsc_user" type="integer" primaryKey="true"/>
+    <column required="true"  name="utsc_date" type="timestamp" primaryKey="true"/>
+    <column required="false" name="utsc_score" type="integer"/>
+    <foreign-key foreignTable="tbluser">
+       <reference local="utsc_user" foreign="us_id"/>
+    </foreign-key>
+  </table>
+  <!-- 25. tblmessage -->
+  <table skipSql="false" abstract="false" name="tblmessage">
+    <column lazyLoad="false" name="ms_id" type="integer" required="true" primaryKey="true"/>
+    <column lazyLoad="false" name="ms_from" type="integer" required="false" primaryKey="false"/>
+    <column lazyLoad="false" name="ms_to" type="integer" required="false" primaryKey="false"/>
+    <column lazyLoad="false" name="ms_subject" type="longvarchar" required="false" primaryKey="false"/>
+    <column lazyLoad="false" name="ms_content" type="longvarchar" required="false" primaryKey="false"/>
+    <column lazyLoad="false" name="ms_read" type="tinyint" default="0" required="false" primaryKey="false"/>
+    <column lazyLoad="false" name="ms_time" type="timestamp" required="false" primaryKey="false"/>
+    <column lazyLoad="false" name="ms_outbox_delete" type="tinyint" default="0" required="false" primaryKey="false"/>
+  </table>
+  <!-- 26. tblblogentrylike -->
+  <table skipSql="false" abstract="false" name="tblblogentrylike">
+    <column required="true"  name="el_entry" type="integer" primaryKey="true"/>
+    <column required="true"  name="el_user" type="integer" primaryKey="true"/>
+    <column required="false" name="el_date" type="timestamp"/>
+  </table>
+
+    <!-- 26. tblnotification_type -->
+  <table skipSql="false" abstract="false" name="tblnotification_type">
+    <column lazyLoad="false" name="nt_id" type="integer" required="true" primaryKey="true"/>
+    <column lazyLoad="false" name="nt_name" type="longvarchar" required="false" primaryKey="false"/>
+    <column lazyLoad="false" name="nt_description" type="longvarchar" required="false" primaryKey="false"/>
+    <column lazyLoad="false" name="nt_notification" type="longvarchar" required="false" primaryKey="false"/>
+    <column lazyLoad="false" name="nt_sample" type="longvarchar" required="false" primaryKey="false"/>
+  </table>
+    <!-- 27. tblnotification -->
+  <table skipSql="false" abstract="false" name="tblnotification">
+    <column lazyLoad="false" name="n_id" autoIncrement="true" type="integer" required="true" primaryKey="true"/>
+    <column lazyLoad="false" name="n_time" type="integer" required="false" primaryKey="false"/>
+    <column lazyLoad="false" name="nt_id" type="integer" required="false" primaryKey="false"/>
+    <foreign-key foreignTable="tblnotification_type">
+       <reference local="nt_id" foreign="nt_id"/>
+    </foreign-key>
+  </table>
+      <!-- 28. tblnotification_user -->
+  <table skipSql="false" abstract="false" name="tblnotification_user">
+    <column lazyLoad="false" name="n_id" type="integer" required="true" primaryKey="true"/>
+    <column lazyLoad="false" name="us_id" type="integer" required="false" primaryKey="true"/>
+    <column lazyLoad="false" name="nu_read" type="integer" required="false" primaryKey="false"/>
+    <foreign-key foreignTable="tblnotification">
+       <reference local="n_id" foreign="n_id"/>
+    </foreign-key>
+    <foreign-key foreignTable="tbluser">
+       <reference local="us_id" foreign="us_id"/>
+    </foreign-key>
+  </table>
+    <!-- 27. tblnotification_detail -->
+  <table skipSql="false" abstract="false" name="tblnotification_detail">
+    <column lazyLoad="false" name="n_id" type="integer" required="true" primaryKey="true"/>
+    <column lazyLoad="false" name="nd_index" type="longvarchar" required="false" primaryKey="true"/>
+    <column lazyLoad="false" name="nd_detail" type="longvarchar" required="false" primaryKey="false"/>
+  </table>
+
+   <!--cac table phuc vu cho chuc nang: cung cap ma kich hoat cho violet-->
+   <table skipSql="false" abstract="false" name="violetactive">
+    <column primaryKey="true" lazyLoad="false" name="va_prokey" type="varchar" size="15" required="true"/>
+    <column required="true" name="va_customerid" type="integer" /><!--la sc_id trong bang tblblogschools-->
+    <column lazyLoad="false" name="va_activekey" type="varchar" required="true" size="39"/>
+    <column lazyLoad="false" name="va_version" type="varchar" required="true" size="5"/>
+    <column required="true" name="va_activedate" type="date"/>
+    <column required="true" name="va_pay" type="tinyint" default="0"/>
+    <foreign-key foreignTable="tblblogschools">
+       <reference local="va_customerid" foreign="sc_id"/>
+    </foreign-key>
+   </table>
+   <table skipSql="false" abstract="false" name="violetprokey">
+    <column primaryKey="true" lazyLoad="false" name="vp_prokey" type="varchar" size="15" required="true"/>
+    <column required="true" name="vp_type" type="tinyint" size="1" default="0"/>
+   </table>
+   <table skipSql="false" abstract="false" name="violetdealer">
+    <column primaryKey="true" lazyLoad="false" name="vd_id" type="integer" size="11" required="true" autoIncrement="true"/>
+    <column required="true" name="vd_dealerid" type="integer" size="11"/>
+    <column required="true" name="vd_name" type="varchar" size="255"/>
+    <column required="true" name="vd_date" type="date"/>
+   </table>
+   <!--het-->
+</database>
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/config/config.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/config/config.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/config/config.php	(revision 19)
@@ -0,0 +1,5 @@
+<?php
+
+// symfony directories
+$sf_symfony_lib_dir  = '/usr/local/src/symfony/lib';
+$sf_symfony_data_dir = '/usr/local/src/symfony/data';
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/config/databases.yml
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/config/databases.yml	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/config/databases.yml	(revision 19)
@@ -0,0 +1,7 @@
+all:
+  propel:
+    class:       sfPropel13Database
+    param:
+      dsn:       mysql:dbname=tvtl;host=127.0.0.1
+      username:  root
+      password:  123456
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/config/factories.yml
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/config/factories.yml	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/config/factories.yml	(revision 19)
@@ -0,0 +1,10 @@
+all:
+  user:
+    class: sfMyUser
+
+  storage:
+    class: sfDatabaseSessionStorage
+    param:
+      session_dsn: mysql:dbname=sessions;host=127.0.0.1
+      session_user: sessionuser
+      session_password: sessionpassword
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/config/propel.ini
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/config/propel.ini	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/config/propel.ini	(revision 19)
@@ -0,0 +1,47 @@
+propel.targetPackage       = lib.model
+propel.packageObjectModel  = true
+propel.project             = violetspace
+propel.database            = mysql
+propel.database.createUrl  = mysql://localhost/
+propel.database.url        = mysql:host=localhost;dbname=tvtl
+propel.database.user       = root
+propel.database.password   = 123456
+propel.database.encoding   = utf8
+
+propel.addGenericAccessors = true
+propel.addGenericMutators  = true
+propel.addTimeStamp        = false
+
+propel.schema.validate     = false
+
+; directories
+propel.home                    = .
+propel.output.dir              = /home/www
+propel.schema.dir              = ${propel.output.dir}/config
+propel.conf.dir                = ${propel.output.dir}/config
+propel.phpconf.dir             = ${propel.output.dir}/config
+propel.sql.dir                 = ${propel.output.dir}/data/sql
+propel.runtime.conf.file       = runtime-conf.xml
+propel.php.dir                 = ${propel.output.dir}
+propel.default.schema.basename = schema
+propel.datadump.mapper.from    = *schema.xml
+propel.datadump.mapper.to      = *data.xml
+
+; builder settings
+propel.builder.peer.class              = plugins.sfPropel13Plugin.lib.propel.builder.SfPeerBuilder
+propel.builder.object.class            = plugins.sfPropel13Plugin.lib.propel.builder.SfObjectBuilder
+
+propel.builder.objectstub.class        = addon.propel.builder.SfExtensionObjectBuilder
+propel.builder.peerstub.class          = addon.propel.builder.SfExtensionPeerBuilder
+propel.builder.objectmultiextend.class = addon.propel.builder.SfMultiExtendObjectBuilder
+propel.builder.mapbuilder.class        = addon.propel.builder.SfMapBuilderBuilder
+propel.builder.interface.class         = propel.engine.builder.om.php5.PHP5InterfaceBuilder
+propel.builder.node.class              = propel.engine.builder.om.php5.PHP5NodeBuilder
+propel.builder.nodepeer.class          = propel.engine.builder.om.php5.PHP5NodePeerBuilder
+propel.builder.nodestub.class          = propel.engine.builder.om.php5.PHP5ExtensionNodeBuilder
+propel.builder.nodepeerstub.class      = propel.engine.builder.om.php5.PHP5ExtensionNodePeerBuilder
+
+propel.builder.addIncludes = false
+propel.builder.addComments = false
+
+propel.builder.addBehaviors = false
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/config/properties.ini
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/config/properties.ini	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/config/properties.ini	(revision 19)
@@ -0,0 +1,2 @@
+[symfony]
+  name=violetspace
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/config/rsync_exclude.txt
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/config/rsync_exclude.txt	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/config/rsync_exclude.txt	(revision 19)
@@ -0,0 +1,4 @@
+.svn
+/web/uploads/*
+/cache/*
+/log/*
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/config/schema-transformed.xml
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/config/schema-transformed.xml	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/config/schema-transformed.xml	(revision 19)
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<database defaultPhpNamingMethod="underscore" heavyIndexing="false" name="propel" defaultIdMethod="native" noXsd="true" package="lib.model"><table skipSql="false" abstract="false" name="tblblogcheckinfo"><column autoIncrement="false" lazyLoad="false" required="true" name="ci_userid" type="integer" primaryKey="true"/><column primaryKey="false" autoIncrement="false" lazyLoad="false" required="true" name="ci_birthday" type="date"/><column primaryKey="false" autoIncrement="false" lazyLoad="false" required="true" name="ci_phone" type="varchar" size="30"/><column primaryKey="false" autoIncrement="false" lazyLoad="false" required="true" name="ci_pr" type="longvarchar"/><column primaryKey="false" autoIncrement="false" lazyLoad="false" required="true" name="ci_numberid" type="varchar" size="30"/><column primaryKey="false" autoIncrement="false" lazyLoad="false" required="true" name="ci_position" type="integer"/><column primaryKey="false" autoIncrement="false" lazyLoad="false" required="true" name="ci_school" type="integer"/><column primaryKey="false" autoIncrement="false" lazyLoad="false" required="true" name="ci_district" type="integer"/><column primaryKey="false" autoIncrement="false" lazyLoad="false" required="true" name="ci_province" type="integer"/><column primaryKey="false" autoIncrement="false" lazyLoad="false" required="true" name="ci_badge" type="varchar" size="30"/><column primaryKey="false" autoIncrement="false" lazyLoad="false" required="true" name="ci_subject" type="varchar" size="30"/><column primaryKey="false" autoIncrement="false" lazyLoad="false" required="true" name="ci_score" type="integer"/><foreign-key onDelete="none" onUpdate="none" foreignTable="tbluser"><reference local="ci_userid" foreign="us_id"/></foreign-key></table><table skipSql="false" abstract="false" name="tbluser"><column lazyLoad="false" required="true" name="us_id" type="integer" autoIncrement="true" primaryKey="true"/><column primaryKey="false" autoIncrement="false" lazyLoad="false" required="false" name="us_username" type="varchar" size="30"/><column primaryKey="false" autoIncrement="false" lazyLoad="false" required="false" name="us_password" type="varchar" size="50"/><column primaryKey="false" autoIncrement="false" lazyLoad="false" required="true" name="us_firstname" type="varchar" size="50"/><column primaryKey="false" autoIncrement="false" lazyLoad="false" required="true" name="us_lastname" type="varchar" size="50"/><column primaryKey="false" autoIncrement="false" lazyLoad="false" required="false" name="us_sex" type="tinyint" default="0"/><column primaryKey="false" autoIncrement="false" lazyLoad="false" required="true" name="us_email" type="varchar" size="100"/><column primaryKey="false" autoIncrement="false" lazyLoad="false" required="false" name="us_phone" type="varchar" size="50"/><column primaryKey="false" autoIncrement="false" lazyLoad="false" required="false" name="us_aclgroup" type="integer"/><column primaryKey="false" autoIncrement="false" lazyLoad="false" required="false" name="us_school" type="varchar" size="100"/><column primaryKey="false" autoIncrement="false" lazyLoad="false" required="false" name="us_province" type="varchar" size="50"/><column primaryKey="false" autoIncrement="false" lazyLoad="false" required="false" name="us_lastvisited" type="timestamp"/><column primaryKey="false" autoIncrement="false" lazyLoad="false" required="false" name="us_registerdate" type="timestamp"/><column primaryKey="false" autoIncrement="false" lazyLoad="false" required="true" name="us_rating" type="integer" default="0"/><column primaryKey="false" autoIncrement="false" lazyLoad="false" required="false" name="us_download" type="integer" default="0"/><column primaryKey="false" autoIncrement="false" lazyLoad="false" required="false" name="us_avatar" type="varchar" size="255"/><column primaryKey="false" autoIncrement="false" lazyLoad="false" required="false" name="us_status" type="integer" default="null"/><column primaryKey="false" autoIncrement="false" lazyLoad="false" required="false" name="us_key" type="integer" default="null"/><column primaryKey="false" autoIncrement="false" lazyLoad="false" required="false" name="us_company" type="integer" default="0"/><column primaryKey="false" autoIncrement="false" lazyLoad="false" required="false" name="us_score" type="integer" default="0"/><column primaryKey="false" autoIncrement="false" lazyLoad="false" required="false" name="us_pointplus" type="integer" default="5"/><column primaryKey="false" autoIncrement="false" lazyLoad="false" required="false" name="us_checked" type="tinyint" default="0"/><column primaryKey="false" autoIncrement="false" lazyLoad="false" required="false" name="us_checkinfo" type="integer"/><column primaryKey="false" autoIncrement="false" lazyLoad="false" required="false" name="us_idmd5" type="varchar" size="32"/><column primaryKey="false" autoIncrement="false" lazyLoad="false" required="false" name="us_homepage" type="varchar" size="255"/><column primaryKey="false" autoIncrement="false" lazyLoad="false" required="false" name="us_money" type="integer" default="0"/></table><table skipSql="false" abstract="false" name="tblspacecategory"><column lazyLoad="false" name="cat_id" type="integer" primaryKey="true" required="true" autoIncrement="true"/><column primaryKey="false" autoIncrement="false" lazyLoad="false" name="cat_name" type="varchar" size="255" required="true"/><column primaryKey="false" autoIncrement="false" lazyLoad="false" name="cat_parent" type="integer" required="true"/><column primaryKey="false" autoIncrement="false" lazyLoad="false" name="cat_user" type="integer" required="true"/><column primaryKey="false" autoIncrement="false" lazyLoad="false" name="cat_date" type="timestamp" required="true"/></table><table skipSql="false" abstract="false" name="tblspaceresource"><column lazyLoad="false" name="res_id" type="integer" primaryKey="true" required="true" autoIncrement="true"/><column primaryKey="false" autoIncrement="false" lazyLoad="false" name="res_filename" type="varchar" size="255" required="true"/><column primaryKey="false" required="false" autoIncrement="false" lazyLoad="false" name="res_filesize" type="integer"/><column primaryKey="false" required="false" autoIncrement="false" lazyLoad="false" name="res_filecrc" type="integer"/></table><table skipSql="false" abstract="false" name="tblspacefile"><column lazyLoad="false" name="file_id" type="integer" primaryKey="true" required="true" autoIncrement="true"/><column primaryKey="false" autoIncrement="false" lazyLoad="false" name="file_resource" type="integer" required="true"/><column primaryKey="false" autoIncrement="false" lazyLoad="false" name="file_category" type="integer" required="true"/><column primaryKey="false" autoIncrement="false" lazyLoad="false" name="file_user" type="integer" required="true"/><column primaryKey="false" required="false" autoIncrement="false" lazyLoad="false" name="file_name" type="varchar" size="255"/><column primaryKey="false" required="false" autoIncrement="false" lazyLoad="false" name="file_type" type="varchar" size="15"/><column primaryKey="false" autoIncrement="false" lazyLoad="false" name="file_date" type="timestamp" required="true"/><foreign-key onDelete="none" onUpdate="none" foreignTable="tblspaceresource"><reference local="file_resource" foreign="res_id"/></foreign-key></table></database>
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/config/schema.xml
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/config/schema.xml	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/config/schema.xml	(revision 19)
@@ -0,0 +1,79 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<database defaultPhpNamingMethod="underscore" heavyIndexing="false" name="propel" defaultIdMethod="native" noXsd="true" package="lib.model">
+
+  <table skipSql="false" abstract="false" name="tblblogcheckinfo">
+    <column required="true" name="ci_userid" type="integer" primaryKey="true"/>
+    <column required="true" name="ci_birthday" type="date"/>
+    <column required="true" name="ci_phone" type="varchar" size="30"/>
+    <column required="true" name="ci_pr" type="longvarchar"/>
+    <column required="true" name="ci_numberid" type="varchar" size="30"/>
+    <column required="true" name="ci_position" type="integer"/>
+    <column required="true" name="ci_school" type="integer"/>
+    <column required="true" name="ci_district" type="integer"/>
+    <column required="true" name="ci_province" type="integer"/>
+    <column required="true" name="ci_badge" type="varchar" size="30"/>
+    <column required="true" name="ci_subject" type="varchar" size="30"/>
+    <column required="true" name="ci_score" type="integer"/>
+    <foreign-key foreignTable="tbluser">
+       <reference local="ci_userid" foreign="us_id"/>
+    </foreign-key>
+  </table>
+
+  <!-- 21. tbluser -->
+  <table skipSql="false" abstract="false" name="tbluser">
+    <column required="true"  name="us_id" type="integer" autoIncrement="true" primaryKey="true"/>
+    <column required="false" name="us_username" type="varchar" size="30"/>
+    <column required="false" name="us_password" type="varchar" size="50"/>
+    <column required="true"  name="us_firstname" type="varchar" size="50"/>
+    <column required="true"  name="us_lastname" type="varchar" size="50"/>
+    <column required="false" name="us_sex" type="tinyint" default="0"/>
+    <column required="true"  name="us_email" type="varchar" size="100"/>
+    <column required="false" name="us_phone" type="varchar" size="50"/>
+    <column required="false" name="us_aclgroup" type="integer"/>
+    <column required="false" name="us_school" type="varchar" size="100"/>
+    <column required="false" name="us_province" type="varchar" size="50"/>
+    <column required="false" name="us_lastvisited" type="timestamp"/>
+    <column required="false" name="us_registerdate" type="timestamp" />
+    <column required="true"  name="us_rating" type="integer"  default="0"/>
+    <column required="false" name="us_download" type="integer" default="0" />
+    <column required="false" name="us_avatar" type="varchar" size="255"/>
+    <column required="false" name="us_status" type="integer" default="null"/>
+    <column required="false" name="us_key" type="integer" default="null"/>
+    <column required="false" name="us_company" type="integer" default="0"/>
+    <column required="false" name="us_score" type="integer" default="0"/>
+    <column required="false" name="us_pointplus" type="integer" default="5"/>
+    <column required="false" name="us_checked" type="tinyint" default="0"/>
+    <column required="false" name="us_checkinfo" type="integer"/>
+    <column required="false" name="us_idmd5" type="varchar" size="32"/>
+    <column required="false" name="us_homepage" type="varchar" size="255"/>
+    <column required="false" name="us_money" type="integer" default="0"/>
+  </table>
+
+  <table skipSql="false" abstract="false" name="tblspacecategory">
+    <column name="cat_id" type="integer" primaryKey="true" required="true" autoIncrement="true" />
+    <column name="cat_name" type="varchar" size="255" required="true" />
+    <column name="cat_parent" type="integer" required="true" />
+    <column name="cat_user" type="integer" required="true" />
+    <column name="cat_date" type="timestamp" required="true" />
+  </table>
+
+  <table skipSql="false" abstract="false" name="tblspaceresource">
+    <column name="res_id" type="integer" primaryKey="true" required="true" autoIncrement="true" />
+    <column name="res_filename" type="varchar" size="255" required="true" />
+    <column name="res_filesize" type="integer" />
+    <column name="res_filecrc" type="integer" />
+  </table>
+
+  <table skipSql="false" abstract="false" name="tblspacefile">
+    <column name="file_id" type="integer" primaryKey="true" required="true" autoIncrement="true" />
+    <column name="file_resource" type="integer" required="true" />
+    <column name="file_category" type="integer" required="true" />
+    <column name="file_user" type="integer" required="true" />
+    <column name="file_name" type="varchar" size="255" />
+    <column name="file_type" type="varchar" size="15" />
+    <column name="file_date" type="timestamp" required="true" />
+    <foreign-key foreignTable="tblspaceresource">
+       <reference local="file_resource" foreign="res_id"/>
+    </foreign-key>
+  </table>
+</database>
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/data/sql/lib.model.schema.sql
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/data/sql/lib.model.schema.sql	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/data/sql/lib.model.schema.sql	(revision 19)
@@ -0,0 +1,101 @@
+
+# This is a fix for InnoDB in MySQL >= 4.1.x
+# It "suspends judgement" for fkey relationships until are tables are set.
+SET FOREIGN_KEY_CHECKS = 0;
+
+#-----------------------------------------------------------------------------
+#-- tbluser
+#-----------------------------------------------------------------------------
+
+DROP TABLE IF EXISTS `tbluser`;
+
+
+CREATE TABLE `tbluser`
+(
+	`us_id` INTEGER  NOT NULL AUTO_INCREMENT,
+	`us_username` VARCHAR(30),
+	`us_password` VARCHAR(50),
+	`us_firstname` VARCHAR(50)  NOT NULL,
+	`us_lastname` VARCHAR(50)  NOT NULL,
+	`us_sex` TINYINT default 0,
+	`us_email` VARCHAR(100)  NOT NULL,
+	`us_phone` VARCHAR(50),
+	`us_aclgroup` INTEGER,
+	`us_school` VARCHAR(100),
+	`us_province` VARCHAR(50),
+	`us_lastvisited` DATETIME,
+	`us_registerdate` DATETIME,
+	`us_rating` INTEGER default 0 NOT NULL,
+	`us_download` INTEGER default 0,
+	`us_avatar` VARCHAR(255),
+	`us_status` INTEGER default null,
+	`us_key` INTEGER default null,
+	`us_company` INTEGER default 0,
+	`us_score` INTEGER default 0,
+	`us_pointplus` INTEGER default 5,
+	`us_checked` TINYINT default 0,
+	`us_checkinfo` INTEGER,
+	`us_idmd5` VARCHAR(32),
+	`us_homepage` VARCHAR(255),
+	`us_money` INTEGER default 0,
+	PRIMARY KEY (`us_id`)
+)Type=MyISAM;
+
+#-----------------------------------------------------------------------------
+#-- tblspacecategory
+#-----------------------------------------------------------------------------
+
+DROP TABLE IF EXISTS `tblspacecategory`;
+
+
+CREATE TABLE `tblspacecategory`
+(
+	`cat_id` INTEGER  NOT NULL AUTO_INCREMENT,
+	`cat_name` VARCHAR(255)  NOT NULL,
+	`cat_parent` INTEGER  NOT NULL,
+	`cat_user` INTEGER  NOT NULL,
+	`cat_date` DATETIME  NOT NULL,
+	PRIMARY KEY (`cat_id`)
+)Type=MyISAM;
+
+#-----------------------------------------------------------------------------
+#-- tblspaceresource
+#-----------------------------------------------------------------------------
+
+DROP TABLE IF EXISTS `tblspaceresource`;
+
+
+CREATE TABLE `tblspaceresource`
+(
+	`res_id` INTEGER  NOT NULL AUTO_INCREMENT,
+	`res_filename` VARCHAR(255)  NOT NULL,
+	`res_filesize` INTEGER,
+	`res_filecrc` INTEGER,
+	PRIMARY KEY (`res_id`)
+)Type=MyISAM;
+
+#-----------------------------------------------------------------------------
+#-- tblspacefile
+#-----------------------------------------------------------------------------
+
+DROP TABLE IF EXISTS `tblspacefile`;
+
+
+CREATE TABLE `tblspacefile`
+(
+	`file_id` INTEGER  NOT NULL AUTO_INCREMENT,
+	`file_resource` INTEGER  NOT NULL,
+	`file_category` INTEGER  NOT NULL,
+	`file_user` INTEGER  NOT NULL,
+	`file_name` VARCHAR(255),
+	`file_type` VARCHAR(15),
+	`file_date` DATETIME  NOT NULL,
+	PRIMARY KEY (`file_id`),
+	INDEX `tblspacefile_FI_1` (`file_resource`),
+	CONSTRAINT `tblspacefile_FK_1`
+		FOREIGN KEY (`file_resource`)
+		REFERENCES `tblspaceresource` (`res_id`)
+)Type=MyISAM;
+
+# This restores the fkey checks, after having unset them earlier
+SET FOREIGN_KEY_CHECKS = 1;
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/data/sql/sqldb.map
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/data/sql/sqldb.map	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/data/sql/sqldb.map	(revision 19)
@@ -0,0 +1,2 @@
+# Sqlfile -> Database map
+lib.model.schema.sql=propel
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/index.html
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/index.html	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/index.html	(revision 19)
@@ -0,0 +1,1 @@
+<h1>Welcome!</h1>
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/info.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/info.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/info.php	(revision 19)
@@ -0,0 +1,2 @@
+<?php
+phpinfo();
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/lib/common/html2text.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/lib/common/html2text.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/lib/common/html2text.php	(revision 19)
@@ -0,0 +1,440 @@
+<?php
+
+/*************************************************************************
+ *                                                                       *
+ * class.html2text.inc                                                   *
+ *                                                                       *
+ *************************************************************************
+ *                                                                       *
+ * Converts HTML to formatted plain text                                 *
+ *                                                                       *
+ * Copyright (c) 2005 Jon Abernathy <jon@chuggnutt.com>                  *
+ * All rights reserved.                                                  *
+ *                                                                       *
+ * This script is free software; you can redistribute it and/or modify   *
+ * it under the terms of the GNU General Public License as published by  *
+ * the Free Software Foundation; either version 2 of the License, or     *
+ * (at your option) any later version.                                   *
+ *                                                                       *
+ * The GNU General Public License can be found at                        *
+ * http://www.gnu.org/copyleft/gpl.html.                                 *
+ *                                                                       *
+ * This script 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 General Public License for more details.                          *
+ *                                                                       *
+ * Author(s): Jon Abernathy <jon@chuggnutt.com>                          *
+ *                                                                       *
+ * Last modified: 11/02/06                                               *
+ *                                                                       *
+ *************************************************************************/
+
+
+/**
+ *  Takes HTML and converts it to formatted, plain text.
+ *
+ *  Thanks to Alexander Krug (http://www.krugar.de/) to pointing out and
+ *  correcting an error in the regexp search array. Fixed 7/30/03.
+ *
+ *  Updated set_html() function's file reading mechanism, 9/25/03.
+ *
+ *  Thanks to Joss Sanglier (http://www.dancingbear.co.uk/) for adding
+ *  several more HTML entity codes to the $search and $replace arrays.
+ *  Updated 11/7/03.
+ *
+ *  Thanks to Darius Kasperavicius (http://www.dar.dar.lt/) for
+ *  suggesting the addition of $allowed_tags and its supporting function
+ *  (which I slightly modified). Updated 3/12/04.
+ *
+ *  Thanks to Justin Dearing for pointing out that a replacement for the
+ *  <TH> tag was missing, and suggesting an appropriate fix.
+ *  Updated 8/25/04.
+ *
+ *  Thanks to Mathieu Collas (http://www.myefarm.com/) for finding a
+ *  display/formatting bug in the _build_link_list() function: email
+ *  readers would show the left bracket and number ("[1") as part of the
+ *  rendered email address.
+ *  Updated 12/16/04.
+ *
+ *  Thanks to Wojciech Bajon (http://histeria.pl/) for submitting code
+ *  to handle relative links, which I hadn't considered. I modified his
+ *  code a bit to handle normal HTTP links and MAILTO links. Also for
+ *  suggesting three additional HTML entity codes to search for.
+ *  Updated 03/02/05.
+ *
+ *  Thanks to Jacob Chandler for pointing out another link condition
+ *  for the _build_link_list() function: "https".
+ *  Updated 04/06/05.
+ *
+ *  Thanks to Marc Bertrand (http://www.dresdensky.com/) for
+ *  suggesting a revision to the word wrapping functionality; if you
+ *  specify a $width of 0 or less, word wrapping will be ignored.
+ *  Updated 11/02/06.
+ *
+ *  @author Jon Abernathy <jon@chuggnutt.com>
+ *  @version 0.6.2
+ *  @since PHP 4.0.2
+ */
+class html2text
+{
+
+    /**
+     *  Contains the HTML content to convert.
+     *
+     *  @private string $html
+     *  @access public
+     */
+    private $html;
+
+    /**
+     *  Contains the converted, formatted text.
+     *
+     *  @private string $text
+     *  @access public
+     */
+    private $text;
+
+    /**
+     *  Maximum width of the formatted text, in columns.
+     *
+     *  Set this value to 0 (or less) to ignore word wrapping
+     *  and not constrain text to a fixed-width column.
+     *
+     *  @private integer $width
+     *  @access public
+     */
+    private $width = 0;
+
+    /**
+     *  List of preg* regular expression patterns to search for,
+     *  used in conjunction with $replace.
+     *
+     *  @private array $search
+     *  @access public
+     *  @see $replace
+     */
+    private $search = array(
+        "/\r/",                                  // Non-legal carriage return
+        "/[\n\t]+/",                             // Newlines and tabs
+        '/<script[^>]*>.*?<\/script>/i',         // <script>s -- which strip_tags supposedly has problems with
+        //'/<!-- .* -->/',                         // Comments -- which strip_tags might have problem a with
+        '/<h[123][^>]*>(.+?)<\/h[123]>/ie',      // H1 - H3
+        '/<h[456][^>]*>(.+?)<\/h[456]>/ie',      // H4 - H6
+        '/<p[^>]*>/i',                           // <P>
+        '/<br[^>]*>/i',                          // <br>
+        '/<b[^>]*>(.+?)<\/b>/ie',                // <b>
+        '/<i[^>]*>(.+?)<\/i>/i',                 // <i>
+        '/(<ul[^>]*>|<\/ul>)/i',                 // <ul> and </ul>
+        '/(<ol[^>]*>|<\/ol>)/i',                 // <ol> and </ol>
+        '/<li[^>]*>/i',                          // <li>
+        '/<a href="([^"]+)"[^>]*>(.+?)<\/a>/ie', // <a href="">
+        '/<hr[^>]*>/i',                          // <hr>
+        '/(<table[^>]*>|<\/table>)/i',           // <table> and </table>
+        '/(<tr[^>]*>|<\/tr>)/i',                 // <tr> and </tr>
+        '/<td[^>]*>(.+?)<\/td>/i',               // <td> and </td>
+        '/<th[^>]*>(.+?)<\/th>/i',               // <th> and </th>
+        '/&nbsp;/i',
+        '/&quot;/i',
+        '/&gt;/i',
+        '/&lt;/i',
+        '/&amp;/i',
+        '/&copy;/i',
+        '/&trade;/i',
+        '/&#8220;/',
+        '/&#8221;/',
+        '/&#8211;/',
+        '/&#8217;/',
+        '/&#38;/',
+        '/&#169;/',
+        '/&#8482;/',
+        '/&#151;/',
+        '/&#147;/',
+        '/&#148;/',
+        '/&#149;/',
+        '/&reg;/i',
+        '/&bull;/i',
+        '/&[&;]+;/i'
+    );
+
+    /**
+     *  List of pattern replacements corresponding to patterns searched.
+     *
+     *  @private array $replace
+     *  @access public
+     *  @see $search
+     */
+    private $replace = array(
+        '',                                     // Non-legal carriage return
+        ' ',                                    // Newlines and tabs
+        '',                                     // <script>s -- which strip_tags supposedly has problems with
+        //'',                                   // Comments -- which strip_tags might have problem a with
+        "\"\n\n\\1\n\n\"",                          // H1 - H3
+        "ucwords(\"\n\n\\1\n\n\")",             // H4 - H6
+        "\n\n\t",                               // <P>
+        "\n",                                   // <br>
+        '"\\1"',                                  // <b>
+        '_\\1_',                                // <i>
+        "\n\n",                                 // <ul> and </ul>
+        "\n\n",                                 // <ol> and </ol>
+        "\t*",                                  // <li>
+        '',//'$this->_build_link_list($link_count++, "\\1", "\\2")',
+                                                // <a href="">
+        "\n-------------------------\n",        // <hr>
+        "\n\n",                                 // <table> and </table>
+        "\n",                                   // <tr> and </tr>
+        "\t\t\\1\n",                            // <td> and </td>
+        "\"\t\t\\1\n\"",            // <th> and </th>
+        ' ',
+        '"',
+        '>',
+        '<',
+        '&',
+        '(c)',
+        '(tm)',
+        '"',
+        '"',
+        '-',
+        "'",
+        '&',
+        '(c)',
+        '(tm)',
+        '--',
+        '"',
+        '"',
+        '*',
+        '(R)',
+        '*',
+        ''
+    );
+
+    /**
+     *  Contains a list of HTML tags to allow in the resulting text.
+     *
+     *  @private string $allowed_tags
+     *  @access public
+     *  @see set_allowed_tags()
+     */
+    private $allowed_tags = '';
+
+    /**
+     *  Contains the base URL that relative links should resolve to.
+     *
+     *  @private string $url
+     *  @access public
+     */
+    private $url;
+
+    /**
+     *  Indicates whether content in the $html variable has been converted yet.
+     *
+     *  @private boolean $converted
+     *  @access private
+     *  @see $html, $text
+     */
+    private $_converted = false;
+
+    /**
+     *  Contains URL addresses from links to be rendered in plain text.
+     *
+     *  @private string $link_list
+     *  @access private
+     *  @see _build_link_list()
+     */
+    private $_link_list;
+
+    /**
+     *  Constructor.
+     *
+     *  If the HTML source string (or file) is supplied, the class
+     *  will instantiate with that source propagated, all that has
+     *  to be done it to call get_text().
+     *
+     *  @param string $source HTML content
+     *  @param boolean $from_file Indicates $source is a file to pull content from
+     *  @access public
+     *  @return void
+     */
+    function html2text( $source = '', $from_file = false )
+    {
+        if ( !empty($source) ) {
+            $this->set_html($source, $from_file);
+        }
+        $this->set_base_url();
+    }
+
+    /**
+     *  Loads source HTML into memory, either from $source string or a file.
+     *
+     *  @param string $source HTML content
+     *  @param boolean $from_file Indicates $source is a file to pull content from
+     *  @access public
+     *  @return void
+     */
+    function set_html( $source, $from_file = false )
+    {
+        $this->html = $source;
+
+        if ( $from_file && file_exists($source) ) {
+            $fp = fopen($source, 'r');
+            $this->html = fread($fp, filesize($source));
+            fclose($fp);
+        }
+
+        $this->_converted = false;
+    }
+
+    /**
+     *  Returns the text, converted from HTML.
+     *
+     *  @access public
+     *  @return string
+     */
+    function get_text()
+    {
+        if ( !$this->_converted ) {
+            $this->_convert();
+        }
+
+        return $this->text;
+    }
+
+    /**
+     *  Prints the text, converted from HTML.
+     *
+     *  @access public
+     *  @return void
+     */
+    function print_text()
+    {
+        print $this->get_text();
+    }
+
+    /**
+     *  Alias to print_text(), operates identically.
+     *
+     *  @access public
+     *  @return void
+     *  @see print_text()
+     */
+    function p()
+    {
+        print $this->get_text();
+    }
+
+    /**
+     *  Sets the allowed HTML tags to pass through to the resulting text.
+     *
+     *  Tags should be in the form "<p>", with no corresponding closing tag.
+     *
+     *  @access public
+     *  @return void
+     */
+    function set_allowed_tags( $allowed_tags = '' )
+    {
+        if ( !empty($allowed_tags) ) {
+            $this->allowed_tags = $allowed_tags;
+        }
+    }
+
+    /**
+     *  Sets a base URL to handle relative links.
+     *
+     *  @access public
+     *  @return void
+     */
+    function set_base_url( $url = '' )
+    {
+        if ( empty($url) ) {
+            $this->url = 'http://' . $_SERVER['HTTP_HOST'];
+        } else {
+            // Strip any trailing slashes for consistency (relative
+            // URLs may already start with a slash like "/file.html")
+            if ( substr($url, -1) == '/' ) {
+                $url = substr($url, 0, -1);
+            }
+            $this->url = $url;
+        }
+    }
+
+    /**
+     *  Workhorse function that does actual conversion.
+     *
+     *  First performs custom tag replacement specified by $search and
+     *  $replace arrays. Then strips any remaining HTML tags, reduces whitespace
+     *  and newlines to a readable format, and word wraps the text to
+     *  $width characters.
+     *
+     *  @access private
+     *  @return void
+     */
+    function _convert()
+    {
+        // Variables used for building the link list
+        $link_count = 1;
+        $this->_link_list = '';
+
+        $text = trim(stripslashes($this->html));
+
+        // Run our defined search-and-replace
+        $text = preg_replace($this->search, $this->replace, $text);
+
+        // Strip any other HTML tags
+        $text = strip_tags($text, $this->allowed_tags);
+
+        // Bring down number of empty lines to 2 max
+        $text = preg_replace("/\n\s+\n/", "\n", $text);
+        $text = preg_replace("/[\n]{3,}/", "\n\n", $text);
+
+        // Add link list
+        /*
+        if ( !empty($this->_link_list) ) {
+            $text .= "\n\nLinks:\n------\n" . $this->_link_list;
+        }
+        */
+
+        // Wrap the text to a readable format
+        // for PHP versions >= 4.0.2. Default width is 75
+        // If width is 0 or less, don't wrap the text.
+        if ( $this->width > 0 ) {
+        	$text = wordwrap($text, $this->width);
+        }
+
+        $this->text = $text;
+
+        $this->_converted = true;
+    }
+
+    /**
+     *  Helper function called by preg_replace() on link replacement.
+     *
+     *  Maintains an internal list of links to be displayed at the end of the
+     *  text, with numeric indices to the original point in the text they
+     *  appeared. Also makes an effort at identifying and handling absolute
+     *  and relative links.
+     *
+     *  @param integer $link_count Counter tracking current link number
+     *  @param string $link URL of the link
+     *  @param string $display Part of the text to associate number with
+     *  @access private
+     *  @return string
+     */
+    function _build_link_list($link_count, $link, $display)
+    {
+        if ( substr($link, 0, 7) == 'http://' || substr($link, 0, 8) == 'https://' ||
+             substr($link, 0, 7) == 'mailto:' ) {
+            $this->_link_list .= "[$link_count] $link\n";
+        } else {
+            $this->_link_list .= "[$link_count] " . $this->url;
+            if ( substr($link, 0, 1) != '/' ) {
+                $this->_link_list .= '/';
+            }
+            $this->_link_list .= "$link\n";
+        }
+
+        return $display . ' [' . $link_count . ']';
+    }
+
+}
+
+?>
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/lib/common/htmlFilter.class.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/lib/common/htmlFilter.class.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/lib/common/htmlFilter.class.php	(revision 19)
@@ -0,0 +1,70 @@
+<?php
+
+function equation_callback($match) {
+  $ret = new html2text(str_replace('\\', '\\\\', $match[0]));
+  $ret = $ret->get_text();
+  return $ret;
+}
+
+class htmlFilter {
+  public static function filterText($text) {
+#    $text = preg_replace('@\$\$([^\$\$]*)\$\$@', '<img src="http://s1.wordpress.com/latex.php?bg=ffffff&fg=000000&s=0&latex=$1" align="absmiddle"/>', $text);
+     $text = preg_replace('@\$\$([^\$\$]*)\$\$@', '<img src="http://latex.codecogs.com/gif.latex?$1" align="absmiddle"/>', $text);
+#    $text = str_replace(array('www.codecogs.com/gif.latex?', 'codecogs.izyba.com/gif.latex?'), 'www.forkosh.dreamhost.com/mathtex.cgi?', $text);
+    return $text;
+  }
+
+  public static function preFilter($text) {
+    $config = array(
+           'indent'         => false,
+           'clean'          => true,
+#           'drop-proprietary-attributes'    =>    true,
+           'output-xhtml'   => true,
+           'fix-bad-comments'   => true,
+           'hide-comments'   => true,
+           'input-encoding' => 'utf8',
+           'char-encoding' => 'utf8',
+           'output-encoding' => 'utf8',
+           'show-body-only' => true,
+           'word-2000'   => false,
+           'wrap'           => 0);
+    //if (blogStore::$userId==1) {
+    $tidy = tidy_repair_string($text, $config, 'utf8');
+    //} else {
+    //  $tidy = $text;
+    //}
+    $text = preg_replace_callback('@\$\$[^\$\$]*\$\$@', 'equation_callback', $tidy);
+    sfLoader::loadHelpers('Helper');
+    use_helper('Tag', 'Text');
+    //$text = auto_link_text($text, 'all', '_blank');
+    return $text;
+  }
+
+  /**
+   * Enter description here...
+   *
+   * @param string $text
+   * @return string validated text (empty string if cannot validate)
+   */
+  public static function validateHtml($text) {
+  	$tidy = new tidy();
+  	if ($tidy->parseString($text, array(
+  		'input-encoding' => 'utf8',
+      'output-encoding' => 'utf8'
+  	))) {
+			$content = '';
+			foreach ($tidy->head()->child as $el) {
+				if (@$el->name!='title') {
+					$content .= $el->value;
+				}
+			}
+
+			foreach ($tidy->body()->child as $el) {
+				$content .= $el->value;
+			}
+  		return trim($content);
+  	} else {
+  		return '';
+  	}
+  }
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/lib/common/myMail.class.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/lib/common/myMail.class.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/lib/common/myMail.class.php	(revision 19)
@@ -0,0 +1,60 @@
+<?php
+
+class myMail {
+  
+  public $setFrom;
+  public $From;
+  public $FromName;
+  public $To;
+  public $ToName;
+  public $Subject;
+  public $Body;
+  public $ReplyTo;
+  
+  public function __construct() {
+    $this->setFrom('hotro@violet.vn', 'Thu vien Violet');
+  }
+
+  public function setFrom($address, $name = null) {
+    $this->From = $address;
+    $this->FromName = $name;
+  }
+
+  public function addAddress($address, $name = null) {
+    $this->To = $address;
+    $this->ToName = $name;
+  }
+
+  public function addReplyTo($address, $name = null) {
+    $this->ReplyTo = $address;
+  }
+
+  public function setSubject($subject) {
+    $this->Subject = $subject;
+  }
+
+  public function setBody($body) {
+    $this->Body = $body;
+  }
+
+  public function send() {
+    $url = 'http://54.254.211.41';
+    $postData = array();
+    $postData['from'] = $this->From;
+    $postData['fromname'] = $this->FromName;
+    $postData['replyto'] = $this->ReplyTo;
+    $postData['to'] = $this->To;
+    $postData['toname'] = $this->ToName;
+    $postData['subject'] = $this->Subject;
+    $postData['content'] = $this->Body;
+    $ch = curl_init();
+    curl_setopt($ch, CURLOPT_URL, $url);
+    curl_setopt($ch, CURLOPT_RETURNTRANSFER,1);
+    curl_setopt($ch, CURLOPT_POST, 1);
+    curl_setopt($ch, CURLOPT_POSTFIELDS, $postData);
+    $result = curl_exec($ch);
+    curl_close($ch);
+    myUtility::log($this->ToName.' <'.$this->To.'> "'.$this->Subject.'"', 'mail.log');
+    return $result=='true';
+  }
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/lib/common/myUtility.class.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/lib/common/myUtility.class.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/lib/common/myUtility.class.php	(revision 19)
@@ -0,0 +1,554 @@
+<?php
+  class myUtility {
+    static $log_dir = null;
+
+    /**
+     * Return extension of a file name
+     *
+     */
+    public static function getFileExt($fileName) {
+      $names = explode('.', $fileName);
+      $i = count($names);
+      if ($i>0) return  strtolower($names[$i-1]); else return '';
+    }
+
+    /**
+     * return file name (no extension)
+     *
+     *
+     * @param String $fileName
+     */
+    public static function getFileName($fileName) {
+      $names = explode('.', $fileName);
+      $i = count($names);
+      if (count($names)>0) array_pop($names);
+      return join('.', $names);
+    }
+
+    /**
+     * return safe file name (lower byte character)
+     *
+     * @param unknown_type $fileName
+     */
+    public static function getSafeFileName($fileName) {
+      $names = explode('.', $fileName);
+      $ext = array_pop($names);
+      $safe = preg_replace('@[^A-Za-z0-9_]+@', '', join($names));
+      if ($safe=='') $safe = '0';
+      return $safe.'.'.$ext;
+    }
+
+    /**
+     * Convert from UTF-8 to non mark Vietnamese text
+     *
+     * @param String $value: input text
+     * @return Non marke Vietnamese text
+     */
+    public static function vietDecode($value)
+    {
+      $vietChar 	= 'Ã¡|Ã |áº£|Ã£|áº¡|Ä|áº¯|áº±|áº³|áºµ|áº·|Ã¢|áº¥|áº§|áº©|áº«|áº­|Ã©|Ãš|áº»|áºœ|áº¹|Ãª|áº¿|á»|á»|á»
+|á»|Ã³|Ã²|á»|Ãµ|á»|Æ¡|á»|á»|á»|á»¡|á»£|ÃŽ|á»|á»|á»|á»|á»|Ãº|Ã¹|á»§|Å©|á»¥|Æ°|á»©|á»«|á»­|á»¯|á»±|Ã­|Ã¬|á»|Ä©|á»|Ãœ|á»³|á»·|á»¹|á»µ|Ä|Ã|Ã|áº¢|Ã|áº |Ä|áº®|áº°|áº²|áºŽ|áº¶|Ã|áº€|áºŠ|áºš|áºª|áº¬|Ã|Ã|áºº|áºŒ|áºž|Ã|áºŸ|á»|á»|á»|á»|Ã|Ã|á»|Ã|á»|Æ |á»|á»|á»|á» |á»¢|Ã|á»|á»|á»|á»|á»|Ã|Ã|á»Š|Åš|á»€|Æ¯|á»š|á»ª|á»¬|á»®|á»°|Ã|Ã|á»|Äš|á»|Ã|á»²|á»¶|á»ž|á»Ž|Ä';
+			$engChar	= 'a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|e|e|e|e|e|e|e|e|e|e|e|o|o|o|o|o|o|o|o|o|o|o|o|o|o|o|o|o|u|u|u|u|u|u|u|u|u|u|u|i|i|i|i|i|y|y|y|y|y|d|A|A|A|A|A|A|A|A|A|A|A|A|A|A|A|A|A|E|E|E|E|E|E|E|E|E|E|E|O|O|O|O|O|O|O|O|O|O|O|O|O|O|O|O|O|U|U|U|U|U|U|U|U|U|U|U|I|I|I|I|I|Y|Y|Y|Y|Y|D';
+			$arrVietChar 	= explode('|', $vietChar);
+			$arrEngChar		= explode('|', $engChar);
+			return str_replace($arrVietChar, $arrEngChar, $value);
+    }
+
+    public static function getUrlName($name) {
+      $name = strtolower(myUtility::vietDecode($name));
+      $name = preg_replace('@[^\w\d_]+@', '', $name);
+      return $name;
+    }
+
+    /**
+     * Check hard disk for not exist fileName, if file exists, change it name
+     *
+     * @param unknown_type $pathName
+     * @param unknown_type $fileName
+     * @param unknown_type $extName
+     */
+    public static function GetNoDuplicateFileName($pathName, &$fileName, $extName) {
+      $i = 0;
+      $newFileName = $fileName;
+      while (file_exists("$pathName/$newFileName.$extName")) {
+        $newFileName = $fileName . (++$i);
+      }
+      $fileName = $newFileName;
+    }
+
+    public static function moveDirectory($src, $dst) {
+      if (!is_dir($dst)) {umask(0); mkdir($dst, 0777, true);}
+      foreach (scandir($src) as $file) {
+        if ($file=='.' || $file=='..') continue;
+        $srcm = $src.'/'.$file;
+        $dstm = $dst.'/'.$file;
+        if (is_dir($srcm)) myUtility::moveDirectory($srcm, $dstm);
+        else {
+          rename($srcm, $dstm);
+          chmod($dstm, 0777);
+        }
+      }
+      rmdir($src);
+    }
+
+    public static function cleanDirectory($path) {
+      foreach (scandir($path) as $dir) {
+        if ($dir=='.' || $dir=='..') continue;
+        $dname = $path.'/'.$dir; 
+        if (is_dir($dname)) self::cleanDirectory($dname);
+        else if (is_file($dname)) unlink($dname);
+      }
+      rmdir($path);
+    }
+
+    public static function ScaleAspect(&$width, &$height, $maxWidth, $maxHeight) {
+      $sx = $maxWidth / $width;
+      $sy = $maxHeight / $height;
+      if ($sx>$sy) $sx = $sy;
+      $width = round($width * $sx / 2) * 2;
+      $height = round($height * $sx / 2) * 2;
+    }
+
+    /**
+     * Enter description here...
+     *
+     * @param unknown_type $fileName
+     * @param unknown_type $fileThumb
+     * @param unknown_type $time
+     * @param unknown_type $info
+     * @return unknown
+     */
+    public static function FlvToThumbnail($fileName, $fileThumb, $time = null, $info = null) {
+      try {
+        if ($info==null) $info = self::GetVideoInfo($fileName);
+
+        if (!isset($info['ID_VIDEO_FORMAT'])) return false;
+        if (!isset($info['ID_LENGTH'])) return false;
+        $width = doubleval($info['ID_VIDEO_WIDTH']);
+        $height = doubleval($info['ID_VIDEO_HEIGHT']);
+
+        self::ScaleAspect($width, $height, 150, 100);
+
+        if ($time===null) $time = doubleval($info['ID_LENGTH']) / 2;
+
+        $logFileName = 'convert_flv_thumb.log';
+
+        // no .THM file so need to use ffmpeg to get tumbnail image
+    		//ffmpeg -y -i MVI_6640.AVI -s qcif -f mjpeg -t 0.001 movie.jpg
+    		$ffmpeg_cmd = sfConfig::get('app_ffmpeg_exe');
+    		$command = "$ffmpeg_cmd -y -v 0 -itsoffset -$time -i ". escapeshellarg($fileName) ." -s {$width}x{$height} -f mjpeg -vframes 1 ". escapeshellarg($fileThumb);
+    		//myUtility::log("\n\n\n********".$command, $logFileName);
+
+    		$descriptorspec = array(
+           0 => array("pipe", "r"),  // stdin is a pipe that the child will read from
+           1 => array("pipe", "w"),  // stdout is a pipe that the child will write to
+           2 => array("pipe", "w"),  // stdout is a pipe that the child will write to
+        );
+        $process = proc_open($command, $descriptorspec, $pipes);
+        if (is_resource($process)) {
+          $ret = true;
+          while (!feof($pipes[2])) {
+            $line = fgets($pipes[2],1024);
+            //myUtility::log($line, $logFileName);
+            if (preg_match('@: no such file or directory@', $line)) $ret = false;
+            if (preg_match('@^Error while opening codec for output stream@', $line)) $ret = false;
+            if (preg_match('@Unknown format@', $line)) $ret = false;
+          }
+          fclose($pipes[2]);
+          proc_close($process);
+          return $ret;
+        } else return false;
+      } catch (Exception $e) {
+        myUtility::log($e->getMessage(), $logFileName);
+        return false;
+      }
+    }
+
+    public static function ImageToJpg($imageName, $jpgName) {
+      $convert_cmd = sfConfig::get('app_convert_exe');
+      $command = "$convert_cmd ". escapeshellarg($imageName) ." ". escapeshellarg($jpgName);
+      $descriptorspec = array(
+         0 => array("pipe", "r"),  // stdin is a pipe that the child will read from
+         1 => array("pipe", "w"),  // stdout is a pipe that the child will write to
+      );
+      $process = proc_open($command, $descriptorspec, $pipes);
+      if (is_resource($process)) {
+        while (!feof($pipes[1])) {
+          $line = fgets($pipes[1], 1024);
+        }
+        fclose($pipes[1]);
+        proc_close($process);
+      }
+    }
+
+    public static function MovieToFlv($movieName, $flvName) {
+      try {
+        $logFileName = 'convert_flv.log';
+        $ffmpeg_cmd = sfConfig::get('app_ffmpeg_exe');
+
+    		// generate the Flash FLV version of the file
+      	// cif = 352x288
+      	$command = "$ffmpeg_cmd -y -v 0 -i ". escapeshellarg($movieName) ." -s cif -ar 44100 -r 15 ". escapeshellarg($flvName);
+      	//myUtility::log("\n\n\n********".$command, $logFileName);
+
+      	$descriptorspec = array(
+           0 => array("pipe", "r"),  // stdin is a pipe that the child will read from
+           1 => array("pipe", "w"),  // stdout is a pipe that the child will write to
+           2 => array("pipe", "w"),  // stdout is a pipe that the child will write to
+        );
+      	$process = proc_open($command, $descriptorspec, $pipes);
+        if (is_resource($process)) {
+          $ret = true;
+          while (!feof($pipes[2])) {
+            $line = fgets($pipes[2],1024);
+            //myUtility::log($line, $logFileName);
+            if (preg_match('@: no such file or directory@', $line)) $ret = false;
+            if (preg_match('@^Error while opening codec for output stream@', $line)) $ret = false;
+            if (preg_match('@Unknown format@', $line)) $ret = false;
+          }
+          fclose($pipes[2]);
+          proc_close($process);
+          return $ret;
+        } else return false;
+      } catch (Exception $e) {
+        myUtility::log($e->getMessage(), $logFileName);
+        return false;
+      }
+    }
+
+    /**
+     * Get Video info
+     *
+     * @param unknown_type $movieName
+     * @return array of info
+     *   'ID_VIDEO_WIDTH' => width of video
+     *   'ID_VIDEO_HEIGHT' => height of video
+     *   'ID_LENGTH' => lengh of video (in second)
+     *   'ID_VIDEO_FORMAT' => video codec
+     *   'ID_AUDIO_FORMAT' => audio codec
+     */
+    public static function GetVideoInfo($movieName) {
+      try {
+        $logFileName = 'video_info.log';
+        $mplayer_cmd = sfConfig::get('app_mplayer_exe');
+
+    		// generate the Flash FLV version of the file
+      	// cif = 352x288
+      	$command = "$mplayer_cmd -identify " . escapeshellarg($movieName) ." -ao null -vo null -frames 0";
+      	//myUtility::log("\n\n\n********".$command, $logFileName);
+
+      	$descriptorspec = array(
+           0 => array("pipe", "r"),  // stdin is a pipe that the child will read from
+           1 => array("pipe", "w"),  // stdout is a pipe that the child will write to
+           2 => array("pipe", "w"),  // stdout is a pipe that the child will write to
+        );
+      	$process = proc_open($command, $descriptorspec, $pipes);
+        if (is_resource($process)) {
+          $ret = array();
+          while (!feof($pipes[1])) {
+            $line = fgets($pipes[1],1024);
+            //myUtility::log($line, $logFileName);
+            if (preg_match('@ID_VIDEO_FORMAT|ID_VIDEO_WIDTH|ID_VIDEO_HEIGHT|ID_AUDIO_FORMAT|ID_LENGTH@', $line)) {
+              $col = explode('=', trim($line));
+              $ret[$col[0]] = $col[1];
+            }
+          }
+          fclose($pipes[1]);
+          proc_close($process);
+          return $ret;
+        } else return false;
+      } catch (Exception $e) {
+        myUtility::log($e->getMessage(), $logFileName);
+        return array();
+      }
+    }
+
+    public static function SizeImage($maxWidth, $maxHW, $fileName, $thumbFileName, $allowBigger=true, $externalFileName=false) {
+      try {
+        $logFileName = 'convert_img.log';
+
+        $width = intval($maxWidth); $height = intval($maxHW);
+        if ($width==null || $height==null) return false;
+        if (false==$allowBigger) {
+          list($mwidth, $mheight) = myUtility::getImageSize($fileName, $externalFileName);
+          if ($mwidth==0 || $mheight==0) return  false;
+          $mwidth = intval($mwidth); $mheight = intval($mheight);
+          if ($mwidth<=$width && $mheight<=$height) {
+            $width = $mwidth;
+            $height = $mheight;
+          }
+        }
+
+        $img_cmd = sfConfig::get('app_convert_exe');
+        if ($externalFileName)
+          $fileName = '"'.$fileName.'"';
+        else
+          $fileName = escapeshellarg($fileName);
+      	$command = "$img_cmd -resize {$width}x{$height} -flatten -background white -verbose " . $fileName . ' ' . escapeshellarg($thumbFileName);
+      	//myUtility::log("Execute ".$command, $logFileName, "\n");
+
+      	$descriptorspec = array(
+           0 => array("pipe", "r"),  // stdin is a pipe that the child will read from
+           1 => array("pipe", "w"),  // stdout is a pipe that the child will write to
+        );
+      	$process = proc_open($command, $descriptorspec, $pipes);
+
+      	if (is_resource($process)) {
+      	  $ret = true;
+      	  while (!feof($pipes[1])) {
+            $line = fgets($pipes[1],1024);
+            //if ($line != '') myUtility::log($line, $logFileName);
+            if (preg_match('@missing an image filename@', $line)) $ret = false;
+          }
+          fclose($pipes[1]);
+      	  proc_close($process);
+      	  return $ret;
+      	}
+      	return false;
+      } catch (Exception $e) {
+        myUtility::log($e->getMessage(), $logFileName);
+        return false;
+      }
+    }
+
+    public static function FlvAddMeta($fileName) {
+      try {
+        $logFileName = 'meta_flv.log';
+        $img_cmd = sfConfig::get('app_flvtool2_exe');
+
+        $command = "$img_cmd -U " . escapeshellarg($fileName);
+        $descriptorspec = array(
+           0 => array("pipe", "r"),  // stdin is a pipe that the child will read from
+           1 => array("pipe", "w"),  // stdout is a pipe that the child will write to
+        );
+        //myUtility::log($command, $logFileName);
+        $process = proc_open($command, $descriptorspec, $pipes);
+
+        if (is_resource($process)) {
+          $ret = true;
+          while (!feof($pipes[1])) {
+            //myUtility::log($line, $logFileName);
+            $line = fgets($pipes[1],1024);
+          }
+          fclose($pipes[1]);
+          proc_close($process);
+          return $ret;
+        } else return false;
+      } catch (Exception $e) {
+        myUtility::log($e->getMessage(), $logFileName);
+        return false;
+      }
+    }
+
+    public static function getSWFImageSize($fileName) {
+      try {
+        $width = 640;
+        $height = 480;
+
+        $img_cmd =sfConfig::get('app_swfdump_exe');
+        $command = "$img_cmd -X -Y " . escapeshellarg($fileName);
+        $descriptorspec = array(
+           0 => array("pipe", "r"),  // stdin is a pipe that the child will read from
+           1 => array("pipe", "w"),  // stdout is a pipe that the child will write to
+        );
+        $process = proc_open($command, $descriptorspec, $pipes);
+
+        if (is_resource($process)) {
+          while (!feof($pipes[1])) {
+            $line = fgets($pipes[1],1024);
+            if (preg_match('@-X ([0-9]+) -Y ([0-9]+)@', $line, $size)) {
+              $width = intval($size[1]);
+              $height = intval($size[2]);
+            }
+          }
+          fclose($pipes[1]);
+          proc_close($process);
+        }
+        return array($width, $height);
+      } catch (Exception $e) {
+        return array($width, $height);
+      }
+    }
+
+    public static function getImageSize($fileName, $externalFile=false) {
+
+      $length = strlen($fileName);
+      $ext = $length>3?substr($fileName, $length-3, 3):'';
+      $ext = strtolower($ext);
+      if ($ext=='swf') return self::getSWFImageSize($fileName);
+      $width = 0;
+      $height = 0;
+
+      if ($externalFile)
+        $fileName = '"'.$fileName.'"';
+      else
+        $fileName = escapeshellarg($fileName);
+
+      $img_cmd = sfConfig::get('app_identify_exe');
+      $command = "$img_cmd -format %wx%h\\n " . $fileName;
+      $descriptorspec = array(
+         0 => array("pipe", "r"),  // stdin is a pipe that the child will read from
+         1 => array("pipe", "w"),  // stdout is a pipe that the child will write to
+      );
+      $process = proc_open($command, $descriptorspec, $pipes);
+
+      if (is_resource($process)) {
+        $ret = true;
+        while (!feof($pipes[1])) {
+          $line = trim(fgets($pipes[1],1024));
+          if (preg_match('@Improper image header@', $line)) $ret = false;
+          if (preg_match('@Not a JPEG file@', $line)) $ret = false;
+          if (preg_match('@no decode delegate for this image format@', $line)) $ret = false;
+          if ($line!=null) {
+            if ($width == null && preg_match('@([0-9]+)x([0-9]+)@', $line, $size)) {
+              $width = intval($size[1]);
+              $height = intval($size[2]);
+            }
+          }
+        }
+        fclose($pipes[1]);
+        proc_close($process);
+      } else $ret = false;
+      return array($width, $height);
+    }
+
+    public static function global_image_tag($fileName, $width, $height, $vars = null) {
+      $ext = myUtility::getFileExt($fileName);
+      switch ($ext) {
+        case 'swf':
+          return flash_tag($fileName, $width, $height, $vars, true);
+        default:
+          return image_tag($fileName, array('width'=>$width, 'height'=>$height));
+      }
+    }
+
+    public static function redirectWithCustomReferer($host, $retHost='', $param = null) {
+      echo "
+            <head>
+              <meta http-equiv='Content-Type' content='text/html; charset=utf-8' />
+            </head>
+            <form method='post' action='$host'>
+              <input type='hidden' id='ret' name='ret' value='$retHost'/>
+            </form>
+            Xin quÃœ vá» Äá»£i giÃ¢y lÃ¡t... Náº¿u trang web khÃŽng tá»± Äá»ng chuyá»n, hÃ£y <a href='#' onclick='submitform()'>Click vÃ o ÄÃ¢y</a>
+            <script>
+              function submitform() {
+                document.forms[0].submit();
+              }
+              window.setTimeout('submitform()',50);
+            </script>
+           ";
+      exit();
+    }
+
+    /**
+     * execute native sql
+     *
+     * @param unknown_type $sql
+     * @return array of rows, each row is an array of fields (no key)
+     */
+    public static function execSql($sql, $noResult = false) {
+      $criteria = new Criteria();
+      $dbMap = Propel::getDatabaseMap($criteria->getDbName());
+      $db = Propel::getDB($criteria->getDbName());
+
+      $con = Propel::getConnection($criteria->getDbName(), Propel::CONNECTION_READ);
+
+      $stmt = $con->prepare($sql);
+      $stmt->execute();
+      if ($noResult==true) return;
+      $rows = array();
+      try {
+        while ($row = $stmt->fetch(PDO::FETCH_NUM)) {
+          $rows[] = $row;
+        }
+      } catch (Exception $e) {}
+      $stmt->closeCursor();
+      return $rows;
+    }
+
+    public static function log($message, $fileName = 'blog.log', $prefix = '') {
+      if (null == self::$log_dir) self::$log_dir = sfConfig::get('sf_log_dir');
+      error_log($prefix.date('Y-m-d H:i:s ').substr(session_id(), 0, 5).' '.$message."\n", 3, self::$log_dir.'/'.$fileName);
+    }
+
+    public static function track_upload($message, $logFile) {
+      error_log(date('H:i:s ').$message."\n", 3, sfConfig::get('sf_web_dir').'/uploads/previews/upinfo/'.$logFile.'_'.date('Ymd').'.log');
+    }
+
+    /**
+     * Truncates +text+ to the length of +length+ and replaces the last three characters with the +truncate_string+
+     * if the +text+ is longer than +length+.
+     */
+    public static function mb_truncate_text($text, $length = 33, $truncate_string = '...', $truncate_lastspace = false)
+    {
+      if ($text == '') {
+        return '';
+      }
+
+      if (mb_strlen($text, 'utf8') > $length) {
+        $truncate_text = mb_substr($text, 0, $length - strlen($truncate_string), 'utf8');
+        if ($truncate_lastspace) {
+          $truncate_text = preg_replace('/\s+?(\S+)?$/', '', $truncate_text);
+        }
+
+        return $truncate_text.$truncate_string;
+      }
+      else {
+        return $text;
+      }
+    }
+
+    public static function htmlToText($str) {
+      $text = new html2text($str);
+      return $text->get_text();
+    }
+
+    /**
+     * Return first day of week that include $date
+     *
+     * @param string $date (not include time)
+     * @return string first day of week
+     */
+    public static function dateToWeek($date) {
+      $time = strtotime($date);
+      $dayOfWeek = date('w', $time);
+      return date('Y-m-d', strtotime("$date -$dayOfWeek day"));
+    }
+
+    /**
+     * Create random password
+     *
+     * @param int $lenght: length of random password
+     * @return password
+     */
+    public function create_password($length = 6)
+    {
+      $chars = '0123456789';
+      srand(time());
+      $pass = '';
+      for ($i = 0; $i < $length; $i++) {
+        $num = rand(0, strlen($chars)-1);
+        $pass .= $chars[$num];
+      }
+      return $pass;
+    }
+
+    public function getRealIpAddr() {
+      if (!empty($_SERVER['HTTP_CLIENT_IP'])) {   //check ip from share internet
+        $ip = $_SERVER['HTTP_CLIENT_IP'];
+      } elseif (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) {  //to check ip is pass from proxy
+        $ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
+      } else {
+        $ip = $_SERVER['REMOTE_ADDR'];
+      }
+      return $ip;
+    }
+
+    public function validate($filterclass, &$data, &$error) {
+      $filter = new $filterclass();
+      $filter->initialize(null);
+      return $filter->execute($data, $error);
+    }
+  }
+?>
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/lib/common/myZip.class.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/lib/common/myZip.class.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/lib/common/myZip.class.php	(revision 19)
@@ -0,0 +1,195 @@
+<?php
+
+class myFolder {
+  public $fileList = array();
+  public $dirList = array();
+
+  public function addFile($fileName, $fullFileName) {
+    $this->fileList[$fileName] = $fullFileName;
+  }
+
+  public function addFolder($dirName) {
+    $this->dirList[$dirName] = new myFolder();
+  }
+
+  public function &getFolder($dirName, &$folderList) {
+    $temp = @$this->dirList[$dirName];
+    if ($temp==null) {
+      $this->addFolder($dirName);
+      $folderList[] = $dirName;
+    }
+
+    return $this->dirList[$dirName];
+  }
+};
+
+class myListFile
+{
+  public $listFile;
+  public $listFileName = array();
+  public $listFileNameArray = array();
+  public $listFolder = array();
+  public $listFileSizeArray = array();
+  public $listFileSize = array();
+
+
+  public function myListFile() {
+    $this->listFile = new myFolder();
+  }
+
+  public function addFile($path, $att, $size = 0)
+  {
+    $path = str_replace("\\", '/', $path);
+    $pathArr = split('/', $path);
+    $fileName = '';
+    if ($att[0]!='D') $fileName = array_pop($pathArr);
+    $pathObj = &$this->listFile;
+    for ($i=0; $i<count($pathArr); $i++)
+      $pathObj = &$pathObj->getFolder($pathArr[$i], $this->listFolder);
+
+    if ($fileName!=null) {
+      $pathObj->addFile($fileName, $path);
+      $this->listFileName[$fileName] = $path;
+      $this->listFileNameArray[] = $path;
+      $this->listFileSizeArray[] = $size;
+      $this->listFileSize[$path] = $size;
+    }
+  }
+
+  public function isPPT(&$fileName) {
+    if (count($this->listFileName)==1) {
+      foreach ($this->listFileName as $fileName) {
+        return myUtility::getFileExt($fileName  ) == 'ppt';
+      }
+    }
+    return false;
+  }
+
+  public function findFile($extension, &$findSize)
+  {
+    if (!is_array($extension)) $extension = array($extension);
+    $ret = array();
+    $findSize = array();
+    $n = count($this->listFileNameArray);
+    for ($i = 0; $i < $n; $i++) {
+      $file = $this->listFileNameArray[$i];
+      if (in_array(myUtility::getFileExt($file), $extension)) {
+        $ret[] = $file;
+        $findSize[] = $this->listFileSizeArray[$i];
+      }
+    }
+    return $ret;
+  }
+
+  public function pregFindFile($pattern, &$findSize) {
+    $ret = array();
+    $findSize = array();
+    $n = count($this->listFileNameArray);
+    for ($i = 0; $i < $n; $i++) {
+      $file = $this->listFileNameArray[$i];
+      if (preg_match($pattern, $file)) {
+        $ret[] = $file;
+        $findSize[] = $this->listFileSizeArray[$i];
+      }
+    }
+    return $ret;
+  }
+};
+
+class myZip {
+  public static function Unzip($zipFile, $destFolder)
+  {
+    $zip_cmd = sfConfig::get('app_7z_exe');
+  	$command = "$zip_cmd x -y -p123456 -o" . escapeshellarg($destFolder) . ' ' . escapeshellarg($zipFile);
+  	$descriptorspec = array(
+       0 => array("pipe", "r"),  // stdin is a pipe that the child will read from
+       1 => array("pipe", "w"),  // stdout is a pipe that the child will write to
+       //2 => array("file", "/tmp/error-output.txt", "a") // stderr is a file to write to
+    );
+    //var_dump($command); exit();
+  	$process = proc_open($command, $descriptorspec, $pipes);
+
+  	if (is_resource($process)) {
+  	  while (!feof($pipes[1])) {
+        $line = fgets($pipes[1],1024);
+        if (preg_match('@Wrong password@', $line)) {
+          fclose($pipes[1]);
+          proc_close($process);
+          return false;
+        }
+      }
+      fclose($pipes[1]);
+  	  proc_close($process);
+  	}
+  }
+
+  /**
+   * Enter description here...
+   *
+   * @param string $zipFile
+   * @return myListFile
+   */
+  public static function ListFile($zipFile)
+  {
+    //$logFileName = 'zip.log';
+    $listFile = new myListFile();
+    $ext = myUtility::getFileExt($zipFile);
+    if ($ext!='zip' && $ext!='7z' && $ext!='rar' && $ext!='gzip' && $ext!='gz') {
+      $zipFile = str_replace("\\", '/', $zipFile);
+      $zipArray = split('/', $zipFile);
+      $zipFile = array_pop($zipArray);
+      $listFile->addFile($zipFile, '.', 0);
+      return $listFile;
+    }
+
+    $zip_cmd = sfConfig::get('app_7z_exe');
+    $descriptorspec = array(
+       0 => array("pipe", "r"),  // stdin is a pipe that the child will read from
+       1 => array("pipe", "w"),  // stdout is a pipe that the child will write to
+    );
+
+    ///////////////////////////////////////////////////////////////////////
+    // Check password
+    $command = "$zip_cmd l -slt -p123456 " . escapeshellarg($zipFile);
+    //myUtility::log("\n\n\n\n$command", $logFileName);
+  	$process = proc_open($command, $descriptorspec, $pipes);
+  	if (is_resource($process)) {
+  	  while (!feof($pipes[1])) {
+ 	      $s = fgets($pipes[1], 1024);
+ 	      //myUtility::log($s, $logFileName);
+        if (preg_match('@Wrong password|not supported archive|Encrypted = \+@', $s)) {
+          fclose($pipes[1]);
+          proc_close($process);
+          return $listFile;
+        }
+  	  }
+      fclose($pipes[1]);
+  	  proc_close($process);
+  	} else return $listFile;
+
+  	///////////////////////////////////////////////////////////////////////
+  	// Lay danh sach ten file
+    $command = "$zip_cmd l -p123456 " . escapeshellarg($zipFile);
+    //myUtility::log("\n\n\n\n$command", $logFileName);
+  	$process = proc_open($command, $descriptorspec, $pipes);
+
+  	if (is_resource($process)) {
+  	  while (!feof($pipes[1])) {
+        $s = fgets($pipes[1], 1024);
+        //myUtility::log($s, $logFileName);
+        if (preg_match('@Wrong password@', $s)) {
+          fclose($pipes[1]);
+          proc_close($process);
+          return $listFile;
+        }
+        if (preg_match('@[0-9]+\-[0-9]+\-[0-9]+ [0-9]+:[0-9]+:[0-9]+ (.....) +([0-9]+) +([0-9]+)?  (.*)$@', $s, $match)) {
+          $match[3] = preg_replace('@\r|\n@', '', $match[3]);
+          $listFile->addFile($match[4], $match[1], $match[2]);
+        }
+  	  }
+      fclose($pipes[1]);
+  	  proc_close($process);
+  	  return $listFile;
+  	} else return $listFile;
+  }
+};
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/lib/common/onlineUser.class.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/lib/common/onlineUser.class.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/lib/common/onlineUser.class.php	(revision 19)
@@ -0,0 +1,71 @@
+<?php
+class onlineUser {
+
+  protected static $instance = null;
+
+  public static function getInstance() {
+    if (self::$instance==null) {
+      self::$instance = new onlineUser();
+    }
+    return self::$instance;
+  }
+
+  public function addUser(sfMyUser $user) {
+    if (sfDatabaseSessionStorage::$is_bot) return;
+    $this->user = $user;
+    $pdo = sfDatabaseSessionStorage::$pdo;
+    $blog = blogStore::$blogId;
+    $time = time();
+
+    if ($user->isAuthenticated()) {
+      $id = $pdo->quote($user->getUserId());
+      $fullname = $pdo->quote($user->getUserFullname());
+      $pdo->exec("insert into online_user values($blog, $id, $fullname, $time) on duplicate key update ou_time=$time");
+    } else {
+      $crc = crc32(myUtility::getRealIpAddr());
+      $pdo->exec("insert into online_guest values($blog, $crc, $time) on duplicate key update og_time=$time");
+    }
+  }
+
+  public function removeCurrentUser() {
+    if ($this->user) {
+      if ($this->user->isAuthenticated()) {
+        sfDatabaseSessionStorage::$pdo->exec('delete from online_user where ou_userid = '.$this->user->getUserId());
+      } else {
+        $crc = crc32(myUtility::getRealIpAddr());
+        sfDatabaseSessionStorage::$pdo->exec('delete from online_guest where og_crc = '.$crc);
+      }
+    }
+  }
+
+  public function getOnlineUsers($baseLink, &$numGuest, &$numUser, $maxNum=100) {
+    $ret = '';
+    $bl_id = blogStore::$blogId;
+    $pdo = sfDatabaseSessionStorage::$pdo;
+    $numGuest = $pdo->query("select count(*) from online_guest where og_blog=$bl_id")->fetchColumn();
+    $numUser = $pdo->query("select count(*) from online_user where ou_blog=$bl_id")->fetchColumn();
+    $stmt = $pdo->query("select ou_userid, ou_user_fullname from online_user where ou_blog=$bl_id limit $maxNum");
+    while ($row = $stmt->fetch(PDO::FETCH_NUM)) {
+      $ret .= '<li>'.link_to($row[1], $baseLink.$row[0]).'</li>';
+    }
+    return $ret;
+  }
+
+  public function getAllOnlineUsers($baseLink, &$numGuest, &$numUser, $maxNum=100) {
+    $ret = '';
+    $bl_id = blogStore::$blogId;
+    $pdo = sfDatabaseSessionStorage::$pdo;
+    $numGuest = $pdo->query("select count(*) from sessions where ss_userid=0")->fetchColumn();
+    $numUser = $pdo->query("select count(*) from sessions where ss_userid>0")->fetchColumn();
+    $stmt = $pdo->query("select ss_userid, ss_user_fullname from sessions where ss_userid>0 limit $maxNum");
+    $order = 0;
+    while ($row = $stmt->fetch(PDO::FETCH_NUM)) {
+      if (++$order == 10) $ret .="<div id='user_online' style='display:none; cursor:pointer'>";
+      $ret .= '<li>'.link_to($row[1], $baseLink.$row[0]).'</li>';
+    }
+    if ($numUser>=10) {
+      $ret .="</div><span id='user_off' style=\"display:none; cursor:pointer\" onClick=\"document.getElementById('user_online').style.display='none';document.getElementById('user_on').style.display='inline';  document.getElementById('user_off').style.display='none'; \" > << </span>    <span style=\"cursor:pointer\" id='user_on' onClick=\"document.getElementById('user_online').style.display='inline'; document.getElementById('user_on').style.display='none';document.getElementById('user_off').style.display='inline'; \" > >> </span>";
+    } 
+    return $ret;
+  }
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/lib/common/sfDatabaseSessionStorage.class.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/lib/common/sfDatabaseSessionStorage.class.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/lib/common/sfDatabaseSessionStorage.class.php	(revision 19)
@@ -0,0 +1,139 @@
+<?php
+
+/* sfDatabaseSessionStorage
+ *
+ * @Author: Nguyen Phu Quang
+ *
+ */
+class sfDatabaseSessionStorage extends sfSessionStorage {
+
+  public static $new_session = true;
+  public static $is_bot = false;
+
+  private static $mysql_dsn;
+  private static $mysql_user;
+  private static $mysql_password;
+  public static $pdo;
+
+  /**
+   * Initialize this Storage.
+   *
+   * @param Context A Context instance.
+   * @param array   An associative array of initialization parameters.
+   */
+  public function initialize($context, $parameters = null) {
+
+    $parameters['auto_start'] = false;
+    parent::initialize($context, $parameters);
+    if (preg_match('@bot\.html|ia_archiver|msnbot|Slurp;@', @$_SERVER['HTTP_USER_AGENT']))
+      self::$is_bot = true;
+
+    self::$mysql_dsn = $parameters['session_dsn'];
+    self::$mysql_user = $parameters['session_user'];
+    self::$mysql_password = $parameters['session_password'];
+
+    // use this object as the session handler
+    session_set_save_handler(array($this, 'sessionOpen'),
+                             array($this, 'sessionClose'),
+                             array($this, 'sessionRead'),
+                             array($this, 'sessionWrite'),
+                             array($this, 'sessionDestroy'),
+                             array($this, 'sessionGC'));
+    session_start();
+  }
+
+  public function sessionOpen($path, $name) {
+     self::$pdo = new PDO(self::$mysql_dsn, self::$mysql_user, self::$mysql_password);
+  }
+
+  public function sessionClose() {
+    return true;
+  }
+
+  public function sessionDestroy($id) {
+    self::$pdo->exec('delete from sessions where ss_id="'.$id.'"');
+  }
+
+  public function sessionGC($lifetime) {
+    $last = time() - $lifetime;
+    self::$pdo->exec("delete from sessions where ss_time<$last");
+    self::$pdo->exec("delete from online_guest where og_time<$last");
+    self::$pdo->exec("delete from online_user where ou_time<$last");
+    return true;
+  }
+
+  /**
+   * Read a session.
+   *
+   * @param string A session ID.
+   *
+   * @return data from database if the session was read else returns string empty
+   *
+   */
+  public function sessionRead($id) {
+    if (self::$is_bot) return '';
+    $stmt = self::$pdo->query("select ss_data from sessions where ss_id='$id' limit 1");
+    if ($stmt && $row = $stmt->fetch(PDO::FETCH_NUM)) {
+      self::$new_session = false;
+      if ($row[0]=='vol_lock') {
+        sfContext::getInstance()->getResponse()->setCookie('vol_lock', 1, time()+86400*5);
+        $row[0] = '';
+      }
+      return $row[0];
+    }
+    return '';
+  }
+
+  /**
+   * Write session data.
+   *
+   * @param string A session ID.
+   * @param string A serialized chunk of session data.
+   *
+   * @return bool true, if the session was written, otherwise an exception is thrown.
+   */
+  public function sessionWrite($id, $data) {
+    if (self::$is_bot) return true;
+    $time = time();
+    $user = sfContext::getInstance()->getUser();
+    $userId = $user->getUserId();
+    $userName = $user->getUserName();
+    $fullname = $user->getUserFullname();
+
+    if (self::$new_session==false) {
+      self::$pdo->exec("update sessions set ss_userid=$userId, ss_username='$userName', ss_user_fullname='$fullname', ".
+      "ss_time=$time, ss_data='$data' where ss_id='$id'");
+    } else {
+      self::$pdo->exec("insert into sessions values('$id', $userId, '$userName', '$userFullname', $time, '$data')");
+      self::$new_session = false;
+    }
+    return true;
+  }
+
+  public static function kickUserByName($user_name, $lock=false) {
+    $user_name = self::$pdo->quote($user_name);
+    $stmt = self::$pdo->query('select ss_userid from sessions where ss_username='.$user_name.' limit 1');
+    if ($stmt && $row = $stmt->fetch(PDO::FETCH_NUM)) {
+      if ($lock==false) {
+        self::$pdo->exec('delete from sessions where ss_username='.$user_name);
+      } else {
+        self::$pdo->exec('update sessions set ss_data="vol_lock" where ss_username='.$user_name);
+      }
+      self::$pdo->exec('delete from online_user where ou_userid='.$row[0]);
+    }
+  }
+
+  /**
+   * Kick out an user
+   *
+   * @param string $session_id
+   */
+  public static function kickUser($session_id) {
+    self::connect_session_db();
+    $stmt = self::$pdo->query('select ss_userid from sessions where ss_id="'.$session_id.'"');
+    if ($stmt && $row = $stmt->fetch(PDO::FETCH_NUM) && $row[0] != 0) {
+      self::$pdo->exec('delete from sessions where ss_id="'.$session_id.'"');
+      self::$pdo->exec('delete from online_user where ou_userid='.$row[0]);
+    }
+  }
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/lib/common/sfEntryException.class.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/lib/common/sfEntryException.class.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/lib/common/sfEntryException.class.php	(revision 19)
@@ -0,0 +1,26 @@
+<?php
+  class sfEntryException extends sfException {
+    const NOT_FOUND = 1000;
+    const ERASED = 1001;
+    const CATEGORY_NOT_FOUND = 1002;
+    const LINK_DUPLICATE = 1003;
+
+    public $errorNum;
+    public function __construct($errorNum) {
+      $this->errorNum = $errorNum;
+      sfException::__construct($this->getEntryMessage(), $errorNum);
+    }
+
+    public function getEntryMessage() {
+      switch ($this->errorNum) {
+        case self::NOT_FOUND:
+          return 'TÃ i liá»u khÃŽng tá»n táº¡i';
+        case self::ERASED:
+          return 'TÃ i liá»u ÄÃ£ bá» xÃ³a';
+        case self::CATEGORY_NOT_FOUND:
+          return 'ChÆ°a lá»±a chá»n thÆ° má»¥c ÄÆ°a tÃ i liá»u lÃªn';
+        case self::LINK_DUPLICATE:
+          return 'TÃ i liá»u nÃ y ÄÃ£ ÄÆ°á»£c ÄÆ°a vÃ o má»t má»¥c khÃ¡c trong cÃ¹ng trang riÃªng';
+      }
+    }
+  }
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/lib/common/sfFilterValidator.class.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/lib/common/sfFilterValidator.class.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/lib/common/sfFilterValidator.class.php	(revision 19)
@@ -0,0 +1,37 @@
+<?php
+
+class sfFilterValidator extends sfValidator
+{
+	public static $filters = array(
+		'@\b(cáº·c|cáº¶c|lá»n|lá»n|buá»i|buá»i|cá»©t|cá»št|fuck|sex)\b@',
+		'@[^\w|Ä|Ä](ÄÃ©o|ÄÃo|ÄÃ©o|ÄÃo|Äá»t|Äá»t|Äá»t|Äá»t|á»a|á»a|Äá»¥|Äá»€|Äá»¥|Äá»€)[^\w]@',
+	);
+	public static $vnfilters = array(
+		'@\b(kiem tien tren mang|kiem tien online|hack tien|hack tai khoan|duong vat|am ho)\b@',
+		'@\b(dcm|dkm|vcl|vkl|cave|kak|may`|ma`y|bo may|me may|dit me|dit con me)\b@'
+	);
+
+	public function execute(&$value, &$error)
+  {
+    $error = $this->getParameterHolder()->get('filter_error');
+		$content = strtolower($value);
+		$content = str_replace('  ', ' ', $content);
+    $content = ' '.$content.' ';
+		foreach (self::$filters as $filter) {
+			if (preg_match($filter, $content)) return false;
+		}
+		$vncontent = myUtility::vietDecode(myUtility::htmlToText($content));
+		foreach (self::$vnfilters as $filter) {
+			if (preg_match($filter, $vncontent)) return false;
+		}
+		return true;
+	}
+
+  public function initialize($context, $parameters = null)
+  {
+    parent::initialize($context);
+    $this->getParameterHolder()->set('filter_error', 'Ná»i dung cÃ³ tá»« ngá»¯ khÃŽng phÃ¹ há»£p');
+    $this->getParameterHolder()->add($parameters);
+    return true;
+  }
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/lib/common/sfFullnameValidator.class.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/lib/common/sfFullnameValidator.class.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/lib/common/sfFullnameValidator.class.php	(revision 19)
@@ -0,0 +1,50 @@
+<?php
+
+class sfFullnameValidator extends sfStringValidator
+{
+  public function execute(&$fullname, &$error)
+  {
+    if (!parent::execute($fullname, $error)) return false;
+
+    $specical_char = '1234567890,.<>/?;:\'"`~!@#$%^&*()-_=+\\|[]{}';
+    for ($i = 0; $i < strlen($specical_char); $i++) {
+      $pos = stripos($fullname, $specical_char[$i]);
+      if ($pos !== false) {$error = 'Please do not enter special char'; return false;}
+    }
+
+    $fullname = mb_convert_case($fullname, MB_CASE_TITLE, "UTF-8");
+    $names = explode(' ', $fullname);
+    $count = count($names);
+    if($count < 2) {$error = 'Please enter exact your fullname'; return false;}
+
+    $cousin = $names[0];
+    $surnames = array(
+    "Bui", "Dam", "Dao", "Duong", "Do", "Doan", "Dang", "Dinh",
+    "Ha", "Ho", "Hoang", "Huynh", "Kieu", "Khong", "Le", "Luu",
+    "Luong", "Ly", "Nguyen", "Ngo", "Ta", "Thai", "Tran", "Trinh",
+    "Ton", "Tong", "Truong", "Pham", "Vo", "Vu", "Vuong");
+    if (in_array($cousin, $surnames)) {$error = 'Please enter in Vietnamese'; return false;}
+
+    $surnamesVietcode = array(
+    //---- VNI code ---
+    "BuÃži", "ÃaÃžm", "ÃaÃžo", "DÃ¶ÃŽng", "ÃoÃ£", "ÃoaÃžn", "ÃaÃ«ng", "Ãinh",
+    "HaÃž", "HoaÃžng", "HuyÃžnh", "KieÃ u", "KhoÃ¥ng", "LeÃ¢", "LÃ¶u",           // thiáº¿u "HoÃ " (Há»)
+    "LÃ¶ÃŽng", "LyÃ¹", "NguyeÃ£n", "NgoÃ¢", "TaÃ¯", "ThaÃ¹i", "TraÃ n", "TrÃ²nh",
+    "ToÃ¢n", "TrÃ¶ÃŽng", "PhaÃ¯m", "VoÃµ", "VuÃµ", "VÃ¶ÃŽng",                     // thiáº¿u "ToÃ¡ng" (Tá»ng)
+    //---- TCVN3 code ----
+    "BÃ¯i", "Â§Îm", "Â§Îo", "DÂ­Â¬Ng", "Â§Ã", "Â§OÂµn", "Â§Ãng", "Â§Inh",
+    "Â®Îm", "Â®Îo", "Â®Ã", "Â®OÂµn", "Â®Ãng", "Â®Inh",
+    "HÂµ", "HÃ¥", "HoÂµng", "HuÃºnh", "KiÃ²u", "KhÃŠng", "LÂª", "LÂ­U",
+    "LÂ­Â¬Ng", "NguyÃŽn", "NgÂ«", "TÂ¹", "ThÂži", "TrÃ§n", "TrÃŸnh",              // thiáº¿u "LÃœ" (LÃœ)
+    "TÂ«N", "TrÂ­Â¬Ng", "PhÂ¹M", "VÃ¢", "VÂ­Â¬Ng");                              // thiáº¿u "TÃšng" (Tá»ng) vÃ  "VÃ²" (VÅ©)
+    if (in_array($cousin, $surnamesVietcode)) {$error = 'Please disable the Viet Typing program and input again'; return false;}
+
+    for ($i = 0; $i < $count; $i++){
+      if ($names[$i] == '') continue;
+      if ($i == 0) $fullname = $names[$i] ;
+      else $fullname .= ' '.$names[$i];
+    }
+
+    return true;
+  }
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/lib/common/sfIdnumberValidator.class.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/lib/common/sfIdnumberValidator.class.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/lib/common/sfIdnumberValidator.class.php	(revision 19)
@@ -0,0 +1,10 @@
+<?php
+
+class sfIdnumberValidator extends sfValidator
+{
+  public function execute(&$idno, &$error)
+  {
+    $error = "Sá» CMND khÃŽng ÄÃºng chuáº©n";
+    return preg_match('/^\d{9,12}$/', $idno);
+  }
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/lib/common/sfMyUser.class.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/lib/common/sfMyUser.class.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/lib/common/sfMyUser.class.php	(revision 19)
@@ -0,0 +1,208 @@
+<?php
+
+class sfMyUser extends sfBasicSecurityUser
+{
+  public function initialize($context, $parameters = null)
+  {
+    parent::initialize($context, $parameters);
+
+    $storage = $this->getContext()->getStorage();
+    $time = $storage->read(parent::LAST_REQUEST_NAMESPACE);
+    if ($time == null && !$this->isAuthenticated()) $this->autoLogin();
+
+    if ($this->isAuthenticated()) {
+      $ip = myUtility::getRealIpAddr();
+      $storeip = $this->getAttribute('userip', null, 'user');
+      if ($storeip == null) $this->setAttribute('userip', $ip, 'user');
+      else if ($storeip != $ip) {
+        $this->setAuthenticated(false);
+        session_regenerate_id(true);
+      }
+    }
+  }
+
+  public function rememberLogin($user, $remember = false) {
+    $value = $remember? base64_encode(serialize(array($user->getUsKey(), $user->getUsId()))): '';
+    sfContext::getInstance()->getResponse()->setCookie('tvtl', $value, time() + 86400*15, '/');
+  }
+
+  public function autoLogin() {
+    $remember = sfContext::getInstance()->getRequest()->getCookie('tvtl');
+    if (!$remember) return;
+    $info = unserialize(base64_decode($remember));
+    if (is_array($info) && count($info)==2) {
+      $c = new Criteria();
+      $c->add(TbluserPeer::US_KEY, $info[0]);
+      $c->add(TbluserPeer::US_ID, $info[1]);
+      $tbluser = TbluserPeer::doSelectOne($c);
+      try {
+        if ($tbluser!=null) $this->signIn($tbluser);
+      } catch (Exception $e) {}
+    }
+  }
+
+  public function signIn($user) {
+    $user->getObject()->checkUserLock();
+    if (class_exists('sfDatabaseSessionStorage', false)) sfDatabaseSessionStorage::kickUserByName($user->getUsUsername());
+    $this->setAuthenticated(true);
+    $this->setAttribute('userid', $user->getUsId(), 'user');
+    $this->setAttribute('username', $user->getUsUsername(), 'user');
+    $this->setAttribute('userfullname', $user->getUsFullname(), 'user');
+    $this->setAttribute('usertitle', $user->getObject()->getTitle(), 'user');
+    $this->setAttribute('aclgroup', $user->getUsAclgroup(), 'user');
+    $this->setAttribute('password', $user->getUsPassword(), 'user');
+
+    if ($user->getUsAclgroup()=='1' || $user->getUsAclgroup()=='2') {
+        $this->addCredential('moderator');
+    }
+    $this->addCredential('user');
+    $user->getObject()->onLogin();
+  }
+
+  public function signOut()
+  {
+    onlineUser::getInstance()->removeCurrentUser();
+    $this->getAttributeHolder()->removeNamespace('user');
+
+    $this->clearVote();
+    $this->clearBlogmember();
+    $this->setAuthenticated(false);
+    $this->clearCredentials();
+  }
+
+  public function isAdministrator()
+  {
+  	return $this->isAuthenticated() && $this->getAttribute('aclgroup', '', 'user') == '1';
+  }
+
+  public function getUserId() {
+    if ($this->isAuthenticated()) return $this->getAttribute('userid', '', 'user');
+    else return 0;
+  }
+
+  public function getUserName() {
+    if ($this->isAuthenticated()) return $this->getAttribute('username', '', 'user');
+    else return '';
+  }
+
+  public function getUserFullname() {
+    if ($this->isAuthenticated()) return $this->getAttribute('userfullname', '', 'user');
+    else return '';
+  }
+
+  public function getUserTitle() {
+    if ($this->isAuthenticated()) return $this->getAttribute('usertitle', '', 'user');
+    else return '';
+  }
+
+  /**
+   * return type of sort of current user (date/download/rate)
+   */
+  public function getUserSort() {
+    $request = sfContext::getInstance()->getRequest();
+    $sort = $request->getCookie('sort');
+    $sort = $request->getParameter('sort');
+    if ($sort==null) $sort = $request->getCookie('sort', 'date');
+    else sfContext::getInstance()->getResponse()->setCookie('sort', $sort);
+    return $sort;
+  }
+
+  public function setUserSort($sort) {
+    if ($sort == '') {
+      $sort = $this->getRequest()->getCookie('sort');
+      if ($sort != null) return;
+      $sort = 'date';
+    }
+    sfContext::getInstance()->getResponse()->setCookie('sort', $sort, time()+60*60*24*15, '/');
+  }
+
+  public function setIsRegistering($referer) {
+    if ($referer==null) {
+      $referer = sfContext::getRequest()->getReferer();
+    }
+    return $this->setAttribute('regrefer', $referer, 'user');
+  }
+
+  public function getIsRegistering() {
+    return null!=$this->getAttribute('regrefer', null, 'user');
+  }
+
+  public function getRegisterReferer() {
+    return $this->getAttribute('regrefer', null, 'user');
+  }
+
+  public function hasCredential($credentials, $useAnd = true)
+  {
+    $ret = true;
+    if ((is_array($credentials) && $i = in_array('blogadmin', $credentials)) || $credentials=='blogadmin') {
+      $ret = $this->isAdministrator() || (blogStore::$userId == blogStore::$blog->getBlUser());
+      if (@$i) unset($credentials[$i]); else $credentials = array();
+    }
+    return $ret && sfBasicSecurityUser::hasCredential($credentials, $useAnd);
+  }
+
+  /**
+   * return true if this user is member of blog
+   *
+   * @return bool
+   */
+  public function isBlogMember() {
+    if (!class_exists('blogStore')) return false;
+    if (!$this->isAuthenticated()) return false;
+    $isMember = $this->getAttribute('ismember'.blogStore::$blogId);
+    if ($isMember===null) {
+      $tblbloguser = TblbloguserPeer::retrieveByPK(blogStore::$blogId, blogStore::$userId);
+      if ($tblbloguser == null) {
+        $this->setIsBlogMember(false);
+      } else {
+        $this->setIsBlogMember($tblbloguser->getUsRole());
+      }
+      return $this->getAttribute('ismember'.blogStore::$blogId);
+    } else return $isMember;
+  }
+
+  /**
+   * Set current user is member of blog ($user_id==1) or not ($user_id==0)
+   *
+   * @param unknown_type $user_id
+   */
+  public function setIsBlogMember($is_member) {
+    $this->setAttribute('ismember'.blogStore::$blogId, $is_member);
+  }
+
+  /**
+   * Clear blogmember cookie information
+   *
+   */
+  public function clearBlogmember() {
+    if (!class_exists('blogStore')) return;
+    $this->getAttributeHolder()->remove('ismember'.blogStore::$blogId);
+  }
+
+  /**
+   * return status vote
+   * false: never vote yet
+   * true: voted
+   * null: Nothing to vote
+   */
+  public function isVote() {
+    if (blogStore::$tblblogpoll==null) return null;
+    $cookieName = 'isvote'.blogStore::$tblblogpoll->getPollId();
+    $isvote = $this->getAttribute($cookieName);
+    if ($isvote === null) {
+      $c = new Criteria();
+      $c->add(TblblogpolldataPeer::PD_POLL, blogStore::$tblblogpoll->getPollId());
+      $c->add(TblblogpolldataPeer::PD_IP, $_SERVER['REMOTE_ADDR']);
+      $num = TblblogpolldataPeer::doCount($c);
+      $this->setAttribute($cookieName, $num>0?1:0);
+      return $num>0;
+    } else return $isvote==1;
+  }
+
+  public function clearVote() {
+    if (!class_exists('blogStore')) return;
+    if (blogStore::$tblblogpoll==null) return;
+    $cookieName = 'isvote'.blogStore::$tblblogpoll->getPollId();
+    $this->getAttributeHolder()->remove($cookieName);
+  }
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/lib/common/sfPhoneValidator.class.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/lib/common/sfPhoneValidator.class.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/lib/common/sfPhoneValidator.class.php	(revision 19)
@@ -0,0 +1,10 @@
+<?php
+
+class sfPhoneValidator extends sfValidator
+{
+  public function execute(&$phone, &$error)
+  {
+    $error = "Sá» Äiá»n thoáº¡i khÃŽng ÄÃºng chuáº©n";
+    return preg_match('/^(09\d{8}|01\d{9})$/', $phone);
+  }
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/lib/common/userBase.class.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/lib/common/userBase.class.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/lib/common/userBase.class.php	(revision 19)
@@ -0,0 +1,123 @@
+<?php
+
+class userBase {
+
+  const MAX_PLUS_POINT = 30;
+
+  protected $user;
+
+  public function userBase($user) {
+    $this->user = $user;
+  }
+
+  public function getTitle() {
+    return '';
+  }
+
+  public function getAvatar($type = 'avatar', $options = array()) {
+    $avatar = $this->user->getUsAvatar();
+    if (strpos($avatar, ':') !== false) {
+      $avatars = unserialize($avatar);
+      $avatar = $avatars[($type=='avatar'? 0: 1)][0];
+    }
+    if ($avatar == null) {
+      $mf = ($this->user->getUsSex()==2? 'f': '');
+      $avatar = "no_$type$mf.jpg";
+    }
+    return image_tag(sfConfig::get('app_thumbnail_root').$this->getAvatarPath($type, false).$avatar, $options);
+  }
+
+  public function getHtmlName($avatar = false, $homepage = false) {
+    if ($this->user->getUsId() == null) return "KhÃŽng rÃµ";
+    $html = '';
+    $link = '/user/show?id='.$this->user->getUsId();
+    if ($avatar) {
+      $avalink = link_to($this->getAvatar('avatar', array('style'=>'float:left', 'width'=>'30px', 'height'=>30)), $link);
+      $html .= content_tag('div', $avalink, array('class'=>'ava'));
+    }
+    $html .= link_to($this->user->getUsFullname(), $link);
+    if ($homepage) {
+        $url = $this->user->getUsHomepage();
+        if ($url) $html .= ' ('.link_to('trang riÃªng', $url).')';
+    }
+    return $html;
+  }
+
+  public function getAvatarPath($type = 'avatar', $absolute = true) {
+    return sfConfig::get($absolute? 'sf_upload_dir': 'sf_upload_dir_name')."/thumbnails/$type/";
+  }
+
+  public function SaveAvatar($action) {
+    $us_id = $this->user->getUsId();
+    $avatar = $us_id.'.jpg';
+    $this->user->setUsAvatar($avatar);
+    $fileName1 = $this->getAvatarPath('avatar').$avatar;
+    $fileName2 = $this->getAvatarPath('photo').$avatar;
+
+    $tempFile = $action->getRequest()->CopyTempFile($action->uploaded, "user_{$us_id}_picture.jpg");
+    list($width, $height) = @getimagesize($tempFile);
+    if ($width/$height < 163/187) myUtility::SizeImage(150, 200, $tempFile, $fileName2);
+    else if ($width/$height > 187/163) myUtility::SizeImage(200, 150, $tempFile, $fileName2);
+    else myUtility::SizeImage(175, 175, $tempFile, $fileName2);
+    myUtility::SizeImage(60, 60, $tempFile, $fileName1);
+    myUtility::track_upload($fileName1, 'thumbnails');
+    myUtility::track_upload($fileName2, 'thumbnails');
+    unlink($tempFile);
+  }
+
+  public function checkUserLock() {
+    /*
+    if (sfContext::getInstance()->getRequest()->getCookie('vol_lock')==1) {
+      throw new Exception('MÃ¡y tÃ­nh nÃ y ÄÃ£ bá» khÃ³a truy cáº­p');
+    }
+    */
+
+    // Check whether user can signIn or not
+    switch ($this->user->getUsStatus()) {
+      case 4:
+      case 5:
+      case 6:
+      case 7:
+        if (strtotime($this->user->getUsLastvisited()) > time()) {
+          throw new Exception('TÃ i khoáº£n nÃ y bá» khÃ³a Äáº¿n '.$this->user->getUsLastvisited('H:i d-m-Y'));
+        }
+        else $this->user->setUsStatus($this->user->getUsStatus() - 4);
+        break;
+      case 8:
+        sfContext::getInstance()->getResponse()->setCookie('vol_lock', 1, time() + 86400*5);
+        throw new Exception('TÃ i khoáº£n nÃ y ÄÃ£ bá» khÃ³a vÄ©nh viá»
+n');
+        break;
+    }
+
+    sfDatabaseSessionStorage::kickUserByName($this->user->getUsUsername());
+  }
+
+  public function onLogin() {
+    // cá»ng Äiá»m trong láº§n ÄÄng nháº­p Äáº§u tiÃªn cá»§a tuáº§n
+    $lastvisited = $this->user->getUsLastvisited();
+    if ($lastvisited != null && date("W", strtotime($lastvisited)) != date("W")) {
+      $maxPlus = self::MAX_PLUS_POINT;
+      $download = explode(',', $this->user->getUsDownload());
+      $plus = min(intval($download[0]), $maxPlus);
+      $plus = max($plus, $maxPlus - $this->user->getUsScore());
+      $this->user->setUsPointPlus($this->user->getUsPointPlus() + $plus);
+      $this->user->setUsScore($this->user->getUsScore() + $plus);
+      $download[0] = 0;
+      $this->user->setUsDownload(implode(',', $download));
+    }
+
+    $this->user->setUsLastvisited(date('Y-m-d H:i:s'));
+    $this->user->save();
+    myUtility::log('['.$this->user->getUsId().']: '.myUtility::getRealIpAddr(), 'login.log');
+  }
+
+  public static function getUserObject($user) {
+    $tblcheckinfo = $user->getTblblogcheckinfo();
+    if (!$tblcheckinfo) return new userBase($user);
+
+    $position = $tblcheckinfo->getCiPosition();
+    if ($position < 40) return new userTeacher($user);
+    else return new userBase($user);
+  }
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/lib/common/userMessage.class.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/lib/common/userMessage.class.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/lib/common/userMessage.class.php	(revision 19)
@@ -0,0 +1,103 @@
+<?php
+
+class userMessage {
+
+  public static $lastMessage = '';
+
+  /**
+   * Create confirm email for register user or user has not been activate
+   * or user who has email cannot be sent (mail system failed)
+   *
+   * @param Tbluser $tbluser
+   * @param String $password: User password, get password from $tbluser
+   * @return myMail
+   */
+
+  public static function sendConfirmEmail($tbluser, $password=null) {
+    $fullname = $tbluser->getUsFullname();
+    $link = sfContext::getInstance()->getController()->genUrl('/user/confirm?active='.md5($tbluser->getUsId()), true);
+
+    $mail = new myMail();
+    $mail->addAddress($tbluser->getUsEmail(), $fullname);
+    $mail->setSubject('Xac nhan thong tin dang ky tai Thu vien truc tuyen Violet');
+    $mail->setBody(
+
+    'KÃ­nh chÃ o '.$fullname.' !<br />'.
+    'QuÃœ vá» ÄÃ£ ÄÄng kÃœ thÃ nh viÃªn táº¡i ThÆ° viá»n trá»±c tuyáº¿n Violet, xin vui lÃ²ng:<br />'.
+    '<b><a href="'.$link.'">nháº¥n vÃ o ÄÃ¢y Äá» xÃ¡c nháº­n thÃŽng tin ÄÄng kÃœ lÃ  chÃ­nh xÃ¡c</a></b><br /><br />'.
+    'Tá»« cÃ¡c láº§n sau quÃœ vá» cÃ³ thá» ÄÄng nháº­p vá»i:<br />'.
+    'TÃªn truy nháº­p: <b>'.$tbluser->getUsUsername().'</b><br />'.
+    ($password? 'Máº­t kháº©u: <b>'.$password.'</b><br />': '').
+    '<br /><br />'.
+    'Neu quy vi khong doc duoc Tieng Viet co dau, day la ban Tieng Viet khong dau:<br />'.
+    'Kinh chao '.myUtility::vietDecode($fullname).'!<br />'.
+    'Quy vi da dang ky thanh vien tai Thu vien truc tuyen Violet, xin vui long:<br />'.
+    '<b><a href="'.$link.'">nhan vao day de xac nhan thong tin dang ky la chinh xac</a></b><br /><br />'.
+    'Tu cac lan sau quy vi co the dang nhap voi:<br />'.
+    'Ten truy nhap: <b>'.$tbluser->getUsUsername().'</b><br/>'.
+    ($password? 'Mat khau: <b>'.$password.'</b><br />': ''));
+
+    $sendResult = $mail->send();
+    self::$lastMessage = ($sendResult == true)?
+    'ThÆ° xÃ¡c nháº­n vá»«a ÄÆ°á»£c gá»­i vÃ o Äá»a chá» <font color="blue">'.$tbluser->getUsEmail().'</font><br/>'.
+    'HÃ£y má» e-mail vÃ  nháº¥n vÃ o ÄÆ°á»ng liÃªn káº¿t trong ÄÃ³. LÆ°u Ãœ lÃ  pháº£i tÃ¬m trong cáº£ pháº§n ThÆ° Äáº¿n (Inbox) vÃ  ThÆ° rÃ¡c (Spam, Bulk)<br/>'.
+    'Sau ÄÃ³ nháº¥n vÃ o nÃºt dÆ°á»i ÄÃ¢y Äá» ÄÄng nháº­p<br/><br/>'
+    :
+    '<p>Xin lá»i, hiá»n táº¡i chÃºng tÃŽi chÆ°a thá» gá»­i ÄÆ°á»£c email.<br />'.
+    'Tuy nhiÃªn quÃœ vá» cÃ³ thá» sá»­ dá»¥ng chá»©c nÄng "gá»­i láº¡i email xÃ¡c nháº­n" '.
+    'hiá»n ra trong nhá»¯ng láº§n ÄÄng nháº­p vá» sau</p>';
+
+    return $sendResult;
+  }
+
+  public static function sendForgotPassEmail($tbluser) {
+    $fullname = $tbluser->getUsFullname();
+    $us_pass = myUtility::create_password();
+    $link = sfContext::getInstance()->getController()->genUrl('/user/requestpass?pwd='.md5($us_pass).
+    '&mail='.md5($tbluser->getUsEmail()).'&rand='.md5($tbluser->getUsPassword()).'&id='.$tbluser->getUsId() , true);
+
+    $mail = new myMail();
+    $mail->addAddress($tbluser->getUsEmail(), $fullname);
+    $mail->setSubject('Thong tin thanh vien tai Thu vien truc tuyen Violet');
+    $mail->setBody(
+
+    'KÃ­nh chÃ o '.$fullname.'!<br />'.
+    'Náº¿u quÃœ vá» ÄÃ£ sá»­ dá»¥ng chá»©c nÄng <i>QuÃªn máº­t kháº©u</i> trong ThÆ° viá»n Violet,<br />'.
+    'xin vui lÃ²ng <a href="'.$link.'"><b>nháº¥n vÃ o ÄÃ¢y Äá» táº¡o láº¡i máº­t kháº©u</b></a><br /><br />'.
+    'Sau khi táº¡o láº¡i máº­t kháº©u, quÃœ vá» sáºœ ÄÄng nháº­p vá»i<br />'.
+    'TÃªn truy nháº­p: <b>'.$tbluser->getUsUsername().'</b><br />'.
+    'Máº­t kháº©u: <b>'.$us_pass.'</b><br /><br />'.
+    'Xin trÃ¢n trá»ng cáº£m Æ¡n<br />'.
+    '=======================================<br />'.
+    '<br /><br />'.
+    'Neu quy vi khong doc duoc Tieng Viet co dau, day la ban Tieng Viet khong dau:<br />'.
+    'Kinh chao '.myUtility::vietDecode($fullname).'!<br />'.
+    'Neu quy vi da su dung chuc nang <i>Quen mat khau</i> trong Thu vien Violet,<br />'.
+    'xin vui long <a href="'.$link.'"><b>nhan vao day de tao lai mat khau</b></a><br /><br />'.
+    'Sau khi tao lai mat khau, quy vi se dang nhap voi<br />'.
+    'Ten truy nhap: <b>'.$tbluser->getUsUsername().'</b><br />'.
+    'Mat khau: <b>'.$us_pass.'</b><br /><br />'.
+    'Xin tran trong cam on<br />');
+
+    $sendResult = $mail->send();
+    self::$lastMessage = ($sendResult == true)?
+    '<p>Email táº¡o máº­t kháº©u má»i ÄÃ£ ÄÆ°á»£c gá»­i tá»i <font color="blue">'.$us_mail.'</font><br/>'.
+    'HÃ£y má» e-mail vÃ  nháº¥n vÃ o ÄÆ°á»ng liÃªn káº¿t trong ÄÃ³<br/> '.
+    'LÆ°u Ãœ lÃ  pháº£i tÃ¬m trong cáº£ pháº§n <font color="blue">ThÆ° Äáº¿n (Inbox)</font> vÃ  <font color="blue">ThÆ° rÃ¡c (Spam, Bulk)</font></p>'
+    :
+    '<p>Xin lá»i, hiá»n táº¡i chÃºng tÃŽi chÆ°a thá» gá»­i ÄÆ°á»£c email.<br />'.
+    'HÃ£y soáº¡n email tiÃªu Äá» lÃ  "Äá» nghá» Äá»i máº­t kháº©u" vÃ  ná»i dung lÃ  máº­t kháº©u má»i cá»§a quÃœ vá», sau ÄÃ³ '.
+    'gá»­i vÃ o Äá»a chá» hotro@violet.vn. ChÃºng tÃŽi sáºœ Äá»i cho quÃœ vá» trong vÃ²ng 12h</p>';
+
+    return $sendResult;
+  }
+
+  public static function registerSucessMessage($tbluser) {
+    return
+    '<p>ChÃºc má»«ng quÃœ vá» ÄÃ£ lÃ  thÃ nh viÃªn cá»§a ThÆ° viá»n</p>'.
+    '<p>Tá»« nay, quÃœ vá» cÃ³ thá» ÄÄng nháº­p vÃ o ThÆ° viá»n vá»i tÃªn truy nháº­p '.
+    '<font color="blue">'.$tbluser->getUsUsername().'</font> vÃ  máº­t kháº©u vá»«a ÄÄng kÃœ</p>'.
+    '<p>Vui lÃ²ng nháº¥n vÃ o dÃ²ng chá»¯ dÆ°á»i ÄÃ¢y Äá» báº¯t Äáº§u ÄÄng nháº­p</p>';
+  }
+}
+?>
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/lib/common/userTeacher.class.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/lib/common/userTeacher.class.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/lib/common/userTeacher.class.php	(revision 19)
@@ -0,0 +1,11 @@
+<?php
+
+class userTeacher extends userBase {
+
+  public function getTitle() {
+    $sex = $this->user->getUsSex();
+    if ($sex == 2) return 'cÃŽ giÃ¡o';
+    if ($sex == 1) return 'tháº§y';
+    return '';
+  }
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/lib/model/Tblblogcheckinfo.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/lib/model/Tblblogcheckinfo.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/lib/model/Tblblogcheckinfo.php	(revision 19)
@@ -0,0 +1,50 @@
+<?php
+
+/**
+ * Subclass for representing a row from the 'tblblogcheckinfo' table.
+ *
+ * 
+ *
+ * @package lib.model
+ */ 
+class Tblblogcheckinfo extends BaseTblblogcheckinfo
+{
+	/**
+	 * Initializes internal state of Tblblogcheckinfo object.
+	 * @see        parent::__construct()
+	 */
+	public function __construct()
+	{
+		// Make sure that parent constructor is always invoked, since that
+		// is where any default values for this object are set.
+		parent::__construct();
+	}
+
+  public function getCiBadgeTitle() {
+    $badgeid = explode(',', $this->getCiBadge());
+    if (!isset($badgeid[0])) $badgeid[0] = 0;
+    if (!isset($badgeid[1])) $badgeid[1] = 0;
+    if (!isset($badgeid[2])) $badgeid[2] = 0;
+    return
+      blogStore::$acad_title[1][$badgeid[0]] .
+      blogStore::$diploma[1][$badgeid[1]] .
+      blogStore::$badge[1][$badgeid[2]];
+  }
+
+  public function getCiSubjectTitle() {
+    $sub_id = explode(',', $this->getCiSubject());
+    $subject = '';
+    foreach ($sub_id as $id) {
+      $sub1 = @blogStore::$subject1[$id];
+      $sub2 = @blogStore::$subject2[$id];
+      $subject .= ($subject==''? '': ', ').($sub1? $sub1: $sub2);
+    }
+    return $subject;
+  }
+
+  public function getCiPositionTitle() {
+    $pos = $this->getCiPosition();
+    if ($pos) return blogStore::$position[$pos];
+    else return '';
+  }
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/lib/model/TblblogcheckinfoPeer.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/lib/model/TblblogcheckinfoPeer.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/lib/model/TblblogcheckinfoPeer.php	(revision 19)
@@ -0,0 +1,12 @@
+<?php
+
+/**
+ * Subclass for performing query and update operations on the 'tblblogcheckinfo' table.
+ *
+ * 
+ *
+ * @package lib.model
+ */ 
+class TblblogcheckinfoPeer extends BaseTblblogcheckinfoPeer
+{
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/lib/model/Tblspacecategory.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/lib/model/Tblspacecategory.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/lib/model/Tblspacecategory.php	(revision 19)
@@ -0,0 +1,23 @@
+<?php
+
+/**
+ * Subclass for representing a row from the 'tblspacecategory' table.
+ *
+ * 
+ *
+ * @package lib.model
+ */ 
+class Tblspacecategory extends BaseTblspacecategory
+{
+	/**
+	 * Initializes internal state of Tblspacecategory object.
+	 * @see        parent::__construct()
+	 */
+	public function __construct()
+	{
+		// Make sure that parent constructor is always invoked, since that
+		// is where any default values for this object are set.
+		parent::__construct();
+	}
+
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/lib/model/TblspacecategoryPeer.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/lib/model/TblspacecategoryPeer.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/lib/model/TblspacecategoryPeer.php	(revision 19)
@@ -0,0 +1,12 @@
+<?php
+
+/**
+ * Subclass for performing query and update operations on the 'tblspacecategory' table.
+ *
+ * 
+ *
+ * @package lib.model
+ */ 
+class TblspacecategoryPeer extends BaseTblspacecategoryPeer
+{
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/lib/model/Tblspacefile.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/lib/model/Tblspacefile.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/lib/model/Tblspacefile.php	(revision 19)
@@ -0,0 +1,40 @@
+<?php
+
+/**
+ * Subclass for representing a row from the 'tblspacefile' table.
+ *
+ * 
+ *
+ * @package lib.model
+ */ 
+class Tblspacefile extends BaseTblspacefile
+{
+	/**
+	 * Initializes internal state of Tblspacefile object.
+	 * @see        parent::__construct()
+	 */
+	public function __construct()
+	{
+		// Make sure that parent constructor is always invoked, since that
+		// is where any default values for this object are set.
+		parent::__construct();
+	}
+
+  public function setFileName($v) {
+    parent::setFileName($v);
+    $dotPos = strrpos($v, '.');
+    if ($dotPos !== false) $this->setFileType(strtolower(substr($v, $dotPos + 1)));
+  }
+
+  public function delete(PropelPDO $con = null) {
+    $resId = $this->getFileResource();
+    parent::delete($con);
+
+    $c1 = new Criteria();
+    $c1->add(TblspacefilePeer::FILE_RESOURCE, $resId);
+    if (TblspacefilePeer::doCount($c1) == 0) {
+      $tblres = TblspaceresourcePeer::retrieveByPk($resId);
+      $tblres->delete($con);
+    }
+  }
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/lib/model/TblspacefilePeer.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/lib/model/TblspacefilePeer.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/lib/model/TblspacefilePeer.php	(revision 19)
@@ -0,0 +1,12 @@
+<?php
+
+/**
+ * Subclass for performing query and update operations on the 'tblspacefile' table.
+ *
+ * 
+ *
+ * @package lib.model
+ */ 
+class TblspacefilePeer extends BaseTblspacefilePeer
+{
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/lib/model/Tblspaceresource.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/lib/model/Tblspaceresource.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/lib/model/Tblspaceresource.php	(revision 19)
@@ -0,0 +1,40 @@
+<?php
+
+/**
+ * Subclass for representing a row from the 'tblspaceresource' table.
+ *
+ * 
+ *
+ * @package lib.model
+ */ 
+class Tblspaceresource extends BaseTblspaceresource
+{
+	/**
+	 * Initializes internal state of Tblspaceresource object.
+	 * @see        parent::__construct()
+	 */
+	public function __construct()
+	{
+		// Make sure that parent constructor is always invoked, since that
+		// is where any default values for this object are set.
+		parent::__construct();
+	}
+
+  private function getResPath($create = false) {
+    $resId = $this->getResId();
+    $path = violetUtil::getSpacePath(true) . floor($resId/1000).'/'.$resId;
+    if ($create && !file_exists($path)) mkdir($path, 0777, true);
+    return $path;
+  }
+
+  public function getFullFilename($create = false) {
+    return $this->getResPath($create).'/'.$this->getResFilename();
+  }
+
+  public function delete(PropelPDO $con = null) {
+    $path = $this->getResPath();
+    unlink($path.'/'.$this->getResFilename());
+    rmdir($path);
+    parent::delete($con);
+  }
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/lib/model/TblspaceresourcePeer.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/lib/model/TblspaceresourcePeer.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/lib/model/TblspaceresourcePeer.php	(revision 19)
@@ -0,0 +1,12 @@
+<?php
+
+/**
+ * Subclass for performing query and update operations on the 'tblspaceresource' table.
+ *
+ * 
+ *
+ * @package lib.model
+ */ 
+class TblspaceresourcePeer extends BaseTblspaceresourcePeer
+{
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/lib/model/Tbluser.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/lib/model/Tbluser.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/lib/model/Tbluser.php	(revision 19)
@@ -0,0 +1,235 @@
+<?php
+
+/**
+ * Subclass for representing a row from the 'tbluser' table.
+ *
+ *
+ *
+ * @package lib.model
+ */
+class Tbluser extends BaseTbluser {
+
+  private $oldUsername = null;
+  protected $userObj = null;
+
+  public function getObject() {
+    if ($this->userObj == null) $this->userObj = userBase::getUserObject($this);
+    return $this->userObj;
+  }
+
+  public function setUsUsername($v) {
+    if ($this->oldUsername==null) $this->oldUsername = $this->getUsUsername();
+    parent::setUsUsername($v);
+  }
+
+  public function save(PropelPDO $con = null) {
+    $create = $this->getUsId()==null;
+
+    // update infor in tblbloguser
+    if ($this->isColumnModified(TbluserPeer::US_USERNAME)) {
+      $c = new Criteria();
+      $c->add(TblbloguserPeer::US_USER, $this->getUsId());
+      $tblblogusers = TblbloguserPeer::doSelect($c);
+      foreach ($tblblogusers as $tblbloguser) {
+        $tblbloguser->setUsNickname($this->getUsUsername());
+        $tblbloguser->save();
+      }
+      $c = new Criteria();
+      $c->add(TblblogPeer::BL_USER, $this->getUsId());
+      $c->add(TblblogPeer::BL_SHORTNAME, $this->oldUsername);
+      $c->add(TblblogPeer::BL_TYPE, 1);
+      $tblblog = TblblogPeer::doSelectOne($c);
+      if ($tblblog) {
+        $tblblog->setBlShortname($this->getUsUsername());
+        $tblblog->save();
+      }
+    }
+    if ($this->isColumnModified(TbluserPeer::US_LASTNAME) || $this->isColumnModified(TbluserPeer::US_FIRSTNAME)) {
+      $val = new Criteria();
+      $val->add(TblbloguserPeer::US_FULLNAME, $this->getUsFullName());
+      $c = new Criteria();
+      $c->add(TblbloguserPeer::US_USER, $this->getUsId());
+      BasePeer::doUpdate($c, $val, Propel::getConnection(TblbloguserPeer::DATABASE_NAME));
+    }
+    if ($this->isColumnModified(TbluserPeer::US_SCORE)) {
+      $val = new Criteria();
+      $val->add(TblblogcheckinfoPeer::CI_SCORE, $this->getUsScore());
+      $c = new Criteria();
+      $c->add(TblblogcheckinfoPeer::CI_USERID, $this->getUsId());
+      BasePeer::doUpdate($c, $val, Propel::getConnection(TblblogcheckinfoPeer::DATABASE_NAME));
+    }
+
+    parent::save($con);
+    if ($create) {
+      $this->setUsIdmd5(md5($this->getUsId()));
+      parent::save($con);
+    }
+  }
+
+  /**
+   *
+   * @return full name of user
+   */
+  public function getUsFullname() {
+    if ($this->getUsStatus()<10) {
+      if (null==$this->getUsLastname() && null==$this->getUsFirstname())
+        return $this->getUsUsername();
+      else
+        return $this->getUsLastname().' '.$this->getUsFirstname();
+    } else {
+      return 'Äang bá» khÃ³a';
+    }
+  }
+
+  public function setUsFullname($fullname) {
+    $names = split(' ', $fullname);
+    $firstname = array_pop($names);
+    $lastname = join($names, ' ');
+    $this->setUsFirstname($firstname);
+    $this->setUsLastname($lastname);
+  }
+
+  public function getUsHomePage() {
+  	$homePage = parent::getUsHomepage();
+  	if ($homePage === null) {
+      $c = new Criteria();
+      $c->add(TblblogPeer::BL_USER, $this->getUsId());
+      $c->add(TblblogPeer::BL_TYPE, 1);
+      $tblblog = TblblogPeer::doSelectOne($c);
+      if (!$tblblog) $homePage = '';
+      else {
+        $homePage = $tblblog->getRootUrl();
+        if (preg_match('@^http://(.+)/@', $homePage, $match)) $homePage = $match[1];
+      }
+      $this->setUsHomepage($homePage);
+      $this->save();
+    }
+    if ($homePage != '') $homePage = 'http://'.$homePage;
+  	return $homePage;
+  }
+
+  public function getUsKey() {
+    $key = parent::getUsKey();
+    if ($key == null) {
+      $key = rand(1, time());
+      $this->setUsKey($key);
+      $this->save();
+    }
+    return $key;
+  }
+
+  /**
+   *
+   * @return number of presentation which is downloaded by user
+   */
+  public function getDownloadPresentationCount() {
+    $c = new Criteria();
+    $c->add(TbluserpresentationPeer::USPRE_USER, $this->getUsId());
+    return TbluserpresentationPeer::doCount($c);
+  }
+
+  /**
+   *
+   * @return number of document which is downloaded by user
+   */
+  public function getDownloadDocumentCount() {
+    $c = new Criteria();
+    $c->add(TbluserdocumentPeer::USDOC_USER, $this->getUsId());
+    return TbluserdocumentPeer::doCount($c);
+  }
+
+  /**
+   *
+   * @return number of presentation which is uploaded by user
+   */
+  public function getUploadPresentationCount() {
+    $c = new Criteria();
+    $c->add(TblpresentationPeer::PR_USER, $this->getUsId());
+    $c->add(TblpresentationPeer::PR_STATUS, array(0,1,100,101), Criteria::IN);
+    return TblpresentationPeer::doCount($c);
+  }
+
+  /**
+   *
+   * @return number of document which is uploaded by user
+   */
+  public function getUploadDocumentCount() {
+    $c = new Criteria();
+    $c->add(TbldocumentPeer::DOC_USER, $this->getUsId());
+    $c->add(TbldocumentPeer::DOC_STATUS, array(0,1,100,101), Criteria::IN);
+    return TbldocumentPeer::doCount($c);
+  }
+
+  //diem upload bai giang
+  public function getUploadPresentationsPoint() {
+    $c = new Criteria();
+    $c->add(TblpresentationPeer::PR_USER, $this->getUsId());
+    $c->add(TblpresentationPeer::PR_STATUS, array(0,1,100,101), Criteria::IN);
+    $c->addSelectColumn('sum(pr_hit)');
+    $rs = TblpresentationPeer::doSelectStmt($c);
+    $row = $rs->fetch(PDO::FETCH_NUM);
+    $rs->closeCursor();
+    return (int)$row[0];
+  }
+
+  //diem upload tu lieu
+  public function getUploadDocumentsPoint() {
+    $c = new Criteria();
+    $c->add(TbldocumentPeer::DOC_USER, $this->getUsId());
+    $c->add(TbldocumentPeer::DOC_STATUS, array(0,1,100,101), Criteria::IN);
+    $c->addSelectColumn('sum(doc_hit)');
+    $rs = TbldocumentPeer::doSelectStmt($c);
+    $row = $rs->fetch(PDO::FETCH_NUM);
+    $rs->closeCursor();
+    return (int)$row[0];
+  }
+
+  //diem download (bai giang, ko tinh tu lieu)
+  public function getDownloadPresentationsPoint() {
+    $c = new Criteria();
+    $c->add(TbluserpresentationPeer::USPRE_USER, $this->getUsId());
+    $down_pre = TbluserpresentationPeer::doCount($c);
+    return $down_pre;
+  }
+
+  //tong diem cua thanh vien
+  public function getUserPoint() {
+    $up_pre = $this->getUploadPresentationsPoint();
+    $up_doc = $this->getUploadDocumentsPoint();
+    $down_pre = $this->getDownloadPresentationsPoint();
+
+    $score = 80 + $this->getUsPointplus() + $up_pre*3 + $up_doc*1 - $down_pre*1;
+    if ($score != $this->getUsScore()) {
+      $this->setUsScore($score);
+      $this->save();
+    }
+    return $score;
+  }
+
+  public function incDownload($save = true, $incWeekScore = 0) {
+    $download = explode(',', $this->getUsDownload());
+    if (isset($download[1])) $download[1] = intval($download[1]) + 1;
+    if ($incWeekScore != 0)  $download[0] = intval($download[0]) + $incWeekScore;
+    $this->setUsDownload(implode(',', $download));
+    if ($save) $this->save();
+  }
+
+  public function incUpload($save = true) {
+    $download = explode(',', $this->getUsDownload());
+    if (!isset($download[2])) return;
+    $download[2] = intval($download[2]) + 1;
+    $this->setUsDownload(implode(',', $download));
+    if ($save) $this->save();
+  }
+
+  public function getUsUpDown() {
+    $download = explode(',', $this->getUsDownload());
+    if (!isset($download[1]) || !isset($download[2])) {
+      $download[1] = $this->getDownloadPresentationCount() + $this->getDownloadDocumentCount();
+      $download[2] = $this->getUploadPresentationCount() + $this->getUploadDocumentCount();
+      $this->setUsDownload(implode(',', $download));
+      $this->save();
+    }
+    return $download;
+  }
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/lib/model/TbluserPeer.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/lib/model/TbluserPeer.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/lib/model/TbluserPeer.php	(revision 19)
@@ -0,0 +1,16 @@
+<?php
+
+/**
+ * Subclass for performing query and update operations on the 'tbluser' table.
+ *
+ *
+ *
+ * @package lib.model
+ */
+class TbluserPeer extends BaseTbluserPeer
+{
+	public static function getNumOfUsers() {
+    $c = new Criteria();
+    return TbluserPeer::doCount($c);
+	}
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/lib/model/map/TblblogcheckinfoMapBuilder.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/lib/model/map/TblblogcheckinfoMapBuilder.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/lib/model/map/TblblogcheckinfoMapBuilder.php	(revision 19)
@@ -0,0 +1,61 @@
+<?php
+
+
+
+class TblblogcheckinfoMapBuilder implements MapBuilder {
+
+	
+	const CLASS_NAME = 'lib.model.map.TblblogcheckinfoMapBuilder';
+
+	
+	private $dbMap;
+
+	
+	public function isBuilt()
+	{
+		return ($this->dbMap !== null);
+	}
+
+	
+	public function getDatabaseMap()
+	{
+		return $this->dbMap;
+	}
+
+	
+	public function doBuild()
+	{
+		$this->dbMap = Propel::getDatabaseMap(TblblogcheckinfoPeer::DATABASE_NAME);
+
+		$tMap = $this->dbMap->addTable(TblblogcheckinfoPeer::TABLE_NAME);
+		$tMap->setPhpName('Tblblogcheckinfo');
+		$tMap->setClassname('Tblblogcheckinfo');
+
+		$tMap->setUseIdGenerator(false);
+
+		$tMap->addForeignPrimaryKey('CI_USERID', 'CiUserid', 'INTEGER' , 'tbluser', 'US_ID', true, null);
+
+		$tMap->addColumn('CI_BIRTHDAY', 'CiBirthday', 'DATE', true, null);
+
+		$tMap->addColumn('CI_PHONE', 'CiPhone', 'VARCHAR', true, 30);
+
+		$tMap->addColumn('CI_PR', 'CiPr', 'LONGVARCHAR', true, null);
+
+		$tMap->addColumn('CI_NUMBERID', 'CiNumberid', 'VARCHAR', true, 30);
+
+		$tMap->addColumn('CI_POSITION', 'CiPosition', 'INTEGER', true, null);
+
+		$tMap->addColumn('CI_SCHOOL', 'CiSchool', 'INTEGER', true, null);
+
+		$tMap->addColumn('CI_DISTRICT', 'CiDistrict', 'INTEGER', true, null);
+
+		$tMap->addColumn('CI_PROVINCE', 'CiProvince', 'INTEGER', true, null);
+
+		$tMap->addColumn('CI_BADGE', 'CiBadge', 'VARCHAR', true, 30);
+
+		$tMap->addColumn('CI_SUBJECT', 'CiSubject', 'VARCHAR', true, 30);
+
+		$tMap->addColumn('CI_SCORE', 'CiScore', 'INTEGER', true, null);
+
+	} 
+} 
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/lib/model/map/TblspacecategoryMapBuilder.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/lib/model/map/TblspacecategoryMapBuilder.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/lib/model/map/TblspacecategoryMapBuilder.php	(revision 19)
@@ -0,0 +1,47 @@
+<?php
+
+
+
+class TblspacecategoryMapBuilder implements MapBuilder {
+
+	
+	const CLASS_NAME = 'lib.model.map.TblspacecategoryMapBuilder';
+
+	
+	private $dbMap;
+
+	
+	public function isBuilt()
+	{
+		return ($this->dbMap !== null);
+	}
+
+	
+	public function getDatabaseMap()
+	{
+		return $this->dbMap;
+	}
+
+	
+	public function doBuild()
+	{
+		$this->dbMap = Propel::getDatabaseMap(TblspacecategoryPeer::DATABASE_NAME);
+
+		$tMap = $this->dbMap->addTable(TblspacecategoryPeer::TABLE_NAME);
+		$tMap->setPhpName('Tblspacecategory');
+		$tMap->setClassname('Tblspacecategory');
+
+		$tMap->setUseIdGenerator(true);
+
+		$tMap->addPrimaryKey('CAT_ID', 'CatId', 'INTEGER', true, null);
+
+		$tMap->addColumn('CAT_NAME', 'CatName', 'VARCHAR', true, 255);
+
+		$tMap->addColumn('CAT_PARENT', 'CatParent', 'INTEGER', true, null);
+
+		$tMap->addColumn('CAT_USER', 'CatUser', 'INTEGER', true, null);
+
+		$tMap->addColumn('CAT_DATE', 'CatDate', 'TIMESTAMP', true, null);
+
+	} 
+} 
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/lib/model/map/TblspacefileMapBuilder.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/lib/model/map/TblspacefileMapBuilder.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/lib/model/map/TblspacefileMapBuilder.php	(revision 19)
@@ -0,0 +1,51 @@
+<?php
+
+
+
+class TblspacefileMapBuilder implements MapBuilder {
+
+	
+	const CLASS_NAME = 'lib.model.map.TblspacefileMapBuilder';
+
+	
+	private $dbMap;
+
+	
+	public function isBuilt()
+	{
+		return ($this->dbMap !== null);
+	}
+
+	
+	public function getDatabaseMap()
+	{
+		return $this->dbMap;
+	}
+
+	
+	public function doBuild()
+	{
+		$this->dbMap = Propel::getDatabaseMap(TblspacefilePeer::DATABASE_NAME);
+
+		$tMap = $this->dbMap->addTable(TblspacefilePeer::TABLE_NAME);
+		$tMap->setPhpName('Tblspacefile');
+		$tMap->setClassname('Tblspacefile');
+
+		$tMap->setUseIdGenerator(true);
+
+		$tMap->addPrimaryKey('FILE_ID', 'FileId', 'INTEGER', true, null);
+
+		$tMap->addForeignKey('FILE_RESOURCE', 'FileResource', 'INTEGER', 'tblspaceresource', 'RES_ID', true, null);
+
+		$tMap->addColumn('FILE_CATEGORY', 'FileCategory', 'INTEGER', true, null);
+
+		$tMap->addColumn('FILE_USER', 'FileUser', 'INTEGER', true, null);
+
+		$tMap->addColumn('FILE_NAME', 'FileName', 'VARCHAR', false, 255);
+
+		$tMap->addColumn('FILE_TYPE', 'FileType', 'VARCHAR', false, 15);
+
+		$tMap->addColumn('FILE_DATE', 'FileDate', 'TIMESTAMP', true, null);
+
+	} 
+} 
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/lib/model/map/TblspaceresourceMapBuilder.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/lib/model/map/TblspaceresourceMapBuilder.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/lib/model/map/TblspaceresourceMapBuilder.php	(revision 19)
@@ -0,0 +1,45 @@
+<?php
+
+
+
+class TblspaceresourceMapBuilder implements MapBuilder {
+
+	
+	const CLASS_NAME = 'lib.model.map.TblspaceresourceMapBuilder';
+
+	
+	private $dbMap;
+
+	
+	public function isBuilt()
+	{
+		return ($this->dbMap !== null);
+	}
+
+	
+	public function getDatabaseMap()
+	{
+		return $this->dbMap;
+	}
+
+	
+	public function doBuild()
+	{
+		$this->dbMap = Propel::getDatabaseMap(TblspaceresourcePeer::DATABASE_NAME);
+
+		$tMap = $this->dbMap->addTable(TblspaceresourcePeer::TABLE_NAME);
+		$tMap->setPhpName('Tblspaceresource');
+		$tMap->setClassname('Tblspaceresource');
+
+		$tMap->setUseIdGenerator(true);
+
+		$tMap->addPrimaryKey('RES_ID', 'ResId', 'INTEGER', true, null);
+
+		$tMap->addColumn('RES_FILENAME', 'ResFilename', 'VARCHAR', true, 255);
+
+		$tMap->addColumn('RES_FILESIZE', 'ResFilesize', 'INTEGER', false, null);
+
+		$tMap->addColumn('RES_FILECRC', 'ResFilecrc', 'INTEGER', false, null);
+
+	} 
+} 
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/lib/model/map/TbluserMapBuilder.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/lib/model/map/TbluserMapBuilder.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/lib/model/map/TbluserMapBuilder.php	(revision 19)
@@ -0,0 +1,89 @@
+<?php
+
+
+
+class TbluserMapBuilder implements MapBuilder {
+
+	
+	const CLASS_NAME = 'lib.model.map.TbluserMapBuilder';
+
+	
+	private $dbMap;
+
+	
+	public function isBuilt()
+	{
+		return ($this->dbMap !== null);
+	}
+
+	
+	public function getDatabaseMap()
+	{
+		return $this->dbMap;
+	}
+
+	
+	public function doBuild()
+	{
+		$this->dbMap = Propel::getDatabaseMap(TbluserPeer::DATABASE_NAME);
+
+		$tMap = $this->dbMap->addTable(TbluserPeer::TABLE_NAME);
+		$tMap->setPhpName('Tbluser');
+		$tMap->setClassname('Tbluser');
+
+		$tMap->setUseIdGenerator(true);
+
+		$tMap->addPrimaryKey('US_ID', 'UsId', 'INTEGER', true, null);
+
+		$tMap->addColumn('US_USERNAME', 'UsUsername', 'VARCHAR', false, 30);
+
+		$tMap->addColumn('US_PASSWORD', 'UsPassword', 'VARCHAR', false, 50);
+
+		$tMap->addColumn('US_FIRSTNAME', 'UsFirstname', 'VARCHAR', true, 50);
+
+		$tMap->addColumn('US_LASTNAME', 'UsLastname', 'VARCHAR', true, 50);
+
+		$tMap->addColumn('US_SEX', 'UsSex', 'TINYINT', false, null);
+
+		$tMap->addColumn('US_EMAIL', 'UsEmail', 'VARCHAR', true, 100);
+
+		$tMap->addColumn('US_PHONE', 'UsPhone', 'VARCHAR', false, 50);
+
+		$tMap->addColumn('US_ACLGROUP', 'UsAclgroup', 'INTEGER', false, null);
+
+		$tMap->addColumn('US_SCHOOL', 'UsSchool', 'VARCHAR', false, 100);
+
+		$tMap->addColumn('US_PROVINCE', 'UsProvince', 'VARCHAR', false, 50);
+
+		$tMap->addColumn('US_LASTVISITED', 'UsLastvisited', 'TIMESTAMP', false, null);
+
+		$tMap->addColumn('US_REGISTERDATE', 'UsRegisterdate', 'TIMESTAMP', false, null);
+
+		$tMap->addColumn('US_RATING', 'UsRating', 'INTEGER', true, null);
+
+		$tMap->addColumn('US_DOWNLOAD', 'UsDownload', 'INTEGER', false, null);
+
+		$tMap->addColumn('US_AVATAR', 'UsAvatar', 'VARCHAR', false, 255);
+
+		$tMap->addColumn('US_STATUS', 'UsStatus', 'INTEGER', false, null);
+
+		$tMap->addColumn('US_KEY', 'UsKey', 'INTEGER', false, null);
+
+		$tMap->addColumn('US_COMPANY', 'UsCompany', 'INTEGER', false, null);
+
+		$tMap->addColumn('US_SCORE', 'UsScore', 'INTEGER', false, null);
+
+		$tMap->addColumn('US_POINTPLUS', 'UsPointplus', 'INTEGER', false, null);
+
+		$tMap->addColumn('US_CHECKED', 'UsChecked', 'TINYINT', false, null);
+
+		$tMap->addColumn('US_CHECKINFO', 'UsCheckinfo', 'INTEGER', false, null);
+
+		$tMap->addColumn('US_IDMD5', 'UsIdmd5', 'VARCHAR', false, 32);
+
+		$tMap->addColumn('US_HOMEPAGE', 'UsHomepage', 'VARCHAR', false, 255);
+
+		$tMap->addColumn('US_MONEY', 'UsMoney', 'INTEGER', false, null);
+
+	} 
+} 
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/lib/model/om/BaseTblblogcheckinfo.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/lib/model/om/BaseTblblogcheckinfo.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/lib/model/om/BaseTblblogcheckinfo.php	(revision 19)
@@ -0,0 +1,826 @@
+<?php
+
+
+abstract class BaseTblblogcheckinfo extends BaseObject  implements Persistent {
+
+
+	
+	protected static $peer;
+
+	
+	protected $ci_userid;
+
+	
+	protected $ci_birthday;
+
+	
+	protected $ci_phone;
+
+	
+	protected $ci_pr;
+
+	
+	protected $ci_numberid;
+
+	
+	protected $ci_position;
+
+	
+	protected $ci_school;
+
+	
+	protected $ci_district;
+
+	
+	protected $ci_province;
+
+	
+	protected $ci_badge;
+
+	
+	protected $ci_subject;
+
+	
+	protected $ci_score;
+
+	
+	protected $aTbluser;
+
+	
+	protected $alreadyInSave = false;
+
+	
+	protected $alreadyInValidation = false;
+
+	
+	public function __construct()
+	{
+		parent::__construct();
+		$this->applyDefaultValues();
+	}
+
+	
+	public function applyDefaultValues()
+	{
+	}
+
+	
+	public function getCiUserid()
+	{
+		return $this->ci_userid;
+	}
+
+	
+	public function getCiBirthday($format = '%x')
+	{
+		if ($this->ci_birthday === null) {
+			return null;
+		}
+
+
+		if ($this->ci_birthday === '0000-00-00') {
+									return null;
+		} else {
+			try {
+				$dt = new DateTime($this->ci_birthday);
+			} catch (Exception $x) {
+				throw new PropelException("Internally stored date/time/timestamp value could not be converted to DateTime: " . var_export($this->ci_birthday, true), $x);
+			}
+		}
+
+		if ($format === null) {
+						return $dt;
+		} elseif (strpos($format, '%') !== false) {
+			return strftime($format, $dt->format('U'));
+		} else {
+			return $dt->format($format);
+		}
+	}
+
+	
+	public function getCiPhone()
+	{
+		return $this->ci_phone;
+	}
+
+	
+	public function getCiPr()
+	{
+		return $this->ci_pr;
+	}
+
+	
+	public function getCiNumberid()
+	{
+		return $this->ci_numberid;
+	}
+
+	
+	public function getCiPosition()
+	{
+		return $this->ci_position;
+	}
+
+	
+	public function getCiSchool()
+	{
+		return $this->ci_school;
+	}
+
+	
+	public function getCiDistrict()
+	{
+		return $this->ci_district;
+	}
+
+	
+	public function getCiProvince()
+	{
+		return $this->ci_province;
+	}
+
+	
+	public function getCiBadge()
+	{
+		return $this->ci_badge;
+	}
+
+	
+	public function getCiSubject()
+	{
+		return $this->ci_subject;
+	}
+
+	
+	public function getCiScore()
+	{
+		return $this->ci_score;
+	}
+
+	
+	public function setCiUserid($v)
+	{
+		if ($v !== null) {
+			$v = (int) $v;
+		}
+
+		if ($this->ci_userid !== $v) {
+			$this->ci_userid = $v;
+			$this->modifiedColumns[] = TblblogcheckinfoPeer::CI_USERID;
+		}
+
+		if ($this->aTbluser !== null && $this->aTbluser->getUsId() !== $v) {
+			$this->aTbluser = null;
+		}
+
+		return $this;
+	} 
+	
+	public function setCiBirthday($v)
+	{
+						if ($v === null || $v === '') {
+			$dt = null;
+		} elseif ($v instanceof DateTime) {
+			$dt = $v;
+		} else {
+									try {
+				if (is_numeric($v)) { 					$dt = new DateTime('@'.$v, new DateTimeZone('UTC'));
+															$dt->setTimeZone(new DateTimeZone(date_default_timezone_get()));
+				} else {
+					$dt = new DateTime($v);
+				}
+			} catch (Exception $x) {
+				throw new PropelException('Error parsing date/time value: ' . var_export($v, true), $x);
+			}
+		}
+
+		if ( $this->ci_birthday !== null || $dt !== null ) {
+			
+			$currNorm = ($this->ci_birthday !== null && $tmpDt = new DateTime($this->ci_birthday)) ? $tmpDt->format('Y-m-d') : null;
+			$newNorm = ($dt !== null) ? $dt->format('Y-m-d') : null;
+
+			if ( ($currNorm !== $newNorm) 					)
+			{
+				$this->ci_birthday = ($dt ? $dt->format('Y-m-d') : null);
+				$this->modifiedColumns[] = TblblogcheckinfoPeer::CI_BIRTHDAY;
+			}
+		} 
+		return $this;
+	} 
+	
+	public function setCiPhone($v)
+	{
+		if ($v !== null) {
+			$v = (string) $v;
+		}
+
+		if ($this->ci_phone !== $v) {
+			$this->ci_phone = $v;
+			$this->modifiedColumns[] = TblblogcheckinfoPeer::CI_PHONE;
+		}
+
+		return $this;
+	} 
+	
+	public function setCiPr($v)
+	{
+		if ($v !== null) {
+			$v = (string) $v;
+		}
+
+		if ($this->ci_pr !== $v) {
+			$this->ci_pr = $v;
+			$this->modifiedColumns[] = TblblogcheckinfoPeer::CI_PR;
+		}
+
+		return $this;
+	} 
+	
+	public function setCiNumberid($v)
+	{
+		if ($v !== null) {
+			$v = (string) $v;
+		}
+
+		if ($this->ci_numberid !== $v) {
+			$this->ci_numberid = $v;
+			$this->modifiedColumns[] = TblblogcheckinfoPeer::CI_NUMBERID;
+		}
+
+		return $this;
+	} 
+	
+	public function setCiPosition($v)
+	{
+		if ($v !== null) {
+			$v = (int) $v;
+		}
+
+		if ($this->ci_position !== $v) {
+			$this->ci_position = $v;
+			$this->modifiedColumns[] = TblblogcheckinfoPeer::CI_POSITION;
+		}
+
+		return $this;
+	} 
+	
+	public function setCiSchool($v)
+	{
+		if ($v !== null) {
+			$v = (int) $v;
+		}
+
+		if ($this->ci_school !== $v) {
+			$this->ci_school = $v;
+			$this->modifiedColumns[] = TblblogcheckinfoPeer::CI_SCHOOL;
+		}
+
+		return $this;
+	} 
+	
+	public function setCiDistrict($v)
+	{
+		if ($v !== null) {
+			$v = (int) $v;
+		}
+
+		if ($this->ci_district !== $v) {
+			$this->ci_district = $v;
+			$this->modifiedColumns[] = TblblogcheckinfoPeer::CI_DISTRICT;
+		}
+
+		return $this;
+	} 
+	
+	public function setCiProvince($v)
+	{
+		if ($v !== null) {
+			$v = (int) $v;
+		}
+
+		if ($this->ci_province !== $v) {
+			$this->ci_province = $v;
+			$this->modifiedColumns[] = TblblogcheckinfoPeer::CI_PROVINCE;
+		}
+
+		return $this;
+	} 
+	
+	public function setCiBadge($v)
+	{
+		if ($v !== null) {
+			$v = (string) $v;
+		}
+
+		if ($this->ci_badge !== $v) {
+			$this->ci_badge = $v;
+			$this->modifiedColumns[] = TblblogcheckinfoPeer::CI_BADGE;
+		}
+
+		return $this;
+	} 
+	
+	public function setCiSubject($v)
+	{
+		if ($v !== null) {
+			$v = (string) $v;
+		}
+
+		if ($this->ci_subject !== $v) {
+			$this->ci_subject = $v;
+			$this->modifiedColumns[] = TblblogcheckinfoPeer::CI_SUBJECT;
+		}
+
+		return $this;
+	} 
+	
+	public function setCiScore($v)
+	{
+		if ($v !== null) {
+			$v = (int) $v;
+		}
+
+		if ($this->ci_score !== $v) {
+			$this->ci_score = $v;
+			$this->modifiedColumns[] = TblblogcheckinfoPeer::CI_SCORE;
+		}
+
+		return $this;
+	} 
+	
+	public function hasOnlyDefaultValues()
+	{
+						if (array_diff($this->modifiedColumns, array())) {
+				return false;
+			}
+
+				return true;
+	} 
+	
+	public function hydrate($row, $startcol = 0, $rehydrate = false)
+	{
+		try {
+
+			$this->ci_userid = ($row[$startcol + 0] !== null) ? (int) $row[$startcol + 0] : null;
+			$this->ci_birthday = ($row[$startcol + 1] !== null) ? (string) $row[$startcol + 1] : null;
+			$this->ci_phone = ($row[$startcol + 2] !== null) ? (string) $row[$startcol + 2] : null;
+			$this->ci_pr = ($row[$startcol + 3] !== null) ? (string) $row[$startcol + 3] : null;
+			$this->ci_numberid = ($row[$startcol + 4] !== null) ? (string) $row[$startcol + 4] : null;
+			$this->ci_position = ($row[$startcol + 5] !== null) ? (int) $row[$startcol + 5] : null;
+			$this->ci_school = ($row[$startcol + 6] !== null) ? (int) $row[$startcol + 6] : null;
+			$this->ci_district = ($row[$startcol + 7] !== null) ? (int) $row[$startcol + 7] : null;
+			$this->ci_province = ($row[$startcol + 8] !== null) ? (int) $row[$startcol + 8] : null;
+			$this->ci_badge = ($row[$startcol + 9] !== null) ? (string) $row[$startcol + 9] : null;
+			$this->ci_subject = ($row[$startcol + 10] !== null) ? (string) $row[$startcol + 10] : null;
+			$this->ci_score = ($row[$startcol + 11] !== null) ? (int) $row[$startcol + 11] : null;
+			$this->resetModified();
+
+			$this->setNew(false);
+
+			if ($rehydrate) {
+				$this->ensureConsistency();
+			}
+
+						return $startcol + 12; 
+		} catch (Exception $e) {
+			throw new PropelException("Error populating Tblblogcheckinfo object", $e);
+		}
+	}
+
+	
+	public function ensureConsistency()
+	{
+
+		if ($this->aTbluser !== null && $this->ci_userid !== $this->aTbluser->getUsId()) {
+			$this->aTbluser = null;
+		}
+	} 
+	
+	public function reload($deep = false, PropelPDO $con = null)
+	{
+		if ($this->isDeleted()) {
+			throw new PropelException("Cannot reload a deleted object.");
+		}
+
+		if ($this->isNew()) {
+			throw new PropelException("Cannot reload an unsaved object.");
+		}
+
+		if ($con === null) {
+			$con = Propel::getConnection(TblblogcheckinfoPeer::DATABASE_NAME, Propel::CONNECTION_READ);
+		}
+
+				
+		$stmt = TblblogcheckinfoPeer::doSelectStmt($this->buildPkeyCriteria(), $con);
+		$row = $stmt->fetch(PDO::FETCH_NUM);
+		$stmt->closeCursor();
+		if (!$row) {
+			throw new PropelException('Cannot find matching row in the database to reload object values.');
+		}
+		$this->hydrate($row, 0, true); 
+		if ($deep) {  
+			$this->aTbluser = null;
+		} 	}
+
+	
+	public function delete(PropelPDO $con = null)
+	{
+		if ($this->isDeleted()) {
+			throw new PropelException("This object has already been deleted.");
+		}
+
+		if ($con === null) {
+			$con = Propel::getConnection(TblblogcheckinfoPeer::DATABASE_NAME, Propel::CONNECTION_WRITE);
+		}
+		
+		$con->beginTransaction();
+		try {
+			TblblogcheckinfoPeer::doDelete($this, $con);
+			$this->setDeleted(true);
+			$con->commit();
+		} catch (PropelException $e) {
+			$con->rollBack();
+			throw $e;
+		}
+	}
+
+	
+	public function save(PropelPDO $con = null)
+	{
+		if ($this->isDeleted()) {
+			throw new PropelException("You cannot save an object that has been deleted.");
+		}
+
+		if ($con === null) {
+			$con = Propel::getConnection(TblblogcheckinfoPeer::DATABASE_NAME, Propel::CONNECTION_WRITE);
+		}
+		
+		$con->beginTransaction();
+		try {
+			$affectedRows = $this->doSave($con);
+			$con->commit();
+			TblblogcheckinfoPeer::addInstanceToPool($this);
+			return $affectedRows;
+		} catch (PropelException $e) {
+			$con->rollBack();
+			throw $e;
+		}
+	}
+
+	
+	protected function doSave(PropelPDO $con)
+	{
+		$affectedRows = 0; 		if (!$this->alreadyInSave) {
+			$this->alreadyInSave = true;
+
+												
+			if ($this->aTbluser !== null) {
+				if ($this->aTbluser->isModified() || $this->aTbluser->isNew()) {
+					$affectedRows += $this->aTbluser->save($con);
+				}
+				$this->setTbluser($this->aTbluser);
+			}
+
+
+						if ($this->isModified()) {
+				if ($this->isNew()) {
+					$pk = TblblogcheckinfoPeer::doInsert($this, $con);
+					$affectedRows += 1; 										 										 
+					$this->setNew(false);
+				} else {
+					$affectedRows += TblblogcheckinfoPeer::doUpdate($this, $con);
+				}
+
+				$this->resetModified(); 			}
+
+			$this->alreadyInSave = false;
+
+		}
+		return $affectedRows;
+	} 
+	
+	protected $validationFailures = array();
+
+	
+	public function getValidationFailures()
+	{
+		return $this->validationFailures;
+	}
+
+	
+	public function validate($columns = null)
+	{
+		$res = $this->doValidate($columns);
+		if ($res === true) {
+			$this->validationFailures = array();
+			return true;
+		} else {
+			$this->validationFailures = $res;
+			return false;
+		}
+	}
+
+	
+	protected function doValidate($columns = null)
+	{
+		if (!$this->alreadyInValidation) {
+			$this->alreadyInValidation = true;
+			$retval = null;
+
+			$failureMap = array();
+
+
+												
+			if ($this->aTbluser !== null) {
+				if (!$this->aTbluser->validate($columns)) {
+					$failureMap = array_merge($failureMap, $this->aTbluser->getValidationFailures());
+				}
+			}
+
+
+			if (($retval = TblblogcheckinfoPeer::doValidate($this, $columns)) !== true) {
+				$failureMap = array_merge($failureMap, $retval);
+			}
+
+
+
+			$this->alreadyInValidation = false;
+		}
+
+		return (!empty($failureMap) ? $failureMap : true);
+	}
+
+	
+	public function getByName($name, $type = BasePeer::TYPE_PHPNAME)
+	{
+		$pos = TblblogcheckinfoPeer::translateFieldName($name, $type, BasePeer::TYPE_NUM);
+		$field = $this->getByPosition($pos);
+		return $field;
+	}
+
+	
+	public function getByPosition($pos)
+	{
+		switch($pos) {
+			case 0:
+				return $this->getCiUserid();
+				break;
+			case 1:
+				return $this->getCiBirthday();
+				break;
+			case 2:
+				return $this->getCiPhone();
+				break;
+			case 3:
+				return $this->getCiPr();
+				break;
+			case 4:
+				return $this->getCiNumberid();
+				break;
+			case 5:
+				return $this->getCiPosition();
+				break;
+			case 6:
+				return $this->getCiSchool();
+				break;
+			case 7:
+				return $this->getCiDistrict();
+				break;
+			case 8:
+				return $this->getCiProvince();
+				break;
+			case 9:
+				return $this->getCiBadge();
+				break;
+			case 10:
+				return $this->getCiSubject();
+				break;
+			case 11:
+				return $this->getCiScore();
+				break;
+			default:
+				return null;
+				break;
+		} 	}
+
+	
+	public function toArray($keyType = BasePeer::TYPE_PHPNAME, $includeLazyLoadColumns = true)
+	{
+		$keys = TblblogcheckinfoPeer::getFieldNames($keyType);
+		$result = array(
+			$keys[0] => $this->getCiUserid(),
+			$keys[1] => $this->getCiBirthday(),
+			$keys[2] => $this->getCiPhone(),
+			$keys[3] => $this->getCiPr(),
+			$keys[4] => $this->getCiNumberid(),
+			$keys[5] => $this->getCiPosition(),
+			$keys[6] => $this->getCiSchool(),
+			$keys[7] => $this->getCiDistrict(),
+			$keys[8] => $this->getCiProvince(),
+			$keys[9] => $this->getCiBadge(),
+			$keys[10] => $this->getCiSubject(),
+			$keys[11] => $this->getCiScore(),
+		);
+		return $result;
+	}
+
+	
+	public function setByName($name, $value, $type = BasePeer::TYPE_PHPNAME)
+	{
+		$pos = TblblogcheckinfoPeer::translateFieldName($name, $type, BasePeer::TYPE_NUM);
+		return $this->setByPosition($pos, $value);
+	}
+
+	
+	public function setByPosition($pos, $value)
+	{
+		switch($pos) {
+			case 0:
+				$this->setCiUserid($value);
+				break;
+			case 1:
+				$this->setCiBirthday($value);
+				break;
+			case 2:
+				$this->setCiPhone($value);
+				break;
+			case 3:
+				$this->setCiPr($value);
+				break;
+			case 4:
+				$this->setCiNumberid($value);
+				break;
+			case 5:
+				$this->setCiPosition($value);
+				break;
+			case 6:
+				$this->setCiSchool($value);
+				break;
+			case 7:
+				$this->setCiDistrict($value);
+				break;
+			case 8:
+				$this->setCiProvince($value);
+				break;
+			case 9:
+				$this->setCiBadge($value);
+				break;
+			case 10:
+				$this->setCiSubject($value);
+				break;
+			case 11:
+				$this->setCiScore($value);
+				break;
+		} 	}
+
+	
+	public function fromArray($arr, $keyType = BasePeer::TYPE_PHPNAME)
+	{
+		$keys = TblblogcheckinfoPeer::getFieldNames($keyType);
+
+		if (array_key_exists($keys[0], $arr)) $this->setCiUserid($arr[$keys[0]]);
+		if (array_key_exists($keys[1], $arr)) $this->setCiBirthday($arr[$keys[1]]);
+		if (array_key_exists($keys[2], $arr)) $this->setCiPhone($arr[$keys[2]]);
+		if (array_key_exists($keys[3], $arr)) $this->setCiPr($arr[$keys[3]]);
+		if (array_key_exists($keys[4], $arr)) $this->setCiNumberid($arr[$keys[4]]);
+		if (array_key_exists($keys[5], $arr)) $this->setCiPosition($arr[$keys[5]]);
+		if (array_key_exists($keys[6], $arr)) $this->setCiSchool($arr[$keys[6]]);
+		if (array_key_exists($keys[7], $arr)) $this->setCiDistrict($arr[$keys[7]]);
+		if (array_key_exists($keys[8], $arr)) $this->setCiProvince($arr[$keys[8]]);
+		if (array_key_exists($keys[9], $arr)) $this->setCiBadge($arr[$keys[9]]);
+		if (array_key_exists($keys[10], $arr)) $this->setCiSubject($arr[$keys[10]]);
+		if (array_key_exists($keys[11], $arr)) $this->setCiScore($arr[$keys[11]]);
+	}
+
+	
+	public function buildCriteria()
+	{
+		$criteria = new Criteria(TblblogcheckinfoPeer::DATABASE_NAME);
+
+		if ($this->isColumnModified(TblblogcheckinfoPeer::CI_USERID)) $criteria->add(TblblogcheckinfoPeer::CI_USERID, $this->ci_userid);
+		if ($this->isColumnModified(TblblogcheckinfoPeer::CI_BIRTHDAY)) $criteria->add(TblblogcheckinfoPeer::CI_BIRTHDAY, $this->ci_birthday);
+		if ($this->isColumnModified(TblblogcheckinfoPeer::CI_PHONE)) $criteria->add(TblblogcheckinfoPeer::CI_PHONE, $this->ci_phone);
+		if ($this->isColumnModified(TblblogcheckinfoPeer::CI_PR)) $criteria->add(TblblogcheckinfoPeer::CI_PR, $this->ci_pr);
+		if ($this->isColumnModified(TblblogcheckinfoPeer::CI_NUMBERID)) $criteria->add(TblblogcheckinfoPeer::CI_NUMBERID, $this->ci_numberid);
+		if ($this->isColumnModified(TblblogcheckinfoPeer::CI_POSITION)) $criteria->add(TblblogcheckinfoPeer::CI_POSITION, $this->ci_position);
+		if ($this->isColumnModified(TblblogcheckinfoPeer::CI_SCHOOL)) $criteria->add(TblblogcheckinfoPeer::CI_SCHOOL, $this->ci_school);
+		if ($this->isColumnModified(TblblogcheckinfoPeer::CI_DISTRICT)) $criteria->add(TblblogcheckinfoPeer::CI_DISTRICT, $this->ci_district);
+		if ($this->isColumnModified(TblblogcheckinfoPeer::CI_PROVINCE)) $criteria->add(TblblogcheckinfoPeer::CI_PROVINCE, $this->ci_province);
+		if ($this->isColumnModified(TblblogcheckinfoPeer::CI_BADGE)) $criteria->add(TblblogcheckinfoPeer::CI_BADGE, $this->ci_badge);
+		if ($this->isColumnModified(TblblogcheckinfoPeer::CI_SUBJECT)) $criteria->add(TblblogcheckinfoPeer::CI_SUBJECT, $this->ci_subject);
+		if ($this->isColumnModified(TblblogcheckinfoPeer::CI_SCORE)) $criteria->add(TblblogcheckinfoPeer::CI_SCORE, $this->ci_score);
+
+		return $criteria;
+	}
+
+	
+	public function buildPkeyCriteria()
+	{
+		$criteria = new Criteria(TblblogcheckinfoPeer::DATABASE_NAME);
+
+		$criteria->add(TblblogcheckinfoPeer::CI_USERID, $this->ci_userid);
+
+		return $criteria;
+	}
+
+	
+	public function getPrimaryKey()
+	{
+		return $this->getCiUserid();
+	}
+
+	
+	public function setPrimaryKey($key)
+	{
+		$this->setCiUserid($key);
+	}
+
+	
+	public function copyInto($copyObj, $deepCopy = false)
+	{
+
+		$copyObj->setCiUserid($this->ci_userid);
+
+		$copyObj->setCiBirthday($this->ci_birthday);
+
+		$copyObj->setCiPhone($this->ci_phone);
+
+		$copyObj->setCiPr($this->ci_pr);
+
+		$copyObj->setCiNumberid($this->ci_numberid);
+
+		$copyObj->setCiPosition($this->ci_position);
+
+		$copyObj->setCiSchool($this->ci_school);
+
+		$copyObj->setCiDistrict($this->ci_district);
+
+		$copyObj->setCiProvince($this->ci_province);
+
+		$copyObj->setCiBadge($this->ci_badge);
+
+		$copyObj->setCiSubject($this->ci_subject);
+
+		$copyObj->setCiScore($this->ci_score);
+
+
+		$copyObj->setNew(true);
+
+	}
+
+	
+	public function copy($deepCopy = false)
+	{
+				$clazz = get_class($this);
+		$copyObj = new $clazz();
+		$this->copyInto($copyObj, $deepCopy);
+		return $copyObj;
+	}
+
+	
+	public function getPeer()
+	{
+		if (self::$peer === null) {
+			self::$peer = new TblblogcheckinfoPeer();
+		}
+		return self::$peer;
+	}
+
+	
+	public function setTbluser(Tbluser $v = null)
+	{
+		if ($v === null) {
+			$this->setCiUserid(NULL);
+		} else {
+			$this->setCiUserid($v->getUsId());
+		}
+
+		$this->aTbluser = $v;
+
+				if ($v !== null) {
+			$v->setTblblogcheckinfo($this);
+		}
+
+		return $this;
+	}
+
+
+	
+	public function getTbluser(PropelPDO $con = null)
+	{
+		if ($this->aTbluser === null && ($this->ci_userid !== null)) {
+			$this->aTbluser = TbluserPeer::retrieveByPK($this->ci_userid, $con);
+						$this->aTbluser->setTblblogcheckinfo($this);
+		}
+		return $this->aTbluser;
+	}
+
+	
+	public function clearAllReferences($deep = false)
+	{
+		if ($deep) {
+		} 
+			$this->aTbluser = null;
+	}
+
+} 
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/lib/model/om/BaseTblblogcheckinfoPeer.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/lib/model/om/BaseTblblogcheckinfoPeer.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/lib/model/om/BaseTblblogcheckinfoPeer.php	(revision 19)
@@ -0,0 +1,643 @@
+<?php
+
+
+abstract class BaseTblblogcheckinfoPeer {
+
+	
+	const DATABASE_NAME = 'propel';
+
+	
+	const TABLE_NAME = 'tblblogcheckinfo';
+
+	
+	const CLASS_DEFAULT = 'lib.model.Tblblogcheckinfo';
+
+	
+	const NUM_COLUMNS = 12;
+
+	
+	const NUM_LAZY_LOAD_COLUMNS = 0;
+
+	
+	const CI_USERID = 'tblblogcheckinfo.CI_USERID';
+
+	
+	const CI_BIRTHDAY = 'tblblogcheckinfo.CI_BIRTHDAY';
+
+	
+	const CI_PHONE = 'tblblogcheckinfo.CI_PHONE';
+
+	
+	const CI_PR = 'tblblogcheckinfo.CI_PR';
+
+	
+	const CI_NUMBERID = 'tblblogcheckinfo.CI_NUMBERID';
+
+	
+	const CI_POSITION = 'tblblogcheckinfo.CI_POSITION';
+
+	
+	const CI_SCHOOL = 'tblblogcheckinfo.CI_SCHOOL';
+
+	
+	const CI_DISTRICT = 'tblblogcheckinfo.CI_DISTRICT';
+
+	
+	const CI_PROVINCE = 'tblblogcheckinfo.CI_PROVINCE';
+
+	
+	const CI_BADGE = 'tblblogcheckinfo.CI_BADGE';
+
+	
+	const CI_SUBJECT = 'tblblogcheckinfo.CI_SUBJECT';
+
+	
+	const CI_SCORE = 'tblblogcheckinfo.CI_SCORE';
+
+	
+	public static $instances = array();
+
+	
+	private static $mapBuilder = null;
+
+	
+	private static $fieldNames = array (
+		BasePeer::TYPE_PHPNAME => array ('CiUserid', 'CiBirthday', 'CiPhone', 'CiPr', 'CiNumberid', 'CiPosition', 'CiSchool', 'CiDistrict', 'CiProvince', 'CiBadge', 'CiSubject', 'CiScore', ),
+		BasePeer::TYPE_STUDLYPHPNAME => array ('ciUserid', 'ciBirthday', 'ciPhone', 'ciPr', 'ciNumberid', 'ciPosition', 'ciSchool', 'ciDistrict', 'ciProvince', 'ciBadge', 'ciSubject', 'ciScore', ),
+		BasePeer::TYPE_COLNAME => array (self::CI_USERID, self::CI_BIRTHDAY, self::CI_PHONE, self::CI_PR, self::CI_NUMBERID, self::CI_POSITION, self::CI_SCHOOL, self::CI_DISTRICT, self::CI_PROVINCE, self::CI_BADGE, self::CI_SUBJECT, self::CI_SCORE, ),
+		BasePeer::TYPE_FIELDNAME => array ('ci_userid', 'ci_birthday', 'ci_phone', 'ci_pr', 'ci_numberid', 'ci_position', 'ci_school', 'ci_district', 'ci_province', 'ci_badge', 'ci_subject', 'ci_score', ),
+		BasePeer::TYPE_NUM => array (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, )
+	);
+
+	
+	private static $fieldKeys = array (
+		BasePeer::TYPE_PHPNAME => array ('CiUserid' => 0, 'CiBirthday' => 1, 'CiPhone' => 2, 'CiPr' => 3, 'CiNumberid' => 4, 'CiPosition' => 5, 'CiSchool' => 6, 'CiDistrict' => 7, 'CiProvince' => 8, 'CiBadge' => 9, 'CiSubject' => 10, 'CiScore' => 11, ),
+		BasePeer::TYPE_STUDLYPHPNAME => array ('ciUserid' => 0, 'ciBirthday' => 1, 'ciPhone' => 2, 'ciPr' => 3, 'ciNumberid' => 4, 'ciPosition' => 5, 'ciSchool' => 6, 'ciDistrict' => 7, 'ciProvince' => 8, 'ciBadge' => 9, 'ciSubject' => 10, 'ciScore' => 11, ),
+		BasePeer::TYPE_COLNAME => array (self::CI_USERID => 0, self::CI_BIRTHDAY => 1, self::CI_PHONE => 2, self::CI_PR => 3, self::CI_NUMBERID => 4, self::CI_POSITION => 5, self::CI_SCHOOL => 6, self::CI_DISTRICT => 7, self::CI_PROVINCE => 8, self::CI_BADGE => 9, self::CI_SUBJECT => 10, self::CI_SCORE => 11, ),
+		BasePeer::TYPE_FIELDNAME => array ('ci_userid' => 0, 'ci_birthday' => 1, 'ci_phone' => 2, 'ci_pr' => 3, 'ci_numberid' => 4, 'ci_position' => 5, 'ci_school' => 6, 'ci_district' => 7, 'ci_province' => 8, 'ci_badge' => 9, 'ci_subject' => 10, 'ci_score' => 11, ),
+		BasePeer::TYPE_NUM => array (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, )
+	);
+
+	
+	public static function getMapBuilder()
+	{
+		if (self::$mapBuilder === null) {
+			self::$mapBuilder = new TblblogcheckinfoMapBuilder();
+		}
+		return self::$mapBuilder;
+	}
+	
+	static public function translateFieldName($name, $fromType, $toType)
+	{
+		$toNames = self::getFieldNames($toType);
+		$key = isset(self::$fieldKeys[$fromType][$name]) ? self::$fieldKeys[$fromType][$name] : null;
+		if ($key === null) {
+			throw new PropelException("'$name' could not be found in the field names of type '$fromType'. These are: " . print_r(self::$fieldKeys[$fromType], true));
+		}
+		return $toNames[$key];
+	}
+
+	
+
+	static public function getFieldNames($type = BasePeer::TYPE_PHPNAME)
+	{
+		if (!array_key_exists($type, self::$fieldNames)) {
+			throw new PropelException('Method getFieldNames() expects the parameter $type to be one of the class constants BasePeer::TYPE_PHPNAME, BasePeer::TYPE_STUDLYPHPNAME, BasePeer::TYPE_COLNAME, BasePeer::TYPE_FIELDNAME, BasePeer::TYPE_NUM. ' . $type . ' was given.');
+		}
+		return self::$fieldNames[$type];
+	}
+
+	
+	public static function alias($alias, $column)
+	{
+		return str_replace(TblblogcheckinfoPeer::TABLE_NAME.'.', $alias.'.', $column);
+	}
+
+	
+	public static function addSelectColumns(Criteria $criteria)
+	{
+
+		$criteria->addSelectColumn(TblblogcheckinfoPeer::CI_USERID);
+
+		$criteria->addSelectColumn(TblblogcheckinfoPeer::CI_BIRTHDAY);
+
+		$criteria->addSelectColumn(TblblogcheckinfoPeer::CI_PHONE);
+
+		$criteria->addSelectColumn(TblblogcheckinfoPeer::CI_PR);
+
+		$criteria->addSelectColumn(TblblogcheckinfoPeer::CI_NUMBERID);
+
+		$criteria->addSelectColumn(TblblogcheckinfoPeer::CI_POSITION);
+
+		$criteria->addSelectColumn(TblblogcheckinfoPeer::CI_SCHOOL);
+
+		$criteria->addSelectColumn(TblblogcheckinfoPeer::CI_DISTRICT);
+
+		$criteria->addSelectColumn(TblblogcheckinfoPeer::CI_PROVINCE);
+
+		$criteria->addSelectColumn(TblblogcheckinfoPeer::CI_BADGE);
+
+		$criteria->addSelectColumn(TblblogcheckinfoPeer::CI_SUBJECT);
+
+		$criteria->addSelectColumn(TblblogcheckinfoPeer::CI_SCORE);
+
+	}
+
+	
+	public static function doCount(Criteria $criteria, $distinct = false, PropelPDO $con = null)
+	{
+				$criteria = clone $criteria;
+
+								$criteria->setPrimaryTableName(TblblogcheckinfoPeer::TABLE_NAME);
+
+		if ($distinct && !in_array(Criteria::DISTINCT, $criteria->getSelectModifiers())) {
+			$criteria->setDistinct();
+		}
+
+		if (!$criteria->hasSelectClause()) {
+			TblblogcheckinfoPeer::addSelectColumns($criteria);
+		}
+
+		$criteria->clearOrderByColumns(); 		$criteria->setDbName(self::DATABASE_NAME); 
+		if ($con === null) {
+			$con = Propel::getConnection(TblblogcheckinfoPeer::DATABASE_NAME, Propel::CONNECTION_READ);
+		}
+				$stmt = BasePeer::doCount($criteria, $con);
+
+		if ($row = $stmt->fetch(PDO::FETCH_NUM)) {
+			$count = (int) $row[0];
+		} else {
+			$count = 0; 		}
+		$stmt->closeCursor();
+		return $count;
+	}
+	
+	public static function doSelectOne(Criteria $criteria, PropelPDO $con = null)
+	{
+		$critcopy = clone $criteria;
+		$critcopy->setLimit(1);
+		$objects = TblblogcheckinfoPeer::doSelect($critcopy, $con);
+		if ($objects) {
+			return $objects[0];
+		}
+		return null;
+	}
+	
+	public static function doSelect(Criteria $criteria, PropelPDO $con = null)
+	{
+		return TblblogcheckinfoPeer::populateObjects(TblblogcheckinfoPeer::doSelectStmt($criteria, $con));
+	}
+	
+	public static function doSelectStmt(Criteria $criteria, PropelPDO $con = null)
+	{
+		if ($con === null) {
+			$con = Propel::getConnection(TblblogcheckinfoPeer::DATABASE_NAME, Propel::CONNECTION_READ);
+		}
+
+		if (!$criteria->hasSelectClause()) {
+			$criteria = clone $criteria;
+			TblblogcheckinfoPeer::addSelectColumns($criteria);
+		}
+
+				$criteria->setDbName(self::DATABASE_NAME);
+
+				return BasePeer::doSelect($criteria, $con);
+	}
+	
+	public static function addInstanceToPool(Tblblogcheckinfo $obj, $key = null)
+	{
+		if (Propel::isInstancePoolingEnabled()) {
+			if ($key === null) {
+				$key = (string) $obj->getCiUserid();
+			} 			self::$instances[$key] = $obj;
+		}
+	}
+
+	
+	public static function removeInstanceFromPool($value)
+	{
+		if (Propel::isInstancePoolingEnabled() && $value !== null) {
+			if (is_object($value) && $value instanceof Tblblogcheckinfo) {
+				$key = (string) $value->getCiUserid();
+			} elseif (is_scalar($value)) {
+								$key = (string) $value;
+			} else {
+				$e = new PropelException("Invalid value passed to removeInstanceFromPool().  Expected primary key or Tblblogcheckinfo object; got " . (is_object($value) ? get_class($value) . ' object.' : var_export($value,true)));
+				throw $e;
+			}
+
+			unset(self::$instances[$key]);
+		}
+	} 
+	
+	public static function getInstanceFromPool($key)
+	{
+		if (Propel::isInstancePoolingEnabled()) {
+			if (isset(self::$instances[$key])) {
+				return self::$instances[$key];
+			}
+		}
+		return null; 	}
+	
+	
+	public static function clearInstancePool()
+	{
+		self::$instances = array();
+	}
+	
+	
+	public static function getPrimaryKeyHashFromRow($row, $startcol = 0)
+	{
+				if ($row[$startcol + 0] === null) {
+			return null;
+		}
+		return (string) $row[$startcol + 0];
+	}
+
+	
+	public static function populateObjects(PDOStatement $stmt)
+	{
+		$results = array();
+	
+				$cls = TblblogcheckinfoPeer::getOMClass();
+		$cls = substr('.'.$cls, strrpos('.'.$cls, '.') + 1);
+				while ($row = $stmt->fetch(PDO::FETCH_NUM)) {
+			$key = TblblogcheckinfoPeer::getPrimaryKeyHashFromRow($row, 0);
+			if (null !== ($obj = TblblogcheckinfoPeer::getInstanceFromPool($key))) {
+																$results[] = $obj;
+			} else {
+		
+				$obj = new $cls();
+				$obj->hydrate($row);
+				$results[] = $obj;
+				TblblogcheckinfoPeer::addInstanceToPool($obj, $key);
+			} 		}
+		$stmt->closeCursor();
+		return $results;
+	}
+
+	
+	public static function doCountJoinTbluser(Criteria $criteria, $distinct = false, PropelPDO $con = null, $join_behavior = Criteria::LEFT_JOIN)
+	{
+				$criteria = clone $criteria;
+
+								$criteria->setPrimaryTableName(TblblogcheckinfoPeer::TABLE_NAME);
+
+		if ($distinct && !in_array(Criteria::DISTINCT, $criteria->getSelectModifiers())) {
+			$criteria->setDistinct();
+		}
+
+		if (!$criteria->hasSelectClause()) {
+			TblblogcheckinfoPeer::addSelectColumns($criteria);
+		}
+		
+		$criteria->clearOrderByColumns(); 		
+				$criteria->setDbName(self::DATABASE_NAME);
+
+		if ($con === null) {
+			$con = Propel::getConnection(TblblogcheckinfoPeer::DATABASE_NAME, Propel::CONNECTION_READ);
+		}
+
+		$criteria->addJoin(array(TblblogcheckinfoPeer::CI_USERID,), array(TbluserPeer::US_ID,), $join_behavior);
+		$stmt = BasePeer::doCount($criteria, $con);
+
+		if ($row = $stmt->fetch(PDO::FETCH_NUM)) {
+			$count = (int) $row[0];
+		} else {
+			$count = 0; 		}
+		$stmt->closeCursor();
+		return $count;
+	}
+
+
+	
+	public static function doSelectJoinTbluser(Criteria $c, $con = null, $join_behavior = Criteria::LEFT_JOIN)
+	{
+		$c = clone $c;
+
+				if ($c->getDbName() == Propel::getDefaultDB()) {
+			$c->setDbName(self::DATABASE_NAME);
+		}
+
+		TblblogcheckinfoPeer::addSelectColumns($c);
+		$startcol = (TblblogcheckinfoPeer::NUM_COLUMNS - TblblogcheckinfoPeer::NUM_LAZY_LOAD_COLUMNS);
+		TbluserPeer::addSelectColumns($c);
+
+		$c->addJoin(array(TblblogcheckinfoPeer::CI_USERID,), array(TbluserPeer::US_ID,), $join_behavior);
+		$stmt = BasePeer::doSelect($c, $con);
+		$results = array();
+
+		while ($row = $stmt->fetch(PDO::FETCH_NUM)) {
+			$key1 = TblblogcheckinfoPeer::getPrimaryKeyHashFromRow($row, 0);
+			if (null !== ($obj1 = TblblogcheckinfoPeer::getInstanceFromPool($key1))) {
+															} else {
+
+				$omClass = TblblogcheckinfoPeer::getOMClass();
+
+				$cls = substr('.'.$omClass, strrpos('.'.$omClass, '.') + 1);
+				$obj1 = new $cls();
+				$obj1->hydrate($row);
+				TblblogcheckinfoPeer::addInstanceToPool($obj1, $key1);
+			} 
+			$key2 = TbluserPeer::getPrimaryKeyHashFromRow($row, $startcol);
+			if ($key2 !== null) {
+				$obj2 = TbluserPeer::getInstanceFromPool($key2);
+				if (!$obj2) {
+
+					$omClass = TbluserPeer::getOMClass();
+
+					$cls = substr('.'.$omClass, strrpos('.'.$omClass, '.') + 1);
+					$obj2 = new $cls();
+					$obj2->hydrate($row, $startcol);
+					TbluserPeer::addInstanceToPool($obj2, $key2);
+				} 
+								$obj2->setTblblogcheckinfo($obj1);
+
+			} 
+			$results[] = $obj1;
+		}
+		$stmt->closeCursor();
+		return $results;
+	}
+
+
+	
+	public static function doCountJoinAll(Criteria $criteria, $distinct = false, PropelPDO $con = null, $join_behavior = Criteria::LEFT_JOIN)
+	{
+				$criteria = clone $criteria;
+
+								$criteria->setPrimaryTableName(TblblogcheckinfoPeer::TABLE_NAME);
+
+		if ($distinct && !in_array(Criteria::DISTINCT, $criteria->getSelectModifiers())) {
+			$criteria->setDistinct();
+		}
+
+		if (!$criteria->hasSelectClause()) {
+			TblblogcheckinfoPeer::addSelectColumns($criteria);
+		}
+		
+		$criteria->clearOrderByColumns(); 		
+				$criteria->setDbName(self::DATABASE_NAME);
+
+		if ($con === null) {
+			$con = Propel::getConnection(TblblogcheckinfoPeer::DATABASE_NAME, Propel::CONNECTION_READ);
+		}
+
+		$criteria->addJoin(array(TblblogcheckinfoPeer::CI_USERID,), array(TbluserPeer::US_ID,), $join_behavior);
+		$stmt = BasePeer::doCount($criteria, $con);
+
+		if ($row = $stmt->fetch(PDO::FETCH_NUM)) {
+			$count = (int) $row[0];
+		} else {
+			$count = 0; 		}
+		$stmt->closeCursor();
+		return $count;
+	}
+
+	
+	public static function doSelectJoinAll(Criteria $c, $con = null, $join_behavior = Criteria::LEFT_JOIN)
+	{
+		$c = clone $c;
+
+				if ($c->getDbName() == Propel::getDefaultDB()) {
+			$c->setDbName(self::DATABASE_NAME);
+		}
+
+		TblblogcheckinfoPeer::addSelectColumns($c);
+		$startcol2 = (TblblogcheckinfoPeer::NUM_COLUMNS - TblblogcheckinfoPeer::NUM_LAZY_LOAD_COLUMNS);
+
+		TbluserPeer::addSelectColumns($c);
+		$startcol3 = $startcol2 + (TbluserPeer::NUM_COLUMNS - TbluserPeer::NUM_LAZY_LOAD_COLUMNS);
+
+		$c->addJoin(array(TblblogcheckinfoPeer::CI_USERID,), array(TbluserPeer::US_ID,), $join_behavior);
+		$stmt = BasePeer::doSelect($c, $con);
+		$results = array();
+
+		while ($row = $stmt->fetch(PDO::FETCH_NUM)) {
+			$key1 = TblblogcheckinfoPeer::getPrimaryKeyHashFromRow($row, 0);
+			if (null !== ($obj1 = TblblogcheckinfoPeer::getInstanceFromPool($key1))) {
+															} else {
+				$omClass = TblblogcheckinfoPeer::getOMClass();
+
+				$cls = substr('.'.$omClass, strrpos('.'.$omClass, '.') + 1);
+				$obj1 = new $cls();
+				$obj1->hydrate($row);
+				TblblogcheckinfoPeer::addInstanceToPool($obj1, $key1);
+			} 
+			
+			$key2 = TbluserPeer::getPrimaryKeyHashFromRow($row, $startcol2);
+			if ($key2 !== null) {
+				$obj2 = TbluserPeer::getInstanceFromPool($key2);
+				if (!$obj2) {
+
+					$omClass = TbluserPeer::getOMClass();
+
+
+					$cls = substr('.'.$omClass, strrpos('.'.$omClass, '.') + 1);
+					$obj2 = new $cls();
+					$obj2->hydrate($row, $startcol2);
+					TbluserPeer::addInstanceToPool($obj2, $key2);
+				} 
+								$obj1->setTbluser($obj2);
+			} 
+			$results[] = $obj1;
+		}
+		$stmt->closeCursor();
+		return $results;
+	}
+
+	
+	public static function getTableMap()
+	{
+		return Propel::getDatabaseMap(self::DATABASE_NAME)->getTable(self::TABLE_NAME);
+	}
+
+	
+	public static function getOMClass()
+	{
+		return TblblogcheckinfoPeer::CLASS_DEFAULT;
+	}
+
+	
+	public static function doInsert($values, PropelPDO $con = null)
+	{
+		if ($con === null) {
+			$con = Propel::getConnection(TblblogcheckinfoPeer::DATABASE_NAME, Propel::CONNECTION_WRITE);
+		}
+
+		if ($values instanceof Criteria) {
+			$criteria = clone $values; 		} else {
+			$criteria = $values->buildCriteria(); 		}
+
+
+				$criteria->setDbName(self::DATABASE_NAME);
+
+		try {
+									$con->beginTransaction();
+			$pk = BasePeer::doInsert($criteria, $con);
+			$con->commit();
+		} catch(PropelException $e) {
+			$con->rollBack();
+			throw $e;
+		}
+
+		return $pk;
+	}
+
+	
+	public static function doUpdate($values, PropelPDO $con = null)
+	{
+		if ($con === null) {
+			$con = Propel::getConnection(TblblogcheckinfoPeer::DATABASE_NAME, Propel::CONNECTION_WRITE);
+		}
+
+		$selectCriteria = new Criteria(self::DATABASE_NAME);
+
+		if ($values instanceof Criteria) {
+			$criteria = clone $values; 
+			$comparison = $criteria->getComparison(TblblogcheckinfoPeer::CI_USERID);
+			$selectCriteria->add(TblblogcheckinfoPeer::CI_USERID, $criteria->remove(TblblogcheckinfoPeer::CI_USERID), $comparison);
+
+		} else { 			$criteria = $values->buildCriteria(); 			$selectCriteria = $values->buildPkeyCriteria(); 		}
+
+				$criteria->setDbName(self::DATABASE_NAME);
+
+		return BasePeer::doUpdate($selectCriteria, $criteria, $con);
+	}
+
+	
+	public static function doDeleteAll($con = null)
+	{
+		if ($con === null) {
+			$con = Propel::getConnection(TblblogcheckinfoPeer::DATABASE_NAME, Propel::CONNECTION_WRITE);
+		}
+		$affectedRows = 0; 		try {
+									$con->beginTransaction();
+			$affectedRows += BasePeer::doDeleteAll(TblblogcheckinfoPeer::TABLE_NAME, $con);
+			$con->commit();
+			return $affectedRows;
+		} catch (PropelException $e) {
+			$con->rollBack();
+			throw $e;
+		}
+	}
+
+	
+	 public static function doDelete($values, PropelPDO $con = null)
+	 {
+		if ($con === null) {
+			$con = Propel::getConnection(TblblogcheckinfoPeer::DATABASE_NAME, Propel::CONNECTION_WRITE);
+		}
+
+		if ($values instanceof Criteria) {
+												TblblogcheckinfoPeer::clearInstancePool();
+
+						$criteria = clone $values;
+		} elseif ($values instanceof Tblblogcheckinfo) {
+						TblblogcheckinfoPeer::removeInstanceFromPool($values);
+						$criteria = $values->buildPkeyCriteria();
+		} else {
+			
+
+
+			$criteria = new Criteria(self::DATABASE_NAME);
+			$criteria->add(TblblogcheckinfoPeer::CI_USERID, (array) $values, Criteria::IN);
+
+			foreach ((array) $values as $singleval) {
+								TblblogcheckinfoPeer::removeInstanceFromPool($singleval);
+			}
+		}
+
+				$criteria->setDbName(self::DATABASE_NAME);
+
+		$affectedRows = 0; 
+		try {
+									$con->beginTransaction();
+			
+			$affectedRows += BasePeer::doDelete($criteria, $con);
+
+			$con->commit();
+			return $affectedRows;
+		} catch (PropelException $e) {
+			$con->rollBack();
+			throw $e;
+		}
+	}
+
+	
+	public static function doValidate(Tblblogcheckinfo $obj, $cols = null)
+	{
+		$columns = array();
+
+		if ($cols) {
+			$dbMap = Propel::getDatabaseMap(TblblogcheckinfoPeer::DATABASE_NAME);
+			$tableMap = $dbMap->getTable(TblblogcheckinfoPeer::TABLE_NAME);
+
+			if (! is_array($cols)) {
+				$cols = array($cols);
+			}
+
+			foreach ($cols as $colName) {
+				if ($tableMap->containsColumn($colName)) {
+					$get = 'get' . $tableMap->getColumn($colName)->getPhpName();
+					$columns[$colName] = $obj->$get();
+				}
+			}
+		} else {
+
+		}
+
+		$res =  BasePeer::doValidate(TblblogcheckinfoPeer::DATABASE_NAME, TblblogcheckinfoPeer::TABLE_NAME, $columns);
+    if ($res !== true) {
+        $request = sfContext::getInstance()->getRequest();
+        foreach ($res as $failed) {
+            $col = TblblogcheckinfoPeer::translateFieldname($failed->getColumn(), BasePeer::TYPE_COLNAME, BasePeer::TYPE_PHPNAME);
+            $request->setError($col, $failed->getMessage());
+        }
+    }
+
+    return $res;
+	}
+
+	
+	public static function retrieveByPK($pk, PropelPDO $con = null)
+	{
+
+		if (null !== ($obj = TblblogcheckinfoPeer::getInstanceFromPool((string) $pk))) {
+			return $obj;
+		}
+
+		if ($con === null) {
+			$con = Propel::getConnection(TblblogcheckinfoPeer::DATABASE_NAME, Propel::CONNECTION_READ);
+		}
+
+		$criteria = new Criteria(TblblogcheckinfoPeer::DATABASE_NAME);
+		$criteria->add(TblblogcheckinfoPeer::CI_USERID, $pk);
+
+		$v = TblblogcheckinfoPeer::doSelect($criteria, $con);
+
+		return !empty($v) > 0 ? $v[0] : null;
+	}
+
+	
+	public static function retrieveByPKs($pks, PropelPDO $con = null)
+	{
+		if ($con === null) {
+			$con = Propel::getConnection(TblblogcheckinfoPeer::DATABASE_NAME, Propel::CONNECTION_READ);
+		}
+
+		$objs = null;
+		if (empty($pks)) {
+			$objs = array();
+		} else {
+			$criteria = new Criteria(TblblogcheckinfoPeer::DATABASE_NAME);
+			$criteria->add(TblblogcheckinfoPeer::CI_USERID, $pks, Criteria::IN);
+			$objs = TblblogcheckinfoPeer::doSelect($criteria, $con);
+		}
+		return $objs;
+	}
+
+} 
+
+Propel::getDatabaseMap(BaseTblblogcheckinfoPeer::DATABASE_NAME)->addTableBuilder(BaseTblblogcheckinfoPeer::TABLE_NAME, BaseTblblogcheckinfoPeer::getMapBuilder());
+
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/lib/model/om/BaseTblspacecategory.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/lib/model/om/BaseTblspacecategory.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/lib/model/om/BaseTblspacecategory.php	(revision 19)
@@ -0,0 +1,527 @@
+<?php
+
+
+abstract class BaseTblspacecategory extends BaseObject  implements Persistent {
+
+
+	
+	protected static $peer;
+
+	
+	protected $cat_id;
+
+	
+	protected $cat_name;
+
+	
+	protected $cat_parent;
+
+	
+	protected $cat_user;
+
+	
+	protected $cat_date;
+
+	
+	protected $alreadyInSave = false;
+
+	
+	protected $alreadyInValidation = false;
+
+	
+	public function __construct()
+	{
+		parent::__construct();
+		$this->applyDefaultValues();
+	}
+
+	
+	public function applyDefaultValues()
+	{
+	}
+
+	
+	public function getCatId()
+	{
+		return $this->cat_id;
+	}
+
+	
+	public function getCatName()
+	{
+		return $this->cat_name;
+	}
+
+	
+	public function getCatParent()
+	{
+		return $this->cat_parent;
+	}
+
+	
+	public function getCatUser()
+	{
+		return $this->cat_user;
+	}
+
+	
+	public function getCatDate($format = 'Y-m-d H:i:s')
+	{
+		if ($this->cat_date === null) {
+			return null;
+		}
+
+
+		if ($this->cat_date === '0000-00-00 00:00:00') {
+									return null;
+		} else {
+			try {
+				$dt = new DateTime($this->cat_date);
+			} catch (Exception $x) {
+				throw new PropelException("Internally stored date/time/timestamp value could not be converted to DateTime: " . var_export($this->cat_date, true), $x);
+			}
+		}
+
+		if ($format === null) {
+						return $dt;
+		} elseif (strpos($format, '%') !== false) {
+			return strftime($format, $dt->format('U'));
+		} else {
+			return $dt->format($format);
+		}
+	}
+
+	
+	public function setCatId($v)
+	{
+		if ($v !== null) {
+			$v = (int) $v;
+		}
+
+		if ($this->cat_id !== $v) {
+			$this->cat_id = $v;
+			$this->modifiedColumns[] = TblspacecategoryPeer::CAT_ID;
+		}
+
+		return $this;
+	} 
+	
+	public function setCatName($v)
+	{
+		if ($v !== null) {
+			$v = (string) $v;
+		}
+
+		if ($this->cat_name !== $v) {
+			$this->cat_name = $v;
+			$this->modifiedColumns[] = TblspacecategoryPeer::CAT_NAME;
+		}
+
+		return $this;
+	} 
+	
+	public function setCatParent($v)
+	{
+		if ($v !== null) {
+			$v = (int) $v;
+		}
+
+		if ($this->cat_parent !== $v) {
+			$this->cat_parent = $v;
+			$this->modifiedColumns[] = TblspacecategoryPeer::CAT_PARENT;
+		}
+
+		return $this;
+	} 
+	
+	public function setCatUser($v)
+	{
+		if ($v !== null) {
+			$v = (int) $v;
+		}
+
+		if ($this->cat_user !== $v) {
+			$this->cat_user = $v;
+			$this->modifiedColumns[] = TblspacecategoryPeer::CAT_USER;
+		}
+
+		return $this;
+	} 
+	
+	public function setCatDate($v)
+	{
+						if ($v === null || $v === '') {
+			$dt = null;
+		} elseif ($v instanceof DateTime) {
+			$dt = $v;
+		} else {
+									try {
+				if (is_numeric($v)) { 					$dt = new DateTime('@'.$v, new DateTimeZone('UTC'));
+															$dt->setTimeZone(new DateTimeZone(date_default_timezone_get()));
+				} else {
+					$dt = new DateTime($v);
+				}
+			} catch (Exception $x) {
+				throw new PropelException('Error parsing date/time value: ' . var_export($v, true), $x);
+			}
+		}
+
+		if ( $this->cat_date !== null || $dt !== null ) {
+			
+			$currNorm = ($this->cat_date !== null && $tmpDt = new DateTime($this->cat_date)) ? $tmpDt->format('Y-m-d H:i:s') : null;
+			$newNorm = ($dt !== null) ? $dt->format('Y-m-d H:i:s') : null;
+
+			if ( ($currNorm !== $newNorm) 					)
+			{
+				$this->cat_date = ($dt ? $dt->format('Y-m-d H:i:s') : null);
+				$this->modifiedColumns[] = TblspacecategoryPeer::CAT_DATE;
+			}
+		} 
+		return $this;
+	} 
+	
+	public function hasOnlyDefaultValues()
+	{
+						if (array_diff($this->modifiedColumns, array())) {
+				return false;
+			}
+
+				return true;
+	} 
+	
+	public function hydrate($row, $startcol = 0, $rehydrate = false)
+	{
+		try {
+
+			$this->cat_id = ($row[$startcol + 0] !== null) ? (int) $row[$startcol + 0] : null;
+			$this->cat_name = ($row[$startcol + 1] !== null) ? (string) $row[$startcol + 1] : null;
+			$this->cat_parent = ($row[$startcol + 2] !== null) ? (int) $row[$startcol + 2] : null;
+			$this->cat_user = ($row[$startcol + 3] !== null) ? (int) $row[$startcol + 3] : null;
+			$this->cat_date = ($row[$startcol + 4] !== null) ? (string) $row[$startcol + 4] : null;
+			$this->resetModified();
+
+			$this->setNew(false);
+
+			if ($rehydrate) {
+				$this->ensureConsistency();
+			}
+
+						return $startcol + 5; 
+		} catch (Exception $e) {
+			throw new PropelException("Error populating Tblspacecategory object", $e);
+		}
+	}
+
+	
+	public function ensureConsistency()
+	{
+
+	} 
+	
+	public function reload($deep = false, PropelPDO $con = null)
+	{
+		if ($this->isDeleted()) {
+			throw new PropelException("Cannot reload a deleted object.");
+		}
+
+		if ($this->isNew()) {
+			throw new PropelException("Cannot reload an unsaved object.");
+		}
+
+		if ($con === null) {
+			$con = Propel::getConnection(TblspacecategoryPeer::DATABASE_NAME, Propel::CONNECTION_READ);
+		}
+
+				
+		$stmt = TblspacecategoryPeer::doSelectStmt($this->buildPkeyCriteria(), $con);
+		$row = $stmt->fetch(PDO::FETCH_NUM);
+		$stmt->closeCursor();
+		if (!$row) {
+			throw new PropelException('Cannot find matching row in the database to reload object values.');
+		}
+		$this->hydrate($row, 0, true); 
+		if ($deep) {  
+		} 	}
+
+	
+	public function delete(PropelPDO $con = null)
+	{
+		if ($this->isDeleted()) {
+			throw new PropelException("This object has already been deleted.");
+		}
+
+		if ($con === null) {
+			$con = Propel::getConnection(TblspacecategoryPeer::DATABASE_NAME, Propel::CONNECTION_WRITE);
+		}
+		
+		$con->beginTransaction();
+		try {
+			TblspacecategoryPeer::doDelete($this, $con);
+			$this->setDeleted(true);
+			$con->commit();
+		} catch (PropelException $e) {
+			$con->rollBack();
+			throw $e;
+		}
+	}
+
+	
+	public function save(PropelPDO $con = null)
+	{
+		if ($this->isDeleted()) {
+			throw new PropelException("You cannot save an object that has been deleted.");
+		}
+
+		if ($con === null) {
+			$con = Propel::getConnection(TblspacecategoryPeer::DATABASE_NAME, Propel::CONNECTION_WRITE);
+		}
+		
+		$con->beginTransaction();
+		try {
+			$affectedRows = $this->doSave($con);
+			$con->commit();
+			TblspacecategoryPeer::addInstanceToPool($this);
+			return $affectedRows;
+		} catch (PropelException $e) {
+			$con->rollBack();
+			throw $e;
+		}
+	}
+
+	
+	protected function doSave(PropelPDO $con)
+	{
+		$affectedRows = 0; 		if (!$this->alreadyInSave) {
+			$this->alreadyInSave = true;
+
+			if ($this->isNew() ) {
+				$this->modifiedColumns[] = TblspacecategoryPeer::CAT_ID;
+			}
+
+						if ($this->isModified()) {
+				if ($this->isNew()) {
+					$pk = TblspacecategoryPeer::doInsert($this, $con);
+					$affectedRows += 1; 										 										 
+					$this->setCatId($pk);  
+					$this->setNew(false);
+				} else {
+					$affectedRows += TblspacecategoryPeer::doUpdate($this, $con);
+				}
+
+				$this->resetModified(); 			}
+
+			$this->alreadyInSave = false;
+
+		}
+		return $affectedRows;
+	} 
+	
+	protected $validationFailures = array();
+
+	
+	public function getValidationFailures()
+	{
+		return $this->validationFailures;
+	}
+
+	
+	public function validate($columns = null)
+	{
+		$res = $this->doValidate($columns);
+		if ($res === true) {
+			$this->validationFailures = array();
+			return true;
+		} else {
+			$this->validationFailures = $res;
+			return false;
+		}
+	}
+
+	
+	protected function doValidate($columns = null)
+	{
+		if (!$this->alreadyInValidation) {
+			$this->alreadyInValidation = true;
+			$retval = null;
+
+			$failureMap = array();
+
+
+			if (($retval = TblspacecategoryPeer::doValidate($this, $columns)) !== true) {
+				$failureMap = array_merge($failureMap, $retval);
+			}
+
+
+
+			$this->alreadyInValidation = false;
+		}
+
+		return (!empty($failureMap) ? $failureMap : true);
+	}
+
+	
+	public function getByName($name, $type = BasePeer::TYPE_PHPNAME)
+	{
+		$pos = TblspacecategoryPeer::translateFieldName($name, $type, BasePeer::TYPE_NUM);
+		$field = $this->getByPosition($pos);
+		return $field;
+	}
+
+	
+	public function getByPosition($pos)
+	{
+		switch($pos) {
+			case 0:
+				return $this->getCatId();
+				break;
+			case 1:
+				return $this->getCatName();
+				break;
+			case 2:
+				return $this->getCatParent();
+				break;
+			case 3:
+				return $this->getCatUser();
+				break;
+			case 4:
+				return $this->getCatDate();
+				break;
+			default:
+				return null;
+				break;
+		} 	}
+
+	
+	public function toArray($keyType = BasePeer::TYPE_PHPNAME, $includeLazyLoadColumns = true)
+	{
+		$keys = TblspacecategoryPeer::getFieldNames($keyType);
+		$result = array(
+			$keys[0] => $this->getCatId(),
+			$keys[1] => $this->getCatName(),
+			$keys[2] => $this->getCatParent(),
+			$keys[3] => $this->getCatUser(),
+			$keys[4] => $this->getCatDate(),
+		);
+		return $result;
+	}
+
+	
+	public function setByName($name, $value, $type = BasePeer::TYPE_PHPNAME)
+	{
+		$pos = TblspacecategoryPeer::translateFieldName($name, $type, BasePeer::TYPE_NUM);
+		return $this->setByPosition($pos, $value);
+	}
+
+	
+	public function setByPosition($pos, $value)
+	{
+		switch($pos) {
+			case 0:
+				$this->setCatId($value);
+				break;
+			case 1:
+				$this->setCatName($value);
+				break;
+			case 2:
+				$this->setCatParent($value);
+				break;
+			case 3:
+				$this->setCatUser($value);
+				break;
+			case 4:
+				$this->setCatDate($value);
+				break;
+		} 	}
+
+	
+	public function fromArray($arr, $keyType = BasePeer::TYPE_PHPNAME)
+	{
+		$keys = TblspacecategoryPeer::getFieldNames($keyType);
+
+		if (array_key_exists($keys[0], $arr)) $this->setCatId($arr[$keys[0]]);
+		if (array_key_exists($keys[1], $arr)) $this->setCatName($arr[$keys[1]]);
+		if (array_key_exists($keys[2], $arr)) $this->setCatParent($arr[$keys[2]]);
+		if (array_key_exists($keys[3], $arr)) $this->setCatUser($arr[$keys[3]]);
+		if (array_key_exists($keys[4], $arr)) $this->setCatDate($arr[$keys[4]]);
+	}
+
+	
+	public function buildCriteria()
+	{
+		$criteria = new Criteria(TblspacecategoryPeer::DATABASE_NAME);
+
+		if ($this->isColumnModified(TblspacecategoryPeer::CAT_ID)) $criteria->add(TblspacecategoryPeer::CAT_ID, $this->cat_id);
+		if ($this->isColumnModified(TblspacecategoryPeer::CAT_NAME)) $criteria->add(TblspacecategoryPeer::CAT_NAME, $this->cat_name);
+		if ($this->isColumnModified(TblspacecategoryPeer::CAT_PARENT)) $criteria->add(TblspacecategoryPeer::CAT_PARENT, $this->cat_parent);
+		if ($this->isColumnModified(TblspacecategoryPeer::CAT_USER)) $criteria->add(TblspacecategoryPeer::CAT_USER, $this->cat_user);
+		if ($this->isColumnModified(TblspacecategoryPeer::CAT_DATE)) $criteria->add(TblspacecategoryPeer::CAT_DATE, $this->cat_date);
+
+		return $criteria;
+	}
+
+	
+	public function buildPkeyCriteria()
+	{
+		$criteria = new Criteria(TblspacecategoryPeer::DATABASE_NAME);
+
+		$criteria->add(TblspacecategoryPeer::CAT_ID, $this->cat_id);
+
+		return $criteria;
+	}
+
+	
+	public function getPrimaryKey()
+	{
+		return $this->getCatId();
+	}
+
+	
+	public function setPrimaryKey($key)
+	{
+		$this->setCatId($key);
+	}
+
+	
+	public function copyInto($copyObj, $deepCopy = false)
+	{
+
+		$copyObj->setCatName($this->cat_name);
+
+		$copyObj->setCatParent($this->cat_parent);
+
+		$copyObj->setCatUser($this->cat_user);
+
+		$copyObj->setCatDate($this->cat_date);
+
+
+		$copyObj->setNew(true);
+
+		$copyObj->setCatId(NULL); 
+	}
+
+	
+	public function copy($deepCopy = false)
+	{
+				$clazz = get_class($this);
+		$copyObj = new $clazz();
+		$this->copyInto($copyObj, $deepCopy);
+		return $copyObj;
+	}
+
+	
+	public function getPeer()
+	{
+		if (self::$peer === null) {
+			self::$peer = new TblspacecategoryPeer();
+		}
+		return self::$peer;
+	}
+
+	
+	public function clearAllReferences($deep = false)
+	{
+		if ($deep) {
+		} 
+	}
+
+} 
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/lib/model/om/BaseTblspacecategoryPeer.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/lib/model/om/BaseTblspacecategoryPeer.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/lib/model/om/BaseTblspacecategoryPeer.php	(revision 19)
@@ -0,0 +1,441 @@
+<?php
+
+
+abstract class BaseTblspacecategoryPeer {
+
+	
+	const DATABASE_NAME = 'propel';
+
+	
+	const TABLE_NAME = 'tblspacecategory';
+
+	
+	const CLASS_DEFAULT = 'lib.model.Tblspacecategory';
+
+	
+	const NUM_COLUMNS = 5;
+
+	
+	const NUM_LAZY_LOAD_COLUMNS = 0;
+
+	
+	const CAT_ID = 'tblspacecategory.CAT_ID';
+
+	
+	const CAT_NAME = 'tblspacecategory.CAT_NAME';
+
+	
+	const CAT_PARENT = 'tblspacecategory.CAT_PARENT';
+
+	
+	const CAT_USER = 'tblspacecategory.CAT_USER';
+
+	
+	const CAT_DATE = 'tblspacecategory.CAT_DATE';
+
+	
+	public static $instances = array();
+
+	
+	private static $mapBuilder = null;
+
+	
+	private static $fieldNames = array (
+		BasePeer::TYPE_PHPNAME => array ('CatId', 'CatName', 'CatParent', 'CatUser', 'CatDate', ),
+		BasePeer::TYPE_STUDLYPHPNAME => array ('catId', 'catName', 'catParent', 'catUser', 'catDate', ),
+		BasePeer::TYPE_COLNAME => array (self::CAT_ID, self::CAT_NAME, self::CAT_PARENT, self::CAT_USER, self::CAT_DATE, ),
+		BasePeer::TYPE_FIELDNAME => array ('cat_id', 'cat_name', 'cat_parent', 'cat_user', 'cat_date', ),
+		BasePeer::TYPE_NUM => array (0, 1, 2, 3, 4, )
+	);
+
+	
+	private static $fieldKeys = array (
+		BasePeer::TYPE_PHPNAME => array ('CatId' => 0, 'CatName' => 1, 'CatParent' => 2, 'CatUser' => 3, 'CatDate' => 4, ),
+		BasePeer::TYPE_STUDLYPHPNAME => array ('catId' => 0, 'catName' => 1, 'catParent' => 2, 'catUser' => 3, 'catDate' => 4, ),
+		BasePeer::TYPE_COLNAME => array (self::CAT_ID => 0, self::CAT_NAME => 1, self::CAT_PARENT => 2, self::CAT_USER => 3, self::CAT_DATE => 4, ),
+		BasePeer::TYPE_FIELDNAME => array ('cat_id' => 0, 'cat_name' => 1, 'cat_parent' => 2, 'cat_user' => 3, 'cat_date' => 4, ),
+		BasePeer::TYPE_NUM => array (0, 1, 2, 3, 4, )
+	);
+
+	
+	public static function getMapBuilder()
+	{
+		if (self::$mapBuilder === null) {
+			self::$mapBuilder = new TblspacecategoryMapBuilder();
+		}
+		return self::$mapBuilder;
+	}
+	
+	static public function translateFieldName($name, $fromType, $toType)
+	{
+		$toNames = self::getFieldNames($toType);
+		$key = isset(self::$fieldKeys[$fromType][$name]) ? self::$fieldKeys[$fromType][$name] : null;
+		if ($key === null) {
+			throw new PropelException("'$name' could not be found in the field names of type '$fromType'. These are: " . print_r(self::$fieldKeys[$fromType], true));
+		}
+		return $toNames[$key];
+	}
+
+	
+
+	static public function getFieldNames($type = BasePeer::TYPE_PHPNAME)
+	{
+		if (!array_key_exists($type, self::$fieldNames)) {
+			throw new PropelException('Method getFieldNames() expects the parameter $type to be one of the class constants BasePeer::TYPE_PHPNAME, BasePeer::TYPE_STUDLYPHPNAME, BasePeer::TYPE_COLNAME, BasePeer::TYPE_FIELDNAME, BasePeer::TYPE_NUM. ' . $type . ' was given.');
+		}
+		return self::$fieldNames[$type];
+	}
+
+	
+	public static function alias($alias, $column)
+	{
+		return str_replace(TblspacecategoryPeer::TABLE_NAME.'.', $alias.'.', $column);
+	}
+
+	
+	public static function addSelectColumns(Criteria $criteria)
+	{
+
+		$criteria->addSelectColumn(TblspacecategoryPeer::CAT_ID);
+
+		$criteria->addSelectColumn(TblspacecategoryPeer::CAT_NAME);
+
+		$criteria->addSelectColumn(TblspacecategoryPeer::CAT_PARENT);
+
+		$criteria->addSelectColumn(TblspacecategoryPeer::CAT_USER);
+
+		$criteria->addSelectColumn(TblspacecategoryPeer::CAT_DATE);
+
+	}
+
+	
+	public static function doCount(Criteria $criteria, $distinct = false, PropelPDO $con = null)
+	{
+				$criteria = clone $criteria;
+
+								$criteria->setPrimaryTableName(TblspacecategoryPeer::TABLE_NAME);
+
+		if ($distinct && !in_array(Criteria::DISTINCT, $criteria->getSelectModifiers())) {
+			$criteria->setDistinct();
+		}
+
+		if (!$criteria->hasSelectClause()) {
+			TblspacecategoryPeer::addSelectColumns($criteria);
+		}
+
+		$criteria->clearOrderByColumns(); 		$criteria->setDbName(self::DATABASE_NAME); 
+		if ($con === null) {
+			$con = Propel::getConnection(TblspacecategoryPeer::DATABASE_NAME, Propel::CONNECTION_READ);
+		}
+				$stmt = BasePeer::doCount($criteria, $con);
+
+		if ($row = $stmt->fetch(PDO::FETCH_NUM)) {
+			$count = (int) $row[0];
+		} else {
+			$count = 0; 		}
+		$stmt->closeCursor();
+		return $count;
+	}
+	
+	public static function doSelectOne(Criteria $criteria, PropelPDO $con = null)
+	{
+		$critcopy = clone $criteria;
+		$critcopy->setLimit(1);
+		$objects = TblspacecategoryPeer::doSelect($critcopy, $con);
+		if ($objects) {
+			return $objects[0];
+		}
+		return null;
+	}
+	
+	public static function doSelect(Criteria $criteria, PropelPDO $con = null)
+	{
+		return TblspacecategoryPeer::populateObjects(TblspacecategoryPeer::doSelectStmt($criteria, $con));
+	}
+	
+	public static function doSelectStmt(Criteria $criteria, PropelPDO $con = null)
+	{
+		if ($con === null) {
+			$con = Propel::getConnection(TblspacecategoryPeer::DATABASE_NAME, Propel::CONNECTION_READ);
+		}
+
+		if (!$criteria->hasSelectClause()) {
+			$criteria = clone $criteria;
+			TblspacecategoryPeer::addSelectColumns($criteria);
+		}
+
+				$criteria->setDbName(self::DATABASE_NAME);
+
+				return BasePeer::doSelect($criteria, $con);
+	}
+	
+	public static function addInstanceToPool(Tblspacecategory $obj, $key = null)
+	{
+		if (Propel::isInstancePoolingEnabled()) {
+			if ($key === null) {
+				$key = (string) $obj->getCatId();
+			} 			self::$instances[$key] = $obj;
+		}
+	}
+
+	
+	public static function removeInstanceFromPool($value)
+	{
+		if (Propel::isInstancePoolingEnabled() && $value !== null) {
+			if (is_object($value) && $value instanceof Tblspacecategory) {
+				$key = (string) $value->getCatId();
+			} elseif (is_scalar($value)) {
+								$key = (string) $value;
+			} else {
+				$e = new PropelException("Invalid value passed to removeInstanceFromPool().  Expected primary key or Tblspacecategory object; got " . (is_object($value) ? get_class($value) . ' object.' : var_export($value,true)));
+				throw $e;
+			}
+
+			unset(self::$instances[$key]);
+		}
+	} 
+	
+	public static function getInstanceFromPool($key)
+	{
+		if (Propel::isInstancePoolingEnabled()) {
+			if (isset(self::$instances[$key])) {
+				return self::$instances[$key];
+			}
+		}
+		return null; 	}
+	
+	
+	public static function clearInstancePool()
+	{
+		self::$instances = array();
+	}
+	
+	
+	public static function getPrimaryKeyHashFromRow($row, $startcol = 0)
+	{
+				if ($row[$startcol + 0] === null) {
+			return null;
+		}
+		return (string) $row[$startcol + 0];
+	}
+
+	
+	public static function populateObjects(PDOStatement $stmt)
+	{
+		$results = array();
+	
+				$cls = TblspacecategoryPeer::getOMClass();
+		$cls = substr('.'.$cls, strrpos('.'.$cls, '.') + 1);
+				while ($row = $stmt->fetch(PDO::FETCH_NUM)) {
+			$key = TblspacecategoryPeer::getPrimaryKeyHashFromRow($row, 0);
+			if (null !== ($obj = TblspacecategoryPeer::getInstanceFromPool($key))) {
+																$results[] = $obj;
+			} else {
+		
+				$obj = new $cls();
+				$obj->hydrate($row);
+				$results[] = $obj;
+				TblspacecategoryPeer::addInstanceToPool($obj, $key);
+			} 		}
+		$stmt->closeCursor();
+		return $results;
+	}
+	
+	public static function getTableMap()
+	{
+		return Propel::getDatabaseMap(self::DATABASE_NAME)->getTable(self::TABLE_NAME);
+	}
+
+	
+	public static function getOMClass()
+	{
+		return TblspacecategoryPeer::CLASS_DEFAULT;
+	}
+
+	
+	public static function doInsert($values, PropelPDO $con = null)
+	{
+		if ($con === null) {
+			$con = Propel::getConnection(TblspacecategoryPeer::DATABASE_NAME, Propel::CONNECTION_WRITE);
+		}
+
+		if ($values instanceof Criteria) {
+			$criteria = clone $values; 		} else {
+			$criteria = $values->buildCriteria(); 		}
+
+		if ($criteria->containsKey(TblspacecategoryPeer::CAT_ID) && $criteria->keyContainsValue(TblspacecategoryPeer::CAT_ID) ) {
+			throw new PropelException('Cannot insert a value for auto-increment primary key ('.TblspacecategoryPeer::CAT_ID.')');
+		}
+
+
+				$criteria->setDbName(self::DATABASE_NAME);
+
+		try {
+									$con->beginTransaction();
+			$pk = BasePeer::doInsert($criteria, $con);
+			$con->commit();
+		} catch(PropelException $e) {
+			$con->rollBack();
+			throw $e;
+		}
+
+		return $pk;
+	}
+
+	
+	public static function doUpdate($values, PropelPDO $con = null)
+	{
+		if ($con === null) {
+			$con = Propel::getConnection(TblspacecategoryPeer::DATABASE_NAME, Propel::CONNECTION_WRITE);
+		}
+
+		$selectCriteria = new Criteria(self::DATABASE_NAME);
+
+		if ($values instanceof Criteria) {
+			$criteria = clone $values; 
+			$comparison = $criteria->getComparison(TblspacecategoryPeer::CAT_ID);
+			$selectCriteria->add(TblspacecategoryPeer::CAT_ID, $criteria->remove(TblspacecategoryPeer::CAT_ID), $comparison);
+
+		} else { 			$criteria = $values->buildCriteria(); 			$selectCriteria = $values->buildPkeyCriteria(); 		}
+
+				$criteria->setDbName(self::DATABASE_NAME);
+
+		return BasePeer::doUpdate($selectCriteria, $criteria, $con);
+	}
+
+	
+	public static function doDeleteAll($con = null)
+	{
+		if ($con === null) {
+			$con = Propel::getConnection(TblspacecategoryPeer::DATABASE_NAME, Propel::CONNECTION_WRITE);
+		}
+		$affectedRows = 0; 		try {
+									$con->beginTransaction();
+			$affectedRows += BasePeer::doDeleteAll(TblspacecategoryPeer::TABLE_NAME, $con);
+			$con->commit();
+			return $affectedRows;
+		} catch (PropelException $e) {
+			$con->rollBack();
+			throw $e;
+		}
+	}
+
+	
+	 public static function doDelete($values, PropelPDO $con = null)
+	 {
+		if ($con === null) {
+			$con = Propel::getConnection(TblspacecategoryPeer::DATABASE_NAME, Propel::CONNECTION_WRITE);
+		}
+
+		if ($values instanceof Criteria) {
+												TblspacecategoryPeer::clearInstancePool();
+
+						$criteria = clone $values;
+		} elseif ($values instanceof Tblspacecategory) {
+						TblspacecategoryPeer::removeInstanceFromPool($values);
+						$criteria = $values->buildPkeyCriteria();
+		} else {
+			
+
+
+			$criteria = new Criteria(self::DATABASE_NAME);
+			$criteria->add(TblspacecategoryPeer::CAT_ID, (array) $values, Criteria::IN);
+
+			foreach ((array) $values as $singleval) {
+								TblspacecategoryPeer::removeInstanceFromPool($singleval);
+			}
+		}
+
+				$criteria->setDbName(self::DATABASE_NAME);
+
+		$affectedRows = 0; 
+		try {
+									$con->beginTransaction();
+			
+			$affectedRows += BasePeer::doDelete($criteria, $con);
+
+			$con->commit();
+			return $affectedRows;
+		} catch (PropelException $e) {
+			$con->rollBack();
+			throw $e;
+		}
+	}
+
+	
+	public static function doValidate(Tblspacecategory $obj, $cols = null)
+	{
+		$columns = array();
+
+		if ($cols) {
+			$dbMap = Propel::getDatabaseMap(TblspacecategoryPeer::DATABASE_NAME);
+			$tableMap = $dbMap->getTable(TblspacecategoryPeer::TABLE_NAME);
+
+			if (! is_array($cols)) {
+				$cols = array($cols);
+			}
+
+			foreach ($cols as $colName) {
+				if ($tableMap->containsColumn($colName)) {
+					$get = 'get' . $tableMap->getColumn($colName)->getPhpName();
+					$columns[$colName] = $obj->$get();
+				}
+			}
+		} else {
+
+		}
+
+		$res =  BasePeer::doValidate(TblspacecategoryPeer::DATABASE_NAME, TblspacecategoryPeer::TABLE_NAME, $columns);
+    if ($res !== true) {
+        $request = sfContext::getInstance()->getRequest();
+        foreach ($res as $failed) {
+            $col = TblspacecategoryPeer::translateFieldname($failed->getColumn(), BasePeer::TYPE_COLNAME, BasePeer::TYPE_PHPNAME);
+            $request->setError($col, $failed->getMessage());
+        }
+    }
+
+    return $res;
+	}
+
+	
+	public static function retrieveByPK($pk, PropelPDO $con = null)
+	{
+
+		if (null !== ($obj = TblspacecategoryPeer::getInstanceFromPool((string) $pk))) {
+			return $obj;
+		}
+
+		if ($con === null) {
+			$con = Propel::getConnection(TblspacecategoryPeer::DATABASE_NAME, Propel::CONNECTION_READ);
+		}
+
+		$criteria = new Criteria(TblspacecategoryPeer::DATABASE_NAME);
+		$criteria->add(TblspacecategoryPeer::CAT_ID, $pk);
+
+		$v = TblspacecategoryPeer::doSelect($criteria, $con);
+
+		return !empty($v) > 0 ? $v[0] : null;
+	}
+
+	
+	public static function retrieveByPKs($pks, PropelPDO $con = null)
+	{
+		if ($con === null) {
+			$con = Propel::getConnection(TblspacecategoryPeer::DATABASE_NAME, Propel::CONNECTION_READ);
+		}
+
+		$objs = null;
+		if (empty($pks)) {
+			$objs = array();
+		} else {
+			$criteria = new Criteria(TblspacecategoryPeer::DATABASE_NAME);
+			$criteria->add(TblspacecategoryPeer::CAT_ID, $pks, Criteria::IN);
+			$objs = TblspacecategoryPeer::doSelect($criteria, $con);
+		}
+		return $objs;
+	}
+
+} 
+
+Propel::getDatabaseMap(BaseTblspacecategoryPeer::DATABASE_NAME)->addTableBuilder(BaseTblspacecategoryPeer::TABLE_NAME, BaseTblspacecategoryPeer::getMapBuilder());
+
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/lib/model/om/BaseTblspacefile.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/lib/model/om/BaseTblspacefile.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/lib/model/om/BaseTblspacefile.php	(revision 19)
@@ -0,0 +1,654 @@
+<?php
+
+
+abstract class BaseTblspacefile extends BaseObject  implements Persistent {
+
+
+	
+	protected static $peer;
+
+	
+	protected $file_id;
+
+	
+	protected $file_resource;
+
+	
+	protected $file_category;
+
+	
+	protected $file_user;
+
+	
+	protected $file_name;
+
+	
+	protected $file_type;
+
+	
+	protected $file_date;
+
+	
+	protected $aTblspaceresource;
+
+	
+	protected $alreadyInSave = false;
+
+	
+	protected $alreadyInValidation = false;
+
+	
+	public function __construct()
+	{
+		parent::__construct();
+		$this->applyDefaultValues();
+	}
+
+	
+	public function applyDefaultValues()
+	{
+	}
+
+	
+	public function getFileId()
+	{
+		return $this->file_id;
+	}
+
+	
+	public function getFileResource()
+	{
+		return $this->file_resource;
+	}
+
+	
+	public function getFileCategory()
+	{
+		return $this->file_category;
+	}
+
+	
+	public function getFileUser()
+	{
+		return $this->file_user;
+	}
+
+	
+	public function getFileName()
+	{
+		return $this->file_name;
+	}
+
+	
+	public function getFileType()
+	{
+		return $this->file_type;
+	}
+
+	
+	public function getFileDate($format = 'Y-m-d H:i:s')
+	{
+		if ($this->file_date === null) {
+			return null;
+		}
+
+
+		if ($this->file_date === '0000-00-00 00:00:00') {
+									return null;
+		} else {
+			try {
+				$dt = new DateTime($this->file_date);
+			} catch (Exception $x) {
+				throw new PropelException("Internally stored date/time/timestamp value could not be converted to DateTime: " . var_export($this->file_date, true), $x);
+			}
+		}
+
+		if ($format === null) {
+						return $dt;
+		} elseif (strpos($format, '%') !== false) {
+			return strftime($format, $dt->format('U'));
+		} else {
+			return $dt->format($format);
+		}
+	}
+
+	
+	public function setFileId($v)
+	{
+		if ($v !== null) {
+			$v = (int) $v;
+		}
+
+		if ($this->file_id !== $v) {
+			$this->file_id = $v;
+			$this->modifiedColumns[] = TblspacefilePeer::FILE_ID;
+		}
+
+		return $this;
+	} 
+	
+	public function setFileResource($v)
+	{
+		if ($v !== null) {
+			$v = (int) $v;
+		}
+
+		if ($this->file_resource !== $v) {
+			$this->file_resource = $v;
+			$this->modifiedColumns[] = TblspacefilePeer::FILE_RESOURCE;
+		}
+
+		if ($this->aTblspaceresource !== null && $this->aTblspaceresource->getResId() !== $v) {
+			$this->aTblspaceresource = null;
+		}
+
+		return $this;
+	} 
+	
+	public function setFileCategory($v)
+	{
+		if ($v !== null) {
+			$v = (int) $v;
+		}
+
+		if ($this->file_category !== $v) {
+			$this->file_category = $v;
+			$this->modifiedColumns[] = TblspacefilePeer::FILE_CATEGORY;
+		}
+
+		return $this;
+	} 
+	
+	public function setFileUser($v)
+	{
+		if ($v !== null) {
+			$v = (int) $v;
+		}
+
+		if ($this->file_user !== $v) {
+			$this->file_user = $v;
+			$this->modifiedColumns[] = TblspacefilePeer::FILE_USER;
+		}
+
+		return $this;
+	} 
+	
+	public function setFileName($v)
+	{
+		if ($v !== null) {
+			$v = (string) $v;
+		}
+
+		if ($this->file_name !== $v) {
+			$this->file_name = $v;
+			$this->modifiedColumns[] = TblspacefilePeer::FILE_NAME;
+		}
+
+		return $this;
+	} 
+	
+	public function setFileType($v)
+	{
+		if ($v !== null) {
+			$v = (string) $v;
+		}
+
+		if ($this->file_type !== $v) {
+			$this->file_type = $v;
+			$this->modifiedColumns[] = TblspacefilePeer::FILE_TYPE;
+		}
+
+		return $this;
+	} 
+	
+	public function setFileDate($v)
+	{
+						if ($v === null || $v === '') {
+			$dt = null;
+		} elseif ($v instanceof DateTime) {
+			$dt = $v;
+		} else {
+									try {
+				if (is_numeric($v)) { 					$dt = new DateTime('@'.$v, new DateTimeZone('UTC'));
+															$dt->setTimeZone(new DateTimeZone(date_default_timezone_get()));
+				} else {
+					$dt = new DateTime($v);
+				}
+			} catch (Exception $x) {
+				throw new PropelException('Error parsing date/time value: ' . var_export($v, true), $x);
+			}
+		}
+
+		if ( $this->file_date !== null || $dt !== null ) {
+			
+			$currNorm = ($this->file_date !== null && $tmpDt = new DateTime($this->file_date)) ? $tmpDt->format('Y-m-d H:i:s') : null;
+			$newNorm = ($dt !== null) ? $dt->format('Y-m-d H:i:s') : null;
+
+			if ( ($currNorm !== $newNorm) 					)
+			{
+				$this->file_date = ($dt ? $dt->format('Y-m-d H:i:s') : null);
+				$this->modifiedColumns[] = TblspacefilePeer::FILE_DATE;
+			}
+		} 
+		return $this;
+	} 
+	
+	public function hasOnlyDefaultValues()
+	{
+						if (array_diff($this->modifiedColumns, array())) {
+				return false;
+			}
+
+				return true;
+	} 
+	
+	public function hydrate($row, $startcol = 0, $rehydrate = false)
+	{
+		try {
+
+			$this->file_id = ($row[$startcol + 0] !== null) ? (int) $row[$startcol + 0] : null;
+			$this->file_resource = ($row[$startcol + 1] !== null) ? (int) $row[$startcol + 1] : null;
+			$this->file_category = ($row[$startcol + 2] !== null) ? (int) $row[$startcol + 2] : null;
+			$this->file_user = ($row[$startcol + 3] !== null) ? (int) $row[$startcol + 3] : null;
+			$this->file_name = ($row[$startcol + 4] !== null) ? (string) $row[$startcol + 4] : null;
+			$this->file_type = ($row[$startcol + 5] !== null) ? (string) $row[$startcol + 5] : null;
+			$this->file_date = ($row[$startcol + 6] !== null) ? (string) $row[$startcol + 6] : null;
+			$this->resetModified();
+
+			$this->setNew(false);
+
+			if ($rehydrate) {
+				$this->ensureConsistency();
+			}
+
+						return $startcol + 7; 
+		} catch (Exception $e) {
+			throw new PropelException("Error populating Tblspacefile object", $e);
+		}
+	}
+
+	
+	public function ensureConsistency()
+	{
+
+		if ($this->aTblspaceresource !== null && $this->file_resource !== $this->aTblspaceresource->getResId()) {
+			$this->aTblspaceresource = null;
+		}
+	} 
+	
+	public function reload($deep = false, PropelPDO $con = null)
+	{
+		if ($this->isDeleted()) {
+			throw new PropelException("Cannot reload a deleted object.");
+		}
+
+		if ($this->isNew()) {
+			throw new PropelException("Cannot reload an unsaved object.");
+		}
+
+		if ($con === null) {
+			$con = Propel::getConnection(TblspacefilePeer::DATABASE_NAME, Propel::CONNECTION_READ);
+		}
+
+				
+		$stmt = TblspacefilePeer::doSelectStmt($this->buildPkeyCriteria(), $con);
+		$row = $stmt->fetch(PDO::FETCH_NUM);
+		$stmt->closeCursor();
+		if (!$row) {
+			throw new PropelException('Cannot find matching row in the database to reload object values.');
+		}
+		$this->hydrate($row, 0, true); 
+		if ($deep) {  
+			$this->aTblspaceresource = null;
+		} 	}
+
+	
+	public function delete(PropelPDO $con = null)
+	{
+		if ($this->isDeleted()) {
+			throw new PropelException("This object has already been deleted.");
+		}
+
+		if ($con === null) {
+			$con = Propel::getConnection(TblspacefilePeer::DATABASE_NAME, Propel::CONNECTION_WRITE);
+		}
+		
+		$con->beginTransaction();
+		try {
+			TblspacefilePeer::doDelete($this, $con);
+			$this->setDeleted(true);
+			$con->commit();
+		} catch (PropelException $e) {
+			$con->rollBack();
+			throw $e;
+		}
+	}
+
+	
+	public function save(PropelPDO $con = null)
+	{
+		if ($this->isDeleted()) {
+			throw new PropelException("You cannot save an object that has been deleted.");
+		}
+
+		if ($con === null) {
+			$con = Propel::getConnection(TblspacefilePeer::DATABASE_NAME, Propel::CONNECTION_WRITE);
+		}
+		
+		$con->beginTransaction();
+		try {
+			$affectedRows = $this->doSave($con);
+			$con->commit();
+			TblspacefilePeer::addInstanceToPool($this);
+			return $affectedRows;
+		} catch (PropelException $e) {
+			$con->rollBack();
+			throw $e;
+		}
+	}
+
+	
+	protected function doSave(PropelPDO $con)
+	{
+		$affectedRows = 0; 		if (!$this->alreadyInSave) {
+			$this->alreadyInSave = true;
+
+												
+			if ($this->aTblspaceresource !== null) {
+				if ($this->aTblspaceresource->isModified() || $this->aTblspaceresource->isNew()) {
+					$affectedRows += $this->aTblspaceresource->save($con);
+				}
+				$this->setTblspaceresource($this->aTblspaceresource);
+			}
+
+			if ($this->isNew() ) {
+				$this->modifiedColumns[] = TblspacefilePeer::FILE_ID;
+			}
+
+						if ($this->isModified()) {
+				if ($this->isNew()) {
+					$pk = TblspacefilePeer::doInsert($this, $con);
+					$affectedRows += 1; 										 										 
+					$this->setFileId($pk);  
+					$this->setNew(false);
+				} else {
+					$affectedRows += TblspacefilePeer::doUpdate($this, $con);
+				}
+
+				$this->resetModified(); 			}
+
+			$this->alreadyInSave = false;
+
+		}
+		return $affectedRows;
+	} 
+	
+	protected $validationFailures = array();
+
+	
+	public function getValidationFailures()
+	{
+		return $this->validationFailures;
+	}
+
+	
+	public function validate($columns = null)
+	{
+		$res = $this->doValidate($columns);
+		if ($res === true) {
+			$this->validationFailures = array();
+			return true;
+		} else {
+			$this->validationFailures = $res;
+			return false;
+		}
+	}
+
+	
+	protected function doValidate($columns = null)
+	{
+		if (!$this->alreadyInValidation) {
+			$this->alreadyInValidation = true;
+			$retval = null;
+
+			$failureMap = array();
+
+
+												
+			if ($this->aTblspaceresource !== null) {
+				if (!$this->aTblspaceresource->validate($columns)) {
+					$failureMap = array_merge($failureMap, $this->aTblspaceresource->getValidationFailures());
+				}
+			}
+
+
+			if (($retval = TblspacefilePeer::doValidate($this, $columns)) !== true) {
+				$failureMap = array_merge($failureMap, $retval);
+			}
+
+
+
+			$this->alreadyInValidation = false;
+		}
+
+		return (!empty($failureMap) ? $failureMap : true);
+	}
+
+	
+	public function getByName($name, $type = BasePeer::TYPE_PHPNAME)
+	{
+		$pos = TblspacefilePeer::translateFieldName($name, $type, BasePeer::TYPE_NUM);
+		$field = $this->getByPosition($pos);
+		return $field;
+	}
+
+	
+	public function getByPosition($pos)
+	{
+		switch($pos) {
+			case 0:
+				return $this->getFileId();
+				break;
+			case 1:
+				return $this->getFileResource();
+				break;
+			case 2:
+				return $this->getFileCategory();
+				break;
+			case 3:
+				return $this->getFileUser();
+				break;
+			case 4:
+				return $this->getFileName();
+				break;
+			case 5:
+				return $this->getFileType();
+				break;
+			case 6:
+				return $this->getFileDate();
+				break;
+			default:
+				return null;
+				break;
+		} 	}
+
+	
+	public function toArray($keyType = BasePeer::TYPE_PHPNAME, $includeLazyLoadColumns = true)
+	{
+		$keys = TblspacefilePeer::getFieldNames($keyType);
+		$result = array(
+			$keys[0] => $this->getFileId(),
+			$keys[1] => $this->getFileResource(),
+			$keys[2] => $this->getFileCategory(),
+			$keys[3] => $this->getFileUser(),
+			$keys[4] => $this->getFileName(),
+			$keys[5] => $this->getFileType(),
+			$keys[6] => $this->getFileDate(),
+		);
+		return $result;
+	}
+
+	
+	public function setByName($name, $value, $type = BasePeer::TYPE_PHPNAME)
+	{
+		$pos = TblspacefilePeer::translateFieldName($name, $type, BasePeer::TYPE_NUM);
+		return $this->setByPosition($pos, $value);
+	}
+
+	
+	public function setByPosition($pos, $value)
+	{
+		switch($pos) {
+			case 0:
+				$this->setFileId($value);
+				break;
+			case 1:
+				$this->setFileResource($value);
+				break;
+			case 2:
+				$this->setFileCategory($value);
+				break;
+			case 3:
+				$this->setFileUser($value);
+				break;
+			case 4:
+				$this->setFileName($value);
+				break;
+			case 5:
+				$this->setFileType($value);
+				break;
+			case 6:
+				$this->setFileDate($value);
+				break;
+		} 	}
+
+	
+	public function fromArray($arr, $keyType = BasePeer::TYPE_PHPNAME)
+	{
+		$keys = TblspacefilePeer::getFieldNames($keyType);
+
+		if (array_key_exists($keys[0], $arr)) $this->setFileId($arr[$keys[0]]);
+		if (array_key_exists($keys[1], $arr)) $this->setFileResource($arr[$keys[1]]);
+		if (array_key_exists($keys[2], $arr)) $this->setFileCategory($arr[$keys[2]]);
+		if (array_key_exists($keys[3], $arr)) $this->setFileUser($arr[$keys[3]]);
+		if (array_key_exists($keys[4], $arr)) $this->setFileName($arr[$keys[4]]);
+		if (array_key_exists($keys[5], $arr)) $this->setFileType($arr[$keys[5]]);
+		if (array_key_exists($keys[6], $arr)) $this->setFileDate($arr[$keys[6]]);
+	}
+
+	
+	public function buildCriteria()
+	{
+		$criteria = new Criteria(TblspacefilePeer::DATABASE_NAME);
+
+		if ($this->isColumnModified(TblspacefilePeer::FILE_ID)) $criteria->add(TblspacefilePeer::FILE_ID, $this->file_id);
+		if ($this->isColumnModified(TblspacefilePeer::FILE_RESOURCE)) $criteria->add(TblspacefilePeer::FILE_RESOURCE, $this->file_resource);
+		if ($this->isColumnModified(TblspacefilePeer::FILE_CATEGORY)) $criteria->add(TblspacefilePeer::FILE_CATEGORY, $this->file_category);
+		if ($this->isColumnModified(TblspacefilePeer::FILE_USER)) $criteria->add(TblspacefilePeer::FILE_USER, $this->file_user);
+		if ($this->isColumnModified(TblspacefilePeer::FILE_NAME)) $criteria->add(TblspacefilePeer::FILE_NAME, $this->file_name);
+		if ($this->isColumnModified(TblspacefilePeer::FILE_TYPE)) $criteria->add(TblspacefilePeer::FILE_TYPE, $this->file_type);
+		if ($this->isColumnModified(TblspacefilePeer::FILE_DATE)) $criteria->add(TblspacefilePeer::FILE_DATE, $this->file_date);
+
+		return $criteria;
+	}
+
+	
+	public function buildPkeyCriteria()
+	{
+		$criteria = new Criteria(TblspacefilePeer::DATABASE_NAME);
+
+		$criteria->add(TblspacefilePeer::FILE_ID, $this->file_id);
+
+		return $criteria;
+	}
+
+	
+	public function getPrimaryKey()
+	{
+		return $this->getFileId();
+	}
+
+	
+	public function setPrimaryKey($key)
+	{
+		$this->setFileId($key);
+	}
+
+	
+	public function copyInto($copyObj, $deepCopy = false)
+	{
+
+		$copyObj->setFileResource($this->file_resource);
+
+		$copyObj->setFileCategory($this->file_category);
+
+		$copyObj->setFileUser($this->file_user);
+
+		$copyObj->setFileName($this->file_name);
+
+		$copyObj->setFileType($this->file_type);
+
+		$copyObj->setFileDate($this->file_date);
+
+
+		$copyObj->setNew(true);
+
+		$copyObj->setFileId(NULL); 
+	}
+
+	
+	public function copy($deepCopy = false)
+	{
+				$clazz = get_class($this);
+		$copyObj = new $clazz();
+		$this->copyInto($copyObj, $deepCopy);
+		return $copyObj;
+	}
+
+	
+	public function getPeer()
+	{
+		if (self::$peer === null) {
+			self::$peer = new TblspacefilePeer();
+		}
+		return self::$peer;
+	}
+
+	
+	public function setTblspaceresource(Tblspaceresource $v = null)
+	{
+		if ($v === null) {
+			$this->setFileResource(NULL);
+		} else {
+			$this->setFileResource($v->getResId());
+		}
+
+		$this->aTblspaceresource = $v;
+
+						if ($v !== null) {
+			$v->addTblspacefile($this);
+		}
+
+		return $this;
+	}
+
+
+	
+	public function getTblspaceresource(PropelPDO $con = null)
+	{
+		if ($this->aTblspaceresource === null && ($this->file_resource !== null)) {
+			$this->aTblspaceresource = TblspaceresourcePeer::retrieveByPK($this->file_resource, $con);
+			
+		}
+		return $this->aTblspaceresource;
+	}
+
+	
+	public function clearAllReferences($deep = false)
+	{
+		if ($deep) {
+		} 
+			$this->aTblspaceresource = null;
+	}
+
+} 
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/lib/model/om/BaseTblspacefilePeer.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/lib/model/om/BaseTblspacefilePeer.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/lib/model/om/BaseTblspacefilePeer.php	(revision 19)
@@ -0,0 +1,622 @@
+<?php
+
+
+abstract class BaseTblspacefilePeer {
+
+	
+	const DATABASE_NAME = 'propel';
+
+	
+	const TABLE_NAME = 'tblspacefile';
+
+	
+	const CLASS_DEFAULT = 'lib.model.Tblspacefile';
+
+	
+	const NUM_COLUMNS = 7;
+
+	
+	const NUM_LAZY_LOAD_COLUMNS = 0;
+
+	
+	const FILE_ID = 'tblspacefile.FILE_ID';
+
+	
+	const FILE_RESOURCE = 'tblspacefile.FILE_RESOURCE';
+
+	
+	const FILE_CATEGORY = 'tblspacefile.FILE_CATEGORY';
+
+	
+	const FILE_USER = 'tblspacefile.FILE_USER';
+
+	
+	const FILE_NAME = 'tblspacefile.FILE_NAME';
+
+	
+	const FILE_TYPE = 'tblspacefile.FILE_TYPE';
+
+	
+	const FILE_DATE = 'tblspacefile.FILE_DATE';
+
+	
+	public static $instances = array();
+
+	
+	private static $mapBuilder = null;
+
+	
+	private static $fieldNames = array (
+		BasePeer::TYPE_PHPNAME => array ('FileId', 'FileResource', 'FileCategory', 'FileUser', 'FileName', 'FileType', 'FileDate', ),
+		BasePeer::TYPE_STUDLYPHPNAME => array ('fileId', 'fileResource', 'fileCategory', 'fileUser', 'fileName', 'fileType', 'fileDate', ),
+		BasePeer::TYPE_COLNAME => array (self::FILE_ID, self::FILE_RESOURCE, self::FILE_CATEGORY, self::FILE_USER, self::FILE_NAME, self::FILE_TYPE, self::FILE_DATE, ),
+		BasePeer::TYPE_FIELDNAME => array ('file_id', 'file_resource', 'file_category', 'file_user', 'file_name', 'file_type', 'file_date', ),
+		BasePeer::TYPE_NUM => array (0, 1, 2, 3, 4, 5, 6, )
+	);
+
+	
+	private static $fieldKeys = array (
+		BasePeer::TYPE_PHPNAME => array ('FileId' => 0, 'FileResource' => 1, 'FileCategory' => 2, 'FileUser' => 3, 'FileName' => 4, 'FileType' => 5, 'FileDate' => 6, ),
+		BasePeer::TYPE_STUDLYPHPNAME => array ('fileId' => 0, 'fileResource' => 1, 'fileCategory' => 2, 'fileUser' => 3, 'fileName' => 4, 'fileType' => 5, 'fileDate' => 6, ),
+		BasePeer::TYPE_COLNAME => array (self::FILE_ID => 0, self::FILE_RESOURCE => 1, self::FILE_CATEGORY => 2, self::FILE_USER => 3, self::FILE_NAME => 4, self::FILE_TYPE => 5, self::FILE_DATE => 6, ),
+		BasePeer::TYPE_FIELDNAME => array ('file_id' => 0, 'file_resource' => 1, 'file_category' => 2, 'file_user' => 3, 'file_name' => 4, 'file_type' => 5, 'file_date' => 6, ),
+		BasePeer::TYPE_NUM => array (0, 1, 2, 3, 4, 5, 6, )
+	);
+
+	
+	public static function getMapBuilder()
+	{
+		if (self::$mapBuilder === null) {
+			self::$mapBuilder = new TblspacefileMapBuilder();
+		}
+		return self::$mapBuilder;
+	}
+	
+	static public function translateFieldName($name, $fromType, $toType)
+	{
+		$toNames = self::getFieldNames($toType);
+		$key = isset(self::$fieldKeys[$fromType][$name]) ? self::$fieldKeys[$fromType][$name] : null;
+		if ($key === null) {
+			throw new PropelException("'$name' could not be found in the field names of type '$fromType'. These are: " . print_r(self::$fieldKeys[$fromType], true));
+		}
+		return $toNames[$key];
+	}
+
+	
+
+	static public function getFieldNames($type = BasePeer::TYPE_PHPNAME)
+	{
+		if (!array_key_exists($type, self::$fieldNames)) {
+			throw new PropelException('Method getFieldNames() expects the parameter $type to be one of the class constants BasePeer::TYPE_PHPNAME, BasePeer::TYPE_STUDLYPHPNAME, BasePeer::TYPE_COLNAME, BasePeer::TYPE_FIELDNAME, BasePeer::TYPE_NUM. ' . $type . ' was given.');
+		}
+		return self::$fieldNames[$type];
+	}
+
+	
+	public static function alias($alias, $column)
+	{
+		return str_replace(TblspacefilePeer::TABLE_NAME.'.', $alias.'.', $column);
+	}
+
+	
+	public static function addSelectColumns(Criteria $criteria)
+	{
+
+		$criteria->addSelectColumn(TblspacefilePeer::FILE_ID);
+
+		$criteria->addSelectColumn(TblspacefilePeer::FILE_RESOURCE);
+
+		$criteria->addSelectColumn(TblspacefilePeer::FILE_CATEGORY);
+
+		$criteria->addSelectColumn(TblspacefilePeer::FILE_USER);
+
+		$criteria->addSelectColumn(TblspacefilePeer::FILE_NAME);
+
+		$criteria->addSelectColumn(TblspacefilePeer::FILE_TYPE);
+
+		$criteria->addSelectColumn(TblspacefilePeer::FILE_DATE);
+
+	}
+
+	
+	public static function doCount(Criteria $criteria, $distinct = false, PropelPDO $con = null)
+	{
+				$criteria = clone $criteria;
+
+								$criteria->setPrimaryTableName(TblspacefilePeer::TABLE_NAME);
+
+		if ($distinct && !in_array(Criteria::DISTINCT, $criteria->getSelectModifiers())) {
+			$criteria->setDistinct();
+		}
+
+		if (!$criteria->hasSelectClause()) {
+			TblspacefilePeer::addSelectColumns($criteria);
+		}
+
+		$criteria->clearOrderByColumns(); 		$criteria->setDbName(self::DATABASE_NAME); 
+		if ($con === null) {
+			$con = Propel::getConnection(TblspacefilePeer::DATABASE_NAME, Propel::CONNECTION_READ);
+		}
+				$stmt = BasePeer::doCount($criteria, $con);
+
+		if ($row = $stmt->fetch(PDO::FETCH_NUM)) {
+			$count = (int) $row[0];
+		} else {
+			$count = 0; 		}
+		$stmt->closeCursor();
+		return $count;
+	}
+	
+	public static function doSelectOne(Criteria $criteria, PropelPDO $con = null)
+	{
+		$critcopy = clone $criteria;
+		$critcopy->setLimit(1);
+		$objects = TblspacefilePeer::doSelect($critcopy, $con);
+		if ($objects) {
+			return $objects[0];
+		}
+		return null;
+	}
+	
+	public static function doSelect(Criteria $criteria, PropelPDO $con = null)
+	{
+		return TblspacefilePeer::populateObjects(TblspacefilePeer::doSelectStmt($criteria, $con));
+	}
+	
+	public static function doSelectStmt(Criteria $criteria, PropelPDO $con = null)
+	{
+		if ($con === null) {
+			$con = Propel::getConnection(TblspacefilePeer::DATABASE_NAME, Propel::CONNECTION_READ);
+		}
+
+		if (!$criteria->hasSelectClause()) {
+			$criteria = clone $criteria;
+			TblspacefilePeer::addSelectColumns($criteria);
+		}
+
+				$criteria->setDbName(self::DATABASE_NAME);
+
+				return BasePeer::doSelect($criteria, $con);
+	}
+	
+	public static function addInstanceToPool(Tblspacefile $obj, $key = null)
+	{
+		if (Propel::isInstancePoolingEnabled()) {
+			if ($key === null) {
+				$key = (string) $obj->getFileId();
+			} 			self::$instances[$key] = $obj;
+		}
+	}
+
+	
+	public static function removeInstanceFromPool($value)
+	{
+		if (Propel::isInstancePoolingEnabled() && $value !== null) {
+			if (is_object($value) && $value instanceof Tblspacefile) {
+				$key = (string) $value->getFileId();
+			} elseif (is_scalar($value)) {
+								$key = (string) $value;
+			} else {
+				$e = new PropelException("Invalid value passed to removeInstanceFromPool().  Expected primary key or Tblspacefile object; got " . (is_object($value) ? get_class($value) . ' object.' : var_export($value,true)));
+				throw $e;
+			}
+
+			unset(self::$instances[$key]);
+		}
+	} 
+	
+	public static function getInstanceFromPool($key)
+	{
+		if (Propel::isInstancePoolingEnabled()) {
+			if (isset(self::$instances[$key])) {
+				return self::$instances[$key];
+			}
+		}
+		return null; 	}
+	
+	
+	public static function clearInstancePool()
+	{
+		self::$instances = array();
+	}
+	
+	
+	public static function getPrimaryKeyHashFromRow($row, $startcol = 0)
+	{
+				if ($row[$startcol + 0] === null) {
+			return null;
+		}
+		return (string) $row[$startcol + 0];
+	}
+
+	
+	public static function populateObjects(PDOStatement $stmt)
+	{
+		$results = array();
+	
+				$cls = TblspacefilePeer::getOMClass();
+		$cls = substr('.'.$cls, strrpos('.'.$cls, '.') + 1);
+				while ($row = $stmt->fetch(PDO::FETCH_NUM)) {
+			$key = TblspacefilePeer::getPrimaryKeyHashFromRow($row, 0);
+			if (null !== ($obj = TblspacefilePeer::getInstanceFromPool($key))) {
+																$results[] = $obj;
+			} else {
+		
+				$obj = new $cls();
+				$obj->hydrate($row);
+				$results[] = $obj;
+				TblspacefilePeer::addInstanceToPool($obj, $key);
+			} 		}
+		$stmt->closeCursor();
+		return $results;
+	}
+
+	
+	public static function doCountJoinTblspaceresource(Criteria $criteria, $distinct = false, PropelPDO $con = null, $join_behavior = Criteria::LEFT_JOIN)
+	{
+				$criteria = clone $criteria;
+
+								$criteria->setPrimaryTableName(TblspacefilePeer::TABLE_NAME);
+
+		if ($distinct && !in_array(Criteria::DISTINCT, $criteria->getSelectModifiers())) {
+			$criteria->setDistinct();
+		}
+
+		if (!$criteria->hasSelectClause()) {
+			TblspacefilePeer::addSelectColumns($criteria);
+		}
+		
+		$criteria->clearOrderByColumns(); 		
+				$criteria->setDbName(self::DATABASE_NAME);
+
+		if ($con === null) {
+			$con = Propel::getConnection(TblspacefilePeer::DATABASE_NAME, Propel::CONNECTION_READ);
+		}
+
+		$criteria->addJoin(array(TblspacefilePeer::FILE_RESOURCE,), array(TblspaceresourcePeer::RES_ID,), $join_behavior);
+		$stmt = BasePeer::doCount($criteria, $con);
+
+		if ($row = $stmt->fetch(PDO::FETCH_NUM)) {
+			$count = (int) $row[0];
+		} else {
+			$count = 0; 		}
+		$stmt->closeCursor();
+		return $count;
+	}
+
+
+	
+	public static function doSelectJoinTblspaceresource(Criteria $c, $con = null, $join_behavior = Criteria::LEFT_JOIN)
+	{
+		$c = clone $c;
+
+				if ($c->getDbName() == Propel::getDefaultDB()) {
+			$c->setDbName(self::DATABASE_NAME);
+		}
+
+		TblspacefilePeer::addSelectColumns($c);
+		$startcol = (TblspacefilePeer::NUM_COLUMNS - TblspacefilePeer::NUM_LAZY_LOAD_COLUMNS);
+		TblspaceresourcePeer::addSelectColumns($c);
+
+		$c->addJoin(array(TblspacefilePeer::FILE_RESOURCE,), array(TblspaceresourcePeer::RES_ID,), $join_behavior);
+		$stmt = BasePeer::doSelect($c, $con);
+		$results = array();
+
+		while ($row = $stmt->fetch(PDO::FETCH_NUM)) {
+			$key1 = TblspacefilePeer::getPrimaryKeyHashFromRow($row, 0);
+			if (null !== ($obj1 = TblspacefilePeer::getInstanceFromPool($key1))) {
+															} else {
+
+				$omClass = TblspacefilePeer::getOMClass();
+
+				$cls = substr('.'.$omClass, strrpos('.'.$omClass, '.') + 1);
+				$obj1 = new $cls();
+				$obj1->hydrate($row);
+				TblspacefilePeer::addInstanceToPool($obj1, $key1);
+			} 
+			$key2 = TblspaceresourcePeer::getPrimaryKeyHashFromRow($row, $startcol);
+			if ($key2 !== null) {
+				$obj2 = TblspaceresourcePeer::getInstanceFromPool($key2);
+				if (!$obj2) {
+
+					$omClass = TblspaceresourcePeer::getOMClass();
+
+					$cls = substr('.'.$omClass, strrpos('.'.$omClass, '.') + 1);
+					$obj2 = new $cls();
+					$obj2->hydrate($row, $startcol);
+					TblspaceresourcePeer::addInstanceToPool($obj2, $key2);
+				} 
+								$obj2->addTblspacefile($obj1);
+
+			} 
+			$results[] = $obj1;
+		}
+		$stmt->closeCursor();
+		return $results;
+	}
+
+
+	
+	public static function doCountJoinAll(Criteria $criteria, $distinct = false, PropelPDO $con = null, $join_behavior = Criteria::LEFT_JOIN)
+	{
+				$criteria = clone $criteria;
+
+								$criteria->setPrimaryTableName(TblspacefilePeer::TABLE_NAME);
+
+		if ($distinct && !in_array(Criteria::DISTINCT, $criteria->getSelectModifiers())) {
+			$criteria->setDistinct();
+		}
+
+		if (!$criteria->hasSelectClause()) {
+			TblspacefilePeer::addSelectColumns($criteria);
+		}
+		
+		$criteria->clearOrderByColumns(); 		
+				$criteria->setDbName(self::DATABASE_NAME);
+
+		if ($con === null) {
+			$con = Propel::getConnection(TblspacefilePeer::DATABASE_NAME, Propel::CONNECTION_READ);
+		}
+
+		$criteria->addJoin(array(TblspacefilePeer::FILE_RESOURCE,), array(TblspaceresourcePeer::RES_ID,), $join_behavior);
+		$stmt = BasePeer::doCount($criteria, $con);
+
+		if ($row = $stmt->fetch(PDO::FETCH_NUM)) {
+			$count = (int) $row[0];
+		} else {
+			$count = 0; 		}
+		$stmt->closeCursor();
+		return $count;
+	}
+
+	
+	public static function doSelectJoinAll(Criteria $c, $con = null, $join_behavior = Criteria::LEFT_JOIN)
+	{
+		$c = clone $c;
+
+				if ($c->getDbName() == Propel::getDefaultDB()) {
+			$c->setDbName(self::DATABASE_NAME);
+		}
+
+		TblspacefilePeer::addSelectColumns($c);
+		$startcol2 = (TblspacefilePeer::NUM_COLUMNS - TblspacefilePeer::NUM_LAZY_LOAD_COLUMNS);
+
+		TblspaceresourcePeer::addSelectColumns($c);
+		$startcol3 = $startcol2 + (TblspaceresourcePeer::NUM_COLUMNS - TblspaceresourcePeer::NUM_LAZY_LOAD_COLUMNS);
+
+		$c->addJoin(array(TblspacefilePeer::FILE_RESOURCE,), array(TblspaceresourcePeer::RES_ID,), $join_behavior);
+		$stmt = BasePeer::doSelect($c, $con);
+		$results = array();
+
+		while ($row = $stmt->fetch(PDO::FETCH_NUM)) {
+			$key1 = TblspacefilePeer::getPrimaryKeyHashFromRow($row, 0);
+			if (null !== ($obj1 = TblspacefilePeer::getInstanceFromPool($key1))) {
+															} else {
+				$omClass = TblspacefilePeer::getOMClass();
+
+				$cls = substr('.'.$omClass, strrpos('.'.$omClass, '.') + 1);
+				$obj1 = new $cls();
+				$obj1->hydrate($row);
+				TblspacefilePeer::addInstanceToPool($obj1, $key1);
+			} 
+			
+			$key2 = TblspaceresourcePeer::getPrimaryKeyHashFromRow($row, $startcol2);
+			if ($key2 !== null) {
+				$obj2 = TblspaceresourcePeer::getInstanceFromPool($key2);
+				if (!$obj2) {
+
+					$omClass = TblspaceresourcePeer::getOMClass();
+
+
+					$cls = substr('.'.$omClass, strrpos('.'.$omClass, '.') + 1);
+					$obj2 = new $cls();
+					$obj2->hydrate($row, $startcol2);
+					TblspaceresourcePeer::addInstanceToPool($obj2, $key2);
+				} 
+								$obj2->addTblspacefile($obj1);
+			} 
+			$results[] = $obj1;
+		}
+		$stmt->closeCursor();
+		return $results;
+	}
+
+	
+	public static function getTableMap()
+	{
+		return Propel::getDatabaseMap(self::DATABASE_NAME)->getTable(self::TABLE_NAME);
+	}
+
+	
+	public static function getOMClass()
+	{
+		return TblspacefilePeer::CLASS_DEFAULT;
+	}
+
+	
+	public static function doInsert($values, PropelPDO $con = null)
+	{
+		if ($con === null) {
+			$con = Propel::getConnection(TblspacefilePeer::DATABASE_NAME, Propel::CONNECTION_WRITE);
+		}
+
+		if ($values instanceof Criteria) {
+			$criteria = clone $values; 		} else {
+			$criteria = $values->buildCriteria(); 		}
+
+		if ($criteria->containsKey(TblspacefilePeer::FILE_ID) && $criteria->keyContainsValue(TblspacefilePeer::FILE_ID) ) {
+			throw new PropelException('Cannot insert a value for auto-increment primary key ('.TblspacefilePeer::FILE_ID.')');
+		}
+
+
+				$criteria->setDbName(self::DATABASE_NAME);
+
+		try {
+									$con->beginTransaction();
+			$pk = BasePeer::doInsert($criteria, $con);
+			$con->commit();
+		} catch(PropelException $e) {
+			$con->rollBack();
+			throw $e;
+		}
+
+		return $pk;
+	}
+
+	
+	public static function doUpdate($values, PropelPDO $con = null)
+	{
+		if ($con === null) {
+			$con = Propel::getConnection(TblspacefilePeer::DATABASE_NAME, Propel::CONNECTION_WRITE);
+		}
+
+		$selectCriteria = new Criteria(self::DATABASE_NAME);
+
+		if ($values instanceof Criteria) {
+			$criteria = clone $values; 
+			$comparison = $criteria->getComparison(TblspacefilePeer::FILE_ID);
+			$selectCriteria->add(TblspacefilePeer::FILE_ID, $criteria->remove(TblspacefilePeer::FILE_ID), $comparison);
+
+		} else { 			$criteria = $values->buildCriteria(); 			$selectCriteria = $values->buildPkeyCriteria(); 		}
+
+				$criteria->setDbName(self::DATABASE_NAME);
+
+		return BasePeer::doUpdate($selectCriteria, $criteria, $con);
+	}
+
+	
+	public static function doDeleteAll($con = null)
+	{
+		if ($con === null) {
+			$con = Propel::getConnection(TblspacefilePeer::DATABASE_NAME, Propel::CONNECTION_WRITE);
+		}
+		$affectedRows = 0; 		try {
+									$con->beginTransaction();
+			$affectedRows += BasePeer::doDeleteAll(TblspacefilePeer::TABLE_NAME, $con);
+			$con->commit();
+			return $affectedRows;
+		} catch (PropelException $e) {
+			$con->rollBack();
+			throw $e;
+		}
+	}
+
+	
+	 public static function doDelete($values, PropelPDO $con = null)
+	 {
+		if ($con === null) {
+			$con = Propel::getConnection(TblspacefilePeer::DATABASE_NAME, Propel::CONNECTION_WRITE);
+		}
+
+		if ($values instanceof Criteria) {
+												TblspacefilePeer::clearInstancePool();
+
+						$criteria = clone $values;
+		} elseif ($values instanceof Tblspacefile) {
+						TblspacefilePeer::removeInstanceFromPool($values);
+						$criteria = $values->buildPkeyCriteria();
+		} else {
+			
+
+
+			$criteria = new Criteria(self::DATABASE_NAME);
+			$criteria->add(TblspacefilePeer::FILE_ID, (array) $values, Criteria::IN);
+
+			foreach ((array) $values as $singleval) {
+								TblspacefilePeer::removeInstanceFromPool($singleval);
+			}
+		}
+
+				$criteria->setDbName(self::DATABASE_NAME);
+
+		$affectedRows = 0; 
+		try {
+									$con->beginTransaction();
+			
+			$affectedRows += BasePeer::doDelete($criteria, $con);
+
+			$con->commit();
+			return $affectedRows;
+		} catch (PropelException $e) {
+			$con->rollBack();
+			throw $e;
+		}
+	}
+
+	
+	public static function doValidate(Tblspacefile $obj, $cols = null)
+	{
+		$columns = array();
+
+		if ($cols) {
+			$dbMap = Propel::getDatabaseMap(TblspacefilePeer::DATABASE_NAME);
+			$tableMap = $dbMap->getTable(TblspacefilePeer::TABLE_NAME);
+
+			if (! is_array($cols)) {
+				$cols = array($cols);
+			}
+
+			foreach ($cols as $colName) {
+				if ($tableMap->containsColumn($colName)) {
+					$get = 'get' . $tableMap->getColumn($colName)->getPhpName();
+					$columns[$colName] = $obj->$get();
+				}
+			}
+		} else {
+
+		}
+
+		$res =  BasePeer::doValidate(TblspacefilePeer::DATABASE_NAME, TblspacefilePeer::TABLE_NAME, $columns);
+    if ($res !== true) {
+        $request = sfContext::getInstance()->getRequest();
+        foreach ($res as $failed) {
+            $col = TblspacefilePeer::translateFieldname($failed->getColumn(), BasePeer::TYPE_COLNAME, BasePeer::TYPE_PHPNAME);
+            $request->setError($col, $failed->getMessage());
+        }
+    }
+
+    return $res;
+	}
+
+	
+	public static function retrieveByPK($pk, PropelPDO $con = null)
+	{
+
+		if (null !== ($obj = TblspacefilePeer::getInstanceFromPool((string) $pk))) {
+			return $obj;
+		}
+
+		if ($con === null) {
+			$con = Propel::getConnection(TblspacefilePeer::DATABASE_NAME, Propel::CONNECTION_READ);
+		}
+
+		$criteria = new Criteria(TblspacefilePeer::DATABASE_NAME);
+		$criteria->add(TblspacefilePeer::FILE_ID, $pk);
+
+		$v = TblspacefilePeer::doSelect($criteria, $con);
+
+		return !empty($v) > 0 ? $v[0] : null;
+	}
+
+	
+	public static function retrieveByPKs($pks, PropelPDO $con = null)
+	{
+		if ($con === null) {
+			$con = Propel::getConnection(TblspacefilePeer::DATABASE_NAME, Propel::CONNECTION_READ);
+		}
+
+		$objs = null;
+		if (empty($pks)) {
+			$objs = array();
+		} else {
+			$criteria = new Criteria(TblspacefilePeer::DATABASE_NAME);
+			$criteria->add(TblspacefilePeer::FILE_ID, $pks, Criteria::IN);
+			$objs = TblspacefilePeer::doSelect($criteria, $con);
+		}
+		return $objs;
+	}
+
+} 
+
+Propel::getDatabaseMap(BaseTblspacefilePeer::DATABASE_NAME)->addTableBuilder(BaseTblspacefilePeer::TABLE_NAME, BaseTblspacefilePeer::getMapBuilder());
+
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/lib/model/om/BaseTblspaceresource.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/lib/model/om/BaseTblspaceresource.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/lib/model/om/BaseTblspaceresource.php	(revision 19)
@@ -0,0 +1,596 @@
+<?php
+
+
+abstract class BaseTblspaceresource extends BaseObject  implements Persistent {
+
+
+	
+	protected static $peer;
+
+	
+	protected $res_id;
+
+	
+	protected $res_filename;
+
+	
+	protected $res_filesize;
+
+	
+	protected $res_filecrc;
+
+	
+	protected $collTblspacefiles;
+
+	
+	private $lastTblspacefileCriteria = null;
+
+	
+	protected $alreadyInSave = false;
+
+	
+	protected $alreadyInValidation = false;
+
+	
+	public function __construct()
+	{
+		parent::__construct();
+		$this->applyDefaultValues();
+	}
+
+	
+	public function applyDefaultValues()
+	{
+	}
+
+	
+	public function getResId()
+	{
+		return $this->res_id;
+	}
+
+	
+	public function getResFilename()
+	{
+		return $this->res_filename;
+	}
+
+	
+	public function getResFilesize()
+	{
+		return $this->res_filesize;
+	}
+
+	
+	public function getResFilecrc()
+	{
+		return $this->res_filecrc;
+	}
+
+	
+	public function setResId($v)
+	{
+		if ($v !== null) {
+			$v = (int) $v;
+		}
+
+		if ($this->res_id !== $v) {
+			$this->res_id = $v;
+			$this->modifiedColumns[] = TblspaceresourcePeer::RES_ID;
+		}
+
+		return $this;
+	} 
+	
+	public function setResFilename($v)
+	{
+		if ($v !== null) {
+			$v = (string) $v;
+		}
+
+		if ($this->res_filename !== $v) {
+			$this->res_filename = $v;
+			$this->modifiedColumns[] = TblspaceresourcePeer::RES_FILENAME;
+		}
+
+		return $this;
+	} 
+	
+	public function setResFilesize($v)
+	{
+		if ($v !== null) {
+			$v = (int) $v;
+		}
+
+		if ($this->res_filesize !== $v) {
+			$this->res_filesize = $v;
+			$this->modifiedColumns[] = TblspaceresourcePeer::RES_FILESIZE;
+		}
+
+		return $this;
+	} 
+	
+	public function setResFilecrc($v)
+	{
+		if ($v !== null) {
+			$v = (int) $v;
+		}
+
+		if ($this->res_filecrc !== $v) {
+			$this->res_filecrc = $v;
+			$this->modifiedColumns[] = TblspaceresourcePeer::RES_FILECRC;
+		}
+
+		return $this;
+	} 
+	
+	public function hasOnlyDefaultValues()
+	{
+						if (array_diff($this->modifiedColumns, array())) {
+				return false;
+			}
+
+				return true;
+	} 
+	
+	public function hydrate($row, $startcol = 0, $rehydrate = false)
+	{
+		try {
+
+			$this->res_id = ($row[$startcol + 0] !== null) ? (int) $row[$startcol + 0] : null;
+			$this->res_filename = ($row[$startcol + 1] !== null) ? (string) $row[$startcol + 1] : null;
+			$this->res_filesize = ($row[$startcol + 2] !== null) ? (int) $row[$startcol + 2] : null;
+			$this->res_filecrc = ($row[$startcol + 3] !== null) ? (int) $row[$startcol + 3] : null;
+			$this->resetModified();
+
+			$this->setNew(false);
+
+			if ($rehydrate) {
+				$this->ensureConsistency();
+			}
+
+						return $startcol + 4; 
+		} catch (Exception $e) {
+			throw new PropelException("Error populating Tblspaceresource object", $e);
+		}
+	}
+
+	
+	public function ensureConsistency()
+	{
+
+	} 
+	
+	public function reload($deep = false, PropelPDO $con = null)
+	{
+		if ($this->isDeleted()) {
+			throw new PropelException("Cannot reload a deleted object.");
+		}
+
+		if ($this->isNew()) {
+			throw new PropelException("Cannot reload an unsaved object.");
+		}
+
+		if ($con === null) {
+			$con = Propel::getConnection(TblspaceresourcePeer::DATABASE_NAME, Propel::CONNECTION_READ);
+		}
+
+				
+		$stmt = TblspaceresourcePeer::doSelectStmt($this->buildPkeyCriteria(), $con);
+		$row = $stmt->fetch(PDO::FETCH_NUM);
+		$stmt->closeCursor();
+		if (!$row) {
+			throw new PropelException('Cannot find matching row in the database to reload object values.');
+		}
+		$this->hydrate($row, 0, true); 
+		if ($deep) {  
+			$this->collTblspacefiles = null;
+			$this->lastTblspacefileCriteria = null;
+
+		} 	}
+
+	
+	public function delete(PropelPDO $con = null)
+	{
+		if ($this->isDeleted()) {
+			throw new PropelException("This object has already been deleted.");
+		}
+
+		if ($con === null) {
+			$con = Propel::getConnection(TblspaceresourcePeer::DATABASE_NAME, Propel::CONNECTION_WRITE);
+		}
+		
+		$con->beginTransaction();
+		try {
+			TblspaceresourcePeer::doDelete($this, $con);
+			$this->setDeleted(true);
+			$con->commit();
+		} catch (PropelException $e) {
+			$con->rollBack();
+			throw $e;
+		}
+	}
+
+	
+	public function save(PropelPDO $con = null)
+	{
+		if ($this->isDeleted()) {
+			throw new PropelException("You cannot save an object that has been deleted.");
+		}
+
+		if ($con === null) {
+			$con = Propel::getConnection(TblspaceresourcePeer::DATABASE_NAME, Propel::CONNECTION_WRITE);
+		}
+		
+		$con->beginTransaction();
+		try {
+			$affectedRows = $this->doSave($con);
+			$con->commit();
+			TblspaceresourcePeer::addInstanceToPool($this);
+			return $affectedRows;
+		} catch (PropelException $e) {
+			$con->rollBack();
+			throw $e;
+		}
+	}
+
+	
+	protected function doSave(PropelPDO $con)
+	{
+		$affectedRows = 0; 		if (!$this->alreadyInSave) {
+			$this->alreadyInSave = true;
+
+			if ($this->isNew() ) {
+				$this->modifiedColumns[] = TblspaceresourcePeer::RES_ID;
+			}
+
+						if ($this->isModified()) {
+				if ($this->isNew()) {
+					$pk = TblspaceresourcePeer::doInsert($this, $con);
+					$affectedRows += 1; 										 										 
+					$this->setResId($pk);  
+					$this->setNew(false);
+				} else {
+					$affectedRows += TblspaceresourcePeer::doUpdate($this, $con);
+				}
+
+				$this->resetModified(); 			}
+
+			if ($this->collTblspacefiles !== null) {
+				foreach ($this->collTblspacefiles as $referrerFK) {
+					if (!$referrerFK->isDeleted()) {
+						$affectedRows += $referrerFK->save($con);
+					}
+				}
+			}
+
+			$this->alreadyInSave = false;
+
+		}
+		return $affectedRows;
+	} 
+	
+	protected $validationFailures = array();
+
+	
+	public function getValidationFailures()
+	{
+		return $this->validationFailures;
+	}
+
+	
+	public function validate($columns = null)
+	{
+		$res = $this->doValidate($columns);
+		if ($res === true) {
+			$this->validationFailures = array();
+			return true;
+		} else {
+			$this->validationFailures = $res;
+			return false;
+		}
+	}
+
+	
+	protected function doValidate($columns = null)
+	{
+		if (!$this->alreadyInValidation) {
+			$this->alreadyInValidation = true;
+			$retval = null;
+
+			$failureMap = array();
+
+
+			if (($retval = TblspaceresourcePeer::doValidate($this, $columns)) !== true) {
+				$failureMap = array_merge($failureMap, $retval);
+			}
+
+
+				if ($this->collTblspacefiles !== null) {
+					foreach ($this->collTblspacefiles as $referrerFK) {
+						if (!$referrerFK->validate($columns)) {
+							$failureMap = array_merge($failureMap, $referrerFK->getValidationFailures());
+						}
+					}
+				}
+
+
+			$this->alreadyInValidation = false;
+		}
+
+		return (!empty($failureMap) ? $failureMap : true);
+	}
+
+	
+	public function getByName($name, $type = BasePeer::TYPE_PHPNAME)
+	{
+		$pos = TblspaceresourcePeer::translateFieldName($name, $type, BasePeer::TYPE_NUM);
+		$field = $this->getByPosition($pos);
+		return $field;
+	}
+
+	
+	public function getByPosition($pos)
+	{
+		switch($pos) {
+			case 0:
+				return $this->getResId();
+				break;
+			case 1:
+				return $this->getResFilename();
+				break;
+			case 2:
+				return $this->getResFilesize();
+				break;
+			case 3:
+				return $this->getResFilecrc();
+				break;
+			default:
+				return null;
+				break;
+		} 	}
+
+	
+	public function toArray($keyType = BasePeer::TYPE_PHPNAME, $includeLazyLoadColumns = true)
+	{
+		$keys = TblspaceresourcePeer::getFieldNames($keyType);
+		$result = array(
+			$keys[0] => $this->getResId(),
+			$keys[1] => $this->getResFilename(),
+			$keys[2] => $this->getResFilesize(),
+			$keys[3] => $this->getResFilecrc(),
+		);
+		return $result;
+	}
+
+	
+	public function setByName($name, $value, $type = BasePeer::TYPE_PHPNAME)
+	{
+		$pos = TblspaceresourcePeer::translateFieldName($name, $type, BasePeer::TYPE_NUM);
+		return $this->setByPosition($pos, $value);
+	}
+
+	
+	public function setByPosition($pos, $value)
+	{
+		switch($pos) {
+			case 0:
+				$this->setResId($value);
+				break;
+			case 1:
+				$this->setResFilename($value);
+				break;
+			case 2:
+				$this->setResFilesize($value);
+				break;
+			case 3:
+				$this->setResFilecrc($value);
+				break;
+		} 	}
+
+	
+	public function fromArray($arr, $keyType = BasePeer::TYPE_PHPNAME)
+	{
+		$keys = TblspaceresourcePeer::getFieldNames($keyType);
+
+		if (array_key_exists($keys[0], $arr)) $this->setResId($arr[$keys[0]]);
+		if (array_key_exists($keys[1], $arr)) $this->setResFilename($arr[$keys[1]]);
+		if (array_key_exists($keys[2], $arr)) $this->setResFilesize($arr[$keys[2]]);
+		if (array_key_exists($keys[3], $arr)) $this->setResFilecrc($arr[$keys[3]]);
+	}
+
+	
+	public function buildCriteria()
+	{
+		$criteria = new Criteria(TblspaceresourcePeer::DATABASE_NAME);
+
+		if ($this->isColumnModified(TblspaceresourcePeer::RES_ID)) $criteria->add(TblspaceresourcePeer::RES_ID, $this->res_id);
+		if ($this->isColumnModified(TblspaceresourcePeer::RES_FILENAME)) $criteria->add(TblspaceresourcePeer::RES_FILENAME, $this->res_filename);
+		if ($this->isColumnModified(TblspaceresourcePeer::RES_FILESIZE)) $criteria->add(TblspaceresourcePeer::RES_FILESIZE, $this->res_filesize);
+		if ($this->isColumnModified(TblspaceresourcePeer::RES_FILECRC)) $criteria->add(TblspaceresourcePeer::RES_FILECRC, $this->res_filecrc);
+
+		return $criteria;
+	}
+
+	
+	public function buildPkeyCriteria()
+	{
+		$criteria = new Criteria(TblspaceresourcePeer::DATABASE_NAME);
+
+		$criteria->add(TblspaceresourcePeer::RES_ID, $this->res_id);
+
+		return $criteria;
+	}
+
+	
+	public function getPrimaryKey()
+	{
+		return $this->getResId();
+	}
+
+	
+	public function setPrimaryKey($key)
+	{
+		$this->setResId($key);
+	}
+
+	
+	public function copyInto($copyObj, $deepCopy = false)
+	{
+
+		$copyObj->setResFilename($this->res_filename);
+
+		$copyObj->setResFilesize($this->res_filesize);
+
+		$copyObj->setResFilecrc($this->res_filecrc);
+
+
+		if ($deepCopy) {
+									$copyObj->setNew(false);
+
+			foreach ($this->getTblspacefiles() as $relObj) {
+				if ($relObj !== $this) {  					$copyObj->addTblspacefile($relObj->copy($deepCopy));
+				}
+			}
+
+		} 
+
+		$copyObj->setNew(true);
+
+		$copyObj->setResId(NULL); 
+	}
+
+	
+	public function copy($deepCopy = false)
+	{
+				$clazz = get_class($this);
+		$copyObj = new $clazz();
+		$this->copyInto($copyObj, $deepCopy);
+		return $copyObj;
+	}
+
+	
+	public function getPeer()
+	{
+		if (self::$peer === null) {
+			self::$peer = new TblspaceresourcePeer();
+		}
+		return self::$peer;
+	}
+
+	
+	public function clearTblspacefiles()
+	{
+		$this->collTblspacefiles = null; 	}
+
+	
+	public function initTblspacefiles()
+	{
+		$this->collTblspacefiles = array();
+	}
+
+	
+	public function getTblspacefiles($criteria = null, PropelPDO $con = null)
+	{
+		if ($criteria === null) {
+			$criteria = new Criteria(TblspaceresourcePeer::DATABASE_NAME);
+		}
+		elseif ($criteria instanceof Criteria)
+		{
+			$criteria = clone $criteria;
+		}
+
+		if ($this->collTblspacefiles === null) {
+			if ($this->isNew()) {
+			   $this->collTblspacefiles = array();
+			} else {
+
+				$criteria->add(TblspacefilePeer::FILE_RESOURCE, $this->res_id);
+
+				TblspacefilePeer::addSelectColumns($criteria);
+				$this->collTblspacefiles = TblspacefilePeer::doSelect($criteria, $con);
+			}
+		} else {
+						if (!$this->isNew()) {
+												
+
+				$criteria->add(TblspacefilePeer::FILE_RESOURCE, $this->res_id);
+
+				TblspacefilePeer::addSelectColumns($criteria);
+				if (!isset($this->lastTblspacefileCriteria) || !$this->lastTblspacefileCriteria->equals($criteria)) {
+					$this->collTblspacefiles = TblspacefilePeer::doSelect($criteria, $con);
+				}
+			}
+		}
+		$this->lastTblspacefileCriteria = $criteria;
+		return $this->collTblspacefiles;
+	}
+
+	
+	public function countTblspacefiles(Criteria $criteria = null, $distinct = false, PropelPDO $con = null)
+	{
+		if ($criteria === null) {
+			$criteria = new Criteria(TblspaceresourcePeer::DATABASE_NAME);
+		} else {
+			$criteria = clone $criteria;
+		}
+
+		if ($distinct) {
+			$criteria->setDistinct();
+		}
+
+		$count = null;
+
+		if ($this->collTblspacefiles === null) {
+			if ($this->isNew()) {
+				$count = 0;
+			} else {
+
+				$criteria->add(TblspacefilePeer::FILE_RESOURCE, $this->res_id);
+
+				$count = TblspacefilePeer::doCount($criteria, $con);
+			}
+		} else {
+						if (!$this->isNew()) {
+												
+
+				$criteria->add(TblspacefilePeer::FILE_RESOURCE, $this->res_id);
+
+				if (!isset($this->lastTblspacefileCriteria) || !$this->lastTblspacefileCriteria->equals($criteria)) {
+					$count = TblspacefilePeer::doCount($criteria, $con);
+				} else {
+					$count = count($this->collTblspacefiles);
+				}
+			} else {
+				$count = count($this->collTblspacefiles);
+			}
+		}
+		$this->lastTblspacefileCriteria = $criteria;
+		return $count;
+	}
+
+	
+	public function addTblspacefile(Tblspacefile $l)
+	{
+		if ($this->collTblspacefiles === null) {
+			$this->initTblspacefiles();
+		}
+		if (!in_array($l, $this->collTblspacefiles, true)) { 			array_push($this->collTblspacefiles, $l);
+			$l->setTblspaceresource($this);
+		}
+	}
+
+	
+	public function clearAllReferences($deep = false)
+	{
+		if ($deep) {
+			if ($this->collTblspacefiles) {
+				foreach ((array) $this->collTblspacefiles as $o) {
+					$o->clearAllReferences($deep);
+				}
+			}
+		} 
+		$this->collTblspacefiles = null;
+	}
+
+} 
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/lib/model/om/BaseTblspaceresourcePeer.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/lib/model/om/BaseTblspaceresourcePeer.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/lib/model/om/BaseTblspaceresourcePeer.php	(revision 19)
@@ -0,0 +1,436 @@
+<?php
+
+
+abstract class BaseTblspaceresourcePeer {
+
+	
+	const DATABASE_NAME = 'propel';
+
+	
+	const TABLE_NAME = 'tblspaceresource';
+
+	
+	const CLASS_DEFAULT = 'lib.model.Tblspaceresource';
+
+	
+	const NUM_COLUMNS = 4;
+
+	
+	const NUM_LAZY_LOAD_COLUMNS = 0;
+
+	
+	const RES_ID = 'tblspaceresource.RES_ID';
+
+	
+	const RES_FILENAME = 'tblspaceresource.RES_FILENAME';
+
+	
+	const RES_FILESIZE = 'tblspaceresource.RES_FILESIZE';
+
+	
+	const RES_FILECRC = 'tblspaceresource.RES_FILECRC';
+
+	
+	public static $instances = array();
+
+	
+	private static $mapBuilder = null;
+
+	
+	private static $fieldNames = array (
+		BasePeer::TYPE_PHPNAME => array ('ResId', 'ResFilename', 'ResFilesize', 'ResFilecrc', ),
+		BasePeer::TYPE_STUDLYPHPNAME => array ('resId', 'resFilename', 'resFilesize', 'resFilecrc', ),
+		BasePeer::TYPE_COLNAME => array (self::RES_ID, self::RES_FILENAME, self::RES_FILESIZE, self::RES_FILECRC, ),
+		BasePeer::TYPE_FIELDNAME => array ('res_id', 'res_filename', 'res_filesize', 'res_filecrc', ),
+		BasePeer::TYPE_NUM => array (0, 1, 2, 3, )
+	);
+
+	
+	private static $fieldKeys = array (
+		BasePeer::TYPE_PHPNAME => array ('ResId' => 0, 'ResFilename' => 1, 'ResFilesize' => 2, 'ResFilecrc' => 3, ),
+		BasePeer::TYPE_STUDLYPHPNAME => array ('resId' => 0, 'resFilename' => 1, 'resFilesize' => 2, 'resFilecrc' => 3, ),
+		BasePeer::TYPE_COLNAME => array (self::RES_ID => 0, self::RES_FILENAME => 1, self::RES_FILESIZE => 2, self::RES_FILECRC => 3, ),
+		BasePeer::TYPE_FIELDNAME => array ('res_id' => 0, 'res_filename' => 1, 'res_filesize' => 2, 'res_filecrc' => 3, ),
+		BasePeer::TYPE_NUM => array (0, 1, 2, 3, )
+	);
+
+	
+	public static function getMapBuilder()
+	{
+		if (self::$mapBuilder === null) {
+			self::$mapBuilder = new TblspaceresourceMapBuilder();
+		}
+		return self::$mapBuilder;
+	}
+	
+	static public function translateFieldName($name, $fromType, $toType)
+	{
+		$toNames = self::getFieldNames($toType);
+		$key = isset(self::$fieldKeys[$fromType][$name]) ? self::$fieldKeys[$fromType][$name] : null;
+		if ($key === null) {
+			throw new PropelException("'$name' could not be found in the field names of type '$fromType'. These are: " . print_r(self::$fieldKeys[$fromType], true));
+		}
+		return $toNames[$key];
+	}
+
+	
+
+	static public function getFieldNames($type = BasePeer::TYPE_PHPNAME)
+	{
+		if (!array_key_exists($type, self::$fieldNames)) {
+			throw new PropelException('Method getFieldNames() expects the parameter $type to be one of the class constants BasePeer::TYPE_PHPNAME, BasePeer::TYPE_STUDLYPHPNAME, BasePeer::TYPE_COLNAME, BasePeer::TYPE_FIELDNAME, BasePeer::TYPE_NUM. ' . $type . ' was given.');
+		}
+		return self::$fieldNames[$type];
+	}
+
+	
+	public static function alias($alias, $column)
+	{
+		return str_replace(TblspaceresourcePeer::TABLE_NAME.'.', $alias.'.', $column);
+	}
+
+	
+	public static function addSelectColumns(Criteria $criteria)
+	{
+
+		$criteria->addSelectColumn(TblspaceresourcePeer::RES_ID);
+
+		$criteria->addSelectColumn(TblspaceresourcePeer::RES_FILENAME);
+
+		$criteria->addSelectColumn(TblspaceresourcePeer::RES_FILESIZE);
+
+		$criteria->addSelectColumn(TblspaceresourcePeer::RES_FILECRC);
+
+	}
+
+	
+	public static function doCount(Criteria $criteria, $distinct = false, PropelPDO $con = null)
+	{
+				$criteria = clone $criteria;
+
+								$criteria->setPrimaryTableName(TblspaceresourcePeer::TABLE_NAME);
+
+		if ($distinct && !in_array(Criteria::DISTINCT, $criteria->getSelectModifiers())) {
+			$criteria->setDistinct();
+		}
+
+		if (!$criteria->hasSelectClause()) {
+			TblspaceresourcePeer::addSelectColumns($criteria);
+		}
+
+		$criteria->clearOrderByColumns(); 		$criteria->setDbName(self::DATABASE_NAME); 
+		if ($con === null) {
+			$con = Propel::getConnection(TblspaceresourcePeer::DATABASE_NAME, Propel::CONNECTION_READ);
+		}
+				$stmt = BasePeer::doCount($criteria, $con);
+
+		if ($row = $stmt->fetch(PDO::FETCH_NUM)) {
+			$count = (int) $row[0];
+		} else {
+			$count = 0; 		}
+		$stmt->closeCursor();
+		return $count;
+	}
+	
+	public static function doSelectOne(Criteria $criteria, PropelPDO $con = null)
+	{
+		$critcopy = clone $criteria;
+		$critcopy->setLimit(1);
+		$objects = TblspaceresourcePeer::doSelect($critcopy, $con);
+		if ($objects) {
+			return $objects[0];
+		}
+		return null;
+	}
+	
+	public static function doSelect(Criteria $criteria, PropelPDO $con = null)
+	{
+		return TblspaceresourcePeer::populateObjects(TblspaceresourcePeer::doSelectStmt($criteria, $con));
+	}
+	
+	public static function doSelectStmt(Criteria $criteria, PropelPDO $con = null)
+	{
+		if ($con === null) {
+			$con = Propel::getConnection(TblspaceresourcePeer::DATABASE_NAME, Propel::CONNECTION_READ);
+		}
+
+		if (!$criteria->hasSelectClause()) {
+			$criteria = clone $criteria;
+			TblspaceresourcePeer::addSelectColumns($criteria);
+		}
+
+				$criteria->setDbName(self::DATABASE_NAME);
+
+				return BasePeer::doSelect($criteria, $con);
+	}
+	
+	public static function addInstanceToPool(Tblspaceresource $obj, $key = null)
+	{
+		if (Propel::isInstancePoolingEnabled()) {
+			if ($key === null) {
+				$key = (string) $obj->getResId();
+			} 			self::$instances[$key] = $obj;
+		}
+	}
+
+	
+	public static function removeInstanceFromPool($value)
+	{
+		if (Propel::isInstancePoolingEnabled() && $value !== null) {
+			if (is_object($value) && $value instanceof Tblspaceresource) {
+				$key = (string) $value->getResId();
+			} elseif (is_scalar($value)) {
+								$key = (string) $value;
+			} else {
+				$e = new PropelException("Invalid value passed to removeInstanceFromPool().  Expected primary key or Tblspaceresource object; got " . (is_object($value) ? get_class($value) . ' object.' : var_export($value,true)));
+				throw $e;
+			}
+
+			unset(self::$instances[$key]);
+		}
+	} 
+	
+	public static function getInstanceFromPool($key)
+	{
+		if (Propel::isInstancePoolingEnabled()) {
+			if (isset(self::$instances[$key])) {
+				return self::$instances[$key];
+			}
+		}
+		return null; 	}
+	
+	
+	public static function clearInstancePool()
+	{
+		self::$instances = array();
+	}
+	
+	
+	public static function getPrimaryKeyHashFromRow($row, $startcol = 0)
+	{
+				if ($row[$startcol + 0] === null) {
+			return null;
+		}
+		return (string) $row[$startcol + 0];
+	}
+
+	
+	public static function populateObjects(PDOStatement $stmt)
+	{
+		$results = array();
+	
+				$cls = TblspaceresourcePeer::getOMClass();
+		$cls = substr('.'.$cls, strrpos('.'.$cls, '.') + 1);
+				while ($row = $stmt->fetch(PDO::FETCH_NUM)) {
+			$key = TblspaceresourcePeer::getPrimaryKeyHashFromRow($row, 0);
+			if (null !== ($obj = TblspaceresourcePeer::getInstanceFromPool($key))) {
+																$results[] = $obj;
+			} else {
+		
+				$obj = new $cls();
+				$obj->hydrate($row);
+				$results[] = $obj;
+				TblspaceresourcePeer::addInstanceToPool($obj, $key);
+			} 		}
+		$stmt->closeCursor();
+		return $results;
+	}
+	
+	public static function getTableMap()
+	{
+		return Propel::getDatabaseMap(self::DATABASE_NAME)->getTable(self::TABLE_NAME);
+	}
+
+	
+	public static function getOMClass()
+	{
+		return TblspaceresourcePeer::CLASS_DEFAULT;
+	}
+
+	
+	public static function doInsert($values, PropelPDO $con = null)
+	{
+		if ($con === null) {
+			$con = Propel::getConnection(TblspaceresourcePeer::DATABASE_NAME, Propel::CONNECTION_WRITE);
+		}
+
+		if ($values instanceof Criteria) {
+			$criteria = clone $values; 		} else {
+			$criteria = $values->buildCriteria(); 		}
+
+		if ($criteria->containsKey(TblspaceresourcePeer::RES_ID) && $criteria->keyContainsValue(TblspaceresourcePeer::RES_ID) ) {
+			throw new PropelException('Cannot insert a value for auto-increment primary key ('.TblspaceresourcePeer::RES_ID.')');
+		}
+
+
+				$criteria->setDbName(self::DATABASE_NAME);
+
+		try {
+									$con->beginTransaction();
+			$pk = BasePeer::doInsert($criteria, $con);
+			$con->commit();
+		} catch(PropelException $e) {
+			$con->rollBack();
+			throw $e;
+		}
+
+		return $pk;
+	}
+
+	
+	public static function doUpdate($values, PropelPDO $con = null)
+	{
+		if ($con === null) {
+			$con = Propel::getConnection(TblspaceresourcePeer::DATABASE_NAME, Propel::CONNECTION_WRITE);
+		}
+
+		$selectCriteria = new Criteria(self::DATABASE_NAME);
+
+		if ($values instanceof Criteria) {
+			$criteria = clone $values; 
+			$comparison = $criteria->getComparison(TblspaceresourcePeer::RES_ID);
+			$selectCriteria->add(TblspaceresourcePeer::RES_ID, $criteria->remove(TblspaceresourcePeer::RES_ID), $comparison);
+
+		} else { 			$criteria = $values->buildCriteria(); 			$selectCriteria = $values->buildPkeyCriteria(); 		}
+
+				$criteria->setDbName(self::DATABASE_NAME);
+
+		return BasePeer::doUpdate($selectCriteria, $criteria, $con);
+	}
+
+	
+	public static function doDeleteAll($con = null)
+	{
+		if ($con === null) {
+			$con = Propel::getConnection(TblspaceresourcePeer::DATABASE_NAME, Propel::CONNECTION_WRITE);
+		}
+		$affectedRows = 0; 		try {
+									$con->beginTransaction();
+			$affectedRows += BasePeer::doDeleteAll(TblspaceresourcePeer::TABLE_NAME, $con);
+			$con->commit();
+			return $affectedRows;
+		} catch (PropelException $e) {
+			$con->rollBack();
+			throw $e;
+		}
+	}
+
+	
+	 public static function doDelete($values, PropelPDO $con = null)
+	 {
+		if ($con === null) {
+			$con = Propel::getConnection(TblspaceresourcePeer::DATABASE_NAME, Propel::CONNECTION_WRITE);
+		}
+
+		if ($values instanceof Criteria) {
+												TblspaceresourcePeer::clearInstancePool();
+
+						$criteria = clone $values;
+		} elseif ($values instanceof Tblspaceresource) {
+						TblspaceresourcePeer::removeInstanceFromPool($values);
+						$criteria = $values->buildPkeyCriteria();
+		} else {
+			
+
+
+			$criteria = new Criteria(self::DATABASE_NAME);
+			$criteria->add(TblspaceresourcePeer::RES_ID, (array) $values, Criteria::IN);
+
+			foreach ((array) $values as $singleval) {
+								TblspaceresourcePeer::removeInstanceFromPool($singleval);
+			}
+		}
+
+				$criteria->setDbName(self::DATABASE_NAME);
+
+		$affectedRows = 0; 
+		try {
+									$con->beginTransaction();
+			
+			$affectedRows += BasePeer::doDelete($criteria, $con);
+
+			$con->commit();
+			return $affectedRows;
+		} catch (PropelException $e) {
+			$con->rollBack();
+			throw $e;
+		}
+	}
+
+	
+	public static function doValidate(Tblspaceresource $obj, $cols = null)
+	{
+		$columns = array();
+
+		if ($cols) {
+			$dbMap = Propel::getDatabaseMap(TblspaceresourcePeer::DATABASE_NAME);
+			$tableMap = $dbMap->getTable(TblspaceresourcePeer::TABLE_NAME);
+
+			if (! is_array($cols)) {
+				$cols = array($cols);
+			}
+
+			foreach ($cols as $colName) {
+				if ($tableMap->containsColumn($colName)) {
+					$get = 'get' . $tableMap->getColumn($colName)->getPhpName();
+					$columns[$colName] = $obj->$get();
+				}
+			}
+		} else {
+
+		}
+
+		$res =  BasePeer::doValidate(TblspaceresourcePeer::DATABASE_NAME, TblspaceresourcePeer::TABLE_NAME, $columns);
+    if ($res !== true) {
+        $request = sfContext::getInstance()->getRequest();
+        foreach ($res as $failed) {
+            $col = TblspaceresourcePeer::translateFieldname($failed->getColumn(), BasePeer::TYPE_COLNAME, BasePeer::TYPE_PHPNAME);
+            $request->setError($col, $failed->getMessage());
+        }
+    }
+
+    return $res;
+	}
+
+	
+	public static function retrieveByPK($pk, PropelPDO $con = null)
+	{
+
+		if (null !== ($obj = TblspaceresourcePeer::getInstanceFromPool((string) $pk))) {
+			return $obj;
+		}
+
+		if ($con === null) {
+			$con = Propel::getConnection(TblspaceresourcePeer::DATABASE_NAME, Propel::CONNECTION_READ);
+		}
+
+		$criteria = new Criteria(TblspaceresourcePeer::DATABASE_NAME);
+		$criteria->add(TblspaceresourcePeer::RES_ID, $pk);
+
+		$v = TblspaceresourcePeer::doSelect($criteria, $con);
+
+		return !empty($v) > 0 ? $v[0] : null;
+	}
+
+	
+	public static function retrieveByPKs($pks, PropelPDO $con = null)
+	{
+		if ($con === null) {
+			$con = Propel::getConnection(TblspaceresourcePeer::DATABASE_NAME, Propel::CONNECTION_READ);
+		}
+
+		$objs = null;
+		if (empty($pks)) {
+			$objs = array();
+		} else {
+			$criteria = new Criteria(TblspaceresourcePeer::DATABASE_NAME);
+			$criteria->add(TblspaceresourcePeer::RES_ID, $pks, Criteria::IN);
+			$objs = TblspaceresourcePeer::doSelect($criteria, $con);
+		}
+		return $objs;
+	}
+
+} 
+
+Propel::getDatabaseMap(BaseTblspaceresourcePeer::DATABASE_NAME)->addTableBuilder(BaseTblspaceresourcePeer::TABLE_NAME, BaseTblspaceresourcePeer::getMapBuilder());
+
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/lib/model/om/BaseTbluser.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/lib/model/om/BaseTbluser.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/lib/model/om/BaseTbluser.php	(revision 19)
@@ -0,0 +1,1405 @@
+<?php
+
+
+abstract class BaseTbluser extends BaseObject  implements Persistent {
+
+
+	
+	protected static $peer;
+
+	
+	protected $us_id;
+
+	
+	protected $us_username;
+
+	
+	protected $us_password;
+
+	
+	protected $us_firstname;
+
+	
+	protected $us_lastname;
+
+	
+	protected $us_sex;
+
+	
+	protected $us_email;
+
+	
+	protected $us_phone;
+
+	
+	protected $us_aclgroup;
+
+	
+	protected $us_school;
+
+	
+	protected $us_province;
+
+	
+	protected $us_lastvisited;
+
+	
+	protected $us_registerdate;
+
+	
+	protected $us_rating;
+
+	
+	protected $us_download;
+
+	
+	protected $us_avatar;
+
+	
+	protected $us_status;
+
+	
+	protected $us_key;
+
+	
+	protected $us_company;
+
+	
+	protected $us_score;
+
+	
+	protected $us_pointplus;
+
+	
+	protected $us_checked;
+
+	
+	protected $us_checkinfo;
+
+	
+	protected $us_idmd5;
+
+	
+	protected $us_homepage;
+
+	
+	protected $us_money;
+
+	
+	protected $singleTblblogcheckinfo;
+
+	
+	protected $alreadyInSave = false;
+
+	
+	protected $alreadyInValidation = false;
+
+	
+	public function __construct()
+	{
+		parent::__construct();
+		$this->applyDefaultValues();
+	}
+
+	
+	public function applyDefaultValues()
+	{
+		$this->us_sex = 0;
+		$this->us_rating = 0;
+		$this->us_download = 0;
+		$this->us_status = 0;
+		$this->us_key = 0;
+		$this->us_company = 0;
+		$this->us_score = 0;
+		$this->us_pointplus = 5;
+		$this->us_checked = 0;
+		$this->us_money = 0;
+	}
+
+	
+	public function getUsId()
+	{
+		return $this->us_id;
+	}
+
+	
+	public function getUsUsername()
+	{
+		return $this->us_username;
+	}
+
+	
+	public function getUsPassword()
+	{
+		return $this->us_password;
+	}
+
+	
+	public function getUsFirstname()
+	{
+		return $this->us_firstname;
+	}
+
+	
+	public function getUsLastname()
+	{
+		return $this->us_lastname;
+	}
+
+	
+	public function getUsSex()
+	{
+		return $this->us_sex;
+	}
+
+	
+	public function getUsEmail()
+	{
+		return $this->us_email;
+	}
+
+	
+	public function getUsPhone()
+	{
+		return $this->us_phone;
+	}
+
+	
+	public function getUsAclgroup()
+	{
+		return $this->us_aclgroup;
+	}
+
+	
+	public function getUsSchool()
+	{
+		return $this->us_school;
+	}
+
+	
+	public function getUsProvince()
+	{
+		return $this->us_province;
+	}
+
+	
+	public function getUsLastvisited($format = 'Y-m-d H:i:s')
+	{
+		if ($this->us_lastvisited === null) {
+			return null;
+		}
+
+
+		if ($this->us_lastvisited === '0000-00-00 00:00:00') {
+									return null;
+		} else {
+			try {
+				$dt = new DateTime($this->us_lastvisited);
+			} catch (Exception $x) {
+				throw new PropelException("Internally stored date/time/timestamp value could not be converted to DateTime: " . var_export($this->us_lastvisited, true), $x);
+			}
+		}
+
+		if ($format === null) {
+						return $dt;
+		} elseif (strpos($format, '%') !== false) {
+			return strftime($format, $dt->format('U'));
+		} else {
+			return $dt->format($format);
+		}
+	}
+
+	
+	public function getUsRegisterdate($format = 'Y-m-d H:i:s')
+	{
+		if ($this->us_registerdate === null) {
+			return null;
+		}
+
+
+		if ($this->us_registerdate === '0000-00-00 00:00:00') {
+									return null;
+		} else {
+			try {
+				$dt = new DateTime($this->us_registerdate);
+			} catch (Exception $x) {
+				throw new PropelException("Internally stored date/time/timestamp value could not be converted to DateTime: " . var_export($this->us_registerdate, true), $x);
+			}
+		}
+
+		if ($format === null) {
+						return $dt;
+		} elseif (strpos($format, '%') !== false) {
+			return strftime($format, $dt->format('U'));
+		} else {
+			return $dt->format($format);
+		}
+	}
+
+	
+	public function getUsRating()
+	{
+		return $this->us_rating;
+	}
+
+	
+	public function getUsDownload()
+	{
+		return $this->us_download;
+	}
+
+	
+	public function getUsAvatar()
+	{
+		return $this->us_avatar;
+	}
+
+	
+	public function getUsStatus()
+	{
+		return $this->us_status;
+	}
+
+	
+	public function getUsKey()
+	{
+		return $this->us_key;
+	}
+
+	
+	public function getUsCompany()
+	{
+		return $this->us_company;
+	}
+
+	
+	public function getUsScore()
+	{
+		return $this->us_score;
+	}
+
+	
+	public function getUsPointplus()
+	{
+		return $this->us_pointplus;
+	}
+
+	
+	public function getUsChecked()
+	{
+		return $this->us_checked;
+	}
+
+	
+	public function getUsCheckinfo()
+	{
+		return $this->us_checkinfo;
+	}
+
+	
+	public function getUsIdmd5()
+	{
+		return $this->us_idmd5;
+	}
+
+	
+	public function getUsHomepage()
+	{
+		return $this->us_homepage;
+	}
+
+	
+	public function getUsMoney()
+	{
+		return $this->us_money;
+	}
+
+	
+	public function setUsId($v)
+	{
+		if ($v !== null) {
+			$v = (int) $v;
+		}
+
+		if ($this->us_id !== $v) {
+			$this->us_id = $v;
+			$this->modifiedColumns[] = TbluserPeer::US_ID;
+		}
+
+		return $this;
+	} 
+	
+	public function setUsUsername($v)
+	{
+		if ($v !== null) {
+			$v = (string) $v;
+		}
+
+		if ($this->us_username !== $v) {
+			$this->us_username = $v;
+			$this->modifiedColumns[] = TbluserPeer::US_USERNAME;
+		}
+
+		return $this;
+	} 
+	
+	public function setUsPassword($v)
+	{
+		if ($v !== null) {
+			$v = (string) $v;
+		}
+
+		if ($this->us_password !== $v) {
+			$this->us_password = $v;
+			$this->modifiedColumns[] = TbluserPeer::US_PASSWORD;
+		}
+
+		return $this;
+	} 
+	
+	public function setUsFirstname($v)
+	{
+		if ($v !== null) {
+			$v = (string) $v;
+		}
+
+		if ($this->us_firstname !== $v) {
+			$this->us_firstname = $v;
+			$this->modifiedColumns[] = TbluserPeer::US_FIRSTNAME;
+		}
+
+		return $this;
+	} 
+	
+	public function setUsLastname($v)
+	{
+		if ($v !== null) {
+			$v = (string) $v;
+		}
+
+		if ($this->us_lastname !== $v) {
+			$this->us_lastname = $v;
+			$this->modifiedColumns[] = TbluserPeer::US_LASTNAME;
+		}
+
+		return $this;
+	} 
+	
+	public function setUsSex($v)
+	{
+		if ($v !== null) {
+			$v = (int) $v;
+		}
+
+		if ($this->us_sex !== $v || $v === 0) {
+			$this->us_sex = $v;
+			$this->modifiedColumns[] = TbluserPeer::US_SEX;
+		}
+
+		return $this;
+	} 
+	
+	public function setUsEmail($v)
+	{
+		if ($v !== null) {
+			$v = (string) $v;
+		}
+
+		if ($this->us_email !== $v) {
+			$this->us_email = $v;
+			$this->modifiedColumns[] = TbluserPeer::US_EMAIL;
+		}
+
+		return $this;
+	} 
+	
+	public function setUsPhone($v)
+	{
+		if ($v !== null) {
+			$v = (string) $v;
+		}
+
+		if ($this->us_phone !== $v) {
+			$this->us_phone = $v;
+			$this->modifiedColumns[] = TbluserPeer::US_PHONE;
+		}
+
+		return $this;
+	} 
+	
+	public function setUsAclgroup($v)
+	{
+		if ($v !== null) {
+			$v = (int) $v;
+		}
+
+		if ($this->us_aclgroup !== $v) {
+			$this->us_aclgroup = $v;
+			$this->modifiedColumns[] = TbluserPeer::US_ACLGROUP;
+		}
+
+		return $this;
+	} 
+	
+	public function setUsSchool($v)
+	{
+		if ($v !== null) {
+			$v = (string) $v;
+		}
+
+		if ($this->us_school !== $v) {
+			$this->us_school = $v;
+			$this->modifiedColumns[] = TbluserPeer::US_SCHOOL;
+		}
+
+		return $this;
+	} 
+	
+	public function setUsProvince($v)
+	{
+		if ($v !== null) {
+			$v = (string) $v;
+		}
+
+		if ($this->us_province !== $v) {
+			$this->us_province = $v;
+			$this->modifiedColumns[] = TbluserPeer::US_PROVINCE;
+		}
+
+		return $this;
+	} 
+	
+	public function setUsLastvisited($v)
+	{
+						if ($v === null || $v === '') {
+			$dt = null;
+		} elseif ($v instanceof DateTime) {
+			$dt = $v;
+		} else {
+									try {
+				if (is_numeric($v)) { 					$dt = new DateTime('@'.$v, new DateTimeZone('UTC'));
+															$dt->setTimeZone(new DateTimeZone(date_default_timezone_get()));
+				} else {
+					$dt = new DateTime($v);
+				}
+			} catch (Exception $x) {
+				throw new PropelException('Error parsing date/time value: ' . var_export($v, true), $x);
+			}
+		}
+
+		if ( $this->us_lastvisited !== null || $dt !== null ) {
+			
+			$currNorm = ($this->us_lastvisited !== null && $tmpDt = new DateTime($this->us_lastvisited)) ? $tmpDt->format('Y-m-d H:i:s') : null;
+			$newNorm = ($dt !== null) ? $dt->format('Y-m-d H:i:s') : null;
+
+			if ( ($currNorm !== $newNorm) 					)
+			{
+				$this->us_lastvisited = ($dt ? $dt->format('Y-m-d H:i:s') : null);
+				$this->modifiedColumns[] = TbluserPeer::US_LASTVISITED;
+			}
+		} 
+		return $this;
+	} 
+	
+	public function setUsRegisterdate($v)
+	{
+						if ($v === null || $v === '') {
+			$dt = null;
+		} elseif ($v instanceof DateTime) {
+			$dt = $v;
+		} else {
+									try {
+				if (is_numeric($v)) { 					$dt = new DateTime('@'.$v, new DateTimeZone('UTC'));
+															$dt->setTimeZone(new DateTimeZone(date_default_timezone_get()));
+				} else {
+					$dt = new DateTime($v);
+				}
+			} catch (Exception $x) {
+				throw new PropelException('Error parsing date/time value: ' . var_export($v, true), $x);
+			}
+		}
+
+		if ( $this->us_registerdate !== null || $dt !== null ) {
+			
+			$currNorm = ($this->us_registerdate !== null && $tmpDt = new DateTime($this->us_registerdate)) ? $tmpDt->format('Y-m-d H:i:s') : null;
+			$newNorm = ($dt !== null) ? $dt->format('Y-m-d H:i:s') : null;
+
+			if ( ($currNorm !== $newNorm) 					)
+			{
+				$this->us_registerdate = ($dt ? $dt->format('Y-m-d H:i:s') : null);
+				$this->modifiedColumns[] = TbluserPeer::US_REGISTERDATE;
+			}
+		} 
+		return $this;
+	} 
+	
+	public function setUsRating($v)
+	{
+		if ($v !== null) {
+			$v = (int) $v;
+		}
+
+		if ($this->us_rating !== $v || $v === 0) {
+			$this->us_rating = $v;
+			$this->modifiedColumns[] = TbluserPeer::US_RATING;
+		}
+
+		return $this;
+	} 
+	
+	public function setUsDownload($v)
+	{
+		if ($v !== null) {
+			$v = (int) $v;
+		}
+
+		if ($this->us_download !== $v || $v === 0) {
+			$this->us_download = $v;
+			$this->modifiedColumns[] = TbluserPeer::US_DOWNLOAD;
+		}
+
+		return $this;
+	} 
+	
+	public function setUsAvatar($v)
+	{
+		if ($v !== null) {
+			$v = (string) $v;
+		}
+
+		if ($this->us_avatar !== $v) {
+			$this->us_avatar = $v;
+			$this->modifiedColumns[] = TbluserPeer::US_AVATAR;
+		}
+
+		return $this;
+	} 
+	
+	public function setUsStatus($v)
+	{
+		if ($v !== null) {
+			$v = (int) $v;
+		}
+
+		if ($this->us_status !== $v || $v === 0) {
+			$this->us_status = $v;
+			$this->modifiedColumns[] = TbluserPeer::US_STATUS;
+		}
+
+		return $this;
+	} 
+	
+	public function setUsKey($v)
+	{
+		if ($v !== null) {
+			$v = (int) $v;
+		}
+
+		if ($this->us_key !== $v || $v === 0) {
+			$this->us_key = $v;
+			$this->modifiedColumns[] = TbluserPeer::US_KEY;
+		}
+
+		return $this;
+	} 
+	
+	public function setUsCompany($v)
+	{
+		if ($v !== null) {
+			$v = (int) $v;
+		}
+
+		if ($this->us_company !== $v || $v === 0) {
+			$this->us_company = $v;
+			$this->modifiedColumns[] = TbluserPeer::US_COMPANY;
+		}
+
+		return $this;
+	} 
+	
+	public function setUsScore($v)
+	{
+		if ($v !== null) {
+			$v = (int) $v;
+		}
+
+		if ($this->us_score !== $v || $v === 0) {
+			$this->us_score = $v;
+			$this->modifiedColumns[] = TbluserPeer::US_SCORE;
+		}
+
+		return $this;
+	} 
+	
+	public function setUsPointplus($v)
+	{
+		if ($v !== null) {
+			$v = (int) $v;
+		}
+
+		if ($this->us_pointplus !== $v || $v === 5) {
+			$this->us_pointplus = $v;
+			$this->modifiedColumns[] = TbluserPeer::US_POINTPLUS;
+		}
+
+		return $this;
+	} 
+	
+	public function setUsChecked($v)
+	{
+		if ($v !== null) {
+			$v = (int) $v;
+		}
+
+		if ($this->us_checked !== $v || $v === 0) {
+			$this->us_checked = $v;
+			$this->modifiedColumns[] = TbluserPeer::US_CHECKED;
+		}
+
+		return $this;
+	} 
+	
+	public function setUsCheckinfo($v)
+	{
+		if ($v !== null) {
+			$v = (int) $v;
+		}
+
+		if ($this->us_checkinfo !== $v) {
+			$this->us_checkinfo = $v;
+			$this->modifiedColumns[] = TbluserPeer::US_CHECKINFO;
+		}
+
+		return $this;
+	} 
+	
+	public function setUsIdmd5($v)
+	{
+		if ($v !== null) {
+			$v = (string) $v;
+		}
+
+		if ($this->us_idmd5 !== $v) {
+			$this->us_idmd5 = $v;
+			$this->modifiedColumns[] = TbluserPeer::US_IDMD5;
+		}
+
+		return $this;
+	} 
+	
+	public function setUsHomepage($v)
+	{
+		if ($v !== null) {
+			$v = (string) $v;
+		}
+
+		if ($this->us_homepage !== $v) {
+			$this->us_homepage = $v;
+			$this->modifiedColumns[] = TbluserPeer::US_HOMEPAGE;
+		}
+
+		return $this;
+	} 
+	
+	public function setUsMoney($v)
+	{
+		if ($v !== null) {
+			$v = (int) $v;
+		}
+
+		if ($this->us_money !== $v || $v === 0) {
+			$this->us_money = $v;
+			$this->modifiedColumns[] = TbluserPeer::US_MONEY;
+		}
+
+		return $this;
+	} 
+	
+	public function hasOnlyDefaultValues()
+	{
+						if (array_diff($this->modifiedColumns, array(TbluserPeer::US_SEX,TbluserPeer::US_RATING,TbluserPeer::US_DOWNLOAD,TbluserPeer::US_STATUS,TbluserPeer::US_KEY,TbluserPeer::US_COMPANY,TbluserPeer::US_SCORE,TbluserPeer::US_POINTPLUS,TbluserPeer::US_CHECKED,TbluserPeer::US_MONEY))) {
+				return false;
+			}
+
+			if ($this->us_sex !== 0) {
+				return false;
+			}
+
+			if ($this->us_rating !== 0) {
+				return false;
+			}
+
+			if ($this->us_download !== 0) {
+				return false;
+			}
+
+			if ($this->us_status !== 0) {
+				return false;
+			}
+
+			if ($this->us_key !== 0) {
+				return false;
+			}
+
+			if ($this->us_company !== 0) {
+				return false;
+			}
+
+			if ($this->us_score !== 0) {
+				return false;
+			}
+
+			if ($this->us_pointplus !== 5) {
+				return false;
+			}
+
+			if ($this->us_checked !== 0) {
+				return false;
+			}
+
+			if ($this->us_money !== 0) {
+				return false;
+			}
+
+				return true;
+	} 
+	
+	public function hydrate($row, $startcol = 0, $rehydrate = false)
+	{
+		try {
+
+			$this->us_id = ($row[$startcol + 0] !== null) ? (int) $row[$startcol + 0] : null;
+			$this->us_username = ($row[$startcol + 1] !== null) ? (string) $row[$startcol + 1] : null;
+			$this->us_password = ($row[$startcol + 2] !== null) ? (string) $row[$startcol + 2] : null;
+			$this->us_firstname = ($row[$startcol + 3] !== null) ? (string) $row[$startcol + 3] : null;
+			$this->us_lastname = ($row[$startcol + 4] !== null) ? (string) $row[$startcol + 4] : null;
+			$this->us_sex = ($row[$startcol + 5] !== null) ? (int) $row[$startcol + 5] : null;
+			$this->us_email = ($row[$startcol + 6] !== null) ? (string) $row[$startcol + 6] : null;
+			$this->us_phone = ($row[$startcol + 7] !== null) ? (string) $row[$startcol + 7] : null;
+			$this->us_aclgroup = ($row[$startcol + 8] !== null) ? (int) $row[$startcol + 8] : null;
+			$this->us_school = ($row[$startcol + 9] !== null) ? (string) $row[$startcol + 9] : null;
+			$this->us_province = ($row[$startcol + 10] !== null) ? (string) $row[$startcol + 10] : null;
+			$this->us_lastvisited = ($row[$startcol + 11] !== null) ? (string) $row[$startcol + 11] : null;
+			$this->us_registerdate = ($row[$startcol + 12] !== null) ? (string) $row[$startcol + 12] : null;
+			$this->us_rating = ($row[$startcol + 13] !== null) ? (int) $row[$startcol + 13] : null;
+			$this->us_download = ($row[$startcol + 14] !== null) ? (int) $row[$startcol + 14] : null;
+			$this->us_avatar = ($row[$startcol + 15] !== null) ? (string) $row[$startcol + 15] : null;
+			$this->us_status = ($row[$startcol + 16] !== null) ? (int) $row[$startcol + 16] : null;
+			$this->us_key = ($row[$startcol + 17] !== null) ? (int) $row[$startcol + 17] : null;
+			$this->us_company = ($row[$startcol + 18] !== null) ? (int) $row[$startcol + 18] : null;
+			$this->us_score = ($row[$startcol + 19] !== null) ? (int) $row[$startcol + 19] : null;
+			$this->us_pointplus = ($row[$startcol + 20] !== null) ? (int) $row[$startcol + 20] : null;
+			$this->us_checked = ($row[$startcol + 21] !== null) ? (int) $row[$startcol + 21] : null;
+			$this->us_checkinfo = ($row[$startcol + 22] !== null) ? (int) $row[$startcol + 22] : null;
+			$this->us_idmd5 = ($row[$startcol + 23] !== null) ? (string) $row[$startcol + 23] : null;
+			$this->us_homepage = ($row[$startcol + 24] !== null) ? (string) $row[$startcol + 24] : null;
+			$this->us_money = ($row[$startcol + 25] !== null) ? (int) $row[$startcol + 25] : null;
+			$this->resetModified();
+
+			$this->setNew(false);
+
+			if ($rehydrate) {
+				$this->ensureConsistency();
+			}
+
+						return $startcol + 26; 
+		} catch (Exception $e) {
+			throw new PropelException("Error populating Tbluser object", $e);
+		}
+	}
+
+	
+	public function ensureConsistency()
+	{
+
+	} 
+	
+	public function reload($deep = false, PropelPDO $con = null)
+	{
+		if ($this->isDeleted()) {
+			throw new PropelException("Cannot reload a deleted object.");
+		}
+
+		if ($this->isNew()) {
+			throw new PropelException("Cannot reload an unsaved object.");
+		}
+
+		if ($con === null) {
+			$con = Propel::getConnection(TbluserPeer::DATABASE_NAME, Propel::CONNECTION_READ);
+		}
+
+				
+		$stmt = TbluserPeer::doSelectStmt($this->buildPkeyCriteria(), $con);
+		$row = $stmt->fetch(PDO::FETCH_NUM);
+		$stmt->closeCursor();
+		if (!$row) {
+			throw new PropelException('Cannot find matching row in the database to reload object values.');
+		}
+		$this->hydrate($row, 0, true); 
+		if ($deep) {  
+			$this->singleTblblogcheckinfo = null;
+
+		} 	}
+
+	
+	public function delete(PropelPDO $con = null)
+	{
+		if ($this->isDeleted()) {
+			throw new PropelException("This object has already been deleted.");
+		}
+
+		if ($con === null) {
+			$con = Propel::getConnection(TbluserPeer::DATABASE_NAME, Propel::CONNECTION_WRITE);
+		}
+		
+		$con->beginTransaction();
+		try {
+			TbluserPeer::doDelete($this, $con);
+			$this->setDeleted(true);
+			$con->commit();
+		} catch (PropelException $e) {
+			$con->rollBack();
+			throw $e;
+		}
+	}
+
+	
+	public function save(PropelPDO $con = null)
+	{
+		if ($this->isDeleted()) {
+			throw new PropelException("You cannot save an object that has been deleted.");
+		}
+
+		if ($con === null) {
+			$con = Propel::getConnection(TbluserPeer::DATABASE_NAME, Propel::CONNECTION_WRITE);
+		}
+		
+		$con->beginTransaction();
+		try {
+			$affectedRows = $this->doSave($con);
+			$con->commit();
+			TbluserPeer::addInstanceToPool($this);
+			return $affectedRows;
+		} catch (PropelException $e) {
+			$con->rollBack();
+			throw $e;
+		}
+	}
+
+	
+	protected function doSave(PropelPDO $con)
+	{
+		$affectedRows = 0; 		if (!$this->alreadyInSave) {
+			$this->alreadyInSave = true;
+
+			if ($this->isNew() ) {
+				$this->modifiedColumns[] = TbluserPeer::US_ID;
+			}
+
+						if ($this->isModified()) {
+				if ($this->isNew()) {
+					$pk = TbluserPeer::doInsert($this, $con);
+					$affectedRows += 1; 										 										 
+					$this->setUsId($pk);  
+					$this->setNew(false);
+				} else {
+					$affectedRows += TbluserPeer::doUpdate($this, $con);
+				}
+
+				$this->resetModified(); 			}
+
+			if ($this->singleTblblogcheckinfo !== null) {
+				if (!$this->singleTblblogcheckinfo->isDeleted()) {
+						$affectedRows += $this->singleTblblogcheckinfo->save($con);
+				}
+			}
+
+			$this->alreadyInSave = false;
+
+		}
+		return $affectedRows;
+	} 
+	
+	protected $validationFailures = array();
+
+	
+	public function getValidationFailures()
+	{
+		return $this->validationFailures;
+	}
+
+	
+	public function validate($columns = null)
+	{
+		$res = $this->doValidate($columns);
+		if ($res === true) {
+			$this->validationFailures = array();
+			return true;
+		} else {
+			$this->validationFailures = $res;
+			return false;
+		}
+	}
+
+	
+	protected function doValidate($columns = null)
+	{
+		if (!$this->alreadyInValidation) {
+			$this->alreadyInValidation = true;
+			$retval = null;
+
+			$failureMap = array();
+
+
+			if (($retval = TbluserPeer::doValidate($this, $columns)) !== true) {
+				$failureMap = array_merge($failureMap, $retval);
+			}
+
+
+				if ($this->singleTblblogcheckinfo !== null) {
+					if (!$this->singleTblblogcheckinfo->validate($columns)) {
+						$failureMap = array_merge($failureMap, $this->singleTblblogcheckinfo->getValidationFailures());
+					}
+				}
+
+
+			$this->alreadyInValidation = false;
+		}
+
+		return (!empty($failureMap) ? $failureMap : true);
+	}
+
+	
+	public function getByName($name, $type = BasePeer::TYPE_PHPNAME)
+	{
+		$pos = TbluserPeer::translateFieldName($name, $type, BasePeer::TYPE_NUM);
+		$field = $this->getByPosition($pos);
+		return $field;
+	}
+
+	
+	public function getByPosition($pos)
+	{
+		switch($pos) {
+			case 0:
+				return $this->getUsId();
+				break;
+			case 1:
+				return $this->getUsUsername();
+				break;
+			case 2:
+				return $this->getUsPassword();
+				break;
+			case 3:
+				return $this->getUsFirstname();
+				break;
+			case 4:
+				return $this->getUsLastname();
+				break;
+			case 5:
+				return $this->getUsSex();
+				break;
+			case 6:
+				return $this->getUsEmail();
+				break;
+			case 7:
+				return $this->getUsPhone();
+				break;
+			case 8:
+				return $this->getUsAclgroup();
+				break;
+			case 9:
+				return $this->getUsSchool();
+				break;
+			case 10:
+				return $this->getUsProvince();
+				break;
+			case 11:
+				return $this->getUsLastvisited();
+				break;
+			case 12:
+				return $this->getUsRegisterdate();
+				break;
+			case 13:
+				return $this->getUsRating();
+				break;
+			case 14:
+				return $this->getUsDownload();
+				break;
+			case 15:
+				return $this->getUsAvatar();
+				break;
+			case 16:
+				return $this->getUsStatus();
+				break;
+			case 17:
+				return $this->getUsKey();
+				break;
+			case 18:
+				return $this->getUsCompany();
+				break;
+			case 19:
+				return $this->getUsScore();
+				break;
+			case 20:
+				return $this->getUsPointplus();
+				break;
+			case 21:
+				return $this->getUsChecked();
+				break;
+			case 22:
+				return $this->getUsCheckinfo();
+				break;
+			case 23:
+				return $this->getUsIdmd5();
+				break;
+			case 24:
+				return $this->getUsHomepage();
+				break;
+			case 25:
+				return $this->getUsMoney();
+				break;
+			default:
+				return null;
+				break;
+		} 	}
+
+	
+	public function toArray($keyType = BasePeer::TYPE_PHPNAME, $includeLazyLoadColumns = true)
+	{
+		$keys = TbluserPeer::getFieldNames($keyType);
+		$result = array(
+			$keys[0] => $this->getUsId(),
+			$keys[1] => $this->getUsUsername(),
+			$keys[2] => $this->getUsPassword(),
+			$keys[3] => $this->getUsFirstname(),
+			$keys[4] => $this->getUsLastname(),
+			$keys[5] => $this->getUsSex(),
+			$keys[6] => $this->getUsEmail(),
+			$keys[7] => $this->getUsPhone(),
+			$keys[8] => $this->getUsAclgroup(),
+			$keys[9] => $this->getUsSchool(),
+			$keys[10] => $this->getUsProvince(),
+			$keys[11] => $this->getUsLastvisited(),
+			$keys[12] => $this->getUsRegisterdate(),
+			$keys[13] => $this->getUsRating(),
+			$keys[14] => $this->getUsDownload(),
+			$keys[15] => $this->getUsAvatar(),
+			$keys[16] => $this->getUsStatus(),
+			$keys[17] => $this->getUsKey(),
+			$keys[18] => $this->getUsCompany(),
+			$keys[19] => $this->getUsScore(),
+			$keys[20] => $this->getUsPointplus(),
+			$keys[21] => $this->getUsChecked(),
+			$keys[22] => $this->getUsCheckinfo(),
+			$keys[23] => $this->getUsIdmd5(),
+			$keys[24] => $this->getUsHomepage(),
+			$keys[25] => $this->getUsMoney(),
+		);
+		return $result;
+	}
+
+	
+	public function setByName($name, $value, $type = BasePeer::TYPE_PHPNAME)
+	{
+		$pos = TbluserPeer::translateFieldName($name, $type, BasePeer::TYPE_NUM);
+		return $this->setByPosition($pos, $value);
+	}
+
+	
+	public function setByPosition($pos, $value)
+	{
+		switch($pos) {
+			case 0:
+				$this->setUsId($value);
+				break;
+			case 1:
+				$this->setUsUsername($value);
+				break;
+			case 2:
+				$this->setUsPassword($value);
+				break;
+			case 3:
+				$this->setUsFirstname($value);
+				break;
+			case 4:
+				$this->setUsLastname($value);
+				break;
+			case 5:
+				$this->setUsSex($value);
+				break;
+			case 6:
+				$this->setUsEmail($value);
+				break;
+			case 7:
+				$this->setUsPhone($value);
+				break;
+			case 8:
+				$this->setUsAclgroup($value);
+				break;
+			case 9:
+				$this->setUsSchool($value);
+				break;
+			case 10:
+				$this->setUsProvince($value);
+				break;
+			case 11:
+				$this->setUsLastvisited($value);
+				break;
+			case 12:
+				$this->setUsRegisterdate($value);
+				break;
+			case 13:
+				$this->setUsRating($value);
+				break;
+			case 14:
+				$this->setUsDownload($value);
+				break;
+			case 15:
+				$this->setUsAvatar($value);
+				break;
+			case 16:
+				$this->setUsStatus($value);
+				break;
+			case 17:
+				$this->setUsKey($value);
+				break;
+			case 18:
+				$this->setUsCompany($value);
+				break;
+			case 19:
+				$this->setUsScore($value);
+				break;
+			case 20:
+				$this->setUsPointplus($value);
+				break;
+			case 21:
+				$this->setUsChecked($value);
+				break;
+			case 22:
+				$this->setUsCheckinfo($value);
+				break;
+			case 23:
+				$this->setUsIdmd5($value);
+				break;
+			case 24:
+				$this->setUsHomepage($value);
+				break;
+			case 25:
+				$this->setUsMoney($value);
+				break;
+		} 	}
+
+	
+	public function fromArray($arr, $keyType = BasePeer::TYPE_PHPNAME)
+	{
+		$keys = TbluserPeer::getFieldNames($keyType);
+
+		if (array_key_exists($keys[0], $arr)) $this->setUsId($arr[$keys[0]]);
+		if (array_key_exists($keys[1], $arr)) $this->setUsUsername($arr[$keys[1]]);
+		if (array_key_exists($keys[2], $arr)) $this->setUsPassword($arr[$keys[2]]);
+		if (array_key_exists($keys[3], $arr)) $this->setUsFirstname($arr[$keys[3]]);
+		if (array_key_exists($keys[4], $arr)) $this->setUsLastname($arr[$keys[4]]);
+		if (array_key_exists($keys[5], $arr)) $this->setUsSex($arr[$keys[5]]);
+		if (array_key_exists($keys[6], $arr)) $this->setUsEmail($arr[$keys[6]]);
+		if (array_key_exists($keys[7], $arr)) $this->setUsPhone($arr[$keys[7]]);
+		if (array_key_exists($keys[8], $arr)) $this->setUsAclgroup($arr[$keys[8]]);
+		if (array_key_exists($keys[9], $arr)) $this->setUsSchool($arr[$keys[9]]);
+		if (array_key_exists($keys[10], $arr)) $this->setUsProvince($arr[$keys[10]]);
+		if (array_key_exists($keys[11], $arr)) $this->setUsLastvisited($arr[$keys[11]]);
+		if (array_key_exists($keys[12], $arr)) $this->setUsRegisterdate($arr[$keys[12]]);
+		if (array_key_exists($keys[13], $arr)) $this->setUsRating($arr[$keys[13]]);
+		if (array_key_exists($keys[14], $arr)) $this->setUsDownload($arr[$keys[14]]);
+		if (array_key_exists($keys[15], $arr)) $this->setUsAvatar($arr[$keys[15]]);
+		if (array_key_exists($keys[16], $arr)) $this->setUsStatus($arr[$keys[16]]);
+		if (array_key_exists($keys[17], $arr)) $this->setUsKey($arr[$keys[17]]);
+		if (array_key_exists($keys[18], $arr)) $this->setUsCompany($arr[$keys[18]]);
+		if (array_key_exists($keys[19], $arr)) $this->setUsScore($arr[$keys[19]]);
+		if (array_key_exists($keys[20], $arr)) $this->setUsPointplus($arr[$keys[20]]);
+		if (array_key_exists($keys[21], $arr)) $this->setUsChecked($arr[$keys[21]]);
+		if (array_key_exists($keys[22], $arr)) $this->setUsCheckinfo($arr[$keys[22]]);
+		if (array_key_exists($keys[23], $arr)) $this->setUsIdmd5($arr[$keys[23]]);
+		if (array_key_exists($keys[24], $arr)) $this->setUsHomepage($arr[$keys[24]]);
+		if (array_key_exists($keys[25], $arr)) $this->setUsMoney($arr[$keys[25]]);
+	}
+
+	
+	public function buildCriteria()
+	{
+		$criteria = new Criteria(TbluserPeer::DATABASE_NAME);
+
+		if ($this->isColumnModified(TbluserPeer::US_ID)) $criteria->add(TbluserPeer::US_ID, $this->us_id);
+		if ($this->isColumnModified(TbluserPeer::US_USERNAME)) $criteria->add(TbluserPeer::US_USERNAME, $this->us_username);
+		if ($this->isColumnModified(TbluserPeer::US_PASSWORD)) $criteria->add(TbluserPeer::US_PASSWORD, $this->us_password);
+		if ($this->isColumnModified(TbluserPeer::US_FIRSTNAME)) $criteria->add(TbluserPeer::US_FIRSTNAME, $this->us_firstname);
+		if ($this->isColumnModified(TbluserPeer::US_LASTNAME)) $criteria->add(TbluserPeer::US_LASTNAME, $this->us_lastname);
+		if ($this->isColumnModified(TbluserPeer::US_SEX)) $criteria->add(TbluserPeer::US_SEX, $this->us_sex);
+		if ($this->isColumnModified(TbluserPeer::US_EMAIL)) $criteria->add(TbluserPeer::US_EMAIL, $this->us_email);
+		if ($this->isColumnModified(TbluserPeer::US_PHONE)) $criteria->add(TbluserPeer::US_PHONE, $this->us_phone);
+		if ($this->isColumnModified(TbluserPeer::US_ACLGROUP)) $criteria->add(TbluserPeer::US_ACLGROUP, $this->us_aclgroup);
+		if ($this->isColumnModified(TbluserPeer::US_SCHOOL)) $criteria->add(TbluserPeer::US_SCHOOL, $this->us_school);
+		if ($this->isColumnModified(TbluserPeer::US_PROVINCE)) $criteria->add(TbluserPeer::US_PROVINCE, $this->us_province);
+		if ($this->isColumnModified(TbluserPeer::US_LASTVISITED)) $criteria->add(TbluserPeer::US_LASTVISITED, $this->us_lastvisited);
+		if ($this->isColumnModified(TbluserPeer::US_REGISTERDATE)) $criteria->add(TbluserPeer::US_REGISTERDATE, $this->us_registerdate);
+		if ($this->isColumnModified(TbluserPeer::US_RATING)) $criteria->add(TbluserPeer::US_RATING, $this->us_rating);
+		if ($this->isColumnModified(TbluserPeer::US_DOWNLOAD)) $criteria->add(TbluserPeer::US_DOWNLOAD, $this->us_download);
+		if ($this->isColumnModified(TbluserPeer::US_AVATAR)) $criteria->add(TbluserPeer::US_AVATAR, $this->us_avatar);
+		if ($this->isColumnModified(TbluserPeer::US_STATUS)) $criteria->add(TbluserPeer::US_STATUS, $this->us_status);
+		if ($this->isColumnModified(TbluserPeer::US_KEY)) $criteria->add(TbluserPeer::US_KEY, $this->us_key);
+		if ($this->isColumnModified(TbluserPeer::US_COMPANY)) $criteria->add(TbluserPeer::US_COMPANY, $this->us_company);
+		if ($this->isColumnModified(TbluserPeer::US_SCORE)) $criteria->add(TbluserPeer::US_SCORE, $this->us_score);
+		if ($this->isColumnModified(TbluserPeer::US_POINTPLUS)) $criteria->add(TbluserPeer::US_POINTPLUS, $this->us_pointplus);
+		if ($this->isColumnModified(TbluserPeer::US_CHECKED)) $criteria->add(TbluserPeer::US_CHECKED, $this->us_checked);
+		if ($this->isColumnModified(TbluserPeer::US_CHECKINFO)) $criteria->add(TbluserPeer::US_CHECKINFO, $this->us_checkinfo);
+		if ($this->isColumnModified(TbluserPeer::US_IDMD5)) $criteria->add(TbluserPeer::US_IDMD5, $this->us_idmd5);
+		if ($this->isColumnModified(TbluserPeer::US_HOMEPAGE)) $criteria->add(TbluserPeer::US_HOMEPAGE, $this->us_homepage);
+		if ($this->isColumnModified(TbluserPeer::US_MONEY)) $criteria->add(TbluserPeer::US_MONEY, $this->us_money);
+
+		return $criteria;
+	}
+
+	
+	public function buildPkeyCriteria()
+	{
+		$criteria = new Criteria(TbluserPeer::DATABASE_NAME);
+
+		$criteria->add(TbluserPeer::US_ID, $this->us_id);
+
+		return $criteria;
+	}
+
+	
+	public function getPrimaryKey()
+	{
+		return $this->getUsId();
+	}
+
+	
+	public function setPrimaryKey($key)
+	{
+		$this->setUsId($key);
+	}
+
+	
+	public function copyInto($copyObj, $deepCopy = false)
+	{
+
+		$copyObj->setUsUsername($this->us_username);
+
+		$copyObj->setUsPassword($this->us_password);
+
+		$copyObj->setUsFirstname($this->us_firstname);
+
+		$copyObj->setUsLastname($this->us_lastname);
+
+		$copyObj->setUsSex($this->us_sex);
+
+		$copyObj->setUsEmail($this->us_email);
+
+		$copyObj->setUsPhone($this->us_phone);
+
+		$copyObj->setUsAclgroup($this->us_aclgroup);
+
+		$copyObj->setUsSchool($this->us_school);
+
+		$copyObj->setUsProvince($this->us_province);
+
+		$copyObj->setUsLastvisited($this->us_lastvisited);
+
+		$copyObj->setUsRegisterdate($this->us_registerdate);
+
+		$copyObj->setUsRating($this->us_rating);
+
+		$copyObj->setUsDownload($this->us_download);
+
+		$copyObj->setUsAvatar($this->us_avatar);
+
+		$copyObj->setUsStatus($this->us_status);
+
+		$copyObj->setUsKey($this->us_key);
+
+		$copyObj->setUsCompany($this->us_company);
+
+		$copyObj->setUsScore($this->us_score);
+
+		$copyObj->setUsPointplus($this->us_pointplus);
+
+		$copyObj->setUsChecked($this->us_checked);
+
+		$copyObj->setUsCheckinfo($this->us_checkinfo);
+
+		$copyObj->setUsIdmd5($this->us_idmd5);
+
+		$copyObj->setUsHomepage($this->us_homepage);
+
+		$copyObj->setUsMoney($this->us_money);
+
+
+		if ($deepCopy) {
+									$copyObj->setNew(false);
+
+			$relObj = $this->getTblblogcheckinfo();
+			if ($relObj) {
+				$copyObj->setTblblogcheckinfo($relObj->copy($deepCopy));
+			}
+
+		} 
+
+		$copyObj->setNew(true);
+
+		$copyObj->setUsId(NULL); 
+	}
+
+	
+	public function copy($deepCopy = false)
+	{
+				$clazz = get_class($this);
+		$copyObj = new $clazz();
+		$this->copyInto($copyObj, $deepCopy);
+		return $copyObj;
+	}
+
+	
+	public function getPeer()
+	{
+		if (self::$peer === null) {
+			self::$peer = new TbluserPeer();
+		}
+		return self::$peer;
+	}
+
+	
+	public function getTblblogcheckinfo(PropelPDO $con = null)
+	{
+
+		if ($this->singleTblblogcheckinfo === null && !$this->isNew()) {
+			$this->singleTblblogcheckinfo = TblblogcheckinfoPeer::retrieveByPK($this->us_id, $con);
+		}
+
+		return $this->singleTblblogcheckinfo;
+	}
+
+	
+	public function setTblblogcheckinfo(Tblblogcheckinfo $v)
+	{
+		$this->singleTblblogcheckinfo = $v;
+
+				if ($v->getTbluser() === null) {
+			$v->setTbluser($this);
+		}
+
+		return $this;
+	}
+
+	
+	public function clearAllReferences($deep = false)
+	{
+		if ($deep) {
+			if ($this->singleTblblogcheckinfo) {
+				$this->singleTblblogcheckinfo->clearAllReferences($deep);
+			}
+		} 
+		$this->singleTblblogcheckinfo = null;
+	}
+
+} 
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/lib/model/om/BaseTbluserPeer.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/lib/model/om/BaseTbluserPeer.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/lib/model/om/BaseTbluserPeer.php	(revision 19)
@@ -0,0 +1,546 @@
+<?php
+
+
+abstract class BaseTbluserPeer {
+
+	
+	const DATABASE_NAME = 'propel';
+
+	
+	const TABLE_NAME = 'tbluser';
+
+	
+	const CLASS_DEFAULT = 'lib.model.Tbluser';
+
+	
+	const NUM_COLUMNS = 26;
+
+	
+	const NUM_LAZY_LOAD_COLUMNS = 0;
+
+	
+	const US_ID = 'tbluser.US_ID';
+
+	
+	const US_USERNAME = 'tbluser.US_USERNAME';
+
+	
+	const US_PASSWORD = 'tbluser.US_PASSWORD';
+
+	
+	const US_FIRSTNAME = 'tbluser.US_FIRSTNAME';
+
+	
+	const US_LASTNAME = 'tbluser.US_LASTNAME';
+
+	
+	const US_SEX = 'tbluser.US_SEX';
+
+	
+	const US_EMAIL = 'tbluser.US_EMAIL';
+
+	
+	const US_PHONE = 'tbluser.US_PHONE';
+
+	
+	const US_ACLGROUP = 'tbluser.US_ACLGROUP';
+
+	
+	const US_SCHOOL = 'tbluser.US_SCHOOL';
+
+	
+	const US_PROVINCE = 'tbluser.US_PROVINCE';
+
+	
+	const US_LASTVISITED = 'tbluser.US_LASTVISITED';
+
+	
+	const US_REGISTERDATE = 'tbluser.US_REGISTERDATE';
+
+	
+	const US_RATING = 'tbluser.US_RATING';
+
+	
+	const US_DOWNLOAD = 'tbluser.US_DOWNLOAD';
+
+	
+	const US_AVATAR = 'tbluser.US_AVATAR';
+
+	
+	const US_STATUS = 'tbluser.US_STATUS';
+
+	
+	const US_KEY = 'tbluser.US_KEY';
+
+	
+	const US_COMPANY = 'tbluser.US_COMPANY';
+
+	
+	const US_SCORE = 'tbluser.US_SCORE';
+
+	
+	const US_POINTPLUS = 'tbluser.US_POINTPLUS';
+
+	
+	const US_CHECKED = 'tbluser.US_CHECKED';
+
+	
+	const US_CHECKINFO = 'tbluser.US_CHECKINFO';
+
+	
+	const US_IDMD5 = 'tbluser.US_IDMD5';
+
+	
+	const US_HOMEPAGE = 'tbluser.US_HOMEPAGE';
+
+	
+	const US_MONEY = 'tbluser.US_MONEY';
+
+	
+	public static $instances = array();
+
+	
+	private static $mapBuilder = null;
+
+	
+	private static $fieldNames = array (
+		BasePeer::TYPE_PHPNAME => array ('UsId', 'UsUsername', 'UsPassword', 'UsFirstname', 'UsLastname', 'UsSex', 'UsEmail', 'UsPhone', 'UsAclgroup', 'UsSchool', 'UsProvince', 'UsLastvisited', 'UsRegisterdate', 'UsRating', 'UsDownload', 'UsAvatar', 'UsStatus', 'UsKey', 'UsCompany', 'UsScore', 'UsPointplus', 'UsChecked', 'UsCheckinfo', 'UsIdmd5', 'UsHomepage', 'UsMoney', ),
+		BasePeer::TYPE_STUDLYPHPNAME => array ('usId', 'usUsername', 'usPassword', 'usFirstname', 'usLastname', 'usSex', 'usEmail', 'usPhone', 'usAclgroup', 'usSchool', 'usProvince', 'usLastvisited', 'usRegisterdate', 'usRating', 'usDownload', 'usAvatar', 'usStatus', 'usKey', 'usCompany', 'usScore', 'usPointplus', 'usChecked', 'usCheckinfo', 'usIdmd5', 'usHomepage', 'usMoney', ),
+		BasePeer::TYPE_COLNAME => array (self::US_ID, self::US_USERNAME, self::US_PASSWORD, self::US_FIRSTNAME, self::US_LASTNAME, self::US_SEX, self::US_EMAIL, self::US_PHONE, self::US_ACLGROUP, self::US_SCHOOL, self::US_PROVINCE, self::US_LASTVISITED, self::US_REGISTERDATE, self::US_RATING, self::US_DOWNLOAD, self::US_AVATAR, self::US_STATUS, self::US_KEY, self::US_COMPANY, self::US_SCORE, self::US_POINTPLUS, self::US_CHECKED, self::US_CHECKINFO, self::US_IDMD5, self::US_HOMEPAGE, self::US_MONEY, ),
+		BasePeer::TYPE_FIELDNAME => array ('us_id', 'us_username', 'us_password', 'us_firstname', 'us_lastname', 'us_sex', 'us_email', 'us_phone', 'us_aclgroup', 'us_school', 'us_province', 'us_lastvisited', 'us_registerdate', 'us_rating', 'us_download', 'us_avatar', 'us_status', 'us_key', 'us_company', 'us_score', 'us_pointplus', 'us_checked', 'us_checkinfo', 'us_idmd5', 'us_homepage', 'us_money', ),
+		BasePeer::TYPE_NUM => array (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, )
+	);
+
+	
+	private static $fieldKeys = array (
+		BasePeer::TYPE_PHPNAME => array ('UsId' => 0, 'UsUsername' => 1, 'UsPassword' => 2, 'UsFirstname' => 3, 'UsLastname' => 4, 'UsSex' => 5, 'UsEmail' => 6, 'UsPhone' => 7, 'UsAclgroup' => 8, 'UsSchool' => 9, 'UsProvince' => 10, 'UsLastvisited' => 11, 'UsRegisterdate' => 12, 'UsRating' => 13, 'UsDownload' => 14, 'UsAvatar' => 15, 'UsStatus' => 16, 'UsKey' => 17, 'UsCompany' => 18, 'UsScore' => 19, 'UsPointplus' => 20, 'UsChecked' => 21, 'UsCheckinfo' => 22, 'UsIdmd5' => 23, 'UsHomepage' => 24, 'UsMoney' => 25, ),
+		BasePeer::TYPE_STUDLYPHPNAME => array ('usId' => 0, 'usUsername' => 1, 'usPassword' => 2, 'usFirstname' => 3, 'usLastname' => 4, 'usSex' => 5, 'usEmail' => 6, 'usPhone' => 7, 'usAclgroup' => 8, 'usSchool' => 9, 'usProvince' => 10, 'usLastvisited' => 11, 'usRegisterdate' => 12, 'usRating' => 13, 'usDownload' => 14, 'usAvatar' => 15, 'usStatus' => 16, 'usKey' => 17, 'usCompany' => 18, 'usScore' => 19, 'usPointplus' => 20, 'usChecked' => 21, 'usCheckinfo' => 22, 'usIdmd5' => 23, 'usHomepage' => 24, 'usMoney' => 25, ),
+		BasePeer::TYPE_COLNAME => array (self::US_ID => 0, self::US_USERNAME => 1, self::US_PASSWORD => 2, self::US_FIRSTNAME => 3, self::US_LASTNAME => 4, self::US_SEX => 5, self::US_EMAIL => 6, self::US_PHONE => 7, self::US_ACLGROUP => 8, self::US_SCHOOL => 9, self::US_PROVINCE => 10, self::US_LASTVISITED => 11, self::US_REGISTERDATE => 12, self::US_RATING => 13, self::US_DOWNLOAD => 14, self::US_AVATAR => 15, self::US_STATUS => 16, self::US_KEY => 17, self::US_COMPANY => 18, self::US_SCORE => 19, self::US_POINTPLUS => 20, self::US_CHECKED => 21, self::US_CHECKINFO => 22, self::US_IDMD5 => 23, self::US_HOMEPAGE => 24, self::US_MONEY => 25, ),
+		BasePeer::TYPE_FIELDNAME => array ('us_id' => 0, 'us_username' => 1, 'us_password' => 2, 'us_firstname' => 3, 'us_lastname' => 4, 'us_sex' => 5, 'us_email' => 6, 'us_phone' => 7, 'us_aclgroup' => 8, 'us_school' => 9, 'us_province' => 10, 'us_lastvisited' => 11, 'us_registerdate' => 12, 'us_rating' => 13, 'us_download' => 14, 'us_avatar' => 15, 'us_status' => 16, 'us_key' => 17, 'us_company' => 18, 'us_score' => 19, 'us_pointplus' => 20, 'us_checked' => 21, 'us_checkinfo' => 22, 'us_idmd5' => 23, 'us_homepage' => 24, 'us_money' => 25, ),
+		BasePeer::TYPE_NUM => array (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, )
+	);
+
+	
+	public static function getMapBuilder()
+	{
+		if (self::$mapBuilder === null) {
+			self::$mapBuilder = new TbluserMapBuilder();
+		}
+		return self::$mapBuilder;
+	}
+	
+	static public function translateFieldName($name, $fromType, $toType)
+	{
+		$toNames = self::getFieldNames($toType);
+		$key = isset(self::$fieldKeys[$fromType][$name]) ? self::$fieldKeys[$fromType][$name] : null;
+		if ($key === null) {
+			throw new PropelException("'$name' could not be found in the field names of type '$fromType'. These are: " . print_r(self::$fieldKeys[$fromType], true));
+		}
+		return $toNames[$key];
+	}
+
+	
+
+	static public function getFieldNames($type = BasePeer::TYPE_PHPNAME)
+	{
+		if (!array_key_exists($type, self::$fieldNames)) {
+			throw new PropelException('Method getFieldNames() expects the parameter $type to be one of the class constants BasePeer::TYPE_PHPNAME, BasePeer::TYPE_STUDLYPHPNAME, BasePeer::TYPE_COLNAME, BasePeer::TYPE_FIELDNAME, BasePeer::TYPE_NUM. ' . $type . ' was given.');
+		}
+		return self::$fieldNames[$type];
+	}
+
+	
+	public static function alias($alias, $column)
+	{
+		return str_replace(TbluserPeer::TABLE_NAME.'.', $alias.'.', $column);
+	}
+
+	
+	public static function addSelectColumns(Criteria $criteria)
+	{
+
+		$criteria->addSelectColumn(TbluserPeer::US_ID);
+
+		$criteria->addSelectColumn(TbluserPeer::US_USERNAME);
+
+		$criteria->addSelectColumn(TbluserPeer::US_PASSWORD);
+
+		$criteria->addSelectColumn(TbluserPeer::US_FIRSTNAME);
+
+		$criteria->addSelectColumn(TbluserPeer::US_LASTNAME);
+
+		$criteria->addSelectColumn(TbluserPeer::US_SEX);
+
+		$criteria->addSelectColumn(TbluserPeer::US_EMAIL);
+
+		$criteria->addSelectColumn(TbluserPeer::US_PHONE);
+
+		$criteria->addSelectColumn(TbluserPeer::US_ACLGROUP);
+
+		$criteria->addSelectColumn(TbluserPeer::US_SCHOOL);
+
+		$criteria->addSelectColumn(TbluserPeer::US_PROVINCE);
+
+		$criteria->addSelectColumn(TbluserPeer::US_LASTVISITED);
+
+		$criteria->addSelectColumn(TbluserPeer::US_REGISTERDATE);
+
+		$criteria->addSelectColumn(TbluserPeer::US_RATING);
+
+		$criteria->addSelectColumn(TbluserPeer::US_DOWNLOAD);
+
+		$criteria->addSelectColumn(TbluserPeer::US_AVATAR);
+
+		$criteria->addSelectColumn(TbluserPeer::US_STATUS);
+
+		$criteria->addSelectColumn(TbluserPeer::US_KEY);
+
+		$criteria->addSelectColumn(TbluserPeer::US_COMPANY);
+
+		$criteria->addSelectColumn(TbluserPeer::US_SCORE);
+
+		$criteria->addSelectColumn(TbluserPeer::US_POINTPLUS);
+
+		$criteria->addSelectColumn(TbluserPeer::US_CHECKED);
+
+		$criteria->addSelectColumn(TbluserPeer::US_CHECKINFO);
+
+		$criteria->addSelectColumn(TbluserPeer::US_IDMD5);
+
+		$criteria->addSelectColumn(TbluserPeer::US_HOMEPAGE);
+
+		$criteria->addSelectColumn(TbluserPeer::US_MONEY);
+
+	}
+
+	
+	public static function doCount(Criteria $criteria, $distinct = false, PropelPDO $con = null)
+	{
+				$criteria = clone $criteria;
+
+								$criteria->setPrimaryTableName(TbluserPeer::TABLE_NAME);
+
+		if ($distinct && !in_array(Criteria::DISTINCT, $criteria->getSelectModifiers())) {
+			$criteria->setDistinct();
+		}
+
+		if (!$criteria->hasSelectClause()) {
+			TbluserPeer::addSelectColumns($criteria);
+		}
+
+		$criteria->clearOrderByColumns(); 		$criteria->setDbName(self::DATABASE_NAME); 
+		if ($con === null) {
+			$con = Propel::getConnection(TbluserPeer::DATABASE_NAME, Propel::CONNECTION_READ);
+		}
+				$stmt = BasePeer::doCount($criteria, $con);
+
+		if ($row = $stmt->fetch(PDO::FETCH_NUM)) {
+			$count = (int) $row[0];
+		} else {
+			$count = 0; 		}
+		$stmt->closeCursor();
+		return $count;
+	}
+	
+	public static function doSelectOne(Criteria $criteria, PropelPDO $con = null)
+	{
+		$critcopy = clone $criteria;
+		$critcopy->setLimit(1);
+		$objects = TbluserPeer::doSelect($critcopy, $con);
+		if ($objects) {
+			return $objects[0];
+		}
+		return null;
+	}
+	
+	public static function doSelect(Criteria $criteria, PropelPDO $con = null)
+	{
+		return TbluserPeer::populateObjects(TbluserPeer::doSelectStmt($criteria, $con));
+	}
+	
+	public static function doSelectStmt(Criteria $criteria, PropelPDO $con = null)
+	{
+		if ($con === null) {
+			$con = Propel::getConnection(TbluserPeer::DATABASE_NAME, Propel::CONNECTION_READ);
+		}
+
+		if (!$criteria->hasSelectClause()) {
+			$criteria = clone $criteria;
+			TbluserPeer::addSelectColumns($criteria);
+		}
+
+				$criteria->setDbName(self::DATABASE_NAME);
+
+				return BasePeer::doSelect($criteria, $con);
+	}
+	
+	public static function addInstanceToPool(Tbluser $obj, $key = null)
+	{
+		if (Propel::isInstancePoolingEnabled()) {
+			if ($key === null) {
+				$key = (string) $obj->getUsId();
+			} 			self::$instances[$key] = $obj;
+		}
+	}
+
+	
+	public static function removeInstanceFromPool($value)
+	{
+		if (Propel::isInstancePoolingEnabled() && $value !== null) {
+			if (is_object($value) && $value instanceof Tbluser) {
+				$key = (string) $value->getUsId();
+			} elseif (is_scalar($value)) {
+								$key = (string) $value;
+			} else {
+				$e = new PropelException("Invalid value passed to removeInstanceFromPool().  Expected primary key or Tbluser object; got " . (is_object($value) ? get_class($value) . ' object.' : var_export($value,true)));
+				throw $e;
+			}
+
+			unset(self::$instances[$key]);
+		}
+	} 
+	
+	public static function getInstanceFromPool($key)
+	{
+		if (Propel::isInstancePoolingEnabled()) {
+			if (isset(self::$instances[$key])) {
+				return self::$instances[$key];
+			}
+		}
+		return null; 	}
+	
+	
+	public static function clearInstancePool()
+	{
+		self::$instances = array();
+	}
+	
+	
+	public static function getPrimaryKeyHashFromRow($row, $startcol = 0)
+	{
+				if ($row[$startcol + 0] === null) {
+			return null;
+		}
+		return (string) $row[$startcol + 0];
+	}
+
+	
+	public static function populateObjects(PDOStatement $stmt)
+	{
+		$results = array();
+	
+				$cls = TbluserPeer::getOMClass();
+		$cls = substr('.'.$cls, strrpos('.'.$cls, '.') + 1);
+				while ($row = $stmt->fetch(PDO::FETCH_NUM)) {
+			$key = TbluserPeer::getPrimaryKeyHashFromRow($row, 0);
+			if (null !== ($obj = TbluserPeer::getInstanceFromPool($key))) {
+																$results[] = $obj;
+			} else {
+		
+				$obj = new $cls();
+				$obj->hydrate($row);
+				$results[] = $obj;
+				TbluserPeer::addInstanceToPool($obj, $key);
+			} 		}
+		$stmt->closeCursor();
+		return $results;
+	}
+	
+	public static function getTableMap()
+	{
+		return Propel::getDatabaseMap(self::DATABASE_NAME)->getTable(self::TABLE_NAME);
+	}
+
+	
+	public static function getOMClass()
+	{
+		return TbluserPeer::CLASS_DEFAULT;
+	}
+
+	
+	public static function doInsert($values, PropelPDO $con = null)
+	{
+		if ($con === null) {
+			$con = Propel::getConnection(TbluserPeer::DATABASE_NAME, Propel::CONNECTION_WRITE);
+		}
+
+		if ($values instanceof Criteria) {
+			$criteria = clone $values; 		} else {
+			$criteria = $values->buildCriteria(); 		}
+
+		if ($criteria->containsKey(TbluserPeer::US_ID) && $criteria->keyContainsValue(TbluserPeer::US_ID) ) {
+			throw new PropelException('Cannot insert a value for auto-increment primary key ('.TbluserPeer::US_ID.')');
+		}
+
+
+				$criteria->setDbName(self::DATABASE_NAME);
+
+		try {
+									$con->beginTransaction();
+			$pk = BasePeer::doInsert($criteria, $con);
+			$con->commit();
+		} catch(PropelException $e) {
+			$con->rollBack();
+			throw $e;
+		}
+
+		return $pk;
+	}
+
+	
+	public static function doUpdate($values, PropelPDO $con = null)
+	{
+		if ($con === null) {
+			$con = Propel::getConnection(TbluserPeer::DATABASE_NAME, Propel::CONNECTION_WRITE);
+		}
+
+		$selectCriteria = new Criteria(self::DATABASE_NAME);
+
+		if ($values instanceof Criteria) {
+			$criteria = clone $values; 
+			$comparison = $criteria->getComparison(TbluserPeer::US_ID);
+			$selectCriteria->add(TbluserPeer::US_ID, $criteria->remove(TbluserPeer::US_ID), $comparison);
+
+		} else { 			$criteria = $values->buildCriteria(); 			$selectCriteria = $values->buildPkeyCriteria(); 		}
+
+				$criteria->setDbName(self::DATABASE_NAME);
+
+		return BasePeer::doUpdate($selectCriteria, $criteria, $con);
+	}
+
+	
+	public static function doDeleteAll($con = null)
+	{
+		if ($con === null) {
+			$con = Propel::getConnection(TbluserPeer::DATABASE_NAME, Propel::CONNECTION_WRITE);
+		}
+		$affectedRows = 0; 		try {
+									$con->beginTransaction();
+			$affectedRows += BasePeer::doDeleteAll(TbluserPeer::TABLE_NAME, $con);
+			$con->commit();
+			return $affectedRows;
+		} catch (PropelException $e) {
+			$con->rollBack();
+			throw $e;
+		}
+	}
+
+	
+	 public static function doDelete($values, PropelPDO $con = null)
+	 {
+		if ($con === null) {
+			$con = Propel::getConnection(TbluserPeer::DATABASE_NAME, Propel::CONNECTION_WRITE);
+		}
+
+		if ($values instanceof Criteria) {
+												TbluserPeer::clearInstancePool();
+
+						$criteria = clone $values;
+		} elseif ($values instanceof Tbluser) {
+						TbluserPeer::removeInstanceFromPool($values);
+						$criteria = $values->buildPkeyCriteria();
+		} else {
+			
+
+
+			$criteria = new Criteria(self::DATABASE_NAME);
+			$criteria->add(TbluserPeer::US_ID, (array) $values, Criteria::IN);
+
+			foreach ((array) $values as $singleval) {
+								TbluserPeer::removeInstanceFromPool($singleval);
+			}
+		}
+
+				$criteria->setDbName(self::DATABASE_NAME);
+
+		$affectedRows = 0; 
+		try {
+									$con->beginTransaction();
+			
+			$affectedRows += BasePeer::doDelete($criteria, $con);
+
+			$con->commit();
+			return $affectedRows;
+		} catch (PropelException $e) {
+			$con->rollBack();
+			throw $e;
+		}
+	}
+
+	
+	public static function doValidate(Tbluser $obj, $cols = null)
+	{
+		$columns = array();
+
+		if ($cols) {
+			$dbMap = Propel::getDatabaseMap(TbluserPeer::DATABASE_NAME);
+			$tableMap = $dbMap->getTable(TbluserPeer::TABLE_NAME);
+
+			if (! is_array($cols)) {
+				$cols = array($cols);
+			}
+
+			foreach ($cols as $colName) {
+				if ($tableMap->containsColumn($colName)) {
+					$get = 'get' . $tableMap->getColumn($colName)->getPhpName();
+					$columns[$colName] = $obj->$get();
+				}
+			}
+		} else {
+
+		}
+
+		$res =  BasePeer::doValidate(TbluserPeer::DATABASE_NAME, TbluserPeer::TABLE_NAME, $columns);
+    if ($res !== true) {
+        $request = sfContext::getInstance()->getRequest();
+        foreach ($res as $failed) {
+            $col = TbluserPeer::translateFieldname($failed->getColumn(), BasePeer::TYPE_COLNAME, BasePeer::TYPE_PHPNAME);
+            $request->setError($col, $failed->getMessage());
+        }
+    }
+
+    return $res;
+	}
+
+	
+	public static function retrieveByPK($pk, PropelPDO $con = null)
+	{
+
+		if (null !== ($obj = TbluserPeer::getInstanceFromPool((string) $pk))) {
+			return $obj;
+		}
+
+		if ($con === null) {
+			$con = Propel::getConnection(TbluserPeer::DATABASE_NAME, Propel::CONNECTION_READ);
+		}
+
+		$criteria = new Criteria(TbluserPeer::DATABASE_NAME);
+		$criteria->add(TbluserPeer::US_ID, $pk);
+
+		$v = TbluserPeer::doSelect($criteria, $con);
+
+		return !empty($v) > 0 ? $v[0] : null;
+	}
+
+	
+	public static function retrieveByPKs($pks, PropelPDO $con = null)
+	{
+		if ($con === null) {
+			$con = Propel::getConnection(TbluserPeer::DATABASE_NAME, Propel::CONNECTION_READ);
+		}
+
+		$objs = null;
+		if (empty($pks)) {
+			$objs = array();
+		} else {
+			$criteria = new Criteria(TbluserPeer::DATABASE_NAME);
+			$criteria->add(TbluserPeer::US_ID, $pks, Criteria::IN);
+			$objs = TbluserPeer::doSelect($criteria, $con);
+		}
+		return $objs;
+	}
+
+} 
+
+Propel::getDatabaseMap(BaseTbluserPeer::DATABASE_NAME)->addTableBuilder(BaseTbluserPeer::TABLE_NAME, BaseTbluserPeer::getMapBuilder());
+
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/log/apiuser.log
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/log/apiuser.log	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/log/apiuser.log	(revision 19)
@@ -0,0 +1,11 @@
+2014-05-07 16:03:32 774c6 127.0.0.1 login from Test, account: thuylinh
+2014-05-07 16:07:19 774c6 127.0.0.1 login from Test, account: thuylinh
+2014-05-07 16:26:26 774c6 127.0.0.1 login from Test, account: thuylinh
+2014-05-07 16:29:03 774c6 127.0.0.1 login from Test, account: thuylinh
+2014-05-07 16:29:04 774c6 127.0.0.1 login from Test, account: thuylinh
+2014-05-07 16:29:05 774c6 127.0.0.1 login from Test, account: thuylinh
+2014-05-07 16:39:59 774c6 127.0.0.1 login from Test, account: thuylinh
+2014-05-07 17:14:31 774c6 127.0.0.1 login from Test, account: thuylinh
+2014-05-07 17:14:34 774c6 127.0.0.1 login from Test, account: thuylinh
+2014-05-09 15:57:01 774c6 127.0.0.1 login from Test, account: thuylinh
+2014-07-07 14:44:45 774c6 127.0.0.1 login from Test, account: thuylinh
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/log/login.log
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/log/login.log	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/log/login.log	(revision 19)
@@ -0,0 +1,11 @@
+2014-05-07 16:03:32 774c6 [659]: 127.0.0.1
+2014-05-07 16:07:19 774c6 [659]: 127.0.0.1
+2014-05-07 16:26:26 774c6 [659]: 127.0.0.1
+2014-05-07 16:29:03 774c6 [659]: 127.0.0.1
+2014-05-07 16:29:04 774c6 [659]: 127.0.0.1
+2014-05-07 16:29:05 774c6 [659]: 127.0.0.1
+2014-05-07 16:39:59 774c6 [659]: 127.0.0.1
+2014-05-07 17:14:31 774c6 [659]: 127.0.0.1
+2014-05-07 17:14:34 774c6 [659]: 127.0.0.1
+2014-05-09 15:57:01 774c6 [659]: 127.0.0.1
+2014-07-07 14:44:45 774c6 [659]: 127.0.0.1
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/LICENSE
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/LICENSE	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/LICENSE	(revision 19)
@@ -0,0 +1,7 @@
+Copyright (c) 2007 Joshua May
+
+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-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/README
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/README	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/README	(revision 19)
@@ -0,0 +1,14 @@
+sfPropel13Plugin
+=========================
+
+Contents
+--------
+
+You will find more information in the wiki page dedicated to sfPropel13: http://www.symfony-project.com/trac/wiki/sfPropel13Plugin
+
+
+License
+-------
+
+For the full copyright and license information, please view the LICENSE
+file that was distributed with this source code.
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/autopackage2.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/autopackage2.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/autopackage2.php	(revision 19)
@@ -0,0 +1,110 @@
+<?php
+/**
+ * script to automate the generation of the
+ * package.xml file.
+ * 
+ * Originally writted by Stephan Schmidt <schst@php-tools.net>
+ *
+ * @author      Joshua May
+ * @package     sfPropel13Plugin
+ */
+
+require_once 'PEAR/PackageFileManager2.php';
+
+/**
+ * Base version
+ */
+$baseVersion = '0.6.0';
+
+/**
+ * current version
+ */
+$version    = $baseVersion;
+$dir        = dirname( __FILE__ );
+
+/**
+ * Current API version
+ */
+$apiVersion = '0.6.0';
+
+/**
+ * current state
+ */
+$state = 'beta';
+
+/**
+ * current API stability
+ */
+$apiStability = 'beta';
+
+/**
+ * release notes
+ */
+$notes = <<<EOT
+--
+EOT;
+
+/**
+ * package description
+ */
+$description = <<<EOT
+sfPropel13Plugin instroduces Propel 1.3 (beta) functionality into symfony 1.0. It *should* work without modifying
+any core libraries, thus offering greater stability (despite being beta, it's now using PDO instead of Creole), and
+immensely improved performance.
+EOT;
+
+$package = new PEAR_PackageFileManager2();
+
+$result = $package->setOptions(array(
+    'filelistgenerator' => 'file',
+    'ignore'            => array('autopackage2.php', 'package.xml', '.svn'),
+    'simpleoutput'      => true,
+    'baseinstalldir'    => '/',
+    'packagedirectory'  => $dir,
+    'dir_roles'         => array(
+                                 'docs' => 'doc',
+                                 'examples' => 'doc',
+                                 'tests' => 'test',
+                                 )
+    ));
+if (PEAR::isError($result)) {
+    echo $result->getMessage();
+    die();
+}
+
+$package->setPackage('sfPropel13Plugin');
+$package->setSummary('Propel 1.3 (beta) functionality in symfony 1.0');
+$package->setDescription($description);
+
+$package->setChannel('pear.symfony-project.com');
+$package->setAPIVersion($apiVersion);
+$package->setReleaseVersion($version);
+$package->setReleaseStability($state);
+$package->setAPIStability($apiStability);
+$package->setNotes($notes);
+$package->setPackageType('php');
+$package->setLicense('MIT License', 'http://www.symfony-project.com/license');
+
+$package->addMaintainer('lead', 'notjosh', 'Joshua May', 'josh@notjosh.com', 'yes');
+
+$package->setPhpDep('5.2.0');
+$package->setPearinstallerDep('1.4.1');
+
+$package->addPackageDepWithChannel(
+	'required',
+    'symfony',
+	'pear.symfony-project.com',
+    '1.0.0',
+	'1.1.0',
+	false,
+	'1.1.0');
+
+
+$package->generateContents();
+
+$result = $package->writePackageFile();
+
+if (PEAR::isError($result)) {
+    echo $result->getMessage();
+    die();
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/config/config.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/config/config.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/config/config.php	(revision 19)
@@ -0,0 +1,2 @@
+<?php
+set_include_path(realpath(dirname(__FILE__).'/../lib/vendor') . PATH_SEPARATOR . get_include_path());
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/data/generator/sfPropelAdmin/default/skeleton/actions/actions.class.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/data/generator/sfPropelAdmin/default/skeleton/actions/actions.class.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/data/generator/sfPropelAdmin/default/skeleton/actions/actions.class.php	(revision 19)
@@ -0,0 +1,13 @@
+<?php
+
+/**
+ * ##MODULE_NAME## actions.
+ *
+ * @package    ##PROJECT_NAME##
+ * @subpackage ##MODULE_NAME##
+ * @author     ##AUTHOR_NAME##
+ * @version    SVN: $Id: actions.class.php 2288 2006-10-02 15:22:13Z fabien $
+ */
+class ##MODULE_NAME##Actions extends auto##MODULE_NAME##Actions
+{
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/data/generator/sfPropelAdmin/default/skeleton/config/generator.yml
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/data/generator/sfPropelAdmin/default/skeleton/config/generator.yml	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/data/generator/sfPropelAdmin/default/skeleton/config/generator.yml	(revision 19)
@@ -0,0 +1,5 @@
+generator:
+  class:              sfPropel13AdminGenerator
+  param:
+    model_class:      ##MODEL_CLASS##
+    theme:            ##THEME##
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/data/generator/sfPropelAdmin/default/template/actions/actions.class.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/data/generator/sfPropelAdmin/default/template/actions/actions.class.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/data/generator/sfPropelAdmin/default/template/actions/actions.class.php	(revision 19)
@@ -0,0 +1,484 @@
+[?php
+
+/**
+ * <?php echo $this->getGeneratedModuleName() ?> actions.
+ *
+ * @package    ##PROJECT_NAME##
+ * @subpackage <?php echo $this->getGeneratedModuleName() ?>
+
+ * @author     Fabien Potencier <fabien.potencier@symfony-project.com>
+ * @version    SVN: $Id: actions.class.php 5102 2007-09-15 07:47:25Z fabien $
+ */
+class <?php echo $this->getGeneratedModuleName() ?>Actions extends sfActions
+{
+  public function executeIndex()
+  {
+    return $this->forward('<?php echo $this->getModuleName() ?>', 'list');
+  }
+
+  public function executeList()
+  {
+    $this->processSort();
+
+    $this->processFilters();
+
+<?php if ($this->getParameterValue('list.filters')): ?>
+    $this->filters = $this->getUser()->getAttributeHolder()->getAll('sf_admin/<?php echo $this->getSingularName() ?>/filters');
+<?php endif ?>
+
+    // pager
+    $this->pager = new sfPropelPager('<?php echo $this->getClassName() ?>', <?php echo $this->getParameterValue('list.max_per_page', 20) ?>);
+    $c = new Criteria();
+    $this->addSortCriteria($c);
+    $this->addFiltersCriteria($c);
+    $this->pager->setCriteria($c);
+    $this->pager->setPage($this->getRequestParameter('page', 1));
+<?php if ($this->getParameterValue('list.peer_method')): ?>
+    $this->pager->setPeerMethod('<?php echo $this->getParameterValue('list.peer_method') ?>');
+<?php endif ?>
+<?php if ($this->getParameterValue('list.peer_count_method')): ?>
+    $this->pager->setPeerCountMethod('<?php echo $this->getParameterValue('list.peer_count_method') ?>');
+<?php endif ?>
+    $this->pager->init();
+  }
+
+  public function executeCreate()
+  {
+    return $this->forward('<?php echo $this->getModuleName() ?>', 'edit');
+  }
+
+  public function executeSave()
+  {
+    return $this->forward('<?php echo $this->getModuleName() ?>', 'edit');
+  }
+
+<?php $listActions = $this->getParameterValue('list.batch_actions') ?>
+<?php if (null !== $listActions): ?>
+  public function executeBatchAction()
+  {
+    $action = $this->getRequestParameter('sf_admin_batch_action');
+    switch($action)
+    {
+<?php foreach ((array) $listActions as $actionName => $params): ?>
+<?php
+// default values
+if ($actionName[0] == '_')
+{
+  $actionName = substr($actionName, 1);
+  $name       = $actionName;
+  $action     = $actionName;
+}
+else
+{
+  $name   = $actionName;
+  $action = isset($params['action']) ? $params['action'] : sfInflector::camelize($actionName);
+}
+?>
+      case "<?php echo $name ?>":
+        $this->forward('<?php echo $this->getModuleName() ?>', '<?php echo $action ?>');
+        break;
+<?php endforeach; ?>
+    }
+
+    return $this->redirect('<?php echo $this->getModuleName() ?>/list');
+  }
+<?php endif; ?>
+
+  public function executeDeleteSelected()
+  {
+    $this->selectedItems = $this->getRequestParameter('sf_admin_batch_selection', array());
+
+    try
+    {
+      <?php echo $this->getClassName() ?>Peer::doDelete($this->selectedItems);
+    }
+    catch (PropelException $e)
+    {
+      $this->getRequest()->setError('delete', 'Could not delete the selected <?php echo sfInflector::humanize($this->getPluralName()) ?>. Make sure they do not have any associated items.');
+      return $this->forward('<?php echo $this->getModuleName() ?>', 'list');
+    }
+
+    return $this->redirect('<?php echo $this->getModuleName() ?>/list');
+  }
+
+  public function executeEdit()
+  {
+    $this-><?php echo $this->getSingularName() ?> = $this->get<?php echo $this->getClassName() ?>OrCreate();
+
+    if ($this->getRequest()->getMethod() == sfRequest::POST)
+    {
+      $this->update<?php echo $this->getClassName() ?>FromRequest();
+
+      $this->save<?php echo $this->getClassName() ?>($this-><?php echo $this->getSingularName() ?>);
+
+      $this->setFlash('notice', 'Your modifications have been saved');
+
+      if ($this->getRequestParameter('save_and_add'))
+      {
+        return $this->redirect('<?php echo $this->getModuleName() ?>/create');
+      }
+      else if ($this->getRequestParameter('save_and_list'))
+      {
+        return $this->redirect('<?php echo $this->getModuleName() ?>/list');
+      }
+      else
+      {
+        return $this->redirect('<?php echo $this->getModuleName() ?>/edit?<?php echo $this->getPrimaryKeyUrlParams('this->') ?>);
+      }
+    }
+    else
+    {
+      $this->labels = $this->getLabels();
+    }
+  }
+
+  public function executeDelete()
+  {
+    $this-><?php echo $this->getSingularName() ?> = <?php echo $this->getClassName() ?>Peer::retrieveByPk(<?php echo $this->getRetrieveByPkParamsForAction(40) ?>);
+    $this->forward404Unless($this-><?php echo $this->getSingularName() ?>);
+
+    try
+    {
+      $this->delete<?php echo $this->getClassName() ?>($this-><?php echo $this->getSingularName() ?>);
+    }
+    catch (PropelException $e)
+    {
+      $this->getRequest()->setError('delete', 'Could not delete the selected <?php echo sfInflector::humanize($this->getSingularName()) ?>. Make sure it does not have any associated items.');
+      return $this->forward('<?php echo $this->getModuleName() ?>', 'list');
+    }
+
+<?php foreach ($this->getColumnCategories('edit.display') as $category): ?>
+<?php foreach ($this->getColumns('edit.display', $category) as $name => $column): ?>
+<?php $input_type = $this->getParameterValue('edit.fields.'.$column->getName().'.type') ?>
+<?php if ($input_type == 'admin_input_file_tag'): ?>
+<?php $upload_dir = $this->replaceConstants($this->getParameterValue('edit.fields.'.$column->getName().'.upload_dir')) ?>
+      $currentFile = sfConfig::get('sf_upload_dir')."/<?php echo $upload_dir ?>/".$this-><?php echo $this->getSingularName() ?>->get<?php echo $column->getPhpName() ?>();
+      if (is_file($currentFile))
+      {
+        unlink($currentFile);
+      }
+
+<?php endif; ?>
+<?php endforeach; ?>
+<?php endforeach; ?>
+    return $this->redirect('<?php echo $this->getModuleName() ?>/list');
+  }
+
+  public function handleErrorEdit()
+  {
+    $this->preExecute();
+    $this-><?php echo $this->getSingularName() ?> = $this->get<?php echo $this->getClassName() ?>OrCreate();
+    $this->update<?php echo $this->getClassName() ?>FromRequest();
+
+    $this->labels = $this->getLabels();
+
+    return sfView::SUCCESS;
+  }
+
+  protected function save<?php echo $this->getClassName() ?>($<?php echo $this->getSingularName() ?>)
+  {
+    $<?php echo $this->getSingularName() ?>->save();
+
+<?php foreach ($this->getColumnCategories('edit.display') as $category): ?>
+<?php foreach ($this->getColumns('edit.display', $category) as $name => $column): $type = $column->getType(); ?>
+<?php $name = $column->getName() ?>
+<?php if ($column->isPrimaryKey()) continue ?>
+<?php $credentials = $this->getParameterValue('edit.fields.'.$column->getName().'.credentials') ?>
+<?php $input_type = $this->getParameterValue('edit.fields.'.$column->getName().'.type') ?>
+<?php
+
+$user_params = $this->getParameterValue('edit.fields.'.$column->getName().'.params');
+$user_params = is_array($user_params) ? $user_params : sfToolkit::stringToArray($user_params);
+$through_class = isset($user_params['through_class']) ? $user_params['through_class'] : '';
+
+?>
+<?php if ($through_class): ?>
+<?php
+
+$class = $this->getClassName();
+$related_class = sfPropelManyToMany::getRelatedClass($class, $through_class);
+$related_table = constant($related_class.'Peer::TABLE_NAME');
+$middle_table = constant($through_class.'Peer::TABLE_NAME');
+$this_table = constant($class.'Peer::TABLE_NAME');
+
+$related_column = sfPropelManyToMany::getRelatedColumn($class, $through_class);
+$column = sfPropelManyToMany::getColumn($class, $through_class);
+
+?>
+<?php if ($input_type == 'admin_double_list' || $input_type == 'admin_check_list' || $input_type == 'admin_select_list'): ?>
+<?php if ($credentials): $credentials = str_replace("\n", ' ', var_export($credentials, true)) ?>
+    if ($this->getUser()->hasCredential(<?php echo $credentials ?>))
+    {
+<?php endif; ?>
+      // Update many-to-many for "<?php echo $name ?>"
+      $c = new Criteria();
+      $c->add(<?php echo $through_class ?>Peer::<?php echo strtoupper($column->getColumnName()) ?>, $<?php echo $this->getSingularName() ?>->getPrimaryKey());
+      <?php echo $through_class ?>Peer::doDelete($c);
+
+      $ids = $this->getRequestParameter('associated_<?php echo $name ?>');
+      if (is_array($ids))
+      {
+        foreach ($ids as $id)
+        {
+          $<?php echo ucfirst($through_class) ?> = new <?php echo $through_class ?>();
+          $<?php echo ucfirst($through_class) ?>->set<?php echo $column->getPhpName() ?>($<?php echo $this->getSingularName() ?>->getPrimaryKey());
+          $<?php echo ucfirst($through_class) ?>->set<?php echo $related_column->getPhpName() ?>($id);
+          $<?php echo ucfirst($through_class) ?>->save();
+        }
+      }
+
+<?php if ($credentials): ?>
+    }
+<?php endif; ?>
+<?php endif; ?>
+<?php endif; ?>
+<?php endforeach; ?>
+<?php endforeach; ?>
+  }
+
+  protected function delete<?php echo $this->getClassName() ?>($<?php echo $this->getSingularName() ?>)
+  {
+    $<?php echo $this->getSingularName() ?>->delete();
+  }
+
+  protected function update<?php echo $this->getClassName() ?>FromRequest()
+  {
+    $<?php echo $this->getSingularName() ?> = $this->getRequestParameter('<?php echo $this->getSingularName() ?>');
+
+<?php foreach ($this->getColumnCategories('edit.display') as $category): ?>
+<?php foreach ($this->getColumns('edit.display', $category) as $name => $column): $type = $column->getType(); ?>
+<?php $name = $column->getName() ?>
+<?php if ($column->isPrimaryKey()) continue ?>
+<?php $credentials = $this->getParameterValue('edit.fields.'.$column->getName().'.credentials') ?>
+<?php $input_type = $this->getParameterValue('edit.fields.'.$column->getName().'.type') ?>
+<?php if ($credentials): $credentials = str_replace("\n", ' ', var_export($credentials, true)) ?>
+    if ($this->getUser()->hasCredential(<?php echo $credentials ?>))
+    {
+<?php endif; ?>
+<?php if ($input_type == 'admin_input_file_tag'): ?>
+<?php $upload_dir = $this->replaceConstants($this->getParameterValue('edit.fields.'.$column->getName().'.upload_dir')) ?>
+    $currentFile = sfConfig::get('sf_upload_dir')."/<?php echo $upload_dir ?>/".$this-><?php echo $this->getSingularName() ?>->get<?php echo $column->getPhpName() ?>();
+    if (!$this->getRequest()->hasErrors() && isset($<?php echo $this->getSingularName() ?>['<?php echo $name ?>_remove']))
+    {
+      $this-><?php echo $this->getSingularName() ?>->set<?php echo $column->getPhpName() ?>('');
+      if (is_file($currentFile))
+      {
+        unlink($currentFile);
+      }
+    }
+
+    if (!$this->getRequest()->hasErrors() && $this->getRequest()->getFileSize('<?php echo $this->getSingularName() ?>[<?php echo $name ?>]'))
+    {
+<?php elseif ($type != PropelColumnTypes::BOOLEAN): ?>
+    if (isset($<?php echo $this->getSingularName() ?>['<?php echo $name ?>']))
+    {
+<?php endif; ?>
+<?php if ($input_type == 'admin_input_file_tag'): ?>
+<?php if ($this->getParameterValue('edit.fields.'.$column->getName().'.filename')): ?>
+      $fileName = "<?php echo str_replace('"', '\\"', $this->replaceConstants($this->getParameterValue('edit.fields.'.$column->getName().'.filename'))) ?>";
+<?php else: ?>
+      $fileName = md5($this->getRequest()->getFileName('<?php echo $this->getSingularName() ?>[<?php echo $name ?>]').time().rand(0, 99999));
+<?php endif ?>
+      $ext = $this->getRequest()->getFileExtension('<?php echo $this->getSingularName() ?>[<?php echo $name ?>]');
+      if (is_file($currentFile))
+      {
+        unlink($currentFile);
+      }
+      $this->getRequest()->moveFile('<?php echo $this->getSingularName() ?>[<?php echo $name ?>]', sfConfig::get('sf_upload_dir')."/<?php echo $upload_dir ?>/".$fileName.$ext);
+      $this-><?php echo $this->getSingularName() ?>->set<?php echo $column->getPhpName() ?>($fileName.$ext);
+<?php elseif ($type == PropelColumnTypes::DATE || $type == PropelColumnTypes::TIMESTAMP): ?>
+      if ($<?php echo $this->getSingularName() ?>['<?php echo $name ?>'])
+      {
+        try
+        {
+          $dateFormat = new sfDateFormat($this->getUser()->getCulture());
+          <?php $inputPattern  = $type == PropelColumnTypes::DATE ? 'd' : 'g'; ?>
+          <?php $outputPattern = $type == PropelColumnTypes::DATE ? 'i' : 'I'; ?>
+          if (!is_array($<?php echo $this->getSingularName() ?>['<?php echo $name ?>']))
+          {
+            $value = $dateFormat->format($<?php echo $this->getSingularName() ?>['<?php echo $name ?>'], '<?php echo $outputPattern ?>', $dateFormat->getInputPattern('<?php echo $inputPattern ?>'));
+          }
+          else
+          {
+            $value_array = $<?php echo $this->getSingularName() ?>['<?php echo $name ?>'];
+            $value = $value_array['year'].'-'.$value_array['month'].'-'.$value_array['day'].(isset($value_array['hour']) ? ' '.$value_array['hour'].':'.$value_array['minute'].(isset($value_array['second']) ? ':'.$value_array['second'] : '') : '');
+          }
+          $this-><?php echo $this->getSingularName() ?>->set<?php echo $column->getPhpName() ?>($value);
+        }
+        catch (sfException $e)
+        {
+          // not a date
+        }
+      }
+      else
+      {
+        $this-><?php echo $this->getSingularName() ?>->set<?php echo $column->getPhpName() ?>(null);
+      }
+<?php elseif ($type == PropelColumnTypes::BOOLEAN): ?>
+    $this-><?php echo $this->getSingularName() ?>->set<?php echo $column->getPhpName() ?>(isset($<?php echo $this->getSingularName() ?>['<?php echo $name ?>']) ? $<?php echo $this->getSingularName() ?>['<?php echo $name ?>'] : 0);
+<?php elseif ($column->isForeignKey()): ?>
+    $this-><?php echo $this->getSingularName() ?>->set<?php echo $column->getPhpName() ?>($<?php echo $this->getSingularName() ?>['<?php echo $name ?>'] ? $<?php echo $this->getSingularName() ?>['<?php echo $name ?>'] : null);
+<?php else: ?>
+      $this-><?php echo $this->getSingularName() ?>->set<?php echo $column->getPhpName() ?>($<?php echo $this->getSingularName() ?>['<?php echo $name ?>']);
+<?php endif; ?>
+<?php if ($type != PropelColumnTypes::BOOLEAN): ?>
+    }
+<?php endif; ?>
+<?php if ($credentials): ?>
+      }
+<?php endif; ?>
+<?php endforeach; ?>
+<?php endforeach; ?>
+  }
+
+  protected function get<?php echo $this->getClassName() ?>OrCreate(<?php echo $this->getMethodParamsForGetOrCreate() ?>)
+  {
+    if (<?php echo $this->getTestPksForGetOrCreate() ?>)
+    {
+      $<?php echo $this->getSingularName() ?> = new <?php echo $this->getClassName() ?>();
+    }
+    else
+    {
+      $<?php echo $this->getSingularName() ?> = <?php echo $this->getClassName() ?>Peer::retrieveByPk(<?php echo $this->getRetrieveByPkParamsForGetOrCreate() ?>);
+
+      $this->forward404Unless($<?php echo $this->getSingularName() ?>);
+    }
+
+    return $<?php echo $this->getSingularName() ?>;
+  }
+
+  protected function processFilters()
+  {
+<?php if ($this->getParameterValue('list.filters')): ?>
+    if ($this->getRequest()->hasParameter('filter'))
+    {
+      $filters = $this->getRequestParameter('filters');
+<?php foreach ($this->getColumns('list.filters') as $column): $type = $column->getType() ?>
+<?php if ($type == PropelColumnTypes::DATE || $type == PropelColumnTypes::TIMESTAMP): ?>
+      if (isset($filters['<?php echo $column->getName() ?>']['from']) && $filters['<?php echo $column->getName() ?>']['from'] !== '')
+      {
+        $filters['<?php echo $column->getName() ?>']['from'] = $this->getContext()->getI18N()->getTimestampForCulture($filters['<?php echo $column->getName() ?>']['from'], $this->getUser()->getCulture());
+      }
+      if (isset($filters['<?php echo $column->getName() ?>']['to']) && $filters['<?php echo $column->getName() ?>']['to'] !== '')
+      {
+        $filters['<?php echo $column->getName() ?>']['to'] = $this->getContext()->getI18N()->getTimestampForCulture($filters['<?php echo $column->getName() ?>']['to'], $this->getUser()->getCulture());
+      }
+<?php endif; ?>
+<?php endforeach; ?>
+
+      $this->getUser()->getAttributeHolder()->removeNamespace('sf_admin/<?php echo $this->getSingularName() ?>/filters');
+      $this->getUser()->getAttributeHolder()->add($filters, 'sf_admin/<?php echo $this->getSingularName() ?>/filters');
+    }
+<?php endif; ?>
+  }
+
+  protected function processSort()
+  {
+    if ($this->getRequestParameter('sort'))
+    {
+      $this->getUser()->setAttribute('sort', $this->getRequestParameter('sort'), 'sf_admin/<?php echo $this->getSingularName() ?>/sort');
+      $this->getUser()->setAttribute('type', $this->getRequestParameter('type', 'asc'), 'sf_admin/<?php echo $this->getSingularName() ?>/sort');
+    }
+
+    if (!$this->getUser()->getAttribute('sort', null, 'sf_admin/<?php echo $this->getSingularName() ?>/sort'))
+    {
+<?php if ($sort = $this->getParameterValue('list.sort')): ?>
+<?php if (is_array($sort)): ?>
+      $this->getUser()->setAttribute('sort', '<?php echo $sort[0] ?>', 'sf_admin/<?php echo $this->getSingularName() ?>/sort');
+      $this->getUser()->setAttribute('type', '<?php echo $sort[1] ?>', 'sf_admin/<?php echo $this->getSingularName() ?>/sort');
+<?php else: ?>
+      $this->getUser()->setAttribute('sort', '<?php echo $sort ?>', 'sf_admin/<?php echo $this->getSingularName() ?>/sort');
+      $this->getUser()->setAttribute('type', 'asc', 'sf_admin/<?php echo $this->getSingularName() ?>/sort');
+<?php endif; ?>
+<?php endif; ?>
+    }
+  }
+
+  protected function addFiltersCriteria($c)
+  {
+<?php if ($this->getParameterValue('list.filters')): ?>
+<?php foreach ($this->getColumns('list.filters') as $column): $type = $column->getType() ?>
+<?php if (($column->isPartial() || $column->isComponent()) && $this->getParameterValue('list.fields.'.$column->getName().'.filter_criteria_disabled')) continue ?>
+    if (isset($this->filters['<?php echo $column->getName() ?>_is_empty']))
+    {
+      $criterion = $c->getNewCriterion(<?php echo $this->getPeerClassName() ?>::<?php echo strtoupper($column->getName()) ?>, '');
+      $criterion->addOr($c->getNewCriterion(<?php echo $this->getPeerClassName() ?>::<?php echo strtoupper($column->getName()) ?>, null, Criteria::ISNULL));
+      $c->add($criterion);
+    }
+<?php if ($type == PropelColumnTypes::DATE || $type == PropelColumnTypes::TIMESTAMP): ?>
+    else if (isset($this->filters['<?php echo $column->getName() ?>']))
+    {
+      if (isset($this->filters['<?php echo $column->getName() ?>']['from']) && $this->filters['<?php echo $column->getName() ?>']['from'] !== '')
+      {
+<?php if ($type == PropelColumnTypes::DATE): ?>
+        $criterion = $c->getNewCriterion(<?php echo $this->getPeerClassName() ?>::<?php echo strtoupper($column->getName()) ?>, date('Y-m-d', $this->filters['<?php echo $column->getName() ?>']['from']), Criteria::GREATER_EQUAL);
+<?php else: ?>
+        $criterion = $c->getNewCriterion(<?php echo $this->getPeerClassName() ?>::<?php echo strtoupper($column->getName()) ?>, $this->filters['<?php echo $column->getName() ?>']['from'], Criteria::GREATER_EQUAL);
+<?php endif; ?>
+      }
+      if (isset($this->filters['<?php echo $column->getName() ?>']['to']) && $this->filters['<?php echo $column->getName() ?>']['to'] !== '')
+      {
+        if (isset($criterion))
+        {
+<?php if ($type == PropelColumnTypes::DATE): ?>
+          $criterion->addAnd($c->getNewCriterion(<?php echo $this->getPeerClassName() ?>::<?php echo strtoupper($column->getName()) ?>, date('Y-m-d', $this->filters['<?php echo $column->getName() ?>']['to']), Criteria::LESS_EQUAL));
+<?php else: ?>
+          $criterion->addAnd($c->getNewCriterion(<?php echo $this->getPeerClassName() ?>::<?php echo strtoupper($column->getName()) ?>, $this->filters['<?php echo $column->getName() ?>']['to'], Criteria::LESS_EQUAL));
+<?php endif; ?>
+        }
+        else
+        {
+<?php if ($type == PropelColumnTypes::DATE): ?>
+          $criterion = $c->getNewCriterion(<?php echo $this->getPeerClassName() ?>::<?php echo strtoupper($column->getName()) ?>, date('Y-m-d', $this->filters['<?php echo $column->getName() ?>']['to']), Criteria::LESS_EQUAL);
+<?php else: ?>
+          $criterion = $c->getNewCriterion(<?php echo $this->getPeerClassName() ?>::<?php echo strtoupper($column->getName()) ?>, $this->filters['<?php echo $column->getName() ?>']['to'], Criteria::LESS_EQUAL);
+<?php endif; ?>
+        }
+      }
+
+      if (isset($criterion))
+      {
+        $c->add($criterion);
+      }
+    }
+<?php else: ?>
+    else if (isset($this->filters['<?php echo $column->getName() ?>']) && $this->filters['<?php echo $column->getName() ?>'] !== '')
+    {
+<?php if ($type == PropelColumnTypes::CHAR || $type == PropelColumnTypes::VARCHAR || $type == PropelColumnTypes::LONGVARCHAR): ?>
+      $c->add(<?php echo $this->getPeerClassName() ?>::<?php echo strtoupper($column->getName()) ?>, strtr($this->filters['<?php echo $column->getName() ?>'], '*', '%'), Criteria::LIKE);
+<?php else: ?>
+      $c->add(<?php echo $this->getPeerClassName() ?>::<?php echo strtoupper($column->getName()) ?>, $this->filters['<?php echo $column->getName() ?>']);
+<?php endif; ?>
+    }
+<?php endif; ?>
+<?php endforeach; ?>
+<?php endif; ?>
+  }
+
+  protected function addSortCriteria($c)
+  {
+    if ($sort_column = $this->getUser()->getAttribute('sort', null, 'sf_admin/<?php echo $this->getSingularName() ?>/sort'))
+    {
+      $sort_column = <?php echo $this->getClassName() ?>Peer::translateFieldName($sort_column, BasePeer::TYPE_FIELDNAME, BasePeer::TYPE_COLNAME);
+      if ($this->getUser()->getAttribute('type', null, 'sf_admin/<?php echo $this->getSingularName() ?>/sort') == 'asc')
+      {
+        $c->addAscendingOrderByColumn($sort_column);
+      }
+      else
+      {
+        $c->addDescendingOrderByColumn($sort_column);
+      }
+    }
+  }
+
+  protected function getLabels()
+  {
+    return array(
+<?php foreach ($this->getColumnCategories('edit.display') as $category): ?>
+<?php foreach ($this->getColumns('edit.display', $category) as $name => $column): ?>
+      '<?php echo $this->getSingularName() ?>{<?php echo $column->getName() ?>}' => '<?php $label_name = str_replace("'", "\\'", $this->getParameterValue('edit.fields.'.$column->getName().'.name')); echo $label_name ?><?php if ($label_name): ?>:<?php endif ?>',
+<?php endforeach; ?>
+<?php endforeach; ?>
+    );
+  }
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/data/generator/sfPropelAdmin/default/template/templates/_edit_actions.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/data/generator/sfPropelAdmin/default/template/templates/_edit_actions.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/data/generator/sfPropelAdmin/default/template/templates/_edit_actions.php	(revision 19)
@@ -0,0 +1,13 @@
+<ul class="sf_admin_actions">
+<?php $editActions = $this->getParameterValue('edit.actions') ?>
+<?php if (null !== $editActions): ?>
+<?php foreach ((array) $editActions as $actionName => $params): ?>
+  <?php if ($actionName == '_delete') continue ?>
+  <?php echo $this->addCredentialCondition($this->getButtonToAction($actionName, $params, true), $params) ?>
+<?php endforeach; ?>
+<?php else: ?>
+  <?php echo $this->getButtonToAction('_list', array(), true) ?>
+  <?php echo $this->getButtonToAction('_save', array(), true) ?>
+  <?php echo $this->getButtonToAction('_save_and_add', array(), true) ?>
+<?php endif; ?>
+</ul>
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/data/generator/sfPropelAdmin/default/template/templates/_edit_form.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/data/generator/sfPropelAdmin/default/template/templates/_edit_form.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/data/generator/sfPropelAdmin/default/template/templates/_edit_form.php	(revision 19)
@@ -0,0 +1,86 @@
+[?php echo form_tag('<?php echo $this->getModuleName() ?>/save', array(
+  'id'        => 'sf_admin_edit_form',
+  'name'      => 'sf_admin_edit_form',
+  'multipart' => true,
+<?php foreach ($this->getColumnCategories('edit.display') as $category): ?>
+<?php foreach ($this->getColumns('edit.display', $category) as $name => $column): ?>
+<?php if (false !== strpos($this->getParameterValue('edit.fields.'.$column->getName().'.type'), 'admin_double_list')): ?>
+  'onsubmit'  => 'double_list_submit(); return true;'
+<?php break 2; ?>
+<?php endif; ?>
+<?php endforeach; ?>
+<?php endforeach; ?>
+)) ?]
+
+<?php foreach ($this->getPrimaryKey() as $pk): ?>
+[?php echo object_input_hidden_tag($<?php echo $this->getSingularName() ?>, 'get<?php echo $pk->getPhpName() ?>') ?]
+<?php endforeach; ?>
+
+<?php $first = true ?>
+<?php foreach ($this->getColumnCategories('edit.display') as $category): ?>
+<?php
+  if ($category[0] == '-')
+  {
+    $category_name = substr($category, 1);
+    $collapse = true;
+
+    if ($first)
+    {
+      $first = false;
+      echo "[?php use_javascript(sfConfig::get('sf_prototype_web_dir').'/js/prototype') ?]\n";
+      echo "[?php use_javascript(sfConfig::get('sf_admin_web_dir').'/js/collapse') ?]\n";
+    }
+  }
+  else
+  {
+    $category_name = $category;
+    $collapse = false;
+  }
+?>
+<fieldset id="sf_fieldset_<?php echo preg_replace('/[^a-z0-9_]/', '_', strtolower($category_name)) ?>" class="<?php if ($collapse): ?> collapse<?php endif; ?>">
+<?php if ($category != 'NONE'): ?><h2>[?php echo __('<?php echo $category_name ?>') ?]</h2>
+
+<?php endif; ?>
+
+<?php $hides = $this->getParameterValue('edit.hide', array()) ?>
+<?php foreach ($this->getColumns('edit.display', $category) as $name => $column): ?>
+<?php if (in_array($column->getName(), $hides)) continue ?>
+<?php if ($column->isPrimaryKey()) continue ?>
+<?php $credentials = $this->getParameterValue('edit.fields.'.$column->getName().'.credentials') ?>
+<?php if ($credentials): $credentials = str_replace("\n", ' ', var_export($credentials, true)) ?>
+    [?php if ($sf_user->hasCredential(<?php echo $credentials ?>)): ?]
+<?php endif; ?>
+<div class="form-row">
+  [?php echo label_for('<?php echo $this->getParameterValue("edit.fields.".$column->getName().".label_for", $this->getSingularName()."[".$column->getName()."]") ?>', __($labels['<?php echo $this->getSingularName() ?>{<?php echo $column->getName() ?>}']), '<?php if ($column->isNotNull()): ?>class="required" <?php endif; ?>') ?]
+  <div class="content[?php if ($sf_request->hasError('<?php echo $this->getSingularName() ?>{<?php echo $column->getName() ?>}')): ?] form-error[?php endif; ?]">
+  [?php if ($sf_request->hasError('<?php echo $this->getSingularName() ?>{<?php echo $column->getName() ?>}')): ?]
+    [?php echo form_error('<?php echo $this->getSingularName() ?>{<?php echo $column->getName() ?>}', array('class' => 'form-error-msg')) ?]
+  [?php endif; ?]
+
+  [?php $value = <?php echo $this->getColumnEditTag($column); ?>; echo $value ? $value : '&nbsp;' ?]
+  <?php echo $this->getHelp($column, 'edit') ?>
+  </div>
+</div>
+<?php if ($credentials): ?>
+    [?php endif; ?]
+<?php endif; ?>
+
+<?php endforeach; ?>
+</fieldset>
+<?php endforeach; ?>
+
+[?php include_partial('edit_actions', array('<?php echo $this->getSingularName() ?>' => $<?php echo $this->getSingularName() ?>)) ?]
+
+</form>
+
+<ul class="sf_admin_actions">
+<?php
+/*
+ * WARNING: delete is a form, it must be outside the main form
+ */
+ $editActions = $this->getParameterValue('edit.actions');
+?>
+  <?php if (null === $editActions || (null !== $editActions && array_key_exists('_delete', $editActions))): ?>
+    <?php echo $this->addCredentialCondition($this->getButtonToAction('_delete', $editActions['_delete'], true), $editActions['_delete']) ?>
+  <?php endif; ?>
+</ul>
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/data/generator/sfPropelAdmin/default/template/templates/_edit_messages.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/data/generator/sfPropelAdmin/default/template/templates/_edit_messages.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/data/generator/sfPropelAdmin/default/template/templates/_edit_messages.php	(revision 19)
@@ -0,0 +1,15 @@
+[?php if ($sf_request->hasErrors()): ?]
+<div class="form-errors">
+<h2>[?php echo __('There are some errors that prevent the form to validate') ?]</h2>
+<dl>
+[?php foreach ($sf_request->getErrorNames() as $name): ?]
+  <dt>[?php echo __($labels[$name]) ?]</dt>
+  <dd>[?php echo __($sf_request->getError($name)) ?]</dd>
+[?php endforeach; ?]
+</dl>
+</div>
+[?php elseif ($sf_flash->has('notice')): ?]
+<div class="save-ok">
+<h2>[?php echo __($sf_flash->get('notice')) ?]</h2>
+</div>
+[?php endif; ?]
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/data/generator/sfPropelAdmin/default/template/templates/_filters.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/data/generator/sfPropelAdmin/default/template/templates/_filters.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/data/generator/sfPropelAdmin/default/template/templates/_filters.php	(revision 19)
@@ -0,0 +1,37 @@
+[?php use_helper('Object') ?]
+
+<?php if ($this->getParameterValue('list.filters')): ?>
+<div class="sf_admin_filters">
+[?php echo form_tag('<?php echo $this->getModuleName() ?>/list', array('method' => 'get')) ?]
+
+  <fieldset>
+    <h2>[?php echo __('filters') ?]</h2>
+<?php foreach ($this->getColumns('list.filters') as $column): $type = $column->getType() ?>
+<?php $credentials = $this->getParameterValue('list.fields.'.$column->getName().'.credentials') ?>
+<?php if ($credentials): $credentials = str_replace("\n", ' ', var_export($credentials, true)) ?>
+    [?php if ($sf_user->hasCredential(<?php echo $credentials ?>)): ?]
+<?php endif; ?>
+    <div class="form-row">
+    <label for="<?php echo $column->getName() ?>">[?php echo __('<?php echo str_replace("'", "\\'", $this->getParameterValue('list.fields.'.$column->getName().'.name')) ?>:') ?]</label>
+    <div class="content">
+    [?php echo <?php echo $this->getColumnFilterTag($column) ?> ?]
+<?php if ($this->getParameterValue('list.fields.'.$column->getName().'.filter_is_empty')): ?>
+    <div>[?php echo checkbox_tag('filters[<?php echo $column->getName() ?>_is_empty]', 1, isset($filters['<?php echo $column->getName() ?>_is_empty']) ? $filters['<?php echo $column->getName() ?>_is_empty'] : null) ?]&nbsp;<label for="filters[<?php echo $column->getName() ?>_is_empty]">[?php echo __('is empty') ?]</label></div>
+<?php endif; ?>
+    </div>
+    </div>
+<?php if ($credentials): ?>
+    [?php endif; ?]
+<?php endif; ?>
+
+    <?php endforeach; ?>
+  </fieldset>
+
+  <ul class="sf_admin_actions">
+    <li>[?php echo button_to(__('reset'), '<?php echo $this->getModuleName() ?>/list?filter=filter', 'class=sf_admin_action_reset_filter') ?]</li>
+    <li>[?php echo submit_tag(__('filter'), 'name=filter class=sf_admin_action_filter') ?]</li>
+  </ul>
+
+</form>
+</div>
+<?php endif; ?>
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/data/generator/sfPropelAdmin/default/template/templates/_list.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/data/generator/sfPropelAdmin/default/template/templates/_list.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/data/generator/sfPropelAdmin/default/template/templates/_list.php	(revision 19)
@@ -0,0 +1,43 @@
+<?php if ($this->getParameterValue('list.batch_actions')): ?>
+[?php echo form_tag('<?php echo $this->getModuleNAme() ?>/batchAction') ?]
+<?php endif; ?>
+<table cellspacing="0" class="sf_admin_list">
+<thead>
+<tr>
+<?php if ($this->getParameterValue('list.batch_actions')): ?>
+  <th id="sf_admin_list_th_sf_batch_actions">[?php echo checkbox_tag('foo', 1, 0, array('onclick' => "boxes = document.getElementsByTagName('input'); for(index in boxes) { box = boxes[index]; if (box.type == 'checkbox' && box.className == 'sf_admin_batch_checkbox') box.checked = this.checked } return true;")) ?]</th>
+<?php endif; ?>
+[?php include_partial('list_th_<?php echo $this->getParameterValue('list.layout', 'tabular') ?>') ?]
+<?php if ($this->getParameterValue('list.object_actions')): ?>
+  <th id="sf_admin_list_th_sf_actions">[?php echo __('Actions') ?]</th>
+<?php endif; ?>
+</tr>
+</thead>
+<tbody>
+[?php $i = 1; foreach ($pager->getResults() as $<?php echo $this->getSingularName() ?>): $odd = fmod(++$i, 2) ?]
+<tr class="sf_admin_row_[?php echo $odd ?]">
+[?php include_partial('list_td_batch_actions', array('<?php echo $this->getSingularName() ?>' => $<?php echo $this->getSingularName() ?>)) ?]
+[?php include_partial('list_td_<?php echo $this->getParameterValue('list.layout', 'tabular') ?>', array('<?php echo $this->getSingularName() ?>' => $<?php echo $this->getSingularName() ?>)) ?]
+[?php include_partial('list_td_actions', array('<?php echo $this->getSingularName() ?>' => $<?php echo $this->getSingularName() ?>)) ?]
+</tr>
+[?php endforeach; ?]
+</tbody>
+<tfoot>
+<tr><th colspan="<?php echo count($this->getColumns('list.display')) + ($this->getParameterValue('list.object_actions') ? 1 : 0) + ($this->getParameterValue('list.batch_actions') ? 1 : 0) ?>">
+<div class="float-right">
+[?php if ($pager->haveToPaginate()): ?]
+  [?php echo link_to(image_tag(sfConfig::get('sf_admin_web_dir').'/images/first.png', array('align' => 'absmiddle', 'alt' => __('First'), 'title' => __('First'))), '<?php echo $this->getModuleName() ?>/list?page=1') ?]
+  [?php echo link_to(image_tag(sfConfig::get('sf_admin_web_dir').'/images/previous.png', array('align' => 'absmiddle', 'alt' => __('Previous'), 'title' => __('Previous'))), '<?php echo $this->getModuleName() ?>/list?page='.$pager->getPreviousPage()) ?]
+
+  [?php foreach ($pager->getLinks() as $page): ?]
+    [?php echo link_to_unless($page == $pager->getPage(), $page, '<?php echo $this->getModuleName() ?>/list?page='.$page) ?]
+  [?php endforeach; ?]
+
+  [?php echo link_to(image_tag(sfConfig::get('sf_admin_web_dir').'/images/next.png', array('align' => 'absmiddle', 'alt' => __('Next'), 'title' => __('Next'))), '<?php echo $this->getModuleName() ?>/list?page='.$pager->getNextPage()) ?]
+  [?php echo link_to(image_tag(sfConfig::get('sf_admin_web_dir').'/images/last.png', array('align' => 'absmiddle', 'alt' => __('Last'), 'title' => __('Last'))), '<?php echo $this->getModuleName() ?>/list?page='.$pager->getLastPage()) ?]
+[?php endif; ?]
+</div>
+[?php echo format_number_choice('[0] no result|[1] 1 result|(1,+Inf] %1% results', array('%1%' => $pager->getNbResults()), $pager->getNbResults()) ?]
+</th></tr>
+</tfoot>
+</table>
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/data/generator/sfPropelAdmin/default/template/templates/_list_actions.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/data/generator/sfPropelAdmin/default/template/templates/_list_actions.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/data/generator/sfPropelAdmin/default/template/templates/_list_actions.php	(revision 19)
@@ -0,0 +1,10 @@
+<ul class="sf_admin_actions">
+<?php $listActions = $this->getParameterValue('list.actions') ?>
+<?php if (null !== $listActions): ?>
+  <?php foreach ((array) $listActions as $actionName => $params): ?>
+    <?php echo $this->addCredentialCondition($this->getButtonToAction($actionName, $params, false), $params) ?>
+  <?php endforeach; ?>
+<?php else: ?>
+  <?php echo $this->getButtonToAction('_create', array(), false) ?>
+<?php endif; ?>
+</ul>
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/data/generator/sfPropelAdmin/default/template/templates/_list_batch_actions.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/data/generator/sfPropelAdmin/default/template/templates/_list_batch_actions.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/data/generator/sfPropelAdmin/default/template/templates/_list_batch_actions.php	(revision 19)
@@ -0,0 +1,13 @@
+<?php $listActions = $this->getParameterValue('list.batch_actions') ?>
+<?php if (!is_null($listActions)): ?>
+<div id="sf_admin_batch_action_choice">
+  <select name="sf_admin_batch_action">
+    <option value="">[?php echo __('Choose an action') ?]</option>
+    <?php foreach ((array) $listActions as $actionName => $params): ?>
+    <?php echo $this->addCredentialCondition($this->getOptionToAction($actionName, $params), $params) ?>
+    <?php endforeach; ?>
+  </select>
+  [?php echo submit_tag(__('Ok')) ?]
+  </form>
+</div>
+<?php endif; ?>
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/data/generator/sfPropelAdmin/default/template/templates/_list_messages.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/data/generator/sfPropelAdmin/default/template/templates/_list_messages.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/data/generator/sfPropelAdmin/default/template/templates/_list_messages.php	(revision 19)
@@ -0,0 +1,8 @@
+[?php if ($sf_request->hasError('delete')): ?]
+<div class="form-errors">
+  <h2>[?php echo __('Could not delete the selected %name%', array('%name%' => '<?php echo sfInflector::humanize($this->getSingularName()) ?>')) ?]</h2>
+  <ul>
+    <li>[?php echo __($sf_request->getError('delete')) ?]</li>
+  </ul>
+</div>
+[?php endif; ?]
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/data/generator/sfPropelAdmin/default/template/templates/_list_td_actions.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/data/generator/sfPropelAdmin/default/template/templates/_list_td_actions.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/data/generator/sfPropelAdmin/default/template/templates/_list_td_actions.php	(revision 19)
@@ -0,0 +1,9 @@
+<?php if ($this->getParameterValue('list.object_actions')): ?>
+<td>
+<ul class="sf_admin_td_actions">
+<?php foreach ($this->getParameterValue('list.object_actions') as $actionName => $params): ?>
+  <?php echo $this->addCredentialCondition($this->getLinkToAction($actionName, $params, true), $params) ?>
+<?php endforeach; ?>
+</ul>
+</td>
+<?php endif; ?>
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/data/generator/sfPropelAdmin/default/template/templates/_list_td_batch_actions.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/data/generator/sfPropelAdmin/default/template/templates/_list_td_batch_actions.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/data/generator/sfPropelAdmin/default/template/templates/_list_td_batch_actions.php	(revision 19)
@@ -0,0 +1,5 @@
+<?php if ($this->getParameterValue('list.batch_actions')): ?>
+<td>
+[?php echo checkbox_tag('sf_admin_batch_selection[]', $<?php echo $this->getSingularName() ?>->getPrimaryKey(), 0, array('class' => 'sf_admin_batch_checkbox')) ?]
+</td>
+<?php endif; ?>
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/data/generator/sfPropelAdmin/default/template/templates/_list_td_stacked.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/data/generator/sfPropelAdmin/default/template/templates/_list_td_stacked.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/data/generator/sfPropelAdmin/default/template/templates/_list_td_stacked.php	(revision 19)
@@ -0,0 +1,16 @@
+<td colspan="<?php echo count($this->getColumns('list.display'))  ?>">
+<?php if ($this->getParameterValue('list.params')): ?>
+  <?php echo $this->getI18NString('list.params') ?>
+<?php else: ?>
+<?php $hides = $this->getParameterValue('list.hide', array()) ?>
+<?php foreach ($this->getColumns('list.display') as $column): ?>
+<?php if (in_array($column->getName(), $hides)) continue ?>
+  <?php if ($column->isLink()): ?>
+  [?php echo link_to(<?php echo $this->getColumnListTag($column) ?> ? <?php echo $this->getColumnListTag($column) ?> : __('-'), '<?php echo $this->getModuleName() ?>/edit?<?php echo $this->getPrimaryKeyUrlParams() ?>) ?]
+  <?php else: ?>
+  [?php echo <?php echo $this->getColumnListTag($column) ?> ?]
+  <?php endif; ?>
+   - 
+<?php endforeach; ?>
+<?php endif; ?>
+</td>
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/data/generator/sfPropelAdmin/default/template/templates/_list_td_tabular.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/data/generator/sfPropelAdmin/default/template/templates/_list_td_tabular.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/data/generator/sfPropelAdmin/default/template/templates/_list_td_tabular.php	(revision 19)
@@ -0,0 +1,16 @@
+<?php $hs = $this->getParameterValue('list.hide', array()) ?>
+<?php foreach ($this->getColumns('list.display') as $column): ?>
+<?php if (in_array($column->getName(), $hs)) continue ?>
+<?php $credentials = $this->getParameterValue('list.fields.'.$column->getName().'.credentials') ?>
+<?php if ($credentials): $credentials = str_replace("\n", ' ', var_export($credentials, true)) ?>
+    [?php if ($sf_user->hasCredential(<?php echo $credentials ?>)): ?]
+<?php endif; ?>
+  <?php if ($column->isLink()): ?>
+  <td>[?php echo link_to(<?php echo $this->getColumnListTag($column) ?> ? <?php echo $this->getColumnListTag($column) ?> : __('-'), '<?php echo $this->getModuleName() ?>/edit?<?php echo $this->getPrimaryKeyUrlParams() ?>) ?]</td>
+<?php else: ?>
+  <td>[?php echo <?php echo $this->getColumnListTag($column) ?> ?]</td>
+  <?php endif; ?>
+<?php if ($credentials): ?>
+    [?php endif; ?]
+<?php endif; ?>
+<?php endforeach; ?>
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/data/generator/sfPropelAdmin/default/template/templates/_list_th_stacked.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/data/generator/sfPropelAdmin/default/template/templates/_list_th_stacked.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/data/generator/sfPropelAdmin/default/template/templates/_list_th_stacked.php	(revision 19)
@@ -0,0 +1,1 @@
+[?php include_partial('list_th_tabular') ?]
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/data/generator/sfPropelAdmin/default/template/templates/_list_th_tabular.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/data/generator/sfPropelAdmin/default/template/templates/_list_th_tabular.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/data/generator/sfPropelAdmin/default/template/templates/_list_th_tabular.php	(revision 19)
@@ -0,0 +1,24 @@
+<?php $hides = $this->getParameterValue('list.hide', array()) ?>
+<?php foreach ($this->getColumns('list.display') as $column): ?>
+<?php if (in_array($column->getName(), $hides)) continue ?>
+<?php $credentials = $this->getParameterValue('list.fields.'.$column->getName().'.credentials') ?>
+<?php if ($credentials): $credentials = str_replace("\n", ' ', var_export($credentials, true)) ?>
+    [?php if ($sf_user->hasCredential(<?php echo $credentials ?>)): ?]
+<?php endif; ?>
+  <th id="sf_admin_list_th_<?php echo $column->getName() ?>">
+    <?php if ($column->isReal()): ?>
+      [?php if ($sf_user->getAttribute('sort', null, 'sf_admin/<?php echo $this->getSingularName() ?>/sort') == '<?php echo $column->getName() ?>'): ?]
+      [?php echo link_to(__('<?php echo str_replace("'", "\\'", $this->getParameterValue('list.fields.'.$column->getName().'.name')) ?>'), '<?php echo $this->getModuleName() ?>/list?sort=<?php echo $column->getName() ?>&type='.($sf_user->getAttribute('type', 'asc', 'sf_admin/<?php echo $this->getSingularName() ?>/sort') == 'asc' ? 'desc' : 'asc')) ?]
+      ([?php echo __($sf_user->getAttribute('type', 'asc', 'sf_admin/<?php echo $this->getSingularName() ?>/sort')) ?])
+      [?php else: ?]
+      [?php echo link_to(__('<?php echo str_replace("'", "\\'", $this->getParameterValue('list.fields.'.$column->getName().'.name')) ?>'), '<?php echo $this->getModuleName() ?>/list?sort=<?php echo $column->getName() ?>&type=asc') ?]
+      [?php endif; ?]
+    <?php else: ?>
+    [?php echo __('<?php echo str_replace("'", "\\'", $this->getParameterValue('list.fields.'.$column->getName().'.name')) ?>') ?]
+    <?php endif; ?>
+    <?php echo $this->getHelpAsIcon($column, 'list') ?>
+  </th>
+<?php if ($credentials): ?>
+    [?php endif; ?]
+<?php endif; ?>
+<?php endforeach; ?>
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/data/generator/sfPropelAdmin/default/template/templates/editSuccess.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/data/generator/sfPropelAdmin/default/template/templates/editSuccess.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/data/generator/sfPropelAdmin/default/template/templates/editSuccess.php	(revision 19)
@@ -0,0 +1,22 @@
+[?php use_helper('Object', 'Validation', 'ObjectAdmin', 'I18N', 'Date') ?]
+
+[?php use_stylesheet('<?php echo $this->getParameterValue('css', sfConfig::get('sf_admin_web_dir').'/css/main') ?>') ?]
+
+<div id="sf_admin_container">
+
+<h1><?php echo $this->getI18NString('edit.title', 'edit '.$this->getModuleName()) ?></h1>
+
+<div id="sf_admin_header">
+[?php include_partial('<?php echo $this->getModuleName() ?>/edit_header', array('<?php echo $this->getSingularName() ?>' => $<?php echo $this->getSingularName() ?>)) ?]
+</div>
+
+<div id="sf_admin_content">
+[?php include_partial('<?php echo $this->getModuleName() ?>/edit_messages', array('<?php echo $this->getSingularName() ?>' => $<?php echo $this->getSingularName() ?>, 'labels' => $labels)) ?]
+[?php include_partial('<?php echo $this->getModuleName() ?>/edit_form', array('<?php echo $this->getSingularName() ?>' => $<?php echo $this->getSingularName() ?>, 'labels' => $labels)) ?]
+</div>
+
+<div id="sf_admin_footer">
+[?php include_partial('<?php echo $this->getModuleName() ?>/edit_footer', array('<?php echo $this->getSingularName() ?>' => $<?php echo $this->getSingularName() ?>)) ?]
+</div>
+
+</div>
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/data/generator/sfPropelAdmin/default/template/templates/listSuccess.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/data/generator/sfPropelAdmin/default/template/templates/listSuccess.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/data/generator/sfPropelAdmin/default/template/templates/listSuccess.php	(revision 19)
@@ -0,0 +1,34 @@
+[?php use_helper('I18N', 'Date') ?]
+
+[?php use_stylesheet('<?php echo $this->getParameterValue('css', sfConfig::get('sf_admin_web_dir').'/css/main') ?>') ?]
+
+<div id="sf_admin_container">
+
+<h1><?php echo $this->getI18NString('list.title', $this->getModuleName().' list') ?></h1>
+
+<div id="sf_admin_header">
+[?php include_partial('<?php echo $this->getModuleName() ?>/list_header', array('pager' => $pager)) ?]
+[?php include_partial('<?php echo $this->getModuleName() ?>/list_messages', array('pager' => $pager)) ?]
+</div>
+
+<div id="sf_admin_bar">
+<?php if ($this->getParameterValue('list.filters')): ?>
+[?php include_partial('filters', array('filters' => $filters)) ?]
+<?php endif; ?>
+</div>
+
+<div id="sf_admin_content">
+[?php if (!$pager->getNbResults()): ?]
+[?php echo __('no result') ?]
+[?php else: ?]
+[?php include_partial('<?php echo $this->getModuleName() ?>/list', array('pager' => $pager)) ?]
+[?php endif; ?]
+[?php include_partial('list_batch_actions') ?]
+[?php include_partial('list_actions') ?]
+</div>
+
+<div id="sf_admin_footer">
+[?php include_partial('<?php echo $this->getModuleName() ?>/list_footer', array('pager' => $pager)) ?]
+</div>
+
+</div>
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/data/generator/sfPropelCrud/default/skeleton/actions/actions.class.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/data/generator/sfPropelCrud/default/skeleton/actions/actions.class.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/data/generator/sfPropelCrud/default/skeleton/actions/actions.class.php	(revision 19)
@@ -0,0 +1,13 @@
+<?php
+
+/**
+ * ##MODULE_NAME## actions.
+ *
+ * @package    ##PROJECT_NAME##
+ * @subpackage ##MODULE_NAME##
+ * @author     ##AUTHOR_NAME##
+ * @version    SVN: $Id: actions.class.php 2288 2006-10-02 15:22:13Z fabien $
+ */
+class ##MODULE_NAME##Actions extends auto##MODULE_NAME##Actions
+{
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/data/generator/sfPropelCrud/default/skeleton/config/generator.yml
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/data/generator/sfPropelCrud/default/skeleton/config/generator.yml	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/data/generator/sfPropelCrud/default/skeleton/config/generator.yml	(revision 19)
@@ -0,0 +1,5 @@
+generator:
+  class:              sfPropel13CrudGenerator
+  param:
+    model_class:      ##MODEL_CLASS##
+    theme:            default
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/data/generator/sfPropelCrud/default/template/actions/actions.class.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/data/generator/sfPropelCrud/default/template/actions/actions.class.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/data/generator/sfPropelCrud/default/template/actions/actions.class.php	(revision 19)
@@ -0,0 +1,89 @@
+[?php
+
+/**
+ * <?php echo $this->getGeneratedModuleName() ?> actions.
+ *
+ * @package    ##PROJECT_NAME##
+ * @subpackage <?php echo $this->getGeneratedModuleName() ?>
+
+ * @author     ##AUTHOR_NAME##
+ * @version    SVN: $Id: actions.class.php 3335 2007-01-23 16:19:56Z fabien $
+ */
+class <?php echo $this->getGeneratedModuleName() ?>Actions extends sfActions
+{
+  public function executeIndex()
+  {
+    return $this->forward('<?php echo $this->getModuleName() ?>', 'list');
+  }
+
+  public function executeList()
+  {
+    $this-><?php echo $this->getPluralName() ?> = <?php echo $this->getClassName() ?>Peer::doSelect(new Criteria());
+  }
+
+  public function executeShow()
+  {
+    $this-><?php echo $this->getSingularName() ?> = <?php echo $this->getClassName() ?>Peer::retrieveByPk(<?php echo $this->getRetrieveByPkParamsForAction(49) ?>);
+    $this->forward404Unless($this-><?php echo $this->getSingularName() ?>);
+  }
+
+  public function executeCreate()
+  {
+    $this-><?php echo $this->getSingularName() ?> = new <?php echo $this->getClassName() ?>();
+
+    $this->setTemplate('edit');
+  }
+
+  public function executeEdit()
+  {
+    $this-><?php echo $this->getSingularName() ?> = <?php echo $this->getClassName() ?>Peer::retrieveByPk(<?php echo $this->getRetrieveByPkParamsForAction(49) ?>);
+    $this->forward404Unless($this-><?php echo $this->getSingularName() ?>);
+  }
+
+  public function executeUpdate()
+  {
+    if (<?php echo $this->getTestPksForGetOrCreate(false) ?>)
+    {
+      $<?php echo $this->getSingularName() ?> = new <?php echo $this->getClassName() ?>();
+    }
+    else
+    {
+      $<?php echo $this->getSingularName() ?> = <?php echo $this->getClassName() ?>Peer::retrieveByPk(<?php echo $this->getRetrieveByPkParamsForAction(45) ?>);
+      $this->forward404Unless($<?php echo $this->getSingularName() ?>);
+    }
+
+<?php foreach ($this->getTableMap()->getColumns() as $name => $column): $type = $column->getType(); ?>
+<?php if ($name == 'CREATED_AT' || $name == 'UPDATED_AT') continue ?>
+<?php $name = sfInflector::underscore($column->getPhpName()) ?>
+<?php if ($type == PropelColumnTypes::DATE || $type == PropelColumnTypes::TIMESTAMP): ?>
+    if ($this->getRequestParameter('<?php echo $name ?>'))
+    {
+      list($d, $m, $y) = sfI18N::getDateForCulture($this->getRequestParameter('<?php echo $name ?>'), $this->getUser()->getCulture());
+      $<?php echo $this->getSingularName() ?>->set<?php echo $column->getPhpName() ?>("$y-$m-$d");
+    }
+<?php elseif ($type == PropelColumnTypes::BOOLEAN): ?>
+    $<?php echo $this->getSingularName() ?>->set<?php echo $column->getPhpName() ?>($this->getRequestParameter('<?php echo $name ?>', 0));
+<?php elseif ($column->isForeignKey()): ?>
+    $<?php echo $this->getSingularName() ?>->set<?php echo $column->getPhpName() ?>($this->getRequestParameter('<?php echo $name ?>') ? $this->getRequestParameter('<?php echo $name ?>') : null);
+<?php else: ?>
+    $<?php echo $this->getSingularName() ?>->set<?php echo $column->getPhpName() ?>($this->getRequestParameter('<?php echo $name ?>'));
+<?php endif; ?>
+<?php endforeach; ?>
+
+    $<?php echo $this->getSingularName() ?>->save();
+
+    return $this->redirect('<?php echo $this->getModuleName() ?>/show?<?php echo $this->getPrimaryKeyUrlParams() ?>);
+<?php //' ?>
+  }
+
+  public function executeDelete()
+  {
+    $<?php echo $this->getSingularName() ?> = <?php echo $this->getClassName() ?>Peer::retrieveByPk(<?php echo $this->getRetrieveByPkParamsForAction(43) ?>);
+
+    $this->forward404Unless($<?php echo $this->getSingularName() ?>);
+
+    $<?php echo $this->getSingularName() ?>->delete();
+
+    return $this->redirect('<?php echo $this->getModuleName() ?>/list');
+  }
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/data/generator/sfPropelCrud/default/template/templates/editSuccess.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/data/generator/sfPropelCrud/default/template/templates/editSuccess.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/data/generator/sfPropelCrud/default/template/templates/editSuccess.php	(revision 19)
@@ -0,0 +1,29 @@
+[?php use_helper('Object') ?]
+
+[?php echo form_tag('<?php echo $this->getModuleName() ?>/update') ?]
+
+<?php foreach ($this->getPrimaryKey() as $pk): ?>
+[?php echo object_input_hidden_tag($<?php echo $this->getSingularName() ?>, 'get<?php echo $pk->getPhpName() ?>') ?]
+<?php endforeach; ?>
+
+<table>
+<tbody>
+<?php foreach ($this->getTableMap()->getColumns() as $name => $column): ?>
+<?php if ($column->isPrimaryKey()) continue ?>
+<?php if ($name == 'CREATED_AT' || $name == 'UPDATED_AT') continue ?>
+<tr>
+  <th><?php echo sfInflector::humanize(sfInflector::underscore($column->getPhpName())) ?><?php if ($column->isNotNull()): ?>*<?php endif; ?>:</th>
+  <td>[?php echo <?php echo $this->getCrudColumnEditTag($column) ?> ?]</td>
+</tr>
+<?php endforeach; ?>
+</tbody>
+</table>
+<hr />
+[?php echo submit_tag('save') ?]
+[?php if (<?php echo $this->getPrimaryKeyIsSet() ?>): ?]
+  &nbsp;[?php echo link_to('delete', '<?php echo $this->getModuleName() ?>/delete?<?php echo $this->getPrimaryKeyUrlParams() ?>, 'post=true&confirm=Are you sure?') ?]
+  &nbsp;[?php echo link_to('cancel', '<?php echo $this->getModuleName() ?>/show?<?php echo $this->getPrimaryKeyUrlParams() ?>) ?]
+[?php else: ?]
+  &nbsp;[?php echo link_to('cancel', '<?php echo $this->getModuleName() ?>/list') ?]
+[?php endif; ?]
+</form>
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/data/generator/sfPropelCrud/default/template/templates/listSuccess.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/data/generator/sfPropelCrud/default/template/templates/listSuccess.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/data/generator/sfPropelCrud/default/template/templates/listSuccess.php	(revision 19)
@@ -0,0 +1,26 @@
+<h1><?php echo $this->getModuleName() ?></h1>
+
+<table>
+<thead>
+<tr>
+<?php foreach ($this->getTableMap()->getColumns() as $column): ?>
+  <th><?php echo sfInflector::humanize(sfInflector::underscore($column->getPhpName())) ?></th>
+<?php endforeach; ?>
+</tr>
+</thead>
+<tbody>
+[?php foreach ($<?php echo $this->getPluralName() ?> as $<?php echo $this->getSingularName() ?>): ?]
+<tr>
+<?php foreach ($this->getTableMap()->getColumns() as $column): ?>
+  <?php if ($column->isPrimaryKey()): ?>
+  <td>[?php echo link_to($<?php echo $this->getSingularName() ?>->get<?php echo $column->getPhpName() ?>(), '<?php echo $this->getModuleName() ?>/show?<?php echo $this->getPrimaryKeyUrlParams() ?>) ?]</td>
+  <?php else: ?>
+  <td>[?php echo $<?php echo $this->getSingularName() ?>->get<?php echo $column->getPhpName() ?>() ?]</td>
+  <?php endif; ?>
+<?php endforeach; ?>
+</tr>
+[?php endforeach; ?]
+</tbody>
+</table>
+
+[?php echo link_to ('create', '<?php echo $this->getModuleName() ?>/create') ?]
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/data/generator/sfPropelCrud/default/template/templates/showSuccess.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/data/generator/sfPropelCrud/default/template/templates/showSuccess.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/data/generator/sfPropelCrud/default/template/templates/showSuccess.php	(revision 19)
@@ -0,0 +1,13 @@
+<table>
+<tbody>
+<?php foreach ($this->getTableMap()->getColumns() as $column): ?>
+<tr>
+<th><?php echo sfInflector::humanize(sfInflector::underscore($column->getPhpName())) ?>: </th>
+<td>[?= $<?php echo $this->getSingularName() ?>->get<?php echo $column->getPhpName() ?>() ?]</td>
+</tr>
+<?php endforeach; ?>
+</tbody>
+</table>
+<hr />
+[?php echo link_to('edit', '<?php echo $this->getModuleName() ?>/edit?<?php echo $this->getPrimaryKeyUrlParams() ?>) ?]
+&nbsp;[?php echo link_to('list', '<?php echo $this->getModuleName() ?>/list') ?]
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/data/tasks/sfPakePropel13.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/data/tasks/sfPakePropel13.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/data/tasks/sfPakePropel13.php	(revision 19)
@@ -0,0 +1,294 @@
+<?php
+/*
+ * This file is part of the sfPropel13Plugin package.
+ * (c) 2007 Joshua May <notjosh@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * @package    symfony.plugins
+ * @subpackage sfPropel13Plugin
+ * @author     Joshua May <notjosh@gmail.com>
+ * @version    SVN: $Id$
+ */
+
+// ----
+// Task runners
+// ----
+function run_propel_13_build_model($task, $args)
+{
+  _propel_convert_yml_schema(false, 'generated-');
+  _propel_copy_xml_schema_from_plugins('generated-');
+  _call_phing_13($task, 'om');
+  $finder = pakeFinder::type('file')->name('generated-*schema.xml');
+  pake_remove($finder, array('config', 'plugins'));
+}
+
+function run_propel_13_build_sql($task, $args)
+{
+  _propel_convert_yml_schema(false, 'generated-');
+  _propel_copy_xml_schema_from_plugins('generated-');
+  _call_phing_13($task, 'sql');
+  $finder = pakeFinder::type('file')->name('generated-*schema.xml');
+  pake_remove($finder, 'config');
+}
+
+function run_propel_13_insert_sql($task, $args)
+{
+  _propel_convert_yml_schema(false, 'generated-');
+  _propel_copy_xml_schema_from_plugins('generated-');
+  _call_phing_13($task, 'insert-sql');
+  $finder = pakeFinder::type('file')->name('generated-*schema.xml');
+  pake_remove($finder, 'config');
+}
+
+function run_propel_13_build_db($task, $args)
+{
+  _call_phing_13($task, 'create-db', false);
+}
+
+function run_propel_13_build_schema($task, $args)
+{
+  _call_phing_13($task, 'creole', false);
+
+  // fix database name
+  if (file_exists('config/schema.xml'))
+  {
+    $schema = file_get_contents('config/schema.xml');
+    $schema = preg_replace('/<database\s+name="[^"]+"/s', '<database name="propel"', $schema);
+    file_put_contents('config/schema.xml', $schema);
+  }
+
+  if (!isset($args[0]) || $args[0] != 'xml')
+  {
+    _propel_convert_xml_schema(false, '');
+    $finder = pakeFinder::type('file')->name('schema.xml');
+    pake_remove($finder, 'config');
+  }
+}
+
+function run_propel_13_load_data($task, $args)
+{
+  //_init_db_path();
+  //run_propel_load_data($task, $args)
+  
+  
+  if (!count($args))
+  {
+    throw new Exception('You must provide the app.');
+  }
+
+  $app = $args[0];
+
+  if (!is_dir(sfConfig::get('sf_app_dir').DIRECTORY_SEPARATOR.$app))
+  {
+    throw new Exception('The app "'.$app.'" does not exist.');
+  }
+
+  if (count($args) > 1 && $args[count($args) - 1] == 'append')
+  {
+    array_pop($args);
+    $delete = false;
+  }
+  else
+  {
+    $delete = true;
+  }
+
+  $env = empty($args[1]) ? 'dev' : $args[1];
+
+  // define constants
+  define('SF_ROOT_DIR',    sfConfig::get('sf_root_dir'));
+  define('SF_APP',         $app);
+  define('SF_ENVIRONMENT', $env);
+  define('SF_DEBUG',       true);
+
+  // get configuration
+  require_once SF_ROOT_DIR.DIRECTORY_SEPARATOR.'apps'.DIRECTORY_SEPARATOR.SF_APP.DIRECTORY_SEPARATOR.'config'.DIRECTORY_SEPARATOR.'config.php';
+  
+  _init_db_path();
+
+  if (count($args) == 1)
+  {
+    if (!$pluginDirs = glob(sfConfig::get('sf_root_dir').'/plugins/*/data'))
+    {
+      $pluginDirs = array();
+    }
+    $fixtures_dirs = pakeFinder::type('dir')->name('fixtures')->in(array_merge($pluginDirs, array(sfConfig::get('sf_data_dir'))));
+  }
+  else
+  {
+    $fixtures_dirs = array_slice($args, 1);
+  }
+
+  $databaseManager = new sfDatabaseManager();
+  $databaseManager->initialize();
+
+  $data = new sfPropel13Data();
+  $data->setDeleteCurrentData($delete);
+
+  foreach ($fixtures_dirs as $fixtures_dir)
+  {
+    if (!is_readable($fixtures_dir))
+    {
+      continue;
+    }
+
+    pake_echo_action('propel', sprintf('load data from "%s"', $fixtures_dir));
+    $data->loadData($fixtures_dir);
+  }
+}
+
+function run_propel_13_dump_data($task, $args)
+{
+  if (!count($args))
+  {
+    throw new Exception('You must provide the app.');
+  }
+
+  $app = $args[0];
+
+  if (!is_dir(sfConfig::get('sf_app_dir').DIRECTORY_SEPARATOR.$app))
+  {
+    throw new Exception('The app "'.$app.'" does not exist.');
+  }
+
+  if (!isset($args[1]))
+  {
+    throw new Exception('You must provide a filename.');
+  }
+
+  $filename = $args[1];
+
+  $env = empty($args[2]) ? 'dev' : $args[2];
+
+  // define constants
+  define('SF_ROOT_DIR',    sfConfig::get('sf_root_dir'));
+  define('SF_APP',         $app);
+  define('SF_ENVIRONMENT', $env);
+  define('SF_DEBUG',       true);
+
+  // get configuration
+  require_once SF_ROOT_DIR.DIRECTORY_SEPARATOR.'apps'.DIRECTORY_SEPARATOR.SF_APP.DIRECTORY_SEPARATOR.'config'.DIRECTORY_SEPARATOR.'config.php';
+
+  _init_db_path();
+  
+  $databaseManager = new sfDatabaseManager();
+  $databaseManager->initialize();
+
+  if (!sfToolkit::isPathAbsolute($filename))
+  {
+    $dir = sfConfig::get('sf_data_dir').DIRECTORY_SEPARATOR.'fixtures';
+    pake_mkdirs($dir);
+    $filename = $dir.DIRECTORY_SEPARATOR.$filename;
+  }
+
+  pake_echo_action('propel', sprintf('dumping data to "%s"', $filename));
+
+  $data = new sfPropel13Data();
+  $data->dumpData($filename);
+}
+
+function run_propel_13_build_all($task, $args)
+{
+  run_propel_13_build_model($task, $args);
+  run_propel_13_build_sql($task, $args);
+  run_propel_13_insert_sql($task, $args);
+}
+
+function run_propel_13_build_all_load($task, $args)
+{
+  run_propel_13_build_all($task, $args);
+  run_propel_13_load_data($task, $args);
+}
+
+function run_propel_13_convert_xml_schema($task, $args)
+{
+  _propel_convert_xml_schema(true);
+}
+
+function run_propel_13_convert_yml_schema($task, $args)
+{
+  _propel_convert_yml_schema(true);
+}
+
+// ----
+// Internal functions
+// ----
+function _call_phing_13($task, $task_name, $check_schema = true)
+{
+  $schemas = pakeFinder::type('file')->name('*schema.xml')->relative()->follow_link()->in('config');
+  if ($check_schema && !$schemas)
+  {
+    throw new Exception('You must create a schema.yml or schema.xml file.');
+  }
+
+  $pluginDir = realpath(dirname(__FILE__).DIRECTORY_SEPARATOR.'..'.DIRECTORY_SEPARATOR.'..'.DIRECTORY_SEPARATOR.'lib'.DIRECTORY_SEPARATOR.'vendor');
+  if (false === strpos('propel-generator', get_include_path()))
+  {
+    set_include_path($pluginDir.'/propel-generator/classes'.PATH_SEPARATOR.get_include_path());
+  }
+
+  // needed to include the right Propel builders
+  set_include_path(sfConfig::get('sf_symfony_lib_dir').PATH_SEPARATOR.get_include_path());
+  set_include_path(sfConfig::get('sf_root_dir').PATH_SEPARATOR.get_include_path());
+
+  // add phing 2.3 to include_path
+  set_include_path(realpath(dirname(__FILE__) . '/../../lib/vendor/phing/classes') . PATH_SEPARATOR . get_include_path());
+
+  // call phing targets
+  pake_import('Phing', false);
+
+  $options = array(
+    'project.dir'       => sfConfig::get('sf_root_dir').'/config',
+    'build.properties'  => 'propel.ini',
+    'propel.output.dir' => sfConfig::get('sf_root_dir'),
+  );
+  pakePhingTask::call_phing($task, array($task_name), $pluginDir.'/propel-generator/build.xml', $options);
+
+  chdir(sfConfig::get('sf_root_dir'));
+}
+
+function _init_db_path()
+{
+  $vendorDir = realpath(dirname(__FILE__).DIRECTORY_SEPARATOR.'..'.DIRECTORY_SEPARATOR.'..'.DIRECTORY_SEPARATOR.'lib'.DIRECTORY_SEPARATOR.'vendor');
+  set_include_path($vendorDir.PATH_SEPARATOR.get_include_path());
+}
+
+// ----
+// Task definitions
+// ----
+pake_desc('create classes for current model');
+pake_task('propel-13-build-model', 'project_exists');
+
+pake_desc('create sql for current model');
+pake_task('propel-13-build-sql', 'project_exists');
+
+pake_desc('create schema.xml from existing database');
+pake_task('propel-13-build-schema', 'project_exists');
+
+pake_desc('create schema.xml from schema.yml');
+pake_task('propel-13-convert-yml-schema', 'project_exists');
+
+pake_desc('create schema.yml from schema.xml');
+pake_task('propel-13-convert-xml-schema', 'project_exists');
+
+pake_desc('load data from fixtures directory');
+pake_task('propel-13-load-data', 'project_exists');
+
+pake_desc('dump data to fixtures directory');
+pake_task('propel-13-dump-data', 'project_exists');
+
+//pake_desc('create database for current model');
+//pake_task('propel-13-build-db', 'project_exists');
+
+pake_desc('insert sql for current model');
+pake_task('propel-13-insert-sql', 'project_exists');
+
+pake_desc('generate propel model and sql and initialize database');
+pake_task('propel-13-build-all', 'project_exists');
+
+pake_desc('generate propel model and sql and initialize database, and load data');
+pake_task('propel-13-build-all-load', 'propel-13-build-all');
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/data/tasks/sfPakePropel13AdminGenerator.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/data/tasks/sfPakePropel13AdminGenerator.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/data/tasks/sfPakePropel13AdminGenerator.php	(revision 19)
@@ -0,0 +1,77 @@
+<?php
+/*
+ * This file is part of the sfPropel13Plugin package.
+ * (c) 2007 Joshua May <notjosh@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * @package    symfony.plugins
+ * @subpackage sfPropel13Plugin
+ * @author     Joshua May <notjosh@gmail.com>
+ * @version    SVN: $Id$
+ */
+
+pake_desc('initialize a new propel admin module');
+pake_task('propel-13-init-admin', 'app_exists');
+
+function run_propel_13_init_admin($task, $args)
+{
+//  run_propel_init_admin($task, $args);
+
+
+
+
+  if (count($args) < 2)
+  {
+    throw new Exception('You must provide your module name.');
+  }
+
+  if (count($args) < 3)
+  {
+    throw new Exception('You must provide your model class name.');
+  }
+
+  $app         = $args[0];
+  $module      = $args[1];
+  $model_class = $args[2];
+  $theme       = isset($args[3]) ? $args[3] : 'default';
+
+  try
+  {
+    $author_name = $task->get_property('author', 'symfony');
+  }
+  catch (pakeException $e)
+  {
+    $author_name = 'Your name here';
+  }
+
+  $constants = array(
+    'PROJECT_NAME' => $task->get_property('name', 'symfony'),
+    'APP_NAME'     => $app,
+    'MODULE_NAME'  => $module,
+    'MODEL_CLASS'  => $model_class,
+    'AUTHOR_NAME'  => $author_name,
+    'THEME'        => $theme, 
+  );
+
+  $moduleDir = sfConfig::get('sf_root_dir').'/'.sfConfig::get('sf_apps_dir_name').'/'.$app.'/'.sfConfig::get('sf_app_module_dir_name').'/'.$module;
+
+  // create module structure
+  $finder = pakeFinder::type('any')->ignore_version_control()->discard('.sf');
+  $dirs = sfLoader::getGeneratorSkeletonDirs('sfPropelAdmin', $theme);
+  foreach ($dirs as $dir)
+  {
+    if (is_dir($dir))
+    {
+      pake_mirror($finder, $dir, $moduleDir);
+      break;
+    }
+  }
+
+  // customize php and yml files
+  $finder = pakeFinder::type('file')->name('*.php', '*.yml');
+  pake_replace_tokens($finder, $moduleDir, '##', '##', $constants);
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/data/tasks/sfPakePropel13CrudGenerator.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/data/tasks/sfPakePropel13CrudGenerator.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/data/tasks/sfPakePropel13CrudGenerator.php	(revision 19)
@@ -0,0 +1,151 @@
+<?php
+/*
+ * This file is part of the sfPropel13Plugin package.
+ * (c) 2007 Joshua May <notjosh@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * @package    symfony.plugins
+ * @subpackage sfPropel13Plugin
+ * @author     Joshua May <notjosh@gmail.com>
+ * @version    SVN: $Id$
+ */
+
+pake_desc('initialize a new propel CRUD module');
+pake_task('propel-13-init-crud', 'app_exists');
+
+pake_desc('generate a new propel CRUD module');
+pake_task('propel-13-generate-crud', 'app_exists');
+
+function run_propel_13_init_crud($task, $args)
+{
+//  run_propel_init_crud($task, $args);
+
+
+
+
+  if (count($args) < 2)
+  {
+    throw new Exception('You must provide your module name.');
+  }
+
+  if (count($args) < 3)
+  {
+    throw new Exception('You must provide your model class name.');
+  }
+
+  $app         = $args[0];
+  $module      = $args[1];
+  $model_class = $args[2];
+
+  try
+  {
+    $author_name = $task->get_property('author', 'symfony');
+  }
+  catch (pakeException $e)
+  {
+    $author_name = 'Your name here';
+  }
+
+  $constants = array(
+    'PROJECT_NAME' => $task->get_property('name', 'symfony'),
+    'APP_NAME'     => $app,
+    'MODULE_NAME'  => $module,
+    'MODEL_CLASS'  => $model_class,
+    'AUTHOR_NAME'  => $author_name,
+  );
+
+  $sf_root_dir = sfConfig::get('sf_root_dir');
+  $moduleDir   = $sf_root_dir.'/'.sfConfig::get('sf_apps_dir_name').'/'.$app.'/'.sfConfig::get('sf_app_module_dir_name').'/'.$module;
+
+  // create basic application structure
+  $finder = pakeFinder::type('any')->ignore_version_control()->discard('.sf');
+  
+  $dir = dirname(__FILE__) . DIRECTORY_SEPARATOR . '..' . '/generator/sfPropelCrud/default/skeleton';
+  $dir = realpath($dir);
+  
+  pake_mirror($finder, $dir, $moduleDir);
+
+  // create basic test
+  pake_copy(sfConfig::get('sf_symfony_data_dir').'/skeleton/module/test/actionsTest.php', $sf_root_dir.'/test/functional/'.$app.'/'.$module.'ActionsTest.php');
+
+  // customize test file
+  pake_replace_tokens($module.'ActionsTest.php', $sf_root_dir.'/test/functional/'.$app, '##', '##', $constants);
+
+  // customize php and yml files
+  $finder = pakeFinder::type('file')->name('*.php', '*.yml');
+  pake_replace_tokens($finder, $moduleDir, '##', '##', $constants);
+}
+
+function run_propel_13_generate_crud($task, $args)
+{
+  _init_db_path();
+
+  if (count($args) < 2)
+  {
+    throw new Exception('You must provide your module name.');
+  }
+
+  if (count($args) < 3)
+  {
+    throw new Exception('You must provide your model class name.');
+  }
+
+  $theme = isset($args[3]) ? $args[3] : 'default';
+
+  $app         = $args[0];
+  $module      = $args[1];
+  $model_class = $args[2];
+
+  $sf_root_dir = sfConfig::get('sf_root_dir');
+
+  // generate module
+  $tmp_dir = $sf_root_dir.DIRECTORY_SEPARATOR.'cache'.DIRECTORY_SEPARATOR.'tmp'.DIRECTORY_SEPARATOR.md5(uniqid(rand(), true));
+  sfConfig::set('sf_module_cache_dir', $tmp_dir);
+  $generator_manager = new sfGeneratorManager();
+  $generator_manager->initialize();
+  $generator_manager->generate('sfPropel13CrudGenerator', array('model_class' => $model_class, 'moduleName' => $module, 'theme' => $theme));
+
+  $moduleDir = $sf_root_dir.'/'.sfConfig::get('sf_apps_dir_name').'/'.$app.'/'.sfConfig::get('sf_app_module_dir_name').'/'.$module;
+
+  // copy our generated module
+  $finder = pakeFinder::type('any');
+  pake_mirror($finder, $tmp_dir.'/auto'.ucfirst($module), $moduleDir);
+
+  // change module name
+  pake_replace_tokens($moduleDir.'/actions/actions.class.php', getcwd(), '', '', array('auto'.ucfirst($module) => $module));
+
+  try
+  {
+    $author_name = $task->get_property('author', 'symfony');
+  }
+  catch (pakeException $e)
+  {
+    $author_name = 'Your name here';
+  }
+
+  $constants = array(
+    'PROJECT_NAME' => $task->get_property('name', 'symfony'),
+    'APP_NAME'     => $app,
+    'MODULE_NAME'  => $module,
+    'MODEL_CLASS'  => $model_class,
+    'AUTHOR_NAME'  => $author_name,
+  );
+
+  // customize php and yml files
+  $finder = pakeFinder::type('file')->name('*.php', '*.yml');
+  pake_replace_tokens($finder, $moduleDir, '##', '##', $constants);
+
+  // create basic test
+  pake_copy(sfConfig::get('sf_symfony_data_dir').'/skeleton/module/test/actionsTest.php', $sf_root_dir.'/test/functional/'.$app.'/'.$module.'ActionsTest.php');
+
+  // customize test file
+  pake_replace_tokens($module.'ActionsTest.php', $sf_root_dir.'/test/functional/'.$app, '##', '##', $constants);
+
+  // delete temp files
+  $finder = pakeFinder::type('any');
+  pake_remove($finder, $tmp_dir);
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/propel/builder/SfObjectBuilder.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/propel/builder/SfObjectBuilder.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/propel/builder/SfObjectBuilder.php	(revision 19)
@@ -0,0 +1,341 @@
+<?php
+
+require_once 'propel/engine/builder/om/php5/PHP5ObjectBuilder.php';
+
+/*
+ * This file is part of the symfony package.
+ * (c) 2004-2006 Fabien Potencier <fabien.potencier@symfony-project.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * @package    symfony
+ * @subpackage addon
+ * @author     Fabien Potencier <fabien.potencier@symfony-project.com>
+ * @version    SVN: $Id: SfObjectBuilder.php 3493 2007-02-18 09:23:10Z fabien $
+ */
+class SfObjectBuilder extends PHP5ObjectBuilder
+{
+  public function build()
+  {
+    if (!DataModelBuilder::getBuildProperty('builderAddComments'))
+    {
+      return sfToolkit::stripComments(parent::build());
+    }
+    
+    return parent::build();
+  }
+
+  protected function addIncludes(&$script)
+  {
+    if (!DataModelBuilder::getBuildProperty('builderAddIncludes'))
+    {
+      return;
+    }
+
+    parent::addIncludes($script);
+
+    // include the i18n classes if needed
+    if ($this->getTable()->getAttribute('isI18N'))
+    {
+      $relatedTable   = $this->getDatabase()->getTable($this->getTable()->getAttribute('i18nTable'));
+
+      $script .= '
+require_once \''.$this->getFilePath($this->getStubObjectBuilder()->getPackage().'.'.$relatedTable->getPhpName().'Peer').'\';
+require_once \''.$this->getFilePath($this->getStubObjectBuilder()->getPackage().'.'.$relatedTable->getPhpName()).'\';
+';
+    }
+  }
+
+  protected function addClassBody(&$script)
+  {
+    parent::addClassBody($script);
+
+    if ($this->getTable()->getAttribute('isI18N'))
+    {
+      if (count($this->getTable()->getPrimaryKey()) > 1)
+      {
+        throw new Exception('i18n support only works with a single primary key');
+      }
+
+      $this->addCultureAccessorMethod($script);
+      $this->addCultureMutatorMethod($script);
+
+      $this->addI18nMethods($script);
+    }
+
+    if (DataModelBuilder::getBuildProperty('builderAddBehaviors'))
+    {
+      $this->addCall($script);
+    }
+  }
+
+  protected function addCall(&$script)
+  {
+    $script .= "
+
+  public function __call(\$method, \$arguments)
+  {
+    if (!\$callable = sfMixer::getCallable('{$this->getClassname()}:'.\$method))
+    {
+      throw new sfException(sprintf('Call to undefined method {$this->getClassname()}::%s', \$method));
+    }
+
+    array_unshift(\$arguments, \$this);
+
+    return call_user_func_array(\$callable, \$arguments);
+  }
+
+";
+  }
+
+  protected function addAttributes(&$script)
+  {
+    parent::addAttributes($script);
+
+    if ($this->getTable()->getAttribute('isI18N'))
+    {
+      $script .= '
+  /**
+   * The value for the culture field.
+   * @var string
+   */
+  protected $culture;
+';
+    }
+  }
+
+  protected function addCultureAccessorMethod(&$script)
+  {
+    $script .= '
+  public function getCulture()
+  {
+    return $this->culture;
+  }
+';
+  }
+
+  protected function addCultureMutatorMethod(&$script)
+  {
+    $script .= '
+  public function setCulture($culture)
+  {
+    $this->culture = $culture;
+  }
+';
+  }
+
+  protected function addI18nMethods(&$script)
+  {
+    $table = $this->getTable();
+    $pks = $table->getPrimaryKey();
+    $pk = $pks[0]->getPhpName();
+
+    foreach ($table->getReferrers() as $fk)
+    {
+      $tblFK = $fk->getTable();
+      if ($tblFK->getName() == $table->getAttribute('i18nTable'))
+      {
+        $className = $tblFK->getPhpName();
+        $culture = '';
+        $culture_peername = '';
+        foreach ($tblFK->getColumns() as $col)
+        {
+          if (("true" === strtolower($col->getAttribute('isCulture'))))
+          {
+            $culture = $col->getPhpName();
+            $culture_peername = PeerBuilder::getColumnName($col, $className);
+          }
+        }
+
+        foreach ($tblFK->getColumns() as $col)
+        {
+          if ($col->isPrimaryKey()) continue;
+
+          $script .= '
+  public function get'.$col->getPhpName().'()
+  {
+    $obj = $this->getCurrent'.$className.'();
+
+    return ($obj ? $obj->get'.$col->getPhpName().'() : null);
+  }
+
+  public function set'.$col->getPhpName().'($value)
+  {
+    $this->getCurrent'.$className.'()->set'.$col->getPhpName().'($value);
+  }
+';
+        }
+
+$script .= '
+  protected $current_i18n = array();
+
+  public function getCurrent'.$className.'()
+  {
+    if (!isset($this->current_i18n[$this->culture]))
+    {
+      $obj = '.$className.'Peer::retrieveByPK($this->get'.$pk.'(), $this->culture);
+      if ($obj)
+      {
+        $this->set'.$className.'ForCulture($obj, $this->culture);
+      }
+      else
+      {
+        $this->set'.$className.'ForCulture(new '.$className.'(), $this->culture);
+        $this->current_i18n[$this->culture]->set'.$culture.'($this->culture);
+      }
+    }
+
+    return $this->current_i18n[$this->culture];
+  }
+
+  public function set'.$className.'ForCulture($object, $culture)
+  {
+    $this->current_i18n[$culture] = $object;
+    $this->add'.$className.'($object);
+  }
+';
+      }
+    }
+  }
+
+  protected function addDoSave(&$script)
+  {
+    $tmp = '';
+    parent::addDoSave($tmp);
+    // add autosave to i18n object even if the base object is not changed
+    $tmp = preg_replace_callback('#(\$this\->(.+?)\->isModified\(\))#', array($this, 'i18nDoSaveCallback'), $tmp);
+
+    $script .= $tmp;
+  }
+
+  private function i18nDoSaveCallback($matches)
+  {
+    $value = $matches[1];
+
+    // get the related class to see if it is a i18n one
+    $table = $this->getTable();
+    $column = null;
+    foreach ($table->getForeignKeys() as $fk)
+    {
+      if ($matches[2] == $this->getFKVarName($fk))
+      {
+        $column = $fk;
+        break;
+      }
+    }
+    $foreign_table = $this->getDatabase()->getTable($fk->getForeignTableName());
+    if ($foreign_table->getAttribute('isI18N'))
+    {
+      $foreign_tables_i18n_table = $this->getDatabase()->getTable($foreign_table->getAttribute('i18nTable'));
+      $value .= ' || $this->'.$matches[2].'->getCurrent'.$foreign_tables_i18n_table->getPhpName().'()->isModified()';
+    }
+
+    return $value;
+  }
+
+  protected function addDelete(&$script)
+  {
+    $tmp = '';
+    parent::addDelete($tmp);
+
+    if (DataModelBuilder::getBuildProperty('builderAddBehaviors'))
+    {
+      // add sfMixer call
+      $pre_mixer_script = "
+
+    foreach (sfMixer::getCallables('{$this->getClassname()}:delete:pre') as \$callable)
+    {
+      \$ret = call_user_func(\$callable, \$this, \$con);
+      if (\$ret)
+      {
+        return;
+      }
+    }
+
+";
+      $post_mixer_script = "
+
+    foreach (sfMixer::getCallables('{$this->getClassname()}:delete:post') as \$callable)
+    {
+      call_user_func(\$callable, \$this, \$con);
+    }
+
+";
+      $tmp = preg_replace('/{/', '{'.$pre_mixer_script, $tmp, 1);
+      $tmp = preg_replace('/}\s*$/', $post_mixer_script.'  }', $tmp);
+    }
+
+    // update current script
+    $script .= $tmp;
+  }
+
+  protected function addSave(&$script)
+  {
+    $tmp = '';
+    parent::addSave($tmp);
+
+    // add support for created_(at|on) and updated_(at|on) columns
+    $date_script = '';
+    $updated = false;
+    $created = false;
+    foreach ($this->getTable()->getColumns() as $col)
+    {
+      $clo = strtolower($col->getName());
+
+      if (!$updated && in_array($clo, array('updated_at', 'updated_on')))
+      {
+        $updated = true;
+        $date_script .= "
+    if (\$this->isModified() && !\$this->isColumnModified(".$this->getColumnConstant($col)."))
+    {
+      \$this->set".$col->getPhpName()."(time());
+    }
+";
+      }
+      else if (!$created && in_array($clo, array('created_at', 'created_on')))
+      {
+        $created = true;
+        $date_script .= "
+    if (\$this->isNew() && !\$this->isColumnModified(".$this->getColumnConstant($col)."))
+    {
+      \$this->set".$col->getPhpName()."(time());
+    }
+";
+      }
+    }
+    $tmp = preg_replace('/{/', '{'.$date_script, $tmp, 1);
+
+    if (DataModelBuilder::getBuildProperty('builderAddBehaviors'))
+    {
+      // add sfMixer call
+      $pre_mixer_script = "
+
+    foreach (sfMixer::getCallables('{$this->getClassname()}:save:pre') as \$callable)
+    {
+      \$affectedRows = call_user_func(\$callable, \$this, \$con);
+      if (is_int(\$affectedRows))
+      {
+        return \$affectedRows;
+      }
+    }
+
+";
+      $post_mixer_script = <<<EOF
+
+    foreach (sfMixer::getCallables('{$this->getClassname()}:save:post') as \$callable)
+    {
+      call_user_func(\$callable, \$this, \$con, \$affectedRows);
+    }
+
+EOF;
+      $tmp = preg_replace('/{/', '{'.$pre_mixer_script, $tmp, 1);
+      $tmp = preg_replace('/(\$con\->commit\(\);)/', '$1'.$post_mixer_script, $tmp);
+    }
+
+    // update current script
+    $script .= $tmp;
+  }
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/propel/builder/SfPeerBuilder.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/propel/builder/SfPeerBuilder.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/propel/builder/SfPeerBuilder.php	(revision 19)
@@ -0,0 +1,358 @@
+<?php
+
+require_once 'propel/engine/builder/om/php5/PHP5PeerBuilder.php';
+
+/*
+ * This file is part of the symfony package.
+ * (c) 2004-2006 Fabien Potencier <fabien.potencier@symfony-project.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * @package    symfony
+ * @subpackage addon
+ * @author     Fabien Potencier <fabien.potencier@symfony-project.com>
+ * @version    SVN: $Id: SfPeerBuilder.php 3663 2007-03-23 13:43:19Z fabien $
+ */
+class SfPeerBuilder extends PHP5PeerBuilder
+{
+  public function build()
+  {
+    if (!DataModelBuilder::getBuildProperty('builderAddComments'))
+    {
+      return sfToolkit::stripComments(parent::build());
+    }
+
+    return parent::build();
+  }
+
+  protected function addIncludes(&$script)
+  {
+    if (!DataModelBuilder::getBuildProperty('builderAddIncludes'))
+    {
+      return;
+    }
+
+    parent::addIncludes($script);
+  }
+
+  protected function addSelectMethods(&$script)
+  {
+    parent::addSelectMethods($script);
+
+    if ($this->getTable()->getAttribute('isI18N'))
+    {
+      $this->addDoSelectWithI18n($script);
+    }
+  }
+
+  protected function addDoSelectWithI18n(&$script)
+  {
+    $table = $this->getTable();
+    $thisTableObjectBuilder = OMBuilder::getNewObjectBuilder($table);
+    $className = $table->getPhpName();
+    $pks = $table->getPrimaryKey();
+    $pk = PeerBuilder::getColumnName($pks[0], $className);
+
+    // get i18n table name and culture column name
+    foreach ($table->getReferrers() as $fk)
+    {
+      $tblFK = $fk->getTable();
+      if ($tblFK->getName() == $table->getAttribute('i18nTable'))
+      {
+        $i18nClassName = $tblFK->getPhpName();
+        // FIXME
+        $i18nPeerClassName = $i18nClassName.'Peer';
+
+        $i18nTable = $table->getDatabase()->getTable($tblFK->getName());
+        $i18nTableObjectBuilder = OMBuilder::getNewObjectBuilder($i18nTable);
+        $i18nTablePeerBuilder = OMBuilder::getNewPeerBuilder($i18nTable);
+        $i18nPks = $i18nTable->getPrimaryKey();
+        $i18nPk = PeerBuilder::getColumnName($i18nPks[0], $i18nClassName);
+
+        $culturePhpName = '';
+        $cultureColumnName = '';
+        foreach ($tblFK->getColumns() as $col)
+        {
+          if (("true" === strtolower($col->getAttribute('isCulture'))))
+          {
+            $culturePhpName = $col->getPhpName();
+            $cultureColumnName = PeerBuilder::getColumnName($col, $i18nClassName);
+          }
+        }
+      }
+    }
+
+    $script .= "
+
+  /**
+   * Selects a collection of $className objects pre-filled with their i18n objects.
+   *
+   * @return array Array of $className objects.
+   * @throws PropelException Any exceptions caught during processing will be
+   *     rethrown wrapped into a PropelException.
+   */
+  public static function doSelectWithI18n(Criteria \$c, \$culture = null, \$con = null)
+  {
+    if (\$culture === null)
+    {
+      \$culture = sfContext::getInstance()->getUser()->getCulture();
+    }
+
+    // Set the correct dbName if it has not been overridden
+    if (\$c->getDbName() == Propel::getDefaultDB())
+    {
+      \$c->setDbName(self::DATABASE_NAME);
+    }
+
+    ".$this->getPeerClassname()."::addSelectColumns(\$c);
+    \$startcol = (".$this->getPeerClassname()."::NUM_COLUMNS - ".$this->getPeerClassname()."::NUM_LAZY_LOAD_COLUMNS) + 1;
+
+    ".$i18nPeerClassName."::addSelectColumns(\$c);
+
+    \$c->addJoin(".$pk.", ".$i18nPk.");
+    \$c->add(".$cultureColumnName.", \$culture);
+
+    \$rs = ".$this->basePeerClassname."::doSelect(\$c, \$con);
+    \$results = array();
+
+    while(\$rs->next()) {
+";
+            if ($table->getChildrenColumn()) {
+              $script .= "
+      \$omClass = ".$this->getPeerClassname()."::getOMClass(\$rs, 1);
+";
+            } else {
+              $script .= "
+      \$omClass = ".$this->getPeerClassname()."::getOMClass();
+";
+            }
+            $script .= "
+      \$cls = Propel::import(\$omClass);
+      \$obj1 = new \$cls();
+      \$obj1->hydrate(\$rs);
+      \$obj1->setCulture(\$culture);
+";
+//            if ($i18nTable->getChildrenColumn()) {
+              $script .= "
+      \$omClass = ".$i18nTablePeerBuilder->getPeerClassname()."::getOMClass(\$rs, \$startcol);
+";
+//            } else {
+//              $script .= "
+//      \$omClass = ".$i18nTablePeerBuilder->getPeerClassname()."::getOMClass();
+//";
+//            }
+
+            $script .= "
+      \$cls = Propel::import(\$omClass);
+      \$obj2 = new \$cls();
+      \$obj2->hydrate(\$rs, \$startcol);
+
+      \$obj1->set".$i18nClassName."ForCulture(\$obj2, \$culture);
+      \$obj2->set".$className."(\$obj1);
+
+      \$results[] = \$obj1;
+    }
+    return \$results;
+  }
+";
+  }
+
+  protected function addDoValidate(&$script)
+  {
+      $tmp = '';
+      parent::addDoValidate($tmp);
+
+      $script .= str_replace("return {$this->basePeerClassname}::doValidate(".$this->getPeerClassname()."::DATABASE_NAME, ".$this->getPeerClassname()."::TABLE_NAME, \$columns);\n",
+        "\$res =  {$this->basePeerClassname}::doValidate(".$this->getPeerClassname()."::DATABASE_NAME, ".$this->getPeerClassname()."::TABLE_NAME, \$columns);\n".
+        "    if (\$res !== true) {\n".
+        "        \$request = sfContext::getInstance()->getRequest();\n".
+        "        foreach (\$res as \$failed) {\n".
+        "            \$col = ".$this->getPeerClassname()."::translateFieldname(\$failed->getColumn(), BasePeer::TYPE_COLNAME, BasePeer::TYPE_PHPNAME);\n".
+        "            \$request->setError(\$col, \$failed->getMessage());\n".
+        "        }\n".
+        "    }\n\n".
+        "    return \$res;\n", $tmp);
+  }
+
+  protected function addDoSelectStmt(&$script)
+  {
+    $tmp = '';
+    parent::addDoSelectStmt($tmp);
+
+    if (DataModelBuilder::getBuildProperty('builderAddBehaviors'))
+    {
+      $mixer_script = "
+
+    foreach (sfMixer::getCallables('{$this->getClassname()}:doSelectStmt:doSelectStmt') as \$callable)
+    {
+      call_user_func(\$callable, '{$this->getClassname()}', \$criteria, \$con);
+    }
+
+";
+      $tmp = preg_replace('/{/', '{'.$mixer_script, $tmp, 1);
+    }
+
+    $script .= $tmp;
+  }
+
+	protected function addDoCountJoin(&$script)
+	{
+		$tmp = '';
+    parent::addDoCountJoin($tmp);
+
+		if (DataModelBuilder::getBuildProperty('builderAddBehaviors'))
+    {
+      $mixer_script = "
+
+    foreach (sfMixer::getCallables('{$this->getClassname()}:doCountJoin:doCountJoin') as \$callable)
+    {
+      call_user_func(\$callable, '{$this->getClassname()}', \$criteria, \$con);
+    }
+
+";
+      $tmp = preg_replace('/public static function doCountJoin.*\(Criteria \$criteria, \$distinct = false, PropelPDO \$con = null\)\n\s*{/', '\0'.$mixer_script, $tmp);
+    }
+
+		$script .= $tmp;
+	}
+
+  protected function addDoSelectJoin(&$script)
+  {
+    $tmp = '';
+    parent::addDoSelectJoin($tmp);
+
+    if (DataModelBuilder::getBuildProperty('builderAddBehaviors'))
+    {
+      $mixer_script = "
+
+    foreach (sfMixer::getCallables('{$this->getClassname()}:doSelectJoin:doSelectJoin') as \$callable)
+    {
+      call_user_func(\$callable, '{$this->getClassname()}', \$c, \$con);
+    }
+
+";
+      $tmp = preg_replace('/public static function doSelectJoin.*\(Criteria \$c, \$con = null\)\n\s*{/', '\0'.$mixer_script, $tmp);
+    }
+
+    $script .= $tmp;
+  }
+
+  protected function addDoSelectJoinAll(&$script)
+  {
+    $tmp = '';
+    parent::addDoSelectJoinAll($tmp);
+
+    if (DataModelBuilder::getBuildProperty('builderAddBehaviors'))
+    {
+      $mixer_script = "
+
+    foreach (sfMixer::getCallables('{$this->getClassname()}:doSelectJoinAll:doSelectJoinAll') as \$callable)
+    {
+      call_user_func(\$callable, '{$this->getClassname()}', \$c, \$con);
+    }
+
+";
+      $tmp = preg_replace('/{/', '{'.$mixer_script, $tmp, 1);
+    }
+
+    $script .= $tmp;
+  }
+  
+  protected function addDoSelectJoinAllExcept(&$script)
+  {
+    $tmp = '';
+    parent::addDoSelectJoinAllExcept($tmp);
+
+    if (DataModelBuilder::getBuildProperty('builderAddBehaviors'))
+    {
+      $mixer_script = "
+
+    foreach (sfMixer::getCallables('{$this->getClassname()}:doSelectJoinAllExcept:doSelectJoinAllExcept') as \$callable)
+    {
+      call_user_func(\$callable, '{$this->getClassname()}', \$c, \$con);
+    }
+
+";
+      $tmp = preg_replace('/public static function doSelectJoinAllExcept.*\(Criteria \$c, \$con = null\)\n\s*{/', '\0'.$mixer_script, $tmp);
+    }
+
+    $script .= $tmp;
+  }
+
+  protected function addDoUpdate(&$script)
+  {
+    $tmp = '';
+    parent::addDoUpdate($tmp);
+
+    if (DataModelBuilder::getBuildProperty('builderAddBehaviors'))
+    {
+      // add sfMixer call
+      $pre_mixer_script = "
+
+    foreach (sfMixer::getCallables('{$this->getClassname()}:doUpdate:pre') as \$callable)
+    {
+      \$ret = call_user_func(\$callable, '{$this->getClassname()}', \$values, \$con);
+      if (false !== \$ret)
+      {
+        return \$ret;
+      }
+    }
+
+";
+
+      $post_mixer_script = "
+
+    foreach (sfMixer::getCallables('{$this->getClassname()}:doUpdate:post') as \$callable)
+    {
+      call_user_func(\$callable, '{$this->getClassname()}', \$values, \$con, \$ret);
+    }
+
+    return \$ret;
+";
+
+      $tmp = preg_replace('/{/', '{'.$pre_mixer_script, $tmp, 1);
+      $tmp = preg_replace("/\t\treturn ([^}]+)/", "\t\t\$ret = $1".$post_mixer_script.'  ', $tmp, 1);
+    }
+
+    $script .= $tmp;
+  }
+
+  protected function addDoInsert(&$script)
+  {
+    $tmp = '';
+    parent::addDoInsert($tmp);
+
+    if (DataModelBuilder::getBuildProperty('builderAddBehaviors'))
+    {
+      // add sfMixer call
+      $pre_mixer_script = "
+
+    foreach (sfMixer::getCallables('{$this->getClassname()}:doInsert:pre') as \$callable)
+    {
+      \$ret = call_user_func(\$callable, '{$this->getClassname()}', \$values, \$con);
+      if (false !== \$ret)
+      {
+        return \$ret;
+      }
+    }
+
+";
+
+      $post_mixer_script = "
+    foreach (sfMixer::getCallables('{$this->getClassname()}:doInsert:post') as \$callable)
+    {
+      call_user_func(\$callable, '{$this->getClassname()}', \$values, \$con, \$pk);
+    }
+
+    return";
+
+      $tmp = preg_replace('/{/', '{'.$pre_mixer_script, $tmp, 1);
+      $tmp = preg_replace("/\t\treturn/", "\t\t".$post_mixer_script, $tmp, 1);
+    }
+
+    $script .= $tmp;
+  }
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/propel/database/sfPropel13Database.class.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/propel/database/sfPropel13Database.class.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/propel/database/sfPropel13Database.class.php	(revision 19)
@@ -0,0 +1,245 @@
+<?php
+/*
+ * This file is part of the sfPropel13Plugin package.
+ * (c) 2007 Joshua May <notjosh@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+class sfPropel13Database extends sfDatabase
+{
+  static protected $config = array();
+  
+  /**
+   * @see sfDatabase::initialize()
+   */
+  public function initialize($parameters = null, $name = 'propel')
+  {
+    parent::initialize($parameters);
+    if (!$this->hasParameter('datasource'))
+    {
+      $this->setParameter('datasource', $name);
+    }
+
+    $this->addConfig();
+
+    $is_default = $this->getParameter('is_default', false);
+
+    // first defined if none listed as default
+    if ($is_default || count(self::$config['propel']['datasources']) == 1)
+    {
+      $this->setDefaultConfig();
+    }
+  	
+    // setup propel
+    if (null !== $this->getParameter('instance-pooling'))
+    {
+      $instancePooling = $this->getParameter('instance-pooling');
+      if (is_bool($instancePooling))
+      {
+      	if ($instancePooling)
+      	{
+      	  Propel::enableInstancePooling();
+      	}
+      	else
+      	{
+      	  Propel::disableInstancePooling();
+      	}
+      }
+    }
+
+    Propel::setConfiguration(self::$config);
+    Propel::initialize();
+  }
+  
+  public function setDefaultConfig()
+  {
+    self::$config['propel']['datasources']['default'] = $this->getParameter('datasource');
+  }
+
+  public function addConfig()
+  {
+  	if ($dsn = $this->getParameter('dsn'))
+  	{
+  	  $params = array();
+
+  		// check for non-pdo dsn
+  		if (false !== strpos($dsn, '//'))
+  		{
+        // derive pdo dsn (etc) from old style dsn
+        $params = $this->parseOldDsn($dsn);
+
+        $dsn = $params['phptype'] . ':dbname=' . $params['database'] . ';host=' . $params['hostspec'];
+        $this->setParameter('dsn', $dsn);
+      }
+      else
+      {
+        $params = $this->parseDsn($dsn);
+      }
+
+      $options = array('phptype', 'hostspec', 'database', 'username', 'password', 'port', 'protocol', 'encoding', 'persistent');
+      foreach ($options as $option)
+      {
+        if (!$this->getParameter($option) && isset($params[$option]))
+        {
+          $this->setParameter($option, $params[$option]);
+        }
+      }
+  	}
+
+    self::$config['propel']['datasources'][$this->getParameter('datasource')] =
+      array(
+        'adapter'      => $this->getParameter('phptype'),
+        'connection'   =>
+        array(
+          'dsn' => $this->getParameter('dsn'),
+          'user' => $this->getParameter('username'),
+          'password' => $this->getParameter('password'),
+
+          // not sure which (if any) of these are still relevant now that we use pdo.. doesn't break if i leave them though..?
+          'phptype'    => $this->getParameter('phptype'),
+          'hostspec'   => $this->getParameter('hostspec'),
+          'port'       => $this->getParameter('port'),
+          'encoding'   => $this->getParameter('encoding'),
+          'persistent' => $this->getParameter('persistent'),
+          'protocol'   => $this->getParameter('protocol'),
+        ),
+      );
+  }
+
+  /**
+   * parse the new styled dsn, really i only want to grab the 'phptype' out
+   *
+   * @param string $dsn
+   * @return array
+   */
+  private function parseDsn($dsn)
+  {
+    // i only really need the phptype, for now!
+
+    return array(
+      'phptype' => substr($dsn, 0, strpos($dsn, ':'))
+    );
+  }
+
+  /**
+   * this is the old Creole::parseDSN method, so i can parse old dsn's and connect via pdo still
+   *
+   * @param string $dsn
+   * @return array
+   */
+  private function parseOldDsn($dsn)
+  {
+    if (is_array($dsn))
+    {
+        return $dsn;
+    }
+
+    $parsed = array(
+        'phptype'  => null,
+        'username' => null,
+        'password' => null,
+        'protocol' => null,
+        'hostspec' => null,
+        'port'     => null,
+        'socket'   => null,
+        'database' => null
+    );
+
+    $info = parse_url($dsn);
+
+    if (count($info) === 1)
+    { // if there's only one element in result, then it must be the phptype
+        $parsed['phptype'] = array_pop($info);
+        return $parsed;
+    }
+
+    // some values can be copied directly
+    $parsed['phptype'] = @$info['scheme'];
+    $parsed['username'] = @$info['user'];
+    $parsed['password'] = @$info['pass'];
+    $parsed['port'] = @$info['port'];
+
+    $host = @$info['host'];
+    if (false !== ($pluspos = strpos($host, '+')))
+    {
+      $parsed['protocol'] = substr($host,0,$pluspos);
+
+      if ($parsed['protocol'] === 'unix')
+      {
+        $parsed['socket'] = substr($host,$pluspos+1);
+      }
+      else
+      {
+          $parsed['hostspec'] = substr($host,$pluspos+1);
+      }
+    }
+    else
+    {
+        $parsed['hostspec'] = $host;
+    }
+
+    if (isset($info['path']))
+    {
+        $parsed['database'] = substr($info['path'], 1); // remove first char, which is '/'
+    }
+
+    if (isset($info['query']))
+    {
+      $opts = explode('&', $info['query']);
+      foreach ($opts as $opt)
+      {
+        list($key, $value) = explode('=', $opt);
+
+        if (!isset($parsed[$key]))
+        { // don't allow params overwrite
+          $parsed[$key] = urldecode($value);
+        }
+      }
+    }
+
+    return $parsed;
+  }
+
+  public static function getConfiguration()
+  {
+    return self::$config;
+  }
+
+  public function setConnectionParameter($key, $value)
+  {
+    if ($key == 'host')
+    {
+      $key = 'hostspec';
+    }
+
+    self::$config['propel']['datasources'][$this->getParameter('datasource')]['connection'][$key] = $value;
+    $this->setParameter($key, $value);
+  }
+	
+  /**
+   * Connect to the database.
+   * Stores the PDO connection in $connection
+   *
+   */
+  public function connect()
+  {
+  	$this->connection = Propel::getConnection();
+  }
+
+  /**
+   * Execute the shutdown procedure.
+   *
+   * @return void
+   *
+   * @throws <b>sfDatabaseException</b> If an error occurs while shutting down this database.
+   */
+  public function shutdown()
+  {
+    if ($this->connection !== null)
+    {
+      @$this->connection = null;
+    }
+  }
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/propel/generator/sfPropel13AdminGenerator.class.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/propel/generator/sfPropel13AdminGenerator.class.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/propel/generator/sfPropel13AdminGenerator.class.php	(revision 19)
@@ -0,0 +1,167 @@
+<?php
+/*
+ * This file is part of the sfPropel13Plugin package.
+ * (c) 2007 Joshua May <notjosh@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+class sfPropel13AdminGenerator extends sfPropel13CrudGenerator
+{
+  /**
+   * Initializes the current sfGenerator instance.
+   *
+   * @param sfGeneratorManager A sfGeneratorManager instance
+   */
+  public function initialize($generatorManager)
+  {
+    parent::initialize($generatorManager);
+
+    $this->setGeneratorClass('sfPropelAdmin');
+  }
+
+  public function getAllColumns()
+  {
+    $phpNames = array();
+    foreach ($this->getTableMap()->getColumns() as $column)
+    {
+      $phpNames[] = new sfPropel13AdminColumn($column->getPhpName(), $column);
+    }
+
+    return $phpNames;
+  }
+
+  public function getAdminColumnForField($field, $flag = null)
+  {
+    $phpName = sfInflector::camelize($field);
+
+    return new sfPropel13AdminColumn($phpName, $this->getColumnForPhpName($phpName), $flag);
+  }
+
+  // returns a column phpName or null if none was found
+  public function getColumnForPhpName($phpName)
+  {
+    // search the matching column for this column name
+
+    foreach ($this->getTableMap()->getColumns() as $column)
+    {
+      if ($column->getPhpName() == $phpName)
+      {
+        return $column;
+      }
+    }
+
+    // not a "real" column, so we will simulate one
+    return null;
+  }
+  
+  public function getColumnFilterTag($column, $params = array())
+  {
+    $user_params = $this->getParameterValue('list.fields.'.$column->getName().'.params');
+    $user_params = is_array($user_params) ? $user_params : sfToolkit::stringToArray($user_params);
+    $params      = $user_params ? array_merge($params, $user_params) : $params;
+
+    if ($column->isComponent())
+    {
+      return "get_component('".$this->getModuleName()."', '".$column->getName()."', array('type' => 'list'))";
+    }
+    else if ($column->isPartial())
+    {
+      return "get_partial('".$column->getName()."', array('type' => 'filter', 'filters' => \$filters))";
+    }
+
+    $type = $column->getType();
+
+    $default_value = "isset(\$filters['".$column->getName()."']) ? \$filters['".$column->getName()."'] : null";
+    $unquotedName = 'filters['.$column->getName().']';
+    $name = "'$unquotedName'";
+
+    if ($column->isForeignKey())
+    {
+      $params = $this->getObjectTagParams($params, array('include_blank' => true, 'related_class'=>$this->getRelatedClassName($column), 'text_method'=>'__toString', 'control_name'=>$unquotedName));
+      return "object_select_tag($default_value, null, $params)";
+
+    }
+    else if ($type == PropelColumnTypes::DATE)
+    {
+      // rich=false not yet implemented
+      $params = $this->getObjectTagParams($params, array('rich' => true, 'calendar_button_img' => sfConfig::get('sf_admin_web_dir').'/images/date.png'));
+      return "input_date_range_tag($name, $default_value, $params)";
+    }
+    else if ($type == PropelColumnTypes::TIMESTAMP)
+    {
+      // rich=false not yet implemented
+      $params = $this->getObjectTagParams($params, array('rich' => true, 'withtime' => true, 'calendar_button_img' => sfConfig::get('sf_admin_web_dir').'/images/date.png'));
+      return "input_date_range_tag($name, $default_value, $params)";
+    }
+    else if ($type == PropelColumnTypes::BOOLEAN)
+    {
+      $defaultIncludeCustom = '__("yes or no")';
+
+      $option_params = $this->getObjectTagParams($params, array('include_custom' => $defaultIncludeCustom));
+      $params = $this->getObjectTagParams($params);
+
+      // little hack
+      $option_params = preg_replace("/'".preg_quote($defaultIncludeCustom)."'/", $defaultIncludeCustom, $option_params);
+
+      $options = "options_for_select(array(1 => __('yes'), 0 => __('no')), $default_value, $option_params)";
+
+      return "select_tag($name, $options, $params)";
+    }
+    else if ($type == PropelColumnTypes::CHAR || $type == PropelColumnTypes::VARCHAR || $type == PropelColumnTypes::LONGVARCHAR)
+    {
+      $size = ($column->getSize() < 15 ? $column->getSize() : 15);
+      $params = $this->getObjectTagParams($params, array('size' => $size));
+      return "input_tag($name, $default_value, $params)";
+    }
+    else if ($type == PropelColumnTypes::INTEGER || $type == PropelColumnTypes::TINYINT || $type == PropelColumnTypes::SMALLINT || $type == PropelColumnTypes::BIGINT)
+    {
+      $params = $this->getObjectTagParams($params, array('size' => 7));
+      return "input_tag($name, $default_value, $params)";
+    }
+    else if ($type == PropelColumnTypes::FLOAT || $type == PropelColumnTypes::DOUBLE || $type == PropelColumnTypes::DECIMAL || $type == PropelColumnTypes::NUMERIC || $type == PropelColumnTypes::REAL)
+    {
+      $params = $this->getObjectTagParams($params, array('size' => 7));
+      return "input_tag($name, $default_value, $params)";
+    }
+    else
+    {
+      $params = $this->getObjectTagParams($params, array('disabled' => true));
+      return "input_tag($name, $default_value, $params)";
+    }
+  }
+}
+
+class sfPropel13AdminColumn extends sfAdminColumn
+{
+  // propel to creole type conversion
+  private static $propelToCreole = array(
+    PropelColumnTypes::BOOLEAN       => CreoleTypes::BOOLEAN,
+    PropelColumnTypes::BINARY        => CreoleTypes::BLOB,
+    PropelColumnTypes::BIGINT        => CreoleTypes::BIGINT,
+    PropelColumnTypes::BLOB          => CreoleTypes::BLOB,
+    PropelColumnTypes::CHAR          => CreoleTypes::CHAR,
+    PropelColumnTypes::CLOB          => CreoleTypes::CLOB,
+    PropelColumnTypes::DATE          => CreoleTypes::DATE,
+    PropelColumnTypes::DECIMAL       => CreoleTypes::DECIMAL,
+    PropelColumnTypes::DOUBLE        => CreoleTypes::DOUBLE,
+    PropelColumnTypes::FLOAT         => CreoleTypes::FLOAT,
+    PropelColumnTypes::INTEGER       => CreoleTypes::INTEGER,
+    PropelColumnTypes::LONGVARBINARY => CreoleTypes::LONGVARBINARY,
+    PropelColumnTypes::LONGVARCHAR   => CreoleTypes::TEXT,
+    PropelColumnTypes::NUMERIC       => CreoleTypes::NUMERIC,
+    PropelColumnTypes::REAL          => CreoleTypes::REAL,
+    PropelColumnTypes::SMALLINT      => CreoleTypes::SMALLINT,
+    PropelColumnTypes::TIMESTAMP     => CreoleTypes::TIMESTAMP,
+    PropelColumnTypes::TIME          => CreoleTypes::TIME,
+    PropelColumnTypes::TINYINT       => CreoleTypes::TINYINT,
+    PropelColumnTypes::VARCHAR       => CreoleTypes::VARCHAR,
+    PropelColumnTypes::VARBINARY     => CreoleTypes::VARBINARY
+  );
+  
+  public function getCreoleType()
+  {
+    return $this->column ? self::$propelToCreole[$this->column->getType()] : null;
+  }
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/propel/generator/sfPropel13CrudGenerator.class.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/propel/generator/sfPropel13CrudGenerator.class.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/propel/generator/sfPropel13CrudGenerator.class.php	(revision 19)
@@ -0,0 +1,141 @@
+<?php
+/*
+ * This file is part of the sfPropel13Plugin package.
+ * (c) 2007 Joshua May <notjosh@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+class sfPropel13CrudGenerator extends sfPropelCrudGenerator
+{
+  public function getColumnEditTag($column, $params = array())
+  {
+    // user defined parameters
+    $user_params = $this->getParameterValue('edit.fields.'.$column->getName().'.params');
+    $user_params = is_array($user_params) ? $user_params : sfToolkit::stringToArray($user_params);
+    $params      = $user_params ? array_merge($params, $user_params) : $params;
+
+    if ($column->isComponent())
+    {
+      return "get_component('".$this->getModuleName()."', '".$column->getName()."', array('type' => 'edit', '{$this->getSingularName()}' => \${$this->getSingularName()}))";
+    }
+    else if ($column->isPartial())
+    {
+      return "get_partial('".$column->getName()."', array('type' => 'edit', '{$this->getSingularName()}' => \${$this->getSingularName()}))";
+    }
+
+    // default control name
+    $params = array_merge(array('control_name' => $this->getSingularName().'['.$column->getName().']'), $params);
+
+    // default parameter values
+    $type = $column->getType();
+    if ($type == PropelColumnTypes::DATE)
+    {
+      $params = array_merge(array('rich' => true, 'calendar_button_img' => sfConfig::get('sf_admin_web_dir').'/images/date.png'), $params);
+    }
+    else if ($type == PropelColumnTypes::TIMESTAMP)
+    {
+      $params = array_merge(array('rich' => true, 'withtime' => true, 'calendar_button_img' => sfConfig::get('sf_admin_web_dir').'/images/date.png'), $params);
+    }
+
+    // user sets a specific tag to use
+    if ($inputType = $this->getParameterValue('edit.fields.'.$column->getName().'.type'))
+    {
+      if ($inputType == 'plain')
+      {
+        return $this->getColumnListTag($column, $params);
+      }
+      else
+      {
+        return $this->getPHPObjectHelper($inputType, $column, $params);
+      }
+    }
+
+    // guess the best tag to use with column type
+    return $this->getCrudColumnEditTag($column, $params);
+  }
+  
+  public function getCrudColumnEditTag($column, $params = array())
+  {
+    $type = $column->getType();
+
+    if ($column->isForeignKey())
+    {
+      if (!$column->isNotNull() && !isset($params['include_blank']))
+      {
+        $params['include_blank'] = true;
+      }
+
+      return $this->getPHPObjectHelper('select_tag', $column, $params, array('related_class' => $this->getRelatedClassName($column)));
+    }
+    else if ($type == PropelColumnTypes::DATE)
+    {
+      // rich=false not yet implemented
+      return $this->getPHPObjectHelper('input_date_tag', $column, $params, array('rich' => true));
+    }
+    else if ($type == PropelColumnTypes::TIMESTAMP)
+    {
+      // rich=false not yet implemented
+      return $this->getPHPObjectHelper('input_date_tag', $column, $params, array('rich' => true, 'withtime' => true));
+    }
+    else if ($type == PropelColumnTypes::BOOLEAN)
+    {
+      return $this->getPHPObjectHelper('checkbox_tag', $column, $params);
+    }
+    else if ($type == PropelColumnTypes::CHAR || $type == PropelColumnTypes::VARCHAR)
+    {
+      $size = ($column->getSize() > 20 ? ($column->getSize() < 80 ? $column->getSize() : 80) : 20);
+      return $this->getPHPObjectHelper('input_tag', $column, $params, array('size' => $size));
+    }
+    else if ($type == PropelColumnTypes::INTEGER || $type == PropelColumnTypes::TINYINT || $type == PropelColumnTypes::SMALLINT || $type == PropelColumnTypes::BIGINT)
+    {
+      return $this->getPHPObjectHelper('input_tag', $column, $params, array('size' => 7));
+    }
+    else if ($type == PropelColumnTypes::FLOAT || $type == PropelColumnTypes::DOUBLE || $type == PropelColumnTypes::DECIMAL || $type == PropelColumnTypes::NUMERIC || $type == PropelColumnTypes::REAL)
+    {
+      return $this->getPHPObjectHelper('input_tag', $column, $params, array('size' => 7));
+    }
+    else if ($type == PropelColumnTypes::CLOB || $type == PropelColumnTypes::LONGVARCHAR)
+    {
+      return $this->getPHPObjectHelper('textarea_tag', $column, $params, array('size' => '30x3'));
+    }
+    else
+    {
+      return $this->getPHPObjectHelper('input_tag', $column, $params, array('disabled' => true));
+    }
+  }
+  
+  public function getColumnListTag($column, $params = array())
+  {
+    $user_params = $this->getParameterValue('list.fields.'.$column->getName().'.params');
+    $user_params = is_array($user_params) ? $user_params : sfToolkit::stringToArray($user_params);
+    $params      = $user_params ? array_merge($params, $user_params) : $params;
+
+    $type = $column->getType();
+    
+    $columnGetter = $this->getColumnGetter($column, true);
+
+    if ($column->isComponent())
+    {
+      return "get_component('".$this->getModuleName()."', '".$column->getName()."', array('type' => 'list', '{$this->getSingularName()}' => \${$this->getSingularName()}))";
+    }
+    else if ($column->isPartial())
+    {
+      return "get_partial('".$column->getName()."', array('type' => 'list', '{$this->getSingularName()}' => \${$this->getSingularName()}))";
+    }
+    else if ($type == PropelColumnTypes::DATE || $type == PropelColumnTypes::TIMESTAMP)
+    {
+      $format = isset($params['date_format']) ? $params['date_format'] : ($type == PropelColumnTypes::DATE ? 'D' : 'f');
+      return "($columnGetter !== null && $columnGetter !== '') ? format_date($columnGetter, \"$format\") : ''";
+    }
+    elseif ($type == PropelColumnTypes::BOOLEAN)
+    {
+      return "$columnGetter ? image_tag(sfConfig::get('sf_admin_web_dir').'/images/tick.png') : '&nbsp;'";
+    }
+    else
+    {
+      return "$columnGetter";
+    }
+  }
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/propel/sfPropel13Autoload.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/propel/sfPropel13Autoload.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/propel/sfPropel13Autoload.php	(revision 19)
@@ -0,0 +1,20 @@
+<?php
+/*
+ * This file is part of the sfPropel13Plugin package.
+ * (c) 2007 Joshua May <notjosh@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+require_once 'propel/Propel.php';
+
+if (sfConfig::get('sf_debug') && sfConfig::get('sf_logging_enabled'))
+{
+  // add logger
+  Propel::setLogger(sfPropel13LogWrapper::getInstance());
+}
+
+// propel initialization
+Propel::setConfiguration(sfPropel13Database::getConfiguration());
+Propel::initialize();
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/propel/sfPropel13Data.class.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/propel/sfPropel13Data.class.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/propel/sfPropel13Data.class.php	(revision 19)
@@ -0,0 +1,158 @@
+<?php
+/*
+ * This file is part of the sfPropel13Plugin package.
+ * (c) 2007 Joshua May <notjosh@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * This class is the Propel 1.2 implementation of sfPropelData.  It interacts with the data source
+ * and loads data.
+ *
+ * @package    symfony
+ * @subpackage addon
+ * @author     Fabien Potencier <fabien.potencier@symfony-project.com>
+ * @version    SVN: $Id: sfPropelData.class.php 4940 2007-08-30 14:11:28Z fabien $
+ */
+class sfPropel13Data extends sfPropelData
+{
+
+  /**
+   * @see sfPropelData::loadData()
+   */
+  public function loadData($directory_or_file = null, $connectionName = 'propel')
+  {
+    $fixture_files = $this->getFiles($directory_or_file);
+
+    // wrap all database operations in a single transaction
+    $this->con = Propel::getConnection($connectionName);
+    try
+    {
+      $this->con->beginTransaction();
+
+      $this->doDeleteCurrentData($fixture_files);
+
+      $this->doLoadData($fixture_files);
+
+      $this->con->commit();
+    }
+    catch (Exception $e)
+    {
+      $this->con->rollback();
+      throw $e;
+    }
+  }
+
+  /**
+   * @see sfPropelData::dumpData()
+   */
+  public function dumpData($directory_or_file = null, $tables = 'all', $connectionName = 'propel')
+  {
+    $sameFile = true;
+    if (is_dir($directory_or_file))
+    {
+      // multi files
+      $sameFile = false;
+    }
+    else
+    {
+      // same file
+      // delete file
+    }
+
+    $this->con = Propel::getConnection($connectionName);
+
+    // get tables
+    if ('all' === $tables || is_null($tables))
+    {
+      // load all map builder classes
+      $files = sfFinder::type('file')->name('*MapBuilder.php')->in(sfLoader::getModelDirs());
+      foreach ($files as $file)
+      {
+        $mapBuilderClass = basename($file, '.php');
+        $map = new $mapBuilderClass();
+        $map->doBuild();
+      }
+
+      $dbMap = Propel::getDatabaseMap($connectionName);
+      $tables = array();
+      foreach ($dbMap->getTables() as $table)
+      {
+        $tables[] = $table->getPhpName();
+      }
+    }
+    else if (!is_array($tables))
+    {
+      $tables = array($tables);
+    }
+
+    $dumpData = array();
+
+    // load map classes
+
+    array_walk($tables, array($this, 'loadMapBuilder'));
+
+    $tables = $this->fixOrderingOfForeignKeyData($tables);
+
+    foreach ($tables as $tableName)
+    {
+      $tableMap = $this->maps[$tableName]->getDatabaseMap()->getTable(constant($tableName.'Peer::TABLE_NAME'));
+
+      // get db info
+      $stmt = $this->con->prepare('SELECT * FROM '.constant($tableName.'Peer::TABLE_NAME'));
+      $stmt->execute();
+
+      while ($row = $stmt->fetch())
+      {
+        $pk = $tableName;
+        $values = array();
+        foreach ($tableMap->getColumns() as $column)
+        {
+          $col = strtolower($column->getColumnName());
+          if ($column->isPrimaryKey())
+          {
+            $pk .= '_'.$row[$col];
+          }
+          else if ($column->isForeignKey())
+          {
+            $relatedTable = $this->maps[$tableName]->getDatabaseMap()->getTable($column->getRelatedTableName());
+
+            $values[$col] = $relatedTable->getPhpName().'_'.$row[$col];
+          }
+          else
+          {
+            $values[$col] = $row[$col];
+          }
+        }
+
+        if (!isset($dumpData[$tableName]))
+        {
+          $dumpData[$tableName] = array();
+        }
+
+        $dumpData[$tableName][$pk] = $values;
+      }
+    }
+
+    // save to file(s)
+    if ($sameFile)
+    {
+      file_put_contents($directory_or_file, Spyc::YAMLDump($dumpData));
+    }
+    else
+    {
+      $i = 0;
+      foreach ($tables as $tableName)
+      {
+        if (!isset($dumpData[$tableName]))
+        {
+          continue;
+        }
+
+        file_put_contents(sprintf("%s/%03d-%s.yml", $directory_or_file, ++$i, $tableName), Spyc::YAMLDump(array($tableName => $dumpData[$tableName])));
+      }
+    }
+  }
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/propel/sfPropel13LogWrapper.class.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/propel/sfPropel13LogWrapper.class.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/propel/sfPropel13LogWrapper.class.php	(revision 19)
@@ -0,0 +1,68 @@
+<?php
+
+class sfPropel13LogWrapper
+{
+  protected static $instance = null;
+	
+  public static function getInstance()
+  {
+    if (!sfPropel13LogWrapper::$instance)
+    {
+      // the class exists
+      $class = __CLASS__;
+      sfPropel13LogWrapper::$instance = new $class();
+    }
+
+    return sfPropel13LogWrapper::$instance;
+  }
+  
+  protected function logger()
+  {
+  	return sfLogger::getInstance();
+  }
+
+  public function log($message, $priority = SF_LOG_INFO)
+  {
+    $this->logger()->log('{Propel} ' . $message, $priority);
+  }
+
+  public function emerg($message)
+  {
+    $this->log($message, SF_LOG_EMERG);
+  }
+
+  public function alert($message)
+  {
+    $this->log($message, SF_LOG_ALERT);
+  }
+
+  public function crit($message)
+  {
+    $this->log($message, SF_LOG_CRIT);
+  }
+
+  public function err($message)
+  {
+    $this->log($message, SF_LOG_ERR);
+  }
+
+  public function warning($message)
+  {
+    $this->log($message, SF_LOG_WARNING);
+  }
+
+  public function notice($message)
+  {
+    $this->log($message, SF_LOG_NOTICE);
+  }
+
+  public function info($message)
+  {
+    $this->log($message, SF_LOG_INFO);
+  }
+  
+  public function debug($message)
+  {
+    $this->log($message, SF_LOG_DEBUG);
+  }
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/CHANGELOG
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/CHANGELOG	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/CHANGELOG	(revision 19)
@@ -0,0 +1,194 @@
+                           _________________________
+                           P     H     I     N     G
+
+
+Aut. 21, 2006 - Phing 2.2.0
+
+  * Refactored parser to support many tags as children of base <project> tag (HL)
+
+  * Added new IfTask (HL)
+
+  * Added "spawn" attribute to ExecTask (only applies to *nix)
+
+  * Several bugfixes & behavior imporvements to ExecTask (HL, MR, Ben Gollmer)
+
+  * Bugfixes & refactoring for SVNLastRevisionTask (MR, Knut Urdalen)
+
+  * Fixed reference copy bug (HL, Matthias Pigulla)
+
+  * Added SvnExportTask (MR)
+
+  * Added support for FileList in DeleteTask. (HL)
+
+  * Added support for using setting Properties using CDATA value of <property> tag. (HL)
+
+  * Added ReferenceExistsCondition (Matthias Pigulla)
+
+  * Added Phing::log() static method & integrated PHP error handling with Phing logging (HL)
+
+  * Added new task to run the ionCube Encoder (MR)
+
+  * Added new HTML Tidy filter (HL)
+
+  * Added PhpLintTask (Knut Urdalen)
+
+  * Added XmlLintTask (Knut Urdalen)
+
+  * Added ZendCodeAnalyzerTask (Knut Urdalen)
+  
+  * Removed CoverageFormatter class (MR)
+    NOTE: This changes the usage of the collection of PHPUnit2 code coverage reports, see the
+    updated documentation for the CoverageSetupTask
+  
+  * Added Unzip and Untar tasks contributed by Joakim Bodin
+
+  * [#8, #49] Fixed bugs in TarTask related to including empty directories (HL)
+  
+  * [#44] Fixed bug related to copying empty dirs. (HL)
+  
+  * [#32] Fixed PHPUnit2 tasks to work with PHPUnit2-3.0.0 (MR)
+  
+  * [#31] Fixed bug with using PHPDocumentor 1.3.0RC6 (MR)
+  
+  * [#43] Fixed top-level (no target) IfTask behavior (Matthias Pigulla)
+  
+  * [#41] Removed some lingering E_STRICT errors, bugs with 5.1.x and PHP >= 5.0.5 (HL)
+  
+  * [#25] Fixed 'phing' script to also run on non-bash unix /bin/sh 
+  
+  * Numerous documentation improvements by many members of the community (Thanks!)
+  
+Sept. 18, 2005 - Phing 2.1.1
+
+  * Added support for specifying 4-char mask (e.g. 1777) to ChmodTask. (Hans Lellelid)
+
+  * Added .svn files to default excludes in DirectoryScanner.
+
+  * Updated PHPUnit2 BatchTest to use class detection and non-dot-path loader. (Michiel Rook)
+
+  * Added support for importing non dot-path files (Michiel Rook)
+
+  * Add better error message when build fails with exception (Hans Lellelid)
+
+  * Fixed runtime error when errors were encountered in AppendTask (Hans Lellelid)
+
+
+June 17, 2005 - Phing 2.1.0
+
+  * Renamed File -> PhingFile to avoid namespace collisions (Michiel Rook)
+
+  * Add ZipTask to create .zip files (Michiel Rook)
+
+  * Removed redudant logging of build errors in Phing::start() (Michiel Rook)
+
+  * Added tasks to execute PHPUnit2 testsuites and generate coverage and
+    test reports. (Michiel Rook, Sebastian Bergmann)
+
+  * Added SvnLastRevisionTask that stores the number of the last revision
+    of a workingcopy in a property. (Michiel Rook)
+
+  * Added MailTask that sends a message by mail() (Michiel Rook, contributed by Francois Harvey)
+
+  * New IncludePathTask (<includepath/>) for adding values to PHP's include_path. (Hans Lellelid)
+
+  * Fix to Phing::import() to *not* attempt to invoke __autoload() in class_exists() check. (Hans Lellelid)
+
+  * Fixed AppendTask to allow use of only <fileset> as source. (Hans Lellelid)
+
+  * Removed dependency on posix, by changing posix_uname to php_uname if needed. (Christian Stocker)
+
+  * Fixed issues: (Michiel Rook)
+    11  ExtendedFileStream does not work on Windows
+    12  CoverageFormatter problem on Windows
+    13  DOMElement warnings in PHPUnit2 tasks
+    14  RuntimeException conflicts with SPL class
+    15  It is not possible to execute it with PHP5.1
+    16  Add Passthru option to ExecTask
+    17  Blank list on foreach task will loop once
+    19  Problem with <formatter outfile="...">
+    20  Phpunit2report missing XSL stylesheets
+    21  Warnings when output dir does not exist in PHPUnit2Report
+
+Oct 16, 2004 - Phing 2.0.0
+  * Minor fixes to make Phing run under E_STRICT/PHP5.
+  * Fix to global/system properties not being set in project. (Matt Zandstra)
+  * Fixes to deprecated return by reference issues w/ PHP5.0.0
+
+June 8, 2004 - Phing 2.0.0b3
+  * Brought up-to-date w/ PHP5.0.0RC3
+  * Fixed several bugs in ForeachTask
+  * Fixed runtime errors and incomplete inheriting of properties in PhingTask
+  * Added <fileset> support to AppendTask
+
+March 19, 2004 - Phing 2.0.0b2
+
+  * Brought up-to-date w/ PHP5.0.0RC1 (Hans)
+  * Fixed bug in seting XSLT params using XSLTask (Hans, Jeff Moss)
+  * Fixed PHPUnit test framework for PHPUnit-2.0.0alpha3
+  * Added "Adhoc" tasks, which allow for defining PHP task or type classes within the
+  buildfile. (Hans)
+  * Added PhpEvalTask which allows property values to be set to simple PHP evaluations or
+  the results of function/method calls. (Hans)
+  * Added new phing.listener.PearLogger listener (logger).  Also, the -logfile arg is now
+  supported. (Hans)
+  * Fixed broken ForeachTask task.  (Manuel)
+
+Dec 24, 2003 - Phing 2.0.0b1
+
+  * Added PEAR installation framework & ability to build Phing into PEAR package.
+  * Added TarTask using PEAR Archive_Tar
+  * Added PearPackageTask which creates a PEAR package.xml (using PEAR_PackageFileManager).
+  * Added ResolvePathTask which converts relative paths into absolute paths.
+  * Removed System class, due to namespace collision w/ PEAR.
+  * Basic "working?" tests performed with all selectors.
+  * Added selectors:  TypeSelector, ContainsRegexpSelector
+  * CreoleSQLExec task is now operational.
+  * Corrected non-fatal bugs in: DeleteTask, ReflexiveTask
+  * All core Phing classes now in PHP5 syntax (no "var" used, etc.)
+  * CopyTask will not stop build execution if a file cannot be copied (will log and
+  continue to next file).
+  * New abstract MatchingTask task makes it easier to create your own tasks that use
+  selectors.
+  * Removed redundant calls in DirectoryScanner (<fileset> scanning now much faster).
+  * Fixed fatal errors in File::equals()
+
+Nov 24, 2003 - Phing 2.0.0a2
+
+  * Fixed ReplaceTokens filter to correctly replace matched tokens
+  * Changed "project.basedir" property to be absolute path of basedir
+  * Made IntrospectionHelper more tollerant of add*() and addConfigured*() signatures
+  * New CvsTask and CvsPassTask for working with CVS repositories
+  * New TranslateGettext filter substitutes _("hello!") with "hola!" / "bonjour!" / etc.
+  * More consistent use of classhints to enable auto-casting by IntrospectionHelper
+  * Fixed infinite loop bug in FileUtils::normalize() for paths containing "/./"
+  * Fixed bug in CopyFile/fileset that caused termination of copy operation on encounter
+  of unreadable file
+
+Nov 6, 20003 - Phing 2.0.0a1
+
+  * First release of Phing 2, an extensive rewrite and upgrade.
+  * Refactored much of codebase, using new PHP5 features (e.g. Interfaces, Exceptions!)
+  * Many, many, many bugfixes to existing functionality
+  * Restructuring for more intuitive directory layout, change the parser class names.
+  * Introduction of new tasks: AppendTask, ReflexiveTask, ExitTask, Input, PropertyPrompt
+  * Introduction of new types: Path, FileList, DirSet, selectors, conditions
+  * Introduction of new filters: ReplaceRegexp
+  * Introduction of new logger: AnsiColorLogger
+  * Many features from ANT 1.5 added to existing Tasks/Types
+  * New "Register Slot" functionality allows for tracking "inner" dynamic variables.
+
+May 15 2003 - Phing 1.0-rc2
+
+  * Many bug fixes
+  * Several new system tasks introduced
+
+
+March 06 2003 - Phing 1.0-rc1
+  * Release candidate 1
+
+
+October 15 2002 - Phing 1.0-pre1
+  * Initial pre-release
+
+
+--$Id: CHANGELOG 123 2006-09-14 20:19:08Z mrook $
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/CREDITS
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/CREDITS	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/CREDITS	(revision 19)
@@ -0,0 +1,45 @@
+                         _________________________
+                         P     H     I     N     G
+
+  New PHP5 PHING/2 Development
+  ----------------------------
+    
+  Hans Lellelid <hans@xmpl.org>
+  David Giffin <david@giffin.org>
+  Michiel Rook <michiel.rook@gmail.com>
+  Sebastian Bergmann <sb@sebastian-bergmann.de>
+
+  If you've done work on phing and you are not listed here, please feel free
+  to add yourself.
+						 
+  Original PHING/1 Development
+  -----------------------------
+
+  Andreas Aderhold <andi@binarycloud.com>
+  Alex Black <enigma@turingstudio.com>
+  Albert Lash <alash@plateauinnovation.com>
+  Charlie Killian <charlie@tizac.com>
+  Manuel Holtgrewe <grin@gmx.net>
+  Andrzej Nowodworski <a.nowodworski@learn.pl>
+  Jason Hines <jason@greenhell.com>
+  Jesse Estevez <jesseestevez@earthlink.net>
+  Andris Spruds <Andris.Spruds@stud.lba.lv>
+  Ronald TAO <ronaldtao@hotmail.com>
+  Yannick Lecaillez <yl@seasonfive.com>
+  Hans Lellelid <hans@xmpl.org>
+  
+  Other libraries/contributions
+  ------------------------------
+
+  Apache ANT Project
+  License: Apache 1.1
+  Phing is a port of the Apache ANT project.
+  http://ant.apache.org/
+
+  TAR Manager Class
+  License: LGPL
+  The Tar archive abstraction class
+  (c) Josh Barger <joshb@npt.com>
+  http://phpclasses.upperdesign.com/browse.html/package/529.html
+
+  --$Id: CREDITS 123 2006-09-14 20:19:08Z mrook $
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/LICENSE
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/LICENSE	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/LICENSE	(revision 19)
@@ -0,0 +1,165 @@
+		   GNU LESSER GENERAL PUBLIC LICENSE
+                       Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+
+  This version of the GNU Lesser General Public License incorporates
+the terms and conditions of version 3 of the GNU General Public
+License, supplemented by the additional permissions listed below.
+
+  0. Additional Definitions. 
+
+  As used herein, "this License" refers to version 3 of the GNU Lesser
+General Public License, and the "GNU GPL" refers to version 3 of the GNU
+General Public License.
+
+  "The Library" refers to a covered work governed by this License,
+other than an Application or a Combined Work as defined below.
+
+  An "Application" is any work that makes use of an interface provided
+by the Library, but which is not otherwise based on the Library.
+Defining a subclass of a class defined by the Library is deemed a mode
+of using an interface provided by the Library.
+
+  A "Combined Work" is a work produced by combining or linking an
+Application with the Library.  The particular version of the Library
+with which the Combined Work was made is also called the "Linked
+Version".
+
+  The "Minimal Corresponding Source" for a Combined Work means the
+Corresponding Source for the Combined Work, excluding any source code
+for portions of the Combined Work that, considered in isolation, are
+based on the Application, and not on the Linked Version.
+
+  The "Corresponding Application Code" for a Combined Work means the
+object code and/or source code for the Application, including any data
+and utility programs needed for reproducing the Combined Work from the
+Application, but excluding the System Libraries of the Combined Work.
+
+  1. Exception to Section 3 of the GNU GPL.
+
+  You may convey a covered work under sections 3 and 4 of this License
+without being bound by section 3 of the GNU GPL.
+
+  2. Conveying Modified Versions.
+
+  If you modify a copy of the Library, and, in your modifications, a
+facility refers to a function or data to be supplied by an Application
+that uses the facility (other than as an argument passed when the
+facility is invoked), then you may convey a copy of the modified
+version:
+
+   a) under this License, provided that you make a good faith effort to
+   ensure that, in the event an Application does not supply the
+   function or data, the facility still operates, and performs
+   whatever part of its purpose remains meaningful, or
+
+   b) under the GNU GPL, with none of the additional permissions of
+   this License applicable to that copy.
+
+  3. Object Code Incorporating Material from Library Header Files.
+
+  The object code form of an Application may incorporate material from
+a header file that is part of the Library.  You may convey such object
+code under terms of your choice, provided that, if the incorporated
+material is not limited to numerical parameters, data structure
+layouts and accessors, or small macros, inline functions and templates
+(ten or fewer lines in length), you do both of the following:
+
+   a) Give prominent notice with each copy of the object code that the
+   Library is used in it and that the Library and its use are
+   covered by this License.
+
+   b) Accompany the object code with a copy of the GNU GPL and this license
+   document.
+
+  4. Combined Works.
+
+  You may convey a Combined Work under terms of your choice that,
+taken together, effectively do not restrict modification of the
+portions of the Library contained in the Combined Work and reverse
+engineering for debugging such modifications, if you also do each of
+the following:
+
+   a) Give prominent notice with each copy of the Combined Work that
+   the Library is used in it and that the Library and its use are
+   covered by this License.
+
+   b) Accompany the Combined Work with a copy of the GNU GPL and this license
+   document.
+
+   c) For a Combined Work that displays copyright notices during
+   execution, include the copyright notice for the Library among
+   these notices, as well as a reference directing the user to the
+   copies of the GNU GPL and this license document.
+
+   d) Do one of the following:
+
+       0) Convey the Minimal Corresponding Source under the terms of this
+       License, and the Corresponding Application Code in a form
+       suitable for, and under terms that permit, the user to
+       recombine or relink the Application with a modified version of
+       the Linked Version to produce a modified Combined Work, in the
+       manner specified by section 6 of the GNU GPL for conveying
+       Corresponding Source.
+
+       1) Use a suitable shared library mechanism for linking with the
+       Library.  A suitable mechanism is one that (a) uses at run time
+       a copy of the Library already present on the user's computer
+       system, and (b) will operate properly with a modified version
+       of the Library that is interface-compatible with the Linked
+       Version. 
+
+   e) Provide Installation Information, but only if you would otherwise
+   be required to provide such information under section 6 of the
+   GNU GPL, and only to the extent that such information is
+   necessary to install and execute a modified version of the
+   Combined Work produced by recombining or relinking the
+   Application with a modified version of the Linked Version. (If
+   you use option 4d0, the Installation Information must accompany
+   the Minimal Corresponding Source and Corresponding Application
+   Code. If you use option 4d1, you must provide the Installation
+   Information in the manner specified by section 6 of the GNU GPL
+   for conveying Corresponding Source.)
+
+  5. Combined Libraries.
+
+  You may place library facilities that are a work based on the
+Library side by side in a single library together with other library
+facilities that are not Applications and are not covered by this
+License, and convey such a combined library under terms of your
+choice, if you do both of the following:
+
+   a) Accompany the combined library with a copy of the same work based
+   on the Library, uncombined with any other library facilities,
+   conveyed under the terms of this License.
+
+   b) Give prominent notice with the combined library that part of it
+   is a work based on the Library, and explaining where to find the
+   accompanying uncombined form of the same work.
+
+  6. Revised Versions of the GNU Lesser General Public License.
+
+  The Free Software Foundation may publish revised and/or new versions
+of the GNU Lesser General Public License from time to time. Such new
+versions will be similar in spirit to the present version, but may
+differ in detail to address new problems or concerns.
+
+  Each version is given a distinguishing version number. If the
+Library as you received it specifies that a certain numbered version
+of the GNU Lesser General Public License "or any later version"
+applies to it, you have the option of following the terms and
+conditions either of that published version or of any later version
+published by the Free Software Foundation. If the Library as you
+received it does not specify a version number of the GNU Lesser
+General Public License, you may choose any version of the GNU Lesser
+General Public License ever published by the Free Software Foundation.
+
+  If the Library as you received it specifies that a proxy can decide
+whether future versions of the GNU Lesser General Public License shall
+apply, that proxy's public statement of acceptance of any version is
+permanent authorization for you to choose that version for the
+Library.
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/README
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/README	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/README	(revision 19)
@@ -0,0 +1,78 @@
+                         _________________________
+                         P     H     I     N     G
+
+
+
+  What is it?
+  -----------
+
+  Phing is a PHP based build tool. In theory it is kind of like "make"
+  without makes drawbacks and with the full portability and performance
+  of PHP. (PH)pmake (I)s (N)ot (G)numake
+  
+  Why?
+  ----
+
+  Why another build tool when there is already make, gnumake, nmake, jam, ant,
+  and others? Because all those tools have limitations that the binarycloud
+  development team could not live with when developing software across
+  different platforms. Make-like tools are inherently shell-based: they
+  evaluate a set of dependencies, then execute commands not unlike what you
+  would issue on a shell.
+  
+  This means that you can easily extend these tools by using or writing any
+  program for the OS that you are working on; however, this also means that
+  you limit yourself to the OS, or at least the OS type, such as Unix, that
+  you are working on.
+
+  Makefiles are inherently evil as well. Anybody who has worked on them for
+  any time has run into the dreaded tab problem. "Is my command not executing
+  because I have a space in front of my tab?!!". Tools like Jam took care of
+  this to a great degree, but still have yet another format to use and
+  remember. Of course there is the Java based build tool ant, that is very
+  good approach to what now Phing is. But still based on Java you have to have
+  at least a running JRE installation on your plattfrom.
+  Great for Java projects but we thought this is very consistent way to build
+  a PHP based project. Additionally ant does not support a autoconf tool that
+  writes out proper buildfiles based on some simple rules prior defined in a
+  XML Configuration file.
+
+  Phing is different. Instead of a model where it is extended with shell-based
+  commands, Phing is extended using PHP classes. Instead of writing shell
+  commands, the configuration files are XML-based, calling a target tree where
+  various tasks get executed. Each task is run by an object that implements
+  a particular Task action.
+  
+  Of course, this removes some of the expressive power that is inherent in
+  being able to construct a shell command such as
+    % `find . -name foo -exec rm {}`
+  but it gives you the ability to be cross-platform - to work anywhere and
+  everywhere. And if you really need to execute a shell command, Phing has an <exec>
+  task that allows different commands to be executed based on the operating
+  system it is executing on.
+
+  The Latest Version
+  ------------------
+
+  Details of the latest version can be found on the Phing homepage
+  <http://phing.info/>.
+
+  Documentation
+  -------------
+
+  Documentation is available in XHTML format in the docs/ directory. In particular, 
+  open the docs/phing_guide/book/index.html in a frames-compatible browser to see the 
+  phing user guide.
+
+  For online documentation, you can also visit the Phing website: http://phing.info/
+
+  Licensing
+  ---------
+
+  This software is licensed under the terms you may find in the file
+  named "LICENSE" in this directory.
+
+  Thanks for using PHING.
+
+
+  --$Id: README 364 2008-05-11 02:33:32Z hans $
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/bin/pear-phing
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/bin/pear-phing	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/bin/pear-phing	(revision 19)
@@ -0,0 +1,22 @@
+#!/bin/sh
+
+# ------------------------------------------------------------------------
+# The phing build script for Unix based systems
+# $Id: pear-phing 241 2007-09-25 20:53:17Z mrook $
+# ------------------------------------------------------------------------
+
+# Change this to reflect your environment if the default value doesn't work
+PHP_COMMAND="@PHP-BIN@"
+export PHP_COMMAND
+
+# -------------------------------------------------------------------------
+# Do not change anything below this line unless you know what you're doing.
+# -------------------------------------------------------------------------
+
+if (test -z "$PHP_COMMAND") ; then
+	echo "WARNING: PHP_COMMAND environment not set. (Assuming php on PATH)"
+	PHP_COMMAND=php
+	export PHP_COMMAND
+fi
+
+$PHP_COMMAND -d html_errors=off -qC @PEAR-DIR@/phing.php -logger phing.listener.AnsiColorLogger "$@"
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/bin/pear-phing.bat
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/bin/pear-phing.bat	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/bin/pear-phing.bat	(revision 19)
@@ -0,0 +1,44 @@
+@ECHO OFF
+
+:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+:: The phing build script for Windows based systems
+:: $Id: pear-phing.bat 123 2006-09-14 20:19:08Z mrook $
+:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+
+::----------------------------------------------------------------------------------
+:: Please set following to PHP's CLI
+:: NOTE: In PHP 4.2.x the PHP-CLI used to be named php-cli.exe. 
+::       PHP 4.3.x names it php.exe but stores it in a subdir called /cli/php.exe
+::       E.g. for PHP 4.2 C:\phpdev\php-4.2-Win32\php-cli.exe
+::            for PHP 4.3 C:\phpdev\php-4.3-Win32\cli\php.exe
+  
+  SET phpCli=@PHP-BIN@
+
+::---------------------------------------------------------------------------------
+::---------------------------------------------------------------------------------
+:: Do not modify below this line!! (Unless you know what your doing :)
+::---------------------------------------------------------------------------------
+::---------------------------------------------------------------------------------
+
+:: Check existence of php.exe
+IF EXIST "%phpCli%" (
+  SET doNothing=
+) ELSE GOTO :NoPhpCli
+
+"%phpCli%" -d html_errors=off -qC "@PEAR-DIR@\phing.php" %*
+GOTO :EOF
+
+::
+:: php.exe not found error  
+GOTO :PAUSE_END
+:NoPhpCli
+ECHO ** ERROR *****************************************************************
+ECHO * Sorry, can't find the php.exe file.
+ECHO * You must edit this file to point to your php.exe (CLI version!)
+ECHO *    [Currently set to %phpCli%]
+ECHO **************************************************************************
+
+GOTO :PAUSE_END
+
+:PAUSE_END
+PAUSE
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/bin/phing
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/bin/phing	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/bin/phing	(revision 19)
@@ -0,0 +1,87 @@
+#!/bin/sh
+# Shell wrapper for Phing
+# $Id: phing 151 2007-02-13 20:44:58Z hans $
+#
+# This script will do the following:
+# - check for PHP_COMMAND env, if found, use it.
+#   - if not found assume php is on the path
+# - check for PHING_HOME evn, if found use it
+#   - if not look for it
+# - check for PHP_CLASSPATH, if found use it
+#   - if not found set it using PHING_HOME/classes
+
+
+# Put all args in quotes
+phing_exec_debug=false
+phing_exec_args=
+for arg in "$@" ; do
+  phing_exec_args="$phing_exec_args \"$arg\""
+done
+
+if [ -z "$PHING_HOME" ] ; then
+
+  # echo "WARNING: PHING_HOME environment not set. Attempting to guess."
+
+  # try to find PHING
+  if [ -d /opt/phing ] ; then 
+    PHING_HOME=/opt/phing
+  fi
+
+  if [ -d "${HOME}/opt/phing" ] ; then 
+    PHING_HOME="${HOME}/opt/phing"
+  fi
+
+  if [ -d "/usr/local/phing" ] ; then 
+    PHING_HOME="/usr/local/phing"
+  fi
+
+  if [ -d "${HOME}/usr/phing" ] ; then 
+    PHING_HOME="${HOME}/usr/phing"
+  fi
+  
+  ## resolve links - $0 may be a link to phing's home
+  PRG="$0"
+  progname=`basename "$0"`
+  saveddir=`pwd`
+
+  # need this for relative symlinks
+  dirname_prg=`dirname "$PRG"`
+  cd "$dirname_prg"
+  
+  while [ -h "$PRG" ] ; do
+    ls=`ls -ld "$PRG"`
+    link=`expr "$ls" : '.*-> \(.*\)$'`
+    if expr "$link" : '/.*' > /dev/null; then
+	PRG="$link"
+    else
+	PRG=`dirname "$PRG"`"/$link"
+    fi
+  done
+  
+  PHING_HOME=`dirname "$PRG"`/..
+
+  cd "$saveddir"
+
+  # make it fully qualified
+  PHING_HOME=`cd "$PHING_HOME" && pwd`
+  
+  # make it available in PHP via getenv("PHING_HOME")
+  export PHING_HOME
+fi
+
+if (test -z "$PHP_COMMAND") ; then
+	# echo "WARNING: PHP_COMMAND environment not set. (Assuming php on PATH)"
+	PHP_COMMAND=php
+	export PHP_COMMAND
+fi
+
+if (test -z "$PHP_CLASSPATH") ; then
+	PHP_CLASSPATH=$PHING_HOME/classes
+	export PHP_CLASSPATH
+fi
+
+phing_exec_cmd="exec $PHP_COMMAND -d html_errors=off -qC \"$PHING_HOME/bin/phing.php\" -logger phing.listener.AnsiColorLogger $phing_exec_args"
+if $phing_exec_debug ; then
+  echo $phing_exec_cmd
+fi
+eval $phing_exec_cmd
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/bin/phing.bat
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/bin/phing.bat	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/bin/phing.bat	(revision 19)
@@ -0,0 +1,58 @@
+@echo off
+
+rem *********************************************************************
+rem ** the phing build script for Windows based systems
+rem ** $Id: phing.bat 143 2007-02-05 14:57:57Z hans $
+rem *********************************************************************
+
+rem This script will do the following:
+rem - check for PHP_COMMAND env, if found, use it.
+rem   - if not found detect php, if found use it, otherwise err and terminate
+rem - check for PHING_HOME evn, if found use it
+rem   - if not found error and leave
+rem - check for PHP_CLASSPATH, if found use it
+rem   - if not found set it using PHING_HOME/classes
+
+if "%OS%"=="Windows_NT" @setlocal
+
+rem %~dp0 is expanded pathname of the current script under NT
+set DEFAULT_PHING_HOME=%~dp0..
+
+goto init
+goto cleanup
+
+:init
+
+if "%PHING_HOME%" == "" set PHING_HOME=%DEFAULT_PHING_HOME%
+set DEFAULT_PHING_HOME=
+
+if "%PHP_COMMAND%" == "" goto no_phpcommand
+if "%PHP_CLASSPATH%" == "" goto set_classpath
+
+goto run
+goto cleanup
+
+:run
+%PHP_COMMAND% -d html_errors=off -qC %PHING_HOME%\bin\phing.php %1 %2 %3 %4 %5 %6 %7 %8 %9
+goto cleanup
+
+:no_phpcommand
+REM echo ------------------------------------------------------------------------
+REM echo WARNING: Set environment var PHP_COMMAND to the location of your php.exe
+REM echo          executable (e.g. C:\PHP\php.exe).  (Assuming php.exe on Path)
+REM echo ------------------------------------------------------------------------
+set PHP_COMMAND=php.exe
+goto init
+
+:err_home
+echo ERROR: Environment var PHING_HOME not set. Please point this
+echo variable to your local phing installation!
+goto cleanup
+
+:set_classpath
+set PHP_CLASSPATH=%PHING_HOME%\classes
+goto init
+
+:cleanup
+if "%OS%"=="Windows_NT" @endlocal
+REM pause
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/bin/phing.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/bin/phing.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/bin/phing.php	(revision 19)
@@ -0,0 +1,56 @@
+<?php
+
+/**
+ * This is the Phing command line launcher. It starts up the system evironment
+ * tests for all important paths and properties and kicks of the main command-
+ * line entry point of phing located in phing.Phing
+ * @version $Revision: 1.7 $
+ */
+ 
+// Set any INI options for PHP
+// ---------------------------
+
+/* set classpath */
+if (getenv('PHP_CLASSPATH')) {
+    if (!defined('PHP_CLASSPATH')) { define('PHP_CLASSPATH',  getenv('PHP_CLASSPATH') . PATH_SEPARATOR . get_include_path()); }
+    ini_set('include_path', PHP_CLASSPATH);
+} else {
+    if (!defined('PHP_CLASSPATH')) { define('PHP_CLASSPATH',  get_include_path()); }
+}
+
+require_once 'phing/Phing.php';
+
+try {
+	
+	/* Setup Phing environment */
+	Phing::startup();
+
+	// Set phing.home property to the value from environment
+	// (this may be NULL, but that's not a big problem.) 
+	Phing::setProperty('phing.home', getenv('PHING_HOME'));
+
+	// Grab and clean up the CLI arguments
+	$args = isset($argv) ? $argv : $_SERVER['argv']; // $_SERVER['argv'] seems to not work (sometimes?) when argv is registered
+	array_shift($args); // 1st arg is script name, so drop it
+	
+	// Invoke the commandline entry point
+	Phing::fire($args);
+	
+	// Invoke any shutdown routines.
+	Phing::shutdown();
+	
+} catch (ConfigurationException $x) {
+	
+	Phing::printMessage($x);
+	exit(-1); // This was convention previously for configuration errors.
+	
+} catch (Exception $x) {
+	
+	// Assume the message was already printed as part of the build and
+	// exit with non-0 error code.
+	
+	exit(1);
+	
+}
+
+?>
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/BuildEvent.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/BuildEvent.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/BuildEvent.php	(revision 19)
@@ -0,0 +1,198 @@
+<?php
+/*
+ *  $Id: BuildEvent.php 173 2007-03-12 20:34:30Z hans $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+require_once 'phing/system/lang/EventObject.php';
+
+/**
+ * Encapsulates a build specific event.
+ *
+ * <p>We have three sources of events all handled by this class:
+ * 
+ * <ul>
+ *  <li>Project level events</li>
+ *  <li>Target level events</li>
+ *  <li>Task level events</li>
+ * </ul>
+ *
+ * <p> Events are all fired from the project class by creating an event object
+ * using this class and passing it to the listeners.
+ *
+ * @author    Andreas Aderhold <andi@binarycloud.com>
+ * @author    Hans Lellelid <hans@xmpl.org>
+ * @version   $Revision: 1.10 $
+ * @package   phing
+ */
+class BuildEvent extends EventObject {
+
+    /**
+     * A reference to the project
+     * @var Project
+     */
+    protected $project;
+
+    /**
+     * A reference to the target
+     * @var Target
+     */
+    protected $target;
+
+    /**
+     * A reference to the task
+     *
+     * @var Task
+     */
+    protected $task;
+
+    /**
+     * The message of this event, if the event is a message
+     * @var string
+     */
+    protected $message = null;
+
+    /**
+     * The priority of the message
+     *
+     * @var    string
+     * @see    $message
+     */
+    protected $priority = Project::MSG_VERBOSE;
+
+    /**
+     * The execption that caused the event, if any
+     *
+     * @var    object
+     */
+    protected $exception = null;
+
+    /**
+     * Construct a BuildEvent for a project, task or target source event
+     *
+     * @param  object  project the project that emitted the event.
+     */
+    public function __construct($source) {
+        parent::__construct($source);
+        if ($source instanceof Project) {
+            $this->project = $source;
+            $this->target = null;
+            $this->task = null;
+        } elseif ($source instanceof Target) {
+            $this->project = $source->getProject();
+            $this->target = $source;
+            $this->task = null;
+        } elseif ($source instanceof Task) {
+            $this->project = $source->getProject();
+            $this->target = $source->getOwningTarget();
+            $this->task = $source;
+        } else {
+            throw new Exception("Can not construct BuildEvent, unknown source given.");
+        }
+    }
+
+    /**
+     * Sets the message with details and the message priority for this event.
+     *
+     * @param  string   The string message of the event
+     * @param  integer  The priority this message should have
+     */
+    public function setMessage($message, $priority) {
+        $this->message = (string) $message;
+        $this->priority = (int) $priority;
+    }
+
+    /**
+     * Set the exception that was the cause of this event.
+     *
+     * @param  Exception The exception that caused the event
+     */
+    public function setException($exception) {
+        $this->exception = $exception;
+    }
+
+    /**
+     * Returns the project instance that fired this event.
+     *
+     * The reference to the project instance is set by the constructor if this
+     * event was fired from the project class.
+     *
+     * @return  Project  The project instance that fired this event
+     */
+    public function getProject() {
+        return $this->project;
+    }
+
+    /**
+     * Returns the target instance that fired this event.
+     *
+     * The reference to the target instance is set by the constructor if this
+     * event was fired from the target class.
+     *
+     * @return Target The target that fired this event
+     */
+    public function getTarget() {
+        return $this->target;
+    }
+
+    /**
+     * Returns the target instance that fired this event.
+     *
+     * The reference to the task instance is set by the constructor if this
+     * event was fired within a task.
+     *
+     * @return Task The task that fired this event
+     */
+    public function getTask() {
+        return $this->task;
+    }
+
+    /**
+     * Returns the logging message. This field will only be set for
+     * "messageLogged" events.
+     *
+     * @return string The log message
+     */
+    function getMessage() {
+        return $this->message;
+    }
+
+    /**
+     * Returns the priority of the logging message. This field will only
+     * be set for "messageLogged" events.
+     *
+     * @return integer The message priority
+     */
+    function getPriority() {
+        return $this->priority;
+    }
+
+    /**
+     * Returns the exception that was thrown, if any.
+     * This field will only be set for "taskFinished", "targetFinished", and
+     * "buildFinished" events.
+     *
+     * @see BuildListener::taskFinished()
+     * @see BuildListener::targetFinished()
+     * @see BuildListener::buildFinished()
+     * @return Exception
+     */
+    public function getException() {
+        return $this->exception;
+    }
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/BuildException.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/BuildException.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/BuildException.php	(revision 19)
@@ -0,0 +1,121 @@
+<?php
+/*
+ *  $Id: BuildException.php 287 2007-11-04 14:59:39Z hans $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>. 
+ */
+
+/**
+ * BuildException is for when things go wrong in a build execution.
+ *
+ * @author   Andreas Aderhold <andi@binarycloud.com>
+ * @version  $Revision: 1.12 $
+ * @package  phing
+ */
+class BuildException extends Exception {
+
+    /**
+	 * Location in the xml file.
+	 * @var Location
+	 */
+    protected $location;
+            
+    /**
+	 * The nested "cause" exception.
+	 * @var Exception
+	 */
+    protected $cause;
+    
+    /**
+     * Construct a BuildException.
+     * Supported signatures:
+     *         throw new BuildException($causeExc);
+     *         throw new BuildException($msg);
+     *         throw new Buildexception($causeExc, $loc);
+     *         throw new BuildException($msg, $causeExc);
+     *         throw new BuildException($msg, $loc);
+     *         throw new BuildException($msg, $causeExc, $loc);
+     */
+    function __construct($p1, $p2 = null, $p3 = null) {        
+        
+        $cause = null;
+        $loc = null;
+        $msg = "";
+        
+        if ($p3 !== null) {
+            $cause = $p2;
+            $loc = $p3;
+            $msg = $p1;
+        } elseif ($p2 !== null) {
+            if ($p2 instanceof Exception) {
+                $cause = $p2;
+                $msg = $p1;
+            } elseif ($p2 instanceof Location) {
+                $loc = $p2;
+                if ($p1 instanceof Exception) {
+                    $cause = $p1;
+                } else {
+                    $msg = $p1;
+                }
+            }
+        } elseif ($p1 instanceof Exception) {
+            $cause = $p1;
+        } else {
+            $msg = $p1;
+        }
+        
+        parent::__construct($msg);
+        
+        if ($cause !== null) {
+            $this->cause = $cause;
+            $this->message .= " [wrapped: " . $cause->getMessage() ."]";
+        }
+        
+        if ($loc !== null) {
+            $this->setLocation($loc);
+        }                
+    }
+    
+    /**
+     * Gets the cause exception.
+     *
+     * @return Exception
+     */
+    public function getCause() {
+        return $this->cause;
+    }
+    
+    /**
+     * Gets the location of error in XML file.
+     *
+     * @return Location
+     */
+    public function getLocation() {
+        return $this->location;
+    }
+
+    /**
+     * Sets the location of error in XML file.
+     *
+     * @param Locaiton $loc
+     */
+    public function setLocation(Location $loc) {        
+        $this->location = $loc;
+        $this->message = $loc->toString() . ': ' . $this->message;
+    }
+
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/BuildListener.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/BuildListener.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/BuildListener.php	(revision 19)
@@ -0,0 +1,91 @@
+<?php
+/*
+ *  $Id: BuildListener.php 123 2006-09-14 20:19:08Z mrook $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+/**
+ * Interface for build listeners.
+ *
+ * Classes that implement a listener must extend this class and (faux)implement
+ * all methods that are decleard as dummies below.
+ *
+ * @author    Andreas Aderhold <andi@binarycloud.com>
+ * @author    Hans Lellelid <hans@xmpl.org>
+ * @version   $Revision: 1.6 $
+ * @see       BuildEvent
+ * @see       Project::addBuildListener()
+ * @package   phing
+ */
+interface BuildListener {
+
+    /**
+     * Fired before any targets are started.
+     *
+     * @param BuildEvent The BuildEvent
+     */
+    function buildStarted(BuildEvent $event);
+
+    /**
+     * Fired after the last target has finished.
+     *
+     * @param BuildEvent The BuildEvent
+     * @see BuildEvent::getException()
+     */
+    function buildFinished(BuildEvent $event);
+
+    /**
+     * Fired when a target is started.
+     *
+     * @param BuildEvent The BuildEvent
+     * @see BuildEvent::getTarget()
+     */
+    function targetStarted(BuildEvent $event);
+
+    /**
+     * Fired when a target has finished.
+     *
+     * @param BuildEvent The BuildEvent
+     * @see BuildEvent#getException()
+     */
+    function targetFinished(BuildEvent $event);
+
+    /**
+     * Fired when a task is started.
+     *
+     * @param BuildEvent The BuildEvent
+     * @see BuildEvent::getTask()
+     */
+    function taskStarted(BuildEvent $event);
+
+    /**
+     *  Fired when a task has finished.
+     *
+     *  @param BuildEvent The BuildEvent
+     *  @see BuildEvent::getException()
+     */
+    function taskFinished(BuildEvent $event);
+
+    /**
+     *  Fired whenever a message is logged.
+     *
+     *  @param BuildEvent The BuildEvent
+     *  @see BuildEvent::getMessage()
+     */
+    function messageLogged(BuildEvent $event);
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/BuildLogger.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/BuildLogger.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/BuildLogger.php	(revision 19)
@@ -0,0 +1,70 @@
+<?php
+/*
+ *  $Id: BuildLogger.php 147 2007-02-06 20:32:22Z hans $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+require_once 'phing/BuildListener.php';
+
+/**
+ * Interface for build loggers.
+ * 
+ * Build loggers are build listeners but with some additional functionality:
+ *   - They can be configured with a log level (below which they will ignore messages)
+ *   - They have error and output streams 
+ *
+ * Classes that implement a listener must implement this interface.
+ *
+ * @author    Hans Lellelid <hans@xmpl.org>
+ * @version   $Revision: 1.6 $
+ * @see       BuildEvent
+ * @see       Project::addBuildListener()
+ * @package   phing
+ */
+interface BuildLogger extends BuildListener {
+
+	/**
+	 * Sets the min log level that this logger should respect.
+	 * 
+	 * Messages below this level are ignored.
+	 *
+     * Constants for the message levels are in Project.php. The order of
+     * the levels, from least to most verbose, is:
+     *   - Project::MSG_ERR
+     *   - Project::MSG_WARN
+     *   - Project::MSG_INFO
+     *   - Project::MSG_VERBOSE
+     *   - Project::MSG_DEBUG
+     *
+	 * @param int $level The log level integer (e.g. Project::MSG_VERBOSE, etc.).
+	 */
+    public function setMessageOutputLevel($level);
+
+    /**
+     * Sets the standard output stream to use.
+     * @param OutputStream $output Configured output stream (e.g. STDOUT) for standard output. 
+     */
+    public function setOutputStream(OutputStream $output);
+
+    /**
+     * Sets the output stream to use for errors.
+     * @param OutputStream $err Configured output stream (e.g. STDERR) for errors.
+     */
+    public function setErrorStream(OutputStream $err);
+
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/ConfigurationException.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/ConfigurationException.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/ConfigurationException.php	(revision 19)
@@ -0,0 +1,83 @@
+<?php
+/*
+ *  $Id: BuildException.php 123 2006-09-14 20:19:08Z mrook $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+/**
+ * ConfigurationException is thrown by Phing during the configuration and setup phase of the project.
+ *
+ * @author   Hans Lellelid <hans@xmpl.org>
+ * @version  $Revision$
+ * @package  phing
+ */
+class ConfigurationException extends Exception {
+
+    /**
+	 * Location in the xml file.
+	 * @var Location
+	 */
+    protected $location;
+
+    /**
+	 * The nested "cause" exception.
+	 * @var Exception
+	 */
+    protected $cause;
+
+    /**
+     * Construct a BuildException.
+     * Supported signatures:
+     *         throw new BuildException($causeExc);
+     *         throw new BuildException($msg);
+     *         throw new BuildException($msg, $causeExc);
+     */
+    function __construct($p1, $p2 = null, $p3 = null) {
+
+    	$cause = null;
+    	$msg = "";
+
+    	if ($p2 !== null) {
+    		if ($p2 instanceof Exception) {
+    			$cause = $p2;
+    			$msg = $p1;
+    		}
+    	} elseif ($p1 instanceof Exception) {
+    		$cause = $p1;
+    	} else {
+    		$msg = $p1;
+    	}
+
+    	parent::__construct($msg);
+
+    	if ($cause !== null) {
+    		$this->cause = $cause;
+    		$this->message .= " [wrapped: " . $cause->getMessage() ."]";
+    	}
+    }
+	
+    /**
+     * Gets the cause exception.
+     *
+     * @return Exception
+     */
+    public function getCause() {
+    	return $this->cause;
+    }
+     
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/IntrospectionHelper.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/IntrospectionHelper.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/IntrospectionHelper.php	(revision 19)
@@ -0,0 +1,542 @@
+<?php
+
+/*
+ *  $Id: IntrospectionHelper.php 144 2007-02-05 15:19:00Z hans $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+include_once 'phing/types/Reference.php';
+include_once 'phing/types/Path.php';
+include_once 'phing/util/StringHelper.php';
+
+/**
+ * Helper class that collects the methods that a task or nested element
+ * holds to set attributes, create nested elements or hold PCDATA
+ * elements.
+ *
+ *<ul>
+ * <li><strong>SMART-UP INLINE DOCS</strong></li>
+ * <li><strong>POLISH-UP THIS CLASS</strong></li>
+ *</ul>
+ *
+ * @author    Andreas Aderhold <andi@binarycloud.com>
+ * @author    Hans Lellelid <hans@xmpl.org>
+ * @copyright © 2001,2002 THYRELL. All rights reserved
+ * @version   $Revision: 1.19 $
+ * @package   phing
+ */
+class IntrospectionHelper {
+
+
+
+    /** 
+     * Holds the attribute setter methods.
+     * 
+     * @var array string[]
+     */
+    private $attributeSetters = array();
+
+    /**  
+     * Holds methods to create nested elements. 
+     *
+     * @var array string[]
+     */
+    private $nestedCreators = array();
+
+    /**
+     * Holds methods to store configured nested elements. 
+     *
+     * @var array string[]
+     */
+    private $nestedStorers = array();
+    
+    /**
+     * Map from attribute names to nested types.
+     */
+    private $nestedTypes = array();
+        
+    /**
+     * New idea in phing: any class can register certain
+     * keys -- e.g. "task.current_file" -- which can be used in
+     * task attributes, if supported.  In the build XML these
+     * are referred to like this:
+     *         <regexp pattern="\n" replace="%{task.current_file}"/>
+     * In the type/task a listener method must be defined:
+     *         function setListeningReplace($slot) {}
+     * @var array string[]
+      */
+    private $slotListeners = array();
+    
+    /** 
+     * The method to add PCDATA stuff. 
+     *
+     * @var string Method name of the addText (redundant?) method, if class supports it :)
+     */
+    private $methodAddText = null;
+
+    /**
+     * The Class that's been introspected.
+     *
+     * @var     object
+     * @access  private
+     */
+    private $bean;
+    
+    /**
+     * The cache of IntrospectionHelper classes instantiated by getHelper().
+     * @var array IntrospectionHelpers[]
+     */
+    private static $helpers = array();
+    
+    /** 
+     * Factory method for helper objects. 
+     *
+     * @param string $class The class to create a Helper for
+     */
+    public static function getHelper($class) {
+        if (!isset(self::$helpers[$class])) {
+            self::$helpers[$class] = new IntrospectionHelper($class);
+        }
+        return self::$helpers[$class];
+    }
+
+    /**
+     * This function constructs a new introspection helper for a specific class.
+     * 
+     * This method loads all methods for the specified class and categorizes them
+     * as setters, creators, slot listeners, etc.  This way, the setAttribue() doesn't
+     * need to perform any introspection -- either the requested attribute setter/creator
+     * exists or it does not & a BuildException is thrown.
+     * 
+     * @param string $bean The classname for this IH.
+     */
+    function __construct($class) {
+    
+        $this->bean = new ReflectionClass($class);
+        
+        //$methods = get_class_methods($bean);
+        foreach($this->bean->getMethods() as $method) {
+        
+            if ($method->isPublic()) {                
+            
+                // We're going to keep case-insensitive method names
+                // for as long as we're allowed :)  It makes it much
+                // easier to map XML attributes to PHP class method names.
+                $name = strtolower($method->getName());
+                
+                // There are a few "reserved" names that might look like attribute setters
+                // but should actually just be skipped.  (Note: this means you can't ever
+                // have an attribute named "location" or "tasktype" or a nested element named "task".)
+                if ($name === "setlocation" || $name === "settasktype" || $name === "addtask") {
+                    continue;
+                }
+                
+                if ($name === "addtext") {
+                    
+                    $this->methodAddText = $method;
+                    
+                } elseif (strpos($name, "setlistening") === 0) {
+                    
+                    // Phing supports something unique called "RegisterSlots"
+                    // These are dynamic values that use a basic slot system so that
+                    // classes can register to listen to specific slots, and the value
+                    // will always be grabbed from the slot (and never set in the project
+                    // component).  This is useful for things like tracking the current
+                    // file being processed by a filter (e.g. AppendTask sets an append.current_file
+                    // slot, which can be ready by the XSLTParam type.)
+                    
+                    if (count($method->getParameters()) !== 1) {
+                        throw new BuildException($method->getDeclaringClass()->getName()."::".$method->getName()."() must take exactly one parameter.");
+                    }
+                                                
+                    $this->slotListeners[$name] = $method;
+                    
+                } elseif (strpos($name, "set") === 0) {
+                    
+                    // A standard attribute setter.
+                    
+                    if (count($method->getParameters()) !== 1) {
+                        throw new BuildException($method->getDeclaringClass()->getName()."::".$method->getName()."() must take exactly one parameter.");
+                    }
+                    
+                    $this->attributeSetters[$name] = $method;
+                    
+                } elseif (strpos($name, "create") === 0) {                            
+                    
+                    if (count($method->getParameters()) > 0) {
+                        throw new BuildException($method->getDeclaringClass()->getName()."::".$method->getName()."() may not take any parameters.");
+                    }
+                    
+                    // Because PHP doesn't support return types, we are going to do
+                    // two things here to guess return type:
+                    //     1) parse comments for an explicit value
+                    //     2) if that fails, assume that the part of the method after "create"
+                    //    is the name of the return type (in many cases it is not)
+                    
+                    // This isn't super important -- i.e. we're not instantaiting classes
+                    // based on this information.  It's more just so that IntrospectionHelper
+                    // can keep track of all the nested types -- and provide more helpful
+                    // exception messages, etc.
+                                
+                    preg_match('/@return[\s]+([\w]+)/', $method->getDocComment(), $matches);
+                    if (!empty($matches[1]) && class_exists($matches[1], false)) {
+                        $this->nestedTypes[$name] = $matches[1];
+                    } else {                    
+                        // assume that method createEquals() creates object of type "Equals"
+                        // (that example would be false, of course)                    
+                        $this->nestedTypes[$name] = $this->getPropertyName($name, "create");
+                    }
+                    
+                    $this->nestedCreators[$name] = $method;
+                    
+                } elseif (strpos($name, "addconfigured") === 0) {
+                    
+                    // *must* use class hints if using addConfigured ...
+                    
+                    // 1 param only
+                    $params = $method->getParameters();
+                    
+                    if (count($params) < 1) {
+                        throw new BuildException($method->getDeclaringClass()->getName()."::".$method->getName()."() must take at least one parameter.");
+                    }
+                    
+                    if (count($params) > 1) {
+                        $this->warn($method->getDeclaringClass()->getName()."::".$method->getName()."() takes more than one parameter. (IH only uses the first)");
+                    }
+                    
+                    $classname = null;
+                    
+                    if (($hint = $params[0]->getClass()) !== null) { 
+                        $classname = $hint->getName();    
+                    }                    
+                    
+                    if ($classname === null) {
+                        throw new BuildException($method->getDeclaringClass()->getName()."::".$method->getName()."() method MUST use a class hint to indicate the class type of parameter.");
+                    }
+                        
+                    $this->nestedTypes[$name] = $classname;
+                
+                    $this->nestedStorers[$name] = $method;
+                    
+                } elseif (strpos($name, "add") === 0) {
+                    
+                    // *must* use class hints if using add ...
+                    
+                    // 1 param only
+                    $params = $method->getParameters();
+                    if (count($params) < 1) {
+                        throw new BuildException($method->getDeclaringClass()->getName()."::".$method->getName()."() must take at least one parameter.");
+                    }
+                    
+                    if (count($params) > 1) {
+                        $this->warn($method->getDeclaringClass()->getName()."::".$method->getName()."() takes more than one parameter. (IH only uses the first)");
+                    }
+
+                    $classname = null;
+                    
+                    if (($hint = $params[0]->getClass()) !== null) { 
+                        $classname = $hint->getName();    
+                    }                    
+                    
+                    // we don't use the classname here, but we need to make sure it exists before
+                    // we later try to instantiate a non-existant class
+                    if ($classname === null) {
+                        throw new BuildException($method->getDeclaringClass()->getName()."::".$method->getName()."() method MUST use a class hint to indicate the class type of parameter.");
+                    }
+                
+                    $this->nestedCreators[$name] = $method;
+                } 
+            } // if $method->isPublic()        
+        } // foreach        
+    }
+
+
+    /** Sets the named attribute. */
+    function setAttribute(Project $project, $element, $attributeName, &$value) {
+        
+        // we want to check whether the value we are setting looks like
+        // a slot-listener variable:  %{task.current_file}
+        //
+        // slot-listener variables are not like properties, in that they cannot be mixed with
+        // other text values.  The reason for this disparity is that properties are only
+        // set when first constructing objects from XML, whereas slot-listeners are always dynamic.
+        //
+        // This is made possible by PHP5 (objects automatically passed by reference) and PHP's loose
+        // typing.
+        
+        if (StringHelper::isSlotVar($value)) {
+            
+            $as = "setlistening" . strtolower($attributeName);
+
+            if (!isset($this->slotListeners[$as])) {
+                $msg = $this->getElementName($project, $element) . " doesn't support a slot-listening '$attributeName' attribute.";
+                throw new BuildException($msg);
+            }
+            
+            $method = $this->slotListeners[$as];
+            
+            $key = StringHelper::slotVar($value);
+            $value = Register::getSlot($key); // returns a RegisterSlot object which will hold current value of that register (accessible using getValue())
+            
+        } else {
+            
+            // Traditional value options
+            
+            $as = "set".strtolower($attributeName);
+            
+            if (!isset($this->attributeSetters[$as])) {
+                $msg = $this->getElementName($project, $element) . " doesn't support the '$attributeName' attribute.";
+                throw new BuildException($msg);
+            }
+            
+            $method = $this->attributeSetters[$as];            
+            
+            if ($as == "setrefid") {            
+                $value = new Reference($value);
+            } else {
+            
+                // decode any html entities in string
+                $value = html_entity_decode($value);                
+                
+                // value is a string representation of a boolean type,
+                // convert it to primitive
+                if (StringHelper::isBoolean($value)) {
+
+                    $value = StringHelper::booleanValue($value);
+                }
+                
+                // does method expect a PhingFile object? if so, then 
+                // pass a project-relative file.
+                $params = $method->getParameters();
+
+                $classname = null;
+                
+                if (($hint = $params[0]->getClass()) !== null) { 
+                    $classname = $hint->getName();    
+                }
+                
+                // there should only be one param; we'll just assume ....
+                if ($classname !== null) {
+                    switch(strtolower($classname)) {
+                        case "phingfile":
+                            $value = $project->resolveFile($value);
+                            break;
+                        case "path":
+                            $value = new Path($project, $value);
+                            break;
+                        case "reference":
+                            $value = new Reference($value);
+                            break;            
+                        // any other object params we want to support should go here ...
+                    }
+                    
+                } // if hint !== null
+                
+            } // if not setrefid
+            
+        } // if is slot-listener
+        
+        try {
+            $project->log("    -calling setter ".$method->getDeclaringClass()->getName()."::".$method->getName()."()", Project::MSG_DEBUG);
+            $method->invoke($element, $value);
+        } catch(Exception $exc) {
+            throw new BuildException($exc);
+        }
+        
+    }
+
+    /** Adds PCDATA areas.*/
+    function addText(Project $project, $element, $text) {
+        if ($this->methodAddText === null) {
+            $msg = $this->getElementName($project, $element)." doesn't support nested text data.";
+            throw new BuildException($msg);
+        }        
+        try {
+            $method = $this->methodAddText;
+            $method->invoke($element, $text);
+        } catch (Exception $exc) {
+            throw new BuildException($exc);
+        }
+    }
+
+    /**
+     * Creates a named nested element. 
+     * 
+     * Valid creators can be in the form createFoo() or addFoo(Bar).
+     * @return object Returns the nested element.
+     * @throws BuildException
+     */
+    function createElement(Project $project, $element, $elementName) {
+    
+        $addMethod = "add".strtolower($elementName);
+        $createMethod = "create".strtolower($elementName);
+        $nestedElement = null;
+        
+        if (isset($this->nestedCreators[$createMethod])) {
+            
+            $method = $this->nestedCreators[$createMethod];
+             try { // try to invoke the creator method on object
+                $project->log("    -calling creator ".$method->getDeclaringClass()->getName()."::".$method->getName()."()", Project::MSG_DEBUG);
+                $nestedElement = $method->invoke($element);
+            } catch (Exception $exc) {
+                throw new BuildException($exc);
+            }            
+            
+        } elseif (isset($this->nestedCreators[$addMethod])) {            
+            
+            $method = $this->nestedCreators[$addMethod];
+            
+            // project components must use class hints to support the add methods
+            
+            try { // try to invoke the adder method on object
+            
+                $project->log("    -calling adder ".$method->getDeclaringClass()->getName()."::".$method->getName()."()", Project::MSG_DEBUG);
+                // we've already assured that correct num of params
+                // exist and that method is using class hints                
+                $params = $method->getParameters();
+
+                $classname = null;
+            
+                if (($hint = $params[0]->getClass()) !== null) { 
+                    $classname = $hint->getName();    
+                }                
+                
+                // create a new instance of the object and add it via $addMethod                
+                $nestedElement = new $classname();
+                
+                $method->invoke($element, $nestedElement);
+                                
+            } catch (Exception $exc) {
+                throw new BuildException($exc);
+            }
+        } else {
+            $msg = $this->getElementName($project, $element) . " doesn't support the '$elementName' creator/adder.";
+            throw new BuildException($msg);
+        }                                
+        
+        if ($nestedElement instanceof ProjectComponent) {
+            $nestedElement->setProject($project);
+        }
+        
+        return $nestedElement;
+    }
+
+    /**
+     * Creates a named nested element.
+     * @return void
+     * @throws BuildException
+     */
+    function storeElement($project, $element, $child, $elementName = null) {
+    
+        if ($elementName === null) {
+            return;
+        }
+        
+        $storer = "addconfigured".strtolower($elementName);
+          
+        if (isset($this->nestedStorers[$storer])) {
+            
+            $method = $this->nestedStorers[$storer];
+            
+            try {                                
+                $project->log("    -calling storer ".$method->getDeclaringClass()->getName()."::".$method->getName()."()", Project::MSG_DEBUG);                    
+                $method->invoke($element, $child);            
+            } catch (Exception $exc) {
+                throw new BuildException($exc);
+            }
+        }
+        
+    }
+
+    /** Does the introspected class support PCDATA? */
+    function supportsCharacters() {
+        return ($this->methodAddText !== null);
+    }
+
+    /** Return all attribues supported by the introspected class. */
+    function getAttributes() {
+        $attribs = array();
+        foreach (array_keys($this->attributeSetters) as $setter) {
+            $attribs[] =$this->getPropertyName($setter, "set");
+        }
+        return $attribs;
+    }
+
+    /** Return all nested elements supported by the introspected class. */
+    function getNestedElements() {
+        return $this->nestedTypes;
+    }
+    
+    /**
+     * Get the the name for an element.
+     * When possible the full classnam (phing.tasks.system.PropertyTask) will
+     * be returned.  If not available (loaded in taskdefs or typedefs) then the
+     * XML element name will be returned.
+     *
+     * @param Project $project
+     * @param object $element The Task or type element.
+     * @return string Fully qualified class name of element when possible.
+     */
+    function getElementName(Project $project, $element) {
+       
+          $taskdefs = $project->getTaskDefinitions();
+        $typedefs = $project->getDataTypeDefinitions();
+        
+        // check if class of element is registered with project (tasks & types)        
+        // most element types don't have a getTag() method
+        $elClass = get_class($element);
+        
+        if (!in_array('getTag', get_class_methods($elClass))) {
+                // loop through taskdefs and typesdefs and see if the class name
+                // matches (case-insensitive) any of the classes in there
+                foreach(array_merge($taskdefs, $typedefs) as $elName => $class) {
+                    if (0 === strcasecmp($elClass, StringHelper::unqualify($class))) {
+                        return $class;
+                    }
+                }
+                return "$elClass (unknown)";
+        } else {
+            // ->getTag() method does exist, so use it
+            $elName = $element->getTag();
+            if (isset($taskdefs[$elName])) {
+                return $taskdefs[$elName];
+            } elseif (isset($typedefs[$elName])) {
+
+                return $typedefs[$elName];
+            } else {
+                return "$elName (unknown)";
+            }
+        }        
+    }
+
+    /** extract the name of a property from a method name - subtracting  a given prefix. */
+    function getPropertyName($methodName, $prefix) {
+        $start = strlen($prefix);
+        return strtolower(substr($methodName, $start));
+    }
+    
+    /**
+     * Prints warning message to screen if -debug was used.
+     */
+    function warn($msg) {
+        if (Phing::getMsgOutputLevel() === Project::MSG_DEBUG) {
+            print("[IntrospectionHelper] " . $msg . "\n");
+        }
+    }
+
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/Phing.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/Phing.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/Phing.php	(revision 19)
@@ -0,0 +1,1333 @@
+<?php
+/*
+ * $Id: Phing.php 342 2008-01-21 14:49:48Z mrook $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+require_once 'phing/Project.php';
+require_once 'phing/ProjectComponent.php';
+require_once 'phing/Target.php';
+require_once 'phing/Task.php';
+
+include_once 'phing/BuildException.php';
+include_once 'phing/ConfigurationException.php';
+include_once 'phing/BuildEvent.php';
+
+include_once 'phing/parser/Location.php';
+include_once 'phing/parser/ExpatParser.php';
+include_once 'phing/parser/AbstractHandler.php';
+include_once 'phing/parser/ProjectConfigurator.php';
+include_once 'phing/parser/RootHandler.php';
+include_once 'phing/parser/ProjectHandler.php';
+include_once 'phing/parser/TaskHandler.php';
+include_once 'phing/parser/TargetHandler.php';
+include_once 'phing/parser/DataTypeHandler.php';
+include_once 'phing/parser/NestedElementHandler.php';
+
+include_once 'phing/system/util/Properties.php';
+include_once 'phing/util/StringHelper.php';
+include_once 'phing/system/io/PhingFile.php';
+include_once 'phing/system/io/OutputStream.php';
+include_once 'phing/system/io/FileOutputStream.php';
+include_once 'phing/system/io/FileReader.php';
+include_once 'phing/system/util/Register.php';
+
+/**
+ * Entry point into Phing.  This class handles the full lifecycle of a build -- from
+ * parsing & handling commandline arguments to assembling the project to shutting down
+ * and cleaning up in the end.
+ *
+ * If you are invoking Phing from an external application, this is still
+ * the class to use.  Your applicaiton can invoke the start() method, passing
+ * any commandline arguments or additional properties.
+ *
+ * @author    Andreas Aderhold <andi@binarycloud.com>
+ * @author    Hans Lellelid <hans@xmpl.org>
+ * @version   $Revision: 1.51 $
+ * @package   phing
+ */
+class Phing {
+
+	/** The default build file name */
+	const DEFAULT_BUILD_FILENAME = "build.xml";
+
+	/** Our current message output status. Follows Project::MSG_XXX */
+	private static $msgOutputLevel = Project::MSG_INFO;
+
+	/** PhingFile that we are using for configuration */
+	private $buildFile = null;
+
+	/** The build targets */
+	private $targets = array();
+
+	/**
+	 * Set of properties that are passed in from commandline or invoking code.
+	 * @var Properties
+	 */
+	private static $definedProps;
+
+	/** Names of classes to add as listeners to project */
+	private $listeners = array();
+
+	private $loggerClassname = null;
+
+	/** The class to handle input (can be only one). */
+	private $inputHandlerClassname;
+
+	/** Indicates if this phing should be run */
+	private $readyToRun = false;
+
+	/** Indicates we should only parse and display the project help information */
+	private $projectHelp = false;
+
+	/** Used by utility function getResourcePath() */
+	private static $importPaths;
+
+	/** System-wide static properties (moved from System) */
+	private static $properties = array();
+
+	/** Static system timer. */
+	private static $timer;
+
+	/** The current Project */
+	private static $currentProject;
+
+	/** Whether to capture PHP errors to buffer. */
+	private static $phpErrorCapture = false;
+
+	/** Array of captured PHP errors */
+	private static $capturedPhpErrors = array();
+
+	/**
+	 * @var OUtputStream Stream for standard output.
+	 */
+	private static $out;
+
+	/**
+	 * @var OutputStream Stream for error output.
+	 */
+	private static $err;
+
+	/**
+	 * @var boolean Whether we are using a logfile.
+	 */
+	private static $isLogFileUsed = false;
+	
+	/**
+	 * Array to hold original ini settings that Phing changes (and needs
+	 * to restore in restoreIni() method).
+	 *
+	 * @var array Struct of array(setting-name => setting-value)
+	 * @see restoreIni()
+	 */
+	private static $origIniSettings = array();
+
+	/**
+	 * Entry point allowing for more options from other front ends.
+	 *
+	 * This method encapsulates the complete build lifecycle.
+	 *
+	 * @param array $args The commandline args passed to phing shell script.
+	 * @param array $additionalUserProperties   Any additional properties to be passed to Phing (alternative front-end might implement this).
+	 *                                          These additional properties will be available using the getDefinedProperty() method and will
+	 *                                          be added to the project's "user" properties
+	 * @see execute()
+	 * @see runBuild()
+	 * @throws Exception - if there is an error during build
+	 */
+	public static function start($args, array $additionalUserProperties = null) {
+		
+		try {
+			$m = new Phing();
+			$m->execute($args);
+		} catch (Exception $exc) {
+			self::handleLogfile();
+			throw $exc;
+		}
+
+		if ($additionalUserProperties !== null) {
+			foreach($additionalUserProperties as $key => $value) {
+				$m->setDefinedProperty($key, $value);
+			}
+		}
+
+		try {
+			$m->runBuild();
+		} catch(Exception $exc) {
+			self::handleLogfile();
+			throw $exc;
+		}
+
+		// everything fine, shutdown
+		self::handleLogfile();
+	}
+
+	/**
+	 * Prints the message of the Exception if it's not null.
+	 * @param Exception $t
+	 */
+	public static function printMessage(Exception $t) {
+		if (self::$err === null) { // Make sure our error output is initialized
+			self::initializeOutputStreams();
+		}
+		if (self::getMsgOutputLevel() >= Project::MSG_VERBOSE) {
+			self::$err->write($t->__toString() . PHP_EOL);
+		} else {
+			self::$err->write($t->getMessage() . PHP_EOL);
+		}
+	}
+
+	/**
+	 * Sets the stdout and stderr streams if they are not already set.
+	 */
+	private static function initializeOutputStreams() {
+		if (self::$out === null) {
+			self::$out = new OutputStream(fopen("php://stdout", "w"));
+		}
+		if (self::$err === null) {
+			self::$err = new OutputStream(fopen("php://stderr", "w"));
+		}
+	}
+
+	/**
+	 * Sets the stream to use for standard (non-error) output.
+	 * @param OutputStream $stream The stream to use for standard output.
+	 */
+	public static function setOutputStream(OutputStream $stream) {
+		self::$out = $stream;
+	}
+
+	/**
+	 * Gets the stream to use for standard (non-error) output.
+	 * @return OutputStream
+	 */
+	public static function getOutputStream() {
+		return self::$out;
+	}
+
+	/**
+	 * Sets the stream to use for error output.
+	 * @param OutputStream $stream The stream to use for error output.
+	 */
+	public static function setErrorStream(OutputStream $stream) {
+		self::$err = $stream;
+	}
+
+	/**
+	 * Gets the stream to use for error output.
+	 * @return OutputStream
+	 */
+	public static function getErrorStream() {
+		return self::$err;
+	}
+
+	/**
+	 * Close logfiles, if we have been writing to them.
+	 *
+	 * @since Phing 2.3.0
+	 */
+	private static function handleLogfile() {
+		if (self::$isLogFileUsed) {
+			self::$err->close();
+			self::$out->close();
+		}
+	}
+
+	/**
+	 * Making output level a static property so that this property
+	 * can be accessed by other parts of the system, enabling
+	 * us to display more information -- e.g. backtraces -- for "debug" level.
+	 * @return int
+	 */
+	public static function getMsgOutputLevel() {
+		return self::$msgOutputLevel;
+	}
+
+	/**
+	 * Command line entry point. This method kicks off the building
+	 * of a project object and executes a build using either a given
+	 * target or the default target.
+	 *
+	 * @param array $args Command line args.
+	 * @return void
+	 */
+	public static function fire($args) {
+		self::start($args, null);
+	}
+
+	/**
+	 * Setup/initialize Phing environment from commandline args.
+	 * @param array $args commandline args passed to phing shell.
+	 * @return void
+	 */
+	public function execute($args) {
+
+		self::$definedProps = new Properties();
+		$this->searchForThis = null;
+		
+		// 1) First handle any options which should always
+		// Note: The order in which these are executed is important (if multiple of these options are specified)
+		
+		if (in_array('-help', $args) || in_array('-h', $args)) {
+			$this->printUsage();
+			return;
+		}
+		
+		if (in_array('-version', $args) || in_array('-v', $args)) {
+			$this->printVersion();
+			return;
+		}
+		
+		// 2) Next pull out stand-alone args.
+		// Note: The order in which these are executed is important (if multiple of these options are specified)
+		
+		if (false !== ($key = array_search('-quiet', $args, true))) {
+			self::$msgOutputLevel = Project::MSG_WARN;
+			unset($args[$key]);
+		}
+		
+		if (false !== ($key = array_search('-verbose', $args, true))) {
+			self::$msgOutputLevel = Project::MSG_VERBOSE;
+			unset($args[$key]);
+		}
+		
+		if (false !== ($key = array_search('-debug', $args, true))) {
+			self::$msgOutputLevel = Project::MSG_DEBUG;
+			unset($args[$key]);
+		}
+		
+		// 3) Finally, cycle through to parse remaining args
+		// 
+		$keys = array_keys($args); // Use keys and iterate to max(keys) since there may be some gaps
+		for($i=0, $max = max(array_keys($args)); $i <= $max; $i++) {
+			
+			if (!array_key_exists($i, $args)) {
+				// skip this argument, since it must have been removed above.
+				continue;
+			}
+			
+			$arg = $args[$i];
+			
+			if ($arg == "-logfile") {
+				try {
+					// see: http://phing.info/trac/ticket/65
+					if (!isset($args[$i+1])) {
+						$msg = "You must specify a log file when using the -logfile argument\n";
+						throw new ConfigurationException($msg);
+					} else {
+						$logFile = new PhingFile($args[++$i]);
+						$out = new FileOutputStream($logFile); // overwrite
+						self::setOutputStream($out);
+						self::setErrorStream($out);
+						self::$isLogFileUsed = true;
+					}
+				} catch (IOException $ioe) {
+					$msg = "Cannot write on the specified log file. Make sure the path exists and you have write permissions.";
+					throw new ConfigurationException($msg, $ioe);
+				}
+			} elseif ($arg == "-buildfile" || $arg == "-file" || $arg == "-f") {
+				if (!isset($args[$i+1])) {
+					$msg = "You must specify a buildfile when using the -buildfile argument.";
+					throw new ConfigurationException($msg);
+				} else {
+					$this->buildFile = new PhingFile($args[++$i]);
+				}
+			} elseif ($arg == "-listener") {
+				if (!isset($args[$i+1])) {
+					$msg = "You must specify a listener class when using the -listener argument";
+					throw new ConfigurationException($msg);
+				} else {
+					$this->listeners[] = $args[++$i];
+				}
+			} elseif (StringHelper::startsWith("-D", $arg)) {
+				$name = substr($arg, 2);
+				$value = null;
+				$posEq = strpos($name, "=");
+				if ($posEq !== false) {
+					$value = substr($name, $posEq+1);
+					$name  = substr($name, 0, $posEq);
+				} elseif ($i < count($args)-1) {
+					$value = $args[++$i];
+				}
+				self::$definedProps->setProperty($name, $value);
+			} elseif ($arg == "-logger") {
+				if (!isset($args[$i+1])) {
+					$msg = "You must specify a classname when using the -logger argument";
+					throw new ConfigurationException($msg);
+				} else {
+					$this->loggerClassname = $args[++$i];
+				}
+			} elseif ($arg == "-inputhandler") {
+				if ($this->inputHandlerClassname !== null) {
+					throw new ConfigurationException("Only one input handler class may be specified.");
+				}
+				if (!isset($args[$i+1])) {
+					$msg = "You must specify a classname when using the -inputhandler argument";
+					throw new ConfigurationException($msg);
+				} else {
+					$this->inputHandlerClassname = $args[++$i];
+				}
+			} elseif ($arg == "-projecthelp" || $arg == "-targets" || $arg == "-list" || $arg == "-l" || $arg == "-p") {
+				// set the flag to display the targets and quit
+				$this->projectHelp = true;
+			} elseif ($arg == "-find") {
+				// eat up next arg if present, default to build.xml
+				if ($i < count($args)-1) {
+					$this->searchForThis = $args[++$i];
+				} else {
+					$this->searchForThis = self::DEFAULT_BUILD_FILENAME;
+				}
+			} elseif (substr($arg,0,1) == "-") {
+				// we don't have any more args
+				self::$err->write("Unknown argument: $arg" . PHP_EOL);
+				self::printUsage();
+				return;
+			} else {
+				// if it's no other arg, it may be the target
+				array_push($this->targets, $arg);
+			}
+		}
+
+		// if buildFile was not specified on the command line,
+		if ($this->buildFile === null) {
+			// but -find then search for it
+			if ($this->searchForThis !== null) {
+				$this->buildFile = $this->_findBuildFile(self::getProperty("user.dir"), $this->searchForThis);
+			} else {
+				$this->buildFile = new PhingFile(self::DEFAULT_BUILD_FILENAME);
+			}
+		}
+		// make sure buildfile exists
+		if (!$this->buildFile->exists()) {
+			throw new ConfigurationException("Buildfile: " . $this->buildFile->__toString() . " does not exist!");
+		}
+
+		// make sure it's not a directory
+		if ($this->buildFile->isDirectory()) {
+			throw new ConfigurationException("Buildfile: " . $this->buildFile->__toString() . " is a dir!");
+		}
+
+		$this->readyToRun = true;
+	}
+
+	/**
+	 * Helper to get the parent file for a given file.
+	 *
+	 * @param PhingFile $file
+	 * @return PhingFile Parent file or null if none
+	 */
+	private function _getParentFile(PhingFile $file) {
+		$filename = $file->getAbsolutePath();
+		$file     = new PhingFile($filename);
+		$filename = $file->getParent();
+		return ($filename === null) ? null : new PhingFile($filename);
+	}
+
+	/**
+	 * Search parent directories for the build file.
+	 *
+	 * Takes the given target as a suffix to append to each
+	 * parent directory in search of a build file.  Once the
+	 * root of the file-system has been reached an exception
+	 * is thrown.
+	 *
+	 * @param string $start Start file path.
+	 * @param string $suffix Suffix filename to look for in parents.
+	 * @return PhingFile A handle to the build file
+	 *
+	 * @throws BuildException    Failed to locate a build file
+	 */
+	private function _findBuildFile($start, $suffix) {
+		$startf = new PhingFile($start);
+		$parent = new PhingFile($startf->getAbsolutePath());
+		$file   = new PhingFile($parent, $suffix);
+
+		// check if the target file exists in the current directory
+		while (!$file->exists()) {
+			// change to parent directory
+			$parent = $this->_getParentFile($parent);
+
+			// if parent is null, then we are at the root of the fs,
+			// complain that we can't find the build file.
+			if ($parent === null) {
+				throw new ConfigurationException("Could not locate a build file!");
+			}
+			// refresh our file handle
+			$file = new PhingFile($parent, $suffix);
+		}
+		return $file;
+	}
+
+	/**
+	 * Executes the build.
+	 * @return void
+	 */
+	function runBuild() {
+
+		if (!$this->readyToRun) {
+			return;
+		}
+
+		$project = new Project();
+
+		self::setCurrentProject($project);
+		set_error_handler(array('Phing', 'handlePhpError'));
+
+		$error = null;
+
+		$this->addBuildListeners($project);
+		$this->addInputHandler($project);
+
+		// set this right away, so that it can be used in logging.
+		$project->setUserProperty("phing.file", $this->buildFile->getAbsolutePath());
+
+		try {
+			$project->fireBuildStarted();
+			$project->init();
+		} catch (Exception $exc) {
+			$project->fireBuildFinished($exc);
+			throw $exc;
+		}
+
+		$project->setUserProperty("phing.version", $this->getPhingVersion());
+
+		$e = self::$definedProps->keys();
+		while (count($e)) {
+			$arg   = (string) array_shift($e);
+			$value = (string) self::$definedProps->getProperty($arg);
+			$project->setUserProperty($arg, $value);
+		}
+		unset($e);
+
+		$project->setUserProperty("phing.file", $this->buildFile->getAbsolutePath());
+
+		// first use the Configurator to create the project object
+		// from the given build file.
+
+		try {
+			ProjectConfigurator::configureProject($project, $this->buildFile);
+		} catch (Exception $exc) {
+			$project->fireBuildFinished($exc);
+			restore_error_handler();
+			self::unsetCurrentProject();
+			throw $exc;
+		}
+
+		// make sure that we have a target to execute
+		if (count($this->targets) === 0) {
+			$this->targets[] = $project->getDefaultTarget();
+		}
+
+		// execute targets if help param was not given
+		if (!$this->projectHelp) {
+
+			try {
+				$project->executeTargets($this->targets);
+			} catch (Exception $exc) {
+				$project->fireBuildFinished($exc);
+				restore_error_handler();
+				self::unsetCurrentProject();
+				throw $exc;
+			}
+		}
+		// if help is requested print it
+		if ($this->projectHelp) {
+			try {
+				$this->printDescription($project);
+				$this->printTargets($project);
+			} catch (Exception $exc) {
+				$project->fireBuildFinished($exc);
+				restore_error_handler();
+				self::unsetCurrentProject();
+				throw $exc;
+			}
+		}
+
+		// finally {
+		if (!$this->projectHelp) {
+			$project->fireBuildFinished(null);
+		}
+
+		restore_error_handler();
+		self::unsetCurrentProject();
+	}
+
+	/**
+	 * Bind any registered build listeners to this project.
+	 *
+	 * This means adding the logger and any build listeners that were specified
+	 * with -listener arg.
+	 *
+	 * @param Project $project
+	 * @return void
+	 */
+	private function addBuildListeners(Project $project) {
+		// Add the default listener
+		$project->addBuildListener($this->createLogger());
+
+		foreach($this->listeners as $listenerClassname) {
+			try {
+				$clz = Phing::import($listenerClassname);
+			} catch (Exception $x) {
+				$msg = "Unable to instantiate specified listener "
+				. "class " . $listenerClassname . " : "
+				. $e->getMessage();
+				throw new ConfigurationException($msg);
+			}
+				
+			$listener = new $clz();
+				
+			if ($listener instanceof StreamRequiredBuildLogger) {
+				throw new ConfigurationException("Unable to add " . $listenerClassname . " as a listener, since it requires explicit error/output streams. (You can specify it as a -logger.)");
+			}
+			$project->addBuildListener($listener);
+		}
+	}
+
+	/**
+	 * Creates the InputHandler and adds it to the project.
+	 *
+	 * @param Project $project the project instance.
+	 *
+	 * @throws BuildException if a specified InputHandler
+	 *                           class could not be loaded.
+	 */
+	private function addInputHandler(Project $project) {
+		if ($this->inputHandlerClassname === null) {
+			$handler = new DefaultInputHandler();
+		} else {
+			try {
+				$clz = Phing::import($this->inputHandlerClassname);
+				$handler = new $clz();
+				if ($project !== null && method_exists($handler, 'setProject')) {
+					$handler->setProject($project);
+				}
+			} catch (Exception $e) {
+				$msg = "Unable to instantiate specified input handler "
+				. "class " . $this->inputHandlerClassname . " : "
+				. $e->getMessage();
+				throw new ConfigurationException($msg);
+			}
+		}
+		$project->setInputHandler($handler);
+	}
+
+	/**
+	 * Creates the default build logger for sending build events to the log.
+	 * @return BuildLogger The created Logger
+	 */
+	private function createLogger() {
+		if ($this->loggerClassname !== null) {
+			self::import($this->loggerClassname);
+			// get class name part
+			$classname = self::import($this->loggerClassname);
+			$logger = new $classname;
+			if (!($logger instanceof BuildLogger)) {
+				throw new BuildException($classname . ' does not implement the BuildLogger interface.');
+			}
+		} else {
+			require_once 'phing/listener/DefaultLogger.php';
+			$logger = new DefaultLogger();
+		}
+		$logger->setMessageOutputLevel(self::$msgOutputLevel);
+		$logger->setOutputStream(self::$out);
+		$logger->setErrorStream(self::$err);
+		return $logger;
+	}
+
+	/**
+	 * Sets the current Project
+	 * @param Project $p
+	 */
+	public static function setCurrentProject($p) {
+		self::$currentProject = $p;
+	}
+
+	/**
+	 * Unsets the current Project
+	 */
+	public static function unsetCurrentProject() {
+		self::$currentProject = null;
+	}
+
+	/**
+	 * Gets the current Project.
+	 * @return Project Current Project or NULL if none is set yet/still.
+	 */
+	public static function getCurrentProject() {
+		return self::$currentProject;
+	}
+
+	/**
+	 * A static convenience method to send a log to the current (last-setup) Project.
+	 * If there is no currently-configured Project, then this will do nothing.
+	 * @param string $message
+	 * @param int $priority Project::MSG_INFO, etc.
+	 */
+	public static function log($message, $priority = Project::MSG_INFO) {
+		$p = self::getCurrentProject();
+		if ($p) {
+			$p->log($message, $priority);
+		}
+	}
+
+	/**
+	 * Error handler for PHP errors encountered during the build.
+	 * This uses the logging for the currently configured project.
+	 */
+	public static function handlePhpError($level, $message, $file, $line) {
+
+		// don't want to print supressed errors
+		if (error_reporting() > 0) {
+
+			if (self::$phpErrorCapture) {
+					
+				self::$capturedPhpErrors[] = array('message' => $message, 'level' => $level, 'line' => $line, 'file' => $file);
+
+			} else {
+					
+				$message = '[PHP Error] ' . $message;
+				$message .= ' [line ' . $line . ' of ' . $file . ']';
+
+				switch ($level) {
+
+					case E_STRICT:
+					case E_NOTICE:
+					case E_USER_NOTICE:
+						self::log($message, Project::MSG_VERBOSE);
+						break;
+					case E_WARNING:
+					case E_USER_WARNING:
+						self::log($message, Project::MSG_WARN);
+						break;
+					case E_ERROR:
+					case E_USER_ERROR:
+					default:
+						self::log($message, Project::MSG_ERR);
+
+				} // switch
+
+			} // if phpErrorCapture
+
+		} // if not @
+
+	}
+
+	/**
+	 * Begins capturing PHP errors to a buffer.
+	 * While errors are being captured, they are not logged.
+	 */
+	public static function startPhpErrorCapture() {
+		self::$phpErrorCapture = true;
+		self::$capturedPhpErrors = array();
+	}
+
+	/**
+	 * Stops capturing PHP errors to a buffer.
+	 * The errors will once again be logged after calling this method.
+	 */
+	public static function stopPhpErrorCapture() {
+		self::$phpErrorCapture = false;
+	}
+
+	/**
+	 * Clears the captured errors without affecting the starting/stopping of the capture.
+	 */
+	public static function clearCapturedPhpErrors() {
+		self::$capturedPhpErrors = array();
+	}
+
+	/**
+	 * Gets any PHP errors that were captured to buffer.
+	 * @return array array('message' => message, 'line' => line number, 'file' => file name, 'level' => error level)
+	 */
+	public static function getCapturedPhpErrors() {
+		return self::$capturedPhpErrors;
+	}
+
+	/**  Prints the usage of how to use this class */
+	public static function printUsage() {
+
+		$msg = "";
+		$msg .= "phing [options] [target [target2 [target3] ...]]" . PHP_EOL;
+		$msg .= "Options: " . PHP_EOL;
+		$msg .= "  -h -help               print this message" . PHP_EOL;
+		$msg .= "  -l -list               list available targets in this project" . PHP_EOL;
+		$msg .= "  -v -version            print the version information and exit" . PHP_EOL;
+		$msg .= "  -q -quiet              be extra quiet" . PHP_EOL;
+		$msg .= "  -verbose               be extra verbose" . PHP_EOL;
+		$msg .= "  -debug                 print debugging information" . PHP_EOL;
+		$msg .= "  -logfile <file>        use given file for log" . PHP_EOL;
+		$msg .= "  -logger <classname>    the class which is to perform logging" . PHP_EOL;
+		$msg .= "  -f -buildfile <file>   use given buildfile" . PHP_EOL;
+		$msg .= "  -D<property>=<value>   use value for given property" . PHP_EOL;
+		$msg .= "  -find <file>           search for buildfile towards the root of the" . PHP_EOL;
+		$msg .= "                         filesystem and use it" . PHP_EOL;
+		$msg .= "  -inputhandler <file>   the class to use to handle user input" . PHP_EOL;
+		//$msg .= "  -recursive <file>      search for buildfile downwards and use it" . PHP_EOL;
+		$msg .= PHP_EOL;
+		$msg .= "Report bugs to <dev@phing.tigris.org>".PHP_EOL;
+		self::$err->write($msg);
+	}
+
+	/**
+	 * Prints the current Phing version.
+	 */
+	public static function printVersion() {
+		self::$out->write(self::getPhingVersion().PHP_EOL);
+	}
+
+	/**
+	 * Gets the current Phing version based on VERSION.TXT file.
+	 * @return string
+	 * @throws BuildException - if unable to find version file.
+	 */
+	function getPhingVersion() {
+		$versionPath = self::getResourcePath("phing/etc/VERSION.TXT");
+		if ($versionPath === null) {
+			$versionPath = self::getResourcePath("etc/VERSION.TXT");
+		}
+		if ($versionPath === null) {
+			throw new ConfigurationException("No VERSION.TXT file found; try setting phing.home environment variable.");
+		}
+		try { // try to read file
+			$buffer = null;
+			$file = new PhingFile($versionPath);
+			$reader = new FileReader($file);
+			$reader->readInto($buffer);
+			$buffer = trim($buffer);
+			//$buffer = "PHING version 1.0, Released 2002-??-??";
+			$phingVersion = $buffer;
+		} catch (IOException $iox) {
+			throw new ConfigurationException("Can't read version information file");
+		}
+		return $phingVersion;
+	}
+
+	/**
+	 * Print the project description, if any
+	 */
+	public static function printDescription(Project $project) {
+		if ($project->getDescription() !== null) {
+			self::$out->write($project->getDescription() . PHP_EOL);
+		}
+	}
+
+	/** Print out a list of all targets in the current buildfile */
+	function printTargets($project) {
+		// find the target with the longest name
+		$maxLength = 0;
+		$targets = $project->getTargets();
+		$targetNames = array_keys($targets);
+		$targetName = null;
+		$targetDescription = null;
+		$currentTarget = null;
+
+		// split the targets in top-level and sub-targets depending
+		// on the presence of a description
+
+		$subNames = array();
+		$topNameDescMap = array();
+
+		foreach($targets as $currentTarget) {
+			$targetName = $currentTarget->getName();
+			$targetDescription = $currentTarget->getDescription();
+
+			// subtargets are targets w/o descriptions
+			if ($targetDescription === null) {
+				$subNames[] = $targetName;
+			} else {
+				// topNames and topDescriptions are handled later
+				// here we store in hash map (for sorting purposes)
+				$topNameDescMap[$targetName] = $targetDescription;
+				if (strlen($targetName) > $maxLength) {
+					$maxLength = strlen($targetName);
+				}
+			}
+		}
+
+		// Sort the arrays
+		sort($subNames); // sort array values, resetting keys (which are numeric)
+		ksort($topNameDescMap); // sort the keys (targetName) keeping key=>val associations
+
+		$topNames = array_keys($topNameDescMap);
+		$topDescriptions = array_values($topNameDescMap);
+
+		$defaultTarget = $project->getDefaultTarget();
+
+		if ($defaultTarget !== null && $defaultTarget !== "") {
+			$defaultName = array();
+			$defaultDesc = array();
+			$defaultName[] = $defaultTarget;
+
+			$indexOfDefDesc = array_search($defaultTarget, $topNames, true);
+			if ($indexOfDefDesc !== false && $indexOfDefDesc >= 0) {
+				$defaultDesc = array();
+				$defaultDesc[] = $topDescriptions[$indexOfDefDesc];
+			}
+
+			$this->_printTargets($defaultName, $defaultDesc, "Default target:", $maxLength);
+
+		}
+		$this->_printTargets($topNames, $topDescriptions, "Main targets:", $maxLength);
+		$this->_printTargets($subNames, null, "Subtargets:", 0);
+	}
+
+	/**
+	 * Writes a formatted list of target names with an optional description.
+	 *
+	 * @param array $names The names to be printed.
+	 *              Must not be <code>null</code>.
+	 * @param array $descriptions The associated target descriptions.
+	 *                     May be <code>null</code>, in which case
+	 *                     no descriptions are displayed.
+	 *                     If non-<code>null</code>, this should have
+	 *                     as many elements as <code>names</code>.
+	 * @param string $heading The heading to display.
+	 *                Should not be <code>null</code>.
+	 * @param int $maxlen The maximum length of the names of the targets.
+	 *               If descriptions are given, they are padded to this
+	 *               position so they line up (so long as the names really
+	 *               <i>are</i> shorter than this).
+	 */
+	private function _printTargets($names, $descriptions, $heading, $maxlen) {
+
+		$spaces = '  ';
+		while (strlen($spaces) < $maxlen) {
+			$spaces .= $spaces;
+		}
+		$msg = "";
+		$msg .= $heading . PHP_EOL;
+		$msg .= str_repeat("-",79) . PHP_EOL;
+
+		$total = count($names);
+		for($i=0; $i < $total; $i++) {
+			$msg .= " ";
+			$msg .= $names[$i];
+			if (!empty($descriptions)) {
+				$msg .= substr($spaces, 0, $maxlen - strlen($names[$i]) + 2);
+				$msg .= $descriptions[$i];
+			}
+			$msg .= PHP_EOL;
+		}
+		if ($total > 0) {
+			self::$out->write($msg . PHP_EOL);
+		}
+	}
+
+	/**
+	 * Import a dot-path notation class path.
+	 * @param string $dotPath
+	 * @param mixed $classpath String or object supporting __toString()
+	 * @return string The unqualified classname (which can be instantiated).
+	 * @throws BuildException - if cannot find the specified file
+	 */
+	public static function import($dotPath, $classpath = null) {
+
+		// first check to see that the class specified hasn't already been included.
+		// (this also handles case where this method is called w/ a classname rather than dotpath)
+		$classname = StringHelper::unqualify($dotPath);
+		if (class_exists($classname, false)) {
+			return $classname;
+		}
+
+		$dotClassname = basename($dotPath);
+		$dotClassnamePos = strlen($dotPath) - strlen($dotClassname);
+			
+		// 1- temporarily replace escaped '.' with another illegal char (#)
+		$tmp = str_replace('\.', '##', $dotClassname);
+		// 2- swap out the remaining '.' with DIR_SEP
+		$tmp = strtr($tmp, '.', DIRECTORY_SEPARATOR);
+		// 3- swap back the escaped '.'
+		$tmp = str_replace('##', '.', $tmp);
+
+		$classFile = $tmp . ".php";
+
+		$path = substr_replace($dotPath, $classFile, $dotClassnamePos);
+
+		Phing::__import($path, $classpath);
+
+		return $classname;
+	}
+
+	/**
+	 * Import a PHP file
+	 * @param string $path Path to the PHP file
+	 * @param mixed $classpath String or object supporting __toString()
+	 * @throws BuildException - if cannot find the specified file
+	 */
+	public static function __import($path, $classpath = null) {
+
+		if ($classpath) {
+
+			// Apparently casting to (string) no longer invokes __toString() automatically.
+			if (is_object($classpath)) {
+				$classpath = $classpath->__toString();
+			}
+
+			// classpaths are currently additive, but we also don't want to just
+			// indiscriminantly prepand/append stuff to the include_path.  This means
+			// we need to parse current incldue_path, and prepend any
+			// specified classpath locations that are not already in the include_path.
+			//
+			// NOTE:  the reason why we do it this way instead of just changing include_path
+			// and then changing it back, is that in many cases applications (e.g. Propel) will
+			// include/require class files from within method calls.  This means that not all
+			// necessary files will be included in this import() call, and hence we can't
+			// change the include_path back without breaking those apps.  While this method could
+			// be more expensive than switching & switching back (not sure, but maybe), it makes it
+			// possible to write far less expensive run-time applications (e.g. using Propel), which is
+			// really where speed matters more.
+
+			$curr_parts = explode(PATH_SEPARATOR, get_include_path());
+			$add_parts = explode(PATH_SEPARATOR, $classpath);
+			$new_parts = array_diff($add_parts, $curr_parts);
+			if ($new_parts) {
+				set_include_path(implode(PATH_SEPARATOR, array_merge($new_parts, $curr_parts)));
+			}
+		}
+
+		$ret = include_once($path);
+
+		if ($ret === false) {
+			$msg = "Error importing $path";
+			if (self::getMsgOutputLevel() >= Project::MSG_DEBUG) {
+				$x = new Exception("for-path-trace-only");
+				$msg .= $x->getTraceAsString();
+			}
+			throw new ConfigurationException($msg);
+		}
+	}
+
+	/**
+	 * Looks on include path for specified file.
+	 * @return string File found (null if no file found).
+	 */
+	public static function getResourcePath($path) {
+
+		if (self::$importPaths === null) {
+			$paths = get_include_path();
+			self::$importPaths = explode(PATH_SEPARATOR, ini_get("include_path"));
+		}
+
+		$path = str_replace('\\', DIRECTORY_SEPARATOR, $path);
+		$path = str_replace('/', DIRECTORY_SEPARATOR, $path);
+
+		foreach (self::$importPaths as $prefix) {
+			$testPath = $prefix . DIRECTORY_SEPARATOR . $path;
+			if (file_exists($testPath)) {
+				return $testPath;
+			}
+		}
+
+		// Check for the property phing.home
+		$homeDir = self::getProperty('phing.home');
+		if ($homeDir) {
+			$testPath = $homeDir . DIRECTORY_SEPARATOR . $path;
+			if (file_exists($testPath)) {
+				return $testPath;
+			}
+		}
+
+		// If we are using this via PEAR then check for the file in the data dir
+		// This is a bit of a hack, but works better than previous solution of assuming
+		// data_dir is on the include_path.
+		$dataDir = '@DATA-DIR@';
+		if ($dataDir{0} != '@') { // if we're using PEAR then the @ DATA-DIR @ token will have been substituted.
+			$testPath = $dataDir . DIRECTORY_SEPARATOR . $path;
+			if (file_exists($testPath)) {
+				return $testPath;
+			}
+		} else {
+			// We're not using PEAR, so do one additional check based on path of 
+			// current file (Phing.php)
+			$maybeHomeDir = realpath(dirname(__FILE__) . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR  . '..');
+			$testPath = $maybeHomeDir . DIRECTORY_SEPARATOR . $path; 
+			if (file_exists($testPath)) {
+				return $testPath;
+			}
+		}
+
+		return null;
+	}
+
+	// -------------------------------------------------------------------------------------------
+	// System-wide methods (moved from System class, which had namespace conflicts w/ PEAR System)
+	// -------------------------------------------------------------------------------------------
+
+	/**
+	 * Set System constants which can be retrieved by calling Phing::getProperty($propName).
+	 * @return void
+	 */
+	private static function setSystemConstants() {
+
+		/*
+		 * PHP_OS returns on
+		 *   WindowsNT4.0sp6  => WINNT
+		 *   Windows2000      => WINNT
+		 *   Windows ME       => WIN32
+		 *   Windows 98SE     => WIN32
+		 *   FreeBSD 4.5p7    => FreeBSD
+		 *   Redhat Linux     => Linux
+		 *   Mac OS X		  => Darwin
+		 */
+		self::setProperty('host.os', PHP_OS);
+
+		// this is used by some tasks too
+		self::setProperty('os.name', PHP_OS);
+
+		// it's still possible this won't be defined,
+		// e.g. if Phing is being included in another app w/o
+		// using the phing.php script.
+		if (!defined('PHP_CLASSPATH')) {
+			define('PHP_CLASSPATH', get_include_path());
+		}
+
+		self::setProperty('php.classpath', PHP_CLASSPATH);
+
+		// try to determine the host filesystem and set system property
+		// used by Fileself::getFileSystem to instantiate the correct
+		// abstraction layer
+
+		switch (strtoupper(PHP_OS)) {
+			case 'WINNT':
+				self::setProperty('host.fstype', 'WINNT');
+				self::setProperty('php.interpreter', getenv('PHP_COMMAND'));
+				break;
+			case 'WIN32':
+				self::setProperty('host.fstype', 'WIN32');
+				break;
+			default:
+				self::setProperty('host.fstype', 'UNIX');
+				break;
+		}
+
+		self::setProperty('line.separator', PHP_EOL);
+		self::setProperty('php.version', PHP_VERSION);
+		self::setProperty('user.home', getenv('HOME'));
+		self::setProperty('application.startdir', getcwd());
+
+		// try to detect machine dependent information
+		$sysInfo = array();
+		if (strtoupper(substr(PHP_OS, 0, 3)) !== 'WIN' && function_exists("posix_uname")) {
+			$sysInfo = posix_uname();
+		} else {
+			$sysInfo['nodename'] = php_uname('n');
+			$sysInfo['machine']= php_uname('m') ;
+			//this is a not so ideal substition, but maybe better than nothing
+			$sysInfo['domain'] = isset($_SERVER['SERVER_NAME']) ? $_SERVER['SERVER_NAME'] : "unknown";
+			$sysInfo['release'] = php_uname('r');
+			$sysInfo['version'] = php_uname('v');
+		}
+			
+
+		self::setProperty("host.name", isset($sysInfo['nodename']) ? $sysInfo['nodename'] : "unknown");
+		self::setProperty("host.arch", isset($sysInfo['machine']) ? $sysInfo['machine'] : "unknown");
+		self::setProperty("host.domain",isset($sysInfo['domain']) ? $sysInfo['domain'] : "unknown");
+		self::setProperty("host.os.release", isset($sysInfo['release']) ? $sysInfo['release'] : "unknown");
+		self::setProperty("host.os.version", isset($sysInfo['version']) ? $sysInfo['version'] : "unknown");
+		unset($sysInfo);
+	}
+
+	/**
+	 * This gets a property that was set via command line or otherwise passed into Phing.
+	 * "Defined" in this case means "externally defined".  The reason this method exists is to
+	 * provide a public means of accessing commandline properties for (e.g.) logger or listener
+	 * scripts.  E.g. to specify which logfile to use, PearLogger needs to be able to access
+	 * the pear.log.name property.
+	 *
+	 * @param string $name
+	 * @return string value of found property (or null, if none found).
+	 */
+	public static function getDefinedProperty($name) {
+		return self::$definedProps->getProperty($name);
+	}
+
+	/**
+	 * This sets a property that was set via command line or otherwise passed into Phing.
+	 *
+	 * @param string $name
+	 * @return string value of found property (or null, if none found).
+	 */
+	public static function setDefinedProperty($name, $value) {
+		return self::$definedProps->setProperty($name, $value);
+	}
+
+	/**
+	 * Returns property value for a System property.
+	 * System properties are "global" properties like application.startdir,
+	 * and user.dir.  Many of these correspond to similar properties in Java
+	 * or Ant.
+	 *
+	 * @param string $paramName
+	 * @return string Value of found property (or null, if none found).
+	 */
+	public static function getProperty($propName) {
+
+		// some properties are detemined on each access
+		// some are cached, see below
+
+		// default is the cached value:
+		$val = isset(self::$properties[$propName]) ? self::$properties[$propName] : null;
+
+		// special exceptions
+		switch($propName) {
+			case 'user.dir':
+				$val = getcwd();
+				break;
+		}
+
+		return $val;
+	}
+
+	/** Retuns reference to all properties*/
+	public static function &getProperties() {
+		return self::$properties;
+	}
+
+	public static function setProperty($propName, $propValue) {
+		$propName = (string) $propName;
+		$oldValue = self::getProperty($propName);
+		self::$properties[$propName] = $propValue;
+		return $oldValue;
+	}
+
+	public static function currentTimeMillis() {
+		list($usec, $sec) = explode(" ",microtime());
+		return ((float)$usec + (float)$sec);
+	}
+
+	/**
+	 * Sets the include path to PHP_CLASSPATH constant (if this has been defined).
+	 * @return void
+	 * @throws ConfigurationException - if the include_path could not be set (for some bizarre reason)
+	 */
+	private static function setIncludePaths() {
+		if (defined('PHP_CLASSPATH')) {
+			$result = set_include_path(PHP_CLASSPATH);
+			if ($result === false) {
+				throw new ConfigurationException("Could not set PHP include_path.");
+			}
+			self::$origIniSettings['include_path'] = $result; // save original value for setting back later
+		}
+	}
+
+	/**
+	 * Sets PHP INI values that Phing needs.
+	 * @return void
+	 */
+	private static function setIni() {
+		
+		self::$origIniSettings['error_reporting'] = error_reporting(E_ALL);
+		
+		// We won't bother storing original max_execution_time, since 1) the value in 
+		// php.ini may be wrong (and there's no way to get the current value) and 
+		// 2) it would mean something very strange to set it to a value less than time script
+		// has already been running, which would be the likely change.
+		
+		set_time_limit(0);
+		
+		self::$origIniSettings['magic_quotes_gpc'] = ini_set('magic_quotes_gpc', 'off');
+		self::$origIniSettings['short_open_tag'] = ini_set('short_open_tag', 'off');
+		self::$origIniSettings['default_charset'] = ini_set('default_charset', 'iso-8859-1');
+		self::$origIniSettings['register_globals'] = ini_set('register_globals', 'off');
+		self::$origIniSettings['allow_call_time_pass_reference'] = ini_set('allow_call_time_pass_reference', 'on');
+		self::$origIniSettings['track_errors'] = ini_set('track_errors', 1);
+		
+		// should return memory limit in MB
+		$mem_limit = (int) ini_get('memory_limit');
+		if ($mem_limit < 32) {
+			// We do *not* need to save the original value here, since we don't plan to restore
+			// this after shutdown (we don't trust the effectiveness of PHP's garbage collection).
+			ini_set('memory_limit', '32M'); // nore: this may need to be higher for many projects
+		}
+	}
+	
+	/**
+	 * Restores [most] PHP INI values to their pre-Phing state.
+	 * 
+	 * Currently the following settings are not restored:
+	 * 	- max_execution_time (because getting current time limit is not possible)
+	 *  - memory_limit (which may have been increased by Phing)
+	 * 
+	 * @return void
+	 */
+	private static function restoreIni()
+	{
+		foreach(self::$origIniSettings as $settingName => $settingValue) {
+			switch($settingName) {
+				case 'error_reporting':
+					error_reporting($settingValue);
+					break;
+				default:
+					ini_set($settingName, $settingValue);
+			}
+		}
+	}
+
+	/**
+	 * Returns reference to Timer object.
+	 * @return Timer
+	 */
+	public static function getTimer() {
+		if (self::$timer === null) {
+			include_once 'phing/system/util/Timer.php';
+			self::$timer= new Timer();
+		}
+		return self::$timer;
+	}
+
+	/**
+	 * Start up Phing.
+	 * Sets up the Phing environment but does not initiate the build process.
+	 * @return void
+	 * @throws Exception - If the Phing environment cannot be initialized. 
+	 */
+	public static function startup() {
+
+		// setup STDOUT and STDERR defaults
+		self::initializeOutputStreams();
+
+		// some init stuff
+		self::getTimer()->start();
+
+		self::setSystemConstants();
+		self::setIncludePaths();
+		self::setIni();
+	}
+
+	/**
+	 * Halts the system.
+	 * @deprecated This method is deprecated and is no longer called by Phing internally.  Any
+	 * 				normal shutdown routines are handled by the shutdown() method.
+	 * @see shutdown()
+	 */
+	public static function halt() {
+		self::shutdown();
+	}
+
+	/**
+	 * Performs any shutdown routines, such as stopping timers.
+	 * @return void
+	 */
+	public static function shutdown() {
+		self::restoreIni();
+		self::getTimer()->stop();
+	}
+
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/Project.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/Project.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/Project.php	(revision 19)
@@ -0,0 +1,968 @@
+<?php
+/*
+ *  $Id: Project.php 345 2008-01-30 19:46:32Z mrook $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+include_once 'phing/system/io/PhingFile.php';
+include_once 'phing/util/FileUtils.php';
+include_once 'phing/TaskAdapter.php';
+include_once 'phing/util/StringHelper.php';
+include_once 'phing/BuildEvent.php';
+include_once 'phing/input/DefaultInputHandler.php';
+
+/**
+ *  The Phing project class. Represents a completely configured Phing project.
+ *  The class defines the project and all tasks/targets. It also contains
+ *  methods to start a build as well as some properties and FileSystem
+ *  abstraction.
+ *
+ * @author    Andreas Aderhold <andi@binarycloud.com>
+ * @author    Hans Lellelid <hans@xmpl.org>
+ * @version   $Revision: 1.29 $
+ * @package   phing
+ */
+class Project {
+
+	// Logging level constants.
+	const MSG_DEBUG = 4;
+	const MSG_VERBOSE = 3;
+	const MSG_INFO = 2;
+	const MSG_WARN = 1;
+	const MSG_ERR = 0;
+	
+    /** contains the targets */
+    private $targets         = array();
+    /** global filterset (future use) */
+    private $globalFilterSet = array();
+    /**  all globals filters (future use) */
+    private $globalFilters   = array();
+    
+    /** Project properties map (usually String to String). */
+    private $properties = array();
+    
+    /**
+     * Map of "user" properties (as created in the Ant task, for example).
+     * Note that these key/value pairs are also always put into the
+     * project properties, so only the project properties need to be queried.
+     * Mapping is String to String.
+     */
+    private $userProperties = array();
+    
+    /**
+     * Map of inherited "user" properties - that are those "user"
+     * properties that have been created by tasks and not been set
+     * from the command line or a GUI tool.
+     * Mapping is String to String.
+     */
+    private $inheritedProperties = array();
+    
+    /** task definitions for this project*/
+    private $taskdefs = array();
+    
+    /** type definitions for this project */
+    private $typedefs = array();
+    
+    /** holds ref names and a reference to the referred object*/
+    private $references = array();
+    
+    /** The InputHandler being used by this project. */
+    private $inputHandler;
+    
+    /* -- properties that come in via xml attributes -- */
+    
+    /** basedir (PhingFile object) */
+    private $basedir;
+    
+    /** the default target name */
+    private $defaultTarget = 'all';
+    
+    /** project name (required) */
+    private $name;
+    
+    /** project description */
+    private $description;
+
+    /** a FileUtils object */
+    private $fileUtils;
+    
+    /**  Build listeneers */
+    private $listeners = array();
+
+    /**
+     *  Constructor, sets any default vars.
+     */
+    function __construct() {
+        $this->fileUtils = new FileUtils();
+        $this->inputHandler = new DefaultInputHandler();
+    }
+
+    /**
+     * Sets the input handler
+     */
+    public function setInputHandler(InputHandler $handler) {
+        $this->inputHandler = $handler;
+    }
+
+    /**
+     * Retrieves the current input handler.
+     */
+    public function getInputHandler() {
+        return $this->inputHandler;
+    }
+
+    /** inits the project, called from main app */
+    function init() {
+        // set builtin properties
+        $this->setSystemProperties();
+        
+        // load default tasks
+        $taskdefs = Phing::getResourcePath("phing/tasks/defaults.properties");
+        
+        try { // try to load taskdefs
+            $props = new Properties();
+            $in = new PhingFile((string)$taskdefs);
+
+            if ($in === null) {
+                throw new BuildException("Can't load default task list");
+            }
+            $props->load($in);
+
+            $enum = $props->propertyNames();
+            foreach($enum as $key) {
+                $value = $props->getProperty($key);
+                $this->addTaskDefinition($key, $value);
+            }
+        } catch (IOException $ioe) {
+            throw new BuildException("Can't load default task list");
+        }
+
+        // load default tasks
+        $typedefs = Phing::getResourcePath("phing/types/defaults.properties");
+
+        try { // try to load typedefs
+            $props = new Properties();
+            $in    = new PhingFile((string)$typedefs);
+            if ($in === null) {
+                throw new BuildException("Can't load default datatype list");
+            }
+            $props->load($in);
+
+            $enum = $props->propertyNames();
+            foreach($enum as $key) {
+                $value = $props->getProperty($key);
+                $this->addDataTypeDefinition($key, $value);
+            }
+        } catch(IOException $ioe) {
+            throw new BuildException("Can't load default datatype list");
+        }
+    }
+
+    /** returns the global filterset (future use) */
+    function getGlobalFilterSet() {
+        return $this->globalFilterSet;
+    }
+
+    // ---------------------------------------------------------
+    // Property methods
+    // ---------------------------------------------------------
+    
+    /**
+     * Sets a property. Any existing property of the same name
+     * is overwritten, unless it is a user property.
+     * @param string $name The name of property to set.
+     *             Must not be <code>null</code>.
+     * @param string $value The new value of the property.
+     *              Must not be <code>null</code>.
+     * @return void
+     */
+    public function setProperty($name, $value) {
+	
+        // command line properties take precedence
+        if (isset($this->userProperties[$name])) {
+            $this->log("Override ignored for user property " . $name, Project::MSG_VERBOSE);
+            return;
+        }
+
+        if (isset($this->properties[$name])) {
+            $this->log("Overriding previous definition of property " . $name, Project::MSG_VERBOSE);
+        }
+
+        $this->log("Setting project property: " . $name . " -> " . $value, Project::MSG_DEBUG);
+        $this->properties[$name] = $value;
+    }
+
+    /**
+     * Sets a property if no value currently exists. If the property
+     * exists already, a message is logged and the method returns with
+     * no other effect.
+     *
+     * @param string $name The name of property to set.
+     *             Must not be <code>null</code>.
+     * @param string $value The new value of the property.
+     *              Must not be <code>null</code>.
+     * @since 2.0
+     */
+    public function setNewProperty($name, $value) {
+        if (isset($this->properties[$name])) {
+            $this->log("Override ignored for property " . $name, Project::MSG_DEBUG);
+            return;
+        }
+        $this->log("Setting project property: " . $name . " -> " . $value, Project::MSG_DEBUG);
+        $this->properties[$name] = $value;
+    }
+
+    /**
+     * Sets a user property, which cannot be overwritten by
+     * set/unset property calls. Any previous value is overwritten.
+     * @param string $name The name of property to set.
+     *             Must not be <code>null</code>.
+     * @param string $value The new value of the property.
+     *              Must not be <code>null</code>.
+     * @see #setProperty()
+     */
+    public function setUserProperty($name, $value) {
+        $this->log("Setting ro project property: " . $name . " -> " . $value, Project::MSG_DEBUG);
+        $this->userProperties[$name] = $value;
+        $this->properties[$name] = $value;
+    }
+
+    /**
+     * Sets a user property, which cannot be overwritten by set/unset
+     * property calls. Any previous value is overwritten. Also marks
+     * these properties as properties that have not come from the
+     * command line.
+     *
+     * @param string $name The name of property to set.
+     *             Must not be <code>null</code>.
+     * @param string $value The new value of the property.
+     *              Must not be <code>null</code>.
+     * @see #setProperty()
+     */
+    public function setInheritedProperty($name, $value) {
+        $this->inheritedProperties[$name] = $value;
+        $this->setUserProperty($name, $value);
+    }
+
+    /**
+     * Sets a property unless it is already defined as a user property
+     * (in which case the method returns silently).
+     *
+     * @param name The name of the property.
+     *             Must not be <code>null</code>.
+     * @param value The property value. Must not be <code>null</code>.
+     */
+    private function setPropertyInternal($name, $value) {
+        if (isset($this->userProperties[$name])) {
+			$this->log("Override ignored for user property " . $name, Project::MSG_VERBOSE);
+            return;
+        }
+        $this->properties[$name] = $value;
+    }
+
+    /**
+     * Returns the value of a property, if it is set.
+     *
+     * @param string $name The name of the property.
+     *             May be <code>null</code>, in which case
+     *             the return value is also <code>null</code>.
+     * @return string The property value, or <code>null</code> for no match
+     *         or if a <code>null</code> name is provided.
+     */
+    public function getProperty($name) {
+        if (!isset($this->properties[$name])) {
+            return null;
+        }
+        return $this->properties[$name];
+    }
+
+    /**
+     * Replaces ${} style constructions in the given value with the
+     * string value of the corresponding data types.
+     *
+     * @param value The string to be scanned for property references.
+     *              May be <code>null</code>.
+     *
+     * @return the given string with embedded property names replaced
+     *         by values, or <code>null</code> if the given string is
+     *         <code>null</code>.
+     *
+     * @exception BuildException if the given value has an unclosed
+     *                           property name, e.g. <code>${xxx</code>
+     */
+    public function replaceProperties($value) {
+        return ProjectConfigurator::replaceProperties($this, $value, $this->properties);
+    }
+
+    /**
+     * Returns the value of a user property, if it is set.
+     *
+     * @param string $name The name of the property.
+     *             May be <code>null</code>, in which case
+     *             the return value is also <code>null</code>.
+     * @return string  The property value, or <code>null</code> for no match
+     *         or if a <code>null</code> name is provided.
+     */
+     public function getUserProperty($name) {
+        if (!isset($this->userProperties[$name])) {
+            return null;
+        }
+        return $this->userProperties[$name];
+    }
+
+    /**
+     * Returns a copy of the properties table.
+     * @return array A hashtable containing all properties
+     *         (including user properties).
+     */
+    public function getProperties() {
+        return $this->properties;
+    }
+
+    /**
+     * Returns a copy of the user property hashtable
+     * @return a hashtable containing just the user properties
+     */
+    public function getUserProperties() {
+        return $this->userProperties;
+    }
+
+    /**
+     * Copies all user properties that have been set on the command
+     * line or a GUI tool from this instance to the Project instance
+     * given as the argument.
+     *
+     * <p>To copy all "user" properties, you will also have to call
+     * {@link #copyInheritedProperties copyInheritedProperties}.</p>
+     *
+     * @param Project $other the project to copy the properties to.  Must not be null.
+     * @return void
+     * @since phing 2.0
+     */
+    public function copyUserProperties(Project $other) {        
+        foreach($this->userProperties as $arg => $value) {
+            if (isset($this->inheritedProperties[$arg])) {
+                continue;
+            }
+            $other->setUserProperty($arg, $value);
+        }
+    }
+
+    /**
+     * Copies all user properties that have not been set on the
+     * command line or a GUI tool from this instance to the Project
+     * instance given as the argument.
+     *
+     * <p>To copy all "user" properties, you will also have to call
+     * {@link #copyUserProperties copyUserProperties}.</p>
+     *
+     * @param other the project to copy the properties to.  Must not be null.
+     *
+     * @since phing 2.0
+     */
+    public function copyInheritedProperties(Project $other) {
+        foreach($this->userProperties as $arg => $value) {
+            if ($other->getUserProperty($arg) !== null) {
+                continue;
+            }
+            $other->setInheritedProperty($arg, $value);
+        }        
+    }
+    
+    // ---------------------------------------------------------
+    //  END Properties methods
+    // ---------------------------------------------------------
+
+
+    function setDefaultTarget($targetName) {
+        $this->defaultTarget = (string) trim($targetName);
+    }
+
+    function getDefaultTarget() {
+        return (string) $this->defaultTarget;
+    }
+
+    /**
+     * Sets the name of the current project
+     *
+     * @param    string   name of project
+     * @return   void
+     * @access   public
+     * @author   Andreas Aderhold, andi@binarycloud.com
+     */
+
+    function setName($name) {
+        $this->name = (string) trim($name);
+        $this->setProperty("phing.project.name", $this->name);
+    }
+
+    /**
+     * Returns the name of this project
+     *
+     * @returns  string  projectname
+     * @access   public
+     * @author   Andreas Aderhold, andi@binarycloud.com
+     */
+    function getName() {
+        return (string) $this->name;
+    }
+
+    /** Set the projects description */
+    function setDescription($description) {
+        $this->description = (string) trim($description);
+    }
+
+    /** return the description, null otherwise */
+    function getDescription() {
+        return $this->description;
+    }
+
+    /** Set basedir object from xml*/
+    function setBasedir($dir) {
+        if ($dir instanceof PhingFile) {
+            $dir = $dir->getAbsolutePath();
+        }
+
+        $dir = $this->fileUtils->normalize($dir);
+
+        $dir = new PhingFile((string) $dir);
+        if (!$dir->exists()) {
+            throw new BuildException("Basedir ".$dir->getAbsolutePath()." does not exist");
+        }
+        if (!$dir->isDirectory()) {
+            throw new BuildException("Basedir ".$dir->getAbsolutePath()." is not a directory");
+        }
+        $this->basedir = $dir;
+        $this->setPropertyInternal("project.basedir", $this->basedir->getAbsolutePath());
+        $this->log("Project base dir set to: " . $this->basedir->getPath(), Project::MSG_VERBOSE);
+        
+        // [HL] added this so that ./ files resolve correctly.  This may be a mistake ... or may be in wrong place.                
+        chdir($dir->getAbsolutePath());
+    }
+
+    /**
+     * Returns the basedir of this project
+     *
+     * @returns  PhingFile  Basedir PhingFile object
+     * @access   public
+     * @throws   BuildException
+     * @author   Andreas Aderhold, andi@binarycloud.com
+     */
+    function getBasedir() {
+        if ($this->basedir === null) {            
+            try { // try to set it
+                $this->setBasedir(".");
+            } catch (BuildException $exc) {
+                throw new BuildException("Can not set default basedir. ".$exc->getMessage());
+            }
+        }
+        return $this->basedir;
+    }
+
+    /**
+     * Sets system properties and the environment variables for this project.
+     * 
+     * @return void
+     */
+    function setSystemProperties() {
+        
+        // first get system properties
+        $systemP = array_merge( self::getProperties(), Phing::getProperties() );
+        foreach($systemP as $name => $value) {
+            $this->setPropertyInternal($name, $value);
+        }
+        
+        // and now the env vars
+        foreach($_SERVER as $name => $value) {
+            // skip arrays
+            if (is_array($value)) {
+                continue;
+            }
+            $this->setPropertyInternal('env.' . $name, $value);
+        }
+        return true;
+    }
+
+
+    /**
+     * Adds a task definition.
+     * @param string $name Name of tag.
+     * @param string $class The class path to use.
+     * @param string $classpath The classpat to use.
+     */
+    function addTaskDefinition($name, $class, $classpath = null) {
+        $name  = $name;
+        $class = $class;
+        if ($class === "") {
+            $this->log("Task $name has no class defined.", Project::MSG_ERR);
+        }  elseif (!isset($this->taskdefs[$name])) {
+            Phing::import($class, $classpath);
+            $this->taskdefs[$name] = $class;
+            $this->log("  +Task definiton: $name ($class)", Project::MSG_DEBUG);
+        } else {
+            $this->log("Task $name ($class) already registerd, skipping", Project::MSG_VERBOSE);
+        }
+    }
+
+    function &getTaskDefinitions() {
+        return $this->taskdefs;
+    }
+
+    /**
+     * Adds a data type definition.
+     * @param string $name Name of tag.
+     * @param string $class The class path to use.
+     * @param string $classpath The classpat to use.
+     */
+    function addDataTypeDefinition($typeName, $typeClass, $classpath = null) {    
+        if (!isset($this->typedefs[$typeName])) {        
+            Phing::import($typeClass, $classpath);
+            $this->typedefs[$typeName] = $typeClass;
+            $this->log("  +User datatype: $typeName ($typeClass)", Project::MSG_DEBUG);
+        } else {
+            $this->log("Type $name ($class) already registerd, skipping", Project::MSG_VERBOSE);
+        }
+    }
+
+    function getDataTypeDefinitions() {
+        return $this->typedefs;
+    }
+
+    /** add a new target to the project */
+    function addTarget($targetName, &$target) {
+        if (isset($this->targets[$targetName])) {
+            throw new BuildException("Duplicate target: $targetName");
+        }
+        $this->addOrReplaceTarget($targetName, $target);
+    }
+
+    function addOrReplaceTarget($targetName, &$target) {
+        $this->log("  +Target: $targetName", Project::MSG_DEBUG);
+        $target->setProject($this);
+        $this->targets[$targetName] = $target;
+    }
+
+    function getTargets() {
+        return $this->targets;
+    }
+
+    /**
+     * Create a new task instance and return reference to it. This method is
+     * sorta factory like. A _local_ instance is created and a reference returned to
+     * that instance. Usually PHP destroys local variables when the function call
+     * ends. But not if you return a reference to that variable.
+     * This is kinda error prone, because if no reference exists to the variable
+     * it is destroyed just like leaving the local scope with primitive vars. There's no
+     * central place where the instance is stored as in other OOP like languages.
+     *
+     * [HL] Well, ZE2 is here now, and this is  still working. We'll leave this alone
+     * unless there's any good reason not to.
+     *
+     * @param    string    $taskType    Task name
+     * @returns  Task                A task object
+     * @throws   BuildException
+     *           Exception
+     */
+    function createTask($taskType) {
+        try {
+            $cls = "";
+            $tasklwr = strtolower($taskType);
+            foreach ($this->taskdefs as $name => $class) {
+                if (strtolower($name) === $tasklwr) {
+                    $cls = StringHelper::unqualify($class);                                    
+                    break;
+                }
+            }
+            
+            if ($cls === "") {
+                return null;
+            }
+            
+            if (!class_exists($cls)) {
+                throw new BuildException("Could not instantiate class $cls, even though a class was specified. (Make sure that the specified class file contains a class with the correct name.)");
+            }
+            
+            $o = new $cls();        
+    
+            if ($o instanceof Task) {
+                $task = $o;
+            } else {
+                $this->log ("  (Using TaskAdapter for: $taskType)", Project::MSG_DEBUG);
+                // not a real task, try adapter
+                $taskA = new TaskAdapter();
+                $taskA->setProxy($o);
+                $task = $taskA;
+            }
+            $task->setProject($this);
+            $task->setTaskType($taskType);
+            // set default value, can be changed by the user
+            $task->setTaskName($taskType);
+            $this->log ("  +Task: " . $taskType, Project::MSG_DEBUG);
+        } catch (Exception $t) {
+            throw new BuildException("Could not create task of type: " . $taskType, $t);
+        }
+        // everything fine return reference
+        return $task;
+    }
+
+    /**
+     * Create a task instance and return reference to it
+     * See createTask() for explanation how this works
+     *
+     * @param    string   Type name
+     * @returns  object   A datatype object
+     * @throws   BuildException
+     *           Exception
+     */
+    function createDataType($typeName) {        
+        try {
+            $cls = "";
+            $typelwr = strtolower($typeName);
+            foreach ($this->typedefs as $name => $class) {
+                if (strtolower($name) === $typelwr) {
+                    $cls = StringHelper::unqualify($class);                                    
+                    break;
+                }
+            }
+            
+            if ($cls === "") {
+                return null;
+            }
+            
+            if (!class_exists($cls)) {
+                throw new BuildException("Could not instantiate class $cls, even though a class was specified. (Make sure that the specified class file contains a class with the correct name.)");
+            }
+            
+            $type = new $cls();
+            $this->log("  +Type: $typeName", Project::MSG_DEBUG);
+            if (!($type instanceof DataType)) {
+                throw new Exception("$class is not an instance of phing.types.DataType");
+            }
+            if ($type instanceof ProjectComponent) {
+                $type->setProject($this);
+            }
+        } catch (Exception $t) {
+            throw new BuildException("Could not create type: $typeName", $t);
+        }
+        // everything fine return reference
+        return $type;
+    }
+
+    /**
+     * Executes a list of targets
+     *
+     * @param    array  List of target names to execute
+     * @returns  void
+     * @throws   BuildException
+     */
+    function executeTargets($targetNames) {
+        foreach($targetNames as $tname) {
+            $this->executeTarget($tname);
+        }
+    }
+
+    /**
+     * Executes a target
+     *
+     * @param    string  Name of Target to execute
+     * @returns  void
+     * @throws   BuildException
+     */
+    function executeTarget($targetName) {
+
+        // complain about executing void
+        if ($targetName === null) {
+            throw new BuildException("No target specified");
+        }
+
+        // invoke topological sort of the target tree and run all targets
+        // until targetName occurs.
+        $sortedTargets = $this->_topoSort($targetName, $this->targets);        
+
+        $curIndex = (int) 0;
+        $curTarget = null;
+        do {
+            try {
+                $curTarget = $sortedTargets[$curIndex++];
+                $curTarget->performTasks();
+            } catch (BuildException $exc) {
+                $this->log("Execution of target \"".$curTarget->getName()."\" failed for the following reason: ".$exc->getMessage(), Project::MSG_ERR);
+                throw $exc;
+            }
+        } while ($curTarget->getName() !== $targetName);
+    }
+
+
+    function resolveFile($fileName, $rootDir = null) {
+        if ($rootDir === null) {
+            return $this->fileUtils->resolveFile($this->basedir, $fileName);
+        } else {
+            return $this->fileUtils->resolveFile($rootDir, $fileName);
+        }
+    }    
+
+    /**
+     * Topologically sort a set of Targets.
+     * @param  $root is the (String) name of the root Target. The sort is
+     *         created in such a way that the sequence of Targets until the root
+     *         target is the minimum possible such sequence.
+     * @param  $targets is a array representing a "name to Target" mapping
+     * @return An array of Strings with the names of the targets in
+     *         sorted order.
+     */
+    function _topoSort($root, &$targets) {
+
+        $root     = (string) $root;
+        $ret      = array();
+        $state    = array();
+        $visiting = array();
+
+        // We first run a DFS based sort using the root as the starting node.
+        // This creates the minimum sequence of Targets to the root node.
+        // We then do a sort on any remaining unVISITED targets.
+        // This is unnecessary for doing our build, but it catches
+        // circular dependencies or missing Targets on the entire
+        // dependency tree, not just on the Targets that depend on the
+        // build Target.
+
+        $this->_tsort($root, $targets, $state, $visiting, $ret);
+
+        $retHuman = "";
+        for ($i=0, $_i=count($ret); $i < $_i; $i++) {
+            $retHuman .= $ret[$i]->toString()." ";
+        }
+        $this->log("Build sequence for target '$root' is: $retHuman", Project::MSG_VERBOSE);
+
+        $keys = array_keys($targets);
+        while($keys) {
+            $curTargetName = (string) array_shift($keys);
+            if (!isset($state[$curTargetName])) {
+                $st = null;
+            } else {
+                $st = (string) $state[$curTargetName];
+            }
+
+            if ($st === null) {
+                $this->_tsort($curTargetName, $targets, $state, $visiting, $ret);
+            } elseif ($st === "VISITING") {
+                throw new Exception("Unexpected node in visiting state: $curTargetName");
+            }
+        }
+
+        $retHuman = "";
+        for ($i=0,$_i=count($ret); $i < $_i; $i++) {
+            $retHuman .= $ret[$i]->toString()." ";
+        }
+        $this->log("Complete build sequence is: $retHuman", Project::MSG_VERBOSE);
+
+        return $ret;
+    }
+
+    // one step in a recursive DFS traversal of the target dependency tree.
+    // - The array "state" contains the state (VISITED or VISITING or null)
+    //   of all the target names.
+    // - The stack "visiting" contains a stack of target names that are
+    //   currently on the DFS stack. (NB: the target names in "visiting" are
+    //    exactly the target names in "state" that are in the VISITING state.)
+    // 1. Set the current target to the VISITING state, and push it onto
+    //    the "visiting" stack.
+    // 2. Throw a BuildException if any child of the current node is
+    //    in the VISITING state (implies there is a cycle.) It uses the
+    //    "visiting" Stack to construct the cycle.
+    // 3. If any children have not been VISITED, tsort() the child.
+    // 4. Add the current target to the Vector "ret" after the children
+    //    have been visited. Move the current target to the VISITED state.
+    //    "ret" now contains the sorted sequence of Targets upto the current
+    //    Target.
+
+    function _tsort($root, &$targets, &$state, &$visiting, &$ret) {
+        $state[$root] = "VISITING";
+        $visiting[]  = $root;
+
+        if (!isset($targets[$root]) || !($targets[$root] instanceof Target)) {
+            $target = null;
+        } else {
+            $target = $targets[$root];
+        }
+
+        // make sure we exist
+        if ($target === null) {
+            $sb = "Target '$root' does not exist in this project.";
+            array_pop($visiting);
+            if (!empty($visiting)) {
+                $parent = (string) $visiting[count($visiting)-1];
+                $sb .= "It is used from target '$parent'.";
+            }
+            throw new BuildException($sb);
+        }
+
+        $deps = $target->getDependencies();
+
+        while($deps) {
+            $cur = (string) array_shift($deps);
+            if (!isset($state[$cur])) {
+                $m = null;
+            } else {
+                $m = (string) $state[$cur];
+            }
+            if ($m === null) {
+                // not been visited
+                $this->_tsort($cur, $targets, $state, $visiting, $ret);
+            } elseif ($m == "VISITING") {
+                // currently visiting this node, so have a cycle
+                throw $this->_makeCircularException($cur, $visiting);
+            }
+        }
+
+        $p = (string) array_pop($visiting);
+        if ($root !== $p) {
+            throw new Exception("Unexpected internal error: expected to pop $root but got $p");
+        }
+
+        $state[$root] = "VISITED";
+        $ret[] = $target;
+    }
+
+    function _makeCircularException($end, $stk) {
+        $sb = "Circular dependency: $end";
+        do {
+            $c = (string) array_pop($stk);
+            $sb .= " <- ".$c;
+        } while($c != $end);
+        return new BuildException($sb);
+    }
+
+    /**
+     * Adds a reference to an object. This method is called when the parser
+     * detects a id="foo" attribute. It passes the id as $name and a reference
+     * to the object assigned to this id as $value
+     */
+    function addReference($name, $object) {
+        if (isset($this->references[$name])) {
+            $this->log("Overriding previous definition of reference to $name", Project::MSG_WARN);
+        }
+        $this->log("Adding reference: $name -> ".get_class($object), Project::MSG_DEBUG);
+        $this->references[$name] = $object;
+    }
+
+    /**
+     * Returns the references array.
+     * @return array
+     */
+    function getReferences() {
+        return $this->references;
+    }
+	
+	/**
+	 * Returns a specific reference.
+	 * @param string $key The reference id/key.
+	 * @return Reference or null if not defined
+	 */
+	function getReference($key)
+	{
+		if (isset($this->references[$key])) {
+		    return $this->references[$key];
+		}
+		return null; // just to be explicit
+	}
+
+    /**
+     * Abstracting and simplifyling Logger calls for project messages
+     */
+    function log($msg, $level = Project::MSG_INFO) {
+        $this->logObject($this, $msg, $level);
+    }
+
+    function logObject($obj, $msg, $level) {
+        $this->fireMessageLogged($obj, $msg, $level);
+    }
+
+    function addBuildListener(BuildListener $listener) {
+        $this->listeners[] = $listener;
+    }
+
+    function removeBuildListener(BuildListener $listener) {
+        $newarray = array();
+        for ($i=0, $size=count($this->listeners); $i < $size; $i++) {
+            if ($this->listeners[$i] !== $listener) {
+                $newarray[] = $this->listeners[$i];
+            }
+        }
+        $this->listeners = $newarray;
+    }
+
+    function getBuildListeners() {
+        return $this->listeners;
+    }
+
+    function fireBuildStarted() {
+        $event = new BuildEvent($this);        
+        foreach($this->listeners as $listener) {
+            $listener->buildStarted($event);
+        }
+    }
+
+    function fireBuildFinished($exception) {        
+        $event = new BuildEvent($this);
+        $event->setException($exception);
+        foreach($this->listeners as $listener) {
+            $listener->buildFinished($event);
+        }
+    }
+
+    function fireTargetStarted($target) {
+        $event = new BuildEvent($target);        
+           foreach($this->listeners as $listener) {
+            $listener->targetStarted($event);
+        }
+    }
+
+    function fireTargetFinished($target, $exception) {
+        $event = new BuildEvent($target);        
+        $event->setException($exception);
+        foreach($this->listeners as $listener) {
+            $listener->targetFinished($event);
+        }
+    }
+
+    function fireTaskStarted($task) {
+        $event = new BuildEvent($task);        
+        foreach($this->listeners as $listener) {
+            $listener->taskStarted($event);
+        }
+    }
+
+    function fireTaskFinished($task, $exception) {
+        $event = new BuildEvent($task);        
+        $event->setException($exception);
+        foreach($this->listeners as $listener) {
+            $listener->taskFinished($event);
+        }
+    }
+
+    function fireMessageLoggedEvent($event, $message, $priority) {
+        $event->setMessage($message, $priority);
+        foreach($this->listeners as $listener) {
+            $listener->messageLogged($event);
+        }
+    }
+
+    function fireMessageLogged($object, $message, $priority) {
+        $this->fireMessageLoggedEvent(new BuildEvent($object), $message, $priority);
+    }
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/ProjectComponent.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/ProjectComponent.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/ProjectComponent.php	(revision 19)
@@ -0,0 +1,70 @@
+<?php
+/*
+ *  $Id: ProjectComponent.php 176 2007-03-14 14:23:39Z hans $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+/**
+ *  Abstract class providing properties and methods common to all
+ *  the project components
+ *
+ * @author    Andreas Aderhold <andi@binarycloud.com>
+ * @author    Hans Lellelid <hans@xmpl.org> 
+ * @version   $Revision: 1.5 $
+ * @package   phing
+ */
+abstract class ProjectComponent {
+
+    /**
+     * Holds a reference to the project that a project component
+     * (a task, a target, etc.) belongs to
+     *
+     * @var Project A reference to the current project instance
+     */
+    protected $project = null;
+
+    /**
+     * References the project to the current component.
+     *
+     * @param Project $project The reference to the current project
+     */
+    public function setProject($project) {
+        $this->project = $project;
+    }
+
+    /**
+     * Returns a reference to current project
+     *
+     * @return Project Reference to current porject object
+     */
+    public function getProject() {
+        return $this->project;
+    }
+
+    /**
+     *  Logs a message with the given priority.
+     *
+     *  @param string $msg The message to be logged.
+     *  @param integer $level The message's priority at this message should have
+     */
+    public function log($msg, $level = Project::MSG_INFO) {
+        if ($this->project !== null) {
+            $this->project->log($msg, $level);
+        }
+    }
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/RuntimeConfigurable.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/RuntimeConfigurable.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/RuntimeConfigurable.php	(revision 19)
@@ -0,0 +1,118 @@
+<?php
+/*
+ *  $Id: RuntimeConfigurable.php 123 2006-09-14 20:19:08Z mrook $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+/**
+ *  Wrapper class that holds the attributes of a Task (or elements
+ *  nested below that level) and takes care of configuring that element
+ *  at runtime.
+ *
+ *  <strong>SMART-UP INLINE DOCS</strong>
+ *
+ * @author    Andreas Aderhold <andi@binarycloud.com>
+ * @author    Hans Lellelid <hans@xmpl.org>
+ * @version   $Revision: 1.6 $
+ * @package   phing
+ */
+class RuntimeConfigurable {
+
+    private $elementTag = null;
+    private $children = array();
+    private $wrappedObject = null;
+    private $attributes = array();
+    private $characters = "";
+
+
+    /** @param proxy The element to wrap. */
+    function __construct($proxy, $elementTag) {
+        $this->wrappedObject = $proxy;
+        $this->elementTag = $elementTag;
+    }
+
+    function setProxy($proxy) {
+        $this->wrappedObject = $proxy;
+    }
+
+    /** Set's the attributes for the wrapped element. */
+    function setAttributes($attributes) {
+        $this->attributes = $attributes;
+    }
+
+    /** Returns the AttributeList of the wrapped element. */
+    function getAttributes() {
+        return $this->attributes;
+    }
+
+    /** Adds child elements to the wrapped element. */
+    function addChild(RuntimeConfigurable $child) {
+        $this->children[] = $child;
+    }
+
+    /** Returns the child with index */
+    function getChild($index) {
+        return $this->children[(int)$index];
+    }
+
+    /** Add characters from #PCDATA areas to the wrapped element. */
+    function addText($data) {
+        $this->characters .= (string) $data;
+    }
+
+    function getElementTag() {
+        return $this->elementTag;
+    }
+
+
+    /** Configure the wrapped element and all children. */
+    function maybeConfigure(Project $project) {
+        $id = null;
+
+        // DataType configured in ProjectConfigurator
+        //        if ( is_a($this->wrappedObject, "DataType") )
+        //            return;
+
+        if ($this->attributes || $this->characters) {
+            ProjectConfigurator::configure($this->wrappedObject, $this->attributes, $project);
+
+            if (isset($this->attributes["id"])) {
+                $id = $this->attributes["id"];
+            }
+
+            $this->attributes = null;
+
+            if ($this->characters) {
+                ProjectConfigurator::addText($project, $this->wrappedObject, (string) $this->characters);
+                $this->characters="";
+            }
+            if ($id !== null) {
+                $project->addReference($id, $this->wrappedObject);
+            }
+        }
+
+        if ( is_array($this->children) && !empty($this->children) ) {
+            // Configure all child of this object ...
+            foreach($this->children as $child) {
+                $child->maybeConfigure($project);
+                ProjectConfigurator::storeChild($project, $this->wrappedObject, $child->wrappedObject, strtolower($child->getElementTag()));
+            }
+        }
+    }
+}
+
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/Target.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/Target.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/Target.php	(revision 19)
@@ -0,0 +1,317 @@
+<?php
+/*
+ * $Id: Target.php 175 2007-03-14 13:52:03Z hans $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+include_once 'phing/TaskContainer.php';
+
+/**
+ *  The Target component. Carries all required target data. Implements the
+ *  abstract class {@link TaskContainer}
+ *
+ *  @author    Andreas Aderhold <andi@binarycloud.com>
+ *  @copyright ï¿œ 2001,2002 THYRELL. All rights reserved
+ *  @version   $Revision: 1.10 $ $Date: 2007-03-14 13:52:03 +0000 (Wed, 14 Mar 2007) $
+ *  @access    public
+ *  @see       TaskContainer
+ *  @package   phing
+ */
+
+class Target implements TaskContainer {
+    
+    /** name of target */
+    private $name;
+    
+    /** dependencies */
+    private $dependencies = array();
+    
+    /** holds objects of children of this target */
+    private $children = array();
+    
+    /** the if cond. from xml */
+    private $ifCondition = "";
+    
+    /** the unless cond. from xml */
+    private $unlessCondition = "";
+    
+    /** description of this target */
+    private $description;
+    
+    /** reference to project */
+    private $project;
+
+    /**
+     *  References the project to the current component.
+     *
+     *  @param Project The reference to the current project
+     */
+    public function setProject(Project $project) {
+        $this->project = $project;
+    }
+
+    /**
+     *  Returns reference to current project
+     *
+     *  @return Project Reference to current porject object
+     */
+    public function getProject() {
+        return $this->project;
+    }
+
+    /**
+     *  Sets the target dependencies from xml
+     *
+     *  @param string $depends Comma separated list of targetnames that depend on
+     *                  this target
+     *  @throws BuildException
+     */
+    public function setDepends($depends) {
+        // explode should be faster than strtok
+        $deps = explode(',', $depends);
+        for ($i=0, $size=count($deps); $i < $size; $i++) {
+            $trimmed = trim($deps[$i]);
+            if ($trimmed === "") {
+                throw new BuildException("Syntax Error: Depend attribute for target ".$this->getName()." is malformed.");
+            } 
+            $this->addDependency($trimmed);
+        }
+    }
+
+    /**
+     *  Adds a singular dependent target name to the list
+     *
+     *  @param   string   The dependency target to add
+     *  @access  public
+     */
+    public function addDependency($dependency) {
+        $this->dependencies[] = (string) $dependency;
+    }
+
+    /**
+     *  Returns reference to indexed array of the dependencies this target has.
+     *
+     *  @return  array  Referece to target dependencoes
+     */
+    public function getDependencies() {
+        return $this->dependencies;
+    }
+
+    /**
+     *  Sets the name of the target
+     *
+     *  @param  string   Name of this target
+     */
+    public function setName($name) {
+        $this->name = (string) $name;
+    }
+
+    /**
+     *  Returns name of this target.
+     *
+     *  @return  string     The name of the target
+     *  @access   public
+     */
+    function getName() {
+        return (string) $this->name;
+    }
+
+    /**
+     *  Adds a task element to the list of this targets child elements
+     *
+     *  @param   object  The task object to add
+     *  @access  public
+     */
+    function addTask(Task $task) {
+        $this->children[] = $task;
+    }
+
+    /**
+     *  Adds a runtime configurable element to the list of this targets child
+     *  elements.
+     *
+     *  @param   object  The RuntimeConfigurabel object
+     *  @access  public
+     */
+    function addDataType($rtc) {
+        $this->children[] = $rtc;
+    }
+
+    /**
+     *  Returns an array of all tasks this target has as childrens.
+     *
+     *  The task objects are copied here. Don't use this method to modify
+     *  task objects.
+     *
+     *  @return  array  Task[]
+     */
+    public function getTasks() {
+        $tasks = array();
+        for ($i=0,$size=count($this->children); $i < $size; $i++) {
+            $tsk = $this->children[$i];
+            if ($tsk instanceof Task) {
+                // note: we're copying objects here!
+                $tasks[] = clone $tsk;
+            }
+        }
+        return $tasks;
+    }
+
+    /**
+     *  Set the if-condition from the XML tag, if any. The property name given
+     *  as parameter must be present so the if condition evaluates to true
+     *
+     *  @param   string  The property name that has to be present
+     *  @access  public
+     */
+    public function setIf($property) {
+        $this->ifCondition = ($property === null) ? "" : $property;
+    }
+
+    /**
+     *  Set the unless-condition from the XML tag, if any. The property name
+     *  given as parameter must be present so the unless condition evaluates
+     *  to true
+     *
+     *  @param   string  The property name that has to be present
+     *  @access  public
+     */
+    public function setUnless($property) {
+        $this->unlessCondition = ($property === null) ? "" : $property;
+    }
+
+    /**
+     *  Sets a textual description of this target.
+     *
+     *  @param string The description text
+     */
+    public function setDescription($description) {
+        if ($description !== null && strcmp($description, "") !== 0) {
+            $this->description = (string) $description;
+        } else {
+            $this->description = null;
+        }
+    }
+
+    /**
+     *  Returns the description of this target.
+     *
+     *  @return string The description text of this target
+     */
+    public function getDescription() {
+        return $this->description;
+    }
+
+    /**
+     *  Returns a string representation of this target. In our case it
+     *  simply returns the target name field
+     *
+     *  @return string The string representation of this target
+     */
+    function toString() {
+        return (string) $this->name;
+    }
+
+    /**
+     *  The entry point for this class. Does some checking, then processes and
+     *  performs the tasks for this target.
+     *
+     */
+    public function main() {
+        if ($this->testIfCondition() && $this->testUnlessCondition()) {
+            foreach($this->children as $o) {
+                if ($o instanceof Task) {
+                    // child is a task
+                    $o->perform();
+                } else {
+                    // child is a RuntimeConfigurable
+                    $o->maybeConfigure($this->project);
+                }
+            }
+        } elseif (!$this->testIfCondition()) {
+            $this->project->log("Skipped target '".$this->name."' because property '".$this->ifCondition."' not set.", Project::MSG_VERBOSE);
+        } else {
+            $this->project->log("Skipped target '".$this->name."' because property '".$this->unlessCondition."' set.", Project::MSG_VERBOSE);
+        }
+    }
+
+    /**
+     *  Performs the tasks by calling the main method of this target that
+     *  actually executes the tasks.
+     *
+     *  This method is for ZE2 and used for proper exception handling of
+     *  task exceptions.
+     */
+    public function performTasks() {
+        try {// try to execute this target
+            $this->project->fireTargetStarted($this);
+            $this->main();
+            $this->project->fireTargetFinished($this, $null=null);
+        } catch (BuildException $exc) {
+            // log here and rethrow
+            $this->project->fireTargetFinished($this, $exc);
+            throw $exc;
+        }
+    }    
+
+    /**
+     *  Tests if the property set in ifConfiditon exists.
+     *
+     *  @return  boolean  <code>true</code> if the property specified
+     *                    in <code>$this->ifCondition</code> exists;
+     *                    <code>false</code> otherwise
+     */
+    private function testIfCondition() {
+        if ($this->ifCondition === "") {
+            return true;
+        }
+
+        $properties = explode(",", $this->ifCondition);
+
+        $result = true;
+        foreach ($properties as $property) {
+            $test = ProjectConfigurator::replaceProperties($this->getProject(), $property, $this->project->getProperties());
+            $result = $result && ($this->project->getProperty($test) !== null);
+        }
+
+        return $result;
+    }
+
+    /**
+     *  Tests if the property set in unlessCondition exists.
+     *
+     *  @return  boolean  <code>true</code> if the property specified
+     *                    in <code>$this->unlessCondition</code> exists;
+     *                    <code>false</code> otherwise
+     */
+    private function testUnlessCondition() {
+        if ($this->unlessCondition === "") {
+            return true;
+        }
+        
+        $properties = explode(",", $this->unlessCondition);
+
+        $result = true;
+        foreach ($properties as $property) {
+            $test = ProjectConfigurator::replaceProperties($this->getProject(), $property, $this->project->getProperties());
+            $result = $result && ($this->project->getProperty($test) === null);
+        }
+        return $result;
+    }
+
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/Task.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/Task.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/Task.php	(revision 19)
@@ -0,0 +1,265 @@
+<?php
+/*
+ *  $Id: Task.php 174 2007-03-12 21:01:37Z hans $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+require_once 'phing/ProjectComponent.php';
+include_once 'phing/RuntimeConfigurable.php';
+
+/**
+ * The base class for all Tasks.
+ *
+ * Use {@link Project#createTask} to register a new Task.
+ *
+ * @author    Andreas Aderhold <andi@binarycloud.com>
+ * @copyright ï¿œ 2001,2002 THYRELL. All rights reserved
+ * @version   $Revision: 1.11 $
+ * @see       Project#createTask()
+ * @package   phing
+ */
+abstract class Task extends ProjectComponent {
+
+    /**
+	 * @var Target owning Target object
+	 */
+    protected $target;
+    
+    /**
+	 * @var string description of the task
+	 */
+    protected $description;
+    
+    /**
+	 * @var string internal taskname (req)
+	 */
+    protected $taskType;
+    
+    /**
+	 * @var string Taskname for logger
+	 */
+    protected $taskName;
+    
+    /**
+	 * @var Location stored buildfile location
+	 */
+    protected $location;
+    
+    /**
+	 * @var RuntimeConfigurable wrapper of the task
+	 */
+    protected $wrapper;
+
+    /**
+     * Sets the owning target this task belongs to.
+     *
+     * @param Target Reference to owning target
+     */
+    public function setOwningTarget(Target $target) {
+        $this->target = $target;
+    }
+
+    /**
+     * Returns the owning target of this task.
+     *
+     * @return Target The target object that owns this task
+     */
+    public function getOwningTarget() {
+        return $this->target;
+    }
+
+    /**
+     * Returns the name of task, used only for log messages
+     *
+     * @return string Name of this task
+     */
+    public function getTaskName() {
+        if ($this->taskName === null) {
+            // if no task name is set, then it's possible
+            // this task was created from within another task.  We don't
+            // therefore know the XML tag name for this task, so we'll just
+            // use the class name stripped of "task" suffix.  This is only
+            // for log messages, so we don't have to worry much about accuracy.
+            return preg_replace('/task$/i', '', get_class($this));
+        }
+        return $this->taskName;
+    }
+
+    /**
+     * Sets the name of this task for log messages
+     *
+     * @return string A string representing the name of this task for log
+     */
+    public function setTaskName($name) {
+        $this->taskName = (string) $name;
+    }
+
+    /**
+     * Returns the name of the task under which it was invoked,
+     * usually the XML tagname
+     *
+     * @return string The type of this task (XML Tag)
+     */
+    public function getTaskType() {
+        return $this->taskType;
+    }
+
+    /**
+     * Sets the type of the task. Usually this is the name of the XML tag
+     *
+     * @param string The type of this task (XML Tag)
+     */
+    public function setTaskType($name) {
+        $this->taskType = (string) $name;
+    }
+	
+	/**
+	 * Returns a name 
+	 * 
+	 */
+	protected function getRegisterSlot($slotName) {
+		return Register::getSlot('task.' . $this->getTaskName() . '.' . $slotName);
+	}
+	
+    /**
+     * Provides a project level log event to the task.
+     *
+     * @param string  The message to log
+     * @param integer The priority of the message
+     * @see BuildEvent
+     * @see BuildListener
+     */
+    function log($msg, $level = Project::MSG_INFO) {
+        $this->project->logObject($this, $msg, $level);
+    }
+
+    /**
+     * Sets a textual description of the task
+     *
+     * @param string $desc The text describing the task
+     */
+    public function setDescription($desc) {
+        $this->description = $desc;
+    }
+
+    /**
+     * Returns the textual description of the task
+     *
+     * @return string The text description of the task
+     */
+    public function getDescription() {
+        return $this->description;
+    }
+
+    /**
+     * Called by the parser to let the task initialize properly.
+     * Should throw a BuildException if something goes wrong with the build
+     *
+     * This is abstract here, but may not be overloaded by subclasses.
+     *
+     * @throws BuildException
+     */
+    public function init() {
+    }
+
+    /**
+     *  Called by the project to let the task do it's work. This method may be
+     *  called more than once, if the task is invoked more than once. For
+     *  example, if target1 and target2 both depend on target3, then running
+     *  <em>phing target1 target2</em> will run all tasks in target3 twice.
+     *
+     *  Should throw a BuildException if someting goes wrong with the build
+     *
+     *  This is abstract here. Must be overloaded by real tasks.
+     */
+    abstract public function main();
+
+    /**
+     * Returns the location within the buildfile this task occurs. Used
+     * by {@link BuildException} to give detailed error messages.
+     *
+     * @return Location The location object describing the position of this
+     *                  task within the buildfile.
+     */
+    function getLocation() {
+        return $this->location;
+    }
+
+    /**
+     * Sets the location within the buildfile this task occurs. Called by
+     * the parser to set location information.
+     *
+     * @param Location $location The location object describing the position of this
+     *                  		 task within the buildfile.
+     */
+    function setLocation(Location $location) {
+        $this->location = $location;
+    }
+
+    /**
+     * Returns the wrapper object for runtime configuration
+     *
+     * @return RuntimeConfigurable The wrapper object used by this task
+     */
+    function getRuntimeConfigurableWrapper() {
+        if ($this->wrapper === null) {
+            $this->wrapper = new RuntimeConfigurable($this, $this->getTaskName());
+        }
+        return $this->wrapper;
+    }
+
+    /**
+     *  Sets the wrapper object this task should use for runtime
+     *  configurable elements.
+     *
+     * @param RuntimeConfigurable $wrapper The wrapper object this task should use
+     */
+    function setRuntimeConfigurableWrapper(RuntimeConfigurable $wrapper) {
+        $this->wrapper = $wrapper;
+    }
+
+    /**
+     *  Configure this task if it hasn't been done already.
+     */
+    public function maybeConfigure() {
+        if ($this->wrapper !== null) {
+            $this->wrapper->maybeConfigure($this->project);
+        }
+    }
+
+    /**
+     * Perfrom this task
+     */
+    public function perform() {
+
+        try { // try executing task
+            $this->project->fireTaskStarted($this);
+            $this->maybeConfigure();
+            $this->main();
+            $this->project->fireTaskFinished($this, $null=null);
+        } catch (Exception $exc) {
+            if ($exc instanceof BuildException) {
+                if ($exc->getLocation() === null) {
+                    $exc->setLocation($this->getLocation());
+                }
+            }
+            $this->project->fireTaskFinished($this, $exc);
+            throw $exc;
+        }
+    }
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/TaskAdapter.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/TaskAdapter.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/TaskAdapter.php	(revision 19)
@@ -0,0 +1,84 @@
+<?php
+/*
+ *  $Id: TaskAdapter.php 144 2007-02-05 15:19:00Z hans $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+require_once 'phing/Task.php';
+
+/**
+ *  Use introspection to "adapt" an arbitrary ( not extending Task, but with
+ *  similar patterns).
+ *
+ *  @author    Andreas Aderhold <andi@binarycloud.com>
+ *  @copyright © 2001,2002 THYRELL. All rights reserved
+ *  @version   $Revision: 1.7 $
+ *  @package   phing
+ */
+class TaskAdapter extends Task {
+    
+    /** target object */
+    private $proxy;
+    
+    /**
+     * Main entry point.
+     * @return void
+     */
+    function main() {
+    
+        if (method_exists($this->proxy, "setProject")) {
+            try {  // try to set project
+                $this->proxy->setProject($this->project);
+            } catch (Exception $ex) {
+                $this->log("Error setting project in " . get_class($this->proxy) . Project::MSG_ERR);
+                throw new BuildException($ex);
+            }
+        } else {
+            throw new Exception("Error setting project in class " . get_class($this->proxy));
+        }
+               
+        if (method_exists($this->proxy, "main")) {
+            try { //try to call main
+                $this->proxy->main($this->project);
+            } catch (Exception $ex) {
+                $this->log("Error in " . get_class($this->proxy), Project::MSG_ERR);
+                throw new BuildException($ex->getMessage());
+            }
+        } else {
+            throw new BuildException("Your task-like class '" . get_class($this->proxy) ."' does not have a main() method");
+        }
+    }
+
+    /**
+     * Set the target object.
+     * @param object $o
+     * @return void
+     */
+    function setProxy($o) {
+        $this->proxy = $o;
+    }
+
+    /**
+     * Gets the target object.
+     * @return object
+     */
+    function getProxy() {
+        return $this->proxy;
+    }
+
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/TaskContainer.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/TaskContainer.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/TaskContainer.php	(revision 19)
@@ -0,0 +1,42 @@
+<?php
+/*
+ *  $Id: TaskContainer.php 123 2006-09-14 20:19:08Z mrook $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+/**
+ *  Abstract interface for objects which can contain tasks (targets)
+ *  Used to check if a class can contain tasks (via instanceof)
+ *
+ *  @author    Andreas Aderhold <andi@binarycloud.com>
+ *  @copyright © 2001,2002 THYRELL. All rights reserved
+ *  @version   $Revision: 1.5 $ $Date: 2006-09-14 20:19:08 +0000 (Thu, 14 Sep 2006) $
+ *  @access    public
+ *  @package   phing
+ */
+interface TaskContainer {
+
+    /**
+     *  Adds a task to this task container. Must be implemented
+     *  by derived class
+     *
+     *  @param  object  The task to be added to the container
+     *  @access public
+     */
+    function addTask(Task $task);
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/UnknownElement.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/UnknownElement.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/UnknownElement.php	(revision 19)
@@ -0,0 +1,215 @@
+<?php
+/*
+ *  $Id: UnknownElement.php 205 2007-07-29 21:04:42Z hans $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+require_once 'phing/Task.php';
+
+/**
+ * Wrapper class that holds all information necessary to create a task
+ * that did not exist when Phing started.
+ *
+ * <em> This has something to do with phing encountering an task XML element
+ * it is not aware of at start time. This is a situation where special steps
+ * need to be taken so that the element is then known.</em>
+ *
+ * @author    Andreas Aderhold <andi@binarycloud.com>
+ * @author    Hans Lellelid <hans@xmpl.org>
+ * @version   $Revision: 1.9 $
+ * @package   phing
+ */
+class UnknownElement extends Task {
+
+    private $elementName;
+    private $realThing;
+    private $children = array();
+
+    /**
+     * Constructs a UnknownElement object
+     *
+     * @param    string  The XML element name that is unknown
+     * @access   public
+     */
+    function __construct($elementName) {
+        $this->elementName = (string) $elementName;
+    }
+
+    /**
+     * Return the XML element name that this <code>UnnownElement</code>
+     * handles.
+     *
+     * @return  string  The XML element name that is unknown
+     */
+    public function getTag() {
+        return (string) $this->elementName;
+    }
+
+    /**
+     * Tries to configure the unknown element
+     *
+     * @throws  BuildException if the element can not be configured
+     */
+    public function maybeConfigure() {
+    
+        $this->realThing = $this->makeObject($this, $this->wrapper);
+        $this->wrapper->setProxy($this->realThing);
+        if ($this->realThing instanceof Task) {
+            $this->realThing->setRuntimeConfigurableWrapper($this->wrapper);
+        }
+    
+        $this->handleChildren($this->realThing, $this->wrapper);
+        $this->wrapper->maybeConfigure($this->getProject());
+                                    
+    }
+
+    /**
+     * Called when the real task has been configured for the first time.
+     *
+     * @throws  BuildException if the task can not be created
+     */
+    public function main() {
+    
+        if ($this->realThing === null) {
+            // plain impossible to get here, maybeConfigure should
+            // have thrown an exception.
+            throw new BuildException("Should not be executing UnknownElement::main() -- task/type: {$this->elementName}");
+        }
+        
+        if ($this->realThing instanceof Task) {
+            $this->realThing->main();
+        }
+        
+    }
+
+    /**
+     * Add a child element to the unknown element
+     *
+     * @param   object  The object representing the child element
+     */
+    public function addChild(UnknownElement $child) {
+        $this->children[] = $child;
+    }
+
+    /**
+     *  Handle child elemets of the unknown element, if any.
+     *
+     *  @param ProjectComponent The parent object the unkown element belongs to
+     *  @param object The parent wrapper object
+     */
+    function handleChildren(ProjectComponent $parent, $parentWrapper) {
+
+        if ($parent instanceof TaskAdapter) {
+            $parent = $parent->getProxy();
+        }
+
+        $parentClass = get_class($parent);
+        $ih = IntrospectionHelper::getHelper($parentClass);
+
+        for ($i=0, $childrenCount=count($this->children); $i < $childrenCount; $i++) {
+
+            $childWrapper = $parentWrapper->getChild($i);
+            $child = $this->children[$i];
+            $realChild = null;
+            if ($parent instanceof TaskContainer) {
+                $realChild = $this->makeTask($child, $childWrapper, false);
+                $parent->addTask($realChild);
+            } else {
+				$project = $this->project === null ? $parent->project : $this->project;
+				$realChild = $ih->createElement($project, $parent, $child->getTag());
+            }
+
+            $childWrapper->setProxy($realChild);
+            if ($realChild instanceof Task) {
+                $realChild->setRuntimeConfigurableWrapper($childWrapper);
+            }
+			
+            if ($realChild instanceof ProjectComponent) {
+            	$child->handleChildren($realChild, $childWrapper);
+            }
+            
+            if ($realChild instanceof Task) {
+                $realChild->maybeConfigure();
+            }
+        }
+    }
+
+    /**
+     * Creates a named task or data type. If the real object is a task,
+     * it is configured up to the init() stage.
+     *
+     * @param UnknownElement $ue The unknown element to create the real object for.
+     *           Must not be <code>null</code>.
+     * @param RuntimeConfigurable $w  Ignored in this implementation.
+     * @return object The Task or DataType represented by the given unknown element.
+     */
+    protected function makeObject(UnknownElement $ue, RuntimeConfigurable $w) {
+        $o = $this->makeTask($ue, $w, true);
+        if ($o === null) {
+            $o = $this->project->createDataType($ue->getTag());
+        }
+        if ($o === null) {
+            throw new BuildException("Could not create task/type: '".$ue->getTag()."'. Make sure that this class has been declared using taskdef / typedef.");
+        }
+        return $o;
+    }
+    
+    /**
+     *  Create a named task and configure it up to the init() stage.
+     *
+     * @param UnknownElement $ue The unknwon element to create a task from
+     * @param RuntimeConfigurable $w The wrapper object
+     * @param boolean $onTopLevel Whether to treat this task as if it is top-level.
+     * @return Task The freshly created task
+     */
+    protected function makeTask(UnknownElement $ue, RuntimeConfigurable $w, $onTopLevel = false) {
+
+        $task = $this->project->createTask($ue->getTag());
+
+        if ($task === null) {
+            if (!$onTopLevel) {
+                throw new BuildException("Could not create task of type: '".$this->elementName."'. Make sure that this class has been declared using taskdef.");
+            }
+            return null;            
+        }
+
+        // used to set the location within the xmlfile so that exceptions can
+        // give detailed messages
+
+        $task->setLocation($this->getLocation());
+        $attrs = $w->getAttributes();
+        if (isset($attrs['id'])) {
+            $this->project->addReference($attrs['id'], $task);
+        }
+
+        // UnknownElement always has an associated target
+        $task->setOwningTarget($this->target);
+
+        $task->init();
+        return $task;
+    }
+
+    /**
+     *  Get the name of the task to use in logging messages.
+     *
+     *  @return  string  The task's name
+     */
+    function getTaskName() {
+        return $this->realThing === null ? parent::getTaskName() : $this->realThing->getTaskName();
+    }
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/filters/BaseFilterReader.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/filters/BaseFilterReader.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/filters/BaseFilterReader.php	(revision 19)
@@ -0,0 +1,157 @@
+<?php
+
+/*
+ *  $Id: BaseFilterReader.php 325 2007-12-20 15:44:58Z hans $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+*/
+
+include_once 'phing/system/io/FilterReader.php';
+include_once 'phing/system/io/StringReader.php';
+
+
+/**
+ * Base class for core filter readers.
+ *
+ * @author    <a href="mailto:yl@seasonfive.com">Yannick Lecaillez</a>
+ * @version   $Revision: 1.8 $ $Date: 2007-12-20 15:44:58 +0000 (Thu, 20 Dec 2007) $
+ * @access    public
+ * @see       FilterReader
+ * @package   phing.filters
+ */
+class BaseFilterReader extends FilterReader {
+    
+    /** Have the parameters passed been interpreted? */
+    protected $initialized = false;
+    
+    /** The Phing project this filter is part of. */
+    protected $project = null;
+
+    /**
+     * Constructor used by Phing's introspection mechanism.
+     * The original filter reader is only used for chaining
+     * purposes, never for filtering purposes (and indeed
+     * it would be useless for filtering purposes, as it has
+     * no real data to filter). ChainedReaderHelper uses
+     * this placeholder instance to create a chain of real filters.
+     * 
+     * @param Reader $in
+     */
+    function __construct($in = null) {
+        if ($in === null) {
+            $dummy = "";
+            $in = new StringReader($dummy);
+        }
+        parent::__construct($in);
+    }
+
+    /**
+     * Returns the initialized status.
+     * 
+     * @return boolean whether or not the filter is initialized
+     */
+    function getInitialized() {
+        return $this->initialized;
+    }
+
+    /**
+     * Sets the initialized status.
+     * 
+     * @param boolean $initialized Whether or not the filter is initialized.
+     */
+    function setInitialized($initialized) {
+        $this->initialized = (boolean) $initialized;
+    }
+
+    /**
+     * Sets the project to work with.
+     * 
+     * @param object $project The project this filter is part of. 
+     *                Should not be <code>null</code>.
+     */
+    function setProject(Project $project) {
+        // type check, error must never occur, bad code of it does      
+        $this->project = $project;
+    }
+
+    /**
+     * Returns the project this filter is part of.
+     * 
+     * @return object The project this filter is part of
+     */
+    function getProject() {
+        return $this->project;
+    }
+
+    /**
+     * Reads characters.
+     *
+     * @param  off  Offset at which to start storing characters.
+     * @param  len  Maximum number of characters to read.
+     *
+     * @return Characters read, or -1 if the end of the stream
+     *         has been reached
+     *
+     * @throws IOException If an I/O error occurs
+     */
+    function read($len = null) {
+        return $this->in->read($len);
+    }
+
+    /**
+     * Reads a line of text ending with '\n' (or until the end of the stream).
+     * The returned String retains the '\n'.
+     * 
+     * @return the line read, or <code>null</code> if the end of the
+               stream has already been reached
+     * 
+     * @throws IOException if the underlying reader throws one during 
+     *                        reading
+     */
+    function readLine() {
+        $line = null;
+
+        while ( ($ch = $this->in->read(1)) !== -1 ) {
+            $line .= $ch;
+            if ( $ch === "\n" )
+                break;
+        }
+
+        return $line;
+    }
+    
+    /**
+     * Returns whether the end of file has been reached with input stream.
+     * @return boolean
+     */ 
+    function eof() {
+        return $this->in->eof();
+    }
+    
+    /**
+     * Convenience method to support logging in filters.
+     * @param string $msg Message to log.
+     * @param int $level Priority level.
+     */
+    function log($msg, $level = Project::MSG_INFO) {
+        if ($this->project !== null) {
+            $this->project->log("[filter:".get_class($this)."] ".$msg, $level);    
+        }
+    }
+}
+
+
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/filters/BaseParamFilterReader.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/filters/BaseParamFilterReader.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/filters/BaseParamFilterReader.php	(revision 19)
@@ -0,0 +1,69 @@
+<?php
+
+/*
+ *  $Id: BaseParamFilterReader.php 325 2007-12-20 15:44:58Z hans $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+*/
+
+include_once 'phing/filters/BaseFilterReader.php';
+include_once 'phing/types/Parameterizable.php';
+include_once 'phing/types/Parameter.php';
+
+/**
+ * Base class for core filter readers.
+ *
+ * @author <a href="mailto:yl@seasonfive.com">Yannick Lecaillez</a>
+ * @copyright © 2003 seasonfive. All rights reserved
+ * @version   $Revision: 1.5 $ $Date: 2007-12-20 15:44:58 +0000 (Thu, 20 Dec 2007) $
+ * @access    public
+ * @see       FilterReader
+ * @package   phing.filters
+ */
+class BaseParamFilterReader extends BaseFilterReader implements Parameterizable {
+    
+    /** The passed in parameter array. */
+    protected $_parameters = array();
+    
+    /*
+     * Sets the parameters used by this filter, and sets
+     * the filter to an uninitialized status.
+     * 
+     * @param array Array of parameters to be used by this filter.
+     *              Should not be <code>null</code>.
+    */
+    function setParameters($parameters) {
+        // type check, error must never occur, bad code of it does
+        if ( !is_array($parameters) ) {
+            throw new Exception("Expected parameters array got something else");            
+        }
+
+        $this->_parameters = $parameters;
+        $this->setInitialized(false);
+    }
+
+    /*
+     * Returns the parameters to be used by this filter.
+     * 
+     * @return the parameters to be used by this filter
+    */
+    function &getParameters() {
+        return $this->_parameters;
+    }
+}
+
+
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/filters/ChainableReader.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/filters/ChainableReader.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/filters/ChainableReader.php	(revision 19)
@@ -0,0 +1,42 @@
+<?php
+
+/*
+ *  $Id: ChainableReader.php 325 2007-12-20 15:44:58Z hans $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+*/
+
+/**
+ * Interface indicating that a reader may be chained to another one.
+ *
+ * @author Magesh Umasankar
+ */
+interface ChainableReader {
+
+    /**
+     * Returns a reader with the same configuration as this one,
+     * but filtering input from the specified reader.
+     * 
+     * @param Reader $rdr the reader which the returned reader should be filtering
+     * 
+     * @return Reader A reader with the same configuration as this one, but
+     *         filtering input from the specified reader
+     */
+    public function chain(Reader $rdr);
+}
+
+
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/filters/ExpandProperties.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/filters/ExpandProperties.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/filters/ExpandProperties.php	(revision 19)
@@ -0,0 +1,82 @@
+<?php
+
+/*
+ *  $Id: ExpandProperties.php 325 2007-12-20 15:44:58Z hans $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+*/
+
+require_once 'phing/filters/BaseFilterReader.php';
+include_once 'phing/filters/ChainableReader.php';
+
+/**
+ * Expands Phing Properties, if any, in the data.
+ * <p>
+ * Example:<br>
+ * <pre><expandproperties/></pre>
+ * Or:
+ * <pre><filterreader classname="phing.filters.ExpandProperties'/></pre>
+ *
+ * @author    Yannick Lecaillez <yl@seasonfive.com>
+ * @author    Hans Lellelid <hans@xmpl.org>
+ * @version   $Revision: 1.6 $
+ * @see       BaseFilterReader
+ * @package   phing.filters
+ */
+class ExpandProperties extends BaseFilterReader implements ChainableReader {
+   
+    /**
+     * Returns the filtered stream. 
+     * The original stream is first read in fully, and the Phing properties are expanded.
+     * 
+     * @return mixed     the filtered stream, or -1 if the end of the resulting stream has been reached.
+     * 
+     * @exception IOException if the underlying stream throws an IOException
+     * during reading
+     */
+    function read($len = null) {
+                
+        $buffer = $this->in->read($len);
+        
+        if($buffer === -1) {
+            return -1;
+        }
+        
+        $project = $this->getProject();
+        $buffer = ProjectConfigurator::replaceProperties($project, $buffer, $project->getProperties());
+        
+        return $buffer;
+    }
+        
+    /**
+     * Creates a new ExpandProperties filter using the passed in
+     * Reader for instantiation.
+     * 
+     * @param object A Reader object providing the underlying stream.
+     *               Must not be <code>null</code>.
+     * 
+     * @return object A new filter based on this configuration, but filtering
+     *         the specified reader
+     */
+    function chain(Reader $reader) {
+        $newFilter = new ExpandProperties($reader);
+        $newFilter->setProject($this->getProject());
+        return $newFilter;
+    }
+}
+
+
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/filters/HeadFilter.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/filters/HeadFilter.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/filters/HeadFilter.php	(revision 19)
@@ -0,0 +1,161 @@
+<?php
+
+/*
+ *  $Id: HeadFilter.php 325 2007-12-20 15:44:58Z hans $  
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+*/
+
+include_once 'phing/filters/BaseParamFilterReader.php';
+include_once 'phing/filters/ChainableReader.php';
+
+/**
+ * Reads the first <code>n</code> lines of a stream.
+ * (Default is first 10 lines.)
+ * <p>
+ * Example:
+ * <pre><headfilter lines="3"/></pre>
+ * Or:
+ * <pre><filterreader classname="phing.filters.HeadFilter">
+ *    <param name="lines" value="3"/>
+ * </filterreader></pre>
+ *
+ * @author    <a href="mailto:yl@seasonfive.com">Yannick Lecaillez</a>
+ * @author    hans lellelid, hans@velum.net
+ * @version   $Revision: 1.6 $ $Date: 2007-12-20 15:44:58 +0000 (Thu, 20 Dec 2007) $
+ * @access    public
+ * @see       FilterReader
+ * @package   phing.filters
+ */
+class HeadFilter extends BaseParamFilterReader implements ChainableReader {
+
+    /**
+     * Parameter name for the number of lines to be returned.
+     */ 
+    const LINES_KEY = "lines";
+    
+    /**
+     * Number of lines currently read in.
+     * @var integer
+     */ 
+    private $_linesRead = 0;
+    
+    /**
+     * Number of lines to be returned in the filtered stream.
+     * @var integer
+     */ 
+    private $_lines     = 10;
+
+    /**
+     * Returns first n lines of stream.
+     * @return the resulting stream, or -1
+     * if the end of the resulting stream has been reached
+     * 
+     * @exception IOException if the underlying stream throws an IOException
+     * during reading     
+     */
+    function read($len = null) {
+    
+        if ( !$this->getInitialized() ) {
+            $this->_initialize();
+            $this->setInitialized(true);
+        }
+        
+        // note, if buffer contains fewer lines than
+        // $this->_lines this code will not work.
+        
+        if($this->_linesRead < $this->_lines) {
+        
+            $buffer = $this->in->read($len);
+            
+            if($buffer === -1) {
+                return -1;
+            }
+            
+            // now grab first X lines from buffer
+            
+            $lines = explode("\n", $buffer);
+            
+            $linesCount = count($lines);
+            
+            // must account for possibility that the num lines requested could 
+            // involve more than one buffer read.            
+            $len = ($linesCount > $this->_lines ? $this->_lines - $this->_linesRead : $linesCount);
+            $filtered_buffer = implode("\n", array_slice($lines, 0, $len) );
+            $this->_linesRead += $len;
+            
+            return $filtered_buffer;
+        
+        }
+        
+        return -1; // EOF, since the file is "finished" as far as subsequent filters are concerned.
+    }    
+
+    /**
+     * Sets the number of lines to be returned in the filtered stream.
+     * 
+     * @param integer $lines the number of lines to be returned in the filtered stream.
+     */
+    function setLines($lines) {
+        $this->_lines = (int) $lines;
+    }
+
+    /**
+     * Returns the number of lines to be returned in the filtered stream.
+     * 
+     * @return integer The number of lines to be returned in the filtered stream.
+     */
+    function getLines() {
+        return $this->_lines;
+    }
+
+    /**
+     * Creates a new HeadFilter using the passed in
+     * Reader for instantiation.
+     * 
+     * @param object A Reader object providing the underlying stream.
+     *            Must not be <code>null</code>.
+     * 
+     * @return object A new filter based on this configuration, but filtering
+     *         the specified reader.
+     */
+    function chain(Reader $reader) {
+        $newFilter = new HeadFilter($reader);
+        $newFilter->setLines($this->getLines());
+        $newFilter->setInitialized(true);
+        $newFilter->setProject($this->getProject());        
+        return $newFilter;
+    }
+
+    /**
+     * Scans the parameters list for the "lines" parameter and uses
+     * it to set the number of lines to be returned in the filtered stream.
+     */
+    private function _initialize() {
+        $params = $this->getParameters();
+        if ( $params !== null ) {
+            for($i = 0, $_i=count($params) ; $i < $_i; $i++) {
+                if ( self::LINES_KEY == $params[$i]->getName() ) {
+                    $this->_lines = (int) $params[$i]->getValue();
+                    break;
+                }
+            }
+        }
+    }
+}
+
+
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/filters/LineContains.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/filters/LineContains.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/filters/LineContains.php	(revision 19)
@@ -0,0 +1,258 @@
+<?php
+
+/*
+ *  $Id: LineContains.php 325 2007-12-20 15:44:58Z hans $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+include_once 'phing/filters/BaseParamFilterReader.php';
+include_once 'phing/filters/BaseFilterReader.php';
+include_once 'phing/filters/ChainableReader.php';
+
+/**
+ * Filter which includes only those lines that contain all the user-specified
+ * strings.
+ *
+ * Example:
+ *
+ * <pre><linecontains>
+ *   <contains value="foo">
+ *   <contains value="bar">
+ * </linecontains></pre>
+ *
+ * Or:
+ *
+ * <pre><filterreader classname="phing.filters.LineContains">
+ *    <param type="contains" value="foo"/>
+ *    <param type="contains" value="bar"/>
+ * </filterreader></pre>
+ *
+ * This will include only those lines that contain <code>foo</code> and
+ * <code>bar</code>.
+ *
+ * @author    Yannick Lecaillez <yl@seasonfive.com>
+ * @author    Hans Lellelid <hans@velum.net>
+ * @version   $Revision: 1.11 $
+ * @see       PhingFilterReader
+ * @package   phing.filters
+*/
+class LineContains extends BaseParamFilterReader implements ChainableReader {
+
+    /**
+     * The parameter name for the string to match on.
+     * @var string
+     */ 
+    const CONTAINS_KEY = "contains";
+
+    /**
+     * Array of Contains objects.
+     * @var array
+     */ 
+    private $_contains = array();
+
+    /**
+     * [Deprecated] 
+     * @var string
+     */ 
+    private $_line = null;
+
+    /**
+     * Returns all lines in a buffer that contain specified strings.
+     * @return mixed buffer, -1 on EOF
+     */
+    function read($len = null) {
+        if ( !$this->getInitialized() ) {
+            $this->_initialize();
+            $this->setInitialized(true);
+        }
+        
+        $buffer = $this->in->read($len);
+        
+        if ($buffer === -1) {
+            return -1;
+        }
+        
+        $lines = explode("\n", $buffer);        
+        $matched = array();        
+        $containsSize = count($this->_contains);
+        
+        foreach($lines as $line) {                                
+            for($i = 0 ; $i < $containsSize ; $i++) {
+                $containsStr = $this->_contains[$i]->getValue();
+                if ( strstr($line, $containsStr) === false ) {
+                    $line = null;
+                    break;
+                }
+            }                
+            if($line !== null) {
+                $matched[] = $line;
+            }                
+        }        
+        $filtered_buffer = implode("\n", $matched);    
+        return $filtered_buffer;
+    }
+    
+    /**
+     * [Deprecated. For reference only, used to be read() method.] 
+     * Returns the next character in the filtered stream, only including
+     * lines from the original stream which contain all of the specified words.
+     *
+     * @return the next character in the resulting stream, or -1
+     * if the end of the resulting stream has been reached
+     *
+     * @exception IOException if the underlying stream throws an IOException
+     * during reading
+     */
+    function readChar() {
+        if ( !$this->getInitialized() ) {
+            $this->_initialize();
+            $this->setInitialized(true);
+        }
+
+        $ch = -1;
+
+        if ( $this->_line !== null ) {
+            $ch = substr($this->_line, 0, 1);
+            if ( strlen($this->_line) === 1 )
+                $this->_line = null;
+            else
+                $this->_line = substr($this->_line, 1);
+        } else {
+            $this->_line = $this->readLine();
+            if ( $this->_line === null ) {
+                $ch = -1;
+            } else {
+                $containsSize = count($this->_contains);
+                for($i = 0 ; $i < $containsSize ; $i++) {
+                    $containsStr = $this->_contains[$i]->getValue();
+                    if ( strstr($this->_line, $containsStr) === false ) {
+                        $this->_line = null;
+                        break;
+                    }
+                }
+                return $this->readChar();
+            }
+        }
+
+        return $ch;
+    }
+
+    /**
+     * Adds a <code><contains></code> nested element.
+     *
+     * @return Contains The <code>contains</code> element added.
+     *                  Must not be <code>null</code>.
+     */
+    function createContains() {
+        $num = array_push($this->_contains, new Contains());
+        return $this->_contains[$num-1];
+    }
+
+    /**
+     * Sets the array of words which must be contained within a line read
+     * from the original stream in order for it to match this filter.
+     *
+     * @param array $contains An array of words which must be contained
+     *                 within a line in order for it to match in this filter.
+     *                 Must not be <code>null<code>.
+     */
+    function setContains($contains) {
+        // type check, error must never occur, bad code of it does
+        if ( !is_array($contains) ) {
+            throw new Exception("Excpected array got something else");
+        }
+
+        $this->_contains = $contains;
+    }
+
+    /**
+     * Returns the vector of words which must be contained within a line read
+     * from the original stream in order for it to match this filter.
+     *
+     * @return array The array of words which must be contained within a line read
+     *         from the original stream in order for it to match this filter. The
+     *         returned object is "live" - in other words, changes made to the
+     *         returned object are mirrored in the filter.
+     */
+    function getContains() {
+        return $this->_contains;
+    }
+
+    /**
+     * Creates a new LineContains using the passed in
+     * Reader for instantiation.
+     *
+     * @param object A Reader object providing the underlying stream.
+     *               Must not be <code>null</code>.
+     *
+     * @return object A new filter based on this configuration, but filtering
+     *         the specified reader
+     */
+    function chain(Reader $reader) {
+        $newFilter = new LineContains($reader);
+        $newFilter->setContains($this->getContains());
+        $newFilter->setInitialized(true);
+        $newFilter->setProject($this->getProject());        
+        return $newFilter;
+    }
+
+    /**
+     * Parses the parameters to add user-defined contains strings.
+     */
+    private function _initialize() {
+        $params = $this->getParameters();
+        if ( $params !== null ) {
+            foreach($params as $param) {
+                if ( self::CONTAINS_KEY == $param->getType() ) {
+                    $cont = new Contains();
+                    $cont->setValue($param->getValue());
+                    array_push($this->_contains, $cont);
+                    break; // because we only support a single contains
+                }
+            }
+        }
+    }
+}
+
+/**
+ * Holds a contains element.
+ */
+class Contains {
+
+    /**
+     * @var string
+     */ 
+    private $_value;
+    
+    /**
+     * Set 'contains' value.
+     * @param string $contains
+     */ 
+    function setValue($contains) {
+        $this->_value = (string) $contains;
+    }
+    
+    /**
+     * Returns 'contains' value.
+     * @return string
+     */ 
+    function getValue() {
+        return $this->_value;
+    }
+}
+
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/filters/LineContainsRegexp.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/filters/LineContainsRegexp.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/filters/LineContainsRegexp.php	(revision 19)
@@ -0,0 +1,179 @@
+<?php
+/*
+ *  $Id: LineContainsRegexp.php 325 2007-12-20 15:44:58Z hans $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+*/
+
+include_once 'phing/filters/BaseParamFilterReader.php';
+include_once 'phing/types/RegularExpression.php';
+include_once 'phing/filters/ChainableReader.php';
+
+/**
+ * Filter which includes only those lines that contain the user-specified
+ * regular expression matching strings.
+ *
+ * Example:
+ * <pre><linecontainsregexp>
+ *   <regexp pattern="foo*">
+ * </linecontainsregexp></pre>
+ *
+ * Or:
+ *
+ * <pre><filterreader classname="phing.filters.LineContainsRegExp">
+ *    <param type="regexp" value="foo*"/>
+ * </filterreader></pre>
+ *
+ * This will fetch all those lines that contain the pattern <code>foo</code>
+ *
+ * @author    Yannick Lecaillez <yl@seasonfive.com>
+ * @author    Hans Lellelid <hans@xmpl.org>
+ * @version   $Revision: 1.8 $
+ * @see       FilterReader
+ * @package   phing.filters
+ */
+class LineContainsRegexp extends BaseParamFilterReader implements ChainableReader {
+
+    /**
+     * Parameter name for regular expression.
+     * @var string
+     */ 
+    const REGEXP_KEY = "regexp";
+    
+    /**
+     * Regular expressions that are applied against lines.
+     * @var array
+     */ 
+    private    $_regexps = array();
+        
+    /**
+     * Returns all lines in a buffer that contain specified strings.
+     * @return mixed buffer, -1 on EOF
+     */
+    function read($len = null) {
+    
+        if ( !$this->getInitialized() ) {
+            $this->_initialize();
+            $this->setInitialized(true);
+        }
+        
+        $buffer = $this->in->read($len);
+        
+        if ($buffer === -1) {
+            return -1;
+        }
+        
+        $lines = explode("\n", $buffer);        
+        $matched = array();        
+        
+        $regexpsSize = count($this->_regexps);
+        foreach($lines as $line) {    
+             for($i = 0 ; $i<$regexpsSize ; $i++) {
+                    $regexp = $this->_regexps[$i];
+                    $re = $regexp->getRegexp($this->getProject());
+                    $matches = $re->matches($line);
+                    if ( !$matches ) {
+                        $line = null;
+                        break;
+                    }
+            }            
+            if($line !== null) {
+                $matched[] = $line;
+            }                
+        }        
+        $filtered_buffer = implode("\n", $matched);    
+        return $filtered_buffer;
+    }
+    
+    /**
+     * Adds a <code>regexp</code> element.
+     * 
+     * @return object regExp The <code>regexp</code> element added. 
+     */
+    function createRegexp() {
+        $num = array_push($this->_regexps, new RegularExpression());
+        return $this->_regexps[$num-1];
+    }
+
+    /**
+     * Sets the vector of regular expressions which must be contained within 
+     * a line read from the original stream in order for it to match this 
+     * filter.
+     * 
+     * @param regexps An array of regular expressions which must be contained 
+     *                within a line in order for it to match in this filter. Must not be 
+     *                <code>null</code>.
+     */
+    function setRegexps($regexps) {
+        // type check, error must never occur, bad code of it does
+        if ( !is_array($regexps) ) {
+            throw new Exception("Excpected an 'array', got something else");
+        }
+        $this->_regexps = $regexps;
+    }
+
+    /**
+     * Returns the array of regular expressions which must be contained within 
+     * a line read from the original stream in order for it to match this 
+     * filter.
+     * 
+     * @return array The array of regular expressions which must be contained within 
+     *         a line read from the original stream in order for it to match this 
+     *         filter. The returned object is "live" - in other words, changes made to 
+     *         the returned object are mirrored in the filter.
+     */
+    function getRegexps() {
+        return $this->_regexps;
+    }
+
+    /**
+     * Creates a new LineContainsRegExp using the passed in
+     * Reader for instantiation.
+     * 
+     * @param object A Reader object providing the underlying stream.
+     *               Must not be <code>null</code>.
+     * 
+     * @return object A new filter based on this configuration, but filtering
+     *         the specified reader
+     */
+    function chain(Reader $reader) {
+        $newFilter = new LineContainsRegExp($reader);
+        $newFilter->setRegexps($this->getRegexps());
+        $newFilter->setInitialized(true);
+        $newFilter->setProject($this->getProject());        
+        return $newFilter;
+    }
+
+    /**
+     * Parses parameters to add user defined regular expressions.
+     */
+    private function _initialize() {
+        $params = $this->getParameters();
+        if ( $params !== null ) {
+            for($i = 0 ; $i<count($params) ; $i++) {
+                if ( self::REGEXP_KEY === $params[$i]->getType() ) {
+                    $pattern = $params[$i]->getValue();
+                    $regexp = new RegularExpression();
+                    $regexp->setPattern($pattern);
+                    array_push($this->_regexps, $regexp);
+                }
+            }
+        }
+    }
+}
+
+
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/filters/PrefixLines.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/filters/PrefixLines.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/filters/PrefixLines.php	(revision 19)
@@ -0,0 +1,142 @@
+<?php
+
+/*
+ *  $Id: PrefixLines.php 325 2007-12-20 15:44:58Z hans $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+*/
+
+include_once 'phing/filters/BaseParamFilterReader.php';
+include_once 'phing/filters/ChainableReader.php';
+
+/**
+ * Attaches a prefix to every line.
+ *
+ * Example:
+ * <pre><prefixlines prefix="Foo"/></pre>
+ *
+ * Or:
+ *
+ * <pre><filterreader classname="phing.filters.PrefixLines">
+ *  <param name="prefix" value="Foo"/>
+ * </filterreader></pre>
+ *
+ * @author    <a href="mailto:yl@seasonfive.com">Yannick Lecaillez</a>
+ * @author    hans lellelid, hans@velum.net
+ * @version   $Revision: 1.6 $ $Date: 2007-12-20 15:44:58 +0000 (Thu, 20 Dec 2007) $
+ * @access    public
+ * @see       FilterReader
+ * @package   phing.filters
+*/
+class PrefixLines extends BaseParamFilterReader implements ChainableReader {
+
+    /**
+     * Parameter name for the prefix.
+     * @var string
+     */ 
+    const PREFIX_KEY = "lines";
+    
+    /**
+     * The prefix to be used.
+     * @var string
+     */ 
+    private    $_prefix = null;
+ 
+    /**
+     * Adds a prefix to each line of input stream and returns resulting stream.
+     * 
+     * @return mixed buffer, -1 on EOF
+     */
+    function read($len = null) {
+        if ( !$this->getInitialized() ) {
+            $this->_initialize();
+            $this->setInitialized(true);
+        }
+        
+        $buffer = $this->in->read($len);
+        
+        if ($buffer === -1) {
+            return -1;
+        }
+        
+        $lines = explode("\n", $buffer);        
+        $filtered = array();        
+        
+        foreach($lines as $line) {
+            $line = $this->_prefix . $line;
+            $filtered[] = $line;
+        }
+                
+        $filtered_buffer = implode("\n", $filtered);    
+        return $filtered_buffer;
+    }
+    
+    /**
+     * Sets the prefix to add at the start of each input line.
+     * 
+     * @param string $prefix The prefix to add at the start of each input line.
+     *               May be <code>null</code>, in which case no prefix
+     *               is added.
+     */
+    function setPrefix($prefix) {
+        $this->_prefix = (string) $prefix;
+    }
+
+    /**
+     * Returns the prefix which will be added at the start of each input line.
+     * 
+     * @return string The prefix which will be added at the start of each input line
+     */
+    function getPrefix() {
+        return $this->_prefix;
+    }
+
+    /**
+     * Creates a new PrefixLines filter using the passed in
+     * Reader for instantiation.
+     * 
+     * @param object A Reader object providing the underlying stream.
+     *               Must not be <code>null</code>.
+     * 
+     * @return object A new filter based on this configuration, but filtering
+     *         the specified reader
+     */
+    function chain(Reader $reader) {  
+        $newFilter = new PrefixLines($reader);
+        $newFilter->setPrefix($this->getPrefix());
+        $newFilter->setInitialized(true);
+        $newFilter->setProject($this->getProject());        
+        return $newFilter;
+    }
+
+    /**
+     * Initializes the prefix if it is available from the parameters.
+     */
+    private function _initialize() {
+        $params = $this->getParameters();
+        if ( $params !== null ) {
+            for($i = 0, $_i=count($params) ; $i < $_i ; $i++) {
+                if ( self::PREFIX_KEY == $params[$i]->getName() ) {
+                    $this->_prefix = (string) $params[$i]->getValue();
+                    break;
+                }
+            }
+        }
+    }
+}
+
+
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/filters/ReplaceRegexp.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/filters/ReplaceRegexp.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/filters/ReplaceRegexp.php	(revision 19)
@@ -0,0 +1,129 @@
+<?php
+
+/*
+ *  $Id: ReplaceRegexp.php 325 2007-12-20 15:44:58Z hans $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+*/
+
+require_once 'phing/filters/BaseFilterReader.php';
+include_once 'phing/filters/ChainableReader.php';
+include_once 'phing/types/RegularExpression.php';
+
+/**
+ * Performs a regexp find/replace on stream.
+ * <p>
+ * Example:<br>
+ * <pre>
+ * <replaceregexp>
+ *    <regexp pattern="\r\n" replace="\n"/>
+ *    <regexp pattern="(\w+)\.xml" replace="\1.php" ignoreCase="true"/>
+ * </replaceregexp>
+ * </pre>
+ *
+ * @author    Hans Lellelid <hans@xmpl.org>
+ * @version   $Revision: 1.5 $
+ * @package   phing.filters
+ */
+class ReplaceRegexp extends BaseFilterReader implements ChainableReader {
+    
+    /**
+     * @var array RegularExpression[]
+     */
+    private $regexps = array();            
+    
+    /**
+     * Creator method handles nested <regexp> tags.
+     * @return RegularExpression
+     */
+    function createRegexp() {
+        $num = array_push($this->regexps, new RegularExpression());
+        return $this->regexps[$num-1];
+    }
+    
+    /**
+     * Sets the current regexps.
+     * (Used when, e.g., cloning/chaining the method.)
+     * @param array RegularExpression[]
+     */
+    function setRegexps($regexps) {
+        $this->regexps = $regexps;
+    }
+    
+    /**
+     * Gets the current regexps.
+     * (Used when, e.g., cloning/chaining the method.)
+     * @return array RegularExpression[]
+     */    
+    function getRegexps() {
+        return $this->regexps;
+    }
+    
+    /**
+     * Returns the filtered stream. 
+     * The original stream is first read in fully, and the regex replace is performed.
+     * 
+     * @param int $len Required $len for Reader compliance.
+     * 
+     * @return mixed The filtered stream, or -1 if the end of the resulting stream has been reached.
+     * 
+     * @exception IOException if the underlying stream throws an IOException
+     * during reading
+     */
+    function read($len = null) {
+                
+        $buffer = $this->in->read($len);
+        
+        if($buffer === -1) {
+            return -1;
+        }
+
+        // perform regex replace here ...
+        foreach($this->regexps as $exptype) {
+            $regexp = $exptype->getRegexp($this->project);
+            try {
+                $buffer = $regexp->replace($buffer);
+                $this->log("Performing regexp replace: /".$regexp->getPattern()."/".$regexp->getReplace()."/g".($regexp->getIgnoreCase() ? 'i' : ''), Project::MSG_VERBOSE);
+            } catch (Exception $e) {
+                // perhaps mismatch in params (e.g. no replace or pattern specified)
+                $this->log("Error performing regexp replace: " . $e->getMessage(), Project::MSG_WARN);
+            }
+        }
+        
+        return $buffer;
+    }
+
+    /**
+     * Creates a new ReplaceRegExp filter using the passed in
+     * Reader for instantiation.
+     * 
+     * @param Reader $reader A Reader object providing the underlying stream.
+     *               Must not be <code>null</code>.
+     * 
+     * @return ReplaceRegExp A new filter based on this configuration, but filtering
+     *         the specified reader
+     */
+    function chain(Reader $reader) {
+        $newFilter = new ReplaceRegExp($reader);
+        $newFilter->setProject($this->getProject());
+        $newFilter->setRegexps($this->getRegexps());
+        return $newFilter;
+    }
+
+}
+
+
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/filters/ReplaceTokens.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/filters/ReplaceTokens.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/filters/ReplaceTokens.php	(revision 19)
@@ -0,0 +1,415 @@
+<?php
+
+/*
+ *  $Id: ReplaceTokens.php 325 2007-12-20 15:44:58Z hans $  
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+*/
+
+include_once 'phing/filters/BaseParamFilterReader.php';
+include_once 'phing/types/TokenSource.php';
+include_once 'phing/filters/ChainableReader.php';
+
+/*
+ * Replaces tokens in the original input with user-supplied values.
+ *
+ * Example:
+ *
+ * <pre><replacetokens begintoken="#" endtoken="#">;
+ *   <token key="DATE" value="${TODAY}"/>
+ * </replacetokens></pre>
+ *
+ * Or:
+ *
+ * <pre><filterreader classname="phing.filters.ReplaceTokens">
+ *   <param type="tokenchar" name="begintoken" value="#"/>
+ *   <param type="tokenchar" name="endtoken" value="#"/>
+ *   <param type="token" name="DATE" value="${TODAY}"/>
+ * </filterreader></pre>
+ *
+ * @author    <a href="mailto:yl@seasonfive.com">Yannick Lecaillez</a>
+ * @author    hans lellelid, hans@velum.net
+ * @version   $Revision: 1.14 $ $Date: 2007-12-20 15:44:58 +0000 (Thu, 20 Dec 2007) $
+ * @access    public
+ * @see       BaseParamFilterReader
+ * @package   phing.filters
+ */
+class ReplaceTokens extends BaseParamFilterReader implements ChainableReader {
+
+    /**
+     * Default "begin token" character.
+     * @var string
+     */
+    const DEFAULT_BEGIN_TOKEN = "@";
+
+    /**
+     * Default "end token" character.
+     * @var string
+     */
+    const DEFAULT_END_TOKEN = "@";
+
+    /**
+     * [Deprecated] Data that must be read from, if not null.
+     * @var string
+     */
+    private    $_queuedData = null;
+
+    /**
+     * Array to hold the replacee-replacer pairs (String to String).
+     * @var array
+     */
+    private $_tokens = array();
+
+    /**
+     * Array to hold the token sources that make tokens from
+     * different sources available
+     * @var array
+     */
+    private $_tokensources = array();
+
+    /**
+     * Array holding all tokens given directly to the Filter and
+     * those passed via a TokenSource.
+     * @var array
+     */
+    private $_alltokens = null;
+
+    /**
+     * Character marking the beginning of a token.
+     * @var string
+     */
+    private    $_beginToken = "@";  // self::DEFAULT_BEGIN_TOKEN;
+
+    /**
+     * Character marking the end of a token.
+     * @var string
+     */
+    private    $_endToken = "@"; //self::DEFAULT_END_TOKEN;
+
+    /**
+     * Performs lookup on key and returns appropriate replacement string.
+     * @param array $matches Array of 1 el containing key to search for.
+     * @return string     Text with which to replace key or value of key if none is found.
+     * @access private
+     */
+    private function replaceTokenCallback($matches) {
+                
+        $key = $matches[1];
+        
+        /* Get tokens from tokensource and merge them with the
+         * tokens given directly via build file. This should be 
+         * done a bit more elegantly
+         */
+        if ($this->_alltokens === null) {
+            $this->_alltokens = array();
+
+            $count = count($this->_tokensources);
+            for ($i = 0; $i < $count; $i++) {
+                $source = $this->_tokensources[$i];
+                $this->_alltokens = array_merge($this->_alltokens, $source->getTokens());
+            }
+
+
+            $this->_alltokens = array_merge($this->_tokens, $this->_alltokens);
+        }
+
+        $tokens = $this->_alltokens;
+
+        $replaceWith = null;
+        $count = count($tokens);
+
+        for ($i = 0; $i < $count; $i++) {
+            if ($tokens[$i]->getKey() === $key) {
+                $replaceWith = $tokens[$i]->getValue();
+            }
+        }
+
+        if ($replaceWith === null) {
+            $replaceWith = $this->_beginToken . $key . $this->_endToken;            
+            $this->log("No token defined for key \"".$this->_beginToken  . $key . $this->_endToken."\"");
+        } else {
+            $this->log("Replaced \"".$this->_beginToken  . $key . $this->_endToken ."\" with \"".$replaceWith."\"");
+        }
+
+        return $replaceWith;
+    }
+
+    /**
+     * Returns stream with tokens having been replaced with appropriate values.
+     * If a replacement value is not found for a token, the token is left in the stream.
+     * 
+     * @return mixed filtered stream, -1 on EOF.
+     */
+    function read($len = null) {
+        if ( !$this->getInitialized() ) {
+            $this->_initialize();
+            $this->setInitialized(true);
+        }
+
+        // read from next filter up the chain
+        $buffer = $this->in->read($len);
+
+        if($buffer === -1) {
+            return -1;
+        }    
+        
+        // filter buffer
+        $buffer = preg_replace_callback(
+            "/".preg_quote($this->_beginToken)."([\w\.\-:]+?)".preg_quote($this->_endToken)."/",
+            array($this, 'replaceTokenCallback'), $buffer);
+
+        return $buffer;
+    }
+   
+    /**
+     * Sets the "begin token" character.
+     * 
+     * @param string $beginToken the character used to denote the beginning of a token.
+     */
+    function setBeginToken($beginToken) {
+        $this->_beginToken = (string) $beginToken;
+    }
+
+    /**
+     * Returns the "begin token" character.
+     * 
+     * @return string The character used to denote the beginning of a token.
+     */
+    function getBeginToken() {
+        return $this->_beginToken;
+    }
+
+    /**
+     * Sets the "end token" character.
+     * 
+     * @param string $endToken the character used to denote the end of a token
+     */
+    function setEndToken($endToken) {
+        $this->_endToken = (string) $endToken;
+    }
+
+    /**
+     * Returns the "end token" character.
+     * 
+     * @return the character used to denote the beginning of a token
+     */
+    function getEndToken() {
+        return $this->_endToken;
+    }
+
+    /**
+     * Adds a token element to the map of tokens to replace.
+     * 
+     * @return object The token added to the map of replacements.
+     *               Must not be <code>null</code>.
+     */
+    function createToken() {
+        $num = array_push($this->_tokens, new Token());
+        return $this->_tokens[$num-1];
+    }
+    
+    /**
+     * Adds a token source to the sources of this filter.
+     *
+     * @return  object  A Reference to the source just added.
+     */
+    function createTokensource() {
+        $num = array_push($this->_tokensources, new TokenSource());
+        return $this->_tokensources[$num-1];
+    }
+
+    /**
+     * Sets the map of tokens to replace.
+     * ; used by ReplaceTokens::chain()
+     *
+     * @param array A map (String->String) of token keys to replacement
+     *              values. Must not be <code>null</code>.
+     */
+    function setTokens($tokens) {
+        // type check, error must never occur, bad code of it does
+        if ( !is_array($tokens) ) {
+            throw new Exception("Excpected 'array', got something else");
+        }
+
+        $this->_tokens = $tokens;
+    }
+
+    /**
+     * Returns the map of tokens which will be replaced.
+     * ; used by ReplaceTokens::chain()
+     *
+     * @return array A map (String->String) of token keys to replacement values.
+     */
+    function getTokens() {
+        return $this->_tokens;
+    }
+
+    /**
+     * Sets the tokensources to use; used by ReplaceTokens::chain()
+     * 
+     * @param   array   An array of token sources.
+     */ 
+    function setTokensources($sources) {
+        // type check
+        if ( !is_array($sources)) {
+            throw new Exception("Exspected 'array', got something else");
+        }
+        $this->_tokensources = $sources;
+    }
+
+    /**
+     * Returns the token sources used by this filter; used by ReplaceTokens::chain()
+     * 
+     * @return  array
+     */
+    function getTokensources() {
+        return $this->_tokensources;
+    }
+
+    /**
+     * Creates a new ReplaceTokens using the passed in
+     * Reader for instantiation.
+     * 
+     * @param object A Reader object providing the underlying stream.
+     *               Must not be <code>null</code>.
+     * 
+     * @return object A new filter based on this configuration, but filtering
+     *         the specified reader
+     */
+    function chain(Reader $reader) {
+        $newFilter = new ReplaceTokens($reader);
+        $newFilter->setProject($this->getProject());
+        $newFilter->setBeginToken($this->getBeginToken());
+        $newFilter->setEndToken($this->getEndToken());
+        $newFilter->setTokens($this->getTokens());
+        $newFilter->setTokensources($this->getTokensources());
+        $newFilter->setInitialized(true);
+        return $newFilter;
+    }
+
+    /**
+     * Initializes tokens and loads the replacee-replacer hashtable.
+     * This method is only called when this filter is used through
+     * a <filterreader> tag in build file.
+     */
+    private function _initialize() {
+        $params = $this->getParameters();
+        if ( $params !== null ) {
+            for($i = 0 ; $i<count($params) ; $i++) {
+                if ( $params[$i] !== null ) {
+                    $type = $params[$i]->getType();
+                    if ( $type === "tokenchar" ) {
+                        $name = $params[$i]->getName();
+                        if ( $name === "begintoken" ) {
+                            $this->_beginToken = substr($params[$i]->getValue(), 0, 1);
+                        } else if ( $name === "endtoken" ) {
+                            $this->_endToken = substr($params[$i]->getValue(), 0, 1);
+                        }
+                    } else if ( $type === "token" ) {
+                        $name  = $params[$i]->getName();
+                        $value = $params[$i]->getValue();
+
+                        $tok = new Token();
+                        $tok->setKey($name);
+                        $tok->setValue($value);
+
+                        array_push($this->_tokens, $tok);
+                    } else if ( $type === "tokensource" ) {
+                        // Store data from nested tags in local array
+                        $arr = array(); $subparams = $params[$i]->getParams();
+                        $count = count($subparams);
+                        for ($i = 0; $i < $count; $i++)  {
+                            $arr[$subparams[$i]->getName()] = $subparams[$i]->getValue();
+                        }
+
+                        // Create TokenSource
+                        $tokensource = new TokenSource();
+                        if (isset($arr["classname"])) 
+                            $tokensource->setClassname($arr["classname"]);
+
+                        // Copy other parameters 1:1 to freshly created TokenSource
+                        foreach ($arr as $key => $value) {
+                            if (strtolower($key) === "classname")
+                                continue;
+                            $param = $tokensource->createParam();
+                            $param->setName($key);
+                            $param->setValue($value);
+                        }
+
+                        $this->_tokensources[] = $tokensource;
+                    }
+                }
+            }
+        }
+    }
+}
+
+/**
+ * Holds a token.
+ */
+class Token {
+
+    /**
+     * Token key.
+     * @var string
+     */
+    private $_key;
+
+    /**
+     * Token value.
+     * @var string
+     */
+    private $_value;
+
+    /**
+     * Sets the token key.
+     * 
+     * @param string $key The key for this token. Must not be <code>null</code>.
+     */
+    function setKey($key) {
+        $this->_key = (string) $key;
+    }
+
+    /**
+     * Sets the token value.
+     * 
+     * @param string $value The value for this token. Must not be <code>null</code>.
+     */
+    function setValue($value) {
+        $this->_value = (string) $value;
+    }
+
+    /**
+     * Returns the key for this token.
+     * 
+     * @return string The key for this token.
+     */
+    function getKey() {
+        return $this->_key;
+    }
+
+    /**
+     * Returns the value for this token.
+     * 
+     * @return string The value for this token.
+     */
+    function getValue() {
+        return $this->_value;
+    }
+}
+
+
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/filters/StripLineBreaks.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/filters/StripLineBreaks.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/filters/StripLineBreaks.php	(revision 19)
@@ -0,0 +1,148 @@
+<?php
+
+/*
+ *  $Id: StripLineBreaks.php 325 2007-12-20 15:44:58Z hans $  
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+*/
+
+include_once 'phing/filters/BaseParamFilterReader.php';
+include_once 'phing/filters/ChainableReader.php';
+
+/**
+ * Filter to flatten the stream to a single line.
+ * 
+ * Example:
+ *
+ * <pre><striplinebreaks/></pre>
+ *
+ * Or:
+ *
+ * <pre><filterreader classname="phing.filters.StripLineBreaks"/></pre>
+ *
+ * @author    <a href="mailto:yl@seasonfive.com">Yannick Lecaillez</a>
+ * @author    hans lellelid, hans@velum.net
+ * @version   $Revision: 1.8 $ $Date: 2007-12-20 15:44:58 +0000 (Thu, 20 Dec 2007) $
+ * @access    public
+ * @see       BaseParamFilterReader
+ * @package   phing.filters
+ */
+class StripLineBreaks extends BaseParamFilterReader implements ChainableReader {
+
+    /**
+     * Default line-breaking characters.
+     * @var string
+     */
+    const DEFAULT_LINE_BREAKS = "\r\n";
+    
+    /**
+     * Parameter name for the line-breaking characters parameter.
+     * @var string
+     */
+    const LINES_BREAKS_KEY = "linebreaks";
+    
+    /**
+     * The characters that are recognized as line breaks.
+     * @var string
+     */ 
+    private    $_lineBreaks = "\r\n"; // self::DEFAULT_LINE_BREAKS;
+ 
+    /**
+     * Returns the filtered stream, only including
+     * characters not in the set of line-breaking characters.
+     * 
+     * @return mixed    the resulting stream, or -1
+     *         if the end of the resulting stream has been reached.
+     * 
+     * @exception IOException if the underlying stream throws an IOException
+     *            during reading     
+     */
+    function read($len = null) {
+        if ( !$this->getInitialized() ) {
+            $this->_initialize();
+            $this->setInitialized(true);
+        }
+
+        $buffer = $this->in->read($len);
+        if($buffer === -1) {
+            return -1;
+        }
+        
+        $buffer = preg_replace("/[".$this->_lineBreaks."]/", '', $buffer);           
+
+        return $buffer;
+    }
+    
+     /**
+     * Sets the line-breaking characters.
+     * 
+     * @param string $lineBreaks A String containing all the characters to be
+     *                   considered as line-breaking.
+     */
+    function setLineBreaks($lineBreaks) {
+        $this->_lineBreaks = (string) $lineBreaks;
+    }
+
+    /**
+     * Gets the line-breaking characters.
+     * 
+     * @return string A String containing all the characters that are considered as line-breaking.
+     */ 
+    function getLineBreaks() {
+        return $this->_lineBreaks;
+    }
+
+    /**
+     * Creates a new StripLineBreaks using the passed in
+     * Reader for instantiation.
+     * 
+     * @param object A Reader object providing the underlying stream.
+     *               Must not be <code>null</code>.
+     * 
+     * @return object A new filter based on this configuration, but filtering
+     *         the specified reader
+     */
+    function chain(Reader $reader) {
+        $newFilter = new StripLineBreaks($reader);
+        $newFilter->setLineBreaks($this->getLineBreaks());
+        $newFilter->setInitialized(true);
+        $newFilter->setProject($this->getProject());        
+        return $newFilter;
+    }
+
+    /**
+     * Parses the parameters to set the line-breaking characters.
+     */
+    private function _initialize() {
+        $userDefinedLineBreaks = null;
+        $params = $this->getParameters();
+        if ( $params !== null ) {
+            for($i = 0 ; $i<count($params) ; $i++) {
+                if ( self::LINE_BREAKS_KEY === $params[$i]->getName() ) {
+                    $userDefinedLineBreaks = $params[$i]->getValue();
+                    break;
+                }
+            }
+        }
+
+        if ( $userDefinedLineBreaks !== null ) {
+            $this->_lineBreaks = $userDefinedLineBreaks;
+        }
+    }
+}
+
+
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/filters/StripLineComments.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/filters/StripLineComments.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/filters/StripLineComments.php	(revision 19)
@@ -0,0 +1,205 @@
+<?php
+
+/*
+ *  $Id: StripLineComments.php 325 2007-12-20 15:44:58Z hans $  
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+*/
+
+include_once 'phing/filters/BaseParamFilterReader.php';
+include_once 'phing/filters/ChainableReader.php';
+
+/*
+ * This filter strips line comments.
+ *
+ * Example:
+ *
+ * <pre><striplinecomments>
+ *   <comment value="#"/>
+ *   <comment value="--"/>
+ *   <comment value="REM "/>
+ *   <comment value="rem "/>
+ *   <comment value="//"/>
+ * </striplinecomments></pre>
+ *
+ * Or:
+ *
+ * <pre><filterreader classname="phing.filters.StripLineComments">
+ *   <param type="comment" value="#"/>
+ *   <param type="comment" value="--"/>
+ *   <param type="comment" value="REM "/>
+ *   <param type="comment" value="rem "/>
+ *   <param type="comment" value="//"/>
+ * </filterreader></pre>
+ *
+ * @author    <a href="mailto:yl@seasonfive.com">Yannick Lecaillez</a>
+ * @author    hans lellelid, hans@velum.net
+ * @version   $Revision: 1.8 $ $Date: 2007-12-20 15:44:58 +0000 (Thu, 20 Dec 2007) $
+ * @access    public
+ * @see       BaseParamFilterReader
+ * @package   phing.filters
+ */
+class StripLineComments extends BaseParamFilterReader implements ChainableReader {
+    
+    /** Parameter name for the comment prefix. */
+    const COMMENTS_KEY = "comment";
+    
+    /** Array that holds the comment prefixes. */
+    private $_comments = array();
+    
+    /**
+     * Returns stream only including
+     * lines from the original stream which don't start with any of the 
+     * specified comment prefixes.
+     * 
+     * @return mixed the resulting stream, or -1
+     *         if the end of the resulting stream has been reached.
+     * 
+     * @throws IOException if the underlying stream throws an IOException
+     *            during reading     
+     */
+    function read($len = null) {
+    
+        if ( !$this->getInitialized() ) {
+            $this->_initialize();
+            $this->setInitialized(true);
+        }
+        
+        $buffer = $this->in->read($len);
+        
+        if ($buffer === -1) {
+            return -1;
+        }
+        
+        $lines = explode("\n", $buffer);        
+        $filtered = array();    
+            
+        $commentsSize = count($this->_comments);
+        
+        foreach($lines as $line) {            
+            for($i = 0; $i < $commentsSize; $i++) {
+                $comment = $this->_comments[$i]->getValue();
+                if ( StringHelper::startsWith($comment, ltrim($line)) ) {
+                    $line = null;
+                    break;
+                }
+            }
+            if ($line !== null) {
+                $filtered[] = $line;
+            }
+        }
+                
+        $filtered_buffer = implode("\n", $filtered);    
+        return $filtered_buffer;
+    }        
+
+    /*
+     * Adds a <code>comment</code> element to the list of prefixes.
+     * 
+     * @return comment The <code>comment</code> element added to the
+     *                 list of comment prefixes to strip.
+    */
+    function createComment() {
+        $num = array_push($this->_comments, new Comment());
+        return $this->_comments[$num-1];
+    }
+
+    /*
+     * Sets the list of comment prefixes to strip.
+     * 
+     * @param comments A list of strings, each of which is a prefix
+     *                 for a comment line. Must not be <code>null</code>.
+    */
+    function setComments($lineBreaks) {
+        if (!is_array($lineBreaks)) {
+            throw new Exception("Excpected 'array', got something else");
+        }
+        $this->_comments = $lineBreaks;
+    }
+
+    /*
+     * Returns the list of comment prefixes to strip.
+     * 
+     * @return array The list of comment prefixes to strip.
+    */
+    function getComments() {
+        return $this->_comments;
+    }
+
+    /*
+     * Creates a new StripLineComments using the passed in
+     * Reader for instantiation.
+     * 
+     * @param reader A Reader object providing the underlying stream.
+     *               Must not be <code>null</code>.
+     * 
+     * @return a new filter based on this configuration, but filtering
+     *         the specified reader
+     */
+    function chain(Reader $reader) {
+        $newFilter = new StripLineComments($reader);
+        $newFilter->setComments($this->getComments());
+        $newFilter->setInitialized(true);
+        $newFilter->setProject($this->getProject());        
+        return $newFilter;
+    }
+
+    /*
+     * Parses the parameters to set the comment prefixes.
+    */
+    private function _initialize() {
+        $params = $this->getParameters();
+        if ( $params !== null ) {
+            for($i = 0 ; $i<count($params) ; $i++) {
+                if ( self::COMMENTS_KEY === $params[$i]->getType() ) {
+                    $comment = new Comment();
+                    $comment->setValue($params[$i]->getValue());
+                    array_push($this->_comments, $comment);
+                }
+            }
+        }
+    }
+}
+
+/*
+ * The class that holds a comment representation.
+*/
+class Comment {
+    
+    /** The prefix for a line comment. */
+    private    $_value;
+
+    /*
+     * Sets the prefix for this type of line comment.
+     *
+     * @param string $value The prefix for a line comment of this type.
+     *                Must not be <code>null</code>.
+     */
+    function setValue($value) {
+        $this->_value = (string) $value;
+    }
+
+    /*
+     * Returns the prefix for this type of line comment.
+     * 
+     * @return string The prefix for this type of line comment.
+    */
+    function getValue() {
+        return $this->_value;
+    }
+}
+
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/filters/StripPhpComments.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/filters/StripPhpComments.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/filters/StripPhpComments.php	(revision 19)
@@ -0,0 +1,188 @@
+<?php
+
+/*
+ *  $Id: StripPhpComments.php 325 2007-12-20 15:44:58Z hans $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+*/
+
+include_once 'phing/filters/BaseFilterReader.php';
+include_once 'phing/filters/ChainableReader.php';
+
+/**
+ * This is a Php comment and string stripper reader that filters
+ * those lexical tokens out for purposes of simple Php parsing.
+ * (if you have more complex Php parsing needs, use a real lexer).
+ * Since this class heavily relies on the single char read function,
+ * you are reccomended to make it work on top of a buffered reader.
+ *
+ * @author    <a href="mailto:yl@seasonfive.com">Yannick Lecaillez</a>
+ * @author    hans lellelid, hans@velum.net
+ * @version   $Revision: 1.6 $ $Date: 2007-12-20 15:44:58 +0000 (Thu, 20 Dec 2007) $
+ * @access    public
+ * @see       FilterReader
+ * @package   phing.filters
+ */
+class StripPhpComments extends BaseFilterReader implements ChainableReader {
+    /**
+     * The read-ahead character, used for effectively pushing a single
+     * character back. -1 indicates that no character is in the buffer.
+     */
+    private $_readAheadCh = -1;
+
+    /**
+     * Whether or not the parser is currently in the middle of a string
+     * literal.
+     * @var boolean
+     */
+    private $_inString = false;    
+
+    /**
+     * Returns the  stream without Php comments.
+     * 
+     * @return the resulting stream, or -1
+     *         if the end of the resulting stream has been reached
+     * 
+     * @throws IOException if the underlying stream throws an IOException
+     *                        during reading     
+     */
+    function read($len = null) {
+    
+        $buffer = $this->in->read($len);
+        if($buffer === -1) {
+            return -1;
+        }
+        
+        // This regex replace /* */ and // style comments
+        $buffer = preg_replace('/\/\*[^*]*\*+([^\/*][^*]*\*+)*\/|\/\/[^\n]*|("(\\\\.|[^"\\\\])*"|\'(\\\\.|[^\'\\\\])*\'|.[^\/"\'\\\\]*)/s', "$2", $buffer);
+                
+        // The regex above is not identical to, but is based on the expression below:
+        //
+        // created by Jeffrey Friedl
+        //   and later modified by Fred Curtis.
+        //     s{
+        //          /\*         ##  Start of /* ... */ comment
+        //          [^*]*\*+    ##  Non-* followed by 1-or-more *'s
+        //          (
+        //            [^/*][^*]*\*+
+        //          )*          ##  0-or-more things which don't start with /
+        //                      ##    but do end with '*'
+        //          /           ##  End of /* ... */ comment
+        //
+        //        |         ##     OR  various things which aren't comments:
+        //
+        //          (
+        //            "           ##  Start of " ... " string
+        //            (
+        //              \\.           ##  Escaped char
+        //            |               ##    OR
+        //              [^"\\]        ##  Non "\
+        //            )*
+        //           "           ##  End of " ... " string
+        //
+        //          |         ##     OR
+        //
+        //            '           ##  Start of ' ... ' string
+        //            (
+        //              \\.           ##  Escaped char
+        //            |               ##    OR
+        //              [^'\\]        ##  Non '\
+        //            )*
+        //            '           ##  End of ' ... ' string
+        //
+        //          |         ##     OR
+        //
+        //            .           ##  Anything other char
+        //            [^/"'\\]*   ##  Chars which doesn't start a comment, string or escape
+        //          )
+        //        }{$2}gxs;
+                                
+        return $buffer;
+    }
+        
+    
+    /*
+     * Returns the next character in the filtered stream, not including
+     * Php comments.
+     * 
+     * @return the next character in the resulting stream, or -1
+     *         if the end of the resulting stream has been reached
+     * 
+     * @throws IOException if the underlying stream throws an IOException
+     *                        during reading     
+     * @deprecated
+     */
+    function readChar() {
+        $ch = -1;
+
+        if ( $this->_readAheadCh !== -1 ) {
+            $ch = $this->_readAheadCh;
+            $this->_readAheadCh = -1;
+        } else {
+            $ch = $this->in->readChar();
+            if ( $ch === "\"" ) {
+                $this->_inString = !$this->_inString;
+            } else {
+                if ( !$this->_inString ) {
+                    if ( $ch === "/" ) {
+                        $ch = $this->in->readChar();
+                        if ( $ch === "/" ) {
+                            while ( $ch !== "\n" && $ch !== -1 ) {
+                                $ch = $this->in->readChar();
+                            }
+                        } else if ( $ch === "*" ) {
+                            while ( $ch !== -1 ) {
+                                $ch = $this->in->readChar();
+                                while ( $ch === "*" && $ch !== -1 ) {
+                                    $ch = $this->in->readChar();
+                                }
+
+                                if ( $ch === "/" ) {
+                                    $ch = $this->readChar();
+                                    echo "$ch\n";
+                                    break;
+                                }
+                            }
+                        } else {
+                            $this->_readAheadCh = $ch;
+                            $ch = "/";
+                        }
+                    }
+                }
+            }
+        }
+
+        return $ch;
+    }
+
+    /**
+     * Creates a new StripPhpComments using the passed in
+     * Reader for instantiation.
+     * 
+     * @param reader A Reader object providing the underlying stream.
+     *               Must not be <code>null</code>.
+     * 
+     * @return a new filter based on this configuration, but filtering
+     *         the specified reader
+     */
+    function chain(Reader $reader) {
+        $newFilter = new StripPhpComments($reader);
+        $newFilter->setProject($this->getProject());        
+        return $newFilter;
+    }
+}
+
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/filters/StripWhitespace.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/filters/StripWhitespace.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/filters/StripWhitespace.php	(revision 19)
@@ -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 please see
+ * <http://phing.info>.
+*/
+
+include_once 'phing/filters/BaseFilterReader.php';
+include_once 'phing/filters/ChainableReader.php';
+
+/**
+ * Strips whitespace from [php] files using PHP stripwhitespace() method.
+ * 
+ * @author    Hans Lellelid, hans@velum.net
+ * @version   $Revision$ $Date$
+ * @see       FilterReader
+ * @package   phing.filters
+ * @todo -c use new PHP functions to perform this instead of regex.
+ */
+class StripWhitespace extends BaseFilterReader implements ChainableReader {
+   	
+	private $processed = false;
+	
+    /**
+     * Returns the  stream without Php comments and whitespace.
+     * 
+     * @return the resulting stream, or -1
+     *         if the end of the resulting stream has been reached
+     * 
+     * @throws IOException if the underlying stream throws an IOException
+     *                        during reading     
+     */
+    function read($len = null) {
+    
+		if ($this->processed === true) {
+            return -1; // EOF
+        }
+		
+		// Read XML
+        $php = null;
+        while ( ($buffer = $this->in->read($len)) !== -1 ) {
+			$php .= $buffer;
+		}
+		
+        if ($php === null ) { // EOF?
+            return -1;
+        }
+		
+		if(empty($php)) {
+            $this->log("PHP file is empty!", Project::MSG_WARN);
+            return ''; // return empty string, don't attempt to strip whitespace
+        }
+		        
+		// write buffer to a temporary file, since php_strip_whitespace() needs a filename
+		$file = new PhingFile(tempnam(PhingFile::getTempDir(), 'stripwhitespace'));
+		file_put_contents($file->getAbsolutePath(), $php);
+		$output = php_strip_whitespace($file->getAbsolutePath());
+		unlink($file->getAbsolutePath());
+		
+		$this->processed = true;
+		
+        return $output;
+    }
+
+    /**
+     * Creates a new StripWhitespace using the passed in
+     * Reader for instantiation.
+     * 
+     * @param reader A Reader object providing the underlying stream.
+     *               Must not be <code>null</code>.
+     * 
+     * @return a new filter based on this configuration, but filtering
+     *         the specified reader
+     */
+    public function chain(Reader $reader) {
+        $newFilter = new StripWhitespace($reader);
+        $newFilter->setProject($this->getProject());        
+        return $newFilter;
+    }
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/filters/TabToSpaces.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/filters/TabToSpaces.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/filters/TabToSpaces.php	(revision 19)
@@ -0,0 +1,144 @@
+<?php
+
+/*
+ *  $Id: TabToSpaces.php 325 2007-12-20 15:44:58Z hans $  
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+*/
+
+require_once 'phing/filters/BaseParamFilterReader.php';
+require_once 'phing/filters/ChainableReader.php';
+
+/**
+ * Converts tabs to spaces.
+ *
+ * Example:
+ *
+ * <pre><tabtospaces tablength="8"></pre>
+ *
+ * Or:
+ *
+ * <pre><filterreader classname="phing.filters.TabsToSpaces">
+ *   <param name="tablength" value="8">
+ * </filterreader></pre>
+ *
+ * @author    Yannick Lecaillez <yl@seasonfive.com>
+ * @author    Hans Lellelid <hans@xmpl.org>
+ * @version   $Revision: 1.9 $
+ * @see       BaseParamFilterReader
+ * @package   phing.filters
+ */
+class TabToSpaces extends BaseParamFilterReader implements ChainableReader {
+
+    /**
+     * The default tab length. 
+     * @var int
+     */
+    const DEFAULT_TAB_LENGTH = 8;
+    
+    /**
+     * Parameter name for the length of a tab.
+     * @var string
+     */
+    const TAB_LENGTH_KEY = "tablength";
+    
+    /**
+     * Tab length in this filter.
+     * @var int
+     */  
+    private $tabLength = 8; //self::DEFAULT_TAB_LENGTH;    
+
+    /**
+     * Returns stream after converting tabs to the specified number of spaces.
+     * 
+     * @return the resulting stream, or -1
+     *         if the end of the resulting stream has been reached
+     * 
+     * @exception IOException if the underlying stream throws an IOException
+     *            during reading     
+     */
+    function read($len = null) {
+    
+        if ( !$this->getInitialized() ) {
+            $this->_initialize();
+            $this->setInitialized(true);
+        }
+
+          $buffer = $this->in->read($len);
+        
+        if($buffer === -1) {
+            return -1;
+        }
+        
+        $buffer = str_replace("\t", str_repeat(' ', $this->tabLength), $buffer);
+        
+        return $buffer;        
+    }
+    
+    /**
+     * Sets the tab length.
+     * 
+     * @param int $tabLength The number of spaces to be used when converting a tab.
+     */
+    function setTablength($tabLength) {
+        $this->tabLength = (int) $tabLength;
+    }
+
+    /**
+     * Returns the tab length.
+     * 
+     * @return int The number of spaces used when converting a tab
+     */
+    function getTablength() {
+        return $this->tabLength;
+    }
+
+    /**
+     * Creates a new TabsToSpaces using the passed in
+     * Reader for instantiation.
+     * 
+     * @param Reader $reader A Reader object providing the underlying stream.
+     *               Must not be <code>null</code>.
+     * 
+     * @return Reader A new filter based on this configuration, but filtering
+     *         the specified reader
+     */
+    function chain(Reader $reader) {
+        $newFilter = new TabToSpaces($reader);
+        $newFilter->setTablength($this->getTablength());
+        $newFilter->setInitialized(true);
+        $newFilter->setProject($this->getProject());        
+        return $newFilter;
+    }
+
+    /**
+     * Parses the parameters to set the tab length.
+     */
+    private function _initialize() {
+        $params = $this->getParameters();
+        if ( $params !== null ) {
+            for($i = 0 ; $i<count($params) ; $i++) {
+                if (self::TAB_LENGTH_KEY === $params[$i]->getName()) {
+                    $this->tabLength = $params[$i]->getValue();
+                    break;
+                }
+            }
+        }
+    }
+}
+
+
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/filters/TailFilter.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/filters/TailFilter.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/filters/TailFilter.php	(revision 19)
@@ -0,0 +1,157 @@
+<?php
+
+/*
+ *  $Id: TailFilter.php 325 2007-12-20 15:44:58Z hans $  
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+*/
+
+require_once 'phing/filters/BaseParamFilterReader.php';
+
+/**
+ * Reads the last <code>n</code> lines of a stream. (Default is last10 lines.)
+ *
+ * Example:
+ *
+ * <pre><tailfilter lines="3" /></pre>
+ *
+ * Or:
+ *
+ * <pre><filterreader classname="phing.filters.TailFilter">
+ *   <param name="lines" value="3">
+ * </filterreader></pre>
+ *
+ * @author    <a href="mailto:yl@seasonfive.com">Yannick Lecaillez</a>
+ * @author    hans lellelid, hans@velum.net
+ * @copyright © 2003 seasonfive. All rights reserved
+ * @version   $Revision: 1.7 $
+ * @see       BaseParamFilterReader
+ * @package   phing.filters
+ */
+class TailFilter extends BaseParamFilterReader implements ChainableReader {
+
+    /**
+     * Parameter name for the number of lines to be returned.
+     * @var string
+     */
+    const LINES_KEY = "lines";
+    
+    
+    /**
+     * Number of lines to be returned in the filtered stream.
+     * @var integer
+     */ 
+    private $_lines = 10;
+    
+    /**
+     * Array to hold lines.
+     * @var array
+     */ 
+    private    $_lineBuffer = array();
+                
+    /**
+     * Returns the last n lines of a file.
+     * @param int $len Num chars to read.
+     * @return mixed The filtered buffer or -1 if EOF.
+     */
+    function read($len = null) {
+    
+        while ( ($buffer = $this->in->read($len)) !== -1 ) {
+            // Remove the last "\n" from buffer for
+            // prevent explode to add an empty cell at
+            // the end of array
+            $buffer= trim($buffer, "\n");
+            
+            $lines = explode("\n", $buffer);
+
+            if ( count($lines) >= $this->_lines ) {
+                // Buffer have more (or same) number of lines than needed.
+                // Fill lineBuffer with the last "$this->_lines" lasts ones.
+                $off = count($lines)-$this->_lines;
+                $this->_lineBuffer = array_slice($lines, $off);
+            } else {
+                // Some new lines ...
+                // Prepare space for insert these new ones
+                $this->_lineBuffer = array_slice($this->_lineBuffer, count($lines)-1);
+                $this->_lineBuffer = array_merge($this->_lineBuffer, $lines);
+            }
+        }
+
+        if ( empty($this->_lineBuffer) )
+            $ret = -1;
+        else {
+            $ret = implode("\n", $this->_lineBuffer);
+            $this->_lineBuffer = array();
+        }
+
+        return $ret;
+    }
+
+    /**
+     * Sets the number of lines to be returned in the filtered stream.
+     * 
+     * @param integer $lines the number of lines to be returned in the filtered stream.
+     */
+    function setLines($lines) {
+        $this->_lines = (int) $lines;
+    }
+
+    /**
+     * Returns the number of lines to be returned in the filtered stream.
+     * 
+     * @return integer The number of lines to be returned in the filtered stream.
+     */
+    function getLines() {
+        return $this->_lines;
+    }
+
+    /**
+     * Creates a new TailFilter using the passed in
+     * Reader for instantiation.
+     * 
+     * @param object A Reader object providing the underlying stream.
+     *               Must not be <code>null</code>.
+     * 
+     * @return object A new filter based on this configuration, but filtering
+     *         the specified reader.
+     */
+    function chain(Reader $reader) {
+        $newFilter = new TailFilter($reader);
+        $newFilter->setLines($this->getLines());
+        $newFilter->setInitialized(true);
+        $newFilter->setProject($this->getProject());        
+        return $newFilter;
+    }
+
+    /**
+     * Scans the parameters list for the "lines" parameter and uses
+     * it to set the number of lines to be returned in the filtered stream.
+     */
+    private function _initialize() {
+        $params = $this->getParameters();
+        if ( $params !== null ) {
+            for($i=0, $_i=count($params); $i < $_i; $i++) {
+                if ( self::LINES_KEY == $params[$i]->getName() ) {
+                    $this->_lines = (int) $params[$i]->getValue();
+                    break;
+                }
+            }
+        }
+    }
+}
+
+
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/filters/TidyFilter.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/filters/TidyFilter.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/filters/TidyFilter.php	(revision 19)
@@ -0,0 +1,162 @@
+<?php
+/*
+ *  $Id: TidyFilter.php 123 2006-09-14 20:19:08Z mrook $  
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+*/
+
+include_once 'phing/filters/BaseParamFilterReader.php';
+include_once 'phing/filters/ChainableReader.php';
+
+/**
+ * This filter uses the bundled-with-PHP Tidy extension to filter input.
+ * 
+ * <p>
+ * Example:<br/>
+ * <pre>
+ * <tidyfilter encoding="utf8">
+ *   <config name="indent" value="true"/>
+ *   <config name="output-xhtml" value="true"/>
+ * </tidyfilter>
+ * </pre>
+ * 
+ * @author Hans Lellelid <hans@xmpl.org>
+ * @version   $Revision: 1.2 $ $Date: 2006-09-14 20:19:08 +0000 (Thu, 14 Sep 2006) $
+ * @package   phing.filters
+ */
+class TidyFilter extends BaseParamFilterReader implements ChainableReader {
+   	
+	/** @var string Encoding of resulting document. */
+	private $encoding = 'utf8';
+   
+    /** @var array Parameter[] */
+	private $configParameters = array();
+     
+	/**
+	 * Set the encoding for resulting (X)HTML document.
+	 * @param string $v
+	 */
+	public function setEncoding($v) {
+		$this->encoding = $v;
+	}
+	
+	/**
+	 * Sets the config params.
+	 * @param array Parameter[]
+	 * @see chain()
+	 */
+	public function setConfigParameters($params)
+	{
+		$this->configParameters = $params;
+	}
+	
+	/**
+	 * Adds a <config> element (which is a Parameter).
+	 * @return Parameter
+	 */
+	public function createConfig() {
+		$num = array_push($this->configParameters, new Parameter());
+        return $this->configParameters[$num-1];
+	}
+	
+	/**
+	 * Converts the Parameter objects being used to store configuration into a simle assoc array.
+	 * @return array
+	 */
+	private function getDistilledConfig() {
+		$config = array();
+		foreach($this->configParameters as $p) {
+			$config[$p->getName()] = $p->getValue();
+		}
+		return $config;
+	}
+	
+    /**
+     * Reads input and returns Tidy-filtered output.
+     * 
+     * @return the resulting stream, or -1 if the end of the resulting stream has been reached
+     * 
+     * @throws IOException if the underlying stream throws an IOException
+     *                        during reading     
+     */
+    function read($len = null) {
+    	
+		if (!class_exists('Tidy')) {
+			throw new BuildException("You must enable the 'tidy' extension in your PHP configuration in order to use the Tidy filter.");
+		}
+		
+		if ( !$this->getInitialized() ) {
+            $this->_initialize();
+            $this->setInitialized(true);
+        }
+		
+        $buffer = $this->in->read($len);
+        if($buffer === -1) {
+            return -1;
+        }
+		
+		$config = $this->getDistilledConfig();
+		
+		$tidy = new Tidy();
+		$tidy->parseString($buffer, $config, $this->encoding);
+		$tidy->cleanRepair();
+
+		return tidy_get_output($tidy);
+		
+    }
+
+
+    /**
+     * Creates a new TidyFilter using the passed in Reader for instantiation.
+     * 
+     * @param reader A Reader object providing the underlying stream.
+     *               Must not be <code>null</code>.
+     * 
+     * @return a new filter based on this configuration, but filtering
+     *         the specified reader
+     */
+    public function chain(Reader $reader) {
+        $newFilter = new TidyFilter($reader);
+		$newFilter->setConfigParameters($this->configParameters);
+		$newFilter->setEncoding($this->encoding);
+        $newFilter->setProject($this->getProject());
+        return $newFilter;
+    }
+	
+	/**
+     * Initializes any parameters (e.g. config options).
+     * This method is only called when this filter is used through a <filterreader> tag in build file.
+     */
+    private function _initialize() {
+        $params = $this->getParameters();
+		if ($params) {
+			foreach($params as $param) {
+				if ($param->getType() == "config") {
+					$this->configParameters[] = $param;
+				} else {
+					
+					if ($param->getName() == "encoding") {
+					    $this->setEncoding($param->getValue());
+					}
+					
+				}
+				
+			}
+		}
+    }
+
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/filters/TranslateGettext.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/filters/TranslateGettext.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/filters/TranslateGettext.php	(revision 19)
@@ -0,0 +1,285 @@
+<?php
+
+/*
+ *  $Id: TranslateGettext.php 325 2007-12-20 15:44:58Z hans $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+*/
+
+require_once 'phing/filters/BaseParamFilterReader.php';
+include_once 'phing/filters/ChainableReader.php';
+
+/**
+ * Replaces gettext("message id") and _("message id") with the translated string.
+ * 
+ * Gettext is great for creating multi-lingual sites, but in some cases (e.g. for 
+ * performance reasons) you may wish to replace the gettext calls with the translations
+ * of the strings; that's what this task is for.  Note that this is similar to
+ * ReplaceTokens, but both the find and the replace aspect is more complicated -- hence
+ * this is a separate, stand-alone filter.
+ * 
+ * <p>
+ * Example:<br>
+ * <pre>
+ * <translategettext locale="en_US" domain="messages" dir="${webroot}/local"/>
+ * </pre>
+ * 
+ * @author    Hans Lellelid <hans@xmpl.org>
+ * @version   $Revision: 1.11 $ $Date: 2007-12-20 15:44:58 +0000 (Thu, 20 Dec 2007) $
+ * @access    public
+ * @see       BaseFilterReader
+ * @package   phing.filters
+ */
+class TranslateGettext extends BaseParamFilterReader implements ChainableReader {
+
+    // constants for specifying keys to expect
+    // when this is called using <filterreader ... />
+    const DOMAIN_KEY = "domain";
+    const DIR_KEY = "dir";
+    const LOCALE_KEY = "locale";
+    
+    /** The domain to use */
+    private $domain = 'messages';
+    
+    /** The dir containing LC_MESSAGES */
+    private $dir;
+
+    /** The locale to use */
+    private $locale;
+    
+    /** The system locale before it was changed for this filter. */
+    private $storedLocale;
+    
+    /**
+     * Set the text domain to use.
+     * The text domain must correspond to the name of the compiled .mo files.
+     * E.g. "messages" ==> $dir/LC_MESSAGES/messages.mo
+     *         "mydomain" ==> $dir/LC_MESSAGES/mydomain.mo
+     * @param string $domain
+     */
+    function setDomain($domain) {
+        $this->domain = $domain;
+    }
+    
+    /**
+     * Get the current domain.
+     * @return string
+     */
+    function getDomain() {
+        return $this->domain;
+    }
+    
+    /**
+     * Sets the root locale directory.
+     * @param PhingFile $dir
+     */
+    function setDir(PhingFile $dir) {
+        $this->dir = $dir;
+    }
+    
+    /**
+     * Gets the root locale directory.
+     * @return PhingFile
+     */
+    function getDir() {
+        return $this->dir;
+    }
+    
+    /**
+     * Sets the locale to use for translation.
+     * Note that for gettext() to work, you have to make sure this locale
+     * is specific enough for your system (e.g. some systems may allow an 'en' locale,
+     * but others will require 'en_US', etc.).
+     * @param string $locale 
+     */
+    function setLocale($locale) {
+        $this->locale = $locale;
+    }
+    
+    /**
+     * Gets the locale to use for translation.
+     * @return string
+     */
+    function getLocale() {
+        return $this->locale;
+    }
+    
+    /**
+     * Make sure that required attributes are set.
+     * @throws BuldException - if any required attribs aren't set.
+     */
+    protected function checkAttributes() {
+        if (!$this->domain || !$this->locale || !$this->dir) {
+            throw new BuildException("You must specify values for domain, locale, and dir attributes.");
+        }
+    }
+    
+    /**
+     * Initialize the gettext/locale environment.
+     * This method will change some env vars and locale settings; the
+     * restoreEnvironment should put them all back :)
+     * 
+     * @return void
+     * @throws BuildException - if locale cannot be set.
+     * @see restoreEnvironment()
+     */
+    protected function initEnvironment() {
+        $this->storedLocale = getenv("LANG");
+        
+        $this->log("Setting locale to " . $this->locale, Project::MSG_DEBUG);
+        putenv("LANG=".$this->locale);
+        $ret = setlocale(LC_ALL, $this->locale);
+        if ($ret === false) {
+            $msg = "Could not set locale to " . $this->locale
+                    . ". You may need to use fully qualified name"
+                    . " (e.g. en_US instead of en).";
+            throw new BuildException($msg);
+        }        
+        
+        $this->log("Binding domain '".$this->domain."' to "  . $this->dir, Project::MSG_DEBUG);
+        bindtextdomain($this->domain, $this->dir->getAbsolutePath());
+        textdomain($this->domain);        
+    }
+    
+    /**
+     * Restores environment settings and locale.
+     * This does _not_ restore any gettext-specific settings
+     * (e.g. textdomain()).
+     * 
+     * @return void
+     */
+    protected function restoreEnvironment() {
+        putenv("LANG=".$this->storedLocale);
+        setlocale(LC_ALL, $this->storedLocale);
+    }
+
+    /**
+     * Performs gettext translation of msgid and returns translated text.
+     * 
+     * This function simply wraps gettext() call, but provides ability to log
+     * string replacements.  (alternative would be using preg_replace with /e which
+     * would probably be faster, but no ability to debug/log.)
+     * 
+     * @param array $matches Array of matches; we're interested in $matches[2].
+     * @return string Translated text
+     */
+    private function xlateStringCallback($matches) {
+        $charbefore = $matches[1];
+        $msgid = $matches[2];
+        $translated = gettext($msgid);
+        $this->log("Translating \"$msgid\" => \"$translated\"", Project::MSG_DEBUG);
+        return $charbefore . '"' . $translated . '"';
+    }
+        
+    /**
+     * Returns the filtered stream. 
+     * The original stream is first read in fully, and then translation is performed.
+     * 
+     * @return mixed     the filtered stream, or -1 if the end of the resulting stream has been reached.
+     * 
+     * @throws IOException - if the underlying stream throws an IOException during reading
+     * @throws BuildException - if the correct params are not supplied
+     */
+    function read($len = null) {
+                
+        if ( !$this->getInitialized() ) {
+            $this->_initialize();
+            $this->setInitialized(true);
+        }
+        
+        // Make sure correct params/attribs have been set
+        $this->checkAttributes();
+        
+        $buffer = $this->in->read($len);        
+        if($buffer === -1) {
+            return -1;
+        }
+
+        // Setup the locale/gettext environment
+        $this->initEnvironment();
+        
+
+        // replace any occurrences of _("") or gettext("") with
+        // the translated value.
+        //
+        // ([^\w]|^)_\("((\\"|[^"])*)"\)
+        //  --$1---      -----$2----   
+        //                 ---$3--  [match escaped quotes or any char that's not a quote]
+        // 
+        // also match gettext() -- same as above
+        
+        $buffer = preg_replace_callback('/([^\w]|^)_\("((\\\"|[^"])*)"\)/', array($this, 'xlateStringCallback'), $buffer);
+        $buffer = preg_replace_callback('/([^\w]|^)gettext\("((\\\"|[^"])*)"\)/', array($this, 'xlateStringCallback'), $buffer);
+
+        // Check to see if there are any _('') calls and flag an error
+
+        // Check to see if there are any unmatched gettext() calls -- and flag an error        
+                    
+        $matches = array();
+        if (preg_match('/([^\w]|^)(gettext\([^\)]+\))/', $buffer, $matches)) {
+            $this->log("Unable to perform translation on: " . $matches[2], Project::MSG_WARN);
+        }
+                
+        $this->restoreEnvironment();
+        
+        return $buffer;
+    }
+
+    /**
+     * Creates a new TranslateGettext filter using the passed in
+     * Reader for instantiation.
+     * 
+     * @param Reader $reader A Reader object providing the underlying stream.
+     *               Must not be <code>null</code>.
+     * 
+     * @return TranslateGettext A new filter based on this configuration, but filtering
+     *         the specified reader
+     */
+    function chain(Reader $reader) {
+        $newFilter = new TranslateGettext($reader);
+        $newFilter->setProject($this->getProject());
+        $newFilter->setDomain($this->getDomain());
+        $newFilter->setLocale($this->getLocale());
+        $newFilter->setDir($this->getDir());
+        return $newFilter;
+    }
+
+    /**
+     * Parses the parameters if this filter is being used in "generic" mode.
+     */
+    private function _initialize() {
+        $params = $this->getParameters();
+        if ( $params !== null ) {
+            foreach($params as $param) {
+                switch($param->getType()) {
+                    case self::DOMAIN_KEY:
+                        $this->setDomain($param->getValue());
+                        break;
+                    case self::DIR_KEY:
+                        $this->setDir($this->project->resolveFile($param->getValue()));
+                        break;
+                        
+                    case self::LOCALE_KEY:
+                        $this->setLocale($param->getValue());
+                        break;                
+                } // switch
+            }
+        } // if params !== null
+    }
+}
+
+
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/filters/XincludeFilter.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/filters/XincludeFilter.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/filters/XincludeFilter.php	(revision 19)
@@ -0,0 +1,137 @@
+<?php
+
+/*
+ *  $Id: XincludeFilter.php,v 1.16 2005/12/07 20:05:01 hlellelid Exp $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+include_once 'phing/filters/BaseParamFilterReader.php';
+include_once 'phing/filters/ChainableReader.php';
+
+/**
+ * Applies Xinclude parsing to incoming text.
+ * 
+ * Uses PHP DOM XML support
+ * 
+ * @author    Bill Karwin <bill@karwin.com>
+ * @version   $Revision: 1.16 $
+ * @see       FilterReader
+ * @package   phing.filters
+ */
+class XincludeFilter extends BaseParamFilterReader implements ChainableReader {
+
+    private $basedir = null;
+
+    public function setBasedir(PhingFile $dir)
+    {
+        $this->basedir = $dir;
+    }
+
+    public function getBasedir()
+    {
+        return $this->basedir;
+    }
+
+    /**
+     * Reads stream, applies XSLT and returns resulting stream.
+     * @return string transformed buffer.
+     * @throws BuildException - if XSLT support missing, if error in xslt processing
+     */
+    function read($len = null) {
+        
+        if (!class_exists('DomDocument')) {
+            throw new BuildException("Could not find the DomDocument class. Make sure PHP has been compiled/configured to support DOM XML.");
+        }
+        
+        if ($this->processed === true) {
+            return -1; // EOF
+        }
+        
+        // Read XML
+        $_xml = null;
+        while ( ($data = $this->in->read($len)) !== -1 )
+            $_xml .= $data;
+
+        if ($_xml === null ) { // EOF?
+            return -1;
+        }
+
+        if (empty($_xml)) {
+            $this->log("XML file is empty!", Project::MSG_WARN);
+            return ''; 
+        }
+       
+        $this->log("Transforming XML " . $this->in->getResource() . " using Xinclude ", Project::MSG_VERBOSE);
+        
+        $out = '';
+        try {
+            $out = $this->process($_xml);
+            $this->processed = true;
+        } catch (IOException $e) {            
+            throw new BuildException($e);
+        }
+
+        return $out;
+    }
+
+    /**
+     * Try to process the Xinclude transformation
+     *
+     * @param   string  XML to process.
+     *
+     * @throws BuildException   On errors
+     */
+    protected function process($xml) {    
+                
+        if ($this->basedir) {
+            $cwd = getcwd();
+            chdir($this->basedir);
+        }
+
+        $xmlDom = new DomDocument();
+        $xmlDom->loadXML($xml);
+        
+        $xmlDom->xinclude();
+
+        if ($this->basedir) {
+            chdir($cwd);
+        }
+
+        return $xmlDom->saveXML();
+    }    
+
+    /**
+     * Creates a new XincludeFilter using the passed in
+     * Reader for instantiation.
+     *
+     * @param Reader A Reader object providing the underlying stream.
+     *               Must not be <code>null</code>.
+     *
+     * @return Reader A new filter based on this configuration, but filtering
+     *         the specified reader
+     */
+    function chain(Reader $reader) {
+        $newFilter = new XincludeFilter($reader);
+        $newFilter->setProject($this->getProject());
+        $newFilter->setBasedir($this->getBasedir());
+        return $newFilter;
+    }
+
+}
+
+
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/filters/XsltFilter.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/filters/XsltFilter.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/filters/XsltFilter.php	(revision 19)
@@ -0,0 +1,338 @@
+<?php
+
+/*
+ *  $Id: XsltFilter.php 325 2007-12-20 15:44:58Z hans $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+*/
+
+include_once 'phing/filters/BaseParamFilterReader.php';
+include_once 'phing/filters/ChainableReader.php';
+
+/**
+ * Applies XSL stylesheet to incoming text.
+ * 
+ * Uses PHP XSLT support (libxslt).
+ * 
+ * @author    Hans Lellelid <hans@velum.net>
+ * @author    Yannick Lecaillez <yl@seasonfive.com>
+ * @author    Andreas Aderhold <andi@binarycloud.com>
+ * @version   $Revision: 1.16 $
+ * @see       FilterReader
+ * @package   phing.filters
+ */
+class XsltFilter extends BaseParamFilterReader implements ChainableReader {
+
+    /**
+     * Path to XSL stylesheet.
+     * @var string
+     */
+    private $xslFile   = null;
+
+    /**
+     * Whether XML file has been transformed.
+     * @var boolean
+     */
+    private $processed = false;
+    
+    /**
+     * XSLT Params.
+     * @var array
+     */
+    private $xsltParams = array();    
+    
+    /**
+     * Whether to use loadHTML() to parse the input XML file.
+     */
+    private $html = false;
+    
+    /**
+     * Create new XSLT Param object, to handle the <param/> nested element.
+     * @return XSLTParam
+     */
+    function createParam() {
+        $num = array_push($this->xsltParams, new XSLTParam());
+        return $this->xsltParams[$num-1];
+    }
+    
+    /**
+     * Sets the XSLT params for this class.
+     * This is used to "clone" this class, in the chain() method.
+     * @param array $params
+     */
+    function setParams($params) {
+        $this->xsltParams = $params;
+    }
+    
+    /**
+     * Returns the XSLT params set for this class.
+     * This is used to "clone" this class, in the chain() method.
+     * @return array
+     */
+    function getParams() {
+        return $this->xsltParams;
+    }
+        
+    /**
+     * Set the XSLT stylesheet.
+     * @param mixed $file PhingFile object or path.
+     */
+    function setStyle(PhingFile $file) {
+        $this->xslFile = $file;
+    }
+
+    /**
+     * Whether to use HTML parser for the XML.
+     * This is supported in libxml2 -- Yay!
+     * @return boolean
+     */
+    function getHtml() {
+        return $this->html;
+    }
+    
+    /**
+     * Whether to use HTML parser for XML.
+     * @param boolean $b
+     */
+    function setHtml($b) {        
+        $this->html = (boolean) $b;
+    }
+    
+    /**
+     * Get the path to XSLT stylesheet.
+     * @return mixed XSLT stylesheet path.
+     */
+    function getStyle() {
+        return $this->xslFile;
+    }
+    
+    /**
+     * Reads stream, applies XSLT and returns resulting stream.
+     * @return string transformed buffer.
+     * @throws BuildException - if XSLT support missing, if error in xslt processing
+     */
+    function read($len = null) {
+        
+        if (!class_exists('XSLTProcessor')) {
+            throw new BuildException("Could not find the XSLTProcessor class. Make sure PHP has been compiled/configured to support XSLT.");
+        }
+        
+        if ($this->processed === true) {
+            return -1; // EOF
+        }
+        
+        if ( !$this->getInitialized() ) {
+            $this->_initialize();
+            $this->setInitialized(true);
+        }
+
+        // Read XML
+        $_xml = null;
+        while ( ($data = $this->in->read($len)) !== -1 )
+            $_xml .= $data;
+
+        if ($_xml === null ) { // EOF?
+            return -1;
+        }
+
+        if(empty($_xml)) {
+            $this->log("XML file is empty!", Project::MSG_WARN);
+            return ''; // return empty string, don't attempt to apply XSLT
+        }
+       
+        // Read XSLT
+        $_xsl = null;
+        $xslFr = new FileReader($this->xslFile);
+        $xslFr->readInto($_xsl);
+        
+        $this->log("Tranforming XML " . $this->in->getResource() . " using style " . $this->xslFile->getPath(), Project::MSG_VERBOSE);
+        
+        $out = '';
+        try {
+            $out = $this->process($_xml, $_xsl);
+            $this->processed = true;
+        } catch (IOException $e) {            
+            throw new BuildException($e);
+        }
+
+        return $out;
+    }
+
+    // {{{ method _ProcessXsltTransformation($xml, $xslt) throws BuildException
+    /**
+     * Try to process the XSLT transformation
+     *
+     * @param   string  XML to process.
+     * @param   string  XSLT sheet to use for the processing.
+     *
+     * @throws BuildException   On XSLT errors
+     */
+    protected function process($xml, $xsl) {    
+                
+        $processor = new XSLTProcessor();
+        
+        $xmlDom = new DOMDocument();
+        $xslDom = new DOMDocument();        
+        
+        if ($this->html) {            
+            $xmlDom->loadHTML($xml);
+        } else {
+            $xmlDom->loadXML($xml);
+        }
+        
+        $xslDom->loadxml($xsl);
+        
+        $processor->importStylesheet($xslDom);
+
+        // ignoring param "type" attrib, because
+        // we're only supporting direct XSL params right now
+        foreach($this->xsltParams as $param) {
+            $this->log("Setting XSLT param: " . $param->getName() . "=>" . $param->getExpression(), Project::MSG_DEBUG);
+            $processor->setParameter(null, $param->getName(), $param->getExpression());
+        }
+        
+        $result = $processor->transformToXML($xmlDom);
+        
+        if ( !$result ) {
+            //$errno = xslt_errno($processor);
+            //$err   = xslt_error($processor);    
+            throw new BuildException("XSLT Error");            
+        } else {
+            return $result;
+        }
+    }    
+
+    /**
+     * Creates a new XsltFilter using the passed in
+     * Reader for instantiation.
+     *
+     * @param Reader A Reader object providing the underlying stream.
+     *               Must not be <code>null</code>.
+     *
+     * @return Reader A new filter based on this configuration, but filtering
+     *         the specified reader
+     */
+    function chain(Reader $reader) {
+        $newFilter = new XsltFilter($reader);
+        $newFilter->setProject($this->getProject());
+        $newFilter->setStyle($this->getStyle());
+        $newFilter->setInitialized(true);
+        $newFilter->setParams($this->getParams());
+        $newFilter->setHtml($this->getHtml());
+        return $newFilter;
+    }
+
+    /**
+     * Parses the parameters to get stylesheet path.
+     */
+    private function _initialize() {        
+        $params = $this->getParameters();
+        if ( $params !== null ) {
+            for($i = 0, $_i=count($params) ; $i < $_i; $i++) {
+                if ( $params[$i]->getType() === null ) {
+                    if ($params[$i]->getName() === "style") {
+                        $this->setStyle($params[$i]->getValue());
+                    }
+                } elseif ($params[$i]->getType() == "param") {
+                    $xp = new XSLTParam();
+                    $xp->setName($params[$i]->getName());
+                    $xp->setExpression($params[$i]->getValue());
+                    $this->xsltParams[] = $xp;
+                }
+            }
+        }
+    }
+
+}
+
+
+/**
+ * Class that holds an XSLT parameter.
+ */
+class XSLTParam {
+    
+    private $name;
+    
+    private $expr;    
+    
+    /**
+     * Sets param name.
+     * @param string $name
+     */
+    public function setName($name) {
+        $this->name = $name;
+    }
+    
+    /**
+     * Get param name.
+     * @return string
+     */
+    public function getName() {
+        return $this->name;
+    }
+    
+    /**
+     * Sets expression value (alias to the setExpression()) method. 
+     *
+     * @param string $v
+     * @see setExpression()
+     */
+    public function setValue($v)
+    {
+    	$this->setExpression($v);
+    }
+    
+	/**
+     * Gets expression value (alias to the getExpression()) method. 
+     *
+     * @param string $v
+     * @see getExpression()
+     */
+    public function getValue()
+    {
+    	return $this->getExpression();
+    }
+    
+    /**
+     * Sets expression value.
+     * @param string $expr
+     */
+    public function setExpression($expr) {
+        $this->expr = $expr;
+    }
+    
+    /**
+     * Sets expression to dynamic register slot.
+     * @param RegisterSlot $expr
+     */
+    public function setListeningExpression(RegisterSlot $expr) {
+        $this->expr = $expr;    
+    }
+    
+    /**
+     * Returns expression value -- performs lookup if expr is registerslot.
+     * @return string
+     */
+    public function getExpression() {
+        if ($this->expr instanceof RegisterSlot) {
+            return $this->expr->getValue();
+        } else {
+            return $this->expr;
+        }
+    }        
+}
+
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/filters/util/ChainReaderHelper.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/filters/util/ChainReaderHelper.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/filters/util/ChainReaderHelper.php	(revision 19)
@@ -0,0 +1,183 @@
+<?php
+/*
+ *  $Id: ChainReaderHelper.php 325 2007-12-20 15:44:58Z hans $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+*/
+
+include_once 'phing/Project.php';
+include_once 'phing/filters/BaseFilterReader.php';
+include_once 'phing/types/PhingFilterReader.php';
+include_once 'phing/types/FilterChain.php';
+include_once 'phing/types/Parameter.php';
+include_once 'phing/util/FileUtils.php';
+include_once 'phing/util/StringHelper.php';
+include_once 'phing/filters/ChainableReader.php';
+
+/**
+ * Process a FilterReader chain.
+ *
+ * Here, the interesting method is 'getAssembledReader'.
+ * The purpose of this one is to create a simple Reader object which
+ * apply all filters on another primary Reader object. 
+ *
+ * For example : In copyFile (phing.util.FileUtils) the primary Reader
+ * is a FileReader object (more accuratly, a BufferedReader) previously 
+ * setted for the source file to copy. So, consider this filterchain :
+ *        
+ *     <filterchain>
+ *        <stripphpcomments />
+ *        <linecontains>
+ *            <contains value="foo">
+ *        </linecontains>
+ *      <tabtospaces tablength="8" />
+ *    </filterchain>
+ *
+ *    getAssembledReader will return a Reader object wich read on each
+ *    of these filters. Something like this : ('->' = 'which read data from') :
+ *
+ *  [TABTOSPACES] -> [LINECONTAINS] -> [STRIPPHPCOMMENTS] -> [FILEREADER]
+ *                                                         (primary reader)
+ *
+ *  So, getAssembledReader will return the TABTOSPACES Reader object. Then
+ *  each read done with this Reader object will follow this path.
+ *
+ *    Hope this explanation is clear :)
+ *
+ * TODO: Implement the classPath feature.
+ *
+ * @author    <a href="mailto:yl@seasonfive.com">Yannick Lecaillez</a>
+ * @version   $Revision: 1.8 $ $Date: 2007-12-20 15:44:58 +0000 (Thu, 20 Dec 2007) $
+ * @access    public
+ * @package   phing.filters.util
+*/
+class ChainReaderHelper {
+    
+    /** Primary reader to wich the reader chain is to be attached */
+    private $primaryReader = null;
+    
+    /** The site of the buffer to be used. */
+    private $bufferSize = 8192;
+    
+    /** Chain of filters */
+    private $filterChains = array();
+    
+    /** The Phing project */
+    private $project;
+
+    /*
+     * Sets the primary reader
+    */
+    function setPrimaryReader(Reader $reader) {
+        $this->primaryReader = $reader;
+    }
+
+    /*
+     * Set the project to work with
+    */
+    function setProject(Project $project) {
+        $this->project = $project;
+    }
+
+    /*
+     * Get the project
+    */
+    function getProject() {
+        return $this->project;
+    }
+
+    /*
+     * Sets the buffer size to be used.  Defaults to 8192,
+     * if this method is not invoked.
+    */
+    function setBufferSize($size) {
+        $this->bufferSize = $size;
+    }
+
+    /*
+     * Sets the collection of filter reader sets
+    */
+    function setFilterChains(&$fchain) {
+        $this->filterChains = &$fchain;
+    }
+
+    /*
+     * Assemble the reader
+    */
+    function getAssembledReader() {
+    
+        $instream = $this->primaryReader;
+        $filterReadersCount = count($this->filterChains);
+        $finalFilters = array();
+
+        // Collect all filter readers of all filter chains used ...
+        for($i = 0 ; $i<$filterReadersCount ; $i++) {
+            $filterchain = &$this->filterChains[$i];
+            $filterReaders = $filterchain->getFilterReaders();
+            $readerCount = count($filterReaders);
+            for($j = 0 ; $j<$readerCount ; $j++) {
+                $finalFilters[] = $filterReaders[$j];
+            }
+        }
+
+        // ... then chain the filter readers.
+        $filtersCount = count($finalFilters);
+        if ( $filtersCount > 0 ) {
+            for($i = 0 ; $i<$filtersCount ; $i++) {
+                $filter = $finalFilters[$i];
+                
+                if ( $filter instanceof PhingFilterReader ) {
+                
+                    // This filter reader is an external class.
+                    $className = $filter->getClassName();
+                    $classpath = $filter->getClasspath();
+                    $project   = $filter->getProject();
+                    
+                    if ( $className !== null ) {
+                        $cls = Phing::import($className, $classpath);
+                        $impl = new $cls();                        
+                    }
+
+                    if ( !($impl instanceof FilterReader) ) {
+                        throw new Exception($className." does not extend phing.system.io.FilterReader");
+                    }
+                    
+                    $impl->setReader($instream); // chain
+                    $impl->setProject($this->getProject()); // what about $project above ?
+
+                    if ( $impl instanceof Parameterizable ) {
+                        $impl->setParameters($filter->getParams());
+                    }
+                    
+                    $instream = $impl; // now that it's been chained
+                                                            
+                } elseif (($filter instanceof ChainableReader) && ($filter instanceof Reader)) {                   
+                    if ( $this->getProject() !== null && ($filter instanceof BaseFilterReader) ) {
+                        $filter->setProject($this->getProject());
+                    }                    
+                    $instream = $filter->chain($instream);
+                } else {
+                    throw new Exception("Cannot chain invalid filter: " . get_class($filter));
+                }
+            }
+        }
+
+        return $instream;
+    }    
+
+}
+
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/filters/util/IniFileTokenReader.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/filters/util/IniFileTokenReader.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/filters/util/IniFileTokenReader.php	(revision 19)
@@ -0,0 +1,97 @@
+<?php
+/*
+ *  $Id: IniFileTokenReader.php 325 2007-12-20 15:44:58Z hans $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+*/
+
+include_once 'phing/types/TokenReader.php';
+include_once 'phing/system/io/IOException.php';
+include_once 'phing/filters/ReplaceTokens.php'; // For class Token
+
+/**
+ * Class that allows reading tokens from INI files.
+ * 
+ * @author    Manuel Holtgewe
+ * @version   $Revision: 1.7 $
+ * @package   phing.filters.util
+ */
+class IniFileTokenReader extends TokenReader {
+
+    /**
+     * Holds the path to the INI file that is to be read.
+     * @var object  Reference to a PhingFile Object representing
+     *              the path to the INI file.
+     */
+    private $file = null;
+
+    /**
+     * @var string  Sets the section to load from the INI file.
+     *              if omitted, all sections are loaded.
+     */
+    private $section = null;
+
+    /**
+     * Reads the next token from the INI file
+     *
+     * @throws  IOException     On error
+     * @return Token
+     */
+    function readToken() {
+        if ($this->file === null) {
+            throw new BuildException("No File set for IniFileTokenReader");
+        }
+
+        static $tokens = null;
+        if ($tokens === null) {
+            $tokens = array();
+            $arr = parse_ini_file($this->file->getAbsolutePath(), true);
+            if ($this->section === null) {
+                foreach ($arr as $sec_name => $values) {
+                    foreach($arr[$sec_name] as $key => $value) {
+                        $tok = new Token;
+                        $tok->setKey($key);
+                        $tok->setValue($value);
+                        $tokens[] = $tok;
+                    }
+                }
+            } else if (isset($arr[$this->section])) {
+                foreach ($arr[$this->section] as $key => $value) {
+                    $tok = new Token;
+                    $tok->setKey($key);
+                    $tok->setValue($value);
+                    $tokens[] = $tok;
+                }
+            }
+        }
+
+        if (count($tokens) > 0) {
+            return array_pop($tokens);
+        } else
+            return null;
+    }
+    
+    function setFile(PhingFile $file) {
+        $this->file = $file;
+    }
+
+    function setSection($str) {
+        $this->section = (string) $str;
+    }
+}
+
+
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/input/DefaultInputHandler.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/input/DefaultInputHandler.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/input/DefaultInputHandler.php	(revision 19)
@@ -0,0 +1,81 @@
+<?php
+
+/*
+ *  $Id: DefaultInputHandler.php 293 2007-11-04 16:51:45Z hans $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+ 
+require_once 'phing/input/InputHandler.php';
+include_once 'phing/system/io/ConsoleReader.php';
+
+/**
+ * Prompts using print(); reads input from Console.
+ *
+ * @author Hans Lellelid <hans@xmpl.org> (Phing)
+ * @author Stefan Bodewig <stefan.bodewig@epost.de> (Ant)
+ * @version $Revision: 1.6 $
+ * @package phing.input
+ */
+class DefaultInputHandler implements InputHandler {
+    
+    /**
+     * Prompts and requests input.  May loop until a valid input has
+     * been entered.
+     * @throws BuildException 
+     */
+    public function handleInput(InputRequest $request) {
+        $prompt = $this->getPrompt($request);
+        $in = new ConsoleReader();           
+        do {
+            print $prompt;
+            try {
+                $input = $in->readLine();
+                if ($input === "" && ($request->getDefaultValue() !== null) ) {
+                    $input = $request->getDefaultValue();
+                }
+                $request->setInput($input);
+            } catch (Exception $e) {
+                throw new BuildException("Failed to read input from Console.", $e);
+            }
+        } while (!$request->isInputValid());
+    }
+
+    /**
+     * Constructs user prompt from a request.
+     *
+     * <p>This implementation adds (choice1,choice2,choice3,...) to the
+     * prompt for <code>MultipleChoiceInputRequest</code>s.</p>
+     *
+     * @param $request the request to construct the prompt for.
+     *                Must not be <code>null</code>.
+     */
+    protected function getPrompt(InputRequest $request) {
+        $prompt = $request->getPrompt();
+        
+        if ($request instanceof YesNoInputRequest) {
+            $prompt .= '(' . implode('/', $request->getChoices()) .')';
+        } elseif ($request instanceof MultipleChoiceInputRequest) { // (a,b,c,d)
+            $prompt .= '(' . implode(',', $request->getChoices()) . ')';            
+        }
+        if ($request->getDefaultValue() !== null) {
+            $prompt .= ' ['.$request->getDefaultValue().']';
+        }
+        $pchar = $request->getPromptChar();        
+        return $prompt . ($pchar ? $pchar . ' ' : ' ');
+    } 
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/input/InputHandler.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/input/InputHandler.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/input/InputHandler.php	(revision 19)
@@ -0,0 +1,45 @@
+<?php
+
+/*
+ *  $Id: InputHandler.php 123 2006-09-14 20:19:08Z mrook $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+/**
+ * Plugin to Phing to handle requests for user input.
+ *
+ * @author Stefan Bodewig <stefan.bodewig@epost.de>
+ * @version $Revision: 1.3 $
+ * @package phing.input
+ */
+interface InputHandler {
+
+    /**
+     * Handle the request encapsulated in the argument.
+     *
+     * <p>Precondition: the request.getPrompt will return a non-null
+     * value.</p>
+     *
+     * <p>Postcondition: request.getInput will return a non-null
+     * value, request.isInputValid will return true.</p>
+     * @return void
+     * @throws BuildException
+     */
+    public function handleInput(InputRequest $request);
+    
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/input/InputRequest.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/input/InputRequest.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/input/InputRequest.php	(revision 19)
@@ -0,0 +1,107 @@
+<?php
+
+/*
+ *  $Id: InputRequest.php 123 2006-09-14 20:19:08Z mrook $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+/**
+ * Encapsulates an input request.
+ *
+ * @author Hans Lellelid <hans@xmpl.org> (Phing)
+ * @author Stefan Bodewig <stefan.bodewig@epost.de> (Ant)
+ * @version $Revision: 1.4 $
+ * @package phing.input
+ */
+class InputRequest {
+
+    protected $prompt;
+    protected $input;
+    protected $defaultValue;
+    protected $promptChar;
+    
+    /**
+     * @param string $prompt The prompt to show to the user.  Must not be null.
+     */
+    public function __construct($prompt) {
+        if ($prompt === null) {
+            throw new BuildException("prompt must not be null");
+        }        
+        $this->prompt = $prompt;
+    }
+
+    /**
+     * Retrieves the prompt text.
+     */
+    public function getPrompt() {
+        return $this->prompt;
+    }
+
+    /**
+     * Sets the user provided input.
+     */
+    public function setInput($input) {
+        $this->input = $input;
+    }
+    
+    /**
+     * Is the user input valid?
+     */
+    public function isInputValid() {
+        return true;
+    }
+
+    /**
+     * Retrieves the user input.
+     */
+    public function getInput() {
+        return $this->input;
+    }
+    
+    /**
+     * Set the default value to use.
+     * @param mixed $v
+     */
+    public function setDefaultValue($v) {
+        $this->defaultValue = $v;
+    }
+    
+    /**
+     * Return the default value to use.
+     * @return mixed
+     */
+    public function getDefaultValue() {
+        return $this->defaultValue;
+    }
+    
+    /**
+     * Set the default value to use.
+     * @param string $c
+     */
+    public function setPromptChar($c) {
+        $this->promptChar = $c;
+    }
+    
+    /**
+     * Return the default value to use.
+     * @return string
+     */
+    public function getPromptChar() {
+        return $this->promptChar;
+    }
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/input/MultipleChoiceInputRequest.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/input/MultipleChoiceInputRequest.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/input/MultipleChoiceInputRequest.php	(revision 19)
@@ -0,0 +1,58 @@
+<?php
+/*
+ *  $Id: MultipleChoiceInputRequest.php 123 2006-09-14 20:19:08Z mrook $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+require_once 'phing/input/InputRequest.php';
+
+/**
+ * Encapsulates an input request.
+ *
+ * @author Stefan Bodewig <stefan.bodewig@epost.de>
+ * @version $Revision: 1.5 $
+ * @package phing.input
+ */
+class MultipleChoiceInputRequest extends InputRequest {
+
+    protected $choices = array();
+
+    /**
+     * @param string $prompt The prompt to show to the user.  Must not be null.
+     * @param array $choices holds all input values that are allowed.
+     *                Must not be null.
+     */
+    public function __construct($prompt, $choices) {
+        parent::__construct($prompt);        
+        $this->choices = $choices;
+    }
+
+    /**
+     * @return The possible values.
+     */
+    public function getChoices() {
+        return $this->choices;
+    }
+
+    /**
+     * @return true if the input is one of the allowed values.
+     */
+    public function isInputValid() {
+        return in_array($this->getInput(), $this->choices); // not strict (?)
+    }
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/input/PropertyFileInputHandler.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/input/PropertyFileInputHandler.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/input/PropertyFileInputHandler.php	(revision 19)
@@ -0,0 +1,129 @@
+/*
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 2002 The Apache Software Foundation.  All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ *    any, must include the following acknowlegement:
+ *       "This product includes software developed by the
+ *        Apache Software Foundation (http://www.apache.org/)."
+ *    Alternately, this acknowlegement may appear in the software itself,
+ *    if and wherever such third-party acknowlegements normally appear.
+ *
+ * 4. The names "Ant" and "Apache Software
+ *    Foundation" must not be used to endorse or promote products derived
+ *    from this software without prior written permission. For written
+ *    permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache"
+ *    nor may "Apache" appear in their names without prior written
+ *    permission of the Apache Group.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ */
+
+package org.apache.tools.ant.input;
+
+import org.apache.tools.ant.BuildException;
+
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.util.Properties;
+
+/**
+ * Reads input from a property file, the file name is read from the
+ * system property ant.input.properties, the prompt is the key for input.
+ *
+ * @author <a href="mailto:stefan.bodewig@epost.de">Stefan Bodewig</a>
+ * @version $Revision: 1.1 $
+ * @since Ant 1.5
+ */
+public class PropertyFileInputHandler implements InputHandler {
+    private Properties props = null;
+
+    /**
+     * Name of the system property we expect to hold the file name.
+     */
+    public static final String FILE_NAME_KEY = "ant.input.properties";
+
+    /**
+     * Empty no-arg constructor.
+     */
+    public PropertyFileInputHandler() {
+    }
+
+    /**
+     * Picks up the input from a property, using the prompt as the
+     * name of the property.
+     *
+     * @exception BuildException if no property of that name can be found.
+     */
+    public void handleInput(InputRequest request) throws BuildException {
+        readProps();
+        
+        Object o = props.get(request.getPrompt());
+        if (o == null) {
+            throw new BuildException("Unable to find input for \'"
+                                     + request.getPrompt()+"\'");
+        }
+        request.setInput(o.toString());
+        if (!request.isInputValid()) {
+            throw new BuildException("Found invalid input " + o
+                                     + " for \'" + request.getPrompt() + "\'");
+        }
+    }
+
+    /**
+     * Reads the properties file if it hasn't already been read.
+     */
+    private synchronized void readProps() throws BuildException {
+        if (props == null) {
+            String propsFile = System.getProperty(FILE_NAME_KEY);
+            if (propsFile == null) {
+                throw new BuildException("System property "
+                                         + FILE_NAME_KEY
+                                         + " for PropertyFileInputHandler not"
+                                         + " set");
+            }
+            
+            props = new Properties();
+            
+            try {
+                props.load(new FileInputStream(propsFile));
+            } catch (IOException e) {
+                throw new BuildException("Couldn't load " + propsFile, e);
+            }
+        }
+    }
+
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/input/YesNoInputRequest.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/input/YesNoInputRequest.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/input/YesNoInputRequest.php	(revision 19)
@@ -0,0 +1,47 @@
+<?php
+/*
+ *  $Id: YesNoInputRequest.php 123 2006-09-14 20:19:08Z mrook $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+require_once 'phing/input/MultipleChoiceInputRequest.php';
+
+/**
+ * Encapsulates an input request that returns a boolean (yes/no).
+ *
+ * @author Hans Lellelid <hans@xmpl.org>
+ * @version $Revision: 1.4 $
+ * @package phing.input
+ */
+class YesNoInputRequest extends MultipleChoiceInputRequest {     
+
+    /**
+     * @return true if the input is one of the allowed values.
+     */
+    public function isInputValid() {
+        return StringHelper::isBoolean($this->input);        
+    }
+    
+    /**
+     * Converts input to boolean.
+     * @return boolean
+     */
+    public function getInput() {
+        return StringHelper::booleanValue($this->input);
+    }
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/lib/Capsule.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/lib/Capsule.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/lib/Capsule.php	(revision 19)
@@ -0,0 +1,266 @@
+<?php
+
+/**
+ * Capsule is a simple "template" engine that essentially provides an isolated context
+ * for PHP scripts.
+ * 
+ * There is no special templating language, and therefore no limitations to what
+ * can be accomplished within templates. The main purpose of Capsule is to separate 
+ * the business logic from display / output logic.
+ * 
+ * @author Hans Lellelid <hans@xmpl.org>
+ * @version $Revision: 1.9 $ $Date: 2006-09-14 20:19:08 +0000 (Thu, 14 Sep 2006) $
+ */
+class Capsule {
+    
+    /**
+     * Look for templates here (if relative path provided).
+     * @var string
+     */
+    protected $templatePath;
+    
+    /**
+     * Where should output files be written?
+     * (This is named inconsistently to be compatible w/ Texen.)
+     * @var string
+     */
+    protected $outputDirectory;
+    
+    /**
+     * The variables that can be used by the templates.
+     * @var array Hash of variables.
+     */
+    public $vars = array();
+    
+    /**
+     * Has template been initialized.
+     */    
+    protected $initialized = false;
+    
+    /**
+     * Stores the pre-parse() include_path.
+     * @var string
+     */
+    private $old_include_path;
+    
+    function __construct() {
+    }
+    
+    /**
+     * Clears one or several or all variables.
+     * @param mixed $which String name of var, or array of names.
+     * @return void
+     */
+    function clear($which = null) {
+        if ($which === null) {
+            $this->vars = array();
+        } elseif (is_array($which)) {
+            foreach($which as $var) {
+                unset($this->vars[$var]);
+            }
+        } else {
+            unset($this->vars[$which]);
+        }
+    }
+    
+    /**
+     * Set the basepath to use for template lookups.
+     * @param string $v
+     */
+    function setTemplatePath($v) {
+        $this->templatePath = rtrim($v, DIRECTORY_SEPARATOR.'/');
+    }
+
+    /**
+     * Get the basepath to use for template lookups.
+     * @return string
+     */
+    function getTemplatePath() {
+        return $this->templatePath;
+    }
+    
+    /**
+     * Set a basepath to use for output file creation.
+     * @param string $v
+     */
+    function setOutputDirectory($v) {
+        $this->outputDirectory = rtrim($v, DIRECTORY_SEPARATOR.'/');
+    }
+
+    /**
+     * Get basepath to use for output file creation.
+     * @return string
+     */
+    function getOutputDirectory() {
+        return $this->outputDirectory;
+    }
+    
+    /**
+     * Low overhead (no output buffering) method to simply dump template
+     * to buffer.
+     * 
+     * @param string $__template
+     * @return void
+     * @throws Exception - if template cannot be found
+     */ 
+    function display($__template) {
+        
+        // Prepend "private" variable names with $__ in this function
+        // to keep namespace conflict potential to a minimum.
+            
+        // Alias this class to $generator.
+        $generator = $this;
+                        
+        if (isset($this->vars['this'])) {
+            throw new Exception("Assigning a variable named \$this to a context conflicts with class namespace.");
+        }
+        
+        // extract variables into local namespace
+        extract($this->vars);
+        
+        // prepend template path to include path, 
+        // so that include "path/relative/to/templates"; can be used within templates
+        $__old_inc_path = ini_get('include_path');
+        ini_set('include_path', $this->templatePath . PATH_SEPARATOR . $__old_inc_path);
+                
+        @ini_set('track_errors', true);
+        include $__template;
+        @ini_restore('track_errors');
+        
+        // restore the include path
+        ini_set('include_path', $__old_inc_path);
+        
+        if (!empty($php_errormsg)) {
+            throw new Exception("Unable to parse template " . $__template . ": " . $php_errormsg);
+        }
+    }
+    
+    /**
+     * Fetches the results of a tempalte parse and either returns
+     * the string or writes results to a specified output file.
+     *
+     * @param string $template The template filename (relative to templatePath or absolute).
+     * @param string $outputFile If specified, contents of template will also be written to this file.
+     * @param boolean $append Should output be appended to source file?
+     * @return string The "parsed" template output.
+     * @throws Exception - if template not found.
+     */
+    function parse($template, $outputFile = null, $append = false) {
+                
+        // main work done right here:
+        // hopefully this works recursively ... fingers crossed.    
+        ob_start();
+        
+        try {
+            $this->display($template);
+        } catch (Exception $e) {
+            ob_end_flush(); // flush the output on error (so we can see up to what point it parsed everything)
+            throw $e;
+        }
+                
+        $output = ob_get_contents();
+        ob_end_clean();
+        
+        if ($outputFile !== null) {
+            $outputFile = $this->resolvePath($outputFile, $this->outputDirectory);
+            
+            $flags = null;
+            if ($append) $flags = FILE_APPEND;
+            
+            if (!file_put_contents($outputFile, $output, $flags) && $output != "") {
+                throw new Exception("Unable to write output to " . $outputFile);
+            }
+        }
+
+        return $output;
+    }
+    
+    /**
+     * This returns a "best guess" path for the given file.
+     *
+     * @param string $file File name or possibly absolute path.
+     * @param string $basepath The basepath that should be prepended if $file is not absolute.
+     * @return string "Best guess" path for this file.
+     */
+    protected function resolvePath($file, $basepath) {
+        if ( !($file{0} == DIRECTORY_SEPARATOR || $file{0} == '/') 
+            // also account for C:\ style path
+                && !($file{1} == ':' && ($file{2} ==  DIRECTORY_SEPARATOR || $file{2} == '/'))) { 
+            if ($basepath != null) {
+                $file = $basepath . DIRECTORY_SEPARATOR . $file;
+            }
+        }
+        return $file;
+    }
+
+    /**
+     * Gets value of specified var or NULL if var has not been put().
+     * @param string $name Variable name to retrieve.
+     * @return mixed
+     */
+    function get($name) {
+        if (!isset($this->vars[$name])) return null;
+        return $this->vars[$name];
+    }
+    
+    /**
+     * Merges in passed hash to vars array.
+     *
+     * Given an array like:
+     *
+     *            array(     'myvar' => 'Hello',
+     *                    'myvar2' => 'Hello')
+     *
+     * Resulting template will have access to $myvar and $myvar2.
+     *
+     * @param array $vars
+     * @param boolean $recursiveMerge Should matching keys be recursively merged?
+     * @return void
+     */
+    function putAll($vars, $recursiveMerge = false) {
+        if ($recursiveMerge) {
+            $this->vars = array_merge_recursive($this->vars, $vars);
+        } else {
+            $this->vars = array_merge($this->vars, $vars);
+        }
+    }
+    
+    /**
+     * Adds a variable to the context.
+     * 
+     * Resulting template will have access to ${$name$} variable.
+     * 
+     * @param string $name
+     * @param mixed $value
+     */
+    function put($name, $value) {
+        $this->vars[$name] = $value;
+    }
+        
+    /**
+     * Put a variable into the context, assigning it by reference.
+     * This means that if the template modifies the variable, then it
+     * will also be modified in the context.
+     *
+     * @param $name
+     * @param &$value
+     */
+    function putRef($name, &$value) {
+        $this->vars[$name] = &$value;
+    }
+    
+    /**
+     * Makes a copy of the value and puts it into the context.
+     * This is primarily to force copying (cloning) of objects, rather
+     * than the default behavior which is to assign them by reference.
+     * @param string $name
+     * @param mixed $value
+     */
+    function putCopy($name, $value) {
+        if (is_object($value)) {
+            $value = clone $value;
+        }
+        $this->vars[$name] = $value;
+    }
+
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/lib/Zip.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/lib/Zip.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/lib/Zip.php	(revision 19)
@@ -0,0 +1,3590 @@
+<?php
+/* vim: set ts=4 sw=4: */
+// +----------------------------------------------------------------------+
+// | PHP Version 4                                                        |
+// +----------------------------------------------------------------------+
+// | Copyright (c) 1997-2003 The PHP Group                                |
+// +----------------------------------------------------------------------+
+// | This source file is subject to version 3.0 of the PHP license,       |
+// | that is bundled with this package in the file LICENSE, and is        |
+// | available through the world-wide-web at the following url:           |
+// | http://www.php.net/license/3_0.txt.                                  |
+// | If you did not receive a copy of the PHP license and are unable to   |
+// | obtain it through the world-wide-web, please send a note to          |
+// | license@php.net so we can mail you a copy immediately.               |
+// +----------------------------------------------------------------------+
+// | Author: Vincent Blavet <vincent@blavet.net>                          |
+// +----------------------------------------------------------------------+
+//
+// $Id: Zip.php 325 2007-12-20 15:44:58Z hans $
+
+  // ----- Constants
+  define( 'ARCHIVE_ZIP_READ_BLOCK_SIZE', 2048 );
+
+  // ----- File list separator
+  define( 'ARCHIVE_ZIP_SEPARATOR', ',' );
+
+  // ----- Optional static temporary directory
+  //       By default temporary files are generated in the script current
+  //       path.
+  //       If defined :
+  //       - MUST BE terminated by a '/'.
+  //       - MUST be a valid, already created directory
+  //       Samples :
+  // define( 'ARCHIVE_ZIP_TEMPORARY_DIR', '/temp/' );
+  // define( 'ARCHIVE_ZIP_TEMPORARY_DIR', 'C:/Temp/' );
+  define( 'ARCHIVE_ZIP_TEMPORARY_DIR', '' );
+
+  // ----- Error codes
+  define( 'ARCHIVE_ZIP_ERR_NO_ERROR', 0 );
+  define( 'ARCHIVE_ZIP_ERR_WRITE_OPEN_FAIL', -1 );
+  define( 'ARCHIVE_ZIP_ERR_READ_OPEN_FAIL', -2 );
+  define( 'ARCHIVE_ZIP_ERR_INVALID_PARAMETER', -3 );
+  define( 'ARCHIVE_ZIP_ERR_MISSING_FILE', -4 );
+  define( 'ARCHIVE_ZIP_ERR_FILENAME_TOO_LONG', -5 );
+  define( 'ARCHIVE_ZIP_ERR_INVALID_ZIP', -6 );
+  define( 'ARCHIVE_ZIP_ERR_BAD_EXTRACTED_FILE', -7 );
+  define( 'ARCHIVE_ZIP_ERR_DIR_CREATE_FAIL', -8 );
+  define( 'ARCHIVE_ZIP_ERR_BAD_EXTENSION', -9 );
+  define( 'ARCHIVE_ZIP_ERR_BAD_FORMAT', -10 );
+  define( 'ARCHIVE_ZIP_ERR_DELETE_FILE_FAIL', -11 );
+  define( 'ARCHIVE_ZIP_ERR_RENAME_FILE_FAIL', -12 );
+  define( 'ARCHIVE_ZIP_ERR_BAD_CHECKSUM', -13 );
+  define( 'ARCHIVE_ZIP_ERR_INVALID_ARCHIVE_ZIP', -14 );
+  define( 'ARCHIVE_ZIP_ERR_MISSING_OPTION_VALUE', -15 );
+  define( 'ARCHIVE_ZIP_ERR_INVALID_PARAM_VALUE', -16 );
+
+  // ----- Warning codes
+  define( 'ARCHIVE_ZIP_WARN_NO_WARNING', 0 );
+  define( 'ARCHIVE_ZIP_WARN_FILE_EXIST', 1 );
+
+  // ----- Methods parameters
+  define( 'ARCHIVE_ZIP_PARAM_PATH', 'path' );
+  define( 'ARCHIVE_ZIP_PARAM_ADD_PATH', 'add_path' );
+  define( 'ARCHIVE_ZIP_PARAM_REMOVE_PATH', 'remove_path' );
+  define( 'ARCHIVE_ZIP_PARAM_REMOVE_ALL_PATH', 'remove_all_path' );
+  define( 'ARCHIVE_ZIP_PARAM_SET_CHMOD', 'set_chmod' );
+  define( 'ARCHIVE_ZIP_PARAM_EXTRACT_AS_STRING', 'extract_as_string' );
+  define( 'ARCHIVE_ZIP_PARAM_NO_COMPRESSION', 'no_compression' );
+  define( 'ARCHIVE_ZIP_PARAM_BY_NAME', 'by_name' );
+  define( 'ARCHIVE_ZIP_PARAM_BY_INDEX', 'by_index' );
+  define( 'ARCHIVE_ZIP_PARAM_BY_EREG', 'by_ereg' );
+  define( 'ARCHIVE_ZIP_PARAM_BY_PREG', 'by_preg' );
+
+  define( 'ARCHIVE_ZIP_PARAM_PRE_EXTRACT', 'callback_pre_extract' );
+  define( 'ARCHIVE_ZIP_PARAM_POST_EXTRACT', 'callback_post_extract' );
+  define( 'ARCHIVE_ZIP_PARAM_PRE_ADD', 'callback_pre_add' );
+  define( 'ARCHIVE_ZIP_PARAM_POST_ADD', 'callback_post_add' );
+
+
+
+/**
+* Class for manipulating zip archive files
+*
+* A class which provided common methods to manipulate ZIP formatted
+* archive files.
+* It provides creation, extraction, deletion and add features.
+*
+* @author   Vincent Blavet <vincent@blavet.net>
+* @version  $Revision: 1.3 $
+* @package  phing.lib
+*/
+class Archive_Zip
+{
+    /**
+    * The filename of the zip archive.
+    *
+    * @var string Name of the Zip file
+    */
+    var $_zipname='';
+
+    /**
+    * File descriptor of the opened Zip file.
+    *
+    * @var int Internal zip file descriptor
+    */
+    var $_zip_fd=0;
+
+    /**
+    * @var int last error code
+    */
+    var $_error_code=1;
+
+    /**
+    * @var string Last error description
+    */
+    var $_error_string='';
+
+    // {{{ constructor
+    /**
+    * Archive_Zip Class constructor. This flavour of the constructor only
+    * declare a new Archive_Zip object, identifying it by the name of the
+    * zip file.
+    *
+    * @param    string  $p_zipname  The name of the zip archive to create
+    * @access public
+    */
+    function __construct($p_zipname)
+    {
+      if (!extension_loaded('zlib')) {
+          throw new Exception("The extension 'zlib' couldn't be found.\n".
+              "Please make sure your version of PHP was built ".
+              "with 'zlib' support.");
+      }
+
+      // ----- Set the attributes
+      $this->_zipname = $p_zipname;
+      $this->_zip_fd = 0;
+    }
+    // }}}
+
+    // {{{ create()
+    /**
+    * This method creates a Zip Archive with the filename set with
+	* the constructor.
+	* The files and directories indicated in $p_filelist
+    * are added in the archive.
+	* When a directory is in the list, the directory and its content is added
+    * in the archive.
+    * The methods takes a variable list of parameters in $p_params.
+    * The supported parameters for this method are :
+    *   'add_path' : Add a path to the archived files.
+    *   'remove_path' : Remove the specified 'root' path of the archived files.
+    *   'remove_all_path' : Remove all the path of the archived files.
+    *   'no_compression' : The archived files will not be compressed.
+    *
+    * @access public
+    * @param  mixed  $p_filelist  The list of the files or folders to add.
+    *                             It can be a string with filenames separated
+    *                             by a comma, or an array of filenames.
+    * @param  mixed  $p_params  An array of variable parameters and values.
+    * @return mixed An array of file description on success,
+	*               an error code on error
+    */
+    function create($p_filelist, $p_params=0)
+    {
+        $this->_errorReset();
+
+        // ----- Set default values
+        if ($p_params === 0) {
+    	    $p_params = array();
+        }
+        if ($this->_check_parameters($p_params,
+	                                 array('no_compression' => false,
+	                                       'add_path' => "",
+	                                       'remove_path' => "",
+	                                       'remove_all_path' => false)) != 1) {
+		    return 0;
+	    }
+
+        // ----- Look if the $p_filelist is really an array
+        $p_result_list = array();
+        if (is_array($p_filelist)) {
+            $v_result = $this->_create($p_filelist, $p_result_list, $p_params);
+        }
+
+        // ----- Look if the $p_filelist is a string
+        else if (is_string($p_filelist)) {
+            // ----- Create a list with the elements from the string
+            $v_list = explode(ARCHIVE_ZIP_SEPARATOR, $p_filelist);
+
+            $v_result = $this->_create($v_list, $p_result_list, $p_params);
+        }
+
+        // ----- Invalid variable
+        else {
+            $this->_errorLog(ARCHIVE_ZIP_ERR_INVALID_PARAMETER,
+	                         'Invalid variable type p_filelist');
+            $v_result = ARCHIVE_ZIP_ERR_INVALID_PARAMETER;
+        }
+
+        if ($v_result != 1) {
+            return 0;
+        }
+
+        return $p_result_list;
+    }
+    // }}}
+
+    // {{{ add()
+    /**
+    * This method add files or directory in an existing Zip Archive.
+    * If the Zip Archive does not exist it is created.
+	* The files and directories to add are indicated in $p_filelist.
+	* When a directory is in the list, the directory and its content is added
+    * in the archive.
+    * The methods takes a variable list of parameters in $p_params.
+    * The supported parameters for this method are :
+    *   'add_path' : Add a path to the archived files.
+    *   'remove_path' : Remove the specified 'root' path of the archived files.
+    *   'remove_all_path' : Remove all the path of the archived files.
+    *   'no_compression' : The archived files will not be compressed.
+    *   'callback_pre_add' : A callback function that will be called before
+    *                        each entry archiving.
+    *   'callback_post_add' : A callback function that will be called after
+    *                         each entry archiving.
+    *
+    * @access public
+    * @param    mixed  $p_filelist  The list of the files or folders to add.
+    *                               It can be a string with filenames separated
+    *                               by a comma, or an array of filenames.
+    * @param    mixed  $p_params  An array of variable parameters and values.
+    * @return mixed An array of file description on success,
+	*               0 on an unrecoverable failure, an error code is logged.
+    */
+    function add($p_filelist, $p_params=0)
+    {
+        $this->_errorReset();
+
+        // ----- Set default values
+        if ($p_params === 0) {
+        	$p_params = array();
+        }
+        if ($this->_check_parameters($p_params,
+	                                 array ('no_compression' => false,
+	                                        'add_path' => '',
+	                                        'remove_path' => '',
+	                                        'remove_all_path' => false,
+						    	     		'callback_pre_add' => '',
+							    		    'callback_post_add' => '')) != 1) {
+		    return 0;
+	    }
+
+        // ----- Look if the $p_filelist is really an array
+        $p_result_list = array();
+        if (is_array($p_filelist)) {
+            // ----- Call the create fct
+            $v_result = $this->_add($p_filelist, $p_result_list, $p_params);
+        }
+
+        // ----- Look if the $p_filelist is a string
+        else if (is_string($p_filelist)) {
+            // ----- Create a list with the elements from the string
+            $v_list = explode(ARCHIVE_ZIP_SEPARATOR, $p_filelist);
+
+            // ----- Call the create fct
+            $v_result = $this->_add($v_list, $p_result_list, $p_params);
+        }
+
+        // ----- Invalid variable
+        else {
+            $this->_errorLog(ARCHIVE_ZIP_ERR_INVALID_PARAMETER,
+	                         "add() : Invalid variable type p_filelist");
+            $v_result = ARCHIVE_ZIP_ERR_INVALID_PARAMETER;
+        }
+
+        if ($v_result != 1) {
+            return 0;
+        }
+
+        // ----- Return the result list
+        return $p_result_list;
+    }
+    // }}}
+
+    // {{{ listContent()
+    /**
+    * This method gives the names and properties of the files and directories
+	* which are present in the zip archive.
+    * The properties of each entries in the list are :
+    *   filename : Name of the file.
+	*              For create() or add() it's the filename given by the user.
+	*              For an extract() it's the filename of the extracted file.
+    *   stored_filename : Name of the file / directory stored in the archive.
+    *   size : Size of the stored file.
+    *   compressed_size : Size of the file's data compressed in the archive
+    *                     (without the zip headers overhead)
+    *   mtime : Last known modification date of the file (UNIX timestamp)
+    *   comment : Comment associated with the file
+    *   folder : true | false (indicates if the entry is a folder)
+    *   index : index of the file in the archive (-1 when not available)
+    *   status : status of the action on the entry (depending of the action) :
+    *            Values are :
+    *              ok : OK !
+    *              filtered : the file/dir was not extracted (filtered by user)
+    *              already_a_directory : the file can't be extracted because a
+    *                                    directory with the same name already
+	*                                    exists
+    *              write_protected : the file can't be extracted because a file
+    *                                with the same name already exists and is
+    *                                write protected
+    *              newer_exist : the file was not extracted because a newer
+	*                            file already exists
+    *              path_creation_fail : the file is not extracted because the
+	*                                   folder does not exists and can't be
+	*                                   created
+    *              write_error : the file was not extracted because there was a
+    *                            error while writing the file
+    *              read_error : the file was not extracted because there was a
+	*                           error while reading the file
+    *              invalid_header : the file was not extracted because of an
+	*                               archive format error (bad file header)
+    * Note that each time a method can continue operating when there
+    * is an error on a single file, the error is only logged in the file status.
+    *
+    * @access public
+    * @return mixed An array of file description on success,
+	*               0 on an unrecoverable failure, an error code is logged.
+    */
+    function listContent()
+    {
+        $this->_errorReset();
+
+        // ----- Check archive
+        if (!$this->_checkFormat()) {
+            return(0);
+        }
+
+        $v_list = array();
+        if ($this->_list($v_list) != 1) {
+            unset($v_list);
+            return(0);
+        }
+
+        return $v_list;
+    }
+    // }}}
+
+    // {{{ extract()
+    /**
+    * This method extract the files and folders which are in the zip archive.
+    * It can extract all the archive or a part of the archive by using filter
+    * feature (extract by name, by index, by ereg, by preg). The extraction
+    * can occur in the current path or an other path.
+    * All the advanced features are activated by the use of variable
+	* parameters.
+	* The return value is an array of entry descriptions which gives
+	* information on extracted files (See listContent()).
+	* The method may return a success value (an array) even if some files
+	* are not correctly extracted (see the file status in listContent()).
+    * The supported variable parameters for this method are :
+    *   'add_path' : Path where the files and directories are to be extracted
+    *   'remove_path' : First part ('root' part) of the memorized path
+    *                   (if similar) to remove while extracting.
+    *   'remove_all_path' : Remove all the memorized path while extracting.
+    *   'extract_as_string' :
+    *   'set_chmod' : After the extraction of the file the indicated mode
+    *                 will be set.
+    *   'by_name' : It can be a string with file/dir names separated by ',',
+    *               or an array of file/dir names to extract from the archive.
+    *   'by_index' : A string with range of indexes separated by ',',
+    *                (sample "1,3-5,12").
+    *   'by_ereg' : A regular expression (ereg) that must match the extracted
+    *               filename.
+    *   'by_preg' : A regular expression (preg) that must match the extracted
+    *               filename.
+    *   'callback_pre_extract' : A callback function that will be called before
+    *                            each entry extraction.
+    *   'callback_post_extract' : A callback function that will be called after
+    *                            each entry extraction.
+    *
+    * @access public
+    * @param    mixed  $p_params  An array of variable parameters and values.
+    * @return mixed An array of file description on success,
+	*               0 on an unrecoverable failure, an error code is logged.
+    */
+    function extract($p_params=0)
+    {
+
+        $this->_errorReset();
+
+        // ----- Check archive
+        if (!$this->_checkFormat()) {
+            return(0);
+        }
+
+        // ----- Set default values
+        if ($p_params === 0) {
+        	$p_params = array();
+        }
+        if ($this->_check_parameters($p_params,
+	                                 array ('extract_as_string' => false,
+	                                        'add_path' => '',
+	                                        'remove_path' => '',
+	                                        'remove_all_path' => false,
+					    		     		'callback_pre_extract' => '',
+						    			    'callback_post_extract' => '',
+							    		    'set_chmod' => 0,
+								    	    'by_name' => '',
+									        'by_index' => '',
+									        'by_ereg' => '',
+									        'by_preg' => '') ) != 1) {
+	    	return 0;
+	    }
+
+        // ----- Call the extracting fct
+        $v_list = array();
+        if ($this->_extractByRule($v_list, $p_params) != 1) {
+            unset($v_list);
+            return(0);
+        }
+
+        return $v_list;
+    }
+    // }}}
+
+
+    // {{{ delete()
+    /**
+    * This methods delete archive entries in the zip archive.
+    * Notice that at least one filtering rule (set by the variable parameter
+    * list) must be set.
+    * Also notice that if you delete a folder entry, only the folder entry
+    * is deleted, not all the files bellonging to this folder.
+    * The supported variable parameters for this method are :
+    *   'by_name' : It can be a string with file/dir names separated by ',',
+    *               or an array of file/dir names to delete from the archive.
+    *   'by_index' : A string with range of indexes separated by ',',
+    *                (sample "1,3-5,12").
+    *   'by_ereg' : A regular expression (ereg) that must match the extracted
+    *               filename.
+    *   'by_preg' : A regular expression (preg) that must match the extracted
+    *               filename.
+    *
+    * @access public
+    * @param    mixed  $p_params  An array of variable parameters and values.
+    * @return mixed An array of file description on success,
+	*               0 on an unrecoverable failure, an error code is logged.
+    */
+    function delete($p_params)
+    {
+        $this->_errorReset();
+
+        // ----- Check archive
+        if (!$this->_checkFormat()) {
+            return(0);
+        }
+
+        // ----- Set default values
+        if ($this->_check_parameters($p_params,
+	                                 array ('by_name' => '',
+									        'by_index' => '',
+									        'by_ereg' => '',
+									        'by_preg' => '') ) != 1) {
+	    	return 0;
+    	}
+
+        // ----- Check that at least one rule is set
+        if (   ($p_params['by_name'] == '')
+            && ($p_params['by_index'] == '')
+            && ($p_params['by_ereg'] == '')
+            && ($p_params['by_preg'] == '')) {
+            $this->_errorLog(ARCHIVE_ZIP_ERR_INVALID_PARAMETER,
+			                 'At least one filtering rule must'
+							 .' be set as parameter');
+            return 0;
+        }
+
+        // ----- Call the delete fct
+        $v_list = array();
+        if ($this->_deleteByRule($v_list, $p_params) != 1) {
+            unset($v_list);
+            return(0);
+        }
+
+        return $v_list;
+    }
+    // }}}
+
+    // {{{ properties()
+    /**
+    * This method gives the global properties of the archive.
+    *  The properties are :
+    *    nb : Number of files in the archive
+    *    comment : Comment associated with the archive file
+    *    status : not_exist, ok
+    *
+    * @access public
+    * @param    mixed  $p_params  {Description}
+    * @return mixed An array with the global properties or 0 on error.
+    */
+    function properties()
+    {
+        $this->_errorReset();
+
+        // ----- Check archive
+        if (!$this->_checkFormat()) {
+            return(0);
+        }
+
+        // ----- Default properties
+        $v_prop = array();
+        $v_prop['comment'] = '';
+        $v_prop['nb'] = 0;
+        $v_prop['status'] = 'not_exist';
+
+        // ----- Look if file exists
+        if (@is_file($this->_zipname)) {
+            // ----- Open the zip file
+            if (($this->_zip_fd = @fopen($this->_zipname, 'rb')) == 0) {
+                $this->_errorLog(ARCHIVE_ZIP_ERR_READ_OPEN_FAIL,
+				                 'Unable to open archive \''.$this->_zipname
+								 .'\' in binary read mode');
+                return 0;
+            }
+
+            // ----- Read the central directory informations
+            $v_central_dir = array();
+            if (($v_result = $this->_readEndCentralDir($v_central_dir)) != 1) {
+                return 0;
+            }
+
+            $this->_closeFd();
+
+            // ----- Set the user attributes
+            $v_prop['comment'] = $v_central_dir['comment'];
+            $v_prop['nb'] = $v_central_dir['entries'];
+            $v_prop['status'] = 'ok';
+        }
+
+        return $v_prop;
+    }
+    // }}}
+
+
+    // {{{ duplicate()
+    /**
+    * This method creates an archive by copying the content of an other one.
+	* If the archive already exist, it is replaced by the new one without
+	* any warning.
+    *
+    * @access public
+    * @param  mixed  $p_archive  It can be a valid Archive_Zip object or
+	*                            the filename of a valid zip archive.
+    * @return integer 1 on success, 0 on failure.
+    */
+    function duplicate($p_archive)
+    {
+        $this->_errorReset();
+
+        // ----- Look if the $p_archive is a Archive_Zip object
+        if (   (is_object($p_archive))
+		    && (strtolower(get_class($p_archive)) == 'archive_zip')) {
+            $v_result = $this->_duplicate($p_archive->_zipname);
+        }
+
+        // ----- Look if the $p_archive is a string (so a filename)
+        else if (is_string($p_archive)) {
+            // ----- Check that $p_archive is a valid zip file
+            // TBC : Should also check the archive format
+            if (!is_file($p_archive)) {
+                $this->_errorLog(ARCHIVE_ZIP_ERR_MISSING_FILE,
+				                 "No file with filename '".$p_archive."'");
+                $v_result = ARCHIVE_ZIP_ERR_MISSING_FILE;
+            }
+            else {
+                $v_result = $this->_duplicate($p_archive);
+            }
+        }
+
+        // ----- Invalid variable
+        else {
+            $this->_errorLog(ARCHIVE_ZIP_ERR_INVALID_PARAMETER,
+			                 "Invalid variable type p_archive_to_add");
+            $v_result = ARCHIVE_ZIP_ERR_INVALID_PARAMETER;
+        }
+
+        return $v_result;
+    }
+    // }}}
+
+    // {{{ merge()
+    /**
+    *  This method merge a valid zip archive at the end of the
+	*  archive identified by the Archive_Zip object.
+    *  If the archive ($this) does not exist, the merge becomes a duplicate.
+    *  If the archive to add does not exist, the merge is a success.
+    *
+    * @access public
+    * @param mixed $p_archive_to_add  It can be a valid Archive_Zip object or
+	*                                 the filename of a valid zip archive.
+    * @return integer 1 on success, 0 on failure.
+    */
+    function merge($p_archive_to_add)
+    {
+        $v_result = 1;
+        $this->_errorReset();
+
+        // ----- Check archive
+        if (!$this->_checkFormat()) {
+            return(0);
+        }
+
+        // ----- Look if the $p_archive_to_add is a Archive_Zip object
+        if (   (is_object($p_archive_to_add))
+		    && (strtolower(get_class($p_archive_to_add)) == 'archive_zip')) {
+            $v_result = $this->_merge($p_archive_to_add);
+        }
+
+        // ----- Look if the $p_archive_to_add is a string (so a filename)
+        else if (is_string($p_archive_to_add)) {
+            // ----- Create a temporary archive
+            $v_object_archive = new Archive_Zip($p_archive_to_add);
+
+            // ----- Merge the archive
+            $v_result = $this->_merge($v_object_archive);
+        }
+
+        // ----- Invalid variable
+        else {
+            $this->_errorLog(ARCHIVE_ZIP_ERR_INVALID_PARAMETER,
+			                 "Invalid variable type p_archive_to_add");
+            $v_result = ARCHIVE_ZIP_ERR_INVALID_PARAMETER;
+        }
+
+        return $v_result;
+    }
+    // }}}
+
+    // {{{ errorCode()
+    /**
+    * Method that gives the lastest error code.
+    *
+    * @access public
+    * @return integer The error code value.
+    */
+    function errorCode()
+    {
+        return($this->_error_code);
+    }
+    // }}}
+
+    // {{{ errorName()
+    /**
+    * This method gives the latest error code name.
+    *
+    * @access public
+    * @param  boolean $p_with_code  If true, gives the name and the int value.
+    * @return string The error name.
+    */
+    function errorName($p_with_code=false)
+    {
+        $v_const_list = get_defined_constants();
+  	
+      	// ----- Extract error constants from all const.
+        for (reset($v_const_list);
+		     list($v_key, $v_value) = each($v_const_list);) {
+     	    if (substr($v_key, 0, strlen('ARCHIVE_ZIP_ERR_'))
+			    =='ARCHIVE_ZIP_ERR_') {
+    		    $v_error_list[$v_key] = $v_value;
+    	    }
+        }
+    
+        // ----- Search the name form the code value
+        $v_key=array_search($this->_error_code, $v_error_list, true);
+  	    if ($v_key!=false) {
+            $v_value = $v_key;
+  	    }
+  	    else {
+            $v_value = 'NoName';
+  	    }
+  	
+        if ($p_with_code) {
+            return($v_value.' ('.$this->_error_code.')');
+        }
+        else {
+          return($v_value);
+        }
+    }
+    // }}}
+
+    // {{{ errorInfo()
+    /**
+    * This method returns the description associated with the latest error.
+    *
+    * @access public
+    * @param  boolean $p_full If set to true gives the description with the
+    *                         error code, the name and the description.
+    *                         If set to false gives only the description
+    *                         and the error code.
+    * @return string The error description.
+    */
+    function errorInfo($p_full=false)
+    {
+        if ($p_full) {
+            return($this->errorName(true)." : ".$this->_error_string);
+        }
+        else {
+            return($this->_error_string." [code ".$this->_error_code."]");
+        }
+    }
+    // }}}
+
+
+// -----------------------------------------------------------------------------
+// ***** UNDER THIS LINE ARE DEFINED PRIVATE INTERNAL FUNCTIONS *****
+// *****                                                        *****
+// *****       THESES FUNCTIONS MUST NOT BE USED DIRECTLY       *****
+// -----------------------------------------------------------------------------
+
+  // ---------------------------------------------------------------------------
+  // Function : _checkFormat()
+  // Description :
+  //   This method check that the archive exists and is a valid zip archive.
+  //   Several level of check exists. (futur)
+  // Parameters :
+  //   $p_level : Level of check. Default 0.
+  //              0 : Check the first bytes (magic codes) (default value))
+  //              1 : 0 + Check the central directory (futur)
+  //              2 : 1 + Check each file header (futur)
+  // Return Values :
+  //   true on success,
+  //   false on error, the error code is set.
+  // ---------------------------------------------------------------------------
+  /**
+  * Archive_Zip::_checkFormat()
+  *
+  * { Description }
+  *
+  * @param integer $p_level
+  */
+  function _checkFormat($p_level=0)
+  {
+    $v_result = true;
+
+    // ----- Reset the error handler
+    $this->_errorReset();
+
+    // ----- Look if the file exits
+    if (!is_file($this->_zipname)) {
+      // ----- Error log
+      $this->_errorLog(ARCHIVE_ZIP_ERR_MISSING_FILE,
+	                   "Missing archive file '".$this->_zipname."'");
+      return(false);
+    }
+
+    // ----- Check that the file is readeable
+    if (!is_readable($this->_zipname)) {
+      // ----- Error log
+      $this->_errorLog(ARCHIVE_ZIP_ERR_READ_OPEN_FAIL,
+	                   "Unable to read archive '".$this->_zipname."'");
+      return(false);
+    }
+
+    // ----- Check the magic code
+    // TBC
+
+    // ----- Check the central header
+    // TBC
+
+    // ----- Check each file header
+    // TBC
+
+    // ----- Return
+    return $v_result;
+  }
+  // ---------------------------------------------------------------------------
+
+  // ---------------------------------------------------------------------------
+  // Function : _create()
+  // Description :
+  // Parameters :
+  // Return Values :
+  // ---------------------------------------------------------------------------
+  /**
+  * Archive_Zip::_create()
+  *
+  * { Description }
+  *
+  */
+  function _create($p_list, &$p_result_list, &$p_params)
+  {
+    $v_result=1;
+    $v_list_detail = array();
+
+	$p_add_dir = $p_params['add_path'];
+	$p_remove_dir = $p_params['remove_path'];
+	$p_remove_all_dir = $p_params['remove_all_path'];
+
+    // ----- Open the file in write mode
+    if (($v_result = $this->_openFd('wb')) != 1)
+    {
+      // ----- Return
+      return $v_result;
+    }
+
+    // ----- Add the list of files
+    $v_result = $this->_addList($p_list, $p_result_list, $p_add_dir, $p_remove_dir, $p_remove_all_dir, $p_params);
+
+    // ----- Close
+    $this->_closeFd();
+
+    // ----- Return
+    return $v_result;
+  }
+  // ---------------------------------------------------------------------------
+
+  // ---------------------------------------------------------------------------
+  // Function : _add()
+  // Description :
+  // Parameters :
+  // Return Values :
+  // ---------------------------------------------------------------------------
+  /**
+  * Archive_Zip::_add()
+  *
+  * { Description }
+  *
+  */
+  function _add($p_list, &$p_result_list, &$p_params)
+  {
+    $v_result=1;
+    $v_list_detail = array();
+
+	$p_add_dir = $p_params['add_path'];
+	$p_remove_dir = $p_params['remove_path'];
+	$p_remove_all_dir = $p_params['remove_all_path'];
+
+    // ----- Look if the archive exists or is empty and need to be created
+    if ((!is_file($this->_zipname)) || (filesize($this->_zipname) == 0)) {
+      $v_result = $this->_create($p_list, $p_result_list, $p_params);
+      return $v_result;
+    }
+
+    // ----- Open the zip file
+    if (($v_result=$this->_openFd('rb')) != 1) {
+      return $v_result;
+    }
+
+    // ----- Read the central directory informations
+    $v_central_dir = array();
+    if (($v_result = $this->_readEndCentralDir($v_central_dir)) != 1)
+    {
+      $this->_closeFd();
+      return $v_result;
+    }
+
+    // ----- Go to beginning of File
+    @rewind($this->_zip_fd);
+
+    // ----- Creates a temporay file
+    $v_zip_temp_name = ARCHIVE_ZIP_TEMPORARY_DIR.uniqid('archive_zip-').'.tmp';
+
+    // ----- Open the temporary file in write mode
+    if (($v_zip_temp_fd = @fopen($v_zip_temp_name, 'wb')) == 0)
+    {
+      $this->_closeFd();
+
+      $this->_errorLog(ARCHIVE_ZIP_ERR_READ_OPEN_FAIL,
+	                   'Unable to open temporary file \''
+					   .$v_zip_temp_name.'\' in binary write mode');
+      return Archive_Zip::errorCode();
+    }
+
+    // ----- Copy the files from the archive to the temporary file
+    // TBC : Here I should better append the file and go back to erase the
+	// central dir
+    $v_size = $v_central_dir['offset'];
+    while ($v_size != 0)
+    {
+      $v_read_size = ($v_size < ARCHIVE_ZIP_READ_BLOCK_SIZE
+	                  ? $v_size : ARCHIVE_ZIP_READ_BLOCK_SIZE);
+      $v_buffer = fread($this->_zip_fd, $v_read_size);
+      @fwrite($v_zip_temp_fd, $v_buffer, $v_read_size);
+      $v_size -= $v_read_size;
+    }
+
+    // ----- Swap the file descriptor
+    // Here is a trick : I swap the temporary fd with the zip fd, in order to 
+    // use the following methods on the temporary fil and not the real archive
+    $v_swap = $this->_zip_fd;
+    $this->_zip_fd = $v_zip_temp_fd;
+    $v_zip_temp_fd = $v_swap;
+
+    // ----- Add the files
+    $v_header_list = array();
+    if (($v_result = $this->_addFileList($p_list, $v_header_list,
+	                                     $p_add_dir, $p_remove_dir,
+										 $p_remove_all_dir, $p_params)) != 1)
+    {
+      fclose($v_zip_temp_fd);
+      $this->_closeFd();
+      @unlink($v_zip_temp_name);
+
+      // ----- Return
+      return $v_result;
+    }
+
+    // ----- Store the offset of the central dir
+    $v_offset = @ftell($this->_zip_fd);
+
+    // ----- Copy the block of file headers from the old archive
+    $v_size = $v_central_dir['size'];
+    while ($v_size != 0)
+    {
+      $v_read_size = ($v_size < ARCHIVE_ZIP_READ_BLOCK_SIZE
+	                  ? $v_size : ARCHIVE_ZIP_READ_BLOCK_SIZE);
+      $v_buffer = @fread($v_zip_temp_fd, $v_read_size);
+      @fwrite($this->_zip_fd, $v_buffer, $v_read_size);
+      $v_size -= $v_read_size;
+    }
+
+    // ----- Create the Central Dir files header
+    for ($i=0, $v_count=0; $i<sizeof($v_header_list); $i++)
+    {
+      // ----- Create the file header
+      if ($v_header_list[$i]['status'] == 'ok') {
+        if (($v_result=$this->_writeCentralFileHeader($v_header_list[$i]))!=1) {
+          fclose($v_zip_temp_fd);
+          $this->_closeFd();
+          @unlink($v_zip_temp_name);
+
+          // ----- Return
+          return $v_result;
+        }
+        $v_count++;
+      }
+
+      // ----- Transform the header to a 'usable' info
+      $this->_convertHeader2FileInfo($v_header_list[$i], $p_result_list[$i]);
+    }
+
+    // ----- Zip file comment
+    $v_comment = '';
+
+    // ----- Calculate the size of the central header
+    $v_size = @ftell($this->_zip_fd)-$v_offset;
+
+    // ----- Create the central dir footer
+    if (($v_result = $this->_writeCentralHeader($v_count
+	                                              +$v_central_dir['entries'],
+	                                            $v_size, $v_offset,
+												$v_comment)) != 1) {
+      // ----- Reset the file list
+      unset($v_header_list);
+
+      // ----- Return
+      return $v_result;
+    }
+
+    // ----- Swap back the file descriptor
+    $v_swap = $this->_zip_fd;
+    $this->_zip_fd = $v_zip_temp_fd;
+    $v_zip_temp_fd = $v_swap;
+
+    // ----- Close
+    $this->_closeFd();
+
+    // ----- Close the temporary file
+    @fclose($v_zip_temp_fd);
+
+    // ----- Delete the zip file
+    // TBC : I should test the result ...
+    @unlink($this->_zipname);
+
+    // ----- Rename the temporary file
+    // TBC : I should test the result ...
+    //@rename($v_zip_temp_name, $this->_zipname);
+    $this->_tool_Rename($v_zip_temp_name, $this->_zipname);
+
+    // ----- Return
+    return $v_result;
+  }
+  // ---------------------------------------------------------------------------
+
+  // ---------------------------------------------------------------------------
+  // Function : _openFd()
+  // Description :
+  // Parameters :
+  // ---------------------------------------------------------------------------
+  /**
+  * Archive_Zip::_openFd()
+  *
+  * { Description }
+  *
+  */
+  function _openFd($p_mode)
+  {
+    $v_result=1;
+
+    // ----- Look if already open
+    if ($this->_zip_fd != 0)
+    {
+      $this->_errorLog(ARCHIVE_ZIP_ERR_READ_OPEN_FAIL,
+	                   'Zip file \''.$this->_zipname.'\' already open');
+      return Archive_Zip::errorCode();
+    }
+
+    // ----- Open the zip file
+    if (($this->_zip_fd = @fopen($this->_zipname, $p_mode)) == 0)
+    {
+      $this->_errorLog(ARCHIVE_ZIP_ERR_READ_OPEN_FAIL,
+	                   'Unable to open archive \''.$this->_zipname
+					   .'\' in '.$p_mode.' mode');
+      return Archive_Zip::errorCode();
+    }
+
+    // ----- Return
+    return $v_result;
+  }
+  // ---------------------------------------------------------------------------
+
+  // ---------------------------------------------------------------------------
+  // Function : _closeFd()
+  // Description :
+  // Parameters :
+  // ---------------------------------------------------------------------------
+  /**
+  * Archive_Zip::_closeFd()
+  *
+  * { Description }
+  *
+  */
+  function _closeFd()
+  {
+    $v_result=1;
+
+    if ($this->_zip_fd != 0)
+      @fclose($this->_zip_fd);
+    $this->_zip_fd = 0;
+
+    // ----- Return
+    return $v_result;
+  }
+  // ---------------------------------------------------------------------------
+
+  // ---------------------------------------------------------------------------
+  // Function : _addList()
+  // Description :
+  //   $p_add_dir and $p_remove_dir will give the ability to memorize a path which is
+  //   different from the real path of the file. This is usefull if you want to have PclTar
+  //   running in any directory, and memorize relative path from an other directory.
+  // Parameters :
+  //   $p_list : An array containing the file or directory names to add in the tar
+  //   $p_result_list : list of added files with their properties (specially the status field)
+  //   $p_add_dir : Path to add in the filename path archived
+  //   $p_remove_dir : Path to remove in the filename path archived
+  // Return Values :
+  // ---------------------------------------------------------------------------
+  /**
+  * Archive_Zip::_addList()
+  *
+  * { Description }
+  *
+  */
+  function _addList($p_list, &$p_result_list,
+                    $p_add_dir, $p_remove_dir, $p_remove_all_dir, &$p_params)
+  {
+    $v_result=1;
+
+    // ----- Add the files
+    $v_header_list = array();
+    if (($v_result = $this->_addFileList($p_list, $v_header_list,
+	                                     $p_add_dir, $p_remove_dir,
+										 $p_remove_all_dir, $p_params)) != 1) {
+      return $v_result;
+    }
+
+    // ----- Store the offset of the central dir
+    $v_offset = @ftell($this->_zip_fd);
+
+    // ----- Create the Central Dir files header
+    for ($i=0,$v_count=0; $i<sizeof($v_header_list); $i++)
+    {
+      // ----- Create the file header
+      if ($v_header_list[$i]['status'] == 'ok') {
+        if (($v_result = $this->_writeCentralFileHeader($v_header_list[$i])) != 1) {
+          return $v_result;
+        }
+        $v_count++;
+      }
+
+      // ----- Transform the header to a 'usable' info
+      $this->_convertHeader2FileInfo($v_header_list[$i], $p_result_list[$i]);
+    }
+
+    // ----- Zip file comment
+    $v_comment = '';
+
+    // ----- Calculate the size of the central header
+    $v_size = @ftell($this->_zip_fd)-$v_offset;
+
+    // ----- Create the central dir footer
+    if (($v_result = $this->_writeCentralHeader($v_count, $v_size, $v_offset,
+	                                            $v_comment)) != 1)
+    {
+      // ----- Reset the file list
+      unset($v_header_list);
+
+      // ----- Return
+      return $v_result;
+    }
+
+    // ----- Return
+    return $v_result;
+  }
+  // ---------------------------------------------------------------------------
+
+  // ---------------------------------------------------------------------------
+  // Function : _addFileList()
+  // Description :
+  //   $p_add_dir and $p_remove_dir will give the ability to memorize a path which is
+  //   different from the real path of the file. This is usefull if you want to
+  //   run the lib in any directory, and memorize relative path from an other directory.
+  // Parameters :
+  //   $p_list : An array containing the file or directory names to add in the tar
+  //   $p_result_list : list of added files with their properties (specially the status field)
+  //   $p_add_dir : Path to add in the filename path archived
+  //   $p_remove_dir : Path to remove in the filename path archived
+  // Return Values :
+  // ---------------------------------------------------------------------------
+  /**
+  * Archive_Zip::_addFileList()
+  *
+  * { Description }
+  *
+  */
+  function _addFileList($p_list, &$p_result_list,
+                        $p_add_dir, $p_remove_dir, $p_remove_all_dir,
+						&$p_params)
+  {
+    $v_result=1;
+    $v_header = array();
+
+    // ----- Recuperate the current number of elt in list
+    $v_nb = sizeof($p_result_list);
+
+    // ----- Loop on the files
+    for ($j=0; ($j<count($p_list)) && ($v_result==1); $j++)
+    {
+      // ----- Recuperate the filename
+      $p_filename = $this->_tool_TranslateWinPath($p_list[$j], false);
+
+      // ----- Skip empty file names
+      if ($p_filename == "")
+      {
+        continue;
+      }
+
+      // ----- Check the filename
+      if (!file_exists($p_filename))
+      {
+        $this->_errorLog(ARCHIVE_ZIP_ERR_MISSING_FILE,
+		                 "File '$p_filename' does not exists");
+        return Archive_Zip::errorCode();
+      }
+
+      // ----- Look if it is a file or a dir with no all pathnre move
+      if ((is_file($p_filename)) || ((is_dir($p_filename)) && !$p_remove_all_dir)) {
+        // ----- Add the file
+        if (($v_result = $this->_addFile($p_filename, $v_header, $p_add_dir, $p_remove_dir, $p_remove_all_dir, $p_params)) != 1)
+        {
+          // ----- Return status
+          return $v_result;
+        }
+
+        // ----- Store the file infos
+        $p_result_list[$v_nb++] = $v_header;
+      }
+
+      // ----- Look for directory
+      if (is_dir($p_filename))
+      {
+
+        // ----- Look for path
+        if ($p_filename != ".")
+          $v_path = $p_filename."/";
+        else
+          $v_path = "";
+
+        // ----- Read the directory for files and sub-directories
+        $p_hdir = opendir($p_filename);
+        $p_hitem = readdir($p_hdir); // '.' directory
+        $p_hitem = readdir($p_hdir); // '..' directory
+        while ($p_hitem = readdir($p_hdir))
+        {
+
+          // ----- Look for a file
+          if (is_file($v_path.$p_hitem))
+          {
+
+            // ----- Add the file
+            if (($v_result = $this->_addFile($v_path.$p_hitem, $v_header, $p_add_dir, $p_remove_dir, $p_remove_all_dir, $p_params)) != 1)
+            {
+              // ----- Return status
+              return $v_result;
+            }
+
+            // ----- Store the file infos
+            $p_result_list[$v_nb++] = $v_header;
+          }
+
+          // ----- Recursive call to _addFileList()
+          else
+          {
+
+            // ----- Need an array as parameter
+            $p_temp_list[0] = $v_path.$p_hitem;
+            $v_result = $this->_addFileList($p_temp_list, $p_result_list, $p_add_dir, $p_remove_dir, $p_remove_all_dir, $p_params);
+
+            // ----- Update the number of elements of the list
+            $v_nb = sizeof($p_result_list);
+          }
+        }
+
+        // ----- Free memory for the recursive loop
+        unset($p_temp_list);
+        unset($p_hdir);
+        unset($p_hitem);
+      }
+    }
+
+    return $v_result;
+  }
+  // ---------------------------------------------------------------------------
+
+  // ---------------------------------------------------------------------------
+  // Function : _addFile()
+  // Description :
+  // Parameters :
+  // Return Values :
+  // ---------------------------------------------------------------------------
+  /**
+  * Archive_Zip::_addFile()
+  *
+  * { Description }
+  *
+  */
+  function _addFile($p_filename, &$p_header, $p_add_dir, $p_remove_dir, $p_remove_all_dir, &$p_params)
+  {
+    $v_result=1;
+
+    if ($p_filename == "")
+    {
+      // ----- Error log
+      $this->_errorLog(ARCHIVE_ZIP_ERR_INVALID_PARAMETER, "Invalid file list parameter (invalid or empty list)");
+
+      // ----- Return
+      return Archive_Zip::errorCode();
+    }
+
+    // ----- Calculate the stored filename
+    $v_stored_filename = $p_filename;
+
+    // ----- Look for all path to remove
+    if ($p_remove_all_dir) {
+      $v_stored_filename = basename($p_filename);
+    }
+    // ----- Look for partial path remove
+    else if ($p_remove_dir != "")
+    {
+      $p_remove_dir = $this->_tool_TranslateWinPath($p_remove_dir, false);
+    	
+      if (substr($p_remove_dir, -1) != '/')
+        $p_remove_dir .= "/";
+
+      if ((substr($p_filename, 0, 2) == "./") || (substr($p_remove_dir, 0, 2) == "./"))
+      {
+        if ((substr($p_filename, 0, 2) == "./") && (substr($p_remove_dir, 0, 2) != "./"))
+          $p_remove_dir = "./".$p_remove_dir;
+        if ((substr($p_filename, 0, 2) != "./") && (substr($p_remove_dir, 0, 2) == "./"))
+          $p_remove_dir = substr($p_remove_dir, 2);
+      }
+
+      $v_compare = $this->_tool_PathInclusion($p_remove_dir, $p_filename);
+      if ($v_compare > 0)
+//      if (substr($p_filename, 0, strlen($p_remove_dir)) == $p_remove_dir)
+      {
+
+        if ($v_compare == 2) {
+          $v_stored_filename = "";
+        }
+        else {
+          $v_stored_filename = substr($p_filename, strlen($p_remove_dir));
+        }
+      }
+    }
+    // ----- Look for path to add
+    if ($p_add_dir != "")
+    {
+      if (substr($p_add_dir, -1) == "/")
+        $v_stored_filename = $p_add_dir.$v_stored_filename;
+      else
+        $v_stored_filename = $p_add_dir."/".$v_stored_filename;
+    }
+
+    // ----- Filename (reduce the path of stored name)
+    $v_stored_filename = $this->_tool_PathReduction($v_stored_filename);
+
+
+    /* filename length moved after call-back in release 1.3
+    // ----- Check the path length
+    if (strlen($v_stored_filename) > 0xFF)
+    {
+      // ----- Error log
+      $this->_errorLog(-5, "Stored file name is too long (max. 255) : '$v_stored_filename'");
+
+      // ----- Return
+      return Archive_Zip::errorCode();
+    }
+    */
+
+    // ----- Set the file properties
+    clearstatcache();
+    $p_header['version'] = 20;
+    $p_header['version_extracted'] = 10;
+    $p_header['flag'] = 0;
+    $p_header['compression'] = 0;
+    $p_header['mtime'] = filemtime($p_filename);
+    $p_header['crc'] = 0;
+    $p_header['compressed_size'] = 0;
+    $p_header['size'] = filesize($p_filename);
+    $p_header['filename_len'] = strlen($p_filename);
+    $p_header['extra_len'] = 0;
+    $p_header['comment_len'] = 0;
+    $p_header['disk'] = 0;
+    $p_header['internal'] = 0;
+    $p_header['external'] = (is_file($p_filename)?0xFE49FFE0:0x41FF0010);
+    $p_header['offset'] = 0;
+    $p_header['filename'] = $p_filename;
+    $p_header['stored_filename'] = $v_stored_filename;
+    $p_header['extra'] = '';
+    $p_header['comment'] = '';
+    $p_header['status'] = 'ok';
+    $p_header['index'] = -1;
+
+    // ----- Look for pre-add callback
+    if (   (isset($p_params[ARCHIVE_ZIP_PARAM_PRE_ADD]))
+	    && ($p_params[ARCHIVE_ZIP_PARAM_PRE_ADD] != '')) {
+
+      // ----- Generate a local information
+      $v_local_header = array();
+      $this->_convertHeader2FileInfo($p_header, $v_local_header);
+
+      // ----- Call the callback
+      // Here I do not use call_user_func() because I need to send a reference to the
+      // header.
+      eval('$v_result = '.$p_params[ARCHIVE_ZIP_PARAM_PRE_ADD].'(ARCHIVE_ZIP_PARAM_PRE_ADD, $v_local_header);');
+      if ($v_result == 0) {
+        // ----- Change the file status
+        $p_header['status'] = "skipped";
+        $v_result = 1;
+      }
+
+      // ----- Update the informations
+      // Only some fields can be modified
+      if ($p_header['stored_filename'] != $v_local_header['stored_filename']) {
+        $p_header['stored_filename'] = $this->_tool_PathReduction($v_local_header['stored_filename']);
+      }
+    }
+
+    // ----- Look for empty stored filename
+    if ($p_header['stored_filename'] == "") {
+      $p_header['status'] = "filtered";
+    }
+
+    // ----- Check the path length
+    if (strlen($p_header['stored_filename']) > 0xFF) {
+      $p_header['status'] = 'filename_too_long';
+    }
+
+    // ----- Look if no error, or file not skipped
+    if ($p_header['status'] == 'ok') {
+
+      // ----- Look for a file
+      if (is_file($p_filename))
+      {
+        // ----- Open the source file
+        if (($v_file = @fopen($p_filename, "rb")) == 0) {
+          $this->_errorLog(ARCHIVE_ZIP_ERR_READ_OPEN_FAIL, "Unable to open file '$p_filename' in binary read mode");
+          return Archive_Zip::errorCode();
+        }
+        
+        if ($p_params['no_compression']) {
+          // ----- Read the file content
+          $v_content_compressed = @fread($v_file, $p_header['size']);
+
+          // ----- Calculate the CRC
+          $p_header['crc'] = crc32($v_content_compressed);
+        }
+        else {
+          // ----- Read the file content
+          $v_content = @fread($v_file, $p_header['size']);
+
+          // ----- Calculate the CRC
+          $p_header['crc'] = crc32($v_content);
+
+          // ----- Compress the file
+          $v_content_compressed = gzdeflate($v_content);
+        }
+
+        // ----- Set header parameters
+        $p_header['compressed_size'] = strlen($v_content_compressed);
+        $p_header['compression'] = 8;
+
+        // ----- Call the header generation
+        if (($v_result = $this->_writeFileHeader($p_header)) != 1) {
+          @fclose($v_file);
+          return $v_result;
+        }
+
+        // ----- Write the compressed content
+        $v_binary_data = pack('a'.$p_header['compressed_size'], $v_content_compressed);
+        @fwrite($this->_zip_fd, $v_binary_data, $p_header['compressed_size']);
+
+        // ----- Close the file
+        @fclose($v_file);
+      }
+
+      // ----- Look for a directory
+      else
+      {
+        // ----- Set the file properties
+        $p_header['filename'] .= '/';
+        $p_header['filename_len']++;
+        $p_header['size'] = 0;
+        $p_header['external'] = 0x41FF0010;   // Value for a folder : to be checked
+
+        // ----- Call the header generation
+        if (($v_result = $this->_writeFileHeader($p_header)) != 1)
+        {
+          return $v_result;
+        }
+      }
+    }
+
+    // ----- Look for pre-add callback
+    if (   (isset($p_params[ARCHIVE_ZIP_PARAM_POST_ADD]))
+	    && ($p_params[ARCHIVE_ZIP_PARAM_POST_ADD] != '')) {
+
+      // ----- Generate a local information
+      $v_local_header = array();
+      $this->_convertHeader2FileInfo($p_header, $v_local_header);
+
+      // ----- Call the callback
+      // Here I do not use call_user_func() because I need to send a reference to the
+      // header.
+      eval('$v_result = '.$p_params[ARCHIVE_ZIP_PARAM_POST_ADD].'(ARCHIVE_ZIP_PARAM_POST_ADD, $v_local_header);');
+      if ($v_result == 0) {
+        // ----- Ignored
+        $v_result = 1;
+      }
+
+      // ----- Update the informations
+      // Nothing can be modified
+    }
+
+    // ----- Return
+    return $v_result;
+  }
+  // ---------------------------------------------------------------------------
+
+  // ---------------------------------------------------------------------------
+  // Function : _writeFileHeader()
+  // Description :
+  // Parameters :
+  // Return Values :
+  // ---------------------------------------------------------------------------
+  /**
+  * Archive_Zip::_writeFileHeader()
+  *
+  * { Description }
+  *
+  */
+  function _writeFileHeader(&$p_header)
+  {
+    $v_result=1;
+
+    // TBC
+    //for(reset($p_header); $key = key($p_header); next($p_header)) {
+    //}
+
+    // ----- Store the offset position of the file
+    $p_header['offset'] = ftell($this->_zip_fd);
+
+    // ----- Transform UNIX mtime to DOS format mdate/mtime
+    $v_date = getdate($p_header['mtime']);
+    $v_mtime = ($v_date['hours']<<11) + ($v_date['minutes']<<5) + $v_date['seconds']/2;
+    $v_mdate = (($v_date['year']-1980)<<9) + ($v_date['mon']<<5) + $v_date['mday'];
+
+    // ----- Packed data
+    $v_binary_data = pack("VvvvvvVVVvv", 0x04034b50, $p_header['version'], $p_header['flag'],
+                          $p_header['compression'], $v_mtime, $v_mdate,
+                          $p_header['crc'], $p_header['compressed_size'], $p_header['size'],
+                          strlen($p_header['stored_filename']), $p_header['extra_len']);
+
+    // ----- Write the first 148 bytes of the header in the archive
+    fputs($this->_zip_fd, $v_binary_data, 30);
+
+    // ----- Write the variable fields
+    if (strlen($p_header['stored_filename']) != 0)
+    {
+      fputs($this->_zip_fd, $p_header['stored_filename'], strlen($p_header['stored_filename']));
+    }
+    if ($p_header['extra_len'] != 0)
+    {
+      fputs($this->_zip_fd, $p_header['extra'], $p_header['extra_len']);
+    }
+
+    // ----- Return
+    return $v_result;
+  }
+  // ---------------------------------------------------------------------------
+
+  // ---------------------------------------------------------------------------
+  // Function : _writeCentralFileHeader()
+  // Description :
+  // Parameters :
+  // Return Values :
+  // ---------------------------------------------------------------------------
+  /**
+  * Archive_Zip::_writeCentralFileHeader()
+  *
+  * { Description }
+  *
+  */
+  function _writeCentralFileHeader(&$p_header)
+  {
+    $v_result=1;
+
+    // TBC
+    //for(reset($p_header); $key = key($p_header); next($p_header)) {
+    //}
+
+    // ----- Transform UNIX mtime to DOS format mdate/mtime
+    $v_date = getdate($p_header['mtime']);
+    $v_mtime = ($v_date['hours']<<11) + ($v_date['minutes']<<5) + $v_date['seconds']/2;
+    $v_mdate = (($v_date['year']-1980)<<9) + ($v_date['mon']<<5) + $v_date['mday'];
+
+    // ----- Packed data
+    $v_binary_data = pack("VvvvvvvVVVvvvvvVV", 0x02014b50, $p_header['version'], $p_header['version_extracted'],
+                          $p_header['flag'], $p_header['compression'], $v_mtime, $v_mdate, $p_header['crc'],
+                          $p_header['compressed_size'], $p_header['size'],
+                          strlen($p_header['stored_filename']), $p_header['extra_len'], $p_header['comment_len'],
+                          $p_header['disk'], $p_header['internal'], $p_header['external'], $p_header['offset']);
+
+    // ----- Write the 42 bytes of the header in the zip file
+    fputs($this->_zip_fd, $v_binary_data, 46);
+
+    // ----- Write the variable fields
+    if (strlen($p_header['stored_filename']) != 0)
+    {
+      fputs($this->_zip_fd, $p_header['stored_filename'], strlen($p_header['stored_filename']));
+    }
+    if ($p_header['extra_len'] != 0)
+    {
+      fputs($this->_zip_fd, $p_header['extra'], $p_header['extra_len']);
+    }
+    if ($p_header['comment_len'] != 0)
+    {
+      fputs($this->_zip_fd, $p_header['comment'], $p_header['comment_len']);
+    }
+
+    // ----- Return
+    return $v_result;
+  }
+  // ---------------------------------------------------------------------------
+
+  // ---------------------------------------------------------------------------
+  // Function : _writeCentralHeader()
+  // Description :
+  // Parameters :
+  // Return Values :
+  // ---------------------------------------------------------------------------
+  /**
+  * Archive_Zip::_writeCentralHeader()
+  *
+  * { Description }
+  *
+  */
+  function _writeCentralHeader($p_nb_entries, $p_size, $p_offset, $p_comment)
+  {
+    $v_result=1;
+
+    // ----- Packed data
+    $v_binary_data = pack("VvvvvVVv", 0x06054b50, 0, 0, $p_nb_entries, $p_nb_entries, $p_size, $p_offset, strlen($p_comment));
+
+    // ----- Write the 22 bytes of the header in the zip file
+    fputs($this->_zip_fd, $v_binary_data, 22);
+
+    // ----- Write the variable fields
+    if (strlen($p_comment) != 0)
+    {
+      fputs($this->_zip_fd, $p_comment, strlen($p_comment));
+    }
+
+    // ----- Return
+    return $v_result;
+  }
+  // ---------------------------------------------------------------------------
+
+  // ---------------------------------------------------------------------------
+  // Function : _list()
+  // Description :
+  // Parameters :
+  // Return Values :
+  // ---------------------------------------------------------------------------
+  /**
+  * Archive_Zip::_list()
+  *
+  * { Description }
+  *
+  */
+  function _list(&$p_list)
+  {
+    $v_result=1;
+
+    // ----- Open the zip file
+    if (($this->_zip_fd = @fopen($this->_zipname, 'rb')) == 0)
+    {
+      // ----- Error log
+      $this->_errorLog(ARCHIVE_ZIP_ERR_READ_OPEN_FAIL, 'Unable to open archive \''.$this->_zipname.'\' in binary read mode');
+
+      // ----- Return
+      return Archive_Zip::errorCode();
+    }
+
+    // ----- Read the central directory informations
+    $v_central_dir = array();
+    if (($v_result = $this->_readEndCentralDir($v_central_dir)) != 1)
+    {
+      return $v_result;
+    }
+
+    // ----- Go to beginning of Central Dir
+    @rewind($this->_zip_fd);
+    if (@fseek($this->_zip_fd, $v_central_dir['offset']))
+    {
+      // ----- Error log
+      $this->_errorLog(ARCHIVE_ZIP_ERR_INVALID_ARCHIVE_ZIP, 'Invalid archive size');
+
+      // ----- Return
+      return Archive_Zip::errorCode();
+    }
+
+    // ----- Read each entry
+    for ($i=0; $i<$v_central_dir['entries']; $i++)
+    {
+      // ----- Read the file header
+      if (($v_result = $this->_readCentralFileHeader($v_header)) != 1)
+      {
+        return $v_result;
+      }
+      $v_header['index'] = $i;
+
+      // ----- Get the only interesting attributes
+      $this->_convertHeader2FileInfo($v_header, $p_list[$i]);
+      unset($v_header);
+    }
+
+    // ----- Close the zip file
+    $this->_closeFd();
+
+    // ----- Return
+    return $v_result;
+  }
+  // ---------------------------------------------------------------------------
+
+  // ---------------------------------------------------------------------------
+  // Function : _convertHeader2FileInfo()
+  // Description :
+  //   This function takes the file informations from the central directory
+  //   entries and extract the interesting parameters that will be given back.
+  //   The resulting file infos are set in the array $p_info
+  //     $p_info['filename'] : Filename with full path. Given by user (add),
+  //                           extracted in the filesystem (extract).
+  //     $p_info['stored_filename'] : Stored filename in the archive.
+  //     $p_info['size'] = Size of the file.
+  //     $p_info['compressed_size'] = Compressed size of the file.
+  //     $p_info['mtime'] = Last modification date of the file.
+  //     $p_info['comment'] = Comment associated with the file.
+  //     $p_info['folder'] = true/false : indicates if the entry is a folder or not.
+  //     $p_info['status'] = status of the action on the file.
+  // Parameters :
+  // Return Values :
+  // ---------------------------------------------------------------------------
+  /**
+  * Archive_Zip::_convertHeader2FileInfo()
+  *
+  * { Description }
+  *
+  */
+  function _convertHeader2FileInfo($p_header, &$p_info)
+  {
+    $v_result=1;
+
+    // ----- Get the interesting attributes
+    $p_info['filename'] = $p_header['filename'];
+    $p_info['stored_filename'] = $p_header['stored_filename'];
+    $p_info['size'] = $p_header['size'];
+    $p_info['compressed_size'] = $p_header['compressed_size'];
+    $p_info['mtime'] = $p_header['mtime'];
+    $p_info['comment'] = $p_header['comment'];
+    $p_info['folder'] = (($p_header['external']&0x00000010)==0x00000010);
+    $p_info['index'] = $p_header['index'];
+    $p_info['status'] = $p_header['status'];
+
+    // ----- Return
+    return $v_result;
+  }
+  // ---------------------------------------------------------------------------
+
+  // ---------------------------------------------------------------------------
+  // Function : _extractByRule()
+  // Description :
+  //   Extract a file or directory depending of rules (by index, by name, ...)
+  // Parameters :
+  //   $p_file_list : An array where will be placed the properties of each
+  //                  extracted file
+  //   $p_path : Path to add while writing the extracted files
+  //   $p_remove_path : Path to remove (from the file memorized path) while writing the
+  //                    extracted files. If the path does not match the file path,
+  //                    the file is extracted with its memorized path.
+  //                    $p_remove_path does not apply to 'list' mode.
+  //                    $p_path and $p_remove_path are commulative.
+  // Return Values :
+  //   1 on success,0 or less on error (see error code list)
+  // ---------------------------------------------------------------------------
+  /**
+  * Archive_Zip::_extractByRule()
+  *
+  * { Description }
+  *
+  */
+  function _extractByRule(&$p_file_list, &$p_params)
+  {
+    $v_result=1;
+
+	$p_path = $p_params['add_path'];
+	$p_remove_path = $p_params['remove_path'];
+	$p_remove_all_path = $p_params['remove_all_path'];
+
+    // ----- Check the path
+    if (($p_path == "")
+	    || ((substr($p_path, 0, 1) != "/")
+	    && (substr($p_path, 0, 3) != "../") && (substr($p_path,1,2)!=":/")))
+      $p_path = "./".$p_path;
+
+    // ----- Reduce the path last (and duplicated) '/'
+    if (($p_path != "./") && ($p_path != "/")) {
+      // ----- Look for the path end '/'
+      while (substr($p_path, -1) == "/") {
+        $p_path = substr($p_path, 0, strlen($p_path)-1);
+      }
+    }
+
+    // ----- Look for path to remove format (should end by /)
+    if (($p_remove_path != "") && (substr($p_remove_path, -1) != '/')) {
+      $p_remove_path .= '/';
+    }
+    $p_remove_path_size = strlen($p_remove_path);
+
+    // ----- Open the zip file
+    if (($v_result = $this->_openFd('rb')) != 1)
+    {
+      return $v_result;
+    }
+
+    // ----- Read the central directory informations
+    $v_central_dir = array();
+    if (($v_result = $this->_readEndCentralDir($v_central_dir)) != 1)
+    {
+      // ----- Close the zip file
+      $this->_closeFd();
+
+      return $v_result;
+    }
+
+    // ----- Start at beginning of Central Dir
+    $v_pos_entry = $v_central_dir['offset'];
+
+    // ----- Read each entry
+    $j_start = 0;
+    for ($i=0, $v_nb_extracted=0; $i<$v_central_dir['entries']; $i++) {
+      // ----- Read next Central dir entry
+      @rewind($this->_zip_fd);
+      if (@fseek($this->_zip_fd, $v_pos_entry)) {
+        $this->_closeFd();
+
+        $this->_errorLog(ARCHIVE_ZIP_ERR_INVALID_ARCHIVE_ZIP,
+		                 'Invalid archive size');
+
+        return Archive_Zip::errorCode();
+      }
+
+      // ----- Read the file header
+      $v_header = array();
+      if (($v_result = $this->_readCentralFileHeader($v_header)) != 1) {
+        $this->_closeFd();
+
+        return $v_result;
+      }
+
+      // ----- Store the index
+      $v_header['index'] = $i;
+
+      // ----- Store the file position
+      $v_pos_entry = ftell($this->_zip_fd);
+
+      // ----- Look for the specific extract rules
+      $v_extract = false;
+
+      // ----- Look for extract by name rule
+      if (   (isset($p_params[ARCHIVE_ZIP_PARAM_BY_NAME]))
+          && ($p_params[ARCHIVE_ZIP_PARAM_BY_NAME] != 0)) {
+
+          // ----- Look if the filename is in the list
+          for ($j=0;
+		          ($j<sizeof($p_params[ARCHIVE_ZIP_PARAM_BY_NAME]))
+			   && (!$v_extract);
+			   $j++) {
+
+              // ----- Look for a directory
+              if (substr($p_params[ARCHIVE_ZIP_PARAM_BY_NAME][$j], -1) == "/") {
+
+                  // ----- Look if the directory is in the filename path
+                  if (   (strlen($v_header['stored_filename']) > strlen($p_params[ARCHIVE_ZIP_PARAM_BY_NAME][$j]))
+                      && (substr($v_header['stored_filename'], 0, strlen($p_params[ARCHIVE_ZIP_PARAM_BY_NAME][$j])) == $p_params[ARCHIVE_ZIP_PARAM_BY_NAME][$j])) {
+                      $v_extract = true;
+                  }
+              }
+              // ----- Look for a filename
+              elseif ($v_header['stored_filename'] == $p_params[ARCHIVE_ZIP_PARAM_BY_NAME][$j]) {
+                  $v_extract = true;
+              }
+          }
+      }
+
+      // ----- Look for extract by ereg rule
+      else if (   (isset($p_params[ARCHIVE_ZIP_PARAM_BY_EREG]))
+               && ($p_params[ARCHIVE_ZIP_PARAM_BY_EREG] != "")) {
+
+          if (ereg($p_params[ARCHIVE_ZIP_PARAM_BY_EREG], $v_header['stored_filename'])) {
+              $v_extract = true;
+          }
+      }
+
+      // ----- Look for extract by preg rule
+      else if (   (isset($p_params[ARCHIVE_ZIP_PARAM_BY_PREG]))
+               && ($p_params[ARCHIVE_ZIP_PARAM_BY_PREG] != "")) {
+
+          if (preg_match($p_params[ARCHIVE_ZIP_PARAM_BY_PREG], $v_header['stored_filename'])) {
+              $v_extract = true;
+          }
+      }
+
+      // ----- Look for extract by index rule
+      else if (   (isset($p_params[ARCHIVE_ZIP_PARAM_BY_INDEX]))
+               && ($p_params[ARCHIVE_ZIP_PARAM_BY_INDEX] != 0)) {
+
+          // ----- Look if the index is in the list
+          for ($j=$j_start; ($j<sizeof($p_params[ARCHIVE_ZIP_PARAM_BY_INDEX])) && (!$v_extract); $j++) {
+
+              if (($i>=$p_params[ARCHIVE_ZIP_PARAM_BY_INDEX][$j]['start']) && ($i<=$p_params[ARCHIVE_ZIP_PARAM_BY_INDEX][$j]['end'])) {
+                  $v_extract = true;
+              }
+              if ($i>=$p_params[ARCHIVE_ZIP_PARAM_BY_INDEX][$j]['end']) {
+                  $j_start = $j+1;
+              }
+
+              if ($p_params[ARCHIVE_ZIP_PARAM_BY_INDEX][$j]['start']>$i) {
+                  break;
+              }
+          }
+      }
+
+      // ----- Look for no rule, which means extract all the archive
+      else {
+          $v_extract = true;
+      }
+
+
+      // ----- Look for real extraction
+      if ($v_extract)
+      {
+
+        // ----- Go to the file position
+        @rewind($this->_zip_fd);
+        if (@fseek($this->_zip_fd, $v_header['offset']))
+        {
+          // ----- Close the zip file
+          $this->_closeFd();
+
+          // ----- Error log
+          $this->_errorLog(ARCHIVE_ZIP_ERR_INVALID_ARCHIVE_ZIP, 'Invalid archive size');
+
+          // ----- Return
+          return Archive_Zip::errorCode();
+        }
+
+        // ----- Look for extraction as string
+        if ($p_params[ARCHIVE_ZIP_PARAM_EXTRACT_AS_STRING]) {
+
+          // ----- Extracting the file
+          if (($v_result = $this->_extractFileAsString($v_header, $v_string)) != 1)
+          {
+            // ----- Close the zip file
+            $this->_closeFd();
+
+            return $v_result;
+          }
+
+          // ----- Get the only interesting attributes
+          if (($v_result = $this->_convertHeader2FileInfo($v_header, $p_file_list[$v_nb_extracted])) != 1)
+          {
+            // ----- Close the zip file
+            $this->_closeFd();
+
+            return $v_result;
+          }
+
+          // ----- Set the file content
+          $p_file_list[$v_nb_extracted]['content'] = $v_string;
+
+          // ----- Next extracted file
+          $v_nb_extracted++;
+        }
+        else {
+          // ----- Extracting the file
+          if (($v_result = $this->_extractFile($v_header, $p_path, $p_remove_path, $p_remove_all_path, $p_params)) != 1)
+          {
+            // ----- Close the zip file
+            $this->_closeFd();
+
+            return $v_result;
+          }
+
+          // ----- Get the only interesting attributes
+          if (($v_result = $this->_convertHeader2FileInfo($v_header, $p_file_list[$v_nb_extracted++])) != 1)
+          {
+            // ----- Close the zip file
+            $this->_closeFd();
+
+            return $v_result;
+          }
+        }
+      }
+    }
+
+    // ----- Close the zip file
+    $this->_closeFd();
+
+    // ----- Return
+    return $v_result;
+  }
+  // ---------------------------------------------------------------------------
+
+  // ---------------------------------------------------------------------------
+  // Function : _extractFile()
+  // Description :
+  // Parameters :
+  // Return Values :
+  // ---------------------------------------------------------------------------
+  /**
+  * Archive_Zip::_extractFile()
+  *
+  * { Description }
+  *
+  */
+  function _extractFile(&$p_entry, $p_path, $p_remove_path, $p_remove_all_path, &$p_params)
+  {
+    $v_result=1;
+
+    // ----- Read the file header
+    if (($v_result = $this->_readFileHeader($v_header)) != 1)
+    {
+      // ----- Return
+      return $v_result;
+    }
+
+
+    // ----- Check that the file header is coherent with $p_entry info
+    // TBC
+
+    // ----- Look for all path to remove
+    if ($p_remove_all_path == true) {
+        // ----- Get the basename of the path
+        $p_entry['filename'] = basename($p_entry['filename']);
+    }
+
+    // ----- Look for path to remove
+    else if ($p_remove_path != "")
+    {
+      //if (strcmp($p_remove_path, $p_entry['filename'])==0)
+      if ($this->_tool_PathInclusion($p_remove_path, $p_entry['filename']) == 2)
+      {
+
+        // ----- Change the file status
+        $p_entry['status'] = "filtered";
+
+        // ----- Return
+        return $v_result;
+      }
+
+      $p_remove_path_size = strlen($p_remove_path);
+      if (substr($p_entry['filename'], 0, $p_remove_path_size) == $p_remove_path)
+      {
+
+        // ----- Remove the path
+        $p_entry['filename'] = substr($p_entry['filename'], $p_remove_path_size);
+
+      }
+    }
+
+    // ----- Add the path
+    if ($p_path != '')
+    {
+      $p_entry['filename'] = $p_path."/".$p_entry['filename'];
+    }
+
+    // ----- Look for pre-extract callback
+    if (   (isset($p_params[ARCHIVE_ZIP_PARAM_PRE_EXTRACT]))
+	    && ($p_params[ARCHIVE_ZIP_PARAM_PRE_EXTRACT] != '')) {
+
+      // ----- Generate a local information
+      $v_local_header = array();
+      $this->_convertHeader2FileInfo($p_entry, $v_local_header);
+
+      // ----- Call the callback
+      // Here I do not use call_user_func() because I need to send a reference to the
+      // header.
+      eval('$v_result = '.$p_params[ARCHIVE_ZIP_PARAM_PRE_EXTRACT].'(ARCHIVE_ZIP_PARAM_PRE_EXTRACT, $v_local_header);');
+      if ($v_result == 0) {
+        // ----- Change the file status
+        $p_entry['status'] = "skipped";
+        $v_result = 1;
+      }
+
+      // ----- Update the informations
+      // Only some fields can be modified
+      $p_entry['filename'] = $v_local_header['filename'];
+    }
+
+    // ----- Trace
+
+    // ----- Look if extraction should be done
+    if ($p_entry['status'] == 'ok') {
+
+    // ----- Look for specific actions while the file exist
+    if (file_exists($p_entry['filename']))
+    {
+
+      // ----- Look if file is a directory
+      if (is_dir($p_entry['filename']))
+      {
+
+        // ----- Change the file status
+        $p_entry['status'] = "already_a_directory";
+
+        // ----- Return
+        //return $v_result;
+      }
+      // ----- Look if file is write protected
+      else if (!is_writeable($p_entry['filename']))
+      {
+
+        // ----- Change the file status
+        $p_entry['status'] = "write_protected";
+
+        // ----- Return
+        //return $v_result;
+      }
+
+      // ----- Look if the extracted file is older
+      else if (filemtime($p_entry['filename']) > $p_entry['mtime'])
+      {
+
+        // ----- Change the file status
+        $p_entry['status'] = "newer_exist";
+
+        // ----- Return
+        //return $v_result;
+      }
+    }
+
+    // ----- Check the directory availability and create it if necessary
+    else {
+      if ((($p_entry['external']&0x00000010)==0x00000010) || (substr($p_entry['filename'], -1) == '/'))
+        $v_dir_to_check = $p_entry['filename'];
+      else if (!strstr($p_entry['filename'], "/"))
+        $v_dir_to_check = "";
+      else
+        $v_dir_to_check = dirname($p_entry['filename']);
+
+      if (($v_result = $this->_dirCheck($v_dir_to_check, (($p_entry['external']&0x00000010)==0x00000010))) != 1) {
+
+        // ----- Change the file status
+        $p_entry['status'] = "path_creation_fail";
+
+        // ----- Return
+        //return $v_result;
+        $v_result = 1;
+      }
+    }
+    }
+
+    // ----- Look if extraction should be done
+    if ($p_entry['status'] == 'ok') {
+
+      // ----- Do the extraction (if not a folder)
+      if (!(($p_entry['external']&0x00000010)==0x00000010))
+      {
+
+        // ----- Look for not compressed file
+        if ($p_entry['compressed_size'] == $p_entry['size'])
+        {
+
+          // ----- Opening destination file
+          if (($v_dest_file = @fopen($p_entry['filename'], 'wb')) == 0)
+          {
+
+            // ----- Change the file status
+            $p_entry['status'] = "write_error";
+
+            // ----- Return
+            return $v_result;
+          }
+
+
+          // ----- Read the file by ARCHIVE_ZIP_READ_BLOCK_SIZE octets blocks
+          $v_size = $p_entry['compressed_size'];
+          while ($v_size != 0)
+          {
+            $v_read_size = ($v_size < ARCHIVE_ZIP_READ_BLOCK_SIZE ? $v_size : ARCHIVE_ZIP_READ_BLOCK_SIZE);
+            $v_buffer = fread($this->_zip_fd, $v_read_size);
+            $v_binary_data = pack('a'.$v_read_size, $v_buffer);
+            @fwrite($v_dest_file, $v_binary_data, $v_read_size);
+            $v_size -= $v_read_size;
+          }
+
+          // ----- Closing the destination file
+          fclose($v_dest_file);
+
+          // ----- Change the file mtime
+          touch($p_entry['filename'], $p_entry['mtime']);
+        }
+        else
+        {
+          // ----- Trace
+
+          // ----- Opening destination file
+          if (($v_dest_file = @fopen($p_entry['filename'], 'wb')) == 0) {
+
+            // ----- Change the file status
+            $p_entry['status'] = "write_error";
+
+            return $v_result;
+          }
+
+
+          // ----- Read the compressed file in a buffer (one shot)
+          $v_buffer = @fread($this->_zip_fd, $p_entry['compressed_size']);
+
+          // ----- Decompress the file
+          $v_file_content = gzinflate($v_buffer);
+          unset($v_buffer);
+
+          // ----- Write the uncompressed data
+          @fwrite($v_dest_file, $v_file_content, $p_entry['size']);
+          unset($v_file_content);
+
+          // ----- Closing the destination file
+          @fclose($v_dest_file);
+
+          // ----- Change the file mtime
+          touch($p_entry['filename'], $p_entry['mtime']);
+        }
+
+        // ----- Look for chmod option
+        if (   (isset($p_params[ARCHIVE_ZIP_PARAM_SET_CHMOD]))
+		    && ($p_params[ARCHIVE_ZIP_PARAM_SET_CHMOD] != 0)) {
+
+          // ----- Change the mode of the file
+          chmod($p_entry['filename'], $p_params[ARCHIVE_ZIP_PARAM_SET_CHMOD]);
+        }
+
+      }
+    }
+
+    // ----- Look for post-extract callback
+    if (   (isset($p_params[ARCHIVE_ZIP_PARAM_POST_EXTRACT]))
+	    && ($p_params[ARCHIVE_ZIP_PARAM_POST_EXTRACT] != '')) {
+
+      // ----- Generate a local information
+      $v_local_header = array();
+      $this->_convertHeader2FileInfo($p_entry, $v_local_header);
+
+      // ----- Call the callback
+      // Here I do not use call_user_func() because I need to send a reference to the
+      // header.
+      eval('$v_result = '.$p_params[ARCHIVE_ZIP_PARAM_POST_EXTRACT].'(ARCHIVE_ZIP_PARAM_POST_EXTRACT, $v_local_header);');
+    }
+
+    // ----- Return
+    return $v_result;
+  }
+  // ---------------------------------------------------------------------------
+
+  // ---------------------------------------------------------------------------
+  // Function : _extractFileAsString()
+  // Description :
+  // Parameters :
+  // Return Values :
+  // ---------------------------------------------------------------------------
+  /**
+  * Archive_Zip::_extractFileAsString()
+  *
+  * { Description }
+  *
+  */
+  function _extractFileAsString(&$p_entry, &$p_string)
+  {
+    $v_result=1;
+
+    // ----- Read the file header
+    $v_header = array();
+    if (($v_result = $this->_readFileHeader($v_header)) != 1)
+    {
+      // ----- Return
+      return $v_result;
+    }
+
+
+    // ----- Check that the file header is coherent with $p_entry info
+    // TBC
+
+    // ----- Trace
+
+    // ----- Do the extraction (if not a folder)
+    if (!(($p_entry['external']&0x00000010)==0x00000010))
+    {
+      // ----- Look for not compressed file
+      if ($p_entry['compressed_size'] == $p_entry['size'])
+      {
+        // ----- Trace
+
+        // ----- Reading the file
+        $p_string = fread($this->_zip_fd, $p_entry['compressed_size']);
+      }
+      else
+      {
+        // ----- Trace
+
+        // ----- Reading the file
+        $v_data = fread($this->_zip_fd, $p_entry['compressed_size']);
+
+        // ----- Decompress the file
+        $p_string = gzinflate($v_data);
+      }
+
+      // ----- Trace
+    }
+    else {
+        // TBC : error : can not extract a folder in a string
+    }
+
+    // ----- Return
+    return $v_result;
+  }
+  // ---------------------------------------------------------------------------
+
+  // ---------------------------------------------------------------------------
+  // Function : _readFileHeader()
+  // Description :
+  // Parameters :
+  // Return Values :
+  // ---------------------------------------------------------------------------
+  /**
+  * Archive_Zip::_readFileHeader()
+  *
+  * { Description }
+  *
+  */
+  function _readFileHeader(&$p_header)
+  {
+    $v_result=1;
+
+    // ----- Read the 4 bytes signature
+    $v_binary_data = @fread($this->_zip_fd, 4);
+    $v_data = unpack('Vid', $v_binary_data);
+
+    // ----- Check signature
+    if ($v_data['id'] != 0x04034b50)
+    {
+
+      // ----- Error log
+      $this->_errorLog(ARCHIVE_ZIP_ERR_BAD_FORMAT, 'Invalid archive structure');
+
+      // ----- Return
+      return Archive_Zip::errorCode();
+    }
+
+    // ----- Read the first 42 bytes of the header
+    $v_binary_data = fread($this->_zip_fd, 26);
+
+    // ----- Look for invalid block size
+    if (strlen($v_binary_data) != 26)
+    {
+      $p_header['filename'] = "";
+      $p_header['status'] = "invalid_header";
+
+      // ----- Error log
+      $this->_errorLog(ARCHIVE_ZIP_ERR_BAD_FORMAT, "Invalid block size : ".strlen($v_binary_data));
+
+      // ----- Return
+      return Archive_Zip::errorCode();
+    }
+
+    // ----- Extract the values
+    $v_data = unpack('vversion/vflag/vcompression/vmtime/vmdate/Vcrc/Vcompressed_size/Vsize/vfilename_len/vextra_len', $v_binary_data);
+
+    // ----- Get filename
+    $p_header['filename'] = fread($this->_zip_fd, $v_data['filename_len']);
+
+    // ----- Get extra_fields
+    if ($v_data['extra_len'] != 0) {
+      $p_header['extra'] = fread($this->_zip_fd, $v_data['extra_len']);
+    }
+    else {
+      $p_header['extra'] = '';
+    }
+
+    // ----- Extract properties
+    $p_header['compression'] = $v_data['compression'];
+    $p_header['size'] = $v_data['size'];
+    $p_header['compressed_size'] = $v_data['compressed_size'];
+    $p_header['crc'] = $v_data['crc'];
+    $p_header['flag'] = $v_data['flag'];
+
+    // ----- Recuperate date in UNIX format
+    $p_header['mdate'] = $v_data['mdate'];
+    $p_header['mtime'] = $v_data['mtime'];
+    if ($p_header['mdate'] && $p_header['mtime'])
+    {
+      // ----- Extract time
+      $v_hour = ($p_header['mtime'] & 0xF800) >> 11;
+      $v_minute = ($p_header['mtime'] & 0x07E0) >> 5;
+      $v_seconde = ($p_header['mtime'] & 0x001F)*2;
+
+      // ----- Extract date
+      $v_year = (($p_header['mdate'] & 0xFE00) >> 9) + 1980;
+      $v_month = ($p_header['mdate'] & 0x01E0) >> 5;
+      $v_day = $p_header['mdate'] & 0x001F;
+
+      // ----- Get UNIX date format
+      $p_header['mtime'] = mktime($v_hour, $v_minute, $v_seconde, $v_month, $v_day, $v_year);
+
+    }
+    else
+    {
+      $p_header['mtime'] = time();
+    }
+
+    // ----- Other informations
+
+    // TBC
+    //for(reset($v_data); $key = key($v_data); next($v_data)) {
+    //}
+
+    // ----- Set the stored filename
+    $p_header['stored_filename'] = $p_header['filename'];
+
+    // ----- Set the status field
+    $p_header['status'] = "ok";
+
+    // ----- Return
+    return $v_result;
+  }
+  // ---------------------------------------------------------------------------
+
+  // ---------------------------------------------------------------------------
+  // Function : _readCentralFileHeader()
+  // Description :
+  // Parameters :
+  // Return Values :
+  // ---------------------------------------------------------------------------
+  /**
+  * Archive_Zip::_readCentralFileHeader()
+  *
+  * { Description }
+  *
+  */
+  function _readCentralFileHeader(&$p_header)
+  {
+    $v_result=1;
+
+    // ----- Read the 4 bytes signature
+    $v_binary_data = @fread($this->_zip_fd, 4);
+    $v_data = unpack('Vid', $v_binary_data);
+
+    // ----- Check signature
+    if ($v_data['id'] != 0x02014b50)
+    {
+
+      // ----- Error log
+      $this->_errorLog(ARCHIVE_ZIP_ERR_BAD_FORMAT, 'Invalid archive structure');
+
+      // ----- Return
+      return Archive_Zip::errorCode();
+    }
+
+    // ----- Read the first 42 bytes of the header
+    $v_binary_data = fread($this->_zip_fd, 42);
+
+    // ----- Look for invalid block size
+    if (strlen($v_binary_data) != 42)
+    {
+      $p_header['filename'] = "";
+      $p_header['status'] = "invalid_header";
+
+      // ----- Error log
+      $this->_errorLog(ARCHIVE_ZIP_ERR_BAD_FORMAT, "Invalid block size : ".strlen($v_binary_data));
+
+      // ----- Return
+      return Archive_Zip::errorCode();
+    }
+
+    // ----- Extract the values
+    $p_header = unpack('vversion/vversion_extracted/vflag/vcompression/vmtime/vmdate/Vcrc/Vcompressed_size/Vsize/vfilename_len/vextra_len/vcomment_len/vdisk/vinternal/Vexternal/Voffset', $v_binary_data);
+
+    // ----- Get filename
+    if ($p_header['filename_len'] != 0)
+      $p_header['filename'] = fread($this->_zip_fd, $p_header['filename_len']);
+    else
+      $p_header['filename'] = '';
+
+    // ----- Get extra
+    if ($p_header['extra_len'] != 0)
+      $p_header['extra'] = fread($this->_zip_fd, $p_header['extra_len']);
+    else
+      $p_header['extra'] = '';
+
+    // ----- Get comment
+    if ($p_header['comment_len'] != 0)
+      $p_header['comment'] = fread($this->_zip_fd, $p_header['comment_len']);
+    else
+      $p_header['comment'] = '';
+
+    // ----- Extract properties
+
+    // ----- Recuperate date in UNIX format
+    if ($p_header['mdate'] && $p_header['mtime'])
+    {
+      // ----- Extract time
+      $v_hour = ($p_header['mtime'] & 0xF800) >> 11;
+      $v_minute = ($p_header['mtime'] & 0x07E0) >> 5;
+      $v_seconde = ($p_header['mtime'] & 0x001F)*2;
+
+      // ----- Extract date
+      $v_year = (($p_header['mdate'] & 0xFE00) >> 9) + 1980;
+      $v_month = ($p_header['mdate'] & 0x01E0) >> 5;
+      $v_day = $p_header['mdate'] & 0x001F;
+
+      // ----- Get UNIX date format
+      $p_header['mtime'] = mktime($v_hour, $v_minute, $v_seconde, $v_month, $v_day, $v_year);
+
+    }
+    else
+    {
+      $p_header['mtime'] = time();
+    }
+
+    // ----- Set the stored filename
+    $p_header['stored_filename'] = $p_header['filename'];
+
+    // ----- Set default status to ok
+    $p_header['status'] = 'ok';
+
+    // ----- Look if it is a directory
+    if (substr($p_header['filename'], -1) == '/')
+    {
+      $p_header['external'] = 0x41FF0010;
+    }
+
+
+    // ----- Return
+    return $v_result;
+  }
+  // ---------------------------------------------------------------------------
+
+  // ---------------------------------------------------------------------------
+  // Function : _readEndCentralDir()
+  // Description :
+  // Parameters :
+  // Return Values :
+  // ---------------------------------------------------------------------------
+  /**
+  * Archive_Zip::_readEndCentralDir()
+  *
+  * { Description }
+  *
+  */
+  function _readEndCentralDir(&$p_central_dir)
+  {
+    $v_result=1;
+
+    // ----- Go to the end of the zip file
+    $v_size = filesize($this->_zipname);
+    @fseek($this->_zip_fd, $v_size);
+    if (@ftell($this->_zip_fd) != $v_size) {
+      $this->_errorLog(ARCHIVE_ZIP_ERR_BAD_FORMAT,
+	                   'Unable to go to the end of the archive \''
+					   .$this->_zipname.'\'');
+      return Archive_Zip::errorCode();
+    }
+
+    // ----- First try : look if this is an archive with no commentaries
+	// (most of the time)
+    // in this case the end of central dir is at 22 bytes of the file end
+    $v_found = 0;
+    if ($v_size > 26) {
+      @fseek($this->_zip_fd, $v_size-22);
+      if (($v_pos = @ftell($this->_zip_fd)) != ($v_size-22)) {
+        $this->_errorLog(ARCHIVE_ZIP_ERR_BAD_FORMAT,
+		                 'Unable to seek back to the middle of the archive \''
+						 .$this->_zipname.'\'');
+        return Archive_Zip::errorCode();
+      }
+
+      // ----- Read for bytes
+      $v_binary_data = @fread($this->_zip_fd, 4);
+      $v_data = unpack('Vid', $v_binary_data);
+
+      // ----- Check signature
+      if ($v_data['id'] == 0x06054b50) {
+        $v_found = 1;
+      }
+
+      $v_pos = ftell($this->_zip_fd);
+    }
+
+    // ----- Go back to the maximum possible size of the Central Dir End Record
+    if (!$v_found) {
+      $v_maximum_size = 65557; // 0xFFFF + 22;
+      if ($v_maximum_size > $v_size)
+        $v_maximum_size = $v_size;
+      @fseek($this->_zip_fd, $v_size-$v_maximum_size);
+      if (@ftell($this->_zip_fd) != ($v_size-$v_maximum_size)) {
+        $this->_errorLog(ARCHIVE_ZIP_ERR_BAD_FORMAT,
+		                 'Unable to seek back to the middle of the archive \''
+						 .$this->_zipname.'\'');
+        return Archive_Zip::errorCode();
+      }
+
+      // ----- Read byte per byte in order to find the signature
+      $v_pos = ftell($this->_zip_fd);
+      $v_bytes = 0x00000000;
+      while ($v_pos < $v_size) {
+        // ----- Read a byte
+        $v_byte = @fread($this->_zip_fd, 1);
+
+        // -----  Add the byte
+        $v_bytes = ($v_bytes << 8) | Ord($v_byte);
+
+        // ----- Compare the bytes
+        if ($v_bytes == 0x504b0506) {
+          $v_pos++;
+          break;
+        }
+
+        $v_pos++;
+      }
+
+      // ----- Look if not found end of central dir
+      if ($v_pos == $v_size) {
+        $this->_errorLog(ARCHIVE_ZIP_ERR_BAD_FORMAT,
+		                 "Unable to find End of Central Dir Record signature");
+        return Archive_Zip::errorCode();
+      }
+    }
+
+    // ----- Read the first 18 bytes of the header
+    $v_binary_data = fread($this->_zip_fd, 18);
+
+    // ----- Look for invalid block size
+    if (strlen($v_binary_data) != 18) {
+      $this->_errorLog(ARCHIVE_ZIP_ERR_BAD_FORMAT,
+	                   "Invalid End of Central Dir Record size : "
+					   .strlen($v_binary_data));
+      return Archive_Zip::errorCode();
+    }
+
+    // ----- Extract the values
+    $v_data = unpack('vdisk/vdisk_start/vdisk_entries/ventries/Vsize/Voffset/vcomment_size', $v_binary_data);
+
+    // ----- Check the global size
+    if (($v_pos + $v_data['comment_size'] + 18) != $v_size) {
+      $this->_errorLog(ARCHIVE_ZIP_ERR_BAD_FORMAT,
+	                   "Fail to find the right signature");
+      return Archive_Zip::errorCode();
+    }
+
+    // ----- Get comment
+    if ($v_data['comment_size'] != 0)
+      $p_central_dir['comment'] = fread($this->_zip_fd, $v_data['comment_size']);
+    else
+      $p_central_dir['comment'] = '';
+
+    $p_central_dir['entries'] = $v_data['entries'];
+    $p_central_dir['disk_entries'] = $v_data['disk_entries'];
+    $p_central_dir['offset'] = $v_data['offset'];
+    $p_central_dir['size'] = $v_data['size'];
+    $p_central_dir['disk'] = $v_data['disk'];
+    $p_central_dir['disk_start'] = $v_data['disk_start'];
+
+    // ----- Return
+    return $v_result;
+  }
+  // ---------------------------------------------------------------------------
+
+  // ---------------------------------------------------------------------------
+  // Function : _deleteByRule()
+  // Description :
+  // Parameters :
+  // Return Values :
+  // ---------------------------------------------------------------------------
+  /**
+  * Archive_Zip::_deleteByRule()
+  *
+  * { Description }
+  *
+  */
+  function _deleteByRule(&$p_result_list, &$p_params)
+  {
+    $v_result=1;
+    $v_list_detail = array();
+
+    // ----- Open the zip file
+    if (($v_result=$this->_openFd('rb')) != 1)
+    {
+      // ----- Return
+      return $v_result;
+    }
+
+    // ----- Read the central directory informations
+    $v_central_dir = array();
+    if (($v_result = $this->_readEndCentralDir($v_central_dir)) != 1)
+    {
+      $this->_closeFd();
+      return $v_result;
+    }
+
+    // ----- Go to beginning of File
+    @rewind($this->_zip_fd);
+
+    // ----- Scan all the files
+    // ----- Start at beginning of Central Dir
+    $v_pos_entry = $v_central_dir['offset'];
+    @rewind($this->_zip_fd);
+    if (@fseek($this->_zip_fd, $v_pos_entry)) {
+      // ----- Clean
+      $this->_closeFd();
+
+      $this->_errorLog(ARCHIVE_ZIP_ERR_INVALID_ARCHIVE_ZIP,
+	                   'Invalid archive size');
+      return Archive_Zip::errorCode();
+    }
+
+    // ----- Read each entry
+    $v_header_list = array();
+    $j_start = 0;
+    for ($i=0, $v_nb_extracted=0; $i<$v_central_dir['entries']; $i++) {
+
+      // ----- Read the file header
+      $v_header_list[$v_nb_extracted] = array();
+      $v_result
+	    = $this->_readCentralFileHeader($v_header_list[$v_nb_extracted]);
+      if ($v_result != 1) {
+        // ----- Clean
+        $this->_closeFd();
+
+        return $v_result;
+      }
+
+      // ----- Store the index
+      $v_header_list[$v_nb_extracted]['index'] = $i;
+
+      // ----- Look for the specific extract rules
+      $v_found = false;
+
+      // ----- Look for extract by name rule
+      if (   (isset($p_params[ARCHIVE_ZIP_PARAM_BY_NAME]))
+          && ($p_params[ARCHIVE_ZIP_PARAM_BY_NAME] != 0)) {
+
+          // ----- Look if the filename is in the list
+          for ($j=0;
+		       ($j<sizeof($p_params[ARCHIVE_ZIP_PARAM_BY_NAME]))
+			     && (!$v_found);
+			   $j++) {
+
+              // ----- Look for a directory
+              if (substr($p_params[ARCHIVE_ZIP_PARAM_BY_NAME][$j], -1) == "/") {
+
+                  // ----- Look if the directory is in the filename path
+                  if (   (strlen($v_header_list[$v_nb_extracted]['stored_filename']) > strlen($p_params[ARCHIVE_ZIP_PARAM_BY_NAME][$j]))
+                      && (substr($v_header_list[$v_nb_extracted]['stored_filename'], 0, strlen($p_params[ARCHIVE_ZIP_PARAM_BY_NAME][$j])) == $p_params[ARCHIVE_ZIP_PARAM_BY_NAME][$j])) {
+                      $v_found = true;
+                  }
+                  elseif (   (($v_header_list[$v_nb_extracted]['external']&0x00000010)==0x00000010) /* Indicates a folder */
+                          && ($v_header_list[$v_nb_extracted]['stored_filename'].'/' == $p_params[ARCHIVE_ZIP_PARAM_BY_NAME][$j])) {
+                      $v_found = true;
+                  }
+              }
+              // ----- Look for a filename
+              elseif ($v_header_list[$v_nb_extracted]['stored_filename']
+			          == $p_params[ARCHIVE_ZIP_PARAM_BY_NAME][$j]) {
+                  $v_found = true;
+              }
+          }
+      }
+
+      // ----- Look for extract by ereg rule
+      else if (   (isset($p_params[ARCHIVE_ZIP_PARAM_BY_EREG]))
+               && ($p_params[ARCHIVE_ZIP_PARAM_BY_EREG] != "")) {
+
+          if (ereg($p_params[ARCHIVE_ZIP_PARAM_BY_EREG],
+		           $v_header_list[$v_nb_extracted]['stored_filename'])) {
+              $v_found = true;
+          }
+      }
+
+      // ----- Look for extract by preg rule
+      else if (   (isset($p_params[ARCHIVE_ZIP_PARAM_BY_PREG]))
+               && ($p_params[ARCHIVE_ZIP_PARAM_BY_PREG] != "")) {
+
+          if (preg_match($p_params[ARCHIVE_ZIP_PARAM_BY_PREG],
+		                 $v_header_list[$v_nb_extracted]['stored_filename'])) {
+              $v_found = true;
+          }
+      }
+
+      // ----- Look for extract by index rule
+      else if (   (isset($p_params[ARCHIVE_ZIP_PARAM_BY_INDEX]))
+               && ($p_params[ARCHIVE_ZIP_PARAM_BY_INDEX] != 0)) {
+
+          // ----- Look if the index is in the list
+          for ($j=$j_start;
+		       ($j<sizeof($p_params[ARCHIVE_ZIP_PARAM_BY_INDEX]))
+			     && (!$v_found);
+			   $j++) {
+
+              if (   ($i>=$p_params[ARCHIVE_ZIP_PARAM_BY_INDEX][$j]['start'])
+			      && ($i<=$p_params[ARCHIVE_ZIP_PARAM_BY_INDEX][$j]['end'])) {
+                  $v_found = true;
+              }
+              if ($i>=$p_params[ARCHIVE_ZIP_PARAM_BY_INDEX][$j]['end']) {
+                  $j_start = $j+1;
+              }
+
+              if ($p_params[ARCHIVE_ZIP_PARAM_BY_INDEX][$j]['start']>$i) {
+                  break;
+              }
+          }
+      }
+
+      // ----- Look for deletion
+      if ($v_found) {
+        unset($v_header_list[$v_nb_extracted]);
+      }
+      else {
+        $v_nb_extracted++;
+      }
+    }
+
+    // ----- Look if something need to be deleted
+    if ($v_nb_extracted > 0) {
+
+        // ----- Creates a temporay file
+        $v_zip_temp_name = ARCHIVE_ZIP_TEMPORARY_DIR.uniqid('archive_zip-')
+		                   .'.tmp';
+
+        // ----- Creates a temporary zip archive
+        $v_temp_zip = new Archive_Zip($v_zip_temp_name);
+
+        // ----- Open the temporary zip file in write mode
+        if (($v_result = $v_temp_zip->_openFd('wb')) != 1) {
+            $this->_closeFd();
+
+            // ----- Return
+            return $v_result;
+        }
+
+        // ----- Look which file need to be kept
+        for ($i=0; $i<sizeof($v_header_list); $i++) {
+
+            // ----- Calculate the position of the header
+            @rewind($this->_zip_fd);
+            if (@fseek($this->_zip_fd,  $v_header_list[$i]['offset'])) {
+                // ----- Clean
+                $this->_closeFd();
+                $v_temp_zip->_closeFd();
+                @unlink($v_zip_temp_name);
+
+                $this->_errorLog(ARCHIVE_ZIP_ERR_INVALID_ARCHIVE_ZIP,
+				                 'Invalid archive size');
+                return Archive_Zip::errorCode();
+            }
+
+            // ----- Read the file header
+            if (($v_result = $this->_readFileHeader($v_header_list[$i])) != 1) {
+                // ----- Clean
+                $this->_closeFd();
+                $v_temp_zip->_closeFd();
+                @unlink($v_zip_temp_name);
+
+                return $v_result;
+            }
+
+            // ----- Write the file header
+            $v_result = $v_temp_zip->_writeFileHeader($v_header_list[$i]);
+            if ($v_result != 1) {
+                // ----- Clean
+                $this->_closeFd();
+                $v_temp_zip->_closeFd();
+                @unlink($v_zip_temp_name);
+
+                return $v_result;
+            }
+
+            // ----- Read/write the data block
+            $v_result = $this->_tool_CopyBlock($this->_zip_fd,
+			                                   $v_temp_zip->_zip_fd,
+								       $v_header_list[$i]['compressed_size']);
+            if ($v_result != 1) {
+                // ----- Clean
+                $this->_closeFd();
+                $v_temp_zip->_closeFd();
+                @unlink($v_zip_temp_name);
+
+                return $v_result;
+            }
+        }
+
+        // ----- Store the offset of the central dir
+        $v_offset = @ftell($v_temp_zip->_zip_fd);
+
+        // ----- Re-Create the Central Dir files header
+        for ($i=0; $i<sizeof($v_header_list); $i++) {
+            // ----- Create the file header
+            $v_result=$v_temp_zip->_writeCentralFileHeader($v_header_list[$i]);
+            if ($v_result != 1) {
+            	// ----- Clean
+                $v_temp_zip->_closeFd();
+                $this->_closeFd();
+                @unlink($v_zip_temp_name);
+
+                return $v_result;
+            }
+
+            // ----- Transform the header to a 'usable' info
+            $v_temp_zip->_convertHeader2FileInfo($v_header_list[$i],
+			                                     $p_result_list[$i]);
+        }
+
+
+        // ----- Zip file comment
+        $v_comment = '';
+
+        // ----- Calculate the size of the central header
+        $v_size = @ftell($v_temp_zip->_zip_fd)-$v_offset;
+
+        // ----- Create the central dir footer
+        $v_result = $v_temp_zip->_writeCentralHeader(sizeof($v_header_list),
+		                                             $v_size, $v_offset,
+													 $v_comment);
+        if ($v_result != 1) {
+            // ----- Clean
+            unset($v_header_list);
+            $v_temp_zip->_closeFd();
+            $this->_closeFd();
+            @unlink($v_zip_temp_name);
+
+            return $v_result;
+        }
+
+        // ----- Close
+        $v_temp_zip->_closeFd();
+        $this->_closeFd();
+
+        // ----- Delete the zip file
+        // TBC : I should test the result ...
+        @unlink($this->_zipname);
+
+        // ----- Rename the temporary file
+        // TBC : I should test the result ...
+        //@rename($v_zip_temp_name, $this->_zipname);
+        $this->_tool_Rename($v_zip_temp_name, $this->_zipname);
+
+        // ----- Destroy the temporary archive
+        unset($v_temp_zip);
+    }
+
+    // ----- Return
+    return $v_result;
+  }
+  // ---------------------------------------------------------------------------
+
+  // ---------------------------------------------------------------------------
+  // Function : _dirCheck()
+  // Description :
+  //   Check if a directory exists, if not it creates it and all the parents directory
+  //   which may be useful.
+  // Parameters :
+  //   $p_dir : Directory path to check.
+  // Return Values :
+  //    1 : OK
+  //   -1 : Unable to create directory
+  // ---------------------------------------------------------------------------
+  /**
+  * Archive_Zip::_dirCheck()
+  *
+  * { Description }
+  *
+  * @param [type] $p_is_dir
+  */
+  function _dirCheck($p_dir, $p_is_dir=false)
+  {
+    $v_result = 1;
+
+    // ----- Remove the final '/'
+    if (($p_is_dir) && (substr($p_dir, -1)=='/')) {
+      $p_dir = substr($p_dir, 0, strlen($p_dir)-1);
+    }
+
+    // ----- Check the directory availability
+    if ((is_dir($p_dir)) || ($p_dir == "")) {
+      return 1;
+    }
+
+    // ----- Extract parent directory
+    $p_parent_dir = dirname($p_dir);
+
+    // ----- Just a check
+    if ($p_parent_dir != $p_dir) {
+      // ----- Look for parent directory
+      if ($p_parent_dir != "") {
+        if (($v_result = $this->_dirCheck($p_parent_dir)) != 1) {
+          return $v_result;
+        }
+      }
+    }
+
+    // ----- Create the directory
+    if (!@mkdir($p_dir, 0777)) {
+      $this->_errorLog(ARCHIVE_ZIP_ERR_DIR_CREATE_FAIL,
+	                   "Unable to create directory '$p_dir'");
+      return Archive_Zip::errorCode();
+    }
+
+    // ----- Return
+    return $v_result;
+  }
+  // ---------------------------------------------------------------------------
+
+  // ---------------------------------------------------------------------------
+  // Function : _merge()
+  // Description :
+  //   If $p_archive_to_add does not exist, the function exit with a success result.
+  // Parameters :
+  // Return Values :
+  // ---------------------------------------------------------------------------
+  /**
+  * Archive_Zip::_merge()
+  *
+  * { Description }
+  *
+  */
+  function _merge(&$p_archive_to_add)
+  {
+    $v_result=1;
+
+    // ----- Look if the archive_to_add exists
+    if (!is_file($p_archive_to_add->_zipname)) {
+      // ----- Nothing to merge, so merge is a success
+      return 1;
+    }
+
+    // ----- Look if the archive exists
+    if (!is_file($this->_zipname)) {
+      // ----- Do a duplicate
+      $v_result = $this->_duplicate($p_archive_to_add->_zipname);
+
+      return $v_result;
+    }
+
+    // ----- Open the zip file
+    if (($v_result=$this->_openFd('rb')) != 1) {
+      return $v_result;
+    }
+
+    // ----- Read the central directory informations
+    $v_central_dir = array();
+    if (($v_result = $this->_readEndCentralDir($v_central_dir)) != 1) {
+      $this->_closeFd();
+      return $v_result;
+    }
+
+    // ----- Go to beginning of File
+    @rewind($this->_zip_fd);
+
+    // ----- Open the archive_to_add file
+    if (($v_result=$p_archive_to_add->_openFd('rb')) != 1) {
+      $this->_closeFd();
+      return $v_result;
+    }
+
+    // ----- Read the central directory informations
+    $v_central_dir_to_add = array();
+    $v_result = $p_archive_to_add->_readEndCentralDir($v_central_dir_to_add);
+    if ($v_result != 1) {
+      $this->_closeFd();
+      $p_archive_to_add->_closeFd();
+      return $v_result;
+    }
+
+    // ----- Go to beginning of File
+    @rewind($p_archive_to_add->_zip_fd);
+
+    // ----- Creates a temporay file
+    $v_zip_temp_name = ARCHIVE_ZIP_TEMPORARY_DIR.uniqid('archive_zip-').'.tmp';
+
+    // ----- Open the temporary file in write mode
+    if (($v_zip_temp_fd = @fopen($v_zip_temp_name, 'wb')) == 0) {
+      $this->_closeFd();
+      $p_archive_to_add->_closeFd();
+      $this->_errorLog(ARCHIVE_ZIP_ERR_READ_OPEN_FAIL,
+	                   'Unable to open temporary file \''
+					   .$v_zip_temp_name.'\' in binary write mode');
+      return Archive_Zip::errorCode();
+    }
+
+    // ----- Copy the files from the archive to the temporary file
+    // TBC : Here I should better append the file and go back to erase the
+	// central dir
+    $v_size = $v_central_dir['offset'];
+    while ($v_size != 0) {
+      $v_read_size = ($v_size < ARCHIVE_ZIP_READ_BLOCK_SIZE
+	                  ? $v_size : ARCHIVE_ZIP_READ_BLOCK_SIZE);
+      $v_buffer = fread($this->_zip_fd, $v_read_size);
+      @fwrite($v_zip_temp_fd, $v_buffer, $v_read_size);
+      $v_size -= $v_read_size;
+    }
+
+    // ----- Copy the files from the archive_to_add into the temporary file
+    $v_size = $v_central_dir_to_add['offset'];
+    while ($v_size != 0) {
+      $v_read_size = ($v_size < ARCHIVE_ZIP_READ_BLOCK_SIZE
+	                  ? $v_size : ARCHIVE_ZIP_READ_BLOCK_SIZE);
+      $v_buffer = fread($p_archive_to_add->_zip_fd, $v_read_size);
+      @fwrite($v_zip_temp_fd, $v_buffer, $v_read_size);
+      $v_size -= $v_read_size;
+    }
+
+    // ----- Store the offset of the central dir
+    $v_offset = @ftell($v_zip_temp_fd);
+
+    // ----- Copy the block of file headers from the old archive
+    $v_size = $v_central_dir['size'];
+    while ($v_size != 0) {
+      $v_read_size = ($v_size < ARCHIVE_ZIP_READ_BLOCK_SIZE
+	                  ? $v_size : ARCHIVE_ZIP_READ_BLOCK_SIZE);
+      $v_buffer = @fread($this->_zip_fd, $v_read_size);
+      @fwrite($v_zip_temp_fd, $v_buffer, $v_read_size);
+      $v_size -= $v_read_size;
+    }
+
+    // ----- Copy the block of file headers from the archive_to_add
+    $v_size = $v_central_dir_to_add['size'];
+    while ($v_size != 0) {
+      $v_read_size = ($v_size < ARCHIVE_ZIP_READ_BLOCK_SIZE
+	                  ? $v_size : ARCHIVE_ZIP_READ_BLOCK_SIZE);
+      $v_buffer = @fread($p_archive_to_add->_zip_fd, $v_read_size);
+      @fwrite($v_zip_temp_fd, $v_buffer, $v_read_size);
+      $v_size -= $v_read_size;
+    }
+
+    // ----- Zip file comment
+    // TBC : I should merge the two comments
+    $v_comment = '';
+
+    // ----- Calculate the size of the (new) central header
+    $v_size = @ftell($v_zip_temp_fd)-$v_offset;
+
+    // ----- Swap the file descriptor
+    // Here is a trick : I swap the temporary fd with the zip fd, in order to use
+    // the following methods on the temporary fil and not the real archive fd
+    $v_swap = $this->_zip_fd;
+    $this->_zip_fd = $v_zip_temp_fd;
+    $v_zip_temp_fd = $v_swap;
+
+    // ----- Create the central dir footer
+    if (($v_result = $this->_writeCentralHeader($v_central_dir['entries']
+	                                          +$v_central_dir_to_add['entries'],
+												$v_size, $v_offset,
+												$v_comment)) != 1) {
+      $this->_closeFd();
+      $p_archive_to_add->_closeFd();
+      @fclose($v_zip_temp_fd);
+      $this->_zip_fd = null;
+
+      // ----- Reset the file list
+      unset($v_header_list);
+
+      // ----- Return
+      return $v_result;
+    }
+
+    // ----- Swap back the file descriptor
+    $v_swap = $this->_zip_fd;
+    $this->_zip_fd = $v_zip_temp_fd;
+    $v_zip_temp_fd = $v_swap;
+
+    // ----- Close
+    $this->_closeFd();
+    $p_archive_to_add->_closeFd();
+
+    // ----- Close the temporary file
+    @fclose($v_zip_temp_fd);
+
+    // ----- Delete the zip file
+    // TBC : I should test the result ...
+    @unlink($this->_zipname);
+
+    // ----- Rename the temporary file
+    // TBC : I should test the result ...
+    //@rename($v_zip_temp_name, $this->_zipname);
+    $this->_tool_Rename($v_zip_temp_name, $this->_zipname);
+
+    // ----- Return
+    return $v_result;
+  }
+  // ---------------------------------------------------------------------------
+
+  // ---------------------------------------------------------------------------
+  // Function : _duplicate()
+  // Description :
+  // Parameters :
+  // Return Values :
+  // ---------------------------------------------------------------------------
+  /**
+  * Archive_Zip::_duplicate()
+  *
+  * { Description }
+  *
+  */
+  function _duplicate($p_archive_filename)
+  {
+    $v_result=1;
+
+    // ----- Look if the $p_archive_filename exists
+    if (!is_file($p_archive_filename)) {
+
+      // ----- Nothing to duplicate, so duplicate is a success.
+      $v_result = 1;
+
+      // ----- Return
+      return $v_result;
+    }
+
+    // ----- Open the zip file
+    if (($v_result=$this->_openFd('wb')) != 1) {
+      // ----- Return
+      return $v_result;
+    }
+
+    // ----- Open the temporary file in write mode
+    if (($v_zip_temp_fd = @fopen($p_archive_filename, 'rb')) == 0) {
+      $this->_closeFd();
+      $this->_errorLog(ARCHIVE_ZIP_ERR_READ_OPEN_FAIL,
+	                   'Unable to open archive file \''
+					   .$p_archive_filename.'\' in binary write mode');
+      return Archive_Zip::errorCode();
+    }
+
+    // ----- Copy the files from the archive to the temporary file
+    // TBC : Here I should better append the file and go back to erase the
+	// central dir
+    $v_size = filesize($p_archive_filename);
+    while ($v_size != 0) {
+      $v_read_size = ($v_size < ARCHIVE_ZIP_READ_BLOCK_SIZE
+	                  ? $v_size : ARCHIVE_ZIP_READ_BLOCK_SIZE);
+      $v_buffer = fread($v_zip_temp_fd, $v_read_size);
+      @fwrite($this->_zip_fd, $v_buffer, $v_read_size);
+      $v_size -= $v_read_size;
+    }
+
+    // ----- Close
+    $this->_closeFd();
+
+    // ----- Close the temporary file
+    @fclose($v_zip_temp_fd);
+
+    return $v_result;
+  }
+  // ---------------------------------------------------------------------------
+
+  /**
+  * Archive_Zip::_check_parameters()
+  *
+  * { Description }
+  *
+  * @param integer $p_error_code
+  * @param string $p_error_string
+  */
+  function _check_parameters(&$p_params, $p_default)
+  {
+    
+    // ----- Check that param is an array
+    if (!is_array($p_params)) {
+        $this->_errorLog(ARCHIVE_ZIP_ERR_INVALID_PARAMETER,
+		                 'Unsupported parameter, waiting for an array');
+        return Archive_Zip::errorCode();
+    }
+    
+    // ----- Check that all the params are valid
+    for (reset($p_params); list($v_key, $v_value) = each($p_params); ) {
+    	if (!isset($p_default[$v_key])) {
+            $this->_errorLog(ARCHIVE_ZIP_ERR_INVALID_PARAMETER,
+			                 'Unsupported parameter with key \''.$v_key.'\'');
+
+            return Archive_Zip::errorCode();
+    	}
+    }
+
+	// ----- Set the default values
+    for (reset($p_default); list($v_key, $v_value) = each($p_default); ) {
+    	if (!isset($p_params[$v_key])) {
+    		$p_params[$v_key] = $p_default[$v_key];
+    	}
+    }
+    
+    // ----- Check specific parameters
+    $v_callback_list = array ('callback_pre_add','callback_post_add',
+	                          'callback_pre_extract','callback_post_extract');
+    for ($i=0; $i<sizeof($v_callback_list); $i++) {
+    	$v_key=$v_callback_list[$i];
+        if (   (isset($p_params[$v_key])) && ($p_params[$v_key] != '')) {
+            if (!function_exists($p_params[$v_key])) {
+                $this->_errorLog(ARCHIVE_ZIP_ERR_INVALID_PARAM_VALUE,
+				                 "Callback '".$p_params[$v_key]
+								 ."()' is not an existing function for "
+								 ."parameter '".$v_key."'");
+                return Archive_Zip::errorCode();
+            }
+	    }
+    }
+
+    return(1);
+  }
+  // ---------------------------------------------------------------------------
+
+  // ---------------------------------------------------------------------------
+  // Function : _errorLog()
+  // Description :
+  // Parameters :
+  // ---------------------------------------------------------------------------
+  /**
+  * Archive_Zip::_errorLog()
+  *
+  * { Description }
+  *
+  * @param integer $p_error_code
+  * @param string $p_error_string
+  */
+  function _errorLog($p_error_code=0, $p_error_string='')
+  {
+      $this->_error_code = $p_error_code;
+      $this->_error_string = $p_error_string;
+  }
+  // ---------------------------------------------------------------------------
+
+  // ---------------------------------------------------------------------------
+  // Function : _errorReset()
+  // Description :
+  // Parameters :
+  // ---------------------------------------------------------------------------
+  /**
+  * Archive_Zip::_errorReset()
+  *
+  * { Description }
+  *
+  */
+  function _errorReset()
+  {
+      $this->_error_code = 1;
+      $this->_error_string = '';
+  }
+  // ---------------------------------------------------------------------------
+
+  // ---------------------------------------------------------------------------
+  // Function : $this->_tool_PathReduction()
+  // Description :
+  // Parameters :
+  // Return Values :
+  // ---------------------------------------------------------------------------
+  /**
+  * _tool_PathReduction()
+  *
+  * { Description }
+  *
+  */
+  function _tool_PathReduction($p_dir)
+  {
+    $v_result = "";
+
+    // ----- Look for not empty path
+    if ($p_dir != "")
+    {
+      // ----- Explode path by directory names
+      $v_list = explode("/", $p_dir);
+
+      // ----- Study directories from last to first
+      for ($i=sizeof($v_list)-1; $i>=0; $i--)
+      {
+        // ----- Look for current path
+        if ($v_list[$i] == ".")
+        {
+          // ----- Ignore this directory
+          // Should be the first $i=0, but no check is done
+        }
+        else if ($v_list[$i] == "..")
+        {
+          // ----- Ignore it and ignore the $i-1
+          $i--;
+        }
+        else if (($v_list[$i] == "") && ($i!=(sizeof($v_list)-1)) && ($i!=0))
+        {
+          // ----- Ignore only the double '//' in path,
+          // but not the first and last '/'
+        }
+        else
+        {
+          $v_result = $v_list[$i].($i!=(sizeof($v_list)-1)?"/".$v_result:"");
+        }
+      }
+    }
+
+    // ----- Return
+    return $v_result;
+  }
+  // ---------------------------------------------------------------------------
+
+  // ---------------------------------------------------------------------------
+  // Function : $this->_tool_PathInclusion()
+  // Description :
+  //   This function indicates if the path $p_path is under the $p_dir tree. Or,
+  //   said in an other way, if the file or sub-dir $p_path is inside the dir
+  //   $p_dir.
+  //   The function indicates also if the path is exactly the same as the dir.
+  //   This function supports path with duplicated '/' like '//', but does not
+  //   support '.' or '..' statements.
+  // Parameters :
+  // Return Values :
+  //   0 if $p_path is not inside directory $p_dir
+  //   1 if $p_path is inside directory $p_dir
+  //   2 if $p_path is exactly the same as $p_dir
+  // ---------------------------------------------------------------------------
+  /**
+  * _tool_PathInclusion()
+  *
+  * { Description }
+  *
+  */
+  function _tool_PathInclusion($p_dir, $p_path)
+  {
+    $v_result = 1;
+
+    // ----- Explode dir and path by directory separator
+    $v_list_dir = explode("/", $p_dir);
+    $v_list_dir_size = sizeof($v_list_dir);
+    $v_list_path = explode("/", $p_path);
+    $v_list_path_size = sizeof($v_list_path);
+
+    // ----- Study directories paths
+    $i = 0;
+    $j = 0;
+    while (($i < $v_list_dir_size) && ($j < $v_list_path_size) && ($v_result)) {
+
+      // ----- Look for empty dir (path reduction)
+      if ($v_list_dir[$i] == '') {
+        $i++;
+        continue;
+      }
+      if ($v_list_path[$j] == '') {
+        $j++;
+        continue;
+      }
+
+      // ----- Compare the items
+      if (   ($v_list_dir[$i] != $v_list_path[$j])
+	      && ($v_list_dir[$i] != '')
+		  && ( $v_list_path[$j] != ''))  {
+        $v_result = 0;
+      }
+
+      // ----- Next items
+      $i++;
+      $j++;
+    }
+
+    // ----- Look if everything seems to be the same
+    if ($v_result) {
+      // ----- Skip all the empty items
+      while (($j < $v_list_path_size) && ($v_list_path[$j] == '')) $j++;
+      while (($i < $v_list_dir_size) && ($v_list_dir[$i] == '')) $i++;
+
+      if (($i >= $v_list_dir_size) && ($j >= $v_list_path_size)) {
+        // ----- There are exactly the same
+        $v_result = 2;
+      }
+      else if ($i < $v_list_dir_size) {
+        // ----- The path is shorter than the dir
+        $v_result = 0;
+      }
+    }
+
+    // ----- Return
+    return $v_result;
+  }
+  // ---------------------------------------------------------------------------
+
+  // ---------------------------------------------------------------------------
+  // Function : $this->_tool_CopyBlock()
+  // Description :
+  // Parameters :
+  //   $p_mode : read/write compression mode
+  //             0 : src & dest normal
+  //             1 : src gzip, dest normal
+  //             2 : src normal, dest gzip
+  //             3 : src & dest gzip
+  // Return Values :
+  // ---------------------------------------------------------------------------
+  /**
+  * _tool_CopyBlock()
+  *
+  * { Description }
+  *
+  * @param integer $p_mode
+  */
+  function _tool_CopyBlock($p_src, $p_dest, $p_size, $p_mode=0)
+  {
+    $v_result = 1;
+
+    if ($p_mode==0)
+    {
+      while ($p_size != 0)
+      {
+        $v_read_size = ($p_size < ARCHIVE_ZIP_READ_BLOCK_SIZE
+		                ? $p_size : ARCHIVE_ZIP_READ_BLOCK_SIZE);
+        $v_buffer = @fread($p_src, $v_read_size);
+        @fwrite($p_dest, $v_buffer, $v_read_size);
+        $p_size -= $v_read_size;
+      }
+    }
+    else if ($p_mode==1)
+    {
+      while ($p_size != 0)
+      {
+        $v_read_size = ($p_size < ARCHIVE_ZIP_READ_BLOCK_SIZE
+		                ? $p_size : ARCHIVE_ZIP_READ_BLOCK_SIZE);
+        $v_buffer = @gzread($p_src, $v_read_size);
+        @fwrite($p_dest, $v_buffer, $v_read_size);
+        $p_size -= $v_read_size;
+      }
+    }
+    else if ($p_mode==2)
+    {
+      while ($p_size != 0)
+      {
+        $v_read_size = ($p_size < ARCHIVE_ZIP_READ_BLOCK_SIZE
+		                ? $p_size : ARCHIVE_ZIP_READ_BLOCK_SIZE);
+        $v_buffer = @fread($p_src, $v_read_size);
+        @gzwrite($p_dest, $v_buffer, $v_read_size);
+        $p_size -= $v_read_size;
+      }
+    }
+    else if ($p_mode==3)
+    {
+      while ($p_size != 0)
+      {
+        $v_read_size = ($p_size < ARCHIVE_ZIP_READ_BLOCK_SIZE
+		                ? $p_size : ARCHIVE_ZIP_READ_BLOCK_SIZE);
+        $v_buffer = @gzread($p_src, $v_read_size);
+        @gzwrite($p_dest, $v_buffer, $v_read_size);
+        $p_size -= $v_read_size;
+      }
+    }
+
+    // ----- Return
+    return $v_result;
+  }
+  // ---------------------------------------------------------------------------
+
+  // ---------------------------------------------------------------------------
+  // Function : $this->_tool_Rename()
+  // Description :
+  //   This function tries to do a simple rename() function. If it fails, it
+  //   tries to copy the $p_src file in a new $p_dest file and then unlink the
+  //   first one.
+  // Parameters :
+  //   $p_src : Old filename
+  //   $p_dest : New filename
+  // Return Values :
+  //   1 on success, 0 on failure.
+  // ---------------------------------------------------------------------------
+  /**
+  * _tool_Rename()
+  *
+  * { Description }
+  *
+  */
+  function _tool_Rename($p_src, $p_dest)
+  {
+    $v_result = 1;
+
+    // ----- Try to rename the files
+    if (!@rename($p_src, $p_dest)) {
+
+      // ----- Try to copy & unlink the src
+      if (!@copy($p_src, $p_dest)) {
+        $v_result = 0;
+      }
+      else if (!@unlink($p_src)) {
+        $v_result = 0;
+      }
+    }
+
+    // ----- Return
+    return $v_result;
+  }
+  // ---------------------------------------------------------------------------
+
+  // ---------------------------------------------------------------------------
+  // Function : $this->_tool_TranslateWinPath()
+  // Description :
+  //   Translate windows path by replacing '\' by '/' and optionally removing
+  //   drive letter.
+  // Parameters :
+  //   $p_path : path to translate.
+  //   $p_remove_disk_letter : true | false
+  // Return Values :
+  //   The path translated.
+  // ---------------------------------------------------------------------------
+  /**
+  * _tool_TranslateWinPath()
+  *
+  * { Description }
+  *
+  * @param [type] $p_remove_disk_letter
+  */
+  function _tool_TranslateWinPath($p_path, $p_remove_disk_letter=true)
+  {
+    if (stristr(php_uname(), 'windows')) {
+      // ----- Look for potential disk letter
+      if (   ($p_remove_disk_letter)
+	      && (($v_position = strpos($p_path, ':')) != false)) {
+          $p_path = substr($p_path, $v_position+1);
+      }
+      // ----- Change potential windows directory separator
+      if ((strpos($p_path, '\\') > 0) || (substr($p_path, 0,1) == '\\')) {
+          $p_path = strtr($p_path, '\\', '/');
+      }
+    }
+    return $p_path;
+  }
+  // ---------------------------------------------------------------------------
+
+  }
+  // End of class
+
+
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/listener/AnsiColorLogger.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/listener/AnsiColorLogger.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/listener/AnsiColorLogger.php	(revision 19)
@@ -0,0 +1,234 @@
+<?php
+/*
+ * $Id: AnsiColorLogger.php 356 2008-02-13 20:15:12Z hans $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+require_once 'phing/listener/DefaultLogger.php';
+include_once 'phing/system/util/Properties.php';
+
+/**
+ * Uses ANSI Color Code Sequences to colorize messages
+ * sent to the console.
+ *
+ * If used with the -logfile option, the output file
+ * will contain all the necessary escape codes to
+ * display the text in colorized mode when displayed
+ * in the console using applications like cat, more,
+ * etc.
+ *
+ * This is designed to work on terminals that support ANSI
+ * color codes.  It works on XTerm, ETerm, Mindterm, etc.
+ * It also works on Win9x (with ANSI.SYS loaded.)
+ *
+ * NOTE:
+ * It doesn't work on WinNT's COMMAND.COM even with
+ * ANSI.SYS loaded.
+ *
+ * The default colors used for differentiating
+ * the message levels can be changed by editing the
+ * /org/apache/tools/ant/listener/defaults.properties
+ * file.
+ * This file contains 5 key/value pairs:
+ * AnsiColorLogger.ERROR_COLOR=2;31
+ * AnsiColorLogger.WARNING_COLOR=2;35
+ * AnsiColorLogger.INFO_COLOR=2;36
+ * AnsiColorLogger.VERBOSE_COLOR=2;32
+ * AnsiColorLogger.DEBUG_COLOR=2;34
+ *
+ * Another option is to pass a system variable named
+ * ant.logger.defaults, with value set to the path of
+ * the file that contains user defined Ansi Color
+ * Codes, to the <B>java</B> command using -D option.
+ *
+ * To change these colors use the following chart:
+ *
+ *      <B>ANSI COLOR LOGGER CONFIGURATION</B>
+ *
+ * Format for AnsiColorLogger.*=
+ *  Attribute;Foreground;Background
+ * 
+ *  Attribute is one of the following:
+ *  0 -> Reset All Attributes (return to normal mode)
+ *  1 -> Bright (Usually turns on BOLD)
+ *  2 -> Dim
+ *  3 -> Underline
+ *  5 -> link
+ *  7 -> Reverse
+ *  8 -> Hidden
+ *
+ *  Foreground is one of the following:
+ *  30 -> Black
+ *  31 -> Red
+ *  32 -> Green
+ *  33 -> Yellow
+ *  34 -> Blue
+ *  35 -> Magenta
+ *  36 -> Cyan
+ *  37 -> White
+ *
+ *  Background is one of the following:
+ *  40 -> Black
+ *  41 -> Red
+ *  42 -> Green
+ *  43 -> Yellow
+ *  44 -> Blue
+ *  45 -> Magenta
+ *  46 -> Cyan
+ *  47 -> White
+ * 
+ * @author     Hans Lellelid <hans@xmpl.org> (Phing)
+ * @author     Magesh Umasankar (Ant)
+ * @package    phing.listener
+ * @version    $Revision: 1.13 $
+ */
+final class AnsiColorLogger extends DefaultLogger {
+
+    const ATTR_NORMAL = 0;
+    const ATTR_BRIGHT = 1;
+    const ATTR_DIM = 2;
+    const ATTR_UNDERLINE = 3;
+    const ATTR_BLINK = 5;
+    const ATTR_REVERSE = 7;
+    const ATTR_HIDDEN = 8;
+
+    const FG_BLACK = 30;
+    const FG_RED = 31;
+    const FG_GREEN = 32;
+    const FG_YELLOW = 33;
+    const FG_BLUE = 34;
+    const FG_MAGENTA = 35;
+    const FG_CYAN = 36;
+    const FG_WHITE = 37;
+
+    const BG_BLACK = 40;
+    const BG_RED = 41;
+    const BG_GREEN = 42;
+    const BG_YELLOW = 44;
+    const BG_BLUE = 44;
+    const BG_MAGENTA = 45;
+    const BG_CYAN = 46;
+    const BG_WHITE = 47;
+
+    const PREFIX = "\x1b[";
+    const SUFFIX = "m";
+    const SEPARATOR = ';';
+    const END_COLOR = "\x1b[m"; // self::PREFIX . self::SUFFIX;
+
+    private $errColor;
+    private $warnColor;
+    private $infoColor;
+    private $verboseColor;
+    private $debugColor;
+
+    private $colorsSet = false;
+    
+    /**
+     * Construct new AnsiColorLogger
+     * Perform initializations that cannot be done in var declarations.
+     */
+    public function __construct() {
+        parent::__construct();
+        $this->errColor = self::PREFIX . self::ATTR_DIM . self::SEPARATOR . self::FG_RED . self::SUFFIX;
+        $this->warnColor = self::PREFIX . self::ATTR_DIM . self::SEPARATOR . self::FG_MAGENTA . self::SUFFIX;
+        $this->infoColor = self::PREFIX . self::ATTR_DIM . self::SEPARATOR . self::FG_CYAN . self::SUFFIX;
+        $this->verboseColor = self::PREFIX . self::ATTR_DIM . self::SEPARATOR . self::FG_GREEN . self::SUFFIX;
+        $this->debugColor = self::PREFIX . self::ATTR_DIM . self::SEPARATOR . self::FG_BLUE . self::SUFFIX;
+    }
+    
+    /**
+     * Set the colors to use from a property file specified by the
+     * special ant property ant.logger.defaults
+     */
+    private final function setColors() {
+    
+        $userColorFile = Phing::getProperty("phing.logger.defaults");
+        $systemColorFile = new PhingFile(Phing::getResourcePath("phing/listener/defaults.properties"));
+
+        $in = null;
+
+        try {
+            $prop = new Properties();
+
+            if ($userColorFile !== null) {
+                $prop->load($userColorFile);
+            } else {
+                $prop->load($systemColorFile);
+            }                        
+            
+            $err = $prop->getProperty("AnsiColorLogger.ERROR_COLOR");
+            $warn = $prop->getProperty("AnsiColorLogger.WARNING_COLOR");
+            $info = $prop->getProperty("AnsiColorLogger.INFO_COLOR");
+            $verbose = $prop->getProperty("AnsiColorLogger.VERBOSE_COLOR");
+            $debug = $prop->getProperty("AnsiColorLogger.DEBUG_COLOR");
+            if ($err !== null) {
+                $this->errColor = self::PREFIX . $err . self::SUFFIX;
+            }
+            if ($warn !== null) {
+                $this->warnColor = self::PREFIX . $warn . self::SUFFIX;
+            }
+            if ($info !== null) {
+                $this->infoColor = self::PREFIX . $info . self::SUFFIX;
+            }
+            if ($verbose !== null) {
+                $this->verboseColor = self::PREFIX . $verbose . self::SUFFIX;
+            }
+            if ($debug !== null) {
+                $this->debugColor = self::PREFIX . $debug . self::SUFFIX;
+            }
+        } catch (IOException $ioe) {
+            //Ignore exception - we will use the defaults.
+        }
+    }
+
+    /**
+     * @see DefaultLogger#printMessage
+     * @param string $message
+     * @param OutputStream $stream
+     * @param int $priority
+     */
+    protected final function printMessage($message, OutputStream $stream, $priority) {
+        if ($message !== null) {
+        
+            if (!$this->colorsSet) {
+                $this->setColors();
+                $this->colorsSet = true;
+            }
+            
+            switch ($priority) {
+                case Project::MSG_ERR:
+                    $message = $this->errColor . $message . self::END_COLOR;
+                    break;
+                case Project::MSG_WARN:
+                    $message = $this->warnColor . $message . self::END_COLOR;                    
+                    break;
+                case Project::MSG_INFO:
+                    $message = $this->infoColor . $message . self::END_COLOR;
+                    break;
+                case Project::MSG_VERBOSE:
+                    $message = $this->verboseColor . $message . self::END_COLOR;
+                    break;
+                case Project::MSG_DEBUG:
+                    $message = $this->debugColor . $message . self::END_COLOR;
+                    break;
+            }
+            
+            $stream->write($message . PHP_EOL);
+        }
+    }
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/listener/DefaultLogger.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/listener/DefaultLogger.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/listener/DefaultLogger.php	(revision 19)
@@ -0,0 +1,278 @@
+<?php
+/*
+ *  $Id: DefaultLogger.php 279 2007-11-01 20:11:07Z hans $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+ 
+require_once 'phing/listener/StreamRequiredBuildLogger.php';
+include_once 'phing/BuildEvent.php';
+
+/**
+ *  Writes a build event to the console.
+ *
+ *  Currently, it only writes which targets are being executed, and
+ *  any messages that get logged.
+ *
+ *  @author    Andreas Aderhold <andi@binarycloud.com>
+ *  @copyright ï¿œ 2001,2002 THYRELL. All rights reserved
+ *  @version   $Revision: 1.11 $ $Date: 2007-11-01 20:11:07 +0000 (Thu, 01 Nov 2007) $
+ *  @see       BuildEvent
+ *  @package   phing.listener
+ */
+class DefaultLogger implements StreamRequiredBuildLogger {
+
+    /**
+     *  Size of the left column in output. The default char width is 12.
+     *  @var int
+     */
+    const LEFT_COLUMN_SIZE = 12;
+
+    /**
+     *  The message output level that should be used. The default is
+     *  <code>Project::MSG_VERBOSE</code>.
+     *  @var int
+     */
+    protected $msgOutputLevel = Project::MSG_ERR;
+
+    /**
+     *  Time that the build started
+     *  @var int
+     */
+    protected $startTime;
+    
+    /**
+     * @var OutputStream Stream to use for standard output.
+     */
+    protected $out;
+    
+    /**
+     * @var OutputStream Stream to use for error output.
+     */
+    protected $err;
+
+    /**
+     *  Construct a new default logger.
+     */
+    public function __construct() {
+    	
+    }
+
+    /**
+     *  Set the msgOutputLevel this logger is to respond to.
+     *
+     *  Only messages with a message level lower than or equal to the given
+     *  level are output to the log.
+     *
+     *  <p> Constants for the message levels are in Project.php. The order of
+     *  the levels, from least to most verbose, is:
+     *
+     *  <ul>
+     *    <li>Project::MSG_ERR</li>
+     *    <li>Project::MSG_WARN</li>
+     *    <li>Project::MSG_INFO</li>
+     *    <li>Project::MSG_VERBOSE</li>
+     *    <li>Project::MSG_DEBUG</li>
+     *  </ul>
+     *
+     *  The default message level for DefaultLogger is Project::MSG_ERR.
+     *
+     * @param int $level The logging level for the logger.
+     * @see BuildLogger#setMessageOutputLevel()
+     */
+    public function setMessageOutputLevel($level) {
+        $this->msgOutputLevel = (int) $level;
+    }
+    
+    /**
+     * Sets the output stream.
+     * @param OutputStream $output
+     * @see BuildLogger#setOutputStream()
+     */
+    public function setOutputStream(OutputStream $output) {
+    	$this->out = $output;
+    }
+	
+    /**
+     * Sets the error stream.
+     * @param OutputStream $err
+     * @see BuildLogger#setErrorStream()
+     */
+    public function setErrorStream(OutputStream $err) {
+    	$this->err = $err;
+    }
+    
+    /**
+    *  Sets the start-time when the build started. Used for calculating
+    *  the build-time.
+    *
+    *  @param  object  The BuildEvent
+    *  @access public
+    */
+    public function buildStarted(BuildEvent $event) {
+        $this->startTime = Phing::currentTimeMillis();
+        if ($this->msgOutputLevel >= Project::MSG_INFO) {
+            $this->printMessage("Buildfile: ".$event->getProject()->getProperty("phing.file"), $this->out, Project::MSG_INFO);
+        }
+    }
+
+    /**
+     *  Prints whether the build succeeded or failed, and any errors that
+     *  occured during the build. Also outputs the total build-time.
+     *
+     *  @param  object  The BuildEvent
+     *  @see    BuildEvent::getException()
+     */
+    public function buildFinished(BuildEvent $event) {
+        $error = $event->getException();
+        if ($error === null) {
+            $msg = PHP_EOL . $this->getBuildSuccessfulMessage() . PHP_EOL;
+        } else {
+            $msg = PHP_EOL . $this->getBuildFailedMessage() . PHP_EOL;
+            if (Project::MSG_VERBOSE <= $this->msgOutputLevel || !($error instanceof BuildException)) {
+                $msg .= $error->__toString().PHP_EOL;
+            } else {
+                $msg .= $error->getMessage();
+            }
+        }
+        $msg .= PHP_EOL . "Total time: " .self::formatTime(Phing::currentTimeMillis() - $this->startTime) . PHP_EOL;
+        
+    	if ($error === null) {
+            $this->printMessage($msg, $this->out, Project::MSG_VERBOSE);
+        } else {
+            $this->printMessage($msg, $this->err, Project::MSG_ERR);
+        }
+    }
+
+	/**
+     * Get the message to return when a build failed.
+     * @return string The classic "BUILD FAILED"
+     */
+    protected function getBuildFailedMessage() {
+        return "BUILD FAILED";
+    }
+
+    /**
+     * Get the message to return when a build succeeded.
+     * @return string The classic "BUILD FINISHED"
+     */
+    protected function getBuildSuccessfulMessage() {
+        return "BUILD FINISHED";
+    }
+    
+    /**
+     *  Prints the current target name
+     *
+     *  @param  object  The BuildEvent
+     *  @access public
+     *  @see    BuildEvent::getTarget()
+     */
+    public function targetStarted(BuildEvent $event) {
+        if (Project::MSG_INFO <= $this->msgOutputLevel) {
+        	$msg = PHP_EOL . $event->getProject()->getName() . ' > ' . $event->getTarget()->getName() . ':' . PHP_EOL;
+        	$this->printMessage($msg, $this->out, $event->getPriority());
+        }
+    }
+
+    /**
+     *  Fired when a target has finished. We don't need specific action on this
+     *  event. So the methods are empty.
+     *
+     *  @param  object  The BuildEvent
+     *  @see    BuildEvent::getException()
+     */
+    public function targetFinished(BuildEvent $event) {}
+
+    /**
+     *  Fired when a task is started. We don't need specific action on this
+     *  event. So the methods are empty.
+     *
+     *  @param  object  The BuildEvent
+     *  @access public
+     *  @see    BuildEvent::getTask()
+     */
+    public function taskStarted(BuildEvent $event) {}
+
+    /**
+     *  Fired when a task has finished. We don't need specific action on this
+     *  event. So the methods are empty.
+     *
+     *  @param  object  The BuildEvent
+     *  @access public
+     *  @see    BuildEvent::getException()
+     */
+    public function taskFinished(BuildEvent $event) {}
+
+    /**
+     *  Print a message to the stdout.
+     *
+     *  @param  object  The BuildEvent
+     *  @access public
+     *  @see    BuildEvent::getMessage()
+     */
+    public function messageLogged(BuildEvent $event) {
+    	$priority = $event->getPriority();
+        if ($priority <= $this->msgOutputLevel) {
+            $msg = "";
+            if ($event->getTask() !== null) {
+                $name = $event->getTask();
+                $name = $name->getTaskName();
+                $msg = str_pad("[$name] ", self::LEFT_COLUMN_SIZE, " ", STR_PAD_LEFT);
+            }
+            
+            $msg .= $event->getMessage();
+            
+            if ($priority != Project::MSG_ERR) {
+                $this->printMessage($msg, $this->out, $priority);
+            } else {
+            	$this->printMessage($msg, $this->err, $priority);
+            }
+        }
+    }
+
+    /**
+     *  Formats a time micro integer to human readable format.
+     *
+     *  @param  integer The time stamp
+     *  @access private
+     */
+    public static function formatTime($micros) {
+        $seconds = $micros;
+        $minutes = $seconds / 60;
+        if ($minutes > 1) {
+            return sprintf("%1.0f minute%s %0.2f second%s",
+                                    $minutes, ($minutes === 1 ? " " : "s "),
+                                    $seconds - floor($seconds/60) * 60, ($seconds%60 === 1 ? "" : "s"));
+        } else {
+            return sprintf("%0.4f second%s", $seconds, ($seconds%60 === 1 ? "" : "s"));
+        }
+    }
+    
+    /**
+     * Prints a message to console.
+     * 
+     * @param string $message  The message to print. 
+     *                 Should not be <code>null</code>.
+     * @param resource $stream The stream to use for message printing.
+     * @param int $priority The priority of the message. 
+     *                 (Ignored in this implementation.)
+     * @return void
+     */
+    protected function printMessage($message, OutputStream $stream, $priority) {
+    	$stream->write($message . PHP_EOL);
+    }    
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/listener/NoBannerLogger.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/listener/NoBannerLogger.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/listener/NoBannerLogger.php	(revision 19)
@@ -0,0 +1,59 @@
+<?php
+/*
+ * $Id: NoBannerLogger.php 227 2007-08-28 02:17:00Z hans $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+require_once 'phing/listener/DefaultLogger.php';
+
+/**
+ *  Extends DefaultLogger to strip out empty targets.
+ *
+ *  @author    Andreas Aderhold <andi@binarycloud.com>
+ *  @copyright ï¿œ 2001,2002 THYRELL. All rights reserved
+ *  @version   $Revision: 1.4 $ $Date: 2007-08-28 02:17:00 +0000 (Tue, 28 Aug 2007) $
+ *  @package   phing.listener
+ */
+class NoBannerLogger extends DefaultLogger {
+
+	private $targetName = null;
+
+	function targetStarted(BuildEvent $event) {
+		$target = $event->getTarget();
+		$this->targetName = $target->getName();
+	}
+
+	function targetFinished(BuildEvent $event) {
+		$this->targetName = null;
+	}
+
+	function messageLogged(BuildEvent $event) {
+		
+		if ($event->getPriority() > $this->msgOutputLevel || null === $event->getMessage() || trim($event->getMessage() === "")) {
+			return;
+		}
+		
+		if ($this->targetName !== null) {
+			$msg = PHP_EOL . $event->getProject()->getName() . ' > ' . $this->targetName . ':' . PHP_EOL;
+			$this->printMessage($msg, $this->out, $event->getPriority());
+			$this->targetName = null;
+		}
+
+		parent::messageLogged($event);
+	}
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/listener/PearLogListener.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/listener/PearLogListener.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/listener/PearLogListener.php	(revision 19)
@@ -0,0 +1,197 @@
+<?php
+/*
+ *  $Id: PearLogListener.php 227 2007-08-28 02:17:00Z hans $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+ 
+require_once 'phing/BuildListener.php';
+
+/**
+ * Writes build messages to PEAR Log.
+ * 
+ * By default it will log to file in current directory w/ name 'phing.log'.  You can customize
+ * this behavior by setting properties:
+ * - pear.log.type
+ * - pear.log.name
+ * - pear.log.ident (note that this class changes ident to project name)
+ * - pear.log.conf (note that array values are currently unsupported in Phing property files)
+ * 
+ * <code>
+ *  phing -f build.xml -logger phing.listener.PearLogger -Dpear.log.type=file -Dpear.log.name=/path/to/log.log
+ * </code>
+ * 
+ * @author    Hans Lellelid <hans@xmpl.org>
+ * @version   $Revision: 1.3 $ $Date: 2007-08-28 02:17:00 +0000 (Tue, 28 Aug 2007) $
+ * @see       BuildEvent
+ * @package   phing.listener
+ */
+class PearLogListener implements BuildListener {
+
+    /**
+     *  Size of the left column in output. The default char width is 12.
+     *  @var int
+     */
+    const LEFT_COLUMN_SIZE = 12;
+
+    /**
+     *  Time that the build started
+     *  @var int
+     */
+    protected $startTime;
+    
+    /**
+     * Maps Phing Project::MSG_* constants to PEAR_LOG_* constants.
+     * @var array
+     */
+    protected static $levelMap = array( Project::MSG_DEBUG => PEAR_LOG_DEBUG,
+                                        Project::MSG_INFO => PEAR_LOG_INFO,
+                                        Project::MSG_VERBOSE => PEAR_LOG_NOTICE,
+                                        Project::MSG_WARN => PEAR_LOG_WARNING,
+                                        Project::MSG_ERR => PEAR_LOG_ERR
+                                       );
+    /**
+     * Whether logging has been configured.
+     * @var boolean
+     */
+    protected $logConfigured = false;
+    
+    /**
+     * @var Log PEAR Log object.
+     */
+   	protected $logger;
+   	
+    /**
+     * Configure the logger.
+     */
+    protected function configureLogging() {
+    	
+        $type = Phing::getDefinedProperty('pear.log.type');
+        $name = Phing::getDefinedProperty('pear.log.name');
+        $ident = Phing::getDefinedProperty('pear.log.ident');
+        $conf = Phing::getDefinedProperty('pear.log.conf');
+        
+        if ($type === null) $type = 'file';
+        if ($name === null) $name = 'phing.log';
+        if ($ident === null) $ident = 'phing';
+        if ($conf === null) $conf = array();
+        
+        include_once 'Log.php';
+        if (!class_exists('Log')) {
+        	throw new BuildException("Cannot find PEAR Log class for use by PearLogger.");
+        }
+        
+        $this->logger = Log::singleton($type, $name, $ident, $conf, self::$levelMap[$this->msgOutputLevel]);
+    }        
+    
+    /**
+     * Get the configured PEAR logger to use.
+     * This method just ensures that logging has been configured and returns the configured logger.
+     * @return Log
+     */
+    protected function logger() {
+        if (!$this->logConfigured) {
+            $this->configureLogging();
+        }
+        return $this->logger;
+    }
+
+    /**
+     *  Sets the start-time when the build started. Used for calculating
+     *  the build-time.
+     *
+     * @param  BuildEvent  The BuildEvent
+     */
+    public function buildStarted(BuildEvent $event) {
+        $this->startTime = Phing::currentTimeMillis();
+        $this->logger()->setIdent($event->getProject()->getName());
+        $this->logger()->info("Starting build with buildfile: ". $event->getProject()->getProperty("phing.file"));
+    }
+
+    /**
+     *  Logs whether the build succeeded or failed, and any errors that
+     *  occured during the build. Also outputs the total build-time.
+     *
+     * @param  BuildEvent  The BuildEvent
+     * @see    BuildEvent::getException()
+     */
+    public function buildFinished(BuildEvent $event) {
+        $error = $event->getException();
+        if ($error === null) {
+            $msg = "Finished successful build.";
+        } else {
+            $msg = "Build failed. [reason: " . $error->getMessage() ."]";
+        }
+        $this->logger()->log($msg . " Total time: " . DefaultLogger::formatTime(Phing::currentTimeMillis() - $this->startTime));
+    }
+
+    /**
+     * Logs the current target name
+     *
+     * @param  BuildEvent  The BuildEvent
+     * @see    BuildEvent::getTarget()
+     */
+    public function targetStarted(BuildEvent $event) {}
+
+    /**
+     *  Fired when a target has finished. We don't need specific action on this
+     *  event. So the methods are empty.
+     *
+     *  @param  BuildEvent  The BuildEvent
+     *  @access public
+     *  @see    BuildEvent::getException()
+     */
+    public function targetFinished(BuildEvent $event) {}
+
+    /**
+     *  Fired when a task is started. We don't need specific action on this
+     *  event. So the methods are empty.
+     *
+     *  @param  BuildEvent  The BuildEvent
+     *  @access public
+     *  @see    BuildEvent::getTask()
+     */
+    public function taskStarted(BuildEvent $event) {}
+
+    /**
+     *  Fired when a task has finished. We don't need specific action on this
+     *  event. So the methods are empty.
+     *
+     * @param  BuildEvent  The BuildEvent
+     * @see    BuildEvent::getException()
+     */
+    public function taskFinished(BuildEvent $event) {}
+
+    /**
+     *  Logs a message to the configured PEAR logger.
+     *
+     * @param  BuildEvent  The BuildEvent
+     * @see    BuildEvent::getMessage()
+     */
+    public function messageLogged(BuildEvent $event) {
+        if ($event->getPriority() <= $this->msgOutputLevel) {            
+            $msg = "";
+            if ($event->getTask() !== null) {
+                $name = $event->getTask();
+                $name = $name->getTaskName();
+                $msg = str_pad("[$name] ", self::LEFT_COLUMN_SIZE, " ", STR_PAD_LEFT);
+            }
+            $msg .= $event->getMessage();
+            $this->logger()->log($msg, self::$levelMap[$event->getPriority()]);
+        }
+    }
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/listener/StreamRequiredBuildLogger.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/listener/StreamRequiredBuildLogger.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/listener/StreamRequiredBuildLogger.php	(revision 19)
@@ -0,0 +1,39 @@
+<?php
+/*
+ *  $Id: BuildLogger.php 147 2007-02-06 20:32:22Z hans $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+require_once 'phing/BuildLogger.php';
+
+/**
+ * Interface for build loggers that require that out/err streams be set in order to function.
+ * 
+ * This is just an empty sub-interface to BuildLogger, but is used by Phing to throw
+ * graceful errors when classes like phing.listener.DefaultLogger are being used as 
+ * -listener.
+ *
+ * @author    Hans Lellelid <hans@xmpl.org>
+ * @version   $Revision: 1.6 $
+ * @see       BuildEvent
+ * @see       Project::addBuildListener()
+ * @package   phing
+ */
+interface StreamRequiredBuildLogger extends BuildLogger {
+
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/listener/XmlLogger.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/listener/XmlLogger.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/listener/XmlLogger.php	(revision 19)
@@ -0,0 +1,345 @@
+<?php
+/**
+ * $Id: XmlLogger.php 291 2007-11-04 15:23:03Z hans $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+require_once 'phing/BuildLogger.php';
+require_once 'phing/listener/DefaultLogger.php';
+require_once 'phing/system/util/Timer.php';
+
+/**
+ * Generates a file in the current directory with
+ * an XML description of what happened during a build.
+ * The default filename is "log.xml", but this can be overridden
+ * with the property <code>XmlLogger.file</code>.
+ *
+ * @author Michiel Rook <michiel.rook@gmail.com>
+ * @version $Id: XmlLogger.php 291 2007-11-04 15:23:03Z hans $
+ * @package phing.listener
+ */	
+class XmlLogger implements BuildLogger {
+	
+	/** XML element name for a build. */
+	const BUILD_TAG = "build";
+	
+	/** XML element name for a target. */
+	const TARGET_TAG = "target";
+	
+	/** XML element name for a task. */
+	const TASK_TAG = "task";
+	
+	/** XML element name for a message. */
+	const MESSAGE_TAG = "message";
+	
+	/** XML attribute name for a name. */
+	const NAME_ATTR = "name";
+	
+	/** XML attribute name for a time. */
+	const TIME_ATTR = "time";
+	
+	/** XML attribute name for a message priority. */
+	const PRIORITY_ATTR = "priority";
+	
+	/** XML attribute name for a file location. */
+	const LOCATION_ATTR = "location";
+	
+	/** XML attribute name for an error description. */
+	const ERROR_ATTR = "error";
+	
+	/** XML element name for a stack trace. */
+	const STACKTRACE_TAG = "stacktrace";
+	
+	/**
+	 * @var DOMDocument The XML document created by this logger. 
+	 */
+	private $doc;
+	
+	/**
+	 * @var int Start time for entire build.
+	 */
+	private $buildTimerStart = 0;
+	
+	/**
+	 * @var DOMElement Top-level (root) build element
+	 */
+	private $buildElement;
+	
+	/**
+	 * @var array DOMElement[] The parent of the element being processed.
+	 */
+	private $elementStack = array();
+	
+	/**
+	 * @var array int[] Array of millisecond times for the various elements being processed.
+	 */
+	private $timesStack = array();
+	
+	/**
+	 * @var int
+	 */
+	private $msgOutputLevel = Project::MSG_DEBUG;
+	
+	/**
+     * @var OutputStream Stream to use for standard output.
+     */
+	private $out;
+   
+	/**
+	 * @var OutputStream Stream to use for error output.
+	 */
+	private $err;
+	
+	/**
+	 * @var string Name of filename to create.
+	 */
+	private $outFilename;
+	
+	/**
+	 *  Constructs a new BuildListener that logs build events to an XML file.
+	 */
+	public function __construct() {
+		$this->doc = new DOMDocument("1.0", "UTF-8");
+		$this->doc->formatOutput = true;
+	}
+	
+	/**
+	 * Fired when the build starts, this builds the top-level element for the
+	 * document and remembers the time of the start of the build.
+	 *
+	 * @param BuildEvent Ignored.
+	 */
+	function buildStarted(BuildEvent $event) {
+		$this->buildTimerStart = Phing::currentTimeMillis();
+		$this->buildElement = $this->doc->createElement(XmlLogger::BUILD_TAG);
+		array_push($this->elementStack, $this->buildElement);
+		array_push($this->timesStack, $this->buildTimerStart);
+	}
+	
+	/**
+	 * Fired when the build finishes, this adds the time taken and any
+	 * error stacktrace to the build element and writes the document to disk.
+	 *
+	 * @param BuildEvent $event An event with any relevant extra information.
+	 *              Will not be <code>null</code>.
+	 */
+	public function buildFinished(BuildEvent $event) {
+		
+		$elapsedTime = Phing::currentTimeMillis() - $this->buildTimerStart;
+		
+		$this->buildElement->setAttribute(XmlLogger::TIME_ATTR, DefaultLogger::formatTime($elapsedTime));
+		
+		if ($event->getException() != null) {
+			$this->buildElement->setAttribute(XmlLogger::ERROR_ATTR, $event->getException()->getMessage());
+			$errText = $this->doc->createCDATASection($event->getException()->getTraceAsString());
+			$stacktrace = $this->doc->createElement(XmlLogger::STACKTRACE_TAG);
+			$stacktrace->appendChild($errText);
+			$this->buildElement->appendChild($stacktrace);
+		}
+		
+		$this->doc->appendChild($this->buildElement);
+		
+		$outFilename = $event->getProject()->getProperty("XmlLogger.file");
+        if ($outFilename == null) {
+            $outFilename = "log.xml";
+        }
+        
+        try {
+	        $stream = $this->out;
+	        if ($stream === null) {
+	        	$stream = new FileOutputStream($outFilename); 
+	        }
+	        
+	        // Yes, we could just stream->write() but this will eventually be the better
+			// way to do this (when we need to worry about charset conversions. 
+	        $writer = new OutputStreamWriter($stream);
+	        $writer->write($this->doc->saveXML());
+	        $writer->close();
+        } catch (IOException $exc) {
+        	try {
+        		$stream->close(); // in case there is a stream open still ...
+        	} catch (Exception $x) {}
+        	throw new BuildException("Unable to write log file.", $exc);
+        }
+        
+         // cleanup:remove the buildElement
+        $this->buildElement = null;
+       
+        array_pop($this->elementStack);
+        array_pop($this->timesStack);
+	}
+        
+	
+	/**
+	 * Fired when a target starts building, remembers the current time and the name of the target.
+	 *
+	 * @param BuildEvent $event An event with any relevant extra information.
+	 *              Will not be <code>null</code>.
+	 */
+	public function targetStarted(BuildEvent $event) {
+		$target = $event->getTarget();
+		
+		$targetElement = $this->doc->createElement(XmlLogger::TARGET_TAG);
+		$targetElement->setAttribute(XmlLogger::NAME_ATTR, $target->getName());
+		
+		array_push($this->timesStack, Phing::currentTimeMillis());
+		array_push($this->elementStack, $targetElement);
+	}
+	
+	/**
+	 * Fired when a target finishes building, this adds the time taken
+	 * to the appropriate target element in the log.
+	 *
+	 * @param BuildEvent $event An event with any relevant extra information.
+	 *              Will not be <code>null</code>.
+	 */
+	public function targetFinished(BuildEvent $event) {
+		$targetTimerStart = array_pop($this->timesStack);
+		$targetElement = array_pop($this->elementStack);
+		
+		$elapsedTime = Phing::currentTimeMillis() - $targetTimerStart;
+		$targetElement->setAttribute(XmlLogger::TIME_ATTR, DefaultLogger::formatTime($elapsedTime));
+		
+		$parentElement = $this->elementStack[ count($this->elementStack) - 1 ];
+		$parentElement->appendChild($targetElement);
+	}
+	
+	/**
+	 * Fired when a task starts building, remembers the current time and the name of the task.
+	 *
+	 * @param BuildEvent $event An event with any relevant extra information.
+	 *              Will not be <code>null</code>.
+	 */
+	public function taskStarted(BuildEvent $event) {
+		$task = $event->getTask();
+		
+		$taskElement = $this->doc->createElement(XmlLogger::TASK_TAG);
+		$taskElement->setAttribute(XmlLogger::NAME_ATTR, $task->getTaskName());
+		$taskElement->setAttribute(XmlLogger::LOCATION_ATTR, $task->getLocation()->toString());
+		
+		array_push($this->timesStack, Phing::currentTimeMillis());
+		array_push($this->elementStack, $taskElement);
+	}
+	
+	/**
+	 * Fired when a task finishes building, this adds the time taken
+	 * to the appropriate task element in the log.
+	 *
+	 * @param BuildEvent $event An event with any relevant extra information.
+	 *              Will not be <code>null</code>.
+	 */		
+	public function taskFinished(BuildEvent $event) {
+		$taskTimerStart = array_pop($this->timesStack);
+		$taskElement = array_pop($this->elementStack);
+		
+		$elapsedTime = Phing::currentTimeMillis() - $taskTimerStart;
+		$taskElement->setAttribute(XmlLogger::TIME_ATTR, DefaultLogger::formatTime($elapsedTime));
+		
+		$parentElement = $this->elementStack[ count($this->elementStack) - 1 ];
+		$parentElement->appendChild($taskElement);
+	}
+	
+	/**
+	 * Fired when a message is logged, this adds a message element to the
+	 * most appropriate parent element (task, target or build) and records
+	 * the priority and text of the message.
+	 *
+	 * @param BuildEvent An event with any relevant extra information.
+	 *              Will not be <code>null</code>.
+	 */
+	public function messageLogged(BuildEvent $event)
+	{
+		$priority = $event->getPriority();
+		
+		if ($priority > $this->msgOutputLevel) {
+			return;
+		}
+		
+		$messageElement = $this->doc->createElement(XmlLogger::MESSAGE_TAG);
+		
+		switch ($priority) {
+			case Project::MSG_ERR: 
+				$name = "error"; 
+				break;
+			case Project::MSG_WARN:
+				$name = "warn";
+				break;
+			case Project::MSG_INFO:
+				$name = "info";
+				break;
+			default:
+				$name = "debug";
+				break;
+		}
+		
+		$messageElement->setAttribute(XmlLogger::PRIORITY_ATTR, $name);
+		
+		$messageText = $this->doc->createCDATASection($event->getMessage());
+		
+		$messageElement->appendChild($messageText);
+		
+		if (!empty($this->elementStack)) {
+			$this->elementStack[count($this->elementStack)-1]->appendChild($messageElement);
+		}
+	}
+
+    /**
+     *  Set the msgOutputLevel this logger is to respond to.
+     *
+     *  Only messages with a message level lower than or equal to the given
+     *  level are output to the log.
+     *
+     *  <p> Constants for the message levels are in Project.php. The order of
+     *  the levels, from least to most verbose, is:
+     *
+     *  <ul>
+     *    <li>Project::MSG_ERR</li>
+     *    <li>Project::MSG_WARN</li>
+     *    <li>Project::MSG_INFO</li>
+     *    <li>Project::MSG_VERBOSE</li>
+     *    <li>Project::MSG_DEBUG</li>
+     *  </ul>
+     *
+     *  The default message level for DefaultLogger is Project::MSG_ERR.
+     *
+     * @param int $level The logging level for the logger.
+     * @see BuildLogger#setMessageOutputLevel()
+     */
+    public function setMessageOutputLevel($level) {
+        $this->msgOutputLevel = (int) $level;
+    }
+    
+    /**
+     * Sets the output stream.
+     * @param OutputStream $output
+     * @see BuildLogger#setOutputStream()
+     */
+    public function setOutputStream(OutputStream $output) {
+    	$this->out = $output;
+    }
+	
+    /**
+     * Sets the error stream.
+     * @param OutputStream $err
+     * @see BuildLogger#setErrorStream()
+     */
+    public function setErrorStream(OutputStream $err) {
+    	$this->err = $err;
+    }
+	
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/listener/defaults.properties
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/listener/defaults.properties	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/listener/defaults.properties	(revision 19)
@@ -0,0 +1,43 @@
+####################################################
+#
+#           ANSI COLOR LOGGER CONFIGURATION
+#
+# Format for AnsiColorLogger.*=
+#  Attribute;Foreground;Background
+#
+#  Attribute is one of the following:
+#  0 -> Reset All Attributes (return to normal mode)
+#  1 -> Bright (Usually turns on BOLD)
+#  2 -> Dim
+#  3 -> Underline
+#  5 -> link
+#  7 -> Reverse
+#  8 -> Hidden
+#  
+#  Foreground is one of the following:
+#  30 -> Black
+#  31 -> Red
+#  32 -> Green
+#  33 -> Yellow
+#  34 -> Blue
+#  35 -> Magenta
+#  36 -> Cyan
+#  37 -> White
+#
+#  Background is one of the following:
+#  40 -> Black
+#  41 -> Red
+#  42 -> Green
+#  43 -> Yellow
+#  44 -> Blue
+#  45 -> Magenta
+#  46 -> Cyan
+#  47 -> White
+#
+####################################################
+
+AnsiColorLogger.ERROR_COLOR=2;31
+AnsiColorLogger.WARNING_COLOR=2;35
+AnsiColorLogger.INFO_COLOR=2;36
+AnsiColorLogger.VERBOSE_COLOR=2;32
+AnsiColorLogger.DEBUG_COLOR=2;34
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/mappers/FileNameMapper.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/mappers/FileNameMapper.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/mappers/FileNameMapper.php	(revision 19)
@@ -0,0 +1,59 @@
+<?php
+/* 
+ *  $Id: FileNameMapper.php 123 2006-09-14 20:19:08Z mrook $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>. 
+ */
+
+/**
+ * Interface for filename mapper classes.
+ *
+ * @author Andreas Aderhold, andi@binarycloud.com
+ * @author Hans Lellelid <hans@xmpl.org>
+ * @version $Revision: 1.7 $
+ * @package phing.mappers
+ */
+interface FileNameMapper {
+
+    /**
+     * The mapper implementation.
+     *
+     * @param mixed $sourceFileName The data the mapper works on.
+     * @return  array The data after the mapper has been applied; must be in array format (for some reason).
+     */
+    public function main($sourceFileName);
+
+    /**
+     * Accessor. Sets the to property. The actual implementation
+     * depends on the child class.
+     *
+     * @param string $to To what this mapper should convert the from string
+     * @return void
+     */
+    public function setTo($to);
+
+    /**
+     * Accessor. Sets the from property. What this mapper should
+     * recognize. The actual implementation is dependent upon the
+     * child class
+     *
+     * @param string $from On what this mapper should work
+     * @return void
+     */
+    public function setFrom($from);
+
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/mappers/FlattenMapper.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/mappers/FlattenMapper.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/mappers/FlattenMapper.php	(revision 19)
@@ -0,0 +1,55 @@
+<?php
+/* 
+ *  $Id: FlattenMapper.php 123 2006-09-14 20:19:08Z mrook $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>. 
+ */
+
+require_once 'phing/mappers/FileNameMapper.php';
+
+/**
+ * Removes any directory information from the passed path.
+ *
+ * @author   Andreas Aderhold <andi@binarycloud.com>
+ * @version  $Revision: 1.9 $
+ * @package  phing.mappers
+ */
+class FlattenMapper implements FileNameMapper {
+
+    /**
+     * The mapper implementation. Returns string with source filename
+     * but without leading directory information
+     *
+     * @param string $sourceFileName The data the mapper works on
+     * @return array The data after the mapper has been applied
+     */
+    function main($sourceFileName) {
+        $f = new PhingFile($sourceFileName);
+        return array($f->getName());
+    }
+
+    /**
+     * Ignored here.
+     */
+    function setTo($to) {}
+
+    /**
+     * Ignored here.
+     */
+    function setFrom($from) {}
+
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/mappers/GlobMapper.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/mappers/GlobMapper.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/mappers/GlobMapper.php	(revision 19)
@@ -0,0 +1,113 @@
+<?php
+/* 
+ *  $Id: GlobMapper.php 123 2006-09-14 20:19:08Z mrook $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>. 
+ */
+
+include_once 'phing/mappers/FileNameMapper.php';
+
+/**
+ * description here
+ *
+ * @author   Andreas Aderhold, andi@binarycloud.com
+ * @version  $Revision: 1.10 $
+ * @package   phing.mappers
+ */
+class GlobMapper implements FileNameMapper {
+
+    /**
+     * Part of &quot;from&quot; pattern before the *.
+     */
+    private $fromPrefix = null;
+
+    /**
+     * Part of &quot;from&quot; pattern after the *.
+     */
+    private $fromPostfix = null;
+
+    /**
+     * Length of the prefix (&quot;from&quot; pattern).
+     */
+    private $prefixLength;
+
+    /**
+     * Length of the postfix (&quot;from&quot; pattern).
+     */
+    private $postfixLength;
+
+    /**
+     * Part of &quot;to&quot; pattern before the *.
+     */
+    private $toPrefix = null;
+
+    /**
+     * Part of &quot;to&quot; pattern after the *.
+     */
+    private $toPostfix = null;
+
+
+    function main($_sourceFileName) {
+        if (($this->fromPrefix === null)
+            || !StringHelper::startsWith($this->fromPrefix, $_sourceFileName)
+            || !StringHelper::endsWith($this->fromPostfix, $_sourceFileName)) {
+            return null;
+        }
+        $varpart = $this->_extractVariablePart($_sourceFileName);
+        $substitution = $this->toPrefix.$varpart.$this->toPostfix;
+        return array($substitution);
+    }
+
+
+
+   function setFrom($from) {
+        $index = strrpos($from, '*');
+
+        if ($index === false) {
+            $this->fromPrefix = $from;
+            $this->fromPostfix = "";
+        } else {
+            $this->fromPrefix  = substr($from, 0, $index);
+            $this->fromPostfix = substr($from, $index+1);
+        }
+        $this->prefixLength  = strlen($this->fromPrefix);
+        $this->postfixLength = strlen($this->fromPostfix);
+    }
+
+    /**
+     * Sets the &quot;to&quot; pattern. Required.
+     */
+    function setTo($to) {
+        $index = strrpos($to, '*');
+        if ($index === false) {
+            $this->toPrefix = $to;
+            $this->toPostfix = "";
+        } else {
+            $this->toPrefix  = substr($to, 0, $index);
+            $this->toPostfix = substr($to, $index+1);
+        }
+    }
+
+    private function _extractVariablePart($_name) {
+        // ergh, i really hate php's string functions .... all but natural
+        $start = ($this->prefixLength === 0) ? 0 : $this->prefixLength;
+        $end   = ($this->postfixLength === 0) ? strlen($_name) : strlen($_name) - $this->postfixLength;
+        $len   = $end-$start;
+        return substr($_name, $start, $len);
+    }
+
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/mappers/IdentityMapper.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/mappers/IdentityMapper.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/mappers/IdentityMapper.php	(revision 19)
@@ -0,0 +1,54 @@
+<?php
+/* 
+ *  $Id: IdentityMapper.php 123 2006-09-14 20:19:08Z mrook $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>. 
+ */
+
+require_once 'phing/mappers/FileNameMapper.php';
+
+/**
+ * This mapper does nothing ;)
+ * 
+ * @author    Andreas Aderhold <andi@binarycloud.com>
+ * @author    Hans Lellelid <hans@xmpl.org>
+ * @version   $Revision: 1.7 $
+ * @package   phing.mappers
+ */
+class IdentityMapper implements FileNameMapper {
+
+    /**
+     * The mapper implementation. Basically does nothing in this case.
+     *
+     * @param  string $sourceFileName The data the mapper works on.
+     * @return array The data after the mapper has been applied
+     */
+    function main($sourceFileName) {
+        return array($sourceFileName);
+    }
+
+    /**
+     * Ignored here.
+     */
+    function setTo($to) {}
+
+    /**
+     * Ignored here.
+     */
+    function setFrom($from) {}
+
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/mappers/MergeMapper.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/mappers/MergeMapper.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/mappers/MergeMapper.php	(revision 19)
@@ -0,0 +1,69 @@
+<?php
+/* 
+ *  $Id: MergeMapper.php 123 2006-09-14 20:19:08Z mrook $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>. 
+ */
+
+include_once 'phing/mappers/FileNameMapper.php';
+
+/**
+ * For merging files into a single file.  In practice just returns whatever value
+ * was set for "to".
+ *
+ * @author    Andreas Aderhold <andi@binarycloud.com>
+ * @version   $Revision: 1.8 $
+ * @package   phing.mappers
+ */
+class MergeMapper implements FileNameMapper {
+    
+    /** the merge */
+    private $mergedFile;
+
+    /**
+     * The mapper implementation. Basically does nothing in this case.
+     *
+     * @param    mixed     The data the mapper works on
+     * @returns  mixed     The data after the mapper has been applied
+     * @access   public
+     * @author   Andreas Aderhold, andi@binarycloud.com
+     */
+    function main($sourceFileName) {
+        if ($this->mergedFile === null) {            
+            throw new BuildException("MergeMapper error, to attribute not set");            
+        }         
+        return array($this->mergedFile);
+    }
+
+    /**
+     * Accessor. Sets the to property
+     *
+     * @param    string     To what this mapper should convert the from string
+     * @returns  boolean    True
+     * @access   public
+     * @author   Andreas Aderhold, andi@binarycloud.com
+     */
+    function setTo($to) {
+        $this->mergedFile = $to;
+    }    
+
+    /**
+     * Ignored.
+     */
+    function setFrom($from) {}
+
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/mappers/RegexpMapper.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/mappers/RegexpMapper.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/mappers/RegexpMapper.php	(revision 19)
@@ -0,0 +1,97 @@
+<?php
+/* 
+ *  $Id: RegexpMapper.php 123 2006-09-14 20:19:08Z mrook $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>. 
+ */
+
+require_once 'phing/mappers/FileNameMapper.php';
+include_once 'phing/util/StringHelper.php';
+include_once 'phing/util/regexp/Regexp.php';
+
+/**
+ * Uses regular expressions to perform filename transformations.
+ *
+ * @author Andreas Aderhold <andi@binarycloud.com>
+ * @author Hans Lellelid <hans@velum.net>
+ * @version $Revision: 1.9 $
+ * @package phing.mappers
+ */
+class RegexpMapper implements FileNameMapper {
+
+    /**
+     * @var string
+     */
+    private $to;
+    
+    /**
+     * The Regexp engine.
+     * @var Regexp
+     */
+    private $reg;
+
+    function __construct() {                
+        // instantiage regexp matcher here
+        $this->reg = new Regexp();
+    }
+
+    /**
+     * Sets the &quot;from&quot; pattern. Required.
+     */
+    function setFrom($from) {
+        $this->reg->SetPattern($from);
+    }
+
+    /**
+     * Sets the &quot;to&quot; pattern. Required.
+     */
+    function setTo($to) {
+    
+        // [HL] I'm changing the way this works for now to just use string
+        //$this->to = StringHelper::toCharArray($to);
+        
+        $this->to = $to;
+    }
+
+    function main($sourceFileName) {
+        if ($this->reg === null  || $this->to === null || !$this->reg->matches((string) $sourceFileName)) {
+            return null;
+        }
+        return array($this->replaceReferences($sourceFileName));
+    }
+
+    /**
+     * Replace all backreferences in the to pattern with the matched groups.
+     * groups of the source.
+     * @param string $source The source filename.
+     */
+    private function replaceReferences($source) {
+        
+        // FIXME
+        // Can't we just use engine->replace() to handle this?  the Preg engine
+        // will automatically convert \1 references to $1
+        
+        // the expression has already been processed (when ->matches() was run in Main())
+        // so no need to pass $source again to the engine.
+        $groups = (array) $this->reg->getGroups();            
+        
+        // replace \1 with value of $groups[1] and return the modified "to" string
+        return preg_replace('/\\\([\d]+)/e', "\$groups[$1]", $this->to);            
+    }
+    
+}
+
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/parser/AbstractHandler.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/parser/AbstractHandler.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/parser/AbstractHandler.php	(revision 19)
@@ -0,0 +1,98 @@
+<?php
+
+/*
+ * $Id: AbstractHandler.php 123 2006-09-14 20:19:08Z mrook $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+include_once 'phing/parser/ExpatParseException.php';
+
+/**
+ * This is an abstract class all SAX handler classes must extend
+ *
+ * @author    Andreas Aderhold <andi@binarycloud.com>
+ * @copyright © 2001,2002 THYRELL. All rights reserved
+ * @version   $Revision: 1.6 $
+ * @package   phing.parser
+ */
+abstract class AbstractHandler {
+
+    public $parentHandler = null;
+    public $parser = null;
+
+    /**
+     * Constructs a SAX handler parser.
+     *
+     * The constructor must be called by all derived classes.
+     *
+     * @param   object  the parser object
+     * @param   object  the parent handler of this handler
+     */
+    protected function __construct($parser, $parentHandler) {
+        $this->parentHandler = $parentHandler;
+        $this->parser = $parser;
+        $this->parser->setHandler($this);
+    }
+        
+    /**
+     * Gets invoked when a XML open tag occurs
+     *
+     * Must be overloaded by the child class. Throws an ExpatParseException
+     * if there is no handler registered for an element.
+     *
+     * @param  string  the name of the XML element
+     * @param  array   the attributes of the XML element
+     */
+    public function startElement($name, $attribs) {
+        throw new ExpatParseException("Unexpected element $name");
+    }
+
+    /**
+     * Gets invoked when element closes method.
+     *
+     */
+    protected function finished() {}
+
+    /**
+     * Gets invoked when a XML element ends.
+     *
+     * Can be overloaded by the child class. But should not. It hands
+     * over control to the parentHandler of this.
+     *
+     * @param  string  the name of the XML element
+     */
+    public function endElement($name) {
+        $this->finished();        
+        $this->parser->setHandler($this->parentHandler);
+    }
+
+    /**
+     * Invoked by occurance of #PCDATA.
+     *
+     * @param     string  the name of the XML element
+     * @exception ExpatParserException if there is no CDATA but method
+     *            was called
+     * @access    public
+     */
+    public function characters($data) {
+        $s = trim($data);
+        if (strlen($s) > 0) {
+            throw new ExpatParseException("Unexpected text '$s'", $this->parser->getLocation());
+        }
+    }
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/parser/AbstractSAXParser.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/parser/AbstractSAXParser.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/parser/AbstractSAXParser.php	(revision 19)
@@ -0,0 +1,116 @@
+<?php
+/*
+ *  $Id: AbstractSAXParser.php 322 2007-12-20 03:00:35Z hans $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+/**
+ * The abstract SAX parser class.
+ *
+ * This class represents a SAX parser. It is a abstract calss that must be
+ * implemented by the real parser that must extend this class
+ *
+ * @author    Andreas Aderhold <andi@binarycloud.com>
+ * @author    Hans Lellelid <hans@xmpl.org>
+ * @copyright ï¿œ 2001,2002 THYRELL. All rights reserved
+ * @version   $Revision: 1.13 $
+ * @package   phing.parser
+ */
+abstract class AbstractSAXParser {
+    
+    /** The AbstractHandler object. */
+    protected $handler;
+
+    /**
+     * Constructs a SAX parser
+     */
+    function __construct() {}
+
+    /**
+     * Sets options for PHP interal parser. Must be implemented by the parser
+     * class if it should be used.
+     */
+    abstract function parserSetOption($opt, $val);
+
+    /**
+     * Sets the current element handler object for this parser. Usually this
+     * is an object using extending "AbstractHandler".
+     *
+     * @param AbstractHandler $obj The handler object.
+     */
+    function setHandler( $obj) {
+        $this->handler = $obj;
+    }
+
+    /**
+     * Method that gets invoked when the parser runs over a XML start element.
+     *
+     * This method is called by PHP's internal parser functions and registered
+     * in the actual parser implementation.
+     * It gives control to the current active handler object by calling the
+     * <code>startElement()</code> method.
+     * 
+     * @param  object  the php's internal parser handle
+     * @param  string  the open tag name
+     * @param  array   the tag's attributes if any
+     * @throws Exception - Exceptions may be thrown by the Handler
+     */
+    function startElement($parser, $name, $attribs) {
+        $this->handler->startElement($name, $attribs);
+    }
+
+    /**
+     * Method that gets invoked when the parser runs over a XML close element.
+     *
+     * This method is called by PHP's internal parser funcitons and registered
+     * in the actual parser implementation.
+     *
+     * It gives control to the current active handler object by calling the
+     * <code>endElement()</code> method.
+     *
+     * @param   object  the php's internal parser handle
+     * @param   string  the closing tag name
+     * @throws Exception - Exceptions may be thrown by the Handler
+     */
+    function endElement($parser, $name) {
+        $this->handler->endElement($name);
+    }
+
+    /**
+     * Method that gets invoked when the parser runs over CDATA.
+     *
+     * This method is called by PHP's internal parser functions and registered
+     * in the actual parser implementation.
+     *
+     * It gives control to the current active handler object by calling the
+     * <code>characters()</code> method. That processes the given CDATA.
+     *
+     * @param resource $parser php's internal parser handle.
+     * @param string $data the CDATA
+     * @throws Exception - Exceptions may be thrown by the Handler
+     */
+    function characters($parser, $data) {
+		$this->handler->characters($data);
+    }
+
+    /**
+     * Entrypoint for parser. This method needs to be implemented by the
+     * child classt that utilizes the concrete parser
+     */
+    abstract function parse();
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/parser/DataTypeHandler.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/parser/DataTypeHandler.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/parser/DataTypeHandler.php	(revision 19)
@@ -0,0 +1,144 @@
+<?php
+/*
+ *  $Id: DataTypeHandler.php 123 2006-09-14 20:19:08Z mrook $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+include_once 'phing/RuntimeConfigurable.php';
+
+/**
+ * Configures a Project (complete with Targets and Tasks) based on
+ * a XML build file.
+ * <p>
+ * Design/ZE2 migration note:
+ * If PHP would support nested classes. All the phing/parser/*Filter
+ * classes would be nested within this class
+ *
+ * @author      Andreas Aderhold <andi@binarycloud.com>
+ * @copyright © 2001,2002 THYRELL. All rights reserved
+ * @version   $Revision: 1.8 $ $Date: 2006-09-14 20:19:08 +0000 (Thu, 14 Sep 2006) $
+ * @access    public
+ * @package   phing.parser
+ */
+
+class DataTypeHandler extends AbstractHandler {
+
+    private $target;
+    private $element;
+    private $wrapper;
+
+    /**
+     * Constructs a new DataTypeHandler and sets up everything.
+     *
+     * @param AbstractSAXParser $parser The XML parser (default: ExpatParser)
+     * @param AbstractHandler $parentHandler The parent handler that invoked this handler.
+     * @param ProjectConfigurator $configurator The ProjectConfigurator object
+     * @param Target $target The target object this datatype is contained in (null for top-level datatypes).
+     */
+    function __construct(AbstractSAXParser $parser, AbstractHandler $parentHandler, ProjectConfigurator $configurator, $target = null) { // FIXME b2 typehinting
+        parent::__construct($parser, $parentHandler);
+        $this->target = $target;
+        $this->configurator = $configurator;
+    }
+
+    /**
+     * Executes initialization actions required to setup the data structures
+     * related to the tag.
+     * <p>
+     * This includes:
+     * <ul>
+     * <li>creation of the datatype object</li>
+     * <li>calling the setters for attributes</li>
+     * <li>adding the type to the target object if any</li>
+     * <li>adding a reference to the task (if id attribute is given)</li>
+         * </ul>
+     *
+     * @param  string  the tag that comes in
+     * @param  array   attributes the tag carries
+     * @throws ExpatParseException if attributes are incomplete or invalid
+     * @access public
+     */
+    function init($propType, $attrs) {
+        // shorthands
+        $project = $this->configurator->project;
+        $configurator = $this->configurator;
+
+        try {//try
+            $this->element = $project->createDataType($propType);
+
+            if ($this->element === null) {
+                throw new BuildException("Unknown data type $propType");
+            }
+
+            if ($this->target !== null) {
+                $this->wrapper = new RuntimeConfigurable($this->element, $propType);
+                $this->wrapper->setAttributes($attrs);
+                $this->target->addDataType($this->wrapper);
+            } else {
+                $configurator->configure($this->element, $attrs, $project);
+                $configurator->configureId($this->element, $attrs);
+            }
+
+        } catch (BuildException $exc) {
+            throw new ExpatParseException($exc, $this->parser->getLocation());
+        }
+    }
+
+    /**
+     * Handles character data.
+     *
+     * @param  string  the CDATA that comes in
+     * @access public
+     */
+    function characters($data) {
+        $project = $this->configurator->project;
+        try {//try
+            $this->configurator->addText($project, $this->element, $data);
+        } catch (BuildException $exc) {
+            throw new ExpatParseException($exc->getMessage(), $this->parser->getLocation());
+        }
+    }
+
+    /**
+     * Checks for nested tags within the current one. Creates and calls
+     * handlers respectively.
+     *
+     * @param  string  the tag that comes in
+     * @param  array   attributes the tag carries
+     * @access public
+     */
+    function startElement($name, $attrs) {
+        $nef = new NestedElementHandler($this->parser, $this, $this->configurator, $this->element, $this->wrapper, $this->target);
+        $nef->init($name, $attrs);
+    }
+    
+   /**
+    * Overrides endElement for data types. Tells the type
+    * handler that processing the element had been finished so
+    * handlers know they can perform actions that need to be
+    * based on the data contained within the element.
+    *
+    * @param  string  the name of the XML element
+    * @return void
+    */
+   function endElement($name) {
+       $this->element->parsingComplete();
+       parent::endElement($name);
+   }
+         
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/parser/ExpatParseException.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/parser/ExpatParseException.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/parser/ExpatParseException.php	(revision 19)
@@ -0,0 +1,31 @@
+<?php
+/*
+ *  $Id: ExpatParseException.php 123 2006-09-14 20:19:08Z mrook $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>. 
+ */
+ 
+require_once 'phing/BuildException.php';
+
+/**
+ * This class throws errors for Expat, the XML processor.
+ *
+ * @author   Andreas Aderhold, andi@binarycloud.com
+ * @version  $Revision: 1.5 $ $Date: 2006-09-14 20:19:08 +0000 (Thu, 14 Sep 2006) $
+ * @package  phing.parser
+ */
+class ExpatParseException extends BuildException {}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/parser/ExpatParser.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/parser/ExpatParser.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/parser/ExpatParser.php	(revision 19)
@@ -0,0 +1,140 @@
+<?php
+/*
+ *  $Id: ExpatParser.php 123 2006-09-14 20:19:08Z mrook $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+ 
+require_once 'phing/parser/AbstractSAXParser.php';
+include_once 'phing/parser/ExpatParseException.php';
+include_once 'phing/system/io/IOException.php';
+include_once 'phing/system/io/FileReader.php';
+
+/**
+ * This class is a wrapper for the PHP's internal expat parser.
+ *
+ * It takes an XML file represented by a abstract path name, and starts
+ * parsing the file and calling the different "trap" methods inherited from
+ * the AbstractParser class.
+ *
+ * Those methods then invoke the represenatative methods in the registered
+ * handler classes.
+ *
+ * @author      Andreas Aderhold <andi@binarycloud.com>
+ * @copyright © 2001,2002 THYRELL. All rights reserved
+ * @version   $Revision: 1.8 $ $Date: 2006-09-14 20:19:08 +0000 (Thu, 14 Sep 2006) $
+ * @access    public
+ * @package   phing.parser
+ */
+
+class ExpatParser extends AbstractSAXParser {
+    
+    /** @var resource */
+    private $parser;
+    
+    /** @var Reader */
+    private $reader;
+    
+    private $file;
+    
+    private $buffer = 4096;
+    
+    private $error_string = "";
+    
+    private $line = 0;
+    
+    /** @var Location Current cursor pos in XML file. */
+    private $location;
+
+    /**
+     * Constructs a new ExpatParser object.
+     *
+     * The constructor accepts a PhingFile object that represents the filename
+     * for the file to be parsed. It sets up php's internal expat parser
+     * and options.
+     *
+     * @param Reader $reader  The Reader Object that is to be read from.
+     * @param string $filename Filename to read.
+     * @throws Exception if the given argument is not a PhingFile object
+     */
+    function __construct(Reader $reader, $filename=null) {
+
+        $this->reader = $reader;
+        if ($filename !== null) {
+            $this->file = new PhingFile($filename);
+        }
+        $this->parser = xml_parser_create();
+        $this->buffer = 4096;
+        $this->location = new Location();
+        xml_set_object($this->parser, $this);
+        xml_set_element_handler($this->parser, array($this,"startElement"),array($this,"endElement"));
+        xml_set_character_data_handler($this->parser, array($this, "characters"));
+    }
+
+    /**
+     * Override PHP's parser default settings, created in the constructor.
+     *
+     * @param  string  the option to set
+     * @throws mixed   the value to set
+     * @return boolean true if the option could be set, otherwise false
+     * @access public
+     */
+    function parserSetOption($opt, $val) {
+        return xml_parser_set_option($this->parser, $opt, $val);
+    }
+
+    /**
+     * Returns the location object of the current parsed element. It describes
+     * the location of the element within the XML file (line, char)
+     *
+     * @return object  the location of the current parser
+     * @access public
+     */
+    function getLocation() {
+        if ($this->file !== null) {
+            $path = $this->file->getAbsolutePath();
+        } else {
+            $path = $this->reader->getResource();
+        }
+        $this->location = new Location($path, xml_get_current_line_number($this->parser), xml_get_current_column_number($this->parser));
+        return $this->location;
+    }
+
+    /**
+     * Starts the parsing process.
+     *
+     * @param  string  the option to set
+     * @return int     1 if the parsing succeeded
+     * @throws ExpatParseException if something gone wrong during parsing
+     * @throws IOException if XML file can not be accessed
+     * @access public
+     */
+    function parse() {
+    
+        while ( ($data = $this->reader->read()) !== -1 ) {            
+            if (!xml_parse($this->parser, $data, $this->reader->eof())) {
+                $error = xml_error_string(xml_get_error_code($this->parser));
+                $e = new ExpatParseException($error, $this->getLocation());
+                xml_parser_free($this->parser);                
+                throw $e;  
+            }
+        }
+        xml_parser_free($this->parser);
+        
+        return 1;
+    }
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/parser/Location.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/parser/Location.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/parser/Location.php	(revision 19)
@@ -0,0 +1,72 @@
+<?php
+/*
+ *  $Id: Location.php 123 2006-09-14 20:19:08Z mrook $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+/**
+ * Stores the file name and line number of a XML file
+ *
+ * @author      Andreas Aderhold <andi@binarycloud.com>
+ * @copyright © 2001,2002 THYRELL. All rights reserved
+ * @version   $Revision: 1.6 $ $Date: 2006-09-14 20:19:08 +0000 (Thu, 14 Sep 2006) $
+ * @access    public
+ * @package   phing.parser
+ */
+
+class Location {
+
+    private $fileName;
+    private $lineNumber;
+    private $columnNumber;
+
+    /**
+     * Constructs the location consisting of a file name and line number
+     *
+     * @param  string  the filename
+     * @param  integer the line number
+     * @param  integer the column number
+     * @access public
+     */
+    function Location($fileName = null, $lineNumber = null, $columnNumber = null) {
+        $this->fileName = $fileName;
+        $this->lineNumber = $lineNumber;
+        $this->columnNumber = $columnNumber;
+    }
+
+    /**
+     * Returns the file name, line number and a trailing space.
+     *
+     * An error message can be appended easily. For unknown locations,
+     * returns empty string.
+     *
+     * @return string the string representation of this Location object
+     * @access public
+     */
+    function toString() {
+        $buf = "";
+        if ($this->fileName !== null) {
+            $buf.=$this->fileName;
+            if ($this->lineNumber !== null) {
+                $buf.= ":".$this->lineNumber;
+            }
+            $buf.=":".$this->columnNumber;
+        }
+        return (string) $buf;
+    }
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/parser/NestedElementHandler.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/parser/NestedElementHandler.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/parser/NestedElementHandler.php	(revision 19)
@@ -0,0 +1,186 @@
+<?php
+/*
+ *  $Id: NestedElementHandler.php 123 2006-09-14 20:19:08Z mrook $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+include_once 'phing/IntrospectionHelper.php';
+include_once 'phing/TaskContainer.php';
+
+/**
+ * The nested element handler class.
+ *
+ * This class handles the occurance of runtime registered tags like
+ * datatypes (fileset, patternset, etc) and it's possible nested tags. It
+ * introspects the implementation of the class and sets up the data structures.
+ *
+ * @author      Andreas Aderhold <andi@binarycloud.com>
+ * @copyright © 2001,2002 THYRELL. All rights reserved
+ * @version   $Revision: 1.10 $ $Date: 2006-09-14 20:19:08 +0000 (Thu, 14 Sep 2006) $
+ * @access    public
+ * @package   phing.parser
+ */
+
+class NestedElementHandler extends AbstractHandler {
+
+    /**
+     * Reference to the parent object that represents the parent tag
+     * of this nested element
+     * @var object
+     */
+    private $parent;
+
+    /**
+     * Reference to the child object that represents the child tag
+     * of this nested element
+     * @var object
+     */
+    private $child;
+
+    /**
+     *  Reference to the parent wrapper object
+     *  @var object
+     */
+    private $parentWrapper;
+
+    /**
+     *  Reference to the child wrapper object
+     *  @var object
+     */
+    private $childWrapper;
+
+    /**
+     *  Reference to the related target object
+     *  @var object the target instance
+     */
+    private $target;
+
+    /**
+     *  Constructs a new NestedElement handler and sets up everything.
+     *
+     *  @param  object  the ExpatParser object
+     *  @param  object  the parent handler that invoked this handler
+     *  @param  object  the ProjectConfigurator object
+     *  @param  object  the parent object this element is contained in
+     *  @param  object  the parent wrapper object
+     *  @param  object  the target object this task is contained in
+     *  @access public
+     */
+    function __construct($parser, $parentHandler, $configurator, $parent, $parentWrapper, $target) {
+        parent::__construct($parser, $parentHandler);
+        $this->configurator = $configurator;
+        if ($parent instanceof TaskAdapter) {
+            $this->parent = $parent->getProxy();
+        } else {
+            $this->parent = $parent;
+        }
+        $this->parentWrapper = $parentWrapper;
+        $this->target = $target;        
+    }
+
+    /**
+     * Executes initialization actions required to setup the data structures
+     * related to the tag.
+     * <p>
+     * This includes:
+     * <ul>
+     * <li>creation of the nested element</li>
+     * <li>calling the setters for attributes</li>
+     * <li>adding the element to the container object</li>
+     * <li>adding a reference to the element (if id attribute is given)</li>
+         * </ul>
+     *
+     * @param  string  the tag that comes in
+     * @param  array   attributes the tag carries
+     * @throws ExpatParseException if the setup process fails
+     * @access public
+     */
+    function init($propType, $attrs) {
+        $configurator = $this->configurator;
+        $project = $this->configurator->project;
+
+        // introspect the parent class that is custom
+        $parentClass = get_class($this->parent);
+        $ih = IntrospectionHelper::getHelper($parentClass);
+        try {
+            if ($this->parent instanceof UnknownElement) {
+                $this->child = new UnknownElement(strtolower($propType));
+                $this->parent->addChild($this->child);
+            } else {                
+                $this->child = $ih->createElement($project, $this->parent, strtolower($propType));
+            }
+            
+            $configurator->configureId($this->child, $attrs);
+            
+            if ($this->parentWrapper !== null) {
+                $this->childWrapper = new RuntimeConfigurable($this->child, $propType);
+                $this->childWrapper->setAttributes($attrs);
+                $this->parentWrapper->addChild($this->childWrapper);
+            } else {
+                $configurator->configure($this->child, $attrs, $project);
+                $ih->storeElement($project, $this->parent, $this->child, strtolower($propType));
+            }
+        } catch (BuildException $exc) {
+            throw new ExpatParseException("Error initializing nested element <$propType>", $exc, $this->parser->getLocation());
+        }
+    }
+
+    /**
+     * Handles character data.
+     *
+     * @param  string  the CDATA that comes in
+     * @throws ExpatParseException if the CDATA could not be set-up properly
+     * @access public
+     */
+    function characters($data) {
+
+        $configurator = $this->configurator;        
+        $project = $this->configurator->project;
+
+        if ($this->parentWrapper === null) {
+            try {                
+                $configurator->addText($project, $this->child, $data);
+            } catch (BuildException $exc) {
+                throw new ExpatParseException($exc->getMessage(), $this->parser->getLocation());
+            }
+        } else {                    
+            $this->childWrapper->addText($data);
+        }
+    }
+
+    /**
+     * Checks for nested tags within the current one. Creates and calls
+     * handlers respectively.
+     *
+     * @param  string  the tag that comes in
+     * @param  array   attributes the tag carries
+     * @access public
+     */
+    function startElement($name, $attrs) {
+        //print(get_class($this) . " name = $name, attrs = " . implode(",",$attrs) . "\n");
+		if ($this->child instanceof TaskContainer) {
+                // taskcontainer nested element can contain other tasks - no other
+                // nested elements possible
+			$tc = new TaskHandler($this->parser, $this, $this->configurator, $this->child, $this->childWrapper, $this->target);
+			$tc->init($name, $attrs);
+		} else {
+			$neh = new NestedElementHandler($this->parser, $this, $this->configurator, $this->child, $this->childWrapper, $this->target);
+        	$neh->init($name, $attrs);
+		}
+    }
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/parser/ProjectConfigurator.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/parser/ProjectConfigurator.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/parser/ProjectConfigurator.php	(revision 19)
@@ -0,0 +1,245 @@
+<?php
+/*
+ * $Id: ProjectConfigurator.php 147 2007-02-06 20:32:22Z hans $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+include_once 'phing/system/io/BufferedReader.php';
+include_once 'phing/system/io/FileReader.php';
+include_once 'phing/BuildException.php';
+include_once 'phing/system/lang/FileNotFoundException.php';
+include_once 'phing/system/io/PhingFile.php';
+
+/**
+ * The datatype handler class.
+ *
+ * This class handles the occurance of registered datatype tags like
+ * FileSet
+ *
+ * @author      Andreas Aderhold <andi@binarycloud.com>
+ * @copyright ï¿œ 2001,2002 THYRELL. All rights reserved
+ * @version   $Revision: 1.17 $ $Date: 2007-02-06 20:32:22 +0000 (Tue, 06 Feb 2007) $
+ * @access    public
+ * @package   phing.parser
+ */
+class ProjectConfigurator {
+
+    public $project;
+    public $locator;
+    
+    public $buildFile;
+    public $buildFileParent;
+        
+    /**
+     * Static call to ProjectConfigurator. Use this to configure a
+     * project. Do not use the new operator.
+     *
+     * @param  object  the Project instance this configurator should use
+     * @param  object  the buildfile object the parser should use
+     * @access public
+     */
+    public static function configureProject(Project $project, PhingFile $buildFile) {
+        $pc = new ProjectConfigurator($project, $buildFile);
+        $pc->parse();
+    }
+
+    /**
+     * Constructs a new ProjectConfigurator object
+     * This constructor is private. Use a static call to
+     * <code>configureProject</code> to configure a project.
+     *
+     * @param  object  the Project instance this configurator should use
+     * @param  object  the buildfile object the parser should use
+     * @access private
+     */
+    function __construct(Project $project, PhingFile $buildFile) {
+        $this->project = $project;
+        $this->buildFile = new PhingFile($buildFile->getAbsolutePath());
+        $this->buildFileParent = new PhingFile($this->buildFile->getParent());
+    }
+
+    /**
+     * Creates the ExpatParser, sets root handler and kick off parsing
+     * process.
+     *
+     * @throws BuildException if there is any kind of execption during
+     *         the parsing process
+     * @access private
+     */
+    protected function parse() {
+        try {
+            $reader = new BufferedReader(new FileReader($this->buildFile));
+            $parser = new ExpatParser($reader);
+            $parser->parserSetOption(XML_OPTION_CASE_FOLDING,0);
+            $parser->setHandler(new RootHandler($parser, $this));
+            $this->project->log("parsing buildfile ".$this->buildFile->getName(), Project::MSG_VERBOSE);
+            $parser->parse();
+            $reader->close();
+        } catch (Exception $exc) {
+            throw new BuildException("Error reading project file", $exc);
+        }
+    }
+
+    /**
+     * Configures an element and resolves eventually given properties.
+     *
+     * @param  object  the element to configure
+     * @param  array   the element's attributes
+     * @param  object  the project this element belongs to
+     * @throws Exception if arguments are not valid
+     * @throws BuildException if attributes can not be configured
+     * @access public
+     */
+    public static function configure($target, $attrs, Project $project) {               
+
+        if ($target instanceof TaskAdapter) {
+            $target = $target->getProxy();
+        }
+        
+		// if the target is an UnknownElement, this means that the tag had not been registered
+		// when the enclosing element (task, target, etc.) was configured.  It is possible, however, 
+		// that the tag was registered (e.g. using <taskdef>) after the original configuration.
+		// ... so, try to load it again:
+		if ($target instanceof UnknownElement) {
+			$tryTarget = $project->createTask($target->getTaskType());
+			if ($tryTarget) {
+				$target = $tryTarget;
+			}
+		}
+
+        $bean = get_class($target);
+        $ih = IntrospectionHelper::getHelper($bean);
+
+        foreach ($attrs as $key => $value) {
+            if ($key == 'id') {
+                continue;
+                // throw new BuildException("Id must be set Extermnally");
+            }            
+            $value = self::replaceProperties($project, $value, $project->getProperties());
+            try { // try to set the attribute
+                $ih->setAttribute($project, $target, strtolower($key), $value);
+            } catch (BuildException $be) {
+                // id attribute must be set externally
+                if ($key !== "id") {
+                    throw $be;
+                }
+            }
+        }
+    }
+
+    /**
+     * Configures the #CDATA of an element.
+     *
+     * @param  object  the project this element belongs to
+     * @param  object  the element to configure
+     * @param  string  the element's #CDATA
+     * @access public
+     */
+    public static function addText($project, $target, $text = null) {
+        if ($text === null || strlen(trim($text)) === 0) {
+            return;
+        }    
+        $ih = IntrospectionHelper::getHelper(get_class($target));
+        $text = self::replaceProperties($project, $text, $project->getProperties());
+        $ih->addText($project, $target, $text);
+    }
+
+    /**
+     * Stores a configured child element into its parent object
+     *
+     * @param  object  the project this element belongs to
+     * @param  object  the parent element
+     * @param  object  the child element
+     * @param  string  the XML tagname
+     * @access public
+     */
+    public static function storeChild($project, $parent, $child, $tag) {
+        $ih = IntrospectionHelper::getHelper(get_class($parent));
+        $ih->storeElement($project, $parent, $child, $tag);
+    }
+
+    // The following two properties are a sort of hack
+    // to enable a static function to serve as the callback
+    // for preg_replace_callback().  Clearly we cannot use object
+    // variables, since the replaceProperties() is called statically.
+    // This is IMO better than using global variables in the callback.
+    
+    private static $propReplaceProject;
+    private static $propReplaceProperties;
+         
+    /**
+     * Replace ${} style constructions in the given value with the
+     * string value of the corresponding data types. This method is
+     * static.
+     *
+     * @param  object  the project that should be used for property look-ups
+     * @param  string  the string to be scanned for property references
+     * @param  array   proeprty keys
+     * @return string  the replaced string or <code>null</code> if the string
+     *                 itself was null
+     */
+    public static function replaceProperties(Project $project, $value, $keys) {
+        
+        if ($value === null) {
+            return null;
+        }
+        
+        // These are a "hack" to support static callback for preg_replace_callback()
+        
+        // make sure these get initialized every time        
+        self::$propReplaceProperties = $keys;
+        self::$propReplaceProject = $project;
+        
+        // Because we're not doing anything special (like multiple passes),
+        // regex is the simplest / fastest.  PropertyTask, though, uses
+        // the old parsePropertyString() method, since it has more stringent
+        // requirements.
+        
+        $sb = preg_replace_callback('/\$\{([^}]+)\}/', array('ProjectConfigurator', 'replacePropertyCallback'), $value);
+        return $sb;        
+    }
+    
+    /**
+     * Private [static] function for use by preg_replace_callback to replace a single param.
+     * This method makes use of a static variable to hold the 
+     */
+    private static function replacePropertyCallback($matches)
+    {
+        $propertyName = $matches[1];
+        if (!isset(self::$propReplaceProperties[$propertyName])) {
+                    self::$propReplaceProject->log('Property ${'.$propertyName.'} has not been set.', Project::MSG_VERBOSE);
+                    return $matches[0];
+        } else {
+			self::$propReplaceProject->log('Property ${'.$propertyName.'} => ' . self::$propReplaceProperties[$propertyName], Project::MSG_DEBUG);
+		}
+        return self::$propReplaceProperties[$propertyName];
+    }           
+
+    /**
+     * Scan Attributes for the id attribute and maybe add a reference to
+     * project.
+     *
+     * @param object the element's object
+     * @param array  the element's attributes
+     */
+    public function configureId($target, $attr) {
+        if (isset($attr['id']) && $attr['id'] !== null) {
+            $this->project->addReference($attr['id'], $target);
+        }
+    }
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/parser/ProjectHandler.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/parser/ProjectHandler.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/parser/ProjectHandler.php	(revision 19)
@@ -0,0 +1,153 @@
+<?php
+/*
+ * $Id: ProjectHandler.php 132 2007-01-25 19:38:05Z mrook $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+require_once 'phing/parser/AbstractHandler.php';
+require_once 'phing/system/io/PhingFile.php';
+
+/**
+ * Handler class for the <project> XML element This class handles all elements
+ * under the <project> element.
+ *
+ * @author      Andreas Aderhold <andi@binarycloud.com>
+ * @copyright (c) 2001,2002 THYRELL. All rights reserved
+ * @version   $Revision: 1.14 $ $Date: 2007-01-25 19:38:05 +0000 (Thu, 25 Jan 2007) $
+ * @access    public
+ * @package   phing.parser
+ */
+class ProjectHandler extends AbstractHandler {
+
+    /**
+     * The phing project configurator object.
+     * @var ProjectConfigurator
+     */
+    private $configurator;
+
+    /**
+     * Constructs a new ProjectHandler
+     *
+     * @param  object  the ExpatParser object
+     * @param  object  the parent handler that invoked this handler
+     * @param  object  the ProjectConfigurator object
+     * @access public
+     */
+    function __construct($parser, $parentHandler, $configurator) {
+        $this->configurator = $configurator;
+        parent::__construct($parser, $parentHandler);
+    }
+
+    /**
+     * Executes initialization actions required to setup the project. Usually
+     * this method handles the attributes of a tag.
+     *
+     * @param  string  the tag that comes in
+     * @param  array   attributes the tag carries
+     * @param  object  the ProjectConfigurator object
+     * @throws ExpatParseException if attributes are incomplete or invalid
+     * @access public
+     */
+    function init($tag, $attrs) {
+        $def = null;
+        $name = null;
+        $id    = null;
+        $desc = null;
+        $baseDir = null;
+
+        // some shorthands
+        $project = $this->configurator->project;
+        $buildFileParent = $this->configurator->buildFileParent;
+
+        foreach ($attrs as $key => $value) {
+            if ($key === "default") {
+                $def = $value;
+            } elseif ($key === "name") {
+                $name = $value;
+            } elseif ($key === "id") {
+                $id = $value;
+            } elseif ($key === "basedir") {
+                $baseDir = $value;
+            } elseif ($key === "description") {
+                $desc = $value;
+            } else {
+                throw new ExpatParseException("Unexpected attribute '$key'");
+            }
+        }
+        if ($def === null) {
+            throw new ExpatParseException("The default attribute of project is required");
+        }
+        $project->setDefaultTarget($def);
+
+        if ($name !== null) {
+            $project->setName($name);
+            $project->addReference($name, $project);
+        }
+
+        if ($id !== null) {
+            $project->addReference($id, $project);
+        }
+        
+        if ($desc !== null) {
+            $project->setDescription($desc);
+        }        
+
+        if ($project->getProperty("project.basedir") !== null) {
+            $project->setBasedir($project->getProperty("project.basedir"));
+        } else {
+            if ($baseDir === null) {
+                $project->setBasedir($buildFileParent->getAbsolutePath());
+            } else {
+                // check whether the user has specified an absolute path
+                $f = new PhingFile($baseDir);
+                if ($f->isAbsolute()) {
+                    $project->setBasedir($baseDir);
+                } else {
+                    $project->setBaseDir($project->resolveFile($baseDir, $buildFileParent));
+                }
+            }
+        }
+    }
+
+    /**
+     * Handles start elements within the <project> tag by creating and
+     * calling the required handlers for the detected element.
+     *
+     * @param  string  the tag that comes in
+     * @param  array   attributes the tag carries
+     * @throws ExpatParseException if a unxepected element occurs
+     * @access public
+     */
+    function startElement($name, $attrs) {
+    
+		$project = $this->configurator->project;
+        $types = $project->getDataTypeDefinitions();
+		
+		if ($name == "target") {
+			$tf = new TargetHandler($this->parser, $this, $this->configurator);
+			$tf->init($name, $attrs);
+		} elseif (isset($types[$name])) {
+           $tyf = new DataTypeHandler($this->parser, $this, $this->configurator);
+           $tyf->init($name, $attrs);
+        } else {
+			$tf = new TaskHandler($this->parser, $this, $this->configurator);
+			$tf->init($name, $attrs);
+        }
+    }
+}
+
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/parser/RootHandler.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/parser/RootHandler.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/parser/RootHandler.php	(revision 19)
@@ -0,0 +1,82 @@
+<?php
+/*
+ *  $Id: RootHandler.php 123 2006-09-14 20:19:08Z mrook $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+require_once 'phing/parser/AbstractHandler.php';
+include_once 'phing/parser/ExpatParseException.php';
+include_once 'phing/parser/ProjectHandler.php';
+
+/**
+ * Root filter class for a phing buildfile.
+ *
+ * The root filter is called by the parser first. This is where the phing
+ * specific parsing starts. RootHandler decides what to do next.
+ *
+ * @author    Andreas Aderhold <andi@binarycloud.com>
+ * @copyright © 2001,2002 THYRELL. All rights reserved
+ * @version   $Revision: 1.7 $
+ * @package   phing.parser
+ */
+class RootHandler extends AbstractHandler {
+
+    /**
+     * The phing project configurator object
+     */
+    private $configurator;
+
+    /**
+     * Constructs a new RootHandler
+     *
+     * The root filter is required so the parser knows what to do. It's
+     * called by the ExpatParser that is instatiated in ProjectConfigurator.
+     *
+     * It recieves the expat parse object ref and a reference to the
+     * configurator
+     *
+     * @param AbstractSAXParser $parser The ExpatParser object.
+     * @param ProjectConfigurator $configurator The ProjectConfigurator object.
+     */
+    function __construct(AbstractSAXParser $parser, ProjectConfigurator $configurator) {
+        $this->configurator = $configurator;
+        parent::__construct($parser, $this);
+    }
+
+    /**
+     * Kick off a custom action for a start element tag.
+     *
+     * The root element of our buildfile is the &lt;project&gt; element. The
+     * root filter handles this element if it occurs, creates ProjectHandler 
+     * to handle any nested tags & attributes of the &lt;project&gt; tag,
+     * and calls init.
+     *
+     * @param string $tag The xml tagname
+     * @param array  $attrs The attributes of the tag
+     * @throws ExpatParseException if the first element within our build file
+     *         is not the &gt;project&lt; element
+     */
+    function startElement($tag, $attrs) {
+        if ($tag === "project") {
+            $ph = new ProjectHandler($this->parser, $this, $this->configurator);
+            $ph->init($tag, $attrs);
+        } else {
+            throw new ExpatParseException("Unexpected tag <$tag> in top-level of build file.", $this->parser->getLocation());
+        }
+    }
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/parser/TargetHandler.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/parser/TargetHandler.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/parser/TargetHandler.php	(revision 19)
@@ -0,0 +1,149 @@
+<?php
+/*
+ * $Id: TargetHandler.php 123 2006-09-14 20:19:08Z mrook $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+ 
+require_once 'phing/parser/AbstractHandler.php';
+
+/**
+ * The target handler class.
+ *
+ * This class handles the occurance of a <target> tag and it's possible
+ * nested tags (datatypes and tasks).
+ *
+ * @author    Andreas Aderhold <andi@binarycloud.com>
+ * @copyright  2001,2002 THYRELL. All rights reserved
+ * @version   $Revision: 1.10 $
+ * @package   phing.parser
+ */
+class TargetHandler extends AbstractHandler {
+
+    /**
+     * Reference to the target object that represents the currently parsed
+     * target.
+     * @var object the target instance
+     */
+    private $target;
+
+    /**
+     * The phing project configurator object
+     * @var ProjectConfigurator
+     */
+    private $configurator;
+
+    /**
+     * Constructs a new TargetHandler
+     *
+     * @param  object  the ExpatParser object
+     * @param  object  the parent handler that invoked this handler
+     * @param  object  the ProjectConfigurator object
+     */
+    function __construct(AbstractSAXParser $parser, AbstractHandler $parentHandler, ProjectConfigurator $configurator) {
+        parent::__construct($parser, $parentHandler);
+        $this->configurator = $configurator;      
+    }
+
+    /**
+     * Executes initialization actions required to setup the data structures
+     * related to the tag.
+     * <p>
+     * This includes:
+     * <ul>
+     * <li>creation of the target object</li>
+     * <li>calling the setters for attributes</li>
+     * <li>adding the target to the project</li>
+     * <li>adding a reference to the target (if id attribute is given)</li>
+     * </ul>
+     *
+     * @param  string  the tag that comes in
+     * @param  array   attributes the tag carries
+     * @throws ExpatParseException if attributes are incomplete or invalid
+     */
+    function init($tag, $attrs) {
+        $name = null;
+        $depends = "";
+        $ifCond = null;
+        $unlessCond = null;
+        $id = null;
+        $description = null;
+
+        foreach($attrs as $key => $value) {
+            if ($key==="name") {
+                $name = (string) $value;
+            } else if ($key==="depends") {
+                $depends = (string) $value;
+            } else if ($key==="if") {
+                $ifCond = (string) $value;
+            } else if ($key==="unless") {
+                $unlessCond = (string) $value;
+            } else if ($key==="id") {
+                $id = (string) $value;
+            } else if ($key==="description") {
+                $description = (string)$value;
+            } else {
+                throw new ExpatParseException("Unexpected attribute '$key'", $this->parser->getLocation());
+            }
+        }
+
+        if ($name === null) {
+            throw new ExpatParseException("target element appears without a name attribute",  $this->parser->getLocation());
+        }
+
+        // shorthand
+        $project = $this->configurator->project;
+
+        $this->target = new Target();
+        $this->target->setName($name);
+        $this->target->setIf($ifCond);
+        $this->target->setUnless($unlessCond);
+        $this->target->setDescription($description);
+
+        $project->addTarget($name, $this->target);
+
+        if ($id !== null && $id !== "") {
+            $project->addReference($id, $this->target);
+        }
+        // take care of dependencies
+        if (strlen($depends) > 0) {
+            $this->target->setDepends($depends);
+        }
+
+    }
+
+    /**
+     * Checks for nested tags within the current one. Creates and calls
+     * handlers respectively.
+     *
+     * @param  string  the tag that comes in
+     * @param  array   attributes the tag carries
+     */
+    function startElement($name, $attrs) {
+        // shorthands
+        $project = $this->configurator->project;
+        $types = $project->getDataTypeDefinitions();
+
+        if (isset($types[$name])) {
+            $th = new DataTypeHandler($this->parser, $this, $this->configurator, $this->target);
+            $th->init($name, $attrs);
+        } else {
+            $tmp = new TaskHandler($this->parser, $this, $this->configurator, $this->target, null, $this->target);
+            $tmp->init($name, $attrs);
+        }
+    }
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/parser/TaskHandler.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/parser/TaskHandler.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/parser/TaskHandler.php	(revision 19)
@@ -0,0 +1,234 @@
+<?php
+/*
+ *  $Id: TaskHandler.php 147 2007-02-06 20:32:22Z hans $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+include_once 'phing/UnknownElement.php';
+
+/**
+ * The task handler class.
+ *
+ * This class handles the occurance of a <task> tag and it's possible
+ * nested tags (datatypes and tasks) that may be unknown off bat and are
+ * initialized on the fly.
+ *
+ * @author      Andreas Aderhold <andi@binarycloud.com>
+ * @copyright ï¿œ 2001,2002 THYRELL. All rights reserved
+ * @version   $Revision: 1.10 $
+ * @package   phing.parser
+ */
+class TaskHandler extends AbstractHandler {
+
+    /**
+     * Reference to the target object that contains the currently parsed
+     * task
+     * @var object the target instance
+     */
+    private $target;
+
+    /**
+     * Reference to the target object that represents the currently parsed
+     * target. This must not necessarily be a target, hence extra variable.
+     * @var object the target instance
+     */
+    private $container;
+
+    /**
+     * Reference to the task object that represents the currently parsed
+     * target.
+     * @var Task
+     */
+    private $task;
+	
+	/**
+ 	 * Wrapper for the parent element, if any. The wrapper for this
+	 * element will be added to this wrapper as a child.
+	 * @var RuntimeConfigurable
+	 */
+	private $parentWrapper;
+	
+	/**
+	 * Wrapper for this element which takes care of actually configuring
+	 * the element, if this element is contained within a target.
+	 * Otherwise the configuration is performed with the configure method.
+	 * @see ProjectHelper::configure(Object,AttributeList,Project)
+	 */
+    private $wrapper;
+
+    /**
+     * The phing project configurator object
+     * @var ProjectConfigurator
+     */
+    private $configurator;
+
+    /**
+     * Constructs a new TaskHandler and sets up everything.
+     *
+     * @param AbstractSAXParser The ExpatParser object
+     * @param object $parentHandler The parent handler that invoked this handler
+     * @param ProjectConfigurator $configurator
+     * @param TaskContainer $container The container object this task is contained in (null for top-level tasks).
+	 * @param RuntimeConfigurable $parentWrapper  Wrapper for the parent element, if any.
+     * @param Target $target The target object this task is contained in (null for top-level tasks).
+     */
+    function __construct(AbstractSAXParser $parser, $parentHandler, ProjectConfigurator $configurator, $container = null, $parentWrapper = null, $target = null) {
+        
+        parent::__construct($parser, $parentHandler);
+    
+        if (($container !== null) && !($container instanceof TaskContainer)) {
+            throw new Exception("Argument expected to be a TaskContainer, got something else");
+        }
+		if (($parentWrapper !== null) && !($parentWrapper instanceof RuntimeConfigurable)) {
+            throw new Exception("Argument expected to be a RuntimeConfigurable, got something else.");
+        }
+        if (($target !== null) && !($target instanceof Target)) {
+            throw new Exception("Argument expected to be a Target, got something else");
+        }
+
+		$this->configurator = $configurator;
+        $this->container = $container;
+		$this->parentWrapper = $parentWrapper;
+        $this->target = $target;
+    }
+
+    /**
+     * Executes initialization actions required to setup the data structures
+     * related to the tag.
+     * <p>
+     * This includes:
+     * <ul>
+     * <li>creation of the task object</li>
+     * <li>calling the setters for attributes</li>
+     * <li>adding the task to the container object</li>
+     * <li>adding a reference to the task (if id attribute is given)</li>
+     * <li>executing the task if the container is the &lt;project&gt;
+     * element</li>
+     * </ul>
+     *
+     * @param string $tag The tag that comes in
+     * @param array $attrs Attributes the tag carries
+     * @throws ExpatParseException if attributes are incomplete or invalid
+     */
+    function init($tag, $attrs) {
+        // shorthands
+        try {
+            $configurator = $this->configurator;
+            $project = $this->configurator->project;
+            
+            $this->task = $project->createTask($tag);
+        } catch (BuildException $be) {
+            // swallow here, will be thrown again in
+            // UnknownElement->maybeConfigure if the problem persists.
+            print("Swallowing exception: ".$be->getMessage() . "\n");
+        }
+
+        // the task is not known of bat, try to load it on thy fly
+        if ($this->task === null) {
+            $this->task = new UnknownElement($tag);
+            $this->task->setProject($project);
+            $this->task->setTaskType($tag);
+            $this->task->setTaskName($tag);
+        }
+
+        // add file position information to the task (from parser)
+        // should be used in task exceptions to provide details
+        $this->task->setLocation($this->parser->getLocation());
+        $configurator->configureId($this->task, $attrs);
+		
+		if ($this->container) {
+			$this->container->addTask($this->task);
+		}
+		
+        // Top level tasks don't have associated targets
+		// FIXME: if we do like Ant 1.6 and create an implicitTarget in the projectconfigurator object
+		// then we don't need to check for null here ... but there's a lot of stuff that will break if we
+		// do that at this point.
+        if ($this->target !== null) {
+            $this->task->setOwningTarget($this->target);
+            $this->task->init();
+            $this->wrapper = $this->task->getRuntimeConfigurableWrapper();
+            $this->wrapper->setAttributes($attrs);
+            /*
+			Commenting this out as per thread on Premature configurate of ReuntimeConfigurables 
+            with Matthias Pigulla: http://phing.tigris.org/servlets/ReadMsg?list=dev&msgNo=251
+            
+			if ($this->parentWrapper !== null) { // this may not make sense only within this if-block, but it
+												// seems to address current use cases adequately
+		    	$this->parentWrapper->addChild($this->wrapper);
+			}
+			*/
+        } else {
+            $this->task->init();
+            $configurator->configure($this->task, $attrs, $project);
+        }
+    }
+
+    /**
+     * Executes the task at once if it's directly beneath the <project> tag.
+     */
+    protected function finished() {
+        if ($this->task !== null && $this->target === null && $this->container === null) {
+            try {
+                $this->task->perform();
+            } catch (Exception $e) {
+                $this->task->log($e->getMessage(), Project::MSG_ERR);
+                throw $e;
+            }
+        }
+    }
+
+    /**
+     * Handles character data.
+     *
+     * @param string $data The CDATA that comes in
+     */
+    function characters($data) {
+        if ($this->wrapper === null) {
+            $configurator = $this->configurator;
+            $project = $this->configurator->project;
+            try { // try
+                $configurator->addText($project, $this->task, $data);
+            } catch (BuildException $exc) {
+                throw new ExpatParseException($exc->getMessage(), $this->parser->getLocation());
+            }
+        } else {
+            $this->wrapper->addText($data);
+        }
+    }
+
+    /**
+     * Checks for nested tags within the current one. Creates and calls
+     * handlers respectively.
+     *
+     * @param string $name The tag that comes in
+     * @param array $attrs Attributes the tag carries
+     */
+    function startElement($name, $attrs) {
+        $project = $this->configurator->project;
+        if ($this->task instanceof TaskContainer) {
+            //print("TaskHandler::startElement() (TaskContainer) name = $name, attrs = " . implode(",",$attrs) . "\n");
+            $th = new TaskHandler($this->parser, $this, $this->configurator, $this->task, $this->wrapper, $this->target);
+            $th->init($name, $attrs);
+        } else {
+            //print("TaskHandler::startElement() name = $name, attrs = " . implode(",",$attrs) . "\n");
+            $tmp = new NestedElementHandler($this->parser, $this, $this->configurator, $this->task, $this->wrapper, $this->target);
+            $tmp->init($name, $attrs);
+        }
+    }
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/system/io/BufferedReader.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/system/io/BufferedReader.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/system/io/BufferedReader.php	(revision 19)
@@ -0,0 +1,168 @@
+<?php
+/*
+ *  $Id: BufferedReader.php 227 2007-08-28 02:17:00Z hans $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+*/
+
+include_once 'phing/system/io/Reader.php';
+
+/*
+ * Convenience class for reading files.
+ *
+ * @author    <a href="mailto:yl@seasonfive.com">Yannick Lecaillez</a>
+ * @version   $Revision: 1.6 $ $Date: 2007-08-28 02:17:00 +0000 (Tue, 28 Aug 2007) $
+ * @access    public
+ * @see       FilterReader
+ * @package   phing.system.io
+*/
+class BufferedReader extends Reader {
+
+    private $bufferSize = 0;
+    private $buffer     = null;
+    private $bufferPos  = 0;
+    
+    /**
+     * The Reader we are buffering for.
+     */
+    private $in;
+    
+    /**
+     * 
+     * @param object $reader The reader (e.g. FileReader).
+     * @param integer $buffsize The size of the buffer we should use for reading files.
+     *                             A large buffer ensures that most files (all scripts?) are parsed in 1 buffer.
+     */     
+    function __construct(Reader $reader, $buffsize = 65536) {
+        $this->in = $reader;
+        $this->bufferSize = $buffsize;
+    }
+
+    /**
+     * Reads and returns a chunk of data.
+     * @param int $len Number of bytes to read.  Default is to read configured buffer size number of bytes.
+     * @return mixed buffer or -1 if EOF.
+     */
+    function read($len = null) {
+        
+    	// if $len is specified, we'll use that; otherwise, use the configured buffer size.
+    	if ($len === null) $len = $this->bufferSize; 
+        
+        if ( ($data = $this->in->read($len)) !== -1 ) {
+		
+			// not all files end with a newline character, so we also need to check EOF
+			if (!$this->in->eof()) {
+			
+	            $notValidPart = strrchr($data, "\n");
+	            $notValidPartSize = strlen($notValidPart);
+	        
+	            if ( $notValidPartSize > 1 ) {
+	                // Block doesn't finish on a EOL
+	                // Find the last EOL and forget all following stuff
+	                $dataSize = strlen($data);
+	                $validSize = $dataSize - $notValidPartSize + 1;
+	            
+	                $data = substr($data, 0, $validSize);
+	
+	                // Rewind to the begining of the forgotten stuff.
+	                $this->in->skip(-$notValidPartSize+1);
+	            }
+				
+			} // if !EOF
+        }
+        return $data;
+    }
+    
+    function skip($n) {
+        return $this->in->skip($n);
+    }
+    
+    function reset() {
+        return $this->in->reset();
+    }
+    
+    function close() {
+        return $this->in->close();
+    }
+    
+    function open() {
+        return $this->in->open();
+    }
+    
+    /**
+     * Read a line from input stream.
+     */
+    function readLine() {
+        $line = null;
+        while ( ($ch = $this->readChar()) !== -1 ) {
+            if ( $ch === "\n" ) {
+                break;
+            }
+            $line .= $ch;
+        }
+
+        // Warning : Not considering an empty line as an EOF
+        if ( $line === null && $ch !== -1 )
+            return "";
+
+        return $line;
+    }
+    
+    /**
+     * Reads a single char from the reader.
+     * @return string single char or -1 if EOF.
+     */
+    function readChar() {        
+
+        if ( $this->buffer === null ) {
+            // Buffer is empty, fill it ...
+            $read = $this->in->read($this->bufferSize);
+            if ($read === -1) {
+                $ch = -1;
+            } else {
+                $this->buffer = $read;
+                return $this->readChar(); // recurse
+            }
+        } else {            
+            // Get next buffered char ...
+            // handle case where buffer is read-in, but is empty.  The next readChar() will return -1 EOF,
+            // so we just return empty string (char) at this point.  (Probably could also return -1 ...?)
+            $ch = ($this->buffer !== "") ? $this->buffer{$this->bufferPos} : '';
+            $this->bufferPos++;
+            if ( $this->bufferPos >= strlen($this->buffer) ) {
+                $this->buffer = null;
+                $this->bufferPos = 0;
+            }
+        }
+
+        return $ch;
+    }
+    
+    /**
+     * Returns whether eof has been reached in stream.
+     * This is important, because filters may want to know if the end of the file (and not just buffer)
+     * has been reached.
+     * @return boolean
+     */ 
+    function eof() {
+        return $this->in->eof();
+    }
+
+    function getResource() {
+        return $this->in->getResource();
+    }    
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/system/io/BufferedWriter.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/system/io/BufferedWriter.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/system/io/BufferedWriter.php	(revision 19)
@@ -0,0 +1,71 @@
+<?php
+/*
+ *  $Id: BufferedWriter.php 227 2007-08-28 02:17:00Z hans $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>. 
+ */
+ 
+include_once 'phing/system/io/Writer.php';
+
+/**
+ * Convenience class for writing files.
+ *
+ * @author    Hans Lellelid <hans@xmpl.org>
+ * @version   $Revision: 1.10 $
+ * @package   phing.system.io 
+ */
+class BufferedWriter extends Writer {
+    
+    /**
+     * The size of the buffer in kb.
+     */
+    private $bufferSize    = 0;
+    
+    /**
+     * @var Writer The Writer we are buffering output to.
+     */
+    private $out;
+
+    public function __construct(Writer $writer, $buffsize = 8192) {
+        $this->out = $writer;
+        $this->bufferSize = $buffsize;
+    }
+
+    public function write($buf, $off = null, $len = null) {
+        return $this->out->write($buf, $off, $len);
+    }
+    
+    public function newLine() {
+        $this->write(PHP_EOL);
+    }
+    
+    public function getResource() {
+        return $this->out->getResource();
+    }
+    
+    public function flush() {
+    	$this->out->flush();
+    }
+	
+    /**
+     * Close attached stream.
+     */
+    public function close() {
+        return $this->out->close();
+    }
+    
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/system/io/ConsoleReader.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/system/io/ConsoleReader.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/system/io/ConsoleReader.php	(revision 19)
@@ -0,0 +1,84 @@
+<?php
+/*
+ *  $Id: ConsoleReader.php 325 2007-12-20 15:44:58Z hans $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>. 
+ */
+ 
+include_once 'phing/system/io/Reader.php';
+
+/**
+ * Convenience class for reading console input.
+ * 
+ * @author Hans Lellelid <hans@xmpl.org>
+ * @author Matthew Hershberger <matthewh@lightsp.com>
+ * @version $Revision: 1.4 $
+ * @package phing.system.io
+ */
+class ConsoleReader extends Reader {
+    
+    function readLine() {
+        
+        $out = fgets(STDIN); // note: default maxlen is 1kb
+        $out = rtrim($out);
+
+        return $out;
+    }
+    
+    /**
+     * 
+     * @param int $len Num chars to read.
+     * @return string chars read or -1 if eof.
+     */
+    function read($len = null) {
+        
+        $out = fread(STDIN, $len);
+        
+        
+        return $out;
+        // FIXME
+        // read by chars doesn't work (yet?) with PHP stdin.  Maybe
+        // this is just a language feature, maybe there's a way to get
+        // ability to read chars w/o <enter> ?
+        
+    }   
+        
+    function close() {
+		// STDIN is always open
+    }
+
+    function open() {
+		// STDIN is always open
+    }
+
+    /**
+     * Whether eof has been reached with stream.
+     * @return boolean
+     */
+    function eof() {
+        return feof(STDIN);
+    }        
+    
+    /**
+     * Returns path to file we are reading.
+     * @return string
+     */
+    function getResource() {
+        return "console";
+    }
+}
+
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/system/io/FileInputStream.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/system/io/FileInputStream.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/system/io/FileInputStream.php	(revision 19)
@@ -0,0 +1,76 @@
+<?php
+/*
+ *  $Id: FileWriter.php 123 2006-09-14 20:19:08Z mrook $  
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+require_once 'phing/system/io/InputStream.php';
+require_once 'phing/system/io/PhingFile.php';
+
+/**
+ * Input stream subclass for file streams.
+ * 
+ * @package   phing.system.io
+ */
+class FileInputStream extends InputStream {
+	
+	/**
+	 * @var PhingFile The associated file.
+	 */
+	protected $file;
+	
+    /**
+     * Construct a new FileInputStream.
+     * @param mixed $file
+     * @throws Exception - if invalid argument specified.
+     * @throws IOException - if unable to open file.
+     */
+    public function __construct($file, $append = false) {
+    	if ($file instanceof PhingFile) {
+            $this->file = $file;
+        } elseif (is_string($file)) {
+            $this->file = new PhingFile($file);
+        } else {
+            throw new Exception("Invalid argument type for \$file.");
+        }
+        
+        $stream = @fopen($this->file->getAbsolutePath(), "rb");
+        if ($stream === false) {
+        	throw new IOException("Unable to open " . $this->file->__toString() . " for reading: " . $php_errormsg);
+        }
+        
+        parent::__construct($stream);
+    }
+    
+    /**
+     * Returns a string representation of the attached file.
+     * @return string
+     */
+    public function __toString() {
+        return $this->file->getPath();
+    }
+    
+    /**
+     * Mark is supported by FileInputStream.
+     * @return boolean TRUE
+     */
+	public function markSupported() {
+        return true;
+    }
+}
+
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/system/io/FileOutputStream.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/system/io/FileOutputStream.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/system/io/FileOutputStream.php	(revision 19)
@@ -0,0 +1,71 @@
+<?php
+/*
+ *  $Id: FileWriter.php 123 2006-09-14 20:19:08Z mrook $  
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+require_once 'phing/system/io/OutputStream.php';
+require_once 'phing/system/io/PhingFile.php';
+
+/**
+ * Output stream subclass for file streams.
+ * 
+ * @package   phing.system.io
+ */
+class FileOutputStream extends OutputStream {
+	
+	/**
+	 * @var PhingFile The associated file.
+	 */
+	protected $file;
+	
+    /**
+     * Construct a new FileOutputStream.
+     * @param mixed $file
+     * @param boolean $append Whether to append bytes to end of file rather than beginning.
+     * @throws Exception - if invalid argument specified.
+     * @throws IOException - if unable to open file.
+     */
+    public function __construct($file, $append = false) {
+    	if ($file instanceof PhingFile) {
+            $this->file = $file;
+        } elseif (is_string($file)) {
+            $this->file = new PhingFile($file);
+        } else {
+            throw new Exception("Invalid argument type for \$file.");
+        }
+        if ($append) {
+        	$stream = @fopen($this->file->getAbsolutePath(), "ab");
+        } else {
+        	$stream = @fopen($this->file->getAbsolutePath(), "wb");
+        }
+        if ($stream === false) {
+        	throw new IOException("Unable to open " . $this->file->__toString() . " for writing: " . $php_errormsg);
+        }
+        parent::__construct($stream);
+    }
+    
+    /**
+     * Returns a string representation of the attached file.
+     * @return string
+     */
+    public function __toString() {
+        return $this->file->getPath();
+    }
+}
+
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/system/io/FileReader.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/system/io/FileReader.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/system/io/FileReader.php	(revision 19)
@@ -0,0 +1,41 @@
+<?php
+/*
+ *  $Id: FileReader.php 227 2007-08-28 02:17:00Z hans $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>. 
+ */
+
+require_once 'phing/system/io/InputStreamReader.php';
+require_once 'phing/system/io/FileInputStream.php';
+
+/**
+ * Convenience class for reading files.
+ * @package   phing.system.io
+ */
+class FileReader extends InputStreamReader {
+
+	/**
+     * Construct a new FileReader.
+     * @param mixed $file PhingFile or string pathname.
+     */
+    public function __construct($file) {
+    	$in = new FileInputStream($file);
+    	parent::__construct($in);
+    }
+        
+}
+
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/system/io/FileSystem.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/system/io/FileSystem.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/system/io/FileSystem.php	(revision 19)
@@ -0,0 +1,686 @@
+<?php
+
+/* 
+ *  $Id: FileSystem.php 362 2008-03-08 10:07:53Z mrook $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>. 
+ */
+
+/**
+ * This is an abstract class for platform specific filesystem implementations
+ * you have to implement each method in the platform specific filesystem implementation
+ * classes Your local filesytem implementation must extend this class.
+ * You should also use this class as a template to write your local implementation
+ * Some native PHP filesystem specific methods are abstracted here as well. Anyway
+ * you _must_ always use this methods via a PhingFile object (that by nature uses the
+ * *FileSystem drivers to access the real filesystem via this class using natives.
+ *
+ * FIXME:
+ *  - Error handling reduced to min fallthrough runtime excetions
+ *    more precise errorhandling is done by the PhingFile class
+ *    
+ * @author Charlie Killian <charlie@tizac.com>
+ * @author Hans Lellelid <hans@xmpl.org>
+ * @version $Revision: 1.11 $
+ * @package phing.system.io
+ */
+abstract class FileSystem {    
+
+    /* properties for simple boolean attributes */
+    const BA_EXISTS    = 0x01;
+    const BA_REGULAR   = 0x02;
+    const BA_DIRECTORY = 0x04;
+    const BA_HIDDEN    = 0x08;
+    
+    /** Instance for getFileSystem() method. */
+    private static $fs;
+    
+    /**
+     * Static method to return the FileSystem singelton representing
+     * this platform's local filesystem driver.
+     * @return FileSystem
+     */
+    public static function getFileSystem() {
+        if (self::$fs === null) {
+            switch(Phing::getProperty('host.fstype')) {
+                case 'UNIX':
+                    include_once 'phing/system/io/UnixFileSystem.php';
+                    self::$fs = new UnixFileSystem();
+                break;
+                case 'WIN32':
+                    include_once 'phing/system/io/Win32FileSystem.php';
+                    self::$fs = new Win32FileSystem();
+                break;
+                case 'WINNT':
+                    include_once 'phing/system/io/WinNTFileSystem.php';
+                    self::$fs = new WinNTFileSystem();
+                break;
+                default:
+                    throw new Exception("Host uses unsupported filesystem, unable to proceed");
+            }
+        }
+        return self::$fs;
+    }
+
+    /* -- Normalization and construction -- */
+
+    /**
+     * Return the local filesystem's name-separator character.
+     */
+    abstract function getSeparator();
+
+    /**
+     * Return the local filesystem's path-separator character.
+     */
+    abstract function getPathSeparator();
+
+    /**
+     * Convert the given pathname string to normal form.  If the string is
+     * already in normal form then it is simply returned.
+     */
+    abstract function normalize($strPath);
+
+    /**
+     * Compute the length of this pathname string's prefix.  The pathname
+     * string must be in normal form.
+     */
+    abstract function prefixLength($pathname);
+
+    /**
+     * Resolve the child pathname string against the parent.
+     * Both strings must be in normal form, and the result
+     * will be a string in normal form.
+     */
+    abstract function resolve($parent, $child);
+    
+    /**
+     * Resolve the given abstract pathname into absolute form.  Invoked by the
+     * getAbsolutePath and getCanonicalPath methods in the PhingFile class.
+     */
+    abstract function resolveFile(PhingFile $f);
+
+    /**
+     * Return the parent pathname string to be used when the parent-directory
+     * argument in one of the two-argument PhingFile constructors is the empty
+     * pathname.
+     */
+    abstract function getDefaultParent();
+
+    /**
+     * Post-process the given URI path string if necessary.  This is used on
+     * win32, e.g., to transform "/c:/foo" into "c:/foo".  The path string
+     * still has slash separators; code in the PhingFile class will translate them
+     * after this method returns.
+     */
+    abstract function fromURIPath($path);
+    
+    /* -- Path operations -- */
+
+    /**
+     * Tell whether or not the given abstract pathname is absolute.
+     */
+    abstract function isAbsolute(PhingFile $f);
+
+    /** 
+     * canonicalize filename by checking on disk 
+     * @return mixed Canonical path or false if the file doesn't exist.
+     */
+    function canonicalize($strPath) {
+        return @realpath($strPath);        
+    }
+
+    /* -- Attribute accessors -- */
+
+    /**
+     * Return the simple boolean attributes for the file or directory denoted
+     * by the given abstract pathname, or zero if it does not exist or some
+     * other I/O error occurs.
+     */
+    function getBooleanAttributes($f) {
+        throw new Exception("SYSTEM ERROR method getBooleanAttributes() not implemented by fs driver");
+    }
+
+    /**
+     * Check whether the file or directory denoted by the given abstract
+     * pathname may be accessed by this process.  If the second argument is
+     * false, then a check for read access is made; if the second
+     * argument is true, then a check for write (not read-write)
+     * access is made.  Return false if access is denied or an I/O error
+     * occurs.
+     */
+    function checkAccess(PhingFile $f, $write = false) {
+        // we clear stat cache, its expensive to look up from scratch,
+        // but we need to be sure
+        @clearstatcache();
+
+
+        // Shouldn't this be $f->GetAbsolutePath() ?
+        // And why doesn't GetAbsolutePath() work?
+
+        $strPath = (string) $f->getPath();
+
+        // FIXME
+        // if file object does denote a file that yet not existst
+        // path rights are checked
+        if (!@file_exists($strPath) && !is_dir($strPath)) {
+            $strPath = $f->getParent();
+            if ($strPath === null || !is_dir($strPath)) {
+                $strPath = Phing::getProperty("user.dir");
+            }
+            //$strPath = dirname($strPath);
+        }
+
+        if (!$write) {
+            return (boolean) @is_readable($strPath);
+        } else {
+            return (boolean) @is_writable($strPath);
+        }
+    }
+	
+    /**
+     * Whether file can be deleted.
+     * @param PhingFile $f
+     * @return boolean
+     */
+    function canDelete(PhingFile $f)
+    {
+    	clearstatcache(); 
+ 		$dir = dirname($f->getAbsolutePath()); 
+ 		return (bool) @is_writable($dir); 
+    }
+    
+    /**
+     * Return the time at which the file or directory denoted by the given
+     * abstract pathname was last modified, or zero if it does not exist or
+     * some other I/O error occurs.
+     */
+    function getLastModifiedTime(PhingFile $f) {
+        
+        if (!$f->exists()) {
+            return 0;
+        }
+
+        @clearstatcache();
+        $strPath = (string) $f->getPath();
+        $mtime = @filemtime($strPath);
+        if (false === $mtime) {
+            // FAILED. Log and return err.
+            $msg = "FileSystem::Filemtime() FAILED. Cannot can not get modified time of $strPath. $php_errormsg";
+            throw new Exception($msg);
+        } else {
+            return (int) $mtime;
+        }
+    }
+
+    /**
+     * Return the length in bytes of the file denoted by the given abstract
+     * pathname, or zero if it does not exist, is a directory, or some other
+     * I/O error occurs.
+     */
+    function getLength(PhingFile $f) {
+        $strPath = (string) $f->getAbsolutePath();
+        $fs = filesize((string) $strPath);
+        if ($fs !== false) {
+            return $fs;
+        } else {
+            $msg = "FileSystem::Read() FAILED. Cannot get filesize of $strPath. $php_errormsg";
+            throw new Exception($msg);
+        }
+    }
+
+    /* -- File operations -- */
+
+    /**
+     * Create a new empty file with the given pathname.  Return
+     * true if the file was created and false if a
+     * file or directory with the given pathname already exists.  Throw an
+     * IOException if an I/O error occurs.
+     *
+     * @param       string      Path of the file to be created.
+     *     
+     * @throws      IOException
+     */
+    function createNewFile($strPathname) {
+        if (@file_exists($strPathname))
+            return false;
+            
+        // Create new file
+        $fp = @fopen($strPathname, "w");
+        if ($fp === false) {
+            throw new IOException("The file \"$strPathname\" could not be created");            
+        }
+        @fclose($fp);        
+        return true;
+    }
+
+    /**
+     * Delete the file or directory denoted by the given abstract pathname,
+     * returning true if and only if the operation succeeds.
+     */
+    function delete(PhingFile $f) {
+        if ($f->isDirectory()) {
+            return $this->rmdir($f->getPath());
+        } else {
+            return $this->unlink($f->getPath());
+        }
+    }
+
+    /**
+     * Arrange for the file or directory denoted by the given abstract
+     * pathname to be deleted when Phing::shutdown is called, returning
+    * true if and only if the operation succeeds.
+     */
+    function deleteOnExit($f) {
+        throw new Exception("deleteOnExit() not implemented by local fs driver");
+    }
+
+    /**
+     * List the elements of the directory denoted by the given abstract
+     * pathname.  Return an array of strings naming the elements of the
+     * directory if successful; otherwise, return <code>null</code>.
+     */
+    function listDir(PhingFile $f) {
+        $strPath = (string) $f->getAbsolutePath();
+        $d = @dir($strPath);
+        if (!$d) {
+            return null;
+        }
+        $list = array();
+        while($entry = $d->read()) {
+            if ($entry != "." && $entry != "..") {
+                array_push($list, $entry);
+            }
+        }
+        $d->close();
+        unset($d);
+        return $list;
+    }
+
+    /**
+     * Create a new directory denoted by the given abstract pathname,
+     * returning true if and only if the operation succeeds.
+     */
+    function createDirectory(&$f) {
+        return @mkdir($f->getAbsolutePath(),0755);
+    }
+
+    /**
+     * Rename the file or directory denoted by the first abstract pathname to
+     * the second abstract pathname, returning true if and only if
+     * the operation succeeds.
+     *
+     * @param PhingFile $f1 abstract source file
+     * @param PhingFile $f2 abstract destination file
+     * @return void    
+     * @throws Exception if rename cannot be performed
+     */
+    function rename(PhingFile $f1, PhingFile $f2) {        
+        // get the canonical paths of the file to rename
+        $src = $f1->getAbsolutePath();
+        $dest = $f2->getAbsolutePath();
+        if (false === @rename($src, $dest)) {
+            $msg = "Rename FAILED. Cannot rename $src to $dest. $php_errormsg";
+            throw new Exception($msg);
+        }
+    }
+
+    /**
+     * Set the last-modified time of the file or directory denoted by the
+     * given abstract pathname returning true if and only if the
+     * operation succeeds.
+     * @return void
+     * @throws Exception
+     */
+    function setLastModifiedTime(PhingFile $f, $time) {        
+        $path = $f->getPath();
+        $success = @touch($path, $time);
+        if (!$success) {
+            throw new Exception("Could not touch '" . $path . "' due to: $php_errormsg");
+        }
+    }
+
+    /**
+     * Mark the file or directory denoted by the given abstract pathname as
+     * read-only, returning <code>true</code> if and only if the operation
+     * succeeds.
+     */
+    function setReadOnly($f) {
+        throw new Exception("setReadonle() not implemented by local fs driver");
+    }
+
+    /* -- Filesystem interface -- */
+
+    /**
+     * List the available filesystem roots, return array of PhingFile objects
+     */
+    function listRoots() {
+        throw new Exception("SYSTEM ERROR [listRoots() not implemented by local fs driver]");
+    }
+
+    /* -- Basic infrastructure -- */
+
+    /**
+     * Compare two abstract pathnames lexicographically.
+     */
+    function compare($f1, $f2) {
+        throw new Exception("SYSTEM ERROR [compare() not implemented by local fs driver]");
+    }
+
+    /**
+     * Copy a file.
+     *
+     * @param PhingFile $src Source path and name file to copy.
+     * @param PhingFile $dest Destination path and name of new file.
+     *
+     * @return void     
+     * @throws Exception if file cannot be copied.
+     */
+    function copy(PhingFile $src, PhingFile $dest) {
+        global $php_errormsg;
+        $srcPath  = $src->getAbsolutePath();
+        $destPath = $dest->getAbsolutePath();
+
+        if (false === @copy($srcPath, $destPath)) { // Copy FAILED. Log and return err.
+            // Add error from php to end of log message. $php_errormsg.
+            $msg = "FileSystem::copy() FAILED. Cannot copy $srcPath to $destPath. $php_errormsg";
+            throw new Exception($msg);
+        }
+        
+        try {
+            $dest->setMode($src->getMode());
+        } catch(Exception $exc) {
+            // [MA] does chmod returns an error on systems that do not support it ?
+            // eat it up for now.
+        }
+    }
+
+	/**
+	 * Change the ownership on a file or directory.
+	 *
+	 * @param    string $pathname Path and name of file or directory.
+	 * @param    string $user The user name or number of the file or directory. See http://us.php.net/chown
+	 *
+	 * @return void
+	 * @throws Exception if operation failed.
+	 */
+	function chown($pathname, $user) {
+		if (false === @chown($pathname, $user)) {// FAILED.
+			$msg = "FileSystem::chown() FAILED. Cannot chown $pathname. User $user." . (isset($php_errormsg) ? ' ' . $php_errormsg : "");
+			throw new Exception($msg);
+		}
+    }
+    
+    /**
+     * Change the permissions on a file or directory.
+     *
+     * @param    pathname    String. Path and name of file or directory.
+     * @param    mode        Int. The mode (permissions) of the file or
+     *                        directory. If using octal add leading 0. eg. 0777.
+     *                        Mode is affected by the umask system setting.
+     *
+     * @return void     
+     * @throws Exception if operation failed.
+     */
+    function chmod($pathname, $mode) {    
+        $str_mode = decoct($mode); // Show octal in messages.    
+        if (false === @chmod($pathname, $mode)) {// FAILED.
+            $msg = "FileSystem::chmod() FAILED. Cannot chmod $pathname. Mode $str_mode." . (isset($php_errormsg) ? ' ' . $php_errormsg : "");
+            throw new Exception($msg);
+        }
+    }
+
+    /**
+     * Locks a file and throws an Exception if this is not possible.
+     * @return void
+     * @throws Exception
+     */
+    function lock(PhingFile $f) {
+        $filename = $f->getPath();
+        $fp = @fopen($filename, "w");
+        $result = @flock($fp, LOCK_EX);
+        @fclose($fp);
+        if (!$result) {
+            throw new Exception("Could not lock file '$filename'");
+        }
+    }
+
+    /**
+     * Unlocks a file and throws an IO Error if this is not possible.
+     *
+     * @throws Exception
+     * @return void
+     */
+    function unlock(PhingFile $f) {
+        $filename = $f->getPath();
+        $fp = @fopen($filename, "w");
+        $result = @flock($fp, LOCK_UN);
+        fclose($fp);
+        if (!$result) {
+            throw new Exception("Could not unlock file '$filename'");
+        }
+    }
+
+    /**
+     * Delete a file.
+     *
+     * @param    file    String. Path and/or name of file to delete.
+     *
+     * @return void
+     * @throws Exception - if an error is encountered.
+     */
+    function unlink($file) {
+        global $php_errormsg;
+        if (false === @unlink($file)) {
+            $msg = "FileSystem::unlink() FAILED. Cannot unlink '$file'. $php_errormsg";
+            throw new Exception($msg);
+        }
+    }
+
+    /**
+     * Symbolically link a file to another name.
+     * 
+     * Currently symlink is not implemented on Windows. Don't use if the application is to be portable.
+     *
+     * @param string $target Path and/or name of file to link.
+     * @param string $link Path and/or name of link to be created.
+     * @return void
+     */
+    function symlink($target, $link) {
+    
+        // If Windows OS then symlink() will report it is not supported in
+        // the build. Use this error instead of checking for Windows as the OS.
+
+        if (false === @symlink($target, $link)) {
+            // Add error from php to end of log message. $php_errormsg.
+            $msg = "FileSystem::Symlink() FAILED. Cannot symlink '$target' to '$link'. $php_errormsg";
+            throw new Exception($msg);
+        }
+
+    }
+
+    /**
+     * Set the modification and access time on a file to the present time.
+     *
+     * @param string $file Path and/or name of file to touch.
+     * @param int $time 
+     * @return void
+     */
+    function touch($file, $time = null) {
+        global $php_errormsg;
+        
+        if (null === $time) {
+            $error = @touch($file);
+        } else {
+            $error = @touch($file, $time);
+        }
+
+        if (false === $error) { // FAILED.
+            // Add error from php to end of log message. $php_errormsg.
+            $msg = "FileSystem::touch() FAILED. Cannot touch '$file'. $php_errormsg";            
+            throw new Exception($msg);            
+        }
+    }
+
+    /**
+     * Delete an empty directory OR a directory and all of its contents.
+     *
+     * @param    dir    String. Path and/or name of directory to delete.
+     * @param    children    Boolean.    False: don't delete directory contents.
+     *                                    True: delete directory contents.
+     *
+     * @return void
+     */
+    function rmdir($dir, $children = false) {
+        global $php_errormsg;
+        
+        // If children=FALSE only delete dir if empty.
+        if (false === $children) {
+        
+            if (false === @rmdir($dir)) { // FAILED.
+                // Add error from php to end of log message. $php_errormsg.
+                $msg = "FileSystem::rmdir() FAILED. Cannot rmdir $dir. $php_errormsg";
+                throw new Exception($msg);
+            }
+            
+        } else { // delete contents and dir.
+
+            $handle = @opendir($dir);
+
+            if (false === $handle) { // Error.
+
+                $msg = "FileSystem::rmdir() FAILED. Cannot opendir() $dir. $php_errormsg";                
+                throw new Exception($msg);
+
+            } else { // Read from handle.
+
+                // Don't error on readdir().
+                while (false !== ($entry = @readdir($handle))) {
+
+                    if ($entry != '.' && $entry != '..') {
+
+                        // Only add / if it isn't already the last char.
+                        // This ONLY serves the purpose of making the Logger
+                        // output look nice:)
+
+                        if (strpos(strrev($dir), DIRECTORY_SEPARATOR) === 0) {// there is a /
+                            $next_entry = $dir . $entry;
+                        } else { // no /
+                            $next_entry = $dir . DIRECTORY_SEPARATOR . $entry;
+                        }
+
+                        // NOTE: As of php 4.1.1 is_dir doesn't return FALSE it
+                        // returns 0. So use == not ===.
+
+                        // Don't error on is_dir()
+                        if (false == @is_dir($next_entry)) { // Is file.
+                            
+                            try {
+                                self::unlink($next_entry); // Delete.
+                            } catch (Exception $e) {                            
+                                $msg = "FileSystem::Rmdir() FAILED. Cannot FileSystem::Unlink() $next_entry. ". $e->getMessage();
+                                throw new Exception($msg);
+                            }
+
+                        } else { // Is directory.
+                            
+                            try {
+                                self::rmdir($next_entry, true); // Delete
+                            } catch (Exception $e) {
+                                $msg = "FileSystem::rmdir() FAILED. Cannot FileSystem::rmdir() $next_entry. ". $e->getMessage();
+                                throw new Exception($msg);
+                            }
+
+                        } // end is_dir else
+                    } // end .. if
+                } // end while
+            } // end handle if
+
+            // Don't error on closedir()
+            @closedir($handle);
+            
+            if (false === @rmdir($dir)) { // FAILED.
+                // Add error from php to end of log message. $php_errormsg.
+                $msg = "FileSystem::rmdir() FAILED. Cannot rmdir $dir. $php_errormsg";
+                throw new Exception($msg);
+            }
+            
+        }
+                
+    }
+
+    /**
+     * Set the umask for file and directory creation.
+     *
+     * @param    mode    Int. Permissions ususally in ocatal. Use leading 0 for
+     *                    octal. Number between 0 and 0777.
+     *
+     * @return void
+     * @throws Exception if there is an error performing operation.     
+     */
+    function umask($mode) {
+        global $php_errormsg;
+        
+        // CONSIDERME:
+        // Throw a warning if mode is 0. PHP converts illegal octal numbers to
+        // 0 so 0 might not be what the user intended.
+                        
+        $str_mode = decoct($mode); // Show octal in messages.
+
+        if (false === @umask($mode)) { // FAILED.
+            // Add error from php to end of log message. $php_errormsg.
+            $msg = "FileSystem::Umask() FAILED. Value $mode. $php_errormsg";
+            throw new Exception($msg);
+        }
+    }
+
+    /**
+     * Compare the modified time of two files.
+     *
+     * @param    file1    String. Path and name of file1.
+     * @param    file2    String. Path and name of file2.
+     *
+     * @return    Int.     1 if file1 is newer.
+     *                 -1 if file2 is newer.
+     *                  0 if files have the same time.
+     *                  Err object on failure.
+     *     
+     * @throws Exception - if cannot get modified time of either file.
+     */
+    function compareMTimes($file1, $file2) {
+
+        $mtime1 = filemtime($file1);
+        $mtime2 = filemtime($file2);
+
+        if ($mtime1 === false) { // FAILED. Log and return err.        
+            // Add error from php to end of log message. $php_errormsg.
+            $msg = "FileSystem::compareMTimes() FAILED. Cannot can not get modified time of $file1.";
+            throw new Exception($msg);            
+        } elseif ($mtime2 === false) { // FAILED. Log and return err.
+            // Add error from php to end of log message. $php_errormsg.
+            $msg = "FileSystem::compareMTimes() FAILED. Cannot can not get modified time of $file2.";
+            throw new Exception($msg);
+        } else { // Worked. Log and return compare.                
+            // Compare mtimes.
+            if ($mtime1 == $mtime2) {
+                return 0;
+            } else {
+                return ($mtime1 < $mtime2) ? -1 : 1;
+            } // end compare
+        }
+    }
+        
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/system/io/FileWriter.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/system/io/FileWriter.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/system/io/FileWriter.php	(revision 19)
@@ -0,0 +1,42 @@
+<?php
+/*
+ *  $Id: FileWriter.php 227 2007-08-28 02:17:00Z hans $  
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+require_once 'phing/system/io/OutputStreamWriter.php';
+require_once 'phing/system/io/FileOutputStream.php';
+
+/**
+ * Convenience class for performing file write operations.
+ *
+ * @package   phing.system.io
+ */
+class FileWriter extends OutputStreamWriter {
+    
+    /**
+     * Construct a new FileWriter.
+     * @param mixed $file PhingFile or string pathname.
+     * @param boolean $append Append to existing file?
+     */
+    function __construct($file, $append = false) {
+    	$out = new FileOutputStream($file, $append);
+    	parent::__construct($out);
+    }
+}
+
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/system/io/FilterReader.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/system/io/FilterReader.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/system/io/FilterReader.php	(revision 19)
@@ -0,0 +1,68 @@
+<?php
+/*
+ *  $Id: FilterReader.php 325 2007-12-20 15:44:58Z hans $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>. 
+ */
+
+require_once 'phing/system/io/Reader.php';
+
+/**
+ * Wrapper class for readers, which can be used to apply filters.
+ * @package phing.system.io
+ */
+class FilterReader extends Reader {
+    
+	/** 
+	 * @var Reader
+	 */
+    protected $in;
+    
+    function __construct(Reader $in = null) {
+        $this->in = $in;
+    }
+    
+    public function setReader(Reader $in) {
+        $this->in = $in;
+    }
+    
+    public function skip($n) {
+        return $this->in->skip($n);
+    }
+    
+    /**
+     * Read data from source.
+     * FIXME: Clean up this function signature, as it a) params aren't being used
+     * and b) it doesn't make much sense.
+     */
+    public function read($len = null) {
+        return $this->in->read($len);
+    }
+
+    public function reset() {
+        return $this->in->reset();
+    }
+    
+    public function close() {
+        return $this->in->close();
+    }
+    
+    function getResource() {
+        return $this->in->getResource();
+    }
+}
+
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/system/io/IOException.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/system/io/IOException.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/system/io/IOException.php	(revision 19)
@@ -0,0 +1,27 @@
+<?php
+/*
+ *  $Id: IOException.php 325 2007-12-20 15:44:58Z hans $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>. 
+ */
+
+/**
+ * Extends Exception to take advantage of methods therein.
+ *
+ * @package   phing.system.io
+ */
+class IOException extends Exception {}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/system/io/InputStream.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/system/io/InputStream.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/system/io/InputStream.php	(revision 19)
@@ -0,0 +1,178 @@
+<?php
+/*
+ *  $Id: FileReader.php 123 2006-09-14 20:19:08Z mrook $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>. 
+ */
+
+/**
+ * Wrapper class for PHP stream that supports read operations.
+ * 
+ * @package   phing.system.io
+ */
+class InputStream {
+	
+	/**
+	 * @var resource The attached PHP stream.
+	 */
+	protected $stream;
+	
+	/**
+	 * @var int Position of stream cursor.
+	 */
+    protected $currentPosition = 0;
+    
+    /**
+     * @var int Marked position of stream cursor.
+     */
+    protected $mark = 0;
+	
+	/**
+     * Construct a new InputStream.
+     * @param resource $stream Configured PHP stream for writing.
+     */
+    public function __construct($stream) {
+    	if (!is_resource($stream)) {
+    		throw new IOException("Passed argument is not a valid stream.");
+    	}
+    	$this->stream = $stream;
+    }
+
+    /**
+     * Skip over $n bytes.
+     * @param int $n
+     */
+    public function skip($n) {
+        $start = $this->currentPosition;
+
+        $ret = @fseek($this->stream, $n, SEEK_CUR);
+        if ( $ret === -1 )
+            return -1;
+
+        $this->currentPosition = ftell($this->stream);
+
+        if ( $start > $this->currentPosition )
+            $skipped = $start - $this->currentPosition;
+        else
+            $skipped = $this->currentPosition - $start;
+
+        return $skipped;
+    }
+    
+    /**
+     * Read data from stream until $len chars or EOF.
+     * @param int $len Num chars to read.  If not specified this stream will read until EOF.
+     * @return string chars read or -1 if eof.
+     */
+    public function read($len = null) {
+    	
+        if ($this->eof()) {
+            return -1;
+        }
+        
+        if ($len === null) { // we want to keep reading until we get an eof
+			$out = "";
+        	while(!$this->eof()) {
+        		$out .= fread($this->stream, 8192);
+        		$this->currentPosition = ftell($this->stream);
+        	}
+        } else {
+			$out = fread($this->stream, $len); // adding 1 seems to ensure that next call to read() will return EOF (-1)
+        	$this->currentPosition = ftell($this->stream);
+        }
+
+        return $out;
+    }    
+    
+    /**
+     * Marks the current position in this input stream.
+     * @throws IOException - if the underlying stream doesn't support this method.
+     */
+    public function mark() {
+    	if (!$this->markSupported()) {
+    		throw new IOException(get_class($this) . " does not support mark() and reset() methods.");
+    	}
+        $this->mark = $this->currentPosition;
+    }
+    
+    /**
+     * Whether the input stream supports mark and reset methods.
+     * @return boolean
+     */
+    public function markSupported() {
+    	return false;
+    }
+    
+    /**
+     * Repositions this stream to the position at the time the mark method was last called on this input stream.
+     * @throws IOException - if the underlying stream doesn't support this method.
+     */
+    function reset() {
+    	if (!$this->markSupported()) {
+    		throw new IOException(get_class($this) . " does not support mark() and reset() methods.");
+    	}
+        // goes back to last mark, by default this would be 0 (i.e. rewind file).
+        fseek($this->stream, SEEK_SET, $this->mark);
+        $this->mark = 0;
+    }
+	
+    /**
+     * Closes stream.
+     * @throws IOException if stream cannot be closed (note that calling close() on an already-closed stream will not raise an exception)
+     */
+    public function close() {
+        if ($this->stream === null) {
+            return;
+        }
+        if (false === @fclose($this->stream)) {
+            // FAILED.
+            $msg = "Cannot fclose " . $this->file->__toString() . " $php_errormsg";
+            throw new IOException($msg);
+        }
+        $this->stream = null;
+    }
+    
+    /**
+     * Whether eof has been reached with stream.
+     * @return boolean
+     */
+    public function eof() {
+        return feof($this->stream);
+    }
+     
+    /**
+     * Reads a entire until EOF and places contents in passed-in variable.  Stream is closed after read.
+     *
+     * @param string &$rBuffer String variable where read contents will be put.
+     * @return TRUE on success.
+     * @author  Charlie Killian, charlie@tizac.com
+     * @throws IOException - if there is an error reading from stream.
+     * @deprecated - Instead, use the read() method or a BufferedReader.
+     */
+    public function readInto(&$rBuffer) {
+		$rBuffer = $this->read();
+		$this->close();
+    }
+    
+    /**
+     * Returns string representation of attached stream.
+     * @return string
+     */
+    public function __toString() {
+        return (string) $this->stream;
+    }
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/system/io/InputStreamReader.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/system/io/InputStreamReader.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/system/io/InputStreamReader.php	(revision 19)
@@ -0,0 +1,126 @@
+<?php
+/*
+ *  $Id: FileReader.php 123 2006-09-14 20:19:08Z mrook $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>. 
+ */
+ 
+include_once 'phing/system/io/PhingFile.php';
+include_once 'phing/system/io/Reader.php';
+
+/**
+ * Writer class for OutputStream objects.
+ * 
+ * Unlike the Java counterpart, this class does not (yet) handle
+ * character set transformations.  This will be an important function
+ * of this class with move to supporting PHP6.
+ *  * @package   phing.system.io
+ */
+class InputStreamReader extends Reader {
+	
+	/**
+	 * @var InputStream
+	 */
+	protected $inStream;
+	
+	/**
+     * Construct a new InputStreamReader.
+     * @param InputStream $$inStream InputStream to read from
+     */
+    public function __construct(InputStream $inStream) {
+        $this->inStream = $inStream;
+    }
+	
+    /**
+     * Close the stream.
+     */
+    public function close() {
+    	return $this->inStream->close();
+    }
+	
+    /**
+     * Skip over $n bytes.
+     * @param int $n
+     */
+    public function skip($n) {
+    	return $this->inStream->skip($n);
+    }
+    
+    /**
+     * Read data from file.
+     * @param int $len Num chars to read.
+     * @return string chars read or -1 if eof.
+     */
+    public function read($len = null) {
+    	return $this->inStream->read($len);
+    }
+    
+    /**
+     * Marks the current position in this input stream.
+     * @throws IOException - if the underlying stream doesn't support this method.
+     */
+    public function mark() {
+        $this->inStream->mark();
+    }
+    
+    /**
+     * Whether the attached stream supports mark/reset.
+     * @return boolean
+     */
+    public function markSupported() {
+    	return $this->inStream->markSupported();
+    }
+    
+    /**
+     * Repositions this stream to the position at the time the mark method was last called on this input stream.
+     * @throws IOException - if the underlying stream doesn't support this method.
+     */
+    public function reset() {
+        $this->inStream->reset();
+    }
+
+    /**
+     * Whether eof has been reached with stream.
+     * @return boolean
+     */
+    public function eof() {
+        return $this->inStream->eof();
+    }
+     
+    /**
+     * Reads a entire file and stores the data in the variable
+     * passed by reference.
+     *
+     * @param    string $file    String. Path and/or name of file to read.
+     * @param    object &$rBuffer    Reference. Variable of where to put contents.
+     *
+     * @return    TRUE on success. Err object on failure.
+     * @author  Charlie Killian, charlie@tizac.com
+     * @deprecated Use read() or BufferedReader instead.
+     */
+    public function readInto(&$rBuffer) {
+		return $this->inStream->readInto($rBuffer);
+    }
+    
+    /**
+     * Returns string representation of attached stream.
+     * @return string
+     */
+    public function getResource() {
+        return $this->inStream->__toString();
+    }
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/system/io/OutputStream.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/system/io/OutputStream.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/system/io/OutputStream.php	(revision 19)
@@ -0,0 +1,108 @@
+<?php
+/*
+ *  $Id: FileWriter.php 123 2006-09-14 20:19:08Z mrook $  
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+/**
+ * Wrapper class for PHP stream that supports write operations.
+ * 
+ * @package   phing.system.io
+ */
+class OutputStream {
+	
+	/**
+	 * @var resource The configured PHP stream.
+	 */
+    protected $stream;
+
+    /**
+     * Construct a new OutputStream.
+     * @param resource $stream Configured PHP stream for writing.
+     */
+    public function __construct($stream) {
+    	if (!is_resource($stream)) {
+    		throw new IOException("Passed argument is not a valid stream.");
+    	}
+    	$this->stream = $stream;
+    }
+	
+    /**
+     * Closes attached stream, flushing output first.
+     * @throws IOException if cannot close stream (note that attempting to close an already closed stream will not raise an IOException)
+     * @return void
+     */
+    public function close() {
+    	if ($this->stream === null) {
+            return;
+        }
+        $this->flush();
+        if (false === @fclose($this->stream)) {
+            $msg = "Cannot close " . $this->getResource() . ": $php_errormsg";
+            throw new IOException($msg);
+        }
+		$this->stream = null;
+	}
+    
+	/**
+     * Flushes stream.
+     * 
+     * @throws IOException if unable to flush data (e.g. stream is not open).
+     */
+    public function flush() {
+    	if (false === @fflush($this->stream)) {
+    		throw new IOException("Could not flush stream: " . $php_errormsg);
+    	}
+	}
+	
+    /**
+     * Writes data to stream.
+     *
+     * @param string $buf Binary/character data to write.
+     * @param int $off (Optional) offset.
+     * @param int $len (Optional) number of bytes/chars to write. 
+     * @return void
+     * @throws IOException - if there is an error writing to stream
+     */
+    public function write($buf, $off = null, $len = null) {
+        if ( $off === null && $len === null ) {
+            $to_write = $buf;
+        } elseif ($off !== null && $len === null) {
+        	$to_write = substr($buf, $off);
+        } elseif ($off === null && $len !== null) {
+            $to_write = substr($buf, 0, $len);
+        } else {
+        	$to_write = substr($buf, $off, $len);
+        }
+        
+        $result = @fwrite($this->stream, $to_write);
+
+        if ( $result === false ) {
+            throw new IOException("Error writing to stream.");
+        }
+    }
+    
+    /**
+     * Returns a string representation of the attached PHP stream.
+     * @return string
+     */
+    public function __toString() {
+        return (string) $this->stream;
+    }
+}
+
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/system/io/OutputStreamWriter.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/system/io/OutputStreamWriter.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/system/io/OutputStreamWriter.php	(revision 19)
@@ -0,0 +1,84 @@
+<?php
+/*
+ *  $Id: FileWriter.php 123 2006-09-14 20:19:08Z mrook $  
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+ 
+include_once 'phing/system/io/PhingFile.php';
+require_once 'phing/system/io/Writer.php';
+
+/**
+ * Writer class for OutputStream objects.
+ * 
+ * Unlike the Java counterpart, this class does not (yet) handle
+ * character set transformations.  This will be an important function
+ * of this class with move to supporting PHP6.
+ *
+ * @package   phing.system.io
+ */
+class OutputStreamWriter extends Writer {
+
+	/**
+	 * @var OutputStream
+	 */
+    protected $outStream;
+    
+    /**
+     * Construct a new OutputStreamWriter.
+     * @param OutputStream $outStream OutputStream to write to
+     */
+    public function __construct(OutputStream $outStream) {
+        $this->outStream = $outStream;
+    }
+	
+    /**
+     * Close the stream.
+     */
+    public function close() {
+    	return $this->outStream->close();
+    }
+	
+    /**
+     * Write char data to stream.
+     *
+     * @param unknown_type $buf
+     * @param unknown_type $off
+     * @param unknown_type $len
+     * @return unknown
+     */
+    public function write($buf, $off = null, $len = null) {
+    	return $this->outStream->write($buf, $off, $len);
+    }
+    
+    /**
+     * Flush output to the stream.
+     */
+	public function flush() {
+    	$this->outStream->flush();
+    }
+    
+    /**
+     * Gets a string representation of attached stream resource.
+     *
+     * @return string String representation of output stream
+     */
+    public function getResource() {
+    	return $this->outStream->__toString();
+    }
+}
+
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/system/io/PhingFile.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/system/io/PhingFile.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/system/io/PhingFile.php	(revision 19)
@@ -0,0 +1,882 @@
+<?php
+/*
+ *  $Id: PhingFile.php 362 2008-03-08 10:07:53Z mrook $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+include_once 'phing/system/io/FileSystem.php';
+include_once 'phing/system/lang/NullPointerException.php';
+
+/**
+ * An abstract representation of file and directory pathnames.
+ *
+ * @version   $Revision: 1.1 $
+ * @package   phing.system.io
+ */
+class PhingFile {
+
+    /** separator string, static, obtained from FileSystem */
+    public static $separator;
+
+    /** path separator string, static, obtained from FileSystem (; or :)*/
+    public static $pathSeparator;
+    
+    /**
+     * This abstract pathname's normalized pathname string.  A normalized
+     * pathname string uses the default name-separator character and does not
+     * contain any duplicate or redundant separators.
+     */
+    private $path = null;
+
+    /** The length of this abstract pathname's prefix, or zero if it has no prefix. */
+    private $prefixLength = 0;
+
+    /** constructor */
+    function __construct($arg1 = null, $arg2 = null) {
+        
+        if (self::$separator === null || self::$pathSeparator === null) {
+            $fs = FileSystem::getFileSystem();
+            self::$separator = $fs->getSeparator();
+            self::$pathSeparator = $fs->getPathSeparator();
+        }
+
+        /* simulate signature identified constructors */
+        if ($arg1 instanceof PhingFile && is_string($arg2)) {
+            $this->_constructFileParentStringChild($arg1, $arg2);
+        } elseif (is_string($arg1) && ($arg2 === null)) {
+            $this->_constructPathname($arg1);
+        } elseif(is_string($arg1) && is_string($arg2)) {
+            $this->_constructStringParentStringChild($arg1, $arg2);
+        } else {
+            if ($arg1 === null) {
+                throw new NullPointerException("Argument1 to function must not be null");
+            }
+            $this->path = (string) $arg1;
+            $this->prefixLength = (int) $arg2;
+        }
+    }
+
+    /** Returns the length of this abstract pathname's prefix. */
+    function getPrefixLength() {
+        return (int) $this->prefixLength;
+    }
+    
+    /* -- constructors not called by signature match, so we need some helpers --*/
+
+    function _constructPathname($pathname) {
+        // obtain ref to the filesystem layer
+        $fs = FileSystem::getFileSystem();
+
+        if ($pathname === null) {
+            throw new NullPointerException("Argument to function must not be null");
+        }
+
+        $this->path = (string) $fs->normalize($pathname);
+        $this->prefixLength = (int) $fs->prefixLength($this->path);
+    }
+
+    function _constructStringParentStringChild($parent, $child = null) {
+        // obtain ref to the filesystem layer
+        $fs = FileSystem::getFileSystem();
+
+        if ($child === null) {
+            throw new NullPointerException("Argument to function must not be null");
+        }
+        if ($parent !== null) {
+            if ($parent === "") {
+                $this->path = $fs->resolve($fs->getDefaultParent(), $fs->normalize($child));
+            } else {
+                $this->path = $fs->resolve($fs->normalize($parent), $fs->normalize($child));
+            }
+        } else {
+            $this->path = (string) $fs->normalize($child);
+        }
+        $this->prefixLength = (int) $fs->prefixLength($this->path);
+    }
+
+    function _constructFileParentStringChild($parent, $child = null) {
+        // obtain ref to the filesystem layer
+        $fs = FileSystem::getFileSystem();
+
+        if ($child === null) {
+            throw new NullPointerException("Argument to function must not be null");
+        }
+
+        if ($parent !== null) {
+            if ($parent->path === "") {
+                $this->path = $fs->resolve($fs->getDefaultParent(), $fs->normalize($child));
+            } else {
+                $this->path = $fs->resolve($parent->path, $fs->normalize($child));
+            }
+        } else {
+            $this->path = $fs->normalize($child);
+        }
+        $this->prefixLength = $fs->prefixLength($this->path);
+    }
+
+    /* -- Path-component accessors -- */
+
+    /**
+     * Returns the name of the file or directory denoted by this abstract
+     * pathname.  This is just the last name in the pathname's name
+     * sequence.  If the pathname's name sequence is empty, then the empty
+     * string is returned.
+     *
+     * @return  The name of the file or directory denoted by this abstract
+     *          pathname, or the empty string if this pathname's name sequence
+     *          is empty
+     */
+    function getName() {
+        // that's a lastIndexOf
+        $index = ((($res = strrpos($this->path, self::$separator)) === false) ? -1 : $res);
+        if ($index < $this->prefixLength) {
+            return substr($this->path, $this->prefixLength);
+        }
+        return substr($this->path, $index + 1);
+    }
+
+    /**
+     * Returns the pathname string of this abstract pathname's parent, or
+     * null if this pathname does not name a parent directory.
+     *
+     * The parent of an abstract pathname consists of the pathname's prefix,
+     * if any, and each name in the pathname's name sequence except for the last.
+     * If the name sequence is empty then the pathname does not name a parent
+     * directory.
+     *
+     * @return  The pathname string of the parent directory named by this
+     *          abstract pathname, or null if this pathname does not name a parent
+     */
+    function getParent() {
+        // that's a lastIndexOf
+        $index = ((($res = strrpos($this->path, self::$separator)) === false) ? -1 : $res);
+        if ($index < $this->prefixLength) {
+            if (($this->prefixLength > 0) && (strlen($this->path > $this->prefixLength))) {
+                return substr($this->path, 0, $this->prefixLength);
+            }
+            return null;
+        }
+        return substr($this->path, 0, $index);
+    }
+
+    /**
+     * Returns the abstract pathname of this abstract pathname's parent,
+     * or null if this pathname does not name a parent directory.
+     *
+     * The parent of an abstract pathname consists of the pathname's prefix,
+     * if any, and each name in the pathname's name sequence except for the
+     * last.  If the name sequence is empty then the pathname does not name
+     * a parent directory.
+     *
+     * @return  The abstract pathname of the parent directory named by this
+     *          abstract pathname, or null if this pathname
+     *          does not name a parent
+     */
+    function getParentFile() {
+        $p = $this->getParent();
+        if ($p === null) {
+            return null;
+        }
+        return new PhingFile((string) $p, (int) $this->prefixLength);
+    }
+
+    /**
+     * Converts this abstract pathname into a pathname string.  The resulting
+     * string uses the default name-separator character to separate the names
+     * in the name sequence.
+     *
+     * @return  The string form of this abstract pathname
+     */
+    function getPath() {
+        return (string) $this->path;
+    }
+
+    /**
+     * Tests whether this abstract pathname is absolute.  The definition of
+     * absolute pathname is system dependent.  On UNIX systems, a pathname is
+     * absolute if its prefix is "/".  On Win32 systems, a pathname is absolute
+     * if its prefix is a drive specifier followed by "\\", or if its prefix
+     * is "\\".
+     *
+     * @return  true if this abstract pathname is absolute, false otherwise
+     */
+    function isAbsolute() {
+        return ($this->prefixLength !== 0);
+    }
+
+
+    /**
+     * Returns the absolute pathname string of this abstract pathname.
+     *
+     * If this abstract pathname is already absolute, then the pathname
+     * string is simply returned as if by the getPath method.
+     * If this abstract pathname is the empty abstract pathname then
+     * the pathname string of the current user directory, which is named by the
+     * system property user.dir, is returned.  Otherwise this
+     * pathname is resolved in a system-dependent way.  On UNIX systems, a
+     * relative pathname is made absolute by resolving it against the current
+     * user directory.  On Win32 systems, a relative pathname is made absolute
+     * by resolving it against the current directory of the drive named by the
+     * pathname, if any; if not, it is resolved against the current user
+     * directory.
+     *
+     * @return  The absolute pathname string denoting the same file or
+     *          directory as this abstract pathname
+     * @see     #isAbsolute()
+     */
+    function getAbsolutePath() {
+        $fs = FileSystem::getFileSystem();        
+        return $fs->resolveFile($this);
+    }
+
+    /**
+     * Returns the absolute form of this abstract pathname.  Equivalent to
+     * getAbsolutePath.
+     *
+     * @return  The absolute abstract pathname denoting the same file or
+     *          directory as this abstract pathname
+     */
+    function getAbsoluteFile() {
+        return new PhingFile((string) $this->getAbsolutePath());
+    }
+
+
+    /**
+     * Returns the canonical pathname string of this abstract pathname.
+     *
+     * A canonical pathname is both absolute and unique. The precise
+     * definition of canonical form is system-dependent. This method first
+     * converts this pathname to absolute form if necessary, as if by invoking the
+     * getAbsolutePath() method, and then maps it to its unique form in a
+     * system-dependent way.  This typically involves removing redundant names
+     * such as "." and .. from the pathname, resolving symbolic links
+     * (on UNIX platforms), and converting drive letters to a standard case
+     * (on Win32 platforms).
+     *
+     * Every pathname that denotes an existing file or directory has a
+     * unique canonical form.  Every pathname that denotes a nonexistent file
+     * or directory also has a unique canonical form.  The canonical form of
+     * the pathname of a nonexistent file or directory may be different from
+     * the canonical form of the same pathname after the file or directory is
+     * created.  Similarly, the canonical form of the pathname of an existing
+     * file or directory may be different from the canonical form of the same
+     * pathname after the file or directory is deleted.
+     *
+     * @return  The canonical pathname string denoting the same file or
+     *          directory as this abstract pathname
+     */
+    function getCanonicalPath() {
+        $fs = FileSystem::getFileSystem();
+        return $fs->canonicalize($this->path);
+    }
+
+
+    /**
+     * Returns the canonical form of this abstract pathname.  Equivalent to
+     * getCanonicalPath(.
+     *
+     * @return  PhingFile The canonical pathname string denoting the same file or
+     *          directory as this abstract pathname
+     */
+    function getCanonicalFile() {
+        return new PhingFile($this->getCanonicalPath());
+    }
+
+    /**
+     * Converts this abstract pathname into a file: URL.  The
+     * exact form of the URL is system-dependent.  If it can be determined that
+     * the file denoted by this abstract pathname is a directory, then the
+     * resulting URL will end with a slash.
+     *
+     * Usage note: This method does not automatically escape
+     * characters that are illegal in URLs.  It is recommended that new code
+     * convert an abstract pathname into a URL by first converting it into a
+     * URI, via the toURI() method, and then converting the URI
+     * into a URL via the URI::toURL()
+     *
+     * @return  A URL object representing the equivalent file URL
+     *
+     *
+     */
+    function toURL() {
+        /*
+        // URL class not implemented yet
+        return new URL("file", "", $this->_slashify($this->getAbsolutePath(), $this->isDirectory()));
+        */
+    }
+
+    /**
+     * Constructs a file: URI that represents this abstract pathname.
+     * Not implemented yet
+     */
+    function toURI() {
+        /*
+        $f = $this->getAbsoluteFile();
+           $sp = (string) $this->slashify($f->getPath(), $f->isDirectory());
+           if (StringHelper::startsWith('//', $sp))
+        $sp = '//' + sp;
+           return new URI('file', null, $sp, null);
+        */
+    }
+
+    function _slashify($path, $isDirectory) {
+        $p = (string) $path;
+
+        if (self::$separator !== '/') {
+            $p = str_replace(self::$separator, '/', $p);
+        }
+
+        if (!StringHelper::startsWith('/', $p)) {
+            $p = '/'.$p;
+        }
+
+        if (!StringHelper::endsWith('/', $p) && $isDirectory) {
+            $p = $p.'/';
+        }
+
+        return $p;
+    }
+
+    /* -- Attribute accessors -- */
+
+    /**
+     * Tests whether the application can read the file denoted by this
+     * abstract pathname.
+     *
+     * @return  true if and only if the file specified by this
+     *          abstract pathname exists and can be read by the
+     *          application; false otherwise
+     */
+    function canRead() {
+        $fs = FileSystem::getFileSystem();
+
+        if ($fs->checkAccess($this)) {
+            return (boolean) @is_readable($this->getAbsolutePath());
+        }
+        return false;
+    }
+
+    /**
+     * Tests whether the application can modify to the file denoted by this
+     * abstract pathname.
+     *
+     * @return  true if and only if the file system actually
+     *          contains a file denoted by this abstract pathname and
+     *          the application is allowed to write to the file;
+     *          false otherwise.
+     *
+     */
+    function canWrite() {
+        $fs = FileSystem::getFileSystem();
+        return $fs->checkAccess($this, true);
+    }
+
+    /**
+     * Tests whether the file denoted by this abstract pathname exists.
+     *
+     * @return  true if and only if the file denoted by this
+     *          abstract pathname exists; false otherwise
+     *
+     */
+    function exists() {                
+		clearstatcache();
+        if ($this->isFile()) {
+            return @file_exists($this->path);
+        } else {
+            return @is_dir($this->path);
+        }
+    }
+
+    /**
+     * Tests whether the file denoted by this abstract pathname is a
+     * directory.
+     *
+     * @return true if and only if the file denoted by this
+     *         abstract pathname exists and is a directory;
+     *         false otherwise
+     *
+     */
+    function isDirectory() {
+		clearstatcache();
+        $fs = FileSystem::getFileSystem();
+        if ($fs->checkAccess($this) !== true) {
+            throw new IOException("No read access to ".$this->path);
+        }
+        return @is_dir($this->path);
+    }
+
+    /**
+     * Tests whether the file denoted by this abstract pathname is a normal
+     * file.  A file is normal if it is not a directory and, in
+     * addition, satisfies other system-dependent criteria.  Any non-directory
+     * file created by a Java application is guaranteed to be a normal file.
+     *
+     * @return  true if and only if the file denoted by this
+     *          abstract pathname exists and is a normal file;
+     *          false otherwise
+     */
+    function isFile() {
+		clearstatcache();
+        //$fs = FileSystem::getFileSystem();
+        return @is_file($this->path);
+    }
+
+    /**
+     * Tests whether the file named by this abstract pathname is a hidden
+     * file.  The exact definition of hidden is system-dependent.  On
+     * UNIX systems, a file is considered to be hidden if its name begins with
+     * a period character ('.').  On Win32 systems, a file is considered to be
+     * hidden if it has been marked as such in the filesystem. Currently there
+     * seems to be no way to dermine isHidden on Win file systems via PHP
+     *
+     * @return  true if and only if the file denoted by this
+     *          abstract pathname is hidden according to the conventions of the
+     *          underlying platform
+     */
+    function isHidden() {
+        $fs = FileSystem::getFileSystem();
+        if ($fs->checkAccess($this) !== true) {
+            throw new IOException("No read access to ".$this->path);
+        }
+        return (($fs->getBooleanAttributes($this) & $fs->BA_HIDDEN) !== 0);
+    }
+
+    /**
+     * Returns the time that the file denoted by this abstract pathname was
+     * last modified.
+     *
+     * @return  A integer value representing the time the file was
+     *          last modified, measured in milliseconds since the epoch
+     *          (00:00:00 GMT, January 1, 1970), or 0 if the
+     *          file does not exist or if an I/O error occurs
+     */
+    function lastModified() {
+        $fs = FileSystem::getFileSystem();
+        if ($fs->checkAccess($this) !== true) {
+            throw new IOException("No read access to " . $this->path);
+        }
+        return $fs->getLastModifiedTime($this);
+    }
+
+    /**
+     * Returns the length of the file denoted by this abstract pathname.
+     * The return value is unspecified if this pathname denotes a directory.
+     *
+     * @return  The length, in bytes, of the file denoted by this abstract
+     *          pathname, or 0 if the file does not exist
+     */
+    function length() {
+        $fs = FileSystem::getFileSystem();
+        if ($fs->checkAccess($this) !== true) {
+            throw new IOException("No read access to ".$this->path."\n");
+        }
+        return $fs->getLength($this);
+    }
+
+    /**
+     * Convenience method for returning the contents of this file as a string.
+     * This method uses file_get_contents() to read file in an optimized way.
+     * @return string
+     * @throws Exception - if file cannot be read
+     */
+    function contents() {
+        if (!$this->canRead() || !$this->isFile()) {
+            throw new IOException("Cannot read file contents!");
+        }
+        return file_get_contents($this->getAbsolutePath());
+    }
+    
+    /* -- File operations -- */
+
+    /**
+     * Atomically creates a new, empty file named by this abstract pathname if
+     * and only if a file with this name does not yet exist.  The check for the
+     * existence of the file and the creation of the file if it does not exist
+     * are a single operation that is atomic with respect to all other
+     * filesystem activities that might affect the file.
+     *
+     * @return  true if the named file does not exist and was
+     *          successfully created; <code>false</code> if the named file
+     *          already exists
+     * @throws IOException if file can't be created
+     */
+    function createNewFile($parents=true, $mode=0777) {
+        $file = FileSystem::getFileSystem()->createNewFile($this->path);
+        return $file;
+    }
+
+    /**
+     * Deletes the file or directory denoted by this abstract pathname.  If
+     * this pathname denotes a directory, then the directory must be empty in
+     * order to be deleted.
+     *
+     * @return  true if and only if the file or directory is
+     *          successfully deleted; false otherwise
+     */
+    function delete() {
+        $fs = FileSystem::getFileSystem();
+        if ($fs->canDelete($this) !== true) {
+            throw new IOException("Cannot delete " . $this->path . "\n"); 
+        }
+        return $fs->delete($this);
+    }
+
+    /**
+     * Requests that the file or directory denoted by this abstract pathname
+     * be deleted when php terminates.  Deletion will be attempted only for
+     * normal termination of php and if and if only Phing::shutdown() is
+     * called.
+     *
+     * Once deletion has been requested, it is not possible to cancel the
+     * request.  This method should therefore be used with care.
+     *
+     */
+    function deleteOnExit() {
+        $fs = FileSystem::getFileSystem();
+        $fs->deleteOnExit($this);
+    }
+
+    /**
+     * Returns an array of strings naming the files and directories in the
+     * directory denoted by this abstract pathname.
+     *
+     * If this abstract pathname does not denote a directory, then this
+     * method returns null  Otherwise an array of strings is
+     * returned, one for each file or directory in the directory.  Names
+     * denoting the directory itself and the directory's parent directory are
+     * not included in the result.  Each string is a file name rather than a
+     * complete path.
+     *
+     * There is no guarantee that the name strings in the resulting array
+     * will appear in any specific order; they are not, in particular,
+     * guaranteed to appear in alphabetical order.
+     *
+     * @return  An array of strings naming the files and directories in the
+     *          directory denoted by this abstract pathname.  The array will be
+     *          empty if the directory is empty.  Returns null if
+     *          this abstract pathname does not denote a directory, or if an
+     *          I/O error occurs.
+     *
+     */
+    function listDir($filter = null) {
+        $fs = FileSystem::getFileSystem();
+        return $fs->lister($this, $filter);
+    }
+
+    function listFiles($filter = null) {
+        $ss = $this->listDir($filter);
+        if ($ss === null) {
+            return null;
+        }
+        $n = count($ss);
+        $fs = array();
+        for ($i = 0; $i < $n; $i++) {
+            $fs[$i] = new PhingFile((string)$this->path, (string)$ss[$i]);
+        }
+        return $fs;
+    }
+
+    /**
+     * Creates the directory named by this abstract pathname, including any
+     * necessary but nonexistent parent directories.  Note that if this
+     * operation fails it may have succeeded in creating some of the necessary
+     * parent directories.
+     *
+     * @return  true if and only if the directory was created,
+     *          along with all necessary parent directories; false
+     *          otherwise
+     * @throws  IOException
+     */
+    function mkdirs() {
+        if ($this->exists()) {
+            return false;
+        }
+		try {
+			if ($this->mkdir()) {
+	            return true;
+	        }
+		} catch (IOException $ioe) {
+			// IOException from mkdir() means that directory propbably didn't exist.
+		}        
+        $parentFile = $this->getParentFile();
+        return (($parentFile !== null) && ($parentFile->mkdirs() && $this->mkdir()));
+    }
+
+    /**
+     * Creates the directory named by this abstract pathname.
+     *
+     * @return  true if and only if the directory was created; false otherwise
+     * @throws  IOException
+     */
+    function mkdir() {
+        $fs = FileSystem::getFileSystem();
+
+        if ($fs->checkAccess(new PhingFile($this->path), true) !== true) {
+            throw new IOException("No write access to " . $this->getPath());
+        }
+        return $fs->createDirectory($this);
+    }
+
+    /**
+     * Renames the file denoted by this abstract pathname.
+     *
+     * @param   destFile  The new abstract pathname for the named file
+     * @return  true if and only if the renaming succeeded; false otherwise
+     */
+    function renameTo(PhingFile $destFile) {
+        $fs = FileSystem::getFileSystem();
+        if ($fs->checkAccess($this) !== true) {
+            throw new IOException("No write access to ".$this->getPath());
+        }
+        return $fs->rename($this, $destFile);
+    }
+
+    /**
+     * Simple-copies file denoted by this abstract pathname into another
+     * PhingFile
+     *
+     * @param PhingFile $destFile  The new abstract pathname for the named file
+     * @return true if and only if the renaming succeeded; false otherwise
+     */
+    function copyTo(PhingFile $destFile) {
+        $fs = FileSystem::getFileSystem();
+
+        if ($fs->checkAccess($this) !== true) {
+            throw new IOException("No read access to ".$this->getPath()."\n");
+        }
+
+        if ($fs->checkAccess($destFile, true) !== true) {
+            throw new IOException("File::copyTo() No write access to ".$destFile->getPath());
+        }
+        return $fs->copy($this, $destFile);
+    }
+
+    /**
+     * Sets the last-modified time of the file or directory named by this
+     * abstract pathname.
+     *
+     * All platforms support file-modification times to the nearest second,
+     * but some provide more precision.  The argument will be truncated to fit
+     * the supported precision.  If the operation succeeds and no intervening
+     * operations on the file take place, then the next invocation of the
+     * lastModified method will return the (possibly truncated) time argument
+     * that was passed to this method.
+     *
+     * @param  time  The new last-modified time, measured in milliseconds since
+     *               the epoch (00:00:00 GMT, January 1, 1970)
+     * @return true if and only if the operation succeeded; false otherwise
+     */
+    function setLastModified($time) {
+        $time = (int) $time;
+        if ($time < 0) {
+            throw new Exception("IllegalArgumentException, Negative $time\n");
+        }
+
+        $fs = FileSystem::getFileSystem();
+        return $fs->setLastModifiedTime($this, $time);
+    }
+
+    /**
+     * Marks the file or directory named by this abstract pathname so that
+     * only read operations are allowed.  After invoking this method the file
+     * or directory is guaranteed not to change until it is either deleted or
+     * marked to allow write access.  Whether or not a read-only file or
+     * directory may be deleted depends upon the underlying system.
+     *
+     * @return true if and only if the operation succeeded; false otherwise
+     */
+    function setReadOnly() {
+        $fs = FileSystem::getFileSystem();
+        if ($fs->checkAccess($this, true) !== true) {
+            // Error, no write access
+            throw new IOException("No write access to " . $this->getPath());
+        }
+        return $fs->setReadOnly($this);
+    }
+
+	/**
+	 * Sets the owner of the file.
+	 * @param mixed $user User name or number.
+	 */
+	public function setUser($user) {
+		$fs = FileSystem::getFileSystem();
+		return $fs->chown($this->getPath(), $user);
+    }
+    
+	/**
+     * Retrieve the owner of this file.
+     * @return int User ID of the owner of this file. 
+     */
+    function getUser() {
+        return @fileowner($this->getPath());
+    }
+    
+    /**
+     * Sets the mode of the file
+     * @param int $mode Ocatal mode.
+     */
+    function setMode($mode) {
+        $fs = FileSystem::getFileSystem();
+        return $fs->chmod($this->getPath(), $mode);
+    }
+
+    /**
+     * Retrieve the mode of this file.
+     * @return int
+     */
+    function getMode() {
+        return @fileperms($this->getPath());
+    }
+
+    /* -- Filesystem interface -- */
+
+    /**
+     * List the available filesystem roots.
+     *
+     * A particular platform may support zero or more hierarchically-organized
+     * file systems.  Each file system has a root  directory from which all
+     * other files in that file system can be reached.
+     * Windows platforms, for example, have a root directory for each active
+     * drive; UNIX platforms have a single root directory, namely "/".
+     * The set of available filesystem roots is affected by various system-level
+     * operations such the insertion or ejection of removable media and the
+     * disconnecting or unmounting of physical or virtual disk drives.
+     *
+     * This method returns an array of PhingFile objects that
+     * denote the root directories of the available filesystem roots.  It is
+     * guaranteed that the canonical pathname of any file physically present on
+     * the local machine will begin with one of the roots returned by this
+     * method.
+     *
+     * The canonical pathname of a file that resides on some other machine
+     * and is accessed via a remote-filesystem protocol such as SMB or NFS may
+     * or may not begin with one of the roots returned by this method.  If the
+     * pathname of a remote file is syntactically indistinguishable from the
+     * pathname of a local file then it will begin with one of the roots
+     * returned by this method.  Thus, for example, PhingFile objects
+     * denoting the root directories of the mapped network drives of a Windows
+     * platform will be returned by this method, while PhingFile
+     * objects containing UNC pathnames will not be returned by this method.
+     *
+     * @return  An array of PhingFile objects denoting the available
+     *          filesystem roots, or null if the set of roots
+     *          could not be determined.  The array will be empty if there are
+     *          no filesystem roots.
+     */
+    function listRoots() {
+        $fs = FileSystem::getFileSystem();
+        return (array) $fs->listRoots();
+    }
+
+    /* -- Tempfile management -- */
+
+    /**
+     * Returns the path to the temp directory.
+     */
+    function getTempDir() {
+        return Phing::getProperty('php.tmpdir');
+    }
+
+    /**
+     * Static method that creates a unique filename whose name begins with
+     * $prefix and ends with $suffix in the directory $directory. $directory
+     * is a reference to a PhingFile Object.
+     * Then, the file is locked for exclusive reading/writing.
+     *
+     * @author      manuel holtgrewe, grin@gmx.net
+     * @throws      IOException
+     * @access      public
+     */
+    function createTempFile($prefix, $suffix, PhingFile $directory) {
+        
+        // quick but efficient hack to create a unique filename ;-)
+        $result = null;
+        do {
+            $result = new PhingFile($directory, $prefix . substr(md5(time()), 0, 8) . $suffix);
+        } while (file_exists($result->getPath()));
+
+        $fs = FileSystem::getFileSystem();
+        $fs->createNewFile($result->getPath());
+        $fs->lock($result);
+
+        return $result;
+    }
+
+    /**
+     * If necessary, $File the lock on $File is removed and then the file is
+     * deleted
+     *
+     * @access      public
+     */
+    function removeTempFile() {
+        $fs = FileSystem::getFileSystem();
+        // catch IO Exception
+        $fs->unlock($this);
+        $this->delete();
+    }
+
+
+    /* -- Basic infrastructure -- */
+
+    /**
+     * Compares two abstract pathnames lexicographically.  The ordering
+     * defined by this method depends upon the underlying system.  On UNIX
+     * systems, alphabetic case is significant in comparing pathnames; on Win32
+     * systems it is not.
+     *
+     * @param PhingFile $file Th file whose pathname sould be compared to the pathname of this file.
+     *
+     * @return int Zero if the argument is equal to this abstract pathname, a
+     *        value less than zero if this abstract pathname is
+     *        lexicographically less than the argument, or a value greater
+     *        than zero if this abstract pathname is lexicographically
+     *        greater than the argument
+     */
+    function compareTo(PhingFile $file) {
+        $fs = FileSystem::getFileSystem();
+        return $fs->compare($this, $file);
+    }
+
+    /**
+     * Tests this abstract pathname for equality with the given object.
+     * Returns <code>true</code> if and only if the argument is not
+     * <code>null</code> and is an abstract pathname that denotes the same file
+     * or directory as this abstract pathname.  Whether or not two abstract
+     * pathnames are equal depends upon the underlying system.  On UNIX
+     * systems, alphabetic case is significant in comparing pathnames; on Win32
+     * systems it is not.
+     * @return boolean
+     */
+    function equals($obj) {
+        if (($obj !== null) && ($obj instanceof PhingFile)) {
+            return ($this->compareTo($obj) === 0);
+        }
+        return false;
+    }
+
+    /** Backwards compatibility -- use PHP5's native __tostring method. */
+    function toString() {
+        return $this->getPath();
+    }
+    
+    /** PHP5's native method. */
+    function __toString() {
+        return $this->getPath();
+    }
+}
+
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/system/io/Reader.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/system/io/Reader.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/system/io/Reader.php	(revision 19)
@@ -0,0 +1,91 @@
+<?php
+/*
+ *  $Id: Reader.php 227 2007-08-28 02:17:00Z hans $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+*/
+
+/**
+ * Abstract class for reading character streams.
+ * 
+ * @author Hans Lellelid <hans@xmpl.org>
+ * @author Yannick Lecaillez <yl@seasonfive.com>
+ * @version $Revision: 1.5 $
+ * @package phing.system.io
+ */
+abstract class Reader {
+
+    /**
+     * Read data from source.
+     * 
+     * If length is specified, then only that number of chars is read,
+     * otherwise stream is read until EOF.
+     * 
+     * @param int $len
+     */
+    abstract public function read($len = null);
+            
+    /**
+     * Close stream.
+     * @throws IOException if there is an error closing stream
+     */
+    abstract public function close();
+    
+    /**
+     * Returns the filename, url, etc. that is being read from.
+     * This is critical for, e.g., ExpatParser's ability to know
+     * the filename that is throwing an ExpatParserException, etc.
+     * @return string
+     */
+    abstract function getResource();
+
+    /**
+     * Move stream position relative to current pos.
+     * @param int $n
+     */
+    public function skip($n) {}
+    
+    /**
+     * Reset the current position in stream to beginning or last mark (if supported).
+     */    
+    public function reset() {}
+        
+    /**
+     * If supported, places a "marker" (like a bookmark) at current stream position.
+     * A subsequent call to reset() will move stream position back
+     * to last marker (if supported).
+     */    
+    public function mark() {}
+
+    /**
+     * Whether marking is supported.
+     * @return boolean
+     */
+    public function markSupported() {
+    	return false;
+    }
+    
+    /**
+     * Is stream ready for reading.
+     * @return boolean
+     */
+    public function ready() {
+    	return true;
+    }
+
+}
+
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/system/io/StringReader.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/system/io/StringReader.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/system/io/StringReader.php	(revision 19)
@@ -0,0 +1,84 @@
+<?php
+/*
+ *  $Id: StringReader.php 325 2007-12-20 15:44:58Z hans $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>. 
+ */
+
+/**
+ * Dummy class for reading from string of characters. 
+ * @package phing.system.io
+ */
+class StringReader extends Reader {
+    
+	/**
+	 * @var string
+	 */
+    private $_string;
+    
+    /**
+     * @var int
+     */
+    private $mark = 0;
+    
+    /**
+     * @var int
+     */
+    private $currPos = 0;
+    
+    function __construct($string) {
+        $this->_string = $string;
+    }
+
+    function skip($n) {}
+
+    function read($len = null) {
+        if ($len === null) {
+            return $this->_string;
+        } else {            
+            if ($this->currPos >= strlen($this->_string)) {
+                return -1;
+            }            
+            $out = substr($this->_string, $this->currPos, $len);
+            $this->currPos += $len;
+            return $out;
+        }
+    }
+
+    function mark() {
+        $this->mark = $this->currPos;
+    }
+
+    function reset() {
+        $this->currPos = $this->mark;
+    }
+
+    function close() {}
+
+    function open() {}
+
+    function ready() {}
+
+    function markSupported() {
+        return true;
+    }
+    
+    function getResource() {
+        return '(string) "'.$this->_string . '"';
+    }
+}
+
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/system/io/UnixFileSystem.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/system/io/UnixFileSystem.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/system/io/UnixFileSystem.php	(revision 19)
@@ -0,0 +1,278 @@
+<?php
+/*
+ *  $Id: UnixFileSystem.php 258 2007-10-21 00:46:45Z hans $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+include_once 'phing/system/io/FileSystem.php';
+
+/**
+ * UnixFileSystem class. This class encapsulates the basic file system functions
+ * for platforms using the unix (posix)-stylish filesystem. It wraps php native
+ * functions suppressing normal PHP error reporting and instead uses Exception
+ * to report and error.
+ *
+ * This class is part of a oop based filesystem abstraction and targeted to run
+ * on all supported php platforms.
+ *
+ * Note: For debugging turn track_errors on in the php.ini. The error messages
+ * and log messages from this class will then be clearer because $php_errormsg
+ * is passed as part of the message.
+ *
+ * FIXME:
+ *  - Comments
+ *  - Error handling reduced to min, error are handled by PhingFile mainly
+ *
+ * @author    Andreas Aderhold, andi@binarycloud.com
+ * @version   $Revision: 1.10 $
+ * @package   phing.system.io
+ */
+class UnixFileSystem extends FileSystem {
+
+    /**
+     * returns OS dependant path separator char
+     */
+    function getSeparator() {
+        return '/';
+    }
+
+    /**
+     * returns OS dependant directory separator char
+     */
+    function getPathSeparator() {
+        return ':';
+    }
+
+    /**
+     * A normal Unix pathname contains no duplicate slashes and does not end
+     * with a slash.  It may be the empty string.
+     *
+     * Check that the given pathname is normal.  If not, invoke the real
+     * normalizer on the part of the pathname that requires normalization.
+     * This way we iterate through the whole pathname string only once.
+     */
+    function normalize($strPathname) {
+        
+        if (empty($strPathname)) {
+            return;
+        }
+        
+        // Resolve home directories. We assume /home is where all home
+        // directories reside, b/c there is no other way to do this with
+        // PHP AFAIK.
+        if ($strPathname{0} === "~") {
+            if ($strPathname{1} === "/") { // like ~/foo => /home/user/foo
+                $strPathname = "/home/" . get_current_user() . substr($strPathname, 1);
+            } else { // like ~foo => /home/foo
+                $pos = strpos($strPathname, "/");
+                $name = substr($strPathname, 1, $pos - 2);
+                $strPathname = "/home/" . $name . substr($strPathname, $pos);
+            }
+        }
+
+        $n = strlen($strPathname);
+        $prevChar = 0;
+        for ($i=0; $i < $n; $i++) {
+            $c = $strPathname{$i};
+            if (($prevChar === '/') && ($c === '/')) {
+                return self::normalizer($strPathname, $n, $i - 1);
+            }
+            $prevChar = $c;
+        }
+        if ($prevChar === '/') {
+            return self::normalizer($strPathname, $n, $n - 1);
+        }
+        return $strPathname;
+    }
+
+    /**
+     * Normalize the given pathname, whose length is $len, starting at the given
+     * $offset; everything before this offset is already normal.
+     */
+    protected function normalizer($pathname, $len, $offset) {
+        if ($len === 0) {
+            return $pathname;
+        }
+        $n = (int) $len;
+        while (($n > 0) && ($pathname{$n-1} === '/')) {
+            $n--;
+        }
+        if ($n === 0) {
+            return '/';
+        }
+        $sb = "";
+
+        if ($offset > 0) {
+            $sb .= substr($pathname, 0, $offset);
+        }
+        $prevChar = 0;
+        for ($i = $offset; $i < $n; $i++) {
+            $c = $pathname{$i};
+            if (($prevChar === '/') && ($c === '/')) {
+                continue;
+            }
+            $sb .= $c;
+            $prevChar = $c;
+        }
+        return $sb;
+    }
+
+    /**
+     * Compute the length of the pathname string's prefix.  The pathname
+     * string must be in normal form.
+     */
+    function prefixLength($pathname) {
+        if (strlen($pathname === 0)) {
+            return 0;
+        }
+        return (($pathname{0} === '/') ? 1 : 0);
+    }
+
+    /**
+     * Resolve the child pathname string against the parent.
+     * Both strings must be in normal form, and the result
+     * will be in normal form.
+     */
+    function resolve($parent, $child) {
+
+        if ($child === "") {
+            return $parent;
+        }
+
+        if ($child{0} === '/') {
+            if ($parent === '/') {
+                return $child;
+            }
+            return $parent.$child;
+        }
+
+        if ($parent === '/') {
+            return $parent.$child;
+        }
+
+        return $parent.'/'.$child;
+    }
+
+    function getDefaultParent() {
+        return '/';
+    }
+
+    function isAbsolute(PhingFile $f) {
+        return ($f->getPrefixLength() !== 0);
+    }
+
+    /**
+     * the file resolver
+     */
+    function resolveFile(PhingFile $f) {
+        // resolve if parent is a file oject only
+        if ($this->isAbsolute($f)) {
+            return $f->getPath();
+        } else {
+            return $this->resolve(Phing::getProperty("user.dir"), $f->getPath());
+        }       
+    }
+
+    /* -- most of the following is mapped to the php natives wrapped by FileSystem */    
+
+    /* -- Attribute accessors -- */
+    function getBooleanAttributes(&$f) {
+        //$rv = getBooleanAttributes0($f);
+        $name = $f->getName();
+        $hidden = (strlen($name) > 0) && ($name{0} == '.');
+        return ($hidden ? $this->BA_HIDDEN : 0);
+    }
+
+    /**
+     * set file readonly on unix
+     */
+    function setReadOnly($f) {
+        if ($f instanceof File) {
+            $strPath = (string) $f->getPath();
+            $perms = (int) (@fileperms($strPath) & 0444);
+            return FileSystem::Chmod($strPath, $perms);
+        } else {
+            throw new Exception("IllegalArgutmentType: Argument is not File");
+        }
+    }
+
+    /**
+     * compares file paths lexicographically
+     */
+    function compare($f1, $f2) {
+        if ( ($f1 instanceof PhingFile) && ($f2 instanceof PhingFile) ) {
+            $f1Path = $f1->getPath();
+            $f2Path = $f2->getPath();
+            return (boolean) strcmp((string) $f1Path, (string) $f2Path);
+        } else {
+            throw new Exception("IllegalArgutmentType: Argument is not PhingFile");
+        }
+    }
+
+    /* -- fs interface --*/
+
+    function listRoots() {
+        if (!$this->checkAccess('/', false)) {
+            die ("Can not access root");
+        }
+        return array(new PhingFile("/"));
+    }
+
+    /**
+     * returns the contents of a directory in an array
+     */
+    function lister($f) {
+        $dir = @opendir($f->getAbsolutePath());
+        if (!$dir) {
+            throw new Exception("Can't open directory " . $f->__toString());
+        }
+        $vv = array();
+        while (($file = @readdir($dir)) !== false) {
+            if ($file == "." || $file == "..") {
+                continue;
+            }
+            $vv[] = (string) $file;
+        }
+        @closedir($dir);
+        return $vv;
+    }
+
+    function fromURIPath($p) {
+        if (StringHelper::endsWith("/", $p) && (strlen($p) > 1)) {
+
+            // "/foo/" --> "/foo", but "/" --> "/"            
+            $p = substr($p, 0, strlen($p) - 1);
+
+        }
+
+        return $p;
+    }
+    
+    /**
+     * Whether file can be deleted.
+     * @param PhingFile $f
+     * @return boolean
+     */
+    function canDelete(PhingFile $f) 
+ 	{ 
+ 		@clearstatcache(); 
+ 		$dir = dirname($f->getAbsolutePath()); 
+ 		return (bool) @is_writable($dir); 
+	}
+    
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/system/io/Win32FileSystem.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/system/io/Win32FileSystem.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/system/io/Win32FileSystem.php	(revision 19)
@@ -0,0 +1,477 @@
+<?php
+/*
+ *  $Id: Win32FileSystem.php 325 2007-12-20 15:44:58Z hans $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>. 
+ */
+
+include_once 'phing/system/io/FileSystem.php';
+
+/**
+ *  @package   phing.system.io
+ */
+class Win32FileSystem extends FileSystem {
+
+    protected $slash;
+    protected $altSlash;
+    protected $semicolon;
+
+    private static $driveDirCache = array();
+
+    function __construct() {
+        $this->slash = self::getSeparator();
+        $this->semicolon = self::getPathSeparator();
+        $this->altSlash = ($this->slash === '\\') ? '/' : '\\';
+    }
+
+    function isSlash($c) {
+        return ($c == '\\') || ($c == '/');
+    }
+
+    function isLetter($c) {
+        return ((ord($c) >= ord('a')) && (ord($c) <= ord('z')))
+               || ((ord($c) >= ord('A')) && (ord($c) <= ord('Z')));
+    }
+
+    function slashify($p) {
+        if ((strlen($p) > 0) && ($p{0} != $this->slash)) {
+            return $this->slash.$p;
+        }
+        else {
+            return $p;
+        }
+    }
+
+    /* -- Normalization and construction -- */
+
+    function getSeparator() {
+        // the ascii value of is the \
+        return chr(92);
+    }
+
+    function getPathSeparator() {
+        return ';';
+    }
+
+    /**
+     * A normal Win32 pathname contains no duplicate slashes, except possibly
+     * for a UNC prefix, and does not end with a slash.  It may be the empty
+     * string.  Normalized Win32 pathnames have the convenient property that
+     * the length of the prefix almost uniquely identifies the type of the path
+     * and whether it is absolute or relative:
+     *
+     *    0  relative to both drive and directory
+     *    1  drive-relative (begins with '\\')
+     *    2  absolute UNC (if first char is '\\'), else directory-relative (has form "z:foo")
+     *    3  absolute local pathname (begins with "z:\\")
+     */
+    function normalizePrefix($strPath, $len, &$sb) {
+        $src = 0;
+        while (($src < $len) && $this->isSlash($strPath{$src})) {
+            $src++;
+        }
+        $c = "";
+        if (($len - $src >= 2)
+                && $this->isLetter($c = $strPath{$src})
+                && $strPath{$src + 1} === ':') {
+            /* Remove leading slashes if followed by drive specifier.
+             * This hack is necessary to support file URLs containing drive
+             * specifiers (e.g., "file://c:/path").  As a side effect,
+             * "/c:/path" can be used as an alternative to "c:/path". */
+            $sb .= $c;
+            $sb .= ':';
+            $src += 2;
+        }
+        else {
+            $src = 0;
+            if (($len >= 2)
+                    && $this->isSlash($strPath{0})
+                    && $this->isSlash($strPath{1})) {
+                /* UNC pathname: Retain first slash; leave src pointed at
+                 * second slash so that further slashes will be collapsed
+                 * into the second slash.  The result will be a pathname
+                 * beginning with "\\\\" followed (most likely) by a host
+                 * name. */
+                $src = 1;
+                $sb.=$this->slash;
+            }
+        }
+        return $src;
+    }
+
+    /** Normalize the given pathname, whose length is len, starting at the given
+       offset; everything before this offset is already normal. */
+    protected function normalizer($strPath, $len, $offset) {
+        if ($len == 0) {
+            return $strPath;
+        }
+        if ($offset < 3) {
+            $offset = 0;    //Avoid fencepost cases with UNC pathnames
+        }
+        $src = 0;
+        $slash = $this->slash;
+        $sb = "";
+
+        if ($offset == 0) {
+            // Complete normalization, including prefix
+            $src = $this->normalizePrefix($strPath, $len, $sb);
+        } else {
+            // Partial normalization
+            $src = $offset;
+            $sb .= substr($strPath, 0, $offset);
+        }
+
+        // Remove redundant slashes from the remainder of the path, forcing all
+        // slashes into the preferred slash
+        while ($src < $len) {
+            $c = $strPath{$src++};
+            if ($this->isSlash($c)) {
+                while (($src < $len) && $this->isSlash($strPath{$src})) {
+                    $src++;
+                }
+                if ($src === $len) {
+                    /* Check for trailing separator */
+                    $sn = (int) strlen($sb);
+                    if (($sn == 2) && ($sb{1} === ':')) {
+                        // "z:\\"
+                        $sb .= $slash;
+                        break;
+                    }
+                    if ($sn === 0) {
+                        // "\\"
+                        $sb .= $slash;
+                        break;
+                    }
+                    if (($sn === 1) && ($this->isSlash($sb{0}))) {
+                        /* "\\\\" is not collapsed to "\\" because "\\\\" marks
+                        the beginning of a UNC pathname.  Even though it is
+                        not, by itself, a valid UNC pathname, we leave it as
+                        is in order to be consistent with the win32 APIs,
+                        which treat this case as an invalid UNC pathname
+                        rather than as an alias for the root directory of
+                        the current drive. */
+                        $sb .= $slash;
+                        break;
+                    }
+                    // Path does not denote a root directory, so do not append
+                    // trailing slash
+                    break;
+                } else {
+                    $sb .= $slash;
+                }
+            } else {
+                $sb.=$c;
+            }
+        }
+        $rv = (string) $sb;
+        return $rv;
+    }
+
+    /**
+     * Check that the given pathname is normal.  If not, invoke the real
+     * normalizer on the part of the pathname that requires normalization.
+     * This way we iterate through the whole pathname string only once.
+     * @param string $strPath
+     * @return string
+     */
+    function normalize($strPath) {
+        $n = strlen($strPath);
+        $slash    = $this->slash;
+        $altSlash = $this->altSlash;
+        $prev = 0;
+        for ($i = 0; $i < $n; $i++) {
+            $c = $strPath{$i};
+            if ($c === $altSlash) {
+                return $this->normalizer($strPath, $n, ($prev === $slash) ? $i - 1 : $i);
+            }
+            if (($c === $slash) && ($prev === $slash) && ($i > 1)) {
+                return $this->normalizer($strPath, $n, $i - 1);
+            }
+            if (($c === ':') && ($i > 1)) {
+                return $this->normalizer($strPath, $n, 0);
+            }
+            $prev = $c;
+        }
+        if ($prev === $slash) {
+            return $this->normalizer($strPath, $n, $n - 1);
+        }
+        return $strPath;
+    }
+
+    function prefixLength($strPath) {
+        $path  = (string) $strPath;
+        $slash = (string) $this->slash;
+        $n = (int) strlen($path);
+        if ($n === 0) {
+            return 0;
+        }
+        $c0 = $path{0};
+        $c1 = ($n > 1) ? $path{1} :
+              0;
+        if ($c0 === $slash) {
+            if ($c1 === $slash) {
+                return 2;            // absolute UNC pathname "\\\\foo"
+            }
+            return 1;                // drive-relative "\\foo"
+        }
+
+        if ($this->isLetter($c0) && ($c1 === ':')) {
+            if (($n > 2) && ($path{2}) === $slash) {
+                return 3;            // Absolute local pathname "z:\\foo" */
+            }
+            return 2;                // Directory-relative "z:foo"
+        }
+        return 0;                    // Completely relative
+    }
+
+    function resolve($parent, $child) {
+        $parent = (string) $parent;
+        $child  = (string) $child;
+        $slash  = (string) $this->slash;
+
+        $pn = (int) strlen($parent);
+        if ($pn === 0) {
+            return $child;
+        }
+        $cn = (int) strlen($child);
+        if ($cn === 0) {
+            return $parent;
+        }
+
+        $c = $child;
+        if (($cn > 1) && ($c{0} === $slash)) {
+            if ($c{1} === $slash) {
+                // drop prefix when child is a UNC pathname
+                $c = substr($c, 2);
+            }
+            else {
+                //Drop prefix when child is drive-relative */
+                $c = substr($c, 1);
+            }
+        }
+
+        $p = $parent;
+        if ($p{$pn - 1} === $slash) {
+            $p = substr($p, 0, $pn - 1);
+        }
+        return $p.$this->slashify($c);
+    }
+
+    function getDefaultParent() {
+        return (string) ("".$this->slash);
+    }
+
+    function fromURIPath($strPath) {
+        $p = (string) $strPath;
+        if ((strlen($p) > 2) && ($p{2} === ':')) {
+
+            // "/c:/foo" --> "c:/foo"
+            $p = substr($p,1);
+
+            // "c:/foo/" --> "c:/foo", but "c:/" --> "c:/"
+            if ((strlen($p) > 3) && StringHelper::endsWith('/', $p)) {
+                $p = substr($p, 0, strlen($p) - 1);
+            }
+        } elseif ((strlen($p) > 1) && StringHelper::endsWith('/', $p)) {
+            // "/foo/" --> "/foo"
+            $p = substr($p, 0, strlen($p) - 1);
+        }
+        return (string) $p;
+    }
+
+
+    /* -- Path operations -- */
+
+    function isAbsolute(PhingFile $f) {
+        $pl = (int) $f->getPrefixLength();
+        $p  = (string) $f->getPath();
+        return ((($pl === 2) && ($p{0} === $this->slash)) || ($pl === 3) || ($pl === 1 && $p{0} === $this->slash));
+    }
+
+    /** private */
+    function _driveIndex($d) {
+        $d = (string) $d{0};
+        if ((ord($d) >= ord('a')) && (ord($d) <= ord('z'))) {
+            return ord($d) - ord('a');
+        }
+        if ((ord($d) >= ord('A')) && (ord($d) <= ord('Z'))) {
+            return ord($d) - ord('A');
+        }
+        return -1;
+    }
+
+    /** private */
+    function _getDriveDirectory($drive) {
+        $drive = (string) $drive{0};
+        $i = (int) $this->_driveIndex($drive);
+        if ($i < 0) {
+            return null;
+        }
+
+        $s = (isset(self::$driveDirCache[$i]) ? self::$driveDirCache[$i] : null);
+
+        if ($s !== null) {
+            return $s;
+        }
+
+        $s = $this->_getDriveDirectory($i + 1);
+        self::$driveDirCache[$i] = $s;
+        return $s;
+    }
+
+    function _getUserPath() {
+        //For both compatibility and security, we must look this up every time
+        return (string) $this->normalize(Phing::getProperty("user.dir"));
+    }
+
+    function _getDrive($path) {
+        $path = (string) $path;
+        $pl   = $this->prefixLength($path);
+        return ($pl === 3) ? substr($path, 0, 2) : null;
+    }
+
+    function resolveFile(PhingFile $f) {
+        $path = $f->getPath();
+        $pl   = (int) $f->getPrefixLength();
+
+        if (($pl === 2) && ($path{0} === $this->slash)) {
+            return $path;            // UNC
+        }
+
+        if ($pl === 3) {
+            return $path;            // Absolute local
+        }
+
+        if ($pl === 0) {
+            return (string) ($this->_getUserPath().$this->slashify($path)); //Completely relative
+        }
+
+        if ($pl === 1) {            // Drive-relative
+            $up = (string) $this->_getUserPath();
+            $ud = (string) $this->_getDrive($up);
+            if ($ud !== null) {
+                return (string) $ud.$path;
+            }
+            return (string) $up.$path;            //User dir is a UNC path
+        }
+
+        if ($pl === 2) {                // Directory-relative
+            $up = (string) $this->_getUserPath();
+            $ud = (string) $this->_getDrive($up);
+            if (($ud !== null) && StringHelper::startsWith($ud, $path)) {
+                return (string) ($up . $this->slashify(substr($path,2)));
+            }
+            $drive = (string) $path{0};
+            $dir   = (string) $this->_getDriveDirectory($drive);
+
+            $np = (string) "";
+            if ($dir !== null) {
+                /* When resolving a directory-relative path that refers to a
+                drive other than the current drive, insist that the caller
+                have read permission on the result */
+                $p = (string) $drive . (':'.$dir.$this->slashify(substr($path,2)));
+
+                if (!$this->checkAccess($p, false)) {
+                    // FIXME
+                    // throw security error
+                    die("Can't resolve path $p");
+                }
+                return $p;
+            }
+            return (string) $drive.':'.$this->slashify(substr($path,2)); //fake it
+        }
+        
+        throw new Exception("Unresolvable path: " . $path);
+    }
+
+    /* -- most of the following is mapped to the functions mapped th php natives in FileSystem */
+
+    /* -- Attribute accessors -- */
+
+    function setReadOnly($f) {
+        // dunno how to do this on win
+        throw new Exception("WIN32FileSystem doesn't support read-only yet.");
+    }
+
+    /* -- Filesystem interface -- */
+
+    protected function _access($path) {
+        if (!$this->checkAccess($path, false)) {
+            throw new Exception("Can't resolve path $p");
+        }
+        return true;
+    }
+
+    function _nativeListRoots() {
+        // FIXME
+    }
+
+    function listRoots() {
+        $ds = _nativeListRoots();
+        $n = 0;
+        for ($i = 0; $i < 26; $i++) {
+            if ((($ds >> $i) & 1) !== 0) {
+                if (!$this->access((string)( chr(ord('A') + $i) . ':' . $this->slash))) {
+                    $ds &= ~(1 << $i);
+                } else {
+                    $n++;
+                }
+            }
+        }
+        $fs = array();
+        $j = (int) 0;
+        $slash = (string) $this->slash;
+        for ($i = 0; $i < 26; $i++) {
+            if ((($ds >> $i) & 1) !== 0) {
+                $fs[$j++] = new PhingFile(chr(ord('A') + $i) . ':' . $this->slash);
+            }
+        }
+        return $fs;
+    }
+
+    /* -- Basic infrastructure -- */
+
+    /** compares file paths lexicographically */
+    function compare(PhingFile $f1, PhingFile $f2) {
+        $f1Path = $f1->getPath();
+        $f2Path = $f2->getPath();
+        return (boolean) strcasecmp((string) $f1Path, (string) $f2Path);        
+    }
+
+
+    /**
+     * returns the contents of a directory in an array
+     */
+    function lister($f) {
+        $dir = @opendir($f->getAbsolutePath());
+        if (!$dir) {
+            throw new Exception("Can't open directory " . $f->__toString());
+        }
+        $vv = array();
+        while (($file = @readdir($dir)) !== false) {
+            if ($file == "." || $file == "..") {
+                continue;
+            }
+            $vv[] = (string) $file;
+        }
+        @closedir($dir);
+        return $vv;
+    }
+    
+}
+
+
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/system/io/WinNTFileSystem.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/system/io/WinNTFileSystem.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/system/io/WinNTFileSystem.php	(revision 19)
@@ -0,0 +1,35 @@
+<?php
+/*
+ *  $Id: WinNTFileSystem.php 325 2007-12-20 15:44:58Z hans $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>. 
+ */
+
+include_once 'phing/system/io/Win32FileSystem.php';
+
+/**
+ * FileSystem for Windows NT/2000.
+ *  @package   phing.system.io
+ */
+
+class WinNTFileSystem extends Win32FileSystem {
+
+    /* -- class only for convenience and future use everything is inherinted --*/
+
+
+}
+
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/system/io/Writer.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/system/io/Writer.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/system/io/Writer.php	(revision 19)
@@ -0,0 +1,53 @@
+<?php
+/*
+ *  $Id: Writer.php 227 2007-08-28 02:17:00Z hans $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>. 
+ */
+
+/**
+ * Abstract class for writing character streams.
+ * 
+ * @package   phing.system.io
+ */
+abstract class Writer {
+	
+	/**
+	 * Writes data to output stream.
+	 * @param string $buf
+	 * @param int $off
+	 * @param int $len
+	 */
+    abstract public function write($buf, $off = null, $len = null);
+    
+    /**
+     * Close the stream.
+     * @throws IOException - if there is an error closing stream.
+     */
+    abstract public function close();
+	
+    /**
+     * Flush the stream, if supported by the stream.
+     */
+    public function flush() {}
+    
+    /**
+     * Returns a string representation of resource filename, url, etc. that is being written to.
+     * @return string
+     */    
+    abstract public function getResource();
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/system/lang/Character.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/system/lang/Character.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/system/lang/Character.php	(revision 19)
@@ -0,0 +1,49 @@
+<?php
+/*
+ *  $Id: Character.php 325 2007-12-20 15:44:58Z hans $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+/**
+ * @package phing.system.lang
+ */
+class Character {
+
+    // this class might be extended with plenty of ordinal char constants
+    // and the like to support the multibyte aware datatype (char) in php
+    // in form of an object.
+    // anyway just a thought
+
+    public static function isLetter($char) {
+
+        if (strlen($char) !== 1)
+            $char = 0;
+
+        $char = (int) ord($char);
+
+        if ($char >= ord('A') && $char <= ord('Z'))
+            return true;
+
+        if ($char >= ord('a') && $char <= ord('z'))
+            return true;
+
+        return false;
+    }
+
+}
+
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/system/lang/EventObject.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/system/lang/EventObject.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/system/lang/EventObject.php	(revision 19)
@@ -0,0 +1,52 @@
+<?php
+/*
+ *  $Id: EventObject.php 325 2007-12-20 15:44:58Z hans $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+/**
+ *  @package phing.system.lang
+ */
+class EventObject {
+
+    /** The object on which the Event initially occurred. */
+    protected $source;
+
+    /** Constructs a prototypical Event. */
+    function __construct($source) {
+        if ($source === null) {
+            throw new Exception("Null source");
+        }
+        $this->source = $source;
+    }
+
+    /** The object on which the Event initially occurred. */
+    function getSource() {
+        return $this->source;
+    }
+
+    /** Returns a String representation of this EventObject.*/
+    function toString() {
+        if (method_exists($this->source, "toString")) {
+            return get_class($this)."[source=".$this->source->toString()."]";
+        } else {
+            return get_class($this)."[source=".get_class($this->source)."]";
+        }
+    }
+}
+
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/system/lang/FileNotFoundException.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/system/lang/FileNotFoundException.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/system/lang/FileNotFoundException.php	(revision 19)
@@ -0,0 +1,26 @@
+<?php
+/*
+ *  $Id: FileNotFoundException.php 325 2007-12-20 15:44:58Z hans $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+/**
+ *  @package   phing.system.lang
+ */
+class FileNotFoundException extends Exception {}
+
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/system/lang/NullPointerException.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/system/lang/NullPointerException.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/system/lang/NullPointerException.php	(revision 19)
@@ -0,0 +1,26 @@
+<?php
+/*
+ *  $Id: NullPointerException.php 325 2007-12-20 15:44:58Z hans $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+/**
+ * @package phing.system.lang
+ */
+class NullPointerException extends Exception {}
+
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/system/lang/SecurityException.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/system/lang/SecurityException.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/system/lang/SecurityException.php	(revision 19)
@@ -0,0 +1,26 @@
+<?php
+/*
+ *  $Id: SecurityException.php 325 2007-12-20 15:44:58Z hans $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+/**
+ * @package phing.system.lang
+ */
+class SecurityException extends Exception {}
+
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/system/util/Message.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/system/util/Message.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/system/util/Message.php	(revision 19)
@@ -0,0 +1,9 @@
+<?php
+//
+// FIXME. Logger will be renamed to Message, new level is introduces MSG_NOTICE
+// Message can handle some more later on
+//   - formatted output
+//   - sending to dialog or phpgtk whatever
+//   - etc
+//
+
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/system/util/Properties.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/system/util/Properties.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/system/util/Properties.php	(revision 19)
@@ -0,0 +1,272 @@
+<?php
+
+/*
+ *  $Id: Properties.php 325 2007-12-20 15:44:58Z hans $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+include_once 'phing/system/io/PhingFile.php';
+include_once 'phing/system/io/FileWriter.php';
+
+/**
+ * Convenience class for reading and writing property files.
+ * 
+ * FIXME
+ *        - Add support for arrays (separated by ',')
+ *
+ * @package    phing.system.util
+ * @version $Revision: 1.13 $
+ */
+class Properties {
+
+    private $properties = array();
+
+    /**
+     * Load properties from a file.
+     *
+     * @param PhingFile $file
+     * @return void
+     * @throws IOException - if unable to read file.
+     */
+    function load(PhingFile $file) {
+        if ($file->canRead()) {
+            $this->parse($file->getPath(), false);                    
+        } else {
+            throw new IOException("Can not read file ".$file->getPath());
+        }
+        
+    }
+    
+    /**
+     * Replaces parse_ini_file() or better_parse_ini_file().
+     * Saves a step since we don't have to parse and then check return value
+     * before throwing an error or setting class properties.
+     * 
+     * @param string $filePath
+     * @param boolean $processSections Whether to honor [SectionName] sections in INI file.
+     * @return array Properties loaded from file (no prop replacements done yet).
+     */
+    protected function parse($filePath) {
+
+        // load() already made sure that file is readable                
+        // but we'll double check that when reading the file into 
+        // an array
+        
+        if (($lines = @file($filePath)) === false) {
+            throw new IOException("Unable to parse contents of $filePath");
+        }
+        
+        $this->properties = array();
+        $sec_name = "";
+        
+        foreach($lines as $line) {
+            
+            $line = trim($line);
+    
+            if($line == "")
+                continue;
+                    
+            if ($line{0} == '#' or $line{0} == ';') {
+                // it's a comment, so continue to next line
+                continue;
+            } else {
+                $pos = strpos($line, '=');
+                $property = trim(substr($line, 0, $pos));
+                $value = trim(substr($line, $pos + 1));                
+                $this->properties[$property] = $this->inVal($value);
+            }
+            
+        } // for each line        
+    }
+    
+    /**
+     * Process values when being read in from properties file.
+     * does things like convert "true" => true
+     * @param string $val Trimmed value.
+     * @return mixed The new property value (may be boolean, etc.)
+     */
+    protected function inVal($val) {
+        if ($val === "true") { 
+            $val = true;
+        } elseif ($val === "false") { 
+            $val = false; 
+        }
+        return $val;
+    }
+    
+    /**
+     * Process values when being written out to properties file.
+     * does things like convert true => "true"
+     * @param mixed $val The property value (may be boolean, etc.)
+     * @return string
+     */
+    protected function outVal($val) {
+        if ($val === true) {
+            $val = "true";
+        } elseif ($val === false) {
+            $val = "false";
+        }
+        return $val;
+    }
+    
+    /**
+     * Create string representation that can be written to file and would be loadable using load() method.
+     * 
+     * Essentially this function creates a string representation of properties that is ready to
+     * write back out to a properties file.  This is used by store() method.
+     *
+     * @return string
+     */
+    public function toString() {
+        $buf = "";        
+        foreach($this->properties as $key => $item) {
+            $buf .= $key . "=" . $this->outVal($item) . PHP_EOL;
+        }
+        return $buf;    
+    }
+    
+    /**
+     * Stores current properties to specified file.
+     * 
+     * @param PhingFile $file File to create/overwrite with properties.
+     * @param string $header Header text that will be placed (within comments) at the top of properties file.
+     * @return void
+     * @throws IOException - on error writing properties file.
+     */
+    function store(PhingFile $file, $header = null) {
+        // stores the properties in this object in the file denoted
+        // if file is not given and the properties were loaded from a
+        // file prior, this method stores them in the file used by load()        
+        try {
+            $fw = new FileWriter($file);
+            if ($header !== null) {
+                $fw->write( "# " . $header . PHP_EOL );
+            }
+            $fw->write($this->toString());
+            $fw->close();
+        } catch (IOException $e) {
+            throw new IOException("Error writing property file: " . $e->getMessage());
+        }                
+    }
+    
+    /**
+     * Returns copy of internal properties hash.
+     * Mostly for performance reasons, property hashes are often
+     * preferable to passing around objects.
+     *
+     * @return array
+     */
+    function getProperties() {
+        return $this->properties;
+    }
+    
+    /**
+     * Get value for specified property.
+     * This is the same as get() method.
+     *
+     * @param string $prop The property name (key).
+     * @return mixed
+     * @see get()
+     */
+    function getProperty($prop) {
+        if (!isset($this->properties[$prop])) {
+            return null;
+        }
+        return $this->properties[$prop];
+    }
+
+    /**
+     * Get value for specified property.
+     * This function exists to provide a hashtable-like interface for
+     * properties.
+     *
+     * @param string $prop The property name (key).
+     * @return mixed
+     * @see getProperty()
+     */    
+    function get($prop) {
+         if (!isset($this->properties[$prop])) {
+            return null;
+        }
+        return $this->properties[$prop];
+    }
+    
+    /**
+     * Set the value for a property.
+     *
+     * @param string $key
+     * @param mixed $value
+     * @return mixed Old property value or NULL if none was set.
+     */
+    function setProperty($key, $value) {
+    	$oldValue = null;
+    	if (isset($this->properties[$key])) {
+    		$oldValue = $this->properties[$key];
+    	}
+        $this->properties[$key] = $value;
+        return $oldValue;
+    }
+    
+    /**
+     * Set the value for a property.
+     * This function exists to provide hashtable-lie
+     * interface for properties.
+     *
+     * @param string $key
+     * @param mixed $value
+     */
+    function put($key, $value) {
+        return $this->setProperty($key, $value);
+    }
+    
+    /**
+     * Same as keys() function, returns an array of property names.
+     * @return array
+     */
+    function propertyNames() {
+        return $this->keys();
+    }
+    
+    /**
+     * Whether loaded properties array contains specified property name.
+     * @return boolean
+     */
+    function containsKey($key) {
+        return isset($this->properties[$key]);
+    }
+
+    /**
+     * Returns properties keys.
+     * Use this for foreach() {} iterations, as this is
+     * faster than looping through property values.
+     * @return array
+     */
+    function keys() {
+        return array_keys($this->properties);
+    }
+    
+    /**
+     * Whether properties list is empty.
+     * @return boolean
+     */
+    function isEmpty() {
+        return empty($this->properties);
+    }
+
+}
+
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/system/util/Register.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/system/util/Register.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/system/util/Register.php	(revision 19)
@@ -0,0 +1,115 @@
+<?php
+
+/**
+ * Static class to handle a slot-listening system.
+ *
+ * Unlike the slots/signals Qt model, this class manages something that is
+ * more like a simple hashtable, where each slot has only one value.  For that
+ * reason "Registers" makes more sense, the reference being to CPU registers.
+ *
+ * This could be used for anything, but it's been built for a pretty specific phing
+ * need, and that is to allow access to dynamic values that are set by logic
+ * that is not represented in a build file.  For exampe, we need a system for getting
+ * the current resource (file) that is being processed by a filterchain in a fileset.
+ * 
+ * Each slot corresponds to only one read-only, dynamic-value RegisterSlot object. In
+ * a build.xml register slots are expressed using a syntax similar to variables:
+ * 
+ * <replaceregexp>
+ *    <regexp pattern="\n" replace="%{task.current_file}"/>
+ * </replaceregexp>
+ * 
+ * The task/type must provide a supporting setter for the attribute:
+ * 
+ * <code>
+ *     function setListeningReplace(RegisterSlot $slot) {
+ *        $this->replace = $slot;
+ *  }
+ *
+ *  // in main()
+ *  if ($this->replace instanceof RegisterSlot) {
+ *        $this->regexp->setReplace($this->replace->getValue());
+ *  } else {
+ *        $this->regexp->setReplace($this->replace);
+ *  }
+ * </code>
+ *
+ * @author Hans Lellelid <hans@xmpl.org>
+ * @version $Revision: 1.3 $
+ * @package phing.system.util
+ */
+class Register {
+    
+    /** Slots that have been registered */
+    private static $slots = array();
+    
+    /**
+     * Returns RegisterSlot for specified key.
+     * 
+     * If not slot exists a new one is created for key.
+     * 
+     * @param string $key
+     * @return RegisterSlot
+     */
+    public static function getSlot($key) {
+        if (!isset(self::$slots[$key])) {
+            self::$slots[$key] = new RegisterSlot($key);
+        }
+        return self::$slots[$key];
+    }    
+}
+
+
+/**
+ * Represents a slot in the register.
+ */
+class RegisterSlot {
+    
+    /** The name of this slot. */
+    private $key;
+    
+    /** The value for this slot. */
+    private $value;
+    
+    /**
+     * Constructs a new RegisterSlot, setting the key to passed param.
+     * @param string $key
+     */
+    public function __construct($key) {
+        $this->key = (string) $key;
+    }
+    
+    /**
+     * Sets the key / name for this slot.
+     * @param string $k
+     */
+    public function setKey($k) {
+        $this->key = (string) $k;
+    }
+
+    /**
+     * Gets the key / name for this slot.
+     * @return string
+     */
+    public function getKey() {
+        return $this->key;
+    }
+    
+    /**
+     * Sets the value for this slot.
+     * @param mixed
+     */
+    public function setValue($v) {
+        $this->value = $v;
+    }
+    
+    /**
+     * Returns the value at this slot.
+     * @return mixed
+     */
+    public function getValue() {
+        return $this->value;
+    }
+    
+}
+
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/system/util/Timer.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/system/util/Timer.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/system/util/Timer.php	(revision 19)
@@ -0,0 +1,96 @@
+<?php
+/*
+ *  $Id: Timer.php 123 2006-09-14 20:19:08Z mrook $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+
+/**
+ * This class can be used to obtain the execution time of all of the scripts
+ * that are executed in the process of building a page.
+ *
+ * Example:
+ * To be done before any scripts execute:
+ *
+ * $Timer = new Timer;
+ * $Timer->Start_Timer();
+ *
+ * To be done after all scripts have executed:
+ *
+ * $timer->Stop_Timer();
+ * $timer->Get_Elapsed_Time(int number_of_places);
+ *
+ * @author    Charles Killian
+ * @author    Hans Lellelid <hans@xmpl.org>
+ * @package    phing.system.util
+ * @version    $Revision: 1.5 $ $Date: 2006-09-14 20:19:08 +0000 (Thu, 14 Sep 2006) $
+ */
+class Timer {
+
+    /** start time */
+    protected $stime;
+    
+    /** end time */
+    protected $etime;  
+
+    /**
+     * This function sets the class variable $stime to the current time in
+     * microseconds.
+     * @return void
+     */
+    public function start() {
+        $this->stime = $this->getMicrotime();
+    }
+
+    /**
+     * This function sets the class variable $etime to the current time in
+     * microseconds.
+     * @return void
+     */
+    function stop() {
+        $this->etime = $this->getMicrotime();
+    }
+    
+    /**
+     * This function returns the elapsed time in seconds.
+     *
+     * Call start_time() at the beginning of script execution and end_time() at
+     * the end of script execution.  Then, call elapsed_time() to obtain the
+     * difference between start_time() and end_time().
+     *
+     * @param    $places  decimal place precision of elapsed time (default is 5)
+     * @return string Properly formatted time.
+     */
+    function getElapsedTime($places=5) {
+        $etime = $this->etime - $this->stime;
+        $format = "%0.".$places."f";
+        return (sprintf ($format, $etime));
+    }
+
+    /**
+     * This function returns the current time in microseconds.
+     *
+     * @author    Everett Michaud, Zend.com
+     * @return    current time in microseconds
+     * @access    private
+     */
+    function getMicrotime() {
+        list($usec, $sec) = explode(" ", microtime());
+        return ((float)$usec + (float)$sec);
+    }
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/defaults.properties
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/defaults.properties	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/defaults.properties	(revision 19)
@@ -0,0 +1,86 @@
+; -------------------------------------
+; These taskdefs are loaded at startup.
+; -------------------------------------
+
+; Internal system tasks
+; 
+adhoc=phing.tasks.system.AdhocTask
+adhoc-task=phing.tasks.system.AdhocTaskdefTask
+adhoc-type=phing.tasks.system.AdhocTypedefTask
+append=phing.tasks.system.AppendTask
+available=phing.tasks.system.AvailableTask
+chmod=phing.tasks.system.ChmodTask
+chown=phing.tasks.system.ChownTask
+concat=phing.tasks.system.AppendTask
+condition=phing.tasks.system.ConditionTask
+copy=phing.tasks.system.CopyTask
+cvs=phing.tasks.system.CvsTask
+cvspass=phing.tasks.system.CvsPassTask
+delete=phing.tasks.system.DeleteTask
+echo=phing.tasks.system.EchoTask
+exec=phing.tasks.system.ExecTask
+fail=phing.tasks.system.ExitTask
+foreach=phing.tasks.system.ForeachTask
+includepath=phing.tasks.system.IncludePathTask
+input=phing.tasks.system.InputTask
+mkdir=phing.tasks.system.MkdirTask
+move=phing.tasks.system.MoveTask
+phing=phing.tasks.system.PhingTask
+phingcall=phing.tasks.system.PhingCallTask
+php=phing.tasks.system.PhpEvalTask
+property=phing.tasks.system.PropertyTask
+propertyprompt=phing.tasks.system.PropertyPromptTask
+reflexive=phing.tasks.system.ReflexiveTask
+resolvepath=phing.tasks.system.ResolvePathTask
+taskdef=phing.tasks.system.TaskdefTask
+touch=phing.tasks.system.TouchTask
+tstamp=phing.tasks.system.TstampTask
+typedef=phing.tasks.system.TypedefTask
+uptodate=phing.tasks.system.UpToDateTask
+xslt=phing.tasks.system.XsltTask
+if=phing.tasks.system.IfTask
+warn=phing.tasks.system.WarnTask
+
+; "Core" contributed tasks
+; -- i.e. no taskdef needed.
+
+creole=phing.tasks.ext.creole.CreoleSQLExecTask
+pdo=phing.tasks.ext.pdo.PDOSQLExecTask
+package-as-path=phing.tasks.ext.PackageAsPathTask
+smarty=phing.tasks.ext.SmartyTask
+capsule=phing.tasks.ext.CapsuleTask
+tar=phing.tasks.ext.TarTask
+untar=phing.tasks.ext.UntarTask
+pearpkg=phing.tasks.ext.PearPackageTask
+pearpkg2=phing.tasks.ext.PearPackage2Task
+mail=phing.tasks.ext.MailTask
+zip=phing.tasks.ext.ZipTask
+unzip=phing.tasks.ext.UnzipTask
+scpsend=phing.tasks.ext.ScpSendTask
+
+; "ext" tasks
+phpdoc=phing.tasks.ext.phpdoc.PhpDocumentorTask
+phpdocext=phing.tasks.ext.phpdoc.PhpDocumentorExternalTask
+svnlastrevision=phing.tasks.ext.svn.SvnLastRevisionTask
+svncheckout=phing.tasks.ext.svn.SvnCheckoutTask
+svnexport=phing.tasks.ext.svn.SvnExportTask
+svnupdate=phing.tasks.ext.svn.SvnUpdateTask
+phpunit3=phing.tasks.ext.phpunit.PHPUnitTask
+phpunit3report=phing.tasks.ext.phpunit.PHPUnitReportTask
+phpunit2=phing.tasks.ext.phpunit.PHPUnitTask
+phpunit2report=phing.tasks.ext.phpunit.PHPUnitReportTask
+phpunit=phing.tasks.ext.phpunit.PHPUnitTask
+phpunitreport=phing.tasks.ext.phpunit.PHPUnitReportTask
+coverage-setup=phing.tasks.ext.coverage.CoverageSetupTask
+coverage-merger=phing.tasks.ext.coverage.CoverageMergerTask
+coverage-report=phing.tasks.ext.coverage.CoverageReportTask
+ioncubeencoder=phing.tasks.ext.ioncube.IoncubeEncoderTask
+ioncubelicense=phing.tasks.ext.ioncube.IoncubeLicenseTask
+simpletest=phing.tasks.ext.simpletest.SimpleTestTask
+phplint=phing.tasks.ext.PhpLintTask
+xmllint=phing.tasks.ext.XmlLintTask
+analyze=phing.tasks.ext.ZendCodeAnalyzerTask
+jsllint=phing.tasks.ext.JslLintTask
+manifest=phing.tasks.ext.ManifestTask
+phpcodesniffer=phing.tasks.ext.PhpCodeSnifferTask
+ftpdeploy=phing.tasks.ext.FtpDeployTask
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/CapsuleTask.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/CapsuleTask.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/CapsuleTask.php	(revision 19)
@@ -0,0 +1,478 @@
+<?php
+
+/*
+ *  $Id: CapsuleTask.php 144 2007-02-05 15:19:00Z hans $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>. 
+ */
+ 
+include_once 'phing/Task.php';
+include_once 'phing/BuildException.php';
+include_once 'phing/lib/Capsule.php';
+include_once 'phing/util/StringHelper.php';
+
+/**
+ * A phing task for generating output by using Capsule.
+ *
+ * This is based on the interface to TexenTask from Apache's Velocity engine. 
+ *
+ * @author    Hans Lellelid <hans@xmpl.org>
+ * @version   $Revision: 1.17 $
+ * @package   phing.tasks.ext
+ */
+class CapsuleTask extends Task {
+
+    /**
+     * Capsule "template" engine.
+     * @var Capsule
+     */
+    protected $context;
+       
+    /**
+     * Any vars assigned via the build file.
+     * @var array AssignedVar[]
+     */
+    protected $assignedVars = array();
+    
+    /**
+     * This is the control template that governs the output.
+     * It may or may not invoke the services of worker
+     * templates.
+     * @var string
+     */
+    protected $controlTemplate;
+    
+    /**
+     * This is where Velocity will look for templates
+     * using the file template loader.
+     * @var string
+     */
+    protected $templatePath;
+    
+    /**
+     * This is where texen will place all the output
+     * that is a product of the generation process.
+     * @var string
+     */
+    protected $outputDirectory;
+    
+    /**
+     * This is the file where the generated text
+     * will be placed.
+     * @var string
+     */
+    protected $outputFile;
+
+    /**
+     * <p>
+     * These are properties that are fed into the
+     * initial context from a properties file. This
+     * is simply a convenient way to set some values
+     * that you wish to make available in the context.
+     * </p>
+     * <p>
+     * These values are not critical, like the template path
+     * or output path, but allow a convenient way to
+     * set a value that may be specific to a particular
+     * generation task.
+     * </p>
+     * <p>
+     * For example, if you are generating scripts to allow
+     * user to automatically create a database, then
+     * you might want the <code>$databaseName</code> 
+     * to be placed
+     * in the initial context so that it is available
+     * in a script that might look something like the
+     * following:
+     * <code><pre>
+     * #!bin/sh
+     * 
+     * echo y | mysqladmin create $databaseName
+     * </pre></code>
+     * The value of <code>$databaseName</code> isn't critical to
+     * output, and you obviously don't want to change
+     * the ant task to simply take a database name.
+     * So initial context values can be set with
+     * properties file.
+     *
+     * @var array
+     */
+    protected $contextProperties;
+        
+    // -----------------------------------------------------------------------
+    // The following getters & setters are used by phing to set properties
+    // specified in the XML for the capsule task.
+    // -----------------------------------------------------------------------
+    
+    /**
+     * [REQUIRED] Set the control template for the
+     * generating process.
+     * @param string $controlTemplate
+     * @return void
+     */
+    public function setControlTemplate ($controlTemplate) {
+        $this->controlTemplate = $controlTemplate;
+    }
+
+    /**
+     * Get the control template for the
+     * generating process.
+     * @return string
+     */
+    public function getControlTemplate() {
+        return $this->controlTemplate;
+    }
+
+    /**
+     * [REQUIRED] Set the path where Velocity will look
+     * for templates using the file template
+     * loader.
+     * @return void
+     * @throws Exception 
+     */
+    public function setTemplatePath($templatePath) {
+        $resolvedPath = "";        
+        $tok = strtok($templatePath, ",");
+        while ( $tok ) {            
+            // resolve relative path from basedir and leave
+            // absolute path untouched.
+            $fullPath = $this->project->resolveFile($tok);
+            $cpath = $fullPath->getCanonicalPath();
+            if ($cpath === false) {
+                $this->log("Template directory does not exist: " . $fullPath->getAbsolutePath());
+            } else {
+                $resolvedPath .= $cpath;
+            }
+            $tok = strtok(",");
+            if ( $tok ) {
+                $resolvedPath .= ",";
+            }
+        }
+        $this->templatePath = $resolvedPath;
+     }
+
+    /**
+     * Get the path where Velocity will look
+     * for templates using the file template
+     * loader.
+     * @return string
+     */
+    public function getTemplatePath() {
+        return $this->templatePath;
+    }        
+
+    /**
+     * [REQUIRED] Set the output directory. It will be
+     * created if it doesn't exist.
+     * @param PhingFile $outputDirectory
+     * @return void
+     * @throws Exception
+     */
+    public function setOutputDirectory(PhingFile $outputDirectory) {
+        try {
+            if (!$outputDirectory->exists()) {
+                $this->log("Output directory does not exist, creating: " . $outputDirectory->getPath(),Project::MSG_VERBOSE);
+                if (!$outputDirectory->mkdirs()) {
+                    throw new IOException("Unable to create Ouptut directory: " . $outputDirectory->getAbsolutePath());
+                }
+            }
+            $this->outputDirectory = $outputDirectory->getCanonicalPath();
+        } catch (IOException $ioe) {
+            throw new BuildException($ioe);
+        }
+    }
+      
+    /**
+     * Get the output directory.
+     * @return string
+     */
+    public function getOutputDirectory() {
+        return $this->outputDirectory;
+    }        
+
+    /**
+     * [REQUIRED] Set the output file for the
+     * generation process.
+     * @param string $outputFile (TODO: change this to File)
+     * @return void
+     */
+    public function setOutputFile($outputFile) {
+        $this->outputFile = $outputFile;
+    }
+
+    /**
+     * Get the output file for the
+     * generation process.
+     * @return string
+     */
+    public function getOutputFile() {
+        return $this->outputFile;
+    }        
+    
+    /**
+     * Set the context properties that will be
+     * fed into the initial context be the
+     * generating process starts.
+     * @param string $file
+     * @return void
+     */
+    public function setContextProperties($file) {
+        $sources = explode(",", $file);
+        $this->contextProperties = new Properties();
+        
+        // Always try to get the context properties resource
+        // from a file first. Templates may be taken from a JAR
+        // file but the context properties resource may be a 
+        // resource in the filesystem. If this fails than attempt
+        // to get the context properties resource from the
+        // classpath.
+        for ($i=0, $sourcesLength=count($sources); $i < $sourcesLength; $i++) {
+            $source = new Properties();
+            
+            try {
+            
+                // resolve relative path from basedir and leave
+                // absolute path untouched.
+                $fullPath = $this->project->resolveFile($sources[$i]);
+                $this->log("Using contextProperties file: " . $fullPath->toString());
+                $source->load($fullPath);
+                
+            } catch (Exception $e) {
+              
+              throw new BuildException("Context properties file " . $sources[$i] .
+                            " could not be found in the file system!");
+                     
+            }
+        
+            $keys = $source->keys();
+            
+            foreach ($keys as $key) {
+                $name = $key;
+                $value = $this->project->replaceProperties($source->getProperty($name));
+                $this->contextProperties->setProperty($name, $value);
+            }
+        }
+    }
+
+    /**
+     * Get the context properties that will be
+     * fed into the initial context be the
+     * generating process starts.
+     * @return Properties
+     */
+    public function getContextProperties() {
+        return $this->contextProperties;
+    }     
+
+    /** 
+     * Creates an "AssignedVar" class.
+     */
+    public function createAssign() {
+        $a = new AssignedVar();
+        $this->assignedVars[] = $a;
+        return $a;
+    }
+    
+    // ---------------------------------------------------------------
+    // End of XML setters & getters
+    // ---------------------------------------------------------------
+   
+    /**
+     * Creates a Smarty object.
+     *
+     * @return Smarty initialized (cleared) Smarty context.
+     * @throws Exception the execute method will catch 
+     *         and rethrow as a <code>BuildException</code>
+     */
+    public function initControlContext() {
+        $this->context->clear();
+        foreach($this->assignedVars as $var) {
+            $this->context->put($var->getName(), $var->getValue());
+        }
+        return $this->context;
+    }
+    
+    /**
+     * Execute the input script with Velocity
+     *
+     * @throws BuildException  
+     * BuildExceptions are thrown when required attributes are missing.
+     * Exceptions thrown by Velocity are rethrown as BuildExceptions.
+     */
+    public function main() {
+    
+        // Make sure the template path is set.
+        if (empty($this->templatePath)) {
+            throw new BuildException("The template path needs to be defined!");
+        }            
+    
+        // Make sure the control template is set.
+        if ($this->controlTemplate === null) {
+            throw new BuildException("The control template needs to be defined!");
+        }            
+
+        // Make sure the output directory is set.
+        if ($this->outputDirectory === null) {
+            throw new BuildException("The output directory needs to be defined!");
+        }            
+        
+        // Make sure there is an output file.
+        if ($this->outputFile === null) {
+            throw new BuildException("The output file needs to be defined!");
+        }            
+        
+        // Setup Smarty runtime.
+        
+        // Smarty uses one object to store properties and to store
+        // the context for the template (unlike Velocity).  We setup this object, calling it
+        // $this->context, and then initControlContext simply zeros out
+        // any assigned variables.
+        $this->context = new Capsule();
+                
+        if ($this->templatePath !== null) {
+            $this->log("Using templatePath: " . $this->templatePath);
+            $this->context->setTemplatePath($this->templatePath);
+        }                                                        
+                
+        // Make sure the output directory exists, if it doesn't
+        // then create it.
+        $outputDir = new PhingFile($this->outputDirectory);
+        if (!$outputDir->exists()) {
+            $this->log("Output directory does not exist, creating: " . $outputDir->getAbsolutePath());
+            $outputDir->mkdirs();
+        }
+        
+        $this->context->setOutputDirectory($outputDir->getAbsolutePath());
+        
+        $path = $this->outputDirectory . DIRECTORY_SEPARATOR . $this->outputFile;
+        $this->log("Generating to file " . $path);
+        
+        //$writer = new FileWriter($path);
+                
+        // The generator and the output path should
+        // be placed in the init context here and
+        // not in the generator class itself.
+        $c = $this->initControlContext();
+        
+        // Set any variables that need to always
+        // be loaded
+        $this->populateInitialContext($c);
+        
+        // Feed all the options into the initial
+        // control context so they are available
+        // in the control/worker templates.
+        if ($this->contextProperties !== null) {
+            
+            foreach($this->contextProperties->keys() as $property) {
+                    
+            $value = $this->contextProperties->getProperty($property);
+            
+            // Special exception (from Texen)
+            // for properties ending in file.contents:
+            // in that case we dump the contents of the file
+            // as the "value" for the Property.
+            if (preg_match('/file\.contents$/', $property)) {
+                // pull in contents of file specified 
+                                        
+                $property = substr($property, 0, strpos($property, "file.contents") - 1);
+                
+                // reset value, and then 
+                // read in teh contents of the file into that var
+                $value = "";
+                $f = new PhingFile($project->resolveFile($value)->getCanonicalPath());                        
+                if ($f->exists()) {
+                    $fr = new FileReader($f);
+                    $fr->readInto($value);
+                }
+                                                                
+            } // if ends with file.contents
+            
+            if (StringHelper::isBoolean($value)) {
+                $value = StringHelper::booleanValue($value);
+            }
+                                                            
+            $c->put($property, $value); 
+                 
+            } // foreach property
+                
+        } // if contextProperties !== null
+        
+        try {
+            $this->log("Parsing control template: " . $this->controlTemplate);
+            $c->parse($this->controlTemplate, $path);
+        } catch (Exception $ioe) {
+            throw new BuildException("Cannot write parsed template: ". $ioe->getMessage());
+        }        
+        
+        $this->cleanup();    
+    }
+
+    /**
+     * Place useful objects into the initial context.
+     *
+     *
+     * @param Capsule $context The context to populate, as retrieved from
+     * {@link #initControlContext()}.
+     * @return void
+     * @throws Exception Error while populating context.  The {@link
+     * #main()} method will catch and rethrow as a
+     * <code>BuildException</code>.
+     */
+    protected function populateInitialContext(Capsule $context) {
+        $this->context->put("now", strftime("%c", time()));
+        $this->context->put("task", $this);
+    }
+
+    /**
+     * A hook method called at the end of {@link #execute()} which can
+     * be overridden to perform any necessary cleanup activities (such
+     * as the release of database connections, etc.).  By default,
+     * does nothing.
+     * @return void
+     * @throws Exception Problem cleaning up.
+     */
+    protected function cleanup() {
+    }
+}
+
+
+/**
+ * An "inner" class for holding assigned var values.
+ * May be need to expand beyond name/value in the future.
+ */
+class AssignedVar {
+    
+    private $name;
+    private $value;
+    
+    function setName($v) {
+        $this->name = $v;
+    }
+    
+    function setValue($v) {
+        $this->value = $v;
+    }
+    
+    function getName() {
+        return $this->name;
+    }
+    
+    function getValue() {
+        return $this->value;
+    }
+
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/ExtractBaseTask.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/ExtractBaseTask.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/ExtractBaseTask.php	(revision 19)
@@ -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 please see
+ * <http://phing.info>.
+ */
+
+require_once 'phing/tasks/system/MatchingTask.php';
+
+/**
+ * Base class for extracting tasks such as Unzip and Untar.
+ *
+ * @author    Joakim Bodin <joakim.bodin+phing@gmail.com>
+ * @version   $Revision: 1.0 $
+ * @package   phing.tasks.ext
+ * @since     2.2.0
+ */
+abstract class ExtractBaseTask extends MatchingTask {
+    /**
+     * @var PhingFile $file
+     */
+    protected $file;
+    /**
+     * @var PhingFile $todir
+     */
+    protected $todir;
+    protected $removepath;
+    protected $filesets = array(); // all fileset objects assigned to this task
+
+    /**
+     * Add a new fileset.
+     * @return FileSet
+     */
+    public function createFileSet() {
+        $this->fileset = new FileSet();
+        $this->filesets[] = $this->fileset;
+        return $this->fileset;
+    }
+
+    /**
+     * Set the name of the zip file to extract.
+     * @param PhingFile $file zip file to extract
+     */
+    public function setFile(PhingFile $file) {
+        $this->file = $file;
+    }
+
+    /**
+     * This is the base directory to look in for things to zip.
+     * @param PhingFile $baseDir
+     */
+    public function setToDir(PhingFile $todir) {
+        $this->todir = $todir;
+    }
+    
+    public function setRemovePath($removepath)
+    {
+    	$this->removepath = $removepath;
+    }
+
+    /**
+     * do the work
+     * @throws BuildException
+     */
+    public function main() {
+    
+        $this->validateAttributes();
+        
+        $filesToExtract = array();
+        if ($this->file !== null) {
+            if(!$this->isDestinationUpToDate($this->file)) {
+                $filesToExtract[] = $this->file;
+            } else {
+            	$this->log('Nothing to do: ' . $this->todir->getAbsolutePath() . ' is up to date for ' .  $this->file->getCanonicalPath(), Project::MSG_INFO);
+            }
+        }
+        
+        foreach($this->filesets as $compressedArchiveFileset) {
+            $compressedArchiveDirScanner = $compressedArchiveFileset->getDirectoryScanner($this->project);
+            $compressedArchiveFiles = $compressedArchiveDirScanner->getIncludedFiles();
+            $compressedArchiveDir = $compressedArchiveFileset->getDir($this->project);
+            
+            foreach ($compressedArchiveFiles as $compressedArchiveFilePath) {
+                $compressedArchiveFile = new PhingFile($compressedArchiveDir, $compressedArchiveFilePath);
+                if($compressedArchiveFile->isDirectory())
+                {
+                    throw new BuildException($compressedArchiveFile->getAbsolutePath() . ' compressed archive cannot be a directory.');
+                }
+                
+            	if(!$this->isDestinationUpToDate($compressedArchiveFile)) {
+            	   $filesToExtract[] = $compressedArchiveFile;
+            	} else {
+            		$this->log('Nothing to do: ' . $this->todir->getAbsolutePath() . ' is up to date for ' .  $compressedArchiveFile->getCanonicalPath(), Project::MSG_INFO);
+            	}
+            }
+        }
+        
+        foreach ($filesToExtract as $compressedArchiveFile) {
+            $this->extractArchive($compressedArchiveFile);
+        }
+    }
+    
+    abstract protected function extractArchive(PhingFile $compressedArchiveFile);
+    
+    /**
+     * @param array $files array of filenames
+     * @param PhingFile $dir
+     * @return boolean
+     */
+    protected function isDestinationUpToDate(PhingFile $compressedArchiveFile) {
+        if (!$compressedArchiveFile->exists()) {
+        	throw new BuildException("Could not find file " . $compressedArchiveFile->__toString() . " to extract.");
+        }
+        
+        $compressedArchiveContent = $this->listArchiveContent($compressedArchiveFile);
+        if(is_array($compressedArchiveContent)) {
+            
+            $fileSystem = FileSystem::getFileSystem();
+            foreach ($compressedArchiveContent as $compressArchivePathInfo) {
+                $compressArchiveFilename = $compressArchivePathInfo['filename'];
+                if(!empty($this->removepath) && strlen($compressArchiveFilename) >= strlen($this->removepath))
+                {
+                    $compressArchiveFilename = preg_replace('/^' . $this->removepath . '/','', $compressArchiveFilename);
+                }
+                $compressArchivePath = new PhingFile($this->todir, $compressArchiveFilename);
+                
+                if(!$compressArchivePath->exists() ||
+                    $fileSystem->compareMTimes($compressedArchiveFile->getCanonicalPath(), $compressArchivePath->getCanonicalPath()) == 1) {
+                    return false;
+                }
+            }
+            
+        }
+        
+        return true;
+    }
+    
+    abstract protected function listArchiveContent(PhingFile $compressedArchiveFile);
+    
+    /**
+     * Validates attributes coming in from XML
+     *
+     * @access  private
+     * @return  void
+     * @throws  BuildException
+     */
+    protected function validateAttributes() {
+    
+        if ($this->file === null && count($this->filesets) === 0) {
+            throw new BuildException("Specify at least one source compressed archive - a file or a fileset.");
+        }
+
+        if ($this->todir === null) {
+            throw new BuildException("todir must be set.");
+        }
+        
+        if ($this->todir !== null && $this->todir->exists() && !$this->todir->isDirectory()) {
+            throw new BuildException("todir must be a directory.");
+        }
+
+        if ($this->file !== null && $this->file->exists() && $this->file->isDirectory()) {
+            throw new BuildException("Compressed archive file cannot be a directory.");
+        }
+        
+        if ($this->file !== null && !$this->file->exists()) {
+        	throw new BuildException("Could not find compressed archive file " . $this->file->__toString() . " to extract.");
+        }
+    }
+    
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/FtpDeployTask.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/FtpDeployTask.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/FtpDeployTask.php	(revision 19)
@@ -0,0 +1,176 @@
+<?php
+/**
+ * $Id: FtpDeployTask.php 340 2008-01-21 14:39:50Z mrook $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+require_once 'phing/Task.php';
+require_once 'PEAR.php';
+
+/**
+ * FtpDeployTask
+ * 
+ * Deploys a set of files to a remote FTP server.
+ * 
+ * 
+ * Example usage:
+ * <ftpdeploy host="host" port="21" username="user" password="password" dir="public_html" mode="ascii" clearfirst="true">
+ *   <fileset dir=".">
+ *     <include name="**"/>
+ *     <exclude name="phing"/>
+ *     <exclude name="build.xml"/>
+ *     <exclude name="images/**.png"/>
+ *     <exclude name="images/**.gif"/>
+ *     <exclude name="images/**.jpg"/>
+ *   </fileset>
+ * </ftpdeploy>
+ *
+ * 
+ * @todo Documentation
+ * @author Jorrit Schippers <jorrit at ncode dot nl>
+ * @since 2.3.1
+ */
+class FtpDeployTask extends Task
+{
+	private $host = null;
+	private $port = 0;
+	private $username = null;
+	private $password = null;
+	private $dir = null;
+	private $filesets;
+	private $completeDirMap;
+	private $mode = null;
+	private $clearFirst = false;
+	
+	public function __construct() {
+		$this->filesets = array();
+		$this->completeDirMap = array();
+	}
+	
+	public function setHost($host) {
+		$this->host = $host;
+	}
+	
+	public function setPort($port) {
+		$this->port = (int) $port;
+	}
+	
+	public function setUsername($username) {
+		$this->username = $username;
+	}
+	
+	public function setPassword($password) {
+		$this->password = $password;
+	}
+	
+	public function setDir($dir) {
+		$this->dir = $dir;
+	}
+	
+	public function setMode($mode) {
+		switch(strtolower($mode)) {
+			case 'ascii':
+				$this->mode = FTP_ASCII;
+				break;
+			case 'binary':
+			case 'bin':
+				$this->mode = FTP_BINARY;
+				break;
+		}
+	}
+	
+	public function setClearFirst($clearFirst) {
+		$this->clearFirst = (bool) $clearFirst;
+	}
+	
+	function createFileSet() {
+		$num = array_push($this->filesets, new FileSet());
+		return $this->filesets[$num-1];
+	}
+	
+	/**
+	 * The init method: check if Net_FTP is available
+	 */
+	public function init() {
+		$paths = explode(PATH_SEPARATOR, get_include_path());
+		foreach($paths as $path) {
+			if(file_exists($path.DIRECTORY_SEPARATOR.'Net'.DIRECTORY_SEPARATOR.'FTP.php')) {
+				return true;
+			}
+		}
+		throw new BuildException('The FTP Deploy task requires the Net_FTP PEAR package.');
+	}
+	
+	/**
+	 * The main entry point method.
+	 */
+	public function main() {
+		$project = $this->getProject();
+		
+		require_once 'Net/FTP.php';
+		$ftp = new Net_FTP($this->host, $this->port);
+		$ret = $ftp->connect();
+		if(PEAR::isError($ret))
+			throw new BuildException('Could not connect to FTP server '.$this->post.' on port '.$this->port.': '.$ret->getMessage());
+		$ret = $ftp->login($this->username, $this->password);
+		if(PEAR::isError($ret))
+			throw new BuildException('Could not login to FTP server '.$this->post.' on port '.$this->port.' with username '.$this->username.': '.$ret->getMessage());
+		
+		if($this->clearFirst) {
+			// TODO change to a loop through all files and directories within current directory
+			$this->log('Clearing directory '.$this->dir, Project::MSG_INFO);
+			$dir = substr($this->dir, -1) == '/' ? $this->dir : $this->dir.'/';
+			$ftp->rm($dir, true);
+			$ftp->mkdir($dir);
+		}
+		
+		$ret = $ftp->cd($this->dir);
+		if(PEAR::isError($ret))
+			throw new BuildException('Could not change to directory '.$this->dir.': '.$ret->getMessage());
+		
+		$fs = FileSystem::getFileSystem();
+		$convert = $fs->getSeparator() == '\\';
+		
+		foreach($this->filesets as $fs) {
+			$ds = $fs->getDirectoryScanner($project);
+			$fromDir  = $fs->getDir($project);
+			$srcFiles = $ds->getIncludedFiles();
+			$srcDirs  = $ds->getIncludedDirectories();
+			foreach($srcDirs as $dirname) {
+				if($convert)
+					$dirname = str_replace('\\', '/', $dirname);
+				$this->log('Will create directory '.$dirname, Project::MSG_VERBOSE);
+				$ret = $ftp->mkdir($dirname, true);
+				if(PEAR::isError($ret))
+					throw new BuildException('Could not create directory '.$dirname.': '.$ret->getMessage());
+			}
+			foreach($srcFiles as $filename) {
+				$file = new PhingFile($fromDir->getAbsolutePath(), $filename);
+				if($convert)
+					$filename = str_replace('\\', '/', $filename);
+				$this->log('Will copy '.$file->getCanonicalPath().' to '.$filename, Project::MSG_VERBOSE);
+				$ret = $ftp->put($file->getCanonicalPath(), $filename, true, $this->mode);
+				if(PEAR::isError($ret))
+					throw new BuildException('Could not deploy file '.$filename.': '.$ret->getMessage());
+			}
+		}
+		
+		$ftp->disconnect();
+	}
+}
+?>
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/JslLintTask.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/JslLintTask.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/JslLintTask.php	(revision 19)
@@ -0,0 +1,184 @@
+<?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 please see
+ * <http://phing.info>.
+ */
+  
+require_once 'phing/Task.php';
+
+  /**
+  * A Javascript lint task. Checks syntax of Javascript files.
+  * Javascript lint (http://www.javascriptlint.com) must be in the system path.
+  * This class is based on Knut Urdalen's PhpLintTask.
+  *
+  * @author Stefan Priebsch <stefan.priebsch@e-novative.de>
+  */
+  class JslLintTask extends Task
+  {
+    protected $file;  // the source file (from xml attribute)
+    protected $filesets = array(); // all fileset objects assigned to this task
+
+    protected $showWarnings = true;
+    protected $haltOnFailure = false;
+    protected $hasErrors = false;
+    private $badFiles = array();
+
+    /**
+     * Sets the flag if warnings should be shown
+     * @param boolean $show
+     */
+    public function setShowWarnings($show) {
+      $this->showWarnings = StringHelper::booleanValue($show);
+    }
+
+    /**
+     * The haltonfailure property
+     * @param boolean $aValue
+     */
+    public function setHaltOnFailure($aValue) {
+      $this->haltOnFailure = $aValue;
+    }
+  
+    /**
+     * File to be performed syntax check on
+     * @param PhingFile $file
+     */
+    public function setFile(PhingFile $file) {
+      $this->file = $file;
+    }
+    
+    /**
+     * Nested creator, creates a FileSet for this task
+     *
+     * @return FileSet The created fileset object
+     */
+    function createFileSet() {
+      $num = array_push($this->filesets, new FileSet());
+      return $this->filesets[$num-1];
+    }
+  
+    /**
+     * Execute lint check against PhingFile or a FileSet
+     */
+    public function main() {
+      if(!isset($this->file) and count($this->filesets) == 0) {
+        throw new BuildException("Missing either a nested fileset or attribute 'file' set");
+      }
+  
+      if($this->file instanceof PhingFile) {
+        $this->lint($this->file->getPath());
+      } else { // process filesets
+        $project = $this->getProject();
+        foreach($this->filesets as $fs) {
+          $ds = $fs->getDirectoryScanner($project);
+          $files = $ds->getIncludedFiles();
+          $dir = $fs->getDir($this->project)->getPath();
+          foreach($files as $file) {
+            $this->lint($dir.DIRECTORY_SEPARATOR.$file);
+          }
+        }
+      }
+  
+      if ($this->haltOnFailure && $this->hasErrors) throw new BuildException('Syntax error(s) in JS files:' .implode(', ',$this->badFiles));
+    }
+  
+    /**
+     * Performs the actual syntax check
+     *
+     * @param string $file
+     * @return void
+     */
+    protected function lint($file)
+    {
+      exec('jsl', $output);
+      if (!preg_match('/JavaScript\sLint/', implode('', $output))) throw new BuildException('Javascript Lint not found');
+    
+      $command = 'jsl -output-format file:__FILE__;line:__LINE__;message:__ERROR__ -process ';
+
+      if(file_exists($file))
+      {
+        if(is_readable($file))
+        {
+          $messages = array();
+          exec($command.'"'.$file.'"', $messages);
+
+          $summary = $messages[sizeof($messages) - 1];
+
+          preg_match('/(\d+)\serror/', $summary, $matches);
+          $errorCount = $matches[1];
+          
+          preg_match('/(\d+)\swarning/', $summary, $matches);
+          $warningCount = $matches[1];
+
+          $errors = array();
+          $warnings = array();
+          if ($errorCount > 0 || $warningCount > 0) {
+            $last = false;
+            foreach ($messages as $message) {
+              $matches = array();
+              if (preg_match('/^(\.*)\^$/', $message)) {
+                $column = strlen($message);
+                if ($last == 'error') {
+                  $errors[count($errors) - 1]['column'] = $column;
+                } else if ($last == 'warning') {
+                  $warnings[count($warnings) - 1]['column'] = $column;
+                }
+                $last = false;
+              }
+              if (!preg_match('/^file:(.+);line:(\d+);message:(.+)$/', $message, $matches)) continue;
+              $msg = $matches[3];
+              $data = array('filename' => $matches[1], 'line' => $matches[2], 'message' => $msg);
+              if (preg_match('/^.*error:.+$/i', $msg)) {
+                $errors[] = $data;
+                $last = 'error';
+              } else if (preg_match('/^.*warning:.+$/i', $msg)) {
+                $warnings[] = $data;
+                $last = 'warning';
+              }
+            }
+          }
+
+          if($this->showWarnings && $warningCount > 0)
+          {
+            $this->log($file . ': ' . $warningCount . ' warnings detected', Project::MSG_WARN);
+            foreach ($warnings as $warning) {
+              $this->log('- line ' . $warning['line'] . (isset($warning['column']) ? ' column ' . $warning['column'] : '') . ': ' . $warning['message'], Project::MSG_WARN);
+            }
+          }
+            
+          if($errorCount > 0)
+          {
+            $this->log($file . ': ' . $errorCount . ' errors detected', Project::MSG_ERR);
+            foreach ($errors as $error) {
+              $this->log('- line ' . $error['line'] . (isset($error['column']) ? ' column ' . $error['column'] : '') . ': ' . $error['message'], Project::MSG_ERR);
+            }
+            $this->badFiles[] = $file;
+            $this->hasErrors = true;
+          } else if (!$this->showWarnings || $warningCount == 0) {
+            $this->log($file . ': No syntax errors detected', Project::MSG_INFO);
+          }
+        } else {
+          throw new BuildException('Permission denied: '.$file);
+        }
+      } else {
+        throw new BuildException('File not found: '.$file);
+      }
+    }
+  }
+
+
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/MailTask.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/MailTask.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/MailTask.php	(revision 19)
@@ -0,0 +1,77 @@
+<?php
+/*
+ *  $Id: MailTask.php 43 2006-03-10 14:31:51Z mrook $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+ 
+include_once 'phing/Task.php';
+
+/**
+ *  Send a message by mail() 
+ *
+ *  <mail to="user@example.org" subject="build complete">The build process is a success...</mail> 
+ * 
+ *  @author   Francois Harvey at SecuriWeb (http://www.securiweb.net)
+ *  @version  $Revision: 1.1 $
+ *  @package  phing.tasks.ext
+ */
+class MailTask extends Task {
+
+    protected $recipient;
+      
+    protected $subject;
+    
+    protected $msg;
+
+    function main() {
+        $this->log('Sending mail to ' . $this->recipient );    
+        mail($this->recipient, $this->subject, $this->msg);
+    }
+
+    /** setter for message */
+    function setMsg($msg) {
+        $this->setMessage($msg);
+    }
+
+    /** alias setter */
+    function setMessage($msg) {
+        $this->msg = (string) $msg;
+    }
+    
+    /** setter for subject **/
+    function setSubject($subject) {
+        $this->subject = (string) $subject;    
+    }
+
+    /** setter for recipient **/
+    function setRecipient($recipient) {
+        $this->recipient = (string) $recipient;
+    }
+
+    /** alias for recipient **/
+    function setTo($recipient) {
+        $this->recipient = (string) $recipient;
+    }
+        
+    /** Supporting the <mail>Message</mail> syntax. */
+    function addText($msg)
+    {
+        $this->msg = (string) $msg;
+    }
+}
+
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/ManifestTask.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/ManifestTask.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/ManifestTask.php	(revision 19)
@@ -0,0 +1,341 @@
+<?php
+/**
+ * $Id: ManifestTask.php 341 2008-01-21 14:41:07Z mrook $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+require_once "phing/Task.php";
+require_once 'phing/system/io/PhingFile.php';
+
+/**
+ * ManifestTask
+ * 
+ * Generates a simple Manifest file with optional checksums.
+ * 
+ * 
+ * Manifest schema:
+ * ...
+ * path/to/file		CHECKSUM	[CHECKSUM2]		[CHECKSUM3]
+ * path/to/secondfile		CHECKSUM	[CHECKSUM2]		[CHECKSUM3]
+ * ...
+ * 
+ * Example usage:
+ * <manifest checksum="crc32" file="${dir_build}/Manifest">
+ * 		<fileset refid="files_build" />
+ * </manifest>
+ * 
+ * <manifest checksum="md5,adler32,sha256" file="${dir_build}/Manifest">
+ * 		<fileset refid="files_build" />
+ * </manifest>
+ * 
+ * 
+ * 
+ * @author David Persson <davidpersson at qeweurope dot org>
+ * @since 2.3.1
+ */
+class ManifestTask extends Task
+{
+	var $taskname = 'manifest';
+	
+	/**
+	 * Action
+	 * 
+	 * "w" for reading in files from fileSet
+	 * and writing manifest
+	 * 
+	 * or
+	 * 
+	 * "r" for reading in files from fileSet
+	 * and checking against manifest
+	 * 
+	 * @var string "r" or "w"
+	 */
+	private $action = 'w';
+	
+    /**
+     * The target file passed in the buildfile.
+     */
+    private $destFile = null;
+    
+    /**
+     * Holds filesets
+     *
+     * @var array An Array of objects
+     */
+	private $filesets = array();
+
+    /**
+     * Enable/Disable checksuming or/and select algorithm
+     * true defaults to md5
+     * false disables checksuming
+     * string "md5,sha256,..." enables generation of multiple checksums
+     * string "sha256" generates sha256 checksum only
+     * 
+     * @var mixed
+     */
+	private $checksum = false;
+	
+	/**
+	 * A string used in hashing method
+	 *
+	 * @var string
+	 */
+	private $salt = '';
+	
+	/**
+	 * Holds some data collected during runtime
+	 *
+	 * @var array
+	 */
+	private $meta = array('totalFileCount' => 0,'totalFileSize' => 0);
+	
+	
+    /**
+     * The setter for the attribute "file"
+     * This is where the manifest will be written to/read from
+     * 
+     * @param string Path to readable file
+     * @return void
+     */
+    public function setFile(PhingFile $file)
+    {
+        $this->file = $file;
+    }
+
+    /**
+     * The setter for the attribute "checksum"
+     * 
+     * @param mixed $mixed
+     * @return void
+     */
+    public function setChecksum($mixed)
+    {
+    	if(is_string($mixed)) {
+    		$data = array(strtolower($mixed));
+
+    		if(strpos($data[0],',')) {
+				$data = explode(',',$mixed);
+			}
+			
+			$this->checksum = $data;
+						    		
+    	} elseif($mixed === true) {
+	        $this->checksum = array('md5');
+    		
+    	}
+    }
+    
+    /**
+     * The setter for the optional attribute "salt"
+     *
+     * @param string $string
+     * @return void
+     */
+    public function setSalt($string) 
+    {
+    	$this->salt = $string;
+    }    
+    
+    /**
+     * Nested creator, creates a FileSet for this task
+     *
+     * @access  public
+     * @return  object  The created fileset object
+     */
+    public function createFileSet()
+    {
+        $num = array_push($this->filesets, new FileSet());
+        return $this->filesets[$num-1];
+    }
+
+    /**
+     * The init method: Do init steps.
+     */
+    public function init()
+    {
+      // nothing to do here
+    }
+
+    /**
+     * Delegate the work
+     */
+    public function main()
+    {
+		$this->validateAttributes();
+        
+		if($this->action == 'w') {
+			$this->write();
+			
+		} elseif($this->action == 'r') {
+			$this->read();
+			
+		}
+    }
+
+    /**
+     * Creates Manifest file
+     * Writes to $this->file
+     * 
+     * @throws BuildException
+     */
+    private function write()
+    {
+      	$project = $this->getProject();
+        
+    	if(!touch($this->file->getPath())) {
+			throw new BuildException("Unable to write to ".$this->file->getPath().".");
+		}        
+
+		$this->log("Writing to " . $this->file->__toString(), Project::MSG_INFO);
+
+		if(is_array($this->checksum)) {
+			$this->log("Using " . implode(', ',$this->checksum)." for checksuming.", Project::MSG_INFO);
+		}
+		
+		foreach($this->filesets as $fs) {
+			
+			$dir = $fs->getDir($this->project)->getPath();
+
+            $ds = $fs->getDirectoryScanner($project);
+            $fromDir  = $fs->getDir($project);
+            $srcFiles = $ds->getIncludedFiles();
+            $srcDirs  = $ds->getIncludedDirectories();			
+
+            foreach($ds->getIncludedFiles() as $file_path) {
+				$line = $file_path;
+				if($this->checksum) {
+					foreach($this->checksum as $algo) {
+						if(!$hash = $this->hashFile($dir.'/'.$file_path,$algo)) {
+							throw new BuildException("Hashing $dir/$file_path with $algo failed!");
+						}
+
+						$line .= "\t".$hash;
+					}
+				}
+				$line .= "\n";
+				$manifest[] = $line;
+				$this->log("Adding file ".$file_path,Project::MSG_VERBOSE);
+				$this->meta['totalFileCount'] ++;
+				$this->meta['totalFileSize'] += filesize($dir.'/'.$file_path);
+			}
+			
+		}
+		
+		file_put_contents($this->file,$manifest);
+		
+		$this->log("Done. Total files: ".$this->meta['totalFileCount'].". Total file size: ".$this->meta['totalFileSize']." bytes.", Project::MSG_INFO);    	
+    }
+    
+    /**
+     * @todo implement
+     */
+    private function read()
+    {
+    	throw new BuildException("Checking against manifest not yet supported.");
+    }
+    
+    /**
+     * Wrapper method for hash generation
+     * Automatically selects extension
+     * Falls back to built-in functions
+     * 
+     * @link  http://www.php.net/mhash
+     * @link  http://www.php.net/hash
+     * 
+     * @param string $msg The string that should be hashed
+     * @param string $algo Algorithm
+     * @return mixed String on success, false if $algo is not available 
+     */
+    private function hash($msg,$algo) 
+    {
+		if(extension_loaded('hash')) {
+			$algo = strtolower($algo);
+    		
+			if(in_array($algo,hash_algos())) {
+				return hash($algo,$this->salt.$msg);
+			}
+			
+    	}
+    	
+    	if(extension_loaded('mhash')) {
+			$algo = strtoupper($algo);
+			
+			if(defined('MHASH_'.$algo)) {
+				return mhash('MHASH_'.$algo,$this->salt.$msg);
+			
+			}
+		}
+		
+		switch(strtolower($algo)) {
+			case 'md5':
+				return md5($this->salt.$msg);
+			case 'crc32':
+				return abs(crc32($this->salt.$msg));
+		}
+		
+		return false;
+    }
+    
+    /**
+     * Hash a files contents 
+     * plus it's size an modification time
+     *
+     * @param string $file
+     * @param string $algo
+     * @return mixed String on success, false if $algo is not available 
+     */
+    private function hashFile($file,$algo)
+    {
+    	if(!file_exists($file)) {
+    		return false;
+    	}
+    	
+    	$msg = file_get_contents($file).filesize($file).filemtime($file);
+    	
+    	return $this->hash($msg,$algo);
+    }
+    
+    /**
+     * Validates attributes coming in from XML
+     *
+     * @access  private
+     * @return  void
+     * @throws  BuildException
+     */
+    protected function validateAttributes()
+    {
+        if($this->action != 'r' && $this->action != 'w') {
+    		throw new BuildException("'action' attribute has non valid value. Use 'r' or 'w'");
+    	}
+    	    	
+    	if(empty($this->salt)) {
+    		$this->log("No salt provided. Specify one with the 'salt' attribute.", Project::MSG_WARN);
+    	}
+    	
+        if (is_null($this->file) && count($this->filesets) === 0) {
+            throw new BuildException("Specify at least sources and destination - a file or a fileset.");
+        }
+
+        if (!is_null($this->file) && $this->file->exists() && $this->file->isDirectory()) {
+            throw new BuildException("Destination file cannot be a directory.");
+        }
+        
+    }     
+}
+
+
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/PackageAsPathTask.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/PackageAsPathTask.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/PackageAsPathTask.php	(revision 19)
@@ -0,0 +1,65 @@
+<?php
+
+/*
+ *  $Id: PackageAsPathTask.php 43 2006-03-10 14:31:51Z mrook $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>. 
+ */
+
+require_once 'phing/Task.php';
+
+/**
+ * Convert dot-notation packages to relative paths.
+ *
+ * @author    Hans Lellelid <hans@xmpl.org>
+ * @version   $Revision: 1.5 $
+ * @package   phing.tasks.ext
+ */
+class PackageAsPathTask extends Task {
+
+    /** The package to convert. */
+    protected $pckg;
+
+    /** The value to store the conversion in. */
+    protected $name;
+    
+    /**
+     * Executes the package to patch converstion and stores it
+     * in the user property <code>value</code>.
+     */
+    public function main()
+    {
+        $this->project->setUserProperty($this->name, strtr($this->pckg, '.', '/'));        
+    }
+
+    /**
+     * @param string $pckg the package to convert
+     */
+    public function setPackage($pckg)
+    {
+        $this->pckg = $pckg;
+    }
+
+    /**
+     * @param string $name the Ant variable to store the path in
+     */
+    public function setName($name)
+    {
+        $this->name = $name;
+    }
+    
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/PearPackage2Task.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/PearPackage2Task.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/PearPackage2Task.php	(revision 19)
@@ -0,0 +1,270 @@
+<?php
+/*
+ *  $Id: PearPackage2Task.php 210 2007-08-01 22:48:36Z hans $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+require_once 'phing/tasks/ext/PearPackageTask.php';
+
+/**
+ * A task to create a PEAR package.xml version 2.0 file.
+ *
+ * This class uses the PEAR_PackageFileManager2 class to perform the work.
+ *
+ * This class is designed to be very flexible -- i.e. account for changes to the package.xml w/o
+ * requiring changes to this class.  We've accomplished this by having generic <option> and <mapping>
+ * nested elements.  All options are set using PEAR_PackageFileManager2::setOptions().
+ *
+ * The <option> tag is used to set a simple option value.
+ * <code>
+ * <option name="option_name" value="option_value"/>
+ * or <option name="option_name">option_value</option>
+ * </code>
+ *
+ * The <mapping> tag represents a complex data type.  You can use nested <element> (and nested <element> with
+ * <element> tags) to represent the full complexity of the structure.  Bear in mind that what you are creating
+ * will be mapped to an associative array that will be passed in via PEAR_PackageFileManager2::setOptions().
+ * <code>
+ * <mapping name="option_name">
+ *  <element key="key_name" value="key_val"/>
+ *  <element key="key_name" value="key_val"/>
+ * </mapping>
+ * </code>
+ *
+ * Here's an over-simple example of how this could be used:
+ * <code>
+ * <pearpkg2 name="phing" dir="${build.src.dir}">
+ *  <fileset dir="src">
+ *      <include name="**"/>
+ *  </fileset>
+ *  <option name="outputdirectory" value="./build"/>
+ *  <option name="packagefile" value="package2.xml"/>
+ *  <option name="packagedirectory" value="./${build.dist.dir}"/>
+ *  <option name="baseinstalldir" value="${pkg.prefix}"/>
+ *  <option name="channel" value="my.pear-channel.com"/>
+ *  <option name="summary" value="${pkg.summary}"/>
+ *  <option name="description" value="${pkg.description}"/>
+ *  <option name="apiversion" value="${pkg.version}"/>
+ *  <option name="apistability" value="beta"/>
+ *  <option name="releaseversion" value="${pkg.version}"/>
+ *  <option name="releasestability" value="beta"/>
+ *  <option name="license" value="none"/>
+ *  <option name="phpdep" value="5.0.0"/>
+ *  <option name="pearinstallerdep" value="1.4.6"/>
+ *  <option name="packagetype" value="php"/>
+ *  <option name="notes" value="${pkg.relnotes}"/>
+ *  <mapping name="maintainers">
+ *   <element>
+ *    <element key="handle" value="hlellelid"/>
+ *    <element key="name" value="Hans"/>
+ *    <element key="email" value="hans@xmpl.org"/>
+ *    <element key="role" value="lead"/>
+ *   </element>
+ *  </mapping>
+ * </pearpkg2>
+ * </code>
+ *
+ * Look at the build.xml in the Phing base directory (assuming you have the full distro / CVS version of Phing) to
+ * see a more complete example of how to call this script.
+ *
+ * @author   Stuart Binge <stuart.binge@complinet.com>
+ * @author   Hans Lellelid <hans@xmpl.org>
+ * @package  phing.tasks.ext
+ * @version  $Revision: 1.9 $
+ */
+class PearPackage2Task extends PearPackageTask {
+
+    public function init() {
+        include_once 'PEAR/PackageFileManager2.php';
+        if (!class_exists('PEAR_PackageFileManager2')) {
+            throw new BuildException("You must have installed PEAR_PackageFileManager in order to create a PEAR package.xml version 2.0 file.");
+        }
+    }
+
+    protected function setVersion2Options()
+    {
+        $this->pkg->setPackage($this->package);
+        $this->pkg->setDate(strftime('%Y-%m-%d'));
+        $this->pkg->setTime(strftime('%H:%M:%S')); 
+
+        $newopts = array();
+        foreach ($this->options as $opt) {
+            switch ($opt->getName()) {
+                case 'summary':
+                    $this->pkg->setSummary($opt->getValue());
+                    break;
+
+                case 'description':
+                    $this->pkg->setDescription($opt->getValue());
+                    break;
+
+                case 'uri':
+                    $this->pkg->setUri($opt->getValue());
+                    break;
+
+                case 'license':
+                    $this->pkg->setLicense($opt->getValue());
+                    break;
+
+                case 'channel':
+                    $this->pkg->setChannel($opt->getValue());
+                    break;
+
+                case 'apiversion':
+                    $this->pkg->setAPIVersion($opt->getValue());
+                    break;
+
+                case 'releaseversion':
+                    $this->pkg->setReleaseVersion($opt->getValue());
+                    break;
+
+                case 'releasestability':
+                    $this->pkg->setReleaseStability($opt->getValue());
+                    break;
+
+                case 'apistability':
+                    $this->pkg->setAPIStability($opt->getValue());
+                    break;
+
+                case 'notes':
+                    $this->pkg->setNotes($opt->getValue());
+                    break;
+
+                case 'packagetype':
+                    $this->pkg->setPackageType($opt->getValue());
+                    break;
+
+                case 'phpdep':
+                    $this->pkg->setPhpDep($opt->getValue());
+                    break;
+
+                case 'pearinstallerdep':
+                    $this->pkg->setPearinstallerDep($opt->getValue());
+                    break;
+
+                default:
+                    $newopts[] = $opt;
+                    break;
+            }
+        }
+        $this->options = $newopts;
+
+        $newmaps = array();
+        foreach ($this->mappings as $map) {
+            switch ($map->getName()) {
+                case 'deps':
+                    $deps = $map->getValue();
+                    foreach ($deps as $dep) {
+                        $type = isset($dep['optional']) ? 'optional' : 'required';
+                        $min = isset($dep['min']) ? $dep['min'] : $dep['version'];
+                        $max = isset($dep['max']) ? $dep['max'] : $dep['version'];
+                        $rec = isset($dep['recommended']) ? $dep['recommended'] : $dep['version'];
+                        $channel = isset($dep['channel']) ? $dep['channel'] : false;
+                        $uri = isset($dep['uri']) ? $dep['uri'] : false;
+
+                        if (!empty($channel)) {
+                            $this->pkg->addPackageDepWithChannel(
+                                $type, $dep['name'], $channel, $min, $max, $rec
+                            );
+                        } elseif (!empty($uri)) {
+                            $this->pkg->addPackageDepWithUri(
+                                $type, $dep['name'], $uri
+                            );
+                        }
+                    };
+                    break;
+
+                case 'extdeps':
+                    $deps = $map->getValue();
+                    foreach ($deps as $dep) {
+                        $type = isset($dep['optional']) ? 'optional' : 'required';
+                        $min = isset($dep['min']) ? $dep['min'] : $dep['version'];
+                        $max = isset($dep['max']) ? $dep['max'] : $dep['version'];
+                        $rec = isset($dep['recommended']) ? $dep['recommended'] : $dep['version'];
+
+                        $this->pkg->addExtensionDep(
+                            $type, $dep['name'], $min, $max, $rec
+                        );
+                    };
+                    break;
+
+                case 'maintainers':
+                    $maintainers = $map->getValue();
+
+                    foreach ($maintainers as $maintainer) {
+                        if (!isset($maintainer['active'])) {
+                            $maintainer['active'] = 'yes';
+                        }
+                        $this->pkg->addMaintainer(
+                            $maintainer['role'],
+                            $maintainer['handle'],
+                            $maintainer['name'],
+                            $maintainer['email'],
+                            $maintainer['active']
+                        );
+                    }
+                    break;
+
+                case 'replacements':
+                    $replacements = $map->getValue();
+
+                    foreach($replacements as $replacement) { 
+                        $this->pkg->addReplacement(
+                            $replacement['path'], 
+							$replacement['type'], 
+							$replacement['from'], 
+							$replacement['to']
+						);
+					}
+				    break;
+
+                default:
+                    $newmaps[] = $map;
+            }
+        }
+        $this->mappings = $newmaps;
+    }
+
+    /**
+     * Main entry point.
+     * @return void
+     */
+    public function main()
+    {
+        if ($this->dir === null) {
+            throw new BuildException("You must specify the \"dir\" attribute for PEAR package 2 task.");
+        }
+
+        if ($this->package === null) {
+            throw new BuildException("You must specify the \"name\" attribute for PEAR package 2 task.");
+        }
+
+        $this->pkg = new PEAR_PackageFileManager2();
+
+        $this->setVersion2Options();
+        $this->setOptions();
+
+        $this->pkg->addRelease();
+        $this->pkg->generateContents();
+        $e = $this->pkg->writePackageFile();
+        if (PEAR::isError($e)) {
+            throw new BuildException("Unable to write package file.", new Exception($e->getMessage()));
+        }
+    }
+
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/PearPackageTask.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/PearPackageTask.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/PearPackageTask.php	(revision 19)
@@ -0,0 +1,421 @@
+<?php
+/*
+ *  $Id: PearPackageTask.php 144 2007-02-05 15:19:00Z hans $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+require_once 'phing/tasks/system/MatchingTask.php';
+include_once 'phing/types/FileSet.php';
+
+/**
+ * A task to create PEAR package.xml file.
+ * 
+ * This class uses the PEAR_PackageFileMaintainer class to perform the work.
+ * 
+ * This class is designed to be very flexible -- i.e. account for changes to the package.xml w/o
+ * requiring changes to this class.  We've accomplished this by having generic <option> and <mapping>
+ * nested elements.  All options are set using PEAR_PackageFileMaintainer::setOptions().
+ * 
+ * The <option> tag is used to set a simple option value.
+ * <code>
+ * <option name="option_name" value="option_value"/> 
+ * or <option name="option_name">option_value</option>
+ * </code>
+ * 
+ * The <mapping> tag represents a complex data type.  You can use nested <element> (and nested <element> with
+ * <element> tags) to represent the full complexity of the structure.  Bear in mind that what you are creating
+ * will be mapped to an associative array that will be passed in via PEAR_PackageFileMaintainer::setOptions().
+ * <code>
+ * <mapping name="option_name">
+ *  <element key="key_name" value="key_val"/>
+ *  <element key="key_name" value="key_val"/>
+ * </mapping>
+ * </code>
+ * 
+ * Here's an over-simple example of how this could be used:
+ * <code>
+ * <pearpkg name="phing" dir="${build.src.dir}" destFile="${build.base.dir}/package.xml">
+ *  <fileset>
+ *   <include name="**"/>
+ *  </fileset>
+ *  <option name="notes">Sample release notes here.</option>
+ *  <option name="description">Package description</option>
+ *  <option name="summary">Short description</option>
+ *  <option name="version" value="2.0.0b1"/>
+ *  <option name="state" value="beta"/>
+ *  <mapping name="maintainers">
+ *   <element>
+ *    <element key="handle" value="hlellelid"/>
+ *    <element key="name" value="Hans"/>
+ *    <element key="email" value="hans@xmpl.org"/>
+ *    <element key="role" value="lead"/>
+ *   </element>
+ *  </mapping>
+ * </pearpkg>
+ * </code>
+ *
+ * Look at the build.xml in the Phing base directory (assuming you have the full distro / CVS version of Phing) to
+ * see a more complete example of how to call this script.
+ * 
+ * @author   Hans Lellelid <hans@xmpl.org>
+ * @package  phing.tasks.ext
+ * @version  $Revision: 1.9 $
+ */
+class PearPackageTask extends MatchingTask {
+    
+    /** */        
+    protected $package;
+
+    /** Base directory for reading files. */
+    protected $dir;
+    
+    /** Package file */
+    private $packageFile;
+    
+    /** @var array FileSet[] */
+    private $filesets = array();
+    
+    /** @var PEAR_PackageFileManager */
+    protected $pkg;
+    
+    private $preparedOptions = array();
+    
+    /** @var array PearPkgOption[] */
+    protected $options = array();
+    
+    /** Nested <mapping> (complex options) types. */
+    protected $mappings = array();
+    
+    public function init() {
+        include_once 'PEAR/PackageFileManager.php';
+        if (!class_exists('PEAR_PackageFileManager')) {
+            throw new BuildException("You must have installed PEAR_PackageFileManager in order to create a PEAR package.xml file.");
+        }
+    }
+    
+    /**
+     * Sets PEAR package.xml options, based on class properties.
+     * @return void
+     */
+    protected function setOptions() {
+    
+        // 1) first prepare/populate options        
+        $this->populateOptions();
+
+        // 2) make any final adjustments (this could move into populateOptions() also)
+        
+        // default PEAR basedir would be the name of the package (e.g."phing")
+        if (!isset($this->preparedOptions['baseinstalldir'])) {
+            $this->preparedOptions['baseinstalldir'] = $this->package;
+        }
+        
+        // unless filelistgenerator has been overridden, we use Phing FileSet generator
+        if (!isset($this->preparedOptions['filelistgenerator'])) {
+            if (empty($this->filesets)) {
+                throw new BuildException("You must use a <fileset> tag to specify the files to include in the package.xml");
+            }
+            $this->preparedOptions['filelistgenerator'] = 'Fileset';
+            $this->preparedOptions['usergeneratordir'] = dirname(__FILE__) . DIRECTORY_SEPARATOR . 'pearpackage';
+            // Some PHING-specific options needed by our Fileset reader
+            $this->preparedOptions['phing_project'] = $this->project;
+            $this->preparedOptions['phing_filesets'] = $this->filesets;
+        } elseif ($this->preparedOptions['filelistgeneragor'] != 'Fileset' && !empty($this->filesets)) {
+            throw new BuildException("You cannot use <fileset> element if you have specified the \"filelistgenerator\" option.");
+        }                
+        
+        // 3) Set the options
+                
+        // No need for excessive validation here, since the  PEAR class will do its own 
+        // validation & return errors
+        $e = $this->pkg->setOptions($this->preparedOptions);
+            
+        if (PEAR::isError($e)) {
+            throw new BuildException("Unable to set options.", new Exception($e->getMessage()));
+        }
+    }
+    
+    /**
+     * Fixes the boolean in optional dependencies
+     */
+    private function fixDeps($deps)
+    {
+        foreach (array_keys($deps) as $dep)
+        {
+            if (isset($deps[$dep]['optional']) && $deps[$dep]['optional'])
+            {
+                $deps[$dep]['optional'] = "yes";
+            }
+        }
+        
+        return $deps;
+    }
+    
+    /**
+     * Adds the options that are set via attributes and the nested tags to the options array.
+     */
+    private function populateOptions() {
+        
+        // These values could be overridden if explicitly defined using nested tags    
+        $this->preparedOptions['package'] = $this->package;
+        $this->preparedOptions['packagedirectory'] = $this->dir->getAbsolutePath();
+        
+        if ($this->packageFile !== null) {
+            // create one w/ full path
+            $f = new PhingFile($this->packageFile->getAbsolutePath());
+            $this->preparedOptions['packagefile'] = $f->getName();
+            // must end in trailing slash
+            $this->preparedOptions['outputdirectory'] = $f->getParent() . DIRECTORY_SEPARATOR;
+            $this->log("Creating package file: " . $f->__toString(), Project::MSG_INFO);
+        } else {
+            $this->log("Creating [default] package.xml file in base directory.", Project::MSG_INFO);
+        }
+        
+        // converts option objects and mapping objects into 
+        // key => value options that can be passed to PEAR_PackageFileManager
+        
+        foreach($this->options as $opt) {
+            $this->preparedOptions[ $opt->getName() ] = $opt->getValue(); //no arrays yet. preg_split('/\s*,\s*/', $opt->getValue());
+        }
+        
+        foreach($this->mappings as $map) {
+            $value = $map->getValue(); // getValue returns complex value
+            
+            if ($map->getName() == 'deps')
+            {
+                $value = $this->fixDeps($value);
+            }
+            
+            $this->preparedOptions[ $map->getName() ] = $value;
+        }
+    }
+    
+    /**
+     * Main entry point.
+     * @return void
+     */
+    public function main() {        
+        
+        if ($this->dir === null) {
+            throw new BuildException("You must specify the \"dir\" attribute for PEAR package task.");
+        }
+        
+        if ($this->package === null) {
+            throw new BuildException("You must specify the \"name\" attribute for PEAR package task.");
+        }
+        
+        $this->pkg = new PEAR_PackageFileManager();                
+        
+        $this->setOptions();
+        
+        $e = $this->pkg->writePackageFile();
+        if (PEAR::isError($e)) {
+            throw new BuildException("Unable to write package file.", new Exception($e->getMessage()));
+        }
+        
+    }
+    
+    /**
+     * Used by the PEAR_PackageFileManager_PhingFileSet lister.
+     * @return array FileSet[]
+     */
+    public function getFileSets() {
+        return $this->filesets;
+    }
+    
+    // -------------------------------
+    // Set properties from XML
+    // -------------------------------
+
+    /**
+     * Nested creator, creates a FileSet for this task
+     *
+     * @return FileSet The created fileset object
+     */
+    function createFileSet() {
+        $num = array_push($this->filesets, new FileSet());
+        return $this->filesets[$num-1];
+    }
+    
+    /**
+     * Set "package" property from XML.
+     * @see setName()
+     * @param string $v
+     * @return void
+     */
+    public function setPackage($v) {
+        $this->package = $v;
+    }
+    
+    /**
+     * Sets "dir" property from XML.
+     * @param PhingFile $f
+     * @return void
+     */
+    public function setDir(PhingFile $f) {
+        $this->dir = $f;
+    }
+
+    /**
+     * Sets "name" property from XML.
+     * @param string $v
+     * @return void
+     */
+    public function setName($v) {
+        $this->package = $v;
+    }
+    
+    /**
+     * Sets the file to use for generated package.xml
+     */
+    public function setDestFile(PhingFile $f) {
+        $this->packageFile = $f;
+    }
+    
+    /**
+     * Handles nested generic <option> elements.
+     */
+    function createOption() {
+        $o = new PearPkgOption();
+        $this->options[] = $o;
+        return $o;
+    }
+    
+    /**
+     * Handles nested generic <option> elements.
+     */
+    function createMapping() {
+        $o = new PearPkgMapping();
+        $this->mappings[] = $o;
+        return $o;
+    }
+}
+
+
+
+/**
+ * Generic option class is used for non-complex options.
+ */
+class PearPkgOption {
+    
+    private    $name;
+    private $value;
+    
+    public function setName($v) { $this->name = $v; }
+    public function getName() { return $this->name; }
+    
+    public function setValue($v) { $this->value = $v; }
+    public function getValue() { return $this->value; }
+    public function addText($txt) { $this->value = trim($txt); }
+        
+}
+
+/**
+ * Handles complex options <mapping> elements which are hashes (assoc arrays).
+ */
+class PearPkgMapping {
+
+    private    $name;
+    private $elements = array();    
+    
+    public function setName($v) {
+        $this->name = $v;
+    }
+    
+    public function getName() { 
+        return $this->name;
+    }
+
+    public function createElement() { 
+        $e = new PearPkgMappingElement();
+        $this->elements[] = $e;
+        return $e;
+    }
+        
+    public function    getElements() {
+        return $this->elements;
+    }
+    
+    /**
+     * Returns the PHP hash or array of hashes (etc.) that this mapping represents.
+     * @return array
+     */
+    public function getValue() {
+        $value = array();
+        foreach($this->getElements() as $el) {
+            if ($el->getKey() !== null) {
+                $value[ $el->getKey() ] = $el->getValue();
+            } else {
+                $value[] = $el->getValue();
+            }
+        }
+        return $value;
+    }
+}
+
+/**
+ * Sub-element of <mapping>.
+ */
+class PearPkgMappingElement {
+
+    private    $key;
+    private $value;
+    private $elements = array();
+    
+    public function setKey($v) {
+        $this->key = $v;
+    }
+    
+    public function getKey() {
+        return $this->key;
+    }
+    
+    public function setValue($v) {
+        $this->value = $v;
+    }
+    
+    /**
+     * Returns either the simple value or
+     * the calculated value (array) of nested elements.
+     * @return mixed
+     */
+    public function getValue() {    
+        if (!empty($this->elements)) {
+            $value = array();
+            foreach($this->elements as $el) {
+                if ($el->getKey() !== null) {
+                    $value[ $el->getKey() ] = $el->getValue();
+                } else {
+                    $value[] = $el->getValue();
+                }
+            }            
+            return $value;
+        } else  {
+            return $this->value;        
+        }
+    }
+    
+    /**
+     * Handles nested <element> tags.
+     */
+    public function createElement() {
+        $e = new PearPkgMappingElement();
+        $this->elements[] = $e;
+        return $e;
+    }
+    
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/PhpCodeSnifferTask.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/PhpCodeSnifferTask.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/PhpCodeSnifferTask.php	(revision 19)
@@ -0,0 +1,326 @@
+<?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 please see
+ * <http://phing.info>.
+ */
+
+require_once 'phing/Task.php';
+
+/**
+ * A PHP code sniffer task. Checking the style of one or more PHP source files.
+ *
+ * @author	Dirk Thomas <dirk.thomas@4wdmedia.de>
+ * @package	phing.tasks.ext
+ */
+class PhpCodeSnifferTask extends Task {
+
+	protected $file;	// the source file (from xml attribute)
+	protected $filesets = array(); // all fileset objects assigned to this task
+
+	// parameters for php code sniffer
+	protected $standard = 'Generic';
+	protected $sniffs = array();
+	protected $showWarnings = true;
+	protected $verbosity = 0;
+	protected $tabWidth = 0;
+	protected $allowedFileExtensions = array('php');
+	protected $ignorePatterns = false;
+	protected $noSubdirectories = false;
+	protected $configData = array();
+
+	// parameters to customize output
+	protected $showSniffs = false;
+	protected $outputFormat = 'default';
+
+	/**
+	 * File to be performed syntax check on
+	 * @param PhingFile $file
+	 */
+	public function setFile(PhingFile $file) {
+		$this->file = $file;
+	}
+
+	/**
+	 * Nested creator, creates a FileSet for this task
+	 *
+	 * @return FileSet The created fileset object
+	 */
+	function createFileSet() {
+		$num = array_push($this->filesets, new FileSet());
+		return $this->filesets[$num-1];
+	}
+
+	/**
+	 * Sets the standard to test for
+	 * @param string $standard
+	 */
+	public function setStandard($standard)
+	{
+		if (DIRECTORY_SEPARATOR != '/') $standard = str_replace('/', DIRECTORY_SEPARATOR, $standard);
+		$this->standard = $standard;
+	}
+
+	/**
+	 * Sets the sniffs which the standard should be restricted to
+	 * @param string $sniffs
+	 */
+	public function setSniffs($sniffs)
+	{
+		$token = ' ,;';
+		$sniff = strtok($sniffs, $token);
+		while ($sniff !== false) {
+			$this->sniffs[] = $sniff;
+			$sniff = strtok($token);
+		}
+	}
+
+	/**
+	 * Sets the flag if warnings should be shown
+	 * @param boolean $show
+	 */
+	public function setShowWarnings($show)
+	{
+		$this->showWarnings = StringHelper::booleanValue($show);
+	}
+
+	/**
+	 * Sets the verbosity level
+	 * @param int $level
+	 */
+	public function setVerbosity($level)
+	{
+		$this->verbosity = (int)$level;
+	}
+
+	/**
+	 * Sets the tab width to replace tabs with spaces
+	 * @param int $width
+	 */
+	public function setTabWidth($width)
+	{
+		$this->tabWidth = (int)$width;
+	}
+
+	/**
+	 * Sets the allowed file extensions when using directories instead of specific files
+	 * @param array $extensions
+	 */
+	public function setAllowedFileExtensions($extensions)
+	{
+		$this->allowedFileExtensions = array();
+		$token = ' ,;';
+		$ext = strtok($extensions, $token);
+		while ($ext !== false) {
+			$this->allowedFileExtensions[] = $ext;
+			$ext = strtok($token);
+		}
+	}
+
+	/**
+	 * Sets the ignore patterns to skip files when using directories instead of specific files
+	 * @param array $extensions
+	 */
+	public function setIgnorePatterns($patterns)
+	{
+		$this->ignorePatterns = array();
+		$token = ' ,;';
+		$pattern = strtok($patterns, $token);
+		while ($pattern !== false) {
+			$this->ignorePatterns[] = $pattern;
+			$pattern = strtok($token);
+		}
+	}
+
+	/**
+	 * Sets the flag if subdirectories should be skipped
+	 * @param boolean $subdirectories
+	 */
+	public function setNoSubdirectories($subdirectories)
+	{
+		$this->noSubdirectories = StringHelper::booleanValue($subdirectories);
+	}
+
+	/**
+	 * Creates a config parameter for this task
+	 *
+	 * @return Parameter The created parameter
+	 */
+	public function createConfig() {
+		$num = array_push($this->configData, new Parameter());
+		return $this->configData[$num-1];
+	}
+
+	/**
+	 * Sets the flag if the used sniffs should be listed
+	 * @param boolean $show
+	 */
+	public function setShowSniffs($show)
+	{
+		$this->showSniffs = StringHelper::booleanValue($show);
+	}
+
+	/**
+	 * Sets the output format
+	 * @param string $format
+	 */
+	public function setFormat($format)
+	{
+		$this->outputFormat = $format;
+	}
+
+	/**
+	 * Executes PHP code sniffer against PhingFile or a FileSet
+	 */
+	public function main() {
+		if(!isset($this->file) and count($this->filesets) == 0) {
+			throw new BuildException("Missing either a nested fileset or attribute 'file' set");
+		}
+
+		require_once 'PHP/CodeSniffer.php';
+		$codeSniffer = new PHP_CodeSniffer($this->verbosity, $this->tabWidth);
+		$codeSniffer->setAllowedFileExtensions($this->allowedFileExtensions);
+		if (is_array($this->ignorePatterns)) $codeSniffer->setIgnorePatterns($this->ignorePatterns);
+		foreach ($this->configData as $configData) {
+			$codeSniffer->setConfigData($configData->getName(), $configData->getValue(), true);
+		}
+
+		if ($this->file instanceof PhingFile) {
+			$codeSniffer->process($this->file->getPath(), $this->standard, $this->sniffs, $this->noSubdirectories);
+
+		} else {
+			$fileList = array();
+			$project = $this->getProject();
+			foreach ($this->filesets as $fs) {
+				$ds = $fs->getDirectoryScanner($project);
+				$files = $ds->getIncludedFiles();
+				$dir = $fs->getDir($this->project)->getPath();
+				foreach ($files as $file) {
+					$fileList[] = $dir.DIRECTORY_SEPARATOR.$file;
+				}
+			}
+			$codeSniffer->process($fileList, $this->standard, $this->sniffs, $this->noSubdirectories);
+		}
+		$this->output($codeSniffer);
+	}
+
+	/**
+	 * Outputs the results
+	 * @param PHP_CodeSniffer $codeSniffer
+	 */
+	protected function output($codeSniffer) {
+		if ($this->showSniffs) {
+			$sniffs = $codeSniffer->getSniffs();
+			$sniffStr = '';
+			foreach ($sniffs as $sniff) {
+				$sniffStr .= '- ' . $sniff.PHP_EOL;
+			}
+			$this->log('The list of used sniffs (#' . count($sniffs) . '): ' . PHP_EOL . $sniffStr, Project::MSG_INFO);
+		}
+
+		switch ($this->outputFormat) {
+			case 'default':
+				$this->outputCustomFormat($codeSniffer);
+				break;
+			case 'xml':
+				$codeSniffer->printXMLErrorReport($this->showWarnings);
+				break;
+			case 'checkstyle':
+				$codeSniffer->printCheckstyleErrorReport($this->showWarnings);
+				break;
+			case 'csv':
+				$codeSniffer->printCSVErrorReport($this->showWarnings);
+				break;
+			case 'report':
+				$codeSniffer->printErrorReport($this->showWarnings);
+				break;
+			case 'summary':
+				$codeSniffer->printErrorReportSummary($this->showWarnings);
+				break;
+			case 'doc':
+				$codeSniffer->generateDocs($this->standard, $this->sniffs);
+				break;
+			default:
+				$this->log('Unknown output format "' . $this->outputFormat . '"', Project::MSG_INFO);
+				break;
+		}
+	}
+
+	/**
+	 * Outputs the results with a custom format
+	 * @param PHP_CodeSniffer $codeSniffer
+	 */
+	protected function outputCustomFormat($codeSniffer) {
+		$report = $codeSniffer->prepareErrorReport($this->showWarnings);
+
+		$files = $report['files'];
+		foreach ($files as $file => $attributes) {
+			$errors = $attributes['errors'];
+			$warnings = $attributes['warnings'];
+			$messages = $attributes['messages'];
+			if ($errors > 0) {
+				$this->log($file . ': ' . $errors . ' error' . ($errors > 1 ? 's' : '') . ' detected', Project::MSG_ERR);
+				$this->outputCustomFormatMessages($messages, 'ERROR');
+			} else {
+				$this->log($file . ': No syntax errors detected', Project::MSG_VERBOSE);
+			}
+			if ($warnings > 0) {
+				$this->log($file . ': ' . $warnings . ' warning' . ($warnings > 1 ? 's' : '') . ' detected', Project::MSG_WARN);
+				$this->outputCustomFormatMessages($messages, 'WARNING');
+			}
+		}
+
+		$totalErrors = $report['totals']['errors'];
+		$totalWarnings = $report['totals']['warnings'];
+		$this->log(count($files) . ' files where checked', Project::MSG_INFO);
+		if ($totalErrors > 0) {
+			$this->log($totalErrors . ' error' . ($totalErrors > 1 ? 's' : '') . ' detected', Project::MSG_ERR);
+		} else {
+			$this->log('No syntax errors detected', Project::MSG_INFO);
+		}
+		if ($totalWarnings > 0) {
+			$this->log($totalWarnings . ' warning' . ($totalWarnings > 1 ? 's' : '') . ' detected', Project::MSG_INFO);
+		}
+	}
+
+	/**
+	 * Outputs the messages of a specific type for one file
+	 * @param array $messages
+	 * @param string $type
+	 */
+	protected function outputCustomFormatMessages($messages, $type) {
+		foreach ($messages as $line => $messagesPerLine) {
+			foreach ($messagesPerLine as $column => $messagesPerColumn) {
+				foreach ($messagesPerColumn as $message) {
+					$msgType = $message['type'];
+					if ($type == $msgType) {
+						$logLevel = Project::MSG_INFO;
+						if ($msgType == 'ERROR') {
+							$logLevel = Project::MSG_ERR;
+						} else if ($msgType == 'WARNING') {
+							$logLevel = Project::MSG_WARN;
+						}
+						$text = $message['message'];
+						$string = $msgType . ' in line ' . $line . ' column ' . $column . ': ' . $text;
+						$this->log($string, $logLevel);
+					}
+				}
+			}
+		}
+	}
+
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/PhpLintTask.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/PhpLintTask.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/PhpLintTask.php	(revision 19)
@@ -0,0 +1,159 @@
+<?php
+/*
+ *	$Id: PhpLintTask.php 342 2008-01-21 14:49:48Z mrook $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+require_once 'phing/Task.php';
+
+/**
+ * A PHP lint task. Checking syntax of one or more PHP source file.
+ *
+ * @author	 Knut Urdalen <knut.urdalen@telio.no>
+ * @author	 Stefan Priebsch <stefan.priebsch@e-novative.de>
+ * @package	phing.tasks.ext
+ */
+class PhpLintTask extends Task {
+
+	protected $file;	// the source file (from xml attribute)
+	protected $filesets = array(); // all fileset objects assigned to this task
+
+	protected $errorProperty;
+	protected $haltOnFailure = false;
+	protected $hasErrors = false;
+	private $badFiles = array();
+	protected $interpreter = ''; // php interpreter to use for linting
+
+    /**
+     * Initialize the interpreter with the Phing property
+     */
+    public function __construct() {
+        $this->setInterpreter(Phing::getProperty('php.interpreter'));
+    }
+
+	/**
+	 * Override default php interpreter
+	 * @todo	Do some sort of checking if the path is correct but would 
+	 *			require traversing the systems executeable path too
+	 * @param	string	$sPhp
+	 */
+	public function setInterpreter($sPhp) {
+		$this->Interpreter = $sPhp;
+	}
+
+	/**
+	 * The haltonfailure property
+	 * @param boolean $aValue
+	 */
+	public function setHaltOnFailure($aValue) {
+		$this->haltOnFailure = $aValue;
+	}
+
+	/**
+	 * File to be performed syntax check on
+	 * @param PhingFile $file
+	 */
+	public function setFile(PhingFile $file) {
+		$this->file = $file;
+	}
+
+	/**
+	 * Set an property name in which to put any errors.
+	 * @param string $propname 
+	 */
+	public function setErrorproperty($propname)
+	{
+		$this->errorProperty = $propname;
+	}
+
+	/**
+	 * Nested creator, creates a FileSet for this task
+	 *
+	 * @return FileSet The created fileset object
+	 */
+	function createFileSet() {
+		$num = array_push($this->filesets, new FileSet());
+		return $this->filesets[$num-1];
+	}
+
+	/**
+	 * Execute lint check against PhingFile or a FileSet
+	 */
+	public function main() {
+		if(!isset($this->file) and count($this->filesets) == 0) {
+			throw new BuildException("Missing either a nested fileset or attribute 'file' set");
+		}
+
+		if($this->file instanceof PhingFile) {
+			$this->lint($this->file->getPath());
+		} else { // process filesets
+			$project = $this->getProject();
+			foreach($this->filesets as $fs) {
+				$ds = $fs->getDirectoryScanner($project);
+				$files = $ds->getIncludedFiles();
+				$dir = $fs->getDir($this->project)->getPath();
+				foreach($files as $file) {
+					$this->lint($dir.DIRECTORY_SEPARATOR.$file);
+				}
+			}
+		}
+
+		if ($this->haltOnFailure && $this->hasErrors) throw new BuildException('Syntax error(s) in PHP files: '.implode(', ',$this->badFiles));
+	}
+
+	/**
+	 * Performs the actual syntax check
+	 *
+	 * @param string $file
+	 * @return void
+	 */
+	protected function lint($file) {
+        $command = $this->Interpreter == ''
+            ? 'php'
+            : $this->Interpreter;
+        $command .= ' -l ';
+		if(file_exists($file)) {
+			if(is_readable($file)) {
+				$messages = array();
+				exec($command.'"'.$file.'"', $messages);
+				if(!preg_match('/^No syntax errors detected/', $messages[0])) {
+					if (count($messages) > 1) {
+						if ($this->errorProperty) {
+							$this->project->setProperty($this->errorProperty, $messages[1]);
+						}
+						$this->log($messages[1], Project::MSG_ERR);
+					} else {
+						$this->log("Could not parse file", Project::MSG_ERR);
+					}
+					$this->badFiles[] = $file;	
+					$this->hasErrors = true;
+					
+				} else {
+					$this->log($file.': No syntax errors detected', Project::MSG_INFO);
+				}
+			} else {
+				throw new BuildException('Permission denied: '.$file);
+			}
+		} else {
+			throw new BuildException('File not found: '.$file);
+		}
+	}
+}
+
+
+
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/ScpSendTask.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/ScpSendTask.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/ScpSendTask.php	(revision 19)
@@ -0,0 +1,192 @@
+<?php
+/**
+ * $Id: ScpSendTask.php 325 2007-12-20 15:44:58Z hans $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+require_once 'phing/Task.php';
+
+/**
+ * SCPs a File to a remote server 
+ *
+ * @author Andrew Eddie <andrew.eddie@jamboworks.com> 
+ * @version $Id: ScpSendTask.php 325 2007-12-20 15:44:58Z hans $
+ * @package phing.tasks.ext
+ * @since 2.3.0
+ */
+class ScpSendTask extends Task
+{
+	private $localFile = "";
+
+	private $remoteFile = "";
+
+	private $username = "";
+
+	private $password = "";
+
+	private $host = "";
+
+	private $port = 22;
+
+	private $mode = null;
+
+	private $_connection = null;
+
+	/**
+	 * Sets the remote host
+	 */
+	function setHost($h)
+	{
+		$this->host = $h;
+	}
+
+	/**
+	 * Returns the remote host
+	 */
+	function getHost()
+	{
+		return $this->host;
+	}
+
+	/**
+	 * Sets the remote host port
+	 */
+	function setPort($p)
+	{
+		$this->port = $p;
+	}
+
+	/**
+	 * Returns the remote host port
+	 */
+	function getPort()
+	{
+		return $this->port;
+	}
+
+	/**
+	 * Sets the mode value
+	 */
+	function setMode($value)
+	{
+		$this->mode = $value;
+	}
+
+	/**
+	 * Returns the mode value
+	 */
+	function getMode()
+	{
+		return $this->mode;
+	}
+
+	/**
+	 * Sets the username of the user to scp
+	 */
+	function setUsername($username)
+	{
+		$this->username = $username;
+	}
+
+	/**
+	 * Returns the username
+	 */
+	function getUsername()
+	{
+		return $this->username;
+	}
+
+	/**
+	 * Sets the password of the user to scp
+	 */
+	function setPassword($password)
+	{
+		$this->password = $password;
+	}
+
+	/**
+	 * Returns the password
+	 */
+	function getPassword()
+	{
+		return $this->password;
+	}
+
+	/**
+	 * Sets the local path to scp from
+	 */
+	function setLocalFile($lFile)
+	{
+		$this->localFile = $lFile;
+	}
+
+	/**
+	 * Returns the local path to scp from
+	 */
+	function getLocalFile($lFile)
+	{
+		return $this->localFile;
+	}
+
+	/**
+	 * Sets the remote path to scp to
+	 */
+	function setRemoteFile($rFile)
+	{
+		$this->remoteFile = $rFile;
+	}
+
+	/**
+	 * Returns the remote path to scp to
+	 */
+	function getRemoteFile($rFile)
+	{
+		return $this->remoteFile;
+	}
+
+	/**
+	* The init method: Do init steps.
+	*/
+	public function init()
+	{
+		if (function_exists('ssh2_connect')) {
+			$this->_connection = ssh2_connect($this->host, $this->port);
+			ssh2_auth_password($this->_connection, $this->username, $this->password);
+		} else {
+			print ("ERROR: SSH Extension is not installed");
+		}
+	}
+
+	/**
+	 * The main entry point method.
+	 */
+	public function main()
+	{
+		if (function_exists('ssh2_scp_send') && !is_null($this->_connection))
+		{
+			if (!is_null($this->mode)) {
+				ssh2_scp_send($this->_connection, $this->localFile, $this->remoteFile, $this->mode);
+			} else {
+				ssh2_scp_send($this->_connection, $this->localFile, $this->remoteFile);
+			}
+		} else {
+			print ("ERROR: No SSH Connection Available");
+		}
+	}
+}
+
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/SmartyTask.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/SmartyTask.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/SmartyTask.php	(revision 19)
@@ -0,0 +1,610 @@
+<?php
+
+/*
+ *  $Id: SmartyTask.php 144 2007-02-05 15:19:00Z hans $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>. 
+ */
+ 
+require_once 'phing/Task.php';
+include_once 'phing/BuildException.php';
+include_once 'phing/util/StringHelper.php';
+
+/**
+ * A phing task for generating output by using Smarty.
+ *
+ * This is based on the TexenTask from Apache's Velocity engine.  This class
+ * was originally proted in order to provide a template compiling system for
+ * Torque.
+ *
+ * TODO:
+ *        - Add Path / useClasspath support?
+ *
+ * @author    Hans Lellelid <hans@xmpl.org> (SmartyTask)
+ * @author    Jason van Zyl <jvanzyl@apache.org> (TexenTask)
+ * @author    Robert Burrell Donkin <robertdonkin@mac.com>
+ * @version   $Id: SmartyTask.php 144 2007-02-05 15:19:00Z hans $
+ * @package   phing.tasks.ext
+ */
+class SmartyTask extends Task {
+
+    /**
+     * Smarty template engine.
+     * @var Smarty
+     */
+    protected $context;
+    
+    /**
+     * Variables that are assigned to the context on parse/compile.
+     * @var array
+     */
+    protected $properties = array();
+    
+    /**
+     * This is the control template that governs the output.
+     * It may or may not invoke the services of worker
+     * templates.
+     * @var string
+     */
+    protected $controlTemplate;
+    
+    /**
+     * This is where Velocity will look for templates
+     * using the file template loader.
+     * @var string
+     */
+    protected $templatePath;
+    
+    /**
+     * This is where texen will place all the output
+     * that is a product of the generation process.
+     * @var string
+     */
+    protected $outputDirectory;
+    
+    /**
+     * This is the file where the generated text
+     * will be placed.
+     * @var string
+     */
+    protected $outputFile;
+
+    /**
+     * <p>
+     * These are properties that are fed into the
+     * initial context from a properties file. This
+     * is simply a convenient way to set some values
+     * that you wish to make available in the context.
+     * </p>
+     * <p>
+     * These values are not critical, like the template path
+     * or output path, but allow a convenient way to
+     * set a value that may be specific to a particular
+     * generation task.
+     * </p>
+     * <p>
+     * For example, if you are generating scripts to allow
+     * user to automatically create a database, then
+     * you might want the <code>$databaseName</code> 
+     * to be placed
+     * in the initial context so that it is available
+     * in a script that might look something like the
+     * following:
+     * <code><pre>
+     * #!bin/sh
+     * 
+     * echo y | mysqladmin create $databaseName
+     * </pre></code>
+     * The value of <code>$databaseName</code> isn't critical to
+     * output, and you obviously don't want to change
+     * the ant task to simply take a database name.
+     * So initial context values can be set with
+     * properties file.
+     *
+     * @var array
+     */
+    protected $contextProperties;
+        
+    /**
+     * Smarty compiles templates before parsing / replacing tokens in them.
+     * By default it will try ./templates_c, but you may wish to override this.
+     * @var string
+     */
+    protected $compilePath;
+    
+    /**
+     * Whether to force Smarty to recompile templates.
+     * Smarty does check file modification time, but you can set this
+     * to be *sure* that the template will be compiled (of course it will
+     * be slower if you do).
+     * @var boolean
+     */
+    protected $forceCompile = false;
+    
+    /**
+     * Smarty can use config files.
+     * This tells Smarty where to look for the config files.
+     * @var string
+     */
+    protected $configPath;
+    
+    /**
+     * Customize the left delimiter for Smarty tags.
+     * @var string
+     */
+    protected $leftDelimiter;
+
+    /**
+     * Customize the right delimiter for Smarty tags.
+     * @var string
+     */
+    protected $rightDelimiter;
+
+    // -----------------------------------------------------------------------
+    // The following getters & setters are used by phing to set properties
+    // specified in the XML for the smarty task.
+    // -----------------------------------------------------------------------
+    
+    public function init() {
+        include_once 'Smarty.class.php';
+        if (!class_exists('Smarty')) {
+            throw new BuildException("To use SmartyTask, you must have the path to Smarty.class.php on your include_path or your \$PHP_CLASSPATH environment variable.");
+        }
+    }
+    
+    /**
+     * [REQUIRED] Set the control template for the
+     * generating process.
+     * @param string $controlTemplate
+     * @return void
+     */
+    public function setControlTemplate ($controlTemplate) {
+        $this->controlTemplate = $controlTemplate;
+    }
+
+    /**
+     * Get the control template for the
+     * generating process.
+     * @return string
+     */
+    public function getControlTemplate() {
+        return $this->controlTemplate;
+    }
+
+    /**
+     * [REQUIRED] Set the path where Velocity will look
+     * for templates using the file template
+     * loader.
+     * @return void
+     * @throws Exception 
+     */
+    public function setTemplatePath($templatePath) {
+        $resolvedPath = "";        
+        $tok = strtok($templatePath, ",");
+        while ( $tok ) {            
+            // resolve relative path from basedir and leave
+            // absolute path untouched.
+            $fullPath = $this->project->resolveFile($tok);
+            $cpath = $fullPath->getCanonicalPath();
+            if ($cpath === false) {
+                $this->log("Template directory does not exist: " . $fullPath->getAbsolutePath());
+            } else {
+                $resolvedPath .= $cpath;
+            }
+            $tok = strtok(",");
+            if ( $tok ) {
+                $resolvedPath .= ",";
+            }
+        }
+        $this->templatePath = $resolvedPath;
+     }
+
+    /**
+     * Get the path where Velocity will look
+     * for templates using the file template
+     * loader.
+     * @return string
+     */
+    public function getTemplatePath() {
+        return $this->templatePath;
+    }        
+
+    /**
+     * [REQUIRED] Set the output directory. It will be
+     * created if it doesn't exist.
+     * @param PhingFile $outputDirectory
+     * @return void
+     * @throws Exception
+     */
+    public function setOutputDirectory(PhingFile $outputDirectory) {
+        try {            
+            if (!$outputDirectory->exists()) {
+                $this->log("Output directory does not exist, creating: " . $outputDirectory->getPath(),Project::MSG_VERBOSE);
+                if (!$outputDirectory->mkdirs()) {
+                    throw new IOException("Unable to create Ouptut directory: " . $outputDirectory->getAbsolutePath());
+                }
+            }
+            $this->outputDirectory = $outputDirectory->getCanonicalPath();
+        } catch (IOException $ioe) {
+            throw new BuildException($ioe->getMessage());
+        }
+    }
+      
+    /**
+     * Get the output directory.
+     * @return string
+     */
+    public function getOutputDirectory() {
+        return $this->outputDirectory;
+    }        
+
+    /**
+     * [REQUIRED] Set the output file for the
+     * generation process.
+     * @return void
+     */
+    public function setOutputFile($outputFile) {
+        $this->outputFile = $outputFile;
+    }
+
+    /**
+     * Get the output file for the
+     * generation process.
+     * @return string
+     */
+    public function getOutputFile() {
+        return $this->outputFile;
+    }        
+
+    /**
+     * Set the path Smarty uses as a "cache" for compiled templates.
+     * @param string $compilePath
+     */
+    public function setCompilePath($compilePath) {
+        $this->compilePath = $compilePath;
+    }
+    
+    /**
+     * Get the path Smarty uses for compiling templates.
+     * @return string
+     */
+    public function getCompilePath() {
+        return $this->compilePath;
+    }
+    
+    /**
+     * Set whether Smarty should always recompile tempaltes.
+     * @param boolean $force
+     * @return void
+     */
+    public function setForceCompile($force) {
+        $this->forceCompile = (boolean) $force;
+    }
+    
+    /**
+     * Get whether Smarty should always recompile template.
+     * @return boolean
+     */
+    public function getForceCompile() {
+        return $this->forceCompile;
+    }
+    
+    /**
+     * Set where Smarty looks for config files.
+     * @param string $configPath
+     * @return void
+     */
+    public function setConfigPath($configPath) {
+        $this->configPath = $configPath;
+    }
+    
+    /**
+     * Get the path that Smarty uses for looking for config files.
+     * @return string
+     */
+    public function getConfigPath() {
+        return $this->configPath;
+    }
+    
+    /**
+     * Set Smarty template left delimiter.
+     * @param string $delim
+     * @return void
+     */
+    public function setLeftDelimiter($delim) {
+        $this->leftDelimiter = $delim;
+    }
+    
+    /**
+     * Get Smarty template right delimiter
+     * @return string
+     */
+    public function getLeftDelimiter() {
+        return $this->leftDelimiter;
+    }
+    
+    /**
+     * Set Smarty template right delimiter.
+     * @param string $delim
+     * @return void
+     */
+    public function setRightDelimiter($delim) {
+        $this->rightDelimiter = $delim;
+    }
+    
+    /**
+     * Get Smarty template right delimiter
+     * @return string
+     */
+    public function getRightDelimiter() {
+        return $this->rightDelimiter;
+    }
+    
+    
+    /**
+     * Set the context properties that will be
+     * fed into the initial context be the
+     * generating process starts.
+     * @param string $file
+     * @return void
+     */
+    public function setContextProperties($file) {
+    
+        $sources = explode(",", $file);
+        $this->contextProperties = new Properties();
+        
+        // Always try to get the context properties resource
+        // from a file first. Templates may be taken from a JAR
+        // file but the context properties resource may be a 
+        // resource in the filesystem. If this fails than attempt
+        // to get the context properties resource from the
+        // classpath.
+        for ($i=0, $sourcesLength=count($sources); $i < $sourcesLength; $i++) {
+            $source = new Properties();
+            
+            try {
+            
+                // resolve relative path from basedir and leave
+                // absolute path untouched.
+                $fullPath = $this->project->resolveFile($sources[$i]);
+                $this->log("Using contextProperties file: " . $fullPath->__toString());
+                $source->load($fullPath);
+                
+            } catch (Exception $e) {
+              
+              throw new BuildException("Context properties file " . $sources[$i] .
+                            " could not be found in the file system!");
+                     
+            }
+        
+            $keys = $source->keys();
+            
+            foreach ($keys as $key) {
+                $name = $key;
+                $value = $this->project->replaceProperties($source->getProperty($name));
+                $this->contextProperties->setProperty($name, $value);
+            }
+        }
+    }
+
+    /**
+     * Get the context properties that will be
+     * fed into the initial context be the
+     * generating process starts.
+     * @return Properties
+     */
+    public function getContextProperties() {
+        return $this->contextProperties;
+    }     
+
+    // ---------------------------------------------------------------
+    // End of XML setters & getters
+    // ---------------------------------------------------------------
+
+   
+    /**
+     * Creates a Smarty object.
+     *
+     * @return Smarty initialized (cleared) Smarty context.
+     * @throws Exception the execute method will catch 
+     *         and rethrow as a <code>BuildException</code>
+     */
+    public function initControlContext() {        
+        $this->context->clear_all_assign();        
+        return $this->context;
+    }
+    
+    /**
+     * Execute the input script with Velocity
+     *
+     * @throws BuildException  
+     * BuildExceptions are thrown when required attributes are missing.
+     * Exceptions thrown by Velocity are rethrown as BuildExceptions.
+     */
+    public function main() {
+    
+        // Make sure the template path is set.
+        if (empty($this->templatePath)) {
+            throw new BuildException("The template path needs to be defined!");
+        }            
+    
+        // Make sure the control template is set.
+        if ($this->controlTemplate === null) {
+            throw new BuildException("The control template needs to be defined!");
+        }            
+
+        // Make sure the output directory is set.
+        if ($this->outputDirectory === null) {
+            throw new BuildException("The output directory needs to be defined!");
+        }            
+        
+        // Make sure there is an output file.
+        if ($this->outputFile === null) {
+            throw new BuildException("The output file needs to be defined!");
+        }            
+        
+        // Setup Smarty runtime.
+        
+        // Smarty uses one object to store properties and to store
+        // the context for the template (unlike Velocity).  We setup this object, calling it
+        // $this->context, and then initControlContext simply zeros out
+        // any assigned variables.
+        $this->context = new Smarty();
+        
+        if ($this->compilePath !== null) {
+            $this->log("Using compilePath: " . $this->compilePath);
+            $this->context->compile_dir = $this->compilePath;
+        }
+        
+        if ($this->configPath !== null) {
+            $this->log("Using configPath: " . $this->configPath);
+            $this->context->config_dir = $this->configPath;
+        }        
+        
+        if ($this->forceCompile !== null) {
+            $this->context->force_compile = $this->forceCompile;
+        }
+        
+        if ($this->leftDelimiter !== null) {
+            $this->context->left_delimiter = $this->leftDelimiter;
+        }
+        
+        if ($this->rightDelimiter !== null) {
+            $this->context->right_delimiter = $this->rightDelimiter;
+        }
+        
+        if ($this->templatePath !== null) {
+            $this->log("Using templatePath: " . $this->templatePath);
+            $this->context->template_dir = $this->templatePath;
+        }                                                        
+        
+        $smartyCompilePath = new PhingFile($this->context->compile_dir);
+        if (!$smartyCompilePath->exists()) {
+            $this->log("Compile directory does not exist, creating: " . $smartyCompilePath->getPath(), Project::MSG_VERBOSE);
+            if (!$smartyCompilePath->mkdirs()) {
+                throw new BuildException("Smarty needs a place to compile templates; specify a 'compilePath' or create ".$this->context->compile_dir);
+            }
+        }
+        
+        // Make sure the output directory exists, if it doesn't
+        // then create it.
+        $file = new PhingFile($this->outputDirectory);
+        if (!$file->exists()) {
+            $this->log("Output directory does not exist, creating: " . $file->getAbsolutePath());
+            $file->mkdirs();
+        }
+        
+        $path = $this->outputDirectory . DIRECTORY_SEPARATOR . $this->outputFile;
+        $this->log("Generating to file " . $path);
+        
+        $writer = new FileWriter($path);
+                
+        // The generator and the output path should
+        // be placed in the init context here and
+        // not in the generator class itself.
+        $c = $this->initControlContext();
+        
+        // Set any variables that need to always
+        // be loaded
+        $this->populateInitialContext($c);
+        
+        // Feed all the options into the initial
+        // control context so they are available
+        // in the control/worker templates.
+        if ($this->contextProperties !== null) {
+            
+            foreach($this->contextProperties->keys() as $property) {
+                    
+                $value = $this->contextProperties->getProperty($property);
+                
+                // Special exception (from Texen)
+                // for properties ending in file.contents:
+                // in that case we dump the contents of the file
+                // as the "value" for the Property.
+                if (StringHelper::endsWith("file.contents", $property)) {
+                    // pull in contents of file specified 
+                                            
+                    $property = substr($property, 0, strpos($property, "file.contents") - 1);
+                    
+                    // reset value, and then 
+                    // read in teh contents of the file into that var
+                    $value = "";
+                    $f = new PhingFile($project->resolveFile($value)->getCanonicalPath());                        
+                    if ($f->exists()) {
+                        try {
+                            $fr = new FileReader($f);
+                            $fr->readInto($value);
+                        } catch (Exception $e) {
+                            throw $e;
+                        }
+                    }    
+                                                                    
+                 } // if ends with file.contents
+                
+                    if (StringHelper::isBoolean($value)) {
+                        $value = StringHelper::booleanValue($value);
+                    }
+                                                        
+                 $c->assign($property, $value); 
+                 
+            } // foreach property
+                
+        } // if contextProperties !== null
+        
+        try {
+            //$c->display($this->controlTemplate);            
+            $writer->write($c->fetch($this->controlTemplate));
+            $writer->close();
+        } catch (IOException $ioe) {
+            $writer->close();
+            throw new BuildException("Cannot write parsed template.");
+        }        
+        
+        $this->cleanup();    
+    }
+
+    /**
+     * <p>Place useful objects into the initial context.</p>
+     *
+     * <p>TexenTask places <code>Date().toString()</code> into the
+     * context as <code>$now</code>.  Subclasses who want to vary the
+     * objects in the context should override this method.</p>
+     *
+     * <p><code>$generator</code> is not put into the context in this
+     * method.</p>
+     *
+     * @param context The context to populate, as retrieved from
+     * {@link #initControlContext()}.
+     * @return void
+     * @throws Exception Error while populating context.  The {@link
+     * #execute()} method will catch and rethrow as a
+     * <code>BuildException</code>.
+     */
+    protected function populateInitialContext(Smarty $context)  {       
+    }
+    
+    /**
+     * A hook method called at the end of {@link #execute()} which can
+     * be overridden to perform any necessary cleanup activities (such
+     * as the release of database connections, etc.).  By default,
+     * does nothing.
+     * @return void
+     * @throws Exception Problem cleaning up.
+     */
+    protected function cleanup() {
+    }
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/TarTask.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/TarTask.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/TarTask.php	(revision 19)
@@ -0,0 +1,426 @@
+<?php
+/*
+ *  $Id: TarTask.php 220 2007-08-21 00:03:13Z hans $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+require_once 'phing/tasks/system/MatchingTask.php';
+include_once 'phing/util/SourceFileScanner.php';
+include_once 'phing/mappers/MergeMapper.php';
+include_once 'phing/util/StringHelper.php';
+
+/**
+ * Creates a tar archive using PEAR Archive_Tar.
+ *
+ * @author    Hans Lellelid <hans@xmpl.org> (Phing)
+ * @author    Stefano Mazzocchi <stefano@apache.org> (Ant)
+ * @author    Stefan Bodewig <stefan.bodewig@epost.de> (Ant)
+ * @author    Magesh Umasankar
+ * @version   $Revision: 1.10 $
+ * @package   phing.tasks.ext
+ */
+class TarTask extends MatchingTask {
+    
+    const TAR_NAMELEN = 100;
+    
+    const WARN = "warn";
+    const FAIL = "fail";   
+    const OMIT = "omit";    
+    
+    private $tarFile;
+    private $baseDir;
+	private $includeEmpty = true; // Whether to include empty dirs in the TAR
+	
+    private $longFileMode = "warn";
+
+    private $filesets = array();
+    private $fileSetFiles = array();
+
+    /**
+     * Indicates whether the user has been warned about long files already.
+     */
+    private $longWarningGiven = false;
+    
+    /**
+     * Compression mode.  Available options "gzip", "bzip2", "none" (null).
+     */
+    private $compression = null;
+    
+    /**
+     * Ensures that PEAR lib exists.
+     */
+    public function init() {
+        include_once 'Archive/Tar.php';
+        if (!class_exists('Archive_Tar')) {
+            throw new BuildException("You must have installed the PEAR Archive_Tar class in order to use TarTask.");
+        }
+    }
+    
+    /**
+     * Add a new fileset
+     * @return FileSet
+     */
+    public function createTarFileSet() {
+        $this->fileset = new TarFileSet();
+        $this->filesets[] = $this->fileset;
+        return $this->fileset;
+    }
+    
+    /**
+     * Add a new fileset.  Alias to createTarFileSet() for backwards compatibility.
+     * @return FileSet
+     * @see createTarFileSet()
+     */
+    public function createFileSet() {
+        $this->fileset = new TarFileSet();
+        $this->filesets[] = $this->fileset;
+        return $this->fileset;
+    }
+
+    /**
+     * Set is the name/location of where to create the tar file.
+     * @param PhingFile $destFile The output of the tar
+     */
+    public function setDestFile(PhingFile $destFile) {
+        $this->tarFile = $destFile;
+    }
+
+    /**
+     * This is the base directory to look in for things to tar.
+     * @param PhingFile $baseDir
+     */
+    public function setBasedir(PhingFile $baseDir) {
+        $this->baseDir = $baseDir;
+    }
+
+    /**
+     * Set the include empty dirs flag.
+     * @param  boolean  Flag if empty dirs should be tarred too
+     * @return void
+     * @access public
+     */
+    function setIncludeEmptyDirs($bool) {
+        $this->includeEmpty = (boolean) $bool;
+    }
+
+    /**
+     * Set how to handle long files, those with a path&gt;100 chars.
+     * Optional, default=warn.
+     * <p>
+     * Allowable values are
+     * <ul>
+     * <li>  truncate - paths are truncated to the maximum length
+     * <li>  fail - paths greater than the maximim cause a build exception
+     * <li>  warn - paths greater than the maximum cause a warning and GNU is used
+     * <li>  gnu - GNU extensions are used for any paths greater than the maximum.
+     * <li>  omit - paths greater than the maximum are omitted from the archive
+     * </ul>
+     */
+    public function setLongfile($mode) {
+        $this->longFileMode = $mode;
+    }
+
+    /**
+     * Set compression method.
+     * Allowable values are
+     * <ul>
+     * <li>  none - no compression
+     * <li>  gzip - Gzip compression
+     * <li>  bzip2 - Bzip2 compression
+     * </ul>
+     */
+    public function setCompression($mode) {        
+        switch($mode) {
+            case "gzip":
+                $this->compression = "gz";
+                break;
+            case "bzip2":
+                $this->compression = "bz2";
+                break;
+            case "none":
+                $this->compression = null;
+                break;
+            default:
+                $this->log("Ignoring unknown compression mode: ".$mode, Project::MSG_WARN);
+                $this->compression = null;
+        }
+    }
+    
+    /**
+     * do the work
+     * @throws BuildException
+     */
+    public function main() {
+    
+        if ($this->tarFile === null) {
+            throw new BuildException("tarfile attribute must be set!", $this->getLocation());
+        }
+
+        if ($this->tarFile->exists() && $this->tarFile->isDirectory()) {
+            throw new BuildException("tarfile is a directory!", $this->getLocation());
+        }
+
+        if ($this->tarFile->exists() && !$this->tarFile->canWrite()) {
+            throw new BuildException("Can not write to the specified tarfile!", $this->getLocation());
+        }
+
+        // shouldn't need to clone, since the entries in filesets
+        // themselves won't be modified -- only elements will be added
+        $savedFileSets = $this->filesets;
+        
+        try {
+            if ($this->baseDir !== null) {
+                if (!$this->baseDir->exists()) {
+                    throw new BuildException("basedir does not exist!", $this->getLocation());
+                }
+				if (empty($this->filesets)) { // if there weren't any explicit filesets specivied, then
+	                						  // create a default, all-inclusive fileset using the specified basedir.
+	                $mainFileSet = new TarFileSet($this->fileset);
+	                $mainFileSet->setDir($this->baseDir);
+	                $this->filesets[] = $mainFileSet;
+	            }
+            }
+
+            if (empty($this->filesets)) {
+                throw new BuildException("You must supply either a basedir "
+                                         . "attribute or some nested filesets.",
+                                         $this->getLocation());
+            }                        
+            
+            // check if tar is out of date with respect to each fileset
+            if($this->tarFile->exists()) {
+	            $upToDate = true;
+	            foreach($this->filesets as $fs) {
+	                $files = $fs->getFiles($this->project, $this->includeEmpty);
+	                if (!$this->archiveIsUpToDate($files, $fs->getDir($this->project))) {
+	                    $upToDate = false;
+	                }
+	                for ($i=0, $fcount=count($files); $i < $fcount; $i++) {
+	                    if ($this->tarFile->equals(new PhingFile($fs->getDir($this->project), $files[$i]))) {
+	                        throw new BuildException("A tar file cannot include itself", $this->getLocation());
+	                    }
+	                }
+	            }
+	            if ($upToDate) {
+	                $this->log("Nothing to do: " . $this->tarFile->__toString() . " is up to date.", Project::MSG_INFO);
+	                return;
+	            }
+			}
+			
+            $this->log("Building tar: " . $this->tarFile->__toString(), Project::MSG_INFO);
+            
+            $tar = new Archive_Tar($this->tarFile->getAbsolutePath(), $this->compression);
+            
+            // print errors
+            $tar->setErrorHandling(PEAR_ERROR_PRINT);
+            
+            foreach($this->filesets as $fs) {                                
+                    $files = $fs->getFiles($this->project, $this->includeEmpty);
+                    if (count($files) > 1 && strlen($fs->getFullpath()) > 0) {
+                        throw new BuildException("fullpath attribute may only "
+                                                 . "be specified for "
+                                                 . "filesets that specify a "
+                                                 . "single file.");
+                    }
+                    $fsBasedir = $fs->getDir($this->project);
+                    $filesToTar = array();
+                    for ($i=0, $fcount=count($files); $i < $fcount; $i++) {
+                        $f = new PhingFile($fsBasedir, $files[$i]);
+                        $filesToTar[] = $f->getAbsolutePath();
+                        $this->log("Adding file " . $f->getPath() . " to archive.", Project::MSG_VERBOSE);                
+                    }                    
+                    $tar->addModify($filesToTar, '', $fsBasedir->getAbsolutePath());            
+            }
+                         
+                
+        } catch (IOException $ioe) {
+                $msg = "Problem creating TAR: " . $ioe->getMessage();
+                $this->filesets = $savedFileSets;
+                throw new BuildException($msg, $ioe, $this->getLocation());
+        }
+        
+        $this->filesets = $savedFileSets;
+    }
+           
+    /**
+     * @param array $files array of filenames
+     * @param PhingFile $dir
+     * @return boolean
+     */
+    protected function archiveIsUpToDate($files, $dir) {
+        $sfs = new SourceFileScanner($this);
+        $mm = new MergeMapper();
+        $mm->setTo($this->tarFile->getAbsolutePath());
+        return count($sfs->restrict($files, $dir, null, $mm)) == 0;
+    }
+   
+}
+
+
+/**
+ * This is a FileSet with the option to specify permissions.
+ * 
+ * Permissions are currently not implemented by PEAR Archive_Tar,
+ * but hopefully they will be in the future.
+ * 
+ */
+class TarFileSet extends FileSet {
+
+    private $files = null;
+
+    private $mode = 0100644;
+
+    private $userName = "";
+    private $groupName = "";
+    private $prefix = "";
+    private $fullpath = "";
+    private $preserveLeadingSlashes = false;
+
+    /**
+     *  Get a list of files and directories specified in the fileset.
+     *  @return array a list of file and directory names, relative to
+     *    the baseDir for the project.
+     */
+    public function getFiles(Project $p, $includeEmpty = true) {
+    
+        if ($this->files === null) {
+        
+            $ds = $this->getDirectoryScanner($p);
+            $this->files = $ds->getIncludedFiles();
+            
+            if ($includeEmpty) {
+            
+	            // first any empty directories that will not be implicitly added by any of the files
+				$implicitDirs = array();
+				foreach($this->files as $file) {
+					$implicitDirs[] = dirname($file);
+				} 
+				
+				$incDirs = $ds->getIncludedDirectories();
+				
+				// we'll need to add to that list of implicit dirs any directories
+				// that contain other *directories* (and not files), since otherwise
+				// we get duplicate directories in the resulting tar
+				foreach($incDirs as $dir) {
+					foreach($incDirs as $dircheck) {
+						if (!empty($dir) && $dir == dirname($dircheck)) {
+							$implicitDirs[] = $dir;
+						}
+					}
+				}
+				
+				$implicitDirs = array_unique($implicitDirs);
+				
+				// Now add any empty dirs (dirs not covered by the implicit dirs)
+				// to the files array. 
+				
+				foreach($incDirs as $dir) { // we cannot simply use array_diff() since we want to disregard empty/. dirs
+					if ($dir != "" && $dir != "." && !in_array($dir, $implicitDirs)) {
+						// it's an empty dir, so we'll add it.
+						$this->files[] = $dir;
+					}
+				}
+			} // if $includeEmpty
+			
+        } // if ($this->files===null)
+        
+        return $this->files;
+    }
+
+    /**
+     * A 3 digit octal string, specify the user, group and 
+     * other modes in the standard Unix fashion; 
+     * optional, default=0644
+     * @param string $octalString
+     */
+    public function setMode($octalString) {
+        $octal = (int) $octalString;
+        $this->mode = 0100000 | $octal;
+    }
+
+    public function getMode() {
+        return $this->mode;
+    }
+
+    /**
+     * The username for the tar entry 
+     * This is not the same as the UID, which is
+     * not currently set by the task.
+     */
+    public function setUserName($userName) {
+        $this->userName = $userName;
+    }
+
+    public function getUserName() {
+        return $this->userName;
+    }
+
+    /**
+     * The groupname for the tar entry; optional, default=""
+     * This is not the same as the GID, which is
+     * not currently set by the task.
+     */
+    public function setGroup($groupName) {
+        $this->groupName = $groupName;
+    }
+
+    public function getGroup() {
+        return $this->groupName;
+    }
+
+    /**
+     * If the prefix attribute is set, all files in the fileset
+     * are prefixed with that path in the archive.
+     * optional.
+     */
+    public function setPrefix($prefix) {
+        $this->prefix = $prefix;
+    }
+
+    public function getPrefix() {
+        return $this->prefix;
+    }
+
+    /**
+     * If the fullpath attribute is set, the file in the fileset
+     * is written with that path in the archive. The prefix attribute,
+     * if specified, is ignored. It is an error to have more than one file specified in
+     * such a fileset.
+     */
+    public function setFullpath($fullpath) {
+        $this->fullpath = $fullpath;
+    }
+
+    public function getFullpath() {
+        return $this->fullpath;
+    }
+
+    /**
+     * Flag to indicates whether leading `/'s should
+     * be preserved in the file names.
+     * Optional, default is <code>false</code>.
+     * @return void
+     */
+    public function setPreserveLeadingSlashes($b) {
+        $this->preserveLeadingSlashes = (boolean) $b;
+    }
+
+    public function getPreserveLeadingSlashes() {
+        return $this->preserveLeadingSlashes;
+    }
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/UntarTask.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/UntarTask.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/UntarTask.php	(revision 19)
@@ -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 please see
+ * <http://phing.info>.
+ */
+
+require_once 'phing/tasks/ext/ExtractBaseTask.php';
+
+/**
+ * Extracts one or several tar archives using PEAR Archive_Tar
+ *
+ * @author    Joakim Bodin <joakim.bodin+phing@gmail.com>
+ * @version   $Revision: 1.0 $
+ * @package   phing.tasks.ext
+ * @since     2.2.0
+ */
+class UntarTask extends ExtractBaseTask {
+    
+    /**
+     * Ensures that PEAR lib exists.
+     */
+    public function init() {
+        include_once 'Archive/Tar.php';
+        if (!class_exists('Archive_Tar')) {
+            throw new BuildException("You must have installed the PEAR Archive_Tar class in order to use UntarTask.");
+        }
+    }
+    
+    protected function extractArchive(PhingFile $tarfile)
+    {
+        $this->log("Extracting tar file: " . $tarfile->__toString() . ' to ' . $this->todir->__toString(), Project::MSG_INFO);
+        
+    	try {
+        	$tar = $this->initTar($tarfile);
+        	if(!$tar->extractModify($this->todir->getAbsolutePath(), $this->removepath)) {
+        	    throw new BuildException('Failed to extract tar file: ' . $tarfile->getAbsolutePath());
+        	}
+        } catch (IOException $ioe) {
+            $msg = "Could not extract tar file: " . $ioe->getMessage();
+            throw new BuildException($msg, $ioe, $this->getLocation());
+        }
+    }
+    
+    protected function listArchiveContent(PhingFile $tarfile)
+    {
+        $tar = $this->initTar($tarfile);
+        return $tar->listContent();
+    }
+    
+    /**
+     * Init a Archive_Tar class with correct compression for the given file.
+     *
+     * @param PhingFile $tarfile
+     * @return Archive_Tar the tar class instance
+     */
+    private function initTar(PhingFile $tarfile)
+    {
+        $compression = null;
+        $tarfileName = $tarfile->getName();
+        $mode = substr($tarfileName, strrpos($tarfileName, '.'));
+        switch($mode) {
+            case '.gz':
+                $compression = 'gz';
+                break;
+            case '.bz2':
+                $compression = 'bz2';
+                break;
+            case '.tar':
+                break;
+            default:
+                $this->log('Ignoring unknown compression mode: ' . $mode, Project::MSG_WARN);
+        }
+        
+    	return new Archive_Tar($tarfile->getAbsolutePath(), $compression);
+    }
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/UnzipTask.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/UnzipTask.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/UnzipTask.php	(revision 19)
@@ -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 please see
+ * <http://phing.info>.
+ */
+
+require_once 'phing/tasks/ext/ExtractBaseTask.php';
+require_once 'phing/system/io/FileSystem.php';
+require_once 'phing/lib/Zip.php';
+
+/**
+ * Extracts one or several zip archive using PEAR Archive_Zip (which is presently unreleased
+ * and included with Phing).
+ *
+ * @author    Joakim Bodin <joakim.bodin+phing@gmail.com>
+ * @version   $Revision: 1.0 $
+ * @package   phing.tasks.ext
+ * @since     2.2.0
+ */
+class UnzipTask extends ExtractBaseTask {
+    
+    protected function extractArchive(PhingFile $zipfile)
+    {
+        $extractParams = array('add_path' => $this->todir->getAbsolutePath());
+        if(!empty($this->removepath))
+        {
+            $extractParams['remove_path'] = $this->removepath;
+        }
+        
+        $this->log("Extracting zip: " . $zipfile->__toString() . ' to ' . $this->todir->__toString(), Project::MSG_INFO);
+        
+    	try {
+        	$zip = new Archive_Zip($zipfile->getAbsolutePath());
+        	
+        	$extractResponse = $zip->extract($extractParams);
+        	if(is_array($extractResponse)) {
+        	    foreach ($extractResponse as $extractedPath) {
+        	    	$this->log('Extracted' . $extractedPath['stored_filename'] . ' to ' . $this->todir->__toString(), Project::MSG_VERBOSE);
+        	    }
+        	} else if ($extractResponse === 0) {
+        	    throw new BuildException('Failed to extract zipfile: ' . $zip->errorInfo(true));
+        	}
+        } catch (IOException $ioe) {
+            $msg = "Could not extract ZIP: " . $ioe->getMessage();
+            throw new BuildException($msg, $ioe, $this->getLocation());
+        }
+    }
+    
+    protected function listArchiveContent(PhingFile $zipfile)
+    {
+        $zip = new Archive_Zip($zipfile->getAbsolutePath());
+        return $zip->listContent();
+    }
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/XmlLintTask.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/XmlLintTask.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/XmlLintTask.php	(revision 19)
@@ -0,0 +1,135 @@
+<?php
+/*
+ *  $Id: XmlLintTask.php 325 2007-12-20 15:44:58Z hans $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+require_once 'phing/Task.php';
+
+/**
+ * A XML lint task. Checking syntax of one or more XML files against an XML Schema using the DOM extension.
+ *
+ * @author   Knut Urdalen <knut.urdalen@telio.no>
+ * @package  phing.tasks.ext
+ */
+class XmlLintTask extends Task {
+
+  protected $file;  // the source file (from xml attribute)
+  protected $schema; // the schema file (from xml attribute)
+  protected $filesets = array(); // all fileset objects assigned to this task
+
+  /**
+   * File to be performed syntax check on
+   *
+   * @param PhingFile $file
+   */
+  public function setFile(PhingFile $file) {
+    $this->file = $file;
+  }
+
+  /**
+   * XML Schema Description file to validate against
+   *
+   * @param PhingFile $schema
+   */
+  public function setSchema(PhingFile $schema) {
+    $this->schema = $schema;
+  }
+  
+  /**
+   * Nested creator, creates a FileSet for this task
+   *
+   * @return FileSet The created fileset object
+   */
+  function createFileSet() {
+    $num = array_push($this->filesets, new FileSet());
+    return $this->filesets[$num-1];
+  }
+
+  /**
+   * Execute lint check against PhingFile or a FileSet
+   */
+  public function main() {
+    if(!isset($this->schema)) {
+      throw new BuildException("Missing attribute 'schema'");
+    }
+    $schema = $this->schema->getPath();
+    if(!file_exists($schema)) {
+      throw new BuildException("File not found: ".$schema);
+    }
+    if(!isset($this->file) and count($this->filesets) == 0) {
+      throw new BuildException("Missing either a nested fileset or attribute 'file' set");
+    }
+
+    set_error_handler(array($this, 'errorHandler'));
+    if($this->file instanceof PhingFile) {
+      $this->lint($this->file->getPath());
+    } else { // process filesets
+      $project = $this->getProject();
+      foreach($this->filesets as $fs) {
+	$ds = $fs->getDirectoryScanner($project);
+	$files = $ds->getIncludedFiles();
+	$dir = $fs->getDir($this->project)->getPath();
+	foreach($files as $file) {
+	  $this->lint($dir.DIRECTORY_SEPARATOR.$file);
+	}
+      }
+    }
+    restore_error_handler();
+  }
+
+  /**
+   * Performs validation
+   *
+   * @param string $file
+   * @return void
+   */
+  protected function lint($file) {
+    if(file_exists($file)) {
+      if(is_readable($file)) {
+	$dom = new DOMDocument();
+	$dom->load($file);
+	if($dom->schemaValidate($this->schema->getPath())) {
+	  $this->log($file.' validated', Project::MSG_INFO);
+	} else {
+	  $this->log($file.' fails to validate (See messages above)', Project::MSG_ERR);
+	}
+      } else {
+	throw new BuildException('Permission denied: '.$file);
+      }
+    } else {
+      throw new BuildException('File not found: '.$file);
+    }
+  }
+
+  /**
+   * Local error handler to catch validation errors and log them through Phing
+   *
+   * @param int    $level
+   * @param string $message
+   * @param string $file
+   * @param int    $line
+   */
+  public function errorHandler($level, $message, $file, $line, $context) {
+    $matches = array();
+    preg_match('/^.*\(\): (.*)$/', $message, $matches);
+    $this->log($matches[1], Project::MSG_ERR);
+  }
+
+}
+
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/ZendCodeAnalyzerTask.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/ZendCodeAnalyzerTask.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/ZendCodeAnalyzerTask.php	(revision 19)
@@ -0,0 +1,182 @@
+<?php
+/*
+ *  $Id: ZendCodeAnalyzerTask.php 325 2007-12-20 15:44:58Z hans $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+require_once 'phing/Task.php';
+
+/**
+ * ZendCodeAnalyzerTask analyze PHP source code using the ZendCodeAnalyzer included in Zend Studio 5.1
+ * 
+ * Available warnings:
+ * <b>zend-error</b> - %s(line %d): %s
+ * <b>oneline-comment</b> - One-line comment ends with  tag.
+ * <b>bool-assign</b> - Assignment seen where boolean expression is expected. Did you mean '==' instead of '='?
+ * <b>bool-print</b> - Print statement used when boolean expression is expected.
+ * <b>bool-array</b> - Array used when boolean expression is expected.
+ * <b>bool-object</b> - Object used when boolean expression is expected.
+ * <b>call-time-ref</b> - Call-time reference is deprecated. Define function as accepting parameter by reference instead.
+ * <b>if-if-else</b> - In if-if-else construction else relates to the closest if. Use braces to make the code clearer.
+ * <b>define-params</b> - define() requires two or three parameters.
+ * <b>define-const</b> - First parameter for define() should be string. Maybe you forgot quotes?
+ * <b>break-var</b> - Break/continue with variable is dangerous - break level can be out of scope.
+ * <b>break-depth</b> - Break/continue with depth more than current nesting level.
+ * <b>var-once</b> - Variable '%s' encountered only once. May be a typo?
+ * <b>var-arg-unused</b> - Function argument '%s' is never used.
+ * <b>var-global-unused</b> - Global variable '%s' is defined but never used.
+ * <b>var-use-before-def</b> - Variable '%s' is used before it was assigned.
+ * <b>var-use-before-def-global</b> - Global variable '%s' is used without being assigned. You are probably relying on register_globals feature of PHP. Note that this feature is off by default.
+ * <b>var-no-global</b> - PHP global variable '%s' is used as local. Maybe you wanted to define '%s' as global?
+ * <b>var-value-unused</b> - Value assigned to variable '%s' is never used
+ * <b>var-ref-notmodified</b> - Function parameter '%s' is passed by reference but never modified. Consider passing by value.
+ * <b>return-empty-val</b> - Function '%s' has both empty return and return with value.
+ * <b>return-empty-used</b> - Function '%s' has empty return but return value is used.
+ * <b>return-noref</b> - Function '%s' returns reference but the value is not assigned by reference. Maybe you meant '=&' instead of '='?
+ * <b>return-end-used</b> - Control reaches the end of function '%s'(file %s, line %d) but return value is used.
+ * <b>sprintf-miss-args</b> - Missing arguments for sprintf: format reqires %d arguments but %d are supplied.
+ * <b>sprintf-extra-args</b> - Extra arguments for sprintf: format reqires %d arguments but %d are supplied.
+ * <b>unreach-code</b> - Unreachable code in function '%s'.
+ * <b>include-var</b> - include/require with user-accessible variable can be dangerous. Consider using constant instead.
+ * <b>non-object</b> - Variable '%s' used as object, but has different type.
+ * <b>bad-escape</b> - Bad escape sequence: \%c, did you mean \\%c?
+ * <b>empty-cond</b> - Condition without a body
+ * <b>expr-unused</b> - Expression result is never used
+ *
+ * @author   Knut Urdalen <knut.urdalen@gmail.com>
+ * @package  phing.tasks.ext
+ */
+class ZendCodeAnalyzerTask extends Task {
+  
+  protected $analyzerPath = ""; // Path to ZendCodeAnalyzer binary
+  protected $file = "";  // the source file (from xml attribute)
+  protected $filesets = array(); // all fileset objects assigned to this task
+  protected $warnings = array();
+  protected $counter = 0;
+  protected $disable = array();
+  protected $enable = array();
+  
+  /**
+   * File to be analyzed
+   * 
+   * @param PhingFile $file
+   */
+  public function setFile(PhingFile $file) {
+    $this->file = $file;
+  }
+  
+  /**
+   * Path to ZendCodeAnalyzer binary
+   *
+   * @param string $analyzerPath
+   */
+  public function setAnalyzerPath($analyzerPath) {
+    $this->analyzerPath = $analyzerPath;
+  }
+  
+  /**
+   * Disable warning levels. Seperate warning levels with ','
+   *
+   * @param string $disable
+   */
+  public function setDisable($disable) {
+    $this->disable = explode(",", $disable);
+  }
+  
+  /**
+   * Enable warning levels. Seperate warning levels with ','
+   *
+   * @param string $enable
+   */
+  public function setEnable($enable) {
+    $this->enable = explode(",", $enable);
+  }
+  
+  /**
+   * Nested creator, creates a FileSet for this task
+   *
+   * @return FileSet The created fileset object
+   */
+  function createFileSet() {
+    $num = array_push($this->filesets, new FileSet());
+    return $this->filesets[$num-1];
+  }
+
+  /**
+   * Analyze against PhingFile or a FileSet
+   */
+  public function main() {
+    if(!isset($this->analyzerPath)) {
+      throw new BuildException("Missing attribute 'analyzerPath'");
+    }
+    if(!isset($this->file) and count($this->filesets) == 0) {
+      throw new BuildException("Missing either a nested fileset or attribute 'file' set");
+    }
+    
+    if($this->file instanceof PhingFile) {
+      $this->analyze($this->file->getPath());
+    } else { // process filesets
+      $project = $this->getProject();
+      foreach($this->filesets as $fs) {
+      	$ds = $fs->getDirectoryScanner($project);
+      	$files = $ds->getIncludedFiles();
+      	$dir = $fs->getDir($this->project)->getPath();
+      	foreach($files as $file) {
+	  $this->analyze($dir.DIRECTORY_SEPARATOR.$file);
+      	}
+      }
+    }
+    $this->log("Number of findings: ".$this->counter, Project::MSG_INFO);
+  }
+
+  /**
+   * Analyze file
+   *
+   * @param string $file
+   * @return void
+   */
+  protected function analyze($file) {
+    if(file_exists($file)) {
+      if(is_readable($file)) {
+      	
+      	// Construct shell command
+      	$cmd = $this->analyzerPath." ";
+      	foreach($this->enable as $enable) { // Enable warning levels
+      		$cmd .= " --enable $enable ";
+      	}
+      	foreach($this->disable as $disable) { // Disable warning levels
+      		$cmd .= " --disable $disable ";
+      	}
+      	$cmd .= "$file 2>&1";
+      	
+      	// Execute command
+      	$result = shell_exec($cmd);
+      	$result = explode("\n", $result);
+      	for($i=2, $size=count($result); $i<($size-1); $i++) {
+	  $this->counter++;
+	  $this->log($result[$i], Project::MSG_WARN);
+      	}
+      } else {
+      	throw new BuildException('Permission denied: '.$file);
+      }
+    } else {
+      throw new BuildException('File not found: '.$file);
+    }
+  }
+}
+
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/ZipTask.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/ZipTask.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/ZipTask.php	(revision 19)
@@ -0,0 +1,265 @@
+<?php
+/*
+ *  $Id: ZipTask.php 240 2007-09-25 20:43:37Z mrook $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+require_once 'phing/tasks/system/MatchingTask.php';
+include_once 'phing/util/SourceFileScanner.php';
+include_once 'phing/mappers/MergeMapper.php';
+include_once 'phing/util/StringHelper.php';
+include_once 'phing/lib/Zip.php';
+
+/**
+ * Creates a zip archive using PEAR Archive_Zip (which is presently unreleased
+ * and included with Phing).
+ *
+ * @author    Michiel Rook <michiel.rook@gmail.com>
+ * @version   $Revision: 1.2 $
+ * @package   phing.tasks.ext
+ * @since     2.1.0
+ */
+class ZipTask extends MatchingTask {
+    
+	/**
+	 * @var PhingFile
+	 */
+    private $zipFile;
+    
+    /**
+     * @var PhingFile
+     */
+    private $baseDir;
+	
+    /**
+     * Whether to include empty dirs in the archive.
+     */
+    private $includeEmpty = true;
+    
+    private $filesets = array();
+    private $fileSetFiles = array();
+
+    /**
+     * Add a new fileset.
+     * @return FileSet
+     */
+    public function createFileSet() {
+        $this->fileset = new ZipFileSet();
+        $this->filesets[] = $this->fileset;
+        return $this->fileset;
+    }
+
+    /**
+     * Set is the name/location of where to create the zip file.
+     * @param PhingFile $destFile The output of the zip
+     */
+    public function setDestFile(PhingFile $destFile) {
+        $this->zipFile = $destFile;
+    }
+
+    /**
+     * This is the base directory to look in for things to zip.
+     * @param PhingFile $baseDir
+     */
+    public function setBasedir(PhingFile $baseDir) {
+        $this->baseDir = $baseDir;
+    }
+
+    /**
+     * Set the include empty dirs flag.
+     * @param  boolean  Flag if empty dirs should be tarred too
+     * @return void
+     * @access public
+     */
+    function setIncludeEmptyDirs($bool) {
+        $this->includeEmpty = (boolean) $bool;
+    }
+    
+    /**
+     * do the work
+     * @throws BuildException
+     */
+    public function main() {
+    
+        if ($this->zipFile === null) {
+            throw new BuildException("zipfile attribute must be set!", $this->getLocation());
+        }
+
+        if ($this->zipFile->exists() && $this->zipFile->isDirectory()) {
+            throw new BuildException("zipfile is a directory!", $this->getLocation());
+        }
+
+        if ($this->zipFile->exists() && !$this->zipFile->canWrite()) {
+            throw new BuildException("Can not write to the specified zipfile!", $this->getLocation());
+        }
+
+        // shouldn't need to clone, since the entries in filesets
+        // themselves won't be modified -- only elements will be added
+        $savedFileSets = $this->filesets;
+        
+        try {
+            if ($this->baseDir !== null) {
+                if (!$this->baseDir->exists()) {
+                    throw new BuildException("basedir does not exist!", $this->getLocation());
+                }
+                
+                if (empty($this->filesets))
+                {
+	                // add the main fileset to the list of filesets to process.
+	                $mainFileSet = new ZipFileSet($this->fileset);
+	                $mainFileSet->setDir($this->baseDir);
+	                $this->filesets[] = $mainFileSet;
+                }
+            }
+
+            if (empty($this->filesets)) {
+                throw new BuildException("You must supply either a basedir "
+                                         . "attribute or some nested filesets.",
+                                         $this->getLocation());
+            }                        
+            
+            // check if zip is out of date with respect to each
+            // fileset
+            $upToDate = true;
+            foreach($this->filesets as $fs) {
+            	$files = $fs->getFiles($this->project, $this->includeEmpty);
+                if (!$this->archiveIsUpToDate($files, $fs->getDir($this->project))) {
+                    $upToDate = false;
+                }
+                for ($i=0, $fcount=count($files); $i < $fcount; $i++) {
+                    if ($this->zipFile->equals(new PhingFile($fs->getDir($this->project), $files[$i]))) {
+                        throw new BuildException("A zip file cannot include itself", $this->getLocation());
+                    }
+                }
+            }
+            
+            if ($upToDate) {
+                $this->log("Nothing to do: " . $this->zipFile->__toString() . " is up to date.", Project::MSG_INFO);
+                return;
+            }
+
+            $this->log("Building zip: " . $this->zipFile->__toString(), Project::MSG_INFO);
+            
+            $zip = new Archive_Zip($this->zipFile->getAbsolutePath());
+            
+            foreach($this->filesets as $fs) {
+            	
+            	$files = $fs->getFiles($this->project, $this->includeEmpty);
+            	
+                $fsBasedir = (null != $this->baseDir) ? $this->baseDir :
+									$fs->getDir($this->project);
+                
+                $filesToZip = array();
+                for ($i=0, $fcount=count($files); $i < $fcount; $i++) {
+                    $f = new PhingFile($fsBasedir, $files[$i]);
+                    $filesToZip[] = $f->getAbsolutePath();
+                    $this->log("Adding " . $f->getPath() . " to archive.", Project::MSG_VERBOSE);                        
+                }
+                $zip->add($filesToZip, array('remove_path' => $fsBasedir->getCanonicalPath()));
+            }
+                         
+                
+        } catch (IOException $ioe) {
+                $msg = "Problem creating ZIP: " . $ioe->getMessage();
+                $this->filesets = $savedFileSets;
+                throw new BuildException($msg, $ioe, $this->getLocation());
+        }
+        
+        $this->filesets = $savedFileSets;
+    }
+           
+    /**
+     * @param array $files array of filenames
+     * @param PhingFile $dir
+     * @return boolean
+     */
+    protected function archiveIsUpToDate($files, $dir) {
+        $sfs = new SourceFileScanner($this);
+        $mm = new MergeMapper();
+        $mm->setTo($this->zipFile->getAbsolutePath());
+        return count($sfs->restrict($files, $dir, null, $mm)) == 0;
+    }
+   
+}
+
+
+
+
+/**
+ * This is a FileSet with the to specify permissions.
+ * 
+ * Permissions are currently not implemented by PEAR Archive_Tar,
+ * but hopefully they will be in the future.
+ * 
+ */
+class ZipFileSet extends FileSet {
+
+    private $files = null;
+
+    /**
+     *  Get a list of files and directories specified in the fileset.
+     *  @return array a list of file and directory names, relative to
+     *    the baseDir for the project.
+     */
+    public function getFiles(Project $p, $includeEmpty = true) {
+    
+        if ($this->files === null) {
+        
+            $ds = $this->getDirectoryScanner($p);
+            $this->files = $ds->getIncludedFiles();
+            
+            if ($includeEmpty) {
+            
+	            // first any empty directories that will not be implicitly added by any of the files
+				$implicitDirs = array();
+				foreach($this->files as $file) {
+					$implicitDirs[] = dirname($file);
+				} 
+				
+				$incDirs = $ds->getIncludedDirectories();
+				
+				// we'll need to add to that list of implicit dirs any directories
+				// that contain other *directories* (and not files), since otherwise
+				// we get duplicate directories in the resulting tar
+				foreach($incDirs as $dir) {
+					foreach($incDirs as $dircheck) {
+						if (!empty($dir) && $dir == dirname($dircheck)) {
+							$implicitDirs[] = $dir;
+						}
+					}
+				}
+				
+				$implicitDirs = array_unique($implicitDirs);
+				
+				// Now add any empty dirs (dirs not covered by the implicit dirs)
+				// to the files array. 
+				
+				foreach($incDirs as $dir) { // we cannot simply use array_diff() since we want to disregard empty/. dirs
+					if ($dir != "" && $dir != "." && !in_array($dir, $implicitDirs)) {
+						// it's an empty dir, so we'll add it.
+						$this->files[] = $dir;
+					}
+				}
+			} // if $includeEmpty
+			
+        } // if ($this->files===null)
+        
+        return $this->files;
+    }
+
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/coverage/CoverageMerger.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/coverage/CoverageMerger.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/coverage/CoverageMerger.php	(revision 19)
@@ -0,0 +1,126 @@
+<?php
+/**
+ * $Id: CoverageMerger.php 325 2007-12-20 15:44:58Z hans $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+require_once 'phing/system/util/Properties.php';
+
+/**
+ * Saves coverage output of the test to a specified database
+ *
+ * @author Michiel Rook <michiel.rook@gmail.com>
+ * @version $Id: CoverageMerger.php 325 2007-12-20 15:44:58Z hans $
+ * @package phing.tasks.ext.coverage
+ * @since 2.1.0
+ */
+class CoverageMerger
+{
+	private static function mergeCodeCoverage($left, $right)
+	{
+		$coverageMerged = array();
+
+		reset($left);
+		reset($right);
+
+		while (current($left) && current($right))
+		{
+			$linenr_left = key($left);
+			$linenr_right = key($right);
+
+			if ($linenr_left < $linenr_right)
+			{
+				$coverageMerged[$linenr_left] = current($left);
+
+				next($left);
+			}
+			else
+			if ($linenr_right < $linenr_left)
+			{
+				$coverageMerged[$linenr_right] = current($right);
+				next($right);
+			}
+			else
+			{
+				if (current($left) < 0)
+				{
+					$coverageMerged[$linenr_right] = current($right);
+				}
+				else
+				if (current($right) < 0)
+				{
+					$coverageMerged[$linenr_right] = current($left);
+				}
+				else
+				{
+					$coverageMerged[$linenr_right] = current($left) + current($right);
+				}
+				
+				next($left);
+				next($right);
+			}
+		}
+
+		while (current($left))
+		{
+			$coverageMerged[key($left)] = current($left);
+			next($left);
+		}
+
+		while (current($right))
+		{
+			$coverageMerged[key($right)] = current($right);
+			next($right);
+		}
+
+		return $coverageMerged;
+	}
+
+	static function merge($project, $codeCoverageInformation)
+	{
+		$database = new PhingFile($project->getProperty('coverage.database'));
+
+		$props = new Properties();
+		$props->load($database);
+		
+		$coverageTotal = $codeCoverageInformation;
+		
+		foreach ($coverageTotal as $coverage)
+		{
+			foreach ($coverage as $filename => $coverageFile)
+			{
+				$filename = strtolower($filename);
+				
+				if ($props->getProperty($filename) != null)
+				{
+					$file = unserialize($props->getProperty($filename));
+					$left = $file['coverage'];
+					$right = $coverageFile;
+					
+					$coverageMerged = CoverageMerger::mergeCodeCoverage($left, $right);
+					
+					$file['coverage'] = $coverageMerged;
+					
+					$props->setProperty($filename, serialize($file));
+				}
+			}
+		}
+
+		$props->store($database);
+	}
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/coverage/CoverageMergerTask.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/coverage/CoverageMergerTask.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/coverage/CoverageMergerTask.php	(revision 19)
@@ -0,0 +1,92 @@
+<?php
+/**
+ * $Id: CoverageMergerTask.php 325 2007-12-20 15:44:58Z hans $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+require_once 'phing/Task.php';
+require_once 'phing/system/io/PhingFile.php';
+require_once 'phing/system/io/Writer.php';
+require_once 'phing/system/util/Properties.php';
+require_once 'phing/tasks/ext/coverage/CoverageMerger.php';
+
+/**
+ * Merges code coverage snippets into a code coverage database
+ *
+ * @author Michiel Rook <michiel.rook@gmail.com>
+ * @version $Id: CoverageMergerTask.php 325 2007-12-20 15:44:58Z hans $
+ * @package phing.tasks.ext.coverage
+ * @since 2.1.0
+ */
+class CoverageMergerTask extends Task
+{
+	/** the list of filesets containing the .php filename rules */
+	private $filesets = array();
+
+	/**
+	 * Add a new fileset containing the .php files to process
+	 *
+	 * @param FileSet the new fileset containing .php files
+	 */
+	function addFileSet(FileSet $fileset)
+	{
+		$this->filesets[] = $fileset;
+	}
+
+	/**
+	 * Iterate over all filesets and return all the filenames.
+	 *
+	 * @return array an array of filenames
+	 */
+	private function getFilenames()
+	{
+		$files = array();
+
+		foreach ($this->filesets as $fileset)
+		{
+			$ds = $fileset->getDirectoryScanner($this->project);
+			$ds->scan();
+
+			$includedFiles = $ds->getIncludedFiles();
+			
+			foreach ($includedFiles as $file)
+			{
+				$fs = new PhingFile(basename($ds->getBaseDir()), $file);
+					
+				$files[] = $fs->getAbsolutePath();
+			}
+		}
+
+		return $files;
+	}
+	
+	function main()
+	{
+		$files = $this->getFilenames();
+		
+		$this->log("Merging " . count($files) . " coverage files");
+
+		foreach ($files as $file)
+		{
+			$coverageInformation = unserialize(file_get_contents($file));
+			
+			CoverageMerger::merge($this->project, array($coverageInformation));
+		}
+	}
+}
+
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/coverage/CoverageReportTask.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/coverage/CoverageReportTask.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/coverage/CoverageReportTask.php	(revision 19)
@@ -0,0 +1,418 @@
+<?php
+/**
+ * $Id: CoverageReportTask.php 325 2007-12-20 15:44:58Z hans $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+require_once 'phing/Task.php';
+require_once 'phing/system/io/PhingFile.php';
+require_once 'phing/system/io/Writer.php';
+require_once 'phing/system/util/Properties.php';
+require_once 'phing/tasks/ext/phpunit/PHPUnitUtil.php';
+require_once 'phing/tasks/ext/coverage/CoverageReportTransformer.php';
+
+/**
+ * Transforms information in a code coverage database to XML
+ *
+ * @author Michiel Rook <michiel.rook@gmail.com>
+ * @version $Id: CoverageReportTask.php 325 2007-12-20 15:44:58Z hans $
+ * @package phing.tasks.ext.coverage
+ * @since 2.1.0
+ */
+class CoverageReportTask extends Task
+{
+	private $outfile = "coverage.xml";
+
+	private $transformers = array();
+
+	/** the classpath to use (optional) */
+	private $classpath = NULL;
+	
+	/** the path to the GeSHi library (optional) */
+	private $geshipath = "";
+	
+	/** the path to the GeSHi language files (optional) */
+	private $geshilanguagespath = "";
+	
+	function setClasspath(Path $classpath)
+	{
+		if ($this->classpath === null)
+		{
+			$this->classpath = $classpath;
+		}
+		else
+		{
+			$this->classpath->append($classpath);
+		}
+	}
+
+	function createClasspath()
+	{
+		$this->classpath = new Path();
+		return $this->classpath;
+	}
+	
+	function setGeshiPath($path)
+	{
+		$this->geshipath = $path;
+	}
+
+	function setGeshiLanguagesPath($path)
+	{
+		$this->geshilanguagespath = $path;
+	}
+
+	function __construct()
+	{
+		$this->doc = new DOMDocument();
+		$this->doc->encoding = 'UTF-8';
+		$this->doc->formatOutput = true;
+		$this->doc->appendChild($this->doc->createElement('snapshot'));
+	}
+
+	function setOutfile($outfile)
+	{
+		$this->outfile = $outfile;
+	}
+
+	/**
+	 * Generate a report based on the XML created by this task
+	 */
+	function createReport()
+	{
+		$transformer = new CoverageReportTransformer($this);
+		$this->transformers[] = $transformer;
+		return $transformer;
+	}
+
+	protected function getPackageElement($packageName)
+	{
+		$packages = $this->doc->documentElement->getElementsByTagName('package');
+
+		foreach ($packages as $package)
+		{
+			if ($package->getAttribute('name') == $packageName)
+			{
+				return $package;
+			}
+		}
+
+		return NULL;
+	}
+
+	protected function addClassToPackage($classname, $element)
+	{
+		$packageName = PHPUnitUtil::getPackageName($classname);
+
+		$package = $this->getPackageElement($packageName);
+
+		if ($package === NULL)
+		{
+			$package = $this->doc->createElement('package');
+			$package->setAttribute('name', $packageName);
+			$this->doc->documentElement->appendChild($package);
+		}
+
+		$package->appendChild($element);
+	}
+
+	protected function stripDiv($source)
+	{
+		$openpos = strpos($source, "<div");
+		$closepos = strpos($source, ">", $openpos);
+
+		$line = substr($source, $closepos + 1);
+
+		$tagclosepos = strpos($line, "</div>");
+
+		$line = substr($line, 0, $tagclosepos);
+
+		return $line;
+	}
+
+	protected function highlightSourceFile($filename)
+	{
+		if ($this->geshipath)
+		{
+			require_once $this->geshipath . '/geshi.php';
+			
+			$source = file_get_contents($filename);
+
+			$geshi = new GeSHi($source, 'php', $this->geshilanguagespath);
+
+			$geshi->enable_line_numbers(GESHI_NORMAL_LINE_NUMBERS);
+
+			$geshi->enable_strict_mode(true);
+
+			$geshi->enable_classes(true);
+
+			$geshi->set_url_for_keyword_group(3, ''); 
+
+			$html = $geshi->parse_code();
+
+			$lines = split("<li>|</li>", $html);
+
+			// skip first and last line
+			array_pop($lines);
+			array_shift($lines);
+
+			$lines = array_filter($lines);
+
+			$lines = array_map(array($this, 'stripDiv'), $lines);
+
+			return $lines;
+		}
+		else
+		{
+			$lines = file($filename);
+			
+			for ($i = 0; $i < count($lines); $i++)
+			{
+				$line = $lines[$i];
+				
+				$line = rtrim($line);
+				
+				if (function_exists('mb_convert_encoding'))
+				{
+					$lines[$i] = mb_convert_encoding($line, 'UTF-8');
+				}
+				else
+				{
+					$lines[$i] = utf8_encode($line);
+				}
+			}
+			
+			return $lines;
+		}
+	}
+
+	protected function transformSourceFile($filename, $coverageInformation, $classStartLine = 1)
+	{
+		$sourceElement = $this->doc->createElement('sourcefile');
+		$sourceElement->setAttribute('name', basename($filename));
+		
+		/**
+		 * Add original/full filename to document
+		 */
+		$sourceElement->setAttribute('sourcefile', $filename);
+
+		$filelines = $this->highlightSourceFile($filename);
+
+		$linenr = 1;
+
+		foreach ($filelines as $line)
+		{
+			$lineElement = $this->doc->createElement('sourceline');
+			$lineElement->setAttribute('coveredcount', (isset($coverageInformation[$linenr]) ? $coverageInformation[$linenr] : '0'));
+
+			if ($linenr == $classStartLine)
+			{
+				$lineElement->setAttribute('startclass', 1);
+			}
+
+			$textnode = $this->doc->createTextNode($line);
+			$lineElement->appendChild($textnode);
+
+			$sourceElement->appendChild($lineElement);
+
+			$linenr++;
+		}
+
+		return $sourceElement;
+	}
+	
+	protected function filterCovered($var)
+	{
+		return ($var >= 0);
+	}
+
+	protected function transformCoverageInformation($filename, $coverageInformation)
+	{
+		// Strip last line of coverage information
+		end($coverageInformation);
+		unset($coverageInformation[key($coverageInformation)]);
+		
+		$classes = PHPUnitUtil::getDefinedClasses($filename, $this->classpath);
+		
+		if (is_array($classes))
+		{
+			foreach ($classes as $classname)
+			{
+				$reflection = new ReflectionClass($classname);
+				
+				$methods = $reflection->getMethods();
+				
+				$classElement = $this->doc->createElement('class');
+				$classElement->setAttribute('name', $reflection->getName());
+				
+				$this->addClassToPackage($reflection->getName(), $classElement);
+
+				$classStartLine = $reflection->getStartLine();
+				
+				$methodscovered = 0;
+				$methodcount = 0;
+				
+				// Strange PHP5 reflection bug, classes without parent class or implemented interfaces seem to start one line off
+				if ($reflection->getParentClass() == NULL && count($reflection->getInterfaces()) == 0)
+				{
+					unset($coverageInformation[$classStartLine + 1]);
+				}
+				else
+				{
+					unset($coverageInformation[$classStartLine]);
+				}
+				
+				reset($coverageInformation);				
+				
+				foreach ($methods as $method)
+				{
+					// PHP5 reflection considers methods of a parent class to be part of a subclass, we don't
+					if ($method->getDeclaringClass()->getName() != $reflection->getName())
+					{
+						continue;
+					}
+
+					// small fix for XDEBUG_CC_UNUSED
+					if (isset($coverageInformation[$method->getStartLine()]))
+					{
+						unset($coverageInformation[$method->getStartLine()]);
+					}
+
+					if (isset($coverageInformation[$method->getEndLine()]))
+					{
+						unset($coverageInformation[$method->getEndLine()]);
+					}
+
+					if ($method->isAbstract())
+					{
+						continue;
+					}
+
+					$linenr = key($coverageInformation);
+
+					while ($linenr !== null && $linenr < $method->getStartLine())
+					{
+						next($coverageInformation);
+						$linenr = key($coverageInformation);
+					}
+
+					if (current($coverageInformation) > 0 && $method->getStartLine() <= $linenr && $linenr <= $method->getEndLine())
+					{
+						$methodscovered++;
+					}
+
+					$methodcount++;
+				}
+
+				$statementcount = count($coverageInformation);
+				$statementscovered = count(array_filter($coverageInformation, array($this, 'filterCovered')));
+
+				$classElement->appendChild($this->transformSourceFile($filename, $coverageInformation, $classStartLine));
+
+				$classElement->setAttribute('methodcount', $methodcount);
+				$classElement->setAttribute('methodscovered', $methodscovered);
+				$classElement->setAttribute('statementcount', $statementcount);
+				$classElement->setAttribute('statementscovered', $statementscovered);
+				$classElement->setAttribute('totalcount', $methodcount + $statementcount);
+				$classElement->setAttribute('totalcovered', $methodscovered + $statementscovered);
+			}
+		}
+	}
+
+	protected function calculateStatistics()
+	{
+		$packages = $this->doc->documentElement->getElementsByTagName('package');
+
+		$totalmethodcount = 0;
+		$totalmethodscovered = 0;
+
+		$totalstatementcount = 0;
+		$totalstatementscovered = 0;
+
+		foreach ($packages as $package)
+		{
+			$methodcount = 0;
+			$methodscovered = 0;
+
+			$statementcount = 0;
+			$statementscovered = 0;
+
+			$classes = $package->getElementsByTagName('class');
+
+			foreach ($classes as $class)
+			{
+				$methodcount += $class->getAttribute('methodcount');
+				$methodscovered += $class->getAttribute('methodscovered');
+
+				$statementcount += $class->getAttribute('statementcount');
+				$statementscovered += $class->getAttribute('statementscovered');
+			}
+
+			$package->setAttribute('methodcount', $methodcount);
+			$package->setAttribute('methodscovered', $methodscovered);
+
+			$package->setAttribute('statementcount', $statementcount);
+			$package->setAttribute('statementscovered', $statementscovered);
+
+			$package->setAttribute('totalcount', $methodcount + $statementcount);
+			$package->setAttribute('totalcovered', $methodscovered + $statementscovered);
+
+			$totalmethodcount += $methodcount;
+			$totalmethodscovered += $methodscovered;
+
+			$totalstatementcount += $statementcount;
+			$totalstatementscovered += $statementscovered;
+		}
+
+		$this->doc->documentElement->setAttribute('methodcount', $totalmethodcount);
+		$this->doc->documentElement->setAttribute('methodscovered', $totalmethodscovered);
+
+		$this->doc->documentElement->setAttribute('statementcount', $totalstatementcount);
+		$this->doc->documentElement->setAttribute('statementscovered', $totalstatementscovered);
+
+		$this->doc->documentElement->setAttribute('totalcount', $totalmethodcount + $totalstatementcount);
+		$this->doc->documentElement->setAttribute('totalcovered', $totalmethodscovered + $totalstatementscovered);
+	}
+
+	function main()
+	{
+		$this->log("Transforming coverage report");
+		
+		$database = new PhingFile($this->project->getProperty('coverage.database'));
+		
+		$props = new Properties();
+		$props->load($database);
+
+		foreach ($props->keys() as $filename)
+		{
+			$file = unserialize($props->getProperty($filename));
+
+			$this->transformCoverageInformation($file['fullname'], $file['coverage']);
+		}
+		
+		$this->calculateStatistics();
+
+		$this->doc->save($this->outfile);
+
+		foreach ($this->transformers as $transformer)
+		{
+			$transformer->setXmlDocument($this->doc);
+			$transformer->transform();
+		}
+	}
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/coverage/CoverageReportTransformer.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/coverage/CoverageReportTransformer.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/coverage/CoverageReportTransformer.php	(revision 19)
@@ -0,0 +1,120 @@
+<?php
+/**
+ * $Id: CoverageReportTransformer.php 325 2007-12-20 15:44:58Z hans $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+require_once 'phing/Task.php';
+require_once 'phing/system/io/PhingFile.php';
+require_once 'phing/system/io/FileWriter.php';
+require_once 'phing/util/ExtendedFileStream.php';
+
+/**
+ * Transform a Phing/Xdebug code coverage xml report.
+ * The default transformation generates an html report in framed style.
+ *
+ * @author Michiel Rook <michiel.rook@gmail.com>
+ * @version $Id: CoverageReportTransformer.php 325 2007-12-20 15:44:58Z hans $
+ * @package phing.tasks.ext.coverage
+ * @since 2.1.0
+ */
+class CoverageReportTransformer
+{
+	private $task = NULL;
+	private $styleDir = "";
+	private $toDir = "";
+	private $document = NULL;
+
+	function __construct(Task $task)
+	{
+		$this->task = $task;
+	}
+
+	function setStyleDir($styleDir)
+	{
+		$this->styleDir = $styleDir;
+	}
+
+	function setToDir($toDir)
+	{
+		$this->toDir = $toDir;
+	}
+
+	function setXmlDocument($document)
+	{
+		$this->document = $document;
+	}
+
+	function transform()
+	{
+        $dir = new PhingFile($this->toDir);
+
+        if (!$dir->exists())
+        {
+            throw new BuildException("Directory '" . $this->toDir . "' does not exist");
+        }
+
+		$xslfile = $this->getStyleSheet();
+
+		$xsl = new DOMDocument();
+		$xsl->load($xslfile->getAbsolutePath());
+
+		$proc = new XSLTProcessor();
+		$proc->importStyleSheet($xsl);
+
+		ExtendedFileStream::registerStream();
+
+		// no output for the framed report
+		// it's all done by extension...
+		$proc->setParameter('', 'output.dir', $dir->getAbsolutePath());
+		$proc->transformToXML($this->document);
+	}
+
+	private function getStyleSheet()
+	{
+		$xslname = "coverage-frames.xsl";
+
+		if ($this->styleDir)
+		{
+			$file = new PhingFile($this->styleDir, $xslname);
+		}
+		else
+		{
+			$path = Phing::getResourcePath("phing/etc/$xslname");
+			
+			if ($path === NULL)
+			{
+				$path = Phing::getResourcePath("etc/$xslname");
+
+				if ($path === NULL)
+				{
+					throw new BuildException("Could not find $xslname in resource path");
+				}
+			}
+			
+			$file = new PhingFile($path);
+		}
+
+		if (!$file->exists())
+		{
+			throw new BuildException("Could not find file " . $file->getPath());
+		}
+
+		return $file;
+	}
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/coverage/CoverageSetupTask.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/coverage/CoverageSetupTask.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/coverage/CoverageSetupTask.php	(revision 19)
@@ -0,0 +1,158 @@
+<?php
+/**
+ * $Id: CoverageSetupTask.php 325 2007-12-20 15:44:58Z hans $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+require_once 'phing/Task.php';
+require_once 'phing/system/io/PhingFile.php';
+require_once 'phing/system/io/Writer.php';
+require_once 'phing/system/util/Properties.php';
+require_once 'phing/tasks/ext/coverage/CoverageMerger.php';
+
+/**
+ * Initializes a code coverage database
+ *
+ * @author Michiel Rook <michiel.rook@gmail.com>
+ * @version $Id: CoverageSetupTask.php 325 2007-12-20 15:44:58Z hans $
+ * @package phing.tasks.ext.coverage
+ * @since 2.1.0
+ */
+class CoverageSetupTask extends Task
+{
+	/** the list of filesets containing the .php filename rules */
+	private $filesets = array();
+
+	/** the filename of the coverage database */
+	private $database = "coverage.db";
+
+	/** the classpath to use (optional) */
+	private $classpath = NULL;
+
+	/**
+	 * Add a new fileset containing the .php files to process
+	 *
+	 * @param FileSet the new fileset containing .php files
+	 */
+	function addFileSet(FileSet $fileset)
+	{
+		$this->filesets[] = $fileset;
+	}
+
+	/**
+	 * Sets the filename of the coverage database to use
+	 *
+	 * @param string the filename of the database
+	 */
+	function setDatabase($database)
+	{
+		$this->database = $database;
+	}
+
+	function setClasspath(Path $classpath)
+	{
+		if ($this->classpath === null)
+		{
+			$this->classpath = $classpath;
+		}
+		else
+		{
+			$this->classpath->append($classpath);
+		}
+	}
+
+	function createClasspath()
+	{
+		$this->classpath = new Path();
+		return $this->classpath;
+	}
+	
+	/**
+	 * Iterate over all filesets and return the filename of all files.
+	 *
+	 * @return array an array of (basedir, filenames) pairs
+	 */
+	private function getFilenames()
+	{
+		$files = array();
+
+		foreach ($this->filesets as $fileset)
+		{
+			$ds = $fileset->getDirectoryScanner($this->project);
+			$ds->scan();
+
+			$includedFiles = $ds->getIncludedFiles();
+
+			foreach ($includedFiles as $file)
+			{
+				$fs = new PhingFile(realpath($ds->getBaseDir()), $file);
+					
+				$files[] = array('key' => strtolower($fs->getAbsolutePath()), 'fullname' => $fs->getAbsolutePath());
+			}
+		}
+
+		return $files;
+	}
+	
+	function init()
+	{
+		if (!extension_loaded('xdebug'))
+		{
+			throw new Exception("CoverageSetupTask depends on Xdebug being installed.");
+		}
+	}
+
+	function main()
+	{
+		$files = $this->getFilenames();
+
+		$this->log("Setting up coverage database for " . count($files) . " files");
+
+		$props = new Properties();
+
+		foreach ($files as $file)
+		{
+			$fullname = $file['fullname'];
+			$filename = $file['key'];
+			
+			$props->setProperty($filename, serialize(array('fullname' => $fullname, 'coverage' => array())));
+		}
+
+		$dbfile = new PhingFile($this->database);
+
+		$props->store($dbfile);
+
+		$this->project->setProperty('coverage.database', $dbfile->getAbsolutePath());
+	
+		foreach ($files as $file)
+		{
+			$fullname = $file['fullname'];
+			
+			xdebug_start_code_coverage(XDEBUG_CC_UNUSED);
+			
+			Phing::__import($fullname, $this->classpath);
+			
+			$coverage = xdebug_get_code_coverage();
+			
+			xdebug_stop_code_coverage();
+			
+			CoverageMerger::merge($this->project, array($coverage));
+		}
+	}
+}
+
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/creole/CreoleSQLExecTask.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/creole/CreoleSQLExecTask.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/creole/CreoleSQLExecTask.php	(revision 19)
@@ -0,0 +1,590 @@
+<?php
+/*
+ *  $Id: CreoleSQLExecTask.php 266 2007-10-25 01:32:38Z hans $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+require_once 'phing/tasks/ext/creole/CreoleTask.php';
+include_once 'phing/system/io/StringReader.php';
+
+/**
+ * Executes a series of SQL statements on a database using Creole.
+ *
+ * <p>Statements can
+ * either be read in from a text file using the <i>src</i> attribute or from 
+ * between the enclosing SQL tags.</p>
+ * 
+ * <p>Multiple statements can be provided, separated by semicolons (or the 
+ * defined <i>delimiter</i>). Individual lines within the statements can be 
+ * commented using either --, // or REM at the start of the line.</p>
+ * 
+ * <p>The <i>autocommit</i> attribute specifies whether auto-commit should be 
+ * turned on or off whilst executing the statements. If auto-commit is turned 
+ * on each statement will be executed and committed. If it is turned off the 
+ * statements will all be executed as one transaction.</p>
+ * 
+ * <p>The <i>onerror</i> attribute specifies how to proceed when an error occurs 
+ * during the execution of one of the statements. 
+ * The possible values are: <b>continue</b> execution, only show the error;
+ * <b>stop</b> execution and commit transaction;
+ * and <b>abort</b> execution and transaction and fail task.</p>
+ *
+ * @author    Hans Lellelid <hans@xmpl.org> (Phing)
+ * @author    Jeff Martin <jeff@custommonkey.org> (Ant)
+ * @author    Michael McCallum <gholam@xtra.co.nz> (Ant)
+ * @author    Tim Stephenson <tim.stephenson@sybase.com> (Ant)
+ * @package   phing.tasks.ext
+ * @version   $Revision: 1.21 $
+ */
+class CreoleSQLExecTask extends CreoleTask {
+
+    private $goodSql = 0;
+    private $totalSql = 0;
+
+    const DELIM_ROW = "row";
+    const DELIM_NORMAL = "normal";
+
+    /**
+     * Database connection
+     */
+    private $conn = null;
+
+    /**
+     * files to load
+     */
+    private $filesets = array();
+
+    /**
+     * all filterchains objects assigned to this task
+     */
+    private $filterChains  = array();
+
+    /**
+     * SQL statement
+     */
+    private $statement = null;
+
+    /**
+     * SQL input file
+     */
+    private $srcFile = null;
+
+    /**
+     * SQL input command
+     */
+    private $sqlCommand = "";
+
+    /**
+     * SQL transactions to perform
+     */
+    private $transactions = array();
+
+    /**
+     * SQL Statement delimiter
+     */
+    private $delimiter = ";";
+    
+    /**
+     * The delimiter type indicating whether the delimiter will
+     * only be recognized on a line by itself
+     */
+    private $delimiterType = "normal"; // can't use constant just defined
+    
+    /**
+     * Print SQL results.
+     */
+    private $print = false;
+
+    /**
+     * Print header columns.
+     */
+    private $showheaders = true;
+
+    /**
+     * Results Output file.
+     */
+    private $output = null;
+
+    
+    /**
+     * Action to perform if an error is found
+     **/
+    private $onError = "abort";
+    
+    /**
+     * Encoding to use when reading SQL statements from a file
+     */
+    private $encoding = null;
+
+    /**
+     * Append to an existing file or overwrite it?
+     */
+    private $append = false;
+        
+    /**
+     * Set the name of the SQL file to be run.
+     * Required unless statements are enclosed in the build file
+     */
+    public function setSrc(PhingFile $srcFile) {       
+        $this->srcFile = $srcFile;
+    }
+    
+    /**
+     * Set an inline SQL command to execute. 
+     * NB: Properties are not expanded in this text.
+     */
+    public function addText($sql) {
+        $this->sqlCommand .= $sql;
+    }
+    
+    /**
+     * Adds a set of files (nested fileset attribute).
+     */
+    public function addFileset(FileSet $set) {
+        $this->filesets[] = $set;
+    }
+
+    /**
+     * Creates a filterchain
+     *
+     * @access public
+     * @return  object  The created filterchain object
+     */
+    function createFilterChain() {
+        $num = array_push($this->filterChains, new FilterChain($this->project));
+        return $this->filterChains[$num-1];
+    }
+
+    /**
+     * Add a SQL transaction to execute
+     */
+    public function createTransaction() {
+        $t = new SQLExecTransaction($this);
+        $this->transactions[] = $t;
+        return $t;
+    }
+    
+    /**
+     * Set the file encoding to use on the SQL files read in
+     *
+     * @param encoding the encoding to use on the files
+     */
+    public function setEncoding($encoding) {
+        $this->encoding = $encoding;
+    }
+    
+    /**
+     * Set the statement delimiter.
+     *
+     * <p>For example, set this to "go" and delimitertype to "ROW" for
+     * Sybase ASE or MS SQL Server.</p>
+     *
+     * @param delimiter
+     */
+    public function setDelimiter($delimiter)
+    {
+        $this->delimiter = $delimiter;
+    }
+
+    /**
+     * Set the Delimiter type for this sql task. The delimiter type takes two
+     * values - normal and row. Normal means that any occurence of the delimiter
+     * terminate the SQL command whereas with row, only a line containing just
+     * the delimiter is recognized as the end of the command.
+     *
+     * @param string $delimiterType
+     */
+    public function setDelimiterType($delimiterType)
+    {
+        $this->delimiterType = $delimiterType;
+    }
+    
+    /**
+     * Set the print flag.
+     *
+     * @param boolean $print
+     */
+    public function setPrint($print)
+    {
+        $this->print = (boolean) $print;
+    }
+        
+    /**
+     * Print headers for result sets from the 
+     * statements; optional, default true.
+     * @param boolean $showheaders
+     */
+    public function setShowheaders($showheaders) {
+        $this->showheaders = (boolean) $showheaders;
+    }
+
+    /**
+     * Set the output file; 
+     * optional, defaults to the console.
+     * @param PhingFile $output
+     */
+    public function setOutput(PhingFile $output) {
+        $this->output = $output;
+    }
+
+    /**
+     * whether output should be appended to or overwrite
+     * an existing file.  Defaults to false.
+     * @param $append
+     */
+    public function setAppend($append) {
+        $this->append = (boolean) $append;
+    }
+
+    
+    /**
+     * Action to perform when statement fails: continue, stop, or abort
+     * optional; default &quot;abort&quot;
+     */
+    public function setOnerror($action) {
+        $this->onError = $action;
+    }
+
+    /**
+     * Load the sql file and then execute it
+     * @throws BuildException
+     */
+    public function main()  {
+            
+        $savedTransaction = array();
+        for($i=0,$size=count($this->transactions); $i < $size; $i++) {
+            $savedTransaction[] = clone $this->transactions[$i];
+        }
+        
+        $savedSqlCommand = $this->sqlCommand;
+
+        $this->sqlCommand = trim($this->sqlCommand);
+
+        try {
+            if ($this->srcFile === null && $this->sqlCommand === "" 
+                && empty($this->filesets)) { 
+                if (count($this->transactions) === 0) {
+                    throw new BuildException("Source file or fileset, "
+                                             . "transactions or sql statement "
+                                             . "must be set!", $this->location);
+                }
+            }
+        
+            if ($this->srcFile !== null && !$this->srcFile->exists()) {
+                throw new BuildException("Source file does not exist!", $this->location);
+            }
+
+            // deal with the filesets
+            for ($i = 0,$size=count($this->filesets); $i < $size; $i++) {
+                $fs = $this->filesets[$i];
+                $ds = $fs->getDirectoryScanner($this->project);
+                $srcDir = $fs->getDir($this->project);
+                
+                $srcFiles = $ds->getIncludedFiles();
+                
+                // Make a transaction for each file
+                for ($j=0, $size=count($srcFiles); $j < $size; $j++) {
+                    $t = $this->createTransaction();
+                    $t->setSrc(new PhingFile($srcDir, $srcFiles[$j]));
+                }
+            }
+            
+            // Make a transaction group for the outer command
+            $t = $this->createTransaction();
+            if ($this->srcFile) $t->setSrc($this->srcFile);
+            $t->addText($this->sqlCommand);
+            $this->conn = $this->getConnection();
+
+            try {
+                
+                $this->statement = $this->conn->createStatement();
+                
+                $out = null;
+                
+                try {
+                    
+                    if ($this->output !== null) {
+                        $this->log("Opening output file " . $this->output, Project::MSG_VERBOSE);
+                        $out = new BufferedWriter(new FileWriter($this->output->getAbsolutePath(), $this->append));
+                    }
+                    
+                    // Process all transactions
+                    for ($i=0,$size=count($this->transactions); $i < $size; $i++) {
+                        $this->transactions[$i]->runTransaction($out);
+                        if (!$this->isAutocommit()) {
+                            $this->log("Commiting transaction", Project::MSG_VERBOSE);
+                            $this->conn->commit();
+                        }
+                    }
+                    if ($out) $out->close();
+                } catch (Exception $e) {
+                    if ($out) $out->close();
+                    throw $e;
+                } 
+            } catch (IOException $e) {
+                if (!$this->isAutocommit() && $this->conn !== null && $this->onError == "abort") {
+                    try {
+                        $this->conn->rollback();
+                    } catch (SQLException $ex) {}
+                }
+                throw new BuildException($e->getMessage(), $this->location);
+            } catch (SQLException $e){
+                if (!$this->isAutocommit() && $this->conn !== null && $this->onError == "abort") {
+                    try {
+                        $this->conn->rollback();
+                    } catch (SQLException $ex) {}
+                }
+                throw new BuildException($e->getMessage(), $this->location);
+            }
+            
+            $this->log($this->goodSql . " of " . $this->totalSql .
+                " SQL statements executed successfully");
+        } catch (Exception $e) {
+            $this->transactions = $savedTransaction;
+            $this->sqlCommand = $savedSqlCommand;
+            throw $e;
+        }
+        // finally {
+        $this->transactions = $savedTransaction;
+        $this->sqlCommand = $savedSqlCommand;
+        
+    }
+
+
+    /**
+     * read in lines and execute them
+     * @throws SQLException, IOException 
+     */
+    public function runStatements(Reader $reader, $out = null) {
+        $sql = "";
+        $line = "";
+
+		$buffer = '';
+
+        if ((is_array($this->filterChains)) && (!empty($this->filterChains))) {    
+            $in = FileUtils::getChainedReader(new BufferedReader($reader), $this->filterChains, $this->getProject());
+			while(-1 !== ($read = $in->read())) { // -1 indicates EOF
+				   $buffer .= $read;
+            }
+            $lines = explode("\n", $buffer);
+        } else {
+	        $in = new BufferedReader($reader);
+
+            while (($line = $in->readLine()) !== null) {
+				$lines[] = $line;
+			}
+		}
+
+        try {
+			foreach ($lines as $line) {
+                $line = trim($line);
+                $line = ProjectConfigurator::replaceProperties($this->project, $line,
+                        $this->project->getProperties());
+                
+                if (StringHelper::startsWith("//", $line) || 
+                    StringHelper::startsWith("--", $line) ||
+                    StringHelper::startsWith("#", $line)) {
+                    continue;
+                }
+                
+                if (strlen($line) > 4
+                        && strtoupper(substr($line,0, 4)) == "REM ") {
+                    continue;
+                }
+
+                $sql .= " " . $line;
+                $sql = trim($sql);
+
+                // SQL defines "--" as a comment to EOL
+                // and in Oracle it may contain a hint
+                // so we cannot just remove it, instead we must end it
+                if (strpos($line, "--") !== false) {
+                    $sql .= "\n";
+                }
+
+                if ($this->delimiterType == self::DELIM_NORMAL
+                        && StringHelper::endsWith($this->delimiter, $sql)
+                        || $this->delimiterType == self::DELIM_ROW
+                        && $line == $this->delimiter) {
+                    $this->log("SQL: " . $sql, Project::MSG_VERBOSE);
+                    $this->execSQL(StringHelper::substring($sql, 0, strlen($sql) - strlen($this->delimiter)), $out);
+                    $sql = "";
+                }
+            }
+
+            // Catch any statements not followed by ;
+            if ($sql !== "") {
+                $this->execSQL($sql, $out);
+            }
+        } catch (SQLException $e) {
+            throw new BuildException("Error running statements", $e);
+        }
+    }
+ 
+        
+    /**
+     * Exec the sql statement.
+     * @throws SQLException 
+     */
+    protected function execSQL($sql, $out = null) {
+        // Check and ignore empty statements
+        if (trim($sql) == "") {
+            return;
+        }
+
+        try {
+            $this->totalSql++;
+            if (!$this->statement->execute($sql)) {
+                $this->log($this->statement->getUpdateCount() . " rows affected", Project::MSG_VERBOSE);
+            } else {
+                if ($this->print) {
+                    $this->printResults($out);
+                }
+            }
+            
+            $this->goodSql++;
+            
+        } catch (SQLException $e) {            
+            $this->log("Failed to execute: " . $sql, Project::MSG_ERR);
+            if ($this->onError != "continue") {            
+                throw new BuildException("Failed to execute SQL", $e);
+            }
+            $this->log($e->getMessage(), Project::MSG_ERR);
+        }
+    }
+    
+    /**
+     * print any results in the statement.
+     * @throw SQLException
+     */
+    protected function printResults($out = null) {
+        
+        $rs = null;        
+        do {
+            $rs = $this->statement->getResultSet();
+            
+            if ($rs !== null) {
+            
+                $this->log("Processing new result set.", Project::MSG_VERBOSE);            
+    
+                $line = "";
+
+                $colsprinted = false;
+                
+                while ($rs->next()) {
+                    $fields = $rs->getRow();
+                    
+                    if (!$colsprinted && $this->showheaders) {
+                        $first = true;
+                        foreach($fields as $fieldName => $ignore) {
+                            if ($first) $first = false; else $line .= ",";
+                            $line .= $fieldName;
+                        }
+                        if ($out !== null) {
+                            $out->write($line);
+                            $out->newLine();
+                        } else {
+                            print($line.PHP_EOL);
+                        }
+                        $line = "";
+                        $colsprinted = true;
+                    } // if show headers
+                    
+                    $first = true;
+                    foreach($fields as $columnValue) {
+                        
+                        if ($columnValue != null) {
+                            $columnValue = trim($columnValue);
+                        }
+
+                        if ($first) {
+                            $first = false;
+                        } else {
+                            $line .= ",";
+                        }
+                        $line .= $columnValue;
+                    }
+                    
+                    if ($out !== null) {
+                        $out->write($line);
+                        $out->newLine();
+                    } else {                    
+                        print($line . PHP_EOL);
+                    }
+                    $line = "";
+                    
+                } // while rs->next()
+            }
+        } while ($this->statement->getMoreResults());
+        print(PHP_EOL);
+        if ($out !== null) $out->newLine();
+    }
+}
+
+
+/**
+ * "Inner" class that contains the definition of a new transaction element.
+ * Transactions allow several files or blocks of statements
+ * to be executed using the same JDBC connection and commit
+ * operation in between.
+ */
+class SQLExecTransaction {
+
+    private $tSrcFile = null;
+    private $tSqlCommand = "";
+    private $parent;
+    
+    function __construct($parent)
+    {
+        // Parent is required so that we can log things ...
+        $this->parent = $parent;
+    }
+    
+    public function setSrc(PhingFile $src)
+    {
+        $this->tSrcFile = $src;
+    }
+
+    public function addText($sql)
+    {
+        $this->tSqlCommand .= $sql;
+    }
+
+    /**
+     * @throws IOException, SQLException
+     */
+    public function runTransaction($out = null)
+    {
+        if (!empty($this->tSqlCommand)) {
+            $this->parent->log("Executing commands", Project::MSG_INFO);
+            $this->parent->runStatements(new StringReader($this->tSqlCommand), $out);
+        }
+
+        if ($this->tSrcFile !== null) {
+            $this->parent->log("Executing file: " . $this->tSrcFile->getAbsolutePath(),
+                Project::MSG_INFO);
+
+            $reader = new FileReader($this->tSrcFile);
+
+            $this->parent->runStatements($reader, $out);
+            $reader->close();
+        }
+    }
+}
+
+
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/creole/CreoleTask.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/creole/CreoleTask.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/creole/CreoleTask.php	(revision 19)
@@ -0,0 +1,242 @@
+<?php
+
+/*
+ *  $Id: CreoleTask.php 259 2007-10-21 01:05:43Z hans $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+require_once 'phing/Task.php';
+include_once 'phing/types/Reference.php';
+
+/**
+ * Handles Creole configuration needed by SQL type tasks.
+ *
+ * @author    Hans Lellelid <hans@xmpl.org> (Phing)
+ * @author    Nick Chalko <nick@chalko.com> (Ant)
+ * @author    Jeff Martin <jeff@custommonkey.org> (Ant)
+ * @author    Michael McCallum <gholam@xtra.co.nz> (Ant)
+ * @author    Tim Stephenson <tim.stephenson@sybase.com> (Ant)
+ * @version   $Revision: 1.13 $
+ * @package   phing.tasks.system
+ */
+abstract class CreoleTask extends Task {
+
+    /**
+     * Used for caching loaders / driver. This is to avoid
+     * getting an OutOfMemoryError when calling this task
+     * multiple times in a row.
+     * 
+     * NOT IMPLEMENTED YET
+     */
+    private static $loaderMap = array();
+
+    private $caching = true;
+
+    /**
+     * Autocommit flag. Default value is false
+     */
+    private $autocommit = false;
+    
+    /**
+     * [optional] Classpath to Creole driver to use.
+     * @param string
+     */
+    private $driver;
+    
+    /**
+     * DB url.
+     */
+    private $url;
+
+    /**
+     * User name.
+     */
+    private $userId;
+
+    /**
+     * Password
+     */
+    private $password;
+
+    /**
+     * RDBMS Product needed for this SQL.
+     **/
+    private $rdbms;
+   
+      /**
+     * Initialize CreoleTask.
+     * This method includes any necessary Creole libraries and triggers
+     * appropriate error if they cannot be found.  This is not done in header
+     * because we may want this class to be loaded w/o triggering an error.
+     */
+    function init() {
+        include_once 'creole/Creole.php';
+        if (!class_exists('Creole')) {
+            throw new Exception("Creole task depends on Creole classes being on include_path. (i.e. include of 'creole/Creole.php' failed.)");
+        }
+    }
+
+    /**
+     * Caching loaders / driver. This is to avoid
+     * getting an OutOfMemoryError when calling this task
+     * multiple times in a row; default: true
+     * @param $enable
+     */
+    public function setCaching($enable) {
+        $this->caching = $enable;
+    }
+
+    /**
+     * Sets the database connection URL; required.
+     * @param url The url to set
+     */
+    public function setUrl($url) {
+        $this->url = $url;
+    }
+
+    /**
+     * Set the Creole driver to be used.
+     *
+     * @param string $driver driver class name
+     */
+    public function setDriver($driver)
+    {
+        $this->driver = $driver;
+    }
+        
+    /**
+     * Sets the password; required.
+     * @param password The password to set
+     */
+    public function setPassword($password) {
+        $this->password = $password;
+    }
+
+    /**
+     * Auto commit flag for database connection;
+     * optional, default false.
+     * @param autocommit The autocommit to set
+     */
+    public function setAutocommit($autocommit) {
+        $this->autocommit = $autocommit;
+    }
+
+    /**
+     * Sets the version string, execute task only if 
+     * rdbms version match; optional.
+     * @param version The version to set
+     */
+    public function setVersion($version) {
+        $this->version = $version;
+    }
+       
+    protected function getLoaderMap() {
+        return self::$loaderMap;
+    }
+
+
+    /**
+     * Creates a new Connection as using the driver, url, userid and password specified.
+     * The calling method is responsible for closing the connection.
+     * @return Connection the newly created connection.
+     * @throws BuildException if the UserId/Password/Url is not set or there is no suitable driver or the driver fails to load.
+     */
+    protected function getConnection() {
+            
+        if ($this->url === null) {
+            throw new BuildException("Url attribute must be set!", $this->location);
+        }
+                
+        try {
+
+            $this->log("Connecting to " . $this->getUrl(), Project::MSG_VERBOSE);
+            $info = new Properties();
+            
+            $dsn = Creole::parseDSN($this->url);
+            
+            if (!isset($dsn["username"]) && $this->userId === null) {
+                throw new BuildException("Username must be in URL or userid attribute must be set.", $this->location);                
+            }                        
+            
+            if ($this->userId) {
+                $dsn["username"] = $this->getUserId();
+            }
+            
+            if ($this->password) {
+                $dsn["password"] = $this->getPassword();
+            }
+            
+            if ($this->driver) {
+                Creole::registerDriver($dsn['phptype'], $this->driver);
+            }
+            
+            $conn = Creole::getConnection($dsn);
+            $conn->setAutoCommit($this->autocommit);
+            return $conn;
+            
+        } catch (SQLException $e) {
+            throw new BuildException($e->getMessage(), $this->location);
+        }
+
+    }
+
+    public function isCaching($value) {
+        $this->caching = $value;
+    }
+
+    /**
+     * Gets the autocommit.
+     * @return Returns a boolean
+     */
+    public function isAutocommit() {
+        return $this->autocommit;
+    }
+
+    /**
+     * Gets the url.
+     * @return Returns a String
+     */
+    public function getUrl() {
+        return $this->url;
+    }
+
+    /**
+     * Gets the userId.
+     * @return Returns a String
+     */
+    public function getUserId() {
+        return $this->userId;
+    }
+
+    /**
+     * Set the user name for the connection; required.
+     * @param userId The userId to set
+     */
+    public function setUserid($userId) {
+        $this->userId = $userId;
+    }
+
+    /**
+     * Gets the password.
+     * @return Returns a String
+     */
+    public function getPassword() {
+        return $this->password;
+    }
+
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/dbdeploy/DbDeployTask.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/dbdeploy/DbDeployTask.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/dbdeploy/DbDeployTask.php	(revision 19)
@@ -0,0 +1,192 @@
+<?php
+/*
+ *  $Id: DbDeployTask.php 59 2006-04-28 14:49:47Z lcrouch $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+ 
+require_once 'phing/Task.php';
+require_once 'phing/tasks/ext/dbdeploy/DbmsSyntaxFactory.php';
+
+
+/**
+ *  Generate SQL script for db using dbdeploy schema version table and delta scripts
+ *
+ *  <dbdeploy url="mysql:host=localhost;dbname=test" userid="dbdeploy" password="dbdeploy" dir="db" outputfile=""> 
+ * 
+ *  @author   Luke Crouch at SourceForge (http://sourceforge.net)
+ *  @version  $Revision: 1.1 $
+ *  @package  phing.tasks.ext.dbdeploy
+ */
+
+class DbDeployTask extends Task {
+	
+	public static $TABLE_NAME = 'changelog';
+
+	protected $url;
+	protected $userid;
+	protected $password;
+	protected $dir;
+	protected $outputFile = 'dbdeploy_deploy.sql';
+	protected $undoOutputFile = 'dbdeploy_undo.sql';
+	protected $deltaSet = 'Main';
+	protected $lastChangeToApply = 999;
+	protected $dbmsSyntax = null;
+	
+    function main() {
+    	try{
+    		// get correct DbmsSyntax object
+    		$dbms = substr($this->url, 0, strpos($this->url, ':'));
+    		$dbmsSyntaxFactory = new DbmsSyntaxFactory($dbms);
+    		$this->dbmsSyntax = $dbmsSyntaxFactory->getDbmsSyntax();
+    		
+			// open file handles for output
+    		$outputFileHandle = fopen($this->outputFile, "w+");
+    		$undoOutputFileHandle = fopen($this->undoOutputFile, "w+");
+    		
+    		// figure out which revisions are in the db already
+			$this->appliedChangeNumbers = $this->getAppliedChangeNumbers();
+			$this->log('Current db revision: ' . $this->getLastChangeAppliedInDb());
+			
+			// generate sql file needed to take db to "lastChangeToApply" version
+			$doSql = $this->doDeploy();
+			$undoSql = $this->undoDeploy();
+			
+			// write the do and undo SQL to their respective files
+			fwrite($outputFileHandle, $doSql);
+			fwrite($undoOutputFileHandle, $undoSql);
+			
+    	} catch (Exception $e){
+    		throw new BuildException($e);
+    	}
+    }
+	
+    function getAppliedChangeNumbers(){
+    	if(count($this->appliedChangeNumbers) == 0){
+	        $this->log('Getting applied changed numbers from DB: ' . $this->url );
+	    	$appliedChangeNumbers = array();
+    		$dbh = new PDO($this->url, $this->userid, $this->password);
+    		$dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
+	    	$sql = "SELECT * FROM " . DbDeployTask::$TABLE_NAME . " WHERE delta_set = '$this->deltaSet' ORDER BY change_number";
+			foreach($dbh->query($sql) as $change){
+	    		$appliedChangeNumbers[] = $change['change_number'];
+	    	}
+	    	$this->appliedChangeNumbers = $appliedChangeNumbers;
+    	}
+    	return $this->appliedChangeNumbers;
+    }
+    
+    function getLastChangeAppliedInDb(){
+    	return (count($this->appliedChangeNumbers) > 0) ? max($this->appliedChangeNumbers) : 0;
+    }
+
+    function doDeploy(){
+    	$sqlToPerformDeploy = '';
+    	$lastChangeAppliedInDb = $this->getLastChangeAppliedInDb();    	
+    	$files = $this->getDeltasFilesArray();
+    	ksort($files);
+    	foreach($files as $fileChangeNumber=>$fileName){
+    		if($fileChangeNumber > $lastChangeAppliedInDb && $fileChangeNumber <= $this->lastChangeToApply){
+    			$sqlToPerformDeploy .= '--------------- Fragment begins: ' . $fileChangeNumber . ' ---------------' . "\n";
+    			$sqlToPerformDeploy .= 'INSERT INTO ' . DbDeployTask::$TABLE_NAME . ' (change_number, delta_set, start_dt, applied_by, description)'.
+					' VALUES ('. $fileChangeNumber .', \''. $this->deltaSet .'\', '. $this->dbmsSyntax->generateTimestamp() .', \'dbdeploy\', \''. $fileName .'\');' . "\n";
+				$fullFileName = $this->dir . '/' . $fileName;
+    			$fh = fopen($fullFileName, 'r');
+    			$contents = fread($fh, 	filesize($fullFileName));
+    			$deploySQLFromFile = substr($contents,0,strpos($contents, '--//@UNDO'));    			
+    			$sqlToPerformDeploy .= $deploySQLFromFile;
+    			$sqlToPerformDeploy .= 'UPDATE ' . DbDeployTask::$TABLE_NAME . ' SET complete_dt = ' . $this->dbmsSyntax->generateTimestamp() . ' WHERE change_number = ' . $fileChangeNumber . ' AND delta_set = \'' . $this->deltaSet . '\';' . "\n";
+    			$sqlToPerformDeploy .= '--------------- Fragment ends: ' . $fileChangeNumber . ' ---------------' . "\n";
+    		}
+    	}
+		return $sqlToPerformDeploy;
+    }
+    
+    function undoDeploy(){
+    	$sqlToPerformUndo = '';
+    	$lastChangeAppliedInDb = $this->getLastChangeAppliedInDb();    	
+    	$files = $this->getDeltasFilesArray();
+    	krsort($files);
+    	foreach($files as $fileChangeNumber=>$fileName){
+    		if($fileChangeNumber > $lastChangeAppliedInDb && $fileChangeNumber <= $this->lastChangeToApply){
+				$fullFileName = $this->dir . '/' . $fileName;
+    			$fh = fopen($fullFileName, 'r');
+    			$contents = fread($fh, 	filesize($fullFileName));
+    			$undoSQLFromFile = substr($contents,strpos($contents, '--//@UNDO')+9);    			
+    			$sqlToPerformUndo .= $undoSQLFromFile;
+    			$sqlToPerformUndo .= 'DELETE FROM ' . DbDeployTask::$TABLE_NAME . ' WHERE change_number = ' . $fileChangeNumber . ' AND delta_set = \'' . $this->deltaSet . '\';' . "\n";
+    			$sqlToPerformUndo .= '--------------- Fragment ends: ' . $fileChangeNumber . ' ---------------' . "\n";
+    		}
+    	}
+		return $sqlToPerformUndo;
+    }
+    
+   function getDeltasFilesArray(){
+    	$baseDir = realpath($this->dir);
+    	$dh = opendir($baseDir);
+    	$fileChangeNumberPrefix = '';
+    	while(($file = readdir($dh)) !== false){
+    		if(preg_match('[\d+]', $file, $fileChangeNumberPrefix)){
+    			$files[$fileChangeNumberPrefix[0]] = $file;
+    		}
+    	}
+    	return $files;
+    }
+    
+	function setUrl($url){
+		$this->url = $url;
+	}
+	
+	function setUserId($userid){
+		$this->userid = $userid;
+	}
+	
+	function setPassword($password){
+		$this->password = $password;
+	}
+
+	function setDir($dir){
+		$this->dir = $dir;
+	}
+
+	function setOutputFile($outputFile){
+		$this->outputFile = $outputFile;
+	}
+
+	function setUndoOutputFile($undoOutputFile){
+		$this->undoOutputFile = $undoOutputFile;
+	}
+	
+	function setLastChangeToApply($lastChangeToApply){
+		$this->lastChangeToApply = $lastChangeToApply;
+	}
+
+	function setDeltaSet($deltaSet){
+		$this->deltaSet = $deltaSet;
+	}
+	
+    /**
+     * Add a new fileset.
+     * @return FileSet
+     */
+    public function createFileSet() {
+        $this->fileset = new FileSet();
+        $this->filesets[] = $this->fileset;
+        return $this->fileset;
+    }
+}
+
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/dbdeploy/DbmsSyntax.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/dbdeploy/DbmsSyntax.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/dbdeploy/DbmsSyntax.php	(revision 19)
@@ -0,0 +1,34 @@
+<?php
+/*
+ *  $Id: DbDeployTask.php 59 2006-04-28 14:49:47Z lcrouch $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+ 
+/**
+ *  Utility class for generating necessary server-specific SQL commands
+ *
+ *  @author   Luke Crouch at SourceForge (http://sourceforge.net)
+ *  @version  $Revision: 1.1 $
+ *  @package  phing.tasks.ext.dbdeploy
+ */
+
+abstract class DbmsSyntax
+{
+	public abstract function generateTimestamp();
+}
+
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/dbdeploy/DbmsSyntaxFactory.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/dbdeploy/DbmsSyntaxFactory.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/dbdeploy/DbmsSyntaxFactory.php	(revision 19)
@@ -0,0 +1,59 @@
+<?php
+/*
+ *  $Id: DbDeployTask.php 59 2006-04-28 14:49:47Z lcrouch $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+ 
+require_once 'phing/Task.php';
+require_once 'phing/tasks/ext/dbdeploy/DbmsSyntax.php';
+
+/**
+ *  Factory for generating dbms-specific syntax-generating objects
+ *
+ *  @author   Luke Crouch at SourceForge (http://sourceforge.net)
+ *  @version  $Revision: 1.1 $
+ *  @package  phing.tasks.ext.dbdeploy
+ */
+
+class DbmsSyntaxFactory
+{
+	private $dbms;
+	
+	public function __construct($dbms)
+	{
+		$this->dbms = $dbms;
+	}
+	
+	public function getDbmsSyntax()
+	{
+		switch ($this->dbms){
+			case('sqlite') :
+				require_once 'phing/tasks/ext/dbdeploy/DbmsSyntaxSQLite.php';
+				return new DbmsSyntaxSQLite();
+			case('mysql'):
+				require_once 'phing/tasks/ext/dbdeploy/DbmsSyntaxMysql.php';
+				return new DbmsSyntaxMysql();
+			case('mssql'):
+				require_once 'phing/tasks/ext/dbdeploy/DbmsSyntaxMsSql.php';
+				return new DbmsSyntaxMsSql();
+			default:
+				throw new Exception($this->dbms . ' is not supported by dbdeploy task.');
+		}
+	}
+}
+
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/dbdeploy/DbmsSyntaxMsSql.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/dbdeploy/DbmsSyntaxMsSql.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/dbdeploy/DbmsSyntaxMsSql.php	(revision 19)
@@ -0,0 +1,37 @@
+<?php
+/*
+ *  $Id: DbDeployTask.php 59 2006-04-28 14:49:47Z lcrouch $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+ 
+/**
+ *  Utility class for generating necessary server-specific SQL commands
+ *
+ *  @author   Luke Crouch at SourceForge (http://sourceforge.net)
+ *  @version  $Revision: 1.1 $
+ *  @package  phing.tasks.ext.dbdeploy
+ */
+
+class DbmsSyntaxMsSql extends DbmsSyntax 
+{
+	public function generateTimestamp()
+	{
+		return "DATEDIFF(s, '19700101', GETDATE())";
+	}
+}
+
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/dbdeploy/DbmsSyntaxMysql.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/dbdeploy/DbmsSyntaxMysql.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/dbdeploy/DbmsSyntaxMysql.php	(revision 19)
@@ -0,0 +1,37 @@
+<?php
+/*
+ *  $Id: DbDeployTask.php 59 2006-04-28 14:49:47Z lcrouch $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+ 
+/**
+ *  Utility class for generating necessary server-specific SQL commands
+ *
+ *  @author   Luke Crouch at SourceForge (http://sourceforge.net)
+ *  @version  $Revision: 1.1 $
+ *  @package  phing.tasks.ext.dbdeploy
+ */
+
+class DbmsSyntaxMysql extends DbmsSyntax 
+{
+	public function generateTimestamp()
+	{
+		return "UNIX_TIMESTAMP()";
+	}
+}
+
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/dbdeploy/DbmsSyntaxSQLite.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/dbdeploy/DbmsSyntaxSQLite.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/dbdeploy/DbmsSyntaxSQLite.php	(revision 19)
@@ -0,0 +1,37 @@
+<?php
+/*
+ *  $Id: DbDeployTask.php 59 2006-04-28 14:49:47Z lcrouch $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+ 
+/**
+ *  Utility class for generating necessary server-specific SQL commands
+ *
+ *  @author   Luke Crouch at SourceForge (http://sourceforge.net)
+ *  @version  $Revision: 1.1 $
+ *  @package  phing.tasks.ext.dbdeploy
+ */
+
+class DbmsSyntaxSQLite extends DbmsSyntax 
+{
+	public function generateTimestamp()
+	{
+		return "strftime('%s','now')";
+	}
+}
+
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/ioncube/IoncubeComment.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/ioncube/IoncubeComment.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/ioncube/IoncubeComment.php	(revision 19)
@@ -0,0 +1,43 @@
+<?php
+/**
+ * $Id: IoncubeComment.php 325 2007-12-20 15:44:58Z hans $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+/**
+ * Wrapper for comments for ionCube tasks
+ *
+ * @author Michiel Rook <michiel.rook@gmail.com>
+ * @version $Id: IoncubeComment.php 325 2007-12-20 15:44:58Z hans $
+ * @package phing.tasks.ext.ioncube
+ * @since 2.2.0
+ */
+class IoncubeComment
+{
+	private $value = "";
+	
+	public function getValue()
+	{
+		return $this->value;
+	}
+	
+	public function addText($txt)
+	{
+		$this->value = trim($txt);
+	}
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/ioncube/IoncubeEncoderTask.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/ioncube/IoncubeEncoderTask.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/ioncube/IoncubeEncoderTask.php	(revision 19)
@@ -0,0 +1,487 @@
+<?php
+/**
+ * $Id: IoncubeEncoderTask.php 325 2007-12-20 15:44:58Z hans $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+require_once 'phing/Task.php';
+require_once 'phing/tasks/ext/ioncube/IoncubeComment.php';
+
+/**
+ * Invokes the ionCube Encoder (PHP4 or PHP5)
+ *
+ * @author Michiel Rook <michiel.rook@gmail.com>
+ * @author Andrew Eddie <andrew.eddie@jamboworks.com> 
+ * @version $Id: IoncubeEncoderTask.php 325 2007-12-20 15:44:58Z hans $
+ * @package phing.tasks.ext.ioncube
+ * @since 2.2.0
+ */
+class IoncubeEncoderTask extends Task
+{
+	private $ionSwitches = array();
+	
+	private $ionOptions = array();
+	
+	private $ionOptionsXS = array();
+
+	private $comments = array();
+	
+	private $encoderName = 'ioncube_encoder';
+	
+	private $fromDir = '';
+
+	private $ioncubePath = '/usr/local/ioncube';
+
+	private $phpVersion = '5';
+
+	private $targetOption = '';
+
+	private $toDir = '';
+
+	/**
+	 * Adds a comment to be used in encoded files
+	 */
+	function addComment(IoncubeComment $comment)
+	{
+		$this->comments[] = $comment;
+	}
+
+	/**
+	 * Sets the allowed server
+	 */
+	function setAllowedServer($value)
+	{
+		$this->ionOptionsXS['allowed-server'] = $value;
+	}
+
+	/**
+	 * Returns the allowed server setting
+	 */
+	function getAllowedServer()
+	{
+		return $this->ionOptionsXS['allowed-server'];
+	}
+
+	/**
+	 * Sets the binary option
+	 */
+	function setBinary($value)
+	{
+		$this->ionSwitches['binary'] = $value;
+	}
+
+	/**
+	 * Returns the binary option
+	 */
+	function getBinary()
+	{
+		return $this->ionSwitches['binary'];
+	}
+
+	/**
+	 * Sets files or folders to copy (separated by space)
+	 */
+	function setCopy($value)
+	{
+		$this->ionOptionsXS['copy'] = $value;
+	}
+
+	/**
+	 * Returns the copy setting
+	 */
+	function getCopy()
+	{
+		return $this->ionOptionsXS['copy'];
+	}
+
+	/**
+	 * Sets additional file patterns, files or directories to encode,
+	 * or to reverse the effect of copy (separated by space)
+	 */
+	function setEncode($value)
+	{
+		$this->ionOptionsXS['encode'] = $value;
+	}
+	
+	/**
+	 * Returns the encode setting
+	 */
+	function getEncode()
+	{
+		return $this->enionOptionsXS['encode'];
+	}
+
+	/**
+	 * Sets regexps of additional files to encrypt (separated by space)
+	 */
+	function setEncrypt($value)
+	{
+		$this->ionOptionsXS['encrypt'] = $value;
+	}
+	
+	/**
+	 * Returns regexps of additional files to encrypt (separated by space)
+	 */
+	function getEncrypt()
+	{
+		return $this->ionOptionsXS['encrypt'];
+	}
+
+	/**
+	 * Sets a period after which the files expire
+	 */
+	function setExpirein($value)
+	{
+		$this->ionOptions['expire-in'] = $value;
+	}
+	
+	/**
+	 * Returns the expireIn setting
+	 */
+	function getExpirein()
+	{
+		return $this->ionOptions['expire-in'];
+	}
+
+	/**
+	 * Sets a YYYY-MM-DD date to expire the files 
+	 */
+	function setExpireon($value)
+	{
+		$this->ionOptions['expire-on'] = $value;
+	}
+	
+	/**
+	 * Returns the expireOn setting
+	 */
+	function getExpireon()
+	{
+		return $this->ionOptions['expire-on'];
+	}
+
+	/**
+	 * Sets the source directory
+	 */
+	function setFromDir($value)
+	{
+		$this->fromDir = $value;
+	}
+
+	/**
+	 * Returns the source directory
+	 */
+	function getFromDir()
+	{
+		return $this->fromDir;
+	}
+
+	/**
+	 * Set files and directories to ignore entirely and exclude from the target directory
+	 * (separated by space).
+	 */
+	function setIgnore($value)
+	{
+		$this->ionOptionsXS['ignore'] = $value;
+	}
+
+	/**
+	 * Returns the ignore setting
+	 */
+	function getIgnore()
+	{
+		return $this->ionOptionsXS['ignore'];
+	}
+
+	/**
+	 * Sets the path to the ionCube encoder
+	 */
+	function setIoncubePath($value)
+	{
+		$this->ioncubePath = $value;
+	}
+
+	/**
+	 * Returns the path to the ionCube encoder
+	 */
+	function getIoncubePath()
+	{
+		return $this->ioncubePath;
+	}
+
+	/**
+	 * Set files and directories not to be ignored (separated by space).
+	 */
+	function setKeep($value)
+	{
+		$this->ionOptionsXS['keep'] = $value;
+	}
+
+	/**
+	 * Returns the ignore setting
+	 */
+	function getKeep()
+	{
+		return $this->ionOptionsXS['keep'];
+	}
+
+	/**
+	 * Sets the path to the license file to use
+	 */
+	function setLicensePath($value)
+	{
+		$this->ionOptions['with-license'] = $value;
+	}
+
+	/**
+	 * Returns the path to the license file to use
+	 */
+	function getLicensePath()
+	{
+		return $this->ionOptions['with-license'];
+	}
+
+	/**
+	 * Sets the no-doc-comments option
+	 */
+	function setNoDocComments($value)
+	{
+		$this->ionSwitches['no-doc-comment'] = $value;
+	}
+	
+	/**
+	 * Returns the no-doc-comments option
+	 */
+	function getNoDocComments()
+	{
+		return $this->ionSwitches['no-doc-comment'];
+	}
+	
+	/**
+	 * Sets the obfuscate option
+	 */
+	function setObfuscate($value)
+	{
+		$this->ionOptionsXS['obfuscate'] = $value;
+	}
+	
+	/**
+	 * Returns the optimize option
+	 */
+	function getObfuscate()
+	{
+		return $this->ionOptionsXS['obfuscate'];
+	}
+
+	/**
+	 * Sets the obfuscation key (required if using the obfuscate option)
+	 */
+	function setObfuscationKey($value)
+	{
+		$this->ionOptions['obfuscation-key'] = $value;
+	}
+	
+	/**
+	 * Returns the optimize option
+	 */
+	function getObfuscationKey()
+	{
+		return $this->ionOptions['obfuscation-key'];
+	}
+
+	/**
+	 * Sets the optimize option
+	 */
+	function setOptimize($value)
+	{
+		$this->ionOptions['optimize'] = $value;
+	}
+	
+	/**
+	 * Returns the optimize option
+	 */
+	function getOptimize()
+	{
+		return $this->ionOptions['optimize'];
+	}
+
+	/**
+	 * Sets the passphrase to use when encoding files
+	 */
+	function setPassPhrase($value)
+	{
+		$this->ionOptions['passphrase'] = $value;
+	}
+
+	/**
+	 * Returns the passphrase to use when encoding files
+	 */
+	function getPassPhrase()
+	{
+		return $this->ionOptions['passphrase'];
+	}
+
+	/**
+	 * Sets the version of PHP to use (defaults to 5)
+	 */
+	function setPhpVersion($value)
+	{
+		$this->phpVersion = $value;
+	}
+
+	/**
+	 * Returns the version of PHP to use (defaults to 5)
+	 */
+	function getPhpVersion()
+	{
+		return $this->phpVersion;
+	}
+	
+	/**
+	 * Sets the target directory
+	 */
+	function setToDir($value)
+	{
+		$this->toDir = $value;
+	}
+
+	/**
+	 * Returns the target directory
+	 */
+	function getToDir()
+	{
+		return $this->toDir;
+	}
+
+	/**
+	 * Sets the without-runtime-loader-support option
+	 */
+	function setWithoutRuntimeLoaderSupport($value)
+	{
+		$this->ionSwitches['without-runtime-loader-support'] = $value;
+	}
+	
+	/**
+	 * Returns the without-runtime-loader-support option
+	 */
+	function getWithoutRuntimeLoaderSupport()
+	{
+		return $this->ionSwitches['without-runtime-loader-support'];
+	}
+	
+	/**
+	 * Sets the option to use when encoding target directory already exists (defaults to none)
+	 */
+	function setTargetOption($targetOption)
+	{
+		$this->targetOption = $targetOption;
+	}
+
+	/**
+	 * Returns he option to use when encoding target directory already exists (defaults to none)
+	 */
+	function getTargetOption()
+	{
+		return $this->targetOption;
+	}
+	
+	/**
+	 * The main entry point
+	 *
+	 * @throws BuildException
+	 */
+	function main()
+	{
+		$arguments = $this->constructArguments();
+		
+		$encoder = new PhingFile($this->ioncubePath, $this->encoderName . ($this->phpVersion == 5 ? '5' : ''));
+		
+		$this->log("Running ionCube Encoder...");
+		
+		exec($encoder->__toString() . ' ' . $arguments . " 2>&1", $output, $return);
+		
+        if ($return != 0)
+        {
+			throw new BuildException("Could not execute ionCube Encoder: " . implode(' ', $output));
+        }       
+	}
+
+	/**
+	 * Constructs an argument string for the ionCube encoder
+	 */
+	private function constructArguments()
+	{
+		$arguments = '';
+		
+		foreach ($this->ionSwitches as $name => $value)
+		{
+			if ($value)
+			{
+				$arguments.= "--$name ";
+			}
+		}
+
+		foreach ($this->ionOptions as $name => $value)
+		{
+			$arguments.= "--$name '$value' ";
+		}
+
+		foreach ($this->ionOptionsXS as $name => $value)
+		{
+			foreach (explode(' ', $value) as $arg)
+			{
+				$arguments.= "--$name '$arg' ";
+			}
+		}
+
+		foreach ($this->comments as $comment)
+		{
+			$arguments.= "--add-comment '" . $comment->getValue() . "' ";
+		}
+		
+		if (!empty($this->targetOption))
+		{
+			switch ($this->targetOption)
+			{
+				case "replace":
+				case "merge":
+				case "update":
+				case "rename":
+				{
+					$arguments.= "--" . $this->targetOption . "-target ";
+				} break;
+				
+				default:
+				{
+					throw new BuildException("Unknown target option '" . $this->targetOption . "'");
+				} break;
+			}
+		}
+		
+		if ($this->fromDir != '')
+		{
+			$arguments .= $this->fromDir . ' ';
+		}
+
+		if ($this->toDir != '')
+		{
+			$arguments .= "-o " . $this->toDir . ' ';
+		}
+		
+		return $arguments;
+	}
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/ioncube/IoncubeLicenseTask.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/ioncube/IoncubeLicenseTask.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/ioncube/IoncubeLicenseTask.php	(revision 19)
@@ -0,0 +1,143 @@
+<?php
+/**
+ * $Id: IoncubeLicenseTask.php 325 2007-12-20 15:44:58Z hans $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+require_once 'phing/Task.php';
+require_once 'phing/tasks/ext/ioncube/IoncubeComment.php';
+
+/**
+ * Invokes the ionCube "make_license" program
+ *
+ * @author Michiel Rook <michiel.rook@gmail.com>
+ * @version $Id: IoncubeLicenseTask.php 325 2007-12-20 15:44:58Z hans $
+ * @package phing.tasks.ext.ioncube
+ * @since 2.2.0
+ */
+class IoncubeLicenseTask extends Task
+{
+	private $ioncubePath = "/usr/local/ioncube";
+	
+	private $licensePath = "";
+	private $passPhrase = "";
+	
+	private $comments = array();
+
+	/**
+	 * Sets the path to the ionCube encoder
+	 */
+	function setIoncubePath($ioncubePath)
+	{
+		$this->ioncubePath = $ioncubePath;
+	}
+
+	/**
+	 * Returns the path to the ionCube encoder
+	 */
+	function getIoncubePath()
+	{
+		return $this->ioncubePath;
+	}
+
+	/**
+	 * Sets the path to the license file to use
+	 */
+	function setLicensePath($licensePath)
+	{
+		$this->licensePath = $licensePath;
+	}
+
+	/**
+	 * Returns the path to the license file to use
+	 */
+	function getLicensePath()
+	{
+		return $this->licensePath;
+	}
+
+	/**
+	 * Sets the passphrase to use when encoding files
+	 */
+	function setPassPhrase($passPhrase)
+	{
+		$this->passPhrase = $passPhrase;
+	}
+
+	/**
+	 * Returns the passphrase to use when encoding files
+	 */
+	function getPassPhrase()
+	{
+		return $this->passPhrase;
+	}
+
+	/**
+	 * Adds a comment to be used in encoded files
+	 */
+	function addComment(IoncubeComment $comment)
+	{
+		$this->comments[] = $comment;
+	}
+
+	/**
+	 * The main entry point
+	 *
+	 * @throws BuildException
+	 */
+	function main()
+	{
+		$arguments = $this->constructArguments();
+		
+		$makelicense = new PhingFile($this->ioncubePath, 'make_license');
+		
+		$this->log("Running ionCube make_license...");
+		
+		exec($makelicense->__toString() . " " . $arguments . " 2>&1", $output, $return);
+		
+        if ($return != 0)
+        {
+			throw new BuildException("Could not execute ionCube make_license: " . implode(' ', $output));
+        }       
+	}
+
+	/**
+	 * Constructs an argument string for the ionCube make_license
+	 */
+	private function constructArguments()
+	{
+		$arguments = "";
+		
+		if (!empty($this->passPhrase))
+		{
+			$arguments.= "--passphrase '" . $this->passPhrase . "' ";
+		}
+		
+		foreach ($this->comments as $comment)
+		{
+			$arguments.= "--header-line '" . $comment->getValue() . "' ";
+		}
+		
+		if (!empty($this->licensePath))
+		{
+			$arguments.= "--o '" . $this->licensePath . "' ";
+		}
+
+		return $arguments;
+	}
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/pdo/PDOResultFormatter.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/pdo/PDOResultFormatter.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/pdo/PDOResultFormatter.php	(revision 19)
@@ -0,0 +1,84 @@
+<?php
+/**
+ * $Id: FormatterElement.php 148 2007-02-13 11:15:53Z mrook $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+require_once 'phing/system/io/PhingFile.php';
+
+/**
+ * Abstract 
+ *
+ * @author Hans Lellelid <hans@xmpl.org>
+ * @package phing.tasks.ext.pdo
+ * @since 2.3.0
+ */
+abstract class PDOResultFormatter
+{
+	/**
+	 * Output writer.
+	 *
+	 * @var Writer
+	 */
+	protected $out;
+
+	/**
+	 * Sets the output writer.
+	 *
+	 * @param Writer $out
+	 */
+	public function setOutput(Writer $out) {
+		$this->out = $out;
+	}
+
+	/**
+	 * Gets the output writer.
+	 *
+	 * @return Writer
+	 */
+	public function getOutput() {
+		return $this->out;
+	}
+
+	/**
+	 * Gets the preferred output filename for this formatter.
+	 * @return string
+	 */
+	abstract public function getPreferredOutfile();
+
+	/**
+	 * Perform any initialization.
+	 */
+	public function initialize() {
+
+	}
+
+	/**
+	 * Processes a specific row from PDO result set.
+	 *
+	 * @param array $row Row of PDO result set.
+	 */
+	abstract public function processRow($row);
+
+	/**
+	 * Perform any final tasks and Close the writer.
+	 */
+	public function close() {
+		$this->out->close();
+	}
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/pdo/PDOSQLExecFormatterElement.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/pdo/PDOSQLExecFormatterElement.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/pdo/PDOSQLExecFormatterElement.php	(revision 19)
@@ -0,0 +1,312 @@
+<?php
+/**
+ * $Id: FormatterElement.php 148 2007-02-13 11:15:53Z mrook $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+require_once 'phing/system/io/PhingFile.php';
+require_once 'phing/tasks/ext/pdo/PlainPDOResultFormatter.php';
+require_once 'phing/tasks/ext/pdo/XMLPDOResultFormatter.php';
+
+/**
+ * A class to represent the nested <formatter> element for PDO SQL results.
+ * 
+ * This class is inspired by the similarly-named class in the PHPUnit tasks.
+ *
+ * @author Hans Lellelid <hans@xmpl.org>
+ * @package phing.tasks.ext.pdo
+ * @since 2.3.0
+ */
+class PDOSQLExecFormatterElement
+{
+	/**
+	 * @var PDOResultFormatter
+	 */
+	private $formatter;
+
+	/**
+	 * The type of the formatter (used for built-in formatter classes).
+	 * @var string
+	 */
+	private $type = "";
+
+	/**
+	 * Whether to use file (or write output to phing log).
+	 * @var boolean
+	 */
+	private $useFile = true;
+
+	/**
+	 * Output file for formatter.
+	 * @var PhingFile
+	 */
+	private $outfile;
+
+    /**
+     * Print header columns.
+     * @var boolean
+     */
+    private $showheaders = true;
+
+    /**
+     * Whether to format XML output.
+     * @var boolean
+     */
+    private $formatoutput = true;
+
+    /**
+     * Encoding for XML output.
+     * @var string
+     */
+    private $encoding;
+
+    /**
+	 * Column delimiter.
+	 * Defaults to ','
+	 * @var string
+	 */
+    private $coldelimiter = ",";
+
+	/**
+	 * Row delimiter.
+	 * Defaults to PHP_EOL.
+	 * @var string 
+	 */
+	private $rowdelimiter = PHP_EOL;
+
+    /**
+     * Append to an existing file or overwrite it?
+     * @var boolean
+     */
+    private $append = false;
+
+	/**
+	 * Parameters for a custom formatter.
+	 * @var array Parameter[]
+	 */
+	private $formatterParams = array();
+
+	/**
+	 * @var PDOSQLExecTask 
+	 */
+	private $parentTask;
+
+	/**
+	 * Construct a new PDOSQLExecFormatterElement with parent task.
+	 * @param  PDOSQLExecTask $parentTask
+	 */
+	public function __construct(PDOSQLExecTask $parentTask)
+	{
+		$this->parentTask = $parentTask;
+	}
+
+    /**
+     * Supports nested <param> element (for custom formatter classes).
+     * @return Parameter
+     */
+    public function createParam() {
+    	$num = array_push($this->parameters, new Parameter());
+    	return $this->parameters[$num-1];
+    }
+
+    /**
+     * Gets a configured output writer.
+     * @return Writer
+     */
+    private function getOutputWriter()
+    {
+    	if ($this->useFile) {
+    		$of = $this->getOutfile();
+    		if (!$of) {
+    			$of = new PhingFile($this->formatter->getPreferredOutfile());
+    		}
+    		return new FileWriter($of, $this->append);
+    	} else {
+    		return $this->getDefaultOutput();
+    	}
+    }
+
+    /**
+     * Configures wrapped formatter class with any attributes on this element.
+     */
+    public function prepare() {
+
+    	if (!$this->formatter) {
+    		throw new BuildException("No formatter specified (use type or classname attribute)", $this->getLocation());
+    	}
+
+    	$out = $this->getOutputWriter();
+
+    	print "Setting output writer to: " . get_class($out) . "\n";
+    	$this->formatter->setOutput($out);
+
+    	if ($this->formatter instanceof PlainPDOResultFormatter) {
+    		// set any options that apply to the plain formatter
+    		$this->formatter->setShowheaders($this->showheaders);
+    		$this->formatter->setRowdelim($this->rowdelimiter);
+    		$this->formatter->setColdelim($this->coldelimiter);
+    	} elseif ($this->formatter instanceof XMLPDOResultFormatter) {
+    		// set any options that apply to the xml formatter
+    		$this->formatter->setEncoding($this->encoding);
+    		$this->formatter->setFormatOutput($this->formatoutput);
+    	}
+
+    	foreach($this->formatterParams as $param) {
+    		$param = new Parameter();
+    		$method = 'set' . $param->getName();
+    		if (!method_exists($this->formatter, $param->getName())) {
+    			throw new BuildException("Formatter " . get_class($this->formatter) . " does not have a $method method.", $this->getLocation());
+    		}
+    		call_user_func(array($this->formatter, $method), $param->getValue());
+    	}
+    }
+
+    /**
+     * Sets the formatter type.
+     * @param string $type
+     */
+    function setType($type) {
+    	$this->type = $type;
+    	if ($this->type == "xml") {
+    		$this->formatter = new XMLPDOResultFormatter();
+    	} elseif ($this->type == "plain") {
+    		$this->formatter = new PlainPDOResultFormatter();
+    	} else {
+    		throw new BuildException("Formatter '" . $this->type . "' not implemented");
+    	}
+    }
+
+	/**
+	 * Set classname for a custom formatter (must extend PDOResultFormatter).
+	 * @param string $className
+	 */
+	function setClassName($className) {
+		$classNameNoDot = Phing::import($className);
+		$this->formatter = new $classNameNoDot();
+	}
+
+	/**
+	 * Set whether to write formatter results to file.
+	 * @param boolean $useFile
+	 */
+	function setUseFile($useFile) {
+		$this->useFile = (boolean) $useFile;
+	}
+
+	/**
+	 * Return whether to write formatter results to file.
+	 * @return boolean
+	 */
+	function getUseFile() {
+		return $this->useFile;
+	}
+
+	/**
+	 * Sets the output file for the formatter results.
+	 * @param PhingFile $outFile
+	 */
+	function setOutfile(PhingFile $outfile) {
+		$this->outfile = $outfile;
+	}
+
+	/**
+	 * Get the output file.
+	 * @return PhingFile
+	 */
+	function getOutfile() {
+		return $this->outfile;
+		/*
+		} else {
+			return new PhingFile($this->formatter->getPreferredOutfile());
+		}*/
+	}
+	
+	/**
+     * whether output should be appended to or overwrite
+     * an existing file.  Defaults to false.
+     * @param boolean $append
+     */
+    public function setAppend($append) {
+    	$this->append = (boolean) $append;
+    }
+    
+    /**
+     * Whether output should be appended to file.
+     * @return boolean
+     */
+    public function getAppend() {
+    	return $this->append;
+    }
+    
+	/**
+     * Print headers for result sets from the 
+     * statements; optional, default true.
+     * @param boolean $showheaders
+     */
+    public function setShowheaders($showheaders) {
+    	$this->showheaders = (boolean) $showheaders;
+    }
+    
+	/**
+	 * Sets the column delimiter.
+	 * @param string $v
+	 */
+	public function setColdelim($v) {
+		$this->coldelimiter = $v;
+	}
+	
+	/**
+	 * Sets the row delimiter.
+	 * @param string $v
+	 */
+	public function setRowdelim($v) {
+		$this->rowdelimiter = $v;
+	}
+	
+	/**
+	 * Set the DOM document encoding.
+	 * @param string $v
+	 */
+	public function setEncoding($v) {
+		$this->encoding = $v;
+	}
+	
+	/**
+	 * @param boolean $v
+	 */
+	public function setFormatOutput($v) {
+		$this->formatOutput = (boolean) $v;
+	}
+    
+	/**
+     * Gets a default output writer for this task.
+     * @return Writer
+     */
+    private function getDefaultOutput()
+    {
+    	return new LogWriter($this->parentTask);
+    }
+    
+	/**
+	 * Gets the formatter that has been configured based on this element.
+	 * @return PDOResultFormatter
+	 */
+	function getFormatter() {
+		return $this->formatter;
+	}
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/pdo/PDOSQLExecTask.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/pdo/PDOSQLExecTask.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/pdo/PDOSQLExecTask.php	(revision 19)
@@ -0,0 +1,610 @@
+<?php
+/*
+ *  $Id: CreoleSQLExecTask.php 83 2006-07-07 18:17:00Z mrook $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+require_once 'phing/tasks/ext/pdo/PDOTask.php';
+include_once 'phing/system/io/StringReader.php';
+include_once 'phing/tasks/ext/pdo/PDOSQLExecFormatterElement.php';
+
+/**
+ * Executes a series of SQL statements on a database using PDO.
+ *
+ * <p>Statements can
+ * either be read in from a text file using the <i>src</i> attribute or from 
+ * between the enclosing SQL tags.</p>
+ * 
+ * <p>Multiple statements can be provided, separated by semicolons (or the 
+ * defined <i>delimiter</i>). Individual lines within the statements can be 
+ * commented using either --, // or REM at the start of the line.</p>
+ * 
+ * <p>The <i>autocommit</i> attribute specifies whether auto-commit should be 
+ * turned on or off whilst executing the statements. If auto-commit is turned 
+ * on each statement will be executed and committed. If it is turned off the 
+ * statements will all be executed as one transaction.</p>
+ * 
+ * <p>The <i>onerror</i> attribute specifies how to proceed when an error occurs 
+ * during the execution of one of the statements. 
+ * The possible values are: <b>continue</b> execution, only show the error;
+ * <b>stop</b> execution and commit transaction;
+ * and <b>abort</b> execution and transaction and fail task.</p>
+ *
+ * @author    Hans Lellelid <hans@xmpl.org> (Phing)
+ * @author    Jeff Martin <jeff@custommonkey.org> (Ant)
+ * @author    Michael McCallum <gholam@xtra.co.nz> (Ant)
+ * @author    Tim Stephenson <tim.stephenson@sybase.com> (Ant)
+ * @package   phing.tasks.ext
+ * @version   $Revision: 1.21 $
+ */
+class PDOSQLExecTask extends PDOTask {
+
+	/**
+	 * Count of how many statements were executed successfully.
+	 * @var int
+	 */
+	private $goodSql = 0;
+
+	/**
+	 * Count of total number of SQL statements.
+	 * @var int
+	 */
+	private $totalSql = 0;
+
+	const DELIM_ROW = "row";
+	const DELIM_NORMAL = "normal";
+
+    /**
+     * Database connection
+     * @var PDO
+     */
+    private $conn = null;
+
+    /**
+     * Files to load
+     * @var array FileSet[]
+     */
+    private $filesets = array();
+
+    /**
+     * Formatter elements.
+     * @var array PDOSQLExecFormatterElement[]
+     */
+    private $formatters = array();
+
+    /**
+     * SQL statement
+     * @var PDOStatement
+     */
+    private $statement;
+
+    /**
+     * SQL input file
+     * @var PhingFile
+     */
+    private $srcFile;
+
+    /**
+     * SQL input command
+     * @var string
+     */
+    private $sqlCommand = "";
+
+    /**
+     * SQL transactions to perform
+     */
+    private $transactions = array();
+
+    /**
+     * SQL Statement delimiter (for parsing files)
+     * @var string
+     */
+    private $delimiter = ";";
+
+    /**
+     * The delimiter type indicating whether the delimiter will
+     * only be recognized on a line by itself
+     */
+    private $delimiterType = "normal"; // can't use constant just defined
+
+    /**
+     * Action to perform if an error is found
+     **/
+    private $onError = "abort";
+
+    /**
+     * Encoding to use when reading SQL statements from a file
+     */
+    private $encoding = null;
+
+    /**
+     * Fetch mode for PDO select queries.
+     * @var int
+     */
+    private $fetchMode;
+
+    /**
+     * Set the name of the SQL file to be run.
+     * Required unless statements are enclosed in the build file
+     */
+    public function setSrc(PhingFile $srcFile) {
+    	$this->srcFile = $srcFile;
+    }
+
+    /**
+     * Set an inline SQL command to execute. 
+     * NB: Properties are not expanded in this text.
+     */
+    public function addText($sql) {
+    	$this->sqlCommand .= $sql;
+    }
+
+    /**
+     * Adds a set of files (nested fileset attribute).
+     */
+    public function addFileset(FileSet $set) {
+    	$this->filesets[] = $set;
+    }
+
+    /**
+     * Creates a new PDOSQLExecFormatterElement for <formatter> element.
+     * @return PDOSQLExecFormatterElement
+     */
+    public function createFormatter()
+    {
+    	$fe = new PDOSQLExecFormatterElement($this);
+    	$this->formatters[] = $fe;
+    	return $fe;
+    }
+
+    /**
+     * Add a SQL transaction to execute
+     */
+    public function createTransaction() {
+    	$t = new PDOSQLExecTransaction($this);
+    	$this->transactions[] = $t;
+    	return $t;
+    }
+
+    /**
+     * Set the file encoding to use on the SQL files read in
+     *
+     * @param encoding the encoding to use on the files
+     */
+    public function setEncoding($encoding) {
+    	$this->encoding = $encoding;
+    }
+
+    /**
+     * Set the statement delimiter.
+     *
+     * <p>For example, set this to "go" and delimitertype to "ROW" for
+     * Sybase ASE or MS SQL Server.</p>
+     *
+     * @param delimiter
+     */
+    public function setDelimiter($delimiter)
+    {
+    	$this->delimiter = $delimiter;
+    }
+
+    /**
+     * Set the Delimiter type for this sql task. The delimiter type takes two
+     * values - normal and row. Normal means that any occurence of the delimiter
+     * terminate the SQL command whereas with row, only a line containing just
+     * the delimiter is recognized as the end of the command.
+     *
+     * @param string $delimiterType
+     */
+    public function setDelimiterType($delimiterType)
+    {
+    	$this->delimiterType = $delimiterType;
+    }
+
+    /**
+     * Action to perform when statement fails: continue, stop, or abort
+     * optional; default &quot;abort&quot;
+     */
+    public function setOnerror($action) {
+    	$this->onError = $action;
+    }
+
+    /**
+     * Sets the fetch mode to use for the PDO resultset.
+     * @param mixed $mode The PDO fetchmode integer or constant name.
+     */
+    public function setFetchmode($mode) {
+    	if (is_numeric($mode)) {
+    		$this->fetchMode = (int) $mode;
+    	} else {
+    		if (defined($mode)) {
+    			$this->fetchMode = constant($mode);
+    		} else {
+    			throw new BuildException("Invalid PDO fetch mode specified: " . $mode, $this->getLocation());
+    		}
+    	}
+    }
+
+    /**
+     * Gets a default output writer for this task.
+     * @return Writer
+     */
+    private function getDefaultOutput()
+    {
+    	return new LogWriter($this);
+    }
+
+    /**
+     * Load the sql file and then execute it
+     * @throws BuildException
+     */
+    public function main()  {
+
+    	// Set a default fetchmode if none was specified
+    	// (We're doing that here to prevent errors loading the class is PDO is not available.)
+    	if ($this->fetchMode === null) {
+    		$this->fetchMode = PDO::FETCH_BOTH;
+    	}
+
+    	// Initialize the formatters here.  This ensures that any parameters passed to the formatter
+    	// element get passed along to the actual formatter object
+    	foreach($this->formatters as $fe) {
+    		$fe->prepare();
+    	}
+
+    	$savedTransaction = array();
+    	for($i=0,$size=count($this->transactions); $i < $size; $i++) {
+    		$savedTransaction[] = clone $this->transactions[$i];
+    	}
+
+    	$savedSqlCommand = $this->sqlCommand;
+
+    	$this->sqlCommand = trim($this->sqlCommand);
+
+    	try {
+    		if ($this->srcFile === null && $this->sqlCommand === ""
+    		&& empty($this->filesets)) {
+    			if (count($this->transactions) === 0) {
+    				throw new BuildException("Source file or fileset, "
+    				. "transactions or sql statement "
+    				. "must be set!", $this->location);
+    			}
+    		}
+
+    		if ($this->srcFile !== null && !$this->srcFile->exists()) {
+    			throw new BuildException("Source file does not exist!", $this->location);
+    		}
+
+    		// deal with the filesets
+    		foreach($this->filesets as $fs) {
+    			$ds = $fs->getDirectoryScanner($this->project);
+    			$srcDir = $fs->getDir($this->project);
+    			$srcFiles = $ds->getIncludedFiles();
+    			// Make a transaction for each file
+    			foreach($srcFiles as $srcFile) {
+    				$t = $this->createTransaction();
+    				$t->setSrc(new PhingFile($srcDir, $srcFile));
+    			}
+    		}
+
+    		// Make a transaction group for the outer command
+    		$t = $this->createTransaction();
+    		if ($this->srcFile) $t->setSrc($this->srcFile);
+    		$t->addText($this->sqlCommand);
+    		$this->conn = $this->getConnection();
+
+    		try {
+
+    			$this->statement = null;
+
+    			// Initialize the formatters.
+    			$this->initFormatters();
+
+    			try {
+
+    				// Process all transactions
+    				for ($i=0,$size=count($this->transactions); $i < $size; $i++) {
+    					if (!$this->isAutocommit()) {
+    						$this->log("Beginning transaction", Project::MSG_VERBOSE);
+    						$this->conn->beginTransaction();
+    					}
+    					$this->transactions[$i]->runTransaction();
+    					if (!$this->isAutocommit()) {
+    						$this->log("Commiting transaction", Project::MSG_VERBOSE);
+    						$this->conn->commit();
+    					}
+    				}
+    			} catch (Exception $e) {
+    				throw $e;
+    			}
+    		} catch (IOException $e) {
+    			if (!$this->isAutocommit() && $this->conn !== null && $this->onError == "abort") {
+    				try {
+    					$this->conn->rollback();
+    				} catch (PDOException $ex) {}
+    			}
+    			throw new BuildException($e->getMessage(), $this->location);
+    		} catch (PDOException $e){
+    			if (!$this->isAutocommit() && $this->conn !== null && $this->onError == "abort") {
+    				try {
+    					$this->conn->rollback();
+    				} catch (PDOException $ex) {}
+    			}
+    			throw new BuildException($e->getMessage(), $this->location);
+    		}
+    			
+    		// Close the formatters.
+    		$this->closeFormatters();
+
+    		$this->log($this->goodSql . " of " . $this->totalSql .
+                " SQL statements executed successfully");
+
+    	} catch (Exception $e) {
+    		$this->transactions = $savedTransaction;
+    		$this->sqlCommand = $savedSqlCommand;
+    		throw $e;
+    	}
+    	// finally {
+    	$this->transactions = $savedTransaction;
+    	$this->sqlCommand = $savedSqlCommand;
+
+    }
+
+
+    /**
+     * read in lines and execute them
+     * @throws PDOException, IOException 
+     */
+    public function runStatements(Reader $reader) {
+    	$sql = "";
+		$line = "";
+		$sqlBacklog = "";
+		$hasQuery = false;
+
+		$in = new BufferedReader($reader);
+
+		try {
+			while (($line = $in->readLine()) !== null) {
+				$line = trim($line);
+				$line = ProjectConfigurator::replaceProperties($this->project, $line,
+						$this->project->getProperties());
+
+				if (StringHelper::startsWith("//", $line) ||
+					StringHelper::startsWith("--", $line) ||
+					StringHelper::startsWith("#", $line)) {
+					continue;
+				}
+
+				if (strlen($line) > 4
+						&& strtoupper(substr($line,0, 4)) == "REM ") {
+					continue;
+				}
+
+				if ($sqlBacklog !== "") {
+					$sql = $sqlBacklog;
+					$sqlBacklog = "";
+				}
+
+				$sql .= " " . $line . "\n";
+
+				// SQL defines "--" as a comment to EOL
+				// and in Oracle it may contain a hint
+				// so we cannot just remove it, instead we must end it
+				if (strpos($line, "--") !== false) {
+					$sql .= "\n";
+				}
+
+				// DELIM_ROW doesn't need this (as far as i can tell)
+				if ($this->delimiterType == self::DELIM_NORMAL) {
+
+					$reg = "#((?:\"(?:\\\\.|[^\"])*\"?)+|'(?:\\\\.|[^'])*'?|" . preg_quote($this->delimiter) . ")#";
+
+					$sqlParts = preg_split($reg, $sql, 0, PREG_SPLIT_DELIM_CAPTURE);
+					$sqlBacklog = "";
+					foreach ($sqlParts as $sqlPart) {
+						// we always want to append, even if it's a delim (which will be stripped off later)
+						$sqlBacklog .= $sqlPart;
+
+						// we found a single (not enclosed by ' or ") delimiter, so we can use all stuff before the delim as the actual query
+						if ($sqlPart === $this->delimiter) {
+							$sql = $sqlBacklog;
+							$sqlBacklog = "";
+							$hasQuery = true;
+						}
+					}
+				}
+
+				if ($hasQuery || ($this->delimiterType == self::DELIM_ROW && $line == $this->delimiter)) {
+					// this assumes there is always a delimter on the end of the SQL statement.
+					$sql = StringHelper::substring($sql, 0, strlen($sql) - 1 - strlen($this->delimiter));
+					$this->log("SQL: " . $sql, Project::MSG_VERBOSE);
+					$this->execSQL($sql);
+					$sql = "";
+					$hasQuery = false;
+				}
+			}
+
+			// Catch any statements not followed by ;
+			if ($sql !== "") {
+				$this->execSQL($sql);
+			}
+		} catch (PDOException $e) {
+			throw $e;
+		}
+    }
+
+    /**
+     * Whether the passed-in SQL statement is a SELECT statement.
+     * This does a pretty simple match, checking to see if statement starts with
+     * 'select' (but not 'select into').
+     * 
+     * @param string $sql
+     * @return boolean Whether specified SQL looks like a SELECT query.
+     */
+    protected function isSelectSql($sql)
+    {
+    	$sql = trim($sql);
+    	return (stripos($sql, 'select') === 0 && stripos($sql, 'select into ') !== 0);
+    }
+
+    /**
+     * Exec the sql statement.
+     * @throws PDOException 
+     */
+    protected function execSQL($sql) {
+
+    	// Check and ignore empty statements
+    	if (trim($sql) == "") {
+    		return;
+    	}
+
+    	try {
+    		$this->totalSql++;
+
+    		$this->statement = $this->conn->prepare($sql);
+    		$this->statement->execute();
+    		$this->log($this->statement->rowCount() . " rows affected", Project::MSG_VERBOSE);
+
+    		$this->processResults();
+
+    		$this->statement->closeCursor();
+    		$this->statement = null;
+
+    		$this->goodSql++;
+
+    	} catch (PDOException $e) {
+    		$this->log("Failed to execute: " . $sql, Project::MSG_ERR);
+    		if ($this->onError != "continue") {
+    			throw new BuildException("Failed to execute SQL", $e);
+    		}
+    		$this->log($e->getMessage(), Project::MSG_ERR);
+    	}
+    }
+
+    /**
+     * Returns configured PDOResultFormatter objects (which were created from PDOSQLExecFormatterElement objects).
+     * @return array PDOResultFormatter[]
+     */
+    protected function getConfiguredFormatters()
+    {
+    	$formatters = array();
+    	foreach ($this->formatters as $fe) {
+    		$formatters[] = $fe->getFormatter();
+    	}
+    	return $formatters;
+    }
+
+    /**
+     * Initialize the formatters.
+     */
+    protected function initFormatters() {
+    	$formatters = $this->getConfiguredFormatters();
+    	foreach ($formatters as $formatter) {
+    		$formatter->initialize();
+    	}
+
+    }
+
+    /**
+     * Run cleanup and close formatters.
+     */
+    protected function closeFormatters() {
+    	$formatters = $this->getConfiguredFormatters();
+    	foreach ($formatters as $formatter) {
+    		$formatter->close();
+    	}
+    }
+
+    /**
+     * Passes results from query to any formatters.
+     * @throw PDOException
+     */
+    protected function processResults() {
+
+    	try {
+
+    		$this->log("Processing new result set.", Project::MSG_VERBOSE);
+
+    		$formatters = $this->getConfiguredFormatters();
+
+	    	while ($row = $this->statement->fetch($this->fetchMode)) {
+	    		foreach ($formatters as $formatter) {
+	    			$formatter->processRow($row);
+	    		}
+	    	}
+
+    	} catch (Exception $x) {
+    		$this->log("Error processing reults: " . $x->getMessage(), Project::MSG_ERR);
+    		foreach ($formatters as $formatter) {
+	    		$formatter->close();
+	    	}
+    		throw $x;
+    	}
+
+    }
+}
+
+/**
+ * "Inner" class that contains the definition of a new transaction element.
+ * Transactions allow several files or blocks of statements
+ * to be executed using the same JDBC connection and commit
+ * operation in between.
+ */
+class PDOSQLExecTransaction {
+
+	private $tSrcFile = null;
+	private $tSqlCommand = "";
+	private $parent;
+
+	function __construct($parent)
+	{
+		// Parent is required so that we can log things ...
+		$this->parent = $parent;
+	}
+
+	public function setSrc(PhingFile $src)
+	{
+		$this->tSrcFile = $src;
+	}
+
+	public function addText($sql)
+	{
+		$this->tSqlCommand .= $sql;
+	}
+
+    /**
+     * @throws IOException, PDOException
+     */
+    public function runTransaction()
+    {
+    	if (!empty($this->tSqlCommand)) {
+    		$this->parent->log("Executing commands", Project::MSG_INFO);
+    		$this->parent->runStatements(new StringReader($this->tSqlCommand));
+    	}
+
+    	if ($this->tSrcFile !== null) {
+    		$this->parent->log("Executing file: " . $this->tSrcFile->getAbsolutePath(),
+    		Project::MSG_INFO);
+    		$reader = new FileReader($this->tSrcFile);
+    		$this->parent->runStatements($reader);
+    		$reader->close();
+    	}
+    }
+}
+
+
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/pdo/PDOTask.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/pdo/PDOTask.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/pdo/PDOTask.php	(revision 19)
@@ -0,0 +1,217 @@
+<?php
+
+/*
+ *  $Id: CreoleTask.php 59 2006-04-28 14:49:47Z mrook $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+require_once 'phing/Task.php';
+include_once 'phing/types/Reference.php';
+
+/**
+ * Handles PDO configuration needed by SQL type tasks.
+ *
+ * @author    Hans Lellelid <hans@xmpl.org> (Phing)
+ * @author    Nick Chalko <nick@chalko.com> (Ant)
+ * @author    Jeff Martin <jeff@custommonkey.org> (Ant)
+ * @author    Michael McCallum <gholam@xtra.co.nz> (Ant)
+ * @author    Tim Stephenson <tim.stephenson@sybase.com> (Ant)
+ * @version   $Revision: 1.13 $
+ * @package   phing.tasks.system
+ */
+abstract class PDOTask extends Task {
+
+    private $caching = true;
+
+    /**
+     * Autocommit flag. Default value is false
+     */
+    private $autocommit = false;
+    
+    /**
+     * DB url.
+     */
+    private $url;
+
+    /**
+     * User name.
+     */
+    private $userId;
+
+    /**
+     * Password
+     */
+    private $password;
+
+    /**
+     * RDBMS Product needed for this SQL.
+     **/
+    private $rdbms;
+   
+      /**
+     * Initialize CreoleTask.
+     * This method includes any necessary Creole libraries and triggers
+     * appropriate error if they cannot be found.  This is not done in header
+     * because we may want this class to be loaded w/o triggering an error.
+     */
+    function init() {
+        if (!class_exists('PDO')) {
+            throw new Exception("PDOTask depends on PDO feature being included in PHP.");
+        }
+    }
+
+    /**
+     * Caching loaders / driver. This is to avoid
+     * getting an OutOfMemoryError when calling this task
+     * multiple times in a row; default: true
+     * @param $enable
+     */
+    public function setCaching($enable) {
+        $this->caching = $enable;
+    }
+
+    /**
+     * Sets the database connection URL; required.
+     * @param url The url to set
+     */
+    public function setUrl($url) {
+        $this->url = $url;
+    }
+        
+    /**
+     * Sets the password; required.
+     * @param password The password to set
+     */
+    public function setPassword($password) {
+        $this->password = $password;
+    }
+
+    /**
+     * Auto commit flag for database connection;
+     * optional, default false.
+     * @param autocommit The autocommit to set
+     */
+    public function setAutocommit($autocommit) {
+        $this->autocommit = $autocommit;
+    }
+
+    /**
+     * Sets the version string, execute task only if 
+     * rdbms version match; optional.
+     * @param version The version to set
+     */
+    public function setVersion($version) {
+        $this->version = $version;
+    }
+       
+    protected function getLoaderMap() {
+        return self::$loaderMap;
+    }
+
+
+    /**
+     * Creates a new Connection as using the driver, url, userid and password specified.
+     * The calling method is responsible for closing the connection.
+     * @return Connection the newly created connection.
+     * @throws BuildException if the UserId/Password/Url is not set or there is no suitable driver or the driver fails to load.
+     */
+    protected function getConnection() {
+            
+        if ($this->url === null) {
+            throw new BuildException("Url attribute must be set!", $this->location);
+        }
+                
+        try {
+
+            $this->log("Connecting to " . $this->getUrl(), Project::MSG_VERBOSE);
+            
+            $user = null;
+            $pass = null;
+				
+            if ($this->userId) {
+            	$user = $this->getUserId();
+            }
+            
+            if ($this->password) {
+                $pass = $this->getPassword();
+            }            
+            
+            $conn = new PDO($this->getUrl(), $user, $pass);
+            $conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
+            
+            if ($this->autocommit) {
+            	try {
+					$conn->setAttribute(PDO::ATTR_AUTOCOMMIT, $this->autocommit);
+				} catch (PDOException $pe) {
+					$this->log("Unable to enable auto-commit for this database: " . $pe->getMessage(), Project::MSG_WARN);
+				}
+			}
+            
+            return $conn;
+            
+        } catch (SQLException $e) {
+            throw new BuildException($e->getMessage(), $this->location);
+        }
+
+    }
+
+    public function isCaching($value) {
+        $this->caching = $value;
+    }
+
+    /**
+     * Gets the autocommit.
+     * @return Returns a boolean
+     */
+    public function isAutocommit() {
+        return $this->autocommit;
+    }
+
+    /**
+     * Gets the url.
+     * @return Returns a String
+     */
+    public function getUrl() {
+        return $this->url;
+    }
+
+    /**
+     * Gets the userId.
+     * @return Returns a String
+     */
+    public function getUserId() {
+        return $this->userId;
+    }
+
+    /**
+     * Set the user name for the connection; required.
+     * @param userId The userId to set
+     */
+    public function setUserid($userId) {
+        $this->userId = $userId;
+    }
+
+    /**
+     * Gets the password.
+     * @return Returns a String
+     */
+    public function getPassword() {
+        return $this->password;
+    }
+
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/pdo/PlainPDOResultFormatter.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/pdo/PlainPDOResultFormatter.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/pdo/PlainPDOResultFormatter.php	(revision 19)
@@ -0,0 +1,130 @@
+<?php
+/**
+ * $Id: FormatterElement.php 148 2007-02-13 11:15:53Z mrook $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+require_once 'phing/system/io/PhingFile.php';
+require_once 'phing/tasks/ext/pdo/PDOResultFormatter.php';
+
+/**
+ * Plain text formatter for PDO results. 
+ *
+ * @author Hans Lellelid <hans@xmpl.org>
+ * @package phing.tasks.ext.pdo
+ * @since 2.3.0
+ */
+class PlainPDOResultFormatter extends PDOResultFormatter
+{
+	/**
+	 * Have column headers been printed?
+	 * @var boolean
+	 */
+	private $colsprinted = false;
+
+	/**
+	 * Whether to show headers.
+	 * @var boolean
+	 */
+	private $showheaders = true;
+
+	/**
+	 * Column delimiter.
+	 * Defaults to ','
+	 * @var string
+	 */
+	private $coldelimiter = ",";
+
+	/**
+	 * Row delimiter.
+	 * Defaults to PHP_EOL.
+	 * @var string 
+	 */
+	private $rowdelimiter = PHP_EOL;
+
+	/**
+	 * Set the showheaders attribute.
+	 * @param boolean $v
+	 */
+	public function setShowheaders($v) {
+		$this->showheaders = StringHelper::booleanValue($v);
+	}
+
+	/**
+	 * Sets the column delimiter.
+	 * @param string $v
+	 */
+	public function setColdelim($v) {
+		$this->coldelimiter = $v;
+	}
+
+	/**
+	 * Sets the row delimiter.
+	 * @param string $v
+	 */
+	public function setRowdelim($v) {
+		$this->rowdelimiter = $v;
+	}
+
+	/**
+	 * Processes a specific row from PDO result set.
+	 *
+	 * @param array $row Row of PDO result set.
+	 */
+	public function processRow($row) {
+
+		if (!$this->colsprinted && $this->showheaders) {
+			$first = true;
+			foreach($row as $fieldName => $ignore) {
+				if ($first) $first = false; else $line .= ",";
+				$line .= $fieldName;
+			}
+
+			$this->out->write($line);
+			$this->out->write(PHP_EOL);
+
+			$line = "";
+			$colsprinted = true;
+		} // if show headers
+
+		$first = true;
+		foreach($row as $columnValue) {
+
+			if ($columnValue != null) {
+				$columnValue = trim($columnValue);
+			}
+
+			if ($first) {
+				$first = false;
+			} else {
+				$line .= $this->coldelimiter;
+			}
+			$line .= $columnValue;
+		}
+		
+		$this->out->write($line);
+		$this->out->write($this->rowdelimiter);
+
+	}
+
+	public function getPreferredOutfile()
+	{
+		return new PhingFile('results.txt');
+	}
+	
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/pdo/XMLPDOResultFormatter.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/pdo/XMLPDOResultFormatter.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/pdo/XMLPDOResultFormatter.php	(revision 19)
@@ -0,0 +1,141 @@
+<?php
+/**
+ * $Id: FormatterElement.php 148 2007-02-13 11:15:53Z mrook $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+require_once 'phing/system/io/PhingFile.php';
+require_once 'phing/tasks/ext/pdo/PDOResultFormatter.php';
+
+/**
+ * XML formatter for PDO results.
+ * 
+ * This class reprsents the output of a query using a simple XML schema.
+ * 
+ * <results>
+ * 	<row>
+ * 	 <col name="id">value</col>
+ * 	 <col name="name">value2</col>
+ *  </row>
+ *  <row>
+ *   <col name="id">value</col>
+ * 	 <col name="name">value2</col>
+ *  </row>
+ * </results>
+ *
+ * The actual names of the colums will depend on the fetchmode that was used
+ * with PDO.
+ * 
+ * @author Hans Lellelid <hans@xmpl.org>
+ * @package phing.tasks.ext.pdo
+ * @since 2.3.0
+ */
+class XMLPDOResultFormatter extends PDOResultFormatter {
+
+	/**
+	 * The XML document being created.
+	 * @var DOMDocument
+	 */
+	private $doc;
+
+	/**
+	 * @var DOMElement
+	 */
+	private $rootNode;
+
+	/**
+	 * XML document encoding
+	 *
+	 * @var string
+	 */
+	private $encoding;
+
+	/**
+	 * @var boolean
+	 */
+	private $formatOutput = true;
+	
+	/**
+	 * Set the DOM document encoding.
+	 * @param string $v
+	 */
+	public function setEncoding($v) {
+		$this->encoding = $v;
+	}
+	
+	/**
+	 * @param boolean $v
+	 */
+	public function setFormatOutput($v) {
+		$this->formatOutput = (boolean) $v;
+	}
+
+	public function initialize() {
+		$this->doc = new DOMDocument("1.0", $this->encoding);
+		$this->rootNode = $this->doc->createElement('results');
+		$this->doc->appendChild($this->rootNode);
+		$this->doc->formatOutput = $this->formatOutput;
+	}
+	
+	/**
+	 * Processes a specific row from PDO result set.
+	 *
+	 * @param array $row Row of PDO result set.
+	 */
+	public function processRow($row) {
+		
+		$rowNode = $this->doc->createElement('row');
+		$this->rootNode->appendChild($rowNode);
+
+		foreach($row as $columnName => $columnValue) {
+			
+			$colNode = $this->doc->createElement('column');
+			$colNode->setAttribute('name', $columnName);
+			
+			if ($columnValue != null) {
+				$columnValue = trim($columnValue);
+				$colNode->nodeValue = $columnValue;
+			}
+			$rowNode->appendChild($colNode);
+		}
+		
+	}
+	
+	/**
+	 * Gets a preferred filename for an output file.
+	 * 
+	 * If no filename is specified, this is where the results will be placed
+	 * (unless usefile=false).
+	 * 
+	 * @return string
+	 */
+	public function getPreferredOutfile()
+	{
+		return new PhingFile('results.xml');
+	}
+	
+	/**
+	 * Write XML to file and free the DOM objects.
+	 */
+	public function close() {
+		$this->out->write($this->doc->saveXML());
+		$this->rootNode = null;
+		$this->doc = null;
+		parent::close();
+	}
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/pearpackage/Fileset.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/pearpackage/Fileset.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/pearpackage/Fileset.php	(revision 19)
@@ -0,0 +1,231 @@
+<?php
+/*
+ *  $Id: Fileset.php 325 2007-12-20 15:44:58Z hans $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+include_once 'phing/system/io/PhingFile.php';
+
+/**
+ * Builds list of files for PEAR_PackageFileManager using a Phing FileSet.
+ *
+ * Some code here is taken from PEAR_PackageFileManager_File -- getting results from flat
+ * array into the assoc array expected from getFileList().
+ * 
+ * @author   Greg Beaver 
+ * @author   Hans Lellelid <hans@xmpl.org>
+ * @package  phing.tasks.ext.pearpackage
+ * @version  $Revision: 1.7 $
+ */
+class PEAR_PackageFileManager_Fileset {
+
+    /**
+     * @access private
+     * @var PEAR_PackageFileManager
+     */
+    private $parent;
+    
+    /**
+     * Curent Phing Project.
+     * @var Project
+     */
+    private $project;
+    
+    /**
+     * FileSets to use.
+     * @var array FileSet[]
+     */
+    private $filesets = array();
+
+    /**
+     * Set up the FileSet filelist generator
+     *
+     * 'project' and 'filesets' are the only options that this class uses.
+     * 
+     * @param PEAR_PackageFileManager
+     * @param array
+     */
+    function __construct($parent, $options)
+    {
+        $this->parent = $parent;
+        $this->project = $options['phing_project'];
+        $this->filesets = $options['phing_filesets'];
+    }
+    
+    /**
+     * Generate the <filelist></filelist> section
+     * of the package file.
+     *
+     * This function performs the backend generation of the array
+     * containing all files in this package
+     * @return array structure of all files to include
+     */
+    function getFileList() {    
+
+        $allfiles = array();        
+        
+        foreach($this->filesets as $fs) {
+            $ds = $fs->getDirectoryScanner($this->project);
+            
+            $files = $ds->getIncludedFiles();
+            
+            // We need to store these files keyed by the basedir from DirectoryScanner
+            // so that we can resolve the fullpath of the file later.
+            if (isset($allfiles[$ds->getBasedir()]))
+            {
+                $allfiles[$ds->getBasedir()] = array_merge($allfiles[$ds->getBasedir()], $files);
+            }
+            else
+            {
+                $allfiles[$ds->getBasedir()] = $files;
+            }
+        }
+        
+        $struc = array();
+        
+        foreach($allfiles as $basedir => $files) {
+        
+            foreach($files as $file) {
+                            
+                // paths are relative to $basedir above
+                $path = strtr(dirname($file), DIRECTORY_SEPARATOR, '/');
+    
+                if (!$path || $path == '.') {
+                    $path = '/'; // for array index
+                }
+                
+				$parts = explode('.', basename($file));
+                $ext = array_pop($parts);
+                if (strlen($ext) == strlen($file)) {
+                    $ext = '';
+                }
+                
+                $f = new PhingFile($basedir, $file);
+                
+                $struc[$path][] = array('file' => basename($file),
+                                        'ext' => $ext,
+                                        'path' => (($path == '/') ? basename($file) : $path . '/' . basename($file)),
+                                        'fullpath' => $f->getAbsolutePath());        
+            }                                        
+        }
+                
+        uksort($struc,'strnatcasecmp');
+        foreach($struc as $key => $ind) {
+            usort($ind, array($this, 'sortfiles'));
+            $struc[$key] = $ind;
+        }
+
+        $tempstruc = $struc;
+        $struc = array('/' => $tempstruc['/']);
+        $bv = 0;
+        foreach($tempstruc as $key => $ind) {
+            $save = $key;
+            if ($key != '/') {
+                $struc['/'] = $this->setupDirs($struc['/'], explode('/', $key), $tempstruc[$key]);
+            }
+        }
+        uksort($struc['/'], array($this, 'mystrucsort'));
+
+        return $struc;
+    }
+
+    /**
+     * Recursively move contents of $struc into associative array
+     *
+     * The contents of $struc have many indexes like 'dir/subdir/subdir2'.
+     * This function converts them to
+     * array('dir' => array('subdir' => array('subdir2')))
+     * @param array struc is array('dir' => array of files in dir,
+     *              'dir/subdir' => array of files in dir/subdir,...)
+     * @param array array form of 'dir/subdir/subdir2' array('dir','subdir','subdir2')
+     * @return array same as struc but with array('dir' =>
+     *              array(file1,file2,'subdir' => array(file1,...)))
+     */
+    private function setupDirs($struc, $dir, $contents) {
+    
+        if (!count($dir)) {
+            foreach($contents as $dir => $files) {
+                if (is_string($dir)) {
+                    if (strpos($dir, '/')) {
+                        $test = true;
+                        $a = $contents[$dir];
+                        unset($contents[$dir]);
+                        $b = explode('/', $dir);
+                        $c = array_shift($b);
+                        if (isset($contents[$c])) {
+                            $contents[$c] = $this->setDir($contents[$c], $this->setupDirs(array(), $b, $a));
+                        } else {
+                            $contents[$c] = $this->setupDirs(array(), $b, $a);
+                        }
+                    }
+                }
+            }
+            return $contents;
+        }
+        $me = array_shift($dir);
+        if (!isset($struc[$me])) {
+            $struc[$me] = array();
+        }
+        $struc[$me] = $this->setupDirs($struc[$me], $dir, $contents);
+        return $struc;
+    }
+    
+    /**
+     * Recursively add all the subdirectories of $contents to $dir without erasing anything in
+     * $dir
+     * @param array
+     * @param array
+     * @return array processed $dir
+     */
+    function setDir($dir, $contents)
+    {
+        while(list($one,$two) = each($contents)) {
+            if (isset($dir[$one])) {
+                $dir[$one] = $this->setDir($dir[$one], $contents[$one]);
+            } else {
+                $dir[$one] = $two;
+            }
+        }
+        return $dir;
+    }
+    
+    /**
+     * Sorting functions for the file list
+     * @param string
+     * @param string
+     * @access private
+     */
+    function sortfiles($a, $b)
+    {
+        return strnatcasecmp($a['file'],$b['file']);
+    }
+    
+    function mystrucsort($a, $b)
+    {
+        if (is_numeric($a) && is_string($b)) return 1;
+        if (is_numeric($b) && is_string($a)) return -1;
+        if (is_numeric($a) && is_numeric($b))
+        {
+            if ($a > $b) return 1;
+            if ($a < $b) return -1;
+            if ($a == $b) return 0;
+        }
+        return strnatcasecmp($a,$b);
+    }
+}
+
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/phpdoc/PhingPhpDocumentorSetup.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/phpdoc/PhingPhpDocumentorSetup.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/phpdoc/PhingPhpDocumentorSetup.php	(revision 19)
@@ -0,0 +1,210 @@
+<?php
+/**
+ * $Id: PHPDocumentorTask.php 144 2007-02-05 15:19:00Z hans $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+/**
+ * Phing subclass of the phpDocumentor_setup class provided with PhpDocumentor to work around limitations in PhpDocumentor API.
+ * 
+ * This class is necessary because phpDocumentor_setup does not expose a complete API for setting configuration options.  Because
+ * this class must directly modify some "private" GLOBAL(!) configuration variables, it is liable to break if the PhpDocumentor
+ * internal implementation changes.  Obviously this is far from ideal, but there's also no solution given the inflexibility of the
+ * PhpDocumentor design. 
+ * 
+ * @author Hans Lellelid <hans@xmpl.org>@author hans
+ * @version $Id$
+ * @package phing.tasks.ext.phpdoc
+ */
+class PhingPhpDocumentorSetup extends phpDocumentor_setup {
+	
+	/**
+	 * Constructs a new PhingPhpDocumentorSetup.
+	 *
+	 * @param string $configDir Directory in which to look for configuration files.
+	 */
+	public function __construct($configdir = null) {
+		global $_phpDocumentor_cvsphpfile_exts, $_phpDocumentor_setting, $_phpDocumentor_phpfile_exts;
+		
+		$this->setup = new Io();
+		$this->render = new phpDocumentor_IntermediateParser("Default Title");
+		
+		$GLOBALS['_phpDocumentor_install_dir'] = $configdir;
+        $this->parseIni();
+		
+        // These redundant-looking lines seem to actually make a difference.
+        // See: http://phing.info/trac/ticket/150
+        $_phpDocumentor_phpfile_exts = $GLOBALS['_phpDocumentor_phpfile_exts'];
+		$_phpDocumentor_cvsphpfile_exts = $GLOBALS['_phpDocumentor_cvsphpfile_exts'];
+
+		if (tokenizer_ext) {
+            $this->parse = new phpDocumentorTParser();
+        } else {
+            $this->parse = new Parser();
+        }
+        
+        $this->setMemoryLimit();
+	}
+	
+	/**
+	 * Set whether to generate sourcecode for each file parsed.
+	 *
+	 * This method exists as a hack because there is no API exposed for this in PhpDocumentor.
+	 * Note that because we are setting a "private" GLOBAL(!!) config var with this value, this
+	 * is subject to break if PhpDocumentor internals changes.  
+	 * 
+	 * @param bool $b
+	 */
+	public function setGenerateSourcecode($b) {
+		global $_phpDocumentor_setting;
+		$_phpDocumentor_setting['sourcecode'] = (boolean) $b;
+	}
+	
+	/**
+	 * Set an array of README/INSTALL/CHANGELOG file paths. 
+	 *
+	 * This method exists as a hack because there is no API exposed for this in PhpDocumentor.
+	 * Note that because we are setting a "private" GLOBAL(!!) config var with this value, this
+	 * is subject to break if PhpDocumentor internals changes.  
+	 * 
+	 * @param array $files Absolute paths to files.
+	 */
+	public function setRicFiles($files) {
+		global $_phpDocumentor_RIC_files;
+		$_phpDocumentor_RIC_files = $files;
+	}
+	
+	/**
+	 * Set comma-separated list of tags to ignore.
+	 *
+	 * This method exists as a hack because there is no API exposed for this in PhpDocumentor.
+	 * Note that because we are setting a "private" GLOBAL(!!) config var with this value, this
+	 * is subject to break if PhpDocumentor internals changes.  
+	 * 
+	 * @param string $tags
+	 */
+	public function setIgnoreTags($tags) {
+		global $_phpDocumentor_setting; 
+		$ignoretags = explode(',', $tags);
+		$ignoretags = array_map('trim', $ignoretags);
+		$tags = array();
+		foreach($ignoretags as $tag) {
+		    if (!in_array($tag,array('@global', '@access', '@package', '@ignore', '@name', '@param', '@return', '@staticvar', '@var')))
+		        $tags[] = $tag;
+		}
+		$_phpDocumentor_setting['ignoretags'] = $tags;
+	}
+	
+	/**
+	 * Set whether to parse dirs as PEAR repos. 
+	 *
+	 * This method exists as a hack because there is no API exposed for this in PhpDocumentor.
+	 * Note that because we are setting a "private" GLOBAL(!!) config var with this value, this
+	 * is subject to break if PhpDocumentor internals changes.  
+	 * 
+	 * @param bool $b
+	 */
+	public function setPear($b) {
+		global $_phpDocumentor_setting;
+		$_phpDocumentor_setting['pear'] = (boolean) $b;
+	}
+	
+	/**
+	 * Set fullpath to directory to look in for examples. 
+	 *
+	 * This method exists as a hack because there is no API exposed for this in PhpDocumentor.
+	 * Note that because we are setting a "private" GLOBAL(!!) config var with this value, this
+	 * is subject to break if PhpDocumentor internals changes.  
+	 * 
+	 * @param string $dir
+	 */
+	public function setExamplesDir($dir) {
+		global $_phpDocumentor_setting;
+		$_phpDocumentor_setting['examplesdir'] = $dir;
+	}
+	
+	/**
+	 * Sets the default package name.
+	 *
+	 * This method exists as a hack because there is no API exposed for this in PhpDocumentor.
+	 * Note that because we are setting a "private" GLOBAL(!!) config var with this value, this
+	 * is subject to break if PhpDocumentor internals changes.  
+	 * 
+	 * @param string $name
+	 */
+	public function setDefaultPackageName($name) {
+		$GLOBALS['phpDocumentor_DefaultPackageName'] = trim($name);
+	}
+	
+	/**
+	 * Sets the default category name.
+	 *
+	 * This method exists as a hack because there is no API exposed for this in PhpDocumentor.
+	 * Note that because we are setting a "private" GLOBAL(!!) config var with this value, this
+	 * is subject to break if PhpDocumentor internals changes.  
+	 * 
+	 * @param string $name
+	 */
+	public function setDefaultCategoryName($name) {
+		$GLOBALS['phpDocumentor_DefaultCategoryName'] = trim($name);
+	}
+	
+	/**
+	 * Enables quiet mode.
+	 *
+	 * This method exists as a hack because the API exposed for this method in PhpDocumentor
+	 * doesn't work correctly.
+	 * 
+	 * Note that because we are setting a "private" GLOBAL(!!) config var with this value, this
+	 * is subject to break if PhpDocumentor internals changes.  
+	 * 
+	 */
+	public function setQuietMode() {
+		global $_phpDocumentor_setting;
+		$_phpDocumentor_setting['quiet'] = true;
+		parent::setQuietMode();
+	}
+
+    /**
+     * Control whether or not warnings will be shown for undocumented elements.
+     * Useful for identifying classes and methods that haven't yet been
+     * documented.
+     * 
+     * @param  bool  $bEnable 
+     */
+    public function setUndocumentedelements($bEnable) {
+        $this->render->setUndocumentedElementWarningsMode($bEnable);
+    }
+
+    /**
+     * custom tags, will be recognized and put in tags[] instead of
+     * unknowntags[]
+     *
+     * This method exists as a hack because the API exposed for this method in
+     * PhpDocumentor doesn't work correctly.
+	 * 
+     * Note that because we are setting a "private" GLOBAL(!!) config var with
+     * this value, this is subject to break if PhpDocumentor internals changes.
+     * 
+     * @param  string  $sCustomtags 
+     */
+    public function setCustomtags($sCustomtags) {
+        global $_phpDocumentor_setting;
+        $_phpDocumentor_setting['customtags'] = $sCustomtags;
+    }
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/phpdoc/PhpDocumentorExternalTask.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/phpdoc/PhpDocumentorExternalTask.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/phpdoc/PhpDocumentorExternalTask.php	(revision 19)
@@ -0,0 +1,261 @@
+<?php
+
+/**
+ * $Id: PhpDocumentorExternalTask.php 352 2008-02-06 15:26:43Z mrook $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+require_once 'phing/tasks/ext/phpdoc/PhpDocumentorTask.php';
+
+/**
+ * Task to run phpDocumentor with an external process
+ * 
+ * This classes uses the commandline phpdoc script to build documentation.
+ * Use this task instead of the PhpDocumentorTask when you've a clash with the
+ * Smarty libraries.
+ *
+ * @author Michiel Rook <michiel.rook@gmail.com>
+ * @author Markus Fischer <markus@fischer.name>
+ * @version $Id: PhpDocumentorExternalTask.php 352 2008-02-06 15:26:43Z mrook $
+ * @package phing.tasks.ext.phpdoc
+ */	
+class PhpDocumentorExternalTask extends PhpDocumentorTask
+{
+	/**
+	 * The path to the executable for phpDocumentor
+	 */
+	protected $programPath = 'phpdoc';
+
+	protected $sourcepath = NULL;
+
+    /**
+     * @var bool  ignore symlinks to other files or directories
+     */
+    protected $ignoresymlinks = false;
+
+	/**
+	 * Sets the path to the phpDocumentor executable
+	 */
+	public function setProgramPath($programPath)
+	{
+		$this->programPath = $programPath;
+	}
+
+	/**
+	 * Returns the path to the phpDocumentor executable
+	 */
+	public function getProgramPath()
+	{
+		return $this->programPath;
+	}
+
+	/**
+     * Set the source path. A directory or a comma separate list of directories.
+	 */
+	public function setSourcepath($sourcepath)
+	{
+        $this->sourcepath = $sourcepath;
+	}
+
+    /**
+     * Ignore symlinks to other files or directories.
+     * 
+     * @param  bool  $bSet 
+     */
+    public function setIgnoresymlinks($bSet) {
+        $this->ignoresymlinks = $bSet;
+    }
+
+	/**
+	 * Main entrypoint of the task
+	 */
+	public function main()
+	{
+        $this->validate();
+		$arguments = join(' ', $this->constructArguments());
+
+		$this->log("Running phpDocumentor...");
+
+		exec($this->programPath . " " . $arguments, $output, $return);
+
+		if ($return != 0)
+		{
+			throw new BuildException("Could not execute phpDocumentor: " . implode(' ', $output));
+		}
+		
+		foreach($output as $line)
+		{
+			if(strpos($line, 'ERROR') !== false)
+			{
+				$this->log($line, Project::MSG_ERR);
+				continue;
+			}
+			
+			$this->log($line, Project::MSG_VERBOSE);
+		}
+	}
+
+	/**
+	 * Constructs an argument string for phpDocumentor
+     * @return  array
+	 */
+	protected function constructArguments()
+	{
+        $aArgs = array();
+		if ($this->title)
+		{
+			$aArgs[] = '--title "' . $this->title . '"';
+		}
+
+		if ($this->destdir)
+		{
+			$aArgs[] = '--target "' . $this->destdir->getAbsolutePath() . '"';
+		}
+
+		if ($this->sourcepath)
+		{
+			$aArgs[] = '--directory "' . $this->sourcepath . '"';
+		}
+
+		if ($this->output)
+		{
+			$aArgs[] = '--output ' . $this->output;
+		}
+
+		if ($this->linksource)
+		{
+			$aArgs[] = '--sourcecode on';
+		}
+
+		if ($this->parseprivate)
+		{
+			$aArgs[] = '--parseprivate on';
+		}
+
+		// append any files in filesets
+		$filesToParse = array();
+		foreach($this->filesets as $fs) {		    
+	        $files = $fs->getDirectoryScanner($this->project)->getIncludedFiles();
+	        foreach($files as $filename) {
+	        	 $f = new PhingFile($fs->getDir($this->project), $filename);
+	        	 $filesToParse[] = $f->getAbsolutePath();
+	        }
+		}
+        if (count($filesToParse) > 0) {
+            $aArgs[] = '--filename "' . join(',', $filesToParse) . '"';
+        }
+
+		// append any files in filesets
+		$ricFiles = array();
+		foreach($this->projDocFilesets as $fs) {		    
+	        $files = $fs->getDirectoryScanner($this->project)->getIncludedFiles();
+	        foreach($files as $filename) {
+	        	 $f = new PhingFile($fs->getDir($this->project), $filename);
+	        	 $ricFiles[] = $f->getAbsolutePath();
+	        }
+		}
+        if (count($ricFiles) > 0) {
+            $aArgs[] = '--readmeinstallchangelog "' .
+                join(',', $ricFiles) . '"';
+        }
+
+        if ($this->javadocDesc) {
+            $aArgs[] = '--javadocdesc on';
+        }
+
+        if ($this->quiet) {
+            $aArgs[] = '--quiet on';
+        }
+
+        if ($this->packages) {
+            $aArgs[] = '--packageoutput "' . $this->packages . '"';
+        }
+
+        if ($this->ignoreTags) {
+            $aArgs[] = '--ignore-tags "' . $this->ignoreTags . '"';
+        }
+
+        if ($this->defaultCategoryName) {
+            $aArgs[] = '--defaultcategoryname "' . $this->defaultCategoryName .
+                '"';
+        }
+
+		if ($this->examplesDir) {
+            $aArgs[] = '--examplesdir "' . $this->examplesDir->getAbsolutePath()
+                . '"';
+		}
+
+		if ($this->templateBase) {
+            $aArgs[] = '--templatebase "' . $this->templateBase->getAbsolutePath()
+                . '"';
+		}
+
+        if ($this->pear) {
+            $aArgs[] = '--pear on';
+        }
+
+        if ($this->undocumentedelements) {
+            $aArgs[] = '--undocumentedelements on';
+        }
+
+        if ($this->customtags) {
+            $aArgs[] = '--customtags "' . $this->customtags . '"';
+        }
+
+        if ($this->ignoresymlinks) {
+            $aArgs[] = '--ignoresymlinks on';
+        }
+
+        var_dump($aArgs);exit;
+        return $aArgs;
+	}
+
+    /**
+     * Override PhpDocumentorTask::init() because they're specific to the phpdoc
+     * API which we don't use.
+     */
+    public function init() {
+    }
+
+    /**
+     * Validates that necessary minimum options have been set. Based on
+     * PhpDocumentorTask::validate().
+     */
+    protected function validate() {
+		if (!$this->destdir) {
+            throw new BuildException("You must specify a destdir for phpdoc.",
+                $this->getLocation());
+		}
+		if (!$this->output) {
+            throw new BuildException("You must specify an output format for " .
+                "phpdoc (e.g. HTML:frames:default).", $this->getLocation());
+		}
+		if (empty($this->filesets) && !$this->sourcepath) {
+            throw new BuildException("You have not specified any files to " .
+                "include (<fileset> or sourcepath attribute) for phpdoc.",
+                    $this->getLocation());
+		}
+        if ($this->configdir) {
+            $this->log('Ignoring unsupported configdir-Attribute',
+                Project::MSG_VERBOSE);
+        }
+    }
+};
+
+
+
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/phpdoc/PhpDocumentorTask.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/phpdoc/PhpDocumentorTask.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/phpdoc/PhpDocumentorTask.php	(revision 19)
@@ -0,0 +1,460 @@
+<?php
+
+/**
+ * $Id: PHPDocumentorTask.php 144 2007-02-05 15:19:00Z hans $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+require_once 'phing/Task.php';
+
+/**
+ * Task to run PhpDocumentor.
+ *
+ * @author Hans Lellelid <hans@xmpl.org>
+ * @author Michiel Rook <michiel.rook@gmail.com>
+ * @version $Id$
+ * @package phing.tasks.ext.phpdoc
+ */	
+class PhpDocumentorTask extends Task
+{
+	
+	/**
+	 * @var string Title for browser window / package index.
+	 */
+	protected $title;
+	
+	/**
+	 * @var PhingFile The target directory for output files.
+	 */
+	protected $destdir;
+
+	/**
+	 * @var array FileSet[] Filesets for files to parse.
+	 */
+	protected $filesets = array();
+	
+	/**
+	 * @var array FileSet[] Project documentation (README/INSTALL/CHANGELOG) files.
+	 */
+	protected $projDocFilesets = array();
+	
+	/**
+	 * @var string Package output format. 
+	 */
+	protected $output;
+
+	/**
+	 * @var boolean Whether to generate sourcecode for each file parsed.
+	 */
+	protected $linksource = false;
+	
+	/**
+	 * @var boolean Whether to parse private members.
+	 */
+	protected $parsePrivate = false;
+	
+	/**
+	 * @var boolean Whether to use javadoc descriptions (more primitive).
+	 */
+	protected $javadocDesc = false;
+	
+	/**
+	 * @var PhingFile Base directory for locating template files.
+	 */
+	protected $templateBase;
+	
+	/**
+	 * @var boolean Wheter to suppress output.
+	 */
+	protected $quiet = false;
+	
+	/**
+	 * @var string Comma-separated list of packages to output.
+	 */
+	protected $packages;
+	
+	/** 
+	 * @var string Comma-separated list of tags to ignore.
+	 */
+	protected $ignoreTags;
+	
+	/** 
+	 * @var string Default package name.
+	 */
+	protected $defaultPackageName;
+	
+	/**
+	 * @var string Default category name.
+	 */
+	protected $defaultCategoryName;
+	
+	/**
+	 * @var PhingFile Directory in which to look for examples.
+	 */
+	protected $examplesDir;
+	
+	/**
+	 * @var PhingFile Directory in which to look for configuration files.
+	 */
+	protected $configDir;
+	
+	/**
+	 * @var boolean Whether to parse as a PEAR repository.
+	 */
+	protected $pear = false;
+
+    /**
+     * @var boolean Control whether or not warnings will be shown for
+     *              undocumented elements. Useful for identifying classes and
+     *              methods that haven't yet been documented.
+     */
+    protected $undocumentedelements = false;
+
+    /**
+     * @var string  custom tags, will be recognized and put in tags[] instead of
+     *              unknowntags[].
+     */
+    protected $customtags = '';
+	
+	/**
+	 * Set the title for the generated documentation
+	 */
+	public function setTitle($title) {
+		$this->title = $title;
+	}
+
+	/**
+	 * Set the destination directory for the generated documentation
+	 */
+	public function setDestdir(PhingFile $destdir) {
+		$this->destdir = $destdir;
+	}
+	
+	/**
+	 * Alias for {@link setDestdir()).
+	 * @see setDestdir()
+	 */
+	public function setTarget(PhingFile $destdir) {
+		$this->setDestdir($destdir);
+	}
+
+	/**
+	 * Set the output format (e.g. HTML:Smarty:PHP).
+	 * @param string $output
+	 */		
+	public function setOutput($output) {
+		$this->output = $output;
+	}
+
+	/**
+	 * Set whether to generate sourcecode for each file parsed
+	 * @param boolean
+	 */
+	public function setSourcecode($b) {
+		$this->linksource = $b;
+	}
+	
+	/**
+	 * Set whether to suppress output.
+	 * @param boolean $b
+	 */
+	public function setQuiet($b) {
+		$this->quiet = $b;
+	}
+	
+	/**
+	 * Should private members/classes be documented
+	 * @param boolean
+	 */
+	public function setParseprivate($parseprivate) {
+		$this->parsePrivate = $parseprivate;
+	}
+	
+	/**
+	 * Whether to use javadoc descriptions (more primitive).
+	 * @param boolean
+	 */
+	public function setJavadocdesc($javadoc) {
+		$this->javadocDesc = $javadoc;
+	}
+	
+	/**
+	 * Set (comma-separated) list of packages to output.
+	 *
+	 * @param string $packages
+	 */
+	public function setPackageoutput($packages) {
+		$this->packages = $packages;
+	}
+	
+	/**
+	 * Set (comma-separated) list of tags to ignore.
+	 *
+	 * @param string $tags
+	 */
+	public function setIgnoretags($tags) {
+		$this->ignoreTags = $tags;
+	}
+	
+	/**
+	 * Set a directory to search for examples in.
+	 * @param PhingFile $d
+	 */
+	public function setExamplesdir(PhingFile $d) {
+		$this->examplesDir = $d;
+	}
+	
+	/**
+	 * Set a directory to search for configuration files in.
+	 * @param PhingFile $d
+	 */
+	public function setConfigdir(PhingFile $d) {
+		$this->configDir = $d;
+	}
+	
+	/**
+	 * Sets the default package name.
+	 * @param string $name
+	 */
+	public function setDefaultpackagename($name) {
+		$this->defaultPackageName = $name;
+	}
+	
+	/**
+	 * Sets the default category name.
+	 * @param string $name
+	 */
+	public function setDefaultcategoryname($name) {
+		$this->defaultCategoryName = $name;
+	}
+	
+	/**
+	 * Set whether to parse as PEAR repository.
+	 * @param boolean $b
+	 */
+	public function setPear($b) {
+		$this->pear = $b;
+	}
+	
+    /**
+	 * Creates a FileSet.
+	 * @return FileSet
+	 */
+    public function createFileset() {
+        $num = array_push($this->filesets, new FileSet());
+        return $this->filesets[$num-1];
+    }
+    
+    /**
+     * Creates a readme/install/changelog fileset.
+     * @return FileSet
+     */
+    public function createProjdocfileset() {
+    	$num = array_push($this->projDocFilesets, new FileSet());
+        return $this->projDocFilesets[$num-1];
+    }
+ 	
+	/**
+     * Control whether or not warnings will be shown for undocumented elements.
+     * Useful for identifying classes and methods that haven't yet been
+     * documented.
+	 * @param boolean $b
+	 */
+	public function setUndocumentedelements($b) {
+		$this->undocumentedelements = $b;
+	}
+
+    /**
+     * custom tags, will be recognized and put in tags[] instead of
+     * unknowntags[].
+     * 
+     * @param  string  $sCustomtags 
+     */
+    public function setCustomtags($sCustomtags) {
+        $this->customtags = $sCustomtags;
+    }
+
+	/**
+	 * Set base location of all templates for this parse.
+	 * 
+	 * @param  PhingFile  $destdir 
+	 */
+	public function setTemplateBase(PhingFile $oTemplateBase) {
+		$this->templateBase = $oTemplateBase;
+	}
+
+    /**
+     * Searches include_path for PhpDocumentor install and adjusts include_path appropriately.
+     * @throws BuildException - if unable to find PhpDocumentor on include_path
+     */
+    protected function findPhpDocumentorInstall()
+    {
+    	$found = null;
+    	foreach(explode(PATH_SEPARATOR, get_include_path()) as $path) {
+    		$testpath = $path . DIRECTORY_SEPARATOR . 'PhpDocumentor';
+    		if (file_exists($testpath)) {
+    			$found = $testpath;
+    			break;
+    		}
+    	}
+    	if (!$found) {
+    		throw new BuildException("PhpDocumentor task depends on PhpDocumentor being installed and on include_path.", $this->getLocation());
+    	}
+    	// otherwise, adjust the include_path to path to include the PhpDocumentor directory ... 
+		set_include_path(get_include_path() . PATH_SEPARATOR . $found);
+		include_once ("phpDocumentor/Setup.inc.php");
+		if (!class_exists('phpDocumentor_setup')) {
+			throw new BuildException("Error including PhpDocumentor setup class file.");
+		}
+    }
+    
+	/**
+	 * Load the necessary environment for running PhpDoc.
+	 *
+	 * @throws BuildException - if the phpdoc classes can't be loaded.
+	 */
+	public function init()
+	{
+		$this->findPhpDocumentorInstall();
+        include_once 'phing/tasks/ext/phpdoc/PhingPhpDocumentorSetup.php';
+	}
+	
+	/**
+	 * Main entrypoint of the task
+	 */
+	function main()
+	{
+		$this->validate();
+		$configdir = $this->configDir ? $this->configDir->getAbsolutePath() : null;
+		$phpdoc = new PhingPhpDocumentorSetup($configdir);
+		$this->setPhpDocumentorOptions($phpdoc);
+		//$phpdoc->readCommandLineSettings();
+		$phpdoc->setupConverters($this->output);
+		$phpdoc->createDocs();		
+	}
+	
+	/**
+	 * Validates that necessary minimum options have been set.
+	 * @throws BuildException if validation doesn't pass
+	 */
+	protected function validate()
+	{
+		if (!$this->destdir) {
+			throw new BuildException("You must specify a destdir for phpdoc.", $this->getLocation());
+		}
+		if (!$this->output) {
+			throw new BuildException("You must specify an output format for phpdoc (e.g. HTML:frames:default).", $this->getLocation());
+		}
+		if (empty($this->filesets)) {
+			throw new BuildException("You have not specified any files to include (<fileset>) for phpdoc.", $this->getLocation());
+		}
+	}
+	
+	/**
+	 * Sets the options on the passed-in phpdoc setup object.
+	 * @param PhingPhpDocumentorSetup $phpdoc
+	 */
+	protected function setPhpDocumentorOptions(PhingPhpDocumentorSetup $phpdoc)
+	{
+		
+		// Title MUST be set first ... (because it re-initializes the internal state of the PhpDocu renderer)
+		if ($this->title) {
+			$phpdoc->setTitle($this->title);
+		}
+		
+		if ($this->parsePrivate) {
+			$phpdoc->setParsePrivate();
+		}
+		
+		if ($this->javadocDesc) {
+			$phpdoc->setJavadocDesc();
+		}
+		
+		if ($this->quiet) {
+			$phpdoc->setQuietMode();
+		}
+		
+		if ($this->destdir) {
+			$phpdoc->setTargetDir($this->destdir->getAbsolutePath());
+		}
+				
+		if ($this->packages) {
+			$phpdoc->setPackageOutput($this->packages);
+		}
+		
+		if ($this->templateBase) {
+			$phpdoc->setTemplateBase($this->templateBase->getAbsolutePath());
+		}
+		
+		if ($this->linksource) {
+			$phpdoc->setGenerateSourcecode($this->linksource);
+		}
+		
+		if ($this->examplesDir) {
+			$phpdoc->setExamplesDir($this->examplesDir->getAbsolutePath());
+		}
+		
+		if ($this->ignoreTags) {
+			$phpdoc->setIgnoreTags($this->ignoreTags);
+		}
+		
+		if ($this->defaultPackageName) {
+			$phpdoc->setDefaultPackageName($this->defaultPackageName);
+		}
+		
+		if ($this->defaultCategoryName) {
+			$phpdoc->setDefaultCategoryName($this->defaultCategoryName);
+		}
+		
+		if ($this->pear) {
+			$phpdoc->setPear($this->pear);
+		}
+		
+		// append any files in filesets
+		$filesToParse = array();
+		foreach($this->filesets as $fs) {		    
+	        $files = $fs->getDirectoryScanner($this->project)->getIncludedFiles();
+	        foreach($files as $filename) {
+	        	 $f = new PhingFile($fs->getDir($this->project), $filename);
+	        	 $filesToParse[] = $f->getAbsolutePath();
+	        }
+		}
+		//print_r(implode(",", $filesToParse));
+		$phpdoc->setFilesToParse(implode(",", $filesToParse));
+		
+		
+		// append any files in filesets
+		$ricFiles = array();
+		foreach($this->projDocFilesets as $fs) {		    
+	        $files = $fs->getDirectoryScanner($this->project)->getIncludedFiles();
+	        foreach($files as $filename) {
+	        	 $f = new PhingFile($fs->getDir($this->project), $filename);
+	        	 $ricFiles[] = $f->getAbsolutePath();
+	        }
+		}
+		$phpdoc->setRicFiles($ricFiles);
+
+        if ($this->undocumentedelements) {
+            $phpdoc->setUndocumentedelements($this->undocumentedelements);
+        }
+
+        if ($this->customtags) {
+            $phpdoc->setCustomtags($this->customtags);
+        }
+	}
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/phpunit/BatchTest.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/phpunit/BatchTest.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/phpunit/BatchTest.php	(revision 19)
@@ -0,0 +1,182 @@
+<?php
+/**
+ * $Id: BatchTest.php 350 2008-02-06 15:06:57Z mrook $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+require_once 'phing/types/FileSet.php';
+
+/**
+ * Scans a list of files given by the fileset attribute, extracts
+ * all subclasses of PHPUnit(2)_Framework_TestCase / PHPUnit(2)_Framework_TestSuite.
+ *
+ * @author Michiel Rook <michiel.rook@gmail.com>
+ * @version $Id: BatchTest.php 350 2008-02-06 15:06:57Z mrook $
+ * @package phing.tasks.ext.phpunit
+ * @since 2.1.0
+ */
+class BatchTest
+{
+	/** the list of filesets containing the testcase filename rules */
+	private $filesets = array();
+
+	/** the reference to the project */
+	private $project = NULL;
+
+	/** the classpath to use with Phing::__import() calls */
+	private $classpath = NULL;
+	
+	/** names of classes to exclude */
+	private $excludeClasses = array();
+	
+	/**
+	 * Create a new batchtest instance
+	 *
+	 * @param Project the project it depends on.
+	 */
+	function __construct(Project $project)
+	{
+		$this->project = $project;
+	}
+	
+	/**
+	 * Sets the classes to exclude
+	 */
+	function setExclude($exclude)
+	{
+		$this->excludeClasses = explode(" ", $exclude);
+	}
+
+	/**
+	 * Sets the classpath
+	 */
+	function setClasspath(Path $classpath)
+	{
+		if ($this->classpath === null)
+		{
+			$this->classpath = $classpath;
+		}
+		else
+		{
+			$this->classpath->append($classpath);
+		}
+	}
+
+	/**
+	 * Creates a new Path object
+	 */
+	function createClasspath()
+	{
+		$this->classpath = new Path();
+		return $this->classpath;
+	}
+
+	/**
+	 * Returns the classpath
+	 */
+	function getClasspath()
+	{
+		return $this->classpath;
+	}
+
+	/**
+	 * Add a new fileset containing the XML results to aggregate
+	 *
+	 * @param FileSet the new fileset containing XML results.
+	 */
+	function addFileSet(FileSet $fileset)
+	{
+		$this->filesets[] = $fileset;
+	}
+
+	/**
+	 * Iterate over all filesets and return the filename of all files.
+	 *
+	 * @return array an array of filenames
+	 */
+	private function getFilenames()
+	{
+		$filenames = array();
+
+		foreach ($this->filesets as $fileset)
+		{
+			$ds = $fileset->getDirectoryScanner($this->project);
+			$ds->scan();
+
+			$files = $ds->getIncludedFiles();
+
+			foreach ($files as $file)
+			{
+				$filenames[] = $ds->getBaseDir() . "/" . $file;
+			}
+		}
+
+		return $filenames;
+	}
+	
+	/**
+	 * Checks wheter $input is a subclass of PHPUnit(2)_Framework_TestCasse
+	 * or PHPUnit(2)_Framework_TestSuite
+	 */
+	private function isTestCase($input)
+	{
+		if (PHPUnitUtil::$installedVersion == 3)
+			return is_subclass_of($input, 'PHPUnit_Framework_TestCase') || is_subclass_of($input, 'PHPUnit_Framework_TestSuite');
+		else
+			return is_subclass_of($input, 'PHPUnit2_Framework_TestCase') || is_subclass_of($input, 'PHPUnit2_Framework_TestSuite');
+	}
+	
+	/**
+	 * Filters an array of classes, removes all classes that are not test cases or test suites,
+	 * or classes that are declared abstract
+	 */
+	private function filterTests($input)
+	{
+		$reflect = new ReflectionClass($input);
+		
+		return $this->isTestCase($input) && (!$reflect->isAbstract());
+	}
+
+	/**
+	 * Returns an array of test cases and test suites that are declared
+	 * by the files included by the filesets
+	 *
+	 * @return array an array of PHPUnit(2)_Framework_TestCase or PHPUnit(2)_Framework_TestSuite classes.
+	 */
+	function elements()
+	{
+		$filenames = $this->getFilenames();
+		
+		$declaredClasses = array();		
+
+		foreach ($filenames as $filename)
+		{
+			$definedClasses = PHPUnitUtil::getDefinedClasses($filename, $this->classpath);
+			
+			foreach($definedClasses as $definedClass) {
+				$this->project->log("(PHPUnit) Adding $definedClass (from $filename) to tests.", Project::MSG_DEBUG);
+			}
+			
+			$declaredClasses = array_merge($declaredClasses, $definedClasses);
+		}
+		
+		$elements = array_filter($declaredClasses, array($this, "filterTests"));
+
+		return $elements;
+	}
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/phpunit/FormatterElement.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/phpunit/FormatterElement.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/phpunit/FormatterElement.php	(revision 19)
@@ -0,0 +1,150 @@
+<?php
+/**
+ * $Id: FormatterElement.php 325 2007-12-20 15:44:58Z hans $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+require_once 'phing/system/io/PhingFile.php';
+
+/**
+ * A wrapper for the implementations of PHPUnit2ResultFormatter.
+ *
+ * @author Michiel Rook <michiel.rook@gmail.com>
+ * @version $Id: FormatterElement.php 325 2007-12-20 15:44:58Z hans $
+ * @package phing.tasks.ext.phpunit
+ * @since 2.1.0
+ */
+class FormatterElement
+{
+	protected $formatter = NULL;
+	
+	protected $type = "";
+	
+	protected $useFile = true;
+	
+	protected $toDir = ".";
+	
+	protected $outfile = "";
+
+	function setType($type)
+	{
+		$this->type = $type;
+		
+		if ($this->type == "summary")
+		{
+			if (PHPUnitUtil::$installedVersion == 3)
+			{
+				require_once 'phing/tasks/ext/phpunit/phpunit3/SummaryPHPUnit3ResultFormatter.php';
+				$this->formatter = new SummaryPHPUnit3ResultFormatter();
+			}
+			else			
+			{
+				require_once 'phing/tasks/ext/phpunit/phpunit2/SummaryPHPUnit2ResultFormatter.php';
+				$this->formatter = new SummaryPHPUnit2ResultFormatter();
+			}
+		}
+		else
+		if ($this->type == "xml")
+		{
+			$destFile = new PhingFile($this->toDir, 'testsuites.xml');
+
+			if (PHPUnitUtil::$installedVersion == 3)
+			{
+				require_once 'phing/tasks/ext/phpunit/phpunit3/XMLPHPUnit3ResultFormatter.php';
+				$this->formatter = new XMLPHPUnit3ResultFormatter();
+			}
+			else
+			{
+				require_once 'phing/tasks/ext/phpunit/phpunit2/XMLPHPUnit2ResultFormatter.php';
+				$this->formatter = new XMLPHPUnit2ResultFormatter();
+			}
+		}
+		else
+		if ($this->type == "plain")
+		{
+			if (PHPUnitUtil::$installedVersion == 3)
+			{
+				require_once 'phing/tasks/ext/phpunit/phpunit3/PlainPHPUnit3ResultFormatter.php';
+				$this->formatter = new PlainPHPUnit3ResultFormatter();
+			}
+			else
+			{
+				require_once 'phing/tasks/ext/phpunit/phpunit2/PlainPHPUnit2ResultFormatter.php';
+				$this->formatter = new PlainPHPUnit2ResultFormatter();
+			}
+		}
+		else
+		{
+			throw new BuildException("Formatter '" . $this->type . "' not implemented");
+		}
+	}
+
+	function setClassName($className)
+	{
+		$classNameNoDot = Phing::import($className);
+
+		$this->formatter = new $classNameNoDot();
+	}
+
+	function setUseFile($useFile)
+	{
+		$this->useFile = $useFile;
+	}
+	
+	function getUseFile()
+	{
+		return $this->useFile;
+	}
+	
+	function setToDir($toDir)
+	{
+		$this->toDir = $toDir;
+	}
+	
+	function getToDir()
+	{
+		return $this->toDir;
+	}
+
+	function setOutfile($outfile)
+	{
+		$this->outfile = $outfile;
+	}
+	
+	function getOutfile()
+	{
+		if ($this->outfile)
+		{
+			return $this->outfile;
+		}
+		else
+		{
+			return $this->formatter->getPreferredOutfile() . $this->getExtension();
+		}
+	}
+	
+	function getExtension()
+	{
+		return $this->formatter->getExtension();
+	}
+
+	function getFormatter()
+	{
+		return $this->formatter;
+	}
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/phpunit/PHPUnitReportTask.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/phpunit/PHPUnitReportTask.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/phpunit/PHPUnitReportTask.php	(revision 19)
@@ -0,0 +1,186 @@
+<?php
+/**
+ * $Id: PHPUnitReportTask.php 325 2007-12-20 15:44:58Z hans $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+require_once 'phing/Task.php';
+require_once 'phing/system/io/PhingFile.php';
+require_once 'phing/system/io/FileWriter.php';
+require_once 'phing/util/ExtendedFileStream.php';
+
+/**
+ * Transform a PHPUnit2 xml report using XSLT.
+ * This transformation generates an html report in either framed or non-framed
+ * style. The non-framed style is convenient to have a concise report via mail, 
+ * the framed report is much more convenient if you want to browse into 
+ * different packages or testcases since it is a Javadoc like report.
+ *
+ * @author Michiel Rook <michiel.rook@gmail.com>
+ * @version $Id: PHPUnitReportTask.php 325 2007-12-20 15:44:58Z hans $
+ * @package phing.tasks.ext.phpunit
+ * @since 2.1.0
+ */
+class PHPUnitReportTask extends Task
+{
+	private $format = "noframes";
+	private $styleDir = "";
+	private $toDir = "";
+
+	/** the directory where the results XML can be found */
+	private $inFile = "testsuites.xml";
+
+	/**
+	 * Set the filename of the XML results file to use.
+	 */
+	function setInFile($inFile)
+	{
+		$this->inFile = $inFile;
+	}
+
+	/**
+	 * Set the format of the generated report. Must be noframes or frames.
+	 */
+	function setFormat($format)
+	{
+		$this->format = $format;
+	}
+
+	/**
+	 * Set the directory where the stylesheets are located.
+	 */
+	function setStyleDir($styleDir)
+	{
+		$this->styleDir = $styleDir;
+	}
+
+	/**
+	 * Set the directory where the files resulting from the 
+	 * transformation should be written to.
+	 */
+	function setToDir($toDir)
+	{
+		$this->toDir = $toDir;
+	}
+	
+	/**
+	 * Returns the path to the XSL stylesheet
+	 */
+	private function getStyleSheet()
+	{
+		$xslname = "phpunit2-" . $this->format . ".xsl";
+
+		if ($this->styleDir)
+		{
+			$file = new PhingFile($this->styleDir, $xslname);
+		}
+		else
+		{
+			$path = Phing::getResourcePath("phing/etc/$xslname");
+			
+			if ($path === NULL)
+			{
+				$path = Phing::getResourcePath("etc/$xslname");
+
+				if ($path === NULL)
+				{
+					throw new BuildException("Could not find $xslname in resource path");
+				}
+			}
+			
+			$file = new PhingFile($path);
+		}
+
+		if (!$file->exists())
+		{
+			throw new BuildException("Could not find file " . $file->getPath());
+		}
+
+		return $file;
+	}
+	
+	/**
+	 * Transforms the DOM document
+	 */
+	private function transform(DOMDocument $document)
+	{
+		$dir = new PhingFile($this->toDir);
+		
+		if (!$dir->exists())
+		{
+			throw new BuildException("Directory '" . $this->toDir . "' does not exist");
+		}
+		
+		$xslfile = $this->getStyleSheet();
+
+		$xsl = new DOMDocument();
+		$xsl->load($xslfile->getAbsolutePath());
+
+		$proc = new XSLTProcessor();
+		$proc->importStyleSheet($xsl);
+
+		if ($this->format == "noframes")
+		{
+			$writer = new FileWriter(new PhingFile($this->toDir, "phpunit2-noframes.html"));
+			$writer->write($proc->transformToXML($document));
+			$writer->close();
+		}
+		else
+		{
+			ExtendedFileStream::registerStream();
+
+			// no output for the framed report
+			// it's all done by extension...
+			$dir = new PhingFile($this->toDir);
+			$proc->setParameter('', 'output.dir', $dir->getAbsolutePath());
+			$proc->transformToXML($document);
+		}
+	}
+	
+	/**
+	 * Fixes 'testsuite' elements with no package attribute, adds
+	 * package="default" to those elements.
+	 */
+	private function fixPackages(DOMDocument $document)
+	{
+		$testsuites = $document->getElementsByTagName('testsuite');
+		
+		foreach ($testsuites as $testsuite)
+		{
+			if (!$testsuite->hasAttribute('package'))
+			{
+				$testsuite->setAttribute('package', 'default');
+			}
+		}
+	}
+
+	/**
+	 * The main entry point
+	 *
+	 * @throws BuildException
+	 */
+	public function main()
+	{
+		$testSuitesDoc = new DOMDocument();
+		$testSuitesDoc->load($this->inFile);
+		
+		$this->fixPackages($testSuitesDoc);
+		
+		$this->transform($testSuitesDoc);
+	}
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/phpunit/PHPUnitTask.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/phpunit/PHPUnitTask.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/phpunit/PHPUnitTask.php	(revision 19)
@@ -0,0 +1,390 @@
+<?php
+/**
+ * $Id: PHPUnitTask.php 350 2008-02-06 15:06:57Z mrook $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+require_once 'phing/Task.php';
+require_once 'phing/system/io/PhingFile.php';
+require_once 'phing/system/io/Writer.php';
+require_once 'phing/util/LogWriter.php';
+
+/**
+ * Runs PHPUnit2/3 tests.
+ *
+ * @author Michiel Rook <michiel.rook@gmail.com>
+ * @version $Id: PHPUnitTask.php 350 2008-02-06 15:06:57Z mrook $
+ * @package phing.tasks.ext.phpunit
+ * @see BatchTest
+ * @since 2.1.0
+ */
+class PHPUnitTask extends Task
+{
+	private $batchtests = array();
+	private $formatters = array();
+	private $haltonerror = false;
+	private $haltonfailure = false;
+	private $haltonincomplete = false;
+	private $haltonskipped = false;
+	private $errorproperty;
+	private $failureproperty;
+	private $incompleteproperty;
+	private $skippedproperty;
+	private $printsummary = false;
+	private $testfailed = false;
+	private $codecoverage = false;
+	private $groups = array();
+	private $excludeGroups = array();
+
+	/**
+	 * Initialize Task.
+ 	 * This method includes any necessary PHPUnit2 libraries and triggers
+	 * appropriate error if they cannot be found.  This is not done in header
+	 * because we may want this class to be loaded w/o triggering an error.
+	 */
+	function init() {
+		if (version_compare(PHP_VERSION, '5.0.3') < 0) {
+		    throw new BuildException("PHPUnit2Task requires PHP version >= 5.0.3.", $this->getLocation());
+		}
+		
+		/**
+		 * Determine PHPUnit version number
+		 */
+		@include_once 'PHPUnit/Runner/Version.php';
+		@include_once 'PHPUnit2/Runner/Version.php';
+
+		if (class_exists('PHPUnit_Runner_Version'))
+		{
+			$version = PHPUnit_Runner_Version::id();
+		}
+		elseif (class_exists('PHPUnit2_Runner_Version'))
+		{
+			$version = PHPUnit2_Runner_Version::id();
+		}
+		else
+		{
+			throw new BuildException("PHPUnit task depends on PHPUnit 2 or 3 package being installed.", $this->getLocation());
+		}
+		
+		if (version_compare($version, "3.0.0") >= 0)
+		{
+			PHPUnitUtil::$installedVersion = 3;
+			if (version_compare($version, "3.2.0") >= 0)
+			{
+				PHPUnitUtil::$installedMinorVersion = 2;
+			}
+		}
+		else
+		{
+			PHPUnitUtil::$installedVersion = 2;
+		}
+		
+		/**
+		 * Other dependencies that should only be loaded when class is actually used.
+		 */
+		require_once 'phing/tasks/ext/phpunit/PHPUnitTestRunner.php';
+		require_once 'phing/tasks/ext/phpunit/BatchTest.php';
+		require_once 'phing/tasks/ext/phpunit/FormatterElement.php';
+
+		/**
+		 * Add some defaults to the PHPUnit filter
+		 */
+		if (PHPUnitUtil::$installedVersion == 3)
+		{
+			require_once 'PHPUnit/Framework.php';
+			require_once 'PHPUnit/Util/Filter.php';
+			
+			// point PHPUnit_MAIN_METHOD define to non-existing method
+			if (!defined('PHPUnit_MAIN_METHOD')) {
+				define('PHPUnit_MAIN_METHOD', 'PHPUnitTask::undefined');
+			}
+			
+			PHPUnit_Util_Filter::addFileToFilter('PHPUnitTask.php', 'PHING');
+			PHPUnit_Util_Filter::addFileToFilter('PHPUnitTestRunner.php', 'PHING');
+			PHPUnit_Util_Filter::addFileToFilter('phing/Task.php', 'PHING');
+			PHPUnit_Util_Filter::addFileToFilter('phing/Target.php', 'PHING');
+			PHPUnit_Util_Filter::addFileToFilter('phing/Project.php', 'PHING');
+			PHPUnit_Util_Filter::addFileToFilter('phing/Phing.php', 'PHING');
+			PHPUnit_Util_Filter::addFileToFilter('phing.php', 'PHING');
+		}
+		else
+		{
+			require_once 'PHPUnit2/Framework.php';
+			require_once 'PHPUnit2/Util/Filter.php';
+			
+			PHPUnit2_Util_Filter::addFileToFilter('PHPUnitTask.php');
+			PHPUnit2_Util_Filter::addFileToFilter('PHPUnitTestRunner.php');
+			PHPUnit2_Util_Filter::addFileToFilter('phing/Task.php');
+			PHPUnit2_Util_Filter::addFileToFilter('phing/Target.php');
+			PHPUnit2_Util_Filter::addFileToFilter('phing/Project.php');
+			PHPUnit2_Util_Filter::addFileToFilter('phing/Phing.php');
+			PHPUnit2_Util_Filter::addFileToFilter('phing.php');
+		}
+	}
+	
+	function setErrorproperty($value)
+	{
+		$this->errorproperty = $value;
+	}
+	
+	function setFailureproperty($value)
+	{
+		$this->failureproperty = $value;
+	}
+	
+	function setIncompleteproperty($value)
+	{
+		$this->incompleteproperty = $value;
+	}
+	
+	function setSkippedproperty($value)
+	{
+		$this->skippedproperty = $value;
+	}
+	
+	function setHaltonerror($value)
+	{
+		$this->haltonerror = $value;
+	}
+
+	function setHaltonfailure($value)
+	{
+		$this->haltonfailure = $value;
+	}
+
+	function setHaltonincomplete($value)
+	{
+		$this->haltonincomplete = $value;
+	}
+
+	function setHaltonskipped($value)
+	{
+		$this->haltonskipped = $value;
+	}
+
+	function setPrintsummary($printsummary)
+	{
+		$this->printsummary = $printsummary;
+	}
+	
+	function setCodecoverage($codecoverage)
+	{
+		$this->codecoverage = $codecoverage;
+	}
+
+	function setGroups($groups)
+	{
+		if (PHPUnitUtil::$installedVersion < 3 || (PHPUnitUtil::$installedVersion == 3 && PHPUnitUtil::$installedMinorVersion < 2))
+		{
+			$this->log("The 'groups' attribute is only available with PHPUnit 3.2.0 or newer", Project::MSG_WARN);
+		}
+		$token = ' ,;';
+		$this->groups = array();
+		$tok = strtok($groups, $token);
+		while ($tok !== false) {
+			$this->groups[] = $tok;
+			$tok = strtok($token);
+		}
+	}
+
+	function setExcludeGroups($excludeGroups)
+	{
+		if (PHPUnitUtil::$installedVersion < 3 || (PHPUnitUtil::$installedVersion == 3 && PHPUnitUtil::$installedMinorVersion < 2))
+		{
+			$this->log("The 'excludeGroups' attribute is only available with PHPUnit 3.2.0 or newer", Project::MSG_WARN);
+		}
+		$token = ' ,;';
+		$this->excludeGroups = array();
+		$tok = strtok($groups, $token);
+		while ($tok !== false) {
+			$this->excludeGroups[] = $tok;
+			$tok = strtok($token);
+		}
+	}
+
+	/**
+	 * Add a new formatter to all tests of this task.
+	 *
+	 * @param FormatterElement formatter element
+	 */
+	function addFormatter(FormatterElement $fe)
+	{
+		$this->formatters[] = $fe;
+	}
+
+	/**
+	 * The main entry point
+	 *
+	 * @throws BuildException
+	 */
+	function main()
+	{
+		$tests = array();
+		
+		if ($this->printsummary)
+		{
+			$fe = new FormatterElement();
+			$fe->setType("summary");
+			$fe->setUseFile(false);
+			$this->formatters[] = $fe;
+		}
+		
+		foreach ($this->batchtests as $batchtest)
+		{
+			$tests = array_merge($tests, $batchtest->elements());
+		}			
+		
+		foreach ($this->formatters as $fe)
+		{
+			$formatter = $fe->getFormatter();			
+			$formatter->setProject($this->getProject());
+
+			if ($fe->getUseFile())
+			{
+				$destFile = new PhingFile($fe->getToDir(), $fe->getOutfile());
+				
+				$writer = new FileWriter($destFile->getAbsolutePath());
+
+				$formatter->setOutput($writer);
+			}
+			else
+			{
+				$formatter->setOutput($this->getDefaultOutput());
+			}
+
+			$formatter->startTestRun();
+		}
+		
+		foreach ($tests as $test)
+		{
+			$suite = NULL;
+			
+			if ((PHPUnitUtil::$installedVersion == 3 && is_subclass_of($test, 'PHPUnit_Framework_TestSuite')) || (PHPUnitUtil::$installedVersion == 2 && is_subclass_of($test, 'PHPUnit2_Framework_TestSuite')))
+			{
+				if (is_object($test))
+				{
+					$suite = $test;
+				}
+				else
+				{
+					$suite = new $test();
+				}
+			}
+			else
+			{
+				if (PHPUnitUtil::$installedVersion == 3)
+				{
+					require_once 'PHPUnit/Framework/TestSuite.php';
+					$suite = new PHPUnit_Framework_TestSuite(new ReflectionClass($test));
+				}
+				else
+				{
+					require_once 'PHPUnit2/Framework/TestSuite.php';
+					$suite = new PHPUnit2_Framework_TestSuite(new ReflectionClass($test));
+				}
+			}
+			
+			$this->execute($suite);
+		}
+
+		foreach ($this->formatters as $fe)
+		{
+			$formatter = $fe->getFormatter();
+			$formatter->endTestRun();
+		}
+		
+		if ($this->testfailed)
+		{
+			throw new BuildException("One or more tests failed");
+		}
+	}
+
+	/**
+	 * @throws BuildException
+	 */
+	private function execute($suite)
+	{
+		$runner = new PHPUnitTestRunner($suite, $this->project, $this->groups, $this->excludeGroups);
+		
+		$runner->setCodecoverage($this->codecoverage);
+
+		foreach ($this->formatters as $fe)
+		{
+			$formatter = $fe->getFormatter();
+
+			$runner->addFormatter($formatter);
+		}
+
+		$runner->run();
+
+		$retcode = $runner->getRetCode();
+		
+		if ($retcode == PHPUnitTestRunner::ERRORS) {
+		    if ($this->errorproperty) {
+				$this->project->setNewProperty($this->errorproperty, true);
+			}
+			if ($this->haltonerror) {
+			    $this->testfailed = true;
+			}
+		} elseif ($retcode == PHPUnitTestRunner::FAILURES) {
+			if ($this->failureproperty) {
+				$this->project->setNewProperty($this->failureproperty, true);
+			}
+			
+			if ($this->haltonfailure) {
+				$this->testfailed = true;
+			}
+		} elseif ($retcode == PHPUnitTestRunner::INCOMPLETES) {
+			if ($this->incompleteproperty) {
+				$this->project->setNewProperty($this->incompleteproperty, true);
+			}
+			
+			if ($this->haltonincomplete) {
+				$this->testfailed = true;
+			}
+		} elseif ($retcode == PHPUnitTestRunner::SKIPPED) {
+			if ($this->skippedproperty) {
+				$this->project->setNewProperty($this->skippedproperty, true);
+			}
+			
+			if ($this->haltonskipped) {
+				$this->testfailed = true;
+			}
+		}
+	}
+
+	private function getDefaultOutput()
+	{
+		return new LogWriter($this);
+	}
+
+	/**
+	 * Adds a set of tests based on pattern matching.
+	 *
+	 * @return BatchTest a new instance of a batch test.
+	 */
+	function createBatchTest()
+	{
+		$batchtest = new BatchTest($this->getProject());
+
+		$this->batchtests[] = $batchtest;
+
+		return $batchtest;
+	}
+}
+
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/phpunit/PHPUnitTestRunner.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/phpunit/PHPUnitTestRunner.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/phpunit/PHPUnitTestRunner.php	(revision 19)
@@ -0,0 +1,140 @@
+<?php
+/**
+ * $Id: PHPUnitTestRunner.php 361 2008-03-08 09:36:07Z mrook $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+require_once 'phing/tasks/ext/coverage/CoverageMerger.php';
+
+require_once 'phing/system/util/Timer.php';
+
+/**
+ * Simple Testrunner for PHPUnit2/3 that runs all tests of a testsuite.
+ *
+ * @author Michiel Rook <michiel.rook@gmail.com>
+ * @version $Id: PHPUnitTestRunner.php 361 2008-03-08 09:36:07Z mrook $
+ * @package phing.tasks.ext.phpunit
+ * @since 2.1.0
+ */
+class PHPUnitTestRunner
+{
+	const SUCCESS = 0;
+	const FAILURES = 1;
+	const ERRORS = 2;
+	const INCOMPLETES = 3;
+	const SKIPPED = 4;
+
+	private $test = NULL;
+	private $suite = NULL;
+	private $retCode = 0;
+	private $formatters = array();
+	
+	private $codecoverage = false;
+	
+	private $project = NULL;
+
+	private $groups = array();
+	private $excludeGroups = array();
+
+	function __construct($suite, Project $project, $groups = array(), $excludeGroups = array())
+	{
+		$this->suite = $suite;
+		$this->project = $project;
+		$this->groups = $groups;
+		$this->excludeGroups = $excludeGroups;
+		$this->retCode = self::SUCCESS;
+	}
+	
+	function setCodecoverage($codecoverage)
+	{
+		$this->codecoverage = $codecoverage;
+	}
+
+	function addFormatter($formatter)
+	{
+		$this->formatters[] = $formatter;
+	}
+
+	function run()
+	{
+		$res = NULL;
+		
+		if (PHPUnitUtil::$installedVersion == 3)
+		{
+			require_once 'PHPUnit/Framework/TestSuite.php';			
+			$res = new PHPUnit_Framework_TestResult();
+		}
+		else
+		{
+			require_once 'PHPUnit2/Framework/TestSuite.php';
+			$res = new PHPUnit2_Framework_TestResult();
+		}
+
+		if ($this->codecoverage)
+		{
+			$res->collectCodeCoverageInformation(TRUE);
+		}
+
+		foreach ($this->formatters as $formatter)
+		{
+			$res->addListener($formatter);
+		}
+
+		$this->suite->run($res, false, $this->groups, $this->excludeGroups);
+		
+		if ($this->codecoverage)
+		{
+			$coverageInformation = $res->getCodeCoverageInformation();
+			
+			if (PHPUnitUtil::$installedVersion == 3)
+			{
+				foreach ($coverageInformation as $coverage_info)
+				{
+					CoverageMerger::merge($this->project, array($coverage_info['files']));
+				}
+			}
+			else
+			{
+				CoverageMerger::merge($this->project, $coverageInformation);
+			}
+		}
+		
+		if ($res->errorCount() != 0)
+		{
+			$this->retCode = self::ERRORS;
+		}
+		else if ($res->failureCount() != 0)
+		{
+			$this->retCode = self::FAILURES;
+		}
+		else if ($res->notImplementedCount() != 0)
+		{
+			$this->retCode = self::INCOMPLETES;
+		}
+		else if (PHPUnitUtil::$installedVersion == 3 && $res->skippedCount() != 0)
+		{
+			$this->retCode = self::SKIPPED;
+		}
+	}
+
+	function getRetCode()
+	{
+		return $this->retCode;
+	}
+}
+
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/phpunit/PHPUnitUtil.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/phpunit/PHPUnitUtil.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/phpunit/PHPUnitUtil.php	(revision 19)
@@ -0,0 +1,131 @@
+<?php
+/**
+ * $Id: PHPUnitUtil.php 325 2007-12-20 15:44:58Z hans $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+/**
+ * Various utility functions
+ *
+ * @author Michiel Rook <michiel.rook@gmail.com>
+ * @version $Id: PHPUnitUtil.php 325 2007-12-20 15:44:58Z hans $
+ * @package phing.tasks.ext.phpunit
+ * @since 2.1.0
+ */
+class PHPUnitUtil
+{
+	/**
+	 * Installed PHPUnit major version
+	 */
+	public static $installedVersion = 2;
+	
+	/**
+	 * Installed PHPUnit minor version
+	 */
+	public static $installedMinorVersion = 0;
+	
+	protected static $definedClasses = array();
+	
+	/**
+	 * Returns the package of a class as defined in the docblock of the class using @package
+	 *
+	 * @param string the name of the class
+	 * @return string the name of the package
+	 */
+	static function getPackageName($classname)
+	{
+		$reflect = new ReflectionClass($classname);
+
+		if (preg_match('/@package[\s]+([\.\w]+)/', $reflect->getDocComment(), $matches))
+		{
+			return $matches[1];
+		}
+		else
+		{
+			return "default";
+		}
+	}
+	
+	/**
+	 * Derives the classname from a filename.
+	 * Assumes that there is only one class defined in that particular file, and that
+	 * the naming follows the dot-path (Java) notation scheme.
+	 *
+	 * @param string the filename
+	 * @return string the name fo the class
+	 */
+	static function getClassFromFileName($filename)
+	{
+		$filename = basename($filename);
+		
+		$rpos = strrpos($filename, '.');
+		
+		if ($rpos != -1)
+		{
+			$filename = substr($filename, 0, $rpos);
+		}
+		
+		return $filename;
+	}
+
+	/**
+	 * @param string the filename
+	 * @param Path optional classpath
+	 * @return array list of classes defined in the file
+	 */
+	static function getDefinedClasses($filename, $classpath = NULL)
+	{
+		$filename = realpath($filename);
+		
+		if (!file_exists($filename))
+		{
+			throw new Exception("File '" . $filename . "' does not exist");
+		}
+		
+		if (isset(self::$definedClasses[$filename]))
+		{
+			return self::$definedClasses[$filename];
+		}
+		
+		Phing::__import($filename, $classpath);
+
+		$declaredClasses = get_declared_classes();
+		
+		foreach ($declaredClasses as $classname)
+		{
+			$reflect = new ReflectionClass($classname);
+			
+			self::$definedClasses[$reflect->getFilename()][] = $classname;
+			
+			if (is_array(self::$definedClasses[$reflect->getFilename()]))
+			{			
+				self::$definedClasses[$reflect->getFilename()] = array_unique(self::$definedClasses[$reflect->getFilename()]);
+			}
+		}
+		
+		if (isset(self::$definedClasses[$filename]))
+		{
+			return self::$definedClasses[$filename];
+		}
+		else
+		{
+			return array();
+		}
+	}
+}
+
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/phpunit/phpunit2/PHPUnit2ResultFormatter.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/phpunit/phpunit2/PHPUnit2ResultFormatter.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/phpunit/phpunit2/PHPUnit2ResultFormatter.php	(revision 19)
@@ -0,0 +1,157 @@
+<?php
+/**
+ * $Id: PHPUnit2ResultFormatter.php 325 2007-12-20 15:44:58Z hans $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+require_once 'PHPUnit2/Framework/TestListener.php';
+
+require_once 'phing/system/io/Writer.php';
+
+/**
+ * This abstract class describes classes that format the results of a PHPUnit2 testrun.
+ *
+ * @author Michiel Rook <michiel.rook@gmail.com>
+ * @version $Id: PHPUnit2ResultFormatter.php 325 2007-12-20 15:44:58Z hans $
+ * @package phing.tasks.ext.phpunit.phpunit2
+ * @since 2.1.0
+ */
+abstract class PHPUnit2ResultFormatter implements PHPUnit2_Framework_TestListener
+{
+	protected $out = NULL;
+	
+	protected $project = NULL;
+	
+	private $timer = NULL;
+
+	private $runCount = 0;
+	
+	private $failureCount = 0;
+	
+	private $errorCount = 0;	
+	
+	/**
+	 * Sets the writer the formatter is supposed to write its results to.
+   	 */
+	function setOutput(Writer $out)
+	{
+		$this->out = $out;	
+	}
+
+	/**
+	 * Returns the extension used for this formatter
+	 *
+	 * @return string the extension
+	 */
+	function getExtension()
+	{
+		return "";
+	}
+
+	/**
+	 * Sets the project
+	 *
+	 * @param Project the project
+	 */
+	function setProject(Project $project)
+	{
+		$this->project = $project;
+	}
+	
+	function getPreferredOutfile()
+	{
+		return "";
+	}
+	
+	function startTestRun()
+	{
+	}
+	
+	function endTestRun()
+	{
+	}
+	
+	function startTestSuite(PHPUnit2_Framework_TestSuite $suite)
+	{
+		$this->runCount = 0;
+		$this->failureCount = 0;
+		$this->errorCount = 0;
+		
+		$this->timer = new Timer();
+		$this->timer->start();
+	}
+	
+	function endTestSuite(PHPUnit2_Framework_TestSuite $suite)
+	{
+		$this->timer->stop();
+	}
+
+	function startTest(PHPUnit2_Framework_Test $test)
+	{
+		$this->runCount++;
+	}
+
+	function endTest(PHPUnit2_Framework_Test $test)
+	{
+	}
+
+	function addError(PHPUnit2_Framework_Test $test, Exception $e)
+	{
+		$this->errorCount++;
+	}
+
+	function addFailure(PHPUnit2_Framework_Test $test, PHPUnit2_Framework_AssertionFailedError $t)
+	{
+		$this->failureCount++;
+	}
+
+	function addIncompleteTest(PHPUnit2_Framework_Test $test, Exception $e)
+	{
+	}
+
+	function addSkippedTest(PHPUnit2_Framework_Test $test, Exception $e)
+	{
+	}
+	
+	function getRunCount()
+	{
+		return $this->runCount;
+	}
+	
+	function getFailureCount()
+	{
+		return $this->failureCount;
+	}
+	
+	function getErrorCount()
+	{
+		return $this->errorCount;
+	}
+	
+	function getElapsedTime()
+	{
+		if ($this->timer)
+		{
+			return $this->timer->getElapsedTime();
+		}
+		else
+		{
+			return 0;
+		}
+	}
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/phpunit/phpunit2/PlainPHPUnit2ResultFormatter.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/phpunit/phpunit2/PlainPHPUnit2ResultFormatter.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/phpunit/phpunit2/PlainPHPUnit2ResultFormatter.php	(revision 19)
@@ -0,0 +1,116 @@
+<?php
+/**
+ * $Id: PlainPHPUnit2ResultFormatter.php 325 2007-12-20 15:44:58Z hans $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+require_once 'PHPUnit2/Framework/Test.php';
+require_once 'PHPUnit2/Util/Filter.php';
+
+require_once 'phing/tasks/ext/phpunit/phpunit2/PHPUnit2ResultFormatter.php';
+
+/**
+ * Prints plain text output of the test to a specified Writer.
+ *
+ * @author Michiel Rook <michiel.rook@gmail.com>
+ * @version $Id: PlainPHPUnit2ResultFormatter.php 325 2007-12-20 15:44:58Z hans $
+ * @package phing.tasks.ext.phpunit.phpunit2
+ * @since 2.1.0
+ */
+class PlainPHPUnit2ResultFormatter extends PHPUnit2ResultFormatter
+{
+	private $inner = "";
+	
+	function getExtension()
+	{
+		return ".txt";
+	}
+	
+	function getPreferredOutfile()
+	{
+		return "testresults";
+	}
+
+	function startTestSuite(PHPUnit2_Framework_TestSuite $suite)
+	{
+		parent::startTestSuite($suite);
+		
+		$this->inner = "";
+	}
+	
+	function endTestSuite(PHPUnit2_Framework_TestSuite $suite)
+	{
+		parent::endTestSuite($suite);
+		
+		$sb = "Testsuite: " . $suite->getName() . "\n";
+		$sb.= "Tests run: " . $this->getRunCount();
+		$sb.= ", Failures: " . $this->getFailureCount();
+		$sb.= ", Errors: " . $this->getErrorCount();
+		$sb.= ", Time elapsed: " . $this->getElapsedTime();
+		$sb.= " sec\n";
+
+		if ($this->out != NULL)
+		{
+			$this->out->write($sb);
+			$this->out->write($this->inner);
+		}
+	}
+
+	function addError(PHPUnit2_Framework_Test $test, Exception $e)
+	{
+		parent::addError($test, $e);
+		
+		$this->formatError("ERROR", $test, $e);
+	}
+
+	function addFailure(PHPUnit2_Framework_Test $test, PHPUnit2_Framework_AssertionFailedError $t)
+	{
+		parent::addFailure($test, $t);
+		
+		$this->formatError("FAILED", $test, $t);
+	}
+
+	function addIncompleteTest(PHPUnit2_Framework_Test $test, Exception $e)
+	{
+		parent::addIncompleteTest($test, $e);
+		
+		$this->formatError("INCOMPLETE", $test, $e);
+	}
+
+	private function formatError($type, PHPUnit2_Framework_Test $test, Exception $e)
+	{
+		if ($test != null)
+		{
+			$this->endTest($test);
+		}
+
+		$this->inner.= $test->getName() . " " . $type . "\n";
+		$this->inner.= $e->getMessage() . "\n";
+		$this->inner.= PHPUnit2_Util_Filter::getFilteredStackTrace($e) . "\n";
+	}
+	
+	function endTestRun()
+	{
+		parent::endTestRun();
+		
+		if ($this->out != NULL)
+		{
+			$this->out->close();
+		}
+	}
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/phpunit/phpunit2/SummaryPHPUnit2ResultFormatter.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/phpunit/phpunit2/SummaryPHPUnit2ResultFormatter.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/phpunit/phpunit2/SummaryPHPUnit2ResultFormatter.php	(revision 19)
@@ -0,0 +1,57 @@
+<?php
+/**
+ * $Id: SummaryPHPUnit2ResultFormatter.php 325 2007-12-20 15:44:58Z hans $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+ 
+require_once 'PHPUnit2/Framework/Test.php';
+
+require_once 'phing/tasks/ext/phpunit/phpunit2/PHPUnit2ResultFormatter.php';
+
+/**
+ * Prints short summary output of the test to Phing's logging system.
+ *
+ * @author Michiel Rook <michiel.rook@gmail.com>
+ * @version $Id: SummaryPHPUnit2ResultFormatter.php 325 2007-12-20 15:44:58Z hans $
+ * @package phing.tasks.ext.phpunit.phpunit2
+ * @since 2.1.0
+ */	
+class SummaryPHPUnit2ResultFormatter extends PHPUnit2ResultFormatter
+{
+	function endTestSuite(PHPUnit2_Framework_TestSuite $suite)
+	{
+		parent::endTestSuite($suite);
+		
+		$sb = "Tests run: " . $this->getRunCount();
+		$sb.= ", Failures: " . $this->getFailureCount();
+		$sb.= ", Errors: " . $this->getErrorCount();
+		$sb.= ", Time elapsed: " . $this->getElapsedTime();
+		$sb.= " sec\n";
+		
+		if ($this->out != NULL)
+		{
+			$this->out->write($sb);
+			$this->out->close();
+		}
+	}
+	
+	function getExtension()
+	{
+		return NULL;
+	}
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/phpunit/phpunit2/XMLPHPUnit2ResultFormatter.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/phpunit/phpunit2/XMLPHPUnit2ResultFormatter.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/phpunit/phpunit2/XMLPHPUnit2ResultFormatter.php	(revision 19)
@@ -0,0 +1,116 @@
+<?php
+/**
+ * $Id: XMLPHPUnit2ResultFormatter.php 325 2007-12-20 15:44:58Z hans $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+require_once 'PHPUnit2/Framework/Test.php';
+require_once 'PHPUnit2/Runner/Version.php';
+
+require_once 'PHPUnit2/Util/Log/XML.php';
+
+require_once 'phing/tasks/ext/phpunit/phpunit2/PHPUnit2ResultFormatter.php';
+
+/**
+ * Prints XML output of the test to a specified Writer
+ *
+ * @author Michiel Rook <michiel.rook@gmail.com>
+ * @version $Id: XMLPHPUnit2ResultFormatter.php 325 2007-12-20 15:44:58Z hans $
+ * @package phing.tasks.ext.phpunit.phpunit2
+ * @since 2.1.0
+ */
+class XMLPHPUnit2ResultFormatter extends PHPUnit2ResultFormatter
+{
+	private $logger = NULL;
+	
+	function __construct()
+	{
+		$this->logger = new PHPUnit2_Util_Log_XML();
+		$this->logger->setWriteDocument(false);
+	}
+	
+	function getExtension()
+	{
+		return ".xml";
+	}
+	
+	function getPreferredOutfile()
+	{
+		return "testsuites";
+	}
+	
+	function startTestSuite(PHPUnit2_Framework_TestSuite $suite)
+	{
+		parent::startTestSuite($suite);
+		
+		$this->logger->startTestSuite($suite);
+	}
+	
+	function endTestSuite(PHPUnit2_Framework_TestSuite $suite)
+	{
+		parent::endTestSuite($suite);
+		
+		$this->logger->endTestSuite($suite);
+	}
+	
+	function startTest(PHPUnit2_Framework_Test $test)
+	{
+		parent::startTest($test);
+		
+		$this->logger->startTest($test);
+	}
+
+	function endTest(PHPUnit2_Framework_Test $test)
+	{
+		parent::endTest($test);
+		
+		$this->logger->endTest($test);
+	}
+	
+	function addError(PHPUnit2_Framework_Test $test, Exception $e)
+	{
+		parent::addError($test, $e);
+		
+		$this->logger->addError($test, $e);
+	}
+
+	function addFailure(PHPUnit2_Framework_Test $test, PHPUnit2_Framework_AssertionFailedError $t)
+	{
+		parent::addFailure($test, $t);
+		
+		$this->logger->addFailure($test, $t);
+	}
+
+	function addIncompleteTest(PHPUnit2_Framework_Test $test, Exception $e)
+	{
+		parent::addIncompleteTest($test, $e);
+		
+		$this->logger->addIncompleteTest($test, $e);
+	}
+	
+	function endTestRun()
+	{
+		parent::endTestRun();
+		
+		if ($this->out)
+		{
+			$this->out->write($this->logger->getXML());
+			$this->out->close();
+		}
+	}
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/phpunit/phpunit3/PHPUnit3ResultFormatter.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/phpunit/phpunit3/PHPUnit3ResultFormatter.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/phpunit/phpunit3/PHPUnit3ResultFormatter.php	(revision 19)
@@ -0,0 +1,200 @@
+<?php
+/**
+ * $Id: PHPUnit2ResultFormatter.php 142 2007-02-04 14:06:00Z mrook $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+require_once 'PHPUnit/Framework/TestListener.php';
+
+require_once 'phing/system/io/Writer.php';
+
+/**
+ * This abstract class describes classes that format the results of a PHPUnit2 testrun.
+ *
+ * @author Michiel Rook <michiel.rook@gmail.com>
+ * @version $Id: PHPUnit2ResultFormatter.php 142 2007-02-04 14:06:00Z mrook $
+ * @package phing.tasks.ext.phpunit
+ * @since 2.1.0
+ */
+abstract class PHPUnit3ResultFormatter implements PHPUnit_Framework_TestListener
+{
+	protected $out = NULL;
+	
+	protected $project = NULL;
+	
+	private $timers = false;
+	
+	private $runCounts = false;
+	
+	private $failureCounts = false;
+	
+	private $errorCounts = false;
+	
+	private $incompleteCounts = false;
+	
+	private $skipCounts = false;
+	
+	/**
+	 * Sets the writer the formatter is supposed to write its results to.
+   	 */
+	function setOutput(Writer $out)
+	{
+		$this->out = $out;	
+	}
+
+	/**
+	 * Returns the extension used for this formatter
+	 *
+	 * @return string the extension
+	 */
+	function getExtension()
+	{
+		return "";
+	}
+
+	/**
+	 * Sets the project
+	 *
+	 * @param Project the project
+	 */
+	function setProject(Project $project)
+	{
+		$this->project = $project;
+	}
+	
+	function getPreferredOutfile()
+	{
+		return "";
+	}
+	
+	function startTestRun()
+	{
+		$this->timers = array($this->getMicrotime());
+		$this->runCounts = array(0);
+		$this->failureCounts = array(0);
+		$this->errorCounts = array(0);
+		$this->incompleteCounts = array(0);
+		$this->skipCounts = array(0);
+	}
+	
+	function endTestRun()
+	{
+	}
+	
+	function startTestSuite(PHPUnit_Framework_TestSuite $suite)
+	{
+		$this->timers[] = $this->getMicrotime();
+		$this->runCounts[] = 0;
+		$this->failureCounts[] = 0;
+		$this->errorCounts[] = 0;
+		$this->incompleteCounts[] = 0;
+		$this->skipCounts[] = 0;
+	}
+	
+	function endTestSuite(PHPUnit_Framework_TestSuite $suite)
+	{
+		$lastRunCount = array_pop($this->runCounts);
+		$this->runCounts[count($this->runCounts) - 1] += $lastRunCount;
+		
+		$lastFailureCount = array_pop($this->failureCounts);
+		$this->failureCounts[count($this->failureCounts) - 1] += $lastFailureCount;
+		
+		$lastErrorCount = array_pop($this->errorCounts);
+		$this->errorCounts[count($this->errorCounts) - 1] += $lastErrorCount;
+		
+		$lastIncompleteCount = array_pop($this->incompleteCounts);
+		$this->incompleteCounts[count($this->incompleteCounts) - 1] += $lastIncompleteCount;
+		
+		$lastSkipCount = array_pop($this->skipCounts);
+		$this->skipCounts[count($this->skipCounts) - 1] += $lastSkipCount;
+		
+		array_pop($this->timers);
+	}
+
+	function startTest(PHPUnit_Framework_Test $test)
+	{
+		$this->runCounts[count($this->runCounts) - 1]++;
+	}
+
+	function endTest(PHPUnit_Framework_Test $test, $time)
+	{
+	}
+
+	function addError(PHPUnit_Framework_Test $test, Exception $e, $time)
+	{
+		$this->errorCounts[count($this->errorCounts) - 1]++;
+	}
+
+	function addFailure(PHPUnit_Framework_Test $test, PHPUnit_Framework_AssertionFailedError $e, $time)
+	{
+		$this->failureCounts[count($this->failureCounts) - 1]++;
+	}
+
+	function addIncompleteTest(PHPUnit_Framework_Test $test, Exception $e, $time)
+	{
+		$this->incompleteCounts[count($this->incompleteCounts) - 1]++;
+	}
+
+	function addSkippedTest(PHPUnit_Framework_Test $test, Exception $e, $time)
+	{
+		$this->skipCounts[count($this->skipCounts) - 1]++;
+	}
+	
+	function getRunCount()
+	{
+		return end($this->runCounts);
+	}
+	
+	function getFailureCount()
+	{
+		return end($this->failureCounts);
+	}
+	
+	function getErrorCount()
+	{
+		return end($this->errorCounts);
+	}
+	
+	function getIncompleteCount()
+	{
+		return end($this->incompleteCounts);
+	}
+	
+	function getSkippedCount()
+	{
+		return end($this->skipCounts);
+	}
+	
+	function getElapsedTime()
+	{
+		if (end($this->timers))
+		{
+			return $this->getMicrotime() - end($this->timers);
+		}
+		else
+		{
+			return 0;
+		}
+	}
+
+	private  function getMicrotime() {
+		list($usec, $sec) = explode(' ', microtime());
+		return (float)$usec + (float)$sec;
+	}
+}
+
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/phpunit/phpunit3/PlainPHPUnit3ResultFormatter.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/phpunit/phpunit3/PlainPHPUnit3ResultFormatter.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/phpunit/phpunit3/PlainPHPUnit3ResultFormatter.php	(revision 19)
@@ -0,0 +1,123 @@
+<?php
+/**
+ * $Id: PlainPHPUnit2ResultFormatter.php 142 2007-02-04 14:06:00Z mrook $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+require_once 'phing/tasks/ext/phpunit/phpunit3/PHPUnit3ResultFormatter.php';
+
+/**
+ * Prints plain text output of the test to a specified Writer.
+ *
+ * @author Michiel Rook <michiel.rook@gmail.com>
+ * @version $Id: PlainPHPUnit2ResultFormatter.php 142 2007-02-04 14:06:00Z mrook $
+ * @package phing.tasks.ext.phpunit.phpunit3
+ * @since 2.1.0
+ */
+class PlainPHPUnit3ResultFormatter extends PHPUnit3ResultFormatter
+{
+	private $inner = "";
+	
+	function getExtension()
+	{
+		return ".txt";
+	}
+	
+	function getPreferredOutfile()
+	{
+		return "testresults";
+	}
+
+	function startTestSuite(PHPUnit_Framework_TestSuite $suite)
+	{
+		parent::startTestSuite($suite);
+		
+		$this->inner = "";
+	}
+	
+	function endTestSuite(PHPUnit_Framework_TestSuite $suite)
+	{
+		$sb = "Testsuite: " . $suite->getName() . "\n";
+		$sb.= "Tests run: " . $this->getRunCount();
+		$sb.= ", Failures: " . $this->getFailureCount();
+		$sb.= ", Errors: " . $this->getErrorCount();
+		$sb.= ", Incomplete: " . $this->getIncompleteCount();
+		$sb.= ", Skipped: " . $this->getSkippedCount();
+		$sb.= ", Time elapsed: " . sprintf('%0.5f', $this->getElapsedTime()) . " s\n";
+
+		parent::endTestSuite($suite);
+		
+		if ($this->out != NULL)
+		{
+			$this->out->write($sb);
+			$this->out->write($this->inner);
+		}
+	}
+
+	function addError(PHPUnit_Framework_Test $test, Exception $e, $time)
+	{
+		parent::addError($test, $e, $time);
+		
+		$this->formatError("ERROR", $test, $e);
+	}
+
+	function addFailure(PHPUnit_Framework_Test $test, PHPUnit_Framework_AssertionFailedError $e, $time)
+	{
+		parent::addFailure($test, $e, $time);
+		$this->formatError("FAILED", $test, $e);
+	}
+
+	function addIncompleteTest(PHPUnit_Framework_Test $test, Exception $e, $time)
+	{
+		parent::addIncompleteTest($test, $e, $time);
+		
+		$this->formatError("INCOMPLETE", $test);
+	}
+
+	function addSkippedTest(PHPUnit_Framework_Test $test, Exception $e, $time)
+	{
+		parent::addSkippedTest($test, $e, $time);
+		$this->formatError("SKIPPED", $test);
+	}
+
+	private function formatError($type, PHPUnit_Framework_Test $test, Exception $e = null)
+	{
+		if ($test != null)
+		{
+			$this->endTest($test, time());
+		}
+		
+		$this->inner.= $test->getName() . " " . $type . "\n";
+		
+		if ($e !== null) {
+			$this->inner.= $e->getMessage() . "\n";
+			$this->inner.= PHPUnit_Util_Filter::getFilteredStackTrace($e, false) . "\n";
+		}
+	}
+	
+	function endTestRun()
+	{
+		parent::endTestRun();
+		
+		if ($this->out != NULL)
+		{
+			$this->out->close();
+		}
+	}
+}
+
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/phpunit/phpunit3/SummaryPHPUnit3ResultFormatter.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/phpunit/phpunit3/SummaryPHPUnit3ResultFormatter.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/phpunit/phpunit3/SummaryPHPUnit3ResultFormatter.php	(revision 19)
@@ -0,0 +1,58 @@
+<?php
+/**
+ * $Id: SummaryPHPUnit2ResultFormatter.php 142 2007-02-04 14:06:00Z mrook $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+ 
+require_once 'phing/tasks/ext/phpunit/phpunit3/PHPUnit3ResultFormatter.php';
+
+/**
+ * Prints short summary output of the test to Phing's logging system.
+ *
+ * @author Michiel Rook <michiel.rook@gmail.com>
+ * @version $Id: SummaryPHPUnit2ResultFormatter.php 142 2007-02-04 14:06:00Z mrook $
+ * @package phing.tasks.ext.phpunit
+ * @since 2.1.0
+ */	
+class SummaryPHPUnit3ResultFormatter extends PHPUnit3ResultFormatter
+{
+	function endTestSuite(PHPUnit_Framework_TestSuite $suite)
+	{
+		$sb = "Test: " . $suite->getName();
+		$sb.= ", Run: " . $this->getRunCount();
+		$sb.= ", Failures: " . $this->getFailureCount();
+		$sb.= ", Errors: " . $this->getErrorCount();
+		$sb.= ", Incomplete: " . $this->getIncompleteCount();
+		$sb.= ", Skipped: " . $this->getSkippedCount();
+		$sb.= ", Time elapsed: " . sprintf('%0.5f', $this->getElapsedTime()) . " s\n";
+		
+		parent::endTestSuite($suite);
+		
+		if ($this->out != NULL)
+		{
+			$this->out->write($sb);
+			$this->out->close();
+		}
+	}
+	
+	function getExtension()
+	{
+		return NULL;
+	}
+}
+
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/phpunit/phpunit3/XMLPHPUnit3ResultFormatter.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/phpunit/phpunit3/XMLPHPUnit3ResultFormatter.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/phpunit/phpunit3/XMLPHPUnit3ResultFormatter.php	(revision 19)
@@ -0,0 +1,116 @@
+<?php
+/**
+ * $Id: XMLPHPUnit2ResultFormatter.php 142 2007-02-04 14:06:00Z mrook $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+require_once 'PHPUnit/Util/Log/XML.php';
+
+require_once 'phing/tasks/ext/phpunit/phpunit3/PHPUnit3ResultFormatter.php';
+
+/**
+ * Prints XML output of the test to a specified Writer
+ *
+ * @author Michiel Rook <michiel.rook@gmail.com>
+ * @version $Id: XMLPHPUnit2ResultFormatter.php 142 2007-02-04 14:06:00Z mrook $
+ * @package phing.tasks.ext.phpunit
+ * @since 2.1.0
+ */
+class XMLPHPUnit3ResultFormatter extends PHPUnit3ResultFormatter
+{
+	/**
+	 * @var PHPUnit_Util_Log_XML
+	 */
+	private $logger = NULL;
+	
+	function __construct()
+	{
+		$this->logger = new PHPUnit_Util_Log_XML();
+		$this->logger->setWriteDocument(false);
+	}
+	
+	function getExtension()
+	{
+		return ".xml";
+	}
+	
+	function getPreferredOutfile()
+	{
+		return "testsuites";
+	}
+	
+	function startTestSuite(PHPUnit_Framework_TestSuite $suite)
+	{
+		parent::startTestSuite($suite);
+		
+		$this->logger->startTestSuite($suite);
+	}
+	
+	function endTestSuite(PHPUnit_Framework_TestSuite $suite)
+	{
+		parent::endTestSuite($suite);
+		
+		$this->logger->endTestSuite($suite);
+	}
+	
+	function startTest(PHPUnit_Framework_Test $test)
+	{
+		parent::startTest($test);
+		
+		$this->logger->startTest($test);
+	}
+
+	function endTest(PHPUnit_Framework_Test $test, $time)
+	{
+		parent::endTest($test, $time);
+		
+		$this->logger->endTest($test, $time);
+	}
+	
+	function addError(PHPUnit_Framework_Test $test, Exception $e, $time)
+	{
+		parent::addError($test, $e, $time);
+		
+		$this->logger->addError($test, $e, $time);
+	}
+
+	function addFailure(PHPUnit_Framework_Test $test, PHPUnit_Framework_AssertionFailedError $e, $time)
+	{
+		parent::addFailure($test, $e, $time);
+
+		$this->logger->addFailure($test, $e, $time);
+	}
+
+	function addIncompleteTest(PHPUnit_Framework_Test $test, Exception $e, $time)
+	{
+		parent::addIncompleteTest($test, $e, $time);
+		
+		$this->logger->addIncompleteTest($test, $e, $time);
+	}
+	
+	function endTestRun()
+	{
+		parent::endTestRun();
+		
+		if ($this->out)
+		{
+			$this->out->write($this->logger->getXML());
+			$this->out->close();
+		}
+	}
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/simpletest/SimpleTestCountResultFormatter.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/simpletest/SimpleTestCountResultFormatter.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/simpletest/SimpleTestCountResultFormatter.php	(revision 19)
@@ -0,0 +1,51 @@
+<?php
+/**
+ * $Id: SimpleTestCountResultFormatter.php 325 2007-12-20 15:44:58Z hans $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+require_once 'phing/tasks/ext/simpletest/SimpleTestResultFormatter.php';
+
+/**
+ * Dummy result formatter used to count SimpleTest results
+ *
+ * @author Michiel Rook <michiel.rook@gmail.com>
+ * @version $Id: SimpleTestCountResultFormatter.php 325 2007-12-20 15:44:58Z hans $
+ * @package phing.tasks.ext.simpletest
+ * @since 2.2.0
+ */
+class SimpleTestCountResultFormatter extends SimpleTestResultFormatter
+{
+	const SUCCESS = 0;
+	const FAILURES = 1;
+	const ERRORS = 2;
+	
+	function getRetCode()
+	{
+		if ($this->getExceptionCount() != 0)
+		{
+			return self::ERRORS;
+		}
+		else if ($this->getFailCount() != 0)
+		{
+			return self::FAILURES;
+		}
+		
+		return self::SUCCESS;
+	}	
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/simpletest/SimpleTestFormatterElement.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/simpletest/SimpleTestFormatterElement.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/simpletest/SimpleTestFormatterElement.php	(revision 19)
@@ -0,0 +1,61 @@
+<?php
+/**
+ * $Id: SimpleTestFormatterElement.php 357 2008-02-26 08:51:59Z mrook $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+require_once 'phing/tasks/ext/simpletest/SimpleTestPlainResultFormatter.php';
+require_once 'phing/tasks/ext/simpletest/SimpleTestSummaryResultFormatter.php';
+require_once 'phing/tasks/ext/phpunit/FormatterElement.php';
+
+/**
+ * Child class of "FormatterElement", overrides setType to provide other
+ * formatter classes for SimpleTest
+ *
+ * @author Michiel Rook <michiel.rook@gmail.com>
+ * @version $Id: SimpleTestFormatterElement.php 357 2008-02-26 08:51:59Z mrook $
+ * @package phing.tasks.ext.simpletest
+ * @since 2.2.0
+ */
+class SimpleTestFormatterElement extends FormatterElement
+{
+	function setType($type)
+	{
+		$this->type = $type;
+
+		if ($this->type == "xml")
+		{
+			$destFile = new PhingFile($this->toDir, 'testsuites.xml');
+			//$this->formatter = new SimpleTestXmlResultFormatter();
+		}
+		else
+		if ($this->type == "plain")
+		{
+			$this->formatter = new SimpleTestPlainResultFormatter();
+		}
+		else
+		if ($this->type == "summary")
+		{
+			$this->formatter = new SimpleTestSummaryResultFormatter();
+		}
+		else
+		{
+			throw new BuildException("Formatter '" . $this->type . "' not implemented");
+		}
+	}
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/simpletest/SimpleTestPlainResultFormatter.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/simpletest/SimpleTestPlainResultFormatter.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/simpletest/SimpleTestPlainResultFormatter.php	(revision 19)
@@ -0,0 +1,94 @@
+<?php
+/**
+ * $Id: SimpleTestPlainResultFormatter.php 325 2007-12-20 15:44:58Z hans $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+require_once 'phing/tasks/ext/simpletest/SimpleTestResultFormatter.php';
+
+/**
+ * Prints plain text output of the test to a specified Writer.
+ *
+ * @author Michiel Rook <michiel.rook@gmail.com>
+ * @version $Id: SimpleTestPlainResultFormatter.php 325 2007-12-20 15:44:58Z hans $
+ * @package phing.tasks.ext.simpletest
+ * @since 2.2.0
+ */
+class SimpleTestPlainResultFormatter extends SimpleTestResultFormatter
+{
+	private $inner = "";
+	
+	function getExtension()
+	{
+		return ".txt";
+	}
+	
+	function getPreferredOutfile()
+	{
+		return "testresults";
+	}
+
+	function paintCaseStart($test_name)
+	{
+		parent::paintCaseStart($test_name);
+		
+		$this->inner = "";
+	}
+	
+	function paintCaseEnd($test_name)
+	{
+		parent::paintCaseEnd($test_name);
+		
+		/* Only count suites where more than one test was run */
+		if ($this->getRunCount())
+		{
+			$sb.= "Testsuite: $test_name\n";
+			$sb.= "Tests run: " . $this->getRunCount();
+			$sb.= ", Failures: " . $this->getFailureCount();
+			$sb.= ", Errors: " . $this->getErrorCount();
+			$sb.= ", Time elapsed: " . $this->getElapsedTime();
+			$sb.= " sec\n";
+
+			if ($this->out != NULL)
+			{
+				$this->out->write($sb);
+				$this->out->write($this->inner);
+			}
+		}
+	}
+
+	function paintError($message)
+	{
+		parent::paintError($message);
+		
+		$this->formatError("ERROR", $message);
+	}
+
+	function paintFail($message)
+	{
+		parent::paintFail($message);
+		
+		$this->formatError("FAILED", $message);
+	}
+
+	private function formatError($type, $message)
+	{
+		$this->inner.= $this->getTestName() . " " . $type . "\n";
+		$this->inner.= $message . "\n";	
+	}
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/simpletest/SimpleTestResultFormatter.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/simpletest/SimpleTestResultFormatter.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/simpletest/SimpleTestResultFormatter.php	(revision 19)
@@ -0,0 +1,161 @@
+<?php
+/**
+ * $Id: SimpleTestResultFormatter.php 325 2007-12-20 15:44:58Z hans $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+require_once 'simpletest/scorer.php';
+
+require_once 'phing/system/io/Writer.php';
+
+/**
+ * This abstract class describes classes that format the results of a SimpleTest testrun.
+ *
+ * @author Michiel Rook <michiel.rook@gmail.com>
+ * @version $Id: SimpleTestResultFormatter.php 325 2007-12-20 15:44:58Z hans $
+ * @package phing.tasks.ext.phpunit2
+ * @since 2.2.0
+ */
+abstract class SimpleTestResultFormatter extends SimpleReporter
+{
+	protected $out = NULL;
+	
+	protected $project = NULL;
+	
+	private $timer = NULL;
+
+	private $runCount = 0;
+	
+	private $failureCount = 0;
+	
+	private $errorCount = 0;	
+
+	private $currentTest = "";
+	
+	/**
+	 * Sets the writer the formatter is supposed to write its results to.
+   	 */
+	function setOutput(Writer $out)
+	{
+		$this->out = $out;	
+	}
+
+	/**
+	 * Returns the extension used for this formatter
+	 *
+	 * @return string the extension
+	 */
+	function getExtension()
+	{
+		return "";
+	}
+
+	/**
+	 * Sets the project
+	 *
+	 * @param Project the project
+	 */
+	function setProject(Project $project)
+	{
+		$this->project = $project;
+	}
+	
+	function getPreferredOutfile()
+	{
+		return "";
+	}
+	
+	function paintMethodStart($test_name)
+	{
+		parent::paintMethodStart($test_name);
+		
+		$this->currentTest = $test_name;
+	}
+	
+	function paintMethodEnd($test_name)
+	{
+		parent::paintMethodEnd($test_name);
+		
+		$this->runCount++;
+	}
+	
+	function paintCaseStart($test_name)
+	{
+		parent::paintCaseStart($test_name);
+		
+		$this->runCount = 0;
+		$this->failureCount = 0;
+		$this->errorCount = 0;
+		
+		$this->timer = new Timer();
+		$this->timer->start();
+	}
+		
+	function paintCaseEnd($test_name)
+	{
+		parent::paintCaseEnd($test_name);
+		
+		$this->timer->stop();
+	}
+
+	function paintError($message)
+	{
+		parent::paintError($message);
+		
+		$this->errorCount++;
+	}
+
+	function paintFail($message)
+	{
+		parent::paintFail($message);
+		
+		$this->failureCount++;
+	}
+
+	function getRunCount()
+	{
+		return $this->runCount;
+	}
+	
+	function getFailureCount()
+	{
+		return $this->failureCount;
+	}
+	
+	function getErrorCount()
+	{
+		return $this->errorCount;
+	}
+	
+	function getTestName()
+	{
+		return $this->currentTest;
+	}
+	
+	function getElapsedTime()
+	{
+		if ($this->timer)
+		{
+			return $this->timer->getElapsedTime();
+		}
+		else
+		{
+			return 0;
+		}
+	}
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/simpletest/SimpleTestSummaryResultFormatter.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/simpletest/SimpleTestSummaryResultFormatter.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/simpletest/SimpleTestSummaryResultFormatter.php	(revision 19)
@@ -0,0 +1,53 @@
+<?php
+/**
+ * $Id: SimpleTestSummaryResultFormatter.php 325 2007-12-20 15:44:58Z hans $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+require_once 'phing/tasks/ext/simpletest/SimpleTestResultFormatter.php';
+
+/**
+ * Prints short summary output of the test to Phing's logging system.
+ *
+ * @author Michiel Rook <michiel.rook@gmail.com>
+ * @version $Id: SimpleTestSummaryResultFormatter.php 325 2007-12-20 15:44:58Z hans $
+ * @package phing.tasks.ext.simpletest
+ * @since 2.2.0
+ */
+class SimpleTestSummaryResultFormatter extends SimpleTestResultFormatter
+{
+	function paintCaseEnd($test_name)
+	{
+		parent::paintCaseEnd($test_name);
+		
+		/* Only count suites where more than one test was run */
+		if ($this->getRunCount())
+		{
+			$sb.= "Tests run: " . $this->getRunCount();
+			$sb.= ", Failures: " . $this->getFailureCount();
+			$sb.= ", Errors: " . $this->getErrorCount();
+			$sb.= ", Time elapsed: " . $this->getElapsedTime();
+			$sb.= " sec\n";
+
+			if ($this->out != NULL)
+			{
+				$this->out->write($sb);
+			}
+		}
+	}
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/simpletest/SimpleTestTask.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/simpletest/SimpleTestTask.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/simpletest/SimpleTestTask.php	(revision 19)
@@ -0,0 +1,237 @@
+<?php
+/**
+ * $Id: SimpleTestTask.php 325 2007-12-20 15:44:58Z hans $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+require_once 'phing/Task.php';
+require_once 'phing/system/io/PhingFile.php';
+require_once 'phing/system/io/Writer.php';
+require_once 'phing/util/LogWriter.php';
+
+/**
+ * Runs SimpleTest tests.
+ *
+ * @author Michiel Rook <michiel.rook@gmail.com>
+ * @version $Id: SimpleTestTask.php 325 2007-12-20 15:44:58Z hans $
+ * @package phing.tasks.ext.simpletest
+ * @since 2.2.0
+ */
+class SimpleTestTask extends Task
+{
+	private $formatters = array();
+	private $haltonerror = false;
+	private $haltonfailure = false;
+	private $failureproperty;
+	private $errorproperty;
+	private $printsummary = false;
+	private $testfailed = false;
+
+	/**
+	 * Initialize Task.
+ 	 * This method includes any necessary SimpleTest libraries and triggers
+	 * appropriate error if they cannot be found.  This is not done in header
+	 * because we may want this class to be loaded w/o triggering an error.
+	 */
+	function init() {
+		@include_once 'simpletest/scorer.php';
+		
+		if (!class_exists('SimpleReporter')) {
+			throw new BuildException("SimpleTestTask depends on SimpleTest package being installed.", $this->getLocation());
+		}
+		
+		require_once 'simpletest/reporter.php';
+		require_once 'simpletest/xml.php';
+		require_once 'simpletest/test_case.php';
+		require_once 'phing/tasks/ext/simpletest/SimpleTestCountResultFormatter.php';
+		require_once 'phing/tasks/ext/simpletest/SimpleTestFormatterElement.php';
+	}
+	
+	function setFailureproperty($value)
+	{
+		$this->failureproperty = $value;
+	}
+	
+	function setErrorproperty($value)
+	{
+		$this->errorproperty = $value;
+	}
+	
+	function setHaltonerror($value)
+	{
+		$this->haltonerror = $value;
+	}
+
+	function setHaltonfailure($value)
+	{
+		$this->haltonfailure = $value;
+	}
+
+	function setPrintsummary($printsummary)
+	{
+		$this->printsummary = $printsummary;
+	}
+	
+	/**
+	 * Add a new formatter to all tests of this task.
+	 *
+	 * @param SimpleTestFormatterElement formatter element
+	 */
+	function addFormatter(SimpleTestFormatterElement $fe)
+	{
+		$this->formatters[] = $fe;
+	}
+
+	/**
+	 * Add a new fileset containing the XML results to aggregate
+	 *
+	 * @param FileSet the new fileset containing XML results.
+	 */
+	function addFileSet(FileSet $fileset)
+	{
+		$this->filesets[] = $fileset;
+	}
+
+	/**
+	 * Iterate over all filesets and return the filename of all files
+	 * that end with .php.
+	 *
+	 * @return array an array of filenames
+	 */
+	private function getFilenames()
+	{
+		$filenames = array();
+
+		foreach ($this->filesets as $fileset)
+		{
+			$ds = $fileset->getDirectoryScanner($this->project);
+			$ds->scan();
+
+			$files = $ds->getIncludedFiles();
+
+			foreach ($files as $file)
+			{
+				if (strstr($file, ".php"))
+				{
+					$filenames[] = $ds->getBaseDir() . "/" . $file;
+				}
+			}
+		}
+
+		return $filenames;
+	}
+
+	/**
+	 * The main entry point
+	 *
+	 * @throws BuildException
+	 */
+	function main()
+	{
+		$group = new GroupTest();
+		
+		$filenames = $this->getFilenames();
+		
+		foreach ($filenames as $testfile)
+		{
+			$group->addTestFile($testfile);
+		}
+		
+		if ($this->printsummary)
+		{
+			$fe = new SimpleTestFormatterElement();
+			$fe->setType('summary');
+			$fe->setUseFile(false);
+			$this->formatters[] = $fe;
+		}
+		
+		foreach ($this->formatters as $fe)
+		{
+			$formatter = $fe->getFormatter();
+			$formatter->setProject($this->getProject());
+
+			if ($fe->getUseFile())
+			{
+				$destFile = new PhingFile($fe->getToDir(), $fe->getOutfile());
+				
+				$writer = new FileWriter($destFile->getAbsolutePath());
+
+				$formatter->setOutput($writer);
+			}
+			else
+			{
+				$formatter->setOutput($this->getDefaultOutput());
+			}
+		}
+		
+		$this->execute($group);
+		
+		if ($this->testfailed)
+		{
+			throw new BuildException("One or more tests failed");
+		}
+	}
+	
+	private function execute($suite)
+	{
+		$counter = new SimpleTestCountResultFormatter();
+		$reporter = new MultipleReporter();
+		$reporter->attachReporter($counter);
+		
+		foreach ($this->formatters as $fe)
+		{
+			$formatter = $fe->getFormatter();
+
+			$reporter->attachReporter($formatter);
+		}		
+		
+		$suite->run($reporter);
+		
+		$retcode = $counter->getRetCode();
+		
+		if ($retcode == SimpleTestCountResultFormatter::ERRORS)
+		{
+		    if ($this->errorproperty)
+		    {
+				$this->project->setNewProperty($this->errorproperty, true);
+			}
+			
+			if ($this->haltonerror)
+			{
+			    $this->testfailed = true;
+			}
+		}
+		elseif ($retcode == SimpleTestCountResultFormatter::FAILURES)
+		{
+			if ($this->failureproperty)
+			{
+				$this->project->setNewProperty($this->failureproperty, true);
+			}
+			
+			if ($this->haltonfailure)
+			{
+				$this->testfailed = true;
+			}
+		}
+	}
+
+	private function getDefaultOutput()
+	{
+		return new LogWriter($this);
+	}
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/svn/SvnBaseTask.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/svn/SvnBaseTask.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/svn/SvnBaseTask.php	(revision 19)
@@ -0,0 +1,321 @@
+<?php
+/*
+ *  $Id: SvnBaseTask.php 329 2007-12-22 17:12:59Z mrook $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+ 
+include_once 'phing/Task.php';
+
+/**
+ * Base class for Subversion tasks
+ *
+ * @author Michiel Rook <michiel.rook@gmail.com>
+ * @author Andrew Eddie <andrew.eddie@jamboworks.com> 
+ * @version $Id: SvnBaseTask.php 329 2007-12-22 17:12:59Z mrook $
+ * @package phing.tasks.ext.svn
+ * @see VersionControl_SVN
+ * @since 2.2.0
+ */
+abstract class SvnBaseTask extends Task
+{
+	private $workingCopy = "";
+	
+	private $repositoryUrl = "";
+	
+	private $svnPath = "/usr/bin/svn";
+	
+	private $svn = NULL;
+	
+	private $mode = "";
+	
+	private $svnArgs = array();
+	
+	private $svnSwitches = array();
+
+	private $toDir = "";
+
+	/**
+	 * Initialize Task.
+ 	 * This method includes any necessary SVN libraries and triggers
+	 * appropriate error if they cannot be found.  This is not done in header
+	 * because we may want this class to be loaded w/o triggering an error.
+	 */
+	function init() {
+		include_once 'VersionControl/SVN.php';
+		if (!class_exists('VersionControl_SVN')) {
+			throw new Exception("SvnLastRevisionTask depends on PEAR VersionControl_SVN package being installed.");
+		}
+	}
+
+	/**
+	 * Sets the path to the workingcopy
+	 */
+	function setWorkingCopy($workingCopy)
+	{
+		$this->workingCopy = $workingCopy;
+	}
+
+	/**
+	 * Returns the path to the workingcopy
+	 */
+	function getWorkingCopy()
+	{
+		return $this->workingCopy;
+	}
+
+	/**
+	 * Sets the path/URI to the repository
+	 */
+	function setRepositoryUrl($repositoryUrl)
+	{
+		$this->repositoryUrl = $repositoryUrl;
+	}
+
+	/**
+	 * Returns the path/URI to the repository
+	 */
+	function getRepositoryUrl()
+	{
+		return $this->repositoryUrl;
+	}
+
+	/**
+	 * Sets the path to the SVN executable
+	 */
+	function setSvnPath($svnPath)
+	{
+		$this->svnPath = $svnPath;
+	}
+
+	/**
+	 * Returns the path to the SVN executable
+	 */
+	function getSvnPath()
+	{
+		return $this->svnPath;
+	}
+
+	//
+	// Args
+	//
+
+	/**
+	 * Sets the path to export/checkout to
+	 */
+	function setToDir($toDir)
+	{
+		$this->toDir = $toDir;
+	}
+
+	/**
+	 * Returns the path to export/checkout to
+	 */
+	function getToDir()
+	{
+		return $this->toDir;
+	}
+
+	//
+	// Switches
+	//
+
+	/**
+	 * Sets the force switch
+	 */
+	function setForce($value)
+	{
+		$this->svnSwitches['force'] = $value;
+	}
+
+	/**
+	 * Returns the force switch
+	 */
+	function getForce()
+	{
+		return isset( $this->svnSwitches['force'] ) ? $this->svnSwitches['force'] : '';
+	}
+
+	/**
+	 * Sets the username of the user to export
+	 */
+	function setUsername($value)
+	{
+		$this->svnSwitches['username'] = $value;
+	}
+
+	/**
+	 * Returns the username
+	 */
+	function getUsername()
+	{
+		return isset( $this->svnSwitches['username'] ) ? $this->svnSwitches['username'] : '';
+	}
+
+	/**
+	 * Sets the password of the user to export
+	 */
+	function setPassword($value)
+	{
+		$this->svnSwitches['password'] = $value;
+	}
+
+	/**
+	 * Returns the password
+	 */
+	function getPassword()
+	{
+		return isset( $this->svnSwitches['password'] ) ? $this->svnSwitches['password'] : '';
+	}
+
+	/**
+	 * Sets the no-auth-cache switch
+	 */
+	function setNoCache($value)
+	{
+		$this->svnSwitches['no-auth-cache'] = $value;
+	}
+
+	/**
+	 * Returns the no-auth-cache switch
+	 */
+	function getNoCache()
+	{
+		return isset( $this->svnSwitches['no-auth-cache'] ) ? $this->svnSwitches['no-auth-cache'] : '';
+	}
+	
+	/**
+	 * Sets the non-recursive switch
+	 */
+	function setRecursive($value)
+	{
+		$this->svnSwitches['non-recursive'] = is_bool($value) ? !$value : TRUE;
+	}
+	
+	/**
+	 * Returns the non-recursive switch
+	 */
+	function getRecursive()
+	{
+		return isset( $this->svnSwitches['non-recursive'] ) ? $this->svnSwitches['non-recursive'] : '';
+	}
+
+	/**
+	 * Sets the ignore-externals switch
+	 */
+	function setIgnoreExternals($value)
+	{
+		$this->svnSwitches['ignore-externals'] = $value;
+	}
+	
+	/**
+	 * Returns the ignore-externals switch
+	 */
+	function getIgnoreExternals()
+	{
+		return isset( $this->svnSwitches['ignore-externals'] ) ? $this->svnSwitches['ignore-externals'] : '';
+	}
+	
+	/**
+	 * Creates a VersionControl_SVN class based on $mode
+	 *
+	 * @param string The SVN mode to use (info, export, checkout, ...)
+	 * @throws BuildException
+	 */
+	protected function setup($mode)
+	{
+		$this->mode = $mode;
+		
+		// Set up runtime options. Will be passed to all
+		// subclasses.
+		$options = array('fetchmode' => VERSIONCONTROL_SVN_FETCHMODE_ASSOC, 'svn_path' => $this->getSvnPath());
+		
+		// Pass array of subcommands we need to factory
+		$this->svn = VersionControl_SVN::factory($mode, $options);
+
+		if (!empty($this->repositoryUrl))
+		{
+			$this->svnArgs = array($this->repositoryUrl);
+		}
+		else
+		if (!empty($this->workingCopy))
+		{
+			if (is_dir($this->workingCopy))
+			{
+				if (in_array(".svn", scandir($this->workingCopy)))
+				{
+					$this->svnArgs = array($this->workingCopy);
+				}
+				else
+				{
+					throw new BuildException("'".$this->workingCopy."' doesn't seem to be a working copy");
+				}
+			}
+			else
+			if ($mode=='info' )
+			{
+				if (is_file($this->workingCopy))
+				{
+					$this->svnArgs = array($this->workingCopy);
+				}
+				else
+				{
+					throw new BuildException("'".$this->workingCopy."' is not a directory nor a file");
+				}
+			}
+			else
+			{
+				throw new BuildException("'".$this->workingCopy."' is not a directory");
+			}
+		}
+	}
+	
+	/**
+	 * Executes the constructed VersionControl_SVN instance
+	 *
+	 * @param array Additional arguments to pass to SVN.
+	 * @param array Switches to pass to SVN.
+	 * @return string Output generated by SVN.
+	 */
+	protected function run($args = array(), $switches = array())
+	{
+		$svnstack = PEAR_ErrorStack::singleton('VersionControl_SVN');
+		
+		$tempArgs = $this->svnArgs;
+		
+		$tempArgs = array_merge($tempArgs, $args);
+
+		$tempSwitches = $this->svnSwitches;
+		
+		$tempSwitches = array_merge($tempSwitches, $switches);
+
+		if ($output = $this->svn->run($tempArgs, $tempSwitches))
+		{
+			return $output;
+		}
+		else
+		{
+			if (count($errs = $svnstack->getErrors()))
+			{
+				$err = current($errs);
+
+				throw new BuildException("Failed to run the 'svn " . $this->mode . "' command: " . $err['message']);
+			}
+		}
+	}
+}
+
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/svn/SvnCheckoutTask.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/svn/SvnCheckoutTask.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/svn/SvnCheckoutTask.php	(revision 19)
@@ -0,0 +1,49 @@
+<?php
+/**
+ * $Id: SvnCheckoutTask.php 325 2007-12-20 15:44:58Z hans $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+require_once 'phing/Task.php';
+require_once 'phing/tasks/ext/svn/SvnBaseTask.php';
+
+/**
+ * Checks out a repository to a local directory
+ *
+ * @author Andrew Eddie <andrew.eddie@jamboworks.com>
+ * @version $Id: SvnCheckoutTask.php 325 2007-12-20 15:44:58Z hans $
+ * @package phing.tasks.ext.svn
+ * @since 2.3.0
+ */
+class SvnCheckoutTask extends SvnBaseTask
+{
+	/**
+	 * The main entry point
+	 *
+	 * @throws BuildException
+	 */
+	function main()
+	{
+		$this->setup('checkout');
+
+		$this->log("Checking out SVN repository to '" . $this->getToDir() . "'");
+
+		$this->run(array($this->getToDir()));
+	}
+}
+
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/svn/SvnExportTask.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/svn/SvnExportTask.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/svn/SvnExportTask.php	(revision 19)
@@ -0,0 +1,70 @@
+<?php
+/**
+ * $Id: SvnExportTask.php 363 2008-04-10 16:06:37Z tiddy $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+require_once 'phing/Task.php';
+require_once 'phing/tasks/ext/svn/SvnBaseTask.php';
+
+/**
+ * Exports/checks out a repository to a local directory
+ * with authentication 
+ *
+ * @author Michiel Rook <michiel.rook@gmail.com>
+ * @author Andrew Eddie <andrew.eddie@jamboworks.com> 
+ * @version $Id: SvnExportTask.php 363 2008-04-10 16:06:37Z tiddy $
+ * @package phing.tasks.ext.svn
+ * @since 2.2.0
+ */
+class SvnExportTask extends SvnBaseTask
+{
+#
+    /**
+     * Which Revision to Export
+     * 
+     * @todo check if version_control_svn supports constants
+     * 
+     * @var string
+     */
+    private $revision = 'HEAD';
+
+    /**
+     * The main entry point
+     *
+     * @throws BuildException
+     */
+    function main()
+    {
+        $this->setup('export');
+        
+        $this->log("Exporting SVN repository to '" . $this->getToDir() . "'");
+
+        // revision
+        $switches = array(
+            'r' => $this->revision,
+        );
+
+        $this->run(array($this->getToDir()), $switches);
+    }
+
+    public function setRevision($revision)
+    {
+        $this->revision = $revision;
+    }
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/svn/SvnLastRevisionTask.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/svn/SvnLastRevisionTask.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/svn/SvnLastRevisionTask.php	(revision 19)
@@ -0,0 +1,74 @@
+<?php
+/**
+ * $Id: SvnLastRevisionTask.php 325 2007-12-20 15:44:58Z hans $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+require_once 'phing/Task.php';
+require_once 'phing/tasks/ext/svn/SvnBaseTask.php';
+
+/**
+ * Stores the number of the last revision of a workingcopy in a property
+ *
+ * @author Michiel Rook <michiel.rook@gmail.com>
+ * @version $Id: SvnLastRevisionTask.php 325 2007-12-20 15:44:58Z hans $
+ * @package phing.tasks.ext.svn
+ * @see VersionControl_SVN
+ * @since 2.1.0
+ */
+class SvnLastRevisionTask extends SvnBaseTask
+{
+	private $propertyName = "svn.lastrevision";
+
+	/**
+	 * Sets the name of the property to use
+	 */
+	function setPropertyName($propertyName)
+	{
+		$this->propertyName = $propertyName;
+	}
+
+	/**
+	 * Returns the name of the property to use
+	 */
+	function getPropertyName()
+	{
+		return $this->propertyName;
+	}
+
+	/**
+	 * The main entry point
+	 *
+	 * @throws BuildException
+	 */
+	function main()
+	{
+		$this->setup('info');
+		
+		$output = $this->run();
+		
+		if (preg_match('/Rev:[\s]+([\d]+)/', $output, $matches))
+		{
+			$this->project->setProperty($this->getPropertyName(), $matches[1]);
+		}
+		else
+		{
+			throw new BuildException("Failed to parse the output of 'svn info'.");
+		}
+	}
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/svn/SvnUpdateTask.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/svn/SvnUpdateTask.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/ext/svn/SvnUpdateTask.php	(revision 19)
@@ -0,0 +1,49 @@
+<?php
+/**
+ * $Id: SvnUpdateTask.php 325 2007-12-20 15:44:58Z hans $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+require_once 'phing/Task.php';
+require_once 'phing/tasks/ext/svn/SvnBaseTask.php';
+
+/**
+ * Updates a repository in local directory
+ *
+ * @author Andrew Eddie <andrew.eddie@jamboworks.com>
+ * @version $Id: SvnUpdateTask.php 325 2007-12-20 15:44:58Z hans $
+ * @package phing.tasks.ext.svn
+ * @since 2.3.0
+ */
+class SvnUpdateTask extends SvnBaseTask
+{
+	/**
+	 * The main entry point
+	 *
+	 * @throws BuildException
+	 */
+	function main()
+	{
+		$this->setup('update');
+
+		$this->log("Updating SVN repository at '" . $this->getToDir() . "'");
+
+		$this->run(array($this->getToDir()));
+	}
+}
+
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/system/AdhocTask.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/system/AdhocTask.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/system/AdhocTask.php	(revision 19)
@@ -0,0 +1,88 @@
+<?php
+/*
+ *  $Id: AdhocTask.php 144 2007-02-05 15:19:00Z hans $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+ 
+require_once 'phing/Task.php';
+
+/**
+ * Abstract class for creating adhoc Phing components in buildfile.
+ *
+ * By itself this class can be used to declare a single class within your buildfile.
+ * You can then reference this class in any task that takes custom classes (selectors,
+ * mappers, filters, etc.)
+ * 
+ * Subclasses exist for conveniently declaring and registering tasks and types.
+ * 
+ * @author   Hans Lellelid <hans@xmpl.org>
+ * @version  $Revision: 1.6 $
+ * @package  phing.tasks.system
+ */
+class AdhocTask extends Task {
+            
+    /**
+     * The PHP script
+     * @var string
+     */
+    protected $script;
+    
+    protected $newClasses = array();
+    
+    /**
+     * Main entry point
+     */
+    public function main() {    
+        $this->execute();        
+        if ($this->newClasses) {
+            foreach($this->newClasses as $classname) {
+                $this->log("Added adhoc class " . $classname, Project::MSG_VERBOSE);
+            }
+        } else {
+            $this->log("Adhoc task executed but did not result in any new classes.", Project::MSG_VERBOSE);
+        }
+    }
+    
+    /**
+     * Get array of names of newly defined classes.
+     * @return array
+     */
+    protected function getNewClasses() {
+        return $this->newClasses;
+    }
+    
+    /**
+     * Load the adhoc class, and perform any core validation.
+     * @return string The classname of the ProjectComponent class.
+     * @throws BuildException - if more than one class is defined.
+     */
+    protected function execute() {
+        $classes = get_declared_classes();        
+        eval($this->script);        
+        $this->newClasses = array_diff(get_declared_classes(), $classes);        
+    }
+            
+    /**
+     * Set the script.
+     * @param string $script
+     */
+    public function addText($script) {
+        $this->script = $script;
+    }
+           
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/system/AdhocTaskdefTask.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/system/AdhocTaskdefTask.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/system/AdhocTaskdefTask.php	(revision 19)
@@ -0,0 +1,90 @@
+<?php
+
+/*
+ * $Id: AdhocTaskdefTask.php 144 2007-02-05 15:19:00Z hans $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+ 
+require_once 'phing/tasks/system/AdhocTask.php';
+
+/**
+ * A class for creating adhoc tasks in build file.
+ * 
+ * <target name="test-adhoc">
+ *        <adhoc-task name="foo"><![CDATA[
+ *
+ *            class FooTest extends Task {
+ *                private $bar;
+ *                
+ *                function setBar($bar) {
+ *                    $this->bar = $bar;
+ *                }
+ *                
+ *                function main() {
+ *                    $this->log("In FooTest: " . $this->bar);
+ *                }
+ *            }
+ *
+ *        ]]></adhoc-task>
+ * 
+ *      <foo bar="B.L.I.N.G"/>
+ * </target>
+ *  
+ * @author    Hans Lellelid <hans@xmpl.org>
+ * @version   $Revision: 1.5 $
+ * @package   phing.tasks.system
+ */
+class AdhocTaskdefTask extends AdhocTask {
+
+    /**
+     * The tag that refers to this task.
+     */
+    private $name;
+    
+    /**
+     * Set the tag that will represent this adhoc task/type.
+     * @param string $name
+     */       
+    public function setName($name) {
+        $this->name = $name;
+    }
+    
+    /** Main entry point */
+    public function main() {        
+        if ($this->name === null) {
+            throw new BuildException("The name attribute is required for adhoc task definition.",$this->location);
+        }
+        
+        $this->execute();
+        
+        $classes = $this->getNewClasses();
+        if (count($classes) !== 1) {
+            throw new BuildException("You must define one (and only one) class for AdhocTaskdefTask.");
+        }
+        $classname = array_shift($classes);
+        
+        // instantiate it to make sure it is an instance of Task
+        $t = new $classname();
+        if (!($t instanceof Task)) {
+            throw new BuildException("The adhoc class you defined must be an instance of phing.Task", $this->location);
+        }
+        
+        $this->log("Task " . $this->name . " will be handled by class " . $classname, Project::MSG_VERBOSE);
+        $this->project->addTaskDefinition($this->name, $classname);        
+    }
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/system/AdhocTypedefTask.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/system/AdhocTypedefTask.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/system/AdhocTypedefTask.php	(revision 19)
@@ -0,0 +1,71 @@
+<?php
+
+/*
+ * $Id: AdhocTypedefTask.php 144 2007-02-05 15:19:00Z hans $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+ 
+require_once 'phing/tasks/system/AdhocTask.php';
+
+/**
+ * A class for creating adhoc datatypes in build file.
+ * 
+ * @author    Hans Lellelid <hans@xmpl.org>
+ * @version   $Revision: 1.4 $
+ * @package   phing.tasks.system
+ */
+class AdhocTypedefTask extends AdhocTask {
+
+    /**
+     * The tag that refers to this task.
+     */
+    private $name;
+
+    /**
+     * Set the tag that will represent this adhoc task/type.
+     * @param string $name
+     */       
+    public function setName($name) {
+        $this->name = $name;
+    }
+        
+    /** Main entry point */
+    public function main() {
+    
+        if ($this->name === null) {
+            throw new BuildException("The name attribute is required for adhoc task definition.",$this->location);
+        }
+        
+        $this->execute();
+        
+        $classes = $this->getNewClasses();
+        if (count($classes) !== 1) {
+            throw new BuildException("You must define one (and only one) class for AdhocTypedefTask.");
+        }
+        $classname = array_shift($classes);
+        
+        // instantiate it to make sure it is an instance of ProjectComponent
+        $t = new $classname();
+        if (!($t instanceof ProjectComponent)) {
+            throw new BuildException("The adhoc class you defined must be an instance of phing.ProjectComponent", $this->location);
+        }
+        
+        $this->log("Datatype " . $this->name . " will be handled by class " . $classname, Project::MSG_VERBOSE);
+        $this->project->addDataTypeDefinition($this->name, $classname);        
+    }
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/system/AppendTask.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/system/AppendTask.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/system/AppendTask.php	(revision 19)
@@ -0,0 +1,240 @@
+<?php
+/*
+ *  $Id: AppendTask.php 144 2007-02-05 15:19:00Z hans $  
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+require_once 'phing/Task.php';
+include_once 'phing/types/FileList.php';
+include_once 'phing/types/FileSet.php';
+
+/**
+ *  Appends text, contents of a file or set of files defined by a filelist to a destination file.
+ *
+ * <code>
+ * <append text="And another thing\n" destfile="badthings.log"/>
+ * </code>
+ * OR
+ * <code>
+ * <append file="header.html" destfile="fullpage.html"/>
+ * <append file="body.html" destfile="fullpage.html"/>
+ * <append file="footer.html" destfile="fullpage.html"/>
+ * </code>
+ * OR
+ * <code>
+ * <append destfile="${process.outputfile}">
+ *    <filterchain>
+ *        <xsltfilter style="${process.stylesheet}">
+ *            <param name="mode" expression="${process.xslt.mode}"/>
+ *            <param name="file_name" expression="%{task.append.current_file.basename}"/> <!-- Example of using a RegisterSlot variable -->
+ *        </xsltfilter>
+ *    </filterchain>
+ *     <filelist dir="book/" listfile="book/PhingGuide.book"/>            
+ * </append>
+ * </code>
+ * @package phing.tasks.system
+ * @version $Revision: 1.14 $
+ */
+class AppendTask extends Task {
+    
+    /** Append stuff to this file. */
+    private $to;
+    
+    /** Explicit file to append. */
+    private $file;
+    
+    /** Any filesets of files that should be appended. */
+    private $filesets = array();
+    
+    /** Any filelists of files that should be appended. */
+    private $filelists = array();
+    
+    /** Any filters to be applied before append happens. */
+    private $filterChains = array();
+    
+    /** Text to append. (cannot be used in conjunction w/ files or filesets) */
+    private $text;
+    
+    /** Sets specific file to append. */
+    function setFile(PhingFile $f) {        
+        $this->file = $f;
+    }
+    
+    /**
+     * Set target file to append to.
+     * @deprecated Will be removed with final release.
+     */
+    function setTo(PhingFile $f) {        
+        $this->log("The 'to' attribute is deprecated in favor of 'destFile'; please update your code.", Project::MSG_WARN);
+        $this->to = $f;
+    }
+    
+    /**
+     * The more conventional naming for method to set destination file.
+     * @param PhingFile $f
+     */
+    function setDestFile(PhingFile $f) {        
+        $this->to = $f;
+    }
+    
+    /**
+     * Supports embedded <filelist> element.
+     * @return FileList
+     */
+    function createFileList() {
+        $num = array_push($this->filelists, new FileList());
+        return $this->filelists[$num-1];
+    }
+
+    /**
+     * Nested creator, adds a set of files (nested <fileset> attribute).
+     * This is for when you don't care what order files get appended.
+     * @return FileSet
+     */
+    function createFileSet() {
+        $num = array_push($this->filesets, new FileSet());
+        return $this->filesets[$num-1];
+    }
+    
+    /**
+     * Creates a filterchain
+     *
+     * @return FilterChain The created filterchain object
+     */
+    function createFilterChain() {
+        $num = array_push($this->filterChains, new FilterChain($this->project));
+        return $this->filterChains[$num-1];
+    }    
+    
+    /**
+     * Sets text to append.  (cannot be used in conjunction w/ files or filesets).
+     * @param string $txt
+     */
+    function setText($txt) {
+        $this->text = (string) $txt;
+    }
+
+    /**
+     * Sets text to append. Supports CDATA.
+     * @param string $txt
+     */
+    function addText($txt) {
+        $this->text = (string) $txt;
+    }
+
+    
+    /** Append the file(s). */
+    function main() {
+    
+        if ($this->to === null) {
+            throw new BuildException("You must specify the 'destFile' attribute");
+        }
+        
+        if ($this->file === null && empty($this->filelists) && empty($this->filesets) && $this->text === null) {
+            throw new BuildException("You must specify a file, use a filelist, or specify a text value.");
+        }
+        
+        if ($this->text !== null && ($this->file !== null || !empty($this->filelists))) {
+            throw new BuildException("Cannot use text attribute in conjunction with file or filelists.");
+        }
+        
+        // create a filwriter to append to "to" file.
+        $writer = new FileWriter($this->to, $append=true);
+        
+        if ($this->text !== null) {            
+            
+            // simply append the text
+            $this->log("Appending string to " . $this->to->getPath());
+            
+            // for debugging primarily, maybe comment
+            // out for better performance(?)
+            $lines = explode("\n", $this->text);
+            foreach($lines as $line) {
+                $this->log($line, Project::MSG_VERBOSE);
+            }
+            
+            $writer->write($this->text);
+                        
+        } else {        
+            
+            // append explicitly-specified file
+            if ($this->file !== null) { 
+                try {
+                    $this->appendFile($writer, $this->file);
+                } catch (Exception $ioe) {
+                    $this->log("Unable to append contents of file " . $this->file->getAbsolutePath() . ": " . $ioe->getMessage(), Project::MSG_WARN);
+                }                
+            }
+            
+            // append the files in the filelists
+            foreach($this->filelists as $fl) {
+                try {
+                    $files = $fl->getFiles($this->project);
+                    $this->appendFiles($writer, $files, $fl->getDir($this->project));
+                } catch (BuildException $be) {
+                    $this->log($be->getMessage(), Project::MSG_WARN);
+                }
+            }
+            
+            // append any files in filesets
+            foreach($this->filesets as $fs) {
+                try {
+                    $files = $fs->getDirectoryScanner($this->project)->getIncludedFiles();
+                    $this->appendFiles($writer, $files, $fs->getDir($this->project));
+                } catch (BuildException $be) {
+                    $this->log($be->getMessage(), Project::MSG_WARN);
+                }
+            }                        
+            
+        } // if ($text ) {} else {}
+        
+        $writer->close();
+    }
+    
+    /**
+     * Append an array of files in a directory.
+     * @param FileWriter $writer The FileWriter that is appending to target file.
+     * @param array $files array of files to delete; can be of zero length
+     * @param PhingFile $dir directory to work from
+     */
+    private function appendFiles(FileWriter $writer, $files, PhingFile $dir) {
+        if (!empty($files)) {
+            $this->log("Attempting to append " . count($files) . " files" .($dir !== null ? ", using basedir " . $dir->getPath(): ""));
+            $basenameSlot = Register::getSlot("task.append.current_file");
+            $pathSlot = Register::getSlot("task.append.current_file.path");
+            foreach($files as $filename) {
+                try {
+                    $f = new PhingFile($dir, $filename);
+                    $basenameSlot->setValue($filename);
+                    $pathSlot->setValue($f->getPath());
+                    $this->appendFile($writer, $f);
+                } catch (Exception $ioe) {
+                    $this->log("Unable to append contents of file " . $f->getAbsolutePath() . ": " . $ioe->getMessage(), Project::MSG_WARN);
+                }
+            }
+        } // if !empty        
+    }
+    
+    private function appendFile(FileWriter $writer, PhingFile $f) {
+        $in = FileUtils::getChainedReader(new FileReader($f), $this->filterChains, $this->project);
+        while(-1 !== ($buffer = $in->read())) { // -1 indicates EOF
+            $writer->write($buffer);
+        }
+        $this->log("Appending contents of " . $f->getPath() . " to " . $this->to->getPath());    
+    }
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/system/AvailableTask.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/system/AvailableTask.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/system/AvailableTask.php	(revision 19)
@@ -0,0 +1,135 @@
+<?php
+/*
+ *  $Id: AvailableTask.php 333 2007-12-28 21:30:09Z hans $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+require_once 'phing/Task.php';
+include_once 'phing/tasks/system/condition/ConditionBase.php';
+
+/**
+ *  <available> task.
+ *
+ *  Note: implements condition interface (see condition/Condition.php)
+ *
+ *  @author    Andreas Aderhold <andi@binarycloud.com>
+ *  @copyright ï¿œ 2001,2002 THYRELL. All rights reserved
+ *  @version   $Revision: 1.11 $
+ *  @package   phing.tasks.system
+ */
+class AvailableTask extends Task {
+
+	/** Property to check for. */
+	private $property;
+
+	/** Value property should be set to. */
+	private $value = "true";
+
+	/** Resource to check for */
+	private $resource;
+
+	private $type = null;
+	private $filepath = null;
+
+	function setProperty($property) {
+		$this->property = (string) $property;
+	}
+
+	function setValue($value) {
+		$this->value = (string) $value;
+	}
+
+	function setFile(PhingFile $file) {
+		$this->file = $file;
+	}
+
+	function setResource($resource) {
+		$this->resource = (string) $resource;
+	}
+
+	function setType($type) {
+		$this->type = (string) strtolower($type);
+	}
+
+	function main() {
+		if ($this->property === null) {
+			throw new BuildException("property attribute is required", $this->location);
+		}
+		if ($this->evaluate()) {
+			$this->project->setProperty($this->property, $this->value);
+		}
+	}
+
+	function evaluate() {
+		if ($this->file === null && $this->resource === null) {
+			throw new BuildException("At least one of (file|resource) is required", $this->location);
+		}
+
+		if ($this->type !== null && ($this->type !== "file" && $this->type !== "dir")) {
+			throw new BuildException("Type must be one of either dir or file", $this->location);
+		}
+
+		if (($this->file !== null) && !$this->_checkFile()) {
+			$this->log("Unable to find " . $this->file->__toString() . " to set property " . $this->property, Project::MSG_VERBOSE);
+			return false;
+		}
+
+		if (($this->resource !== null) && !$this->_checkResource($this->resource)) {
+			$this->log("Unable to load resource " . $this->resource . " to set property " . $this->property, Project::MSG_VERBOSE);
+			return false;
+		}
+
+		return true;
+	}
+
+	// this is prepared for the path type
+	private function _checkFile() {
+		if ($this->filepath === null) {
+			return $this->_checkFile1($this->file);
+		} else {
+			$paths = $this->filepath->listDir();
+			for($i=0,$pcnt=count($paths); $i < $pcnt; $i++) {
+				$this->log("Searching " . $paths[$i], Project::MSG_VERBOSE);
+				$tmp = new PhingFile($paths[$i], $this->file->getName());
+				if($tmp->isFile()) {
+					return true;
+				}
+			}
+		}
+		return false;
+	}
+
+	private function _checkFile1(PhingFile $file) {
+		if ($this->type !== null) {
+			if ($this->type === "dir") {
+				return $file->isDirectory();
+			} else if ($this->type === "file") {
+				return $file->isFile();
+			}
+		}
+		return $file->exists();
+	}
+	
+	private function _checkResource($resource) {
+		if (null != ($resourcePath = Phing::getResourcePath($resource))) {
+			return $this->_checkFile1(new PhingFile($resourcePath));
+		} else {
+			return false;
+		}
+	}
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/system/ChmodTask.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/system/ChmodTask.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/system/ChmodTask.php	(revision 19)
@@ -0,0 +1,203 @@
+<?php
+/*
+ *  $Id: ChmodTask.php 242 2007-09-26 15:39:45Z mrook $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+require_once 'phing/Task.php';
+include_once 'phing/types/FileSet.php';
+
+/**
+ * Task that changes the permissions on a file/directory.
+ *
+ * @author    Manuel Holtgrewe <grin@gmx.net>
+ * @author    Hans Lellelid <hans@xmpl.org>
+ * @version   $Revision: 1.12 $
+ * @package   phing.tasks.system
+ */
+class ChmodTask extends Task {
+
+    private $file;
+
+    private $mode;
+
+    private $filesets = array();
+
+    private $filesystem;
+	
+	private $quiet = false;	
+	private $failonerror = true;
+	private $verbose = true;
+    
+	/**
+	 * This flag means 'note errors to the output, but keep going'
+	 * @see setQuiet()
+	 */
+    function setFailonerror($bool) {
+        $this->failonerror = $bool;
+    }	
+
+    /**
+     * Set quiet mode, which suppresses warnings if chmod() fails.
+	 * @see setFailonerror()
+     */
+    function setQuiet($bool) {
+        $this->quiet = $bool;
+        if ($this->quiet) {
+            $this->failonerror = false;
+        }
+    }
+    
+    /**
+     * Set verbosity, which if set to false surpresses all but an overview
+     * of what happened.
+     */
+    function setVerbose($bool) {
+        $this->verbose = (bool)$bool;
+    }
+	
+    /**
+     * Sets a single source file to touch.  If the file does not exist
+     * an empty file will be created.
+     */
+    function setFile(PhingFile $file) {        
+        $this->file = $file;
+    } 
+
+    function setMode($str) {
+        $this->mode = $str;
+    }
+
+    /**
+     * Nested creator, adds a set of files (nested fileset attribute).
+     */
+    function createFileSet() {
+        $num = array_push($this->filesets, new FileSet());
+        return $this->filesets[$num-1];
+    }
+
+    /**
+     * Execute the touch operation.
+     * @return void
+     */
+    function main() {
+        // Check Parameters
+        $this->checkParams();       
+        $this->chmod();
+    }
+    
+    /**
+     * Ensure that correct parameters were passed in.
+     * @return void
+     */
+    private function checkParams() {
+    
+        if ($this->file === null && empty($this->filesets)) {
+            throw new BuildException("Specify at least one source - a file or a fileset.");
+        }
+
+        if ($this->mode === null) {
+            throw new BuildException("You have to specify an octal mode for chmod.");
+        }
+
+        // check for mode to be in the correct format
+        if (!preg_match('/^([0-7]){3,4}$/', $this->mode)) {
+            throw new BuildException("You have specified an invalid mode.");
+        }
+     
+    }
+
+    /**
+     * Does the actual work.
+     * @return void
+     */
+    private function chmod() {
+    	
+		if (strlen($this->mode) === 4) {
+			$mode = octdec($this->mode);
+		} else {
+			// we need to prepend the 0 before converting
+			$mode = octdec("0". $this->mode);
+		}
+        
+        // counters for non-verbose output
+        $total_files = 0;
+        $total_dirs = 0;
+        
+        // one file
+        if ($this->file !== null) {
+            $total_files = 1;
+            $this->chmodFile($this->file, $mode);
+        }
+
+        // filesets
+        foreach($this->filesets as $fs) {
+                    
+            $ds = $fs->getDirectoryScanner($this->project);
+            $fromDir = $fs->getDir($this->project);
+
+            $srcFiles = $ds->getIncludedFiles();
+            $srcDirs = $ds->getIncludedDirectories();
+
+            $filecount = count($srcFiles);
+            $total_files = $total_files + $filecount;
+            for ($j = 0; $j < $filecount; $j++) {
+                $this->chmodFile(new PhingFile($fromDir, $srcFiles[$j]), $mode);
+            }
+
+            $dircount = count($srcDirs);
+            $total_dirs = $total_dirs + $dircount;
+            for ($j = 0; $j <  $dircount; $j++) {
+                $this->chmodFile(new PhingFile($fromDir, $srcDirs[$j]), $mode);
+            }
+        }
+
+        if (!$this->verbose) {
+            $this->log('Total files changed to ' . vsprintf('%o', $mode) . ': ' . $total_files);
+            $this->log('Total directories changed to ' . vsprintf('%o', $mode) . ': ' . $total_dirs);
+        }
+
+    }
+
+	/**
+	 * Actually change the mode for the file.
+	 * @param PhingFile $file
+	 * @param int $mode
+	 */
+    private function chmodFile(PhingFile $file, $mode) {
+        if ( !$file->exists() ) {
+            throw new BuildException("The file " . $file->__toString() . " does not exist");
+        }   
+		     
+		try {
+			$file->setMode($mode);
+			if ($this->verbose) {
+				$this->log("Changed file mode on '" . $file->__toString() ."' to " . vsprintf("%o", $mode));
+			}
+		} catch (Exception $e) {
+			if($this->failonerror) {
+				throw $e;
+			} else {
+				$this->log($e->getMessage(), $this->quiet ? Project::MSG_VERBOSE : Project::MSG_WARN);
+			}
+		}
+    }
+	
+}
+
+
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/system/ChownTask.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/system/ChownTask.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/system/ChownTask.php	(revision 19)
@@ -0,0 +1,195 @@
+<?php
+/*
+ *  $Id: ChownTask.php 353 2008-02-06 19:43:18Z hans $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+require_once 'phing/Task.php';
+include_once 'phing/types/FileSet.php';
+
+/**
+ * Task that changes the permissions on a file/directory.
+ *
+ * @author	  Mehmet Emre Yilmaz <mehmety@gmail.com>
+ * @version   $Revision$
+ * @package   phing.tasks.system
+ */
+class ChownTask extends Task {
+
+    private $file;
+
+    private $user;
+
+    private $filesets = array();
+
+    private $filesystem;
+
+	private $quiet = false;
+	private $failonerror = true;
+	private $verbose = true;
+
+	/**
+	 * This flag means 'note errors to the output, but keep going'
+	 * @see setQuiet()
+	 */
+    function setFailonerror($bool) {
+        $this->failonerror = $bool;
+    }
+
+    /**
+     * Set quiet mode, which suppresses warnings if chown() fails.
+	 * @see setFailonerror()
+     */
+    function setQuiet($bool) {
+        $this->quiet = $bool;
+        if ($this->quiet) {
+            $this->failonerror = false;
+        }
+    }
+
+    /**
+     * Set verbosity, which if set to false surpresses all but an overview
+     * of what happened.
+     */
+    function setVerbose($bool) {
+        $this->verbose = (bool)$bool;
+    }
+
+    /**
+     * Sets a single source file to touch.  If the file does not exist
+     * an empty file will be created.
+     */
+    function setFile(PhingFile $file) {
+        $this->file = $file;
+    }
+
+    function setUser($str) {
+        $this->user = $str;
+    }
+
+    /**
+     * Nested creator, adds a set of files (nested fileset attribute).
+     */
+    function createFileSet() {
+        $num = array_push($this->filesets, new FileSet());
+        return $this->filesets[$num-1];
+    }
+
+    /**
+     * Execute the touch operation.
+     * @return void
+     */
+    function main() {
+        // Check Parameters
+        $this->checkParams();
+        $this->chown();
+    }
+
+    /**
+     * Ensure that correct parameters were passed in.
+     * @return void
+     */
+    private function checkParams() {
+
+        if ($this->file === null && empty($this->filesets)) {
+            throw new BuildException("Specify at least one source - a file or a fileset.");
+        }
+
+        if ($this->user === null) {
+            throw new BuildException("You have to specify a user for chown.");
+        }
+
+        // check for mode to be in the correct format
+
+
+    }
+
+    /**
+     * Does the actual work.
+     * @return void
+     */
+    private function chown() {
+
+		$user= $this->user;
+
+        // counters for non-verbose output
+        $total_files = 0;
+        $total_dirs = 0;
+
+        // one file
+        if ($this->file !== null) {
+            $total_files = 1;
+            $this->chownFile($this->file, $user);
+        }
+
+        // filesets
+        foreach($this->filesets as $fs) {
+
+            $ds = $fs->getDirectoryScanner($this->project);
+            $fromDir = $fs->getDir($this->project);
+
+            $srcFiles = $ds->getIncludedFiles();
+            $srcDirs = $ds->getIncludedDirectories();
+
+            $filecount = count($srcFiles);
+            $total_files = $total_files + $filecount;
+            for ($j = 0; $j < $filecount; $j++) {
+                $this->chownFile(new PhingFile($fromDir, $srcFiles[$j]), $user);
+            }
+
+            $dircount = count($srcDirs);
+            $total_dirs = $total_dirs + $dircount;
+            for ($j = 0; $j <  $dircount; $j++) {
+                $this->chownFile(new PhingFile($fromDir, $srcDirs[$j]), $user);
+            }
+        }
+
+        if (!$this->verbose) {
+            $this->log('Total files changed to ' . vsprintf('%o', $mode) . ': ' . $total_files);
+            $this->log('Total directories changed to ' . vsprintf('%o', $mode) . ': ' . $total_dirs);
+        }
+
+    }
+
+	/**
+	 * Actually change the mode for the file.
+	 * @param PhingFile $file
+	 * @param int $mode
+	 */
+    private function chownFile(PhingFile $file, $user) {
+        if ( !$file->exists() ) {
+            throw new BuildException("The file " . $file->__toString() . " does not exist");
+        }
+
+		try {
+			$file->setUser($user);
+			if ($this->verbose) {
+				$this->log("Changed file owner on '" . $file->__toString() ."' to " . $user);
+			}
+		} catch (Exception $e) {
+			if($this->failonerror) {
+				throw $e;
+			} else {
+				$this->log($e->getMessage(), $this->quiet ? Project::MSG_VERBOSE : Project::MSG_WARN);
+			}
+		}
+    }
+
+}
+
+
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/system/ConditionTask.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/system/ConditionTask.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/system/ConditionTask.php	(revision 19)
@@ -0,0 +1,74 @@
+<?php
+/*
+ *  $Id: ConditionTask.php 43 2006-03-10 14:31:51Z mrook $  
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+*/
+
+require_once 'phing/tasks/system/condition/ConditionBase.php';
+
+/**
+ *  <condition> task as a generalization of <available>
+ *
+ *  <p>This task supports boolean logic as well as pluggable conditions
+ *  to decide, whether a property should be set.</p>
+ *
+ *  <p>This task does not extend Task to take advantage of
+ *  ConditionBase.</p>
+ *
+ *  @author    Andreas Aderhold <andi@binarycloud.com>
+ *  @copyright © 2001,2002 THYRELL. All rights reserved
+ *  @version   $Revision: 1.7 $ $Date: 2006-03-10 14:31:51 +0000 (Fri, 10 Mar 2006) $
+ *  @access    public
+ *  @package   phing.tasks.system
+ */
+class ConditionTask extends ConditionBase {
+
+    private $property;
+    private $value = "true";
+
+    /**
+     * The name of the property to set. Required.
+     */
+    function setProperty($p) {
+        $this->property = $p;
+    }
+
+    /**
+     * The value for the property to set. Defaults to "true".
+     */
+    function setValue($v) {
+        $this->value = $v;
+    }
+
+    /**
+     * See whether our nested condition holds and set the property.
+     */
+    function main() {
+
+        if ($this->countConditions() > 1) {
+            throw new BuildException("You must not nest more than one condition into <condition>");
+        }
+        if ($this->countConditions() < 1) {
+            throw new BuildException("You must nest a condition into <condition>");
+        }
+        $cs = $this->getIterator();        
+        if ($cs->current()->evaluate()) {
+            $this->project->setProperty($this->property, $this->value);
+        }
+    }
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/system/CopyTask.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/system/CopyTask.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/system/CopyTask.php	(revision 19)
@@ -0,0 +1,408 @@
+<?php
+/*
+ *  $Id: CopyTask.php 235 2007-09-05 18:42:02Z hans $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+ 
+require_once 'phing/Task.php';
+include_once 'phing/system/io/PhingFile.php';
+include_once 'phing/util/FileUtils.php';
+include_once 'phing/util/SourceFileScanner.php';
+include_once 'phing/mappers/IdentityMapper.php';
+include_once 'phing/mappers/FlattenMapper.php';
+
+/**
+ * A phing copy task.  Copies a file or directory to a new file
+ * or directory.  Files are only copied if the source file is newer
+ * than the destination file, or when the destination file does not
+ * exist. It is possible to explictly overwrite existing files.
+ *
+ * @author   Andreas Aderhold, andi@binarycloud.com
+ * @version  $Revision: 1.16 $ $Date: 2007-09-05 18:42:02 +0000 (Wed, 05 Sep 2007) $
+ * @package  phing.tasks.system
+ */
+class CopyTask extends Task {
+    
+    protected $file          = null;   // the source file (from xml attribute)
+    protected $destFile      = null;   // the destiantion file (from xml attribute)
+    protected $destDir       = null;   // the destination dir (from xml attribute)
+    protected $overwrite     = false;  // overwrite destination (from xml attribute)
+    protected $preserveLMT   = true;   // sync timestamps (from xml attribute)
+    protected $includeEmpty  = true;   // include empty dirs? (from XML)
+    protected $flatten       = false;  // apply the FlattenMapper right way (from XML)
+    protected $mapperElement = null;
+
+    protected $fileCopyMap   = array(); // asoc array containing mapped file names
+    protected $dirCopyMap    = array(); // asoc array containing mapped file names
+    protected $completeDirMap= array(); // asoc array containing complete dir names
+    protected $fileUtils     = null;    // a instance of fileutils
+    protected $filesets      = array(); // all fileset objects assigned to this task
+    protected $filterChains  = array(); // all filterchains objects assigned to this task
+
+    protected $verbosity     = Project::MSG_VERBOSE;
+
+    /**
+     * Sets up this object internal stuff. i.e. the Fileutils instance
+     *
+     * @return object   The CopyTask instnace
+     * @access public
+     */
+    function __construct() {
+        $this->fileUtils = new FileUtils();
+    }
+
+    /**
+     * Set the overwrite flag. IntrospectionHelper takes care of
+     * booleans in set* methods so we can assume that the right
+     * value (boolean primitive) is coming in here.
+     *
+     * @param  boolean  Overwrite the destination file(s) if it/they already exist
+     * @return void
+     * @access public
+     */
+    function setOverwrite($bool) {
+        $this->overwrite = (boolean) $bool;
+    }
+
+    /**
+     * Used to force listing of all names of copied files.
+     * @param boolean $verbosity
+     */
+    function setVerbose($verbosity) {
+        if ($verbosity) {
+            $this->verbosity = Project::MSG_INFO;
+        } else {
+            $this->verbosity = Project::MSG_VERBOSE;
+        }
+    }
+    
+    /**
+     * Set the preserve timestmap flag. IntrospectionHelper takes care of
+     * booleans in set* methods so we can assume that the right
+     * value (boolean primitive) is coming in here.
+     *
+     * @param  boolean  Preserve the timestamp on the destination file
+     * @return void
+     * @access public
+     */
+    function setTstamp($bool) {
+        $this->preserveLMT = (boolean) $bool;
+    }
+
+
+    /**
+     * Set the include empty dirs flag. IntrospectionHelper takes care of
+     * booleans in set* methods so we can assume that the right
+     * value (boolean primitive) is coming in here.
+     *
+     * @param  boolean  Flag if empty dirs should be cpoied too
+     * @return void
+     * @access public
+     */
+    function setIncludeEmptyDirs($bool) {
+        $this->includeEmpty = (boolean) $bool;
+    }
+
+
+    /**
+     * Set the file. We have to manually take care of the
+     * type that is coming due to limited type support in php
+     * in and convert it manually if neccessary.
+     *
+     * @param  string/object  The source file. Either a string or an PhingFile object
+     * @return void
+     * @access public
+     */
+    function setFile(PhingFile $file) {        
+        $this->file = $file;
+    }
+
+
+    /**
+     * Set the toFile. We have to manually take care of the
+     * type that is coming due to limited type support in php
+     * in and convert it manually if neccessary.
+     *
+     * @param  string/object  The dest file. Either a string or an PhingFile object
+     * @return void
+     * @access public
+     */
+    function setTofile(PhingFile $file) {       
+        $this->destFile = $file;
+    }
+
+
+    /**
+     * Set the toDir. We have to manually take care of the
+     * type that is coming due to limited type support in php
+     * in and convert it manually if neccessary.
+     *
+     * @param  string/object  The directory, either a string or an PhingFile object
+     * @return void
+     * @access public
+     */
+    function setTodir(PhingFile $dir) {        
+        $this->destDir = $dir;
+    }
+
+    /**
+     * Nested creator, creates a FileSet for this task
+     *
+     * @access  public
+     * @return  object  The created fileset object
+     */
+    function createFileSet() {
+        $num = array_push($this->filesets, new FileSet());
+        return $this->filesets[$num-1];
+    }
+
+    /**
+     * Creates a filterchain
+     *
+     * @access public
+     * @return  object  The created filterchain object
+     */
+    function createFilterChain() {
+        $num = array_push($this->filterChains, new FilterChain($this->project));
+        return $this->filterChains[$num-1];
+    }
+
+    /**
+     * Nested creator, creates one Mapper for this task
+     *
+     * @access  public
+     * @return  object  The created Mapper type object
+     * @throws  BuildException
+     */
+    function createMapper() {
+        if ($this->mapperElement !== null) {
+            throw new BuildException("Cannot define more than one mapper", $this->location);
+        }
+        $this->mapperElement = new Mapper($this->project);
+        return $this->mapperElement;
+    }
+
+    /**
+     * The main entry point where everything gets in motion.
+     *
+     * @access  public
+     * @return  true on success
+     * @throws  BuildException
+     */
+    function main() {
+    
+        $this->validateAttributes();
+
+        if ($this->file !== null) {
+            if ($this->file->exists()) {
+                if ($this->destFile === null) {
+                    $this->destFile = new PhingFile($this->destDir, (string) $this->file->getName());
+                }
+                if ($this->overwrite === true || ($this->file->lastModified() > $this->destFile->lastModified())) {
+                    $this->fileCopyMap[$this->file->getAbsolutePath()] = $this->destFile->getAbsolutePath();
+                } else {
+                    $this->log($this->file->getName()." omitted, is up to date");
+                }
+            } else {
+                // terminate build
+                throw new BuildException("Could not find file " . $this->file->__toString() . " to copy.");
+            }
+        }
+
+        $project = $this->getProject();
+
+        // process filesets
+        foreach($this->filesets as $fs) {
+            $ds = $fs->getDirectoryScanner($project);
+            $fromDir  = $fs->getDir($project);
+            $srcFiles = $ds->getIncludedFiles();
+            $srcDirs  = $ds->getIncludedDirectories();
+            
+            if (!$this->flatten && $this->mapperElement === null)
+            {
+				$this->completeDirMap[$fromDir->getAbsolutePath()] = $this->destDir->getAbsolutePath();
+			}
+            
+            $this->_scan($fromDir, $this->destDir, $srcFiles, $srcDirs);
+        }
+
+        // go and copy the stuff
+        $this->doWork();
+
+        if ($this->destFile !== null) {
+            $this->destDir = null;
+        }
+    }
+
+    /**
+     * Validates attributes coming in from XML
+     *
+     * @access  private
+     * @return  void
+     * @throws  BuildException
+     */
+    protected function validateAttributes() {
+    
+        if ($this->file === null && count($this->filesets) === 0) {
+            throw new BuildException("CopyTask. Specify at least one source - a file or a fileset.");
+        }
+
+        if ($this->destFile !== null && $this->destDir !== null) {
+            throw new BuildException("Only one of destfile and destdir may be set.");
+        }
+
+        if ($this->destFile === null && $this->destDir === null) {
+            throw new BuildException("One of destfile or destdir must be set.");
+        }
+
+        if ($this->file !== null && $this->file->exists() && $this->file->isDirectory()) {
+            throw new BuildException("Use a fileset to copy directories.");
+        }
+
+        if ($this->destFile !== null && count($this->filesets) > 0) {
+            throw new BuildException("Cannot concatenate multple files into a single file.");
+        }
+
+        if ($this->destFile !== null) {
+            $this->destDir = new PhingFile($this->destFile->getParent());
+        }
+    }
+
+    /**
+     * Compares source files to destination files to see if they
+     * should be copied.
+     *
+     * @access  private
+     * @return  void
+     */
+    private function _scan(&$fromDir, &$toDir, &$files, &$dirs) {
+        /* mappers should be generic, so we get the mappers here and
+        pass them on to builMap. This method is not redundan like it seems */
+        $mapper = null;
+        if ($this->mapperElement !== null) {
+            $mapper = $this->mapperElement->getImplementation();
+        } else if ($this->flatten) {
+            $mapper = new FlattenMapper();
+        } else {
+            $mapper = new IdentityMapper();
+        }
+        $this->buildMap($fromDir, $toDir, $files, $mapper, $this->fileCopyMap);
+        $this->buildMap($fromDir, $toDir, $dirs, $mapper, $this->dirCopyMap);
+    }
+
+    /**
+     * Builds a map of filenames (from->to) that should be copied
+     *
+     * @access  private
+     * @return  void
+     */
+    private function buildMap(&$fromDir, &$toDir, &$names, &$mapper, &$map) {
+        $toCopy = null;
+        if ($this->overwrite) {
+            $v = array();
+            foreach($names as $name) {
+                $result = $mapper->main($name);
+                if ($result !== null) {
+                    $v[] = $name;
+                }
+            }
+            $toCopy = $v;
+        } else {
+            $ds = new SourceFileScanner($this);
+            $toCopy = $ds->restrict($names, $fromDir, $toDir, $mapper);
+        }
+
+        for ($i=0,$_i=count($toCopy); $i < $_i; $i++) {
+            $src  = new PhingFile($fromDir, $toCopy[$i]);
+            $mapped = $mapper->main($toCopy[$i]);
+            $dest = new PhingFile($toDir, $mapped[0]);
+            $map[$src->getAbsolutePath()] = $dest->getAbsolutePath();
+        }
+    }
+
+
+    /**
+     * Actually copies the files
+     *
+     * @access  private
+     * @return  void
+     * @throws  BuildException
+     */
+    protected function doWork() {
+		
+		// These "slots" allow filters to retrieve information about the currently-being-process files		
+		$fromSlot = $this->getRegisterSlot("currentFromFile");
+		$fromBasenameSlot = $this->getRegisterSlot("currentFromFile.basename");	
+
+		$toSlot = $this->getRegisterSlot("currentToFile");
+		$toBasenameSlot = $this->getRegisterSlot("currentToFile.basename");	
+		
+        $mapSize = count($this->fileCopyMap);
+        $total = $mapSize;
+        if ($mapSize > 0) {
+            $this->log("Copying ".$mapSize." file".(($mapSize) === 1 ? '' : 's')." to ". $this->destDir->getAbsolutePath());
+            // walks the map and actually copies the files
+            $count=0;
+            foreach($this->fileCopyMap as $from => $to) {
+                if ($from === $to) {
+                    $this->log("Skipping self-copy of " . $from, $this->verbosity);
+                    $total--;
+                    continue;
+                }
+                $this->log("From ".$from." to ".$to, $this->verbosity);
+                try { // try to copy file
+				
+					$fromFile = new PhingFile($from);
+					$toFile = new PhingFile($to);
+					
+                    $fromSlot->setValue($fromFile->getPath());
+					$fromBasenameSlot->setValue($fromFile->getName());
+
+					$toSlot->setValue($toFile->getPath());
+					$toBasenameSlot->setValue($toFile->getName());
+					
+                    $this->fileUtils->copyFile($fromFile, $toFile, $this->overwrite, $this->preserveLMT, $this->filterChains, $this->getProject());
+			
+                    $count++;
+                } catch (IOException $ioe) {
+                    $this->log("Failed to copy " . $from . " to " . $to . ": " . $ioe->getMessage(), Project::MSG_ERR);
+                }
+            }
+        }
+
+        // handle empty dirs if appropriate
+        if ($this->includeEmpty) {
+            $destdirs = array_values($this->dirCopyMap);
+            $count = 0;
+            foreach ($destdirs as $destdir) {
+                $d = new PhingFile((string) $destdir);
+                if (!$d->exists()) {
+                    if (!$d->mkdirs()) {
+                        $this->log("Unable to create directory " . $d->__toString(), Project::MSG_ERR);
+                    } else {
+                        $count++;
+                    }
+                }
+            }
+            if ($count > 0) {
+                $this->log("Copied ".$count." empty director" . ($count == 1 ? "y" : "ies") . " to " . $this->destDir->getAbsolutePath());
+            }
+        }
+    }
+
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/system/CvsPassTask.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/system/CvsPassTask.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/system/CvsPassTask.php	(revision 19)
@@ -0,0 +1,173 @@
+<?php
+/*
+ *  $Id: CvsPassTask.php 227 2007-08-28 02:17:00Z hans $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+ 
+require_once 'phing/Task.php';
+include_once 'phing/system/io/BufferedReader.php';
+include_once 'phing/system/io/BufferedWriter.php';
+include_once 'phing/util/StringHelper.php';
+
+/**
+ * Adds an new entry to a CVS password file.
+ *
+ * @author Hans Lellelid <hans@xmpl.org> (Phing)
+ * @author Jeff Martin <jeff@custommonkey.org> (Ant)
+ * @version $Revision: 1.7 $
+ * @package phing.tasks.system
+ */
+class CVSPassTask extends Task {
+
+    /** CVS Root */
+    private $cvsRoot; 
+    /** Password file to add password to */
+    private $passFile;
+    /** Password to add to file */
+    private $password;
+
+    /** Array contain char conversion data */
+    private static $shifts = array(
+          0,   1,   2,   3,   4,   5,   6,   7,   8,   9,  10,  11,  12,  13,  14,  15,
+         16,  17,  18,  19,  20,  21,  22,  23,  24,  25,  26,  27,  28,  29,  30,  31,
+        114, 120,  53,  79,  96, 109,  72, 108,  70,  64,  76,  67, 116,  74,  68,  87,
+        111,  52,  75, 119,  49,  34,  82,  81,  95,  65, 112,  86, 118, 110, 122, 105,
+         41,  57,  83,  43,  46, 102,  40,  89,  38, 103,  45,  50,  42, 123,  91,  35,
+        125,  55,  54,  66, 124, 126,  59,  47,  92,  71, 115,  78,  88, 107, 106,  56,
+         36, 121, 117, 104, 101, 100,  69,  73,  99,  63,  94,  93,  39,  37,  61,  48,
+         58, 113,  32,  90,  44,  98,  60,  51,  33,  97,  62,  77,  84,  80,  85, 223,
+        225, 216, 187, 166, 229, 189, 222, 188, 141, 249, 148, 200, 184, 136, 248, 190,
+        199, 170, 181, 204, 138, 232, 218, 183, 255, 234, 220, 247, 213, 203, 226, 193,
+        174, 172, 228, 252, 217, 201, 131, 230, 197, 211, 145, 238, 161, 179, 160, 212,
+        207, 221, 254, 173, 202, 146, 224, 151, 140, 196, 205, 130, 135, 133, 143, 246,
+        192, 159, 244, 239, 185, 168, 215, 144, 139, 165, 180, 157, 147, 186, 214, 176,
+        227, 231, 219, 169, 175, 156, 206, 198, 129, 164, 150, 210, 154, 177, 134, 127,
+        182, 128, 158, 208, 162, 132, 167, 209, 149, 241, 153, 251, 237, 236, 171, 195,
+        243, 233, 253, 240, 194, 250, 191, 155, 142, 137, 245, 235, 163, 242, 178, 152 
+    );
+
+    /**
+     * Create a CVS task using the default cvspass file location.
+     */
+    public function __construct() {
+        $this->passFile = new PhingFile(
+            Phing::getProperty("cygwin.user.home",
+                Phing::getProperty("user.home"))
+            . DIRECTORY_SEPARATOR . ".cvspass");
+    }
+
+    /**
+     * Does the work.
+     *
+     * @throws BuildException if someting goes wrong with the build
+     */
+    public final function main() {
+        if ($this->cvsRoot === null) {
+            throw new BuildException("cvsroot is required");
+        }
+        if ($this->password === null) {
+            throw new BuildException("password is required");
+        }
+
+        $this->log("cvsRoot: " . $this->cvsRoot, Project::MSG_DEBUG);
+        $this->log("password: " . $this->password, Project::MSG_DEBUG);
+        $this->log("passFile: " . $this->passFile->__toString(), Project::MSG_DEBUG);
+
+        $reader = null;
+        $writer = null;
+        
+        try {
+            $buf = "";
+
+            if ($this->passFile->exists()) {
+                $reader = new BufferedReader(new FileReader($this->passFile));
+                
+                $line = null;
+                while (($line = $reader->readLine()) !== null) {
+                    if (!StringHelper::startsWith($this->cvsRoot, $line)) {
+                        $buf .= $line . PHP_EOL;
+                    }
+                }
+            }
+
+            $pwdfile = $buf . $this->cvsRoot . " A" . $this->mangle($this->password);
+
+            $this->log("Writing -> " . $pwdfile , Project::MSG_DEBUG);
+
+            $writer = new BufferedWriter(new FileWriter($this->passFile));
+            $writer->write($pwdfile);
+            $writer->newLine();
+            
+            $writer->close();
+            if ($reader) {
+                $reader->close();
+            }
+                        
+        } catch (IOException $e) {
+            if ($reader) {
+                try {
+                    $reader->close();
+                } catch (Exception $e) {}                
+            }
+            
+            if ($writer) {
+                try {
+                    $writer->close();
+                } catch (Exception $e) {}                
+            }
+            
+            throw new BuildException($e);
+        }
+    }
+    
+    /**
+     * "Encode" the password.
+     */
+    private final function mangle($password){
+        $buf = "";
+        for ($i = 0, $plen = strlen($password); $i < $plen; $i++) {
+            $buf .= chr(self::$shifts[ord($password{$i})]);
+        }
+        return $buf;
+    }
+
+    /**
+     * The CVS repository to add an entry for.
+     * @param string $cvsRoot
+     */
+    public function setCvsroot($cvsRoot) {
+        $this->cvsRoot = $cvsRoot;
+    }
+
+    /**
+     * Password file to add the entry to.
+     * @param PhingFile $passFile
+     */
+    public function setPassfile(PhingFile $passFile) {
+        $this->passFile = $passFile;
+    }
+
+    /**
+     * Password to be added to the password file.
+     * @param string $password
+     */
+    public function setPassword($password) {
+        $this->password = $password;
+    }
+
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/system/CvsTask.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/system/CvsTask.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/system/CvsTask.php	(revision 19)
@@ -0,0 +1,540 @@
+<?php
+/*
+ *  $Id: CvsTask.php 227 2007-08-28 02:17:00Z hans $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+require_once 'phing/Task.php';
+include_once 'phing/tasks/system/ExecTask.php';
+include_once 'phing/types/Commandline.php';
+
+/**
+ * Task for performing CVS operations.
+ * 
+ *  NOTE: This implementation has been moved here from Cvs.java with
+ *  the addition of some accessors for extensibility.  Another task
+ *  can extend this with some customized output processing.
+ *
+ * @author Hans Lellelid <hans@xmpl.org> (Phing)
+ * @author costin@dnt.ro (Ant)
+ * @author stefano@apache.org (Ant)
+ * @author Wolfgang Werner <wwerner@picturesafe.de> (Ant)
+ * @author Kevin Ross <kevin.ross@bredex.com> (Ant)
+ * @version $Revision: 1.14 $
+ * @package phing.tasks.system
+ */
+class CvsTask extends Task {
+
+    /** 
+     * Default compression level to use, if compression is enabled via
+     * setCompression( true ). 
+     */
+    const DEFAULT_COMPRESSION_LEVEL = 3;
+
+    private $cmd;
+
+    /** 
+     * List of Commandline children 
+     * @var array Commandline[]
+     */
+    private $commandlines = array();
+
+    /**
+     * the CVSROOT variable.
+     */
+    private $cvsRoot;
+
+    /**
+     * the CVS_RSH variable.
+     */
+    private $cvsRsh;
+
+    /**
+     * the package/module to check out.
+     */
+    private $cvsModule;
+
+    /**
+     * the default command.
+     */
+    private static $default_command = "checkout";
+    
+    /**
+     * the CVS command to execute.
+     */
+    private $command = null;
+
+    /**
+     * suppress information messages.
+     */
+    private $quiet = false;
+
+    /**
+     * compression level to use.
+     */
+    private $compression = 0;
+
+    /**
+     * report only, don't change any files.
+     */
+    private $noexec = false;
+
+    /**
+     * CVS port
+     */
+    private $port = 0;
+
+    /**
+     * CVS password file
+     * @var File
+     */
+    private $passFile = null;
+
+    /**
+     * the directory where the checked out files should be placed.
+     * @var File
+     */
+    private $dest;
+   
+    private $error;
+    
+    private $output;
+   
+    /**
+     * If true it will stop the build if cvs exits with error.
+     * Default is false. (Iulian)
+     * @var boolean
+     */
+    private $failOnError = false;
+  
+    public function init() {
+        $this->cmd = new Commandline();
+    }
+    
+    /**
+     * Sets up the environment for toExecute and then runs it.
+     * @param Commandline $toExecute
+     * @throws BuildException
+     */
+    protected function runCommand(Commandline $toExecute) {
+    
+        // We are putting variables into the script's environment
+        // and not removing them (!)  This should be fine, but is 
+        // worth remembering and testing.
+            
+        if ($this->port > 0) {
+            putenv("CVS_CLIENT_PORT=".$this->port);
+        }
+        
+         // Need a better cross platform integration with <cvspass>, so
+         // use the same filename.
+
+        if ($this->passFile === null) {
+            $defaultPassFile = new PhingFile(Phing::getProperty("cygwin.user.home", Phing::getProperty("user.home")) 
+                . DIRECTORY_SEPARATOR . ".cvspass");
+            if($defaultPassFile->exists()) {
+                $this->setPassfile($defaultPassFile);
+            }
+        }
+
+        if ($this->passFile !== null) {
+            if ($this->passFile->isFile() && $this->passFile->canRead()) {            
+                putenv("CVS_PASSFILE=" . $this->passFile->__toString());
+                $this->log("Using cvs passfile: " . $this->passFile->__toString(), Project::MSG_INFO);
+            } elseif (!$this->passFile->canRead()) {
+                $this->log("cvs passfile: " . $this->passFile->__toString() 
+                    . " ignored as it is not readable", Project::MSG_WARN);
+            } else {
+                $this->log("cvs passfile: " . $this->passFile->__toString() 
+                    . " ignored as it is not a file",
+                    Project::MSG_WARN);
+            }
+        }
+
+        if ($this->cvsRsh !== null) {
+            putenv("CVS_RSH=".$this->cvsRsh);
+        }
+
+        // Use the ExecTask to handle execution of the command        
+        $exe = new ExecTask($this->project);
+        $exe->setProject($this->project);
+        
+        //exe.setAntRun(project);
+        if ($this->dest === null) {
+            $this->dest = $this->project->getBaseDir();
+        }
+
+        if (!$this->dest->exists()) {
+            $this->dest->mkdirs();
+        }
+        
+        if ($this->output !== null) {
+            $exe->setOutput($this->output);
+        }
+
+        if ($this->error !== null) {
+            $exe->setError($this->error);
+        }
+        
+        $exe->setDir($this->dest);
+        
+        if (is_object($toExecute)) {
+            $toExecuteStr = $toExecute->__toString(); // unfortunately no more automagic for initial 5.0.0 release :(
+        }
+        
+        $exe->setCommand($toExecuteStr);
+        
+        try {
+            $actualCommandLine = $toExecuteStr; // we converted to string above
+            $this->log($actualCommandLine, Project::MSG_INFO);
+            $retCode = $exe->execute();
+            $this->log("retCode=" . $retCode, Project::MSG_DEBUG);
+            /*Throw an exception if cvs exited with error. (Iulian)*/
+            if ($this->failOnError && $retCode !== 0) {
+                throw new BuildException("cvs exited with error code "
+                                         . $retCode 
+                                         . PHP_EOL
+                                         . "Command line was ["
+                                         . $toExecute->describeCommand() . "]", $this->getLocation());
+            }
+        } catch (IOException $e) {
+            if ($this->failOnError) {
+                throw new BuildException($e, $this->getLocation());
+            } else {
+                $this->log("Caught exception: " . $e, Project::MSG_WARN);
+            }
+        } catch (BuildException $e) {
+            if ($this->failOnError) {
+                throw $e;
+            } else {
+                $t = $e->getCause();
+                if ($t === null) {
+                    $t = $e;
+                }
+                $this->log("Caught exception: " . $t, Project::MSG_WARN);
+            }
+        } catch (Exception $e) {
+            if ($this->failOnError) {
+                throw new BuildException($e, $this->getLocation());
+            } else {
+                $this->log("Caught exception: " . $e, Project::MSG_WARN);
+            }
+        }
+    }
+
+    /**
+     * 
+     * @return void
+     * @throws BuildException
+     */
+    public function main() {
+
+        $savedCommand = $this->getCommand();
+
+        if ($this->getCommand() === null && empty($this->commandlines)) {
+            // re-implement legacy behaviour:
+            $this->setCommand(self::$default_command);
+        }
+
+        $c = $this->getCommand();
+        $cloned = null;
+        if ($c !== null) {
+            $cloned = $this->cmd->__copy();
+            $cloned->createArgument(true)->setLine($c);
+            $this->addConfiguredCommandline($cloned, true);
+        }
+
+        try {
+            for ($i = 0, $vecsize=count($this->commandlines); $i < $vecsize; $i++) {
+                $this->runCommand($this->commandlines[$i]);
+            }
+            
+            // finally    {
+            if ($cloned !== null) {
+                $this->removeCommandline($cloned);
+            }
+            $this->setCommand($savedCommand);
+            
+        } catch (Exception $e) {
+            // finally {
+            if ($cloned !== null) {
+                $this->removeCommandline($cloned);
+            }
+            $this->setCommand($savedCommand);
+            throw $e;
+        }
+    }
+
+    /**
+     * The CVSROOT variable.
+     *
+     * @param string $root
+     */
+    public function setCvsRoot($root) {
+
+        // Check if not real cvsroot => set it to null
+        if ($root !== null) {
+            if (trim($root) == "") {
+                $root = null;
+            }
+        }
+
+        $this->cvsRoot = $root;
+    }
+
+    public function getCvsRoot() {
+        return $this->cvsRoot;
+    }
+
+    /**
+     * The CVS_RSH variable.
+     *
+     * @param rsh
+     */
+    public function setCvsRsh($rsh) {
+        // Check if not real cvsrsh => set it to null
+        if ($rsh !== null) {
+            if (trim($rsh) == "") {
+                $rsh = null;
+            }
+        }
+
+        $this->cvsRsh = $rsh;
+    }
+
+    public function getCvsRsh() {
+        return $this->cvsRsh;
+    }
+
+    /**
+     * Port used by CVS to communicate with the server.
+     *
+     * @param int $port
+     */
+    public function setPort($port){
+        $this->port = $port;
+    }
+
+    /**
+     * @return int
+     */
+    public function getPort() {
+        return $this->port;
+    }
+
+    /**
+     * Password file to read passwords from.
+     *
+     * @param passFile
+     */
+    public function setPassfile(PhingFile $passFile) {
+        $this->passFile = $passFile;
+    }
+    
+    /**
+     * @return File
+     */
+    public function getPassFile() {
+        return $this->passFile;
+    }
+
+    /**
+     * The directory where the checked out files should be placed.
+     *
+     * @param PhingFile $dest
+     */
+    public function setDest(PhingFile $dest) {
+        $this->dest = $dest;
+    }
+
+    public function getDest() {
+        return $this->dest;
+    }
+
+    /**
+     * The package/module to operate upon.
+     *
+     * @param string $p
+     */
+    public function setModule($m) {
+        $this->cvsModule = $m;
+    }
+
+    public function getModule(){
+        return $this->cvsModule;
+    }
+
+    /**
+     * The tag of the package/module to operate upon.
+     * @param string $p
+     */
+    public function setTag($p) {
+        // Check if not real tag => set it to null
+        if ($p !== null && trim($p) !== "") {
+            $this->appendCommandArgument("-r");
+            $this->appendCommandArgument($p);
+        }
+    }
+
+    /**
+     * This needs to be public to allow configuration
+     *      of commands externally.
+     */
+    public function appendCommandArgument($arg) {
+        $this->cmd->createArgument()->setValue($arg);
+    }
+
+    /**
+     * Use the most recent revision no later than the given date.
+     * @param p
+     */
+    public function setDate($p) {
+        if ($p !== null && trim($p) !== "") {
+            $this->appendCommandArgument("-D");
+            $this->appendCommandArgument($p);
+        }
+    }
+
+    /**
+     * The CVS command to execute.
+     * @param string $c
+     */
+    public function setCommand($c) {
+        $this->command = $c;
+    }
+    
+    public function getCommand() {
+        return $this->command;
+    }
+
+    /**
+     * If true, suppress informational messages.
+     * @param boolean $q
+     */
+    public function setQuiet($q) {
+        $this->quiet = $q;
+    }
+
+    /**
+     * If true, report only and don't change any files.
+     *
+     * @param boolean $ne
+     */
+    public function setNoexec($ne) {
+        $this->noexec = (boolean) $ne;
+    }
+
+    /**
+     * Stop the build process if the command exits with
+     * a return code other than 0.
+     * Defaults to false.
+     * @param boolean $failOnError
+     */
+    public function setFailOnError($failOnError) {
+        $this->failOnError = (boolean) $failOnError;
+    }
+
+    /**
+     * Configure a commandline element for things like cvsRoot, quiet, etc.
+     * @return string
+     */
+    protected function configureCommandline($c) {
+        if ($c === null) {
+            return;
+        }
+        $c->setExecutable("cvs");
+        
+        if ($this->cvsModule !== null) {
+            $c->createArgument()->setLine($this->cvsModule);
+        }
+        if ($this->compression > 0 && $this->compression < 10) {
+            $c->createArgument(true)->setValue("-z" . $this->compression);
+        }
+        if ($this->quiet) {
+            $c->createArgument(true)->setValue("-q");
+        }
+        if ($this->noexec) {
+            $c->createArgument(true)->setValue("-n");
+        }
+        if ($this->cvsRoot !== null) {
+            $c->createArgument(true)->setLine("-d" . $this->cvsRoot);
+        }
+    }
+
+    protected function removeCommandline(Commandline $c) {
+        $idx = array_search($c, $this->commandlines, true);
+        if ($idx === false) {
+            return false;
+        }
+        $this->commandlines = array_splice($this->commandlines, $idx, 1);
+        return true;
+    }
+
+    /**
+    * Configures and adds the given Commandline.
+    * @param insertAtStart If true, c is
+    */
+    public function addConfiguredCommandline(Commandline $c, $insertAtStart = false) {
+        if ($c === null) {
+            return; 
+        }
+        $this->configureCommandline($c);
+        if ($insertAtStart) {
+            array_unshift($this->commandlines, $c);
+        } else {
+            array_push($this->commandlines, $c);
+        }
+    }
+
+    /**
+    * If set to a value 1-9 it adds -zN to the cvs command line, else
+    * it disables compression.
+    * @param int $level
+    */
+    public function setCompressionLevel($level) {
+        $this->compression = $level;
+    }
+
+    /**
+     * If true, this is the same as compressionlevel="3".
+     *
+     * @param boolean $usecomp If true, turns on compression using default
+     * level, AbstractCvsTask.DEFAULT_COMPRESSION_LEVEL.
+     */
+    public function setCompression($usecomp) {
+        $this->setCompressionLevel($usecomp ? 
+                            self::DEFAULT_COMPRESSION_LEVEL : 0);
+    }
+
+    /**
+     * File to which output should be written.
+     * @param PhingFile $output
+     */
+    function setOutput(PhingFile $f) {
+        $this->output = $f;
+    }
+    
+    /**
+     * File to which error output should be written.
+     * @param PhingFile $output
+     */
+    function setError(PhingFile $f) {
+        $this->error = $f;
+    }
+
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/system/DeleteTask.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/system/DeleteTask.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/system/DeleteTask.php	(revision 19)
@@ -0,0 +1,277 @@
+<?php
+/*
+ *  $Id: DeleteTask.php 321 2007-12-14 18:00:25Z hans $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+require_once 'phing/Task.php';
+
+/**
+ * Deletes a file or directory, or set of files defined by a fileset.
+ * 
+ * @version   $Revision: 1.13 $
+ * @package   phing.tasks.system
+ */
+class DeleteTask extends Task {
+
+    protected $file;
+    protected $dir;
+    protected $filesets = array();
+    protected $includeEmpty = false;
+
+    protected $quiet = false;
+    protected $failonerror = true;
+    protected $verbosity = Project::MSG_VERBOSE;
+	
+	/** Any filelists of files that should be deleted. */
+    private $filelists = array();
+	
+    /** 
+     * Set the name of a single file to be removed.
+     * @param PhingFile $file
+     */
+    function setFile(PhingFile $file) {       
+        $this->file = $file;
+    }
+
+    /** 
+     * Set the directory from which files are to be deleted.
+     * @param PhingFile $dir
+     */
+    function setDir(PhingFile $dir) {
+        $this->dir = $dir;
+    }
+
+    /**
+     * Used to force listing of all names of deleted files.
+     * @param boolean $verbosity
+     */
+    function setVerbose($verbosity) {
+        if ($verbosity) {
+            $this->verbosity = Project::MSG_INFO;
+        } else {
+            $this->verbosity = Project::MSG_VERBOSE;
+        }
+    }
+
+    /**
+     * If the file does not exist, do not display a diagnostic
+     * message or modify the exit status to reflect an error.
+     * This means that if a file or directory cannot be deleted,
+     * then no error is reported. This setting emulates the
+     * -f option to the Unix rm command. Default is false
+    * meaning things are verbose
+     */
+    function setQuiet($bool) {
+        $this->quiet = $bool;
+        if ($this->quiet) {
+            $this->failonerror = false;
+        }
+    }
+
+    /** this flag means 'note errors to the output, but keep going' */
+    function setFailOnError($bool) {
+        $this->failonerror = $bool;
+    }
+
+
+    /** Used to delete empty directories.*/
+    function setIncludeEmptyDirs($includeEmpty) {
+        $this->includeEmpty = (boolean) $includeEmpty;
+    }
+
+    /** Nested creator, adds a set of files (nested fileset attribute). */
+    function createFileSet() {
+        $num = array_push($this->filesets, new FileSet());
+        return $this->filesets[$num-1];
+    }
+	
+	/** Nested creator, adds a set of files (nested fileset attribute). */
+    function createFileList() {
+        $num = array_push($this->filelists, new FileList());
+        return $this->filelists[$num-1];
+    }
+
+    /** Delete the file(s). */
+    function main() {
+        if ($this->file === null && $this->dir === null && count($this->filesets) === 0 && count($this->filelists) === 0) {
+            throw new BuildException("At least one of the file or dir attributes, or a fileset element, or a filelist element must be set.");
+        }
+
+        if ($this->quiet && $this->failonerror) {
+            throw new BuildException("quiet and failonerror cannot both be set to true", $this->location);
+        }
+
+        // delete a single file
+        if ($this->file !== null) {
+            if ($this->file->exists()) {
+                if ($this->file->isDirectory()) {
+                    $this->log("Directory " . $this->file->__toString() . " cannot be removed using the file attribute. Use dir instead.");
+                } else {
+                    $this->log("Deleting: " . $this->file->__toString());
+                    try {
+                        $this->file->delete();
+                    } catch(Exception $e) {
+                        $message = "Unable to delete file " . $this->file->__toString() .": " .$e->getMessage();
+                        if($this->failonerror) {
+                            throw new BuildException($message);
+                        } else {
+                            $this->log($message, $this->quiet ? Project::MSG_VERBOSE : Project::MSG_WARN);
+                        }                        
+                    }
+                }
+            } else {
+                $this->log("Could not find file " . $this->file->getAbsolutePath() . " to delete.",Project::MSG_VERBOSE);
+            }
+        }
+
+        // delete the directory
+        if ($this->dir !== null && $this->dir->exists() && $this->dir->isDirectory()) {
+            if ($this->verbosity === Project::MSG_VERBOSE) {
+                $this->log("Deleting directory " . $this->dir->__toString());
+            }
+            $this->removeDir($this->dir);
+        }
+		
+		// delete the files in the filelists
+		foreach($this->filelists as $fl) {
+			try {
+				$files = $fl->getFiles($this->project);
+				$this->removeFiles($fl->getDir($this->project), $files, $empty=array());
+			} catch (BuildException $be) {
+				// directory doesn't exist or is not readable
+					if ($this->failonerror) {
+					throw $be;
+				} else {
+					$this->log($be->getMessage(), $this->quiet ? Project::MSG_VERBOSE : Project::MSG_WARN);
+				}
+			}
+		}
+			
+        // delete the files in the filesets
+        foreach($this->filesets as $fs) {
+            try {
+                $ds = $fs->getDirectoryScanner($this->project);
+                $files = $ds->getIncludedFiles();
+                $dirs = $ds->getIncludedDirectories();
+                $this->removeFiles($fs->getDir($this->project), $files, $dirs);
+            } catch (BuildException $be) {
+                    // directory doesn't exist or is not readable
+                    if ($this->failonerror) {
+                        throw $be;
+                    } else {
+                        $this->log($be->getMessage(), $this->quiet ? Project::MSG_VERBOSE : Project::MSG_WARN);
+                    }
+                }
+        }
+    }
+    
+    /**
+     * Recursively removes a directory.
+     * @param PhingFile $d The directory to remove.
+     */
+    private function removeDir($d) {
+        $list = $d->listDir();
+        if ($list === null) {
+            $list = array();
+        }
+        
+        foreach($list as $s) {
+            $f = new PhingFile($d, $s);
+            if ($f->isDirectory()) {
+                $this->removeDir($f);
+            } else {
+                $this->log("Deleting " . $f->__toString(), $this->verbosity);
+                try {
+                    $f->delete();
+                } catch (Exception $e) {
+                    $message = "Unable to delete file " . $f->__toString() . ": " . $e->getMessage();
+                    if($this->failonerror) {
+                        throw new BuildException($message);
+                    } else {
+                        $this->log($message, $this->quiet ? Project::MSG_VERBOSE : Project::MSG_WARN);
+                    }
+                }               
+            }
+        }
+        $this->log("Deleting directory " . $d->getAbsolutePath(), $this->verbosity);
+        try {
+            $d->delete();
+        } catch (Exception $e) {
+            $message = "Unable to delete directory " . $d->__toString() . ": " . $e->getMessage();
+            if($this->failonerror) {
+              throw new BuildException($message);
+            } else {
+              $this->log($message, $this->quiet ? Project::MSG_VERBOSE : Project::MSG_WARN);
+            }
+        }               
+    }
+
+    /**
+     * remove an array of files in a directory, and a list of subdirectories
+     * which will only be deleted if 'includeEmpty' is true
+     * @param PhingFile $d directory to work from
+     * @param array &$files array of files to delete; can be of zero length
+     * @param array &$dirs array of directories to delete; can of zero length
+     */
+    private function removeFiles(PhingFile $d, &$files, &$dirs) {
+        if (count($files) > 0) {
+            $this->log("Deleting " . count($files) . " files from " . $d->__toString());
+            for ($j=0,$_j=count($files); $j < $_j; $j++) {
+                $f = new PhingFile($d, $files[$j]);
+                $this->log("Deleting " . $f->getAbsolutePath(), $this->verbosity);
+                try {
+                    $f->delete();
+                } catch (Exception $e) {
+                    $message = "Unable to delete file " . $f->__toString() . ": " . $e->getMessage();
+                    if($this->failonerror) {
+                        throw new BuildException($message);
+                    } else {
+                        $this->log($message, $this->quiet ? Project::MSG_VERBOSE : Project::MSG_WARN);
+                    }
+                }               
+
+            }
+        }
+
+        if (count($dirs) > 0 && $this->includeEmpty) {
+            $dirCount = 0;
+            for ($j=count($dirs)-1; $j>=0; --$j) {
+                $dir = new PhingFile($d, $dirs[$j]);
+                $dirFiles = $dir->listDir();
+                if ($dirFiles === null || count($dirFiles) === 0) {
+                    $this->log("Deleting " . $dir->__toString(), $this->verbosity);
+                    try {
+                        $dir->delete();
+                        $dirCount++;
+                    } catch (Exception $e) {
+                        $message="Unable to delete directory " . $dir->__toString();
+                        if($this->failonerror) {
+                            throw new BuildException($message);
+                        } else {
+                            $this->log($message, $this->quiet ? Project::MSG_VERBOSE : Project::MSG_WARN);
+                        }
+                    }
+                }
+            }
+            if ($dirCount > 0) {
+                $this->log("Deleted $dirCount director" . ($dirCount==1 ? "y" : "ies") . " from " . $d->__toString());
+            }
+        }
+    }
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/system/EchoTask.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/system/EchoTask.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/system/EchoTask.php	(revision 19)
@@ -0,0 +1,107 @@
+<?php
+/*
+ *  $Id: EchoTask.php 144 2007-02-05 15:19:00Z hans $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+ 
+include_once 'phing/Task.php';
+
+/**
+ *  Echos a message to the logging system or to a file
+ *
+ *  @author   Michiel Rook <michiel.rook@gmail.com>
+ *  @author   Andreas Aderhold, andi@binarycloud.com
+ *  @version  $Revision: 1.5 $ $Date: 2007-02-05 15:19:00 +0000 (Mon, 05 Feb 2007) $
+ *  @package  phing.tasks.system
+ */
+
+class EchoTask extends Task {
+	
+    protected $msg = "";
+    
+    protected $file = "";
+    
+    protected $append = false;
+    
+    protected $level = "info";
+
+    function main() {		
+		switch ($this->level)
+		{
+			case "error": $loglevel = Project::MSG_ERR; break;
+			case "warning": $loglevel = Project::MSG_WARN; break;
+			case "info": $loglevel = Project::MSG_INFO; break;
+			case "verbose": $loglevel = Project::MSG_VERBOSE; break;
+			case "debug": $loglevel = Project::MSG_DEBUG; break;
+		}
+		
+		if (empty($this->file))
+		{
+        	$this->log($this->msg, $loglevel);
+		}
+		else
+		{
+			if ($this->append)
+			{
+				$handle = fopen($this->file, "a");
+			}
+			else
+			{
+				$handle = fopen($this->file, "w");
+			}
+			
+			fwrite($handle, $this->msg);
+			
+			fclose($handle);
+		}
+    }
+    
+    /** setter for file */
+    function setFile($file)
+    {
+		$this->file = (string) $file;
+	}
+
+    /** setter for level */
+    function setLevel($level)
+    {
+		$this->level = (string) $level;
+	}
+
+    /** setter for append */
+    function setAppend($append)
+    {
+		$this->append = $append;
+	}
+
+    /** setter for message */
+    function setMsg($msg) {
+        $this->setMessage($msg);
+    }
+
+    /** alias setter */
+    function setMessage($msg) {
+        $this->msg = (string) $msg;
+    }
+    
+    /** Supporting the <echo>Message</echo> syntax. */
+    function addText($msg)
+    {
+        $this->msg = (string) $msg;
+    }
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/system/ExecTask.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/system/ExecTask.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/system/ExecTask.php	(revision 19)
@@ -0,0 +1,266 @@
+<?php
+
+/*
+ *  $Id: ExecTask.php 334 2008-01-04 14:25:20Z hans $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+require_once 'phing/Task.php';
+
+/**
+ * Executes a command on the shell.
+ *
+ * @author   Andreas Aderhold <andi@binarycloud.com>
+ * @author   Hans Lellelid <hans@xmpl.org>
+ * @version  $Revision: 1.17 $
+ * @package  phing.tasks.system
+ */
+class ExecTask extends Task {
+
+	/**
+	 * Command to execute.
+	 * @var string
+	 */
+	protected $command;
+
+	/**
+	 * Working directory.
+	 * @var File
+	 */
+	protected $dir;
+
+	/**
+	 * Operating system.
+	 * @var string
+	 */
+	protected $os;
+
+	/**
+	 * Whether to escape shell command using escapeshellcmd().
+	 * @var boolean
+	 */
+	protected $escape = false;
+
+	/**
+	 * Where to direct output.
+	 * @var File
+	 */
+	protected $output;
+
+	/**
+	 * Whether to passthru the output
+	 * @var boolean
+	 */
+	protected $passthru = false;
+
+	/**
+	 * Where to direct error output.
+	 * @var File
+	 */
+	protected $error;
+
+	/**
+	 * If spawn is set then [unix] programs will redirect stdout and add '&'.
+	 * @var boolean
+	 */
+	protected $spawn = false;
+
+	/**
+	 * Property name to set with return value from exec call.
+	 *
+	 * @var string
+	 */
+	protected $returnProperty;
+
+	/**
+	 * Whether to check the return code.
+	 * @var boolean
+	 */
+	protected $checkreturn = false;
+
+	/**
+	 * Main method: wraps execute() command.
+	 * @return void
+	 */
+	public function main() {
+		$this->execute();
+	}
+
+	/**
+	 * Executes a program and returns the return code.
+	 * Output from command is logged at INFO level.
+	 * @return int Return code from execution.
+	 */
+	public function execute() {
+
+		// test if os match
+		$myos = Phing::getProperty("os.name");
+		$this->log("Myos = " . $myos, Project::MSG_VERBOSE);
+		if (($this->os !== null) && (strpos($this->os, $myos) === false)) {
+			// this command will be executed only on the specified OS
+			$this->log("Not found in " . $this->os, Project::MSG_VERBOSE);
+			return 0;
+		}
+
+		if ($this->dir !== null) {
+			if ($this->dir->isDirectory()) {
+				$currdir = getcwd();
+				@chdir($this->dir->getPath());
+			} else {
+				throw new BuildException("Can't chdir to:" . $this->dir->__toString());
+			}
+		}
+
+
+		if ($this->escape == true) {
+			// FIXME - figure out whether this is correct behavior
+			$this->command = escapeshellcmd($this->command);
+		}
+
+		if ($this->error !== null) {
+			$this->command .= ' 2> ' . $this->error->getPath();
+			$this->log("Writing error output to: " . $this->error->getPath());
+		}
+
+		if ($this->output !== null) {
+			$this->command .= ' 1> ' . $this->output->getPath();
+			$this->log("Writing standard output to: " . $this->output->getPath());
+		} elseif ($this->spawn) {
+			$this->command .= ' 1>/dev/null';
+			$this->log("Sending ouptut to /dev/null");
+		}
+
+		// If neither output nor error are being written to file
+		// then we'll redirect error to stdout so that we can dump
+		// it to screen below.
+
+		if ($this->output === null && $this->error === null) {
+			$this->command .= ' 2>&1';
+		}
+
+		// we ignore the spawn boolean for windows
+		if ($this->spawn) {
+			$this->command .= ' &';
+		}
+
+		$this->log("Executing command: " . $this->command);
+
+		$output = array();
+		$return = null;
+		exec($this->command, $output, $return);
+
+		if ($this->dir !== null) {
+			@chdir($currdir);
+		}
+
+		foreach($output as $line) {
+			$this->log($line,  ($this->passthru ? Project::MSG_INFO : Project::MSG_VERBOSE));
+		}
+
+		if ($this->returnProperty) {
+			$this->project->setProperty($this->returnProperty, $return);
+		}
+
+		if($return != 0 && $this->checkreturn) {
+			throw new BuildException("Task exited with code $return");
+		}
+
+		return $return;
+	}
+
+	/**
+	 * The command to use.
+	 * @param mixed $command String or string-compatible (e.g. w/ __toString()).
+	 */
+	function setCommand($command) {
+		$this->command = "" . $command;
+	}
+
+	/**
+	 * Whether to use escapeshellcmd() to escape command.
+	 * @param boolean $escape
+	 */
+	function setEscape($escape) {
+		$this->escape = (bool) $escape;
+	}
+
+	/**
+	 * Specify the working directory for executing this command.
+	 * @param PhingFile $dir
+	 */
+	function setDir(PhingFile $dir) {
+		$this->dir = $dir;
+	}
+
+	/**
+	 * Specify OS (or muliple OS) that must match in order to execute this command.
+	 * @param string $os
+	 */
+	function setOs($os) {
+		$this->os = (string) $os;
+	}
+
+	/**
+	 * File to which output should be written.
+	 * @param PhingFile $output
+	 */
+	function setOutput(PhingFile $f) {
+		$this->output = $f;
+	}
+
+	/**
+	 * File to which error output should be written.
+	 * @param PhingFile $output
+	 */
+	function setError(PhingFile $f) {
+		$this->error = $f;
+	}
+
+	/**
+	 * Whether to use passthru the output.
+	 * @param boolean $passthru
+	 */
+	function setPassthru($passthru) {
+		$this->passthru = (bool) $passthru;
+	}
+
+	/**
+	 * Whether to suppress all output and run in the background.
+	 * @param boolean $spawn
+	 */
+	function setSpawn($spawn) {
+		$this->spawn  = (bool) $spawn;
+	}
+
+	/**
+	 * Whether to check the return code.
+	 * @param boolean $checkreturn
+	 */
+	function setCheckreturn($checkreturn) {
+		$this->checkreturn = (bool) $checkreturn;
+	}
+	
+	/**
+	 * The name of property to set to return value from exec() call.
+	 * @param string $prop
+	 */
+	function setReturnProperty($prop) {
+		$this->returnProperty = $prop;
+	}
+}
+
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/system/ExitTask.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/system/ExitTask.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/system/ExitTask.php	(revision 19)
@@ -0,0 +1,118 @@
+<?php
+/*
+ *  $Id: ExitTask.php 43 2006-03-10 14:31:51Z mrook $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+ 
+require_once 'phing/Task.php';
+
+/**
+ * Exits the active build, giving an additional message
+ * if available.
+ *
+ * @author    Hans Lellelid <hans@xmpl.org> (Phing)
+ * @author    Nico Seessle <nico@seessle.de> (Ant)
+ * @version   $Revision: 1.7 $
+ * @package   phing.tasks.system
+ */
+class ExitTask extends Task { 
+
+    private $message;
+    private $ifCondition;
+    private $unlessCondition;
+
+    /**
+     * A message giving further information on why the build exited.
+     *
+     * @param string $value message to output
+     */
+    public function setMsg($value) {
+        $this->setMessage($value);
+    }
+
+    /**
+     * A message giving further information on why the build exited.
+     *
+     * @param value message to output
+     */
+    public function setMessage($value) {
+        $this->message = $value;
+    }
+
+    /**
+     * Only fail if a property of the given name exists in the current project.
+     * @param c property name
+     */
+    public function setIf($c) {
+        $this->ifCondition = $c;
+    }
+
+    /**
+     * Only fail if a property of the given name does not
+     * exist in the current project.
+     * @param c property name
+     */
+    public function setUnless($c) {
+        $this->unlessCondition = $c;
+    }
+
+    /**
+     * @throws BuildException
+     */
+    public function main()  {
+        if ($this->testIfCondition() && $this->testUnlessCondition()) {
+            if ($this->message !== null) { 
+                throw new BuildException($this->message);
+            } else {
+                throw new BuildException("No message");
+            }
+        }
+    }
+
+    /**
+     * Set a multiline message.
+     */
+    public function addText($msg) {
+        if ($this->message === null) {
+            $this->message = "";
+        }
+        $this->message .= $this->project->replaceProperties($msg);
+    }
+
+    /**
+     * @return boolean
+     */
+    private function testIfCondition() {
+        if ($this->ifCondition === null || $this->ifCondition === "") {
+            return true;
+        }
+        
+        return $this->project->getProperty($this->ifCondition) !== null;
+    }
+    
+    /**
+     * @return boolean
+     */
+    private function testUnlessCondition() {
+        if ($this->unlessCondition === null || $this->unlessCondition ===  "") {
+            return true;
+        }
+        return $this->project->getProperty($this->unlessCondition) === null;
+    }
+
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/system/ForeachTask.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/system/ForeachTask.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/system/ForeachTask.php	(revision 19)
@@ -0,0 +1,138 @@
+<?php
+/*
+ *  $Id: ForeachTask.php 144 2007-02-05 15:19:00Z hans $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+require_once 'phing/Task.php';
+include_once 'phing/tasks/system/PhingTask.php';
+
+/**
+ * <foreach> task
+ *
+ * Task definition for the foreach task.  This task takes a list with
+ * delimited values, and executes a target with set param.
+ *
+ * Usage:
+ * <foreach list="values" target="targ" param="name" delimiter="|" />
+ *
+ * Attributes:
+ * list      --> The list of values to process, with the delimiter character,
+ *               indicated by the "delimiter" attribute, separating each value.
+ * target    --> The target to call for each token, passing the token as the
+ *               parameter with the name indicated by the "param" attribute.
+ * param     --> The name of the parameter to pass the tokens in as to the
+ *               target.
+ * delimiter --> The delimiter string that separates the values in the "list"
+ *               parameter.  The default is ",".
+ *
+ * @author    Jason Hines <jason@greenhell.com>
+ * @author    Hans Lellelid <hans@xmpl.org>
+ * @version   $Revision: 1.9 $
+ * @package   phing.tasks.system
+ */
+class ForeachTask extends Task {
+    
+    /** Delimter-separated list of values to process. */
+    private $list;
+    
+    /** Name of parameter to pass to callee */
+    private $param;
+    
+    /** Delimter that separates items in $list */
+    private $delimiter = ',';
+    
+    /**
+     * PhingCallTask that will be invoked w/ calleeTarget.
+     * @var PhingCallTask
+     */
+    private $callee;
+    
+    /**
+     * Target to execute.
+     * @var string
+     */
+    private $calleeTarget;
+
+    function init() {
+        $this->callee = $this->project->createTask("phingcall");
+        $this->callee->setOwningTarget($this->getOwningTarget());
+        $this->callee->setTaskName($this->getTaskName());
+        $this->callee->setLocation($this->getLocation());
+        $this->callee->init();
+    }
+
+    /**
+     * This method does the work.
+     * @return void
+     */   
+    function main() {
+        if ($this->list === null) {
+            throw new BuildException("Missing list to iterate through");
+        }
+        if (trim($this->list) === '') {
+            return;
+        }
+        if ($this->param === null) {
+            throw new BuildException("You must supply a property name to set on each iteration in param");
+        }
+        if ($this->calleeTarget === null) {
+            throw new BuildException("You must supply a target to perform");
+        }
+
+        $callee = $this->callee;
+        $callee->setTarget($this->calleeTarget);
+        $callee->setInheritAll(true);
+        $callee->setInheritRefs(true);
+        
+        $arr = explode($this->delimiter, $this->list);
+        
+        foreach ($arr as $value) {
+            $this->log("Setting param '$this->param' to value '$value'", Project::MSG_VERBOSE);
+            $prop = $callee->createProperty();
+            $prop->setOverride(true);
+            $prop->setName($this->param);
+            $prop->setValue($value);
+            $callee->main();
+        }
+    }
+
+    function setList($list) {
+        $this->list = (string) $list;
+    }
+
+    function setTarget($target) {
+        $this->calleeTarget = (string) $target;
+    }
+
+    function setParam($param) {
+        $this->param = (string) $param;
+    }
+
+    function setDelimiter($delimiter) {
+        $this->delimiter = (string) $delimiter;
+    }
+
+    /**
+     * @return Property
+     */
+    function createProperty() {
+        return $this->callee->createProperty();
+    }
+
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/system/IfTask.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/system/IfTask.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/system/IfTask.php	(revision 19)
@@ -0,0 +1,224 @@
+<?php
+
+/*
+ *  $Id: IfTask.php 43 2006-03-10 14:31:51Z mrook $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+ 
+require_once 'phing/tasks/system/condition/ConditionBase.php';
+require_once 'phing/tasks/system/SequentialTask.php';
+
+/**
+ * Perform some tasks based on whether a given condition holds true or
+ * not.
+ *
+ * <p>This task is heavily based on the Condition framework that can
+ * be found in Ant 1.4 and later, therefore it cannot be used in
+ * conjunction with versions of Ant prior to 1.4.</p>
+ *
+ * <p>This task doesn't have any attributes, the condition to test is
+ * specified by a nested element - see the documentation of your
+ * <code><condition&gt;</code> task (see
+ * <a href="http://jakarta.apache.org/ant/manual/CoreTasks/condition.html">the
+ * online documentation</a> for example) for a complete list of nested
+ * elements.</p>
+ *
+ * <p>Just like the <code><condition&gt;</code> task, only a single
+ * condition can be specified - you combine them using
+ * <code><and&gt;</code> or <code><or&gt;</code> conditions.</p>
+ *
+ * <p>In addition to the condition, you can specify three different
+ * child elements, <code><elseif&gt;</code>, <code><then&gt;</code> and
+ * <code><else&gt;</code>.  All three subelements are optional.
+ *
+ * Both <code><then&gt;</code> and <code><else&gt;</code> must not be
+ * used more than once inside the if task.  Both are
+ * containers for Ant tasks, just like Ant's
+ * <code><parallel&gt;</code> and <code><sequential&gt;</code>
+ * tasks - in fact they are implemented using the same class as Ant's
+ * <code><sequential&gt;</code> task.</p>
+ *
+ *  The <code><elseif&gt;</code> behaves exactly like an <code><if&gt;</code>
+ * except that it cannot contain the <code><else&gt;</code> element
+ * inside of it.  You may specify as may of these as you like, and the
+ * order they are specified is the order they are evaluated in.  If the
+ * condition on the <code><if&gt;</code> is false, then the first
+ * <code><elseif&gt;</code> who's conditional evaluates to true
+ * will be executed.  The <code><else&gt;</code> will be executed
+ * only if the <code><if&gt;</code> and all <code><elseif&gt;</code>
+ * conditions are false.
+ *
+ * <p>Use the following task to define the <code><if&gt;</code>
+ * task before you use it the first time:</p>
+ *
+ * <pre><code>
+ *   <taskdef name="if" classname="net.sf.antcontrib.logic.IfTask" /&gt;
+ * </code></pre>
+ *
+ * <h3>Crude Example</h3>
+ *
+ * <code>
+ * <if>
+ *  <equals arg1="${foo}" arg2="bar" />
+ *  <then>
+ *    <echo message="The value of property foo is bar" />
+ *  </then>
+ *  <else>
+ *    <echo message="The value of property foo is not bar" />
+ *  </else>
+ * </if>
+ * </code>
+ *
+ * <code>
+ * <if>
+ *  <equals arg1="${foo}" arg2="bar" /&gt;
+ *  <then>
+ *   <echo message="The value of property foo is 'bar'" />
+ *  </then>
+ *
+ *  <elseif>
+ *   <equals arg1="${foo}" arg2="foo" />
+ *   <then>
+ *    <echo message="The value of property foo is 'foo'" />
+ *   </then>
+ *  </elseif>
+ *
+ *  <else>
+ *   <echo message="The value of property foo is not 'foo' or 'bar'" />
+ *  </else>
+ * </if>
+ * </code>
+ *
+ * @author <a href="mailto:stefan.bodewig@freenet.de">Stefan Bodewig</a>
+ */
+class IfTask extends ConditionBase {
+
+
+    private $thenTasks = null;
+    private $elseIfTasks = array();
+    private $elseTasks = null;
+
+    /***
+     * A nested Else if task
+     */
+    public function addElseIf(ElseIfTask $ei)
+    {
+        $this->elseIfTasks[] = $ei;
+    }
+
+    /**
+     * A nested <then> element - a container of tasks that will
+     * be run if the condition holds true.
+     *
+     * <p>Not required.</p>
+     */
+    public function addThen(SequentialTask $t) {
+        if ($this->thenTasks != null) {
+            throw new BuildException("You must not nest more than one <then> into <if>");
+        }
+        $this->thenTasks = $t;
+    }
+
+    /**
+     * A nested <else> element - a container of tasks that will
+     * be run if the condition doesn't hold true.
+     *
+     * <p>Not required.</p>
+     */
+    public function addElse(SequentialTask $e) {
+        if ($this->elseTasks != null) {
+            throw new BuildException("You must not nest more than one <else> into <if>");
+        }
+        $this->elseTasks = $e;
+    }
+
+    public function main() {
+	
+        if ($this->countConditions() > 1) {
+            throw new BuildException("You must not nest more than one condition into <if>");
+        }
+        if ($this->countConditions() < 1) {
+            throw new BuildException("You must nest a condition into <if>");
+        }
+		$conditions = $this->getConditions();
+		$c = $conditions[0];
+		
+        if ($c->evaluate()) {
+            if ($this->thenTasks != null) {
+                $this->thenTasks->main();
+            }
+        } else {
+            $done = false;
+            $sz = count($this->elseIfTasks);
+			for($i=0; $i < $sz && !$done; $i++) {
+				$ei = $this->elseIfTasks[$i];
+                if ($ei->evaluate()) {
+                    $done = true;
+                    $ei->main();
+                }
+            }
+
+            if (!$done && $this->elseTasks != null) {
+                $this->elseTasks->main();
+            }
+        }
+    }
+}
+
+/**
+ * "Inner" class for IfTask.
+ * This class has same basic structure as the IfTask, although of course it doesn't support <else> tags.
+ */
+class ElseIfTask extends ConditionBase {
+
+        private $thenTasks = null;
+
+        public function addThen(SequentialTask $t) {
+            if ($this->thenTasks != null) {
+                throw new BuildException("You must not nest more than one <then> into <elseif>");
+            }
+            $this->thenTasks = $t;
+        }
+	
+		/**
+		 * @return boolean
+		 */
+        public function evaluate() {
+		
+            if ($this->countConditions() > 1) {
+                throw new BuildException("You must not nest more than one condition into <elseif>");
+            }
+            if ($this->countConditions() < 1) {
+                throw new BuildException("You must nest a condition into <elseif>");
+            }
+			
+			$conditions = $this->getConditions();
+			$c = $conditions[0];
+
+            return $c->evaluate();
+        }
+		
+		/**
+		 * 
+		 */
+        public function main() {
+            if ($this->thenTasks != null) {
+                $this->thenTasks->main();
+            }
+        }
+    }
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/system/IncludePathTask.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/system/IncludePathTask.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/system/IncludePathTask.php	(revision 19)
@@ -0,0 +1,115 @@
+<?php
+
+/*
+ * $Id: IncludePathTask.php 144 2007-02-05 15:19:00Z hans $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+ 
+require_once 'phing/Task.php';
+include_once 'phing/types/Path.php';
+
+/**
+ * Adds a normalized path to the PHP include_path.
+ * 
+ * This provides a way to alter the include_path without editing any global php.ini settings
+ * or PHP_CLASSPATH environment variable.
+ * 
+ * <code>
+ *   <includepath classpath="new/path/here"/>
+ * </code>
+ * 
+ * @author    Hans Lellelid <hans@xmpl.org>
+ * @version   $Revision: 1.1 $
+ * @package   phing.tasks.system
+ */
+class IncludePathTask extends Task {
+   
+    /**
+     * Classname of task to register.
+     * This can be a dot-path -- relative to a location on PHP include_path.
+     * E.g. path.to.MyClass ->  path/to/MyClass.php
+     * @var string
+     */
+    private $classname;
+    
+    /**
+     * Path to add to PHP include_path to aid in finding specified class.
+     * @var Path
+     */
+    private $classpath;
+    
+    /**
+     * Refid to already defined classpath
+     */
+    private $classpathId;
+    
+    /**
+     * Set the classpath to be used when searching for component being defined
+     * 
+     * @param Path $classpath An Path object containing the classpath.
+     */
+    public function setClasspath(Path $classpath) {
+        if ($this->classpath === null) {
+            $this->classpath = $classpath;
+        } else {
+            $this->classpath->append($classpath);
+        }
+    }
+
+    /**
+     * Create the classpath to be used when searching for component being defined
+     */ 
+    public function createClasspath() {
+        if ($this->classpath === null) {
+            $this->classpath = new Path($this->project);
+        }
+        return $this->classpath->createPath();
+    }
+
+    /**
+     * Reference to a classpath to use when loading the files.
+     */
+    public function setClasspathRef(Reference $r) {
+        $this->classpathId = $r->getRefId();
+        $this->createClasspath()->setRefid($r);
+    }
+
+    
+    /** Main entry point */
+    public function main() {
+    
+        // Apparently casting to (string) no longer invokes __toString() automatically.
+        if (is_object($this->classpath)) {
+            $this->classpath = $this->classpath->__toString();
+        }
+        
+        if (empty($this->classpath)) {
+            throw new BuildException("Provided classpath was empty.");
+        }
+        
+        $curr_parts = explode(PATH_SEPARATOR, get_include_path());
+        $add_parts = explode(PATH_SEPARATOR, $this->classpath);
+        $new_parts = array_diff($add_parts, $curr_parts);
+        
+        if ($new_parts) {
+            $this->log("Prepending new include_path components: " . implode(PATH_SEPARATOR, $new_parts), Project::MSG_VERBOSE);
+            set_include_path(implode(PATH_SEPARATOR, array_merge($new_parts, $curr_parts)));
+        }
+        
+    }
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/system/InputTask.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/system/InputTask.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/system/InputTask.php	(revision 19)
@@ -0,0 +1,146 @@
+<?php
+/*
+ *  $Id: InputTask.php 43 2006-03-10 14:31:51Z mrook $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+require_once 'phing/Task.php';
+include_once 'phing/input/InputRequest.php';
+include_once 'phing/input/YesNoInputRequest.php';
+include_once 'phing/input/MultipleChoiceInputRequest.php';
+ 
+/**
+ * Reads input from the InputHandler.
+ * 
+ * @see       Project::getInputHandler()
+ * @author    Hans Lellelid <hans@xmpl.org> (Phing)
+ * @author    Ulrich Schmidt <usch@usch.net> (Ant)
+ * @author    Stefan Bodewig <stefan.bodewig@epost.de> (Ant)
+ * @version   $Revision: 1.6 $
+ * @package   phing.tasks.system
+ */
+class InputTask extends Task {
+    
+    private $validargs;
+    private $message = ""; // required
+    private $propertyName; // required
+    private $defaultValue;
+    private $promptChar;
+    
+    /**
+     * Defines valid input parameters as comma separated strings. If set, input
+     * task will reject any input not defined as accepted and requires the user
+     * to reenter it. Validargs are case sensitive. If you want 'a' and 'A' to
+     * be accepted you need to define both values as accepted arguments.
+     *
+     * @param validargs A comma separated String defining valid input args.
+     */
+    public function setValidargs ($validargs) {
+        $this->validargs = $validargs;
+    }
+
+    /**
+     * Defines the name of a property to be set from input.
+     *
+     * @param string $name Name for the property to be set from input
+     */
+    public function setPropertyName($name) {
+        $this->propertyName = $name;
+    }
+
+    /**
+     * Sets the Message which gets displayed to the user during the build run.
+     * @param message The message to be displayed.
+     */
+    public function setMessage ($message) {
+        $this->message = $message;
+    }
+
+    /**
+     * Set a multiline message.
+     */
+    public function addText($msg) {
+        $this->message .= $this->project->replaceProperties($msg);
+    }
+    
+    /**
+     * Add a default value.
+     * @param string $v
+     */
+    public function setDefaultValue($v) {
+        $this->defaultValue = $v;
+    }
+    
+    /**
+     * Set the character/string to use for the prompt.
+     * @param string $c
+     */
+    public function setPromptChar($c) {
+        $this->promptChar = $c;
+    }
+    
+    /**
+     * Actual method executed by phing.
+     * @throws BuildException
+     */
+    public function main() {
+    
+        if ($this->propertyName === null) {
+            throw new BuildException("You must specify a value for propertyName attribute.");
+        }
+        
+        if ($this->validargs !== null) {
+            $accept = preg_split('/[\s,]+/', $this->validargs);
+            
+            // is it a boolean (yes/no) inputrequest?
+            $yesno = false;
+            if (count($accept) == 2) {
+                $yesno = true;
+                foreach($accept as $ans) {
+                    if(!StringHelper::isBoolean($ans)) {
+                        $yesno = false;
+                        break;
+                    }
+                }
+            }
+            if ($yesno) $request = new YesNoInputRequest($this->message, $accept);
+            else $request = new MultipleChoiceInputRequest($this->message, $accept);
+        } else {
+            $request = new InputRequest($this->message);
+        }
+        
+        // default default is curr prop value        
+        $request->setDefaultValue($this->project->getProperty($this->propertyName));
+        
+        $request->setPromptChar($this->promptChar);
+        
+        // unless overridden...
+        if ($this->defaultValue !== null) {
+            $request->setDefaultValue($this->defaultValue);
+        }
+        
+        $this->project->getInputHandler()->handleInput($request);
+
+        $value = $request->getInput();
+        
+        if ($value !== null) {
+            $this->project->setUserProperty($this->propertyName, $value);
+        }
+    }
+
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/system/MatchingTask.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/system/MatchingTask.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/system/MatchingTask.php	(revision 19)
@@ -0,0 +1,361 @@
+<?php
+/*
+ *  $Id: MatchingTask.php 43 2006-03-10 14:31:51Z mrook $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+require_once 'phing/Task.php';
+require_once 'phing/types/selectors/SelectorContainer.php';
+include_once 'phing/types/FileSet.php';
+include_once 'phing/types/PatternSet.php';
+include_once 'phing/util/DirectoryScanner.php';
+
+/**
+ * This is an abstract task that should be used by all those tasks that 
+ * require to include or exclude files based on pattern matching.
+ *
+ * This is very closely based on the ANT class of the same name.
+ * 
+ * @author    Hans Lellelid <hans@xmpl.org> (Phing)
+ * @author    Arnout J. Kuiper <ajkuiper@wxs.nl> (Ant)
+ * @author    Stefano Mazzocchi  <stefano@apache.org> (Ant)
+ * @author    Sam Ruby <rubys@us.ibm.com> (Ant)
+ * @author    Jon S. Stevens <jon@clearink.com> (Ant
+ * @author    Stefan Bodewig <stefan.bodewig@epost.de> (Ant)
+ * @author    Bruce Atherton <bruce@callenish.com> (Ant)
+ * @version   $Revision: 1.4 $
+ * @package   phing.tasks.system
+ */
+abstract class MatchingTask extends Task implements SelectorContainer {
+
+    /** @var boolean */
+    protected $useDefaultExcludes = true;
+    
+    /** @var FileSet */
+    protected $fileset;
+    
+    /**
+     * Create instance; set fileset to new FileSet.
+     */
+    public function __construct() {
+        $this->fileset = new FileSet();
+    }
+    
+    /**
+     * @see ProjectComponent::setProject()
+     */
+    public function setProject(Project $project) {
+        parent::setProject($project);
+        $this->fileset->setProject($project);
+    }
+
+    /**
+     * add a name entry on the include list
+     * @return PatternSetNameEntry
+     */
+    public function createInclude() {
+        return $this->fileset->createInclude();
+    }
+
+    /**
+     * add a name entry on the include files list
+     * @return PatternSetNameEntry
+     */
+    public function createIncludesFile() {
+        return $this->fileset->createIncludesFile();
+    }
+
+    /**
+     * add a name entry on the exclude list
+     * @return PatternSetNameEntry
+     */
+    public function createExclude() {
+        return $this->fileset->createExclude();
+    }
+
+    /**
+     * add a name entry on the include files list
+     * @return PatternSetNameEntry
+     */
+    public function createExcludesFile() {
+        return $this->fileset->createExcludesFile();
+    }
+
+    /**
+     * add a set of patterns
+     * @return PatternSet
+     */
+    public function createPatternSet() {
+        return $this->fileset->createPatternSet();
+    }
+
+    /**
+     * Sets the set of include patterns. Patterns may be separated by a comma
+     * or a space.
+     *
+     * @param string $includes the string containing the include patterns
+     * @return void
+     */
+    public function setIncludes($includes) {
+        $this->fileset->setIncludes($includes);
+    }    
+
+    /**
+     * Sets the set of exclude patterns. Patterns may be separated by a comma
+     * or a space.
+     *
+     * @param string $excludes the string containing the exclude patterns
+     */
+    public function setExcludes($excludes) {
+        $this->fileset->setExcludes($excludes);
+    }
+
+    
+    /**
+     * Sets whether default exclusions should be used or not.
+     *
+     * @param boolean $useDefaultExcludes "true"|"on"|"yes" when default exclusions
+     *                           should be used, "false"|"off"|"no" when they
+     *                           shouldn't be used.
+     */
+    public function setDefaultexcludes($useDefaultExcludes) {
+        $this->useDefaultExcludes = (boolean) $useDefaultExcludes;
+    }
+
+    /**
+     * Returns the directory scanner needed to access the files to process.
+     * @return DirectoryScanner
+     */
+    protected function getDirectoryScanner(PhingFile $baseDir) {
+        $this->fileset->setDir($baseDir);
+        $this->fileset->setDefaultexcludes($this->useDefaultExcludes);
+        return $this->fileset->getDirectoryScanner($this->project);
+    }
+
+    /**
+     * Sets the name of the file containing the includes patterns.
+     *
+     * @param PhingFile $includesfile A string containing the filename to fetch
+     * the include patterns from.
+     * @return void
+     */
+    public function setIncludesfile(PhingFile $includesfile) {
+        $this->fileset->setIncludesfile(includesfile);
+    }
+
+    /**
+     * Sets the name of the file containing the includes patterns.
+     *
+     * @param PhingFile $excludesfile A string containing the filename to fetch
+     * the include patterns from.
+     * @return void
+     */
+    public function setExcludesfile(PhingFile $excludesfile) {
+        $this->fileset->setExcludesfile($excludesfile);
+    }
+
+    /**
+     * Sets case sensitivity of the file system
+     *
+     * @param boolean $isCaseSensitive "true"|"on"|"yes" if file system is case
+     *                           sensitive, "false"|"off"|"no" when not.
+     * @return void
+     */
+    public function setCaseSensitive($isCaseSensitive) {
+        $this->fileset->setCaseSensitive($isCaseSensitive);
+    }
+
+    /**
+     * Sets whether or not symbolic links should be followed.
+     *
+     * @param boolean $followSymlinks whether or not symbolic links should be followed
+     * @return void
+     */
+    public function setFollowSymlinks($followSymlinks) {
+        $this->fileset->setFollowSymlinks($followSymlinks);
+    }
+
+    /**
+     * Indicates whether there are any selectors here.
+     *
+     * @return boolean Whether any selectors are in this container
+     */
+    public function hasSelectors() {
+        return $this->fileset->hasSelectors();
+    }
+
+    /**
+     * Gives the count of the number of selectors in this container
+     *
+     * @return int The number of selectors in this container
+     */
+    public function selectorCount() {
+        return $this->fileset->selectorCount();
+    }
+
+    /**
+     * Returns the set of selectors as an array.
+     *
+     * @return array FileSelector[] An array of selectors in this container
+     */
+    public function getSelectors(Project $p) {
+        return $this->fileset->getSelectors($p);
+    }
+
+    /**
+     * Returns an enumerator for accessing the set of selectors.
+     *
+     * @return an enumerator that goes through each of the selectors
+     */
+    public function selectorElements() {
+        return $this->fileset->selectorElements();
+    }
+
+    /**
+     * Add a new selector into this container.
+     *
+     * @param FileSelector $selector the new selector to add
+     * @return void
+     */
+    public function appendSelector(FileSelector $selector) {
+        $this->fileset->appendSelector($selector);
+    }
+
+    /* Methods below all add specific selectors */
+
+    /**
+     * add a "Select" selector entry on the selector list
+     * @return SelectSelector
+     */
+    public function createSelector() {
+        return $this->fileset->createSelector();
+    }
+
+    /**
+     * add an "And" selector entry on the selector list
+     * @return AndSelector
+     */
+    public function createAnd() {
+        return $this->fileset->createAnd();
+    }
+
+    /**
+     * add an "Or" selector entry on the selector list
+     * @return void
+     */
+    public function createOr() {
+        return $this->fileset->createOr();
+    }
+
+    /**
+     * add a "Not" selector entry on the selector list
+     * @return NotSelector
+     */
+    public function createNot() {
+        return $this->fileset->createNot();
+    }
+
+    /**
+     * add a "None" selector entry on the selector list
+     * @return NoneSelector
+     */
+    public function createNone() {
+        return $this->fileset->createNone();
+    }
+
+    /**
+     * add a majority selector entry on the selector list
+     * @return MajoritySelector
+     */
+    public function createMajority() {
+        return $this->fileset->createMajority();
+    }
+
+    /**
+     * add a selector date entry on the selector list
+     * @return DateSelector
+     */
+    public function createDate() {
+        return $this->fileset->addDate();
+    }
+
+    /**
+     * add a selector size entry on the selector list
+     * @return SizeSelector
+     */
+    public function createSize() {
+        return $this->fileset->createSize();
+    }
+
+    /**
+     * add a selector filename entry on the selector list
+     * @return FilenameSelector
+     */
+    public function createFilename() {
+        return $this->fileset->createFilename();
+    }
+
+    /**
+     * add an extended selector entry on the selector list
+     * @return ExtendSelector
+     */
+    public function createCustom() {
+        return $this->fileset->createCustom();
+    }
+
+    /**
+     * add a contains selector entry on the selector list
+     * @return ContainsSelector
+     */
+    public function createContains() {
+        return $this->fileset->createContains();
+    }
+
+    /**
+     * add a present selector entry on the selector list
+     * @return PresentSelector
+     */
+    public function createPresent() {
+        return $this->fileset->createPresent();
+    }
+
+    /**
+     * add a depth selector entry on the selector list
+     * @return DepthSelector
+     */
+    public function createDepth() {
+        return $this->fileset->createDepth();
+    }
+
+    /**
+     * add a depends selector entry on the selector list
+     * @return DependSelector
+     */
+    public function createDepend() {
+        return $this->fileset->createDepend();
+    }
+
+    /**
+     * Accessor for the implict fileset.
+     *
+     * @return FileSet
+     */
+    protected final function getImplicitFileSet() {
+        return $this->fileset;
+    }
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/system/MkdirTask.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/system/MkdirTask.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/system/MkdirTask.php	(revision 19)
@@ -0,0 +1,64 @@
+<?php
+/*
+ *  $Id: MkdirTask.php 43 2006-03-10 14:31:51Z mrook $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+require_once 'phing/Task.php';
+include_once 'phing/system/io/PhingFile.php';
+
+/**
+ * Task to create a directory.
+ *
+ * @author   Andreas Aderhold, andi@binarycloud.com
+ * @version  $Revision: 1.8 $
+ * @package  phing.tasks.system
+ */
+class MkdirTask extends Task {
+
+    /** directory to create*/
+    private $dir;
+
+    /**
+     * create the directory and all parents
+     *
+     * @throws BuildException if dir is somehow invalid, or creation failed.
+     */
+    function main() {
+        if ($this->dir === null) {
+            throw new BuildException("dir attribute is required", $this->location);
+        }
+        if ($this->dir->isFile()) {
+            throw new BuildException("Unable to create directory as a file already exists with that name: " . $this->dir->getAbsolutePath());
+        }
+        if (!$this->dir->exists()) {
+            $result = $this->dir->mkdirs();
+            if (!$result) {
+                $msg = "Directory " . $this->dir->getAbsolutePath() . " creation was not successful for an unknown reason";
+                throw new BuildException($msg, $this->location);
+            }
+            $this->log("Created dir: " . $this->dir->getAbsolutePath());
+        }
+    }
+
+    /** the directory to create; required. */
+    function setDir(PhingFile $dir) {
+        $this->dir = $dir;
+    }
+
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/system/MoveTask.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/system/MoveTask.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/system/MoveTask.php	(revision 19)
@@ -0,0 +1,247 @@
+<?php
+/*
+ *  $Id: MoveTask.php 325 2007-12-20 15:44:58Z hans $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+require_once 'phing/tasks/system/CopyTask.php';
+include_once 'phing/system/io/PhingFile.php';
+include_once 'phing/system/io/IOException.php';
+
+/**
+ * Moves a file or directory to a new file or directory.
+ * 
+ * By default, the destination file is overwritten if it
+ * already exists.  When overwrite is turned off, then files
+ * are only moved if the source file is newer than the
+ * destination file, or when the destination file does not
+ * exist.
+ *
+ * Source files and directories are only deleted when the file or
+ * directory has been copied to the destination successfully.
+ *
+ * @version $Revision: 1.8 $
+ * @package phing.tasks.system
+ */
+class MoveTask extends CopyTask {
+
+    function __construct() {
+        parent::__construct();
+        $this->forceOverwrite = true;
+    }
+    
+    /**
+     * Validates attributes coming in from XML
+     *
+     * @access  private
+     * @return  void
+     * @throws  BuildException
+     */
+    protected function validateAttributes() {    
+        if ($this->file !== null && $this->file->isDirectory()) {
+			if (($this->destFile !== null && $this->destDir !== null)
+				|| ($this->destFile === null && $this->destDir === null)) {
+					throw new BuildException("One and only one of tofile and todir must be set.");
+			}
+            
+            if ($this->destFile === null)
+            {
+				$this->destFile = new PhingFile($this->destDir, $this->file->getName());
+			}
+            
+            if ($this->destDir === null)
+            {
+				$this->destDir = $this->destFile->getParentFile();
+			}
+            
+			$this->completeDirMap[$this->file->getAbsolutePath()] = $this->destFile->getAbsolutePath();
+			
+			$this->file = null;
+		} else {
+			parent::validateAttributes();
+		}
+    }
+    
+    protected function doWork() {
+		if (count($this->completeDirMap) > 0)
+		{
+			foreach ($this->completeDirMap as $from => $to)
+			{
+                $f = new PhingFile($from);
+                $d = new PhingFile($to);
+                
+                $moved = false;
+                try { // try to rename                    
+                    $this->log("Attempting to rename $from to $to", $this->verbosity);
+                    $this->renameFile($f, $d, $this->forceOverwrite);
+                    $moved = true;
+                } catch (IOException $ioe) {
+                    $moved = false;
+                    $this->log("Failed to rename $from to $to: " . $ioe->getMessage(), $this->verbosity);
+                }
+			}
+		}
+    
+        $copyMapSize = count($this->fileCopyMap);
+        if ($copyMapSize > 0) {
+            // files to move
+            $this->log("Moving $copyMapSize files to " . $this->destDir->getAbsolutePath());
+
+            foreach($this->fileCopyMap as $from => $to) {
+                if ($from == $to) {
+                    $this->log("Skipping self-move of $from", $this->verbosity);
+                    continue;
+                }
+
+                $moved = false;
+                $f = new PhingFile($from);
+                $d = new PhingFile($to);
+                
+                $moved = false;
+                try { // try to rename                    
+                    $this->log("Attempting to rename $from to $to", $this->verbosity);
+                    $this->renameFile($f, $d, $this->forceOverwrite);
+                    $moved = true;
+                } catch (IOException $ioe) {
+                    $moved = false;
+                    $this->log("Failed to rename $from to $to: " . $ioe->getMessage(), $this->verbosity);
+                }
+
+                if (!$moved) {                    
+                    try { // try to move
+                        $this->log("Moving $from to $to", $this->verbosity);
+
+                        $this->fileUtils->copyFile($f, $d, $this->forceOverwrite, $this->preserveLMT, $this->filterChains, $this->getProject());                        
+
+                        $f = new PhingFile($fromFile);
+                        $f->delete();
+                    } catch (IOException $ioe) {
+                        $msg = "Failed to move $from to $to: " . $ioe->getMessage();
+                        throw new BuildException($msg, $this->location);
+                    }
+                } // if !moved
+            } // foreach fileCopyMap
+        } // if copyMapSize
+
+        // handle empty dirs if appropriate
+        if ($this->includeEmpty) {
+            $e = array_keys($this->dirCopyMap);
+            $count = 0;
+            foreach ($e as $dir) {
+                $d = new PhingFile((string) $dir);
+                if (!$d->exists()) {
+                    if (!$d->mkdirs()) {
+                        $this->log("Unable to create directory " . $d->getAbsolutePath(), Project::MSG_ERR);
+                    } else {
+                        $count++;
+                    }
+                }
+            }
+            if ($count > 0) {
+                $this->log("moved $count empty director" . ($count == 1 ? "y" : "ies") . " to " . $this->destDir->getAbsolutePath());
+            }
+        }
+
+        if (count($this->filesets) > 0) {
+            // process filesets
+            foreach($this->filesets as $fs) {
+                $dir = $fs->getDir($this->project);
+                if ($this->okToDelete($dir)) {
+                    $this->deleteDir($dir);
+                }
+            }
+        }
+    }
+
+    /** Its only ok to delete a dir tree if there are no files in it. */
+    private function okToDelete($d) {
+        $list = $d->listDir();
+        if ($list === null) {
+            return false;     // maybe io error?
+        }
+        
+        foreach($list as $s) {
+            $f = new PhingFile($d, $s);
+            if ($f->isDirectory()) {
+                if (!$this->okToDelete($f)) {
+                    return false;
+                }
+            } else {
+                // found a file
+                return false;
+            }
+        }
+        return true;
+    }
+
+    /** Go and delete the directory tree. */
+    private function deleteDir($d) {
+    
+        $list = $d->listDir();
+        if ($list === null) {
+            return;      // on an io error list() can return null
+        }
+        
+        foreach($list as $fname) {
+            $f = new PhingFile($d, $fname);
+            if ($f->isDirectory()) {
+                $this->deleteDir($f);
+            } else {
+                throw new BuildException("UNEXPECTED ERROR - The file " . $f->getAbsolutePath() . " should not exist!");
+            }
+        }
+
+        $this->log("Deleting directory " . $d->getPath(), $this->verbosity);
+        try {
+            $d->delete();
+        } catch (Exception $e) {
+            throw new BuildException("Unable to delete directory " . $d->__toString() . ": " . $e->getMessage());
+        }
+    }
+
+    /**
+     * Attempts to rename a file from a source to a destination.
+     * If overwrite is set to true, this method overwrites existing file
+     * even if the destination file is newer.
+     * Otherwise, the source f
+     * ile is renamed only if the destination file #
+     * is older than it.
+     */
+    private function renameFile(PhingFile $sourceFile, PhingFile $destFile, $overwrite) {
+        $renamed = true;
+
+        // ensure that parent dir of dest file exists!
+        $parent = $destFile->getParentFile();
+        if ($parent !== null) {
+            if (!$parent->exists()) {
+                $parent->mkdirs();
+            }
+        }
+        if ($destFile->exists()) {
+            try {
+                $destFile->delete();
+            } catch (Exception $e) {
+                throw new BuildException("Unable to remove existing file " . $destFile->__toString() . ": " . $e->getMessage());
+            }
+        }
+        $renamed = $sourceFile->renameTo($destFile);
+
+        return $renamed;
+    }
+}
+
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/system/PhingCallTask.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/system/PhingCallTask.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/system/PhingCallTask.php	(revision 19)
@@ -0,0 +1,161 @@
+<?php
+/*
+ *  $Id: PhingCallTask.php 299 2007-11-08 20:31:19Z hans $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+require_once 'phing/Task.php';
+
+/**
+ * Call another target in the same project.
+ *
+ * <samp>
+ *    <target name="foo">
+ *      <phingcall target="bar">
+ *        <property name="property1" value="aaaaa" />
+ *        <property name="foo" value="baz" />
+ *       </phingcall>
+ *    </target>
+ *
+ *    <target name="bar" depends="init">
+ *      <echo message="prop is ${property1} ${foo}" />
+ *    </target>
+ * </samp>
+ *
+ * This only works as expected if neither property1 nor foo are defined in the project itself.
+ *
+ * @author    Andreas Aderhold <andi@binarycloud.com>
+ * @copyright 2001,2002 THYRELL. All rights reserved
+ * @version   $Revision: 1.9 $
+ * @access    public
+ * @package   phing.tasks.system
+ */
+class PhingCallTask extends Task {
+
+	/**
+	 * The called Phing task.
+	 *
+	 * @var PhingTask
+	 */
+	private $callee;
+
+	/**
+	 * The target to call.
+	 *
+	 * @var string
+	 */
+	private $subTarget;
+
+	/**
+	 * Whether to inherit all properties from current project.
+	 *
+	 * @var boolean
+	 */
+	private $inheritAll = true;
+
+	/**
+	 * Whether to inherit refs from current project.
+	 *
+	 * @var boolean
+	 */
+	private $inheritRefs = false;
+
+	/**
+	 *  If true, pass all properties to the new Phing project.
+	 *  Defaults to true. Future use.
+	 *  @param boolean new value
+	 */
+	function setInheritAll($inherit) {
+		$this->inheritAll = (boolean) $inherit;
+	}
+
+	/**
+	 *  If true, pass all references to the new Phing project.
+	 *  Defaults to false. Future use.
+	 *
+	 *  @param boolean new value
+	 */
+	function setInheritRefs($inheritRefs) {
+		$this->inheritRefs = (boolean) $inheritRefs;
+	}
+
+	/**
+	 * Alias for createProperty
+	 * @see createProperty()
+	 */
+	function createParam() {
+		if ($this->callee === null) {
+			$this->init();
+		}
+		return $this->callee->createProperty();
+	}
+
+	/**
+	 * Property to pass to the invoked target.
+	 */
+	function createProperty() {
+		if ($this->callee === null) {
+			$this->init();
+		}
+		return $this->callee->createProperty();
+	}
+
+	/**
+	 * Target to execute, required.
+	 */
+	function setTarget($target) {
+		$this->subTarget = (string) $target;
+	}
+
+	/**
+	 *  init this task by creating new instance of the phing task and
+	 *  configuring it's by calling its own init method.
+	 */
+	function init() {
+		$this->callee = $this->project->createTask("phing");
+		$this->callee->setOwningTarget($this->getOwningTarget());
+		$this->callee->setTaskName($this->getTaskName());
+		$this->callee->setHaltOnFailure(true);
+		$this->callee->setLocation($this->getLocation());
+		$this->callee->init();
+	}
+
+	/**
+	 *  hand off the work to the phing task of ours, after setting it up
+	 *  @throws BuildException on validation failure or if the target didn't
+	 *  execute
+	 */
+	function main() {
+
+		$this->log("Running PhingCallTask for target '" . $this->subTarget . "'", Project::MSG_DEBUG);
+		if ($this->callee === null) {
+			$this->init();
+		}
+
+		if ($this->subTarget === null) {
+			throw new BuildException("Attribute target is required.", $this->getLocation());
+		}
+
+		$this->callee->setPhingfile($this->project->getProperty("phing.file"));
+		$this->callee->setTarget($this->subTarget);
+		$this->callee->setInheritAll($this->inheritAll);
+		$this->callee->setInheritRefs($this->inheritRefs);
+		$this->callee->main();
+	}
+
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/system/PhingTask.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/system/PhingTask.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/system/PhingTask.php	(revision 19)
@@ -0,0 +1,623 @@
+<?php
+
+/*
+ *  $Id: PhingTask.php 303 2007-11-08 20:39:33Z hans $  
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+*/
+
+include_once 'phing/Task.php';
+include_once 'phing/util/FileUtils.php';
+include_once 'phing/types/Reference.php';
+include_once 'phing/tasks/system/PropertyTask.php';
+
+/**
+ * Task that invokes phing on another build file.
+ * 
+ * Use this task, for example, if you have nested buildfiles in your project. Unlike
+ * AntTask, PhingTask can even support filesets:
+ * 
+ * <pre>
+ *   <phing>
+ *    <fileset dir="${srcdir}">
+ *      <include name="** /build.xml" /> <!-- space added after ** is there because of PHP comment syntax -->
+ *      <exclude name="build.xml" />
+ *    </fileset>
+ *   </phing>
+ * </pre>
+ * 
+ * @author    Hans Lellelid <hans@xmpl.org>
+ * @version   $Revision: 1.20 $
+ * @package   phing.tasks.system
+ */
+class PhingTask extends Task {
+
+    /** the basedir where is executed the build file */
+    private $dir;
+    
+    /** build.xml (can be absolute) in this case dir will be ignored */
+    private $phingFile;
+    
+    /** the target to call if any */
+    protected $newTarget;
+    
+    /** should we inherit properties from the parent ? */
+    private $inheritAll = true;
+    
+    /** should we inherit references from the parent ? */
+    private $inheritRefs = false;
+
+    /** the properties to pass to the new project */
+    private $properties = array();
+
+    /** the references to pass to the new project */
+    private $references = array();
+
+    /** The filesets that contain the files PhingTask is to be run on. */
+    private $filesets = array();
+
+    /** the temporary project created to run the build file */
+    private $newProject;
+
+    /** Fail the build process when the called build fails? */
+    private $haltOnFailure = false;
+
+    /**
+     *  If true, abort the build process if there is a problem with or in the target build file.
+     *  Defaults to false.
+     *
+     *  @param boolean new value
+     */
+    public function setHaltOnFailure($hof) {
+        $this->haltOnFailure = (boolean) $hof;
+    }
+
+    /**
+     * Creates a Project instance for the project to call.
+     * @return void
+     */
+    public function init() {
+        $this->newProject = new Project();
+        $tdf = $this->project->getTaskDefinitions();
+        $this->newProject->addTaskDefinition("property", $tdf["property"]);
+    }
+
+    /**
+     * Called in execute or createProperty if newProject is null.
+     *
+     * <p>This can happen if the same instance of this task is run
+     * twice as newProject is set to null at the end of execute (to
+     * save memory and help the GC).</p>
+     *
+     * <p>Sets all properties that have been defined as nested
+     * property elements.</p>
+     */
+    private function reinit() {
+        $this->init();
+        $count = count($this->properties);
+        for ($i = 0; $i < $count; $i++) {
+            $p = $this->properties[$i];
+            $newP = $this->newProject->createTask("property");
+            $newP->setName($p->getName());
+            if ($p->getValue() !== null) {
+                $newP->setValue($p->getValue());
+            }
+            if ($p->getFile() !== null) {
+                $newP->setFile($p->getFile());
+            }            
+            if ($p->getPrefix() !== null) {
+                $newP->setPrefix($p->getPrefix());
+            }
+            if ($p->getRefid() !== null) {
+                $newP->setRefid($p->getRefid());
+            }
+            if ($p->getEnvironment() !== null) {
+                $newP->setEnvironment($p->getEnvironment());
+            }
+            if ($p->getUserProperty() !== null) {
+                $newP->setUserProperty($p->getUserProperty());
+            }
+            if ($p->getOverride() !== null) {
+                $newP->setOverride($p->getOverride());
+            }
+            $this->properties[$i] = $newP;
+        }
+    }
+
+    /**
+     * Main entry point for the task.
+     *
+     * @return void
+     */
+    public function main() {
+    
+        // Call Phing on the file set with the attribute "phingfile"
+        if ($this->phingFile !== null or $this->dir !== null) {
+            $this->processFile();
+        }
+
+        // if no filesets are given stop here; else process filesets
+        if (empty($this->filesets)) { 
+            return;
+        }
+        
+        // preserve old settings
+        $savedDir = $this->dir;
+        $savedPhingFile = $this->phingFile;
+        $savedTarget = $this->newTarget;
+
+        // set no specific target for files in filesets
+        // [HL] I'm commenting this out; I don't know why this should not be supported!
+        // $this->newTarget = null;
+        
+        foreach($this->filesets as $fs) {
+
+            $ds = $fs->getDirectoryScanner($this->project);
+
+            $fromDir  = $fs->getDir($this->project);
+            $srcFiles = $ds->getIncludedFiles();
+
+            foreach($srcFiles as $fname) {            
+                $f = new PhingFile($ds->getbasedir(), $fname);
+                $f = $f->getAbsoluteFile();
+                $this->phingFile = $f->getAbsolutePath();
+                $this->dir = $f->getParentFile();
+                $this->processFile();    // run Phing!
+            }
+        }        
+        
+        // side effect free programming ;-)
+        $this->dir = $savedDir;        
+        $this->phingFile = $savedPhingFile;
+        $this->newTarget = $savedTarget;
+        
+        // [HL] change back to correct dir
+        if ($this->dir !== null) {
+            chdir($this->dir->getAbsolutePath());
+        }
+        
+    }
+    
+    /**
+     * Execute phing file.
+     * 
+     * @return void
+     */
+    private function processFile()  {
+
+    	$buildFailed = false;
+        $savedDir = $this->dir;
+        $savedPhingFile = $this->phingFile;
+        $savedTarget = $this->newTarget;
+        
+		$savedBasedirAbsPath = null; // this is used to save the basedir *if* we change it
+        
+        try {
+        
+            if ($this->newProject === null) {
+                $this->reinit();
+            }
+
+            $this->initializeProject();
+            
+            if ($this->dir !== null) {
+            	
+            	$dirAbsPath = $this->dir->getAbsolutePath();
+            	
+            	// BE CAREFUL! -- when the basedir is changed for a project,
+            	// all calls to getAbsolutePath() on a relative-path dir will
+            	// be made relative to the project's basedir!  This means
+            	// that subsequent calls to $this->dir->getAbsolutePath() will be WRONG!
+            	
+            	// We need to save the current project's basedir first.
+            	$savedBasedirAbsPath = $this->getProject()->getBasedir()->getAbsolutePath();
+				 
+                $this->newProject->setBasedir($this->dir);
+                
+                // Now we must reset $this->dir so that it continues to resolve to the same
+                // path.
+                $this->dir = new PhingFile($dirAbsPath);
+                
+                if ($savedDir !== null) { // has been set explicitly
+                    $this->newProject->setInheritedProperty("project.basedir", $this->dir->getAbsolutePath());
+                }
+                
+            } else {
+            	
+            	// Since we're not changing the basedir here (for file resolution),
+            	// we don't need to worry about any side-effects in this scanrio.
+                $this->dir = $this->getProject()->getBasedir();   
+            }
+
+            $this->overrideProperties();
+            if ($this->phingFile === null) {
+                $this->phingFile = "build.xml";
+            }
+            
+            $fu = new FileUtils();
+            $file = $fu->resolveFile($this->dir, $this->phingFile);
+            $this->phingFile = $file->getAbsolutePath();
+            
+            $this->log("Calling Buildfile '" . $this->phingFile . "' with target '" . $this->newTarget . "'");
+                        
+            $this->newProject->setUserProperty("phing.file", $this->phingFile);
+                       
+            ProjectConfigurator::configureProject($this->newProject, new PhingFile($this->phingFile));
+
+            if ($this->newTarget === null) {
+                $this->newTarget = $this->newProject->getDefaultTarget();
+            }
+
+            // Are we trying to call the target in which we are defined?
+            if ($this->newProject->getBaseDir() == $this->project->getBaseDir() &&
+                $this->newProject->getProperty("phing.file") == $this->project->getProperty("phing.file") &&
+                $this->getOwningTarget() !== null &&
+                $this->newTarget == $this->getOwningTarget()->getName()) {
+
+                throw new BuildException("phing task calling its own parent target");
+            }
+
+            $this->addReferences();
+            $this->newProject->executeTarget($this->newTarget);
+            
+        } catch (Exception $e) {
+            $buildFailed = true;
+            $this->log($e->getMessage(), Project::MSG_ERR);
+        	if (Phing::getMsgOutputLevel() <= Project::MSG_DEBUG) { 
+				$lines = explode("\n", $e->getTraceAsString());
+				foreach($lines as $line) {
+					$this->log($line, Project::MSG_DEBUG);
+				}
+            }
+            // important!!! continue on to perform cleanup tasks.    
+		}
+        
+        
+        // reset environment values to prevent side-effects.
+        
+        $this->newProject = null;
+        $pkeys = array_keys($this->properties);
+        foreach($pkeys as $k) {
+            $this->properties[$k]->setProject(null);
+        }
+        
+        $this->dir = $savedDir;        
+        $this->phingFile = $savedPhingFile;
+        $this->newTarget = $savedTarget;
+        
+        // If the basedir for any project was changed, we need to set that back here.
+        if ($savedBasedirAbsPath !== null) {
+            chdir($savedBasedirAbsPath);
+        }
+
+        if ($this->haltOnFailure && $buildFailed) {
+			throw new BuildException("Execution of the target buildfile failed. Aborting.");
+		}
+    }
+
+    /**
+     * Configure the Project, i.e. make intance, attach build listeners
+     * (copy from father project), add Task and Datatype definitions,
+     * copy properties and references from old project if these options
+     * are set via the attributes of the XML tag.
+     *
+     * Developer note:
+     * This function replaces the old methods "init", "_reinit" and 
+     * "_initializeProject".
+     *
+     * @access      protected
+     */
+    private function initializeProject() {
+        
+        $this->newProject->setInputHandler($this->project->getInputHandler());
+        
+        foreach($this->project->getBuildListeners() as $listener) {
+            $this->newProject->addBuildListener($listener);
+        }
+        
+        /* Copy things from old project. Datatypes and Tasks are always
+         * copied, properties and references only if specified so/not
+         * specified otherwise in the XML definition.
+         */
+        // Add Datatype definitions
+        foreach ($this->project->getDataTypeDefinitions() as $typeName => $typeClass) {
+            $this->newProject->addDataTypeDefinition($typeName, $typeClass);
+        }
+        
+        // Add Task definitions
+        foreach ($this->project->getTaskDefinitions() as $taskName => $taskClass) {
+            if ($taskClass == "propertytask") {
+                // we have already added this taskdef in init()
+                continue;
+            }
+            $this->newProject->addTaskDefinition($taskName, $taskClass);
+        }
+
+        // set user-defined properties
+        $this->project->copyUserProperties($this->newProject);
+
+        if (!$this->inheritAll) {
+           // set System built-in properties separately,
+           // b/c we won't inherit them.
+           $this->newProject->setSystemProperties();
+
+        } else {
+            // set all properties from calling project
+            $properties = $this->project->getProperties();
+            foreach ($properties as $name => $value) {                
+                if ($name == "basedir" || $name == "phing.file" || $name == "phing.version") {
+                    // basedir and phing.file get special treatment in main()
+                    continue;
+                }
+                   // don't re-set user properties, avoid the warning message
+                if ($this->newProject->getProperty($name) === null){
+                    // no user property
+                    $this->newProject->setNewProperty($name, $value);
+                }
+            }
+            
+        }
+    
+    }
+
+    /**
+     * Override the properties in the new project with the one
+     * explicitly defined as nested elements here.
+     * @return void
+     * @throws BuildException 
+     */
+    private function overrideProperties() {     
+        foreach(array_keys($this->properties) as $i) {
+            $p = $this->properties[$i];
+            $p->setProject($this->newProject);
+            $p->main();
+        }
+        $this->project->copyInheritedProperties($this->newProject);
+    }
+
+    /**
+     * Add the references explicitly defined as nested elements to the
+     * new project.  Also copy over all references that don't override
+     * existing references in the new project if inheritrefs has been
+     * requested.
+     * 
+     * @return void
+     * @throws BuildException 
+     */
+    private function addReferences() {
+    
+        // parent project references
+        $projReferences = $this->project->getReferences();
+        
+        $newReferences = $this->newProject->getReferences();
+        
+        $subprojRefKeys = array();
+        
+        if (count($this->references) > 0) {
+            for ($i=0, $count=count($this->references); $i < $count; $i++) {
+                $ref = $this->references[$i];            
+                $refid = $ref->getRefId();
+                
+                if ($refid === null) {
+                    throw new BuildException("the refid attribute is required"
+                                             . " for reference elements");
+                }
+                if (!isset($projReferences[$refid])) {
+                    $this->log("Parent project doesn't contain any reference '"
+                        . $refid . "'",
+                        Project::MSG_WARN);
+                    continue;
+                }
+                
+                $subprojRefKeys[] = $refid;
+                //thisReferences.remove(refid);
+                $toRefid = $ref->getToRefid();
+                if ($toRefid === null) {
+                    $toRefid = $refid;
+                }
+                $this->copyReference($refid, $toRefid);
+            }
+        }
+
+        // Now add all references that are not defined in the
+        // subproject, if inheritRefs is true
+        if ($this->inheritRefs) {
+        
+            // get the keys that are were not used by the subproject
+            $unusedRefKeys = array_diff(array_keys($projReferences), $subprojRefKeys);
+            
+            foreach($unusedRefKeys as $key) {
+                if (isset($newReferences[$key])) {
+                    continue;
+                }
+                $this->copyReference($key, $key);
+            }
+        }
+    }
+
+    /**
+     * Try to clone and reconfigure the object referenced by oldkey in
+     * the parent project and add it to the new project with the key
+     * newkey.
+     *
+     * <p>If we cannot clone it, copy the referenced object itself and
+     * keep our fingers crossed.</p>
+     *
+     * @param string $oldKey
+     * @param string $newKey
+     * @return void
+     */
+    private function copyReference($oldKey, $newKey) {
+        $orig = $this->project->getReference($oldKey);
+        if ($orig === null) {
+            $this->log("No object referenced by " . $oldKey . ". Can't copy to " 
+                .$newKey, 
+                PROJECT_SG_WARN);
+            return;
+        }
+
+        $copy = clone $orig;
+
+        if ($copy instanceof ProjectComponent) {
+            $copy->setProject($this->newProject);
+        } elseif (in_array('setProject', get_class_methods(get_class($copy)))) {
+            $copy->setProject($this->newProject);
+		} elseif ($copy instanceof Project) {
+			// don't copy the old "Project" itself
+        } else {
+            $msg = "Error setting new project instance for "
+                . "reference with id " . $oldKey;
+            throw new BuildException($msg);
+        }
+        
+        $this->newProject->addReference($newKey, $copy);
+    }
+
+    /**
+     * If true, pass all properties to the new phing project.
+     * Defaults to true.
+     *
+     * @access      public
+     */
+    function setInheritAll($value) {
+        $this->inheritAll = (boolean) $value;
+    }
+
+    /**
+     * If true, pass all references to the new phing project.
+     * Defaults to false.
+     *
+     * @access      public
+     */
+    function setInheritRefs($value) {
+        $this->inheritRefs = (boolean)$value;
+    }
+
+    /**
+     * The directory to use as a base directory for the new phing project.
+     * Defaults to the current project's basedir, unless inheritall
+     * has been set to false, in which case it doesn't have a default
+     * value. This will override the basedir setting of the called project.
+     *
+     * @access      public
+     */
+    function setDir($d) {
+        if ( is_string($d) )
+            $this->dir = new PhingFile($d);
+        else
+            $this->dir = $d;
+    }
+
+    /**
+     * The build file to use.
+     * Defaults to "build.xml". This file is expected to be a filename relative
+     * to the dir attribute given.
+     *
+     * @access      public
+     */
+    function setPhingfile($s) {
+        // it is a string and not a file to handle relative/absolute
+        // otherwise a relative file will be resolved based on the current
+        // basedir.
+        $this->phingFile = $s;
+    }
+
+   /**
+    * Alias function for setPhingfile
+    *
+    * @access       public
+    */
+    function setBuildfile($s) {
+        $this->setPhingFile($s);
+    }
+
+    /**
+     * The target of the new Phing project to execute.
+     * Defaults to the new project's default target.
+     *
+     * @access      public
+     */
+    function setTarget($s) {
+        $this->newTarget = $s;
+    }
+
+    /**
+     * Support for filesets; This method returns a reference to an instance
+     * of a FileSet object.
+     *
+     * @return FileSet
+     */
+    function createFileSet() {
+        $num = array_push($this->filesets, new FileSet());
+        return $this->filesets[$num-1];
+    }
+
+    /**
+     * Property to pass to the new project.
+     * The property is passed as a 'user property'
+     *
+     * @access      public
+     */
+    function createProperty() {
+        $p = new PropertyTask();
+        $p->setFallback($this->newProject);
+        $p->setUserProperty(true);
+        $this->properties[] = $p;
+        return $p;
+    }
+
+    /**
+     * Reference element identifying a data type to carry
+     * over to the new project.
+     *
+     * @access      public
+     */
+    function createReference() {
+        $num = array_push($this->references, new PhingReference());
+        return $this->references[$num-1];
+    }
+
+}
+
+/**
+ * Helper class that implements the nested <reference>
+ * element of <phing> and <phingcall>.
+ */
+class PhingReference extends Reference {
+
+    private $targetid = null;
+
+    /**
+     * Set the id that this reference to be stored under in the
+     * new project.
+     *
+     * @param targetid the id under which this reference will be passed to
+     *        the new project */
+    public function setToRefid($targetid) {
+        $this->targetid = $targetid;
+    }
+
+    /**
+     * Get the id under which this reference will be stored in the new
+     * project
+     *
+     * @return the id of the reference in the new project.
+     */
+    public function getToRefid() {
+        return $this->targetid;
+    }
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/system/PhpEvalTask.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/system/PhpEvalTask.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/system/PhpEvalTask.php	(revision 19)
@@ -0,0 +1,169 @@
+<?php
+/*
+ *  $Id: PhpEvalTask.php 144 2007-02-05 15:19:00Z hans $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+ 
+require_once 'phing/Task.php';
+
+/**
+ * Executes PHP function or evaluates expression and sets return value to a property.
+ *
+ *    WARNING:
+ *        This task can, of course, be abused with devastating effects.  E.g. do not
+ *        modify internal Phing classes unless you know what you are doing.
+ *
+ * @author   Hans Lellelid <hans@xmpl.org>
+ * @version  $Revision: 1.7 $
+ * @package  phing.tasks.system
+ *
+ * @todo Add support for evaluating expressions
+ */
+class PhpEvalTask extends Task {
+        
+    protected $expression; // Expression to evaluate
+    protected $function; // Function to execute
+    protected $class; // Class containing function to execute
+    protected $returnProperty; // name of property to set to return value 
+    protected $params = array(); // parameters for function calls
+    
+    /** Main entry point. */
+    function main() {
+        
+        if ($this->function === null && $this->expression === null) {
+            throw new BuildException("You must specify a function to execute or PHP expression to evalute.", $this->location);
+        }
+        
+        if ($this->function !== null && $this->expression !== null) {
+            throw new BuildException("You can specify function or expression, but not both.", $this->location);
+        }
+        
+        if ($this->expression !== null && !empty($this->params)) {
+            throw new BuildException("You cannot use nested <param> tags when evaluationg a PHP expression.", $this->location);
+        }
+        
+        $retval = null;
+        if ($this->function !== null) {
+            $retval = $this->callFunction();                                    
+        } elseif ($this->expression !== null) {
+            $retval = $this->evalExpression();
+        }
+        
+        if ($this->returnProperty !== null) {
+            $this->project->setProperty($this->returnProperty, $retval);
+        }
+    }
+    
+    /**
+     * Calls function and returns results.
+     * @return mixed
+     */
+    protected function callFunction() {
+                        
+        if ($this->class !== null) {
+            // import the classname & unqualify it, if necessary
+            $this->class = Phing::import($this->class);
+                        
+            $user_func = array($this->class, $this->function);
+            $h_func = $this->class . '::' . $this->function; // human-readable (for log)
+        } else {
+            $user_func = $this->function;
+            $h_func = $user_func; // human-readable (for log)
+        }
+        
+        // put parameters into simple array
+        $params = array();
+        foreach($this->params as $p) {
+            $params[] = $p->getValue();
+        }
+        
+        $this->log("Calling PHP function: " . $h_func . "()");
+        foreach($params as $p) {
+            $this->log("  param: " . $p, Project::MSG_VERBOSE);
+        } 
+        
+        $return = call_user_func_array($user_func, $params);
+        return $return;
+    }
+    
+    /**
+     * Evaluates expression and returns resulting value.
+     * @return mixed
+     */
+    protected function evalExpression() {
+        $this->log("Evaluating PHP expression: " . $this->expression);
+        if (!StringHelper::endsWith(';', trim($this->expression))) {
+            $this->expression .= ';';
+        }
+        $retval = null;
+        eval('$retval = ' . $this->expression);
+        return $retval;
+    }
+    
+    /** Set function to execute */
+    public function setFunction($f) {
+       $this->function = $f;
+    }
+
+    /** Set [static] class which contains function to execute */
+    public function setClass($c) {
+       $this->class = $c;
+    }
+    
+    /** Sets property name to set with return value of function or expression.*/
+    public function setReturnProperty($r) {
+       $this->returnProperty = $r;
+    }
+    
+    /** Set PHP expression to evaluate. */
+    public function addText($expression) {
+        $this->expression = $expression;
+    }
+
+    /** Set PHP expression to evaluate. */
+    public function setExpression($expression) {
+        $this->expression = $expression;
+    }
+    
+    /** Add a nested <param> tag. */
+    public function createParam() {
+        $p = new FunctionParam();
+        $this->params[] = $p;
+        return $p;
+    }        
+}
+
+/**
+ * Supports the <param> nested tag for PhpTask.
+ */
+class FunctionParam {
+
+    private $val;
+    
+    public function setValue($v) {
+        $this->val = $v;
+    }
+    
+    public function addText($v) {
+        $this->val = $v;
+    }
+    
+    public function getValue() {
+        return $this->val;
+    }
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/system/PropertyPromptTask.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/system/PropertyPromptTask.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/system/PropertyPromptTask.php	(revision 19)
@@ -0,0 +1,234 @@
+<?php
+/*
+ *  $Id: PropertyPromptTask.php 272 2007-10-30 23:06:04Z hans $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+require_once 'phing/Task.php';
+include_once 'phing/system/io/ConsoleReader.php';
+
+/**
+ * Deprecated task that uses console to prompt user for property values.
+ * 
+ * This class is very slightly simpler than the InputTask, but lacks the ability
+ * to use a non-console input handler.  You should, therefore, use InputTask.  This
+ * class can serve as a reference, but will be removed in the future.
+ * 
+ * @author    Hans Lellelid <hans@xmpl.org> (Phing)
+ * @author    Anthony J. Young-Garner <ajyoung@alum.mit.edu> (Ant)
+ * @version   $Revision: 1.4 $
+ * @package   phing.tasks.system
+ * @deprecated - in favor of the more capable InputTask
+ */ 
+class PropertyPromptTask extends Task {
+	
+	/**
+	 * The property name to set with the output.
+	 * @var string
+	 */
+    private $propertyName;        // required
+    
+    /**
+     * The default value to use if no input is entered.
+     * @var string
+     */
+    private $defaultValue;
+    
+    /**
+     * The entered value.
+     * @var string
+     */
+    private $proposedValue;
+    
+    /**
+     * The text to use for the prompt.
+     * @var string
+     */
+    private $promptText;
+    
+    /**
+     * The character to put after the text.
+     * @var string
+     */
+    private $promptCharacter;
+    
+    /**
+     * 
+     */
+    private $useExistingValue;
+
+    /**
+     * Run the PropertyPrompt task.
+     * @throws BuildException
+     */
+    public function main() {
+    	
+        $this->proposedValue = $this->project->getProperty($this->propertyName);
+        $currentValue = $this->defaultValue;
+        
+        if ($currentValue == "" && $this->proposedValue !== null) {
+        		$currentValue = $this->proposedValue;
+       	}
+       	
+        if ($this->useExistingValue !== true || $this->proposedValue === null) {
+                        
+            $this->log("Prompting user for " . $this->propertyName . ". " . $this->getDefaultMessage(), Project::MSG_VERBOSE);
+            
+            print "\n" . $this->promptText . " [" . $currentValue . "] " . $this->promptCharacter . " ";
+
+            /** future version should probably have hooks for validation of user input.*/
+            $reader = new ConsoleReader();
+            
+            try {
+                $this->proposedValue  = $reader->readLine();
+            } catch (IOException $e) {
+                $this->log("Prompt failed. Using default. (Failure reason: " . $e->getMessage().")");
+                $this->proposedValue = $this->defaultValue;
+            }
+            
+            if ($this->proposedValue === "") {
+                $this->log("No value specified, using default.", Project::MSG_VERBOSE);
+                $this->proposedValue = $this->defaultValue;
+            }
+            
+            if (isset($this->proposedValue) && $this->proposedValue !== "") {                    
+                $this->project->setProperty($this->propertyName, $this->proposedValue);
+            }
+             
+        }    
+    }
+    
+    /**
+     * Returns a string to be inserted in the log message
+     * indicating whether a default response was specified
+     * in the build file.
+     */
+    private function getDefaultMessage() {
+        if ($this->defaultValue == "") {
+            return "No default response specified.";
+        } else return "Default response is " . $this->defaultValue . ".";
+    }
+    
+    /**
+     * Returns defaultValue specified 
+     * in this task for the Property
+     * being set.
+     * @return string
+     */
+    public function getDefaultValue() {
+        return $this->defaultValue;
+    }
+    
+    /**
+     * Returns the terminating character used to 
+     * punctuate the prompt text.
+     * @return string
+     */
+    public function getPromptCharacter() {
+        return $this->promptCharacter;
+    }
+    
+    /**
+     * Returns text of the prompt.
+     * @return java.lang.String
+     */
+    public function getPromptText() {
+        return $this->promptText;
+    }
+    
+    /**
+     * Returns name of the Ant Project Property
+     * being set by this task.
+     * @return string
+     */
+    public function getPropertyName() {
+        return $this->propertyName;
+    }
+    /**
+     * Initializes this task.
+     */
+    public function init() {
+        parent::init();
+        $this->defaultValue    = "";
+        $this->promptCharacter = "?";
+        $this->useExistingValue = false;
+    }
+        
+    /**
+     * Insert the method's description here.
+     * Creation date: (12/10/2001 8:16:16 AM)
+     * @return boolean
+     */
+    public function isUseExistingValue() {
+        return $this->useExistingValue;
+    }
+    
+    /**
+     * Sets defaultValue for the Property
+     * being set by this task.
+     * @param string $newDefaultvalue
+     */
+    public function setDefaultvalue($newDefaultvalue) {
+        $this->defaultValue = $newDefaultvalue;
+    }
+    
+    /**
+     * Sets the terminating character used to 
+     * punctuate the prompt text (default is "?").
+     * @param string $newPromptcharacter
+     */
+    public function setPromptCharacter($newPromptcharacter) {
+        $this->promptCharacter = $newPromptcharacter;
+    }
+    
+    /**
+     * Sets text of the prompt.
+     * @param string $newPrompttext
+     */
+    public function setPromptText($newPrompttext) {
+        $this->promptText = $newPrompttext;
+    }
+    
+    /**
+     * Specifies the Phing Project Property
+     * being set by this task.
+     * @param newPropertyname java.lang.String
+     */
+    public function setPropertyName($newPropertyname) {
+        $this->propertyName = $newPropertyname;
+    }
+    
+    /**
+     * 
+     * @param boolean $newUseExistingValue
+     */
+    public function setUseExistingValue($newUseExistingValue) {
+        $this->useExistingValue = $newUseExistingValue;
+    }
+    
+    /**
+     * Sets the prompt text that will be presented to the user.
+     * @param string $prompt
+     * @return void
+     */
+    public function addText($prompt) {
+        $this->setPromptText($prompt);
+    }
+    
+    
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/system/PropertyTask.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/system/PropertyTask.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/system/PropertyTask.php	(revision 19)
@@ -0,0 +1,438 @@
+<?php
+
+/*
+ *  $Id: PropertyTask.php 144 2007-02-05 15:19:00Z hans $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+include_once 'phing/Task.php';
+include_once 'phing/system/util/Properties.php';
+
+/**
+ * Task for setting properties in buildfiles.
+ *
+ * @author    Andreas Aderhold <andi@binarycloud.com>
+ * @author    Hans Lellelid <hans@xmpl.org>
+ * @version   $Revision$
+ * @package   phing.tasks.system
+ */
+class PropertyTask extends Task {
+
+    /** name of the property */
+    protected $name; 
+    
+    /** value of the property */
+    protected $value;
+    
+    protected $reference;
+    protected $env;     // Environment
+    protected $file;
+    protected $ref;
+    protected $prefix;
+    protected $fallback;
+    
+    /** Whether to force overwrite of existing property. */
+    protected $override = false;
+    
+    /** Whether property should be treated as "user" property. */
+    protected $userProperty = false;
+
+    /**
+     * Sets a the name of current property component
+     */
+    function setName($name) {
+        $this->name = (string) $name;
+    }
+    
+    /** Get property component name. */
+    function getName() {
+        return $this->name;
+    }
+
+    /**
+     * Sets a the value of current property component.
+     * @param    mixed      Value of name, all scalars allowed
+     */
+    function setValue($value) {
+        $this->value = (string) $value;
+    }
+	
+	/**
+	 * Sets value of property to CDATA tag contents.
+	 * @param string $values
+	 * @since 2.2.0
+	 */
+	public function addText($value) {
+		$this->setValue($value);
+	}
+    
+    /** Get the value of current property component. */
+    function getValue() {
+        return $this->value;
+    }
+    
+    /** Set a file to use as the source for properties. */
+    function setFile($file) {
+        if (is_string($file)) {
+            $file = new PhingFile($file);
+        }
+        $this->file = $file;
+    }
+    
+    /** Get the PhingFile that is being used as property source. */
+    function getFile() {
+        return $this->file;
+    }
+
+    function setRefid(Reference $ref) {
+        $this->reference = $ref;
+    }
+    
+    function getRefid() {
+        return $this->reference;
+    }
+
+    /**
+     * Prefix to apply to properties loaded using <code>file</code>.
+     * A "." is appended to the prefix if not specified.
+     * @param string $prefix prefix string
+     * @return void
+     * @since 2.0
+     */
+    public function setPrefix($prefix) {
+        $this->prefix = $prefix;
+        if (!StringHelper::endsWith(".", $prefix)) {
+            $this->prefix .= ".";
+        }
+    }
+
+    /**
+     * @return string
+     * @since 2.0
+     */
+    public function getPrefix() {
+        return $this->prefix;
+    }
+
+    /**
+    * the prefix to use when retrieving environment variables.
+    * Thus if you specify environment="myenv"
+    * you will be able to access OS-specific
+    * environment variables via property names "myenv.PATH" or
+    * "myenv.TERM".
+    * <p>
+    * Note that if you supply a property name with a final
+    * "." it will not be doubled. ie environment="myenv." will still
+    * allow access of environment variables through "myenv.PATH" and
+    * "myenv.TERM". This functionality is currently only implemented
+    * on select platforms. Feel free to send patches to increase the number of platforms
+    * this functionality is supported on ;).<br>
+    * Note also that properties are case sensitive, even if the
+    * environment variables on your operating system are not, e.g. it
+    * will be ${env.Path} not ${env.PATH} on Windows 2000.
+    * @param env prefix
+    */
+    function setEnvironment($env) {
+        $this->env = (string) $env;
+    }
+
+    function getEnvironment() {
+        return $this->env;
+    }
+    
+    /**
+     * Set whether this is a user property (ro).
+     * This is deprecated in Ant 1.5, but the userProperty attribute
+     * of the class is still being set via constructor, so Phing will
+     * allow this method to function.
+     * @param boolean $v
+     */
+    function setUserProperty($v) {
+        $this->userProperty = (boolean) $v;
+    }
+    
+    function getUserProperty() {
+        return $this->userProperty;
+    }
+    
+    function setOverride($v) {
+        $this->override = (boolean) $v;
+    }
+    
+    function getOverride() {
+        return $this->override;
+    }
+    
+    function toString() {
+        return (string) $this->value;
+    }
+
+	/**
+	 * @param Project $p
+	 */
+    function setFallback($p) {
+        $this->fallback = $p;
+    }
+    
+    function getFallback() {
+        return $this->fallback;
+    }
+    /**
+     * set the property in the project to the value.
+     * if the task was give a file or env attribute
+     * here is where it is loaded
+     */
+    function main() {
+        if ($this->name !== null) {
+            if ($this->value === null && $this->ref === null) {
+                throw new BuildException("You must specify value or refid with the name attribute", $this->getLocation());
+            }
+        } else {
+            if ($this->file === null && $this->env === null ) {
+                throw new BuildException("You must specify file or environment when not using the name attribute", $this->getLocation());
+            }
+        }
+
+        if ($this->file === null && $this->prefix !== null) {
+            throw new BuildException("Prefix is only valid when loading from a file.", $this->getLocation());
+        }
+        
+        if (($this->name !== null) && ($this->value !== null)) {
+            $this->addProperty($this->name, $this->value);
+        }
+
+        if ($this->file !== null) {
+            $this->loadFile($this->file);
+        }
+
+        if ( $this->env !== null ) {
+            $this->loadEnvironment($this->env);
+        }
+
+        if (($this->name !== null) && ($this->ref !== null)) {
+            // get the refereced property
+            try {
+            $this->addProperty($this->name, $this->reference->getReferencedObject($this->project)->toString());
+            } catch (BuildException $be) {
+                if ($this->fallback !== null) {
+                     $this->addProperty($this->name, $this->reference->getReferencedObject($this->fallback)->toString());
+                } else {
+                    throw $be;
+                }
+            }
+        }
+    }
+    
+    /**
+     * load the environment values
+     * @param string $prefix prefix to place before them
+     */
+    protected function loadEnvironment($prefix) {
+
+        $props = new Properties();
+        if ( substr($prefix, strlen($prefix)-1) == '.' ) {
+            $prefix .= ".";
+        }
+        $this->log("Loading Environment $prefix", Project::MSG_VERBOSE);
+        foreach($_ENV as $key => $value) {
+            $props->setProperty($prefix . '.' . $key, $value);
+        }
+        $this->addProperties($props);
+    }
+
+    /**
+     * iterate through a set of properties,
+     * resolve them then assign them
+     */
+    protected function addProperties($props) {
+        $this->resolveAllProperties($props);
+        foreach($props->keys() as $name) {        
+            $value = $props->getProperty($name);
+            $v = $this->project->replaceProperties($value);            
+            if ($this->prefix !== null) {
+                $name = $this->prefix . $name;
+            }
+            $this->addProperty($name, $v);
+        }
+    }
+
+    /**
+     * add a name value pair to the project property set
+     * @param string $name name of property
+     * @param string $value value to set
+     */
+    protected function addProperty($name, $value) {
+        if ($this->userProperty) {
+            if ($this->project->getUserProperty($name) === null || $this->override) {
+                $this->project->setInheritedProperty($name, $value);
+            } else {
+                $this->log("Override ignored for " . $name, Project::MSG_VERBOSE);
+            }
+        } else {
+            if ($this->override) {
+                $this->project->setProperty($name, $value);
+            } else {
+                $this->project->setNewProperty($name, $value);
+            }
+        }
+    }
+
+    /**
+     * load properties from a file.
+     * @param PhingFile $file
+     */
+    protected function loadFile(PhingFile $file) {
+        $props = new Properties();
+        $this->log("Loading ". $file->getAbsolutePath(), Project::MSG_INFO);
+        try { // try to load file
+            if ($file->exists()) {
+                $props->load($file);
+                $this->addProperties($props);
+            } else {
+                $this->log("Unable to find property file: ". $file->getAbsolutePath() ."... skipped", Project::MSG_WARN);
+            }
+        } catch (IOException $ioe) {
+            throw new BuildException("Could not load properties from file.", $ioe);
+        }
+    }
+    
+    /**
+     * Given a Properties object, this method goes through and resolves
+     * any references to properties within the object.
+     * 
+     * @param Properties $props The collection of Properties that need to be resolved.
+     * @return void
+     */
+    protected function resolveAllProperties(Properties $props) {
+        
+        $keys = $props->keys();
+
+        while(count($keys)) {
+
+            // There may be a nice regex/callback way to handle this
+            // replacement, but at the moment it is pretty complex, and
+            // would probably be a lot uglier to work into a preg_replace_callback()
+            // system.  The biggest problem is the fact that a resolution may require
+            // multiple passes.
+            
+            $name     = array_shift($keys);
+            $value    = $props->getProperty($name);
+            $resolved = false;
+            
+            while(!$resolved) {
+            
+                $fragments = array();
+                $propertyRefs = array();
+
+                // [HL] this was ::parsePropertyString($this->value ...) ... this seems wrong
+                self::parsePropertyString($value, $fragments, $propertyRefs);
+
+                $resolved = true;
+                if (count($propertyRefs) !== 0) {
+
+                    $sb = "";
+
+                    $i = $fragments;
+                    $j = $propertyRefs;
+                    while(count($i)) {
+                        $fragment = array_shift($i);
+                        if ($fragment === null) {
+                            $propertyName = array_shift($j);
+
+                            if ($propertyName === $name) {
+                                // Should we maybe just log this as an error & move on?
+                                // $this->log("Property ".$name." was circularly defined.", Project::MSG_ERR);
+                                throw new BuildException("Property ".$name." was circularly defined.");
+                            }
+
+                            $fragment = $this->getProject()->getProperty($propertyName);
+                            if ($fragment === null) {
+                                if ($props->containsKey($propertyName)) {
+                                    $fragment = $props->getProperty($propertyName);
+                                    $resolved = false; // parse again (could have been replaced w/ another var)
+                                } else {
+                                    $fragment = "\${".$propertyName."}";
+                                }
+                            }
+                        }
+                        $sb .= $fragment;
+                    }
+                    
+                    $this->log("Resolved Property \"$value\" to \"$sb\"", Project::MSG_DEBUG);
+                    $value = $sb;                    
+                    $props->setProperty($name, $value);
+                                 
+                } // if (count($propertyRefs))
+                
+            } // while (!$resolved)
+            
+        } // while (count($keys)
+    }
+
+
+     /**
+     * This method will parse a string containing ${value} style
+     * property values into two lists. The first list is a collection
+     * of text fragments, while the other is a set of string property names
+     * null entries in the first list indicate a property reference from the
+     * second list.
+     *
+     * This is slower than regex, but useful for this class, which has to handle
+     * multiple parsing passes for properties.
+     *
+     * @param string $value The string to be scanned for property references
+     * @param array &$fragments The found fragments
+     * @param  array &$propertyRefs The found refs
+     */
+    protected function parsePropertyString($value, &$fragments, &$propertyRefs) {
+    
+        $prev = 0;
+        $pos  = 0;
+
+        while (($pos = strpos($value, '$', $prev)) !== false) {
+            
+            if ($pos > $prev) {
+                array_push($fragments, StringHelper::substring($value, $prev, $pos-1));
+            }
+            if ($pos === (strlen($value) - 1)) {
+                array_push($fragments, '$');
+                $prev = $pos + 1;
+            } elseif ($value{$pos+1} !== '{' ) {
+
+                // the string positions were changed to value-1 to correct
+                // a fatal error coming from function substring()
+                array_push($fragments, StringHelper::substring($value, $pos, $pos + 1));
+                $prev = $pos + 2;
+            } else {
+                $endName = strpos($value, '}', $pos);
+                if ($endName === false) {
+                    throw new BuildException("Syntax error in property: $value");
+                }
+                $propertyName = StringHelper::substring($value, $pos + 2, $endName-1);
+                array_push($fragments, null);
+                array_push($propertyRefs, $propertyName);
+                $prev = $endName + 1;
+            }
+        }
+
+        if ($prev < strlen($value)) {
+            array_push($fragments, StringHelper::substring($value, $prev));
+        }
+    }
+
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/system/ReflexiveTask.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/system/ReflexiveTask.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/system/ReflexiveTask.php	(revision 19)
@@ -0,0 +1,155 @@
+<?php
+/*
+ *  $Id: ReflexiveTask.php 144 2007-02-05 15:19:00Z hans $  
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+require_once 'phing/Task.php';
+
+/**
+ * This task is for using filter chains to make changes to files and overwrite the original files.
+ * 
+ * This task was created to serve the need for "cleanup" tasks -- e.g. a ReplaceRegexp task or strip task
+ * being used to modify files and then overwrite the modified files.  In many (most?) cases you probably
+ * should just use a copy task  to preserve the original source files, but this task supports situations
+ * where there is no src vs. build directory, and modifying source files is actually desired.
+ * 
+ * <code>
+ *    <reflexive>
+ *        <fileset dir=".">
+ *            <include pattern="*.html">
+ *        </fileset>
+ *        <filterchain>
+ *            <replaceregexp>
+ *                <regexp pattern="\n\r" replace="\n"/>
+ *            </replaceregexp>
+ *        </filterchain> 
+ *    </reflexive>
+ * </code>
+ * 
+ * @author    Hans Lellelid <hans@xmpl.org>
+ * @version   $Revision: 1.11 $
+ * @package   phing.tasks.system
+ */
+class ReflexiveTask extends Task {
+    
+    /** Single file to process. */
+    private $file;
+    
+    /** Any filesets that should be processed. */
+    private $filesets = array();
+    
+    /** Any filters to be applied before append happens. */
+    private $filterChains = array();
+        
+    /** Alias for setFrom() */
+    function setFile(PhingFile $f) {
+        $this->file = $f;
+    }
+    
+    /** Nested creator, adds a set of files (nested fileset attribute). */
+    function createFileSet() {
+        $num = array_push($this->filesets, new FileSet());
+        return $this->filesets[$num-1];
+    }
+
+    /**
+     * Creates a filterchain
+     *
+     * @return  object  The created filterchain object
+     */
+    function createFilterChain() {
+        $num = array_push($this->filterChains, new FilterChain($this->project));
+        return $this->filterChains[$num-1];
+    }                    
+    
+    /** Append the file(s). */
+    function main() {
+            
+        if ($this->file === null && empty($this->filesets)) {
+            throw new BuildException("You must specify a file or fileset(s) for the <reflexive> task.");
+        }
+        
+        // compile a list of all files to modify, both file attrib and fileset elements
+        // can be used.
+        
+        $files = array();
+        
+        if ($this->file !== null) {
+            $files[] = $this->file;
+        }
+        
+        if (!empty($this->filesets)) {
+            $filenames = array();
+            foreach($this->filesets as $fs) {
+                try {
+                    $ds = $fs->getDirectoryScanner($this->project);
+                    $filenames = $ds->getIncludedFiles(); // get included filenames
+                    $dir = $fs->getDir($this->project);
+                    foreach ($filenames as $fname) {
+                        $files[] = new PhingFile($dir, $fname);
+                    }
+                } catch (BuildException $be) {
+                    $this->log($be->getMessage(), Project::MSG_WARN);
+                }
+            }                        
+        }
+        
+        $this->log("Applying reflexive processing to " . count($files) . " files.");
+
+		// These "slots" allow filters to retrieve information about the currently-being-process files		
+		$slot = $this->getRegisterSlot("currentFile");
+		$basenameSlot = $this->getRegisterSlot("currentFile.basename");	
+
+        
+        foreach($files as $file) {
+			// set the register slots
+			
+			$slot->setValue($file->getPath());
+			$basenameSlot->setValue($file->getName());
+			
+            // 1) read contents of file, pulling through any filters
+            $in = null;
+            try {                
+                $contents = "";
+                $in = FileUtils::getChainedReader(new FileReader($file), $this->filterChains, $this->project);
+                while(-1 !== ($buffer = $in->read())) {
+                    $contents .= $buffer;
+                }
+                $in->close();
+            } catch (Exception $e) {
+                if ($in) $in->close();
+                $this->log("Erorr reading file: " . $e->getMessage(), Project::MSG_WARN);
+            }
+            
+            try {
+                // now create a FileWriter w/ the same file, and write to the file
+                $out = new FileWriter($file);
+                $out->write($contents);
+                $out->close();
+                $this->log("Applying reflexive processing to " . $file->getPath(), Project::MSG_VERBOSE);
+            } catch (Exception $e) {
+                if ($out) $out->close();
+                $this->log("Error writing file back: " . $e->getMessage(), Project::MSG_WARN);
+            }
+            
+        }
+                                
+    }   
+
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/system/ResolvePathTask.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/system/ResolvePathTask.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/system/ResolvePathTask.php	(revision 19)
@@ -0,0 +1,122 @@
+<?php
+/*
+ *  $Id: ResolvePathTask.php 144 2007-02-05 15:19:00Z hans $  
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+require_once 'phing/Task.php';
+
+/**
+ * Task for resolving relative paths and setting absolute path in property value.
+ * 
+ * This task was created to address a need for resolving absolute paths of files / directories.
+ * In many cases a relative directory (e.g. "./build") is specified, but it needs to be treated
+ * as an absolute path since other build files (e.g. in subdirs) should all be using the same
+ * path -- and not treating it as a relative path to their own directory.
+ * 
+ * <code>
+ * <property name="relative_path" value="./dirname"/>
+ * <resolvepath propertyName="absolute_path" file="${relative_path}"/>
+ * <echo>Resolved [absolute] path: ${absolute_path}</echo>
+ * </code>
+ * 
+ * TODO:
+ *      - Possibly integrate this with PackageAsPath, for handling/resolving dot-path paths.
+ * 
+ * @author    Hans Lellelid <hans@xmpl.org>
+ * @version   $Revision: 1.6 $
+ * @package   phing.tasks.system
+ */
+class ResolvePathTask extends Task {
+
+    /** Name of property to set. */
+    private $propertyName;
+    
+    /** The [possibly] relative file/path that needs to be resolved. */
+    private $file;
+    
+    /** Base directory used for resolution. */
+    private $dir;
+    
+    /**
+     * Set the name of the property to set.
+     * @param string $v Property name
+     * @return void
+     */
+    public function setPropertyName($v) {
+        $this->propertyName = $v;
+    }
+    
+    /**
+     * Sets a base dir to use for resolution.
+     * @param PhingFile $d
+     */
+    function setDir(PhingFile $d) {
+        $this->dir = $d;
+    }
+    
+    /**
+     * Sets a path (file or directory) that we want to resolve.
+     * This is the same as setFile() -- just more generic name so that it's
+     * clear that you can also use it to set directory.
+     * @param string $f
+     * @see setFile()
+     */
+    function setPath($f) {
+        $this->file = $f;
+    }
+    
+    /**
+     * Sets a file that we want to resolve.
+     * @param string $f
+     */
+    function setFile($f) {
+        $this->file = $f;
+    }
+
+    /**
+     * Perform the resolution & set property.
+     */
+    public function main() {        
+        
+        if (!$this->propertyName) {
+            throw new BuildException("You must specify the propertyName attribute", $this->getLocation());
+        }
+        
+        // Currently only files are supported
+        if ($this->file === null) {
+            throw new BuildException("You must specify a path to resolve", $this->getLocation());
+        }
+        
+		$fs = FileSystem::getFileSystem();
+		
+        // if dir attribute was specified then we should
+        // use that as basedir to which file was relative.
+		// -- unless the file specified is an absolute path
+        if ($this->dir !== null && !$fs->isAbsolute(new PhingFile($this->file))) {
+            $resolved = new PhingFile($this->dir->getPath(), $this->file);
+        } else {
+            // otherwise just resolve it relative to project basedir
+            $resolved = $this->project->resolveFile($this->file);
+        }
+        
+        $this->log("Resolved " . $this->file . " to " . $resolved->getAbsolutePath(), Project::MSG_INFO);
+        $this->project->setProperty($this->propertyName, $resolved->getAbsolutePath());
+    }
+
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/system/SequentialTask.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/system/SequentialTask.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/system/SequentialTask.php	(revision 19)
@@ -0,0 +1,57 @@
+<?php
+
+/*
+ *  $Id: SequentialTask.php 43 2006-03-10 14:31:51Z mrook $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+require_once 'phing/Task.php';
+require_once 'phing/TaskContainer.php';
+
+/**
+ * Sequential is a container task that contains other Phing Task objects.
+ *
+ * The sequential task has no attributes and does not support any nested
+ * elements apart from Ant tasks. Any valid Ant task may be embedded within the
+ * sequential task.
+ *
+ * @since 2.1.2
+ */
+class SequentialTask extends Task implements TaskContainer {
+
+    /** Optional Vector holding the nested tasks */
+    private $nestedTasks = array();
+
+    /**
+     * Add a nested task to Sequential.
+     * @param Task $nestedTask  Nested task to execute Sequential
+     */
+    public function addTask(Task $nestedTask) {
+        $this->nestedTasks[] = $nestedTask;
+    }
+
+    /**
+     * Execute all nestedTasks.
+     * @throws BuildException if one of the nested tasks fails.
+     */
+    public function main() {
+		foreach($this->nestedTasks as $task) {
+			$task->perform();
+		}
+    }
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/system/TaskdefTask.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/system/TaskdefTask.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/system/TaskdefTask.php	(revision 19)
@@ -0,0 +1,127 @@
+<?php
+
+/*
+ * $Id: TaskdefTask.php 144 2007-02-05 15:19:00Z hans $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+ 
+require_once 'phing/Task.php';
+
+/**
+ * Register a task for use within a buildfile.
+ * 
+ * This is for registering your own tasks -- or any non-core Task -- for use within a buildfile.
+ * If you find that you are using a particular class frequently, you may want to edit the 
+ * phing/tasks/defaults.properties file so that it is included by default. You may also
+ * want to submit it (if LGPL or compatible license) to be included in Phing distribution.
+ * 
+ * <pre>
+ *   <taskdef name="mytag" classname="path.to.MyHandlingClass"/>
+ *   .
+ *   .
+ *   <mytag param1="val1" param2="val2"/>
+ * </pre>
+ * 
+ * TODO:
+ *    -- possibly refactor since this is almost the same as TypeDefTask
+ *      (right now these are just too simple to really justify creating an abstract class)
+ * 
+ * @author    Hans Lellelid <hans@xmpl.org>
+ * @version   $Revision: 1.11 $
+ * @package   phing.tasks.system
+ */
+class TaskdefTask extends Task {
+
+    /** Tag name for task that will be used in XML */
+    private $name;
+    
+    /**
+     * Classname of task to register.
+     * This can be a dot-path -- relative to a location on PHP include_path.
+     * E.g. path.to.MyClass ->  path/to/MyClass.php
+     * @var string
+     */
+    private $classname;
+    
+    /**
+     * Path to add to PHP include_path to aid in finding specified class.
+     * @var Path
+     */
+    private $classpath;
+    
+    /**
+     * Refid to already defined classpath
+     */
+    private $classpathId;
+    
+    /**
+     * Set the classpath to be used when searching for component being defined
+     * 
+     * @param Path $classpath An Path object containing the classpath.
+     */
+    public function setClasspath(Path $classpath) {
+        if ($this->classpath === null) {
+            $this->classpath = $classpath;
+        } else {
+            $this->classpath->append($classpath);
+        }
+    }
+
+    /**
+     * Create the classpath to be used when searching for component being defined
+     */ 
+    public function createClasspath() {
+        if ($this->classpath === null) {
+            $this->classpath = new Path($this->project);
+        }
+        return $this->classpath->createPath();
+    }
+
+    /**
+     * Reference to a classpath to use when loading the files.
+     */
+    public function setClasspathRef(Reference $r) {
+        $this->classpathId = $r->getRefId();
+        $this->createClasspath()->setRefid($r);
+    }
+
+    /**
+     * Sets the name that will be used in XML buildfile.
+     * @param string $name
+     */
+    public function setName($name)    {
+        $this->name = $name;
+    }
+    
+    /**
+     * Sets the class name / dotpath to use.
+     * @param string $class
+     */
+    public function setClassname($class) {
+        $this->classname = $class;
+    }
+    
+    /** Main entry point */
+    public function main() {
+        if ($this->name === null || $this->classname === null) {
+            throw new BuildException("You must specify name and class attributes for <taskdef>.");
+        }
+        $this->log("Task " . $this->name . " will be handled by class " . $this->classname, Project::MSG_VERBOSE);
+        $this->project->addTaskDefinition($this->name, $this->classname, $this->classpath);
+    }
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/system/TouchTask.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/system/TouchTask.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/system/TouchTask.php	(revision 19)
@@ -0,0 +1,170 @@
+<?php
+/*
+ *  $Id: TouchTask.php 144 2007-02-05 15:19:00Z hans $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+require_once 'phing/Task.php';
+include_once 'phing/util/DirectoryScanner.php';
+include_once 'phing/types/FileSet.php';
+include_once 'phing/util/FileUtils.php';
+include_once 'phing/system/io/PhingFile.php';
+include_once 'phing/system/io/IOException.php';
+
+/**
+ * Touch a file and/or fileset(s); corresponds to the Unix touch command.
+ *
+ * If the file to touch doesn't exist, an empty one is created.
+ *
+ * @version $Revision: 1.12 $
+ * @package phing.tasks.system
+ */
+class TouchTask extends Task {
+
+    private $file;
+    private $millis    = -1;
+    private $dateTime;
+    private $filesets = array();
+    private $fileUtils;
+
+    function __construct() {
+        $this->fileUtils = new FileUtils();
+    }
+
+    /**
+     * Sets a single source file to touch.  If the file does not exist
+     * an empty file will be created.
+     */
+    function setFile(PhingFile $file) {        
+        $this->file = $file;
+    }
+
+    /**
+     * the new modification time of the file
+     * in milliseconds since midnight Jan 1 1970.
+     * Optional, default=now
+     */
+    function setMillis($millis) {
+        $this->millis = (int) $millis;
+    }
+
+    /**
+     * the new modification time of the file
+     * in the format MM/DD/YYYY HH:MM AM or PM;
+     * Optional, default=now
+     */
+    function setDatetime($dateTime) {
+        $this->dateTime = (string) $dateTime;
+    }
+
+    /**
+     * Nested creator, adds a set of files (nested fileset attribute).
+     * @return FileSet
+     */
+    function createFileSet() {
+        $num = array_push($this->filesets, new FileSet());
+        return $this->filesets[$num-1];
+    }
+
+    /**
+     * Execute the touch operation.
+     */
+    function main() {
+        $savedMillis = $this->millis;
+
+        if ($this->file === null && count($this->filesets) === 0) {
+            throw new BuildException("Specify at least one source - a file or a fileset.");
+        }
+
+        if ($this->file !== null && $this->file->exists() && $this->file->isDirectory()) {
+            throw new BuildException("Use a fileset to touch directories.");
+        }
+
+        try { // try to touch file
+            if ($this->dateTime !== null) {
+                $this->setMillis(strtotime($this->dateTime));
+                if ($this->millis < 0) {
+                    throw new BuildException("Date of {$this->dateTime} results in negative milliseconds value relative to epoch (January 1, 1970, 00:00:00 GMT).");
+                }
+            }
+            $this->_touch();
+        } catch (Exception $ex) {
+            throw new BuildException("Error touch()ing file", $ex, $this->location);
+        }
+        
+        $this->millis = $savedMillis;
+        
+    }
+
+    /**
+     * Does the actual work.
+     */
+    function _touch() {
+        if ($this->file !== null) {
+            if (!$this->file->exists()) {
+                $this->log("Creating " . $this->file->__toString(), Project::MSG_INFO);
+                try { // try to create file
+                    $this->file->createNewFile();
+                } catch(IOException  $ioe) {
+                    throw new BuildException("Error creating new file " . $this->file->__toString(), $ioe, $this->location);
+                }
+            }
+        }
+
+        $resetMillis = false;
+        if ($this->millis < 0) {
+            $resetMillis = true;
+            $this->millis = Phing::currentTimeMillis();
+        }
+
+        if ($this->file !== null) {
+            $this->touchFile($this->file);
+        }
+
+        // deal with the filesets
+        foreach($this->filesets as $fs) {
+        
+            $ds = $fs->getDirectoryScanner($this->getProject());
+            $fromDir = $fs->getDir($this->getProject());
+
+            $srcFiles = $ds->getIncludedFiles();
+            $srcDirs = $ds->getIncludedDirectories();
+
+            for ($j=0,$_j=count($srcFiles); $j < $_j; $j++) {
+                $this->touchFile(new PhingFile($fromDir, (string) $srcFiles[$j]));
+            }
+            
+            for ($j=0,$_j=count($srcDirs); $j < $_j ; $j++) {
+                $this->touchFile(new PhingFile($fromDir, (string) $srcDirs[$j]));
+            }
+        }
+
+        if ($resetMillis) {
+            $this->millis = -1;
+        }
+    }
+
+    private function touchFile($file) {
+        if ( !$file->canWrite() ) {
+            throw new BuildException("Can not change modification date of read-only file " . $file->__toString());
+        }
+        $file->setLastModified($this->millis);
+    }
+
+}
+
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/system/TstampTask.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/system/TstampTask.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/system/TstampTask.php	(revision 19)
@@ -0,0 +1,168 @@
+<?php
+/*
+ *  $Id: TstampTask.php 325 2007-12-20 15:44:58Z hans $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+ 
+require_once 'phing/Task.php';
+
+/**
+ * Sets properties to the current time, or offsets from the current time.
+ * The default properties are TSTAMP, DSTAMP and TODAY;
+ *
+ * Based on Ant's Tstamp task.
+ * 
+ * @author   Michiel Rook <michiel.rook@gmail.com>
+ * @version  $Revision: 1.6 $
+ * @package  phing.tasks.system
+ * @since    2.2.0
+ */
+class TstampTask extends Task
+{
+	private $customFormats = array();
+	
+	private $prefix = "";
+	
+	/**
+	 * Set a prefix for the properties. If the prefix does not end with a "."
+	 * one is automatically added.
+	 * @param prefix the prefix to use.
+	 */
+	public function setPrefix($prefix)
+	{
+		$this->prefix = $prefix;
+		
+		if (!empty($this->prefix))
+		{
+			$this->prefix.= ".";
+		}
+	}
+	
+    /**
+     * Adds a custom format
+     *
+	 * @param TstampCustomFormat custom format
+     */
+	public function addFormat(TstampCustomFormat $cf)
+	{
+		$this->customFormats[] = $cf;
+	}
+
+    /**
+     * Create the timestamps. Custom ones are done before
+     * the standard ones.
+     *
+     * @throws BuildException
+     */
+    public function main()
+    {
+		foreach ($this->customFormats as $cf)
+		{
+			$cf->execute($this);
+		}
+		
+		$dstamp = strftime('%Y%m%d');
+		$this->prefixProperty('DSTAMP', $dstamp);
+		
+		$tstamp = strftime('%H%M');
+		$this->prefixProperty('TSTAMP', $tstamp);
+		
+		$today = strftime('%B %d %Y');
+		$this->prefixProperty('TODAY', $today);
+	}
+	
+    /**
+     * helper that encapsulates prefix logic and property setting
+     * policy (i.e. we use setNewProperty instead of setProperty).
+     */
+    public function prefixProperty($name, $value)
+    {
+        $this->getProject()->setNewProperty($this->prefix . $name, $value);
+    }
+}
+
+class TstampCustomFormat
+{
+	private $propertyName = "";
+	private $pattern = "";
+	private $locale = "";
+	
+	/**
+	 * The property to receive the date/time string in the given pattern
+	 *
+	 * @param propertyName the name of the property.
+	 */
+	public function setProperty($propertyName)
+	{
+		$this->propertyName = $propertyName;
+	}
+
+	/**
+	 * The date/time pattern to be used. The values are as
+	 * defined by the PHP strftime() function.
+	 *
+	 * @param pattern
+	 */
+	public function setPattern($pattern)
+	{
+		$this->pattern = $pattern;
+	}
+	
+	/**
+	 * The locale used to create date/time string.
+	 *
+	 * @param locale
+	 */
+	public function setLocale($locale)
+	{
+		$this->locale = $locale;
+	}
+	
+	/**
+	 * validate parameter and execute the format.
+	 *
+	 * @param TstampTask reference to task
+	 */
+	public function execute(TstampTask $tstamp)
+	{
+		if (empty($this->propertyName))
+		{
+			throw new BuildException("property attribute must be provided");
+		}
+
+		if (empty($this->pattern))
+		{
+			throw new BuildException("pattern attribute must be provided");
+		}
+		
+		if (!empty($this->locale))
+		{
+			setlocale(LC_ALL, $this->locale);
+		}
+		
+		$value = strftime($this->pattern);
+		$tstamp->prefixProperty($this->propertyName, $value);
+		
+		if (!empty($this->locale))
+		{
+			// reset locale
+			setlocale(LC_ALL, NULL);
+		}
+	}
+}
+
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/system/TypedefTask.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/system/TypedefTask.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/system/TypedefTask.php	(revision 19)
@@ -0,0 +1,125 @@
+<?php
+/*
+ *  $Id: TypedefTask.php 43 2006-03-10 14:31:51Z mrook $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+require_once 'phing/Task.php';
+
+/**
+ * Register a datatype for use within a buildfile.
+ * 
+ * This is for registering your own datatypes for use within a buildfile.
+ * 
+ * If you find that you are using a particular class frequently, you may want to edit the 
+ * phing/types/defaults.properties file so that it is included by default.  You may also
+ * want to submit it (if LGPL or compatible license) to be included in Phing distribution.
+ * 
+ * <pre>
+ *   <typedef name="mytype" classname="path.to.MyHandlingClass"/>
+ *   .
+ *   <sometask ...>
+ *     <mytype param1="val1" param2="val2"/>
+ *   </sometask>
+ * </pre>
+ * 
+ * TODO:
+ *    -- possibly refactor since this is almost the same as TaskDefTask
+ *      (right now these are just too simple to really justify creating an abstract class)
+ * 
+ * @author    Hans Lellelid <hans@xmpl.org>
+ * @version   $Revision: 1.7 $
+ * @package   phing.tasks.system
+ */
+class TypedefTask extends Task {
+    
+    /** Tag name for datatype that will be used in XML */
+    private $name;
+    
+    /**
+     * Classname of task to register.
+     * This can be a dot-path -- relative to a location on PHP include_path.
+     * E.g. path.to.MyClass ->  path/to/MyClass.php
+     * @var string
+     */
+    private $classname;
+    
+    /**
+     * Path to add to PHP include_path to aid in finding specified class.
+     * @var Path
+     */
+    private $classpath;
+    
+    /** Refid to already defined classpath */
+    private $classpathId;
+    
+    /**
+     * Set the classpath to be used when searching for component being defined
+     * 
+     * @param Path $classpath An Path object containing the classpath.
+     */
+    public function setClasspath(Path $classpath) {
+        if ($this->classpath === null) {
+            $this->classpath = $classpath;
+        } else {
+            $this->classpath->append($classpath);
+        }
+    }
+
+    /**
+     * Create the classpath to be used when searching for component being defined
+     */ 
+    public function createClasspath() {
+        if ($this->classpath === null) {
+            $this->classpath = new Path($this->project);
+        }
+        return $this->classpath->createPath();
+    }
+
+    /**
+     * Reference to a classpath to use when loading the files.
+     */
+    public function setClasspathRef(Reference $r) {
+        $this->classpathId = $r->getRefId();
+        $this->createClasspath()->setRefid($r);
+    }
+    
+    /** Main entry point */
+    public function main() {
+        if ($this->name === null || $this->classname === null) {
+            throw new BuildException("You must specify name and class attributes for <typedef>.");
+        }        
+        $this->project->addDataTypeDefinition($this->name, $this->classname, $this->classpath);
+    }
+    
+    /**
+     * Sets the name that will be used in XML buildfile.
+     * @param string $name
+     */
+    public function setName($name)    {
+        $this->name = $name;
+    }
+    
+    /**
+     * Sets the class name / dotpath to use.
+     * @param string $class
+     */
+    public function setClassname($class) {
+        $this->classname = $class;
+    }
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/system/UpToDateTask.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/system/UpToDateTask.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/system/UpToDateTask.php	(revision 19)
@@ -0,0 +1,217 @@
+<?php
+/*
+ * $Id: UpToDateTask.php 144 2007-02-05 15:19:00Z hans $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+require_once 'phing/Task.php';
+include_once 'phing/tasks/system/condition/Condition.php';
+include_once 'phing/util/DirectoryScanner.php';
+include_once 'phing/util/SourceFileScanner.php';
+include_once 'phing/mappers/MergeMapper.php';
+
+/**
+ * Sets the given property if the specified target has a timestamp
+ * greater than all of the source files.
+ *
+ * @author    Hans Lellelid <hans@xmpl.org> (Phing)
+ * @author    William Ferguson <williamf@mincom.com> (Ant)
+ * @author    Hiroaki Nakamura <hnakamur@mc.neweb.ne.jp> (Ant)
+ * @author    Stefan Bodewig <stefan.bodewig@epost.de> (Ant)
+ * @version   $Revision: 1.6 $
+ * @package   phing.tasks.system
+ */
+class UpToDateTask extends Task implements Condition {
+
+    private $_property;
+    private $_value;
+    private $_sourceFile;
+    private $_targetFile;
+    private $sourceFileSets = array();
+
+    protected $mapperElement = null;
+
+    /**
+     * The property to set if the target file is more up-to-date than
+     * (each of) the source file(s).
+     *
+     * @param property the name of the property to set if Target is up-to-date.
+     */
+    public function setProperty($property) {
+        $this->_property = $property;
+    }
+
+    /**
+     * The value to set the named property to if the target file is more
+     * up-to-date than (each of) the source file(s). Defaults to 'true'.
+     *
+     * @param value the value to set the property to if Target is up-to-date
+     */
+    public function setValue($value) {
+        $this->_value = $value;
+    }
+
+    /**
+     * Returns the value, or "true" if a specific value wasn't provided.
+     */
+    private function getValue() {
+        return ($this->_value !== null) ? $this->_value : "true";
+    } 
+
+    /**
+     * The file which must be more up-to-date than (each of) the source file(s)
+     * if the property is to be set.
+     *
+     * @param file the file we are checking against.
+     */
+    public function setTargetFile($file) {
+        if (is_string($file)) {
+            $file = new PhingFile($file);
+        }
+        $this->_targetFile = $file;
+    }
+
+    /**
+     * The file that must be older than the target file
+     * if the property is to be set.
+     *
+     * @param file the file we are checking against the target file.
+     */
+    public function setSrcfile($file) {
+        if (is_string($file)) {
+            $file = new PhingFile($file);
+        }
+        $this->_sourceFile = $file;
+    }
+
+    /**
+     * Nested <srcfiles> element.
+     */
+    public function createSrcfiles() {
+        $fs = new FileSet();
+        $this->sourceFileSets[] = $fs;
+        return $fs;
+    }
+
+    /**
+     * Defines the FileNameMapper to use (nested mapper element).
+     */
+    public function createMapper() {
+        if ($this->mapperElement !== null) {
+            throw new BuildException("Cannot define more than one mapper",
+                                     $this->location);
+        }
+        $this->mapperElement = new Mapper($this->getProject());
+        return $this->mapperElement;
+    }
+
+    /**
+     * Evaluate (all) target and source file(s) to
+     * see if the target(s) is/are up-to-date.
+     * @return boolean
+     */
+    public function evaluate() {
+        if (count($this->sourceFileSets) === 0 && $this->_sourceFile === null) {
+            throw new BuildException("At least one srcfile or a nested "
+                                     . "<srcfiles> element must be set.");
+        }
+
+        if (count($this->sourceFileSets) > 0 && $this->_sourceFile !== null) {
+            throw new BuildException("Cannot specify both the srcfile "
+                                     . "attribute and a nested <srcfiles> "
+                                     . "element.");
+        }
+
+        if ($this->_targetFile === null && $this->mapperElement === null) {
+            throw new BuildException("The targetfile attribute or a nested "
+                                     . "mapper element must be set.");
+        }
+
+        // if the target file is not there, then it can't be up-to-date
+        if ($this->_targetFile !== null && !$this->_targetFile->exists()) {
+            return false;
+        } 
+
+        // if the source file isn't there, throw an exception
+        if ($this->_sourceFile !== null && !$this->_sourceFile->exists()) {
+            throw new BuildException($this->_sourceFile->getAbsolutePath() 
+                                     . " not found.");
+        }
+
+        $upToDate = true;
+        for($i=0,$size=count($this->sourceFileSets); $i < $size && $upToDate; $i++) {
+            $fs = $this->sourceFileSets[$i];
+            $ds = $fs->getDirectoryScanner($this->project);
+            $upToDate = $upToDate && $this->scanDir($fs->getDir($this->project),
+                                           $ds->getIncludedFiles());
+        }
+
+        if ($this->_sourceFile !== null) {
+            if ($this->mapperElement === null) {
+                $upToDate = $upToDate &&
+                    ($this->_targetFile->lastModified() >= $this->_sourceFile->lastModified());
+            } else {
+                $sfs = new SourceFileScanner($this);
+                $upToDate = $upToDate &&
+                    count($sfs->restrict($this->_sourceFile->getAbsolutePath(),
+                                  null, null, 
+                                  $this->mapperElement->getImplementation())) === 0;                   
+            }
+        }
+        return $upToDate;
+    }
+
+
+    /**
+     * Sets property to true if target file(s) have a more recent timestamp
+     * than (each of) the corresponding source file(s).
+     * @throws BuildException 
+     */
+    public function main() {
+        if ($this->_property === null) {
+            throw new BuildException("property attribute is required.", 
+                                     $this->location);
+        }
+        $upToDate = $this->evaluate();
+        if ($upToDate) {
+            $this->project->setNewProperty($this->_property, $this->getValue());
+            if ($this->mapperElement === null) {
+                $this->log("File \"" . $this->_targetFile->getAbsolutePath() 
+                    . "\" is up-to-date.", Project::MSG_VERBOSE);
+            } else {
+                $this->log("All target files are up-to-date.",
+                    Project::MSG_VERBOSE);
+            }
+        }
+    }
+
+    protected function scanDir(PhingFile $srcDir, $files) {
+        $sfs = new SourceFileScanner($this);
+        $mapper = null;
+        $dir = $srcDir;
+        if ($this->mapperElement === null) {
+            $mm = new MergeMapper();
+            $mm->setTo($this->_targetFile->getAbsolutePath());
+            $mapper = $mm;
+            $dir = null;
+        } else {
+            $mapper = $this->mapperElement->getImplementation();
+        }
+        return (count($sfs->restrict($files, $srcDir, $dir, $mapper)) === 0);
+    }
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/system/WarnTask.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/system/WarnTask.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/system/WarnTask.php	(revision 19)
@@ -0,0 +1,35 @@
+<?php
+/*
+ *  $Id: WarnTask.php 144 2007-02-05 15:19:00Z hans $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+ 
+require_once 'phing/tasks/system/EchoTask.php';
+
+/**
+ * Simple task to echo a warning message (Project::MSG_WARN) to all output devices.
+ *
+ * @author   Hans Lellelid <hans@xmpl.org>
+ * @version  $Revision: 1.1 $ $Date: 2007-02-05 15:19:00 +0000 (Mon, 05 Feb 2007) $
+ * @package  phing.tasks.system
+ */
+class WarnTask extends EchoTask {
+    function main() {
+        $this->log($this->msg, Project::MSG_WARN);
+    }
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/system/XsltTask.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/system/XsltTask.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/system/XsltTask.php	(revision 19)
@@ -0,0 +1,81 @@
+<?php
+/*
+ *  $Id: XsltTask.php 144 2007-02-05 15:19:00Z hans $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+require_once 'phing/tasks/system/CopyTask.php';
+include_once 'phing/system/io/FileReader.php';
+include_once 'phing/system/io/FileWriter.php';
+include_once 'phing/filters/XsltFilter.php';
+
+/**
+ * Implements an XSLT processing filter while copying files.
+ *
+ * This is a shortcut for calling the <copy> task with the XSLTFilter used
+ * in the <filterchains> section.
+ * 
+ * @author    Andreas Aderhold, andi@binarycloud.com
+ * @version   $Revision: 1.8 $
+ * @package   phing.tasks.system
+ */
+class XsltTask extends CopyTask {
+    
+    /** XSLTFilter object that we use to handle transformation. */
+    private $xsltFilter;
+    
+    /** Parameters to pass to XSLT procesor. */
+    private $parameters = array();
+    
+    /**
+     * Setup the filterchains w/ XSLTFilter that we will use while copying the files.
+     */
+    function init() {
+        $xf = new XsltFilter();
+        $chain = $this->createFilterChain($this->getProject());
+        $chain->addXsltFilter($xf);
+        $this->xsltFilter = $xf;        
+    }
+    
+    /**
+     * Set any XSLT Param and invoke CopyTask::main()
+     * @see CopyTask::main()
+     */
+    function main() {        
+        $this->log("Doing XSLT transformation using stylesheet " . $this->xsltFilter->getStyle(), Project::MSG_VERBOSE);
+        $this->xsltFilter->setParams($this->parameters);
+        parent::main();
+    }
+    
+    /**
+     * Set the stylesheet to use.
+     * @param PhingFile $style
+     */
+    function setStyle(PhingFile $style) {
+        $this->xsltFilter->setStyle($style);
+    }
+    
+    /**
+     * Support nested <param> tags useing XSLTParam class.
+     * @return XSLTParam
+     */
+    function createParam() {
+        $num = array_push($this->parameters, new XSLTParam());
+        return $this->parameters[$num-1];
+    }
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/system/condition/AndCondition.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/system/condition/AndCondition.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/system/condition/AndCondition.php	(revision 19)
@@ -0,0 +1,46 @@
+<?php
+/*
+ * $Id: AndCondition.php 43 2006-03-10 14:31:51Z mrook $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+require_once 'phing/tasks/system/condition/ConditionBase.php';
+
+/**
+ *  <and> condition container.
+ *
+ *  Iterates over all conditions and returns false as soon as one
+ *  evaluates to false.
+ * 
+ *  @author    Hans Lellelid <hans@xmpl.org>
+ *  @author    Andreas Aderhold <andi@binarycloud.com>
+ *  @copyright © 2001,2002 THYRELL. All rights reserved
+ *  @version   $Revision: 1.7 $
+ *  @package   phing.tasks.system.condition
+ */
+class AndCondition extends ConditionBase implements Condition {
+
+    public function evaluate() {
+        foreach($this as $c) { // ConditionBase implements IteratorAggregator
+              if (!$c->evaluate()) {
+                return false;
+            }
+        }
+        return true;       
+    }
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/system/condition/Condition.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/system/condition/Condition.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/system/condition/Condition.php	(revision 19)
@@ -0,0 +1,38 @@
+<?php
+
+/*
+ *  $Id: Condition.php 325 2007-12-20 15:44:58Z hans $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+/**
+ * Condition interface specification:
+ *
+ * Each condition must implement a method applying to this prototye:
+ *
+ * @author Hans Lellelid <hans@xmpl.org>
+ * @version $Revision: 1.4 $
+ * @package phing.tasks.system.condition
+ */
+interface Condition {
+    /**
+     * @return boolean
+     * @throws BuildException
+     */
+    public function evaluate();
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/system/condition/ConditionBase.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/system/condition/ConditionBase.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/system/condition/ConditionBase.php	(revision 19)
@@ -0,0 +1,195 @@
+<?php
+/*
+ *  $Id: ConditionBase.php 43 2006-03-10 14:31:51Z mrook $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+require_once 'phing/ProjectComponent.php';
+include_once 'phing/Project.php';
+include_once 'phing/tasks/system/AvailableTask.php';
+include_once 'phing/tasks/system/condition/Condition.php';
+
+/**
+ *  Abstract baseclass for the <condition> task as well as several
+ *  conditions - ensures that the types of conditions inside the task
+ *  and the "container" conditions are in sync.
+ * 
+ *    @author    Hans Lellelid <hans@xmpl.org>
+ *  @author    Andreas Aderhold <andi@binarycloud.com>
+ *  @copyright © 2001,2002 THYRELL. All rights reserved
+ *  @version   $Revision: 1.16 $
+ *  @package   phing.tasks.system.condition
+ */
+abstract class ConditionBase extends ProjectComponent implements IteratorAggregate {
+        
+    public $conditions = array(); // needs to be public for "inner" class access
+
+    function countConditions() {
+        return count($this->conditions);
+    }
+    
+    /**
+     * Required for IteratorAggregate
+     */
+    function getIterator() {
+        return new ConditionEnumeration($this);
+    }
+    
+    function getConditions() {
+        return $this->conditions;
+    }
+
+    /**
+     * @return void
+     */
+    function addAvailable(AvailableTask $a) {
+        $this->conditions[] = $a;
+    }
+
+    /**
+     * @return NotCondition
+     */
+    function createNot() {
+        include_once 'phing/tasks/system/condition/NotCondition.php';
+        $num = array_push($this->conditions, new NotCondition());
+        return $this->conditions[$num-1];        
+    }
+
+    /**
+     * @return AndCondition
+     */
+    function createAnd() {
+        include_once 'phing/tasks/system/condition/AndCondition.php';
+        $num = array_push($this->conditions, new AndCondition());
+        return $this->conditions[$num-1];
+    }
+    
+    /**
+     * @return OrCondition
+     */
+    function createOr() {
+        include_once 'phing/tasks/system/condition/OrCondition.php';
+        $num = array_push($this->conditions, new OrCondition());
+        return $this->conditions[$num-1];        
+    }
+
+    /**
+     * @return EqualsCondition
+     */
+    function createEquals() {
+        include_once 'phing/tasks/system/condition/EqualsCondition.php';  
+        $num = array_push($this->conditions, new EqualsCondition());
+        return $this->conditions[$num-1];
+    }
+
+    /**
+     * @return OsCondition
+     */
+    function createOs() {
+        include_once 'phing/tasks/system/condition/OsCondition.php';
+        $num = array_push($this->conditions, new OsCondition());
+        return $this->conditions[$num-1];
+    }
+   
+    /**
+     * @return IsFalseCondition
+     */
+    function createIsFalse() {
+        include_once 'phing/tasks/system/condition/IsFalseCondition.php';
+        $num = array_push($this->conditions, new IsFalseCondition());
+        return $this->conditions[$num-1];
+    }
+   
+    /**
+     * @return IsTrueCondition
+     */
+    function createIsTrue() {
+        include_once 'phing/tasks/system/condition/IsTrueCondition.php';
+        $num = array_push($this->conditions, new IsTrueCondition());
+        return $this->conditions[$num-1];
+    }
+   
+    /**
+     * @return ContainsCondition
+     */
+    function createContains() {
+        include_once 'phing/tasks/system/condition/ContainsCondition.php';
+        $num = array_push($this->conditions, new ContainsCondition());
+        return $this->conditions[$num-1];
+    }
+   
+    /**
+     * @return IsSetCondition
+     */
+    function createIsSet() {
+        include_once 'phing/tasks/system/condition/IsSetCondition.php';
+        $num = array_push($this->conditions, new IsSetCondition());
+        return $this->conditions[$num-1];
+    }
+
+    /**
+     * @return ReferenceExistsCondition
+     */
+    function createReferenceExists() {
+        include_once 'phing/tasks/system/condition/ReferenceExistsCondition.php';
+        $num = array_push($this->conditions, new ReferenceExistsCondition());
+        return $this->conditions[$num-1];
+    }
+
+}
+
+/**
+ * "Inner" class for handling enumerations.
+ * Uses build-in PHP5 iterator support.
+ */
+class ConditionEnumeration implements Iterator {
+    
+    /** Current element number */
+    private $num = 0;
+    
+    /** "Outer" ConditionBase class. */
+    private $outer;
+
+    function __construct(ConditionBase $outer) {
+        $this->outer = $outer;
+    }
+    
+    public function valid() {
+        return $this->outer->countConditions() > $this->num;
+    }
+
+    function current() {
+        $o = $this->outer->conditions[$this->num];
+        if ($o instanceof ProjectComponent) {
+            $o->setProject($this->outer->getProject());
+        }
+        return $o;
+    }
+    
+    function next() {
+        $this->num++;
+    }
+    
+    function key() {
+        return $this->num;
+    }
+    
+    function rewind() {
+        $this->num = 0;
+    }
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/system/condition/ContainsCondition.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/system/condition/ContainsCondition.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/system/condition/ContainsCondition.php	(revision 19)
@@ -0,0 +1,76 @@
+<?php
+
+/*
+ *  $Id: ContainsCondition.php 43 2006-03-10 14:31:51Z mrook $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+ 
+require_once 'phing/tasks/system/condition/Condition.php';
+
+/**
+ * Is one string part of another string?
+ *
+ * @author Hans Lellelid <hans@xmpl.org> (Phing)
+ * @author Stefan Bodewig <stefan.bodewig@epost.de> (Ant)
+ * @version $Revision: 1.3 $
+ * @package phing.tasks.system.condition
+ */
+class ContainsCondition implements Condition {
+
+    private $string;
+    private $subString;
+    private $caseSensitive = true;
+
+    /**
+     * The string to search in.
+     * @param string $a1
+     */
+    public function setString($a1) {
+        $this->string = $a1;
+    }
+
+    /**
+     * The string to search for.
+     * @param string $a2
+     */
+    public function setSubstring($a2) {
+        $this->subString = $a2;
+    }
+
+    /**
+     * Whether to search ignoring case or not.
+     */
+    public function setCaseSensitive($b) {
+        $this->caseSensitive = (boolean) $b;
+    }
+
+    /** 
+     * Check whether string contains substring.
+     * @throws BuildException
+     */
+    public function evaluate()  {
+        if ($this->string === null || $this->subString === null) {
+            throw new BuildException("both string and substring are required "
+                                     . "in contains");
+        }
+
+        return $this->caseSensitive 
+            ? strpos($this->string, $this->subString) !== false
+            : substr(strtolower($this->string), strtolower($this->subString)) !== false;
+    }
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/system/condition/EqualsCondition.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/system/condition/EqualsCondition.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/system/condition/EqualsCondition.php	(revision 19)
@@ -0,0 +1,78 @@
+<?php
+/*
+ *  $Id: EqualsCondition.php 43 2006-03-10 14:31:51Z mrook $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+require_once 'phing/tasks/system/condition/Condition.php';
+
+/**
+ *  A simple string comparator.  Compares two strings for eqiality in a
+ *  binary safe manner. Implements the condition interface specification.
+ *
+ *  @author    Andreas Aderhold <andi@binarycloud.com>
+ *  @copyright © 2001,2002 THYRELL. All rights reserved
+ *  @version   $Revision: 1.7 $ $Date: 2006-03-10 14:31:51 +0000 (Fri, 10 Mar 2006) $
+ *  @access    public
+ *  @package   phing.tasks.system.condition
+ */
+class EqualsCondition implements Condition {
+
+    private $arg1;
+    private $arg2;
+    private $trim = false;
+    private $caseSensitive = true;
+    
+    public function setArg1($a1) {
+        $this->arg1 = $a1;
+    }
+
+    public function setArg2($a2) {
+        $this->arg2 = $a2;
+    }
+
+    /**
+     * Should we want to trim the arguments before comparing them?
+     * @param boolean $b
+     */
+    public function setTrim($b) {
+        $this->trim = (boolean) $b;
+    }
+
+    /**
+     * Should the comparison be case sensitive?
+     * @param boolean $b
+     */
+    public function setCaseSensitive($b) {
+        $this->caseSensitive = (boolean) $b;
+    } 
+    
+    public function evaluate() {
+        if ($this->arg1 === null || $this->arg2 === null) {
+            throw new BuildException("Both arg1 and arg2 are required in equals.");
+        }
+        
+        if ($this->trim) {
+            $this->arg1 = trim($this->arg1);
+            $this->arg2 = trim($this->arg2);
+        }
+        
+        //print("[comparison] Comparing '".$this->arg1."' and '".$this->arg2."'\n");
+        return $this->caseSensitive ? $this->arg1 === $this->arg2 : strtolower($this->arg1) === strtolower($this->arg2);
+    }
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/system/condition/IsFalseCondition.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/system/condition/IsFalseCondition.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/system/condition/IsFalseCondition.php	(revision 19)
@@ -0,0 +1,60 @@
+<?php
+/*
+ *  $Id: IsFalseCondition.php 43 2006-03-10 14:31:51Z mrook $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+require_once 'phing/ProjectComponent.php';
+require_once 'phing/tasks/system/condition/Condition.php';
+
+/**
+ * Condition that tests whether a given string evals to false.
+ * 
+ * @author Hans Lellelid (Phing)
+ * @author Steve Loughran (Ant)
+ * @version $Revision: 1.4 $
+ * @package phing.tasks.system.condition
+ */
+class IsFalseCondition extends ProjectComponent implements Condition {
+    
+    /**  
+     * what we eval
+     */ 
+    private $value;
+
+    /**
+     * Set the value to be tested.
+     * @param boolean $value
+     */ 
+    public function setValue($value) {
+        $this->value = $value;
+    }
+
+    /**
+     * return the inverted value;
+     * @throws BuildException if someone forgot to spec a value
+     */ 
+    public function evaluate() {
+        if ($this->value === null) {
+            throw new BuildException("Nothing to test for falsehood");
+        }
+        return !$this->value;
+    }
+
+}
+
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/system/condition/IsSetCondition.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/system/condition/IsSetCondition.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/system/condition/IsSetCondition.php	(revision 19)
@@ -0,0 +1,53 @@
+<?php
+/*
+ *  $Id: IsSetCondition.php 43 2006-03-10 14:31:51Z mrook $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+require_once 'phing/ProjectComponent.php';
+require_once 'phing/tasks/system/condition/Condition.php';
+
+/**
+ * Condition that tests whether a given property has been set.
+ *
+ * @author Hans Lellelid <hans@xmpl.org> (Phing)
+ * @author Stefan Bodewig <stefan.bodewig@epost.de> (Ant)
+ * @version $Revision: 1.4 $
+ * @package phing.tasks.system.condition
+ */
+class IsSetCondition extends ProjectComponent implements Condition {
+    
+    private $property;
+
+    public function setProperty($p) {
+        $this->property = $p;
+    }
+
+    /**
+     * Check whether property is set.
+     * @throws BuildException
+     */
+    public function evaluate()  {
+        if ($this->property === null) {
+            throw new BuildException("No property specified for isset "
+                                     . "condition");
+        }        
+        return $this->project->getProperty($this->property) !== null;
+    }
+
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/system/condition/IsTrueCondition.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/system/condition/IsTrueCondition.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/system/condition/IsTrueCondition.php	(revision 19)
@@ -0,0 +1,59 @@
+<?php
+/*
+ *  $Id: IsTrueCondition.php 43 2006-03-10 14:31:51Z mrook $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+require_once 'phing/ProjectComponent.php';
+require_once 'phing/tasks/system/condition/Condition.php';
+
+/**
+ * Condition that tests whether a given string evals to true.
+ *
+ * @author Hans Lellelid <hans@xmpl.org> (Phing)
+ * @author Steve Loughran (Ant)
+ * @package phing.tasks.system.condition
+ */
+class IsTrueCondition extends ProjectComponent implements Condition {
+
+    /**  
+     * what we eval
+     */ 
+    private $value;
+
+    /**
+     * Set the value to be tested.
+     * @param boolean $value
+     */ 
+    public function setValue($value) {
+        $this->value = $value;
+    }
+
+    /**
+     * return the inverted value;
+     * @throws BuildException if someone forgot to spec a value
+     */ 
+    public function evaluate() {
+        if ($this->value === null) {
+            throw new BuildException("Nothing to test for falsehood");
+        }
+        return $this->value;
+    }
+
+}
+
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/system/condition/NotCondition.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/system/condition/NotCondition.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/system/condition/NotCondition.php	(revision 19)
@@ -0,0 +1,48 @@
+<?php
+/*
+ *  $Id: NotCondition.php 43 2006-03-10 14:31:51Z mrook $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+require_once 'phing/tasks/system/condition/ConditionBase.php';
+
+/**
+ *  <not> condition.
+ *
+ *  Evaluates to true if the single condition nested into it is false
+ *  and vice versa.
+ *
+ *  @author    Andreas Aderhold <andi@binarycloud.com>
+ *  @copyright © 2001,2002 THYRELL. All rights reserved
+ *  @version   $Revision: 1.6 $ $Date: 2006-03-10 14:31:51 +0000 (Fri, 10 Mar 2006) $
+ *  @access    public
+ *  @package   phing.tasks.system.condition
+ */
+class NotCondition extends ConditionBase implements Condition {
+
+    function evaluate() {
+        if ($this->countConditions() > 1) {
+            throw new BuildException("You must not nest more than one condition into <not>");
+        }
+        if ($this->countConditions() < 1) {
+            throw new BuildException("You must nest a condition into <not>");
+        }
+        $conds = $this->getIterator();
+        return !$conds->current()->evaluate();
+    }
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/system/condition/OrCondition.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/system/condition/OrCondition.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/system/condition/OrCondition.php	(revision 19)
@@ -0,0 +1,46 @@
+<?php
+/*
+ *  $Id: OrCondition.php 43 2006-03-10 14:31:51Z mrook $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+require_once 'phing/tasks/system/condition/ConditionBase.php';
+
+/**
+ *  <or> condition container.
+ *
+ *  Iterates over all conditions and returns true as soon as one
+ *  evaluates to true.
+ *
+ *  @author    Andreas Aderhold <andi@binarycloud.com>
+ *  @copyright  2001,2002 THYRELL. All rights reserved
+ *  @version   $Revision: 1.8 $ $Date: 2006-03-10 14:31:51 +0000 (Fri, 10 Mar 2006) $
+ *  @access    public
+ *  @package   phing.tasks.system.condition
+ */
+class OrCondition extends ConditionBase implements Condition {
+
+    function evaluate() {
+        foreach($this as $c) { // ConditionBase implements IteratorAggregator
+              if ($c->evaluate()) {
+                return true;
+            }
+        }
+        return false;
+    }
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/system/condition/OsCondition.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/system/condition/OsCondition.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/system/condition/OsCondition.php	(revision 19)
@@ -0,0 +1,63 @@
+<?php
+/*
+ *  $Id: OsCondition.php 43 2006-03-10 14:31:51Z mrook $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+require_once 'phing/tasks/system/condition/ConditionBase.php';
+
+/**
+ *  Condition that tests the OS type.
+ *
+ *  @author    Andreas Aderhold <andi@binarycloud.com>
+ *  @copyright © 2001,2002 THYRELL. All rights reserved
+ *  @version   $Revision: 1.8 $ $Date: 2006-03-10 14:31:51 +0000 (Fri, 10 Mar 2006) $
+ *  @access    public
+ *  @package   phing.tasks.system.condition
+ */
+class OsCondition implements Condition {
+
+    private $family;
+
+    function setFamily($f) {
+        $this->family = strtolower($f);
+    }
+
+    function evaluate() {
+        $osName = strtolower(Phing::getProperty("os.name"));
+		
+        if ($this->family !== null) {
+            if ($this->family === "windows") {
+                return StringHelper::startsWith("win", $osName);
+            } elseif ($this->family === "mac") {
+                return (strpos($osName, "mac") !== false || strpos($osName, "darwin") !== false);
+            } elseif ($this->family === ("unix")) {
+				return (
+					StringHelper::endsWith("ix", $osName) ||
+					StringHelper::endsWith("ux", $osName) ||
+					StringHelper::endsWith("bsd", $osName) ||
+					StringHelper::startsWith("sunos", $osName) ||
+					StringHelper::startsWith("darwin", $osName)
+				);
+            }
+            throw new BuildException("Don't know how to detect os family '" . $this->family . "'");
+        }
+        return false;
+    }
+
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/system/condition/ReferenceExistsCondition.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/system/condition/ReferenceExistsCondition.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/tasks/system/condition/ReferenceExistsCondition.php	(revision 19)
@@ -0,0 +1,52 @@
+<?php
+/*
+ *  $Id: ReferenceExistsCondition.php 227 2007-08-28 02:17:00Z hans $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+require_once 'phing/ProjectComponent.php'; require_once 'phing/tasks/system/condition/Condition.php';
+
+/**
+ * Condition that tests whether a given reference exists.
+ *
+ * @author Matthias Pigulla <mp@webfactory.de> (Phing)
+ * @version $Revision: 1.1 $
+ * @package phing.tasks.system.condition  */
+class ReferenceExistsCondition extends ProjectComponent implements Condition {
+    
+    private $refid;
+
+    public function setRef($id) {
+      $this->refid = (string) $id;
+    }
+
+    /**
+     * Check whether the reference exists.
+     * @throws BuildException
+     */
+    public function evaluate()  {
+        if ($this->refid === null) {
+            throw new BuildException("No ref attribute specified for reference-exists "
+                                     . "condition");
+        }        
+        $refs = $this->project->getReferences();
+        return isset($refs[$this->refid]);
+    }
+
+}
+
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/types/AbstractFileSet.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/types/AbstractFileSet.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/types/AbstractFileSet.php	(revision 19)
@@ -0,0 +1,570 @@
+<?php
+/*
+ *  $Id: AbstractFileSet.php 144 2007-02-05 15:19:00Z hans $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>. 
+ */
+
+include_once 'phing/system/io/PhingFile.php';
+include_once 'phing/types/DataType.php';
+include_once 'phing/types/PatternSet.php';
+include_once 'phing/types/selectors/BaseSelector.php';
+include_once 'phing/types/selectors/SelectorContainer.php';
+include_once 'phing/types/selectors/BaseSelectorContainer.php';
+
+// Load all of the selectors (not really necessary but
+// helps reveal parse errors right away)
+
+include_once 'phing/types/selectors/AndSelector.php';
+include_once 'phing/types/selectors/ContainsSelector.php';
+include_once 'phing/types/selectors/ContainsRegexpSelector.php';
+include_once 'phing/types/selectors/DateSelector.php';
+include_once 'phing/types/selectors/DependSelector.php';
+include_once 'phing/types/selectors/DepthSelector.php';
+include_once 'phing/types/selectors/ExtendSelector.php';
+include_once 'phing/types/selectors/FilenameSelector.php';
+include_once 'phing/types/selectors/MajoritySelector.php';
+include_once 'phing/types/selectors/NoneSelector.php';
+include_once 'phing/types/selectors/NotSelector.php';
+include_once 'phing/types/selectors/OrSelector.php';
+include_once 'phing/types/selectors/PresentSelector.php';
+include_once 'phing/types/selectors/SizeSelector.php';
+include_once 'phing/types/selectors/TypeSelector.php';
+
+include_once 'phing/util/DirectoryScanner.php';
+
+/**
+ * The FileSet class provides methods and properties for accessing
+ * and managing filesets. It extends ProjectComponent and thus inherits
+ * all methods and properties (not explicitly declared). See ProjectComponent
+ * for further detail.
+ *
+ * TODO:
+ *   - merge this with patternsets: FileSet extends PatternSet !!!
+ *     requires additional mods to the parsing algo
+ *         [HL] .... not sure if that really makes so much sense.  I think
+ *            that perhaps they should use common utility class if there really
+ *            is that much shared functionality
+ *
+ * @author    Andreas Aderhold <andi@binarycloud.com>
+ * @author    Hans Lellelid <hans@xmpl.org>
+ * @version    $Revision: 1.15 $ $Date: 2007-02-05 15:19:00 +0000 (Mon, 05 Feb 2007) $
+ * @see        ProjectComponent
+ * @package    phing.types
+ */
+class AbstractFileSet extends DataType implements SelectorContainer {
+    
+    // These vars are public for cloning purposes
+    
+    /**
+     * @var boolean
+     */
+    public $useDefaultExcludes = true;
+    
+    /**
+     * @var PatternSet
+     */
+    public $defaultPatterns;
+    
+    public $additionalPatterns = array();
+    public $dir;
+    public $isCaseSensitive = true;    
+    public $selectors = array();
+    
+    function __construct($fileset = null) {
+        if ($fileset !== null && ($fileset instanceof FileSet)) {
+            $this->dir = $fileset->dir;
+            $this->defaultPatterns = $fileset->defaultPatterns;
+            $this->additionalPatterns = $fileset->additionalPatterns;
+            $this->useDefaultExcludes = $fileset->useDefaultExcludes;
+            $this->isCaseSensitive = $fileset->isCaseSensitive;
+            $this->selectors = $fileset->selectors;
+        }
+        $this->defaultPatterns = new PatternSet();
+    }
+
+
+    /**
+    * Makes this instance in effect a reference to another PatternSet
+    * instance.
+    * You must not set another attribute or nest elements inside
+    * this element if you make it a reference.
+    */
+    function setRefid(Reference $r) {
+        if ((isset($this->dir) && !is_null($this->dir)) || $this->defaultPatterns->hasPatterns()) {
+            throw $this->tooManyAttributes();
+        }
+        if (!empty($this->additionalPatterns)) {
+            throw $this->noChildrenAllowed();
+        }
+        if (!empty($this->selectors)) {
+            throw $this->noChildrenAllowed();
+        }
+        parent::setRefid($r);
+    }
+
+
+    function setDir($dir) {
+        if ($this->isReference()) {
+            throw $this->tooManyAttributes();
+        }
+        if ($dir instanceof PhingFile) {
+            $dir = $dir->getPath();
+        }
+        $this->dir = new PhingFile((string) $dir);
+    }
+
+
+    function getDir(Project $p) {
+        if ($this->isReference()) {
+            return $this->getRef($p)->getDir($p);
+        }
+        return $this->dir;
+    }
+
+
+    function createPatternSet() {
+        if ($this->isReference()) {
+            throw $this->noChildrenAllowed();
+        }
+        $num = array_push($this->additionalPatterns, new PatternSet());
+        return $this->additionalPatterns[$num-1];
+    }
+
+    /**
+    * add a name entry on the include list
+    */
+    function createInclude() {
+        if ($this->isReference()) {
+            throw $this->noChildrenAllowed();
+        }
+        return $this->defaultPatterns->createInclude();
+    }
+
+    /**
+     * add a name entry on the include files list
+     */
+    function createIncludesFile() {
+        if ($this->isReference()) {
+            throw $this->noChildrenAllowed();
+        }
+        return $this->defaultPatterns->createIncludesFile();
+    }
+
+    /**
+     * add a name entry on the exclude list
+     */
+    function createExclude() {
+        if ($this->isReference()) {
+            throw $this->noChildrenAllowed();
+        }
+        return $this->defaultPatterns->createExclude();
+    }
+
+    /**
+     * add a name entry on the include files list
+     */
+    function createExcludesFile() {
+        if ($this->isReference()) {
+            throw $this->noChildrenAllowed();
+            return;
+        }
+        return $this->defaultPatterns->createExcludesFile();
+    }
+
+    /**
+     * Sets the set of include patterns. Patterns may be separated by a comma
+     * or a space.
+     */
+    function setIncludes($includes) {
+        if ($this->isReference()) {
+            throw $this->tooManyAttributes();
+        }
+        $this->defaultPatterns->setIncludes($includes);
+    }
+
+    /**
+     * Sets the set of exclude patterns. Patterns may be separated by a comma
+     * or a space.
+     */
+    function setExcludes($excludes) {
+        if ($this->isReference()) {
+            throw $this->tooManyAttributes();
+        }
+        $this->defaultPatterns->setExcludes($excludes);
+    }
+
+    /**
+     * Sets the name of the file containing the includes patterns.
+     *
+     * @param $incl The file to fetch the include patterns from.
+     * @throws BE
+     */
+    function setIncludesfile($incl) {
+        if ($this->isReference()) {
+            throw $this->tooManyAttributes();
+        }
+        $this->defaultPatterns->setIncludesfile($incl);
+    }
+
+    /**
+     * Sets the name of the file containing the includes patterns.
+     *
+     * @param $excl The file to fetch the exclude patterns from.
+     * @throws BE
+     */
+    function setExcludesfile($excl) {
+        if ($this->isReference()) {
+            throw $this->tooManyAttributes();
+        }
+        $this->defaultPatterns->setExcludesfile($excl);
+    }
+
+    /**
+     * Sets whether default exclusions should be used or not.
+     *
+     * @param $useDefaultExcludes "true"|"on"|"yes" when default exclusions
+     *                           should be used, "false"|"off"|"no" when they
+     *                           shouldn't be used.
+     */
+    function setDefaultexcludes($useDefaultExcludes) {
+        if ($this->isReference()) {
+            throw $this->tooManyAttributes();
+        }
+        $this->useDefaultExcludes = $useDefaultExcludes;
+    }
+
+    /**
+     * Sets case sensitivity of the file system
+     */
+    function setCaseSensitive($isCaseSensitive) {
+        $this->isCaseSensitive = $isCaseSensitive;
+    }
+
+    /** returns a reference to the dirscanner object belonging to this fileset */
+    function getDirectoryScanner(Project $p) {
+        if ($this->isReference()) {
+            $o = $this->getRef($p);
+            return $o->getDirectoryScanner($p);
+        }
+
+        if ($this->dir === null) {
+            throw new BuildException("No directory specified for fileset.");
+        }
+        if (!$this->dir->exists()) {
+            throw new BuildException("Directory ".$this->dir->getAbsolutePath()." not found.");
+        }
+        if (!$this->dir->isDirectory()) {
+            throw new BuildException($this->dir->getAbsolutePath()." is not a directory.");
+        }
+        $ds = new DirectoryScanner();
+        $this->setupDirectoryScanner($ds, $p);
+        $ds->scan();
+        return $ds;
+    }
+
+    /** feed dirscanner with infos defined by this fileset */
+    protected function setupDirectoryScanner(DirectoryScanner $ds, Project $p) {
+        if ($ds === null) {
+            throw new Exception("DirectoryScanner cannot be null");
+        }
+        // FIXME - pass dir directly wehn dirscanner supports File
+        $ds->setBasedir($this->dir->getPath());
+        
+        foreach($this->additionalPatterns as $addPattern) {
+            $this->defaultPatterns->append($addPattern, $p);
+        }              
+
+        $ds->setIncludes($this->defaultPatterns->getIncludePatterns($p));
+        $ds->setExcludes($this->defaultPatterns->getExcludePatterns($p));
+
+        $p->log("FileSet: Setup file scanner in dir " . $this->dir->__toString() . " with " . $this->defaultPatterns->toString(), Project::MSG_DEBUG);
+        
+        if ($ds instanceof SelectorScanner) {
+            $ds->setSelectors($this->getSelectors($p));
+        }
+        
+        if ($this->useDefaultExcludes) {
+            $ds->addDefaultExcludes();
+        }
+        $ds->setCaseSensitive($this->isCaseSensitive);
+    }
+
+
+    /**
+     * Performs the check for circular references and returns the
+     * referenced FileSet.
+     */
+    function getRef(Project $p) {
+        if (!$this->checked) {
+            $stk = array();
+            array_push($stk, $this);
+            $this->dieOnCircularReference($stk, $p);            
+        }
+
+        $o = $this->ref->getReferencedObject($p);
+        if (!($o instanceof FileSet)) {
+            $msg = $this->ref->getRefId()." doesn't denote a fileset";
+            throw new BuildException($msg);
+        } else {
+            return $o;
+        }
+    }
+    
+    // SelectorContainer methods
+
+    /**
+     * Indicates whether there are any selectors here.
+     *
+     * @return boolean Whether any selectors are in this container
+     */
+    public function hasSelectors() {
+        if ($this->isReference() && $this->getProject() !== null) {
+            return $this->getRef($this->getProject())->hasSelectors();
+        }
+        return !empty($this->selectors);
+    }
+
+    /**
+     * Indicates whether there are any patterns here.
+     *
+     * @return boolean Whether any patterns are in this container.
+     */
+    public function hasPatterns() {
+    
+        if ($this->isReference() && $this->getProject() !== null) {
+            return $this->getRef($this->getProject())->hasPatterns();            
+        }
+
+        if ($this->defaultPatterns->hasPatterns($this->getProject())) {
+            return true;
+        }
+
+        for($i=0,$size=count($this->additionalPatterns); $i < $size; $i++) {
+            $ps = $this->additionalPatterns[$i];
+            if ($ps->hasPatterns($this->getProject())) {
+                return true;
+            }
+        }
+
+        return false;
+    }
+    
+    /**
+     * Gives the count of the number of selectors in this container
+     *
+     * @return int The number of selectors in this container
+     */
+    public function selectorCount() {
+        if ($this->isReference() && $this->getProject() !== null) {
+            try {
+                return $this->getRef($this->getProject())->selectorCount();
+            } catch (Exception $e) {
+                throw $e;
+            }
+        }
+        return count($this->selectors);
+    }
+
+    /**
+     * Returns the set of selectors as an array.
+     *
+     * @return an array of selectors in this container
+     */
+    public function getSelectors(Project $p) {
+        if ($this->isReference()) {
+            return $this->getRef($p)->getSelectors($p);            
+        } else {
+            // *copy* selectors
+            $result = array();
+            for($i=0,$size=count($this->selectors); $i < $size; $i++) {
+                $result[] = clone $this->selectors[$i];
+            }
+            return $result;
+        }
+    }
+
+    /**
+     * Returns an array for accessing the set of selectors.
+     *
+     * @return array The array of selectors
+     */
+    public function selectorElements() {
+        if ($this->isReference() && $this->getProject() !== null) {
+            return $this->getRef($this->getProject())->selectorElements();            
+        }
+        return $this->selectors;
+    }
+
+    /**
+     * Add a new selector into this container.
+     *
+     * @param selector the new selector to add
+     */
+    public function appendSelector(FileSelector $selector) {
+        if ($this->isReference()) {
+            throw $this->noChildrenAllowed();
+        }
+        $this->selectors[] = $selector;
+    }    
+
+    /* Methods below all add specific selectors */
+
+    /**
+     * add a "Select" selector entry on the selector list
+     */
+    public function createSelector() {
+        $o = new SelectSelector();
+        $this->appendSelector($o);
+        return $o;
+    }
+
+    /**
+     * add an "And" selector entry on the selector list
+     */
+    public function createAnd() {
+        $o = new AndSelector();
+        $this->appendSelector($o);
+        return $o;
+    }
+
+    /**
+     * add an "Or" selector entry on the selector list
+     */
+    public function createOr() {
+        $o = new OrSelector();
+        $this->appendSelector($o);
+        return $o;
+    }
+
+    /**
+     * add a "Not" selector entry on the selector list
+     */
+    public function createNot() {
+        $o = new NotSelector();
+        $this->appendSelector($o);
+        return $o;
+    }
+
+    /**
+     * add a "None" selector entry on the selector list
+     */
+    public function createNone() {
+        $o = new NoneSelector();
+        $this->appendSelector($o);
+        return $o;
+    }
+
+    /**
+     * add a majority selector entry on the selector list
+     */
+    public function createMajority() {
+        $o = new MajoritySelector();
+        $this->appendSelector($o);
+        return $o;
+    }
+
+    /**
+     * add a selector date entry on the selector list
+     */
+    public function createDate() {
+        $o = new DateSelector();
+        $this->appendSelector($o);
+        return $o;
+    }
+
+    /**
+     * add a selector size entry on the selector list
+     */
+    public function createSize() {
+        $o = new SizeSelector();
+        $this->appendSelector($o);
+        return $o;
+    }
+
+    /**
+     * add a selector filename entry on the selector list
+     */
+    public function createFilename() {
+        $o = new FilenameSelector();
+        $this->appendSelector($o);
+        return $o;
+    }
+
+    /**
+     * add an extended selector entry on the selector list
+     */
+    public function createCustom() {
+        $o = new ExtendSelector();
+        $this->appendSelector($o);
+        return $o;
+    }
+
+    /**
+     * add a contains selector entry on the selector list
+     */
+    public function createContains() {
+        $o = new ContainsSelector();
+        $this->appendSelector($o);
+        return $o;
+    }
+
+    /**
+     * add a contains selector entry on the selector list
+     */
+    public function createContainsRegexp() {
+        $o = new ContainsRegexpSelector();
+        $this->appendSelector($o);
+        return $o;
+    }
+
+    /**
+     * add a present selector entry on the selector list
+     */
+    public function createPresent() {
+        $o = new PresentSelector();
+        $this->appendSelector($o);
+        return $o;
+    }
+
+    /**
+     * add a depth selector entry on the selector list
+     */
+    public function createDepth() {
+        $o = new DepthSelector();
+        $this->appendSelector($o);
+        return $o;
+    }
+
+    /**
+     * add a depends selector entry on the selector list
+     */
+    public function createDepend() {        
+        $o = new DependSelector();
+        $this->appendSelector($o);
+        return $o;
+    }
+    
+    /**
+     * add a type selector entry on the selector list
+     */
+    public function createType() {
+        $o = new TypeSelector();
+        $this->appendSelector($o);
+        return $o;
+    }
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/types/Commandline.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/types/Commandline.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/types/Commandline.php	(revision 19)
@@ -0,0 +1,467 @@
+<?php
+/*
+ *  $Id: Commandline.php 227 2007-08-28 02:17:00Z hans $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+ 
+
+/**
+ * Commandline objects help handling command lines specifying processes to
+ * execute.
+ *
+ * The class can be used to define a command line as nested elements or as a
+ * helper to define a command line by an application.
+ * <p>
+ * <code>
+ * &lt;someelement&gt;<br>
+ * &nbsp;&nbsp;&lt;acommandline executable="/executable/to/run"&gt;<br>
+ * &nbsp;&nbsp;&nbsp;&nbsp;&lt;argument value="argument 1" /&gt;<br>
+ * &nbsp;&nbsp;&nbsp;&nbsp;&lt;argument line="argument_1 argument_2 argument_3" /&gt;<br>
+ * &nbsp;&nbsp;&nbsp;&nbsp;&lt;argument value="argument 4" /&gt;<br>
+ * &nbsp;&nbsp;&lt;/acommandline&gt;<br>
+ * &lt;/someelement&gt;<br>
+ * </code>
+ * The element <code>someelement</code> must provide a method
+ * <code>createAcommandline</code> which returns an instance of this class.
+ *
+ * @author thomas.haas@softwired-inc.com
+ * @author <a href="mailto:stefan.bodewig@epost.de">Stefan Bodewig</a>
+ */
+class Commandline {
+
+    /**
+     * @var array CommandlineArguments[]
+     */
+    public $arguments = array(); // public so "inner" class can access
+    
+    /**
+     * Full path (if not on %PATH% env var) to executable program.
+     * @var string
+     */
+    public $executable; // public so "inner" class can access
+
+    const DISCLAIMER = "The ' characters around the executable and arguments are not part of the command.";
+
+    public function __construct($to_process = null) {
+        if ($to_process !== null) {                 
+            $tmp = $this->translateCommandline($to_process);
+            if ($tmp) {
+                $this->setExecutable(array_shift($tmp)); // removes first el
+                foreach($tmp as $arg) { // iterate through remaining elements
+                    $this->createArgument()->setValue($arg);
+                }
+            }
+        }    
+    }
+
+
+    /**
+     * Creates an argument object and adds it to our list of args.
+     *
+     * <p>Each commandline object has at most one instance of the
+     * argument class.</p>
+     *
+     * @param boolean $insertAtStart if true, the argument is inserted at the
+     * beginning of the list of args, otherwise it is appended.
+     * @return CommandlineArgument
+     */
+    public function createArgument($insertAtStart = false) {
+        $argument = new CommandlineArgument($this);
+        if ($insertAtStart) {
+            array_unshift($this->arguments, $argument);
+        } else {
+            array_push($this->arguments, $argument);
+        }
+        return $argument;
+    }
+
+    /**
+     * Sets the executable to run.
+     */
+    public function setExecutable($executable) {
+        if (!$executable) {
+            return;
+        }
+        $this->executable = $executable;
+        $this->executable = strtr($this->executable, '/', DIRECTORY_SEPARATOR);
+        $this->executable = strtr($this->executable, '\\', DIRECTORY_SEPARATOR);
+    }
+
+    public function getExecutable() {
+        return $this->executable;
+    }
+
+    public function addArguments($line) {
+        foreach($line as $arg) {
+            $this->createArgument()->setValue($arg);
+        }
+    }
+
+    /**
+     * Returns the executable and all defined arguments.
+     * @return array
+     */
+    public function getCommandline() {
+        $args = $this->getArguments();
+        if ($this->executable === null) {
+            return $args;
+        }
+        return array_merge(array($this->executable), $args);
+    }
+
+
+    /**
+     * Returns all arguments defined by <code>addLine</code>,
+     * <code>addValue</code> or the argument object.
+     */
+    public function getArguments() {
+        $result = array();
+        foreach($this->arguments as $arg) {
+            $parts = $arg->getParts();
+            if ($parts !== null) {                           
+                foreach($parts as $part) {
+                    $result[] = $part;
+                }
+            }
+        }
+        return $result;
+    }
+
+    public function __toString() {
+        return self::toString($this->getCommandline());
+    }
+
+    /**
+     * Put quotes around the given String if necessary.
+     *
+     * <p>If the argument doesn't include spaces or quotes, return it
+     * as is. If it contains double quotes, use single quotes - else
+     * surround the argument by double quotes.</p>
+     *
+     * @exception BuildException if the argument contains both, single
+     *                           and double quotes.
+     */
+    public static function quoteArgument($argument) {
+        if (strpos($argument, "\"") !== false) {
+            if (strpos($argument, "'") !== false) {
+                throw new BuildException("Can't handle single and double quotes in same argument");
+            } else {
+                return escapeshellarg($argument);
+            }
+        } elseif (strpos($argument, "'") !== false || strpos($argument, " ") !== false) {
+            return escapeshellarg($argument);
+            //return '\"' . $argument . '\"';
+        } else {
+            return $argument;
+        }
+    }
+        
+    /**
+     * Quotes the parts of the given array in way that makes them
+     * usable as command line arguments.
+     */
+    public static function toString($lines) {
+        // empty path return empty string
+        if (!$lines) {
+            return "";
+        }
+
+        // path containing one or more elements
+        $result = "";
+        for ($i = 0, $len=count($lines); $i < $len; $i++) {
+            if ($i > 0) {
+                $result .= ' ';
+            }
+            $result .= self::quoteArgument($lines[$i]);
+        }
+        return $result;
+    }
+    
+    /**
+     *
+     * @param string $to_process
+     * @return array
+     */
+    public static function translateCommandline($to_process) {
+        
+        if (!$to_process) {
+            return array();
+        }
+            
+        // parse with a simple finite state machine
+
+        $normal = 0;
+        $inQuote = 1;
+        $inDoubleQuote = 2;
+        
+        $state = $normal;
+        $args = array();
+        $current = "";
+        $lastTokenHasBeenQuoted = false;
+        
+        $tok = strtok($to_process, "");
+        $tokens = preg_split('/(["\' ])/', $to_process, -1, PREG_SPLIT_DELIM_CAPTURE);
+        while(($nextTok = array_shift($tokens)) !== null) {
+            switch ($state) {
+            case $inQuote:
+                if ("'" == $nextTok) {
+                    $lastTokenHasBeenQuoted = true;
+                    $state = $normal;
+                } else {
+                    $current .= $nextTok;
+                }
+                break;
+            case $inDoubleQuote:
+                if ("\"" == $nextTok) {
+                    $lastTokenHasBeenQuoted = true;
+                    $state = $normal;
+                } else {
+                    $current .= $nextTok;
+                }
+                break;
+            default:
+                if ("'" == $nextTok) {
+                    $state = $inQuote;
+                } elseif ("\"" == $nextTok) {
+                    $state = $inDoubleQuote;
+                } elseif (" " == $nextTok) {
+                    if ($lastTokenHasBeenQuoted || strlen($current) != 0) {
+                        $args[] = $current;
+                        $current = "";
+                    }
+                } else {
+                    $current .= $nextTok;
+                }
+                $lastTokenHasBeenQuoted = false;
+                break;
+            }
+        }
+
+        if ($lastTokenHasBeenQuoted || strlen($current) != 0) {
+            $args[] = $current;
+        }
+
+        if ($state == $inQuote || $state == $inDoubleQuote) {
+            throw new BuildException("unbalanced quotes in " . $to_process);
+        }
+
+        return $args;
+    }
+
+    /**
+     * @return int Number of components in current commandline.
+     */
+    public function size() {
+        return count($this->getCommandline());
+    }
+
+    public function __copy() {
+        $c = new Commandline();
+        $c->setExecutable($this->executable);
+        $c->addArguments($this->getArguments());
+        return $c;
+    }
+
+    /**
+     * Clear out the whole command line.  */
+    public function clear() {
+        $this->executable = null;
+        $this->arguments->removeAllElements();
+    }
+
+    /**
+     * Clear out the arguments but leave the executable in place for
+     * another operation.
+     */
+    public function clearArgs() {
+        $this->arguments = array();
+    }
+
+    /**
+     * Return a marker.
+     *
+     * <p>This marker can be used to locate a position on the
+     * commandline - to insert something for example - when all
+     * parameters have been set.</p>
+     * @return CommandlineMarker
+     */
+    public function createMarker() {
+        return new CommandlineMarker($this, count($this->arguments));
+    }
+
+    /**
+     * Returns a String that describes the command and arguments
+     * suitable for verbose output before a call to
+     * <code>Runtime.exec(String[])<code>.
+     *
+     * <p>This method assumes that the first entry in the array is the
+     * executable to run.</p>
+     * @param array $args CommandlineArgument[] to use
+     * @return string
+     */
+    public function describeCommand($args = null) {
+       
+        if ($args === null) {
+            $args = $this->getCommandline();
+        }
+           
+        if (!$args) {
+            return "";
+        }
+        
+        $buf = "Executing '";
+        $buf .= $args[0];
+        $buf .= "'";
+        if (count($args) > 0) {
+            $buf .= " with ";
+            $buf .= $this->describeArguments($args, 1);
+        } else {
+            $buf .= self::DISCLAIMER;
+        }
+        return $buf;
+    }
+
+    /**
+     * Returns a String that describes the arguments suitable for
+     * verbose output before a call to
+     * <code>Runtime.exec(String[])<code>
+     * @param $args arguments to use (default is to use current class args)
+     * @param $offset ignore entries before this index
+     * @return string
+     */
+    protected function describeArguments($args = null, $offset = 0) {
+        if ($args === null) {
+            $args = $this->getArguments();
+        }                
+        
+        if ($args === null || count($args) <= $offset) {
+            return "";
+        }
+        
+        $buf = "argument";
+        if (count($args) > $offset) {
+            $buf .= "s";
+        }
+        $buf .= ":" . PHP_EOL;
+        for ($i = $offset, $alen=count($args); $i < $alen; $i++) {
+            $buf .= "'" . $args[$i] . "'" . PHP_EOL;
+        }
+        $buf .= self::DISCLAIMER;
+        return $buf;
+    }
+}
+
+
+/**
+ * "Inner" class used for nested xml command line definitions.
+ */
+class CommandlineArgument {
+
+    private $parts = array();
+    private $outer;
+    
+    public function __construct(Commandline $outer) {
+        $this->outer = $outer;
+    }
+    
+    /**
+     * Sets a single commandline argument.
+     *
+     * @param string $value a single commandline argument.
+     */
+    public function setValue($value) {
+        $this->parts = array($value);
+    }
+
+    /**
+     * Line to split into several commandline arguments.
+     *
+     * @param line line to split into several commandline arguments
+     */
+    public function setLine($line) {
+        if ($line === null) {
+            return;
+        }
+        $this->parts = $this->outer->translateCommandline($line);
+    }
+
+    /**
+     * Sets a single commandline argument and treats it like a
+     * PATH - ensures the right separator for the local platform
+     * is used.
+     *
+     * @param value a single commandline argument.
+     */
+    public function setPath($value) {
+        $this->parts = array( (string) $value );
+    }
+
+    /**
+     * Sets a single commandline argument to the absolute filename
+     * of the given file.
+     *
+     * @param value a single commandline argument.
+     */
+    public function setFile(PhingFile $value) {
+        $this->parts = array($value->getAbsolutePath());
+    }
+
+    /**
+     * Returns the parts this Argument consists of.
+     * @return array string[]
+     */
+    public function getParts() {
+        return $this->parts;
+    }
+}
+
+/**
+ * Class to keep track of the position of an Argument.
+ */
+// <p>This class is there to support the srcfile and targetfile
+// elements of &lt;execon&gt; and &lt;transform&gt; - don't know
+// whether there might be additional use cases.</p> --SB
+class CommandlineMarker {
+
+    private $position;
+    private $realPos = -1;
+    private $outer;
+    
+    public function __construct(Comandline $outer, $position) {
+        $this->outer = $outer;
+        $this->position = $position;
+    }
+
+    /**
+     * Return the number of arguments that preceeded this marker.
+     *
+     * <p>The name of the executable - if set - is counted as the
+     * very first argument.</p>
+     */
+    public function getPosition() {
+        if ($this->realPos == -1) {
+            $realPos = ($this->outer->executable === null ? 0 : 1);
+            for ($i = 0; $i < $position; $i++) {
+                $arg = $this->arguments[$i];
+                $realPos += count($arg->getParts());
+            }
+        }
+        return $this->realPos;
+    }
+}
+
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/types/DataType.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/types/DataType.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/types/DataType.php	(revision 19)
@@ -0,0 +1,182 @@
+<?php
+/*
+ *  $Id: DataType.php 123 2006-09-14 20:19:08Z mrook $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>. 
+ */
+
+require_once 'phing/ProjectComponent.php';
+include_once 'phing/BuildException.php';
+
+/**
+ * Base class for those classes that can appear inside the build file
+ * as stand alone data types.
+ *
+ * This class handles the common description attribute and provides
+ * a default implementation for reference handling and checking for
+ * circular references that is appropriate for types that can not be
+ * nested inside elements of the same type (i.e. patternset but not path)
+ *
+ * @package   phing.types
+ */
+class DataType extends ProjectComponent {
+
+    /** The descriptin the user has set. */
+    public $description = null;
+
+    /** Value to the refid attribute. Type of Reference*/
+    public $ref = null;
+
+    /**
+     * Are we sure we don't hold circular references?
+     *
+     * Subclasses are responsible for setting this value to false
+     * if we'd need to investigate this condition (usually because a
+     * child element has been added that is a subclass of DataType).
+     * @var boolean
+     */
+    protected $checked = true;
+  
+    /**
+     * Sets a description of the current data type. It will be useful
+     * in commenting what we are doing.
+     */
+    function setDescription($desc) {
+        $this->description = (string) $desc;
+    }
+
+    /** Return the description for the current data type. */
+    function getDescription() {
+        return $this->description;
+    }
+
+    /** Has the refid attribute of this element been set? */
+    function isReference() {
+        return ($this->ref !== null);
+    }
+
+    /**
+     * Set the value of the refid attribute.
+     *
+     * Subclasses may need to check whether any other attributes
+     * have been set as well or child elements have been created and
+     * thus override this method. if they do they must call parent::setRefid()
+	 * 
+	 * @param Reference $r
+	 * @return void
+     */
+    function setRefid(Reference $r) {
+        $this->ref = $r;
+        $this->checked = false;
+    }
+
+    /**
+     * Check to see whether any DataType we hold references to is
+     * included in the Stack (which holds all DataType instances that
+     * directly or indirectly reference this instance, including this
+     * instance itself).
+     *
+     * If one is included, throw a BuildException created by circularReference
+     *
+     * This implementation is appropriate only for a DataType that
+     * cannot hold other DataTypes as children.
+     *
+     * The general contract of this method is that it shouldn't do
+     * anything if checked is true and set it to true on exit.
+     */
+    function dieOnCircularReference(&$stk, Project $p) {
+        if ($this->checked || !$this->isReference()) {
+            return;
+        }
+
+        $o = $this->ref->getReferencedObject($p);
+
+        if ($o instanceof DataType) {
+            
+            // TESTME - make sure that in_array() works just as well here
+            //
+            // check if reference is in stack
+            //$contains = false;
+            //for ($i=0, $size=count($stk); $i < $size; $i++) {
+            //    if ($stk[$i] === $o) {
+            //        $contains = true;
+            //        break;
+            //    }
+            //}
+
+            if (in_array($o, $stk, true)) {
+                // throw build exception
+                throw $this->circularReference();
+            } else {
+                array_push($stk, $o);
+                $o->dieOnCircularReference($stk, $p);
+                array_pop($stk);
+            }
+        }
+        $this->checked = true;
+    }
+
+    /** Performs the check for circular references and returns the referenced object. */
+    function getCheckedRef($requiredClass, $dataTypeName) {
+    
+        if (!$this->checked) {
+            // should be in stack
+            $stk = array();
+            $stk[] = $this;
+            $this->dieOnCircularReference($stk, $this->getProject());            
+        }
+
+        $o = $this->ref->getReferencedObject($this->getProject());
+        if (!($o instanceof $requiredClass) ) {
+            throw new BuildException($this->ref->getRefId()." doesn't denote a " . $dataTypeName);
+        } else {
+            return $o;
+        }
+    }
+
+    /**
+     * Creates an exception that indicates that refid has to be the
+     * only attribute if it is set.
+     */
+    function tooManyAttributes() {
+        return new BuildException( "You must not specify more than one attribute when using refid" );
+    }
+
+    /**
+     * Creates an exception that indicates that this XML element must
+     * not have child elements if the refid attribute is set.
+     */
+    function noChildrenAllowed() {
+        return new BuildException("You must not specify nested elements when using refid");
+    }
+
+    /**
+     * Creates an exception that indicates the user has generated a
+     * loop of data types referencing each other.
+     */
+    function circularReference() {
+        return new BuildException("This data type contains a circular reference.");
+    }
+    
+    /**
+     * Template method being called when the data type has been 
+     * parsed completely.
+     * @return void
+     */
+    function parsingComplete() {}
+}
+
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/types/Description.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/types/Description.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/types/Description.php	(revision 19)
@@ -0,0 +1,53 @@
+<?php
+
+/*
+ *  $Id: Description.php 123 2006-09-14 20:19:08Z mrook $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+/**
+ * Description is used to provide a project-wide description element
+ * (that is, a description that applies to a buildfile as a whole).
+ * If present, the &lt;description&gt; element is printed out before the
+ * target descriptions.
+ * 
+ * Description has no attributes, only text.  There can only be one
+ * project description per project.  A second description element will
+ * overwrite the first.
+ *
+ * @author Hans Lellelid <hans@xmpl.org> (Phing)
+ * @author Craeg Strong <cstrong@arielpartners.com> (Ant)
+ * @package phing.types
+ */
+class Description extends DataType {
+
+    /**
+     * Adds descriptive text to the project.
+     *
+     * @return void
+     */
+    public function addText($text) {
+        $currentDescription = $this->project->getDescription();
+        if ($currentDescription === null) {
+            $this->project->setDescription($text);
+        } else {
+            $this->project->setDescription($currentDescription . $text);
+        }
+    }
+    
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/types/DirSet.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/types/DirSet.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/types/DirSet.php	(revision 19)
@@ -0,0 +1,49 @@
+<?php
+
+/*
+ * $Id: DirSet.php 123 2006-09-14 20:19:08Z mrook $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+ 
+include_once 'phing/types/AbstractFileSet.php';
+
+/**
+ * Subclass as hint for supporting tasks that the included directories
+ * instead of files should be used.
+ *
+ * @package phing.types
+ */
+class DirSet extends AbstractFileSet {
+    
+    public function __construct($dirset = null) {
+        parent::__construct($dirset);
+    }    
+
+    /**
+     * Return a DirSet that has the same basedir and same patternsets
+     * as this one.
+     */
+    public function __clone() {
+        if ($this->isReference()) {
+            return new DirSet($this->getRef($this->getProject()));
+        } else {
+            return new DirSet($this);
+        }
+    }
+
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/types/FileList.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/types/FileList.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/types/FileList.php	(revision 19)
@@ -0,0 +1,224 @@
+<?php
+/*
+ *  $Id: FileList.php 209 2007-08-01 22:42:00Z hans $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>. 
+ */
+
+require_once 'phing/types/DataType.php';
+include_once 'phing/system/io/PhingFile.php';
+
+/**
+ * FileList represents an explicitly named list of files. FileLists
+ * are useful when you want to capture a list of files regardless of
+ * whether they currently exist.
+ *
+ * <filelist 
+ *    id="docfiles" 
+ *   dir="${phing.docs.dir}"
+ *   files="chapters/Installation.html,chapters/Setup.html"/> 
+ *
+ * OR 
+ * 
+ * <filelist
+ *         dir="${doc.src.dir}"
+ *         listfile="${phing.docs.dir}/PhingGuide.book"/>
+ * 
+ * (or a mixture of files="" and listfile="" can be used)
+ * 
+ * @author Hans Lellelid <hans@xmpl.org>
+ * @version $Revision: 1.10 $
+ * @package phing.types
+ */
+class FileList extends DataType {
+        
+    // public for "cloning" purposes
+    
+    /** Array containing all filenames. */
+    public $filenames = array();
+    
+    /** Base directory for this file list. */
+    public $dir;
+    
+    /** PhingFile that contains a list of files (one per line). */
+    public $listfile;
+    
+    /**
+     * Construct a new FileList.
+     * @param array $filelist;
+     */
+    function __construct($filelist = null) {
+        if ($filelist !== null) {
+            $this->dir       = $filelist->dir;
+            $this->filenames = $filelist->filenames;
+            $this->listfile = $filelist->listfile;
+        }
+    }
+
+    /**
+     * Makes this instance in effect a reference to another FileList
+     * instance.
+     */
+    function setRefid(Reference $r) {
+        if ($this->dir !== null || count($this->filenames) !== 0) {
+            throw $this->tooManyAttributes();
+        }
+        parent::setRefid($r);
+    }
+
+    /**
+     * Base directory for files in list.
+     * @param PhingFile $dir
+     */
+    function setDir(PhingFile $dir) {
+        if ($this->isReference()) {
+            throw $this->tooManyAttributes();
+        }
+        if (!($dir instanceof PhingFile)) {
+            $dir = new PhingFile($dir);
+        }
+        $this->dir = $dir;
+    }
+    
+    /**
+     * Get the basedir for files in list.
+     * @return PhingFile
+     */
+    function getDir(Project $p) {
+        if ($this->isReference()) {
+            $ref = $this->getRef($p);
+            return $ref->getDir($p);
+        }
+        return $this->dir;
+    }
+    
+    /**
+     * Set the array of files in list.
+     * @param array $filenames
+     */
+    function setFiles($filenames) {
+        if ($this->isReference()) {
+            throw $this->tooManyAttributes();
+        }
+        if (!empty($filenames)) {
+            $tok = strtok($filenames, ", \t\n\r");            
+            while ($tok !== false) {
+                $fname = trim($tok);
+                if ($fname !== "") {
+                    $this->filenames[] = $tok;
+                }
+                $tok = strtok(", \t\n\r");
+            }
+        }
+    }
+    
+    /**
+     * Sets a source "list" file that contains filenames to add -- one per line.
+     * @param string $file
+     */
+    function setListFile($file) {
+        if ($this->isReference()) {
+            throw $this->tooManyAttributes();
+        }
+        if (!($file instanceof PhingFile)) {
+            $file = new PhingFile($file);
+        }
+        $this->listfile = $file;
+    }
+    
+    /**
+     * Get the source "list" file that contains file names.
+     * @param Project $p
+     * @return PhingFile
+     */
+    function getListFile(Project $p) {
+        if ($this->isReference()) {
+            $ref = $this->getRef($p);
+            return $ref->getListFile($p);
+        }
+        return $this->listfile;
+    }
+
+    /**
+     * Returns the list of files represented by this FileList.
+     * @param Project $p
+     * @return array
+     */
+    function getFiles(Project $p) {
+    
+        if ($this->isReference()) {
+            $ret = $this->getRef($p);
+            $ret = $ret->getFiles($p);
+            return $ret;
+        }
+        
+        if ($this->listfile !== null) {
+            $this->readListFile($p);
+        }
+        
+        return $this->filenames;
+    }
+
+
+    /**
+      * Performs the check for circular references and returns the
+      * referenced FileSet.
+      * @param Project $p
+      */
+    function getRef(Project $p) {
+        if (!$this->checked) {
+            $stk = array();
+            array_push($stk, $this);
+            $this->dieOnCircularReference($stk, $p);            
+        }
+
+        $o = $this->ref->getReferencedObject($p);
+        if (!($o instanceof FileList)) {
+            throw new BuildException($this->ref->getRefId()." doesn't denote a filelist");
+        } else {
+            return $o;
+        }
+    }
+
+    /**
+     * Reads file names from a file and adds them to the files array.
+     * @param Project $p
+     */
+    private function readListFile(Project $p) {
+        $listReader = null;
+        try {
+            // Get a FileReader
+            $listReader = new BufferedReader(new FileReader($this->listfile)); 
+        
+            $line = $listReader->readLine();
+            while ($line !== null) {
+                if (!empty($line)) {
+                    $line = $p->replaceProperties($line);
+                    $this->filenames[] = trim($line);
+                }
+                $line = $listReader->readLine();
+            }            
+        } catch (Exception $e)  {
+            if ($listReader) $listReader->close();            
+            throw new BuildException("An error occured while reading from list file " . $this->listfile->__toString() . ": " . $e->getMessage()); 
+        } 
+        
+        $listReader->close();        
+    }
+
+}
+
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/types/FileSet.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/types/FileSet.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/types/FileSet.php	(revision 19)
@@ -0,0 +1,56 @@
+<?php
+
+/*
+ * $Id: FileSet.php 123 2006-09-14 20:19:08Z mrook $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+require_once 'phing/types/AbstractFileSet.php';
+
+/**
+ * Moved out of MatchingTask to make it a standalone object that could
+ * be referenced (by scripts for example).
+ *
+ * @author Hans Lellelid <hans@xmpl.org> (Phing)
+ * @author Arnout J. Kuiper <ajkuiper@wxs.nl> (Ant)
+ * @author Stefano Mazzocchi <stefano@apache.org> (Ant)
+ * @author Sam Ruby <rubys@us.ibm.com> (Ant)
+ * @author Jon S. Stevens <jon@clearink.com> (Ant)
+ * @author Stefan Bodewig <stefan.bodewig@epost.de> (Ant)
+ * @author Magesh Umasankar (Ant)
+ * @package phing.types
+ */
+class FileSet extends AbstractFileSet {
+    
+    function __construct($fileset = null) {
+        parent::__construct($fileset);
+    }
+
+    /**
+     * Return a FileSet that has the same basedir and same patternsets
+     * as this one.
+     */
+    public function __clone() {
+        if ($this->isReference()) {
+            return new FileSet($this->getRef($this->getProject()));
+        } else {
+            return new FileSet($this);
+        }
+    }
+
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/types/FilterChain.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/types/FilterChain.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/types/FilterChain.php	(revision 19)
@@ -0,0 +1,176 @@
+<?php
+/*
+ *  $Id: FilterChain.php 247 2007-10-16 21:09:37Z hans $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+include_once 'phing/types/DataType.php';
+include_once 'phing/filters/HeadFilter.php';
+include_once 'phing/filters/TailFilter.php';
+include_once 'phing/filters/LineContains.php';
+include_once 'phing/filters/LineContainsRegexp.php';
+include_once 'phing/filters/ExpandProperties.php';
+include_once 'phing/filters/PrefixLines.php';
+include_once 'phing/filters/ReplaceRegexp.php';
+include_once 'phing/filters/ReplaceTokens.php';
+include_once 'phing/filters/StripPhpComments.php';
+include_once 'phing/filters/StripLineBreaks.php';
+include_once 'phing/filters/StripLineComments.php';
+include_once 'phing/filters/StripWhitespace.php';
+include_once 'phing/filters/TabToSpaces.php';
+include_once 'phing/filters/TidyFilter.php';
+include_once 'phing/filters/TranslateGettext.php';
+include_once 'phing/filters/XincludeFilter.php';
+include_once 'phing/filters/XsltFilter.php';
+
+/*
+ * FilterChain may contain a chained set of filter readers.
+ *
+ * @author    Yannick Lecaillez <yl@seasonfive.com>
+ * @version   $Revision: 1.11 $
+ * @package   phing.types
+ */
+class FilterChain extends DataType {
+
+    private $filterReaders = array();
+
+    function __construct(Project $project) {
+        $this->project = $project;
+    }
+
+    function getFilterReaders() {
+        return $this->filterReaders;
+    }
+
+    function addExpandProperties(ExpandProperties $o) {
+        $o->setProject($this->project);
+        $this->filterReaders[] = $o;
+    }
+
+    function addGettext(TranslateGettext $o) {
+        $o->setProject($this->project);
+        $this->filterReaders[] = $o;
+    }
+    
+    function addHeadFilter(HeadFilter $o) {
+        $o->setProject($this->project);
+        $this->filterReaders[] = $o;
+    }
+    
+    function addTailFilter(TailFilter $o) {
+        $o->setProject($this->project);
+        $this->filterReaders[] = $o;
+    }
+    
+    function addLineContains(LineContains $o) {
+        $o->setProject($this->project);
+        $this->filterReaders[] = $o;
+    }
+    
+    function addLineContainsRegExp(LineContainsRegExp $o) {
+        $o->setProject($this->project);
+        $this->filterReaders[] = $o;
+    }
+    
+    function addPrefixLines(PrefixLines $o) {
+        $o->setProject($this->project);
+        $this->filterReaders[] = $o;
+    }
+    
+    function addReplaceTokens(ReplaceTokens $o) {
+        $o->setProject($this->project);
+        $this->filterReaders[] = $o;
+    }
+
+    function addReplaceRegexp(ReplaceRegexp $o) {
+        $o->setProject($this->project);
+        $this->filterReaders[] = $o;
+    }
+    
+    function addStripPhpComments(StripPhpComments $o) {
+        $o->setProject($this->project);
+        $this->filterReaders[] = $o;
+    }
+    
+    function addStripLineBreaks(StripLineBreaks $o) {
+        $o->setProject($this->project);
+        $this->filterReaders[] = $o;
+    }
+    
+    function addStripLineComments(StripLineComments $o) {
+        $o->setProject($this->project);
+        $this->filterReaders[] = $o;        
+    }
+    
+	function addStripWhitespace(StripWhitespace $o) {
+        $o->setProject($this->project);
+        $this->filterReaders[] = $o;
+    }
+    
+	function addTidyFilter(TidyFilter $o) {
+        $o->setProject($this->project);
+        $this->filterReaders[] = $o;
+    }
+	
+    function addTabToSpaces(TabToSpaces $o) {
+        $o->setProject($this->project);
+        $this->filterReaders[] = $o;
+    }
+    
+    function addXincludeFilter(XincludeFilter $o) {
+        $o->setProject($this->project);
+        $this->filterReaders[] = $o;
+    }
+
+    function addXsltFilter(XsltFilter $o) {
+        $o->setProject($this->project);
+        $this->filterReaders[] = $o;
+    }
+    
+    function addFilterReader(PhingFilterReader $o) {
+        $o->setProject($this->project);
+        $this->filterReaders[] = $o;
+    }
+
+    /*
+     * Makes this instance in effect a reference to another FilterChain 
+     * instance.
+     *
+     * <p>You must not set another attribute or nest elements inside
+     * this element if you make it a reference.</p>
+     *
+     * @param r the reference to which this instance is associated
+     * @throw BuildException if this instance already has been configured.
+    */
+    function setRefid(Reference $r) {
+    
+        if ( count($this->filterReaders) === 0 ) {
+            throw $this->tooManyAttributes();
+        }
+
+        // change this to get the objects from the other reference
+        $o = $r->getReferencedObject($this->getProject());
+        if ( $o instanceof FilterChain ) {
+            $this->filterReaders = $o->getFilterReaders();
+        } else {
+            throw new BuildException($r->getRefId()." doesn't refer to a FilterChain");
+        }
+        parent::setRefid($r);
+    }
+    
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/types/Mapper.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/types/Mapper.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/types/Mapper.php	(revision 19)
@@ -0,0 +1,207 @@
+<?php
+/*
+ *  $Id: Mapper.php 325 2007-12-20 15:44:58Z hans $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>. 
+ */
+
+include_once 'phing/types/DataType.php';
+include_once 'phing/types/Path.php';
+
+/**
+ * Filename Mapper maps source file name(s) to target file name(s).
+ * 
+ * Built-in mappers can be accessed by specifying they "type" attribute:
+ * <code>
+ * <mapper type="glob" from="*.php" to="*.php.bak"/>
+ * </code>
+ * Custom mappers can be specified by providing a dot-path to a include_path-relative
+ * class:
+ * <code>
+ * <mapper classname="myapp.mappers.DevToProdMapper" from="*.php" to="*.php"/>
+ * <!-- maps all PHP files from development server to production server, for example -->
+ * </code>
+ *
+ * @author Hans Lellelid <hans@xmpl.org>
+ * @package phing.types
+ */
+class Mapper extends DataType {
+
+    protected $type;    
+    protected $classname;
+    protected $from;
+    protected $to;
+    protected $classpath;
+    protected $classpathId;
+
+    
+    function __construct(Project $project) {
+        $this->project = $project;
+    }
+    
+    /**
+     * Set the classpath to be used when searching for component being defined
+     * 
+     * @param Path $classpath An Path object containing the classpath.
+     */
+    public function setClasspath(Path $classpath) {
+        if ($this->isReference()) {
+            throw $this->tooManyAttributes();
+        }
+        if ($this->classpath === null) {
+            $this->classpath = $classpath;
+        } else {
+            $this->classpath->append($classpath);
+        }
+    }
+
+    /**
+     * Create the classpath to be used when searching for component being defined
+     */ 
+    public function createClasspath() {
+        if ($this->isReference()) {
+            throw $this->tooManyAttributes();
+        }
+        if ($this->classpath === null) {
+            $this->classpath = new Path($this->project);
+        }
+        return $this->classpath->createPath();
+    }
+
+    /**
+     * Reference to a classpath to use when loading the files.
+     */
+    public function setClasspathRef(Reference $r) {
+        if ($this->isReference()) {
+            throw $this->tooManyAttributes();
+        }
+        $this->classpathId = $r->getRefId();
+        $this->createClasspath()->setRefid($r);
+    }
+
+    /** Set the type of FileNameMapper to use. */
+    function setType($type) {
+        if ($this->isReference()) {
+            throw $this->tooManyAttributes();
+        }
+        $this->type = $type;
+    }
+
+    /** Set the class name of the FileNameMapper to use. */
+    function setClassname($classname) {
+        if ($this->isReference()) {
+            throw $this->tooManyAttributes();
+        }
+        $this->classname = $classname;
+    }
+
+    /**
+     * Set the argument to FileNameMapper.setFrom
+     */
+    function setFrom($from) {
+        if ($this->isReference()) {
+            throw $this->tooManyAttributes();
+        }
+        $this->from = $from;
+    }
+
+    /**
+     * Set the argument to FileNameMapper.setTo
+     */
+    function setTo($to) {
+        if ($this->isReference()) {
+            throw $this->tooManyAttributes();
+        }
+        $this->to = $to;
+    }
+
+    /**
+     * Make this Mapper instance a reference to another Mapper.
+     *
+     * You must not set any other attribute if you make it a reference.
+     */
+    function setRefid($r) {
+        if ($this->type !== null || $this->from !== null || $this->to !== null) {
+            throw DataType::tooManyAttributes();
+        }
+        parent::setRefid($r);
+    }
+
+    /** Factory, returns inmplementation of file name mapper as new instance */
+    function getImplementation() {
+        if ($this->isReference()) {
+            $tmp = $this->getRef();
+            return $tmp->getImplementation();
+        }
+
+        if ($this->type === null && $this->classname === null) {
+            throw new BuildException("either type or classname attribute must be set for <mapper>");
+        }
+        
+        if ($this->type !== null) {
+            switch($this->type) {
+            case 'identity':
+                $this->classname = 'phing.mappers.IdentityMapper';
+                break;
+            case 'flatten':
+                $this->classname = 'phing.mappers.FlattenMapper';
+                break;
+            case 'glob':
+                $this->classname = 'phing.mappers.GlobMapper';
+                break;
+            case 'regexp':
+            case 'regex':
+                $this->classname = 'phing.mappers.RegexpMapper';            
+                break;
+            case 'merge':
+                $this->classname = 'phing.mappers.MergeMapper';                
+                break;
+            default:
+                throw new BuildException("Mapper type {$this->type} not known");
+                break;
+            }
+        }
+
+        // get the implementing class
+        $cls = Phing::import($this->classname, $this->classpath);
+        
+        $m = new $cls;
+        $m->setFrom($this->from);
+        $m->setTo($this->to);
+        
+        return $m;
+    }
+
+    /** Performs the check for circular references and returns the referenced Mapper. */
+    private function getRef() {
+        if (!$this->checked) {
+            $stk = array();
+            $stk[] = $this;
+            $this->dieOnCircularReference($stk, $this->project);            
+        }
+
+        $o = $this->ref->getReferencedObject($this->project);
+        if (!($o instanceof Mapper)) {
+            $msg = $this->ref->getRefId()." doesn't denote a mapper";
+            throw new BuildException($msg);
+        } else {
+            return $o;
+        }
+    }
+}
+
+
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/types/Parameter.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/types/Parameter.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/types/Parameter.php	(revision 19)
@@ -0,0 +1,99 @@
+<?php
+/*
+ *  $Id: Parameter.php 325 2007-12-20 15:44:58Z hans $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+*/
+
+include_once 'phing/types/DataType.php';
+
+/*
+ * A parameter is composed of a name, type and value. Nested
+ * Parameters are also possible, but the using task/type has
+ * to support them
+ *
+ * @author    Manuel Holtgrewe
+ * @author    <a href="mailto:yl@seasonfive.com">Yannick Lecaillez</a>
+ * @package   phing.types
+*/
+class Parameter extends DataType {
+
+    /** Parameter name */
+    protected $name;
+    
+    /** Paramter type */
+    protected $type;
+    
+    /** Parameter value */
+    protected $value;
+    
+    /** Nested parameters */
+    protected $parameters = array();
+
+    function setName($name) {
+        $this->name = (string) $name;
+    }
+    
+    function setType($type) {
+        $this->type = (string) $type;
+    }
+
+	/**
+     * Sets value to dynamic register slot.
+     * @param RegisterSlot $value
+     */
+    public function setListeningValue(RegisterSlot $value) {
+        $this->value = $value;
+    }
+	
+    function setValue($value) {
+        $this->value = (string) $value;
+    }
+
+    function getName() {
+        return $this->name;
+    }
+
+    function getType() {
+        return $this->type;
+    }
+
+    function getValue() {
+		if ($this->value instanceof RegisterSlot) {
+            return $this->value->getValue();
+        } else {
+            return $this->value;
+        }
+    }
+    
+    /**
+     * @return Parameter
+     */
+    function createParam() {
+        $num = array_push($this->parameters, new Parameter());
+        return $this->parameters[$num-1];
+    }
+
+    /**
+     * @return array Nested parameters.
+     */
+    function getParams() {
+        return $this->parameters;
+    }
+}
+
+
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/types/Parameterizable.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/types/Parameterizable.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/types/Parameterizable.php	(revision 19)
@@ -0,0 +1,32 @@
+<?php
+
+/*
+ * $Id: Parameterizable.php 123 2006-09-14 20:19:08Z mrook $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+/**
+ * Parameterizable objects take genric key value pairs.
+ *
+ * @author Hans Lellelid, hans@xmpl.org (Phing)
+ * @author Magesh Umasankar (Ant)
+ * @package phing.types
+ */
+interface Parameterizable {
+    function setParameters($parameters);
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/types/Path.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/types/Path.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/types/Path.php	(revision 19)
@@ -0,0 +1,451 @@
+<?php
+/*
+ *  $Id: Path.php 359 2008-02-26 09:16:23Z mrook $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>. 
+ */
+
+require_once 'phing/types/DataType.php';
+include_once 'phing/util/PathTokenizer.php';
+include_once 'phing/types/FileSet.php';
+
+/**
+ * This object represents a path as used by include_path or PATH
+ * environment variable.
+ *
+ * This class has been adopted from the Java Ant equivalent.  The ability have
+ * path structures in Phing is important; however, because of how PHP classes interact
+ * the ability to specify CLASSPATHs makes less sense than Java.Rather than providing
+ * CLASSPATH for any tasks that take classes as parameters, perhaps a better
+ * solution in PHP is to have an IncludePath task, which prepends paths to PHP's include_path
+ * INI variable. This gets around the problem that simply using a path to load the initial
+ * PHP class is not enough (in most cases the loaded class may assume that it is on the global
+ * PHP include_path, and will try to load dependent classes accordingly).  The other option is
+ * to provide a way for this class to add paths to the include path, if desired -- or to create
+ * an IncludePath subclass.  Once added, though, when would a path be removed from the include path?
+ * 
+ * <p>
+ * <code>
+ * &lt;sometask&gt;<br>
+ * &nbsp;&nbsp;&lt;somepath&gt;<br>
+ * &nbsp;&nbsp;&nbsp;&nbsp;&lt;pathelement location="/path/to/file" /&gt;<br>
+ * &nbsp;&nbsp;&nbsp;&nbsp;&lt;pathelement path="/path/to/class2;/path/to/class3" /&gt;<br>
+ * &nbsp;&nbsp;&nbsp;&nbsp;&lt;pathelement location="/path/to/file3" /&gt;<br>
+ * &nbsp;&nbsp;&lt;/somepath&gt;<br>
+ * &lt;/sometask&gt;<br>
+ * </code>
+ * <p>
+ * The object implemention <code>sometask</code> must provide a method called
+ * <code>createSomepath</code> which returns an instance of <code>Path</code>.
+ * Nested path definitions are handled by the Path object and must be labeled
+ * <code>pathelement</code>.<p>
+ *
+ * The path element takes a parameter <code>path</code> which will be parsed
+ * and split into single elements. It will usually be used
+ * to define a path from an environment variable.
+ *
+ * @author Hans Lellelid <hans@xmpl.org> (Phing)
+ * @author Thomas.Haas@softwired-inc.com (Ant)
+ * @author Stefan Bodewig <stefan.bodewig@epost.de> (Ant)
+ * @package phing.types
+ */
+class Path extends DataType {
+
+    private $elements = array();    
+    
+    /**
+     * Constructor for internally instantiated objects sets project.
+     * @param Project $project
+     * @param string $path (for use by IntrospectionHelper)
+     */
+    public function __construct($project = null, $path = null) {
+        if ($project !== null) {
+            $this->setProject($project);
+        }
+        if ($path !== null) {
+            $this->createPathElement()->setPath($path);
+        }        
+    }
+
+    /**
+     * Adds a element definition to the path.
+     * @param $location the location of the element to add (must not be
+     * <code>null</code> nor empty.
+     * @throws BuildException
+     */
+    public function setDir(PhingFile $location) {
+        if ($this->isReference()) {
+            throw $this->tooManyAttributes();
+        }        
+        $this->createPathElement()->setDir($location);
+    }
+
+    /**
+     * Parses a path definition and creates single PathElements.
+     * @param path the path definition.
+     * @throws BuildException
+     */
+    public function setPath($path) {
+        if ($this->isReference()) {
+            throw $this->tooManyAttributes();
+        }
+        $this->createPathElement()->setPath($path);
+    }
+
+    /**
+     * Makes this instance in effect a reference to another Path instance.
+     *
+     * <p>You must not set another attribute or nest elements inside
+     * this element if you make it a reference.</p>
+     * @throws BuildException
+     */
+    public function setRefid(Reference $r)  {
+        if (!empty($this->elements)) {
+            throw $this->tooManyAttributes();
+        }
+        $this->elements[] = $r;
+        parent::setRefid($r);
+    }
+
+    /**
+     * Creates the nested <code>&lt;pathelement&gt;</code> element.
+     * @throws BuildException 
+     */
+    public function createPathElement() {
+        if ($this->isReference()) {
+            throw $this->noChildrenAllowed();
+        }
+        $pe = new PathElement($this);
+        $this->elements[] = $pe;
+        return $pe;
+    }
+
+    /**
+     * Adds a nested <code>&lt;fileset&gt;</code> element.
+     * @throws BuildException 
+     */
+    public function addFileset(FileSet $fs) {
+        if ($this->isReference()) {
+            throw $this->noChildrenAllowed();
+        }
+        $this->elements[] = $fs;
+        $this->checked = false;
+    }
+
+    /**
+     * Adds a nested <code>&lt;dirset&gt;</code> element.
+     * @throws BuildException 
+     */
+    public function addDirset(DirSet $dset) {
+        if ($this->isReference()) {
+            throw $this->noChildrenAllowed();
+        }
+        $this->elements[] = $dset;
+        $this->checked = false;
+    }
+
+    /**
+     * Creates a nested <code>&lt;path&gt;</code> element.
+     * @throws BuildException
+     */
+    public function createPath() {
+        if ($this->isReference()) {
+            throw $this->noChildrenAllowed();
+        }
+        $p = new Path($this->project);
+        $this->elements[] = $p;
+        $this->checked = false;
+        return $p;
+    }
+
+    /**
+     * Append the contents of the other Path instance to this.
+     */
+    public function append(Path $other) {
+        if ($other === null) {
+            return;
+        }
+        $l = $other->listPaths();
+        foreach($l as $path) {
+            if (!in_array($path, $this->elements, true)) {
+                $this->elements[] = $path;
+            }
+        }
+    }
+
+     /**
+     * Adds the components on the given path which exist to this
+     * Path. Components that don't exist, aren't added.
+     *
+     * @param Path $source - Source path whose components are examined for existence.
+     */
+    public function addExisting(Path $source) {
+        $list = $source->listPaths();
+        foreach($list as $el) {
+            $f = null;
+            if ($this->project !== null) {
+                $f = $this->project->resolveFile($el);
+            } else {
+                $f = new PhingFile($el);
+            }
+
+            if ($f->exists()) {
+                $this->setDir($f);
+            } else {
+                $this->log("dropping " . $f->__toString() . " from path as it doesn't exist", 
+                    Project::MSG_VERBOSE);
+            }
+        }
+    }
+
+    /**
+     * Returns all path elements defined by this and nested path objects.
+     * @return array List of path elements.
+     */
+    public function listPaths() {
+        if (!$this->checked) {
+            // make sure we don't have a circular reference here
+            $stk = array();
+            array_push($stk, $this);
+            $this->dieOnCircularReference($stk, $this->project);
+        }
+
+        $result = array();
+        for ($i = 0, $elSize=count($this->elements); $i < $elSize; $i++) {
+            $o = $this->elements[$i];
+            if ($o instanceof Reference) {
+                $o = $o->getReferencedObject($this->project);
+                // we only support references to paths right now
+                if (!($o instanceof Path)) {
+                    $msg = $r->getRefId() . " doesn't denote a path";
+                    throw new BuildException($msg);
+                }
+            }
+            
+            if (is_string($o)) {
+                $result[] = $o;
+            } elseif ($o instanceof PathElement) {
+                $parts = $o->getParts();
+                if ($parts === null) {
+                    throw new BuildException("You must either set location or" 
+                        . " path on <pathelement>");
+                }
+                foreach($parts as $part) {
+                    $result[] = $part;
+                }
+            } elseif ($o instanceof Path) {
+                $p = $o;
+                if ($p->getProject() === null) {
+                    $p->setProject($this->getProject());
+                }
+                $parts = $p->listPaths();
+                foreach($parts as $part) {
+                    $result[] = $part;
+                }
+            } elseif ($o instanceof DirSet) {
+                $dset = $o;
+                $ds = $dset->getDirectoryScanner($this->project);
+                $dirstrs = $ds->getIncludedDirectories();
+                $dir = $dset->getDir($this->project);
+                foreach($dirstrs as $dstr) {
+                    $d = new PhingFile($dir, $dstr);
+                    $result[] = $d->getAbsolutePath();
+                }
+                var_dump($result);
+            } elseif ($o instanceof FileList) {
+                $fl = $o;
+                $dirstrs = $fl->getFiles($this->project);
+                $dir = $fl->getDir($this->project);
+                foreach($dirstrs as $dstr) {
+                    $d = new PhingFile($dir, $dstr);
+                    $result[] = $d->getAbsolutePath();
+                }
+            }
+        }
+        
+        return array_unique($result);
+    }
+
+
+    /**
+     * Returns a textual representation of the path, which can be used as
+     * CLASSPATH or PATH environment variable definition.
+     * @return string A textual representation of the path.
+     */
+    public function __toString() {
+        
+        $list = $this->listPaths();
+
+        // empty path return empty string
+        if (empty($list)) {
+            return "";
+        }
+        
+        return implode(PATH_SEPARATOR, $list);
+    }
+
+    /**
+     * Splits a PATH (with : or ; as separators) into its parts.
+     * @param Project $project
+     * @param string $source
+     */
+    public static function translatePath(Project $project, $source) {
+        $result = array();
+        if ($source == null) {
+          return "";
+        }
+
+        $tok = new PathTokenizer($source);
+        while ($tok->hasMoreTokens()) {
+            $pathElement = $tok->nextToken();
+            try {
+                $element = self::resolveFile($project, $pathElement);
+                for ($i = 0, $_i=strlen($element); $i < $_i; $i++) {
+                    self::translateFileSep($element, $i);
+                }
+                $result[] = $element;
+            } catch (BuildException $e) {
+                $this->project->log("Dropping path element " . $pathElement
+                    . " as it is not valid relative to the project",
+                    Project::MSG_VERBOSE);
+            }
+        }
+        
+        return $result;
+    }
+
+    /**
+     * Returns its argument with all file separator characters
+     * replaced so that they match the local OS conventions.  
+     */
+    public static function translateFile($source) {
+        if ($source == null) {
+          return "";
+        }
+
+        $result = $source;
+        for ($i = 0, $_i=strlen($source); $i < $_i; $i++) {
+            self::translateFileSep($result, $i);
+        }
+        
+        return $result;
+    }
+
+    /**
+     * Translates all occurrences of / or \ to correct separator of the
+     * current platform and returns whether it had to do any
+     * replacements.  
+     */
+    protected static function translateFileSep(&$buffer, $pos) {
+        if ($buffer{$pos} == '/' || $buffer{$pos} == '\\') {
+            $buffer{$pos} = DIRECTORY_SEPARATOR;
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * How many parts does this Path instance consist of.
+     * DEV NOTE: expensive call! list is generated, counted, and then
+     * discareded.
+     * @return int
+     */
+    public function size() {
+        return count($this->listPaths());
+    }
+
+    /**
+     * Return a Path that holds the same elements as this instance.
+     */
+    public function __clone() {
+        $p = new Path($this->project);
+        $p->append($this);
+        return $p;
+    }
+
+    /**
+     * Overrides the version of DataType to recurse on all DataType
+     * child elements that may have been added.  
+     * @throws BuildException
+     */
+    public function dieOnCircularReference(&$stk, Project $p) {
+
+        if ($this->checked) {
+            return;
+        }
+    
+        // elements can contain strings, FileSets, Reference, etc.
+        foreach($this->elements as $o) {
+            
+            if ($o instanceof Reference) {
+                $o = $o->getReferencedObject($p);
+            }
+
+            if ($o instanceof DataType) {
+                if (in_array($o, $stk, true)) {
+                    throw $this->circularReference();
+                } else {
+                    array_push($stk, $o);
+                    $o->dieOnCircularReference($stk, $p);
+                    array_pop($stk);
+                }
+            }
+        }
+        
+        $this->checked = true;
+    }
+
+    /**
+     * Resolve a filename with Project's help - if we know one that is.
+     *
+     * <p>Assume the filename is absolute if project is null.</p>
+     */
+    private static function resolveFile(Project $project, $relativeName) {
+        if ($project !== null) {
+            $f = $project->resolveFile($relativeName);
+            return $f->getAbsolutePath();
+        }
+        return $relativeName;
+    }
+    
+}
+
+
+/**
+ * Helper class, holds the nested <code>&lt;pathelement&gt;</code> values.
+ */
+class PathElement {
+
+    private $parts = array();
+    private $outer;
+    
+    public function __construct(Path $outer) {
+        $this->outer = $outer;
+    }
+    
+    public function setDir(PhingFile $loc) {
+        $this->parts = array(Path::translateFile($loc->getAbsolutePath()));
+    }
+
+    public function setPath($path) {
+        $this->parts = Path::translatePath($this->outer->getProject(), $path);
+    }
+
+    public function getParts() {
+        return $this->parts;
+    }
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/types/PatternSet.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/types/PatternSet.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/types/PatternSet.php	(revision 19)
@@ -0,0 +1,491 @@
+<?php
+/*
+ *  $Id: PatternSet.php 257 2007-10-21 00:27:07Z hans $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+include_once 'phing/system/io/FileReader.php';
+include_once 'phing/types/DataType.php';
+
+/**
+ * The patternset storage component. Carries all necessary data and methods
+ * for the patternset stuff.
+ *
+ * @author   Andreas Aderhold, andi@binarycloud.com
+ * @version  $Revision: 1.8 $
+ * @package  phing.types
+ */
+class PatternSet extends DataType {
+
+	private $includeList = array();
+	private $excludeList = array();
+	private $includesFileList = array();
+	private $excludesFileList = array();
+
+    /**
+     * Makes this instance in effect a reference to another PatternSet
+     * instance.
+     * You must not set another attribute or nest elements inside
+     * this element if you make it a reference.
+     */
+    function setRefid(Reference $r) {
+    	if (!empty($this->includeList) || !empty($this->excludeList)) {
+    		throw $this->tooManyAttributes();
+    	}
+    	parent::setRefid($r);
+    }
+
+
+    /**
+    * Add a name entry on the include list
+    *
+    * @returns PatternSetNameEntry Reference to object
+    * @throws  BuildException
+    */
+    function createInclude() {
+    	if ($this->isReference()) {
+    		throw $this->noChildrenAllowed();
+    	}
+    	return $this->addPatternToList($this->includeList);
+    }
+
+
+    /**
+    * Add a name entry on the include files list
+    *
+    * @returns PatternSetNameEntry Reference to object
+    * @throws  BuildException
+    */
+    function createIncludesFile() {
+    	if ($this->isReference()) {
+    		throw $this->noChildrenAllowed();
+    	}
+    	return $this->addPatternToList($this->includesFileList);
+    }
+
+    /**
+    * Add a name entry on the exclude list
+    *
+    * @returns PatternSetNameEntry Reference to object
+    * @throws  BuildException
+    */
+    function createExclude() {
+    	if ($this->isReference()) {
+    		throw $this->noChildrenAllowed();
+    	}
+    	return $this->addPatternToList($this->excludeList);
+    }
+
+    /**
+	 * add a name entry on the exclude files list
+	 *
+	 * @returns PatternSetNameEntry Reference to object
+	 * @throws  BuildException
+	 */
+    function createExcludesFile() {
+    	if ($this->isReference()) {
+    		throw $this->noChildrenAllowed();
+    		return;
+    	}
+    	return $this->addPatternToList($this->excludesFileList);
+    }
+
+
+    /**
+     * Sets the set of include patterns. Patterns may be separated by a comma
+     * or a space.
+     *
+     * @param   string the string containing the include patterns
+     * @returns void
+     * @throws  BuildException
+     */
+    function setIncludes($includes) {
+    	if ($this->isReference()) {
+    		throw $this->tooManyAttributes();
+    	}
+    	if ($includes !== null && strlen($includes) > 0) {
+    		$tok = strtok($includes, ", ");
+    		while ($tok !== false) {
+    			$o = $this->createInclude();
+    			$o->setName($tok);
+    			$tok = strtok(", ");
+    		}
+    	}
+    }
+
+
+	/**
+	 * Sets the set of exclude patterns. Patterns may be separated by a comma
+	 * or a space.
+	 *
+	 * @param string the string containing the exclude patterns
+	 * @returns void
+     * @throws  BuildException
+	 */
+    function setExcludes($excludes) {
+    	if ($this->isReference()) {
+    		throw $this->tooManyAttributes();
+    	}
+    	if ($excludes !== null && strlen($excludes) > 0) {
+    		$tok = strtok($excludes, ", ");
+    		while ($tok !== false) {
+    			$o = $this->createExclude();
+    			$o->setName($tok);
+    			$tok = strtok(", ");
+    		}
+    	}
+    }
+
+    /**
+     * add a name entry to the given list
+     *
+     * @param array List onto which the nameentry should be added
+     * @returns PatternSetNameEntry  Reference to the created PsetNameEntry instance
+     */
+    private function addPatternToList(&$list) {
+    	$num = array_push($list, new PatternSetNameEntry());
+    	return $list[$num-1];
+    }
+
+    /**
+     * Sets the name of the file containing the includes patterns.
+     *
+     * @param includesFile The file to fetch the include patterns from.
+     */
+    function setIncludesFile($includesFile) {
+    	if ($this->isReference()) {
+    		throw $this->tooManyAttributes();
+    	}
+    	if ($includesFile instanceof File) {
+    		$includesFile = $includesFile->getPath();
+    	}
+    	$o = $this->createIncludesFile();
+    	$o->setName($includesFile);
+    }
+
+    /**
+     * Sets the name of the file containing the excludes patterns.
+     *
+     * @param excludesFile The file to fetch the exclude patterns from.
+     */
+    function setExcludesFile($excludesFile) {
+    	if ($this->isReference()) {
+    		throw $this->tooManyAttributes();
+    	}
+    	if ($excludesFile instanceof File) {
+    		$excludesFile = $excludesFile->getPath();
+    	}
+    	$o = $this->createExcludesFile();
+    	$o->setName($excludesFile);
+    }
+
+
+    /**
+     *  Reads path matching patterns from a file and adds them to the
+     *  includes or excludes list
+     */
+    private function readPatterns(PhingFile $patternfile, &$patternlist, Project $p) {
+    	$patternReader = null;
+    	try {
+    		// Get a FileReader
+    		$patternReader = new BufferedReader(new FileReader($patternfile));
+
+    		// Create one NameEntry in the appropriate pattern list for each
+    		// line in the file.
+    		$line = $patternReader->readLine();
+    		while ($line !== null) {
+    			if (!empty($line)) {
+    				$line = $p->replaceProperties($line);
+    				$this->addPatternToList($patternlist)->setName($line);
+    			}
+    			$line = $patternReader->readLine();
+    		}
+
+    	} catch (IOException $ioe)  {
+    		$msg = "An error occured while reading from pattern file: " . $patternfile->__toString();
+    		if($patternReader) $patternReader->close();
+    		throw new BuildException($msg, $ioe);
+    	}
+
+    	$patternReader->close();
+    }
+
+
+    /** Adds the patterns of the other instance to this set. */
+    function append($other, $p) {
+    	if ($this->isReference()) {
+    		throw new BuildException("Cannot append to a reference");
+    	}
+
+    	$incl = $other->getIncludePatterns($p);
+    	if ($incl !== null) {
+    		foreach($incl as $incl_name) {
+    			$o = $this->createInclude();
+    			$o->setName($incl_name);
+    		}
+    	}
+
+    	$excl = $other->getExcludePatterns($p);
+    	if ($excl !== null) {
+    		foreach($excl as $excl_name) {
+    			$o = $this->createExclude();
+    			$o->setName($excl_name);
+    		}
+    	}
+    }
+
+    /** Returns the filtered include patterns. */
+    function getIncludePatterns(Project $p) {
+    	if ($this->isReference()) {
+    		$o = $this->getRef($p);
+    		return $o->getIncludePatterns($p);
+    	} else {
+    		$this->readFiles($p);
+    		return $this->makeArray($this->includeList, $p);
+    	}
+    }
+
+    /** Returns the filtered exclude patterns. */
+    function getExcludePatterns(Project $p) {
+    	if ($this->isReference()) {
+    		$o = $this->getRef($p);
+    		return $o->getExcludePatterns($p);
+    	} else {
+    		$this->readFiles($p);
+    		return $this->makeArray($this->excludeList, $p);
+    	}
+    }
+
+    /** helper for FileSet. */
+    function hasPatterns() {
+    	return (boolean) count($this->includesFileList) > 0 || count($this->excludesFileList) > 0
+    	|| count($this->includeList) > 0 || count($this->excludeList) > 0;
+    }
+
+    /**
+     * Performs the check for circular references and returns the
+     * referenced PatternSet.
+     */
+    function getRef(Project $p) {
+    	if (!$this->checked) {
+    		$stk = array();
+    		array_push($stk, $this);
+    		$this->dieOnCircularReference($stk, $p);
+    	}
+    	$o = $this->ref->getReferencedObject($p);
+    	if (!($o instanceof PatternSet)) {
+    		$msg = $this->ref->getRefId()." doesn't denote a patternset";
+    		throw new BuildException($msg);
+    	} else {
+    		return $o;
+    	}
+    }
+
+    /** Convert a array of PatternSetNameEntry elements into an array of Strings. */
+    private function makeArray(&$list, Project $p) {
+
+    	if (count($list) === 0) {
+    		return null;
+    	}
+
+    	$tmpNames = array();
+    	foreach($list as $ne) {
+    		$pattern = (string) $ne->evalName($p);
+    		if ($pattern !== null && strlen($pattern) > 0) {
+    			array_push($tmpNames, $pattern);
+    		}
+    	}
+    	return $tmpNames;
+    }
+
+    /** Read includesfile or excludesfile if not already done so. */
+    private function readFiles(Project $p) {
+    	if (!empty($this->includesFileList)) {
+    		foreach($this->includesFileList as $ne) {
+    			$fileName = (string) $ne->evalName($p);
+    			if ($fileName !== null) {
+    				$inclFile = $p->resolveFile($fileName);
+    				if (!$inclFile->exists()) {
+    					throw new BuildException("Includesfile ".$inclFile->getAbsolutePath()." not found.");
+    				}
+    				$this->readPatterns($inclFile, $this->includeList, $p);
+    			}
+    		}
+    		$this->includesFileList = array();
+    	}
+
+    	if (!empty($this->excludesFileList)) {
+    		foreach($this->excludesFileList as $ne) {
+    			$fileName = (string) $ne->evalName($p);
+    			if ($fileName !== null) {
+    				$exclFile = $p->resolveFile($fileName);
+    				if (!$exclFile->exists()) {
+    					throw new BuildException("Excludesfile ".$exclFile->getAbsolutePath()." not found.");
+    					return;
+    				}
+    				$this->readPatterns($exclFile, $this->excludeList, $p);
+    			}
+    		}
+    		$this->excludesFileList = array();
+    	}
+    }
+
+
+    function toString() {
+
+    	// We can't compile includeList into array because, toString() does
+    	// not know about project:
+    	//
+    	// $includes = $this->makeArray($this->includeList, $this->project);
+    	// $excludes = $this->makeArray($this->excludeList, $this->project);
+
+    	if (empty($this->includeList)) {
+    		$includes = "empty";
+    	} else {
+    		$includes = "";
+    		foreach($this->includeList as $ne) {
+    			$includes .= $ne->toString() . ",";
+    		}
+    		$includes = rtrim($includes, ",");
+    	}
+
+    	if (empty($this->excludeList)) {
+    		$excludes = "empty";
+    	} else {
+    		$excludes = "";
+    		foreach($this->excludeList as $ne) {
+    			$excludes .= $ne->toString() . ",";
+    		}
+    		$excludes = rtrim($excludes, ",");
+    	}
+
+    	return "patternSet{ includes: $includes  excludes: $excludes }";
+    }
+}
+
+
+/**
+ * "Internal" class for holding an include/exclude pattern.
+ */
+class PatternSetNameEntry {
+
+	/**
+	 * The pattern.
+	 * @var string
+	 */
+	private $name;
+
+    /**
+     * The if-condition property for this pattern to be applied.
+     * @var string
+     */
+    private $ifCond;
+
+    /**
+     * The unless-condition property for this pattern to be applied.
+     * @var string 
+     */
+    private $unlessCond;
+
+    /**
+     * An alias for the setName() method.
+     * @see setName()
+     * @param string $pattern
+     */
+    public function setPattern($pattern) {
+    	$this->setName($pattern);
+    }
+
+    /**
+     * Set the pattern text.
+     * @param string $name The pattern
+     */
+    public function setName($name) {
+    	$this->name = (string) $name;
+    }
+
+	/**
+	 * Sets an if-condition property for this pattern to match.
+	 * @param string $cond
+	 */
+	public function setIf($cond) {
+		$this->ifCond = (string) $cond;
+	}
+
+
+	/**
+	 * Sets an unless-condition property for this pattern to match.
+	 * @param string $cond
+	 */
+	public function setUnless($cond) {
+		$this->unlessCond = (string) $cond;
+	}
+
+	/**
+	 * Get the pattern text.
+	 * @return string The pattern.
+	 */
+	public function getName() {
+		return $this->name;
+	}
+
+	/**
+	 * Evaluates the pattern.
+	 * @return string The pattern or null if it is ruled out by a condition. 
+	 */
+	public function evalName(Project $project) {
+		return $this->valid($project) ? $this->name : null;
+	}
+
+
+    /**
+     * Checks whether pattern should be applied based on whether the if and unless
+     * properties are set in project.
+     * @param Project $project
+     * @return boolean
+     */
+    public function valid(Project $project) {
+    	if ($this->ifCond !== null && $project->getProperty($this->ifCond) === null) {
+    		return false;
+    	} else if ($this->unlessCond !== null && $project->getProperty($this->unlessCond) !== null) {
+    		return false;
+    	}
+    	return true;
+    }
+
+	/**
+	 * Gets a string representation of this pattern.
+	 * @return string
+	 */
+	public function toString() {
+		$buf = $this->name;
+		if (($this->ifCond !== null) || ($this->unlessCond !== null)) {
+			$buf .= ":";
+			$connector = "";
+
+			if ($this->ifCond !== null) {
+				$buf .= "if->{$this->ifCond}";
+				$connector = ";";
+			}
+			if ($this->unlessCond !== null) {
+				$buf .= "$connector unless->{$this->unlessCond}";
+			}
+		}
+		return $buf;
+	}
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/types/PhingFilterReader.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/types/PhingFilterReader.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/types/PhingFilterReader.php	(revision 19)
@@ -0,0 +1,136 @@
+<?php
+/*
+ *  $Id: PhingFilterReader.php 325 2007-12-20 15:44:58Z hans $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+*/
+
+include_once 'phing/types/DataType.php';
+include_once 'phing/types/Parameter.php';
+
+/*
+ * A PhingFilterReader is a wrapper class that encloses the className
+ * and configuration of a Configurable FilterReader.
+ *
+ * @author    Yannick Lecaillez <yl@seasonfive.com>
+ * @version   $Revision: 1.9 $
+ * @see       FilterReader
+ * @package   phing.types
+*/
+class PhingFilterReader extends DataType {
+
+    private $className;
+    private $parameters = array();
+    private $classPath;
+
+    function setClassName($className) {
+        $this->className = $className;
+    }
+
+    function getClassName() {
+        return $this->className;
+    }
+
+    /**
+     * Set the classpath to load the FilterReader through (attribute).
+     * @param Path $classpath
+     */
+    function setClasspath(Path $classpath) {
+        if ( $this->isReference() ) {
+            throw $this->tooManyAttributes();
+        }
+        if ( $this->classPath === null ) {
+            $this->classPath = $classpath;
+        } else {
+            $this->classPath->append($classpath);
+        }
+    }
+
+    /*
+     * Set the classpath to load the FilterReader through (nested element).
+    */
+    function createClasspath() {
+        if ( $this->isReference() ) {
+            throw $this->noChildrenAllowed();
+        }        
+        if ( $this->classPath === null ) {
+            $this->classPath = new Path($this->project);
+        }
+        return $this->classPath->createPath();
+    }
+
+    function getClasspath() {
+        return $this->classPath;
+    }
+
+    function setClasspathRef(Reference $r) {
+        if ( $this->isReference() ) {
+            throw $this->tooManyAttributes();
+        }
+        $o = $this->createClasspath();
+        $o->setRefid($r);
+    }
+	
+	function addParam(Parameter $param) {
+		$this->parameters[] = $param;
+	}
+
+    function createParam() {
+        $num = array_push($this->parameters, new Parameter());
+        return $this->parameters[$num-1];
+    }
+		
+    function getParams() {
+        // We return a COPY
+        $ret = array();
+        for($i=0,$size=count($this->parameters); $i < $size; $i++) {
+            $ret[] = clone $this->parameters[$i];
+        }
+        return $ret;
+    }
+
+    /*
+     * Makes this instance in effect a reference to another PhingFilterReader 
+     * instance.
+     *
+     * <p>You must not set another attribute or nest elements inside
+     * this element if you make it a reference.</p>
+     *
+     * @param Reference $r the reference to which this instance is associated
+     * @exception BuildException if this instance already has been configured.
+    */
+    function setRefid(Reference $r) {
+        if ( (count($this->parameters) !== 0) || ($this->className !== null) ) {
+            throw $this->tooManyAttributes();
+        }
+        $o = $r->getReferencedObject($this->getProject());
+        if ( $o instanceof PhingFilterReader ) {
+            $this->setClassName($o->getClassName());
+            $this->setClasspath($o->getClassPath());
+            foreach($o->getParams() as $p) {
+                $this->addParam($p);
+            }
+        } else {
+            $msg = $r->getRefId()." doesn\'t refer to a PhingFilterReader";
+            throw new BuildException($msg);
+        }
+
+        parent::setRefid($r);
+    }
+}
+
+
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/types/Reference.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/types/Reference.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/types/Reference.php	(revision 19)
@@ -0,0 +1,56 @@
+<?php
+/*
+ * $Id: Reference.php 325 2007-12-20 15:44:58Z hans $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>. 
+ */
+
+/** Class to hold a reference to another object in the project.
+ * @package phing.types
+ */
+class Reference {
+
+    protected $refid;
+
+    function __construct($id = null) {
+        if ($id !== null) {
+            $this->setRefId($id);
+        }
+    }
+
+    function setRefId($id) {
+        $this->refid = (string) $id;
+    }
+
+    function getRefId() {
+        return $this->refid;
+    }
+
+    /** returns reference to object in references container of project */
+    function getReferencedObject($project) {    
+        if ($this->refid === null) {
+            throw new BuildException("No reference specified");
+        }
+        $refs = $project->getReferences();
+        $o = @$refs[$this->refid];
+        if (!is_object($o)) {       
+            throw new BuildException("Reference {$this->refid} not found.");
+        }
+        return $o;
+    }
+}
+
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/types/RegularExpression.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/types/RegularExpression.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/types/RegularExpression.php	(revision 19)
@@ -0,0 +1,105 @@
+<?php
+/*
+ *  $Id: RegularExpression.php 325 2007-12-20 15:44:58Z hans $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+*/
+
+include_once 'phing/types/DataType.php';
+include_once 'phing/Project.php';
+include_once 'phing/util/regexp/Regexp.php';
+
+/*
+ * A regular expression datatype.  Keeps an instance of the
+ * compiled expression for speed purposes.  This compiled
+ * expression is lazily evaluated (it is compiled the first
+ * time it is needed).  The syntax is the dependent on which
+ * regular expression type you are using.
+ *
+ * @author    <a href="mailto:yl@seasonfive.com">Yannick Lecaillez</a>
+ * @version   $Revision: 1.6 $ $Date: 2007-12-20 15:44:58 +0000 (Thu, 20 Dec 2007) $
+ * @access    public
+ * @see       phing.util.regex.RegexMatcher
+ * @package   phing.types
+*/
+class RegularExpression extends DataType {
+
+    private $regexp   = null;
+    private $ignoreCase = false;
+    
+    function __construct() {
+        $this->regexp  = new Regexp();
+    }
+
+    function setPattern($pattern) {
+        $this->regexp->setPattern($pattern);
+    }
+
+    function setReplace($replace) {
+        $this->regexp->setReplace($replace);
+    }
+    
+    function getPattern($p) {
+        if ( $this->isReference() ) {
+            $ref = $this->getRef($p);
+            return $ref->getPattern($p);
+        }
+        return $this->regexp->getPattern();
+    }
+
+    function getReplace($p) {
+        if ( $this->isReference() ) {
+            $ref = $this->getRef($p);
+            return $ref->getReplace($p);
+        }
+
+        return $this->regexp->getReplace();
+    }
+    
+    function setIgnoreCase($bit) {
+        $this->regexp->setIgnoreCase($bit);
+    }
+    
+    function getIgnoreCase() {
+        return $this->regexp->getIgnoreCase();
+    }
+    
+    function getRegexp(Project $p) {
+        if ( $this->isReference() ) {
+            $ref = $this->getRef($p);
+            return $ref->getRegexp($p);
+        }
+        return $this->regexp;
+    }
+
+    function getRef(Project $p) {
+        if ( !$this->checked ) {
+            $stk = array();
+            array_push($stk, $this);
+            $this->dieOnCircularReference($stk, $p);            
+        }
+
+        $o = $this->ref->getReferencedObject($p);
+        if ( !($o instanceof RegularExpression) ) {
+            throw new BuildException($this->ref->getRefId()." doesn't denote a RegularExpression");
+        } else {
+            return $o;
+        }
+    }
+}
+
+
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/types/TokenReader.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/types/TokenReader.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/types/TokenReader.php	(revision 19)
@@ -0,0 +1,66 @@
+<?php
+/*
+ *  $Id: TokenReader.php 325 2007-12-20 15:44:58Z hans $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+*/
+
+// include_once 'phing/system/io/Reader.php'; // really this is unrelated to Reader
+include_once 'phing/system/io/IOException.php';
+include_once 'phing/filters/ReplaceTokens.php'; // For class Token
+
+/**
+ * Abstract class for TokenReaders.
+ * 
+ * @author    Manuel Holtgewe
+ * @version   $Revision: 1.5 $
+ * @package   phing.filters.util
+ */
+abstract class TokenReader {
+
+    /**
+     * Reference to the Project the TokenReader is used in.
+     * @var Project 
+     */
+    protected $project;
+
+    /**
+     * Constructor
+     * @param   object  Reference to the project the TokenReader is used in.
+     */
+    function __construct(Project $project) {
+        $this->project = $project;
+    }
+
+    /**
+     * Utility function for logging
+     */
+    function log($level, $msg) {
+        $this->project->log($level, $msg);
+    }
+
+    /**
+     * Reads the next token from the Reader
+     *
+     * @throws IOException - On error
+     * @return string
+     */
+    abstract public function readToken();
+    
+}
+
+
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/types/TokenSource.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/types/TokenSource.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/types/TokenSource.php	(revision 19)
@@ -0,0 +1,157 @@
+<?php
+/*
+ *  $Id: TokenSource.php 325 2007-12-20 15:44:58Z hans $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+*/
+
+require_once 'phing/types/DataType.php';
+include_once 'phing/util/StringHelper.php';
+
+/**
+ * A parameter is composed of a name, type and value.
+ *
+ * Example of usage:
+ *
+ * <replacetokens>
+ *   <tokensource classname="phing.filters.util.IniFileTokenReader">
+ *     <!-- all params for the TokenReader here -->
+ *     <param name="file" value="tokens.ini" />
+ *   </tokensource>
+ * </replacetokens>
+ *
+ * or:
+ * 
+ * <filterreader classname="phing.filters.ReplaceTokens">
+ *   <param type="tokensource>
+ *     <param name="classname" value="phing.filters.util.IniFileTokenReader" />
+ *     <param name="file" value="tokens.ini" />
+ *   </param>
+ * </filterreader>
+ *
+ * @author    <a href="mailto:yl@seasonfive.com">Yannick Lecaillez</a>
+ * @package   phing.types
+ */
+class TokenSource extends DataType {
+
+    /**
+     * String to hold the path to the TokenReader
+     * @var     string
+     */
+    protected $classname = null;
+
+    /**
+     * Array holding parameters for the wrapped TokenReader.
+     * @var array
+     */
+    protected $parameters = array();
+
+    /**
+     * Reference to the TokenReader used by this TokenSource
+     * @var TokenReader
+     */
+    protected $reader;
+
+    /**
+     * Array with key/value pairs of tokens
+     */
+    protected $tokens = array();
+
+    /**
+     * This method is called to load the sources from the reader
+     * into the buffer of the source.
+     */
+    function load() {
+        // Create new Reader
+        if ($this->classname === null) {
+            throw new BuildException("No Classname given to TokenSource.");
+        }
+        
+        $classname = Phing::import($this->classname);        
+        $this->reader = new $classname($this->project);
+
+        // Configure Reader
+        $this->configureTokenReader($this->reader);
+
+        // Load Tokens
+        try {
+            while ($token = $this->reader->readToken()) {
+                $this->tokens[] = $token;
+            }
+        } catch (BuildException $e) {
+            $this->log("Error reading TokenSource: " . $e->getMessage(), Project::MSG_WARN);
+        } catch (IOException $e) {
+            $this->log("Error reading TokenSource: " . $e->getMessage(), Project::MSG_WARN);
+        }
+    }
+
+    /**
+     * This function uses the wrapper to read the tokens and then
+     * returns them.
+     *
+     * @access  public
+     */
+    function getTokens() {
+        if ($this->tokens === null)
+            $this->Load();
+
+        return $this->tokens;
+    }
+
+    /**
+     * Configures a TokenReader with the parameters passed to the
+     * TokenSource.
+     * @param TokenReader $reader
+     */
+    private function configureTokenReader(TokenReader $reader) {
+        $count = count($this->parameters);
+        for ($i = 0; $i < $count; $i++) {
+            $method_name = "Set" . $this->parameters[$i]->getName();
+            $value = $this->parameters[$i]->getValue();
+            $reader->$method_name($value);
+        }
+    }
+    
+    /**
+     * Set the classname (dot-path) to use for handling token replacement.
+     * @param string $c
+     */
+    function setClassname($c) {
+        $this->classname = $c;
+    }
+    
+    /**
+     * Returns the qualified classname (dot-path) to use for handling token replacement.
+     * @return string
+     */
+    function getClassname() {
+        return $this->classname;
+    }
+
+    /**
+     * Create nested <param> tag.
+     * Uses standard name/value Parameter class.
+     * @return Parameter
+     */
+    function createParam() {
+        $num = array_push($this->parameters, new Parameter());
+        return $this->parameters[$num-1];
+    }
+}
+
+
+
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/types/defaults.properties
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/types/defaults.properties	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/types/defaults.properties	(revision 19)
@@ -0,0 +1,13 @@
+# phing default types
+commandline=phing.types.Commandline
+fileset=phing.types.FileSet
+dirset=phing.types.DirSet
+filelist=phing.types.FileList
+patternset=phing.types.PatternSet
+mapper=phing.types.Mapper
+filterchain=phing.types.FilterChain
+filterreader=phing.types.PhingFilterReader
+regexp=phing.types.RegularExpression
+param=phing.types.Parameter
+path=phing.types.Path
+selector=phing.types.selectors.SelectSelector
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/types/selectors/AndSelector.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/types/selectors/AndSelector.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/types/selectors/AndSelector.php	(revision 19)
@@ -0,0 +1,67 @@
+<?php
+/*
+ * $Id: AndSelector.php 123 2006-09-14 20:19:08Z mrook $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+require_once 'phing/types/selectors/BaseSelectorContainer.php';
+
+/**
+ * This selector has a collection of other selectors, all of which have to
+ * select a file in order for this selector to select it.
+ *
+ * @author Hans Lellelid, hans@xmpl.org (Phing)
+ * @author <a href="mailto:bruce@callenish.com">Bruce Atherton</a> (Ant)
+ * @package phing.types.selectors
+ */
+class AndSelector extends BaseSelectorContainer {
+
+    public function toString() {
+        $buf = "";
+        if ($this->hasSelectors()) {
+            $buf .= "{andselect: ";
+            $buf .= parent::toString();
+            $buf .= "}";
+        }
+        return $buf;
+    }
+
+    /**
+     * Returns true (the file is selected) only if all other selectors
+     * agree that the file should be selected.
+     *
+     * @param basedir the base directory the scan is being done from
+     * @param filename the name of the file to check
+     * @param file a PhingFile object for the filename that the selector
+     * can use
+     * @return whether the file should be selected or not
+     */
+    public function isSelected(PhingFile $basedir, $filename, PhingFile $file) {
+        $this->validate();
+        $selectors = $this->selectorElements();       
+           for($i=0,$size=count($selectors); $i < $size; $i++) {
+            $result = $selectors[$i]->isSelected($basedir, $filename, $file);
+            if (!$result) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+}
+
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/types/selectors/BaseExtendSelector.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/types/selectors/BaseExtendSelector.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/types/selectors/BaseExtendSelector.php	(revision 19)
@@ -0,0 +1,62 @@
+<?php
+
+/*
+ * $Id: BaseExtendSelector.php 123 2006-09-14 20:19:08Z mrook $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+ 
+require_once 'phing/types/selectors/ExtendFileSelector.php';
+require_once 'phing/types/selectors/BaseSelector.php';
+include_once 'phing/types/Parameter.php';
+
+/**
+ * Convenience base class for all selectors accessed through ExtendSelector.
+ * It provides support for gathering the parameters together as well as for
+ * assigning an error message and throwing a build exception if an error is
+ * detected.
+ *
+ * @author Hans Lellelid, hans@xmpl.org (Phing)
+ * @author Bruce Atherton, bruce@callenish.com (Ant)
+ * @package phing.types.selectors
+ */
+abstract class BaseExtendSelector extends BaseSelector implements ExtendFileSelector {
+
+    /** The passed in parameter array. */
+    protected $parameters = null;
+
+    /**
+     * Set all the Parameters for this custom selector, collected by
+     * the ExtendSelector class.
+     *
+     * @param parameters the complete set of parameters for this selector
+     */
+    public function setParameters($parameters) {
+        $this->parameters = $parameters;
+    }
+
+    /**
+     * Allows access to the parameters gathered and set within the
+     * &lt;custom&gt; tag.
+     *
+     * @return the set of parameters defined for this selector
+     */
+    protected function getParameters() {
+        return $this->parameters;
+    }
+}
+
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/types/selectors/BaseSelector.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/types/selectors/BaseSelector.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/types/selectors/BaseSelector.php	(revision 19)
@@ -0,0 +1,84 @@
+<?php
+/*
+ * $Id: BaseSelector.php 123 2006-09-14 20:19:08Z mrook $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+require_once 'phing/types/selectors/FileSelector.php';
+
+/**
+ * A convenience base class that you can subclass Selectors from. It
+ * provides some helpful common behaviour. Note that there is no need
+ * for Selectors to inherit from this class, it is only necessary that
+ * they implement FileSelector.
+ *
+ * @author <a href="mailto:bruce@callenish.com">Bruce Atherton</a>
+ * @package phing.types.selectors
+ */
+abstract class BaseSelector extends DataType implements FileSelector {
+
+    private $errmsg = null;
+
+    /**
+     * Allows all selectors to indicate a setup error. Note that only
+     * the first error message is recorded.
+     *
+     * @param msg The error message any BuildException should throw.
+     */
+    public function setError($msg) {
+        if ($this->errmsg === null) {
+            $this->errmsg = $msg;
+        }
+    }
+
+    /**
+     * Returns any error messages that have been set.
+     *
+     * @return the error condition
+     */
+    public function getError() {
+        return $this->errmsg;
+    }
+
+
+    /**
+     * <p>Subclasses can override this method to provide checking of their
+     * state. So long as they call validate() from isSelected(), this will
+     * be called automatically (unless they override validate()).</p>
+     * <p>Implementations should check for incorrect settings and call
+     * setError() as necessary.</p>
+     */
+    public function verifySettings() {
+    }
+
+    /**
+     * Subclasses can use this to throw the requisite exception
+     * in isSelected() in the case of an error condition.
+     */
+    public function validate() {
+        if ($this->getError() === null) {
+            $this->verifySettings();
+        }
+        if ($this->getError() !== null) {
+            throw new BuildException($this->errmsg);
+        }
+    }   
+
+}
+
+
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/types/selectors/BaseSelectorContainer.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/types/selectors/BaseSelectorContainer.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/types/selectors/BaseSelectorContainer.php	(revision 19)
@@ -0,0 +1,270 @@
+<?php
+
+/*
+ * $Id: BaseSelectorContainer.php 123 2006-09-14 20:19:08Z mrook $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+require_once 'phing/types/selectors/SelectorContainer.php';
+require_once 'phing/types/selectors/BaseSelector.php';
+
+/**
+ * This is the base class for selectors that can contain other selectors.
+ *
+ * @author <a href="mailto:bruce@callenish.com">Bruce Atherton</a> (Ant)
+ * @package phing.types.selectors
+ */
+abstract class BaseSelectorContainer extends BaseSelector implements SelectorContainer {
+
+    private $selectorsList = array();
+
+    /**
+     * Indicates whether there are any selectors here.
+     */
+    public function hasSelectors() {
+        return !(empty($this->selectorsList));
+    }
+
+    /**
+     * Gives the count of the number of selectors in this container
+     */
+    public function selectorCount() {
+        return count($this->selectorsList);
+    }
+
+    /**
+     * Returns a copy of the selectors as an array.
+     */
+    public function getSelectors(Project $p) {
+        $result = array();
+        for($i=0,$size=count($this->selectorsList); $i < $size; $i++) {
+            $result[] = clone $this->selectorsList[$i];
+        }
+        return $result;
+    }
+
+    /**
+     * Returns an array for accessing the set of selectors (not a copy).
+     */
+    public function selectorElements() {
+        return $this->selectorsList;
+    }
+
+    /**
+     * Convert the Selectors within this container to a string. This will
+     * just be a helper class for the subclasses that put their own name
+     * around the contents listed here.
+     *
+     * @return comma separated list of Selectors contained in this one
+     */
+    public function toString() {
+        $buf = "";
+        $arr = $this->selectorElements();
+        for($i=0,$size=count($arr); $i < $size; $i++) {
+            $buf .= $arr[$i]->toString() . (isset($arr[$i+1]) ? ', ' : '');
+        }
+        return $buf;
+    }
+
+    /**
+     * Add a new selector into this container.
+     *
+     * @param selector the new selector to add
+     * @return the selector that was added
+     */
+    public function appendSelector(FileSelector $selector) {
+        $this->selectorsList[] = $selector;
+    }
+
+    /**
+     * <p>This implementation validates the container by calling
+     * verifySettings() and then validates each contained selector
+     * provided that the selector implements the validate interface.
+     * </p>
+     * <p>Ordinarily, this will validate all the elements of a selector
+     * container even if the isSelected() method of some elements is
+     * never called. This has two effects:</p>
+     * <ul>
+     * <li>Validation will often occur twice.
+     * <li>Since it is not required that selectors derive from
+     * BaseSelector, there could be selectors in the container whose
+     * error conditions are not detected if their isSelected() call
+     * is never made.
+     * </ul>
+     */
+    public function validate() {
+        $this->verifySettings();
+        $errmsg = $this->getError();
+        if ($errmsg !== null) {
+            throw new BuildException($errmsg);
+        }
+        foreach($this->selectorsList as $o) {
+            if ($o instanceof BaseSelector) {
+                $o->validate();
+            }
+        }    
+    }
+
+    /* Methods below all add specific selectors */
+
+    /**
+     * add a "Select" selector entry on the selector list
+     */
+    public function createSelector() {
+        $o = new SelectSelector();
+        $this->appendSelector($o);
+        return $o;
+    }
+
+    /**
+     * add an "And" selector entry on the selector list
+     */
+    public function createAnd() {
+        $o = new AndSelector();
+        $this->appendSelector($o);
+        return $o;
+    }
+
+    /**
+     * add an "Or" selector entry on the selector list
+     */
+    public function createOr() {
+        $o = new OrSelector();
+        $this->appendSelector($o);
+        return $o;
+    }
+
+    /**
+     * add a "Not" selector entry on the selector list
+     */
+    public function createNot() {
+        $o = new NotSelector();
+        $this->appendSelector($o);
+        return $o;
+    }
+
+    /**
+     * add a "None" selector entry on the selector list
+     */
+    public function createNone() {
+        $o = new NoneSelector();
+        $this->appendSelector($o);
+        return $o;
+    }
+
+    /**
+     * add a majority selector entry on the selector list
+     */
+    public function createMajority() {
+        $o = new MajoritySelector();
+        $this->appendSelector($o);
+        return $o;
+    }
+
+    /**
+     * add a selector date entry on the selector list
+     */
+    public function createDate() {
+        $o = new DateSelector();
+        $this->appendSelector($o);
+        return $o;
+    }
+
+    /**
+     * add a selector size entry on the selector list
+     */
+    public function createSize() {
+        $o = new SizeSelector();
+        $this->appendSelector($o);
+        return $o;
+    }
+
+    /**
+     * add a selector filename entry on the selector list
+     */
+    public function createFilename() {
+        $o = new FilenameSelector();
+        $this->appendSelector($o);
+        return $o;
+    }
+
+    /**
+     * add an extended selector entry on the selector list
+     */
+    public function createCustom() {
+        $o = new ExtendSelector();
+        $this->appendSelector($o);
+        return $o;
+    }
+
+    /**
+     * add a contains selector entry on the selector list
+     */
+    public function createContains() {
+        $o = new ContainsSelector();
+        $this->appendSelector($o);
+        return $o;
+    }
+
+    /**
+     * add a contains selector entry on the selector list
+     */
+    public function createContainsRegexp() {
+        $o = new ContainsRegexpSelector();
+        $this->appendSelector($o);
+        return $o;
+    }
+
+    /**
+     * add a present selector entry on the selector list
+     */
+    public function createPresent() {
+        $o = new PresentSelector();
+        $this->appendSelector($o);
+        return $o;
+    }
+
+    /**
+     * add a depth selector entry on the selector list
+     */
+    public function createDepth() {
+        $o = new DepthSelector();
+        $this->appendSelector($o);
+        return $o;
+    }
+
+    /**
+     * add a depends selector entry on the selector list
+     */
+    public function createDepend() {
+        $o = new DependSelector();
+        $this->appendSelector($o);
+        return $o;
+    }
+    
+    /**
+     * add a type selector entry on the selector list
+     */
+    public function createType() {
+        $o = new TypeSelector();
+        $this->appendSelector($o);
+        return $o;
+    }
+    
+}
+
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/types/selectors/ContainsRegexpSelector.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/types/selectors/ContainsRegexpSelector.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/types/selectors/ContainsRegexpSelector.php	(revision 19)
@@ -0,0 +1,164 @@
+<?php
+
+/*
+ * $Id: ContainsRegexpSelector.php 123 2006-09-14 20:19:08Z mrook $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+require_once 'phing/types/selectors/BaseExtendSelector.php';
+include_once 'phing/types/RegularExpression.php';
+
+/**
+ * Selector that filters files based on whether they contain a
+ * particular string using regexp.
+ * 
+ * @author    Hans Lellelid <hans@xmpl.org> (Phing)
+ * @author    Bruce Atherton <bruce@callenish.com> (Ant)
+ * @version   $Revision: 1.3 $
+ * @package   phing.types.selectors
+ */
+class ContainsRegexpSelector extends BaseExtendSelector {
+
+    /** @var string The expression set from XML. */
+    private $userProvidedExpression;
+    
+    /** @var Regexp */
+    private $myExpression;
+     
+    private $casesensitive = true;
+    
+    /** @var RegularExpression */
+    private $myRegExp;
+    
+    const EXPRESSION_KEY = "expression";
+    
+    const CASE_KEY = "casesensitive";
+    
+    public function toString() {
+        $buf = "{containsregexpselector expression: ";
+        $buf .= $this->userProvidedExpression;
+        $buf .= " casesensitive: ";
+        if ($this->casesensitive) {
+            $buf .= "true";
+        } else {
+            $buf .= "false";
+        }
+        $buf .= "}";
+        return $buf;
+    }
+
+    /**
+     * The expression to match on within a file.
+     *
+     * @param string $exp the string that a file must contain to be selected.
+     */
+    public function setExpression($exp) {
+        $this->userProvidedExpression = $exp;
+    }
+
+    /**
+     * Whether to ignore case in the regex match.
+     *
+     * @param boolean $casesensitive whether to pay attention to case sensitivity
+     */
+    public function setCasesensitive($casesensitive) {
+        $this->casesensitive = $casesensitive;
+    }
+
+    /**
+     * When using this as a custom selector, this method will be called.
+     * It translates each parameter into the appropriate setXXX() call.
+     *
+     * @param array $parameters the complete set of parameters for this selector
+     */
+    public function setParameters($parameters) {
+        parent::setParameters($parameters);
+        if ($parameters !== null) {
+            for ($i=0,$size=count($parameters); $i < $size; $i++) {
+                $paramname = $parameters[$i]->getName();
+                switch(strtolower($paramname)) {
+                    case self::EXPRESSION_KEY:
+                        $this->setExpression($parameters[$i]->getValue());
+                        break;
+                    case self::CASE_KEY:
+                        $this->setCasesensitive($parameters[$i]->getValue());
+                        break;
+                    default:
+                        $this->setError("Invalid parameter " . $paramname);
+                }                
+            } // for each param
+        } // if params
+    }
+
+    /**
+     * Checks to make sure all settings are kosher. In this case, it
+     * means that the pattern attribute has been set.
+     *
+     */
+    public function verifySettings() {
+        if ($this->userProvidedExpression === null) {
+            $this->setError("The expression attribute is required");
+        }
+    }
+
+    /**
+     * The heart of the matter. This is where the selector gets to decide
+     * on the inclusion of a file in a particular fileset.
+     *
+     * @param basedir the base directory the scan is being done from
+     * @param filename is the name of the file to check
+     * @param file a PhingFile object the selector can use
+     * @return whether the file should be selected or not
+     */
+    public function isSelected(PhingFile $basedir, $filename, PhingFile $file) {
+
+        $this->validate();
+
+        if ($file->isDirectory()) {
+            return true;
+        }
+        
+        if ($this->myRegExp === null) {
+            $this->myRegExp = new RegularExpression();
+            $this->myRegExp->setPattern($this->userProvidedExpression);            
+            if (!$this->casesensitive) {
+                $this->myRegExp->setIgnoreCase(true);
+            }
+            $this->myExpression = $this->myRegExp->getRegexp($this->getProject());
+        }
+                        
+        $in = null;
+        try {
+            $in = new BufferedReader(new FileReader($file));        
+            $teststr = $in->readLine();
+            while ($teststr !== null) {
+                if ($this->myExpression->matches($teststr)) {
+                    return true;
+                }
+                $teststr = $in->readLine();
+            }
+            return false;
+        } catch (IOException $ioe) {
+            if ($in) $in->close();
+            throw new BuildException("Could not read file " . $filename);
+        }
+        $in->close();                
+    }
+
+}
+
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/types/selectors/ContainsSelector.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/types/selectors/ContainsSelector.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/types/selectors/ContainsSelector.php	(revision 19)
@@ -0,0 +1,151 @@
+<?php
+
+/*
+ * $Id: ContainsSelector.php 123 2006-09-14 20:19:08Z mrook $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+include_once 'phing/types/selectors/BaseExtendSelector.php';
+
+/**
+ * Selector that filters files based on whether they contain a
+ * particular string.
+ * 
+ * @author Hans Lellelid <hans@xmpl.org> (Phing)
+ * @author Bruce Atherton <bruce@callenish.com> (Ant)
+ * @package phing.types.selectors
+ */
+class ContainsSelector extends BaseExtendSelector {
+
+    private $contains = null;
+    private $casesensitive = true;
+    const CONTAINS_KEY = "text";
+    const CASE_KEY = "casesensitive";
+
+    public function toString() {
+        $buf = "{containsselector text: ";
+        $buf .= $this->contains;
+        $buf .= " casesensitive: ";
+        if ($this->casesensitive) {
+            $buf .= "true";
+        } else {
+            $buf .= "false";
+        }
+        $buf .= "}";
+        return $buf;
+    }
+
+    /**
+     * The string to search for within a file.
+     *
+     * @param string $contains the string that a file must contain to be selected.
+     */
+    public function setText($contains) {
+        $this->contains = $contains;
+    }
+
+    /**
+     * Whether to ignore case in the string being searched.
+     *
+     * @param boolean $casesensitive whether to pay attention to case sensitivity
+     */
+    public function setCasesensitive($casesensitive) {
+        $this->casesensitive = $casesensitive;
+    }
+
+    /**
+     * When using this as a custom selector, this method will be called.
+     * It translates each parameter into the appropriate setXXX() call.
+     *
+     * @param array $parameters the complete set of parameters for this selector
+     */
+    public function setParameters($parameters) {
+        parent::setParameters($parameters);
+        if ($parameters !== null) {
+            for ($i=0,$size=count($parameters); $i < $size; $i++) {
+                $paramname = $parameters[$i]->getName();
+                switch(strtolower($paramname)) {
+                    case self::CONTAINS_KEY:
+                        $this->setText($parameters[$i]->getValue());
+                        break;
+                    case self::CASE_KEY:
+                        $this->setCasesensitive($parameters[$i]->getValue());
+                        break;
+                    default:
+                        $this->setError("Invalid parameter " . $paramname);
+                }                
+            } // for each param
+        } // if params
+    }
+
+    /**
+     * Checks to make sure all settings are kosher. In this case, it
+     * means that the pattern attribute has been set.
+     *
+     */
+    public function verifySettings() {
+        if ($this->contains === null) {
+            $this->setError("The text attribute is required");
+        }
+    }
+
+    /**
+     * The heart of the matter. This is where the selector gets to decide
+     * on the inclusion of a file in a particular fileset.
+     *
+     * @param basedir the base directory the scan is being done from
+     * @param filename is the name of the file to check
+     * @param file a PhingFile object the selector can use
+     * @return whether the file should be selected or not
+     */
+    public function isSelected(PhingFile $basedir, $filename, PhingFile $file) {
+
+        $this->validate();
+
+        if ($file->isDirectory()) {
+            return true;
+        }
+
+        $userstr = $this->contains;
+        if (!$this->casesensitive) {
+            $userstr = strtolower($this->contains);
+        }
+        
+        $in = null;
+        try {
+            $in = new BufferedReader(new FileReader($file));        
+            $teststr = $in->readLine();
+            while ($teststr !== null) {
+                if (!$this->casesensitive) {
+                    $teststr = strtolower($teststr);
+                }
+                if (strpos($teststr, $userstr) !== false) {
+                    return true;
+                }
+                $teststr = $in->readLine();
+            }
+            return false;
+        } catch (IOException $ioe) {
+            if ($in) $in->close();
+            throw new BuildException("Could not read file " . $filename);
+        }
+        $in->close();                
+    }
+
+}
+
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/types/selectors/DateSelector.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/types/selectors/DateSelector.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/types/selectors/DateSelector.php	(revision 19)
@@ -0,0 +1,214 @@
+<?php
+
+/*
+ * $Id: DateSelector.php 123 2006-09-14 20:19:08Z mrook $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+require_once 'phing/types/selectors/BaseExtendSelector.php';
+
+/**
+ * Selector that chooses files based on their last modified date. Ant uses
+ * millisecond precision (thanks to Java); PHP is forced to use only seconds
+ * precision.
+ *
+ * @author    Hans Lellelid <hans@xmpl.org> (Phing)
+ * @author    Bruce Atherton <bruce@callenish.com> (Ant)
+ * @version   $Revision: 1.10 $
+ * @package   phing.types.selecctors
+ */
+class DateSelector extends BaseExtendSelector {
+
+    private $seconds = -1; // millis in Ant, but PHP doesn't support that level of precision
+    private $dateTime = null;
+    private $includeDirs = false;
+    private $granularity = 0;
+    private $cmp = 2;
+    const MILLIS_KEY = "millis";
+    const DATETIME_KEY = "datetime";
+    const CHECKDIRS_KEY = "checkdirs";
+    const GRANULARITY_KEY = "granularity";
+    const WHEN_KEY = "when";
+    private static $timeComparisons = array("before", "after", "equal");
+    
+    public function __construct() {
+        //if (Os.isFamily("dos")) {
+        //    granularity = 2000;
+        //}
+    }
+
+    public function toString() {
+        $buf = "{dateselector date: ";
+        $buf .= $this->dateTime;
+        $buf .= " compare: ";
+        if ($this->cmp === 0) {
+            $buf .= "before";
+        } elseif ($this->cmp === 1) {
+            $buf .= "after";
+        } else {
+            $buf .= "equal";
+        }
+        $buf .= " granularity: ";
+        $buf .= $this->granularity;
+        $buf .= "}";
+        return $buf;
+    }
+
+    /**
+     * For users that prefer to express time in seconds since 1970
+     *
+     * @param int $seconds the time to compare file's last modified date to,
+     *        expressed in milliseconds
+     */
+    public function setSeconds($seconds) {
+        $this->seconds = (int) $seconds;
+    }
+
+    /**
+     * Returns the seconds value the selector is set for.
+     */
+    public function getSeconds() {
+        return $this->seconds;
+    }
+
+    /**
+     * Sets the date. The user must supply it in MM/DD/YYYY HH:MM AM_PM
+     * format
+     *
+     * @param string $dateTime a string in MM/DD/YYYY HH:MM AM_PM format
+     */
+    public function setDatetime($dateTime) {        
+        $dt = strtotime($dateTime);
+        if ($dt == -1) {
+            $this->setError("Date of " . $dateTime
+                        . " Cannot be parsed correctly. It should be in"
+                        . " a format parsable by PHP's strtotime() function.");
+        } else {        
+            $this->dateTime = $dateTime;
+            $this->setSeconds($dt);
+        }
+    }
+
+    /**
+     * Should we be checking dates on directories?
+     *
+     * @param boolean $includeDirs whether to check the timestamp on directories
+     */
+    public function setCheckdirs($includeDirs) {
+        $this->includeDirs = (boolean) $includeDirs;
+    }
+
+    /**
+     * Sets the number of milliseconds leeway we will give before we consider
+     * a file not to have matched a date.
+     * @param int $granularity
+     */
+    public function setGranularity($granularity) {
+        $this->granularity = (int) $granularity;
+    }
+
+    /**
+     * Sets the type of comparison to be done on the file's last modified
+     * date.
+     *
+     * @param string $cmp The comparison to perform
+     */
+    public function setWhen($cmp) {
+        $idx = array_search($cmp, self::$timeComparisons, true);
+        if ($idx === null) {
+            $this->setError("Invalid value for ".WHEN_KEY.": ".$cmp);
+        } else {
+            $this->cmp = $idx;
+        }
+    }
+
+    /**
+     * When using this as a custom selector, this method will be called.
+     * It translates each parameter into the appropriate setXXX() call.
+     *
+     * @param array $parameters the complete set of parameters for this selector
+     */
+    public function setParameters($parameters) {
+        parent::setParameters($parameters);
+        if ($parameters !== null) {
+            for ($i=0,$size=count($parameters); $i < $size; $i++) {
+                $paramname = $parameters[$i]->getName();
+                switch(strtolower($paramname)) {
+                    case self::MILLIS_KEY:
+                        $this->setMillis($parameters[$i]->getValue());
+                        break;
+                    case self::DATETIME_KEY:
+                        $this->setDatetime($parameters[$i]->getValue());
+                        break;
+                    case self::CHECKDIRS_KEY:
+                        $this->setCheckdirs($parameters[$i]->getValue());
+                        break;                    
+                    case self::GRANULARITY_KEY:
+                        $this->setGranularity($parameters[$i]->getValue());
+                        break;
+                    case self::WHEN_KEY:
+                        $this->setWhen($parameters[$i]->getValue());
+                        break;
+                    default:
+                        $this->setError("Invalid parameter " . $paramname);
+                } // switch
+            }
+        }
+    }
+
+    /**
+     * This is a consistency check to ensure the selector's required
+     * values have been set.
+     */
+    public function verifySettings() {
+        if ($this->dateTime === null && $this->seconds < 0) {
+            $this->setError("You must provide a datetime or the number of "
+                . "seconds.");
+        } elseif ($this->seconds < 0) {
+            $this->setError("Date of " . $this->dateTime
+                . " results in negative seconds"
+                . " value relative to epoch (January 1, 1970, 00:00:00 GMT).");
+        }
+    }
+
+    /**
+     * The heart of the matter. This is where the selector gets to decide
+     * on the inclusion of a file in a particular fileset.
+     *
+     * @param PhingFile $basedir the base directory the scan is being done from
+     * @param string $filename is the name of the file to check
+     * @param PhingFile $file is a PhingFile object the selector can use
+     * @return boolean Whether the file should be selected or not
+     */
+    public function isSelected(PhingFile $basedir, $filename, PhingFile $file) {
+        $this->validate();
+        if ($file->isDirectory() && ($this->includeDirs === false)) {
+            return true;
+        }
+        if ($this->cmp === 0) {
+            return (($file->lastModified() - $this->granularity) < $this->seconds);
+        } elseif ($this->cmp === 1) {
+            return (($file->lastModified() . $this->granularity) > $this->seconds);
+        } else {
+            return (abs($file->lastModified() -  $this->seconds) <= $this->granularity);
+        }
+    }
+
+}
+
+
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/types/selectors/DependSelector.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/types/selectors/DependSelector.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/types/selectors/DependSelector.php	(revision 19)
@@ -0,0 +1,151 @@
+<?php
+
+/*
+ * $Id: DependSelector.php 123 2006-09-14 20:19:08Z mrook $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+require_once 'phing/types/selectors/BaseSelector.php';
+ 
+/**
+ * Selector that filters files based on whether they are newer than
+ * a matching file in another directory tree. It can contain a mapper
+ * element, so isn't available as an ExtendSelector (since those
+ * parameters can't hold other elements).
+ *
+ * @author    Hans Lellelid <hans@xmpl.org> (Phing)
+ * @author    Bruce Atherton <bruce@callenish.com> (Ant)
+ * @version   $Revision: 1.8 $
+ * @package   phing.types.selectors
+ */
+class DependSelector extends BaseSelector {
+
+    private $targetdir = null;
+    private $mapperElement = null;
+    private $map = null;
+    private $granularity = 0;
+
+    public function __construct() {
+        // not yet supported:
+        //if (Os.isFamily("dos")) {
+        //    $this->granularity = 2000;
+        //}
+    }
+
+    public function toString() {
+        $buf = "{dependselector targetdir: ";
+        if ($this->targetdir === null) {
+            $buf .= "NOT YET SET";
+        } else {
+            $buf .= $this->targetdir->getName();
+        }        
+        $buf .= " granularity: ";
+        $buf .= $this->granularity;
+        if ($this->map !== null) {
+            $buf .= " mapper: ";
+            $buf .= $this->map->toString();
+        } elseif ($this->mapperElement !== null) {
+            $buf .= " mapper: ";
+            $buf .= $this->mapperElement->toString();
+        }
+        $buf .= "}";
+        return $buf;
+    }
+
+    /**
+     * The name of the file or directory which is checked for out-of-date
+     * files.
+     *
+     * @param targetdir the directory to scan looking for files.
+     */
+    public function setTargetdir(PhingFile $targetdir) {
+        $this->targetdir = $targetdir;
+    }
+
+    /**
+     * Sets the number of milliseconds leeway we will give before we consider
+     * a file out of date.
+     */
+    public function setGranularity($granularity) {
+        $this->granularity = (int) granularity;
+    }
+
+    /**
+     * Defines the FileNameMapper to use (nested mapper element).
+     * @throws BuildException
+     */
+    public function createMapper() {
+        if ($this->mapperElement !== null) {
+            throw new BuildException("Cannot define more than one mapper");
+        }
+        $this->mapperElement = new Mapper($this->project);
+        return $this->mapperElement;
+    }
+
+
+    /**
+     * Checks to make sure all settings are kosher. In this case, it
+     * means that the dest attribute has been set and we have a mapper.
+     */
+    public function verifySettings() {
+        if ($this->targetdir === null) {
+            $this->setError("The targetdir attribute is required.");
+        }
+        if ($this->mapperElement === null) {
+            $this->map = new IdentityMapper();
+        } else {
+            $this->map = $this->mapperElement->getImplementation();
+        }
+        if ($this->map === null) {
+            $this->setError("Could not set <mapper> element.");
+        }
+    }
+
+    /**
+     * The heart of the matter. This is where the selector gets to decide
+     * on the inclusion of a file in a particular fileset.
+     *
+     * @param basedir the base directory the scan is being done from
+     * @param filename is the name of the file to check
+     * @param file is a PhingFile object the selector can use
+     * @return whether the file should be selected or not
+     */
+    public function isSelected(PhingFile $basedir, $filename, PhingFile $file) {
+
+        $this->validate();
+        
+        // Determine file whose out-of-dateness is to be checked
+        $destfiles = $this->map->main($filename);
+        
+        // If filename does not match the To attribute of the mapper
+        // then filter it out of the files we are considering
+        if ($destfiles === null) {
+            return false;
+        }
+        // Sanity check
+        if (count($destfiles) !== 1 || $destfiles[0] === null) {
+            throw new BuildException("Invalid destination file results for " . $this->targetdir . " with filename " . $filename);
+        }
+        $destname = $destfiles[0];
+        $destfile = new PhingFile($this->targetdir, $destname);
+
+        return SelectorUtils::isOutOfDate($file, $destfile, $this->granularity);
+    }
+
+}
+
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/types/selectors/DepthSelector.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/types/selectors/DepthSelector.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/types/selectors/DepthSelector.php	(revision 19)
@@ -0,0 +1,158 @@
+<?php
+/*
+ * $Id: DepthSelector.php 123 2006-09-14 20:19:08Z mrook $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+ 
+require_once 'phing/types/selectors/BaseExtendSelector.php';
+
+/**
+ * Selector that filters files based on the how deep in the directory
+ * tree they are.
+ *
+ * @author    Hans Lellelid <hans@xmpl.org> (Phing)
+ * @author    Bruce Atherton <bruce@callenish.com> (Ant)
+ * @version   $Revision: 1.7 $
+ * @package   phing.types.selectors
+ */
+class DepthSelector extends BaseExtendSelector {
+
+    public $min = -1;
+    public $max = -1;
+    const MIN_KEY = "min";
+    const MAX_KEY = "max";
+
+    public function toString() {
+        $buf = "{depthselector min: ";
+        $buf .= $this->min;
+        $buf .= " max: ";
+        $buf .= $this->max;
+        $buf .= "}";
+        return $buf;
+    }
+
+    /**
+     * The minimum depth below the basedir before a file is selected.
+     *
+     * @param min minimum directory levels below basedir to go
+     */
+    public function setMin($min) {
+        $this->min = (int) $min;
+    }
+
+    /**
+     * The minimum depth below the basedir before a file is selected.
+     *
+     * @param min maximum directory levels below basedir to go
+     */
+    public function setMax($max) {
+        $this->max = (int) $max;
+    }
+
+    /**
+     * When using this as a custom selector, this method will be called.
+     * It translates each parameter into the appropriate setXXX() call.
+     *
+     * @param parameters the complete set of parameters for this selector
+     */
+    public function setParameters($parameters) {
+        parent::setParameters($parameters);
+        if ($parameters !== null) {
+            for ($i = 0, $size=count($parameters); $i < $size; $i++) {
+                $paramname = $parameters[$i]->getName();
+                switch(strtolower($paramname)) {
+                    case self::MIN_KEY:
+                        $this->setMin($parameters[$i]->getValue());
+                        break;
+                    case self::MAX_KEY:
+                        $this->setMax($parameters[$i]->getValue());
+                        break;
+                        
+                    default:
+                        $this->setError("Invalud parameter " . $paramname);
+                } // switch                
+            }
+        }
+    }
+
+    /**
+     * Checks to make sure all settings are kosher. In this case, it
+     * means that the max depth is not lower than the min depth.
+     */
+    public function verifySettings() {
+        if ($this->min < 0 && $this->max < 0) {
+            $this->setError("You must set at least one of the min or the " .
+                    "max levels.");
+        }
+        if ($this->max < $this->min && $this->max > -1) {
+            $this->setError("The maximum depth is lower than the minimum.");
+        }
+    }
+
+    /**
+     * The heart of the matter. This is where the selector gets to decide
+     * on the inclusion of a file in a particular fileset. Most of the work
+     * for this selector is offloaded into SelectorUtils, a static class
+     * that provides the same services for both FilenameSelector and
+     * DirectoryScanner.
+     *
+     * @param basedir the base directory the scan is being done from
+     * @param filename is the name of the file to check
+     * @param file is a PhingFile object the selector can use
+     * @return whether the file should be selected or not
+     */
+    public function isSelected(PhingFile $basedir, $filename, PhingFile $file) {
+
+        $this->validate();
+
+        $depth = -1;
+        // If you felt daring, you could cache the basedir absolute path
+        $abs_base = $basedir->getAbsolutePath();
+        $abs_file = $file->getAbsolutePath();
+        
+        $tok_base = explode(DIRECTORY_SEPARATOR, $abs_base);
+        $tok_file = explode(DIRECTORY_SEPARATOR, $abs_file);
+        
+        for($i=0,$size=count($tok_file); $i < $size; $i++) {
+            $filetoken = $tok_file[$i];
+            if (isset($tok_base[$i])) {
+                $basetoken = $tok_base[$i];
+                // Sanity check. Ditch it if you want faster performance
+                if ($basetoken !== $filetoken) {
+                    throw new BuildException("File " . $filename .
+                        " does not appear within " . $abs_base . "directory");
+                }
+            } else { // no more basepath tokens
+                $depth++;
+                if ($this->max > -1 && $depth > $this->max) {
+                    return false;
+                }
+            }
+        }
+        if (isset($tok_base[$i + 1])) {
+            throw new BuildException("File " . $filename .
+                " is outside of " . $abs_base . "directory tree");
+        }
+        if ($this->min > -1 && $depth < $this->min) {
+            return false;
+        }
+        return true;
+    }
+
+}
+
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/types/selectors/ExtendFileSelector.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/types/selectors/ExtendFileSelector.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/types/selectors/ExtendFileSelector.php	(revision 19)
@@ -0,0 +1,43 @@
+<?php
+
+/*
+ * $Id: ExtendFileSelector.php 123 2006-09-14 20:19:08Z mrook $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+require_once 'phing/types/Parameterizable.php';
+require_once 'phing/types/selectors/FileSelector.php';
+
+/**
+ * This is the interface to be used by all custom selectors, those that are
+ * called through the &lt;custom&gt; tag. It is the amalgamation of two
+ * interfaces, the FileSelector and the Paramterizable interface. Note that
+ * you will almost certainly want the default behaviour for handling
+ * Parameters, so you probably want to use the BaseExtendSelector class
+ * as the base class for your custom selector rather than implementing
+ * this interface from scratch.
+ *
+ * @author Hans Lellelid <hans@xmpl.org> (Phing)
+ * @author Bruce Atherton <bruce@callenish.com> (Ant)
+ * @package phing.types.selectors
+ */
+interface ExtendFileSelector extends Parameterizable, FileSelector {
+  // No further methods necessary. This is just an amalgamation of two other
+  // interfaces.
+}
+
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/types/selectors/ExtendSelector.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/types/selectors/ExtendSelector.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/types/selectors/ExtendSelector.php	(revision 19)
@@ -0,0 +1,124 @@
+<?php
+
+/*
+ * $Id: ExtendSelector.php 277 2007-11-01 01:25:23Z hans $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+include_once 'phing/util/StringHelper.php';
+
+/**
+ * Selector that selects files by forwarding the request on to other classes.
+ *
+ * TODO - Consider adding Path (phing.types.Path) support to this class
+ *         and to the Mappers class.  See Ant versions for implimentation details.
+ * 
+ * @author Hans Lellelid <hans@xmpl.org> (Phing)
+ * @author Bruce Atherton <bruce@callenish.com> (Ant)
+ * @package phing.types.selectors
+ */
+class ExtendSelector extends BaseSelector {
+
+    private $classname;
+    private $dynselector;
+    private $parameters = array();
+
+    /**
+     * Sets the classname of the custom selector.
+     *
+     * @param classname is the class which implements this selector
+     */
+    public function setClassname($classname) {
+        $this->classname = $classname;
+    }
+
+    /**
+     * Instantiates the identified custom selector class.
+     */
+    public function selectorCreate() {
+        if ($this->classname !== null && $this->classname !== "") {      
+            try {
+                // assume it's fully qualified, import it
+                $cls = Phing::import($this->classname);
+       
+                // make sure class exists
+                if (class_exists($cls)) {
+                    $this->dynselector = new $cls();
+                } else {
+                    $this->setError("Selector " . $this->classname . " not initialized, no such class");
+                }            
+            } catch (Exception $e) {
+                $this->setError("Selector " . $this->classname . " not initialized, could not create class: " . $e->getMessage());
+            }            
+        } else {
+            $this->setError("There is no classname specified");
+        }
+    }
+
+    /**
+     * Create new parameters to pass to custom selector.
+     *
+     * @param p The new Parameter object
+     */
+    public function addParam(Parameter $p) {
+        $this->parameters[] = $p;
+    }
+
+    /**
+     * These are errors specific to ExtendSelector only. If there are
+     * errors in the custom selector, it should throw a BuildException
+     * when isSelected() is called.
+     */
+    public function verifySettings() {
+        // Creation is done here rather than in isSelected() because some
+        // containers may do a validation pass before running isSelected(),
+        // but we need to check for the existence of the created class.
+        if ($this->dynselector === null) {
+            $this->selectorCreate();
+        }
+        
+        if (empty($this->classname)) {
+            $this->setError("The classname attribute is required");
+        } elseif ($this->dynselector === null) {
+            $this->setError("Internal Error: The custom selector was not created");
+        } elseif ( !($this->dynselector instanceof ExtendFileSelector) && (count($this->parameters) > 0)) {
+            $this->setError("Cannot set parameters on custom selector that does not "
+                   . "implement ExtendFileSelector.");
+        }
+    }
+
+
+    /**
+     * Allows the custom selector to choose whether to select a file. This
+     * is also where the Parameters are passed to the custom selector.
+     *
+     * @throws BuildException
+     */
+    public function isSelected(PhingFile $basedir, $filename, PhingFile $file) {
+        
+        $this->validate();
+        
+        if (count($this->parameters) > 0 && $this->dynselector instanceof ExtendFileSelector) {            
+            // We know that dynselector must be non-null if no error message
+            $this->dynselector->setParameters($this->parameters);
+        }
+        return $this->dynselector->isSelected($basedir, $filename, $file);
+    }
+
+}
+
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/types/selectors/FileSelector.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/types/selectors/FileSelector.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/types/selectors/FileSelector.php	(revision 19)
@@ -0,0 +1,47 @@
+<?php
+
+/*
+ * $Id: FileSelector.php 123 2006-09-14 20:19:08Z mrook $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+/**
+ * This is the interface to be used by all selectors.
+ *
+ * @author Hans Lellelid, hans@xmpl.org (Phing)
+ * @author Bruce Atherton, bruce@callenish.com (Ant)
+ * @package phing.types.selectors
+ */
+interface FileSelector {
+
+    /**
+     * Method that each selector will implement to create their
+     * selection behaviour. If there is a problem with the setup
+     * of a selector, it can throw a BuildException to indicate
+     * the problem.
+     *
+     * @param basedir A PhingFile object for the base directory
+     * @param filename The name of the file to check
+     * @param file A PhingFile object for this filename
+     * @return whether the file should be selected or not
+     * @throws BuildException if the selector was not configured correctly
+     */
+    public function isSelected(PhingFile $basedir, $filename, PhingFile $file);
+
+}
+
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/types/selectors/FilenameSelector.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/types/selectors/FilenameSelector.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/types/selectors/FilenameSelector.php	(revision 19)
@@ -0,0 +1,157 @@
+<?php
+
+/*
+ * $Id: FilenameSelector.php 123 2006-09-14 20:19:08Z mrook $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+
+include_once 'phing/types/selectors/BaseExtendSelector.php';
+
+/**
+ * Selector that filters files based on the filename.
+ *
+ * @author Hans Lellelid, hans@xmpl.org (Phing)
+ * @author Bruce Atherton, bruce@callenish.com (Ant)
+ * @package phing.types.selectors
+ */
+class FilenameSelector extends BaseExtendSelector {
+
+    private $pattern = null;
+    private $casesensitive = true;
+    private $negated = false;
+    const NAME_KEY = "name";
+    const CASE_KEY = "casesensitive";
+    const NEGATE_KEY = "negate";
+
+    public function toString() {
+        $buf = "{filenameselector name: ";
+        $buf .= $this->pattern;
+        $buf .= " negate: ";
+        if ($this->negated) {
+            $buf .= "true";
+        } else {
+            $buf .= "false";
+        }
+        $buf .= " casesensitive: ";
+        if ($this->casesensitive) {
+            $buf .= "true";
+        } else {
+            $buf .= "false";
+        }
+        $buf .= "}";
+        return $buf;
+    }
+
+    /**
+     * The name of the file, or the pattern for the name, that
+     * should be used for selection.
+     *
+     * @param pattern the file pattern that any filename must match
+     *                against in order to be selected.
+     */
+    public function setName($pattern) {
+        $pattern = str_replace('\\', DIRECTORY_SEPARATOR, $pattern);
+        $pattern = str_replace('/', DIRECTORY_SEPARATOR, $pattern);
+                
+        if (StringHelper::endsWith(DIRECTORY_SEPARATOR, $pattern)) {
+            $pattern .= "**";
+        }
+        $this->pattern = $pattern;
+    }
+
+    /**
+     * Whether to ignore case when checking filenames.
+     *
+     * @param casesensitive whether to pay attention to case sensitivity
+     */
+    public function setCasesensitive($casesensitive) {
+        $this->casesensitive = $casesensitive;
+    }
+
+    /**
+     * You can optionally reverse the selection of this selector,
+     * thereby emulating an &lt;exclude&gt; tag, by setting the attribute
+     * negate to true. This is identical to surrounding the selector
+     * with &lt;not&gt;&lt;/not&gt;.
+     *
+     * @param negated whether to negate this selection
+     */
+    public function setNegate($negated) {
+        $this->negated = $negated;
+    }
+
+    /**
+     * When using this as a custom selector, this method will be called.
+     * It translates each parameter into the appropriate setXXX() call.
+     *
+     * @param array $parameters the complete set of parameters for this selector
+     */
+    public function setParameters($parameters) {
+        parent::setParameters($parameters);
+        if ($parameters !== null) {
+            for ($i=0, $len=count($parameters); $i < $len; $i++) {
+                $paramname = $parameters[$i]->getName();
+                switch(strtolower($paramname)) {
+                    case self::NAME_KEY:
+                        $this->setName($parameters[$i]->getValue());
+                        break;
+                    case self::CASE_KEY:
+                        $this->setCasesensitive($parameters[$i]->getValue());
+                        break;
+                    case self::NEGATE_KEY:
+                        $this->setNegate($parameters[$i]->getValue());
+                        break;
+                    default:
+                        $this->setError("Invalid parameter " . $paramname);
+                }
+            } // for each param
+        } // if params
+    }
+
+    /**
+     * Checks to make sure all settings are kosher. In this case, it
+     * means that the name attribute has been set.
+     *
+     */
+    public function verifySettings() {
+        if ($this->pattern === null) {
+            $this->setError("The name attribute is required");
+        }
+    }
+
+    /**
+     * The heart of the matter. This is where the selector gets to decide
+     * on the inclusion of a file in a particular fileset. Most of the work
+     * for this selector is offloaded into SelectorUtils, a static class
+     * that provides the same services for both FilenameSelector and
+     * DirectoryScanner.
+     *
+     * @param basedir the base directory the scan is being done from
+     * @param filename is the name of the file to check
+     * @param file is a PhingFile object the selector can use
+     * @return whether the file should be selected or not
+     */
+    public function isSelected(PhingFile $basedir, $filename, PhingFile $file) {
+        $this->validate();
+        return (SelectorUtils::matchPath($this->pattern, $filename, $this->casesensitive) 
+            === !($this->negated));
+    }
+
+}
+
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/types/selectors/MajoritySelector.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/types/selectors/MajoritySelector.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/types/selectors/MajoritySelector.php	(revision 19)
@@ -0,0 +1,92 @@
+<?php
+
+/*
+ * $Id: MajoritySelector.php 123 2006-09-14 20:19:08Z mrook $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+
+/**
+ * This selector is here just to shake up your thinking a bit. Don't get
+ * too caught up in boolean, there are other ways you can evaluate a
+ * collection of selectors. This one takes a vote of the selectors it
+ * contains, and majority wins. You could also have an "all-but-one"
+ * selector, a "weighted-average" selector, and so on. These are left
+ * as exercises for the reader (as are the usecases where this would
+ * be necessary).
+ *
+ * @author Hans Lellelid <hans@xmpl.org> (Phing)
+ * @author Bruce Atherton <bruce@callenish.com> (Ant)
+ * @package phing.types.selectors
+ */
+class MajoritySelector extends BaseSelectorContainer {
+
+    private $allowtie = true;
+
+    public function toString() {
+        $buf = "";
+        if ($this->hasSelectors()) {
+            $buf .= "{majorityselect: ";
+            $buf .= parent::toString();
+            $buf .= "}";
+        }
+        return $buf;
+    }
+
+    public function setAllowtie($tiebreaker) {
+        $this->allowtie = $tiebreaker;
+    }
+
+    /**
+     * Returns true (the file is selected) if most of the other selectors
+     * agree. In case of a tie, go by the allowtie setting. That defaults
+     * to true, meaning in case of a tie, the file is selected.
+     *
+     * @param basedir the base directory the scan is being done from
+     * @param filename is the name of the file to check
+     * @param file is a PhingFile object for the filename that the selector
+     * can use
+     * @return whether the file should be selected or not
+     */
+    public function isSelected(PhingFile $basedir, $filename, PhingFile $file) {
+        
+        $this->validate();
+        
+        $yesvotes = 0;
+        $novotes = 0;
+        
+        $selectors = $this->selectorElements();
+        for($i=0,$size=count($selectors); $i < $size; $i++) {
+            $result = $selectors[$i]->isSelected($basedir,$filename,$file);
+            if ($result) {
+                $yesvotes = $yesvotes + 1;
+            } else {
+                $novotes = $novotes + 1;
+            }
+        }
+        if ($yesvotes > $novotes) {
+            return true;
+        }
+        else if ($novotes > $yesvotes) {
+            return false;
+        }
+        // At this point, we know we have a tie.
+        return $this->allowtie;
+    }
+}
+
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/types/selectors/NoneSelector.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/types/selectors/NoneSelector.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/types/selectors/NoneSelector.php	(revision 19)
@@ -0,0 +1,71 @@
+<?php
+/*
+ * $Id: NoneSelector.php 123 2006-09-14 20:19:08Z mrook $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+ 
+require_once 'phing/types/selectors/BaseSelectorContainer.php';
+
+/**
+ * This selector has a collection of other selectors. All of those selectors
+ * must refuse to select a file before the file is considered selected by
+ * this selector.
+ *
+ * @author Hans Lellelid <hans@xmpl.org>
+ * @author Bruce Atherton <bruce@callenish.com> (Ant)
+ * @package phing.types.selectors
+ */
+class NoneSelector extends BaseSelectorContainer {
+
+    public function toString() {
+        $buf = "";
+        if ($this->hasSelectors()) {
+            $buf .= "{noneselect: ";
+            $buf .= parent::toString();
+            $buf .= "}";
+        }
+        return $buf;
+    }
+
+    /**
+     * Returns true (the file is selected) only if all other selectors
+     * agree that the file should not be selected.
+     *
+     * @param basedir the base directory the scan is being done from
+     * @param filename is the name of the file to check
+     * @param file is a java.io.File object for the filename that the selector
+     * can use
+     * @return whether the file should be selected or not
+     */
+    public function isSelected(PhingFile $basedir, $filename, PhingFile $file) {
+        
+        $this->validate();
+        
+        $selectors = $this->selectorElements();        
+
+        for($i=0,$size=count($selectors); $i < $size; $i++) {
+            $result = $selectors[$i]->isSelected($basedir, $filename, $file);
+            if ($result) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+}
+
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/types/selectors/NotSelector.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/types/selectors/NotSelector.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/types/selectors/NotSelector.php	(revision 19)
@@ -0,0 +1,59 @@
+<?php
+
+/*
+ * $Id: NotSelector.php 123 2006-09-14 20:19:08Z mrook $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+require_once 'phing/types/selectors/NoneSelector.php';
+
+/**
+ * This selector has one other selectors whose meaning it inverts. It
+ * actually relies on NoneSelector for its implementation of the
+ * isSelected() method, but it adds a check to ensure there is only one
+ * other selector contained within.
+ *
+ * @author Hans Lellelid <hans@xmpl.org> (Phing)
+ * @author Bruce Atherton <bruce@callenish.com> (Ant)
+ * @package phing.types.selectors
+ */
+class NotSelector extends NoneSelector {
+
+    public function toString() {
+        $buf = "";
+        if ($this->hasSelectors()) {
+            $buf .= "{notselect: ";
+            $buf .= parent::toString();
+            $buf .= "}";
+        }
+        return $buf;
+    }
+
+    /**
+     * Makes sure that there is only one entry, sets an error message if
+     * not.
+     */
+    public function verifySettings() {
+        if ($this->selectorCount() != 1) {
+            $this->setError("One and only one selector is allowed within the " .
+                    "<not> tag");
+        }
+    }
+
+}
+
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/types/selectors/OrSelector.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/types/selectors/OrSelector.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/types/selectors/OrSelector.php	(revision 19)
@@ -0,0 +1,72 @@
+<?php
+/*
+ * $Id: OrSelector.php 123 2006-09-14 20:19:08Z mrook $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+require_once 'phing/types/selectors/BaseSelectorContainer.php';
+ 
+/**
+ * This selector has a collection of other selectors, any of which have to
+ * select a file in order for this selector to select it.
+ *
+ * @author Hans Lellelid <hans@xmpl.org> (Phing)
+ * @author Bruce Atherton <bruce@callenish.com> (Ant)
+ * @package phing.types.selectors
+ */
+class OrSelector extends BaseSelectorContainer {
+
+    public function toString() {
+        $buf = "";
+        if ($this->hasSelectors()) {
+            $buf .= "{orselect: ";
+            $buf .= parent::toString();
+            $buf .= "}";
+        }
+        return $buf;
+    }
+
+    /**
+     * Returns true (the file is selected) if any of the other selectors
+     * agree that the file should be selected.
+     *
+     * @param basedir the base directory the scan is being done from
+     * @param filename the name of the file to check
+     * @param file a PhingFile object for the filename that the selector
+     * can use
+     * @return boolean Whether the file should be selected or not
+     */
+    public function isSelected(PhingFile $basedir, $filename, PhingFile $file) {
+        
+        $this->validate();
+        
+        $selectors = $this->selectorElements();
+
+        // First, check that all elements are correctly configured
+        
+        for($i=0,$size=count($selectors); $i < $size; $i++) {
+            $result = $selectors[$i]->isSelected($basedir, $filename, $file);
+            if ($result) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+}
+
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/types/selectors/PresentSelector.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/types/selectors/PresentSelector.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/types/selectors/PresentSelector.php	(revision 19)
@@ -0,0 +1,154 @@
+<?php
+
+/*
+ * $Id: PresentSelector.php 123 2006-09-14 20:19:08Z mrook $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+/**
+ * Selector that filters files based on whether they appear in another
+ * directory tree. It can contain a mapper element, so isn't available
+ * as an ExtendSelector (since those parameters can't hold other
+ * elements).
+ *
+ * @author Hans Lellelid <hans@xmpl.org> (Phing)
+ * @author Bruce Atherton <bruce@callenish.com> (Ant)
+ * @package phing.types.selectors
+ */
+class PresentSelector extends BaseSelector {
+
+    private $targetdir = null;
+    private $mapperElement = null;
+    private $map = null;
+    private $destmustexist = true;
+    private static $filePresence = array("srconly", "both");
+    
+    public function toString() {
+        $buf = "{presentselector targetdir: ";
+        if ($this->targetdir === null) {
+            $buf .= "NOT YET SET";
+        } else {
+            $buf .= $this->targetdir->getName();
+        }
+        $buf .= " present: ";
+        if ($this->destmustexist) {
+            $buf .= "both";
+        } else {
+            $buf .= "srconly";
+        }
+        if ($this->map !== null) {
+            $buf .= $this->map->toString();
+        } elseif ($this->mapperElement !== null) {
+            $buf .= $this->mapperElement->toString();
+        }
+        $buf .= "}";
+        return $buf;
+    }
+
+    /**
+     * The name of the file or directory which is checked for matching
+     * files.
+     *
+     * @param targetdir the directory to scan looking for matching files.
+     */
+    public function setTargetdir(PhingFile $targetdir) {
+        $this->targetdir = $targetdir;
+    }
+
+    /**
+     * Defines the FileNameMapper to use (nested mapper element).
+     * @throws BuildException 
+     */
+    public function createMapper() {
+        if ($this->mapperElement !== null) {
+            throw new BuildException("Cannot define more than one mapper");
+        }
+        $this->mapperElement = new Mapper($this->getProject());
+        return $this->mapperElement;
+    }
+
+
+    /**
+     * This sets whether to select a file if its dest file is present.
+     * It could be a <code>negate</code> boolean, but by doing things
+     * this way, we get some documentation on how the system works.
+     * A user looking at the documentation should clearly understand
+     * that the ONLY files whose presence is being tested are those
+     * that already exist in the source directory, hence the lack of
+     * a <code>destonly</code> option.
+     *
+     * @param string $fp An attribute set to either <code>srconly</code or
+     *           ><code>both</code>.
+     */
+    public function setPresent($fp) {
+        $idx = array_search($fp, self::$filePresence, true);
+        if ( $idx === 0 ) {
+            $this->destmustexist = false;
+        }
+    }
+
+    /**
+     * Checks to make sure all settings are kosher. In this case, it
+     * means that the targetdir attribute has been set and we have a mapper.
+     */
+    public function verifySettings() {
+        if ($this->targetdir === null) {
+            $this->setError("The targetdir attribute is required.");
+        }
+        if ($this->mapperElement === null) {
+            $this->map = new IdentityMapper();
+        } else {
+            $this->map = $this->mapperElement->getImplementation();
+        }
+        if ($this->map === null) {
+            $this->setError("Could not set <mapper> element.");
+        }
+    }
+
+    /**
+     * The heart of the matter. This is where the selector gets to decide
+     * on the inclusion of a file in a particular fileset.
+     *
+     * @param basedir the base directory the scan is being done from
+     * @param filename is the name of the file to check
+     * @param file is a PhingFile object the selector can use
+     * @return whether the file should be selected or not
+     */
+    public function isSelected(PhingFile $basedir, $filename, PhingFile $file) {
+
+        $this->validate();
+
+        // Determine file whose existence is to be checked
+        $destfiles = $this->map->main($filename);
+        // If filename does not match the To attribute of the mapper
+        // then filter it out of the files we are considering
+        if ($destfiles === null) {
+            return false;
+        }
+        // Sanity check
+        if (count($destfiles) !== 1 || $destfiles[0] === null) {
+            throw new BuildException("Invalid destination file results for "
+                . $this->targetdir . " with filename " . $filename);
+        }
+        $destname = $destfiles[0];
+        $destfile = new PhingFile($this->targetdir, $destname);
+        return $destfile->exists() === $this->destmustexist;
+    }
+
+}
+
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/types/selectors/SelectSelector.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/types/selectors/SelectSelector.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/types/selectors/SelectSelector.php	(revision 19)
@@ -0,0 +1,124 @@
+<?php
+
+/*
+ * $Id: SelectSelector.php 123 2006-09-14 20:19:08Z mrook $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+require_once 'phing/types/selectors/AndSelector.php';
+
+/**
+ * This selector just holds one other selector and forwards all
+ * requests to it. It exists so that there is a single selector
+ * type that can exist outside of any targets, as an element of
+ * project. It overrides all of the reference stuff so that it
+ * works as expected. Note that this is the only selector you
+ * can reference.
+ *
+ * @author    Hans Lellelid <hans@xmpl.org> (Phing)
+ * @author    Bruce Atherton <bruce@callenish.com> (Ant)
+ * @version   $Revision: 1.6 $
+ * @package   phing.types.selectors
+ */
+class SelectSelector extends AndSelector {
+         
+    public function toString() {
+        $buf = "";
+        if ($this->hasSelectors()) {
+            $buf .= "{select: ";
+            $buf .= parent::toString();
+            $buf .= "}";
+        }
+        return $buf;
+    }
+
+    /**
+     * Performs the check for circular references and returns the
+     * referenced Selector.
+     */
+    private function getRef() {
+        $o = $this->getCheckedRef(get_class($this), "SelectSelector");
+        return $o;
+    }
+
+    /**
+     * Indicates whether there are any selectors here.
+     */
+    public function hasSelectors() {
+        if ($this->isReference()) {
+            return $this->getRef()->hasSelectors();
+        }
+        return parent::hasSelectors();
+    }
+
+    /**
+     * Gives the count of the number of selectors in this container
+     */
+    public function selectorCount() {
+        if ($this->isReference()) {
+            return $this->getRef()->selectorCount();
+        }
+        return parent::selectorCount();
+    }
+
+    /**
+     * Returns the set of selectors as an array.
+     */
+    public function getSelectors(Project $p) {
+        if ($this->isReference()) {
+            return $this->getRef()->getSelectors($p);
+        }
+        return parent::getSelectors($p);
+    }
+
+    /**
+     * Returns an enumerator for accessing the set of selectors.
+     */
+    public function selectorElements() {
+        if ($this->isReference()) {
+            return $this->getRef()->selectorElements();
+        }
+        return parent::selectorElements();
+    }
+
+    /**
+     * Add a new selector into this container.
+     *
+     * @param selector the new selector to add
+     * @return the selector that was added
+     */
+    public function appendSelector(FileSelector $selector) {
+        if ($this->isReference()) {
+            throw $this->noChildrenAllowed();
+        }
+        parent::appendSelector($selector);
+    }
+
+    /**
+     * Makes sure that there is only one entry, sets an error message if
+     * not.
+     */
+    public function verifySettings() {
+        if ($this->selectorCount() != 1) {
+            $this->setError("One and only one selector is allowed within the "
+            . "<selector> tag");
+        }
+    }
+
+}
+
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/types/selectors/SelectorContainer.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/types/selectors/SelectorContainer.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/types/selectors/SelectorContainer.php	(revision 19)
@@ -0,0 +1,141 @@
+<?php
+
+/*
+ * $Id: SelectorContainer.php 123 2006-09-14 20:19:08Z mrook $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+
+/**
+ * This is the interface for selectors that can contain other selectors.
+ *
+ * @author <a href="mailto:bruce@callenish.com">Bruce Atherton</a>
+ * @package phing.types.selectors
+ */
+interface SelectorContainer {
+
+    /**
+     * Indicates whether there are any selectors here.
+     *
+     * @return whether any selectors are in this container
+     */
+    public function hasSelectors();
+
+    /**
+     * Gives the count of the number of selectors in this container
+     *
+     * @return the number of selectors in this container
+     */
+    public function selectorCount();
+
+    /**
+     * Returns a *copy* of the set of selectors as an array.
+     *
+     * @return an array of selectors in this container
+     */
+    public function getSelectors(Project $p);
+
+    /**
+     * Returns an array for accessing the set of selectors.
+     *
+     * @return an enumerator that goes through each of the selectors
+     */
+    public function selectorElements();
+
+    /**
+     * Add a new selector into this container.
+     *
+     * @param selector the new selector to add
+     * @return the selector that was added
+     */
+    public function appendSelector(FileSelector $selector);
+
+    /* Methods below all add specific selectors */
+
+    /**
+     * add a "Select" selector entry on the selector list
+     */
+    public function createSelector();
+
+    /**
+     * add an "And" selector entry on the selector list
+     */
+    public function createAnd();
+
+    /**
+     * add an "Or" selector entry on the selector list
+     */
+    public function createOr();
+
+    /**
+     * add a "Not" selector entry on the selector list
+     */
+    public function createNot();
+
+    /**
+     * add a "None" selector entry on the selector list
+     */
+    public function createNone();
+
+    /**
+     * add a majority selector entry on the selector list
+     */
+    public function createMajority();
+
+    /**
+     * add a selector date entry on the selector list
+     */
+    public function createDate();
+
+    /**
+     * add a selector size entry on the selector list
+     */
+    public function createSize();
+
+    /**
+     * add a selector filename entry on the selector list
+     */
+    public function createFilename();
+
+    /**
+     * add an extended selector entry on the selector list
+     */
+    public function createCustom();
+
+    /**
+     * add a contains selector entry on the selector list
+     */
+    public function createContains();
+
+    /**
+     * add a present selector entry on the selector list
+     */
+    public function createPresent();
+
+    /**
+     * add a depth selector entry on the selector list
+     */
+    public function createDepth();
+
+    /**
+     * add a depends selector entry on the selector list
+     */
+    public function createDepend();
+
+}
+
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/types/selectors/SelectorScanner.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/types/selectors/SelectorScanner.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/types/selectors/SelectorScanner.php	(revision 19)
@@ -0,0 +1,55 @@
+<?php
+
+/*
+ * $Id: SelectorScanner.php 123 2006-09-14 20:19:08Z mrook $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+
+/**
+ * An interface used to describe the actions required by any type of
+ * directory scanner that supports Selecters.
+ *
+ * @author Hans Lellelid <hans@xmpl.org> (Phing)
+ * @author Bruce Atherton <bruce@callenish.com> (Ant)
+ * @package phing.types.selectors
+ */
+interface SelectorScanner {
+
+    /**
+     * Sets the selectors the scanner should use.
+     *
+     * @param selectors the list of selectors
+     */
+    public function setSelectors($selectors);
+
+    /**
+     * Directories which were selected out of a scan.
+     *
+     * @param selectors list selector objects
+     */
+    public function getDeselectedDirectories();
+
+    /**
+     * Files which were selected out of a scan.
+     *
+     * @param selectors list selector objects
+     */
+    public function getDeselectedFiles();
+
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/types/selectors/SelectorUtils.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/types/selectors/SelectorUtils.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/types/selectors/SelectorUtils.php	(revision 19)
@@ -0,0 +1,440 @@
+<?php
+
+/*
+ * $Id: SelectorUtils.php 123 2006-09-14 20:19:08Z mrook $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+ 
+include_once 'phing/util/StringHelper.php';
+
+/**
+ * <p>This is a utility class used by selectors and DirectoryScanner. The
+ * functionality more properly belongs just to selectors, but unfortunately
+ * DirectoryScanner exposed these as protected methods. Thus we have to
+ * support any subclasses of DirectoryScanner that may access these methods.
+ * </p>
+ * <p>This is a Singleton.</p>
+ *
+ * @author Hans Lellelid, hans@xmpl.org (Phing)
+ * @author Arnout J. Kuiper, ajkuiper@wxs.nl (Ant)
+ * @author Magesh Umasankar
+ * @author Bruce Atherton, bruce@callenish.com (Ant)
+ * @package phing.types.selectors
+ */
+class SelectorUtils {
+
+    private static $instance;
+
+     /**
+      * Retrieves the instance of the Singleton.
+      */
+    public static function getInstance() {
+        if (!isset(self::$instance)) {
+            self::$instance = new SelectorUtils();
+        }
+        return self::$instance;
+    }
+
+    /**
+     * Tests whether or not a given path matches the start of a given
+     * pattern up to the first "**".
+     * <p>
+     * This is not a general purpose test and should only be used if you
+     * can live with false positives. For example, <code>pattern=**\a</code>
+     * and <code>str=b</code> will yield <code>true</code>.
+     *
+     * @param pattern The pattern to match against. Must not be
+     *                <code>null</code>.
+     * @param str     The path to match, as a String. Must not be
+     *                <code>null</code>.
+     * @param isCaseSensitive Whether or not matching should be performed
+     *                        case sensitively.
+     *
+     * @return whether or not a given path matches the start of a given
+     * pattern up to the first "**".
+     */
+    public static function matchPatternStart($pattern, $str, $isCaseSensitive = true) {
+
+        // When str starts with a DIRECTORY_SEPARATOR, pattern has to start with a
+        // DIRECTORY_SEPARATOR.
+        // When pattern starts with a DIRECTORY_SEPARATOR, str has to start with a
+        // DIRECTORY_SEPARATOR.
+        if (StringHelper::startsWith(DIRECTORY_SEPARATOR, $str) !==
+            StringHelper::startsWith(DIRECTORY_SEPARATOR, $pattern)) {
+            return false;
+        }
+
+        $patDirs = explode(DIRECTORY_SEPARATOR, $pattern);
+        $strDirs = explode(DIRECTORY_SEPARATOR, $str);
+
+        $patIdxStart = 0;
+        $patIdxEnd   = count($patDirs)-1;
+        $strIdxStart = 0;
+        $strIdxEnd   = count($strDirs)-1;
+
+        // up to first '**'
+        while ($patIdxStart <= $patIdxEnd && $strIdxStart <= $strIdxEnd) {
+            $patDir = $patDirs[$patIdxStart];
+            if ($patDir == "**") {
+                break;
+            }
+            if (!self::match($patDir, $strDirs[$strIdxStart], $isCaseSensitive)) {
+                return false;
+            }
+            $patIdxStart++;
+            $strIdxStart++;
+        }
+
+        if ($strIdxStart > $strIdxEnd) {
+            // String is exhausted
+            return true;
+        } elseif ($patIdxStart > $patIdxEnd) {
+            // String not exhausted, but pattern is. Failure.
+            return false;
+        } else {
+            // pattern now holds ** while string is not exhausted
+            // this will generate false positives but we can live with that.
+            return true;
+        }
+    }
+    
+    /**
+     * Tests whether or not a given path matches a given pattern.
+     *
+     * @param pattern The pattern to match against. Must not be
+     *                <code>null</code>.
+     * @param str     The path to match, as a String. Must not be
+     *                <code>null</code>.
+     * @param isCaseSensitive Whether or not matching should be performed
+     *                        case sensitively.
+     *
+     * @return <code>true</code> if the pattern matches against the string,
+     *         or <code>false</code> otherwise.
+     */
+    public static function matchPath($pattern, $str, $isCaseSensitive = true) {
+    
+        // When str starts with a DIRECTORY_SEPARATOR, pattern has to start with a
+        // DIRECTORY_SEPARATOR.
+        // When pattern starts with a DIRECTORY_SEPARATOR, str has to start with a
+        // DIRECTORY_SEPARATOR.
+        if (StringHelper::startsWith(DIRECTORY_SEPARATOR, $str) !==
+            StringHelper::startsWith(DIRECTORY_SEPARATOR, $pattern)) {
+            return false;
+        }
+
+        $patDirs = explode(DIRECTORY_SEPARATOR, $pattern);
+        $strDirs = explode(DIRECTORY_SEPARATOR, $str);
+
+        $patIdxStart = 0;
+        $patIdxEnd   = count($patDirs)-1;
+        $strIdxStart = 0;
+        $strIdxEnd   = count($strDirs)-1;
+        
+        // up to first '**'
+        while ($patIdxStart <= $patIdxEnd && $strIdxStart <= $strIdxEnd) {
+            $patDir = $patDirs[$patIdxStart];
+            if ($patDir == "**") {
+                break;
+            }
+            if (!self::match($patDir, $strDirs[$strIdxStart], $isCaseSensitive)) {
+                return false;
+            }
+            $patIdxStart++;
+            $strIdxStart++;
+        }
+        if ($strIdxStart > $strIdxEnd) {
+            // String is exhausted
+            for ($i=$patIdxStart; $i <= $patIdxEnd; $i++) {
+                if ($patDirs[$i] != "**") {
+                    return false;
+                }
+            }
+            return true;
+        } elseif ($patIdxStart > $patIdxEnd) {
+            // String not exhausted, but pattern is. Failure.
+            return false;
+        }
+
+        // up to last '**'
+        while ($patIdxStart <= $patIdxEnd && $strIdxStart <= $strIdxEnd) {
+            $patDir = $patDirs[$patIdxEnd];
+            if ($patDir == "**") {
+                break;
+            }
+            if (!self::match($patDir, $strDirs[$strIdxEnd], $isCaseSensitive)) {
+                return false;
+            }
+            $patIdxEnd--;
+            $strIdxEnd--;
+        }
+        
+        if ($strIdxStart > $strIdxEnd) {
+            // String is exhausted
+            for ($i = $patIdxStart; $i <= $patIdxEnd; $i++) {
+                if ($patDirs[$i] != "**") {
+                    return false;
+                }
+            }
+            return true;
+        }
+
+        while ($patIdxStart != $patIdxEnd && $strIdxStart <= $strIdxEnd) {
+            $patIdxTmp = -1;
+            for ($i = $patIdxStart+1; $i <= $patIdxEnd; $i++) {
+                if ($patDirs[$i] == "**") {
+                    $patIdxTmp = $i;
+                    break;
+                }
+            }
+            if ($patIdxTmp == $patIdxStart+1) {
+                // '**/**' situation, so skip one
+                $patIdxStart++;
+                continue;
+            }
+            // Find the pattern between padIdxStart & padIdxTmp in str between
+            // strIdxStart & strIdxEnd
+            $patLength = ($patIdxTmp-$patIdxStart-1);
+            $strLength = ($strIdxEnd-$strIdxStart+1);
+            $foundIdx  = -1;
+
+            //strLoop:    (start of outer loop)
+            for ($i=0; $i <= $strLength - $patLength; $i++) {                
+                for ($j = 0; $j < $patLength; $j++) {
+                    $subPat = $patDirs[$patIdxStart+$j+1];
+                    $subStr = $strDirs[$strIdxStart+$i+$j];
+                    if (!self::match($subPat, $subStr, $isCaseSensitive)) {
+                        continue 2; // continue up two levels (to strLoop:)
+                    }
+                }                                
+                $foundIdx = $strIdxStart+$i; // only reached if all sub patterns matched
+                break;
+            }
+
+            if ($foundIdx == -1) {
+                return false;
+            }
+
+            $patIdxStart = $patIdxTmp;
+            $strIdxStart = $foundIdx + $patLength;
+        }
+
+        for ($i = $patIdxStart; $i <= $patIdxEnd; $i++) {
+            if ($patDirs[$i] != "**") {
+                return false;
+            }
+        }
+
+        return true;
+    }
+
+    /**
+     * Tests whether or not a string matches against a pattern.
+     * The pattern may contain two special characters:<br>
+     * '*' means zero or more characters<br>
+     * '?' means one and only one character
+     *
+     * @param pattern The pattern to match against.
+     *                Must not be <code>null</code>.
+     * @param str     The string which must be matched against the pattern.
+     *                Must not be <code>null</code>.
+     * @param isCaseSensitive Whether or not matching should be performed
+     *                        case sensitively.
+     *
+     *
+     * @return <code>true</code> if the string matches against the pattern,
+     *         or <code>false</code> otherwise.
+     */
+    public static function match($pattern, $str, $isCaseSensitive = true) {
+    
+        $patArr = StringHelper::toCharArray($pattern);
+        $strArr = StringHelper::toCharArray($str);
+        $patIdxStart = 0;
+        $patIdxEnd   = count($patArr)-1;
+        $strIdxStart = 0;
+        $strIdxEnd   = count($strArr)-1;
+        
+        $containsStar = false;
+        for ($i = 0, $size=count($patArr); $i < $size; $i++) {
+            if ($patArr[$i] == '*') {
+                $containsStar = true;
+                break;
+            }
+        }
+
+        if (!$containsStar) {
+            // No '*'s, so we make a shortcut
+            if ($patIdxEnd != $strIdxEnd) {
+                return false; // Pattern and string do not have the same size
+            }
+            for ($i = 0; $i <= $patIdxEnd; $i++) {
+                $ch = $patArr[$i];
+                if ($ch != '?') {
+                    if ($isCaseSensitive && $ch !== $strArr[$i]) {
+                        return false;// Character mismatch
+                    }
+                    if (!$isCaseSensitive && strtoupper($ch) !==
+                        strtoupper($strArr[$i])) {
+                        return false; // Character mismatch
+                    }
+                }
+            }
+            return true; // String matches against pattern
+        }
+
+        if ($patIdxEnd == 0) {
+            return true; // Pattern contains only '*', which matches anything
+        }
+
+        // Process characters before first star
+        while(($ch = $patArr[$patIdxStart]) != '*' && $strIdxStart <= $strIdxEnd) {
+            if ($ch != '?') {
+                if ($isCaseSensitive && $ch !== $strArr[$strIdxStart]) {
+                    return false;// Character mismatch
+                }
+                if (!$isCaseSensitive && strtoupper($ch) !==
+                    strtoupper($strArr[$strIdxStart])) {
+                    return false;// Character mismatch
+                }
+            }
+            $patIdxStart++;
+            $strIdxStart++;
+        }
+        
+        if ($strIdxStart > $strIdxEnd) {
+            // All characters in the string are used. Check if only '*'s are
+            // left in the pattern. If so, we succeeded. Otherwise failure.
+            for ($i = $patIdxStart; $i <= $patIdxEnd; $i++) {
+                if ($patArr[$i] != '*') {
+                    return false;
+                }
+            }
+            return true;
+        }
+
+        // Process characters after last star
+        while(($ch = $patArr[$patIdxEnd]) != '*' && $strIdxStart <= $strIdxEnd) {
+            if ($ch != '?') {
+                if ($isCaseSensitive && $ch !== $strArr[$strIdxEnd]) {
+                    return false;// Character mismatch
+                }
+                if (!$isCaseSensitive && strtoupper($ch) !==
+                    strtoupper($strArr[$strIdxEnd])) {
+                    return false;// Character mismatch
+                }
+            }
+            $patIdxEnd--;
+            $strIdxEnd--;
+        }
+        if ($strIdxStart > $strIdxEnd) {
+            // All characters in the string are used. Check if only '*'s are
+            // left in the pattern. If so, we succeeded. Otherwise failure.
+            for ($i = $patIdxStart; $i <= $patIdxEnd; $i++) {
+                if ($patArr[$i] != '*') {
+                    return false;
+                }
+            }
+            return true;
+        }
+
+        // process pattern between stars. padIdxStart and patIdxEnd point
+        // always to a '*'.
+        while ($patIdxStart !== $patIdxEnd && $strIdxStart <= $strIdxEnd) {
+            $patIdxTmp = -1;
+            for ($i = $patIdxStart+1; $i <= $patIdxEnd; $i++) {
+                if ($patArr[$i] == '*') {
+                    $patIdxTmp = $i;
+                    break;
+                }
+            }
+            if ($patIdxTmp === $patIdxStart + 1) {
+                // Two stars next to each other, skip the first one.
+                $patIdxStart++;
+                continue;
+            }
+            // Find the pattern between padIdxStart & padIdxTmp in str between
+            // strIdxStart & strIdxEnd
+            $patLength = ($patIdxTmp - $patIdxStart - 1);
+            $strLength = ($strIdxEnd - $strIdxStart + 1);
+            $foundIdx  = -1;
+            
+            //strLoop:
+            for ($i = 0; $i <= $strLength - $patLength; $i++) {
+                for ($j = 0; $j < $patLength; $j++) {
+                    $ch = $patArr[$patIdxStart+$j+1];
+                    if ($ch != '?') {
+                        if ($isCaseSensitive && $ch !== $strArr[$strIdxStart+$i+$j]) {
+                               continue 2; //continue to strLoop:
+                        }
+                        if (!$isCaseSensitive && strtoupper($ch) !==
+                            strtoupper($strArr[$strIdxStart+$i+$j])) {
+                               continue 2; //continue to strLoop:
+                        }
+                    }
+                }
+                // only reached if sub loop completed w/o invoking continue 2
+                $foundIdx = $strIdxStart + $i;
+                break;
+            }
+
+            if ($foundIdx == -1) {
+                return false;
+            }
+
+            $patIdxStart = $patIdxTmp;
+            $strIdxStart = $foundIdx + $patLength;
+        }
+
+        // All characters in the string are used. Check if only '*'s are left
+        // in the pattern. If so, we succeeded. Otherwise failure.
+        for ($i = $patIdxStart; $i <= $patIdxEnd; $i++) {
+            if ($patArr[$i] != '*') {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    /**
+     * Returns dependency information on these two files. If src has been
+     * modified later than target, it returns true. If target doesn't exist,
+     * it likewise returns true. Otherwise, target is newer than src and
+     * is not out of date, thus the method returns false. It also returns
+     * false if the src file doesn't even exist, since how could the
+     * target then be out of date.
+     *
+     * @param PhingFile $src the original file
+     * @param PhingFile $target the file being compared against
+     * @param int $granularity the amount in seconds of slack we will give in
+     *        determining out of dateness
+     * @return whether the target is out of date
+     */
+    public static function isOutOfDate(PhingFile $src, PhingFile $target, $granularity) {
+        if (!$src->exists()) {
+            return false;
+        }
+        if (!$target->exists()) {
+            return true;
+        }
+        if (($src->lastModified() - $granularity) > $target->lastModified()) {
+            return true;
+        }
+        return false;
+    }
+
+}
+
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/types/selectors/SizeSelector.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/types/selectors/SizeSelector.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/types/selectors/SizeSelector.php	(revision 19)
@@ -0,0 +1,228 @@
+<?php
+
+/*
+ * $Id: SizeSelector.php 123 2006-09-14 20:19:08Z mrook $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+
+/**
+ * Selector that filters files based on their size.
+ *
+ * @author Hans Lellelid <hans@xmpl.org> (Phing)
+ * @author Bruce Atherton <bruce@callenish.com> (Ant)
+ * @package phing.types.selectors
+ */
+class SizeSelector extends BaseExtendSelector {
+
+    private $size = -1;
+    private $multiplier = 1;
+    private $sizelimit = -1;
+    private $cmp = 2;
+    const SIZE_KEY = "value";
+    const UNITS_KEY = "units";
+    const WHEN_KEY = "when";
+
+    private static $sizeComparisons =  array("less", "more", "equal");
+    private static $byteUnits = array("K", "k", "kilo", "KILO",
+                                 "Ki", "KI", "ki", "kibi", "KIBI",
+                                 "M", "m", "mega", "MEGA",
+                                 "Mi", "MI", "mi", "mebi", "MEBI",
+                                 "G", "g", "giga", "GIGA",
+                                 "Gi", "GI", "gi", "gibi", "GIBI",
+                                 "T", "t", "tera", "TERA",
+            /* You wish! */      "Ti", "TI", "ti", "tebi", "TEBI"
+                                 );
+
+    public function toString() {
+        $buf = "{sizeselector value: ";
+        $buf .= $this->sizelimit;
+        $buf .= "compare: ";
+        if ($this->cmp === 0) {
+            $buf .= "less";
+        } elseif ($this->cmp === 1) {
+            $buf .= "more";
+        } else {
+            $buf .= "equal";
+        }
+        $buf .= "}";
+        return $buf;
+    }
+
+    /**
+     * A size selector needs to know what size to base its selecting on.
+     * This will be further modified by the multiplier to get an
+     * actual size limit.
+     *
+     * @param size the size to select against expressed in units
+     */
+    public function setValue($size) {
+        $this->size = $size;
+        if (($this->multiplier !== 0) && ($this->size > -1)) {
+            $this->sizelimit = $size * $this->multiplier;
+        }
+    }
+
+    /**
+     * Sets the units to use for the comparison. This is a little
+     * complicated because common usage has created standards that
+     * play havoc with capitalization rules. Thus, some people will
+     * use "K" for indicating 1000's, when the SI standard calls for
+     * "k". Others have tried to introduce "K" as a multiple of 1024,
+     * but that falls down when you reach "M", since "m" is already
+     * defined as 0.001.
+     * <p>
+     * To get around this complexity, a number of standards bodies
+     * have proposed the 2^10 standard, and at least one has adopted
+     * it. But we are still left with a populace that isn't clear on
+     * how capitalization should work.
+     * <p>
+     * We therefore ignore capitalization as much as possible.
+     * Completely mixed case is not possible, but all upper and lower
+     * forms are accepted for all long and short forms. Since we have
+     * no need to work with the 0.001 case, this practice works here.
+     * <p>
+     * This function translates all the long and short forms that a
+     * unit prefix can occur in and translates them into a single
+     * multiplier.
+     *
+     * @param $units The units to compare the size to.
+     * @return void
+     */
+    public function setUnits($units) {
+        $i = array_search($units, self::$byteUnits, true);
+        if ($i === false) $i = -1; // make it java-like
+        
+        $this->multiplier = 0;
+        if (($i > -1) && ($i < 4)) {
+            $this->multiplier = 1000;
+        } elseif (($i > 3) && ($i < 9)) {
+            $this->multiplier = 1024;
+        } elseif (($i > 8) && ($i < 13)) {
+            $this->multiplier = 1000000;
+        } elseif (($i > 12) && ($i < 18)) {
+            $this->multiplier = 1048576;
+        } elseif (($i > 17) && ($i < 22)) {
+            $this->multiplier = 1000000000;
+        } elseif (($i > 21) && ($i < 27)) {
+            $this->multiplier = 1073741824;
+        } elseif (($i > 26) && ($i < 31)) {
+            $this->multiplier = 1000000000000;
+        } elseif (($i > 30) && ($i < 36)) {
+            $this->multiplier = 1099511627776;
+        }
+        if (($this->multiplier > 0) && ($this->size > -1)) {
+            $this->sizelimit = $this->size * $this->multiplier;
+        }
+    }
+
+    /**
+     * This specifies when the file should be selected, whether it be
+     * when the file matches a particular size, when it is smaller,
+     * or whether it is larger.
+     *
+     * @param cmp The comparison to perform, an EnumeratedAttribute
+     */
+    public function setWhen($cmp) {
+        $c = array_search($cmp, self::$sizeComparisons, true);
+        if ($c !== false) {
+            $this->cmp = $c;
+        }
+    }
+
+    /**
+     * When using this as a custom selector, this method will be called.
+     * It translates each parameter into the appropriate setXXX() call.
+     *
+     * @param parameters the complete set of parameters for this selector
+     */
+    public function setParameters($parameters) {
+        parent::setParameters($parameters);
+        if ($parameters !== null) {
+            for ($i = 0, $size=count($parameters); $i < $size; $i++) {
+                $paramname = $parameters[$i]->getName();
+                switch(strtolower($paramname)) {
+                    case self::SIZE_KEY:
+                        try {
+                            $this->setValue($parameters[$i]->getValue());
+                           } catch (Exception $nfe) {
+                               $this->setError("Invalid size setting "
+                                . $parameters[$i]->getValue());
+                           }
+                        break;
+                    case self::UNITS_KEY:                                                
+                        $this->setUnits($parameters[$i]->getValue());
+                        break;
+                    case self::WHEN_KEY:
+                        $this->setWhen($parameters[$i]->getValue());
+                        break;
+                    default:    
+                        $this->setError("Invalid parameter " . $paramname);
+                }
+            }
+        }
+    }
+
+    /**
+     * <p>Checks to make sure all settings are kosher. In this case, it
+     * means that the size attribute has been set (to a positive value),
+     * that the multiplier has a valid setting, and that the size limit
+     * is valid. Since the latter is a calculated value, this can only
+     * fail due to a programming error.
+     * </p>
+     * <p>If a problem is detected, the setError() method is called.
+     * </p>
+     */
+    public function verifySettings() {
+        if ($this->size < 0) {
+            $this->setError("The value attribute is required, and must be positive");
+        } elseif ($this->multiplier < 1) {
+            $this->setError("Invalid Units supplied, must be K,Ki,M,Mi,G,Gi,T,or Ti");
+        } elseif ($this->sizelimit < 0) {
+            $this->setError("Internal error: Code is not setting sizelimit correctly");
+        }
+    }
+
+    /**
+     * The heart of the matter. This is where the selector gets to decide
+     * on the inclusion of a file in a particular fileset.
+     *
+     * @param basedir A PhingFile object for the base directory
+     * @param filename The name of the file to check
+     * @param file A PhingFile object for this filename
+     * @return whether the file should be selected or not
+     */
+    public function isSelected(PhingFile $basedir, $filename, PhingFile $file) {
+
+        $this->validate();
+
+        // Directory size never selected for
+        if ($file->isDirectory()) {
+            return true;
+        }
+        if ($this->cmp === 0) {
+            return ($file->length() < $this->sizelimit);
+        } elseif ($this->cmp === 1) {
+            return ($file->length() > $this->sizelimit);
+        } else {
+            return ($file->length() === $this->sizelimit);
+        }
+    }
+    
+}
+
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/types/selectors/TypeSelector.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/types/selectors/TypeSelector.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/types/selectors/TypeSelector.php	(revision 19)
@@ -0,0 +1,113 @@
+<?php
+
+/*
+ * $Id: TypeSelector.php 123 2006-09-14 20:19:08Z mrook $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+require_once 'phing/types/selectors/BaseExtendSelector.php';
+
+/**
+ * Selector that selects a certain kind of file: directory or regular file.
+ * 
+ * @author    Hans Lellelid <hans@xmpl.org> (Phing)
+ * @author    Jeff Turner <jefft@apache.org> (Ant)
+ * @version   $Revision: 1.3 $
+ * @package   phing.types.selectors
+ */
+class TypeSelector extends BaseExtendSelector {
+
+    private $type;
+
+    /** Key to used for parameterized custom selector */
+    const TYPE_KEY = "type";
+    
+    /** Valid types */
+    private static $types = array('file', 'dir');
+    
+    /**
+     * @return string A string describing this object
+     */
+    public function toString() {
+        $buf = "{typeselector type: " . $this->type . "}";
+        return $buf;
+    }
+
+    /**
+     * Set the type of file to require.
+     * @param string $type The type of file - 'file' or 'dir'
+     */
+    public function setType($type) {       
+        $this->type = $type;
+    }
+
+    /**
+     * When using this as a custom selector, this method will be called.
+     * It translates each parameter into the appropriate setXXX() call.
+     *
+     * @param array $parameters the complete set of parameters for this selector
+     */
+    public function setParameters($parameters) {
+        parent::setParameters($parameters);
+        if ($parameters !== null) {
+            for ($i = 0, $size=count($parameters); $i < $size; $i++) {
+                $paramname = $parameters[$i]->getName();
+                if (self::TYPE_KEY == strtolower($paramname)) {
+                    $this->setType($parameters[$i]->getValue());
+                } else {
+                    $this->setError("Invalid parameter " . $paramname);
+                }
+            }
+        }
+    }
+
+    /**
+     * Checks to make sure all settings are kosher. In this case, it
+     * means that the pattern attribute has been set.
+     *
+     */
+    public function verifySettings() {
+        if ($this->type === null) {
+            $this->setError("The type attribute is required");
+        } elseif (!in_array($this->type, self::$types, true)) {
+            $this->setError("Invalid type specified; must be one of (" . implode(self::$types) . ")");
+        }
+    }
+
+    /**
+     * The heart of the matter. This is where the selector gets to decide
+     * on the inclusion of a file in a particular fileset.
+     *
+     * @param PhingFile $basedir the base directory the scan is being done from
+     * @param string $filename is the name of the file to check
+     * @param PhingFile $file is a PhingFile object the selector can use
+     * @return boolean Whether the file should be selected or not
+     */
+    public function isSelected(PhingFile $basedir, $filename, PhingFile $file) {
+
+        // throw BuildException on error
+        $this->validate();
+
+        if ($file->isDirectory()) {
+            return $this->type === 'dir';
+        } else {
+            return $this->type === 'file';
+        }
+    }
+
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/util/DirectoryScanner.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/util/DirectoryScanner.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/util/DirectoryScanner.php	(revision 19)
@@ -0,0 +1,712 @@
+<?php
+/*
+ *  $Id: DirectoryScanner.php 277 2007-11-01 01:25:23Z hans $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+require_once 'phing/types/selectors/SelectorScanner.php'; 
+include_once 'phing/util/StringHelper.php';
+include_once 'phing/types/selectors/SelectorUtils.php';
+
+/**
+ * Class for scanning a directory for files/directories that match a certain
+ * criteria.
+ *
+ * These criteria consist of a set of include and exclude patterns. With these
+ * patterns, you can select which files you want to have included, and which
+ * files you want to have excluded.
+ *
+ * The idea is simple. A given directory is recursively scanned for all files
+ * and directories. Each file/directory is matched against a set of include
+ * and exclude patterns. Only files/directories that match at least one
+ * pattern of the include pattern list, and don't match a pattern of the
+ * exclude pattern list will be placed in the list of files/directories found.
+ *
+ * When no list of include patterns is supplied, "**" will be used, which
+ * means that everything will be matched. When no list of exclude patterns is
+ * supplied, an empty list is used, such that nothing will be excluded.
+ *
+ * The pattern matching is done as follows:
+ * The name to be matched is split up in path segments. A path segment is the
+ * name of a directory or file, which is bounded by DIRECTORY_SEPARATOR
+ * ('/' under UNIX, '\' under Windows).
+ * E.g. "abc/def/ghi/xyz.php" is split up in the segments "abc", "def", "ghi"
+ * and "xyz.php".
+ * The same is done for the pattern against which should be matched.
+ *
+ * Then the segments of the name and the pattern will be matched against each
+ * other. When '**' is used for a path segment in the pattern, then it matches
+ * zero or more path segments of the name.
+ *
+ * There are special case regarding the use of DIRECTORY_SEPARATOR at
+ * the beginning of the pattern and the string to match:
+ * When a pattern starts with a DIRECTORY_SEPARATOR, the string
+ * to match must also start with a DIRECTORY_SEPARATOR.
+ * When a pattern does not start with a DIRECTORY_SEPARATOR, the
+ * string to match may not start with a DIRECTORY_SEPARATOR.
+ * When one of these rules is not obeyed, the string will not
+ * match.
+ *
+ * When a name path segment is matched against a pattern path segment, the
+ * following special characters can be used:
+ *   '*' matches zero or more characters,
+ *   '?' matches one character.
+ *
+ * Examples:
+ *
+ * "**\*.php" matches all .php files/dirs in a directory tree.
+ *
+ * "test\a??.php" matches all files/dirs which start with an 'a', then two
+ * more characters and then ".php", in a directory called test.
+ *
+ * "**" matches everything in a directory tree.
+ *
+ * "**\test\**\XYZ*" matches all files/dirs that start with "XYZ" and where
+ * there is a parent directory called test (e.g. "abc\test\def\ghi\XYZ123").
+ *
+ * Case sensitivity may be turned off if necessary.  By default, it is
+ * turned on.
+ *
+ * Example of usage:
+ *   $ds = new DirectroyScanner();
+ *   $includes = array("**\*.php");
+ *   $excludes = array("modules\*\**");
+ *   $ds->SetIncludes($includes);
+ *   $ds->SetExcludes($excludes);
+ *   $ds->SetBasedir("test");
+ *   $ds->SetCaseSensitive(true);
+ *   $ds->Scan();
+ *
+ *   print("FILES:");
+ *   $files = ds->GetIncludedFiles();
+ *   for ($i = 0; $i < count($files);$i++) {
+ *     println("$files[$i]\n");
+ *   }
+ *
+ * This will scan a directory called test for .php files, but excludes all
+ * .php files in all directories under a directory called "modules"
+ *
+ * This class is complete preg/ereg free port of the Java class
+ * org.apache.tools.ant.DirectoryScanner. Even functions that use preg/ereg
+ * internally (like split()) are not used. Only the _fast_ string functions
+ * and comparison operators (=== !=== etc) are used for matching and tokenizing.
+ *
+ *  @author   Arnout J. Kuiper, ajkuiper@wxs.nl
+ *  @author   Magesh Umasankar, umagesh@rediffmail.com
+ *  @author   Andreas Aderhold, andi@binarycloud.com
+ *
+ *  @version   $Revision: 1.15 $
+ *  @package   phing.util
+ */
+class DirectoryScanner implements SelectorScanner {
+
+    /** default set of excludes */
+    protected $DEFAULTEXCLUDES = array(
+        "**/*~",
+        "**/#*#",
+        "**/.#*",
+        "**/%*%",
+        "**/CVS",
+        "**/CVS/**",
+        "**/.cvsignore",
+        "**/SCCS",
+        "**/SCCS/**",
+        "**/vssver.scc",
+		"**/.svn",
+		"**/.svn/**",
+		"**/._*",
+		"**/.DS_Store",
+    );
+
+    /** The base directory which should be scanned. */
+    protected $basedir;
+
+    /** The patterns for the files that should be included. */
+    protected $includes = null;
+
+    /** The patterns for the files that should be excluded. */
+    protected $excludes = null;
+
+    /**
+     * The files that where found and matched at least one includes, and matched
+     * no excludes.
+     */
+    protected $filesIncluded;
+
+    /** The files that where found and did not match any includes. Trie */
+    protected $filesNotIncluded;
+
+    /**
+     * The files that where found and matched at least one includes, and also
+     * matched at least one excludes. Trie object.
+     */
+    protected $filesExcluded;
+
+    /**
+     * The directories that where found and matched at least one includes, and
+     * matched no excludes.
+     */
+    protected $dirsIncluded;
+
+    /** The directories that where found and did not match any includes. */
+    protected $dirsNotIncluded;
+
+    /**
+     * The files that where found and matched at least one includes, and also
+     * matched at least one excludes.
+     */
+    protected $dirsExcluded;
+
+    /** Have the vars holding our results been built by a slow scan? */
+    protected $haveSlowResults = false;
+
+    /** Should the file system be treated as a case sensitive one? */
+    protected $isCaseSensitive = true;
+
+    /** Selectors */
+    protected $selectors = null;
+    
+    protected $filesDeselected;
+    protected $dirsDeselected;
+    
+    /** if there are no deselected files */
+    protected $everythingIncluded = true;        
+
+    /**
+     * Does the path match the start of this pattern up to the first "**".
+     * This is a static mehtod and should always be called static
+     *
+     * This is not a general purpose test and should only be used if you
+     * can live with false positives.
+     *
+     * pattern=**\a and str=b will yield true.
+     *
+     * @param   pattern             the (non-null) pattern to match against
+     * @param   str                 the (non-null) string (path) to match
+     * @param   isCaseSensitive     must matches be case sensitive?
+     * @return  boolean             true if matches, otherwise false
+     */
+    function matchPatternStart($pattern, $str, $isCaseSensitive = true) {
+        return SelectorUtils::matchPatternStart($pattern, $str, $isCaseSensitive);
+    }
+
+    /**
+     * Matches a path against a pattern. Static
+     *
+     * @param pattern            the (non-null) pattern to match against
+     * @param str                the (non-null) string (path) to match
+     * @param isCaseSensitive    must a case sensitive match be done?
+     *
+     * @return true when the pattern matches against the string.
+     *         false otherwise.
+     */
+    function matchPath($pattern, $str, $isCaseSensitive = true) {
+        return SelectorUtils::matchPath($pattern, $str, $isCaseSensitive);
+    }
+
+    /**
+     * Matches a string against a pattern. The pattern contains two special
+     * characters:
+     * '*' which means zero or more characters,
+     * '?' which means one and only one character.
+     *
+     * @param  pattern the (non-null) pattern to match against
+     * @param  str     the (non-null) string that must be matched against the
+     *                 pattern
+     *
+     * @return boolean true when the string matches against the pattern,
+     *                 false otherwise.
+     * @access public
+     */
+    function match($pattern, $str, $isCaseSensitive = true) {
+        return SelectorUtils::match($pattern, $str, $isCaseSensitive);
+    }
+
+    /**
+     * Sets the basedir for scanning. This is the directory that is scanned
+     * recursively. All '/' and '\' characters are replaced by
+     * DIRECTORY_SEPARATOR
+     *
+     * @param basedir the (non-null) basedir for scanning
+     */
+    function setBasedir($_basedir) {
+        $_basedir = str_replace('\\', DIRECTORY_SEPARATOR, $_basedir);
+        $_basedir = str_replace('/', DIRECTORY_SEPARATOR, $_basedir);
+        $this->basedir = $_basedir;
+    }
+
+    /**
+     * Gets the basedir that is used for scanning. This is the directory that
+     * is scanned recursively.
+     *
+     * @return the basedir that is used for scanning
+     */
+    function getBasedir() {
+        return $this->basedir;
+    }
+
+    /**
+     * Sets the case sensitivity of the file system
+     *
+     * @param specifies if the filesystem is case sensitive
+     */
+    function setCaseSensitive($_isCaseSensitive) {
+        $this->isCaseSensitive = ($_isCaseSensitive) ? true : false;
+    }
+
+    /**
+     * Sets the set of include patterns to use. All '/' and '\' characters are
+     * replaced by DIRECTORY_SEPARATOR. So the separator used need
+     * not match DIRECTORY_SEPARATOR.
+     *
+     * When a pattern ends with a '/' or '\', "**" is appended.
+     *
+     * @param includes list of include patterns
+     */
+    function setIncludes($_includes = array()) {
+        if (empty($_includes) || is_null($_includes)) {
+            $this->includes = null;
+        } else {
+            for ($i = 0; $i < count($_includes); $i++) {
+                $pattern = null;
+                $pattern = str_replace('\\', DIRECTORY_SEPARATOR, $_includes[$i]);
+                $pattern = str_replace('/', DIRECTORY_SEPARATOR, $pattern);
+                if (StringHelper::endsWith(DIRECTORY_SEPARATOR, $pattern)) {
+                    $pattern .= "**";
+                }
+                $this->includes[] = $pattern;
+            }
+        }
+    }
+
+    /**
+     * Sets the set of exclude patterns to use. All '/' and '\' characters are
+     * replaced by <code>File.separatorChar</code>. So the separator used need
+     * not match <code>File.separatorChar</code>.
+     *
+     * When a pattern ends with a '/' or '\', "**" is appended.
+     *
+     * @param excludes list of exclude patterns
+     */
+
+    function setExcludes($_excludes = array()) {
+        if (empty($_excludes) || is_null($_excludes)) {
+            $this->excludes = null;
+        } else {
+            for ($i = 0; $i < count($_excludes); $i++) {
+                $pattern = null;
+                $pattern = str_replace('\\', DIRECTORY_SEPARATOR, $_excludes[$i]);
+                $pattern = str_replace('/', DIRECTORY_SEPARATOR, $pattern);
+                if (StringHelper::endsWith(DIRECTORY_SEPARATOR, $pattern)) {
+                    $pattern .= "**";
+                }
+                $this->excludes[] = $pattern;
+            }
+        }
+    }
+
+    /**
+     * Scans the base directory for files that match at least one include
+     * pattern, and don't match any exclude patterns.
+     *
+     */
+    function scan() {
+    
+        if ((empty($this->basedir)) || (!@is_dir($this->basedir))) {
+            return false;
+        }
+
+        if ($this->includes === null) {
+            // No includes supplied, so set it to 'matches all'
+            $this->includes = array("**");
+        }
+        if (is_null($this->excludes)) {
+            $this->excludes = array();
+        }
+
+        $this->filesIncluded = array();
+        $this->filesNotIncluded = array();
+        $this->filesExcluded = array();
+        $this->dirsIncluded = array();
+        $this->dirsNotIncluded = array();
+        $this->dirsExcluded = array();
+        $this->dirsDeselected = array();
+        $this->filesDeselected = array();
+        
+        if ($this->isIncluded("")) {
+            if (!$this->isExcluded("")) {
+                if ($this->isSelected("", $this->basedir)) {
+                    $this->dirsIncluded[] = "";
+                } else {
+                    $this->dirsDeselected[] = "";
+                }                
+            } else {
+                $this->dirsExcluded[] = "";
+            }
+        } else {
+            $this->dirsNotIncluded[] = "";
+        }
+
+        $this->scandir($this->basedir, "", true);
+        return true;
+    }
+
+    /**
+     * Toplevel invocation for the scan.
+     *
+     * Returns immediately if a slow scan has already been requested.
+     */
+    protected function slowScan() {
+
+        if ($this->haveSlowResults) {
+            return;
+        }
+
+        // copy trie object add CopyInto() method
+        $excl    = $this->dirsExcluded;
+        $notIncl = $this->dirsNotIncluded;
+
+        for ($i=0, $_i=count($excl); $i < $_i; $i++) {
+            if (!$this->couldHoldIncluded($excl[$i])) {
+                $this->scandir($this->basedir.$excl[$i], $excl[$i].DIRECTORY_SEPARATOR, false);
+            }
+        }
+
+        for ($i=0, $_i=count($notIncl); $i < $_i; $i++) {
+            if (!$this->couldHoldIncluded($notIncl[$i])) {
+                $this->scandir($this->basedir.$notIncl[$i], $notIncl[$i].DIRECTORY_SEPARATOR, false);
+            }
+        }
+
+        $this->haveSlowResults = true;
+    }
+
+    /**
+     * Lists contens of a given directory and returns array with entries
+     *
+     * @param   src String. Source path and name file to copy.
+     *
+     * @access  public
+     * @return  array  directory entries
+     * @author  Albert Lash, alash@plateauinnovation.com
+     */
+
+    function listDir($_dir) {
+        $d = dir($_dir);
+        $list = array();
+        while($entry = $d->read()) {
+            if ($entry != "." && $entry != "..") {
+                $list[] = $entry;
+            }
+        }
+        $d->close();
+        return $list;
+    }
+
+    /**
+     * Scans the passed dir for files and directories. Found files and
+     * directories are placed in their respective collections, based on the
+     * matching of includes and excludes. When a directory is found, it is
+     * scanned recursively.
+     *
+     * @param dir   the directory to scan
+     * @param vpath the path relative to the basedir (needed to prevent
+     *              problems with an absolute path when using dir)
+     *
+     * @access private
+     * @see #filesIncluded
+     * @see #filesNotIncluded
+     * @see #filesExcluded
+     * @see #dirsIncluded
+     * @see #dirsNotIncluded
+     * @see #dirsExcluded
+     */
+    private function scandir($_rootdir, $_vpath, $_fast) {
+        
+        if (!is_readable($_rootdir)) {
+            return;
+        }                                
+        
+        $newfiles = self::listDir($_rootdir);
+        
+        for ($i=0,$_i=count($newfiles); $i < $_i; $i++) {
+            
+            $file = $_rootdir . DIRECTORY_SEPARATOR . $newfiles[$i];
+            $name = $_vpath . $newfiles[$i];
+
+            if (@is_dir($file)) {
+                if ($this->isIncluded($name)) {
+                    if (!$this->isExcluded($name)) {
+                        if ($this->isSelected($name, $file)) {
+                            $this->dirsIncluded[] = $name;
+                            if ($_fast) {
+                                $this->scandir($file, $name.DIRECTORY_SEPARATOR, $_fast);
+                            }
+                        } else {
+                            $this->everythingIncluded = false;
+                            $this->dirsDeselected[] = $name;
+                            if ($_fast && $this->couldHoldIncluded($name)) {
+                                $this->scandir($file, $name.DIRECTORY_SEPARATOR, $_fast);
+                            }                            
+                        }                                                
+                    } else {
+                        $this->everythingIncluded = false;
+                        $this->dirsExcluded[] = $name;
+                        if ($_fast && $this->couldHoldIncluded($name)) {
+                            $this->scandir($file, $name.DIRECTORY_SEPARATOR, $_fast);
+                        }
+                    }
+                } else {
+                    $this->everythingIncluded = false;
+                    $this->dirsNotIncluded[] = $name;
+                    if ($_fast && $this->couldHoldIncluded($name)) {
+                        $this->scandir($file, $name.DIRECTORY_SEPARATOR, $_fast);
+                    }
+                }
+                
+                if (!$_fast) {
+                    $this->scandir($file, $name.DIRECTORY_SEPARATOR, $_fast);
+                }
+                
+            } elseif (@is_file($file)) {
+                if ($this->isIncluded($name)) {
+                    if (!$this->isExcluded($name)) {
+                        if ($this->isSelected($name, $file)) {
+                            $this->filesIncluded[] = $name;
+                        } else {
+                            $this->everythingIncluded = false;
+                            $this->filesDeselected[] = $name;
+                        }                        
+                    } else {
+                        $this->everythingIncluded = false;
+                        $this->filesExcluded[] = $name;
+                    }
+                } else {
+                    $this->everythingIncluded = false;
+                    $this->filesNotIncluded[] = $name;
+                }
+            }
+        }
+    }
+
+    /**
+     * Tests whether a name matches against at least one include pattern.
+     *
+     * @param name the name to match
+     * @return <code>true</code> when the name matches against at least one
+     *         include pattern, <code>false</code> otherwise.
+     */
+    protected function isIncluded($_name) {
+        for ($i=0, $_i=count($this->includes); $i < $_i; $i++) {
+            if (DirectoryScanner::matchPath($this->includes[$i], $_name, $this->isCaseSensitive)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Tests whether a name matches the start of at least one include pattern.
+     *
+     * @param name the name to match
+     * @return <code>true</code> when the name matches against at least one
+     *         include pattern, <code>false</code> otherwise.
+     */
+    protected function couldHoldIncluded($_name) {
+        for ($i = 0; $i < count($this->includes); $i++) {
+            if (DirectoryScanner::matchPatternStart($this->includes[$i], $_name, $this->isCaseSensitive)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Tests whether a name matches against at least one exclude pattern.
+     *
+     * @param name the name to match
+     * @return <code>true</code> when the name matches against at least one
+     *         exclude pattern, <code>false</code> otherwise.
+     */
+    protected function isExcluded($_name) {
+        for ($i = 0; $i < count($this->excludes); $i++) {
+            if (DirectoryScanner::matchPath($this->excludes[$i], $_name, $this->isCaseSensitive)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Get the names of the files that matched at least one of the include
+     * patterns, and matched none of the exclude patterns.
+     * The names are relative to the basedir.
+     *
+     * @return the names of the files
+     */
+    function getIncludedFiles() {
+        return $this->filesIncluded;        
+    }
+
+    /**
+     * Get the names of the files that matched at none of the include patterns.
+     * The names are relative to the basedir.
+     *
+     * @return the names of the files
+     */
+    function getNotIncludedFiles() {
+        $this->slowScan();
+        return $this->filesNotIncluded;
+    }
+
+    /**
+     * Get the names of the files that matched at least one of the include
+     * patterns, an matched also at least one of the exclude patterns.
+     * The names are relative to the basedir.
+     *
+     * @return the names of the files
+     */
+
+    function getExcludedFiles() {
+        $this->slowScan();
+        return $this->filesExcluded;
+    }
+
+    /**
+     * <p>Returns the names of the files which were selected out and
+     * therefore not ultimately included.</p>
+     *
+     * <p>The names are relative to the base directory. This involves
+     * performing a slow scan if one has not already been completed.</p>
+     *
+     * @return the names of the files which were deselected.
+     *
+     * @see #slowScan
+     */
+    public function getDeselectedFiles() {
+        $this->slowScan();        
+        return $this->filesDeselected;
+    }
+
+    /**
+     * Get the names of the directories that matched at least one of the include
+     * patterns, an matched none of the exclude patterns.
+     * The names are relative to the basedir.
+     *
+     * @return the names of the directories
+     */
+
+    function getIncludedDirectories() {
+        return $this->dirsIncluded;        
+    }
+
+    /**
+     * Get the names of the directories that matched at none of the include
+     * patterns.
+     * The names are relative to the basedir.
+     *
+     * @return the names of the directories
+     */
+    function getNotIncludedDirectories() {
+        $this->slowScan();
+        return $this->dirsNotIncluded;        
+    }
+
+    /**
+     * <p>Returns the names of the directories which were selected out and
+     * therefore not ultimately included.</p>
+     *
+     * <p>The names are relative to the base directory. This involves
+     * performing a slow scan if one has not already been completed.</p>
+     *
+     * @return the names of the directories which were deselected.
+     *
+     * @see #slowScan
+     */
+    public function getDeselectedDirectories() {
+        $this->slowScan();
+        return $this->dirsDeselected;
+    }
+    
+    /**
+     * Get the names of the directories that matched at least one of the include
+     * patterns, an matched also at least one of the exclude patterns.
+     * The names are relative to the basedir.
+     *
+     * @return the names of the directories
+     */
+    function getExcludedDirectories() {
+        $this->slowScan();
+        return $this->dirsExcluded;        
+    }
+
+    /**
+     * Adds the array with default exclusions to the current exclusions set.
+     *
+     */
+    function addDefaultExcludes() {
+        //$excludesLength = ($this->excludes == null) ? 0 : count($this->excludes);
+        foreach($this->DEFAULTEXCLUDES as $pattern) {
+            $pattern = str_replace('\\', DIRECTORY_SEPARATOR, $pattern);
+            $pattern = str_replace('/', DIRECTORY_SEPARATOR, $pattern);
+            $this->excludes[] = $pattern;
+        }
+    }
+    
+    /**
+     * Sets the selectors that will select the filelist.
+     *
+     * @param selectors specifies the selectors to be invoked on a scan
+     */
+    public function setSelectors($selectors) {
+        $this->selectors = $selectors;
+    }
+
+    /**
+     * Returns whether or not the scanner has included all the files or
+     * directories it has come across so far.
+     *
+     * @return <code>true</code> if all files and directories which have
+     *         been found so far have been included.
+     */
+    public function isEverythingIncluded() {
+        return $this->everythingIncluded;
+    }
+        
+    /**
+     * Tests whether a name should be selected.
+     *
+     * @param string $name The filename to check for selecting.
+     * @param string $file The full file path.
+     * @return boolean False when the selectors says that the file
+     *         should not be selected, True otherwise.
+     */
+    protected function isSelected($name, $file) {
+        if ($this->selectors !== null) {
+        	$basedir = new PhingFile($this->basedir);
+        	$file = new PhingFile($file);
+        	foreach($this->selectors as $selector) {
+        		if (!$selector->isSelected($basedir, $name, $file)) {
+        			return false;
+        		}
+        	}
+        }
+        return true;
+    }
+
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/util/ExtendedFileStream.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/util/ExtendedFileStream.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/util/ExtendedFileStream.php	(revision 19)
@@ -0,0 +1,132 @@
+<?php
+
+	include_once 'phing/system/io/PhingFile.php';
+
+	/**
+	 * $Id: ExtendedFileStream.php 325 2007-12-20 15:44:58Z hans $
+	 *
+	 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+	 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+	 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+	 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+	 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+	 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+	 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+	 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+	 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+	 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+	 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+	 *
+	 * This software consists of voluntary contributions made by many individuals
+	 * and is licensed under the LGPL. For more information please see
+	 * <http://phing.info>.
+	 */
+
+	/**
+	 * Extended file stream wrapper class which auto-creates directories
+	 *
+	 * @author Michiel Rook <michiel.rook@gmail.com>
+	 * @version $Id: ExtendedFileStream.php 325 2007-12-20 15:44:58Z hans $
+	 * @package phing.util
+	 */
+	class ExtendedFileStream
+	{
+		private $fp = NULL;
+		
+		static function registerStream()
+		{
+			if (!in_array("efile", stream_get_wrappers()))
+			{
+				stream_wrapper_register("efile", "ExtendedFileStream");
+			}
+		}
+		
+		private function createDirectories($path)
+		{
+			$f = new PhingFile($path);
+			if (!$f->exists()) {
+				$f->mkdirs();
+			}
+		}
+		
+		function stream_open($path, $mode, $options, &$opened_path)
+		{
+			/** Small fix for Windows */
+			if ($path[8] == DIRECTORY_SEPARATOR)
+			{
+				$filepath = substr($path, 7);
+			}
+			else
+			{
+				$filepath = substr($path, 8);
+			}
+			
+			$this->createDirectories(dirname($filepath));
+			
+			$this->fp = fopen($filepath, $mode);
+			
+			return true;
+		}
+		
+		function stream_close()
+		{
+			fclose($this->fp);
+			$this->fp = NULL;
+		}
+		
+		function stream_read($count)
+		{
+			return fread($this->fp, $count);
+		}
+		
+		function stream_write($data)
+		{
+			return fwrite($this->fp, $data);
+		}
+		
+		function stream_eof()
+		{
+			return feof($this->fp);
+		}
+		
+		function stream_tell()
+		{
+			return ftell($this->fp);
+		}
+		
+		function stream_seek($offset, $whence)
+		{
+			return fseek($this->fp, $offset, $whence);
+		}
+		
+		function stream_flush()
+		{
+			return fflush($this->fp);
+		}
+		
+		function stream_stat()
+		{
+			return fstat($this->fp);
+		}
+		
+		function unlink($path)
+		{
+			return FALSE;
+		}
+		
+		function rename($path_from, $path_to)
+		{
+			return FALSE;
+		}
+		
+		function mkdir($path, $mode, $options)
+		{
+			return FALSE;
+		}
+		
+		function rmdir($path, $options)
+		{
+			return FALSE;
+		}		
+	};
+
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/util/FileUtils.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/util/FileUtils.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/util/FileUtils.php	(revision 19)
@@ -0,0 +1,294 @@
+<?php
+/*
+ *  $Id: FileUtils.php 325 2007-12-20 15:44:58Z hans $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+include_once 'phing/system/lang/Character.php';
+include_once 'phing/util/StringHelper.php';
+include_once 'phing/system/io/BufferedReader.php';
+include_once 'phing/system/io/BufferedWriter.php';
+include_once 'phing/filters/util/ChainReaderHelper.php';
+include_once 'phing/system/io/PhingFile.php';
+
+/**
+ * File utility class.
+ * - handles os independent stuff etc
+ * - mapper stuff
+ * - filter stuff
+ *
+ * @package  phing.util
+ * @version  $Revision: 1.10 $
+ */
+class FileUtils {
+        
+    /**
+     * Returns a new Reader with filterchains applied.  If filterchains are empty,
+     * simply returns passed reader.
+     * 
+     * @param Reader $in Reader to modify (if appropriate).
+     * @param array &$filterChains filter chains to apply.
+     * @param Project $project
+     * @return Reader Assembled Reader (w/ filter chains).
+     */
+    public static function getChainedReader(Reader $in, &$filterChains, Project $project) {
+        if (!empty($filterChains)) {
+            $crh = new ChainReaderHelper();
+            $crh->setBufferSize(65536); // 64k buffer, but isn't being used (yet?)
+            $crh->setPrimaryReader($in);
+            $crh->setFilterChains($filterChains);
+            $crh->setProject($project);
+            $rdr = $crh->getAssembledReader();
+            return $rdr;
+        } else {
+            return $in;
+        }
+    }
+    
+    /**
+     * Copies a file using filter chains.
+     * 
+     * @param PhingFile $sourceFile
+     * @param PhingFile $destFile
+     * @param boolean $overwrite
+     * @param boolean $preserveLastModified
+     * @param array $filterChains 
+     * @param Project $project
+     * @return void
+     */
+    function copyFile(PhingFile $sourceFile, PhingFile $destFile, $overwrite = false, $preserveLastModified = true, &$filterChains = null, Project $project) {
+       
+        if ($overwrite || !$destFile->exists() || $destFile->lastModified() < $sourceFile->lastModified()) {
+            if ($destFile->exists() && $destFile->isFile()) {
+                $destFile->delete();
+            }
+
+            // ensure that parent dir of dest file exists!
+            $parent = $destFile->getParentFile();
+            if ($parent !== null && !$parent->exists()) {
+                $parent->mkdirs();
+            }
+
+            if ((is_array($filterChains)) && (!empty($filterChains))) {
+                
+                $in = self::getChainedReader(new BufferedReader(new FileReader($sourceFile)), $filterChains, $project);
+                $out = new BufferedWriter(new FileWriter($destFile));                
+                
+                // New read() methods returns a big buffer.                
+                while(-1 !== ($buffer = $in->read())) { // -1 indicates EOF
+                    $out->write($buffer);
+                }
+                
+                if ( $in !== null )
+                    $in->close();
+                if ( $out !== null )
+                    $out->close();
+            } else {
+                // simple copy (no filtering)
+                $sourceFile->copyTo($destFile);
+            }
+
+            if ($preserveLastModified) {
+                $destFile->setLastModified($sourceFile->lastModified());
+            }
+
+        }
+    }
+
+    /**
+     * Interpret the filename as a file relative to the given file -
+     * unless the filename already represents an absolute filename.
+     *
+     * @param  $file the "reference" file for relative paths. This
+     *         instance must be an absolute file and must not contain
+     *         ./ or ../ sequences (same for \ instead of /).
+     * @param  $filename a file name
+     *
+     * @return PhingFile A PhingFile object pointing to an absolute file that doesn't contain ./ or ../ sequences
+     *         and uses the correct separator for the current platform.
+     */
+    function resolveFile($file, $filename) {
+        // remove this and use the static class constant File::seperator
+        // as soon as ZE2 is ready
+        $fs = FileSystem::getFileSystem();
+
+        $filename = str_replace('/', $fs->getSeparator(), str_replace('\\', $fs->getSeparator(), $filename));
+
+        // deal with absolute files
+        if (StringHelper::startsWith($fs->getSeparator(), $filename) ||
+                (strlen($filename) >= 2 && Character::isLetter($filename{0}) && $filename{1} === ':')) {
+            return new PhingFile($this->normalize($filename));
+        }
+
+        if (strlen($filename) >= 2 && Character::isLetter($filename{0}) && $filename{1} === ':') {
+            return new PhingFile($this->normalize($filename));
+        }
+
+        $helpFile = new PhingFile($file->getAbsolutePath());
+
+        $tok = strtok($filename, $fs->getSeparator());
+        while ($tok !== false) {
+            $part = $tok;
+            if ($part === '..') {
+                $parentFile = $helpFile->getParent();
+                if ($parentFile === null) {
+                    $msg = "The file or path you specified ($filename) is invalid relative to ".$file->getPath();
+                    throw new IOException($msg);
+                }
+                $helpFile = new PhingFile($parentFile);
+            } else if ($part === '.') {
+                // Do nothing here
+            } else {
+                $helpFile = new PhingFile($helpFile, $part);
+            }
+            $tok = strtok($fs->getSeparator());
+        }
+        return new PhingFile($helpFile->getAbsolutePath());
+    }
+
+    /**
+     * Normalize the given absolute path.
+     *
+     * This includes:
+     *   - Uppercase the drive letter if there is one.
+     *   - Remove redundant slashes after the drive spec.
+     *   - resolve all ./, .\, ../ and ..\ sequences.
+     *   - DOS style paths that start with a drive letter will have
+     *     \ as the separator.
+     * @param string $path Path to normalize.
+     * @return string
+     */
+    function normalize($path) {
+    
+        $path = (string) $path;
+        $orig = $path;
+
+        $path = str_replace('/', DIRECTORY_SEPARATOR, str_replace('\\', DIRECTORY_SEPARATOR, $path));
+
+        // make sure we are dealing with an absolute path
+        if (!StringHelper::startsWith(DIRECTORY_SEPARATOR, $path)
+                && !(strlen($path) >= 2 && Character::isLetter($path{0}) && $path{1} === ':')) {
+            throw new IOException("$path is not an absolute path");
+        }
+
+        $dosWithDrive = false;
+        $root = null;
+
+        // Eliminate consecutive slashes after the drive spec
+
+        if (strlen($path) >= 2 && Character::isLetter($path{0}) && $path{1} === ':') {
+            $dosWithDrive = true;
+
+            $ca = str_replace('/', '\\', $path);
+            $ca = StringHelper::toCharArray($ca);
+
+            $path = strtoupper($ca[0]).':';
+            
+            for ($i=2, $_i=count($ca); $i < $_i; $i++) {
+                if (($ca[$i] !== '\\') ||
+                        ($ca[$i] === '\\' && $ca[$i - 1] !== '\\')
+                   ) {
+                    $path .= $ca[$i];
+                }
+            }
+         
+            $path = str_replace('\\', DIRECTORY_SEPARATOR, $path);
+
+            if (strlen($path) == 2) {
+                $root = $path;
+                $path = "";
+            } else {
+                $root = substr($path, 0, 3);
+                $path = substr($path, 3);
+            }
+
+        } else {
+            if (strlen($path) == 1) {
+                $root = DIRECTORY_SEPARATOR;
+                $path = "";
+            } else if ($path{1} == DIRECTORY_SEPARATOR) {
+                // UNC drive
+                $root = DIRECTORY_SEPARATOR.DIRECTORY_SEPARATOR;
+                $path = substr($path, 2);
+            }
+            else {
+                $root = DIRECTORY_SEPARATOR;
+                $path = substr($path, 1);
+            }
+        }
+
+        $s = array();
+        array_push($s, $root);
+        $tok = strtok($path, DIRECTORY_SEPARATOR);
+        while ($tok !== false) {            
+            $thisToken = $tok;
+            if ("." === $thisToken) {
+                $tok = strtok(DIRECTORY_SEPARATOR);
+                continue;
+            } elseif (".." === $thisToken) {
+                if (count($s) < 2) {
+                    // using '..' in path that is too short
+                    throw new IOException("Cannot resolve path: $orig");
+                } else {
+                    array_pop($s);
+                }
+            } else { // plain component
+                array_push($s, $thisToken);
+            }
+            $tok = strtok(DIRECTORY_SEPARATOR);
+        }
+
+        $sb = "";
+        for ($i=0,$_i=count($s); $i < $_i; $i++) {
+            if ($i > 1) {
+                // not before the filesystem root and not after it, since root
+                // already contains one
+                $sb .= DIRECTORY_SEPARATOR;
+            }
+            $sb .= (string) $s[$i];
+        }
+
+
+        $path = (string) $sb;
+        if ($dosWithDrive === true) {
+            $path = str_replace('/', '\\', $path);
+        }
+        return $path;
+    }
+    
+    /**
+     * @return boolean Whether contents of two files is the same.
+     */
+    public function contentEquals(PhingFile $file1, PhingFile $file2) {
+        
+        if (!($file1->exists() || $file2->exists())) {
+            return false;
+        }
+
+        if (!($file1->canRead() || $file2->canRead())) {
+            return false;
+        }
+        
+        $c1 = file_get_contents($file1->getAbsolutePath());
+        $c2 = file_get_contents($file2->getAbsolutePath());
+        
+        return trim($c1) == trim($c2);    
+    }
+    
+}
+
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/util/LogWriter.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/util/LogWriter.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/util/LogWriter.php	(revision 19)
@@ -0,0 +1,95 @@
+<?php
+
+	/**
+	 * $Id: LogWriter.php 325 2007-12-20 15:44:58Z hans $
+	 *
+	 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+	 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+	 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+	 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+	 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+	 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+	 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+	 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+	 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+	 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+	 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+	 *
+	 * This software consists of voluntary contributions made by many individuals
+	 * and is licensed under the LGPL. For more information please see
+	 * <http://phing.info>.
+	 */
+	
+	require_once 'phing/system/io/Writer.php';
+	require_once 'phing/Task.php';
+
+	/**
+	 * Extends the Writer class to output messages to Phing's log
+	 *
+	 * @author Michiel Rook <michiel.rook@gmail.com>
+	 * @version $Id: LogWriter.php 325 2007-12-20 15:44:58Z hans $
+	 * @package phing.util
+	 */
+	class LogWriter extends Writer
+	{
+		private $task = NULL;
+		
+		private $level = NULL;
+		
+		/**
+		 * Constructs a new LogWriter object
+		 */
+		function __construct(Task $task, $level = Project::MSG_INFO)
+		{
+			$this->task = $task;
+			$this->level = $level;
+		}
+		
+		/**
+		 * @see Writer::write()
+		 */
+		function write($buf, $off = null, $len = null)
+		{
+			$lines = explode("\n", $buf);
+			
+			foreach ($lines as $line)
+			{
+				if ($line == "")
+				{
+					continue;
+				}
+				
+				$this->task->log($line, $this->level);
+			}
+		}
+		
+		/**
+		 * @see Writer::reset()
+		 */
+		function reset()
+		{
+		}
+
+		/**
+		 * @see Writer::close()
+		 */
+		function close()
+		{
+		}
+		
+		/**
+		 * @see Writer::open()
+		 */
+		function open()
+		{
+		}
+		
+		/**
+		 * @see Writer::getResource()
+		 */
+		function getResource()
+		{
+			return $this->task;
+		}
+	}
+
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/util/PathTokenizer.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/util/PathTokenizer.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/util/PathTokenizer.php	(revision 19)
@@ -0,0 +1,245 @@
+<?php
+/*
+ *  $Id: PathTokenizer.php 123 2006-09-14 20:19:08Z mrook $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>. 
+ */
+
+
+
+include_once 'phing/util/StringHelper.php';
+
+
+
+/**
+
+ * A Path tokenizer takes a path and returns the components that make up
+
+ * that path.
+
+ *
+
+ * The path can use path separators of either ':' or ';' and file separators
+
+ * of either '/' or '\'.
+
+ *
+
+ * @author Hans Lellelid <hans@xmpl.org> (Phing)
+
+ * @author Conor MacNeill (Ant)
+
+ * @author Jeff Tulley <jtulley@novell.com>  (Ant)
+
+ * @pacakge phing.util
+
+ */ 
+
+class PathTokenizer {
+
+    
+
+    /**
+
+     * A array of tokens, created by preg_split().
+
+     */
+
+    private $tokens = array();
+
+    
+
+    /**
+
+     * A string which stores any path components which have been read ahead
+
+     * due to DOS filesystem compensation.
+
+     * @var string
+
+     */
+
+    private $lookahead;
+
+    
+
+    /**
+
+     * Flag to indicate whether or not we are running on a platform with a
+
+     * DOS style filesystem
+
+     * @var boolean
+
+     */
+
+    private $dosStyleFilesystem;
+
+
+
+    /**
+
+     * Constructs a path tokenizer for the specified path.
+
+     * 
+
+     * @param path The path to tokenize. Must not be <code>null</code>.
+
+     */
+
+    public function __construct($path) {
+
+        // on Windows and Unix, we can ignore delimiters and still have
+
+        // enough information to tokenize correctly.    
+
+        $this->tokens = preg_split("/[;:]/", $path, -1, PREG_SPLIT_NO_EMPTY);
+
+        $this->dosStyleFilesystem = ( PATH_SEPARATOR == ';');
+
+    }
+
+
+
+    /**
+
+     * Tests if there are more path elements available from this tokenizer's
+
+     * path. If this method returns <code>true</code>, then a subsequent call 
+
+     * to nextToken will successfully return a token.
+
+     * 
+
+     * @return <code>true</code> if and only if there is at least one token 
+
+     * in the string after the current position; <code>false</code> otherwise.
+
+     */
+
+    public function hasMoreTokens() {
+
+        if ($this->lookahead !== null) {
+
+            return true;
+
+        }        
+
+        return !empty($this->tokens);
+
+    }
+
+    
+
+    /**
+
+     * Returns the next path element from this tokenizer.
+
+     * 
+
+     * @return the next path element from this tokenizer.
+
+     * 
+
+     * @throws Exception if there are no more elements in this tokenizer's path.
+
+     */
+
+    public function nextToken() {
+
+            
+
+        if ($this->lookahead !== null) {
+
+            $token = $this->lookahead;
+
+            $this->lookahead = null;
+
+        } else {
+
+            $token = trim(array_shift($this->tokens));
+
+        }
+
+            
+
+
+
+        if (strlen($token) === 1 && Character::isLetter($token{0})
+
+                                && $this->dosStyleFilesystem
+
+                                && !empty($this->tokens)) {
+
+            // we are on a dos style system so this path could be a drive
+
+            // spec. We look at the next token
+
+            $nextToken = trim(array_shift($this->tokens));
+
+            if (StringHelper::startsWith('\\', $nextToken) || StringHelper::startsWith('/', $nextToken)) {
+
+                // we know we are on a DOS style platform and the next path
+
+                // starts with a slash or backslash, so we know this is a 
+
+                // drive spec
+
+                $token .= ':' . $nextToken;
+
+            } else {
+
+                // store the token just read for next time
+
+                $this->lookahead = $nextToken;
+
+            }
+
+        }
+
+        
+
+        return $token;
+
+    }
+
+
+
+    /**
+
+     * Non StringTokenizer function, that indicates whether the specified path is contained in loaded tokens.
+
+     * We can do this easily because in PHP implimentation we're using arrays.
+
+     * @param string $path path to search for.
+
+     * @return boolean
+
+     */
+
+    public function contains($path) {
+
+        return in_array($path, $this->tokens, true);        
+
+    }
+
+    
+
+}
+
+
+
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/util/SourceFileScanner.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/util/SourceFileScanner.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/util/SourceFileScanner.php	(revision 19)
@@ -0,0 +1,159 @@
+<?php
+/*
+ *  $Id: SourceFileScanner.php 325 2007-12-20 15:44:58Z hans $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>. 
+ */
+
+/**
+ *  Utility class that collects the functionality of the various
+ *  scanDir methods that have been scattered in several tasks before.
+ *
+ *  The only method returns an array of source files. The array is a
+ *  subset of the files given as a parameter and holds only those that
+ *  are newer than their corresponding target files.
+ *  @package   phing.util
+ */
+class SourceFileScanner {
+
+    /** Instance of FileUtils */
+    private $fileUtils;
+    
+    /** Task this class is working for -- for logging purposes. */
+    private $task;
+
+    /**
+     * @param task The task we should log messages through
+     */
+    function __construct($task) {
+        $this->task = $task;
+        $this->fileUtils = new FileUtils();
+    }
+
+    /**
+     * Restrict the given set of files to those that are newer than
+     * their corresponding target files.
+     *
+     * @param files   the original set of files
+     * @param srcDir  all files are relative to this directory
+     * @param destDir target files live here. if null file names
+     *                returned by the mapper are assumed to be absolute.
+     * @param FilenameMapper  knows how to construct a target file names from
+     *                source file names.
+     * @param force   Boolean that determines if the files should be
+     *                forced to be copied.
+     */
+    function restrict(&$files, $srcDir, $destDir, $mapper, $force = false) {
+        $now = time();
+        $targetList = "";
+
+        /*
+          If we're on Windows, we have to munge the time up to 2 secs to
+          be able to check file modification times.
+          (Windows has a max resolution of two secs for modification times)
+        */
+        $osname = strtolower(Phing::getProperty('os.name'));
+
+        // indexOf()
+        $index = ((($res = strpos($osname, 'win')) === false) ? -1 : $res);
+        if ($index  >= 0 ) {
+            $now += 2000;
+        }
+
+        $v = array();
+
+        for ($i=0, $size=count($files); $i < $size; $i++) {
+        
+            $targets = $mapper->main($files[$i]);
+            if (empty($targets)) {
+                $this->task->log($files[$i]." skipped - don't know how to handle it", Project::MSG_VERBOSE);
+                continue;
+            }
+
+            $src = null;
+            try {
+                if ($srcDir === null) {
+                    $src = new PhingFile($files[$i]);
+                } else {
+                    $src = $this->fileUtils->resolveFile($srcDir, $files[$i]);
+                }
+    
+                if ($src->lastModified() > $now) {
+                    $this->task->log("Warning: ".$files[$i]." modified in the future (".$src->lastModified()." > ".$now.")", Project::MSG_WARN);
+                }
+            } catch (IOException $ioe) {
+                $this->task->log("Unable to read file ".$files[$i]." (skipping): " . $ioe->getMessage());
+                continue;
+            }
+            
+            $added = false;
+            $targetList = "";
+
+            for ($j=0,$_j=count($targets); (!$added && $j < $_j); $j++) {
+
+                $dest = null;
+                if ($destDir === null) {
+                    $dest = new PhingFile($targets[$j]);
+                } else {
+                    $dest = $this->fileUtils->resolveFile($destDir, $targets[$j]);
+                }
+
+                if (!$dest->exists()) {
+                    $this->task->log($files[$i]." added as " . $dest->__toString() . " doesn't exist.", Project::MSG_VERBOSE);
+                    $v[] =$files[$i];
+                    $added = true;
+                } elseif ($src->lastModified() > $dest->lastModified()) {
+                    $this->task->log($files[$i]." added as " . $dest->__toString() . " is outdated.", Project::MSG_VERBOSE );
+                    $v[]=$files[$i];
+                    $added = true;
+                } elseif ($force === true) {
+                    $this->task->log($files[$i]." added as " . $dest->__toString() . " is forced to be overwritten.", Project::MSG_VERBOSE );
+                    $v[]=$files[$i];
+                    $added = true;
+                } else {
+                    if (strlen($targetList) > 0) {
+                        $targetList .= ", ";
+                    }
+                    $targetList .= $dest->getAbsolutePath();
+                }
+            }
+
+            if (!$added) {
+                $this->task->log($files[$i]." omitted as ".$targetList." ".(count($targets) === 1 ? " is " : " are ")."up to date.",  Project::MSG_VERBOSE);
+            }
+
+        }
+        $result = array();
+        $result = $v;
+        return $result;
+    }
+
+    /**
+     * Convenience layer on top of restrict that returns the source
+     * files as PhingFile objects (containing absolute paths if srcDir is
+     * absolute).
+     */
+    function restrictAsFiles(&$files, &$srcDir, &$destDir, &$mapper) {
+        $res = $this->restrict($files, $srcDir, $destDir, $mapper);
+        $result = array();
+        for ($i=0; $i<count($res); $i++) {
+            $result[$i] = new PhingFile($srcDir, $res[$i]);
+        }
+        return $result;
+    }
+}
+
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/util/StringHelper.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/util/StringHelper.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/util/StringHelper.php	(revision 19)
@@ -0,0 +1,208 @@
+<?php
+
+/**
+ * String helper utility class.
+ *
+ * This class includes some Java-like functions for parsing strings,
+ * as well as some functions for getting qualifiers / unqualifying phing-style
+ * classpaths.  (e.g. "phing.util.StringHelper").
+ *
+ * @author Hans Lellelid <hans@xmpl.org>
+ * @package phing.system.util
+ */
+class StringHelper {
+
+    private static $TRUE_VALUES = array("on", "true", "t", "yes");
+    private static $FALSE_VALUES = array("off", "false", "f", "no");
+    
+    /**
+     * Replaces identifier tokens with corresponding text values in passed string.
+     *
+     * @params array $strings Array of strings to multiply. (If string is passed, will convert to array)
+     * @params array $tokens The tokens to search for.
+     * @params array $replacements The values with which to replace found tokens.
+     * @return string
+     */
+    public static function multiply($strings, $tokens, $replacements) {
+        $strings = (array) $strings;
+        $results = array();
+        foreach ($strings as $string) {
+            $results[] = str_replace($tokens, $replacements, $string);
+        }        
+        return $results;
+    }
+
+    /**
+     * Remove qualification to name.
+     * E.g. eg.Cat -> Cat
+     * @param string $qualifiedName
+     * @param string $separator Character used to separate.
+     */
+    public static function unqualify($qualifiedName, $separator = '.') {
+        // if false, then will be 0
+        $pos = strrpos($qualifiedName, $separator);
+        if ($pos === false) { 
+            return $qualifiedName;  // there is no '.' in the qualifed name
+        } else {
+            return substr($qualifiedName, $pos + 1); // start just after '.'
+        }
+    }
+
+    /** 
+     * Converts a string to an indexed array of chars
+     * There's really no reason for this to be used in PHP, since strings
+     * are all accessible using the $string{0} notation.
+     * @param string $string
+     * @return array
+     * @deprecated
+     */
+    public static function toCharArray($str) {
+        $ret=array();
+        $len=strlen($str);
+        for ($i=0; $i < $len; $i++) {
+            $ret[] = $str{$i};
+        }
+        return $ret;
+    }
+    
+    /**
+     * Get the qualifier part of a qualified name.
+     * E.g. eg.Cat -> eg
+     * @return string
+     */    
+    public static function qualifier($qualifiedName, $seperator = '.') {
+        $pos = strrchr($qualifiedName, $seperator);
+        if ($pos === false) {
+            return '';
+        } else {
+            return substr($qualifiedName, 0, $pos);
+        }
+    }
+    
+    /**
+     * @param array $columns String[]
+     * @param string $prefix
+     * @return array String[]
+     */ 
+    public static function prefix( $columns, $prefix) {
+        if ($prefix == null) return $columns;
+        $qualified = array();
+        foreach($columns as $key => $column) {
+            $qualified[$key] = $prefix . $column;
+        }        
+        return $qualified;
+    }
+    
+    /**
+     *
+     * @return string
+     */ 
+    public static function root($qualifiedName, $separator = '.') {
+        $loc = strpos($qualifiedName, $separator);
+        return ($loc === false) ? $qualifiedName : substr($qualifiedName, 0, $loc);
+    }
+    
+    /**
+     * @return int
+     */
+    public static function hashCode($string) {
+        return crc32($string);
+    }
+    
+    /**
+     * @return boolean
+     */ 
+    public static function booleanValue($s) {
+        if (is_bool($s)) {
+            return $s; // it's already boolean (not a string)
+        }
+        // otherwise assume it's something like "true" or "t"
+        $trimmed = strtolower(trim($s));
+        return (boolean) in_array($trimmed, self::$TRUE_VALUES);
+    }
+
+    /** tests if a string is a representative of a boolean */
+    public static function isBoolean($s) {
+
+        if (is_bool($s)) {
+            return true; // it already is boolean
+        }
+        
+        if ($s === "" || $s === null || !is_string($s)) {
+            return false; // not a valid string for testing
+        }
+
+        $test = trim(strtolower($s));
+        return (boolean) in_array($test, array_merge(self::$FALSE_VALUES, self::$TRUE_VALUES));
+    }
+        
+    /**
+     * Creates a key based on any number of passed params.
+     * @return string
+     */
+    public static function key() {
+        $args = func_get_args();
+        return serialize($args);
+    }    
+    
+    /** tests if a string starts with a given string */
+    public static function startsWith($check, $string) {
+        if ($check === "" || $check === $string) {
+            return true;
+        } else {
+            return (strpos($string, $check) === 0) ? true : false;
+        }
+    }
+    
+    /** tests if a string ends with a given string */
+    public static function endsWith($check, $string) {
+        if ($check === "" || $check === $string) {
+            return true;
+        } else {
+            return (strpos(strrev($string), strrev($check)) === 0) ? true : false;
+        }
+    }            
+
+    /**
+     * a natural way of getting a subtring, php's circular string buffer and strange
+     * return values suck if you want to program strict as of C or friends 
+     */
+    public static function substring($string, $startpos, $endpos = -1) {
+        $len    = strlen($string);
+        $endpos = (int) (($endpos === -1) ? $len-1 : $endpos);
+        if ($startpos > $len-1 || $startpos < 0) {
+            trigger_error("substring(), Startindex out of bounds must be 0<n<$len", E_USER_ERROR);
+        }
+        if ($endpos > $len-1 || $endpos < $startpos) {
+            trigger_error("substring(), Endindex out of bounds must be $startpos<n<".($len-1), E_USER_ERROR);
+        }
+        if ($startpos === $endpos) {
+            return (string) $string{$startpos};
+        } else {
+            $len = $endpos-$startpos;
+        }
+        return substr($string, $startpos, $len+1);
+    }
+
+    /**
+     * Does the value correspond to a slot variable?
+     * @param string $value    
+     */
+    public static function isSlotVar($value) {
+        $value = trim($value);
+        if ($value === "") return false;
+        return preg_match('/^%\{([\w\.\-]+)\}$/', $value);
+    }
+    
+    /**
+     * Extracts the variable name for a slot var in the format %{task.current_file}
+     * @param string $var The var from build file.
+     * @return string Extracted name part.
+     */
+    public static function slotVar($var) {
+        return trim($var, '%{} ');
+    }
+    
+}
+
+
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/util/regexp/PregEngine.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/util/regexp/PregEngine.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/util/regexp/PregEngine.php	(revision 19)
@@ -0,0 +1,104 @@
+<?php
+/* 
+ *  $Id: PregEngine.php 325 2007-12-20 15:44:58Z hans $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>. 
+ */
+
+require_once 'phing/util/regexp/RegexpEngine.php';
+
+/**
+ * PREG Regexp Engine.
+ * Implements a regexp engine using PHP's preg_match(), preg_match_all(), and preg_replace() functions.
+ * 
+ * @author hans lellelid, hans@velum.net
+ * @package phing.util.regex
+ */
+class PregEngine implements RegexpEngine {
+
+    /**
+     * @var boolean
+     */
+    private $ignoreCase = false;
+        
+    /**
+     * Sets whether or not regex operation is case sensitive.
+     * @param boolean $bit
+     * @return void
+     */
+    function setIgnoreCase($bit) {
+        $this->ignoreCase = (boolean) $bit;
+    }
+
+    /**
+     * Gets whether or not regex operation is case sensitive.
+     * @return boolean
+     */
+    function getIgnoreCase() {
+        return $this->ignoreCase;
+    }
+        
+    /**
+     * The pattern needs to be converted into PREG style -- which includes adding expression delims & any flags, etc.
+     * @param string $pattern
+     * @return string prepared pattern.
+     */
+    private function preparePattern($pattern)
+    {
+        return '/'.$pattern.'/'.($this->ignoreCase ? 'i' : '');
+    }
+    
+    /**
+     * Matches pattern against source string and sets the matches array.
+     * @param string $pattern The regex pattern to match.
+     * @param string $source The source string.
+     * @param array $matches The array in which to store matches.
+     * @return boolean Success of matching operation.
+     */
+    function match($pattern, $source, &$matches) { 
+        return preg_match($this->preparePattern($pattern), $source, $matches);
+    }
+
+    /**
+     * Matches all patterns in source string and sets the matches array.
+     * @param string $pattern The regex pattern to match.
+     * @param string $source The source string.
+     * @param array $matches The array in which to store matches.
+     * @return boolean Success of matching operation.
+     */        
+    function matchAll($pattern, $source, &$matches) {
+        return preg_match_all($this->preparePattern($pattern), $source, $matches);
+    }
+
+    /**
+     * Replaces $pattern with $replace in $source string.
+     * References to \1 group matches will be replaced with more preg-friendly
+     * $1.
+     * @param string $pattern The regex pattern to match.
+     * @param string $replace The string with which to replace matches.
+     * @param string $source The source string.
+     * @return string The replaced source string.
+     */        
+    function replace($pattern, $replace, $source) {
+        // convert \1 -> $1, because we want to use the more generic \1 in the XML
+        // but PREG prefers $1 syntax.
+        $replace = preg_replace('/\\\(\d+)/', '\$$1', $replace);
+        return preg_replace($this->preparePattern($pattern), $replace, $source);
+    }
+
+}
+
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/util/regexp/Regexp.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/util/regexp/Regexp.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/util/regexp/Regexp.php	(revision 19)
@@ -0,0 +1,167 @@
+<?php
+/* 
+ *  $Id: Regexp.php 325 2007-12-20 15:44:58Z hans $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>. 
+ */
+
+/**
+ * A factory class for regex functions.
+ * @author Hans Lellelid <hans@xmpl.org>
+ * @package  phing.util.regexp
+ * @version $Revision: 1.5 $
+ */
+class Regexp {
+
+    /**
+     * Matching groups found. 
+     * @var array
+     */
+    private $groups = array();
+     
+    /**
+     * Pattern to match.
+     * @var string
+     */
+    private $pattern;
+    
+    /**
+     * Replacement pattern.
+     * @var string
+     */
+    private $replace;
+    
+    /**
+     * The regex engine -- e.g. 'preg' or 'ereg';
+     * @var RegexpEngine
+     */
+    private $engine;
+    
+    /**
+     * Constructor sets the regex engine to use (preg by default).
+     * @param string $_engineType The regex engine to use.
+     */
+    function __construct($engineType='preg') {        
+        if ($engineType == 'preg') {
+            include_once 'phing/util/regexp/PregEngine.php';
+            $this->engine = new PregEngine();
+        } elseif ($engineType == 'ereg') {
+            include_once 'phing/util/regexp/EregEngine.php';
+            $this->engine = new EregEngine();
+        } else {
+            throw new BuildException("Invalid engine type for Regexp: " . $engineType);
+        }                
+    }
+
+    /**
+     * Sets pattern to use for matching.
+     * @param string $pat The pattern to match on.
+     * @return void
+     */
+    public function setPattern($pat) {
+        $this->pattern = (string) $pat;        
+    }
+    
+    
+    /**
+     * Gets pattern to use for matching.
+     * @return string The pattern to match on.
+     */
+    public function getPattern() {
+        return $this->pattern;
+    }
+    
+    /**
+     * Sets replacement string.
+     * @param string $rep The pattern to replace matches with.
+     * @return void
+     */
+    public function setReplace($rep) {
+        $this->replace = (string) $rep;
+    }
+    
+    /**
+     * Gets replacement string.
+     * @return string The pattern to replace matches with.
+     * @return void
+     */
+    public function getReplace() {
+        return $this->replace;
+    }
+    
+    /**
+     * Performs match of specified pattern against $subject.
+     * @param string $subject The subject, on which to perform matches.
+     * @return boolean Whether or not pattern matches subject string passed.
+     */
+    public function matches($subject) {
+        if($this->pattern === null) {            
+            throw new Exception("No pattern specified for regexp match().");
+        }
+        return $this->engine->match($this->pattern, $subject, $this->groups);
+    }
+    
+    /**
+     * Performs replacement of specified pattern and replacement strings.
+     * @param string $subject Text on which to perform replacement.
+     * @return string subject after replacement has been performed.
+     */
+    public function replace($subject) {
+        if ($this->pattern === null || $this->replace === null) {
+            throw new Exception("Missing pattern or replacement string regexp replace().");
+        }        
+        return $this->engine->replace($this->pattern, $this->replace, $subject);
+    }
+    
+    /**
+     * Get array of matched groups.
+     * @return array Matched groups
+     */ 
+    function getGroups() {
+        return $this->groups;
+    }
+
+    /**
+     * Get specific matched group. 
+     * @param integer $idx
+     * @return string specified group or NULL if group is not set.
+     */ 
+    function getGroup($idx) { 
+        if (!isset($this->groups[$idx])) {
+            return null;
+        }
+        return $this->groups[$idx];
+    }
+    
+    /**
+     * Sets whether the regexp matching is case insensitive.
+     * (default is false -- i.e. case sensisitive)
+     * @param boolean $bit
+     */ 
+    function setIgnoreCase($bit) {
+        $this->engine->setIgnoreCase($bit);
+    }
+    
+    /**
+     * Gets whether the regexp matching is case insensitive.
+     * @return boolean
+     */
+    function getIgnoreCase() {
+        return $this->engine->getIgnoreCase();
+    }
+} 
+
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/util/regexp/RegexpEngine.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/util/regexp/RegexpEngine.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/classes/phing/util/regexp/RegexpEngine.php	(revision 19)
@@ -0,0 +1,73 @@
+<?php
+/* 
+ *  $Id: RegexpEngine.php 325 2007-12-20 15:44:58Z hans $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>. 
+ */
+
+/**
+ * Contains some shared attributes and methods -- and some abstract methods with
+ * engine-specific implementations that sub-classes must override.
+ * 
+ * @author Hans Lellelid <hans@velum.net>
+ * @package phing.util.regex
+ * @version $Revision: 1.4 $
+ */
+interface RegexpEngine {
+    
+    /**
+     * Sets whether or not regex operation should ingore case.
+     * @param boolean $bit
+     * @return void
+     */
+    public function setIgnoreCase($bit);
+    
+    /**
+     * Returns status of ignore case flag.
+     * @return boolean
+     */
+    public function getIgnoreCase();
+    
+    /**
+     * Matches pattern against source string and sets the matches array.
+     * @param string $pattern The regex pattern to match.
+     * @param string $source The source string.
+     * @param array $matches The array in which to store matches.
+     * @return boolean Success of matching operation.
+     */
+    function match($pattern, $source, &$matches);
+    
+    /**
+     * Matches all patterns in source string and sets the matches array.
+     * @param string $pattern The regex pattern to match.
+     * @param string $source The source string.
+     * @param array $matches The array in which to store matches.
+     * @return boolean Success of matching operation.
+     */    
+    function matchAll($pattern, $source, &$matches);
+
+    /**
+     * Replaces $pattern with $replace in $source string.
+     * @param string $pattern The regex pattern to match.
+     * @param string $replace The string with which to replace matches.
+     * @param string $source The source string.
+     * @return string The replaced source string.
+     */        
+    function replace($pattern, $replace, $source);
+
+}
+
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/docs/docsystem/html/FrameToCBottom.html
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/docs/docsystem/html/FrameToCBottom.html	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/docs/docsystem/html/FrameToCBottom.html	(revision 19)
@@ -0,0 +1,4 @@
+
+</body>
+</html>
+<!-- $Id -->
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/docs/docsystem/html/FrameToCTop.html
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/docs/docsystem/html/FrameToCTop.html	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/docs/docsystem/html/FrameToCTop.html	(revision 19)
@@ -0,0 +1,15 @@
+<!--
+-File         $Id: FrameToCTop.html 123 2006-09-14 20:19:08Z mrook $
+-License      GNU FDL (http://www.gnu.org/copyleft/fdl.html)
+-Copyright    2002, turing
+-Author       alex black, enigma@turingstudio.com
+-->
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/2000/REC-xhtml1-20000126/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+	<title> binarycloud contributor guide </title> 
+	<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
+	<link rel="Stylesheet" rev="Stylesheet" href="../css/FrameToc.css" type="text/css" media="All" charset="iso-8859-1" />
+</head>
+<body>
+
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/docs/docsystem/html/StandardToCBottom.html
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/docs/docsystem/html/StandardToCBottom.html	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/docs/docsystem/html/StandardToCBottom.html	(revision 19)
@@ -0,0 +1,5 @@
+
+
+</body>
+</html>
+<!-- $Id -->
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/docs/docsystem/html/StandardToCTop.html
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/docs/docsystem/html/StandardToCTop.html	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/docs/docsystem/html/StandardToCTop.html	(revision 19)
@@ -0,0 +1,16 @@
+<!--
+-File         $Id: StandardToCTop.html 123 2006-09-14 20:19:08Z mrook $
+-License      GNU FDL (http://www.gnu.org/copyleft/fdl.html)
+-Copyright    2002, turing
+-Author       alex black, enigma@turingstudio.com
+-->
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/2000/REC-xhtml1-20000126/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+	<title> table of contents </title> 
+	<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
+	<link rel="Stylesheet" rev="Stylesheet" href="../css/Documentation.css" type="text/css" media="All" charset="iso-8859-1" />
+</head>
+<body>
+
+<h1>Table of Contents</h1>
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/docs/docsystem/xsl/Chapters.xsl
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/docs/docsystem/xsl/Chapters.xsl	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/docs/docsystem/xsl/Chapters.xsl	(revision 19)
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="ISO-8859-1" ?>
+<!--
+// {{{ Header
+-File         $Id: Chapters.xsl 123 2006-09-14 20:19:08Z mrook $
+-License      LGPL (http://www.gnu.org/copyleft/lesser.html)
+-Copyright    2002, The Turing Studio, Inc.
+-Author       alex black, enigma@turingstudio.com
+// }}}
+-->
+<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
+    <xsl:output omit-xml-declaration="yes" indent="no" method="xml" encoding="iso-8859-1" />
+
+<xsl:template match="//html">
+<xsl:for-each select="//h1"><xsl:text>new Array('</xsl:text><xsl:value-of select="$file_name" /><xsl:text>','</xsl:text><xsl:value-of select="." /><xsl:text>'),</xsl:text></xsl:for-each>
+</xsl:template>
+
+</xsl:stylesheet>
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/docs/docsystem/xsl/Toc.xsl
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/docs/docsystem/xsl/Toc.xsl	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/docs/docsystem/xsl/Toc.xsl	(revision 19)
@@ -0,0 +1,59 @@
+<?xml version="1.0" encoding="ISO-8859-1" ?>
+<!--
+// {{{ Header
+-File         $Id: Toc.xsl 123 2006-09-14 20:19:08Z mrook $
+-License      LGPL (http://www.gnu.org/copyleft/lesser.html)
+-Copyright    2002, The Turing Studio, Inc.
+-Author       alex black, enigma@turingstudio.com
+// }}}
+-->
+<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
+
+    <xsl:output omit-xml-declaration="yes" indent="yes" method="html" encoding="iso-8859-1" />
+	
+    <xsl:template match="/">	
+    <ul>		
+        <xsl:for-each select="//h1">
+        <li>
+            <a>
+                <xsl:attribute name="href">
+                    <xsl:text>../</xsl:text><xsl:value-of select="$file_name" />
+                </xsl:attribute>
+                <xsl:if test="$mode = 'frame'">
+                    <xsl:attribute name="target"><xsl:text>Content</xsl:text></xsl:attribute>
+                </xsl:if>
+                <xsl:value-of select="." />
+            </a>
+        </li>
+        </xsl:for-each>
+        <ul>
+        <xsl:for-each select="//h2">
+            <li>
+                <xsl:if test="a">
+                <a>
+                    <xsl:apply-templates select="a" />
+                    <xsl:value-of select="." />
+                </a>
+                </xsl:if>
+                <xsl:if test="not(a)">
+                    <xsl:value-of select="." />
+                </xsl:if>
+            </li>
+        </xsl:for-each>
+        </ul>
+    </ul>
+    </xsl:template>
+
+    <xsl:template match="a">
+		<xsl:attribute name="href">
+    		<xsl:text>../</xsl:text><xsl:value-of select="$file_name" />
+    		<xsl:if test="@name">
+        		<xsl:text>#</xsl:text><xsl:value-of select="@name" />
+            </xsl:if>
+		</xsl:attribute>
+        <xsl:if test="$mode = 'frame'">
+            <xsl:attribute name="target"><xsl:text>Content</xsl:text></xsl:attribute>
+        </xsl:if>
+    </xsl:template>      
+
+</xsl:stylesheet>
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/docs/example/build.xml
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/docs/example/build.xml	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/docs/example/build.xml	(revision 19)
@@ -0,0 +1,58 @@
+<?xml version="1.0"?>
+
+<project name="Hello World Example" default="build" basedir="." description="This is an example buildfile for Phing.">
+	<target name="prepare">
+		<mkdir dir="reports/coverage"/>
+		<mkdir dir="reports/tests"/>
+		<mkdir dir="docs"/>
+	</target>
+	
+	<target name="reports">
+		<coverage-setup database="reports/coverage.db">
+			<fileset dir="src">
+				<include name="*.php"/>
+				<exclude name="*Test.php"/>
+			</fileset>
+		</coverage-setup>
+		<phpunit codecoverage="true">
+			<formatter type="xml" todir="reports"/>
+			<batchtest>
+				<fileset dir="src">
+					<include name="*Test.php"/>
+				</fileset>
+			</batchtest>
+		</phpunit>
+		<phpunitreport infile="reports/testsuites.xml" format="frames" todir="reports/tests" styledir="../../etc"/>
+		<coverage-report outfile="reports/coverage.xml">
+			<report todir="reports/coverage" styledir="../../etc"/>
+		</coverage-report>
+	</target>
+	
+	<target name="test">
+		<phpunit2 haltonerror="true" haltonfailure="true">
+			<batchtest>
+				<fileset dir="src">
+					<include name="*Test.php"/>
+				</fileset>
+			</batchtest>
+		</phpunit2>
+	</target>
+	
+	<target name="docs">
+		<phpdoc title="Phing Example" destdir="docs"
+			sourcepath="src" output="HTML:Smarty:PHP"
+			linksource="true"/>
+	</target>
+	
+	<target name="build" depends="test,prepare,reports,docs">
+		<zip destfile="helloworld.zip" basedir="src"/>
+		<tar destfile="helloworld.tar" basedir="src"/>
+	</target>
+
+	<target name="clean">
+		<delete dir="reports"/>
+		<delete dir="docs"/>
+		<delete file="helloworld.zip"/>
+		<delete file="helloworld.tar"/>
+	</target>
+</project>
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/docs/example/src/HelloWorld.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/docs/example/src/HelloWorld.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/docs/example/src/HelloWorld.php	(revision 19)
@@ -0,0 +1,18 @@
+<?php
+
+	/**
+	 * The Hello World class!
+	 *
+	 * @author Michiel Rook
+	 * @version $Id: HelloWorld.php 227 2007-08-28 02:17:00Z hans $
+	 * @package hello.world
+	 */
+	class HelloWorld
+	{
+		function sayHello()
+		{
+			return "Hello World!";
+		}
+	};
+
+?>
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/docs/example/src/HelloWorldTest.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/docs/example/src/HelloWorldTest.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/docs/example/src/HelloWorldTest.php	(revision 19)
@@ -0,0 +1,22 @@
+<?php
+
+    require_once "PHPUnit2/Framework/TestCase.php";
+    require_once "HelloWorld.php";
+
+    /**
+    * Test class for HelloWorld
+    *
+    * @author Michiel Rook
+    * @version $Id: HelloWorldTest.php 123 2006-09-14 20:19:08Z mrook $
+    * @package hello.world
+    */
+    class HelloWorldTest extends PHPUnit2_Framework_TestCase
+    {
+        public function testSayHello()
+        {
+            $hello = new HelloWorld();
+            $this->assertEquals("Hello World!", $hello->sayHello());
+        }
+    }
+
+?>
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/docs/phing_guide/book/PhingGuide.book
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/docs/phing_guide/book/PhingGuide.book	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/docs/phing_guide/book/PhingGuide.book	(revision 19)
@@ -0,0 +1,18 @@
+#HTMLDOC
+--titleimage book/frame/TitlePage.html --logoimage book/images/logo-pdfsm.png --header "l.." --tocheader "l.." --footer "1 D" --linkcolor 003366 --linkstyle plain --jpeg=90
+chapters/AboutThisBook.html
+chapters/Introduction.html
+chapters/Setup.html
+chapters/GettingStarted.html
+chapters/ProjectComponents.html
+chapters/ExtendingPhing.html
+chapters/appendixes/AppendixA-FactSheet.html
+chapters/appendixes/AppendixB-CoreTasks.html
+chapters/appendixes/AppendixC-OptionalTasks.html
+chapters/appendixes/AppendixD-CoreTypes.html
+chapters/appendixes/AppendixD2-CoreFilters.html
+chapters/appendixes/AppendixD3-CoreMappers.html
+chapters/appendixes/AppendixD4-CoreSelectors.html
+chapters/appendixes/AppendixE-ProjectComponents.html
+chapters/appendixes/AppendixF-FileFormats.html
+chapters/Bibliography.html
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/docs/phing_guide/book/chapters/AboutThisBook.html
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/docs/phing_guide/book/chapters/AboutThisBook.html	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/docs/phing_guide/book/chapters/AboutThisBook.html	(revision 19)
@@ -0,0 +1,46 @@
+<!--
+-File         $Id: AboutThisBook.html 182 2007-04-17 14:37:01Z mrook $
+-License      GNU FDL (http://www.gnu.org/copyleft/fdl.html)
+-Copyright    2002, turing
+-Author       alex black, enigma@turingstudio.com
+-->
+<!--
+REMOVED UNTIL PHP5 libxml2 support includes loadHTML() method:
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/2000/REC-xhtml1-20000126/DTD/xhtml1-strict.dtd"
+<html xmlns="http://www.w3.org/1999/xhtml"
+-->
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/2000/REC-xhtml1-20000126/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+	<title>Phing Guide - About This Book</title>
+	<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
+	<link rel="Stylesheet" rev="Stylesheet" href="../css/Documentation.css" type="text/css" media="All" charset="iso-8859-1" />
+</head>
+<body>
+<h1>About this book</h1> <h2><a name="Authors"></a>Authors</h2>
+<ul>
+  <li>Andreas Aderhold, andi@binarycloud.com</li>
+  <li>Alex Black, enigma@turingstudio.com</li>
+  <li>Manuel Holtgrewe, grin@gmx.net</li>
+  <li>Hans Lellelid, hans@xmpl.org</li>
+  <li>Michiel Rook, michiel.rook@gmail.com</li>
+</ul>
+<p>Because Phing is based on Ant, parts of this manual are also adapted from the
+  Ant manual (see <a href="Bibliography.html#ant">[ant]</a>).</p>
+<h2><a name="CVS"></a>CVS</h2>
+<p>
+	$Id: AboutThisBook.html 182 2007-04-17 14:37:01Z mrook $
+</p>
+<p>
+	$Revision: 1.4 $
+</p>
+<h2><a name="Copyright"></a>Copyright</h2>
+<p> Copyright 2003, turing and others. </p>
+<h2><a name="License"></a>License</h2>
+<p>
+	See the GNU FDL (<a href="Bibliography.html#gnu-fdl">[gnu-fdl]</a>,
+    which is included in this book.
+</p>
+<pre>Copyright (c) 2002, turing<br />Permission is granted to copy, distribute and/or modify this document<br />under the terms of the GNU Free Documentation License, Version 1.1<br />or any later version published by the Free Software Foundation;<br />A copy of the license is included in the section entitled &quot;License&quot;.</pre>
+</body>
+</html>
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/docs/phing_guide/book/chapters/BasicConcepts.html
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/docs/phing_guide/book/chapters/BasicConcepts.html	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/docs/phing_guide/book/chapters/BasicConcepts.html	(revision 19)
@@ -0,0 +1,139 @@
+<!--
+-File         $Id: BasicConcepts.html 182 2007-04-17 14:37:01Z mrook $
+-License      GNU FDL (http://www.gnu.org/copyleft/fdl.html)
+-Copyright    2002, turing
+-Author       alex black, enigma@turingstudio.com
+-->
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/2000/REC-xhtml1-20000126/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+  <head>
+  <title>Phing Guide - Basic Concepts</title>
+  <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
+  <link rel="Stylesheet" rev="Stylesheet" href="../css/Documentation.css" type="text/css" media="All" charset="iso-8859-1" />
+  </head>
+
+  <body>
+
+<h1><a name="BasicConcepts"></a>Basic Concepts</h1>
+
+<p> Technically Phing uses a layered model to perform its actions. The following
+  section briefly describes the layers used by Phing. If you're only a user who
+  does not want to extend Phing or are not interested in the interior of Phing
+  you can safely skip this chapter.</p>
+
+<h2><a name="InitLayer"></a>The Init Layer</h2>
+
+<p>The Init Layer sets up the working environment for Phing. It
+provides core services like the Logger, a Timer, a file I/O API and
+so forth. For the technical details on Init see the chapter about
+developing with Phing. Basically the Init Layer consists of various
+different file located in different places:</p>
+
+<p>The exact files and techniques used for the init process are not discussed
+  in this chapter. To get a brief idea simply browse the files mentioned above.
+  More detailed insights to the matter are given in: [REF].</p>
+
+<h3><a name="EnvironmentAndPackageSupport"></a>Environment And Package Support</h3>
+
+<p>
+Phing needs to find some files and constants that are accessible
+throughout the system. First of all it determines the system
+environment variables that have to be set during the installation
+of Phing. See <a href="Setup.html">Setting up Phing</a>
+for more information on setting up Phing. If this very essential
+variables can not be found or guessed the program terminates with
+a proper error message. We assume everything is set-up properly
+and the initialization of paths and constants went fine.
+</p>
+
+<p>
+The system uses a generalized package support, similar to the
+Java package support to locate and include required source files.
+This package support must be set-up properly so Phing finds all the
+files it needs. The Init Layer does this for you given your
+environment variables are set properly.
+</p>
+
+<p>
+To put it in a nutshell, the Init Layer
+</p>
+
+<ul>
+  <li>Checks your Phing environment variables and makes them accessible
+      within the Phing application.</li>
+  <li>Provides you with several core services like:<ul>
+    <li>File API</li>
+    <li>Logging system</li>
+    <li>Exception system</li>
+    <li>Event system</li>
+  </ul></li>
+  <li>Provides you with tools to include files using dot-path notation similar to Java's</li>
+</ul>
+
+<h2><a name="PhingLayer"></a>The Phing Layer</h2>
+
+<p>
+While the parts of the system layer might be useful for other applications,
+too, the <em>Phing Layer</em> provides you with several modules that only
+make sense within Phing. The modules in this layer use the first layer
+to throw exceptions, etc., so this one is on top of Init Layer.
+</p>
+
+<h3><a name="SpecializedInitComponents"></a>Specialized Init Components</h3>
+
+<p>
+First, the Phing Layer contains classes derived from some of those in
+Init Layer, like:
+</p>
+
+<ul>
+  <li>Logger for Projects</li>
+  <li>Exception subclasses for the errors that may occur during the
+      Phing build process.</li>
+  <li>Phing Events and Listeners</li>
+  <li>More Complex File API</li>
+</ul>
+
+<h3><a name="PhingTypes"></a>Phing Project Component Classes</h3>
+
+<p>
+Second, the Phing Layer provides you with base classes for Projects and
+the &quot;things&quot; in projects: Targets, Tasks and Types. Phing
+always operates on one project that contains Targets, Tasks and Types.
+</p>
+
+<p> Tasks are &quot;pieces of code&quot; that are executed. They are implemented
+  as classes. See <a href="ExtendingPhing.html">Extending Phing</a> for details.
+  Types are essentially the different type of variables that are available to
+  be used within tasks. These types may be complex (filesets, etc.) or simply
+  a wrapper for key/value pairs. Targets are &quot;chunks of tasks and types&quot;
+  that have a unique name -- sorta like functions/methods. </p>
+
+<p> Every project has a default target that is executed, if no target to execute
+  is given to Phing, but you can call other targets from the command line, too.
+  Targets may <em>depend</em> on each other, e.g. if Target A depends on Target
+  B, Phing will execute B before A. </p>
+
+<h3><a name="BuildFileParser"></a>The Build File Parser</h3>
+
+<p> So, but how to define these Projects and their components? Well, the answer
+  is: We define them within a <em>build file</em>. What format to chose? Because
+  build files have a hierarchical structure -- Projects containing targets, containing
+  tasks etc. -- they are written in XML.</p>
+
+<p>
+These XML files have to be parsed. For that, the Phing Layer provides
+an XML parser that is give a list that maps tag names to classes.
+So, for example, <em>ProjectParser</em> knows, the
+<em>&lt;property&gt;</em> Tag and the information defined in it
+is handled by <em>phing.tasks.system.PropertyTask</em>.
+</p>
+
+<p>
+For more information regarding the Parser and the parsing process and
+how to write your own files, please see
+<a href="ExtendingPhing.html">Extending Phing</a>.
+</p>
+
+  </body>
+</html>
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/docs/phing_guide/book/chapters/Bibliography.html
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/docs/phing_guide/book/chapters/Bibliography.html	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/docs/phing_guide/book/chapters/Bibliography.html	(revision 19)
@@ -0,0 +1,233 @@
+<!--
+-File         $Id: Bibliography.html 182 2007-04-17 14:37:01Z mrook $
+-License      GNU FDL (http://www.gnu.org/copyleft/fdl.html)
+-Copyright    2002, turing
+-Author       alex black, enigma@turingstudio.com
+-->
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/2000/REC-xhtml1-20000126/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+  <title>Phing Guide - Bibliography</title>
+  <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
+  <link rel="Stylesheet" rev="Stylesheet" href="../css/Documentation.css" type="text/css" media="All" charset="iso-8859-1" />
+</head>
+
+<body>
+
+<h1>Bibliography</h1>
+
+<h2><a name="InternationalStandards"></a>International Standards</h2>
+
+<dl>
+  <dt><a name="osi-model"></a>[osi-model]</dt>
+  <dd>
+    <p>OSI (Open System Interconnect) Model</p>
+    <ul>
+      <li><a href="http://www.iso.org" target="_blank">http://www.iso.org</a></li>
+      <li><a href="http://www.instantweb.com/foldoc/foldoc.cgi?OSI" target="_blank">http://www.instantweb.com/foldoc/foldoc.cgi?OSI</a></li>
+    </ul>
+  </dd>
+
+  <dt><a name="xml10-spec"></a>[xml10-spec]</dt>
+  <dd>
+    <p>W3C XML 1.0 Specifications</p>
+    <ul>
+      <li><a href="http://www.w3.org/XML/" target="_blank">http://www.w3.org/XML/</a></li>
+    </ul>
+  </dd>
+
+  <dt><a name="unicode"></a>[unicode]</dt>
+  <dd>
+    <p>Unicode</p>
+    <ul>
+      <li><a href="http://www.unicode.org">http://www.unicode.org</a></li>
+    </ul>
+  </dd>
+</dl>
+
+
+<h2><a name="licenses"></a>Licenses</h2>
+
+<dl>
+  <dt><a name="gnu-lgpl"></a>[gnu-lgpl]</dt>
+  <dd>
+    <p>The GPL (Gnu Lesser Public License)</p>
+    <ul>
+      <li><a href="http://www.gnu.org/licenses/lgpl.html" target="_blank">http://www.gnu.org/licenses/lgpl.html</a></li>
+    </ul>
+  </dd>
+
+  <dt><a name="gnu-fdl"></a>[gnu-fdl]</dt>
+  <dd>
+    <p>The Gnu FDL (Free Documentation License), the license used for this
+       documentation</p>
+    <ul>
+      <li><a href="http://www.gnu.org/licenses/fdl.html" target="_blank">http://www.gnu.org/licenses/fdl.html</a></li>
+    </ul>
+  </dd>
+
+</dl>
+
+
+<h2><a name="os-projects"></a>Open Source Projects</h2>
+
+<dl>
+  <dt><a name="bc"></a>[bc]</dt>
+  <dd>
+    <p>Binarycloud</p>
+    <ul>
+      <li><a href="http://www.binarycloud.com" target="_blank">http://www.binarycloud.com</a></li>
+      <li><a href="http://binarycloud.tigris.org" target="_blank">http://binarycloud.tigris.org</a></li>
+    </ul>
+  </dd>
+
+  <dt><a name="w3c-tidy"></a>[w3c-tidy]</dt>
+  <dd>
+    <p>HTMLTidy, a W3C (x)HTML and XML syntax checker and code beautifier</p>
+    <ul>
+      <li><a href="http://www.w3c.org/People/Raggett/tidy/">http://www.w3c.org/People/Ragget/tidy/</a></li>
+    </ul>
+  </dd>
+
+  <dt><a name="phpdoc"></a>[phpdoc]</dt>
+  <dd>
+    <p>The PHPDoc Project</p>
+    <ul>
+      <li><a href="http://www.phpdoc.de" target="_blank">http://www.phpdoc.de</a></li>
+    </ul>
+  </dd>
+
+  <dt><a name="phpclasses"></a>[phpclasses]</dt>
+  <dd>
+    <p>Manuel Lemos' PHPClasses Repository</p>
+    <ul>
+      <li><a href="http://www.phpclasses.org" target="_blank">http://www.phpclasses.org</a></li>
+    </ul>
+  </dd>
+
+  <dt><a name="pear"></a>[pear]</dt>
+  <dd>
+    <p>PEAR (Php Extension Archive Repository)</p>
+    <ul>
+      <li><a href="http://pear.php.net" target="_blank">http://pear.php.net</a></li>
+    </ul>
+  </dd>
+
+  <dt><a name="ant"></a>[ant]</dt>
+  <dd>
+    <p>Ant, a Java Build Tool, the main inspiration for Phing</p>
+    <ul>
+      <li><a href="http://ant.apache.org" target="_blank">http://ant.apache.org</a></li>
+    </ul>
+  </dd>
+
+  <dt><a name="gnumake"></a>[gnumake]</dt>
+  <dd>
+    <p>GNU make, an inspiration for Phing</p>
+    <ul>
+      <li><a href="http://www.gnu.org/software/make/make.html" target="_blank">http://www.gnu.org/software/make/make.html</a></li>
+    </ul>
+  </dd>
+
+  <dt><a name="pollo"></a>[pollo]</dt>
+  <dd>
+    <p>Pollo, a visual editor for XML files. A schema to edit phing build files
+       is shipped with Phing.</p>
+    <ul>
+      <li><a href="http://pollo.sourceforge.net" target="_blank">http://pollo.sourceforge.net</a></li>
+    </ul>
+  </dd>
+
+  <dt><a name="gingerall"></a>[gingerall]</dt>
+  <dd>
+    <p>Ginger Alliance - Home Of Sablotorn</p>
+    <ul>
+      <li><a href="http://www.gingerall.com" target="_blank">http://www.gingerall.com</a></li>
+    </ul>
+  </dd>
+
+  <dt><a name="php"></a>[php]</dt>
+  <dd>
+    <p>The PHP homepage - PHP Hypertext Preprocessor</p>
+    <ul>
+      <li><a href="http://www.php.net" target="_blank">http://www.php.net</a></li>
+    </ul>
+  </dd>
+
+  <dt><a name="gnu"></a>[gnu]</dt>
+  <dd>
+    <p>The GNU (GNU's Not Unix) Organization</p>
+    <ul>
+      <li><a href="http://www.gnu.org" target="_blank">http://www.gnu.org</a></li>
+    </ul>
+  </dd>
+
+  <dt><a name="phing"></a>[phing]</dt>
+  <dd>
+    <p>Phing (PHing Is Not Gnumake)</p>
+    <ul>
+      <li><a href="http://phing.info/phing" target="_blank">http://phing.info</a></li>
+    </ul>
+  </dd>
+
+<!--
+  <dt><a name=""></a></dt>
+  <dd>
+    <p></p>
+    <ul>
+      <li><a href="http://" target="_blank">http://</a></li>
+    </ul>
+  </dd>
+
+  <dt><a name=""></a></dt>
+  <dd>
+    <p></p>
+    <ul>
+      <li><a href="http://" target="_blank">http://</a></li>
+    </ul>
+  </dd>
+-->
+</dl>
+
+<h2><a name="Manuals"></a>Manuals</h2>
+
+<dl>
+  <dt><a name="cvs-howto"></a>[cvs-howto]</dt>
+  <dd>
+    <p>Short manuals for CVS</p>
+    <ul>
+      <li><a href="http://www.ucolick.org/~de/CVSbeginner.html" target="_blank">http://www.ucolick.org/~de/CVSbeginner.html</a></li>
+    </ul>
+  </dd>
+
+  <dt><a name="cvs-tigris"></a>[cvs-tigris]</dt>
+  <dd>
+    <p>CVS and tigris.org</p>
+    <ul>
+      <li><a href="http://binarycloud.tigris.org/project/www/docs/ddUsingCVS_command-line.html" target="_blank">http://binarycloud.tigris.org/project/www/docs/ddUsingCVS_command-line.html</a></li>
+    </ul>
+  </dd>
+</dl>
+
+<h2><a name="OtherResouces"></a>Other Resources</h2>
+
+<dl>
+  <dt><a name="javadoc"></a>[javadoc]</dt>
+  <dd>
+    <p>Sun Javadoc</p>
+    <ul>
+      <li><a href="http://java.sun.com/j2se/javadoc/" target="_blank">http://java.sun.com/j2se/javadoc/</a></li>
+    </ul>
+  </dd>
+
+  <dt><a name="zend"></a>[zend]</dt>
+  <dd>
+    <p>Zend Technologies, Ltd.</p>
+    <ul>
+      <li><a href="http://www.zend.com" target="_blank">http://www.zend.com</a></li>
+    </ul>
+  </dd>
+</dl>
+
+</body>
+</html>
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/docs/phing_guide/book/chapters/ExtendingPhing.html
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/docs/phing_guide/book/chapters/ExtendingPhing.html	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/docs/phing_guide/book/chapters/ExtendingPhing.html	(revision 19)
@@ -0,0 +1,814 @@
+<!--
+-File         $Id: ExtendingPhing.html 123 2006-09-14 20:19:08Z mrook $
+-License      GNU FDL (http://www.gnu.org/copyleft/fdl.html)
+-Copyright    2002, turing
+-Author       alex black, enigma@turingstudio.com
+-->
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/2000/REC-xhtml1-20000126/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+  <head>
+    <title>Phing Guide - Extending Phing</title>
+    <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
+    <link rel="Stylesheet" rev="Stylesheet" href="../css/Documentation.css" type="text/css" media="All" charset="iso-8859-1" />
+</head>
+<body>
+
+<h1><a name="ExtendingPhing"></a>Extending Phing</h1>
+
+<p>Phing was designed to be flexible and easily extensible. Phing's existing core
+  and optional tasks do provide a great deal of flexibility in processing files,
+  performing database actions, and even getting user feedback during a build process.
+  In some cases, however, the existing tasks just won't suffice and because of
+  Phing's open, modular architecture adding exactly the functionality you need
+  is often quite trivial.</p>
+<p>In this chapter we'll look primarily at how to create your own tasks, since
+  that is probably the most useful way to extend Phing. We'll also give some more
+  information about Phing's design and inner workings.</p>
+<h2><a name="ExtensionPossibilities"></a>Extension Possibilities</h2>
+
+<p>There are three main areas where Phing can be extended: <a href="#Tasks">tasks</a>,
+  <a href="#Types">types</a>, <a href="#Mappers">mappers</a>. The following sections
+  discuss these options.</p>
+
+<h3><a name="Tasks"></a>Tasks</h3>
+
+<p> Tasks are pieces of codes that perform an atomic action like installing a
+  file. Therefore a special worker class hast to be created and stored in a specific
+  location, that actually implements the job. The worker is just the interface
+  to Phing that must fulfill some requirements discussed later in this chapter,
+  however it can - but not necessarily must - use other classes, workers and libraries
+  that aid performing the operations needed. </p>
+
+<h3><a name="Types"></a>Types</h3>
+
+<p> Extending types is a rare need; nevertheless, you can do it. A possible type
+  you might implement is <em>urlset</em>, for example.</p>
+<p>You may end up needing a new type for a task you write; for example, if you
+  were writing the XSLTTask you might discover that you needed a special type
+  for XSLTParams (even though in that case you could probably use the generic
+  name/value Parameter type). In cases where the type is really only for a single
+  task, you may want to just define the type class in the same file as the Task
+  class, rather than creating an official stand-alone <em>Type</em>.</p>
+
+<h3><a name="Mappers"></a>Mappers</h3>
+
+<p> Creating new mappers is also a rare need, since most everything can be handled
+  by the <a href="appendixes/appendixc-coretypes.html#regexpmapper">RegexpMapper</a>.
+  The Mapper framework does provide a simple way for defining your own mappers
+  to use instead, however, and mappers implement a very simple interface.</p>
+
+<h2><a name="SourceLayout"></a>Source Layout</h2>
+
+<h3><a name="FilesandDirectories"></a>Files And Directories</h3>
+
+<p> Before you are going to start to extend Phing let's have a look at the source
+  layout. You should be comfortable with the organization of files witchin the
+  source tree of Phing before start coding. After you extracted the source distribution
+  or checked it out from CVS you should see the following directory structure:</p>
+
+<pre title="DistributionFileLayout">$PHING_HOME
+  |-- bin
+  |-- classes
+  |    `-- phing
+  |         |-- filters
+  |         |    `-- util
+  |         |-- mappers
+  |         |-- parser
+  |         |-- tasks
+  |         |    |-- ext
+  |         |    |-- system
+  |         |    |    `-- condition
+  |         |    `-- user
+  |         `-- types
+  |-- docs
+  |    `-- phing_guide
+  `-- test
+       |-- classes
+	   `-- etc
+</pre>
+<p>
+The following table briefly describes the contents of the major
+directories:
+</p>
+
+<a name="tables.PhingSourceTreeDirectories"></a>
+<table>
+  <caption>Phing source tree directories</caption>
+  <thead>
+  <tr>
+    <th>Directory</th>
+    <th>Contents</th>
+  </tr>
+  </thead>
+  <tbody>
+  <tr>
+    <td><p>bin</p></td>
+    <td>
+    <p>The basic applications (phing, configure) as well as the wrapper scripts
+          for different platforms (currently Unix and Windows).</p>
+    </td>
+  </tr>
+  <tr>
+    <td><p>classes</p></td>
+    <td><p>Repository of all the classes used by Phing. This is the base directory
+          that should be on the PHP include_path. In this directory you will find
+          the subdirectory phing/ with all the Phing relevant classes.</p></td>
+  </tr>
+  <tr>
+    <td><p>docs</p></td>
+    <td>
+    <p>Documentation files. Generated books, online manuals as well as
+       the PHPDoc generated API documentation.</p>
+    </td>
+  </tr>
+  <tr>
+    <td><p>test</p></td>
+    <td>
+    <p>A set of testcases for different tasks, mappers and types. If
+       you are developing in CVS you should add a testcase for each
+       implementation you check in.</p>
+    </td>
+  </tr>
+  </tbody>
+</table>
+
+<p>Currently there is no distinction between the <em>source</em> layout and the
+  <em>build</em> layout of Phing. The <a href="#figures.MainDirLayout">figure
+  above</a> shows the CVS tree that carries some additional files like the Phing
+  website. Later on there may be a buildfile to create a clean distribution tree
+  of Phing itself. </p>
+
+<h3><a name="FileNamingConventions"></a>File Naming Conventions</h3>
+
+<p> There are some filenaming conventions used by Phing. Here's a quick rundown
+  on the most basic conventions. A more detailed list can be found in [See Naming
+  And Coding Standards]: </p>
+
+<ul>
+  <li>Filenames consist of no more or less than two elements: <em>name</em> and
+    <em>extension</em> .</li>
+  <li>Choose short descriptive filenames (must be less than 31 chars)</li>
+  <li>Names must not contain dots.</li>
+  <li>Files containing PHP code must end with the extension <em>.php</em> .</li>
+  <li>There must be only one class per file (no procedural methods allowed, use
+    a separate file for them), with the exception of &quot;inner&quot;-type /
+    helper classes that can be declared in the same file as the &quot;outer&quot;
+    / main class.</li>
+  <li>The name portion of the file must be named exactly like the class it contains.</li>
+  <li>Buildfiles and configure rulesets must end with the extension <em>.xml</em>
+    .</li>
+</ul>
+
+<h3><a name="CodingStandards"></a>Coding Standards</h3>
+
+<p> We are using PEAR coding standards. We are using a less strict version of
+  these standards, but we do insist that new contributions have phpdoc comments
+  and make explicitly declarations about public/protected/private variables and
+  methods. If you have suggestions about improvements to Phing codebase, don't
+  hesitate to let us know.</p>
+
+<h2><a name="SystemInitialization"></a>System Initialization</h2>
+
+<p> PHP installations are typically quite customized -- e.g. different memory_limit,
+  execution timeout values, etc. The first thing that Phing does is modify PHP
+  INI variables to create a standard PHP environment. This is performed by the
+  <em>init layer</em> of Phing that uses a three-level initialization procedure.
+  It basically consists of three different files: </p>
+
+<ul>
+  <li>Platform specific wrapper scripts in bin/</li>
+  <li>Main application in bin/</li>
+  <li>Phing class in classes/phing/</li>
+</ul>
+
+<p> At the first look this may seem to be unnecessary overhead. Why three levels
+  of initialization? The main reason why there are several entry points is that
+  Phing is build so that other frontends (e.g. PHP-GTK) could be used in place
+  of the command line.</p>
+
+<h3><a name="WrapperScripts"></a>Wrapper Scripts</h3>
+
+<p> This scripts are technical not required but provided for the ease of use.
+  Imagine you have to type every time you want to build your project: </p>
+
+<pre>php -qC /path/to/phing/bin/phing.php -verbose all distro snapshot</pre>
+
+<p>
+Indeed that is not very elegant. Furthermore if you are lax in
+setting your environment variables these script can guess the
+proper variables for you. However you should always set them.
+</p>
+
+<p> The scripts are platform dependent, so you will find shell scripts for <em>Unix</em>
+  like platforms (sh) as well as the batch scripts for <em>Windows</em> platforms.
+  If you set-up your path properly you can call Phing everywhere in your system
+  with this command-line (referring to the above example): </p>
+
+<pre>phing -v2 all distro</pre>
+
+<h3><a name="MainApplication"></a>The Main Application (phing.php)</h3>
+
+<p> This is basically a wrapper for the Phing class that actually does all the
+  logic for you. If you look at the sourcecode for phing.php you will see that
+  all real initialization is handled in the Phing class. phing.php is simply the
+  commandline entry point for Phing.</p>
+
+<h3><a name="InitClass"></a>The Phing Class</h3>
+
+<p> Given that all the prior initialization steps passed successfully the Phing
+  is included and <em>Phing::startup()</em> is invoked by the main application
+  script. It sets-up the system components, system constants ini-settings, PEAR
+  and some other stuff. The detailed start-up process is as follows: </p>
+
+<ul>
+  <li>Start Timer</li>
+  <li>Set System Constants</li>
+  <li>Set Ini-Settings</li>
+  <li>Set Include Paths</li>
+</ul>
+
+<p> After the main application completed all operations (successfully or unsuccessfully)
+  it calls <em>Phing::shutdown(EXIT_CODE)</em> that takes care of a proper destruction
+  of all objects and a gracefully termination of the program by returning an <em>exit
+  code</em> for shell usage (see [See Program Exit Codes] for a list of exit codes).
+</p>
+
+<h2><a name="SystemServices"></a>System Services</h2>
+
+<h3><a name="ExceptionSystem"></a>The Exception system</h3>
+<p>Phing uses the PHP5 try/catch/throw Exception system. Phing defines a number
+  of Exception subclasses for more fine-grained handling of Exceptions. Low level
+  Exceptions that cannot be handled will be wrapped in a BuildException and caught
+  by the outer-most catch() {} block.</p>
+
+<h2><a name="BuildLifecycle"></a>Build Lifecycle</h2>
+<p>This section exists to explain -- or try -- how Phing &quot;works&quot;. Particularly,
+  how Phing procedes through a build file and invokes tasks and types based on
+  the tags that it encounters.</p>
+<h3><a name=""></a>How Phing Parses Buildfiles</h3>
+<p>Phing uses an ExpatParser class and PHP's native expat XML functions to handle
+  the parsing of build files. The handler classes all extend the phing.parser.AbstractHandler
+  class. These handler classes &quot;handle&quot; the tags that are found in the
+  buildfile.</p>
+<p>Core tasks and datatypes are mapped to XML tag names in the defaults.properties
+  files -- specifically phing/tasks/defaults.properties and phing/types/defaults.properties.</p>
+<p>It works roughly like this:</p>
+<ol>
+  <li>phing.parser.RootHandler is registered to handle the buildfile XML document</li>
+  <li>RootHanlder expects to find exactly one element: &lt;project&gt;. RootHandler
+    invokes the ProjectHandler with the attributes from the &lt;project&gt; tag
+    or throws an exception if no &lt;project&gt; is found, or if something else
+    is found instead.</li>
+  <li>ProjectHandler expects to find &lt;target&gt; tags; for these ProjectHandler
+    invokes the TargetHandler. ProjectHandler also has exceptions for handling
+    certain tasks that can be performed at the top-level: &lt;resolve&gt;, &lt;taskdef&gt;,
+    &lt;typedef&gt;, and &lt;property&gt;; for these ProjectHandler invokes the
+    TaskHandler class. If a tag is presented that doesn't match any expected tags,
+    then ProjectHandler assumes it is a datatype and invokes the DataTypeHandler.</li>
+  <li>TargetHandler expects all tags to be either tasks or datatypes and invokes
+    the appropriate handler (based on the mappings provided in the defaults.properties
+    files).</li>
+  <li>Tasks and datatypes can have nested elements, but only if they correspond
+    to a create*() method in the task or datatype class. E.g. a nested &lt;param&gt;
+    tag must correspond to a createParam() method of the task or datatype.</li>
+</ol>
+<p><em>... More to come ...</em></p>
+<h2><a name="WritingTasks"></a>Writing Tasks</h2>
+
+<h3><a name="CreatingATask"></a>Creating A Task</h3>
+
+<p> We will start creating a rather simple task which basically does nothing more
+  than echo a message to the screen. See [below] for the source code and the following
+  [below] for the XML definition that is used for this task. </p>
+
+<a href="codelistings.MyEchoTask"></a>
+<pre title="Source code of a simple task that echos a message to the screen">
+&lt;?php
+
+require_once &quot;phing/Task.php&quot;;
+
+class MyEchoTask extends Task {
+
+    /**
+     * The message passed in the buildfile.
+     */
+    private $message = null;
+
+    /**
+     * The setter for the attribute &quot;message&quot;
+     */
+    public function setMessage($str) {
+        $this->message = $str;
+    }
+
+    /**
+     * The init method: Do init steps.
+     */
+    public function init() {
+      // nothing to do here
+    }
+
+    /**
+     * The main entry point method.
+     */
+    public function main() {
+      print($this->message);
+    }
+}
+
+?&gt;
+</pre>
+
+<p> This code contains a rather simple, but complete Phing task. It is assumed
+  that the file is named <em>MyEchoTask.php</em> and placed in <em>classes/phing/tasks/my</em>
+  directory. We'll explain the source code in detail shortly. But first we'd like
+  to discuss how we should register the task to Phing so that it can be executed
+  during the build process. </p>
+
+<h3><a name="UsingTheTask"></a>Using the Task</h3>
+
+<p> The task shown [above] must somehow get called by Phing. Therefore it must
+  be made available to Phing so that the buildfile parser is aware a correlating
+  XML element and it's parameters. Have a look at the minimalistic buildfile example
+  given in [the buildfile below] that does exactly this. </p>
+
+<a name="codelistings.BuildFileEchoTask"></a>
+<pre title="A simple buildfile that tests the echo task">
+&lt;?xml version=&quot;1.0&quot; ?&gt;
+
+&lt;project name=&quot;test&quot; basedir=&quot;.&quot; default=&quot;myecho&quot;&gt;
+    &lt;taskdef name=&quot;myecho&quot; classname=&quot;phing.tasks.my.MyEcho&quot; /&gt;
+
+    &lt;target name=&quot;test.myecho&quot;&gt;
+      &lt;myecho message=&quot;Hello World&quot; /&gt;
+    &lt;/target&gt;
+&lt;/project&gt;
+</pre>
+
+<p> Besides the XML document prolog and the shell elements that are required to
+  properly execute the task (project, target) you'll find the <em>&lt;taskdef&gt;</em>
+  element (line 4) that properly registers your custom task to Phing. For a detailed
+  synopsis of the taskdef element see the [description of this task]. </p>
+
+<p>
+Now, as we have registered the task by assigning a name and the
+worker class ([see source code above]) it is ready for usage within
+the <em>&lt;target&gt;</em> context (line 8). You see that we pass
+the message that our task should echo to the screen via an XML
+attribute called "message".
+</p>
+
+<h3><a name="SourceDiscussion"></a>Source Discussion</h3>
+
+<p>
+No that you've got the knowledge to execute the task in a
+buildfile it's time to discuss how everything works.
+</p>
+
+<h3><a name="TaskStructure"></a>Task Structure</h3>
+
+<p>
+All files containing the definition of a task class follow a
+common well formed structure:
+</p>
+
+<ul>
+  <li>Package imports to import all required packages</li>
+  <li>The class declaration and definition</li>
+  <li>The class's properties</li>
+  <li>The class's constructor</li>
+  <li>Setter methods for each XML attribute</li>
+  <li>The <em>init()</em> method</li>
+  <li>The <em>main()</em> method</li>
+  <li>Arbitrary <em>private</em> (or <em>protected</em>)<em> </em>class methods</li>
+</ul>
+
+<h3><a name="PackageImports"></a>Package Imports</h3>
+
+<p> Always import all the packages/files needed for this task in full written
+  notation. Furthermore you should always import <em>phing.Task</em> at the very
+  top of your <em>import</em> block. Then import all other required system or
+  proprietary packages. Import works quite similar to PHP's native <em>include_once</em>
+  but with some Java-stylish additions providing a file system independent notation.
+</p>
+
+<p>
+For a more in-depth explanation of the used package mechanism
+and the package support API reference, see [package support]
+For a list of stock packages provided with Phing, see
+[package list].
+</p>
+
+<h3><a name="ClassDeclaration"></a>Class Declaration</h3>
+
+<p>
+If you look at line 5 in [the source code of the task] you will find
+the <em>class declaration</em>. This will be familiar to you if
+you are experienced with OOP in PHP (we assume here that you are).
+Furthermore there are some fine-grained rules you must obey when
+creating the classes (see also,[naming and coding standards]):
+</p>
+
+<ul>
+  <li>Your classname must be exactly like the taskname you are going to implement
+    plus the suffix "Task". In our example case the classname is <em>MyEchoTask</em>
+    (constructed by the taskname "myecho" plus the suffix "task"). The upper/lower
+    case casing is currently only for better reading. However, it is encouraged
+    that you use it this way.</li>
+  <li>The task class you are creating must at least extend "Task" to
+      inherit all task specific methods.</li>
+</ul>
+
+<h3><a name="ClassProperties"></a>Class Properties</h3>
+
+<p>
+The next lines you are coding are class properties. Most of them
+are inherited from the Task superclass, so there's not need to
+redeclare them. Nevertheless you should <em>declare</em> the
+following ones by your own:
+</p>
+
+<ul>
+  <li>Taskname. Always hard code the <em>taskname</em> property that
+      equals the name of the XML element that your task claims. Currently
+      this information is not used - but it will be in the future.</li>
+  <li>Your arbitrary properties that reflect the XML
+      attributes/elements which your task accepts.</li>
+</ul>
+
+<p>
+In the MyEchoTask example the coded properties can be found in
+lines 7 to 11. Give you properties meaningful descriptive names
+that clearly state their function within the context. A couple of
+properties are inherited from the superclass that must not be
+declared in the properties part of the code.
+</p>
+
+<p>
+For a list of inherited properties (most of them are reserved,
+so be sure not to overwrite them with your own) can be found in the
+"Phing API Reference" in the docs/api/ directory.
+</p>
+
+<h3><a name="TheConstructor"></a>The Constructor</h3>
+
+<p> The next block that follows is the class's constructor. It must be present
+  and call at least the constructor or the parent class. Of course, you can add
+  some initialization data here. It is recommended that you <em>define</em> your
+  prior declared properties here.</p>
+
+<h3><a name="SetterMethods"></a>Setter Methods</h3>
+
+<p>
+As you can see in the XML definition of our task ([see buildfile above]
+, line 9) there is an attribute defined with the
+task itself, namely "message" with a value of the the text string
+that our task should echo. The task must somehow become aware of
+the attribute name and the value. Therefore the <em>setter
+methods</em> exist.
+</p>
+
+<p>For each attribute you want to import to the task's namespace
+you have to define a method named exactly after the very attribute
+plus the string "Set" prepended. This method accepts exactly one
+parameter that holds the value of the attribute. No you can set the
+value an class internal property to the value incoming via the
+setter method.</p>
+
+<p>In out example the setter is named <em>SetMessage</em> , because the XML attribute
+  the echo task accepts is "message". SetMessage now takes the string "Hello World"
+  provided by the parser and sets the value of the internal class property <em>$strMessage</em>
+  to "Hello World". It is now available to the task for further disposal.</p>
+
+<h3><a name="CreatorMethods"></a>Creator Methods</h3>
+
+<p> Creator methods allow you to manage nested XML tags in your new Phing Task.</p>
+
+<h3><a name="InitMethod"></a><em>init()</em> Method</h3>
+
+<p> The init method gets called when the &lt;taskname&gt; xml element closes.
+  It must be implemented even if it does nothing like in the example above. You
+  can do init steps here required to setup your task object properly. After calling
+  the Init-Method the task object remains untouched by the parser. Init should
+  not perform operations related somehow to the action the task performs. An example
+  of using init may be cleaning up the $strMessage variable in our example (i.e.
+  trim($strMessage)) or importing additional workers needed for this task. </p>
+
+<p>
+The init method should return true or an error object evaluated
+by the governing logic. If you don't implement init method, phing
+will shout down with a fatal error.
+</p>
+
+<h3><a name="MainMethod"></a><em>main()</em> Method</h3>
+
+<p> There is exactly one entry entry point to execute the task. It is called after
+  the complete buildfile has been parsed and all targets and tasks have been scheduled
+  for execution. From this point forward the very implementation of the tasks
+  action starts. In case of our example a message (imported by the proper setter
+  method) is Logged to the screen through the system's "Logger" service (the very
+  action this task is written for). The <em>Log()</em> method-call in this case
+  accepts two parameters: a event constant and the message to log. </p>
+
+<p>
+For a in-depth list of system constants see <a
+href="../document/appendix/AppB.htm#95990">See System
+Constants</a>. For the detailed reference on the system's logger
+see [REF] and the Phing API docs located in the docs/
+subdirectory.
+</p>
+
+<h3><a name="ArbitraryMethods"></a>Arbitrary Methods</h3>
+
+<p> For the more or less simple cases (as our example) all the logic of the task
+  is coded in the Main() method. However for more complex tasks common sense dictates
+  that particular action should be swapped to smaller, logically contained units
+  of code. The most common way to do this is separating logic into private class
+  methods - and in even more complex tasks in separate libraries. </p>
+
+<pre>private function myPrivateMethod() {
+    // definition
+}
+</pre>
+
+<p>
+More reading on this particular topic can be sound in See Naming
+And Coding Standards.
+</p>
+
+<h3><a name="Summary"></a>Summary</h3>
+
+<p>
+You now have learned how to create and use a task. However we
+guess there are much questions open concerning task development:
+"How do I use filesets and mapper" or "How do I implement custom
+nested tags in my task". Most of these concepts and the proper
+usage will be clear if you continue reading this doc. Additionally
+you might check out the appendices for the advanced examples (See
+Advanced Task Example).
+</p>
+
+<h2><a name="WritingTypes"></a>Writing Types</h2>
+
+<p>You should only create a standalone Type if the Type needs to be shared by
+  more than one Task. If the Type is only needed for a specific Task -- for example
+  to handle a special parameter or other tag needed for that Task -- then the
+  Type class should just be defined within the same file as the Task. (For example,
+  <em>phing/filters/XSLTFilter.php</em> also includes an XSLTParam class that
+  is not used anywhere else.)</p>
+<p>For cases where you do need a more generic Type defined, you can create your
+  own Type class -- similar to the way a Task is created [<a href="#WritingTasks">Writing
+  Tasks </a>].</p>
+<h3>Creating a DataType</h3>
+<p>Type classes need to extend the abstract DataType class. Besides providing
+  a means of categorizing types, the DataType class provides the methods necessary
+  to support the &quot;refid&quot; attribute. (All types can be given an id, and
+  can be referred to later using that id.)</p>
+<p>In this example we are creating a DSN type because we have written a number
+  of DB-related Tasks, each of which need to know how to connect to the database;
+  instead of having database parameters for each task, we've created a DSN type
+  so that we can identify the connection params once and then use it in all our
+  db Tasks.</p>
+<pre title="example Type">require_once &quot;phing/types/DataType.php&quot;;
+
+/**
+ * This Type represents a DB Connection.
+ */
+class DSN extends DataType {
+
+  private $url;
+  private $username;
+  private $password;
+  private $persistent = false;
+
+  /**
+   * Sets the URL part: mysql://localhost/mydatabase
+   */
+  public function setUrl($url) {
+    $this-&gt;url = $url;
+  }
+
+  /**
+   * Sets username to use in connection.
+   */
+  public function setUsername($username) {
+    $this-&gt;username = $username;
+  }
+
+  /**
+   * Sets password to use in connection.
+   */
+  public function setPassword($password) {
+    $this-&gt;password = $password;
+  }
+
+  /**
+   * Set whether to use persistent connection.
+   * @param boolean $persist
+   */
+  public function setPersistent($persist) {
+    $this-&gt;persistent = (boolean) $persist;
+  }
+
+  public function getUrl(Project $p) {
+    if ($this-&gt;isReference()) {
+      return $this-&gt;getRef($p)-&gt;getUrl($p);
+    }
+    return $this-&gt;url;
+  }
+
+  public function getUsername(Project $p) {
+    if ($this-&gt;isReference()) {
+      return $this-&gt;getRef($p)-&gt;getUsername($p);
+    }
+    return $this-&gt;username;
+  }
+
+  public function getPassword(Project $p) {
+    if ($this-&gt;isReference()) {
+      return $this-&gt;getRef($p)-&gt;getPassword($p);
+    }
+    return $this-&gt;password;
+  }
+
+  public function getPersistent(Project $p) {
+    if ($this-&gt;isReference()) {
+      return $this-&gt;getRef($p)-&gt;getPersistent($p);
+    }
+    return $this-&gt;persistent;
+  }
+
+  /**
+   * Gets a combined hash/array for DSN as used by PEAR.
+   * @return array
+   */
+  public function getPEARDSN(Project $p) {
+    if ($this-&gt;isReference()) {
+      return $this-&gt;getRef($p)-&gt;getPEARDSN($p);
+    }
+
+    include_once 'DB.php';
+    $dsninfo = DB::parseDSN($this-&gt;url);
+    $dsninfo['username'] = $this-&gt;username;
+    $dsninfo['password'] = $this-&gt;password;
+    $dsninfo['persistent'] = $this-&gt;persistent;
+
+    return $dsninfo;
+  }
+
+  /**
+   * Your datatype must implement this function, which ensures that there
+   * are no circular references and that the reference is of the correct
+   * type (DSN in this example).
+   *
+   * @return DSN
+   */
+  public function getRef(Project $p) {
+    if ( !$this-&gt;checked ) {
+      $stk = array();
+      array_push($stk, $this);
+      $this-&gt;dieOnCircularReference($stk, $p);
+    }
+    $o = $this-&gt;ref-&gt;getReferencedObject($p);
+    if ( !($o instanceof DSN) ) {
+      throw new BuildException($this-&gt;ref-&gt;getRefId().&quot; doesn't denote a DSN&quot;);
+    } else {
+      return $o;
+    }
+  }
+
+}</pre>
+<h3><a name="UsingType"></a>Using the DataType</h3>
+<p>The <em>TypedefTask</em> provides a way to &quot;declare&quot; your type so
+  that you can use it in your build file. Here is how you would use this type
+  in order to define a single DSN and use it for multiple tasks. (Of course you
+  could specify the DSN connection params each time, but the premise behind needing
+  a DSN datatype was to avoid specifying the connection parameters for each task.)</p>
+<a name="codelistings.DSN"></a>
+<pre title="A simple buildfile that tests the echo task">
+&lt;?xml version=&quot;1.0&quot; ?&gt;
+
+&lt;project name=&quot;test&quot; basedir=&quot;.&quot;&gt;
+
+  &lt;typedef name=&quot;dsn&quot; classname=&quot;myapp.types.DSN&quot; /&gt;
+
+  &lt;dsn
+      id=&quot;maindsn&quot;
+      url=&quot;mysql://localhost/mydatabase&quot;
+      username=&quot;root&quot;
+      password=&quot;&quot;
+      persistent=&quot;false&quot; /&gt;
+
+  &lt;target name=&quot;main&quot;&gt;
+
+    &lt;my-special-db-task&gt;
+	     &lt;dsn refid=&quot;maindsn&quot;/&gt;
+    &lt;/my-special-db-task&gt;
+
+    &lt;my-other-db-task&gt;
+      &lt;dsn refid=&quot;maindsn&quot;/&gt;
+    &lt;/my-other-db-task&gt;
+
+  &lt;/target&gt;
+
+&lt;/project&gt;
+</pre>
+
+<h3><a name="TypeSourceDisc"></a>Source Discussion</h3>
+<h4>Getters &amp; Setters</h4>
+<p>You must provide a setter method for every attribute you want to set from the
+  XML build file. It is good practice to also provide a getter method, but in
+  practice you can decide how your tasks will use your task. In the example above,
+  we've provided a getter method for each attribute and we've also provided an
+  additional method: DSN::getPEARDSN() which returns the DSN hash array used by
+  PEAR::DB, PEAR::MDB, and Creole. Depending on the needs of the Tasks using this
+  DataType, we may only wish to provide the getPEARDSN() method rather than a
+  getter for each attribute.</p>
+<p> Also important to note is that the getter method needs to check to see whether
+  the current DataType is a reference to a previously defined DataType -- the
+  DataType::isReference() exists for this purpose. For this reason, the getter
+  methods need to be called with the current project, because References are stored
+  relative to a project.</p>
+<h4>The getRef() Method</h4>
+<p>The getRef() task needs to be implemented in your Type. This method is responsible
+  for returning a referenced object; it needs to check to make sure the referenced
+  object is of the correct type (i.e. you can't try to refer to a RegularExpresson
+  from a DSN DataType) and that the reference is not circular. </p>
+<p>You can probably just copy this method from an existing Type and make the few
+  changes that customize it to your Type.</p>
+<h2><a name="WritingMappers"></a>Writing Mappers</h2>
+<p>Writing your own filename mapper classes will allow you to control how names
+  are transformed in tasks like CopyTask, MoveTask, XSLTTask, etc. In some cases
+  you may want to extend existing mappers (e.g. creating a GlobMapper that also
+  transforms to uppercase); in other cases, you may simply want to create a very
+  specific name transformation that isn't easily accomplished with other mappers
+  like GlobMapper or RegexpMapper.</p>
+<h3><a name="CreatingMapper"></a>Creating a Mapper</h3>
+<p>Writing filename mappers is simplified by interface support in PHP5. Essentially,
+  your custom filename mapper must implement <em>phing.mappers.FileNameMapper</em>.
+  Here's an example of a filename mapper that creates DOS-style file names. For
+  this example, the &quot;to&quot; and &quot;from&quot; attributes are not needed
+  because all files will be transformed. To see the &quot;to&quot; and &quot;from&quot;
+  attributes in action, look at <em>phing.mappers.GlobMapper</em> or <em>phing.mappers.RegexpMapper</em>.
+</p>
+<pre title="sample mapper">require_once &quot;phing/mappers/FileNameMapper.php&quot;;
+
+/**
+ * A mapper that makes those ugly DOS filenames.
+ */
+class DOSMapper implements FileNameMapper {
+
+  /**
+   * The main() method actually performs the mapping.
+   *
+   * In this case we transform the $sourceFilename into
+   * a DOS-compatible name.  E.g.
+   * ExtendingPhing.html -> EXTENDI~.DOC
+   *
+   * @param string $sourceFilename The name to be coverted.
+   * @return array The matched filenames.
+   */
+  public function main($sourceFilename) {
+
+    $info = pathinfo($sourceFilename);
+    $ext = $info['extension'];
+    // get basename w/o extension
+    $bname = preg_replace('/\.\w+\$/', '', $info['basename']);
+
+    if (strlen($bname) &gt; 8) {
+      $bname = substr($bname,0,7) . '~';
+    }
+
+    if (strlen($ext) > 3) {
+      $ext = substr($bname,0,3);
+    }
+
+    if (!empty($ext)) {
+      $res = $bname . '.' . $ext;
+    } else {
+      $res = $bname;
+    }
+
+    return (array) strtoupper($res);
+  }
+
+  /**
+   * The &quot;from&quot; attribute is not needed here, but method must exist.
+   */
+  public function setFrom($from) {}
+
+	 /**
+   * The &quot;from&quot; attribute is not needed here, but method must exist.
+   */
+  public function setTo($to) {}
+
+}
+</pre>
+<h3><a name="UsingMapper"></a>Using the Mapper</h3>
+<p>Assuming that this mapper is saved to <em>myapp/mappers/DOSMapper.php </em>(relative
+  to a path on PHP's <em>include_path</em> or in <em>PHP_CLASSPATH</em> env variable),
+  then you would refer to it like this in your build file:</p>
+<pre title="using example mapper in build file">&lt;mapper classname=&quot;myapp.mappers.DOSMapper&quot;/&gt;</pre>
+
+</body>
+</html>
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/docs/phing_guide/book/chapters/GettingStarted.html
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/docs/phing_guide/book/chapters/GettingStarted.html	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/docs/phing_guide/book/chapters/GettingStarted.html	(revision 19)
@@ -0,0 +1,349 @@
+<!--
+-File         $Id: GettingStarted.html 195 2007-06-14 15:44:13Z mrook $
+-License      GNU FDL (http://www.gnu.org/copyleft/fdl.html)
+-Copyright    2002, turing
+-Author       alex black, enigma@turingstudio.com
+-->
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/2000/REC-xhtml1-20000126/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+  <head>
+    <title>Phing Guide - Getting Started</title>
+    <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
+    <link rel="Stylesheet" rev="Stylesheet" href="../css/Documentation.css" type="text/css" media="All" charset="iso-8859-1" />
+</head>
+<body>
+
+<h1><a name="GettingStarted"></a>Getting Started</h1>
+
+<p> Phing buildfiles are written in XML, and so you will need to know at least
+  some basic things about XML to understand the following chapter. There is a
+  lot of information available on the web: </p>
+
+<ul>
+  <li>The Standard Recommendation of XML by the w3c
+     <a href="http://www.w3.org/TR/2000/REC-xml">http://www.w3.org/TR/2000/REC-xml</a>:
+     very technical but exhaustive.</li>
+  <li><em>XML In 10 Points</em>
+     <a href="http://www.w3.org/XML/1999/XML-in-10-points">http://www.w3.org/XML/1999/XML-in-10-points</a>:
+     Quick introduction into XML.</li>
+  <li><em>A technical introduction to XML</em>
+      <a href="http://www.xml.com/pub/a/98/10/guide0.html">http://www.xml.com/pub/a/98/10/guide0.html</a>:
+      Interesting article by the creator of DocBook.
+      </li>
+</ul>
+
+<h2><a name="XMLAndPhing"></a>XML And Phing</h2>
+
+<p>A valid Phing buildfile has the following basic structure:</p>
+
+
+<ul>
+  <li>The document prolog</li>
+  <li>Exactly one root element called <em>&lt;project&gt;</em> .</li>
+  <li>Several Phing <em>type</em> elements (i.e. <em>&lt;property&gt;</em> , <em>&lt;fileset&gt;</em>
+    , <em>&lt;patternset&gt;</em> etc.)</li>
+  <li>One or more <em>&lt;target&gt;</em> elements containing built-in or user
+    defined Phing <em>task</em> elements (i.e. <em>&lt;install&gt;</em> , <em>&lt;bcc&gt;</em>
+    , etc).</li>
+</ul>
+
+<h2><a name="WritingASimpleBuildfile"></a>Writing A Simple Buildfile</h2>
+
+<p>The Foobar project installs some PHP files from a source location to a target
+  location, creates an archive of this files and provides an optional clean-up
+  of the build tree:</p>
+
+<pre title="Example of a simple build file">
+&lt;?xml version=&quot;1.0&quot;?&gt;
+
+&lt;project name=&quot;FooBar&quot; default=&quot;dist&quot; basedir=&quot;.&quot;&gt;
+    &lt;target name=&quot;prepare&quot;&gt;
+        &lt;echo msg=&quot;Making directory ./build&quot; /&gt;
+        &lt;mkdir dir=&quot;./build&quot; /&gt;
+    &lt;/target&gt;
+
+    &lt;target name=&quot;build&quot; depends=&quot;prepare&quot;&gt;
+        &lt;echo msg=&quot;Copying files to build directory...&quot; /&gt;
+
+        &lt;echo msg=&quot;Copying ./about.php to ./build directory...&quot; /&gt;
+        &lt;copy file=&quot;./about.php&quot; tofile=&quot;./build/about.php&quot; /&gt;
+
+        &lt;echo msg=&quot;Copying ./browsers.php to ./build directory...&quot; /&gt;
+        &lt;copy file=&quot;./browsers.php&quot; tofile=&quot;./build/browsers.php&quot; /&gt;
+
+        &lt;echo msg=&quot;Copying ./contact.php to ./build directory...&quot; /&gt;
+        &lt;copy file=&quot;./contact.php&quot; tofile=&quot;./build/contact.php&quot; /&gt;
+    &lt;/target&gt;
+
+    &lt;target name=&quot;dist&quot; depends=&quot;build&quot;&gt;
+        &lt;echo msg=&quot;Creating archive...&quot; /&gt;
+
+        &lt;tar destfile=&quot;./build/build.tar.gz&quot; compression=&quot;gzip&quot;&gt;
+            &lt;fileset dir=&quot;./build&quot;&gt;
+                &lt;include name=&quot;*&quot; /&gt;
+            &lt;/fileset&gt;
+        &lt;/tar&gt;
+
+        &lt;echo msg=&quot;Files copied and compressed in build directory OK!&quot; /&gt;
+    &lt;/target&gt;
+&lt;/project&gt;
+</pre>
+
+<h3><a name="ProjectElement"></a>Project Element</h3>
+
+<p>The first element after the document prolog is the root element
+named <em>&lt;project&gt;</em> on line 3. This element is a
+container for all other elements and can/must have the following
+attributes:</p>
+
+<table>
+<caption>&lt;project&gt; Attributes</caption>
+
+<thead>
+  <tr>
+    <th>Attribute</th>
+    <th>Meaning</th>
+    <th>Required</th>
+  </tr>
+</thead>
+
+<tbody>
+  <tr>
+    <td>name</td>
+    <td>The name of the project</td>
+    <td>No</td>
+  </tr>
+  <tr>
+    <td>basedir</td>
+    <td>The base directory of the project. If none is specified, the
+        current directory is used.</td>
+    <td>No</td>
+  </tr>
+  <tr>
+    <td>default</td>
+    <td>The default target that is to be executed if no target(s)
+        are specified when calling this build file.</td>
+    <td>Yes</td>
+  </tr>
+  <tr>
+    <td>description</td>
+    <td>The description of the project.</td>
+    <td>Yes</td>
+  </tr>
+</tbody>
+
+</table>
+
+<h3><a name="TargetElement"></a>Target Element</h3>
+
+<p>A target can <em>depend</em> on other targets. You might have a
+target for installing the files in the build tree, for example, and
+a target for creating a distributable tar.gz archive. You can only
+build a distributable when you have installed the files first, so
+the distribute target depends on the install target. Phing resolves
+these dependencies.</p>
+
+<p>It should be noted, however, that Phing's depends attribute only
+specifies the order in which targets should be executed - it does
+not affect whether the target that specifies the dependency(s) gets
+executed if the dependent target(s) did not (need to) run.</p>
+
+<p>Phing tries to execute the targets in the depends attribute in
+the order they appear (from left to right). Keep in mind that it is
+possible that a target can get executed earlier when an earlier
+target depends on it, in this case the dependant is only executed
+once:</p>
+
+<pre>
+    &lt;target name="D" depends="C,B,A" /&gt;
+</pre>
+
+<p>Suppose we want to execute target <tt>D</tt> . From its depends
+attribute, you might think that first target <tt>C</tt> , then
+<tt>B</tt> and then <tt>A</tt> is executed. Wrong! <tt>C</tt>
+depends on <tt>B</tt> , and <tt>B</tt> depends on <tt>A</tt> , so
+first <tt>A</tt> is executed, then <tt>B</tt> , then <tt>C</tt> ,
+and finally <tt>D</tt> .</p>
+
+<p>A target gets executed only once, even when more than one target
+depends on it (see the previous example).</p>
+
+<p>The optional description attribute can be used to provide a
+one-line description of this target, which is printed by the
+<tt>-projecthelp</tt> command-line option.</p>
+
+<h4><a name="TargetAttributes"></a>Target attributes</h4>
+
+<p>You can specify one or more of the following attributes within the target element.</p>
+
+<table>
+<caption>&lt;target&gt; Attributes</caption>
+<thead>
+  <tr>
+    <th>Attribute</th>
+    <th>Meaning</th>
+    <th>Required</th>
+  </tr>
+</thead>
+<tbody>
+  <tr>
+    <td>name</td>
+    <td>The name of the target</td>
+    <td>Yes</td>
+  </tr>
+  <tr>
+    <td>depends</td>
+    <td>A comma-seperated list of targets this target depends on.</td>
+    <td>No</td>
+  </tr>
+  <tr>
+    <td>if</td>
+    <td>The name of the <em>Property</em> that hast to be set in order for
+        this target to be executed</td>
+    <td>No</td>
+  </tr>
+  <tr>
+    <td>unless</td>
+    <td>The name of the <em>Property</em> that must <em>not</em> be set in
+        order for this target to be executed.</td>
+    <td></td>
+  </tr>
+</tbody>
+</table>
+
+<h3><a name="TaskElements"></a>Task Elements</h3>
+
+<p>A <em>task</em> is a piece of PHP code that can be executed.
+This code implements a particular action to perform (i.e. install a
+file). Therefore it must be defined in the buildfile so that it is
+actually invoked by Phing.</p>
+
+<p>These references will be resolved before the task is executed.</p>
+
+<p>Tasks have a common structure:</p>
+
+<pre>
+    &lt;name attribute1="value1" attribute2="value2" ... /&gt;
+</pre>
+
+<p>where <em>name</em> is the name of the task, <em>attributeN</em>
+is the attribute name, and <em>valueN</em> is the value for this
+attribute.</p>
+
+<p>There is a set of core tasks (see <a href="appendixes/AppendixB-CoreTasks.html">Appendix
+  B</a>) along with a number of optional tasks. It is also very easy to write
+  your own tasks (see <a href="ExtendingPhing.html">Extending Phing</a>).</p>
+
+<p>Tasks can be assigned an <em>id</em> attribute:</p>
+
+<pre>
+    &lt;taskname id="taskID" ... /&gt;
+</pre>
+
+<p>By doing this you can refer to specific tasks later on in the
+code of other tasks.</p>
+
+
+<h3><a name="PropertyElement"></a>Property Element</h3>
+
+<p><em>Properties</em> are essentially variables that can be used in the buildfile.
+  These might be set in the buildfile by calling the <a href="appendixes/AppendixB-CoreTasks.html#PropertyTask">PropertyTask</a>,
+  or might be set outside Phing on the command line (properties set on the command
+  always line override the ones in the buildfile). A property has a name and a
+  value only. Properties may be used in the value of task attributes. This is
+  done by placing the property name between &quot; <tt>${</tt> &quot; and &quot;
+  <tt>}</tt> &quot; in the attribute value. For example, if there is a BC_BUILD_DIR
+  property with the value 'build', then this could be used in an attribute like
+  this: <em>${BC_BUILD_DIR}/en</em> . This is resolved to <em>build/en</em>.</p>
+
+<p>It should be noted that if you use a property that is not defined via the property
+  task, the system environment table is searched for this name. For example, if
+  you would use the property <tt>${BCHOME}</tt> and you did not define this prior
+  in the buildfile or at the command line, Phing uses the environment variable
+  <tt>BCHOME</tt> if it exists.</p>
+
+<h4><a name="BuiltInProperties"></a>Built-in Properties</h4>
+
+<p>Phing provides access to system properties as if they had been
+defined using a <em>&lt;property&gt;</em> task. For example,
+<em>${os.name}</em> expands to the name of the operating
+system. See
+<a href="appendixes/AppendixA-FactSheet.html#BuildInProperties">Appendix A</a>
+for a complete list</p>
+
+
+<h2><a name="ComplexBuildfile"></a>More Complex Buildfile</h2>
+
+<pre title="More complex build file">&lt;?xml version=&quot;1.0&quot; ?&gt;
+
+&lt;project name=&quot;testsite&quot; basedir=&quot;.&quot; default=&quot;main&quot;&gt;
+    &lt;property file=&quot;./build.properties&quot; /&gt;
+
+    &lt;property name=&quot;package&quot;  value=&quot;${phing.project.name}&quot; override=&quot;true&quot; /&gt;
+    &lt;property name=&quot;builddir&quot; value=&quot;./build/testsite&quot; override=&quot;true&quot; /&gt;
+    &lt;property name=&quot;srcdir&quot;   value=&quot;${project.basedir}&quot; override=&quot;true&quot; /&gt;
+
+    &lt;!-- Fileset for all files --&gt;
+    &lt;fileset dir=&quot;.&quot; id=&quot;allfiles&quot;&gt;
+        &lt;include name=&quot;**&quot; /&gt;
+    &lt;/fileset&gt;
+
+    &lt;!-- Main Target --&gt;
+    &lt;target name=&quot;main&quot; description=&quot;main target&quot;&gt;
+        &lt;copy todir=&quot;${builddir}&quot;&gt;
+            &lt;fileset refid=&quot;allfiles&quot; /&gt;
+        &lt;/copy&gt;
+    &lt;/target&gt;
+
+    &lt;!-- Rebuild --&gt;
+    &lt;target name=&quot;rebuild&quot; description=&quot;rebuilds this package&quot;&gt;
+        &lt;delete dir=&quot;${builddir}&quot; /&gt;
+        &lt;phingcall target=&quot;main&quot; /&gt;
+    &lt;/target&gt;
+&lt;/project&gt;
+</pre>
+
+<p>
+This build file first defines some properties with the <em>&lt;property&gt;</em>
+task call to <em>PropertyTask</em>. Then, it defines a fileset and two targets.
+Let us have a quick rundown of this build file.
+</p>
+
+<p> The first five four within the <em>project</em> tag define properties. They
+  appear in the two ways this tag can occur: </p>
+<ul>
+  <li>The second <em>property</em> tag contains only the <em>file</em> attribute.
+    The value has to be a relative or absolute path to a property file (for the
+    format, see <a href="appendixes/AppendixE-FileFormats.html">Appendix E</a>).
+  </li>
+  <li>The other times, the tag has a <em>name</em> and a <em>value</em> attribute.
+    After the call, the value defined in the attribute <em>value</em> is available
+    through the key enclosed in &quot;${&quot; and &quot;}&quot;. </li>
+</ul>
+<p>
+The next noticeable thing in the build file is the <em>&lt;fileset&gt;</em> tag.
+It defines a fileset, i.e. a set of multiple files. You can include and exclude
+Files with <em>include</em> and <em>exclude</em> tags within the <em>fileset</em>
+tag. For more information concerning Filesets (i.e. Patterns) see
+<a href="appendixes/AppendixC-CoreTypes.html#Fileset">Appendix C</a>.
+The fileset is given an <em>id</em> attribute, so it can be referenced later on.
+</p>
+
+<p>
+The first task only contains a call to <em>CopyTask</em> via
+<em>&lt;copy&gt;</em>. The interesting thing is within the
+<em>copy</em> tag. Here, a fileset task is not written out with
+nested <em>include</em> or <em>exclude</em> elements, but
+via the <em>refid</em>, the earlier create Fileset is referenced.
+This way, you can use a once defined fileset multiple times in
+your build files.
+</p>
+
+<p> The only noticeable thing in the second target is the call to <em>PhingTask</em>
+  with the <em>&lt;phingcall&gt;</em> tag (see <a href="appendixes/AppendixB-CoreTasks.html#PhingCallTask">Appendix
+  B</a> for more information. The task executes a specified target within the
+  same build file. So, the second target removes the build directory and calls
+  <em>main</em> anew so the project is rebuilt. </p>
+
+</body>
+</html>
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/docs/phing_guide/book/chapters/Introduction.html
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/docs/phing_guide/book/chapters/Introduction.html	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/docs/phing_guide/book/chapters/Introduction.html	(revision 19)
@@ -0,0 +1,94 @@
+<!--
+-File         $Id: Introduction.html 182 2007-04-17 14:37:01Z mrook $
+-License      GNU FDL (http://www.gnu.org/copyleft/fdl.html)
+-Copyright    2002, turing
+-Author       alex black, enigma@turingstudio.com
+-->
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/2000/REC-xhtml1-20000126/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+  <title>Phing Guide - Introduction</title>
+  <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"/>
+  <link rel="Stylesheet" rev="Stylesheet" href="../css/Documentation.css" type="text/css" charset="iso-8859-1"/>
+</head>
+<body>
+
+<h1>Introduction</h1>
+
+<h2><a name="WhatPhingIs"></a>What Phing Is</h2>
+
+<p> Phing is a project build system based on Apache ant <a href="Bibliography.html#ant">[ant]</a>.
+  You can do anything with Phing that you could do with a traditional build system
+  like Gnu make <a href="Bibliography.html#gnumake">[gnumake]</a>, and Phing's
+  use of simple XML build files and extensible PHP &quot;task&quot; classes make
+  it an easy-to-use and highly flexible build framework.</p>
+<p>Because Phing is based on Ant, parts of this manual are also adapted from the
+  ant manual (see <a href="Bibliography.html#ant">[ant]</a>). We are extremely
+  grateful to the folks in the Ant project for creating (and continuing to create)
+  such an inspiring build system model, and for the open-source licensing that
+  makes it possible for us to learn from each other and build increasingly better
+  tools. </p>
+<h2><a name="PhingAndBinarycloud"></a>Phing &amp; Binarycloud:
+  History</h2>
+
+<p> Phing was originally a subproject of Binarycloud. Binarycloud is a highly
+  engineered application framework, designed for use in enterprise environments.
+  Binarycloud uses XML extensively for storing metadata about a project (configuration,
+  nodes, widgets, site structure, etc.). Because Binarycloud is built for PHP,
+  performing extensive XML processing and transformations on each page request
+  is an unrealistic proposition. Phing is used to &quot;compile&quot; the XML
+  metadata into PHP arrays that can be processed without overhead by PHP scripts.
+</p>
+<p>Of course, XML &quot;compilation&quot; is only one of many ways that Binarycloud
+  uses the Phing build system. The Phing build system makes it possible for you
+  to: </p>
+<ul>
+  <li>Build multi language pages from one source tree (see binarycloud documentation
+    and [below in this document]), </li>
+  <li>Centralize metadata (e.g. your data model) in one XML file and generate
+    several files from that XML with different XSLT.</li>
+</ul>
+
+<p> It the beginning, Binarycloud used the GNU make system; however, this approach
+  had some drawbacks: The &quot;space-before-tab&quot;-problem in makefiles, the
+  fact that it is only natively available for Unix systems etc. So, the need for
+  a better build system arose. Apache Ant was a logical choice -- do to its use
+  of XML build files and modular design. The problem was that Ant is written in
+  Java, so you need to install a JVM on your computer to use it. Besides the need
+  for yet another interpreter (i.e. besides PHP), there was also legal/ideological
+  conflict in requiring a commercial JVM (there were problems with Ant on JVMs
+  other than Sun's) for an LGPL'd Binarycloud.</p>
+
+<p>So, the development of Phing began. Phing is a build system written in PHP
+  and uses the ideas of Ant. The first release was designed &amp; developed simultaneously,
+  and thus not very sophisticated. This original system was quickly pushed to
+  its limits and the need for a better Phing became a priority. Andreas Anderhold,
+  who was responsible for Phing/r1, designed and wrote much of the Phing/r2 that
+  followed. Phing/r2 became the Phing-1.0 that exists today for PHP4.</p>
+
+<p>The current development of Phing is focused on Phing 2, which has involved
+  a number of bugfixes, functionality enhancements, and most significantly a conversion
+  of the codebase to use new PHP5 features such as abstract classes, interfaces,
+  and try/catch/throw exception handling.</p>
+
+<h2><a name="HowPhingWorks"></a>How Phing Works</h2>
+<p>Phing uses XML <em>buildfiles</em> that contain a description of the things to do. The buildfile
+is structured into targets that contain the actual commands to perform (e.g. commands to copy a file,
+delete a directory, perform a DB query, etc.).  So, to use Phing, you would first write your buildfile
+and then you would run phing, specifying the target in your buildfile that you want to execute.</p>
+<pre title="simple phing example">% phing -f mybuildfile.xml mytarget</pre>
+<p>By default Phing will look for a buildfile named <em>build.xml</em> (so you don't have to specify the
+buildfile name unless it is not <em>build.xml</em>) and if no target is specified Phing
+will try to execute the default target, as specified in the &lt;project&gt; tag.</p>
+
+<h2><a name="HowCanIHelp"></a>Cool, so how can I help?</h2>
+
+<p>Phing is under active development and there are many things to be done. To
+  get involved, you can start by doing the following:</p>
+<ul>
+  <li>Read this manual to understand Phing ;-)</li>
+  <li>Go to http://phing.tigris.org and subscribe to the &quot;dev&quot; mailing list</li>
+</ul>
+
+</body>
+</html>
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/docs/phing_guide/book/chapters/ProjectComponents.html
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/docs/phing_guide/book/chapters/ProjectComponents.html	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/docs/phing_guide/book/chapters/ProjectComponents.html	(revision 19)
@@ -0,0 +1,539 @@
+<!--
+-File         $Id: ProjectComponents.html 271 2007-10-28 16:42:36Z hans $
+-License      GNU FDL (http://www.gnu.org/copyleft/fdl.html)
+-Copyright    2002, turing
+-Author       alex black, enigma@turingstudio.com
+-->
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/2000/REC-xhtml1-20000126/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+  <head>
+    <title>Phing Guide - Project Components</title>
+    <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
+    <link rel="Stylesheet" rev="Stylesheet" href="../css/Documentation.css" type="text/css" media="All" charset="iso-8859-1" />
+  </head>
+  <body>
+
+<h1>Project Components</h1>
+
+<p> This goal of this chapter is to make you familiar with the basic components
+  of a buildfile. After reading this chapter, you should be able to read and understand
+  the basic structure of any buildfile even if you don't know exactly what the
+  individual pieces do. </p>
+<p>For supplemental reference information, you should see <a href="appendixes/AppendixB-CoreTasks.html">Appendix
+  B</a>, <a href="appendixes/AppendixC-CoreTypes.html">Appendix C</a> and <a href="appendixes/AppendixE-ProjectComponents.html">Appendix
+  D</a>. </p>
+
+<h2><a name="Projects"></a>Projects</h2>
+
+<p> In the structure of a Phing buildfile, there must be exactly one <em>Project</em>
+  defined; the <em>&lt;project&gt; </em>tag is the root element of the buildfile,
+  meaning that everything else in the buildfile is contained within the <em>&lt;project</em>
+  &gt; element.</p>
+
+<pre title="An Example for the use of Projects">
+&lt;?xml version=&quot;1.0&quot;?&gt;
+
+&lt;project name=&quot;test&quot; description=&quot;Simple test build file&quot; default=&quot;main&quot; &gt;
+  &lt;!-- Everything else here --&gt;
+&lt;project&gt;
+</pre>
+
+<p> The listing above shows a sample <em>&lt;project&gt;</em> tag that has all
+  attributes available for Projects. The <em>name</em> and <em>description</em>
+  attributes are fairly self-explanatory; the <em>default</em> attribute specifies
+  the default <em>Target</em> to execute if no target is specified (<a href="#Target">Targets</a>
+  are described below). For a complete reference, see <a href="appendixes/AppendixE-ProjectComponents.html#Project">Appendix
+  D</a>. </p>
+
+<h2><a name="ComponentsInGeneral"></a>Project Components in General</h2>
+
+<p> Project components are everything you can be find inside a project. So Targets
+  are project components, as are Tasks, Types, etc. Project components may have
+  attributes and nested tags. Attributes only contain simple values, i.e. strings,
+  integers etc. Nested elements may be complex Phing types (like FileSets) or
+  simple wrapper classes for values with custom keys (see <a href="appendixes/AppendixC-CoreTypes.html#Fileset">FileSet</a>
+  for example). </p>
+
+<p> Any nested elements must be supported by the class that implements the project
+  component, and because the nested tags are handled by the project component
+  class the same nested tag may have different meanings (and different attributes)
+  depending on the context. So, for example, the nested tag <em>&lt;param</em>.../&gt;
+  within the <em>&lt;phingcall&gt;</em> tag is handled very differently from the<em>&lt;param.../&gt;</em>
+  tag within the <em>&lt;xsltfilter&gt;</em> tag -- in the first case setting
+  project properties, in the second case setting XSLT parameters. </p>
+
+<h2><a name="Targets"></a>Targets</h2>
+
+<p> Targets are collections of project components (but not other targets) that
+  are assigned a unique name within their project. A target generally performs
+  a specific task -- or calls other targets that perform specific tasks -- and
+  therefore a target is a bit like a <em> function</em> (but a target has no return
+  value).</p>
+<p>Targets may <em>depend</em> on other targets. For example, if target A depends
+  on a target B, then when target A is called to be executed, target B will be
+  executed first. Phing automatically resolves these dependencies. You cannot
+  have circular references like: &quot;target A depends on target B that depends
+  on target A&quot;. </p>
+
+<p>
+The following code snippet shows an example of the use of targets.
+</p>
+
+<pre title="Simple target">
+&lt;target name=&quot;othertask&quot; depends=&quot;buildpage&quot; description=&quot;Whatever&quot;&gt;
+  &lt;!-- Task calls here --&gt;
+&lt;target&gt;
+
+&lt;target name=&quot;buildpage&quot; description=&quot;Some description&quot;&gt;
+  &lt;!-- Task calls here --&gt;
+&lt;target&gt;
+</pre>
+
+<p> When Phing is asked to execute the <em>othertask</em> target, it will see
+  the dependency and execute <em>buildpage </em>first. Notice that the the dependency
+  task can be defined after the dependent task.</p>
+
+<h2><a name="Tasks"></a>Tasks</h2>
+
+<p> Tasks are responsible for doing the work in Phing. Basically, tasks are the
+  individual actions that your buildfile can perform. For example, tasks exist
+  to copy a file, create a directory, TAR files in a directory. Tasks may also
+  be more complex such as XsltTask which copies a file and transforms the file
+  using XSLT, SmartyTask which does something similar using Smarty templates,
+  or CreoleTask which executes SQL statements against a specified DB. See <a href="appendixes/AppendixB-CoreTasks.html#XsltTask">Appendix
+  B</a> for descriptions of Phing tasks.</p>
+
+<p> Tasks support parameters in the form of:</p>
+
+<ul>
+  <li>Simple parameters (i.e. strings) passed as XML attributes, or</li>
+  <li>More complex parameters that are passed by nested tags</li>
+</ul>
+
+<p>
+Simple parameters are basically strings. For example, if you pass
+a value <em>&quot;A simple string.&quot;</em> as a parameter, it
+is evaluated as a string and accessible as one. You can also reference
+properties as described in
+<a href="GettingStarted.html#PropertyElement">Getting Started</a>.
+</p>
+
+<p> <em>Note:</em> There are special values that are not mapped to strings, but
+  to boolean values instead. The values <em>true</em>, <em>false</em>, <em>yes</em>,
+  <em>no</em>, <em>on</em> and <em>off</em> are translated to true/false boolean
+  values. </p>
+
+<pre title="Simple parameter example">&lt;property name=&quot;myprop&quot; value=&quot;value&quot; override=&quot;true&quot;/&gt;</pre>
+<p>
+However, some tasks support more complex data types as parameters.
+These are passed to the task with <em>nested tags</em>. Consider the
+following example:
+</p>
+
+<pre title="Example for a task with complex parameters">
+&lt;copy&gt;
+  &lt;fileset dir=&quot;.&quot;&gt;
+    &lt;include name=&quot;**&quot; /&gt;
+  &lt;/fileset&gt;
+&lt;/copy&gt;
+</pre>
+
+<p> Here, <em>CopyTask</em> is passed a complex parameter, a Fileset. Tasks may
+  support multiple complex types in addition to simple parameters. Note that the
+  names of the nested tags used to create the complex types depend on the task
+  implementation. Tasks may support default Phing types (see <a href="#Types">below</a>)
+  or may introduce other types, for example to wrap key/value pairs. </p>
+
+<p> Refer to <a href="appendixes/AppendixB-CoreTasks.html">Appendix B</a> for
+  a list of system tasks and their parameters.</p>
+
+<h2><a name="Types"></a>Types</h2>
+
+<h3><a name="TypesBasics"></a>Basics</h3>
+
+<p> Besides the simple types (strings, integer, booleans) you can use in the parameters
+  of tasks, there are more complex Phing <em>Types</em>. As mentioned above, they
+  are passed to a task by using nesting tags: </p>
+
+<pre>
+&lt;task&gt;
+  &lt;type /&gt;
+&lt;/task&gt;
+
+&lt;!-- or: --&gt;
+
+&lt;task&gt;
+  &lt;type1&gt;
+    &lt;subtype1&gt;
+      &lt;!-- etc. --&gt;
+    &lt;/subtype1&gt;
+  &lt;/type1&gt;
+&lt;/task&gt;
+</pre>
+
+<p> Note that types may consist of multiple nested tags -- and multiple levels
+  of nested tags, as you can see in the second task call above.</p>
+
+<h3><a name="TypesReferencing"></a>Referencing Types</h3>
+
+<p> An additional fact about types you should notice is the possibility of <em>referencing</em>
+  type instances, i.e. you define your type somewhere in your build file and assign
+  an id to it. Later, you can refer to that type by the id you assigned. Example:
+</p>
+
+<pre>
+&lt;project&gt;
+  &lt;fileset id=&quot;foo&quot;&gt;
+    &lt;include name=&quot;*.php&quot; /&gt;
+  &lt;/fileset&gt;
+
+  &lt;!-- Target that uses the type --&gt;
+  &lt;target name=&quot;foo&quot; &gt;
+    &lt;copy todir=&quot;/tmp&quot;&gt;
+      &lt;fileset refid=&quot;foo&quot; />
+    &lt;/copy&gt;
+  &lt;/target&gt;
+&lt;/project&gt;
+</pre>
+
+<p>
+As you can see, the type instance is assigned an id with the
+<em>id</em> attribute and later on called by passing a plain
+<em>fileset</em> tag to <em>CopyTask</em> that only contains
+the <em>refid</em> attribute.
+</p>
+
+<h2><a name="BasicTypes"></a>Basic Types</h2>
+
+<p>
+The following section gives you a quick introduction into the
+basic Phing types. For a complete reference see
+<a href="appendix/AppendixC-CoreTypes.html">Appendix C</a>.
+</p>
+
+<h3><a name="FileSet"></a>FileSet</h3>
+
+<p> FileSets are groups of files. You can include or exclude specific files and
+  patterns to/from a FileSet. The use of patterns is explained below. For a start,
+  look at the following example: </p>
+
+<pre>
+&lt;fileset dir=&quot;/tmp&quot; id=&quot;fileset1&quot;&gt;
+  &lt;include name=&quot;sometemp/file.txt&quot; /&gt;
+  &lt;include name=&quot;othertemp/**&quot; /&gt;
+  &lt;exclude name=&quot;othertemp/file.txt&quot; /&gt;
+&lt;/fileset&gt;
+
+&lt;fileset dir=&quot;/home&quot; id=&quot;fileset2&quot;&gt;
+  &lt;include name=&quot;foo/**&quot; /&gt;
+  &lt;include name=&quot;bar/**/*.php&quot; /&gt;
+  &lt;exclude name=&quot;foo/tmp/**&quot; /&gt;
+&lt;/fileset&gt;
+</pre>
+
+<p> The use of patterns is quite straightforward: If you simply want to match
+  a part of a filename or dirname, you use <strong>*</strong>. If you want to
+  include multiple directories and/or files, you use <strong>**</strong>. This
+  way, filesets provide an easy but powerful way to include files. </p>
+
+<h3><a name="FileList"></a>FileList</h3>
+<p>FileLists, like FileSets, are collections of files; however, a FileList is
+  an explicitly defined list of files -- and the files don't necessarily have
+  to exist on the filesystem. </p>
+<p>Besides being able to refer to nonexistent files, another thing that FileLists
+  allow you to do is specify files <em>in a certain order</em>. Files in FileSets
+  are ordered based on the OS-level directory listing functions, in some cases
+  you may want to specify a list of files to be processed in a certain order --
+  e.g. when concatenating files using the <em>&lt;append&gt;</em> task.</p>
+<pre title="FileList example">&lt;filelist dir=&quot;base/&quot; files=&quot;file1.txt,file2.txt,file3.txt&quot;/&gt;
+
+&lt;!-- OR: --&gt;
+&lt;filelist dir=&quot;basedir/&quot; listfile=&quot;files_to_process.txt&quot;/&gt;</pre>
+
+<h4><a name="FilterchainsFilters"></a>FilterChains and Filters</h4>
+
+<p> FilterChains can be compared to Unix pipes. Unix pipes add a great deal of
+  flexibility to command line operations; for example, if you wanted to copy just
+  those lines that contained the string <em>blee</em> from the first 10 lines
+  of a file called <em>foo</em> to a file called <em>bar</em>, you could do: </p>
+
+<pre>
+cat foo | head -n10 | grep blee &gt; bar
+</pre>
+
+<p> Something like this is not possible with the tasks and types that we have
+  learned about thus far, and this is where the incredible usefulness of <em>FilterChains</em>
+  becomes apparent. They emulate Unix pipes and provide a powerful dimension of
+  file/stream manipulation for the tasks that support them.</p>
+
+<p> FilterChain usage is quite straightforward: you pass the complex Phing type
+  <em>filterchain</em> to a task that supports FilterChains and add individual
+  filters to the FilterChain. In the course of executing the task, the filters
+  are applied (in the order in which they appear in the XML) to the contents of
+  the files that are being manipulated by your task.</p>
+
+<pre>
+&lt;filterchain&gt;
+  &lt;replacetokens&gt;
+    &lt;token key=&quot;BC_PATH&quot; value=&quot;${top.builddir}/&quot;/&gt;
+    &lt;token key=&quot;BC_PATH_USER&quot; value=&quot;${top.builddir}/testsite/user/${lang}/&quot;/&gt;
+  &lt;/replacetokens&gt;
+
+  &lt;filterreader classname=&quot;phing.filters.TailFilter&quot;&gt;
+    &lt;param name=&quot;lines&quot; value=&quot;10&quot;/&gt;
+  &lt;/filterreader&gt;
+&lt;/filterchain&gt;
+</pre>
+<p> The code listing above shows you some example of how to use filter chains.
+  For a complete reference see <a href="appendixes/AppendixC-CoreTypes.html#Filters">Appendix
+  C</a>. This filter chain would replace all occurences of <em>BC_PATH</em> and
+  <em>BC_PATH_USER</em> with the values assigned to them in lines 4 and 5. Additionally,
+  it will only return the last 10 lines of the files. </p>
+<p>Notice above that FilterChain filters have a &quot;shorthand&quot; notation
+  and a long, generic notation. Most filters can be described using both of these
+  forms:</p>
+<pre title="Filter shorthand / longhand comparison">&lt;replacetokens&gt;
+  &lt;token key=&quot;BC_PATH&quot; value=&quot;${top.builddir}/&quot;/&gt;
+  &lt;token key=&quot;BC_PATH_USER&quot; value=&quot;${top.builddir}/testsite/user/${lang}/&quot;/&gt;
+&lt;/replacetokens&gt;
+
+&lt;!-- OR: --&gt;
+
+&lt;filterreader classname=&quot;phing.filters.ReplaceTokens&quot;&gt;
+  &lt;param type=&quot;token&quot; name=&quot;BC_PATH&quot; value=&quot;${top.builddir}/&quot;/&gt;
+  &lt;param type=&quot;token&quot; name=&quot;BC_PATH&quot; value=&quot;${top.builddir}/testsite/user/${lang}/&quot;/&gt;
+&lt;/filterreader&gt;
+</pre>
+<p> As the pipe concept in Unix, the filter concept is quite complex but powerful.
+  To get a better understanding of different filters and how they can be used,
+  take a look at any of the many uses of FilterChains in the build files for the
+  binarycloud <a href="Bibliography.html#bc">[bc]</a> project.</p>
+
+<h4><a name="Mappers"></a>File Mappers</h4>
+
+<p> With FilterChains and filters provide a powerful tool for changing <em>contents</em>
+  of files, Mappers provide a powerful tool for changing the <em>names</em> of
+  files.</p>
+
+<p> To use a Mapper, you must specify a pattern to match on and a replacement
+  pattern that describes how the matched pattern should be transformed. The simplest
+  form is basically no different from the DOS <em>copy</em> command: </p>
+
+<pre>
+copy *.bat *.txt
+</pre>
+
+<p> In Phing this is the <em>glob</em> Mapper:</p>
+<pre title="">&lt;mapper type=&quot;glob&quot; from=&quot;*.bat&quot; to=&quot;*.txt&quot;/&gt;</pre>
+<p>Phing also provides support for more complex mapping using regular expressions:</p>
+
+<pre>
+&lt;mapper type=&quot;regexp&quot; from=&quot;^(.*)\.conf\.xml$$&quot; to=&quot;\1.php&quot;/&gt;
+</pre>
+
+<p>Consider the example below to see how Mappers can be used in a build file.
+  This example includes some of the other concepts introduced in this chapter,
+  such as FilterChains and FileSets. If you don't understand everything, don't
+  worry. The important point is that Mappers are types too, which can be used
+  in tasks that support them.</p>
+<pre>&lt;copy&gt;
+  &lt;fileset dir="."&gt;
+    &lt;include name="*.ent.xml" /&gt;
+  &lt;/fileset&gt;
+
+  &lt;mapper type="regexp" from="^(.*)\.ent\.xml$" to="\1.php"/&gt;
+
+  &lt;filterchain&gt;
+    &lt;filterreader classname="phing.filters.XsltFilter"&gt;
+      &lt;param name="style" value="ent2php.xsl" /&gt;
+    &lt;/filterreader&gt;
+  &lt;/filterchain&gt;
+&lt;/copy&gt;
+</pre>
+
+<p>For a complete reference, see <a href="appendixes/AppendixC-CoreTypes.html#Mappers">Appendix
+  C</a>.</p>
+
+<h2><a name="Conditions">Conditions</a></h2>
+
+<p>Conditions are nested elements of the
+<a href="appendixes/AppendixB-CoreTasks.html#ConditionTask">condition</a> and
+<a href="appendixes/AppendixB-CoreTasks.html#IfTask">if</a> tasks.
+</p>
+
+<h4>not</h4>
+<p>The <code>&lt;not&gt;</code> element expects exactly one other
+condition to be nested into this element, negating the result of the
+condition. It doesn't have any attributes and accepts all nested
+elements of the condition task as nested elements as well.</p>
+
+<h4>and</h4> <p>
+The <code>&lt;and&gt;</code> element doesn't have any attributes and
+accepts an arbitrary number of conditions as nested elements. This condition
+is true if all of its contained conditions are, conditions will be
+evaluated in the order they have been specified in the build file.</p>
+
+<p>The <code>&lt;and&gt;</code> condition has the same shortcut
+semantics as the &amp;&amp; operator in some programming languages, as soon as one of the
+nested conditions is false, no other condition will be evaluated.</p>
+
+<h4>or</h4> <p>
+The <code>&lt;or&gt;</code> element doesn't have any attributes and
+accepts an arbitrary number of conditions as nested elements. This condition
+is true if at least one of its contained conditions is, conditions
+will be evaluated in the order they have been specified in the build
+file.</p>
+
+<p>The <code>&lt;or&gt;</code> condition has the same
+shortcut semantics as the || operator in some programming languages, as soon as one of the
+nested conditions is true, no other condition will be evaluated.</p>
+
+<h4>available</h4>
+<p>This condition is identical to the <a
+href="appendixes/AppendixB-CoreTasks.html#AvailableTask">Available</a> task, all attributes and nested
+elements of that task are supported, the property and value attributes
+are redundant and will be ignored.</p>
+
+<h4>uptodate</h4>
+<p>This condition is identical to the <a
+href="appendixes/AppendixB-CoreTasks.html#UpToDateTask">UpToDate</a> task, all attributes and nested
+elements of that task are supported, the property and value attributes
+are redundant and will be ignored.</p>
+
+<h4>os</h4>
+<p>Test whether the current operating system is of a given type.</p>
+
+<table border="1" cellpadding="2" cellspacing="0">
+  <tr>
+    <td valign="top"><b>Attribute</b></td>
+    <td valign="top"><b>Description</b></td>
+    <td align="center" valign="top"><b>Required</b></td>
+  </tr>
+  <tr>
+    <td valign="top">family</td>
+    <td valign="top">The name of the operating system family to expect.</td>
+    <td valign="top" align="center">Yes</td>
+  </tr>
+</table>
+<p>Supported values for the family attribute are:
+<ul>
+  <li>windows (for all versions of Microsoft Windows)</li>
+  <li>mac (for all Apple Macintosh systems)</li>
+  <li>unix (for all Unix and Unix-like operating systems)</li>
+</ul>
+
+<h4>equals</h4>
+<p>Tests whether the two given Strings are identical</p>
+<table border="1" cellpadding="2" cellspacing="0">
+  <tr>
+    <td valign="top"><b>Attribute</b></td>
+    <td valign="top"><b>Description</b></td>
+    <td align="center" valign="top"><b>Required</b></td>
+  </tr>
+  <tr>
+    <td valign="top">arg1</td>
+    <td valign="top">First string to test.</td>
+    <td valign="top" align="center">Yes</td>
+  </tr>
+  <tr>
+    <td valign="top">arg2</td>
+    <td valign="top">Second string to test.</td>
+    <td valign="top" align="center">Yes</td>
+  </tr>
+  <tr>
+    <td valign="top">casesensitive</td>
+    <td valign="top">Perform a case sensitive comparision.  Default is
+        true.</td>
+    <td valign="top" align="center">No</td>
+  </tr>
+  <tr>
+    <td valign="top">trim</td>
+    <td valign="top">Trim whitespace from arguments before comparing
+        them.  Default is false.</td>
+    <td valign="top" align="center">No</td>
+  </tr>
+</table>
+
+<h4>isset</h4>
+<p>Test whether a given property has been set in this project.</p>
+<table border="1" cellpadding="2" cellspacing="0">
+  <tr>
+    <td valign="top"><b>Attribute</b></td>
+    <td valign="top"><b>Description</b></td>
+    <td align="center" valign="top"><b>Required</b></td>
+  </tr>
+  <tr>
+    <td valign="top">property</td>
+    <td valign="top">The name of the property to test.</td>
+    <td valign="top" align="center">Yes</td>
+  </tr>
+</table>
+
+<h4>contains</h4>
+<p>Tests whether a string contains another one.</p>
+<table border="1" cellpadding="2" cellspacing="0">
+  <tr>
+    <td valign="top"><b>Attribute</b></td>
+    <td valign="top"><b>Description</b></td>
+    <td align="center" valign="top"><b>Required</b></td>
+  </tr>
+  <tr>
+    <td valign="top">string</td>
+    <td valign="top">The string to search in.</td>
+    <td valign="top" align="center">Yes</td>
+  </tr>
+  <tr>
+    <td valign="top">substring</td>
+    <td valign="top">The string to search for.</td>
+    <td valign="top" align="center">Yes</td>
+  </tr>
+  <tr>
+    <td valign="top">casesensitive</td>
+    <td valign="top">Perform a case sensitive comparision.  Default is
+        true.</td>
+    <td valign="top" align="center">No</td>
+  </tr>
+</table>
+
+<h4>istrue</h4>
+<p>Tests whether a string evals to true.</p>
+
+<table border="1" cellpadding="2" cellspacing="0">
+  <tr>
+    <td valign="top"><b>Attribute</b></td>
+    <td valign="top"><b>Description</b></td>
+    <td align="center" valign="top"><b>Required</b></td>
+  </tr>
+  <tr>
+    <td valign="top">value</td>
+    <td valign="top">value to test</td>
+    <td valign="top" align="center">Yes</td>
+  </tr>
+</table>
+<pre>
+    &lt;istrue value=&quot;${someproperty}&quot;/&gt;
+    &lt;istrue value=&quot;false&quot;/&gt;
+</pre>
+
+<h4>isfalse</h4>
+<p>Tests whether a string evals to not true, the negation of &lt;istrue&gt;
+</p>
+<table border="1" cellpadding="2" cellspacing="0">
+  <tr>
+    <td valign="top"><b>Attribute</b></td>
+    <td valign="top"><b>Description</b></td>
+    <td align="center" valign="top"><b>Required</b></td>
+  </tr>
+  <tr>
+    <td valign="top">value</td>
+    <td valign="top">value to test</td>
+    <td valign="top" align="center">Yes</td>
+  </tr>
+</table>
+<pre>
+    &lt;isfalse value=&quot;${someproperty}&quot;/&gt;
+    &lt;isfalse value=&quot;false&quot;/&gt;
+</pre>
+
+</body>
+</html>
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/docs/phing_guide/book/chapters/Setup.html
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/docs/phing_guide/book/chapters/Setup.html	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/docs/phing_guide/book/chapters/Setup.html	(revision 19)
@@ -0,0 +1,298 @@
+<!--
+-File         $Id: Setup.html 358 2008-02-26 09:04:26Z mrook $
+-License      GNU FDL (http://www.gnu.org/copyleft/fdl.html)
+-Copyright    2002, turing
+-Author       alex black, enigma@turingstudio.com
+-->
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/2000/REC-xhtml1-20000126/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+  <head>
+    <title>Phing Guide - Setup</title>
+    <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
+    <link rel="Stylesheet" rev="Stylesheet" href="../css/Documentation.css" type="text/css" media="All" charset="iso-8859-1" />
+  </head>
+  <body>
+
+<h1><a name="SettingUpPhing"></a>Setting-Up Phing</h1>
+
+<p>The goal of this chapter is to help you obtain and correctly setup and execute
+  Phing on your operating system. Once you setup Phing properly you shouldn't
+  need to revisit this chapter, unless you're re-installing or moving your installation
+  to another platform.</p>
+
+<h2><a name="SystemRequirements"></a>System Requirements</h2>
+
+<p> To use Phing you must have installed PHP version 5.0.0b1 or above compiled
+  --with-libxml2, as well as --with-xsl if you want to make use of advanced functionality.
+  At the time of writing PHP5.0.0b2-dev is currently unable to run Phing due to
+  segmentation faults arising somewhere in the XML parsing of the build file.</p>
+
+<p> For more information on PHP and the required modules see the PHP <a href="Bibliography.html#php">[php]</a>
+  website. For a brief list of software dependencies see below. </p>
+
+<h3><a name="OperatingSystems"></a>Operating Systems</h3>
+
+<p> Designed for portability from the get go, Phing runs on all platforms that
+  run PHP. However some advanced functionality may not work properly or is simply
+  ignored on some platforms (i.e. chmod on the Windows platform). </p>
+
+<p> To get the most out of Phing, a Unix style platform is recommended. Namely:
+  Linux, FreeBSD, OpenBSD, etc. </p>
+
+<h3><a name="SoftwareDependencies"></a>Software Dependencies</h3>
+
+<p>For a detailed list of required sofware and libraries, refer to
+the following table of Software dependencies.</p>
+
+<p>NB: This list is not exhaustive, please refer to individual Phing tasks to
+find out additional software requirements.</p>
+
+<table>
+  <caption>
+  Software Dependencies
+  </caption>
+  <thead>
+    <tr>
+      <th>Software</th>
+      <th>Required for</th>
+      <th>Source</th>
+    </tr>
+  </thead>
+  <tbody>
+    <tr>
+      <td>PHP 5.0.2+</td>
+      <td>Execution</td>
+      <td><a href="http://www.php.net">http://www.php.net</a></td>
+    </tr>
+    <tr>
+      <td>PHPUnit2 3.2.0+</td>
+      <td>Additional functionality (task)</td>
+      <td><a href="http://www.phpunit.de">http://www.phpunit.de</a></td>
+    </tr>
+    <tr>
+      <td>Xdebug 2.0.0+</td>
+      <td>Additional functionality (task)</td>
+      <td><a href="http://www.xdebug.org">http://www.xdebug.org</a></td>
+    </tr>
+    <tr>
+      <td>PhpDocumentor 1.4.0+</td>
+      <td>Additional functionality (task)</td>
+      <td><a href="http://www.phpdoc.org">http://www.phpdoc.org</a></td>
+    </tr>
+    <tr>
+      <td>VersionControl_SVN PEAR package</td>
+      <td>Additional functionality (task)</td>
+      <td><a href="http://pear.php.net">http://pear.php.net</a></td>
+    </tr>
+    <tr>
+      <td>SimpleTest 1.0.1 beta+</td>
+      <td>Additional functionality (task)</td>
+      <td><a href="http://simpletest.sourceforge.net">http://simpletest.sourceforge.net</a></td>
+    </tr>
+    <tr>
+      <td>Creole 1.1.0+</td>
+      <td>Additional functionality (task)</td>
+      <td><a href="http://creole.phpdb.org">http://creole.phpdb.org</a></td>
+    </tr>
+    <!-- Zend Optimizer etc. could be added here... -->
+  </tbody>
+</table>
+
+<p><strong>Phing does not work with safe mode enabled! </strong></p>
+<h2><a name="ObtainingPhing"></a>Obtaining Phing</h2>
+
+<p> Phing is free software distributed under the terms of the LGPL.</p>
+
+<h3><a name="DistributionFiles"></a>Distribution Files</h3>
+
+<p> There are several ways to get a Phing distribution package. If you do not
+  want to participate in developing Phing itself it is recommended that you get
+  the latest snapshot or stable packaged distribution. If you are interested in
+  helping with Phing development, get a CVS revision of the files, as described
+  below. </p>
+
+<p> The easiest way to obtain the distribution package is to visit the Phing website
+  <a href="Bibliography.html#phing">[phing] </a>and download the current distribution
+  package in the format you desire. </p>
+<p>As of version 2.0.0b1, you have the option of downloading a PEAR-installable
+  package or the full phing distribution. If you wish to modify phing we suggestion
+  downloading the full version so that you can (e.g.) create your own PEAR package.
+  If you simply wish to use Phing for your own project or need it to build another
+  package, download &amp; install the PEAR package.</p>
+
+<h3><a name="GettingFromCVS"></a>Getting A Development Copy From CVS</h3>
+
+<p>You are encouraged to contibute to the development of Phing. If
+you want to participate in Phing development or if you are simply
+intereseted in the latest features and development, obtain a CVS
+copy as described in the following paragraphs.</p>
+
+<p><strong>The CVS revisions of Phing are not bullet-proof and may
+fail to execute properly on your machine. Only obtain the CVS
+versions if you are absolutely aware of limitations and constraints
+of such an action. Additionally you should sign up to the
+development mailinglist to report and notice errors and
+incompatibilities.</strong></p>
+
+<p>We assume that you are running a Unix style operating system. So
+we expect the CVS software is installed ant the <tt>cvs</tt>
+executable is in your system's search path.. However, the steps for
+a Windows based system are very similar. There is plenty additional
+resources available on how to use CVS
+<a href="Bibliography.html#cvs-howto">[cvs-howto]</a> and on CVS
+speciaities on the Tigris project management platfrom
+<a href="Bibliography.html#cvs-tigris">[cvs-tigris]</a>.</p>
+
+<p>The frist thing you have to do is log onto the CVS server.
+Therefore type the following line at your command promt:</p>
+
+<pre>
+ cvs -d :pserver:guest@cvs.tigris.org:/cvs login
+</pre>
+
+<p>If you signed-up as developer at the Tigris website, login with
+your own password, the same as the one you use to access the site.
+Or use the password "guest" with username "guest".</p>
+
+<p>If this is the only project you working on, you only need to set
+the cvsroot once. Thereafter when you log in to this domain, the
+cvs repository for this project is assumed. If you are working
+multiple projects, however, you must specify the cvsroot each time
+you log in to ensure that the cvs repository you are accessing is
+the right one.</p>
+
+<p>To check out the project source repository an individual module
+(if you don't need the entire repository), type:</p>
+
+<pre>
+cvs -d :pserver:guest@cvs.tigris.org:/cvs checkout phing
+</pre>
+
+<p>This command should result in a scrolling list of files being
+added to the local directory you specified on your machine. Now you
+are ready to use your favourite file editor to work with individual
+files and make changes.</p>
+
+<p>The top-level CVS module contains the Phing project website in addition to
+  the phing application; the Phing files, therefore, reside in the phing/ subdirectory:</p>
+
+<pre>
+./phing/phing
+</pre>
+<h2><a name="Setup.PearInstall"></a>PEAR Install</h2>
+<p>The easiest way to install Phing is using the PEAR installer. Provided that
+  the package you downloaded is a the PEAR-ready package, you can install Phing
+  simply from the command line (Unix or Windows):</p>
+<pre>$&gt; pear install phing-2.0.0b1-pear.tar.gz</pre>
+<p>The pear installer will check any dependencies and place the phing script (phing
+  or phing.bat) into your PHP script directoy (i.e. where the &quot;pear&quot;
+  script resides).</p>
+
+<h2><a name="Setup.NonPearInstall"></a>Non-PEAR Install</h2>
+
+<p>If you are not using the PEAR installer, you will need to setup your environment
+  in order to run Phing. The distribution of Phing consists of three directories:
+  <em>bin</em> , <em>docs</em> and <em>classes</em>. Only the <em>bin</em>, <em>classes</em> and
+  <em>etc</em> directories are required to run Phing. To install Phing, choose
+  a directory and uncompress the distribution file in that directory (you may
+  already have done this in a prior step). This directory will be known as <em>PHING_HOME</em>
+  .</p>
+
+<p><strong>On Windows 95 and Windows 98, the script used to launch Phing will
+  have problems if PHING_HOME is a long filepath. This is due to limitations in
+  the OS's handling of the "for" batch-file statement. It is recommended, therefore,
+  that Phing be installed in a short path, such as C:\opt\phing.</strong></p>
+
+<p>Before you can run Phing there is some additional set up you
+will need to do perform:</p>
+
+<ul>
+  <li>Add the full path to the <em>bin/</em> directory to your path.</li>
+  <li>Set the <em>PHING_HOME</em> environment variable to the directory
+      where you installed Phing. On some operating systems the Phing
+      wrapper scripts can guess PHING_HOME (Unix dialects and Windows
+      NT/2000). However, it is better to not rely on this behavior.</li>
+  <li>Set the <em>PHP_COMMAND</em> environment variable to where your
+      Php binary is located (including the binary i.e.
+      PHP_COMMAND=/usr/bin/php).</li>
+  <li>Set the <em>PHP_CLASSPATH</em> environment variable (see the section below).
+    This should be set at least point to PHING_HOME/classes. Alternatively, you
+    can also just add the phing/classes directory to your PHP include_path ini
+    setting.</li>
+   <li>Check your php.ini file to make sure that you have the following settings:
+   	<ul>
+		<li>max_execution_time = 0 <em>// unlimited execution time</em></li>
+		<li>memory_limit = 32M <em>// you may need more memory depending on size of your build files</em></li>
+	</ul>
+   </li>
+</ul>
+
+<p>If you are using Phing in conjunction with another application, you may need
+  to add additional paths to PHP_CLASSPATH.</p>
+
+<h3><a name="Unix"></a>Unix</h3>
+
+<p>Assuming you are running a Unix dialect operating system with
+the <em>bash bourne shell</em> and Phing is
+installed in <tt>/opt/phing</tt> . The following sets up the
+environment properly:</p>
+
+<pre>
+  export PHP_COMMAND=/usr/bin/php
+  export PHING_HOME=/opt/phing
+  export PHP_CLASSPATH=${PHING_HOME}/classes
+  export PATH=${PATH}:${PHING_HOME}/bin
+</pre>
+<h3><a name="Windows"></a>Windows</h3>
+
+<p>On the Windows platfrom, assuming Phing is installed in
+c:\opt\phing. The following sets up your environment:</p>
+
+<pre>
+  set PHP_COMMAND=c:\opt\php\php.exe
+  set PHING_HOME=c:\opt\phing
+  set PHP_CLASSPATH=c:\opt\phing\classes
+  set PATH=%PATH%;%PHING_HOME%\bin
+</pre>
+<h3>Advanced</h3>
+
+<p>There are lots of variants that can be used to run/prepare Phing. You need
+  at least the following:</p>
+<ul>
+  <li>If you want Phing to be able to use other packages / classes, you can either
+    add them to the PHP_CLASSPATH or to PHP's include_path.</li>
+  <li>Some Tasks in phing/tasks/ext may require 3rd party libraries to be installed.
+    Generally, tools with compatible license (and stable releases) are included
+    in phing/lib so that outside dependencies can be avoided. PEAR libs will not,
+    however, be bundled with Phing since they are generally bundled with PHP.
+    If you are using a 3rd party task, see the Task documentation to be aware
+    of any dependencies.</li>
+</ul>
+
+<p>You are now ready to use the <tt>phing</tt> command at your command prompt,
+  from everywhere in your directory tree.</p>
+
+<h2><a name="CallingPhing"></a>Calling Phing</h2>
+
+<p>Now you are prepared to execute Phing on the command line or via
+script files. The following section briefly describe how to
+properly execute phing.</p>
+
+<h3><a name="CommandLine"></a>Command Line</h3>
+
+<p>Phing execution on the command line is simple. Just change to
+the directory where your buildfile resides and type</p>
+
+<pre>
+$ phing [targetname]
+</pre>
+
+<p>at the command line (where [targetname] is the target you
+want to be executed). Optionally, you may specify command line
+arguments as listed in
+<a href="appendixes/AppendixA-FactSheet.html#CommandLineArguments">Appendix A</a>.
+</p>
+
+  </body>
+</html>
+
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/docs/phing_guide/book/chapters/appendixes/AppendixA-FactSheet.html
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/docs/phing_guide/book/chapters/appendixes/AppendixA-FactSheet.html	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/docs/phing_guide/book/chapters/appendixes/AppendixA-FactSheet.html	(revision 19)
@@ -0,0 +1,746 @@
+<!--
+-File         $Id: AppendixA-FactSheet.html 182 2007-04-17 14:37:01Z mrook $
+-License      GNU FDL (http://www.gnu.org/copyleft/fdl.html)
+-Copyright    2002, turing
+-Author       alex black, enigma@turingstudio.com
+-->
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/2000/REC-xhtml1-20000126/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+	<title>Phing Guide - Fact Sheet</title>
+	<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
+	<link rel="Stylesheet" rev="Stylesheet" href="../../css/Documentation.css" type="text/css" media="All" charset="iso-8859-1" />
+</head>
+<body>
+<h1>Appendix A: Fact Sheet</h1>
+
+<h2><a name="BuiltInProperties"></a>Built-In Properties</h2>
+
+<table>
+<caption>Phing Built-In Properties</caption>
+<thead>
+  <tr>
+    <th>Property</th>
+    <th>Contents</th>
+  </tr>
+</thead>
+<tbody>
+<tr>
+  <td>application.startdir</td>
+  <td>Current work directory</td>
+</tr>
+<tr>
+  <td>env.*</td>
+  <td>Environment variables, extracted from <em>$_SERVER</em>.</td>
+</tr>
+<tr>
+  <td>host.arch</td>
+  <td>System architecture, i.e. <em>i586</em>.
+      <em>Not available on Windows machines.</em></td>
+</tr>
+<tr>
+  <td>host.domain</td>
+  <td>DNS domain name, i.e. php.net. <em>Not available on Windows machines.</em></td>
+</tr>
+<tr>
+  <td>host.fstype</td>
+  <td>The type of the filesystem. Possible values are <em>UNIX</em>,
+      <em>WINNT</em> and <em>WIN32</em></td>
+</tr>
+<tr>
+  <td>host.name</td>
+  <td>Operating System hostname as returned by <em>posix_uname()</em>.
+      <em>Not available on Windows machines.</em></td>
+</tr>
+<tr>
+  <td>host.os</td>
+  <td>Operating System description as set in <em>PHP_OS</em> variable (see <a
+      href="http://www.php.net/manual/en/reserved.constants.core.php">PHP Manual</a>).</td>
+</tr>
+<tr>
+  <td>host.os.release</td>
+  <td>Operating version release, i.e. <em> 2.2.10</em>.
+      <em>Not available on Windows machines.</em></td>
+</tr>
+<tr>
+  <td>host.os.version</td>
+  <td>Operating system version, i.e. <em>#4 Tue Jul 20 17:01:36 MEST 1999</em>.
+      <em>Not available on Windows machines.</em></td>
+</tr>
+<tr>
+  <td>line.separator</td>
+  <td>Character(s) that signal the end of a line, &quot;\n&quot; for Linux,
+      &quot;\r\n&quot; for Windows system, &quot;\r&quot; for Macintosh.</td>
+</tr>
+<tr>
+  <td>os.name</td>
+  <td>Operating System description as set in <em>PHP_OS</em> variable.</td>
+</tr>
+
+<tr>
+  <td>phing.file</td>
+  <td>Full path to current buildfile.</td>
+</tr>
+<tr>
+  <td>phing.home</td>
+  <td>Phing installation directory, not set in <em>PEAR</em> installations.</td>
+</tr>
+<tr>
+  <td>phing.version</td>
+  <td>Current Phing version.</td>
+</tr>
+<tr>
+  <td>phing.project.name</td>
+  <td>Name of the currently processed project.</td>
+</tr>
+
+<tr>
+  <td>php.classpath</td>
+  <td>The value of the environment variable <em>PHP_CLASSPATH</em>.</td>
+</tr>
+<tr>
+  <td>php.version</td>
+  <td>Version of the PHP interpreter. Same as PHP constant <em>PHP_VERSION</em>
+      (see <a href="http://www.php.net/manual/en/reserved.constants.core.php">PHP Manual</a>).
+      </td>
+</tr>
+
+<tr>
+  <td>project.basedir</td>
+  <td>The current project basedir.</td>
+</tr>
+
+<tr>
+  <td>user.home</td>
+  <td>Value of the environment variable <em>HOME</em>.</td>
+</tr>
+
+  </tbody>
+</table>
+
+
+<h2><a name="CommandLineArguments"></a>Command Line Arguments</h2>
+
+<p>Currently, the following command line arguments listed in table
+below are currently available.</p>
+
+<table>
+
+<caption>Phing Command Line Arguments</caption>
+
+<thead>
+  <tr>
+    <th>Parameter</th>
+    <th>Meaning</th>
+  </tr>
+</thead>
+<tbody>
+  <tr>
+    <td>-quiet</td>
+    <td>Quiet operation, no output at all</td>
+  </tr>
+  <tr>
+   <td>-verbose</td>
+   <td>Verbose, give some output</td>
+  </tr>
+  <tr>
+    <td>-debug</td>
+    <td>Output debug information</td>
+  </tr>
+  <tr>
+    <td>-buildfile [builfile]</td>
+    <td>Specify an alternate builfile name. Default is <em>build.xml</em></td>
+  </tr>
+  <tr>
+    <td>-logger path.to.Logger</td>
+    <td>Specify an alternate logger. Default is <em>phing.listener.DefaultLogger</em>.  Other options include <em>phing.listener.NoBannerLogger</em> and <em>phing.listener.AnsiColorLogger</em></td>
+  </tr>
+  <tr>
+    <td>-help</td>
+    <td>Display the help screen</td>
+  </tr>
+  <tr>
+    <td>-projecthelp</td>
+    <td>List the available targets for this project</td>
+  </tr>
+
+  <tr><td colspan="2"><em><strong>TODO Complete this</strong></em></td></tr>
+</tbody>
+</table>
+
+
+<h2><a name="DistributionFileLayout"></a>Distribution File Layout</h2>
+
+<pre title="DistributionFileLayout">$PHING_HOME
+  |-- bin
+  |-- classes
+  |    `-- phing
+  |         |-- filters
+  |         |    `-- util
+  |         |-- mappers
+  |         |-- parser
+  |         |-- tasks
+  |         |    |-- ext
+  |         |    |-- system
+  |         |    |    `-- condition
+  |         |    `-- user
+  |         `-- types
+  |-- docs
+  |    `-- phing_guide
+  `-- test
+       |-- classes
+	   `-- etc
+</pre>
+
+<h2><a name="ProgramExitCodes"></a>Program Exit Codes</h2>
+
+<p>Phing is script-safe - means that you can execute Phing and
+Configure within a automated script context. To check back the
+success of a Phing call it returns an exit code that can be
+captured by your calling script. The following list gives you
+details on the used exit codes and their meaning.</p>
+
+<table>
+<caption>Program Exit Codes</caption>
+
+<thead>
+  <tr>
+    <th>Exitcode</th>
+    <th>Description</th>
+  </tr>
+</thead>
+
+<tbody>
+  <tr>
+    <td>-2</td>
+    <td>Environment not properly defined</td>
+  </tr>
+  <tr>
+    <td>-1</td>
+    <td>Parameter error occured, printed help screen</td>
+  </tr>
+  <tr>
+    <td>0</td>
+    <td>Successful execution, no warnings, no errors</td>
+  </tr>
+  <tr>
+    <td>1</td>
+    <td>Successful execution, but warnings occured</td>
+  </tr>
+</tbody>
+
+</table>
+
+<h2><a name="LGPLLicense"></a>The LGPL License</h2>
+
+<p>
+  Source <a href="http://www.gnu.org/licenses/lgpl.txt">http://www.gnu.org/licenses/lgpl.txt</a>
+</p>
+
+<pre>
+		  GNU LESSER GENERAL PUBLIC LICENSE
+		       Version 2.1, February 1999
+
+ Copyright (C) 1991, 1999 Free Software Foundation, Inc.
+     59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+[This is the first released version of the Lesser GPL.  It also counts
+ as the successor of the GNU Library Public License, version 2, hence
+ the version number 2.1.]
+
+			    Preamble
+
+  The licenses for most software are designed to take away your
+freedom to share and change it.  By contrast, the GNU General Public
+Licenses are intended to guarantee your freedom to share and change
+free software--to make sure the software is free for all its users.
+
+  This license, the Lesser General Public License, applies to some
+specially designated software packages--typically libraries--of the
+Free Software Foundation and other authors who decide to use it.  You
+can use it too, but we suggest you first think carefully about whether
+this license or the ordinary General Public License is the better
+strategy to use in any particular case, based on the explanations below.
+
+  When we speak of free software, we are referring to freedom of use,
+not price.  Our General Public Licenses are designed to make sure that
+you have the freedom to distribute copies of free software (and charge
+for this service if you wish); that you receive source code or can get
+it if you want it; that you can change the software and use pieces of
+it in new free programs; and that you are informed that you can do
+these things.
+
+  To protect your rights, we need to make restrictions that forbid
+distributors to deny you these rights or to ask you to surrender these
+rights.  These restrictions translate to certain responsibilities for
+you if you distribute copies of the library or if you modify it.
+
+  For example, if you distribute copies of the library, whether gratis
+or for a fee, you must give the recipients all the rights that we gave
+you.  You must make sure that they, too, receive or can get the source
+code.  If you link other code with the library, you must provide
+complete object files to the recipients, so that they can relink them
+with the library after making changes to the library and recompiling
+it.  And you must show them these terms so they know their rights.
+
+  We protect your rights with a two-step method: (1) we copyright the
+library, and (2) we offer you this license, which gives you legal
+permission to copy, distribute and/or modify the library.
+
+  To protect each distributor, we want to make it very clear that
+there is no warranty for the free library.  Also, if the library is
+modified by someone else and passed on, the recipients should know
+that what they have is not the original version, so that the original
+author's reputation will not be affected by problems that might be
+introduced by others.
+
+  Finally, software patents pose a constant threat to the existence of
+any free program.  We wish to make sure that a company cannot
+effectively restrict the users of a free program by obtaining a
+restrictive license from a patent holder.  Therefore, we insist that
+any patent license obtained for a version of the library must be
+consistent with the full freedom of use specified in this license.
+
+  Most GNU software, including some libraries, is covered by the
+ordinary GNU General Public License.  This license, the GNU Lesser
+General Public License, applies to certain designated libraries, and
+is quite different from the ordinary General Public License.  We use
+this license for certain libraries in order to permit linking those
+libraries into non-free programs.
+
+  When a program is linked with a library, whether statically or using
+a shared library, the combination of the two is legally speaking a
+combined work, a derivative of the original library.  The ordinary
+General Public License therefore permits such linking only if the
+entire combination fits its criteria of freedom.  The Lesser General
+Public License permits more lax criteria for linking other code with
+the library.
+
+  We call this license the &quot;Lesser&quot; General Public License because it
+does Less to protect the user's freedom than the ordinary General
+Public License.  It also provides other free software developers Less
+of an advantage over competing non-free programs.  These disadvantages
+are the reason we use the ordinary General Public License for many
+libraries.  However, the Lesser license provides advantages in certain
+special circumstances.
+
+  For example, on rare occasions, there may be a special need to
+encourage the widest possible use of a certain library, so that it becomes
+a de-facto standard.  To achieve this, non-free programs must be
+allowed to use the library.  A more frequent case is that a free
+library does the same job as widely used non-free libraries.  In this
+case, there is little to gain by limiting the free library to free
+software only, so we use the Lesser General Public License.
+
+  In other cases, permission to use a particular library in non-free
+programs enables a greater number of people to use a large body of
+free software.  For example, permission to use the GNU C Library in
+non-free programs enables many more people to use the whole GNU
+operating system, as well as its variant, the GNU/Linux operating
+system.
+
+  Although the Lesser General Public License is Less protective of the
+users' freedom, it does ensure that the user of a program that is
+linked with the Library has the freedom and the wherewithal to run
+that program using a modified version of the Library.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.  Pay close attention to the difference between a
+&quot;work based on the library&quot; and a &quot;work that uses the library&quot;.  The
+former contains code derived from the library, whereas the latter must
+be combined with the library in order to run.
+
+		  GNU LESSER GENERAL PUBLIC LICENSE
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  0. This License Agreement applies to any software library or other
+program which contains a notice placed by the copyright holder or
+other authorized party saying it may be distributed under the terms of
+this Lesser General Public License (also called &quot;this License&quot;).
+Each licensee is addressed as &quot;you&quot;.
+
+  A &quot;library&quot; means a collection of software functions and/or data
+prepared so as to be conveniently linked with application programs
+(which use some of those functions and data) to form executables.
+
+  The &quot;Library&quot;, below, refers to any such software library or work
+which has been distributed under these terms.  A &quot;work based on the
+Library&quot; means either the Library or any derivative work under
+copyright law: that is to say, a work containing the Library or a
+portion of it, either verbatim or with modifications and/or translated
+straightforwardly into another language.  (Hereinafter, translation is
+included without limitation in the term &quot;modification&quot;.)
+
+  &quot;Source code&quot; for a work means the preferred form of the work for
+making modifications to it.  For a library, complete source code means
+all the source code for all modules it contains, plus any associated
+interface definition files, plus the scripts used to control compilation
+and installation of the library.
+
+  Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope.  The act of
+running a program using the Library is not restricted, and output from
+such a program is covered only if its contents constitute a work based
+on the Library (independent of the use of the Library in a tool for
+writing it).  Whether that is true depends on what the Library does
+and what the program that uses the Library does.
+
+  1. You may copy and distribute verbatim copies of the Library's
+complete source code as you receive it, in any medium, provided that
+you conspicuously and appropriately publish on each copy an
+appropriate copyright notice and disclaimer of warranty; keep intact
+all the notices that refer to this License and to the absence of any
+warranty; and distribute a copy of this License along with the
+Library.
+
+  You may charge a fee for the physical act of transferring a copy,
+and you may at your option offer warranty protection in exchange for a
+fee.
+
+  2. You may modify your copy or copies of the Library or any portion
+of it, thus forming a work based on the Library, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+    a) The modified work must itself be a software library.
+
+    b) You must cause the files modified to carry prominent notices
+    stating that you changed the files and the date of any change.
+
+    c) You must cause the whole of the work to be licensed at no
+    charge to all third parties under the terms of this License.
+
+    d) If a facility in the modified Library refers to a function or a
+    table of data to be supplied by an application program that uses
+    the facility, other than as an argument passed when the facility
+    is invoked, then you must make a good faith effort to ensure that,
+    in the event an application does not supply such function or
+    table, the facility still operates, and performs whatever part of
+    its purpose remains meaningful.
+
+    (For example, a function in a library to compute square roots has
+    a purpose that is entirely well-defined independent of the
+    application.  Therefore, Subsection 2d requires that any
+    application-supplied function or table used by this function must
+    be optional: if the application does not supply it, the square
+    root function must still compute square roots.)
+
+These requirements apply to the modified work as a whole.  If
+identifiable sections of that work are not derived from the Library,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works.  But when you
+distribute the same sections as part of a whole which is a work based
+on the Library, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote
+it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Library.
+
+In addition, mere aggregation of another work not based on the Library
+with the Library (or with a work based on the Library) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+  3. You may opt to apply the terms of the ordinary GNU General Public
+License instead of this License to a given copy of the Library.  To do
+this, you must alter all the notices that refer to this License, so
+that they refer to the ordinary GNU General Public License, version 2,
+instead of to this License.  (If a newer version than version 2 of the
+ordinary GNU General Public License has appeared, then you can specify
+that version instead if you wish.)  Do not make any other change in
+these notices.
+
+  Once this change is made in a given copy, it is irreversible for
+that copy, so the ordinary GNU General Public License applies to all
+subsequent copies and derivative works made from that copy.
+
+  This option is useful when you wish to copy part of the code of
+the Library into a program that is not a library.
+
+  4. You may copy and distribute the Library (or a portion or
+derivative of it, under Section 2) in object code or executable form
+under the terms of Sections 1 and 2 above provided that you accompany
+it with the complete corresponding machine-readable source code, which
+must be distributed under the terms of Sections 1 and 2 above on a
+medium customarily used for software interchange.
+
+  If distribution of object code is made by offering access to copy
+from a designated place, then offering equivalent access to copy the
+source code from the same place satisfies the requirement to
+distribute the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+  5. A program that contains no derivative of any portion of the
+Library, but is designed to work with the Library by being compiled or
+linked with it, is called a &quot;work that uses the Library&quot;.  Such a
+work, in isolation, is not a derivative work of the Library, and
+therefore falls outside the scope of this License.
+
+  However, linking a &quot;work that uses the Library&quot; with the Library
+creates an executable that is a derivative of the Library (because it
+contains portions of the Library), rather than a &quot;work that uses the
+library&quot;.  The executable is therefore covered by this License.
+Section 6 states terms for distribution of such executables.
+
+  When a &quot;work that uses the Library&quot; uses material from a header file
+that is part of the Library, the object code for the work may be a
+derivative work of the Library even though the source code is not.
+Whether this is true is especially significant if the work can be
+linked without the Library, or if the work is itself a library.  The
+threshold for this to be true is not precisely defined by law.
+
+  If such an object file uses only numerical parameters, data
+structure layouts and accessors, and small macros and small inline
+functions (ten lines or less in length), then the use of the object
+file is unrestricted, regardless of whether it is legally a derivative
+work.  (Executables containing this object code plus portions of the
+Library will still fall under Section 6.)
+
+  Otherwise, if the work is a derivative of the Library, you may
+distribute the object code for the work under the terms of Section 6.
+Any executables containing that work also fall under Section 6,
+whether or not they are linked directly with the Library itself.
+
+  6. As an exception to the Sections above, you may also combine or
+link a &quot;work that uses the Library&quot; with the Library to produce a
+work containing portions of the Library, and distribute that work
+under terms of your choice, provided that the terms permit
+modification of the work for the customer's own use and reverse
+engineering for debugging such modifications.
+
+  You must give prominent notice with each copy of the work that the
+Library is used in it and that the Library and its use are covered by
+this License.  You must supply a copy of this License.  If the work
+during execution displays copyright notices, you must include the
+copyright notice for the Library among them, as well as a reference
+directing the user to the copy of this License.  Also, you must do one
+of these things:
+
+    a) Accompany the work with the complete corresponding
+    machine-readable source code for the Library including whatever
+    changes were used in the work (which must be distributed under
+    Sections 1 and 2 above); and, if the work is an executable linked
+    with the Library, with the complete machine-readable &quot;work that
+    uses the Library&quot;, as object code and/or source code, so that the
+    user can modify the Library and then relink to produce a modified
+    executable containing the modified Library.  (It is understood
+    that the user who changes the contents of definitions files in the
+    Library will not necessarily be able to recompile the application
+    to use the modified definitions.)
+
+    b) Use a suitable shared library mechanism for linking with the
+    Library.  A suitable mechanism is one that (1) uses at run time a
+    copy of the library already present on the user's computer system,
+    rather than copying library functions into the executable, and (2)
+    will operate properly with a modified version of the library, if
+    the user installs one, as long as the modified version is
+    interface-compatible with the version that the work was made with.
+
+    c) Accompany the work with a written offer, valid for at
+    least three years, to give the same user the materials
+    specified in Subsection 6a, above, for a charge no more
+    than the cost of performing this distribution.
+
+    d) If distribution of the work is made by offering access to copy
+    from a designated place, offer equivalent access to copy the above
+    specified materials from the same place.
+
+    e) Verify that the user has already received a copy of these
+    materials or that you have already sent this user a copy.
+
+  For an executable, the required form of the &quot;work that uses the
+Library&quot; must include any data and utility programs needed for
+reproducing the executable from it.  However, as a special exception,
+the materials to be distributed need not include anything that is
+normally distributed (in either source or binary form) with the major
+components (compiler, kernel, and so on) of the operating system on
+which the executable runs, unless that component itself accompanies
+the executable.
+
+  It may happen that this requirement contradicts the license
+restrictions of other proprietary libraries that do not normally
+accompany the operating system.  Such a contradiction means you cannot
+use both them and the Library together in an executable that you
+distribute.
+
+  7. You may place library facilities that are a work based on the
+Library side-by-side in a single library together with other library
+facilities not covered by this License, and distribute such a combined
+library, provided that the separate distribution of the work based on
+the Library and of the other library facilities is otherwise
+permitted, and provided that you do these two things:
+
+    a) Accompany the combined library with a copy of the same work
+    based on the Library, uncombined with any other library
+    facilities.  This must be distributed under the terms of the
+    Sections above.
+
+    b) Give prominent notice with the combined library of the fact
+    that part of it is a work based on the Library, and explaining
+    where to find the accompanying uncombined form of the same work.
+
+  8. You may not copy, modify, sublicense, link with, or distribute
+the Library except as expressly provided under this License.  Any
+attempt otherwise to copy, modify, sublicense, link with, or
+distribute the Library is void, and will automatically terminate your
+rights under this License.  However, parties who have received copies,
+or rights, from you under this License will not have their licenses
+terminated so long as such parties remain in full compliance.
+
+  9. You are not required to accept this License, since you have not
+signed it.  However, nothing else grants you permission to modify or
+distribute the Library or its derivative works.  These actions are
+prohibited by law if you do not accept this License.  Therefore, by
+modifying or distributing the Library (or any work based on the
+Library), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Library or works based on it.
+
+  10. Each time you redistribute the Library (or any work based on the
+Library), the recipient automatically receives a license from the
+original licensor to copy, distribute, link with or modify the Library
+subject to these terms and conditions.  You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties with
+this License.
+
+  11. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Library at all.  For example, if a patent
+license would not permit royalty-free redistribution of the Library by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Library.
+
+If any portion of this section is held invalid or unenforceable under any
+particular circumstance, the balance of the section is intended to apply,
+and the section as a whole is intended to apply in other circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system which is
+implemented by public license practices.  Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+  12. If the distribution and/or use of the Library is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Library under this License may add
+an explicit geographical distribution limitation excluding those countries,
+so that distribution is permitted only in or among countries not thus
+excluded.  In such case, this License incorporates the limitation as if
+written in the body of this License.
+
+  13. The Free Software Foundation may publish revised and/or new
+versions of the Lesser General Public License from time to time.
+Such new versions will be similar in spirit to the present version,
+but may differ in detail to address new problems or concerns.
+
+Each version is given a distinguishing version number.  If the Library
+specifies a version number of this License which applies to it and
+&quot;any later version&quot;, you have the option of following the terms and
+conditions either of that version or of any later version published by
+the Free Software Foundation.  If the Library does not specify a
+license version number, you may choose any version ever published by
+the Free Software Foundation.
+
+  14. If you wish to incorporate parts of the Library into other free
+programs whose distribution conditions are incompatible with these,
+write to the author to ask for permission.  For software which is
+copyrighted by the Free Software Foundation, write to the Free
+Software Foundation; we sometimes make exceptions for this.  Our
+decision will be guided by the two goals of preserving the free status
+of all derivatives of our free software and of promoting the sharing
+and reuse of software generally.
+
+			    NO WARRANTY
+
+  15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
+WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
+EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
+OTHER PARTIES PROVIDE THE LIBRARY &quot;AS IS&quot; WITHOUT WARRANTY OF ANY
+KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
+LIBRARY IS WITH YOU.  SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
+THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+  16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
+WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
+AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
+FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
+CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
+LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
+RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
+FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
+SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGES.
+
+		     END OF TERMS AND CONDITIONS
+
+           How to Apply These Terms to Your New Libraries
+
+  If you develop a new library, and you want it to be of the greatest
+possible use to the public, we recommend making it free software that
+everyone can redistribute and change.  You can do so by permitting
+redistribution under these terms (or, alternatively, under the terms of the
+ordinary General Public License).
+
+  To apply these terms, attach the following notices to the library.  It is
+safest to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least the
+&quot;copyright&quot; line and a pointer to where the full notice is found.
+
+    &lt;one line to give the library's name and a brief idea of what it does.&gt;
+    Copyright (C) &lt;year&gt;  &lt;name of author&gt;
+
+    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
+
+Also add information on how to contact you by electronic and paper mail.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a &quot;copyright disclaimer&quot; for the library, if
+necessary.  Here is a sample; alter the names:
+
+  Yoyodyne, Inc., hereby disclaims all copyright interest in the
+  library `Frob' (a library for tweaking knobs) written by James Random Hacker.
+
+  &lt;signature of Ty Coon&gt;, 1 April 1990
+  Ty Coon, President of Vice
+
+That's all there is to it!
+</pre>
+
+  </body>
+</html>
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/docs/phing_guide/book/chapters/appendixes/AppendixB-CoreTasks.html
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/docs/phing_guide/book/chapters/appendixes/AppendixB-CoreTasks.html	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/docs/phing_guide/book/chapters/appendixes/AppendixB-CoreTasks.html	(revision 19)
@@ -0,0 +1,1870 @@
+<!--
+-File         $Id: AppendixB-CoreTasks.html 360 2008-03-08 09:19:59Z mrook $
+-License      GNU FDL (http://www.gnu.org/copyleft/fdl.html)
+-Copyright    2002, turing
+-Author       alex black, enigma@turingstudio.com
+-->
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/2000/REC-xhtml1-20000126/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+	<title>Phing Guide - Core Tasks</title>
+	<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
+	<link rel="Stylesheet" rev="Stylesheet" href="../../css/Documentation.css" type="text/css" media="All" charset="iso-8859-1" />
+</head>
+<body>
+<h1><a name="AppendixB"></a>Appendix B: Core Tasks</h1>
+
+<p>
+This appendix contains a reference of all core tasks, i.e. all
+tasks that are needed to build a basic project. If you are
+looking for binarycloud related tasks, look in appendix ?.
+</p>
+
+<p> This reference lists the tasks alphabetically by the name of the classes that
+  implement the tasks. So if you are searching for the reference to the <code>&lt;copy&gt;</code>
+  tag, for example, you will want to look at the reference of CopyTask. </p>
+<h2><a name="AdhocTaskdefTask"></a>AdhocTaskdefTask</h2>
+<p> The AdhocTaskdefTask allows you to define a task within your build file.</p>
+<pre title="Example of how to use AdhocTaskdefTask">&lt;target name=&quot;main&quot;<br />        description=&quot;==&gt;test AdhocTask &quot;&gt;<br />		<br />		&lt;adhoc-task name=&quot;foo&quot;&gt;&lt;![CDATA[<br />			class FooTest extends Task {<br />				private $bar;<br />				<br />				function setBar($bar) {<br />					$this-&gt;bar = $bar;<br />				}<br />				<br />				function main() {<br />					$this-&gt;log(&quot;In FooTest: &quot; . $this-&gt;bar);<br />				}<br />			}<br />		]]&gt;&lt;/adhoc-task&gt;<br />	<br />		&lt;foo bar=&quot;B.L.I.N.G&quot;/&gt;<br />&lt;/target&gt;</pre>
+<p> Note that you should use &lt;![CDATA[ ... ]]&gt; so that you don't have to
+  quote entities within your<em> &lt;adhoc-task&gt;&lt;/adhoc-task&gt;</em> tags.</p>
+<h3>Parameters</h3>
+<table>
+  <thead>
+    <tr>
+      <th>Name</th>
+      <th>Type</th>
+      <th>Description</th>
+      <th>Default</th>
+      <th>Required</th>
+    </tr>
+  </thead>
+  <tbody>
+    <tr>
+      <td>name</td>
+      <td>String</td>
+      <td> Name of XML tag that will represent this task.</td>
+      <td>n/a</td>
+      <td>Yes</td>
+    </tr>
+  </tbody>
+</table>
+<h2><a name="AdhocTypedefTask"></a>AdhocTypedefTask</h2>
+<p> The AdhocTypedefTask allows you to define a datatype within your build file.</p>
+<pre title="Example of how to use AdhocTypedefTask">&lt;target name=&quot;main&quot;<br />        description=&quot;==&gt;test AdhocType&quot;&gt;<br />		<br />		&lt;adhoc-type name=&quot;dsn&quot;&gt;&lt;![CDATA[<br />			class CreoleDSN extends DataType {<br />				private $url;<br />				<br />				function setUrl($url) {<br />					$this-&gt;url = $url;<br />				}<br />				<br />				function getUrl() {
+  				return $this-&gt;url;
+				}				<br />			}<br />		]]&gt;&lt;/adhoc-type&gt;<br />
+     &lt;!-- creole-sql task doesn't exist; just an example --&gt;
+     &lt;creole-sql file=&quot;test.sql&quot;&gt;
+       &lt;dsn url=&quot;mysql://root@localhost/test&quot;/&gt;
+		&lt;/creole-sql&gt;<br /><br />&lt;/target&gt;</pre>
+<p> Note that you should use &lt;![CDATA[ ... ]]&gt; so that you don't have to
+  quote entities within your<em> &lt;adhoc-type&gt;&lt;/adhoc-type&gt;</em> tags.</p>
+<h3>Parameters</h3>
+<table>
+  <thead>
+    <tr>
+      <th>Name</th>
+      <th>Type</th>
+      <th>Description</th>
+      <th>Default</th>
+      <th>Required</th>
+    </tr>
+  </thead>
+  <tbody>
+    <tr>
+      <td>name</td>
+      <td>String</td>
+      <td> Name of XML tag that will represent this datatype..</td>
+      <td>n/a</td>
+      <td>Yes</td>
+    </tr>
+  </tbody>
+</table>
+<h2><a name="AppendTask"></a>AppendTask</h2>
+<p> The Append Task appends text or contents of files to a specified file. </p>
+<pre title="Example of how to use AppendTask">
+&lt;append destFile=&quot;${process.outputfile}&quot;&gt;
+  &lt;filterchain&gt;
+    &lt;xsltfilter style=&quot;${process.stylesheet}&quot;&gt;
+	     &lt;param name=&quot;mode&quot; expression=&quot;${process.xslt.mode}&quot;/&gt;
+    &lt;/xsltfilter&gt;
+  &lt;/filterchain&gt;
+  &lt;filelist dir=&quot;book/&quot; listfile=&quot;book/PhingGuide.book&quot;/&gt;
+&lt;/append&gt;</pre>
+<p> In the example above, AppendTask is reading a filename from <em>book/PhingGuide.book</em>,
+  processing the file contents with XSLT, and then appending the result to the
+  file located at <em>${process.outputfile}</em>. This is a real example from
+  the build file used to generate this book! </p>
+<h3>Parameters</h3>
+<table>
+  <thead>
+    <tr>
+      <th>Name</th>
+      <th>Type</th>
+      <th>Description</th>
+      <th>Default</th>
+      <th>Required</th>
+    </tr>
+  </thead>
+  <tbody>
+    <tr>
+      <td>destFile</td>
+      <td>File</td>
+      <td>Path of file to which text should be appended.</td>
+      <td>n/a</td>
+      <td>Yes</td>
+    </tr>
+    <tr>
+      <td>file</td>
+      <td>File</td>
+      <td>Path to file that should be appended to destFile.</td>
+      <td>n/a</td>
+      <td>No</td>
+    </tr>
+	<tr>
+      <td>text</td>
+      <td>String</td>
+      <td> Some literal text to append to file.</td>
+      <td>n/a</td>
+      <td>No</td>
+    </tr>
+  </tbody>
+</table>
+<h3>Supported Nested Tags</h3>
+<ul>
+  <li>FileList</li>
+  <li>FileSet</li>
+  <li>FilterChain</li>
+</ul>
+
+
+<h2><a name="AvailableTask"></a>AvailableTask</h2>
+
+<p>
+Available Task tests if a resource/file is set and sets a certain
+property to a certain value if it exists.
+</p>
+<pre title="Example of how to use AvailableTask">
+&lt;available file=&quot;/tmp/test.txt&quot; property=&quot;test_txt_exists&quot; value=&quot;Yes&quot;/&gt;
+
+&lt;available file=&quot;/home/foo&quot; type=&quot;dir&quot; property=&quot;properties.yetanother&quot; /&gt;
+
+&lt;available file=&quot;/home/foo/bar&quot; property=&quot;foo.bar&quot; value=&quot;Well, yes&quot; /&gt;
+</pre>
+<p>
+Here, <em>AvailableTask</em> first checks for the existance of either
+file or directory named <em>test.txt</em> in <em>/tmp</em>. Then, it
+checks for the directory <em>foo</em> in <em>/home</em> and then
+for the file or directory <em>bar</em> in <em>/home/foo</em>.
+If <em>/tmp/test.txt</em> is found, the property <em>test_txt_exists</em>
+is set to <em>&quot;Yes&quot;</em>, if <em>/home/foo</em> is found
+and a directory, <em>properties.yetanother</em> is set to
+<em>&quot;true&quot;</em> (default). If <em>/home/foo/bar</em> exists,
+<em>AvailableTask</em> will set <em>foo.bar</em> to <em>&quot;Well, yes&quot;</em>.
+</p>
+<h3>Parameters</h3>
+<table>
+  <thead>
+    <tr>
+      <th>Name</th>
+      <th>Type</th>
+      <th>Description</th>
+      <th>Default</th>
+      <th>Required</th>
+    </tr>
+  </thead>
+  <tbody>
+    <tr>
+      <td>property</td>
+      <td>string</td>
+      <td>
+        Name of the property that is to be set.
+      </td>
+      <td>n/a</td>
+      <td>Yes</td>
+    </tr>
+    <tr>
+      <td>value</td>
+      <td>String</td>
+      <td>
+        The value the property is to be set to.
+      </td>
+      <td><em>&quot;true&quot;</em></td>
+      <td>No</td>
+    </tr>
+    <tr>
+      <td>file</td>
+      <td>String</td>
+      <td>
+        File/directory to check existence.
+      </td>
+      <td>n/a</td>
+      <td>Yes (or <em>resource</em>)</td>
+    </tr>
+    <tr>
+      <td>resource</td>
+      <td>String</td>
+      <td>
+        Path of the resource to look for.
+      </td>
+      <td>n/a</td>
+      <td>Yes (or <em>file</em>)</td>
+    </tr>
+    <tr>
+      <td>type</td>
+      <td>String (file|dir)</td>
+      <td>
+        Determines if <em>AvailableTask</em> should look for a
+        file or a directory at the position set by <em>file</em>.
+        If empty, it checks for either file or directory.
+      </td>
+      <td>n/a</td>
+      <td>No</td>
+    </tr>
+  </tbody>
+</table>
+
+<h2><a name="PhingCallTask"></a>PhingCallTask</h2>
+<p> The PhingCallTask calls a target from the same Phing project. A <em>&lt;phingcall&gt;</em>
+  tag may contain <em>&lt;property&gt;</em> tags that define new properties. In
+  the following example, the properties <em>property1</em> and <em>foo</em> are
+  defined and only accessible inside the called target. </p>
+<p>
+  However, this will only work if the properties are not yet
+  set outside the <code>&quot;phingcall&quot;</code> tag.
+</p>
+<h3>Example</h3>
+<pre>&lt;target name=&quot;foo&quot;&gt;
+    &lt;phingcall target=&quot;bar&quot;&gt;
+        &lt;property name=&quot;property1&quot; value=&quot;aaaaa&quot; /&gt;
+        &lt;property name=&quot;foo&quot; value=&quot;baz&quot; /&gt;
+    &lt;/phingcall&gt;
+&lt;/target&gt;
+
+&lt;target name=&quot;bar&quot; depends=&quot;init&quot;&gt;
+    &lt;echo message=&quot;prop is ${property1} ${foo}&quot; /&gt;
+&lt;/target&gt;</pre>
+<h3>Parameters</h3>
+<table>
+  <thead>
+    <tr>
+      <th>Name</th>
+      <th>Type/Values</th>
+      <th>Description</th>
+      <th>Default</th>
+      <th>Required</th>
+    </tr>
+  </thead>
+  <tbody>
+    <tr>
+      <td>target</td>
+      <td>string</td>
+      <td>
+        The name of the target in the same project that is
+        to be called.
+      </td>
+      <td>n/a</td>
+      <td>Yes</td>
+    </tr>
+    <!-- Not used yet. TODO: Document if it is
+    <tr>
+      <td>inheritAll</td>
+      <td>Boolean</td>
+      <td>
+        If true, all
+      </td>
+      <td>true</td>
+      <td>No</td>
+    </tr>
+    <tr>
+      <td>inheritRefs</td>
+      <td>Boolean</td>
+      <td>
+      </td>
+      <td>false</td>
+      <td>No</td>
+    </tr>
+    -->
+  </tbody>
+</table>
+
+<!-- TODO: write and document
+<h2><a name="ConditionTask"></a>ConditionTask</h2>
+<p>
+  The condition system is not yet documented.
+</p>
+-->
+
+<h2><a name="ConditionTask"></a>ConditionTask</h2>
+<p>Sets a property if a certain condition holds true - this is a
+	generalization of <a href="#AvailableTask">Available</a> and
+	<a href="#UpToDateTask">UpToDate</a>.</p>
+<p>If the condition holds true, the property value is set to true by
+	default; otherwise, the property is not set. You can set the value to
+	something other than the default by specifying the <code>value</code>
+	attribute.</p>
+<p>Conditions are specified as nested elements, you must specify exactly
+	one condition - see the <a href="../ProjectComponents.html#Conditions">documentation</a>
+	for a complete list of nested elements.</p>
+<h3>Example</h3>
+<pre>
+&lt;condition property="isMacOrWindows"&gt;
+    &lt;or&gt;
+      &lt;os family="mac"/&gt;
+      &lt;os family="windows"/&gt;
+    &lt;/or&gt;
+  &lt;/condition&gt;
+</pre>
+<h3>Attributes</h3>
+<table>
+  <thead>
+    <tr>
+      <th>Name</th>
+      <th>Type</th>
+      <th>Description</th>
+      <th>Default</th>
+      <th>Required</th>
+    </tr>
+  </thead>
+  <tbody>
+    <tr>
+      <td>property</td>
+      <td>String</td>
+      <td>The name of the property to set.</td>
+      <td>n/a</td>
+      <td>Yes</td>
+    </tr>
+    <tr>
+      <td>value</td>
+      <td>String</td>
+      <td>The value to set the property to. Defaults to "true".</td>
+      <td>true</td>
+      <td>No</td>
+    </tr>
+  </tbody>
+</table>
+
+<h2><a name="CopyTask"></a>CopyTask</h2>
+<p>
+  The phing Copy Task.  Copies a file or directory to a new file
+  or directory.  Files are only copied if the source file is newer
+  than the destination file, or when the destination file does not
+  exist. It is possible to explictly overwrite existing files.
+</p>
+<h3>Example</h3>
+<p>
+On the one hand, CopyTask can be used to copy file by file:
+</p>
+<pre>
+&lt;copy file=&quot;somefile.txt&quot; tofile=&quot;/tmp/anotherfile.bak&quot; overwrite=&quot;true&quot;/&gt;
+</pre>
+<p>
+Additionally, <em>CopyTask</em> supports Filesets, i.e. you can
+easily include/exclude one or more files. For more information,
+see <a href="AppendixD-CoreTypes.html#Fileset">Appendix D</a>.
+Mappers and Filterchains are also supported by <em>CopyTask</em>,
+so you can do almost everything that needs processing the content
+of the files or the filename.
+</p>
+<p>
+<em>Notice:</em> <em>CopyTask</em> does not allow self copying,
+i.e. copying a file to the same name for security reasons.
+</p>
+<pre>
+&lt;copy todir=&quot;/tmp/backup&quot; &gt;
+  &lt;fileset dir=&quot;.&quot;&gt;
+    &lt;include name=&quot;**/*.txt&quot; /&gt;
+    &lt;include name=&quot;**/*.doc&quot; /&gt;
+    &lt;include name=&quot;**/*.swx&quot; /&gt;
+  &lt;/fileset&gt;
+&lt;/copy&gt;
+</pre>
+<h3>Attributes</h3>
+<table>
+  <thead>
+    <tr>
+      <th>Name</th>
+      <th>Type</th>
+      <th>Description</th>
+      <th>Default</th>
+      <th>Required</th>
+    </tr>
+  </thead>
+  <tbody>
+    <tr>
+      <td>file</td>
+      <td>String</td>
+      <td>
+        The source file.
+      </td>
+      <td>Yes</td>
+    </tr>
+     <tr>
+      <td>tofile</td>
+      <td>String</td>
+      <td>
+        <p>
+          The destination the file is to be written to. <em>tofile</em>
+          specifies a <em>full</em> filename. If you only want to specify
+          a directory to copy to, use <em>todir</em>.
+        </p>
+        <p>
+          Either this or the <em>todir</em> attribute is required.
+        </p>
+      </td>
+      <td>n/a</td>
+      <td>Yes (or <em>todir</em>)</td>
+    </tr>
+    <tr>
+      <td>todir</td>
+      <td>String</td>
+      <td>
+        The directory the file is to be copied to. The file will have the
+        same name of the source file. If you want to specify a different
+        name, use <em>tofile</em>.
+      </td>
+      <td>n/a</td>
+      <td>Yes (or <em>tofile</em>)</td>
+    </tr>
+    <tr>
+      <td>overwrite</td>
+      <td>Boolean</td>
+      <td>
+        If set to true, the target file will be overwritten.
+      </td>
+      <td>false</td>
+      <td>No</td>
+    </tr>
+    <tr>
+      <td>tstamp</td>
+      <td>Boolean</td>
+      <td>
+        If set to <em>true</em>, the new file will have the same mtime
+        as the old one.
+      </td>
+      <td>true</td>
+      <td>No</td>
+    </tr>
+     <tr>
+      <td>includeemptydirs</td>
+      <td>Boolean</td>
+      <td>
+        If set to <em>true</em>, also empty directories are copied.
+      </td>
+      <td>true</td>
+      <td>No</td>
+    </tr>
+  </tbody>
+</table>
+<h3>Supported Nested Tags</h3>
+<ul>
+  <li>Fileset</li>
+  <li>Filterchain</li>
+  <li>Mapper</li>
+</ul>
+
+
+<h2><a name="DeleteTask"></a> DeleteTask</h2>
+<p>
+Deletes a file or directory, or set of files defined by a fileset.
+See <a href="AppendixD-CoreTypes.html#Fileset">Appendix D</a>
+for information on Filesets.
+</p>
+<h3>Example</h3>
+<pre>&lt;-- Delete a specific file --&gt;
+&lt;delete file=&quot;/tmp/foo.bar&quot; /&gt;
+
+&lt;-- Delete a directory --&gt;
+&lt;delete dir=&quot;/tmp/darl&quot; includeemptydirs=&quot;true&quot; verbose=&quot;true&quot; failonerror=&quot;true&quot; /&gt;
+
+&lt;-- Delete using a fileset --&gt;
+&lt;delete&gt;
+  &lt;fileset dir=&quot;/tmp&quot;&gt;
+    &lt;include name=&quot;*.bar&quot; /&gt;
+  &lt;/fileset&gt;
+&lt;/delete&gt;
+</pre>
+<h3>Attributes</h3>
+<table>
+  <thead>
+    <tr>
+      <th>Name</th>
+      <th>Type</th>
+      <th>Description</th>
+      <th>Default</th>
+      <th>Required</th>
+    </tr>
+  </thead>
+  <tbody>
+    <tr>
+      <td>file</td>
+      <td>String</td>
+      <td>
+        The file that is to be deleted. You either have to specify
+	this attribute, <em>dir</em>, or use a fileset.
+      </td>
+      <td>n/a</td>
+      <td>Yes</td>
+    </tr>
+    <tr>
+      <td>dir</td>
+      <td>String</td>
+      <td>
+        The directory that is to be deleted. You either have to specify
+        this attribute, <em>file</em>, or use a fileset.
+      </td>
+      <td>n/a</td>
+      <td>Yes (or <em>file</em>)</td>
+    </tr>
+    <tr>
+      <td>verbose</td>
+      <td>Boolean</td>
+      <td>
+        Used to force listing of all names of deleted files.
+      </td>
+      <td>n/a</td>
+      <td>Yes</td>
+    </tr>
+    <tr>
+      <td>quiet</td>
+      <td>Boolean</td>
+      <td>
+        <p>
+          If the file does not exist, do not display a diagnostic
+          message or modify the exit status to reflect an error.
+          This means that if a file or directory cannot be deleted,
+          then no error is reported.
+        </p>
+        <p>
+          This setting emulates the -f option to the Unix <em>rm</em>
+          command. Default is false meaning things are verbose
+        </p>
+       </td>
+      <td>n/a</td>
+      <td>Yes</td>
+    </tr>
+    <tr>
+      <td>failonerror</td>
+      <td>Boolean</td>
+      <td>
+        If this attribute is set to <em>true</em>, DeleteTask will
+        verbose on errors but the build process will not be
+        stopped.
+      </td>
+      <td>true</td>
+      <td>Yes</td>
+    </tr>
+    <tr>
+      <td>includeemptydirs</td>
+      <td>Boolean</td>
+      <td>
+        Determines if empty directories are also to be deleted.
+      </td>
+      <td>false</td>
+      <td>False</td>
+    </tr>
+  </tbody>
+</table>
+<h3>Supported Nested Tags</h3>
+<ul>
+  <li>Fileset</li>
+</ul>
+
+<h2><a name="EchoTask"></a>EchoTask</h2>
+<p>
+Echoes a message to the current loggers and listeners which means standard out unless overridden.
+A level can be specified, which controls at what logging level the message is filtered at. </p>
+
+<p>
+The task can also echo to a file, in which case the option to append rather than overwrite the file is available, and the level option is ignored
+</p>
+<h3>Examples</h3>
+<pre>&lt;echo msg=&quot;Phing rocks!&quot; /&gt;
+
+&lt;echo message=&quot;Binarycloud, too.&quot; /&gt;
+
+&lt;echo&gt;And don't forget Propel.&lt;/echo&gt;
+
+&lt;echo file="test.txt" append="false"&gt;This is a test message&lt;/echo&gt;</pre>
+<h3>Attributes</h3>
+<table>
+  <thead>
+    <tr>
+      <th>Name</th>
+      <th>Type</th>
+      <th>Description</th>
+      <th>Default</th>
+      <th>Required</th>
+    </tr>
+  </thead>
+  <tbody>
+    <tr>
+      <td>msg</td>
+      <td>String</td>
+      <td>
+        The string that is to be send to the output.
+      </td>
+      <td>n/a</td>
+      <td>Yes</td>
+    </tr>
+     <tr>
+      <td>message</td>
+      <td>String</td>
+      <td>
+        Alias for <em>msg</em>.
+      </td>
+      <td>n/a</td>
+      <td>Yes</td>
+    </tr>
+     <tr>
+      <td>file</td>
+      <td>String</td>
+      <td>The file to write the message to.
+      </td>
+      <td>n/a</td>
+      <td>No</td>
+    </tr>
+     <tr>
+      <td>append</td>
+      <td>Boolean</td>
+      <td>Append to an existing file?
+      </td>
+      <td>false</td>
+      <td>No</td>
+    </tr>
+     <tr>
+      <td>level</td>
+      <td>String</td>
+      <td>Control the level at which this message is reported. One of <em>error</em>, <em>warning</em>, <em>info</em>, <em>verbose</em>, <em>debug</em>.
+      </td>
+      <td><em>warning</em></td>
+      <td>No</td>
+    </tr>
+  </tbody>
+</table>
+
+<h2><a name="ExecTask"></a>ExecTask</h2>
+<p>
+  Executes a shell command. You can use this to quickly add a
+  new command to Phing. However, if you want to use this
+  regularly, you should think about writing a Task for it.
+</p>
+<h3>Example</h3>
+<pre>&lt;-- List the contents of &quot;/home&quot;. --&gt;
+&lt;exec command=&quot;ls -l&quot; dir=&quot;/home&quot; /&gt;
+
+&lt;-- Start the make process in &quot;/usr/src/php-4.0&quot;. --&gt;
+&lt;exec command=&quot;make&quot; dir=&quot;/usr/src/php-4.0&quot; /&gt;
+
+&lt;-- List the contents of &quot;/tmp&quot; out to a file. --&gt;
+&lt;exec command=&quot;ls -l /tmp &gt; foo.out&quot; escape=&quot;false&quot; /&gt;
+</pre>
+<h3>Attributes</h3>
+<table>
+  <thead>
+    <tr>
+      <th>Name</th>
+      <th>Type</th>
+      <th>Description</th>
+      <th>Default</th>
+      <th>Required</th>
+    </tr>
+  </thead>
+  <tbody>
+    <tr>
+      <td>command</td>
+      <td>String</td>
+      <td> The command that is to be executed. </td>
+      <td>n/a</td>
+      <td>Yes</td>
+    </tr>
+    <tr>
+      <td>dir</td>
+      <td>String</td>
+      <td> The directory the command is to be executed in. </td>
+      <td>n/a</td>
+      <td>No</td>
+    </tr>
+    <tr>
+      <td>os</td>
+      <td>String</td>
+      <td> Only execute if os.name contains specified text.</td>
+      <td>n/a</td>
+      <td>No</td>
+    </tr>
+    <tr>
+      <td>escape</td>
+      <td>Boolean</td>
+      <td> By default, we escape shell metacharacters before executing. Setting
+        this to false will disable this precaution. </td>
+      <td>TRUE</td>
+      <td>No</td>
+    </tr>
+    <tr>
+      <td>passthru</td>
+      <td>Boolean</td>
+      <td> Wether to passthru the output.</td>
+      <td>FALSE</td>
+      <td>No</td>
+    </tr>
+    <tr>
+      <td>spawn</td>
+      <td>Boolean</td>
+      <td> Wether to spawn unix programs to the background, redirecting stdout.</td>
+      <td>FALSE</td>
+      <td>No</td>
+    </tr>
+    <tr>
+      <td>returnProperty</td>
+      <td>String</td>
+      <td>Property name to set return value to from exec() call.</td>
+      <td>n/a</td>
+      <td>No</td>
+    </tr>
+    <tr>
+      <td>checkreturn</td>
+      <td>Boolean</td>
+      <td> Wether to check the return code of the program, throws a
+	BuildException when returncode != 0.</td>
+      <td>FALSE</td>
+      <td>No</td>
+    </tr>
+  </tbody>
+</table>
+
+<h2><a name="ExitTask"></a>ExitTask</h2>
+<p>
+Causes the current build script execution to fail and the script to exit with an (optional) error message.
+</p>
+<h3>Example</h3>
+<pre>&lt;-- Exit w/ message --&gt;
+&lt;fail message=&quot;Failed for some reason!&quot; /&gt;
+
+&lt;--  Exit if ${errorprop} is defined --&gt;
+&lt;fail if=&quot;errorprop&quot; message=&quot;Detected error!&quot; /&gt;
+
+&lt;-- Exit unless ${dontfail} prop is defined. --&gt;
+&lt;fail unless=&quot;dontfail&quot; message=&quot;Detected error!&quot; /&gt;
+
+</pre>
+<h3>Attributes</h3>
+<table>
+  <thead>
+    <tr>
+      <th>Name</th>
+      <th>Type</th>
+      <th>Description</th>
+      <th>Default</th>
+      <th>Required</th>
+    </tr>
+  </thead>
+  <tbody>
+    <tr>
+      <td>message</td>
+      <td>String</td>
+      <td> The message to display (reason for script abort). </td>
+      <td>&quot;No Message&quot;</td>
+      <td>No</td>
+    </tr>
+    <tr>
+      <td>if</td>
+      <td>String</td>
+      <td>Name of property that must be set for script to exit.</td>
+      <td>n/a</td>
+      <td>No</td>
+    </tr>
+    <tr>
+      <td>unless</td>
+      <td>String</td>
+      <td> Name of property that must <em>not</em> be set in order for script to exit.</td>
+      <td>n/a</td>
+      <td>No</td>
+    </tr>
+  </tbody>
+</table>
+
+<h2><a name="ForeachTask"></a>ForeachTask</h2>
+<p>The foreach task iterates over a list, a list of paths, or both. If both, list
+  and paths, are specified, the list will be evaluated first. Nested paths are
+  evaluated in the order they appear in the task.</p>
+<h3>Example</h3>
+<pre>
+&lt;!-- loop through languages, and call buildlang task with setted param --&gt;
+&lt;property name="languages" value="en,fr,de" /&gt;
+&lt;foreach list="${languages}" param="lang" target="buildlang" /&gt;
+</pre>
+<h3>Attributes</h3>
+<table>
+  <thead>
+    <tr>
+      <th>Name</th>
+      <th>Type</th>
+      <th>Description</th>
+      <th>Default</th>
+      <th>Required</th>
+    </tr>
+  </thead>
+  <tbody>
+    <tr>
+      <td>list</td>
+      <td>string</td>
+      <td>The list of values to process, with the delimiter character, indicated
+        by the "delimiter" attribute, separating each value.</td>
+      <td>n/a</td>
+      <td>Yes</td>
+    </tr>
+    <tr>
+      <td>target</td>
+      <td>string</td>
+      <td>The target to call for each token, passing the token as the parameter
+        with the name indicated by the "param" attribute.</td>
+      <td>n/a</td>
+      <td>Yes</td>
+    </tr>
+    <tr>
+      <td>param</td>
+      <td>string</td>
+      <td>The name of the parameter to pass the tokens in as to the target.</td>
+      <td>n/a</td>
+      <td>Yes</td>
+    </tr>
+    <tr>
+      <td>delimiter</td>
+      <td>string</td>
+      <td>The delimiter string that separates the values in the "list" parameter.
+        The default is ",".</td>
+      <td>,</td>
+      <td>No</td>
+    </tr>
+  </tbody>
+</table>
+
+<h2><a name="IfTask"></a>IfTask</h2>
+<p>Perform some tasks based on whether a given condition holds true or not.</p>
+<h3>Attributes</h3>
+<p>
+This task doesn't have any attributes, the condition to test is specified by a nested
+	element - see the <a href="../ProjectComponents.html#Conditions">documentation</a>
+	for a complete list of nested elements.</p>
+<p>Just like the <code>&lt;condition&gt;</code> task, only a
+    single condition can be specified - you combine them using
+    <code>&lt;and&gt;</code> or <code>&lt;or&gt;</code>
+    conditions.</p>
+<p>In addition to the condition, you can specify three different
+    child elements, <code>&lt;elseif&gt;</code>, <code>&lt;then&gt;</code> and
+    <code>&lt;else&gt;</code>.  All three subelements are optional.
+
+    Both <code>&lt;then&gt;</code> and <code>&lt;else&gt;</code> must not be
+    used more than once inside the if task. Both are
+    containers for Phing tasks.</p>
+
+<p>The <code>&lt;elseif&gt;</code> behaves exactly like an <code>&lt;if&gt;</code>
+    except that it cannot contain the <code>&lt;else&gt;</code> element
+    inside of it.  You may specify as may of these as you like, and the
+    order they are specified is the order they are evaluated in.  If the
+    condition on the <code>&lt;if&gt;</code> is false, then the first
+    <code>&lt;elseif&gt;</code> who's conditional evaluates to true
+    will be executed.  The <code>&lt;else&gt;</code> will be executed
+    only if the <code>&lt;if&gt;</code> and all <code>&lt;elseif&gt;</code>
+    conditions are false.</p>
+<h3>Example</h3>
+<pre>
+&lt;if&gt;
+ &lt;equals arg1="${foo}" arg2="bar" /&gt;
+ &lt;then&gt;
+   &lt;echo message="The value of property foo is bar" /&gt;
+ &lt;/then&gt;
+ &lt;else&gt;
+   &lt;echo message="The value of property foo is not bar" /&gt;
+ &lt;/else&gt;
+&lt;/if&gt;
+</pre>
+
+<pre>
+&lt;if&gt;
+ &lt;equals arg1="${foo}" arg2="bar" /&gt;
+ &lt;then&gt;
+   &lt;echo message="The value of property foo is 'bar'" /&gt;
+ &lt;/then&gt;
+
+ &lt;elseif&gt;
+  &lt;equals arg1="${foo}" arg2="foo" /&gt;
+  &lt;then&gt;
+   &lt;echo message="The value of property foo is 'foo'" /&gt;
+  &lt;/then&gt;
+ &lt;/elseif&gt;
+
+ &lt;else&gt;
+   &lt;echo message="The value of property foo is not 'foo' or 'bar'" /&gt;
+ &lt;/else&gt;
+&lt;/if&gt;
+</pre>
+
+<h2><a name="IncludePathTask"></a>IncludePathTask</h2>
+<p>Sets the PHP include_path configuration option for the duration of this phing run.</p>
+<h3>Example</h3>
+<pre>&lt;includepath classpath=&quot;new/path/here&quot; /&gt;
+&lt;includepath classpath=&quot;path1:path2&quot; /&gt;</pre>
+<h3>Attributes</h3>
+<table>
+  <thead>
+    <tr>
+      <th>Name</th>
+      <th>Type</th>
+      <th>Description</th>
+      <th>Default</th>
+      <th>Required</th>
+    </tr>
+  </thead>
+  <tbody>
+    <tr>
+      <td>classpath</td>
+      <td>String</td>
+      <td>the new include path[s]</td>
+      <td>n/a</td>
+      <td>Yes</td>
+    </tr>
+  </tbody>
+</table>
+
+<h2><a name="InputTask"></a>InputTask</h2>
+<p>The <em>InputTask</em> can be used to interactively set property values based
+  on input from the console (or other Reader).</p>
+<h3>Example</h3>
+<pre>
+&lt;!-- Getting string input --&gt;
+&lt;echo&gt;HTML pages installing to: ${documentRoot}&lt;/echo&gt;
+&lt;echo&gt;PHP classes installing to: ${servletDirectory}&lt;/echo&gt;
+
+&lt;input propertyname=&quot;documentRoot&quot;&gt;Web application document root&lt;/input&gt;
+&lt;input propertyname=&quot;servletDirectory&quot;
+  defaultValue=&quot;/usr/servlets&quot; promptChar=&quot;?&quot;&gt;PHP classes install dir&lt;/input&gt;
+
+&lt;echo&gt;HTML pages installed to ${documentRoot}&lt;/echo&gt;
+&lt;echo&gt;PHP classes installed to ${servletDirectory}&lt;/echo&gt;
+
+&lt;!-- Having the user choose from a set of valid choices --&gt;
+&lt;echo&gt;Choose a valid option:&lt;/echo&gt;
+
+&lt;input propertyname=&quot;optionsChoice&quot; validargs=&quot;foo,bar,bob&quot;&gt;
+  Which item would you like to use
+&lt;/input&gt;
+</pre>
+<h3>Attributes</h3>
+<table>
+  <thead>
+    <tr>
+      <th>Name</th>
+      <th>Type</th>
+      <th>Description</th>
+      <th>Default</th>
+      <th>Required</th>
+    </tr>
+  </thead>
+  <tbody>
+    <tr>
+      <td>propertyName</td>
+      <td>String</td>
+      <td>The name of the property to set.</td>
+      <td>n/a</td>
+      <td>Yes</td>
+    </tr>
+    <tr>
+      <td>defaultValue</td>
+      <td>String</td>
+      <td>The default value to be set if no new value is provided.</td>
+      <td>n/a</td>
+      <td>Yes</td>
+    </tr>
+    <tr>
+      <td height="20">message</td>
+      <td>String</td>
+      <td> Prompt text (same as CDATA).</td>
+      <td>n/a</td>
+      <td>No</td>
+    </tr>
+    <tr>
+      <td>promptChar</td>
+      <td>String</td>
+      <td> The prompt character to follow prompt text.</td>
+      <td>n/a</td>
+      <td>No</td>
+    </tr>
+    <tr>
+      <td>validArgs</td>
+      <td>String</td>
+      <td>Comma-separated list of valid choices the user must supply. If used, one of these options must be chosen.</td>
+      <td>n/a</td>
+      <td>No</td>
+    </tr>
+    <!-- TODO : Add "os" as soon as it is supported -->
+  </tbody>
+</table>
+<h2><a name="MkdirTask"></a>MkdirTask</h2>
+<p>
+  Create a directory.
+</p>
+<h3>Example</h3>
+<pre>&lt;-- Create a temp directory --&gt;
+&lt;mkdir dir=&quot;/tmp/foo&quot; /&gt;
+
+&lt;-- Using mkdir with a property --&gt;
+&lt;mkdir dir=&quot;${dirs.install}/tmp&quot; /&gt;
+</pre>
+<h3>Attributes</h3>
+<table>
+  <thead>
+    <tr>
+      <th>Name</th>
+      <th>Type</th>
+      <th>Description</th>
+      <th>Default</th>
+      <th>Required</th>
+    </tr>
+  </thead>
+  <tbody>
+    <tr>
+      <td>dir</td>
+      <td>String</td>
+      <td>
+        The directory that is to be created.
+      </td>
+      <td>n/a</td>
+      <td>Yes</td>
+    </tr>
+  </tbody>
+</table>
+
+<h2><a name="MoveTask"></a>MoveTask</h2>
+<p>
+  Moves a file or directory to a new file or directory.
+  By default, the destination file is overwritten if it
+  already exists.  When overwrite is turned off, then files
+  are only moved if the source file is newer than the
+  destination file, or when the destination file does not
+  exist.
+</p>
+<p>
+  Source files and directories are only deleted if the file or
+  directory has been copied to the destination successfully.
+</p>
+<h3>Example</h3>
+<pre>&lt;-- The following will move the file &quot;somefile.txt&quot; to &quot;/tmp&quot; and
+    change its filename to &quot;anotherfile.bak&quot;. It will overwrite
+    an existing file. --&gt;
+&lt;move file=&quot;somefile.txt&quot; tofile=&quot;/tmp/anotherfile.bak&quot; overwrite=&quot;true&quot;/&gt;
+
+&lt;-- This will move the &quot;/tmp&quot; directory to &quot;/home/default/tmp&quot;,
+    preserving the directory name. So the final name is
+    &quot;/home/default/tmp/tmp&quot;. Empty directories are also copied --&gt;
+&lt;move file=&quot;/tmp&quot; todir=&quot;/home/default/tmp&quot; includeemptydirs=&quot;true&quot; /&gt;
+</pre>
+<h3>Attributes and Nested Elements</h3>
+<p>
+  For further documentation, see <a href="#CopyTask">CopyTask</a>,
+  since MoveTask only is a child of CopyTask and inherits all attributes.
+</p>
+
+<h2><a name="PhingTask"></a>PhingTask</h2>
+<p>
+  This task calls another build file. You may specify the target that
+  is to be called within the build file. Additionally, the
+  <code>&lt;phing&gt;</code> Tag may contain <code>&lt;property&gt;</code>
+  Tags (see <a href="#PropertyTask">PropertyTask</a>).
+</p>
+<h3>Example</h3>
+<pre>&lt;-- Call target &quot;xslttest&quot; from buildfile &quot;alternativebuildfile.xml&quot; --&gt;
+ &lt;phing phingfile=&quot;alternativebuild.xml&quot; inheritRefs=&quot;true&quot; target=&quot;xslttest&quot; /&gt;
+
+&lt;-- Do a more complex call --&gt;
+&lt;phing phingfile=&quot;somebuild.xml&quot; target=&quot;sometarget&quot;&gt;
+  &lt;property name=&quot;foo&quot; value=&quot;bar&quot;&gt;
+  &lt;property name=&quot;anotherone&quot; value=&quot;32&quot;&gt;
+&lt;/phing&gt;
+</pre>
+<h3>Attributes</h3>
+<table>
+  <thead>
+    <tr>
+      <th>Name</th>
+      <th>Type</th>
+      <th>Description</th>
+      <th>Default</th>
+      <th>Required</th>
+    </tr>
+  </thead>
+  <tbody>
+    <tr>
+      <td>inheritAll</td>
+      <td>Boolean</td>
+      <td>
+        If true, pass all properties to the new phing project.
+      </td>
+      <td>true</td>
+      <td>No</td>
+    </tr>
+    <tr>
+      <td>inheritRefs</td>
+      <td>Boolean</td>
+      <td>
+        If true, pass all references to the new phing project.
+      </td>
+      <td>false</td>
+      <td>No</td>
+    </tr>
+    <tr>
+      <td>dir</td>
+      <td>String</td>
+      <td>
+         The directory to use as a base directory for the new phing project.
+         Default is the current project's basedir, unless inheritall
+         has been set to <em>false</em>, in which case it doesn't have a default
+         value. This will override the basedir setting of the called project.
+       </td>
+      <td>n/a</td>
+      <td>No</td>
+    </tr>
+    <tr>
+      <td>phingFile</td>
+      <td>String</td>
+      <td>
+        The build file to use.
+        Defaults to &quot;build.xml&quot;. This file is expected
+        to be a filename relative to the dir attribute given.
+      </td>
+      <td>n/a</td>
+      <td>Yes</td>
+    </tr>
+    <tr>
+      <td>target</td>
+      <td>String</td>
+      <td>
+        The target of the new Phing project to execute.
+        Default is the new project's default target.
+      </td>
+      <td>n/a</td>
+      <td>No</td>
+    </tr>
+    <tr>
+      <td>haltonfailure</td>
+      <td>Boolean</td>
+      <td>If true, fail the build process when the called build fails</td>
+      <td>false</td>
+      <td>No</td>
+    </tr>
+  </tbody>
+</table>
+
+<h3>Supported Nested Tags</h3>
+<ul>
+  <li>Fileset</li>
+</ul>
+
+<h3>Base directory of the new project</h3>
+<p>
+The base directory of the new project is set dependant on the
+<em>dir</em> and the <em>inheritAll</em> attribute. This is
+important to keep in mind or else you might run into bugs in
+your build.xml's. The following table shows when which value
+is used:
+</p>
+<table>
+  <tbody>
+    <tr>
+      <th><em>dir</em> attribute</th>
+      <th><em>inheritAll</em> attribute</th>
+      <th>new project's basedir</th>
+    </tr>
+    <tr>
+      <td>value provided</td>
+      <td>true</td>
+      <td>value of <em>dir</em> attribute</td>
+    </tr>
+    <tr>
+      <td>value provided</td>
+      <td>false</td>
+      <td>value of <em>dir</em> attribute</td>
+    </tr>
+    <tr>
+      <td>omitted</td>
+      <td>true</td>
+      <td>basedir of calling task (the build file containing
+          the <em>&lt;phing&gt;</em> call.</td>
+    </tr>
+    <tr>
+      <td>omitted</td>
+      <td>false</td>
+      <td>basedir attribute of the <em>&lt;project&gt;</em>
+          element of the new project</td>
+    </tr>
+  </tbody>
+</table>
+
+<h2><a name="PhpEvalTask"></a>PhpEvalTask</h2>
+<p>With the PhpEvalTask, you can set a property to the results
+of evaluating a PHP expression or the result returned by a function/method call.
+</p>
+<h3>Examples</h3>
+<pre>&lt;php function=&quot;crypt&quot; returnProperty=&quot;enc_passwd&quot;&gt;
+  &lt;param value=&quot;${auth.root_passwd}&quot;/&gt;
+&lt;/php&gt;</pre>
+<pre>&lt;php expression=&quot;3 + 4&quot; returnProperty=&quot;sum&quot;/&gt;</pre>
+<h3>Attributes</h3>
+<table>
+  <thead>
+    <tr>
+      <th>Name</th>
+      <th>Type</th>
+      <th>Description</th>
+      <th>Default</th>
+      <th>Required</th>
+    </tr>
+  </thead>
+  <tbody>
+    <tr>
+      <td>function</td>
+      <td>String</td>
+      <td> The name of the Property. </td>
+      <td>n/a</td>
+      <td rowspan="2">One of these is required.</td>
+    </tr>
+    <tr>
+      <td>expression</td>
+      <td>String</td>
+      <td> The expression to evaluate.</td>
+      <td>n/a</td>
+    </tr>
+    <tr>
+      <td>class</td>
+      <td>String</td>
+      <td> The static class which contains function.</td>
+      <td>n/a</td>
+      <td>No</td>
+    </tr>
+    <tr>
+      <td>returnProperty</td>
+      <td>String</td>
+      <td> The name of the property to set with result of expression or function
+        call.</td>
+      <td>n/a</td>
+      <td>No</td>
+    </tr>
+  </tbody>
+</table>
+<h3>Supported Nested Tags</h3>
+<ul>
+  <li>param</li>
+</ul>
+<h2><a name="PropertyTask"></a>PropertyTask</h2>
+<p>
+  With PropertyTask, you can define <em>user</em> properties
+  in your build file.
+</p>
+<h3>Example</h3>
+<pre>&lt;property name=&quot;strings.test&quot; value=&quot;Harr harr, more power!&quot; /&gt;
+&lt;echo message=&quot;${strings.test}&quot; /&gt;
+
+&lt;property name=&quot;foo.bar&quot; value=&quot;Yet another property...&quot; /&gt;
+&lt;echo message=&quot;${foo.bar}&quot; /&gt;
+
+&lt;property file=&quot;build.properties&quot;  /&gt;
+</pre>
+<h3>Attributes</h3>
+<table>
+  <thead>
+    <tr>
+      <th>Name</th>
+      <th>Type</th>
+      <th>Description</th>
+      <th>Default</th>
+      <th>Required</th>
+    </tr>
+  </thead>
+  <tbody>
+    <tr>
+      <td>name</td>
+      <td>String</td>
+      <td>
+        The name of the Property.
+      </td>
+      <td>n/a</td>
+      <td>Yes (unless using file)</td>
+    </tr>
+    <tr>
+      <td>value</td>
+      <td>String</td>
+      <td>
+        The value of the Property.
+      </td>
+      <td>n/a</td>
+      <td>Yes (unless using file)</td>
+    </tr>
+	<tr>
+	 <td>override</td>
+      <td>Boolean</td>
+      <td>
+        Whether to force override of existing value.
+      </td>
+      <td>false</td>
+      <td>No</td>
+	</tr>
+	<tr>
+		<td>file</td>
+		<td>String</td>
+		<td>Path to properties file.</td>
+		<td>n/a</td>
+		<td>No</td>
+	</tr>
+  </tbody>
+</table>
+
+<h2><a name="PropertyPromptTask"></a>PropertyPromptTask</h2>
+<p>
+  PropertyPromptTask is a simple task to read in user input into a property.
+  If you need something more advanced, see the <a href="#InputTask">InputTask</a>.
+</p>
+<h3>Example</h3>
+
+<pre>&lt;propertyprompt propertyName=&quot;someprop&quot; defaultValue=&quot;/var/www&quot;
+		promptText=&quot;Enter your web root&quot; /&gt;
+&lt;echo&gt;${someprop}&lt;/echo&gt;
+</pre>
+<h3>Attributes</h3>
+<table>
+  <thead>
+    <tr>
+      <th>Name</th>
+      <th>Type</th>
+      <th>Description</th>
+      <th>Default</th>
+      <th>Required</th>
+    </tr>
+  </thead>
+  <tbody>
+    <tr>
+      <td>propertyName</td>
+      <td>String</td>
+      <td>
+        The name of the Property to set.
+      </td>
+      <td>n/a</td>
+      <td>Yes</td>
+    </tr>
+    <tr>
+      <td>promptText</td>
+      <td>String</td>
+      <td>
+        The text to use for the prompt.
+      </td>
+      <td>n/a</td>
+      <td>Yes</td>
+    </tr>
+    <tr>
+      <td>promptCharacter</td>
+      <td>String</td>
+      <td>
+        The character to use after the prompt.
+      </td>
+      <td>?</td>
+      <td>No</td>
+    </tr>
+	<tr>
+	 <td>defaultValue</td>
+      <td>String</td>
+      <td>
+		A default value to use (if user just hits enter).
+      </td>
+      <td>n/a</td>
+      <td>No</td>
+	</tr>
+	<tr>
+		<td>useExistingValue</td>
+		<td>String</td>
+		<td>Whether existing property should be used if available. (This will
+			result in user only being prompted if the propertyName property is not already set.)</td>
+		<td>false</td>
+		<td>No</td>
+	</tr>
+  </tbody>
+</table>
+
+<h2><a name="ReflexiveTask"></a>ReflexiveTask</h2>
+<p>The ReflexiveTask performs operations on files. It is essentially a convenient
+  way to transform (using filter chains) files without copying them.</p>
+<h3>Example</h3>
+<pre>&lt;reflexive&gt;
+  &lt;fileset dir=&quot;.&quot;&gt;
+    &lt;include pattern=&quot;*.html&quot;&gt;
+  &lt;/fileset&gt;
+  &lt;filterchain&gt;
+    &lt;replaceregexp&gt;
+      &lt;regexp pattern=&quot;\r\n&quot; replace=&quot;\n&quot;/&gt;
+    &lt;/replaceregexp&gt;
+  &lt;/filterchain&gt;
+&lt;/reflexive&gt;</pre>
+<h3>Attributes</h3>
+<table>
+  <thead>
+    <tr>
+      <th>Name</th>
+      <th>Type</th>
+      <th>Description</th>
+      <th>Default</th>
+      <th>Required</th>
+    </tr>
+  </thead>
+  <tbody>
+    <tr>
+      <td>file</td>
+      <td>String</td>
+      <td> A single file to be processed.</td>
+      <td>n/a</td>
+      <td>Yes (unless &lt;fileset&gt; provided)</td>
+    </tr>
+  </tbody>
+</table>
+<h3>Supported Nested Tags:</h3>
+<ul>
+  <li>fileset</li>
+  <li>filterchain</li>
+</ul>
+<h2><a name="ResolvePathTask"></a>ResolvePathTask</h2>
+<p>The ResolvePathTask turns a relative path into an absolute path, with respect to
+specified directory or the project basedir (if no dir attribute specified).</p>
+<p>This task is useful for turning a user-defined relative path into an absolute
+  path in cases where buildfiles will be called in different directories. Without
+  this task, buildfiles lower in the directory tree would mis-interpret the user-defined
+  relative paths.</p>
+<h3>Example</h3>
+<pre>&lt;property name=&quot;relative_path&quot; value=&quot;./dirname&quot;/&gt;
+
+&lt;resolvepath propertyName=&quot;absolute_path&quot; file=&quot;${relative_path}&quot;/&gt;
+
+&lt;echo&gt;Resolved [absolute] path: ${absolute_path}&lt;/echo&gt;</pre>
+<h3>Attributes</h3>
+<table>
+  <thead>
+    <tr>
+      <th>Name</th>
+      <th>Type</th>
+      <th>Description</th>
+      <th>Default</th>
+      <th>Required</th>
+    </tr>
+    <tr>
+      <td>file</td>
+      <td>String</td>
+      <td> The file or directory path to resolve.</td>
+      <td>n/a</td>
+      <td>Yes</td>
+    </tr>
+    <tr>
+      <td>dir</td>
+      <td>File</td>
+      <td> The base directory to use when resolving &quot;file&quot;.</td>
+      <td>project.basedir</td>
+      <td>No</td>
+    </tr>
+  </thead>
+  <tbody>
+    <tr>
+      <td>propertyName</td>
+      <td>String</td>
+      <td> The name of the property to set with resolved (absolute) path.</td>
+      <td>n/a</td>
+      <td>Yes</td>
+    </tr>
+  </tbody>
+</table>
+<h2><a name="TaskdefTask"></a>TaskdefTask</h2>
+<p>
+  With the TaskdefTask you can import a user task into your
+  buildfile.
+</p>
+<h3>Example</h3>
+<pre>&lt;!-- Includes the Task named &quot;ValidateHTMLTask&quot; and makes it available by
+     &lt;validatehtml&gt; --&gt;
+&lt;taskdef classname=&quot;user.tasks.ValidateHTMLTask&quot; name=&quot;validatehtml&quot; /&gt;
+
+&lt;!-- Includes the Task &quot;RebootTask&quot; from &quot;user/sometasks&quot; somewhere inside
+     the $PHP_CLASSPATH --&gt;
+&lt;taskdef classname=&quot;user.sometasks.RebootTask&quot; name=&quot;reboot&quot; /&gt;
+</pre>
+<h3>Attributes</h3>
+<table>
+  <thead>
+    <tr>
+      <th>Name</th>
+      <th>Type</th>
+      <th>Description</th>
+      <th>Default</th>
+      <th>Required</th>
+    </tr>
+  </thead>
+  <tbody>
+    <tr>
+      <td>classname</td>
+      <td>String</td>
+      <td>
+        The path to the class that defines the TaskClass.
+      </td>
+      <td>n/a</td>
+      <td>Yes</td>
+    </tr>
+    <tr>
+      <td>name</td>
+      <td>String</td>
+      <td>
+        The name the task is available as after importing. If you
+        specify &quot;validate&quot;, for example, you can access
+        the task imported here with <code>&lt;validate&gt;</code>.
+      </td>
+      <td>n/a</td>
+      <td>Yes</td>
+    </tr>
+	<tr>
+      <td>classpath</td>
+      <td>String</td>
+      <td> The classpath to use when including classes. This is added to PHP's
+        include_path.</td>
+      <td>n/a</td>
+      <td>No</td>
+    </tr>
+	<tr>
+      <td>classpathref</td>
+      <td>String</td>
+      <td> Reference to classpath to use when including classes. This is added
+        to PHP's include_path.</td>
+      <td>n/a</td>
+      <td>No</td>
+    </tr>
+  </tbody>
+</table>
+
+<h3>Supported Nested Tags</h3>
+<ul>
+  <li>classpath</li>
+</ul>
+<h2><a name="TouchTask"></a>TouchTask</h2>
+<p>
+  The TouchTask works like the Unix <em>touch</em> command: It
+  sets the modtime of a file to a specific time. Default is
+  the current time.
+</p>
+<h3>Example</h3>
+<pre>&lt;touch file=&quot;README.txt&quot; millis=&quot;102134111&quot; /&gt;
+
+&lt;touch file=&quot;COPYING.lib&quot; datetime=&quot;10/10/1999 09:31 AM&quot; /&gt;
+</pre>
+<h3>Attributes</h3>
+<table>
+  <thead>
+    <tr>
+      <th>Name</th>
+      <th>Type</th>
+      <th>Description</th>
+      <th>Default</th>
+      <th>Required</th>
+    </tr>
+  </thead>
+  <tbody>
+    <tr>
+      <td>file</td>
+      <td>String</td>
+      <td>
+        The file which time is to be changed.
+      </td>
+      <td>n/a</td>
+      <td>No</td>
+    </tr>
+    <tr>
+      <td>datetime</td>
+      <td>DateTime</td>
+      <td>
+        The date and time the mtime of the file is to be set
+        to. The format is &quot;MM/DD/YYYY HH:MM AM or PM&quot;
+      </td>
+      <td><em>now</em></td>
+      <td>No</td>
+    </tr>
+    <tr>
+      <td>millis</td>
+      <td>Integer</td>
+      <td>
+        The millisecons since midnight Jan 1 1970 (Unix epoche).
+      </td>
+      <td><em>now</em></td>
+      <td>No</td>
+    </tr>
+  </tbody>
+</table>
+
+<h2><a name="TstampTask"></a>TstampTask</h2>
+<p>
+Sets the DSTAMP, TSTAMP, and TODAY properties in the current project.
+By default, the DSTAMP property is in the format "%Y%m%d", TSTAMP is in the format "%H%M", and TODAY is in the format "%B %d %Y".
+Use the nested &lt;format&gt; element to specify a different format.</p>
+
+<p>
+These properties can be used in the build-file, for instance, to create time-stamped filenames, or used to replace placeholder tags inside documents to indicate, for example, the release date. The best place for this task is probably in an initialization target.
+</p>
+
+<h3>Examples</h3>
+<pre>&lt;tstamp/&gt;</pre>
+
+<p>sets the standard DSTAMP, TSTAMP, and TODAY properties according to the default formats.</p>
+
+<pre>&lt;tstamp&gt;
+  &lt;format property=&quot;DATE&quot; pattern=&quot;%c&quot; locale=&quot;nl_NL&quot;/&gt;
+&lt;/tstamp&gt;</pre>
+
+<p>sets the standard properties as well as the property DATE with the date/time pattern "%c" using the Dutch locale.</p>
+
+<pre>&lt;tstamp prefix=&quot;start&quot;/&gt;</pre>
+
+<p>sets three properties with the standard formats, prefixed with "start.": start.DSTAMP, start.TSTAMP, and start.TODAY.</p>
+
+<h3>Attributes</h3>
+<table>
+  <thead>
+    <tr>
+      <th>Name</th>
+      <th>Type</th>
+      <th>Description</th>
+      <th>Default</th>
+      <th>Required</th>
+    </tr>
+  </thead>
+  <tbody>
+    <tr>
+      <td>prefix</td>
+      <td>String</td>
+      <td>Prefix used for all properties set.
+      </td>
+      <td>n/a</td>
+      <td>No</td>
+    </tr>
+  </tbody>
+</table>
+
+<h3>Supported Nested Tags</h3>
+<ul>
+  <li>format
+    <p>The Tstamp task supports a &lt;format&gt; nested element that allows a property to be set to the current date and time in a given format.
+    The date/time patterns are as defined in the PHP strftime() function.</p>
+	<h3>Attributes</h3>
+	<table>
+	  <thead>
+		<tr>
+		  <th>Name</th>
+		  <th>Type</th>
+		  <th>Description</th>
+		  <th>Default</th>
+		  <th>Required</th>
+		</tr>
+	  </thead>
+	  <tbody>
+		<tr>
+		  <td>property</td>
+		  <td>String</td>
+		  <td>The property to receive the date/time string in the given pattern. </td>
+		  <td>n/a</td>
+		  <td>Yes</td>
+		</tr>
+		<tr>
+		  <td>classname</td>
+		  <td>String</td>
+		  <td>The date/time pattern to be used. The values are as defined by the PHP strftime() function.</td>
+		  <td>n/a</td>
+		  <td>Yes</td>
+		</tr>
+		<tr>
+		  <td>locale</td>
+		  <td>String</td>
+		  <td>The locale used to create date/time string. For more information see the PHP setlocale() function.</td>
+		  <td>n/a</td>
+		  <td>No</td>
+		</tr>
+	  </tbody>
+	</table>
+  </li>
+</ul>
+
+<h2><a name="TypedefTask"></a>TypedefTask</h2>
+<p>
+  With the TypedefTask you can import a user type into your
+  buildfile.
+</p>
+<h3>Example</h3>
+<pre>&lt;!-- Includes the Type named &quot;CustomProject&quot; and makes it available by
+     &lt;cproject&gt; --&gt;
+&lt;taskdef classname=&quot;user.types.CustomProject&quot; name=&quot;cproject&quot; /&gt;
+</pre>
+<h3>Attributes</h3>
+<table>
+  <thead>
+    <tr>
+      <th>Name</th>
+      <th>Type</th>
+      <th>Description</th>
+      <th>Default</th>
+      <th>Required</th>
+    </tr>
+  </thead>
+  <tbody>
+    <tr>
+      <td>classname</td>
+      <td>String</td>
+      <td>
+        The path to the class that defines the type class.
+      </td>
+      <td>n/a</td>
+      <td>Yes</td>
+    </tr>
+    <tr>
+      <td>name</td>
+      <td>String</td>
+      <td>
+        The name the type is available as after importing. If you
+        specify &quot;cproject&quot;, for example, you can access
+        the type imported here with <code>&lt;cproject&gt;</code>.
+      </td>
+      <td>n/a</td>
+      <td>Yes</td>
+    </tr>
+	<tr>
+      <td>classpath</td>
+      <td>String</td>
+      <td> The classpath to use when including classes. This is added to PHP's
+        include_path.</td>
+      <td>n/a</td>
+      <td>No</td>
+    </tr>
+	<tr>
+      <td>classpathref</td>
+      <td>String</td>
+      <td> Reference to classpath to use when including classes. This is added
+        to PHP's include_path.</td>
+      <td>n/a</td>
+      <td>No</td>
+    </tr>
+  </tbody>
+</table>
+
+<h3>Supported Nested Tags</h3>
+<ul>
+  <li>classpath</li>
+</ul>
+<h2><a name="UpToDateTask"></a>UpToDateTask</h2>
+<p>UpToDateTask tests if a resource/file is set and sets a certain property
+  to a certain value if it exists. </p>
+<pre title="Example of how to use AvailableTask">&lt;uptodate property=&quot;propelBuild.notRequired&quot; targetfile=&quot;${deploy}\propelClasses.tgz&quot; &gt;
+  &lt;srcfiles dir= &quot;${src}/propel&quot; includes=&quot;**/*.php&quot;/&gt;
+&lt;/uptodate&gt;</pre>
+<p>sets the property <em>propelBuild.notRequired</em> to true if the <em>${deploy}/propelClasses.tgz</em>
+  file is more up-to-date than any of the PHP class files in the <em>${src}/propel</em>
+  directory. </p>
+<p>Parameters</p>
+<table>
+  <thead>
+    <tr>
+      <th>Name</th>
+      <th>Type</th>
+      <th>Description</th>
+      <th>Default</th>
+      <th>Required</th>
+    </tr>
+  </thead>
+  <tbody>
+    <tr>
+      <td>property</td>
+      <td>string</td>
+      <td> Name of the property that is to be set. </td>
+      <td>n/a</td>
+      <td>Yes</td>
+    </tr>
+    <tr>
+      <td>value</td>
+      <td>String</td>
+      <td> The value the propert is to be set to. </td>
+      <td><em>&quot;true&quot;</em></td>
+      <td>No</td>
+    </tr>
+    <tr>
+      <td>srcfile</td>
+      <td>String</td>
+      <td> The file to check against target file(s).</td>
+      <td>n/a</td>
+      <td>Yes (or nested <em>srcfiles</em>)</td>
+    </tr>
+    <tr>
+      <td>targetfile</td>
+      <td>String</td>
+      <td> The file for which we want to determine the status.</td>
+      <td>n/a</td>
+      <td>Yes (or nested<em> mapper</em>)</td>
+    </tr>
+  </tbody>
+</table>
+<h3>Supported Nested Tags</h3>
+<ul>
+  <li>FileSet</li>
+  <li>Mapper</li>
+</ul>
+<p>&nbsp;</p>
+<h2><a name="XsltTask"></a>XsltTask</h2>
+<p>
+With <em>XsltTask</em>, you can run a XSLT tranformation on an XML
+file. Actually, <em>XsltTask</em> extends <em>CopyTask</em>, so
+you can use all the elements allowed there.
+</p>
+<h3>Example</h3>
+<pre>&lt;!-- Transform docbook with an imaginary XSLT file --&gt;
+&lt;xslt todir=&quot;/srv/docs/phing&quot; style=&quot;dbk2html.xslt&quot; &gt;
+  &lt;fileset dir=&quot;.&quot;&gt;
+    &lt;include name=&quot;**/*.xml&quot; /&gt;
+  &lt;/fileset&gt;
+&lt;/xslt&gt;
+</pre>
+<h3>Attributes</h3>
+<table>
+  <thead>
+    <tr>
+      <th>Name</th>
+      <th>Type</th>
+      <th>Description</th>
+      <th>Default</th>
+      <th>Required</th>
+    </tr>
+  </thead>
+  <tbody>
+    <tr>
+      <td>style</td>
+      <td>String</td>
+      <td>
+        The path where the Xslt file is located
+      </td>
+      <td>n/a</td>
+      <td>Yes</td>
+    </tr>
+  </tbody>
+</table>
+<p>
+<em>Note:</em> You can also use all the attributes available for
+<a href="#CopyTask">CopyTask</a>.
+</p>
+<h3>Suppported Nested Elements</h3>
+<p>
+<em>Note:</em> You can use all the elements also available for
+<a href="#CopyTask">CopyTask</a>.
+</p>
+
+<p>
+Additionally, you can use <em>&lt;param&gt;</em> tags with a
+<em>name</em> and a <em>expression</em> (or <em>value</em> alias) attribute. These parameters are then
+available from within the xsl style sheet.
+</p>
+
+</body>
+</html>
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/docs/phing_guide/book/chapters/appendixes/AppendixC-OptionalTasks.html
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/docs/phing_guide/book/chapters/appendixes/AppendixC-OptionalTasks.html	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/docs/phing_guide/book/chapters/appendixes/AppendixC-OptionalTasks.html	(revision 19)
@@ -0,0 +1,2256 @@
+<!--
+-File         $Id: AppendixC-OptionalTasks.html 352 2008-02-06 15:26:43Z mrook $
+-License      GNU FDL (http://www.gnu.org/copyleft/fdl.html)
+-Copyright    2002, turing
+-Author       alex black, enigma@turingstudio.com
+-->
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/2000/REC-xhtml1-20000126/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+	<title>Phing Guide - Optional Tasks</title>
+	<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
+	<link rel="Stylesheet" rev="Stylesheet" href="../../css/Documentation.css" type="text/css" media="All" charset="iso-8859-1" />
+</head>
+<body>
+<h1><a name="AppendixC-OptionalTasks"></a>Appendix C: Optional Tasks</h1>
+
+<p>
+This appendix contains a reference of all optional tasks, i.e. tasks that are not directly needed for
+building projects, but can assist in various aspects of development and deployment.
+</p>
+
+<p> This reference lists the tasks alphabetically by the name of the classes that
+  implement the tasks. So if you are searching for the reference to the <code>&lt;phplint&gt;</code>
+  tag, for example, you will want to look at the reference of PhpLintTask. </p>
+
+<h2><a name="DbDeployTask"></a>DbDeployTask</h2>
+<p>The <em>DbDeployTask</em> creates .sql files for making revisions to a database, based on dbdeploy conventions centering around a changelog table in the database. See <a href="http://dbdeploy.com/documentation/getting-started/rules-for-using-dbdeploy/">rules for using dbdeploy</a> for more information. You will need a changelog table like so:</p>
+
+<pre>CREATE TABLE changelog (
+  change_number BIGINT NOT NULL,
+  delta_set VARCHAR(10) NOT NULL,
+  start_dt TIMESTAMP NOT NULL,
+  complete_dt TIMESTAMP NULL,
+  applied_by VARCHAR(100) NOT NULL,
+  description VARCHAR(500) NOT NULL
+)</pre>
+
+<h3>Example</h3>
+<pre>
+&lt;taskdef name=&quot;dbdeploy&quot; classname=&quot;phing.tasks.ext.dbdeploy.DbDeployTask&quot;/&gt;
+
+&lt;dbdeploy
+  url=&quot;sqlite:${project.basedir}/data/db.sqlite&quot;&gt;
+  userid=&quot;dbdeploy&quot;
+  password=&quot;dbdeploy&quot;
+  dir=&quot;${project.basedir}/data/dbdeploy/deltas&quot;
+/&gt;
+</pre>
+
+<p>The above example uses a sqlite database and delta scripts located in dbdeploy/deltas in the project base dir.</p>
+
+<h3>Attributes</h3>
+<table>
+  <thead>
+    <tr>
+      <th>Name</th>
+      <th>Type</th>
+      <th>Description</th>
+      <th>Default</th>
+      <th>Required</th>
+    </tr>
+  </thead>
+  <tbody>
+    <tr>
+      <td>url</td>
+      <td>String</td>
+      <td>PDO connection url</td>
+      <td>n/a</td>
+      <td>Yes</td>
+    </tr>
+    <tr>
+      <td>userid</td>
+      <td>String</td>
+      <td>DB userid to use for accessing the changelog table</td>
+      <td>none</td>
+      <td>As required by db</td>
+    </tr>
+    <tr>
+      <td>password</td>
+      <td>String</td>
+      <td>DB password to use for accessing the changelog table</td>
+      <td>none</td>
+      <td>As required by db</td>
+    </tr>
+    <tr>
+      <td>dir</td>
+      <td>String</td>
+      <td>Directory containing dbdeploy delta scripts</td>
+      <td>none</td>
+      <td>Yes</td>
+    </tr>
+    <tr>
+      <td>outputfile</td>
+      <td>String</td>
+      <td>Filename in which deployment SQL will be generated</td>
+      <td>dbdeploy_deploy.sql</td>
+      <td>No</td>
+    </tr>
+    <tr>
+      <td>undooutputfile</td>
+      <td>String</td>
+      <td>Filename in which undo SQL will be generated</td>
+      <td>dbdeploy_undo.sql</td>
+      <td>No</td>
+    </tr>
+    <tr>
+      <td>deltaset</td>
+      <td>String</td>
+      <td>deltaset to check within db</td>
+      <td>Main</td>
+      <td>No</td>
+    </tr>
+    <tr>
+      <td>lastchangetoapply</td>
+      <td>Integer</td>
+      <td>Highest-numbered delta script to apply to db</td>
+      <td>999</td>
+      <td>No</td>
+    </tr>
+  </tbody>
+</table>
+
+<h2><a name="CoverageMergerTask"></a>CoverageMergerTask</h2>
+<p>The CoverageMergerTask merges code coverage information from external sources with an existing code coverage database.</p>
+
+<p>The format of the code coverage files is expected to be identical to:
+
+<pre>
+file_put_contents('/www/live/testcases/coverage.data', serialize(xdebug_get_code_coverage));
+</pre>
+
+<h3>Supported Nested Tags</h3>
+<ul>
+  <li>fileset</li>
+</ul>
+
+<h3>Example</h3>
+<pre>
+&lt;coverage-merger&gt;
+&nbsp;&nbsp;&lt;fileset dir=&quot;/www/live/testcases&quot;&gt;
+&nbsp;&nbsp;&nbsp;&nbsp;&lt;include name="**/*.data"/&gt;
+&nbsp;&nbsp;&lt;/fileset&gt;
+&lt;/coverage-merger&gt;
+</pre>
+
+<h2><a name="CoverageReportTask"></a>CoverageReportTask</h2>
+<p>The CoverageReportTask formats a coverage database into a framed HTML report using XSLT.
+
+<h3>Attributes</h3>
+<table>
+  <thead>
+    <tr>
+      <th>Name</th>
+      <th>Type</th>
+      <th>Description</th>
+      <th>Default</th>
+      <th>Required</th>
+    </tr>
+  </thead>
+  <tbody>
+    <tr>
+      <td>outfile</td>
+      <td>String</td>
+      <td> The location for the intermediate XML file. </td>
+      <td>coverage.db</td>
+      <td>Yes</td>
+    </tr>
+  </tbody>
+</table>
+
+<h3>Supported Nested Tags</h3>
+<ul>
+  <li>report
+	<h3>Attributes</h3>
+	<table>
+	  <thead>
+		<tr>
+		  <th>Name</th>
+		  <th>Type</th>
+		  <th>Description</th>
+		  <th>Default</th>
+		  <th>Required</th>
+		</tr>
+	  </thead>
+	  <tbody>
+		<tr>
+		  <td>styledir</td>
+		  <td>String</td>
+		  <td> The directory where the stylesheets are located. </td>
+		  <td>n/a</td>
+		  <td>Yes</td>
+		</tr>
+		<tr>
+		  <td>todir</td>
+		  <td>String</td>
+		  <td> The directory where the files resulting from the
+		  transformation should be written to. </td>
+		  <td></td>
+		  <td>Yes</td>
+		</tr>
+	  </tbody>
+	</table>
+  </li>
+</ul>
+
+<h3>Example</h3>
+<pre>
+&lt;coverage-report outfile=&quot;reports/coverage.xml&quot;&gt;
+&nbsp;&nbsp;&lt;report todir=&quot;reports/coverage&quot; styledir=&quot;/home/phing/etc&quot;/&gt;
+&lt;/coverage-report&gt;
+</pre>
+<h2><a name="CoverageSetupTask"></a>CoverageSetupTask</h2>
+<p>The CoverageSetupTask prepares a database which can be used to gather code coverage information for
+unit tests. The code coverage tasks use the <a href="http://www.xdebug.org/" target="_blank">Xdebug</a> extension.</p>
+
+<h3>Attributes</h3>
+<table>
+  <thead>
+    <tr>
+      <th>Name</th>
+      <th>Type</th>
+      <th>Description</th>
+      <th>Default</th>
+      <th>Required</th>
+    </tr>
+  </thead>
+  <tbody>
+    <tr>
+      <td>database</td>
+      <td>String</td>
+      <td>The location for the coverage database. </td>
+      <td>coverage.db</td>
+      <td>Yes</td>
+    </tr>
+  </tbody>
+</table>
+
+<h3>Supported Nested Tags</h3>
+<ul>
+  <li>classpath</li>
+  <li>fileset</li>
+</ul>
+
+<h3>Example</h3>
+<pre>
+&lt;coverage-setup database=&quot;./reports/coverage.db&quot;&gt;
+&nbsp;&nbsp;&lt;fileset dir=&quot;classes&quot;&gt;
+&nbsp;&nbsp;&nbsp;&nbsp;&lt;include name="**/*.php"/&gt;
+&nbsp;&nbsp;&lt;/fileset&gt;
+&lt;/coverage-setup&gt;
+&lt;phpunit codecoverage=&quot;true&quot;&gt;
+&nbsp;&nbsp;&lt;batchtest&gt;
+&nbsp;&nbsp;&nbsp;&nbsp;&lt;fileset dir=&quot;src&quot;&gt;
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;include name=&quot;*Test.php&quot;/&gt;
+&nbsp;&nbsp;&nbsp;&nbsp;&lt;/fileset&gt;
+&nbsp;&nbsp;&lt;/batchtest&gt;
+&lt;/phpunit&gt;
+</pre>
+
+<h2><a name="IoncubeEncoderTask"></a>IoncubeEncoderTask</h2>
+<p>The <em>IoncubeEncoderTask</em> executes the <a href="http://www.ioncube.com" target="_blank">ionCube</a> encoder (for either PHP4 or PHP5 projects).</p>
+
+<p>For more information on the meaning of the various options please consult the ionCube <a href="http://www.ioncube.com/USER-GUIDE.pdf" target="_blank">user guide</a>.</p>
+
+<h3>Example</h3>
+<pre>&lt;ioncubeencoder
+   binary="true"
+   copy="*.ini config/*"
+   encode="*.inc licenses/license.key"
+   encrypt="*.tpl *.xml"
+   encrypt="more"
+   fromdir="files"
+   ignore="*.bak RCS/ *~ docs/"
+   ioncubepath="/usr/local/ioncube"
+   keep="docs/README"
+   licensepath="mylicense.txt"
+   optimize="max"
+   passphrase="mypassphrase"
+   phpversion="4"
+   targetoption="replace"
+   todir="encoded"
+   withoutruntimeloadersupport="true"&gt;
+  &lt;comment&gt;A project encoded with the ionCube encoder.&lt;/comment&gt;
+&lt;/ioncubeencoder&gt;
+</pre>
+
+<h3>Attributes</h3>
+<table>
+  <thead>
+    <tr>
+      <th>Name</th>
+      <th>Type</th>
+      <th>Description</th>
+      <th>Default</th>
+      <th>Required</th>
+    </tr>
+  </thead>
+  <tbody>
+    <tr>
+      <td>allowedserver</td>
+      <td>String</td>
+      <td>Restricts the encoded files to particular servers and/or domains.  Consult the IonCude documentation for more information.</td>
+      <td>none</td>
+      <td>No</td>
+    </tr>
+    <tr>
+      <td>binary</td>
+      <td>Boolean</td>
+      <td>Whether to save encoded files in binary format (default is ASCII format)</td>
+      <td>false</td>
+      <td>No</td>
+    </tr>
+    <tr>
+      <td>copy</td>
+      <td>String</td>
+      <td>Specifies files or directories to exclude from being encoded or encrypted and copy them to the target directory (separated by space).</td>
+      <td>none</td>
+      <td>No</td>
+    </tr>
+    <tr>
+      <td>encode</td>
+      <td>String</td>
+      <td>Specifies additional file patterns, files or directories to encode, or to reverse the effect of <em>copy</em></td>
+      <td>none</td>
+      <td>No</td>
+    </tr>
+    <tr>
+      <td>encrypt</td>
+      <td>String</td>
+      <td>Specify files or directories (space separated list) that are to be encrypted.</td>
+      <td>none</td>
+      <td>No</td>
+    </tr>
+    <tr>
+      <td>expirein</td>
+      <td>String</td>
+      <td>Sets a period in seconds (s), minutes (m), hours (h) or days (d) after which the files expire.  Accepts: <em>500s</em> or <em>55m</em> or <em>24h</em> or <em>7d</em></td>
+      <td>none</td>
+      <td>No</td>
+    </tr>
+    <tr>
+      <td>expireon</td>
+      <td>String</td>
+      <td>Sets a YYYY-MM-DD date to expire the files.</td>
+      <td>none</td>
+      <td>No</td>
+    </tr>
+    <tr>
+      <td>fromdir</td>
+      <td>String</td>
+      <td>Path containing source files</td>
+      <td>none</td>
+      <td>Yes</td>
+    </tr>
+    <tr>
+      <td>ignore</td>
+      <td>String</td>
+      <td>Set files and directories to ignore entirely and exclude from the target directory (separated by space).</td>
+      <td>none</td>
+      <td>Yes</td>
+    </tr>
+    <tr>
+      <td>ioncubepath</td>
+      <td>String</td>
+      <td>Path to the ionCube binaries</td>
+      <td>/usr/local/ioncube</td>
+      <td>No</td>
+    </tr>
+    <tr>
+      <td>keep</td>
+      <td>String</td>
+      <td>Set files and directories not to be ignored (separated by space)./td>
+      <td>none</td>
+      <td>No</td>
+    </tr>
+    <tr>
+      <td>licensepath</td>
+      <td>String</td>
+      <td>Path to the license file that will be used by the encoded files</td>
+      <td>none</td>
+      <td>No</td>
+    </tr>
+    <tr>
+      <td>nodoccomments</td>
+      <td>String</td>
+      <td>Omits documents comments ( /** ... */ ) from the encoded files.</td>
+      <td>none</td>
+      <td>No</td>
+    </tr>
+    <tr>
+      <td>obfuscation-key</td>
+      <td>String</td>
+      <td>The obfuscation key must be supplied when using the obfuscate option</td>
+      <td>none</td>
+      <td>No</td>
+    </tr>
+    <tr>
+      <td>obfuscate</td>
+      <td>String</td>
+      <td>The Encoder can obfuscate the names of global functions, the names of local variables in global functions, and line numbers.  Use either <em>all</em> or any of <em>functions</em>, <em>locals</em> or <em>linenos</em> separated by a space.</td>
+      <td>none</td>
+      <td>No</td>
+    </tr>
+    <tr>
+      <td>optimize</td>
+      <td>String</td>
+      <td>Controls the optimization of the encoded files, accepts either <em>more</em> or <em>max</em></td>
+      <td>none</td>
+      <td>No</td>
+    </tr>
+    <tr>
+      <td>passphrase</td>
+      <td>String</td>
+      <td>The passphrase to use when encoding with a license file</td>
+      <td>none</td>
+      <td>No</td>
+    </tr>
+    <tr>
+      <td>phpversion</td>
+      <td>Integer</td>
+      <td>The PHP version to use</td>
+      <td>5</td>
+      <td>No</td>
+    </tr>
+    <tr>
+      <td>targetoption</td>
+      <td>String</td>
+      <td>Option to use when target directory exists, accepts <em>replace</em>, <em>merge</em>, <em>update</em> and <em>rename</em></td>
+      <td>none</td>
+      <td>No</td>
+    </tr>
+    <tr>
+      <td>todir</td>
+      <td>String</td>
+      <td>Path to save encoded files to</td>
+      <td>none</td>
+      <td>Yes</td>
+    </tr>
+    <tr>
+      <td>withoutruntimeloadersupport</td>
+      <td>Boolean</td>
+      <td>Wether to disable support for runtime initialization of the ionCube Loader</td>
+      <td>false</td>
+      <td>No</td>
+    </tr>
+  </tbody>
+</table>
+
+<h3>Supported Nested Tags</h3>
+<ul>
+  <li>comment
+    <p>Custom text that is added to the start of each encoded file.</p>
+  </li>
+</ul>
+
+<h2><a name="IoncubeLicenseTask"></a>IoncubeLicenseTask</h2>
+<p>The <em>IoncubeLicenseTask</em> executes the <a href="http://www.ioncube.com" target="_blank">ionCube</a> make_license program.</p>
+
+<p>For more information on the meaning of the various options please consult the ionCube <a href="http://www.ioncube.com/USER-GUIDE.pdf" target="_blank">user guide</a>.</p>
+
+<h3>Example</h3>
+<pre>&lt;ioncubelicense ioncubepath="/usr/local/ioncube" licensepath="mylicense.txt" passphrase="mypassphrase">
+  &lt;comment&gt;A license file made with the ionCube encoder.&lt;/comment&gt;
+&lt;/ioncubelicense&gt;
+</pre>
+
+<h3>Attributes</h3>
+<table>
+  <thead>
+    <tr>
+      <th>Name</th>
+      <th>Type</th>
+      <th>Description</th>
+      <th>Default</th>
+      <th>Required</th>
+    </tr>
+  </thead>
+  <tbody>
+    <tr>
+      <td>ioncubepath</td>
+      <td>String</td>
+      <td>Path to the ionCube binaries</td>
+      <td>/usr/local/ioncube</td>
+      <td>No</td>
+    </tr>
+    <tr>
+      <td>licensepath</td>
+      <td>String</td>
+      <td>Path to the license file that will be generated</td>
+      <td>none</td>
+      <td>No</td>
+    </tr>
+    <tr>
+      <td>passphrase</td>
+      <td>String</td>
+      <td>The passphrase to use when generating the license file</td>
+      <td>none</td>
+      <td>No</td>
+    </tr>
+  </tbody>
+</table>
+
+<h3>Supported Nested Tags</h3>
+<ul>
+  <li>comment
+    <p>Custom text that is added to the start of each encoded file.</p>
+  </li>
+</ul>
+
+<h2><a name="PDOSQLExecTask"></a>PDOSQLExecTask</h2>
+
+<p>The <em>PDOSQLExecTask</em> executes SQL statements using PDO.</p>
+
+<h3>Examples</h3>
+
+<pre>&lt;pdo url="pgsql:host=localhost dbname=test">
+  &lt;fileset dir=&quot;sqlfiles&quot;&gt;
+	  &lt;include name=&quot;*.sql&quot;/&gt;
+  &lt;/fileset&gt;<br />&lt;/pdo&gt;
+</pre>
+
+<pre>&lt;pdo url="mysql:host=localhost;dbname=test" userid="username" password="password">
+  &lt;transaction src=&quot;path/to/sqlfile.sql&quot;/&gt;
+  &lt;formatter type=&quot;plain&quot; outfile=&quot;path/to/output.txt&quot;/&gt;
+&lt;/pdo&gt;
+</pre>
+
+<h3>Attributes</h3>
+<table>
+  <thead>
+    <tr>
+      <th>Name</th>
+      <th>Type</th>
+      <th>Description</th>
+      <th>Default</th>
+      <th>Required</th>
+    </tr>
+  </thead>
+  <tbody>
+    <tr>
+      <td>url</td>
+      <td>String</td>
+      <td>PDO connection URL (DSN) </td>
+      <td>none</td>
+      <td>Yes</td>
+    </tr>
+    <tr>
+      <td>userid</td>
+      <td>String</td>
+      <td>Username for connection (if it cannot be specified in URL) </td>
+      <td>none</td>
+      <td>No</td>
+    </tr>
+    <tr>
+      <td>password</td>
+      <td>String</td>
+      <td>The password to use for the connection (if it cannot be specified in URL) </td>
+      <td>none</td>
+      <td>No</td>
+    </tr>
+	<tr>
+      <td>encoding</td>
+      <td>String</td>
+      <td>The database encoding.</td>
+      <td>none</td>
+      <td>No</td>
+    </tr>
+	<tr>
+      <td>src</td>
+      <td>File</td>
+      <td>A single source file of SQL statements to execute.</td>
+      <td>none</td>
+      <td>No</td>
+    </tr>
+	<tr>
+      <td>onerror</td>
+      <td>String</td>
+      <td>The action to perform on error (continue, stop, or abort)</td>
+      <td>abort</td>
+      <td>No</td>
+    </tr>
+	<tr>
+      <td>delimiter</td>
+      <td>String</td>
+      <td>The delimeter to separate SQL statements (e.g. &quot;GO&quot; in MSSQL)</td>
+      <td>;</td>
+      <td>No</td>
+    </tr>
+	<tr>
+      <td>delimitertype</td>
+      <td>String</td>
+      <td>The delimiter type (&quot;normal&quot; or &quot;row&quot;). Normal means that any occurence of the delimiter
+     terminate the SQL command whereas with row, only a line containing just
+     the delimiter is recognized as the end of the command.</td>
+      <td>normal</td>
+      <td>No</td>
+    </tr>
+  </tbody>
+</table>
+
+<h3>Supported Nested Tags</h3>
+<ul>
+  <li>transaction
+    <p>Wrapper for a single transaction.</p>
+  </li>
+  <li>fileset
+    <p>Files containing SQL statements.</p>
+  </li>
+  <li>formatter
+  	 <p>The results of any queries that are executed can be printed in different formats.
+    Output will always be sent to a file, unless you set the <em>usefile</em> attribute to <em>false</em>.
+    The path to the output file file can be specified by the <em>outfile</em> attribute; there is a default filename that
+	will be returned by the formatter if no output file is specified.</p>
+    <p>There are three predefined formatters - one prints the query results in XML format,
+    the other emits plain text. Custom formatters that
+    extend phing.tasks.pdo.PDOResultFormatter can be specified.</p>
+	<h3>Attributes</h3>
+	<table>
+	  <thead>
+		<tr>
+		  <th>Name</th>
+		  <th>Type</th>
+		  <th>Description</th>
+		  <th>Default</th>
+		  <th>Required</th>
+		</tr>
+	  </thead>
+	  <tbody>
+		<tr>
+		  <td>type</td>
+		  <td>String</td>
+		  <td> Use a predefined formatter (either <em>xml</em> or <em>plain</em>). </td>
+		  <td>n/a</td>
+		  <td rowspan="2">One of these attributes is required. </td>
+		</tr>
+		<tr>
+		  <td>classname</td>
+		  <td>String</td>
+		  <td> Name of a custom formatter class (must extend phing.tasks.ext.pdo.PDOResultFormatter). </td>
+		  <td>n/a</td>
+		</tr>
+		<tr>
+		  <td>usefile</td>
+		  <td>Boolean</td>
+		  <td> Boolean that determines whether output should be sent to a file. </td>
+		  <td>true</td>
+		  <td>No</td>
+		</tr>
+		<tr>
+		  <td>outfile</td>
+		  <td>File</td>
+		  <td>Path to file in which to store result. </td>
+		  <td>Depends on formatter</td>
+		  <td>No</td>
+		</tr>
+		<tr>
+      <td>showheaders</td>
+      <td>Boolean</td>
+      <td>(only applies to plain formatter) Whether to show column headers.</td>
+      <td>false</td>
+      <td>No</td>
+    </tr>
+	<tr>
+      <td>coldelim</td>
+      <td>String</td>
+      <td>(only applies to plain formatter) The column delimiter.</td>
+      <td>,</td>
+      <td>No</td>
+    </tr>
+	<tr>
+      <td>rowdelim</td>
+      <td>String</td>
+      <td>(only applies to plain formatter) The row delimiter.</td>
+      <td>\n</td>
+      <td>No</td>
+    </tr>
+	<tr>
+      <td>encoding</td>
+      <td>String</td>
+      <td>(only applies to XML formatter) The xml document encoding.</td>
+      <td>(PHP default)</td>
+      <td>No</td>
+    </tr>
+	<tr>
+      <td>formatoutput</td>
+      <td>Boolean</td>
+      <td>(only applies to XML formatter) Whether to format XML output.</td>
+      <td>true</td>
+      <td>No</td>
+    </tr>
+	  </tbody>
+	</table>
+	<h3>Examples</h3>
+	<pre>&lt;pdo url="pgsql:host=localhost dbname=test">
+  &lt;fileset dir=&quot;sqlfiles&quot;&gt;
+	  &lt;include name=&quot;*.sql&quot;/&gt;
+  &lt;/fileset&gt;
+
+  &lt;!-- xml formatter --&gt;
+  &lt;formatter type=&quot;xml&quot; output=&quot;output.xml&quot;/&gt;
+
+  &lt;!-- custom formatter --&gt;
+  &lt;formatter classname=&quot;path.to.CustomFormatterClass&quot;&gt;
+    &lt;param name=&quot;someClassAttrib&quot; value=&quot;some-value&quot;/&gt;
+  &lt;/formatter&gt;
+
+  &lt;!-- No output file + usefile=false means it goes to phing log --&gt;
+  &lt;formatter type=&quot;plain&quot; usefile=&quot;false&quot; /&gt;<br />&lt;/pdo&gt;
+</pre>
+
+  </li>
+</ul>
+
+<h2><a name="PearPackageTask"></a>PearPackageTask</h2>
+<p>
+  With the PearPackageTask, you can create a package.xml which can be installed
+  using the PEAR installer. Use this in conjunction with the <a href="#Tasks.TarTask">TarTask</a>
+  to completely script the building of a PEAR pacakge.
+</p>
+<p><strong>Note that this task creates a <em>version 1</em> package.xml file.</strong></p>
+
+<p>
+  This task uses the PEAR_PackageFileManager class.  In order to be maximally flexible, the majority
+  of options are set generically (using <em>&lt;option&gt;</em> tag) and are set using PEAR_PackageFileManager::setOptions().
+  Use the <em>&lt;mapping&gt;</em> tag to represent complex values (which are turned into associative arrays and also
+  set using setOptions() method).
+</p>
+<h3>Example</h3>
+<pre>
+&lt;pearpkg name="phing" dir="${build.src.dir}" destFile="${build.base.dir}/package.xml"&gt;
+&lt;fileset&gt;
+&nbsp;&nbsp;&lt;include name="**"/&gt;
+&lt;/fileset&gt;
+&lt;option name="notes"&gt;Sample release notes here.&lt;/option&gt;
+&lt;option name="description"&gt;Package description&lt;/option&gt;
+&lt;option name="summary"&gt;Short description&lt;/option&gt;
+&lt;option name="version" value="2.0.0b1"/&gt;
+&lt;option name="state" value="beta"/&gt;
+ &lt;mapping name="maintainers"&gt;
+&nbsp;&nbsp;&lt;element&gt;
+&nbsp;&nbsp;&nbsp;&lt;element key="handle" value="hlellelid"/&gt;
+&nbsp;&nbsp;&nbsp;&lt;element key="name" value="Hans"/&gt;
+&nbsp;&nbsp;&nbsp;&lt;element key="email" value="hans@xmpl.org"/&gt;
+&nbsp;&nbsp;&nbsp;&lt;element key="role" value="lead"/&gt;
+&nbsp;&nbsp;&lt;/element&gt;
+&lt;/mapping&gt;
+&lt;/pearpkg&gt;
+</pre>
+
+<h3>Attributes</h3>
+<table>
+  <thead>
+    <tr>
+      <th>Name</th>
+      <th>Type</th>
+      <th>Description</th>
+      <th>Default</th>
+      <th>Required</th>
+    </tr>
+  </thead>
+  <tbody>
+    <tr>
+      <td>name</td>
+      <td>String</td>
+      <td>
+        The name of the PEAR package.
+      </td>
+      <td>n/a</td>
+      <td>Yes</td>
+    </tr>
+    <tr>
+      <td>dir</td>
+      <td>String</td>
+      <td>
+        The base directory of files to add to package.
+      </td>
+      <td>n/a</td>
+      <td>Yes</td>
+    </tr>
+	<tr>
+	 <td>destFile</td>
+      <td>String</td>
+      <td>
+        The file to create.
+      </td>
+      <td>package.xml in base directory</td>
+      <td>No</td>
+	</tr>
+  </tbody>
+</table>
+
+<h3>Supported Nested Tags</h3>
+<ul>
+  <li>fileset</li>
+  <li>option</li>
+  <li>mapping</li>
+</ul>
+
+
+<h2><a name="PearPackage2Task"></a>PearPackage2Task</h2>
+<p>
+  With the PearPackage2Task, you can create a <em>version 2</em> package.xml which can be installed
+  using the PEAR installer. Use this in conjunction with the <a href="#Tasks.TarTask">TarTask</a>
+  to completely script the building of a PEAR pacakge.
+</p>
+
+<p>
+  This task uses the PEAR_PackageFileManager2 class.  In order to be maximally flexible, the majority
+  of options are set generically (using <em>&lt;option&gt;</em> tag) and are set using PEAR_PackageFileManager::setOptions().
+  Use the <em>&lt;mapping&gt;</em> tag to represent complex values.
+</p>
+
+<p>
+ Note that  Travis Swicegood  has created a more complete implementation of this functionality which can be found here: <a href="http://pear.domain51.com/index.php?package=Phing_d51PearPkg2Task">http://pear.domain51.com/index.php?package=Phing_d51PearPkg2Task</a>.
+</p>
+
+<h3>Example</h3>
+<pre>&lt;pearpkg2 name="phing" dir="${build.src.dir}"&gt;
+   &lt;option name=&quot;outputdirectory&quot; value=&quot;./build&quot;/&gt;<br />   &lt;option name=&quot;packagefile&quot; value=&quot;package2.xml&quot;/&gt;<br />   &lt;option name=&quot;packagedirectory&quot; value=&quot;./${build.dist.dir}&quot;/&gt;<br />   &lt;option name=&quot;baseinstalldir&quot; value=&quot;${pkg.prefix}&quot;/&gt;<br />   &lt;option name=&quot;channel&quot; value=&quot;my.pear-channel.com&quot;/&gt;<br />   &lt;option name=&quot;summary&quot; value=&quot;${pkg.summary}&quot;/&gt;<br />   &lt;option name=&quot;description&quot; value=&quot;${pkg.description}&quot;/&gt;<br />   &lt;option name=&quot;apiversion&quot; value=&quot;${pkg.version}&quot;/&gt;<br />   &lt;option name=&quot;apistability&quot; value=&quot;beta&quot;/&gt;<br />   &lt;option name=&quot;releaseversion&quot; value=&quot;${pkg.version}&quot;/&gt;<br />   &lt;option name=&quot;releasestability&quot; value=&quot;beta&quot;/&gt;<br />   &lt;option name=&quot;license&quot; value=&quot;none&quot;/&gt;<br />   &lt;option name=&quot;phpdep&quot; value=&quot;5.0.0&quot;/&gt;<br />   &lt;option name=&quot;pearinstallerdep&quot; value=&quot;1.4.6&quot;/&gt;<br />   &lt;option name=&quot;packagetype&quot; value=&quot;php&quot;/&gt;<br />   &lt;option name=&quot;notes&quot; value=&quot;${pkg.relnotes}&quot;/&gt;<br />   &lt;mapping name=&quot;maintainers&quot;&gt;<br />    &lt;element&gt;<br />     &lt;element key=&quot;handle&quot; value=&quot;hlellelid&quot;/&gt;<br />     &lt;element key=&quot;name&quot; value=&quot;Hans&quot;/&gt;<br />     &lt;element key=&quot;email&quot; value=&quot;hans@xmpl.org&quot;/&gt;<br />     &lt;element key=&quot;role&quot; value=&quot;lead&quot;/&gt;<br />    &lt;/element&gt;<br />   &lt;/mapping&gt;<br />&lt;/pearpkg2&gt;</pre>
+
+<h3>Attributes</h3>
+<table>
+  <thead>
+    <tr>
+      <th>Name</th>
+      <th>Type</th>
+      <th>Description</th>
+      <th>Default</th>
+      <th>Required</th>
+    </tr>
+  </thead>
+  <tbody>
+    <tr>
+      <td>name</td>
+      <td>String</td>
+      <td>
+        The name of the PEAR package.      </td>
+      <td>n/a</td>
+      <td>Yes</td>
+    </tr>
+    <tr>
+      <td>dir</td>
+      <td>String</td>
+      <td>
+        The base directory of files to add to package.      </td>
+      <td>n/a</td>
+      <td>Yes</td>
+    </tr>
+  </tbody>
+</table>
+
+<h3>Supported Nested Tags</h3>
+<ul>
+  <li>fileset</li>
+  <li>option</li>
+  <li>mapping</li>
+</ul>
+
+<h2><a name="PhpCodeSnifferTask"></a>PhpCodeSnifferTask</h2>
+<p>This task runs <a href="http://pear.php.net/package/PHP_CodeSniffer" target="_blank">PHP_CodeSniffer</a> to detect violations of a defined set of coding standards.</p>
+<h3>Attributes</h3>
+<table>
+  <thead>
+    <tr>
+      <th>Name</th>
+      <th>Type</th>
+      <th>Description</th>
+      <th>Default</th>
+      <th>Required</th>
+    </tr>
+  </thead>
+  <tbody>
+    <tr>
+      <td>standard</td>
+      <td>String</td>
+      <td>The name of the standard or an absolute path to an external standard to check for.</td>
+      <td>Generic</td>
+      <td>No</td>
+    </tr>
+    <tr>
+      <td>outputFormat</td>
+      <td>String</td>
+      <td>The output format. The <em>default</em> format is specified in the task itself. Additionally the formats of CodeSniffer can be choosen: <em>xml</em>, <em>checkstyle</em>, <em>csv</em>, <em>report</em> and <em>summary</em>. A special case is the format <em>doc</em> which generates the documentation of the standard.</td>
+      <td>default</td>
+      <td>No</td>
+    </tr>
+    <tr>
+      <td>showSniffs</td>
+      <td>Boolean</td>
+      <td>Print the list of used sniffs.</td>
+      <td>false</td>
+      <td>No</td>
+    </tr>
+    <tr>
+      <td>showWarnings</td>
+      <td>Boolean</td>
+      <td>Print warnings.</td>
+      <td>true</td>
+      <td>No</td>
+    </tr>
+    <tr>
+      <td>file</td>
+      <td>String</td>
+      <td>The file or folder to check (usally the nested tag <em>fileset</em> is used instead).</td>
+      <td>false</td>
+      <td>Either this attribute or the nested tag <em>fileset</em> is required.</td>
+    </tr>
+    <tr>
+      <td>sniffs</td>
+      <td>String</td>
+      <td>The list of allowed sniffs (separated by space, comma or semicolon). The sniffs must be part of the choosen standard.</td>
+      <td>n/a</td>
+      <td>No</td>
+    </tr>
+    <tr>
+      <td>verbosity</td>
+      <td>Integer</td>
+      <td>The verbosity level of CodeSniffer where level 1 prints progress information and level 2 prints developer debug information.</td>
+      <td>0</td>
+      <td>No</td>
+    </tr>
+    <tr>
+      <td>tabWidth</td>
+      <td>Integer</td>
+      <td>Replaces tabs with the given number of spaces. If zero no replacing is done.</td>
+      <td>0</td>
+      <td>No</td>
+    </tr>
+    <tr>
+      <td>allowedFileExtensions</td>
+      <td>String</td>
+      <td>The allowed file extensions (separated by space, comma or semicolon) when a directory is specified in the <em>file</em> attribute.</td>
+      <td>php</td>
+      <td>No</td>
+    </tr>
+    <tr>
+      <td>ignorePatterns</td>
+      <td>String</td>
+      <td>The patterns to ignore files and folders (separated by space, comma or semicolon) when a directory is specified in the <em>file</em> attribute.</td>
+      <td>n/a</td>
+      <td>No</td>
+    </tr>
+    <tr>
+      <td>noSubdirectories</td>
+      <td>Boolean</td>
+      <td>Do not recurse into subdirectories when a directory is specified in the <em>file</em> attribute.</td>
+      <td>false</td>
+      <td>No</td>
+    </tr>
+  </tbody>
+</table>
+<h3>Supported Nested Tags</h3>
+<ul>
+  <li>fileset
+    <p>Either this nested tag or the attribute <em>file</em> is required.</p>
+  </li>
+  <li>config
+    <p>The configuration parameters which are usally loaded from the CodeSniffer.conf can be set.</p>
+    <h3>Attributes</h3>
+    <table>
+      <thead>
+        <tr>
+          <th>Name</th>
+          <th>Type</th>
+          <th>Description</th>
+          <th>Default</th>
+          <th>Required</th>
+        </tr>
+      </thead>
+      <tbody>
+        <tr>
+          <td>name</td>
+          <td>String</td>
+          <td>Name of the configuration parameter. </td>
+          <td>n/a</td>
+          <td>Yes</td>
+        </tr>
+        <tr>
+          <td>value</td>
+          <td>String</td>
+          <td>Value of the configuration parameter. </td>
+          <td>n/a</td>
+          <td>Yes</td>
+        </tr>
+      </tbody>
+    </table>
+  </li>
+</ul>
+<h3>Examples</h3>
+<p>Checks all files in the directory <em>file</em> matching the allowed file extension with the <em>PEAR</em> standard and prints the <em>summary</em> report without warnings.</p>
+<pre>&lt;phpcodesniffer
+  standard=&quot;PEAR&quot;
+  format=&quot;summary&quot;
+  file=&quot;/path/to/source-files&quot;
+  allowedFileExtensions=&quot;php php5 inc&quot;/&gt;
+&lt;/phpcodesniffer&gt;
+</pre>
+<p>Checks all matching files in the directory <em>dir</em> with a custom external standard, sets the <em>zend_ca_path</em> configuration which may be required by one of the sniffs, prints a list of used sniffs and prints the <em>default</em> report with warnings.</p>
+<pre>&lt;phpunit
+  standard=&quot;/path/to/external-standard&quot;
+  showSniffs=&quot;true&quot;
+  showWarnigns=&quot;true&quot;&gt;
+  &lt;fileset dir=&quot;/path/to/source-files&quot;&gt;
+    &lt;include name=&quot;**/*.php&quot;/&gt;
+  &lt;/fileset&gt;
+  &lt;config name=&quot;zend_ca_path&quot; value=&quot;/path/to/ZendStudio/bin/ZendCodeAnalyzer&quot;&gt;
+&lt;/phpunit&gt;
+</pre>
+<p>Externally stored custom standard have to follow the same naming conventions as if they were stored in the <em>Standards</em> subdirectory of PHP_CodeSniffer itself.</p>
+
+<h2><a name="PhpDocumentorTask"></a>PhpDocumentorTask</h2>
+<p>This task runs <a href="http://www.phpdoc.org/"
+target="_blank">phpDocumentor</a>, an auto-documentation tool for PHP
+similar to Javadoc.</p>
+<h3>Attributes</h3>
+<table>
+  <thead>
+    <tr>
+      <th>Name</th>
+      <th>Type</th>
+      <th>Description</th>
+      <th>Default</th>
+      <th>Required</th>
+    </tr>
+  </thead>
+  <tbody>
+    <tr>
+      <td>title</td>
+      <td>String</td>
+      <td>Title for browser window / package index. </td>
+      <td>n/a</td>
+      <td>No</td>
+    </tr>
+
+    <tr>
+      <td>destdir</td>
+      <td>String</td>
+      <td>Destination directory for output files. </td>
+      <td>n/a</td>
+      <td rowspan="2">Yes</td>
+    </tr>
+
+    <tr>
+      <td>target</td>
+      <td>String</td>
+      <td>Alias of <em>destdir</em> ("target" is config param used by PhpDocumentor)</td>
+      <td>n/a</td>
+    </tr>
+
+    <tr>
+      <td>output</td>
+      <td>String</td>
+      <td>Output format (such as <em>HTML:Smarty:PHP</em>). </td>
+      <td>n/a</td>
+      <td>Yes</td>
+    </tr>
+
+    <tr>
+      <td>sourcecode</td>
+      <td>Boolean</td>
+      <td>Generate syntax-highlighted sourcecode file for each file parsed?</td>
+      <td>false</td>
+      <td>No</td>
+    </tr>
+
+    <tr>
+      <td>examplesdir</td>
+      <td>String</td>
+      <td>Path to directory in which to look for example documentation.</td>
+      <td>n/a</td>
+      <td>No</td>
+    </tr>
+
+    <tr>
+      <td>parseprivate</td>
+      <td>Boolean</td>
+      <td>Parse @internal and elements marked private.</td>
+      <td>false</td>
+      <td>No</td>
+    </tr>
+
+    <tr>
+      <td>javadocdesc</td>
+      <td>Boolean</td>
+      <td>JavaDoc-compliant description parsing.  Use on/off, default off (more flexibility)</td>
+      <td>false</td>
+      <td>No</td>
+    </tr>
+
+    <tr>
+      <td>quiet</td>
+      <td>Boolean</td>
+      <td>Suppress output to STDOUT.</td>
+      <td>false</td>
+      <td>No</td>
+    </tr>
+
+    <tr>
+      <td>packageoutput</td>
+      <td>String</td>
+      <td>Output documentation only for selected packages.  Use a comma-delimited list</td>
+      <td>n/a</td>
+      <td>No</td>
+    </tr>
+
+    <tr>
+      <td>ignoretags</td>
+      <td>String</td>
+      <td>Comma-separated list of tags to ignore (@package, @subpackage, @access and @ignore may not be ignored).</td>
+      <td>n/a</td>
+      <td>No</td>
+    </tr>
+
+    <tr>
+      <td>defaultpackagename</td>
+      <td>String</td>
+      <td>name to use for the default package.  If not specified, uses 'default'</td>
+      <td>n/a</td>
+      <td>No</td>
+    </tr>
+
+    <tr>
+      <td>defaultcategoryname</td>
+      <td>String</td>
+      <td>name to use for the default category.  If not specified, uses 'default'</td>
+      <td>n/a</td>
+      <td>No</td>
+    </tr>
+
+	<tr>
+      <td>pear</td>
+      <td>Boolean</td>
+      <td>Treat parse dirs as PEAR repository? (package is directory, _members are @access private)</td>
+      <td>false</td>
+      <td>No</td>
+    </tr>
+
+	<tr>
+      <td>templatebase</td>
+      <td>String</td>
+      <td>Set base dirctory of all templates for this parse.</td>
+      <td>n/a</td>
+      <td>No</td>
+    </tr>
+
+	<tr>
+      <td>undocumentedelements</td>
+      <td>Boolean</td>
+      <td>Control whether or not warnings will be shown for undocumented
+          elements. Useful for identifying classes and methods that haven't yet
+          been documented.</td>
+      <td>false</td>
+      <td>No</td>
+    </tr>
+
+	<tr>
+      <td>customtags</td>
+      <td>Boolean</td>
+      <td>Custom tags, will be recognized and put in tags[] instead of
+          unknowntags[].</td>
+      <td>false</td>
+      <td>No</td>
+    </tr>
+
+  </tbody>
+</table>
+
+<h3>Supported Nested Tags</h3>
+<ul>
+  <li>fileset - Files that should be included for parsing</li>
+  <li>projdocfileset - Files that should be treated as README/INSTALL/CHANGELOG files</li>
+</ul>
+
+<h3>Examples</h3>
+<pre>
+&lt;phpdoc title=&quot;API Documentation&quot;
+  destdir=&quot;apidocs&quot;
+  sourcecode=&quot;no&quot;
+  output=&quot;HTML:Smarty:PHP&quot;&gt;
+   &lt;fileset dir=&quot;./classes&quot;&gt;
+      &lt;include name=&quot;**/*.php&quot; /&gt;
+   &lt;/fileset&gt;
+   &lt;projdocfileset dir=&quot;.&quot;&gt;
+      &lt;include name=&quot;README&quot; /&gt;
+      &lt;include name=&quot;INSTALL&quot; /&gt;
+      &lt;include name=&quot;CHANGELOG&quot; /&gt;
+   &lt;/projdocfileset&gt;
+&lt;/phpdoc&gt;
+</pre>
+
+<h2><a name="PhpDocumentorExternalTask"></a>PhpDocumentorExternalTask</h2>
+<p>This is the same as the <a href="#PhpDocumentorTask">PhpDocumentorTask</a>
+but uses the command line application. Use this as a fallback in case you're
+running into troubles when using the phpDocumentor-library with the
+PhpDocumentorTask directly, e.g. when you're using Smarty and have Smarty in
+your library path too.</p>
+<p>This task supports everything the PhpDocumentorTask supports, differences are
+documented below.</p>
+<h3>Additional attributes</h3>
+<table>
+  <thead>
+    <tr>
+      <th>Name</th>
+      <th>Type</th>
+      <th>Description</th>
+      <th>Default</th>
+      <th>Required</th>
+    </tr>
+  </thead>
+  <tbody>
+    <tr>
+      <td>programpath</td>
+      <td>String</td>
+      <td>Path to the phpdoc executable (relative or absolute).</td>
+      <td>n/a</td>
+      <td>No</td>
+    </tr>
+
+    <tr>
+      <td>sourcepath</td>
+      <td>String</td>
+      <td>A directory to scan for parsable files. Supports multiple directories
+          separated with a comma.</td>
+      <td>n/a</td>
+      <td>Yes, if no <tt>&lt;fileset&gt;</tt> is given</td>
+    </tr>
+
+  </tbody>
+</table>
+
+<h3>Unsupported attributes</h3>
+<table>
+  <thead>
+    <tr>
+      <th>Name</th>
+      <th>Description</th>
+    </tr>
+  </thead>
+  <tbody>
+
+    <tr>
+      <td>configdir</td>
+      <td>Currently not supported. The attribute will be ignored and a
+          warning messag will be generated. The build continues (to ease when
+          changing an existing phpdoc task) however this may have unexpected
+          side effects.</td>
+    </tr>
+
+  </tbody>
+</table>
+
+<h2><a name="PhpLintTask"></a>PhpLintTask</h2>
+<p>The <em>PhpLintTask</em> checks syntax (lint) on one or more PHP source code files.</p>
+
+<h3>Attributes</h3>
+<table>
+  <thead>
+    <tr>
+      <th>Name</th>
+      <th>Type</th>
+      <th>Description</th>
+      <th>Default</th>
+      <th>Required</th>
+    </tr>
+  </thead>
+  <tbody>
+    <tr>
+      <td>file</td>
+      <td>String</td>
+      <td>Path to source file</td>
+      <td>n/a</td>
+      <td>No</td>
+    </tr>
+    <tr>
+      <td>haltonfailure</td>
+      <td>Boolean</td>
+      <td> Stop the build process if the linting process. </td>
+      <td>false</td>
+      <td>No</td>
+    </tr>
+    <tr>
+	  <td>errorproperty</td>
+      <td>String</td>
+      <td>The name of a property that will be set to contain the error string (if any).</td>
+      <td>n/a</td>
+      <td>No</td>
+    </tr>
+    <tr>
+      <td>interpreter</td>
+      <td>string</td>
+      <td>Path to alternative PHP interpreter</td>
+      <td>Defaults to the <tt>${php.command}</tt> property which is the
+          interpreter used to execute phing itself.</td>
+      <td>No</td>
+    </tr>
+  </tbody>
+</table>
+
+<h3>Supported Nested Tags</h3>
+<ul>
+  <li>fileset</li>
+</ul>
+
+<h3>Example</h3>
+<pre>
+&lt;phplint file=&quot;path/to/source.php&quot;/&gt;
+</pre>
+<p>Checking syntax of one particular source file.</p>
+<pre>
+&lt;phplint&gt;
+&nbsp;&nbsp;&lt;fileset dir=&quot;src&quot;&gt;
+&nbsp;&nbsp;&nbsp;&nbsp;&lt;include name="**/*.php"/&gt;
+&nbsp;&nbsp;&lt;/fileset&gt;
+&lt;/phplint&gt;
+</pre>
+<p>Check syntax of a fileset of source files.</p>
+<h2><a name="PHPUnitTask"></a>PHPUnitTask</h2>
+<p>This task runs testcases using the <a href="http://www.phpunit.de/" target="_blank">PHPUnit</a> framework.
+It is a functional port of the Ant <a href="http://ant.apache.org/manual/OptionalTasks/junit.html" target="_blank">JUnit</a> task.
+</p>
+<p><b>NB:</b> the identifiers <i>phpunit2</i> (PHPUnit2Task) and <i>phpunit3</i> (PHPUnit3Task) have been deprecated, but are still
+available to maintain backwards compatibility.</p>
+<h3>Attributes</h3>
+<table>
+  <thead>
+    <tr>
+      <th>Name</th>
+      <th>Type</th>
+      <th>Description</th>
+      <th>Default</th>
+      <th>Required</th>
+    </tr>
+  </thead>
+  <tbody>
+    <tr>
+      <td>printsummary</td>
+      <td>Boolean</td>
+      <td> Print one-line statistics for each testcase. </td>
+      <td>false</td>
+      <td>No</td>
+    </tr>
+    <tr>
+      <td>codecoverage</td>
+      <td>Boolean</td>
+      <td> Gather code coverage information while running tests (requires Xdebug). </td>
+      <td>false</td>
+      <td>No</td>
+    </tr>
+    <tr>
+      <td>haltonerror</td>
+      <td>Boolean</td>
+      <td> Stop the build process if an error occurs during the test run. </td>
+      <td>false</td>
+      <td>No</td>
+    </tr>
+    <tr>
+      <td>haltonfailure</td>
+      <td>Boolean</td>
+      <td> Stop the build process if a test fails (errors are considered failures as well). </td>
+      <td>false</td>
+      <td>No</td>
+    </tr>
+    <tr>
+      <td>haltonincomplete</td>
+      <td>Boolean</td>
+      <td> Stop the build process if any incomplete tests are encountered. </td>
+      <td>false</td>
+      <td>No</td>
+    </tr>
+    <tr>
+      <td>haltonskipped</td>
+      <td>Boolean</td>
+      <td> Stop the build process if any skipped tests are encountered. </td>
+      <td>false</td>
+      <td>No</td>
+    </tr>
+	<tr>
+      <td>failureproperty</td>
+      <td>String</td>
+      <td>Name of property to set (to true) on failure.</td>
+      <td>n/a</td>
+      <td>No</td>
+	</tr>
+	<tr>
+      <td>errorproperty</td>
+      <td>String</td>
+      <td>Name of property to set (to true) on error.</td>
+      <td>n/a</td>
+      <td>No</td>
+	</tr>
+	<tr>
+      <td>incompleteproperty</td>
+      <td>String</td>
+      <td>Name of property to set (to true) on incomplete tests.</td>
+      <td>n/a</td>
+      <td>No</td>
+	</tr>
+	<tr>
+      <td>skippedproperty</td>
+      <td>String</td>
+      <td>Name of property to set (to true) on skipped tests.</td>
+      <td>n/a</td>
+      <td>No</td>
+	</tr>
+  </tbody>
+</table>
+<h3>Supported Nested Tags</h3>
+<ul>
+  <li>formatter
+    <p>The results of the tests can be printed in different formats.
+    Output will always be sent to a file, unless you set the <em>usefile</em> attribute to <em>false</em>.
+    The name of the file is predetermined by the formatter and can be changed by the <em>outfile</em> attribute.</p>
+    <p>There are three predefined formatters - one prints the test results in XML format,
+    the other emits plain text. The formatter named brief will only print detailed information for testcases
+    that failed, while plain gives a little statistics line for all test cases. Custom formatters that
+    implement phing.tasks.ext.PHPUnitResultFormatter can be specified.</p>
+    <p>If you use the XML formatter, it may not include the same output that your tests have written as
+    some characters are illegal in XML documents and will be dropped.</p>
+	<h3>Attributes</h3>
+	<table>
+	  <thead>
+		<tr>
+		  <th>Name</th>
+		  <th>Type</th>
+		  <th>Description</th>
+		  <th>Default</th>
+		  <th>Required</th>
+		</tr>
+	  </thead>
+	  <tbody>
+		<tr>
+		  <td>type</td>
+		  <td>String</td>
+		  <td> Use a predefined formatter (either <em>xml</em>, <em>plain</em>, or <em>brief</em>). </td>
+		  <td>n/a</td>
+		  <td rowspan="2">One of these is required.</td>
+		</tr>
+		<tr>
+		  <td>classname</td>
+		  <td>String</td>
+		  <td> Name of a custom formatter class. </td>
+		  <td>n/a</td>
+		</tr>
+		<tr>
+		  <td>usefile</td>
+		  <td>Boolean</td>
+		  <td> Boolean that determines whether output should be sent to a file. </td>
+		  <td>true</td>
+		  <td>No</td>
+		</tr>
+		<tr>
+		  <td>todir</td>
+		  <td>String</td>
+		  <td> Directory to write the file to. </td>
+		  <td>n/a</td>
+		  <td>No</td>
+		</tr>
+		<tr>
+		  <td>outfile</td>
+		  <td>String</td>
+		  <td> Filename of the result. </td>
+		  <td>Depends on formatter</td>
+		  <td>No</td>
+		</tr>
+	  </tbody>
+	</table>
+  </li>
+  <li>batchtest
+	<p>Define a number of tests based on pattern matching.
+	<em>batchtest</em> collects the included files from any number of nested &lt;fileset&gt;s.
+	It then generates a lists of classes that are (in)directly defined by each PHP file.</p>
+	<h3>Attributes</h3>
+	<table>
+	  <thead>
+		<tr>
+		  <th>Name</th>
+		  <th>Type</th>
+		  <th>Description</th>
+		  <th>Default</th>
+		  <th>Required</th>
+		</tr>
+	  </thead>
+	  <tbody>
+		<tr>
+		  <td>exclude</td>
+		  <td>String</td>
+		  <td>A list of classes to exclude from the pattern matching. For example, when you have two baseclasses <em>BaseWebTest</em> and
+		  <em>BaseMathTest</em>, which are included a number of testcases (and thus added to the list of testclasses), you can exclude those
+		  classes from the list by typing <em>exclude=&quot;BaseWebTest BaseMathTest&quot;</em>.</td>
+		  <td>n/a</td>
+		  <td>No</td>
+		</tr>
+		<tr>
+		  <td>classpath</td>
+		  <td>String</td>
+		  <td>Used to define more paths on which - besides the PHP include_path - to look for the test files.</td>
+		  <td>n/a</td>
+		  <td>No</td>
+		</tr>
+	  </tbody>
+	</table>
+	<h3>Supported Nested Tags</h3>
+	<ul>
+	  <li>fileset</li>
+	</ul>
+  </li>
+</ul>
+<h3>Examples</h3>
+<pre>&lt;phpunit&gt;
+  &lt;formatter todir=&quot;reports&quot; type=&quot;xml&quot;/&gt;
+  &lt;batchtest&gt;
+    &lt;fileset dir=&quot;tests&quot;&gt;
+      &lt;include name=&quot;**/*Test*.php&quot;/&gt;
+      &lt;exclude name=&quot;**/Abstract*.php&quot;/&gt;
+    &lt;/fileset&gt;
+  &lt;/batchtest&gt;
+&lt;/phpunit&gt;
+</pre>
+<p>Runs all matching testcases in the directory <em>tests</em>, writing
+XML results to the directory <em>reports</em>.</p>
+<pre>&lt;phpunit codecoverage=&quot;true&quot; haltonfailure=&quot;true&quot; haltonerror=&quot;true&quot;&gt;
+  &lt;formatter type=&quot;plain&quot; usefile=&quot;false&quot;/&gt;
+  &lt;batchtest&gt;
+    &lt;fileset dir=&quot;tests&quot;&gt;
+      &lt;include name=&quot;**/*Test*.php&quot;/&gt;
+    &lt;/fileset&gt;
+  &lt;/batchtest&gt;
+&lt;/phpunit&gt;
+</pre>
+<p>
+Runs all matching testcases in the directory <em>tests</em>, gathers code coverage information, writing plain
+text results to the console. The build process is aborted if a test
+fails.</p>
+
+<p><b>Important note:</b> using a mechanism such as an "AllTests.php" file to execute testcases will bypass the Phing hooks used for reporting
+and counting, and could possibly lead to strange results. Instead, use one of more fileset's to provide a list of testcases to execute.</p>
+
+<h2><a name="PHPUnitReport"></a>PHPUnitReport</h2>
+<p>This task transforms PHPUnit xml reports to HTML using XSLT.</p>
+<p><b>NB:</b> the identifiers <i>phpunit2report</i> (PHPUnit2Report) and <i>phpunit3report</i> (PHPUnit3Report) have been deprecated, but are still
+available to maintain backwards compatibility.</p>
+<h3>Attributes</h3>
+<table>
+  <thead>
+    <tr>
+      <th>Name</th>
+      <th>Type</th>
+      <th>Description</th>
+      <th>Default</th>
+      <th>Required</th>
+    </tr>
+  </thead>
+  <tbody>
+    <tr>
+      <td>infile</td>
+      <td>String</td>
+      <td> The filename of the XML results file to use. </td>
+      <td>testsuites.xml</td>
+      <td>No</td>
+    </tr>
+    <tr>
+      <td>format</td>
+      <td>String</td>
+      <td> The format of the generated report. Must be <em>noframes</em> or
+<em>frames</em>. </td>
+      <td>noframes</td>
+      <td>No</td>
+    </tr>
+    <tr>
+      <td>styledir</td>
+      <td>String</td>
+      <td> The directory where the stylesheets are located. They must
+conform to the following conventions:
+	<ul>
+	  <li>frames format: the stylesheet must be named phpunit2-frames.xsl.</li>
+	  <li>noframes format: the stylesheet must be named phpunit2-noframes.xsl.</li>
+	</ul>
+      </td>
+      <td>n/a</td>
+      <td>Yes</td>
+    </tr>
+    <tr>
+      <td>todir</td>
+      <td>String</td>
+      <td> The directory where the files resulting from the
+transformation should be written to. </td>
+      <td></td>
+      <td>Yes</td>
+    </tr>
+  </tbody>
+</table>
+<h3>Examples</h3>
+<pre>&lt;phpunitreport infile=&quot;reports/testsuites.xml&quot; format=&quot;frames&quot; todir=&quot;reports/tests&quot; styledir=&quot;/home/phing/etc&quot;/&gt;
+</pre>
+<p>Generates a framed report in the directory <em>reports/tests</em> using
+the file <em>reports/testsuites.xml</em> as input.</p>
+
+<p><b>Important note:</b> testclasses that are not explicitly placed in a package (by using a '@package' tag in the class-level DocBlock)
+are listed under the "default" package.</p>
+
+<h2><a name="SvnCheckoutTask"></a>SvnCheckoutTask</h2>
+<p> The <em>SvnCheckoutTask</em> checks out a Subversion repository to a local directory.</p>
+<h3>Examples</h3>
+
+<pre>&lt;svncheckout
+   svnpath=&quot;/usr/bin/svn&quot;
+   username="anony"
+   password="anony"
+   nocache="true"
+   repositoryurl=&quot;svn://localhost/project/trunk/&quot;
+   todir=&quot;/home/user/svnwc&quot;/&gt;
+</pre>
+
+<pre>&lt;svncheckout
+   svnpath=&quot;C:/Subversion/bin/svn.exe&quot;
+   repositoryurl=&quot;svn://localhost/project/trunk/&quot;
+   todir=&quot;C:/projects/svnwc&quot;/&gt;
+</pre>
+
+<h3>Attributes</h3>
+<table>
+  <thead>
+    <tr>
+      <th>Name</th>
+      <th>Type</th>
+      <th>Description</th>
+      <th>Default</th>
+      <th>Required</th>
+    </tr>
+  </thead>
+  <tbody>
+    <tr>
+      <td>svnpath</td>
+      <td>String</td>
+      <td>Path to Subversion binary</td>
+      <td>/usr/bin/svn</td>
+      <td>No</td>
+    </tr>
+    <tr>
+      <td>repositoryurl</td>
+      <td>String</td>
+      <td>URL of SVN repository</td>
+      <td>none</td>
+      <td>Yes</td>
+    </tr>
+    <tr>
+      <td>username</td>
+      <td>String</td>
+      <td>A username used to connect to the SVN server</td>
+      <td>none</td>
+      <td>No</td>
+    </tr>
+    <tr>
+      <td>password</td>
+      <td>String</td>
+      <td>A password used to connect to the SVN server</td>
+      <td>none</td>
+      <td>No</td>
+    </tr>
+    <tr>
+      <td>nocache</td>
+      <td>String</td>
+      <td>Connection credentials will not be cached</td>
+      <td>boolean</td>
+      <td>No</td>
+    </tr>
+    <tr>
+      <td>todir</td>
+      <td>String</td>
+      <td>Path to export to</td>
+      <td>none</td>
+      <td>Yes</td>
+    </tr>
+    <tr>
+      <td>recursive</td>
+      <td>Boolean</td>
+      <td>Recursive behavior</td>
+      <td>true</td>
+      <td>No</td>
+    </tr>
+    <tr>
+      <td>ignoreexternals</td>
+      <td>Boolean</td>
+      <td>Ignore externals definitions</td>
+      <td>false</td>
+      <td>No</td>
+    </tr>
+  </tbody>
+</table>
+
+<h2><a name="SvnExportTask"></a>SvnExportTask</h2>
+<p> The <em>SvnExportTask</em> exports a Subversion repository to a local directory.</p>
+<h3>Examples</h3>
+
+<pre>&lt;svnexport
+   svnpath=&quot;/usr/bin/svn&quot;
+   username="anony"
+   password="anony"
+   force="true"
+   nocache="true"
+   repositoryurl=&quot;svn://localhost/project/trunk/&quot;
+   todir=&quot;/home/user/svnwc&quot;/&gt;
+</pre>
+
+<pre>&lt;svnexport
+   svnpath=&quot;C:/Subversion/bin/svn.exe&quot;
+   repositoryurl=&quot;svn://localhost/project/trunk/&quot;
+   todir=&quot;C:/projects/svnwc&quot;/&gt;
+</pre>
+
+<h3>Attributes</h3>
+<table>
+  <thead>
+    <tr>
+      <th>Name</th>
+      <th>Type</th>
+      <th>Description</th>
+      <th>Default</th>
+      <th>Required</th>
+    </tr>
+  </thead>
+  <tbody>
+    <tr>
+      <td>svnpath</td>
+      <td>String</td>
+      <td>Path to Subversion binary</td>
+      <td>/usr/bin/svn</td>
+      <td>No</td>
+    </tr>
+    <tr>
+      <td>repositoryurl</td>
+      <td>String</td>
+      <td>URL of SVN repository</td>
+      <td>none</td>
+      <td>Yes</td>
+    </tr>
+    <tr>
+      <td>username</td>
+      <td>String</td>
+      <td>A username used to connect to the SVN server</td>
+      <td>none</td>
+      <td>No</td>
+    </tr>
+    <tr>
+      <td>password</td>
+      <td>String</td>
+      <td>A password used to connect to the SVN server</td>
+      <td>none</td>
+      <td>No</td>
+    </tr>
+    <tr>
+      <td>force</td>
+      <td>String</td>
+      <td>Force overwrite files if they already exist</td>
+      <td>boolean</td>
+      <td>No</td>
+    </tr>
+    <tr>
+      <td>nocache</td>
+      <td>String</td>
+      <td>Connection credentials will not be cached</td>
+      <td>boolean</td>
+      <td>No</td>
+    </tr>
+    <tr>
+      <td>todir</td>
+      <td>String</td>
+      <td>Path to export to</td>
+      <td>none</td>
+      <td>Yes</td>
+    </tr>
+    <tr>
+      <td>recursive</td>
+      <td>Boolean</td>
+      <td>Recursive behavior</td>
+      <td>true</td>
+      <td>No</td>
+    </tr>
+    <tr>
+      <td>ignoreexternals</td>
+      <td>Boolean</td>
+      <td>Ignore externals definitions</td>
+      <td>false</td>
+      <td>No</td>
+    </tr>
+  </tbody>
+</table>
+
+<h2><a name="SvnLastRevisionTask"></a>SvnLastRevisionTask</h2>
+<p> The <em>SvnLastRevisionTask</em> stores the number of the last revision of a Subversion workingcopy in a property.</p>
+<h3>Examples</h3>
+
+<pre>&lt;svnlastrevision
+   svnpath=&quot;/usr/bin/svn&quot;
+   workingcopy=&quot;/home/user/svnwc&quot;
+   propertyname=&quot;svn.lastrevision&quot;/&gt;
+</pre>
+
+<pre>&lt;svnlastrevision
+   svnpath=&quot;C:/Subversion/bin/svn.exe&quot;
+   workingcopy=&quot;C:/projects/svnwc&quot;
+   propertyname=&quot;svn.lastrevision&quot;/&gt;
+</pre>
+
+<h3>Attributes</h3>
+<table>
+  <thead>
+    <tr>
+      <th>Name</th>
+      <th>Type</th>
+      <th>Description</th>
+      <th>Default</th>
+      <th>Required</th>
+    </tr>
+  </thead>
+  <tbody>
+    <tr>
+      <td>svnpath</td>
+      <td>String</td>
+      <td>Path to Subversion binary</td>
+      <td>/usr/bin/svn</td>
+      <td>No</td>
+    </tr>
+    <tr>
+      <td>workingcopy</td>
+      <td>String</td>
+      <td>Working copy directory</td>
+      <td>none</td>
+      <td>Yes</td>
+    </tr>
+    <tr>
+      <td>propertyname</td>
+      <td>String</td>
+      <td>Name of property to use</td>
+      <td>svn.lastrevision</td>
+      <td>No</td>
+    </tr>
+  </tbody>
+</table>
+
+<h2><a name="SvnUpdateTask"></a>SvnUpdateTask</h2>
+<p> The <em>SvnCheckoutTask</em> updates a local directory.</p>
+<h3>Examples</h3>
+
+<pre>&lt;svnupdate
+   svnpath=&quot;/usr/bin/svn&quot;
+   username="anony"
+   password="anony"
+   nocache="true"
+   todir=&quot;/home/user/svnwc&quot;/&gt;
+</pre>
+
+<pre>&lt;svnupdate
+   svnpath=&quot;C:/Subversion/bin/svn.exe&quot;
+   todir=&quot;C:/projects/svnwc&quot;/&gt;
+</pre>
+
+<h3>Attributes</h3>
+<table>
+  <thead>
+    <tr>
+      <th>Name</th>
+      <th>Type</th>
+      <th>Description</th>
+      <th>Default</th>
+      <th>Required</th>
+    </tr>
+  </thead>
+  <tbody>
+    <tr>
+      <td>svnpath</td>
+      <td>String</td>
+      <td>Path to Subversion binary</td>
+      <td>/usr/bin/svn</td>
+      <td>No</td>
+    </tr>
+    <tr>
+      <td>username</td>
+      <td>String</td>
+      <td>A username used to connect to the SVN server</td>
+      <td>none</td>
+      <td>No</td>
+    </tr>
+    <tr>
+      <td>password</td>
+      <td>String</td>
+      <td>A password used to connect to the SVN server</td>
+      <td>none</td>
+      <td>No</td>
+    </tr>
+    <tr>
+      <td>nocache</td>
+      <td>Boolean</td>
+      <td>Connection credentials will not be cached</td>
+      <td>false</td>
+      <td>No</td>
+    </tr>
+    <tr>
+      <td>todir</td>
+      <td>String</td>
+      <td>Path to export to</td>
+      <td>none</td>
+      <td>Yes</td>
+    </tr>
+    <tr>
+      <td>recursive</td>
+      <td>Boolean</td>
+      <td>Recursive behavior</td>
+      <td>true</td>
+      <td>No</td>
+    </tr>
+    <tr>
+      <td>ignoreexternals</td>
+      <td>Boolean</td>
+      <td>Ignore externals definitions</td>
+      <td>false</td>
+      <td>No</td>
+    </tr>
+  </tbody>
+</table>
+
+<h2><a name="TarTask"></a>TarTask</h2>
+<p> The <em>TarTask</em> creates a tarball from a fileset or directory.</p>
+
+<h3>Examples</h3>
+<pre>&lt;tar destfile=&quot;phing.tar&quot; compression=&quot;gzip&quot;&gt;
+ &lt;fileset dir=&quot;.&quot;&gt;
+	 &lt;include name=&quot;**/**&quot; /&gt;
+ &lt;/fileset&gt;
+&lt;/tar&gt;
+</pre>
+
+<p>The above example uses a fileset to determine which files to include in
+the archive.</p>
+
+<pre>&lt;tar destfile=&quot;phing.tar&quot; basedir=&quot;.&quot; compression=&quot;gzip&quot;/&gt;</pre>
+
+<p>The second example uses the basedir attribute to include the contents of that directory (including
+subdirectories) in the archive.</p>
+
+<h3>Attributes</h3>
+<table>
+  <thead>
+    <tr>
+      <th>Name</th>
+      <th>Type</th>
+      <th>Description</th>
+      <th>Default</th>
+      <th>Required</th>
+    </tr>
+  </thead>
+  <tbody>
+    <tr>
+      <td>destfile</td>
+      <td>String</td>
+      <td>Tarball filename</td>
+      <td>n/a</td>
+      <td>Yes</td>
+    </tr>
+    <tr>
+      <td>basedir</td>
+      <td>String</td>
+      <td>Base directory to tar (if no fileset specified, entire directory contents
+        will be included in tar)</td>
+      <td>none</td>
+      <td>No</td>
+    </tr>
+    <tr>
+      <td>compression</td>
+      <td>String</td>
+      <td>Type of compression to use (gzip, bzip2, none)</td>
+      <td>none</td>
+      <td>No</td>
+    </tr>
+  </tbody>
+</table>
+
+<p><b>Important note #1:</b> files are not replaced if they are already present in the
+archive.</p>
+
+<p><b>Important note #2:</b> using basedir and fileset simultaneously can result in
+strange contents in the archive.</p>
+
+<h3>Supported Nested Tags</h3>
+<ul>
+  <li>fileset</li>
+</ul>
+
+<h2><a name="UntarTask"></a>UntarTask</h2>
+<p> The <em>UntarTask</em> unpacks one or more tar archives.</p>
+
+<h3>Examples</h3>
+<pre>&lt;untar file=&quot;testtar.tar.gz&quot; todir=&quot;dest&quot;&gt;
+  &lt;fileset dir=&quot;.&quot;&gt;
+    &lt;include name=&quot;*.tar.gz&quot;/&gt;
+    &lt;include name=&quot;*.tar&quot;/&gt;
+  &lt;/fileset&gt;
+&lt;/untar&gt;
+</pre>
+
+<h3>Attributes</h3>
+<table>
+  <thead>
+    <tr>
+      <th>Name</th>
+      <th>Type</th>
+      <th>Description</th>
+      <th>Default</th>
+      <th>Required</th>
+    </tr>
+  </thead>
+  <tbody>
+    <tr>
+      <td>file</td>
+      <td>String</td>
+      <td>Archive filename</td>
+      <td>n/a</td>
+      <td>No</td>
+    </tr>
+    <tr>
+      <td>todir</td>
+      <td>String</td>
+      <td>Directory to unpack the archive(s) to</td>
+      <td>none</td>
+      <td>Yes</td>
+    </tr>
+  </tbody>
+</table>
+
+<h3>Supported Nested Tags</h3>
+<ul>
+  <li>fileset</li>
+</ul>
+
+<h2><a name="UnzipTask"></a>UnzipTask</h2>
+<p> The <em>UnzipTask</em> unpacks one or more ZIP archives.</p>
+
+<h3>Examples</h3>
+<pre>&lt;unzip file=&quot;testzip.zip&quot; todir=&quot;dest&quot;&gt;
+  &lt;fileset dir=&quot;.&quot;&gt;
+    &lt;include name=&quot;*.zip&quot;/&gt;
+  &lt;/fileset&gt;
+&lt;/unzip&gt;
+</pre>
+
+<h3>Attributes</h3>
+<table>
+  <thead>
+    <tr>
+      <th>Name</th>
+      <th>Type</th>
+      <th>Description</th>
+      <th>Default</th>
+      <th>Required</th>
+    </tr>
+  </thead>
+  <tbody>
+    <tr>
+      <td>file</td>
+      <td>String</td>
+      <td>Archive filename</td>
+      <td>n/a</td>
+      <td>No</td>
+    </tr>
+    <tr>
+	  <td>todir</td>
+      <td>String</td>
+      <td>Directory to unpack the archive(s) to</td>
+      <td>none</td>
+      <td>Yes</td>
+    </tr>
+  </tbody>
+</table>
+
+<h3>Supported Nested Tags</h3>
+<ul>
+  <li>fileset</li>
+</ul>
+
+<h2><a name="XmlLintTask"></a>XmlLintTask</h2>
+<p>The <em>XmlLintTask</em> checks syntax (lint) one or more XML files against an XML Schema Definition.</p>
+
+<h3>Attributes</h3>
+<table>
+  <thead>
+    <tr>
+      <th>Name</th>
+      <th>Type</th>
+      <th>Description</th>
+      <th>Default</th>
+      <th>Required</th>
+    </tr>
+  </thead>
+  <tbody>
+    <tr>
+      <td>schema</td>
+      <td>String</td>
+      <td>Path to XSD file</td>
+      <td>n/a</td>
+      <td>Yes</td>
+    </tr>
+    <tr>
+      <td>file</td>
+      <td>String</td>
+      <td>Path to XML file</td>
+      <td>n/a</td>
+      <td>No</td>
+    </tr>
+  </tbody>
+</table>
+
+<h3>Supported Nested Tags</h3>
+<ul>
+  <li>fileset</li>
+</ul>
+
+<h3>Example</h3>
+<pre>
+&lt;xmllint schema=&quot;schema.xsd&quot; file=&quot;config.xml&quot;/&gt;
+</pre>
+<p>Validate one XML file against one XSD file.</p>
+<pre>
+&lt;xmllint schema=&quot;schema.xsd&quot;&gt;
+&nbsp;&nbsp;&lt;fileset dir=&quot;.&quot;&gt;
+&nbsp;&nbsp;&nbsp;&nbsp;&lt;include name="**/config.xml"/&gt;
+&nbsp;&nbsp;&lt;/fileset&gt;
+&lt;/xmllint&gt;
+</pre>
+<p>Validate more XML files against one XSD file.</p>
+
+<h2><a name="ZendCodeAnalyzerTask"></a>ZendCodeAnalyzerTask</h2>
+<p>The <em>ZendCodeAnalyzerTask</em> analyze PHP source files using the Zend Code Analyzer tool that ships with all versions of Zend Studio.</p>
+
+<h3>Attributes</h3>
+<table>
+  <thead>
+    <tr>
+      <th>Name</th>
+      <th>Type</th>
+      <th>Description</th>
+      <th>Default</th>
+      <th>Required</th>
+    </tr>
+  </thead>
+  <tbody>
+    <tr>
+      <td>analyzerPath</td>
+      <td>String</td>
+      <td>Path to Zend Code Analyzer binary</td>
+      <td>n/a</td>
+      <td>Yes</td>
+    </tr>
+    <tr>
+      <td>file</td>
+      <td>String</td>
+      <td>Path to PHP source file</td>
+      <td>n/a</td>
+      <td>No</td>
+    </tr>
+    <tr>
+      <td>disable</td>
+      <td>String</td>
+      <td>Disable warnings seperated by comma</td>
+      <td>n/a</td>
+      <td>No</td>
+    </tr>
+    <tr>
+      <td>enable</td>
+      <td>String</td>
+      <td>Enable warnings separated by comma</td>
+      <td>n/a</td>
+      <td>No</td>
+    </tr>
+  </tbody>
+</table>
+
+<h3>Supported Nested Tags</h3>
+<ul>
+  <li>fileset</li>
+</ul>
+
+<h3>Example</h3>
+<pre>
+&lt;analyze analyzerPath=&quot;/usr/local/Zend/ZendStudioClient-5.1.0/bin/ZendCodeAnalyzer&quot; file=&quot;SomeClass.php&quot;/&gt;
+</pre>
+<p>Analyze one PHP source file with all default warnings enabled.</p>
+<pre>
+&lt;analyze analyzerPath=&quot;/usr/local/Zend/ZendStudioClient-5.1.0/bin/ZendCodeAnalyzer&quot; disable=&quot;var-ref-notmodified,if-if-else&quot;&gt;
+&nbsp;&nbsp;&lt;fileset dir=&quot;.&quot;&gt;
+&nbsp;&nbsp;&nbsp;&nbsp;&lt;include name="**/*.php"/&gt;
+&nbsp;&nbsp;&lt;/fileset&gt;
+&lt;/analyze&gt;
+</pre>
+<p>Analyze a set of PHP source files and disable a few warnings.</p>
+
+<h2><a name="ZipTask"></a>ZipTask</h2>
+<p> The <em>ZipTask</em> creates a .zip archive from a fileset or directory.</p>
+
+<h3>Examples</h3>
+<pre>&lt;zip destfile=&quot;phing.zip&quot;&gt;
+ &lt;fileset dir=&quot;.&quot;&gt;
+	 &lt;include name=&quot;**/**&quot; /&gt;
+ &lt;/fileset&gt;
+&lt;/zip&gt;
+</pre>
+
+<p>The above example uses a fileset to determine which files to include in
+the archive.</p>
+
+<pre>&lt;zip destfile=&quot;phing.zip&quot; basedir=&quot;.&quot;/&gt;</pre>
+
+<p>The second example uses the basedir attribute to include the contents of that directory (including
+subdirectories) in the archive.</p>
+
+<h3>Example</h3>
+
+<h3>Attributes</h3>
+<table>
+  <thead>
+    <tr>
+      <th>Name</th>
+      <th>Type</th>
+      <th>Description</th>
+      <th>Default</th>
+      <th>Required</th>
+    </tr>
+  </thead>
+  <tbody>
+    <tr>
+      <td>destfile</td>
+      <td>String</td>
+      <td>.ZIP filename</td>
+      <td>n/a</td>
+      <td>Yes</td>
+    </tr>
+    <tr>
+      <td>basedir</td>
+      <td>String</td>
+      <td>Base directory to zip (if no fileset specified, entire directory contents
+        will be included in the archive)</td>
+      <td>none</td>
+      <td>No</td>
+    </tr>
+  </tbody>
+</table>
+
+<p><b>Important note:</b> using basedir and fileset simultaneously can result in
+strange contents in the archive.</p>
+
+<h3>Supported Nested Tags</h3>
+<ul>
+  <li>fileset</li>
+</ul>
+
+</body>
+</html>
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/docs/phing_guide/book/chapters/appendixes/AppendixD-CoreTypes.html
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/docs/phing_guide/book/chapters/appendixes/AppendixD-CoreTypes.html	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/docs/phing_guide/book/chapters/appendixes/AppendixD-CoreTypes.html	(revision 19)
@@ -0,0 +1,183 @@
+<!--
+-File         $Id: AppendixD-CoreTypes.html 269 2007-10-28 02:42:44Z hans $
+-License      GNU FDL (http://www.gnu.org/copyleft/fdl.html)
+-Copyright    2002, turing
+-Author       alex black, enigma@turingstudio.com
+-->
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/2000/REC-xhtml1-20000126/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+  <head>
+    <title>Phing Guide - Core Types</title>
+    <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
+    <link rel="Stylesheet" rev="Stylesheet" href="../../css/Documentation.css" type="text/css" media="All" charset="iso-8859-1" />
+  </head>
+  <body>
+<h1><a name="ComplexCoreTypes"></a>Appendix D: Core Types</h1>
+
+<p>This appendix contains a reference of the system <em>data types</em> contained
+  in Phing.</p>
+<h2><a name="FileList"></a>FileList</h2>
+<p>FileLists offer a way to represent a specific list of files. Unlike FileSets,
+  FileLists may contain files that do not exist on the filesystem. Also, FileLists
+  can represent files in a specific order -- whereas FileSets represent files
+  in whichever order they are returned by the filesystem.</p>
+<h3>Usage Examples</h3>
+<pre>&lt;filelist dir=&quot;/etc&quot; files=&quot;httpd/conf/httpd.conf,php.ini&quot;/&gt;
+</pre>
+<p>Or you can use a <em>listfile</em>, which is expected to contain one filename
+  per line:</p>
+<pre>&lt;filelist dir=&quot;conf/&quot; listfile=&quot;ini_files.txt&quot;/&gt;
+</pre>
+<p> This will grab each file as listed in <em>ini_files.txt</em>. This can be
+  useful if one task compiles a list of files to process and another task needs
+  to read in that list and perform some action to those files.</p>
+<h3>Attributes</h3>
+<table>
+  <caption>
+  Attributes for the <em>&lt;fileset&gt;</em> tag
+  </caption>
+  <thead>
+    <tr>
+      <th>Name</th>
+      <th>Type</th>
+      <th>Description</th>
+      <th>Default</th>
+      <th>Required</th>
+    </tr>
+  </thead>
+  <tbody>
+    <tr>
+      <td>dir</td>
+      <td>String</td>
+      <td> The directory, to which the paths given in <em>files </em>or <em>listfile</em>
+        are relative. </td>
+      <td>n/a</td>
+      <td>Yes</td>
+    </tr>
+	    <tr>
+      <td>files</td>
+      <td>String</td>
+      <td> Comma or space-separated list of files.</td>
+      <td>n/a</td>
+      <td>Yes (or <em>listfile)</em></td>
+    </tr>
+	<tr>
+      <td>listfile</td>
+      <td>String</td>
+      <td> A text file with one filename per line.</td>
+      <td>n/a</td>
+      <td>Yes (or <em>files)</em></td>
+    </tr>
+  </tbody>
+</table>
+<h2><a name="Fileset"></a>FileSet</h2>
+
+<p>Filesets offer a easy and straigtforward way to include files.
+You can include/exclude files in/from a fileset using the
+<em>&lt;include&gt;</em>/<em>&lt;exclude&gt;</em> tags. In patterns,
+one asterisk (<strong>*</strong>) maps to a part of a file/directory
+name within a directory level. Two asterisks (<strong>**</strong>)
+may include above the &quot;border&quot; of the directory separator.
+</p>
+
+<h3>Examples</h3>
+<ul>
+  <li><em>test*.xml</em> will include <em>test_42.xml</em>,
+      but it will not include <em>test/some.xml</em>.</li>
+  <li><em>test**.xml</em> fits to <em>test_42.xml</em> as well
+      as to <em>test/bla.xml</em>, for example.</li>
+  <li><em>**/*.ent.xml</em> fits to all files that end with
+      <em>ent.xml</em> in all subdirectories of the directory
+      specified with the <em>dir</em> attribute of the
+      <em>&lt;fileset&gt;</em> tag. However, it will not include
+      any files that are directly in the base directory of the
+      file set.</li>
+</ul>
+
+<h3>Usage Example</h3>
+<pre>&lt;fileset dir=&quot;/etc&quot; &gt;
+  &lt;include name=&quot;httpd/**&quot; /&gt;
+  &lt;include name=&quot;php.ini&quot; /&gt;
+&lt;/fileset&gt;
+</pre>
+<p>
+This will include the apache configuration and PHP configuration
+file from <em>/etc</em>.
+</p>
+
+<h3>Attributes</h3>
+<table>
+  <caption>Attributes for the <em>&lt;fileset&gt;</em> tag</caption>
+  <thead>
+    <tr>
+      <th>Name</th>
+      <th>Type</th>
+      <th>Description</th>
+      <th>Default</th>
+      <th>Required</th>
+    </tr>
+  </thead>
+  <tbody>
+    <tr>
+      <td>dir</td>
+      <td>String</td>
+      <td>
+        The directory, the paths given in <em>include</em>/<em>exclude</em>
+        are relative to.
+      </td>
+      <td>n/a</td>
+      <td>Yes</td>
+    </tr>
+  </tbody>
+</table>
+<p> The only tags that are supported by <em>Fileset</em> are the <em>&lt;include&gt;</em>
+  and the <em>&lt;exclude&gt;</em> tags. These tags must have a <em>name</em>
+  attribute that contains the pattern to include/exclude. </p>
+<h2><a name="Path"></a>Path / Classpath</h2>
+<p>The Path data type can be used to respresent path structures. In many cases
+  the path type will be used for nested &lt;classpath&gt; tags. E.g.</p>
+<pre>&lt;path id=&quot;project.class.path&quot;&gt;
+  &lt;pathelement dir=&quot;lib/&quot;/&gt;
+  &lt;pathelement dir=&quot;ext/&quot;/&gt;
+&lt;/path&gt;
+
+&lt;target name=&quot;blah&quot;&gt;
+  &lt;taskdef name=&quot;mytask&quot; path=&quot;myapp.phing.tasks.MyTask&quot;&gt;
+    &lt;classpath refid=&quot;project.class.path&quot;/&gt;
+  &lt;/taskdef&gt;<br />&lt;/target&gt;</pre>
+<table>
+  <caption>
+  Attributes for <em>&lt;path&gt;</em> tag
+  </caption>
+  <thead>
+    <tr>
+      <th>Name</th>
+      <th>Type</th>
+      <th>Description</th>
+      <th>Default</th>
+      <th>Required</th>
+    </tr>
+  </thead>
+  <tbody>
+    <tr>
+      <td>dir</td>
+      <td>String</td>
+      <td>Specific path to directory</td>
+      <td>n/a</td>
+      <td>No</td>
+    </tr>
+    <tr>
+      <td>path</td>
+      <td>String</td>
+      <td>A path (which contains multiple locations separated by path.separator)
+        to add.</td>
+      <td>n/a</td>
+      <td>No</td>
+    </tr>
+  </tbody>
+</table>
+<h3>Nested Tags</h3>
+<p> The <em>&lt;path&gt; </em>tag supports nested <em>&lt;fileset&gt;</em> and
+  <em>&lt;dirset&gt;</em> tags.</p>
+    </body>
+</html>
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/docs/phing_guide/book/chapters/appendixes/AppendixD2-CoreFilters.html
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/docs/phing_guide/book/chapters/appendixes/AppendixD2-CoreFilters.html	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/docs/phing_guide/book/chapters/appendixes/AppendixD2-CoreFilters.html	(revision 19)
@@ -0,0 +1,620 @@
+<!--
+-File         $Id$
+-License      GNU FDL (http://www.gnu.org/copyleft/fdl.html)
+-Copyright    2002, turing
+-Author       alex black, enigma@turingstudio.com
+-->
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/2000/REC-xhtml1-20000126/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+  <head>
+    <title>Phing Guide - Core Filters</title>
+    <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
+    <link rel="Stylesheet" rev="Stylesheet" href="../../css/Documentation.css" type="text/css" media="All" charset="iso-8859-1" />
+  </head>
+  <body>
+  
+<h1><a name="CoreFilters"></a>Appendix D-2: Core Filters</h1>
+
+<p>Filters are a subset of Phing <em>data types</em> which provide for the transformation of file contents
+during the operation of another task. For example, a filter might replace tokens in a file as part of a copy task.</p>
+
+<p>Filters have to be defined within a <em>&lt;filterchain&gt;</em> context to work. Example:</p>
+
+<pre>
+&lt;filterchain&gt;
+  &lt;expandproperties /&gt;
+&lt;/filterchain&gt;
+</pre>
+<p> There are two ways to use a filter: System filters (the ones shipped with
+  Phing) can be used with their own tag name, such as <em>&lt;xsltfilter</em>&gt;,
+  &lt;<em>expandpropertyfilter</em>&gt; or <em>&lt;tabtospaces</em>&gt;. User-defined
+  filters can use the way is to use the <em>&lt;filterreader&gt;</em> tag.</p>
+
+<h2><a name="PhingFilterReader"></a>PhingFilterReader</h2>
+<p> The PhingFilterReader is used when you want to use filters that are not directly
+  available through their own tag. Example: </p>
+<pre>
+&lt;filterchain&gt;
+  &lt;filterreader classname=&quot;phing.filter.ReplaceTokens&quot;&gt;
+    &lt;-- other way to set attributes --&gt;
+    &lt;param name=&quot;begintoken&quot; value=&quot;@@&quot; /&gt;
+    &lt;param name=&quot;endtoken&quot; value=&quot;@@&quot; /&gt;
+
+    &lt;-- other way to set nested tags --&gt;
+    &lt;param type=&quot;token&quot; key=&quot;bar&quot; value=&quot;foo&quot; /&gt;
+  &lt;/filterreader&gt;
+&lt;/filterchain&gt;
+</pre>
+<p> In the <em>filterreader</em> tag you have to specify the path the class is
+  in. The <em>FilterReader</em> will then load this class and pass the parameters
+  to the loaded filter. There are two types of parameters: First, you can pass
+  &quot;normal&quot; parameters to the loaded filter. That means, you can pass
+  parameters as if they were attributes. If you want to do this, you only specify
+  the <em>name</em> and <em>value</em> attributes in the <em>param</em> tag. You
+  can also pass nested elements to the filter. Then, you have to specify the <em>type</em>
+  attribute. This attribute specifies the name of the nested tag. </p>
+<p>The result of the example above is identical with the following code: </p>
+<pre>
+&lt;filterchain&gt;
+  &lt;replacetokens begintoken=&quot;@@&quot; endtoken=&quot;@@&quot;&gt;
+    &lt;token key=&quot;bar&quot; value=&quot;foo&quot; />
+  &lt;/replacetokens&gt;
+&lt;/filterchain&gt;</pre>
+<h3>Attributes</h3>
+<table>
+  <caption>
+  Attributes for <em>&lt;filterreader&gt;</em>
+  </caption>
+  <thead>
+    <tr>
+      <th>Name</th>
+      <th>Type</th>
+      <th>Description</th>
+      <th>Default</th>
+      <th>Required</th>
+    </tr>
+  </thead>
+  <tbody>
+    <tr>
+      <td>classname</td>
+      <td>String</td>
+      <td> Name of class to use (in dot-path notation).</td>
+      <td>n/a</td>
+      <td>Yes</td>
+    </tr>
+    <tr>
+      <td>classpath</td>
+      <td>String</td>
+      <td> The classpath to use when including classes. This is added to PHP's
+        include_path.</td>
+      <td>n/a</td>
+      <td>No</td>
+    </tr>
+    <tr>
+      <td>classpathref</td>
+      <td>String</td>
+      <td> Reference to classpath to use when including classes. This is added
+        to PHP's include_path.</td>
+      <td>n/a</td>
+      <td>No</td>
+    </tr>
+  </tbody>
+</table>
+<h3>Nested Tags</h3>
+<p> The <em>PhingFilterReader</em> supports nested &lt;classpath&gt;.</p>
+<h3>Advanced</h3>
+<p>In order to support the &lt;filterreader ... /&gt; sytax, your class must
+extend the BaseParamFilterReader class.  Most of the filters that are bundled
+with Phing can be invoked using this syntax.  The noteable exception (at time of
+writing) is the ReplaceRegexp filter, which expects find/replace parameters that do not fit the
+name/value mold. For this reason, you must always use the shorthand &lt;replaceregexp .../&gt; to invoke
+this filter.</p>
+
+<h2><a name="ExpandProperties"></a>ExpandProperties</h2>
+<p>
+The ExpandProperties simply replaces property names with their
+property values. For example, if you have the following in your
+build file:
+</p>
+<pre>
+&lt;property name=&quot;description.txt&quot; value=&quot;This is a text file&quot; /&gt;
+
+&lt;copy todir=&quot;/tmp&quot;&gt;
+  &lt;filterchain&gt;
+    &lt;expandproperties /&gt;
+  &lt;/filterchain&gt;
+
+  &lt;fileset dir=&quot;.&quot;&gt;
+    &lt;include name=&quot;**&quot; /&gt;
+  &lt;/fileset&gt;
+&lt;/copy&gt;
+</pre>
+<p>
+And the string <em>${description.txt}</em> it will be replaced by
+<em>This is a text file</em>.
+</p>
+
+<h2><a name="HeadFilter"></a>HeadFilter</h2>
+<p>
+This filter reads the first <em>n</em> lines of a file; the others
+are not further passed through the filter chain. Usage example:
+</p>
+<pre>
+&lt;filterchain&gt;
+  &lt;headfilter lines=&quot;20&quot; /&gt;
+&lt;/filterchain&gt;
+</pre>
+<h3>Attributes</h3>
+<table>
+  <caption>
+  Attributes for the <em>&lt;headfilter&gt; </em>tag
+  </caption>
+  <thead>
+    <tr>
+      <th>Name</th>
+      <th>Type</th>
+      <th>Description</th>
+      <th>Default</th>
+      <th>Required</th>
+    </tr>
+  </thead>
+  <tbody>
+    <tr>
+      <td>lines</td>
+      <td>Integer</td>
+      <td>
+        Number of lines to read.
+      </td>
+      <td>10</td>
+      <td>No</td>
+    </tr>
+  </tbody>
+</table>
+
+<h2><a name="LineContains"></a>Line Contains</h2>
+<p>
+This filter is only &quot;permeable&quot; for lines that contain
+the expression given as parameter. For example, the following
+filterchain would only let all the lines pass that contain
+<em>class</em>:
+</p>
+<pre>
+&lt;filterchain&gt;
+  &lt;linecontains&gt;
+    &lt;contains value=&quot;class&quot; /&gt;
+  &lt;/linecontains&gt;
+&lt;/filterchain&gt;
+</pre>
+
+<h3>Nested Tags</h3>
+
+<p>
+The <em>linecontains</em> tag must contain one or more <em>contains</em>
+tags. Latter must have a <em>value</em> attribute that has to be set
+to the string the line has to contain to be let through.
+</p>
+
+<h2><a name="LineContainsRegexp"></a>LineContainsRegexp</h2>
+<p>
+This filter is similar to <a href="#LineContains">LineContains</a>
+but you can specify regular expressions instead of simple strings.
+</p>
+<pre>
+&lt;filterchain&gt;
+  &lt;linecontainsregexp&gt;
+    &lt;regexp pattern=&quot;foo(.*)bar&quot; /&gt;
+  &lt;/linecontainsregexp&gt;
+&lt;/filterchain&gt;
+</pre>
+
+<h3>Nested Tags</h3>
+
+<p>
+The <em>LineContains</em> filter has to contain at least one <em>regexp</em>
+tag. This must have a <em>pattern</em> attribute that is set to a
+regular expression.
+</p>
+
+<h2><a name="PrefixLines"></a>PrefixLines</h2>
+<p>
+This filter adds a prefix to every line. The following example will add
+the string <em>foo: </em> in front of every line.
+</p>
+<pre>
+&lt;filterchain&gt;
+  &lt;prefixlines prefix=&quot;foo: &quot; /&gt;
+&lt;/filterchain&gt;
+</pre>
+<h3>Attributes</h3>
+<table>
+  <caption>
+  Attributes for the <em>&lt;prefixlines&gt;</em> tag
+  </caption>
+  <thead>
+    <tr>
+      <th>Name</th>
+      <th>Type</th>
+      <th>Description</th>
+      <th>Default</th>
+      <th>Required</th>
+    </tr>
+  </thead>
+  <tbody>
+    <tr>
+      <td>prefix</td>
+      <td>string</td>
+      <td>
+        Strint to prepend to every line.
+      </td>
+      <td>n/a</td>
+      <td>Yes</td>
+    </tr>
+  </tbody>
+</table>
+
+<h2><a name="ReplaceTokens"></a>ReplaceTokens</h2>
+<p>
+The <em>ReplaceTokens</em> filter will replace certain tokens. Tokens
+are strings enclosed in special characters. If you want to replace
+<em>##BCHOME##</em> by the path to the directory set in the
+environment variable <em>BCHOME</em>, you could do the following:
+</p>
+<pre>
+&lt;property environment=&quot;env&quot; />
+
+&lt;filterchain&gt;
+  &lt;replacetokens begintoken=&quot;##&quot; endtoken=&quot;##&quot;&gt;
+    &lt;token key=&quot;BCHOME&quot; value=&quot;${env.BCHOME}&quot; /&gt;
+  &lt;/replacetokens&gt;
+&lt;/filterchain&gt;
+</pre>
+<h3>Attributes</h3>
+<table>
+  <caption>
+  Attributes for the <em>&lt;replacetokens&gt;</em> tag
+  </caption>
+  <thead>
+    <tr>
+      <th>Name</th>
+      <th>Type</th>
+      <th>Description</th>
+      <th>Default</th>
+      <th>Required</th>
+    </tr>
+  </thead>
+  <tbody>
+    <tr>
+      <td>begintoken</td>
+      <td>string</td>
+      <td>
+        The string that marks the beginning of a token.
+      </td>
+      <td>@</td>
+      <td>No</td>
+    </tr>
+    <tr>
+      <td>endtoken</td>
+      <td>string</td>
+      <td>
+        The string that marks the end of a token.
+      </td>
+      <td>@</td>
+      <td>No</td>
+    </tr>
+  </tbody>
+</table>
+<h3>Nested Tags</h3>
+<p>
+The <em>ReplaceTokens</em> filter must contain one or more <em>token</em>
+tags. These must have a <em>key</em> and a <em>value</em> attribute.
+</p>
+
+<h2><a name="ReplaceRegexp"></a>ReplaceRegexp</h2>
+<p>
+The <em>ReplaceRegexp</em> filter will perform a regexp find/replace on the input
+stream. For example, if you want to replace ANT with Phing (ignoring case) and you want
+to replace references to *.java with *.php:
+</p>
+<pre>
+&lt;filterchain&gt;
+  &lt;replaceregexp&gt;
+	&lt;regexp pattern=&quot;ANT&quot; replace=&quot;Phing&quot; ignoreCase=&quot;true&quot;/&gt;
+	&lt;regexp pattern=&quot;(\w+)\.java&quot; replace=&quot;\1.php&quot;/&gt;
+  &lt;/replaceregexp&gt;
+&lt;/filterchain&gt;
+</pre>
+
+<h3>Nested Tags</h3>
+<p>
+The <em>ReplaceTokens</em> filter must contain one or more <em>regexp</em>
+tags. These must have <em>pattern</em> and <em>replace</em> attributes -- and optionally
+the <em>ignoreCase</em> attribute.
+</p>
+
+
+<h2><a name="StripLineBreaks"></a>StripLineBreaks</h2>
+<p>
+The <em>StripLineBreaks</em> filter removes all linebreaks from the
+stream passed through the filter chain.
+</p>
+<pre>
+&lt;filterchain&gt;
+  &lt;striplinebreaks /&gt;
+&lt;/filterchain&gt;
+</pre>
+
+<h2><a name="StripLineComments"></a>StripLineComments</h2>
+<p>
+The <em>StripLineComments</em> filter removes all line comments from
+the stream passed through the filter chain:
+</p>
+<pre>
+&lt;filterchain&gt;
+  &lt;striplinecomments&gt;
+    &lt;comment value=&quot;#&quot; /&gt;
+    &lt;comment value=&quot;--&quot; /&gt;
+    &lt;comment value=&quot;//&quot; /&gt;
+  &lt;/striplinecomments&gt;
+&lt;/filterchain&gt;
+</pre>
+
+<h3>Nested Tags</h3>
+<p>
+The <em>striplinecomments</em> tag must contain one or more <em>comment</em>
+tags. These must have a <em>value</em> attribute that specifies the
+character(s) that start a line comment.
+</p>
+
+<h2><a name="StripPhpComments"></a>StripPhpComments</h2>
+<p>
+The <em>StripPhpComments</em> filter removes all PHP comments from
+the stream passed through the filter.
+</p>
+<pre>
+&lt;filterchain&gt;
+  &lt;stripphpcomments /&gt;
+&lt;/filterchain&gt;
+</pre>
+
+<h2><a name="StripWhitespace"></a>StripWhitespace</h2>
+<p>
+The <em>StripWhitespace</em> filter removes all PHP comments and whitespace from
+the stream passed through the filter.  Internally, this filter uses the php_strip_whitespace() function.
+</p>
+<pre>
+&lt;filterchain&gt;
+  &lt;stripwhitespace /&gt;
+&lt;/filterchain&gt;
+</pre>
+
+<h2><a name="TabToSpaces"></a>TabToSpaces</h2>
+<p>
+The TabToSpaces filter replaces all tab characters with a given
+count of space characters.
+</p>
+<pre>
+&lt;filterchain&gt;
+  &lt;tabtospaces tablength=&quot;8&quot; /&gt;
+&lt;/filterchain&gt;
+</pre>
+<h3>Attributes</h3>
+<table>
+  <caption>
+  Attributes for the <em>&lt;tabtospaces&gt;</em> filter
+  </caption>
+  <thead>
+    <tr>
+      <th>Name</th>
+      <th>Type</th>
+      <th>Description</th>
+      <th>Default</th>
+      <th>Required</th>
+    </tr>
+  </thead>
+  <tbody>
+    <tr>
+      <td>tablength</td>
+      <td>Integer</td>
+      <td>
+        The number of space characters that a tab is to represent.
+      </td>
+      <td>8</td>
+      <td>No</td>
+    </tr>
+  </tbody>
+</table>
+
+<h2><a name="TailFilter"></a>TailFilter</h2>
+<p>
+Similar to <a href="#HeadFilter">HeadFilter</a>,
+this filter reads the last <em>n</em> lines of a file; the others
+are not further passed through the filter chain. Usage example:
+</p>
+<pre>
+&lt;filterchain&gt;
+  &lt;tailfilter lines=&quot;20&quot; /&gt;
+&lt;/filterchain&gt;
+</pre>
+<h3>Attributes</h3>
+<table>
+  <caption>
+  Attributes for the <em>&lt;tailfilter&gt;</em> tag
+  </caption>
+  <thead>
+    <tr>
+      <th>Name</th>
+      <th>Type</th>
+      <th>Description</th>
+      <th>Default</th>
+      <th>Required</th>
+    </tr>
+  </thead>
+  <tbody>
+    <tr>
+      <td>lines</td>
+      <td>Integer</td>
+      <td>
+        Number of lines from the back to read.
+      </td>
+      <td>10</td>
+      <td>No</td>
+    </tr>
+  </tbody>
+</table>
+
+<h2><a name="TidyFilter"></a>TidyFilter</h2>
+<p>
+The <em>TidyFilter</em> allows you to use the <a href="http://php.net/tidy">PHP
+tidy extension</a> to clean up and repeair HTML documents. Usage example:
+</p>
+<pre>
+&lt;filterchain&gt;
+  &lt;tidyfilter encoding=&quot;utf8&quot;&gt;
+    &lt;config name=&quot;indent&quot; value=&quot;true&quot; /&gt;
+    &lt;config name=&quot;output-xhtml&quot; value=&quot;true&quot; /&gt;
+  &lt;/tidyfilter&gt;
+&lt;/filterchain&gt;
+</pre>
+<h3>Attributes</h3>
+<table>
+  <caption>
+  Attributes for the <em>&lt;tidyfilter&gt;</em> tag
+  </caption>
+  <thead>
+    <tr>
+      <th>Name</th>
+      <th>Type</th>
+      <th>Description</th>
+      <th>Default</th>
+      <th>Required</th>
+    </tr>
+  </thead>
+  <tbody>
+    <tr>
+      <td>encoding</td>
+      <td>String</td>
+      <td>
+        The expected input encoding of the file.
+      </td>
+      <td>utf8</td>
+      <td>No</td>
+    </tr>
+  </tbody>
+</table>
+<h3>Nested Tags</h3>
+<p>
+The <em>TidyFilter</em> supports nested &lt;config&gt; tags to configure how
+Tidy should manipulate the documents. For a complete list of configuration
+options see the offical
+<a href="http://tidy.sourceforge.net/docs/quickref.html">Quick Reference</a>.
+</p>
+
+<h2><a name="XincludeFilter"></a>XincludeFilter</h2>
+<p>
+The <em>XincludeFilter</em> processes a stream for Xinclude tags, and processes the inclusions.
+This is useful for processing modular XML files.  DocBook book files are one example of
+modular XML files.  Usage example:
+<pre>
+&lt;!--
+  Render a DocBook book file called manual.xml, which
+  contains Xinclude tags to include individual book sections.
+  --&gt;
+&lt;copy todir=&quot;${manual.dest.dir}&quot;&gt;
+  &lt;filterchain&gt;
+    &lt;xincludefilter basedir=&quot;${manual.src.dir}&quot; /&gt;
+    &lt;xsltfilter style=&quot;${manual.src.dir}/html.xsl&quot;&gt;
+      &lt;param name=&quot;base.dir&quot; expression=&quot;${manual.dest.dir}/&quot; /&gt;
+    &lt;/xsltfilter&gt;
+  &lt;/filterchain&gt;
+  &lt;fileset dir=&quot;${manual.src.dir}&quot;&gt;
+    &lt;include name=&quot;manual.xml&quot; /&gt;
+  &lt;/fileset&gt;
+&lt;/copy&gt;
+</pre>
+<h3>Attributes</h3>
+<table>
+  <caption>
+  Attributes for the <em>&lt;xincludefilter&gt;</em> tag
+  </caption>
+  <thead>
+    <tr>
+      <th>Name</th>
+      <th>Type</th>
+      <th>Description</th>
+      <th>Default</th>
+      <th>Required</th>
+    </tr>
+  </thead>
+  <tbody>
+    <tr>
+      <td>basedir</td>
+      <td>String</td>
+      <td>
+        The working directory from which to
+        process the Xincludes.  Relative pathnames
+        in the include tags are based on this
+        location.
+      </td>
+      <td>Project basedir</td>
+      <td>No</td>
+    </tr>
+  </tbody>
+</table>
+
+<h2><a name="XsltFilter"></a>XsltFilter</h2>
+<p>
+The <em>XsltFilter</em> applies a XSL template to the stream.
+Though you can use this filter directly, you should use
+<a href="AppendixB-CoreTasks.html#XsltTask">XsltTask</a>
+which is shortcut to the following lines:
+</p>
+<pre>
+&lt;filterchain&gt;
+  &lt;xsltfilter style=&quot;somexslt.xsl&quot; /&gt;
+&lt;/filterchain&gt;
+</pre>
+<h3>Attributes</h3>
+<table>
+  <caption>
+  Attributes for the <em>&lt;xsltfilter&gt;</em> tag
+  </caption>
+  <thead>
+    <tr>
+      <th>Name</th>
+      <th>Type</th>
+      <th>Description</th>
+      <th>Default</th>
+      <th>Required</th>
+    </tr>
+  </thead>
+  <tbody>
+    <tr>
+      <td>style</td>
+      <td>String</td>
+      <td>
+        The XSLT stylesheet to use for transformation.
+      </td>
+      <td>n/a</td>
+      <td>Yes</td>
+    </tr>
+	<tr>
+      <td>html</td>
+      <td>Boolean</td>
+      <td>
+        Whether to parse the input as HTML (using libxml2 DOMDocument::loadHTML()).
+      </td>
+      <td>false</td>
+      <td>No</td>
+    </tr>
+  </tbody>
+</table>
+
+<h3>Nested Tags</h3>
+<p>
+The <em>XsltFilter</em> filter may contain one or more <em>param</em>
+tags to pass any XSLT parameters to the stylesheet. These <em>param</em> tags
+must have <em>name</em> and <em>expression</em> attributes.
+</p>
+
+  </body>
+</html>
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/docs/phing_guide/book/chapters/appendixes/AppendixD3-CoreMappers.html
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/docs/phing_guide/book/chapters/appendixes/AppendixD3-CoreMappers.html	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/docs/phing_guide/book/chapters/appendixes/AppendixD3-CoreMappers.html	(revision 19)
@@ -0,0 +1,242 @@
+<!--
+-File         $Id$
+-License      GNU FDL (http://www.gnu.org/copyleft/fdl.html)
+-Copyright    2002, turing
+-Author       alex black, enigma@turingstudio.com
+-->
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/2000/REC-xhtml1-20000126/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+  <head>
+    <title>Phing Guide - Core Mappers</title>
+    <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
+    <link rel="Stylesheet" rev="Stylesheet" href="../../css/Documentation.css" type="text/css" media="All" charset="iso-8859-1" />
+  </head>
+  <body>
+<h1><a name="CoreMappers"></a>Appendix D-3: Core Mappers</h1>
+<p>
+While filters are applied to the <em>content</em> of files, Mappers
+are applied to the <em>filenames</em>. All mappers have the same
+API, i.e. the way you use them is the same:
+</p>
+<pre>
+&lt;mapper type=&quot;<em>mappername</em>&quot; from=&quot;<em>frompattern</em>&quot; to=&quot;<em>topattern</em>&quot; /&gt;
+</pre>
+<h3>Attributes</h3>
+<table>
+  <caption>
+  Attributes for the <em>&lt;mapper&gt;</em> tag
+  </caption>
+  <thead>
+    <tr>
+      <th>Name</th>
+      <th>Type</th>
+      <th>Description</th>
+      <th>Default</th>
+      <th>Required</th>
+    </tr>
+  </thead>
+  <tbody>
+    <tr>
+      <td>type</td>
+      <td>String</td>
+      <td>
+        Type of the mapper.
+      </td>
+      <td>n/a</td>
+      <td rowspan="2"> One of these is required.</td>
+    </tr>
+    <tr>
+      <td>classname</td>
+      <td>String</td>
+      <td>
+		Dot-path to a custom mapper class to use.
+      </td>
+      <td>n/a</td>
+      
+    </tr>
+    <tr>
+      <td>from</td>
+      <td>String</td>
+      <td>
+        The pattern the filename is to be matched to. The
+        exact meaning is dependent on the implementation
+        of the mapper.
+      </td>
+      <td>n/a</td>
+      <td>depends on the implementation of the mapper</td>
+    </tr>
+    <tr>
+      <td>to</td>
+      <td>String</td>
+      <td>
+        The pattern according to which the filename is to
+        be changed to. Here, the usage is dependent on
+        the implementation of the mapper, too.
+      </td>
+      <td>n/a</td>
+      <td>depends on the implementation of the mapper</td>
+    </tr>
+  </tbody>
+</table>
+
+<h2><a name="FlattenMapper"></a>FlattenMapper</h2>
+<p>
+The <em>FlattenMapper</em> removes the directories from
+a filename and solely returns the filename.
+</p>
+<pre>
+&lt;copy todir=&quot;/tmp&quot;&gt;
+  &lt;mapper type=&quot;flatten&quot; /&gt;
+
+  &lt;fileset refid=&quot;someid&quot; /&gt;
+&lt;/copy&gt;
+</pre>
+<p>
+This code will copy all files in the fileset to /tmp. All
+files will be in the target directory.
+</p>
+<h3>Examples</h3>
+<pre>
+&lt;mapper type=&quot;flatten&quot; /&gt;
+</pre>
+<p>
+Applying the mapper, you will get the following results from the
+following filenames:
+</p>
+<table>
+  <tr>
+    <th>From</th>
+    <th>To</th>
+  </tr>
+  <tr>
+    <td>test.txt</td>
+    <td>test.txt</td>
+  </tr>
+  <tr>
+    <td>./foo/bar/test.bak</td>
+    <td>test.bak</td>
+  </tr>
+</table>
+
+<h2><a name="GlobMapper"></a>GlobMapper</h2>
+<p>
+The <em>GlobMapper</em> works like the <em>copy</em> command in DOS:
+</p>
+<pre>
+&lt;copy todir=&quot;/tmp&quot;&gt;
+  &lt;mapper type=&quot;glob&quot; from=&quot;*.php&quot; to=&quot;*.php.bak&quot;/&gt;
+
+  &lt;fileset refid=&quot;someid&quot; /&gt;
+&lt;/copy&gt;
+</pre>
+<p>
+This will change the extension of all files matching the pattern
+<em>*.php</em> to <em>.php.bak</em>.
+</p>
+<h3>Examples</h3>
+<pre>
+&lt;mapper type=&quot;glob&quot; from=&quot;*txt&quot; to=&quot;*txt.bak&quot;/&gt;
+</pre>
+<p>
+Applying the mapper, you will get the following results from the
+following filenames:
+</p>
+<table>
+  <tr>
+    <th>From</th>
+    <th>To</th>
+  </tr>
+  <tr>
+    <td>test.txt</td>
+    <td>test.txt.bak</td>
+  </tr>
+  <tr>
+    <td>./foo/bar/test.txt</td>
+    <td>./foo/bar/test.txt.bak</td>
+  </tr>
+  <tr>
+    <td>mytxt</td>
+    <td>mytxt.bak</td>
+  </tr>
+  <tr>
+    <td>SomeClass.php</td>
+    <td><em>ignored</em>, SomeClass.php</td>
+  </tr>
+</table>
+
+<h2><a name="IdentityMapper"></a>IdentityMapper</h2>
+<p>
+The <em>IdentityMapper</em> will not change anything on the
+source filenames.
+</p>
+
+<h2><a name="MergeMapper"></a>MergeMapper</h2>
+<p>
+The <em>MergeMapper</em> changes all source filenames to the same
+filename.
+</p>
+<h3>Examples</h3>
+<pre>
+&lt;mapper type=&quot;merge&quot; to=&quot;test.tar&quot;/&gt;
+</pre>
+<p>
+Applying the mapper, you will get the following results from the
+following filenames:
+</p>
+<table>
+  <tr>
+    <th>From</th>
+    <th>To</th>
+  </tr>
+  <tr>
+    <td>test.txt</td>
+    <td>test.tar</td>
+  </tr>
+  <tr>
+    <td>./foo/bar/test.txt</td>
+    <td>test.tar</td>
+  </tr>
+  <tr>
+    <td>mytxt</td>
+    <td>test.tar</td>
+  </tr>
+  <tr>
+    <td>SomeClass.php</td>
+    <td>test.tar</td>
+  </tr>
+</table>
+
+<h2><a name="RegexpMapper"></a>RegexpMapper</h2>
+<p>
+The <em>RegexpMapper</em> changes filenames according to a pattern
+defined by a regular expression. This is the most powerful mapper and
+you should be able to use it for every possible application.
+</p>
+<h3>Examples</h3>
+<pre>
+&lt;mapper type=&quot;regexp&quot; from=&quot;^(.*)\.conf\.xml&quot; to=&quot;\1.php&quot;/&gt;
+</pre>
+<p>
+The mapper as above will do the following mappings:
+</p>
+<table>
+  <tr>
+    <th>From</th>
+    <th>To</th>
+  </tr>
+  <tr>
+    <td>test.txt</td>
+    <td><em>ignore</em>, test.txt</td>
+  </tr>
+  <tr>
+    <td>./foo/bar/test.conf.xml</td>
+    <td>./foo/bar/test.php</td>
+  </tr>
+  <tr>
+    <td>someconf.conf.xml</td>
+    <td>someconf.php</td>
+  </tr>
+</table>
+
+  </body>
+</html>
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/docs/phing_guide/book/chapters/appendixes/AppendixD4-CoreSelectors.html
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/docs/phing_guide/book/chapters/appendixes/AppendixD4-CoreSelectors.html	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/docs/phing_guide/book/chapters/appendixes/AppendixD4-CoreSelectors.html	(revision 19)
@@ -0,0 +1,39 @@
+<!--
+-File         $Id$
+-License      GNU FDL (http://www.gnu.org/copyleft/fdl.html)
+-Copyright    2002, turing
+-Author       alex black, enigma@turingstudio.com
+-->
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/2000/REC-xhtml1-20000126/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+  <head>
+    <title>Phing Guide - Core Selectors</title>
+    <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
+    <link rel="Stylesheet" rev="Stylesheet" href="../../css/Documentation.css" type="text/css" media="All" charset="iso-8859-1" />
+  </head>
+  <body>
+<h1><a name="ComplexCoreTypes"></a>Appendix D: Core Selectors</h1>
+
+<p>Selectors are a specific subset of Phing <em>data types</em> that allow you to fine-tune matching in a 
+<a href="AppendixD-CoreTypes.html#Fileset">FileSet</a> (or DirSet).</p>
+
+<p><strong>This documentation has not yet been written; please use the <a href="http://ant.apache.org/manual/CoreTypes/selectors.html">Ant documentation</a> for now, since the
+APIs for the Phing selectors are largely the same.</strong></p>
+
+<p>Phing supports the following selectors, which typically match on both files and directories in a &lt;fileset&gt;:</p>
+
+<ul>
+	<li> &lt;contains&gt; - Select files that contain a specific string</li>
+	<li> &lt;date&gt; - Select files/directories that have been modified either before or after a specific date/time</li>
+	<li> &lt;depend&gt; - Select files/directories that have been modified more recently than equivalent items elsewhere</li>
+	<li> &lt;depth&gt; - Select files/directories that appear at a specific depth in a directory tree</li>
+	<li> &lt;different&gt; - Select files that are different from those elsewhere</li>
+	<li> &lt;filename&gt; - Select files/directories whose name matches a particular pattern. Equivalent to the include and exclude elements of a patternset.</li>
+	<li> &lt;present&gt; - Select files/directories that either do or do not exist in some other location</li>
+	<li> &lt;containsregexp&gt; - Select files that contain text matching a regular expression</li>
+	<li> &lt;size&gt; - Select files that are larger or smaller than a particular number of bytes.</li>
+	<li> &lt;type&gt; - Select files/directories by type ('file' or 'dir')</li>
+</ul>
+
+  </body>
+</html>
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/docs/phing_guide/book/chapters/appendixes/AppendixE-ProjectComponents.html
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/docs/phing_guide/book/chapters/appendixes/AppendixE-ProjectComponents.html	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/docs/phing_guide/book/chapters/appendixes/AppendixE-ProjectComponents.html	(revision 19)
@@ -0,0 +1,176 @@
+<!--
+-File         $Id: AppendixE-ProjectComponents.html 182 2007-04-17 14:37:01Z mrook $
+-License      GNU FDL (http://www.gnu.org/copyleft/fdl.html)
+-Copyright    2002, turing
+-Author       alex black, enigma@turingstudio.com
+-->
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/2000/REC-xhtml1-20000126/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+  <head>
+    <title>Phing Guide - Project Components</title>
+    <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
+    <link rel="Stylesheet" rev="Stylesheet" href="../../css/Documentation.css" type="text/css" media="All" charset="iso-8859-1" />
+  </head>
+  <body>
+<h1><a name="ProjectComponents"></a>Appendix E: Project Components</h1>
+<p>
+This file will give you a quick introduction and a reference of the
+things that you may see in a build files besides
+<a href="AppendixB-CoreTasks.html">tasks</a> and
+<a href="AppendixD-CoreTypes.html">types</a>.
+</p>
+
+<h2><a name="Project"></a>Phing Projects</h2>
+<p>
+Projects are the outermost container for everything in build files.
+The <em>&lt;project&gt;</em> tag also is the root tag in build files.
+It contains the name, the directory, a short description and a
+default target.
+</p>
+<p>
+Project may contain task calls and targets (see below).
+</p>
+<h3>Example</h3>
+<pre>
+&lt;?xml version=&quot;1.0&quot; ?&gt;
+
+&lt;project name=&quot;TestProject&quot; basedir=&quot;.&quot; default=&quot;main&quot;
+         description=&quot;This is a test project to show how to use projects ;-)&quot;&gt;
+
+  &lt;!-- Everything else goes here --&gt;
+
+&lt;/project&gt;
+</pre>
+<h3>Attributes</h3>
+<table>
+  <tbody>
+    <tr>
+      <th>Name</th>
+      <th>Type</th>
+      <th>Description</th>
+      <th>Default</th>
+      <th>Required</th>
+    </tr>
+    <tr>
+      <td>basedir</td>
+      <td>String</td>
+      <td>
+        The base directory of the project, i.e. the directory
+        all paths are relative to.
+      </td>
+      <td>n/a</td>
+      <td>Yes</td>
+    </tr>
+    <tr>
+      <td>default</td>
+      <td>String</td>
+      <td>
+        The name of the target that is executed if none is
+        explicitely specified when calling Phing
+      </td>
+      <td>all</td>
+      <td>No</td>
+    </tr>
+    <tr>
+      <td>description</td>
+      <td>String</td>
+      <td>
+        A free text description of the project
+      </td>
+      <td>n/a</td>
+      <td>No</td>
+    </tr>
+    <tr>
+      <td>name</td>
+      <td>String</td>
+      <td>
+        Name of the project
+      </td>
+      <td>n/a</td>
+      <td>Yes</td>
+    </tr>
+  </tbody>
+</table>
+
+<h2><a name="Target"></a>Targets</h2>
+<p>
+</p>
+<h3>Example</h3>
+<pre>
+&lt;target if=&quot;lang&quot; unless=&quot;lang.en&quot; depends=&quot;foo1,foo2&quot;
+       name=&quot;main&quot; description=&quot;This is an example target&quot; &gt;
+
+  &lt;!-- everything else goes here --&gt;
+
+&lt;/target&gt;
+</pre>
+<p>
+The target defined in the example above is only executed, if the
+property <em>${lang}</em> is set and the property <em>${lang.en}</em>
+is not set. Additionally, id depends on the targets <em>foo1</em> and
+<em>foo2</em>. That means, the targets <em>foo1</em> and <em>foo2</em>
+are executed before the target <em>main</em> is executed. The name
+of the target is <em>main</em> and it also has a description.
+</p>
+<h3>Attributes</h3>
+<table>
+  <tbody>
+    <tr>
+      <th>Name</th>
+      <th>Type</th>
+      <th>Description</th>
+      <th>Default</th>
+      <th>Required</th>
+    </tr>
+    <tr>
+      <td>depends</td>
+      <td>String</td>
+      <td>
+        One or more names of targets that have to be executed before
+        this target can be executed.
+      </td>
+      <td>n/a</td>
+      <td>No</td>
+    </tr>
+    <tr>
+      <td>description</td>
+      <td>String</td>
+      <td>
+        A free text description of the target.
+      </td>
+      <td>n/a</td>
+      <td>No</td>
+    </tr>
+    <tr>
+      <td>if</td>
+      <td>String</td>
+      <td>
+        The name of the property that is to be set if the target is
+        to be executed.
+      </td>
+      <td>n/a</td>
+      <td>No</td>
+    </tr>
+    <tr>
+      <td>name</td>
+      <td>String</td>
+      <td>
+        The name of the target
+      </td>
+      <td>n/a</td>
+      <td>Yes</td>
+    </tr>
+    <tr>
+      <td>unless</td>
+      <td>String</td>
+      <td>
+        The name of the property that is to be set if the target is
+        not to be executed.
+      </td>
+      <td>n/a</td>
+      <td>No</td>
+    </tr>
+ </tbody>
+</table>
+  </body>
+</html>
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/docs/phing_guide/book/chapters/appendixes/AppendixF-FileFormats.html
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/docs/phing_guide/book/chapters/appendixes/AppendixF-FileFormats.html	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/docs/phing_guide/book/chapters/appendixes/AppendixF-FileFormats.html	(revision 19)
@@ -0,0 +1,86 @@
+<!--
+-File         $Id: AppendixF-FileFormats.html 182 2007-04-17 14:37:01Z mrook $
+-License      GNU FDL (http://www.gnu.org/copyleft/fdl.html)
+-Copyright    2002, turing
+-Author       alex black, enigma@turingstudio.com
+-->
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/2000/REC-xhtml1-20000126/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+	<title>Phing Guide - File Formats</title>
+	<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
+	<link rel="Stylesheet" rev="Stylesheet" href="../../css/Documentation.css" type="text/css" media="All" charset="iso-8859-1" />
+</head>
+<body>
+
+<h1><a name="AppendixFFileFormats"></a>Appendix F: File Formats</h1>
+
+<h2><a name="BuildFileFormat"></a>Build File Format</h2>
+
+<p>
+  The following XML file shows a skelleton build file, that only contains
+  a project and a target. See the references for the Phing Types and Tasks
+  for information on how to use them.
+</p>
+
+<pre title="Buildfile format">
+&lt;?xml version=&quot;1.0&quot; ?&gt;
+
+&lt;!--
+  The root tag of each build file must be a &quot;project&quot; tag.
+--&gt;
+&lt;project name=&quot;(projectname)&quot; [basedir=&quot;(projectbasedir)&quot;]
+         [default=&quot;(targetname)&quot;] [description=&quot;(projectdescription)&quot;]&gt;
+
+  &lt;!--
+    Type and task calls here, i.e. filesets, patternsets,
+    CopyTask calls etc.
+  --&gt;
+
+  &lt;target name=&quot;(targetname)&quot; [depends=&quot;targetname1,targetname2&quot;]
+          [if=&quot;(ifproperty)&quot;] [unless=&quot;(unlessproperty)&quot;]&gt;
+    &lt;!--
+      Type and task calls here, i.e. filesets, patternsets,
+      CopyTask calls, etc.
+    --&gt;
+  &lt;/target&gt;
+
+  &lt;!--
+    More targets here
+  --&gt;
+&lt;/project&gt;
+</pre>
+
+<h2><a name="PropertyFileFormat"></a>Property File Format</h2>
+
+<p>
+<em>Property Files</em> define properties. Properties are
+stored in key/value pairs and may only contain plain text.
+The suffix of these files should be <em>.properties</em>, the
+default Property File for a Build File is <em>build.properties</em>
+</p>
+
+<pre>
+# Property files contain key/value pairs
+key=value
+
+# Property keys may contain alphanumeric chars and colons, but
+# not special chars. This way you can create pseudo-namespaces
+myapp.window.hsize=300
+myapp.window.vsize=200
+myapp.window.xpos=10
+myapp.window.ypos=100
+
+# You can refer to values of other properties by enclosing their
+# keys in &quot;${}&quot;.
+text.width=${myapp.window.hsize}
+
+# <em>Everything</em> behind the equal sign is the value, you do
+# not have to enclose strings:
+text=This is some text, Your OS is ${php.os}
+
+# I guess that is all there is to property files
+</pre>
+
+</body>
+</html>
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/docs/phing_guide/book/css/Documentation.css
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/docs/phing_guide/book/css/Documentation.css	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/docs/phing_guide/book/css/Documentation.css	(revision 19)
@@ -0,0 +1,197 @@
+/**
+ * {{{ Header
+ * -File        $Id: Documentation.css 198 2007-06-17 19:40:54Z mrook $
+ * -License     LGPL (http://www.gnu.org/copyleft/lesser.html)
+ * -Copyright    2001, Entity
+ * -Author       author, email@example.com
+ * }}}
+ */
+
+/**
+ * This is the standard CSS for binarycloud XHTML documentation
+ * it should be used with:
+ * <link rel="Stylesheet" rev="Stylesheet" href="css/Documentation.css" type="text/css" media="All" charset="iso-8859-1" />
+ *
+ * This CSS provides all necessary style information for the
+ * XHTML reduced element set - do not embed custom CSS in 
+ * your documents, and do not assign formatting attributes
+ * to your elements.
+ */
+
+body
+{
+	margin: 20px 75px 20px 40px;
+	background: #FFFFFF;
+}
+
+a
+{
+	color: #003366;
+	font-weight: bold;
+	text-decoration: underline;
+} 
+
+a:visited 
+{
+	color: #003366;
+	text-decoration: underline;
+	font-weight: bold;
+} 
+a:active { color: #ffffff; } 
+a:hover { color: #000000; } 		 
+
+h1
+{
+    page-break-before: auto;
+	font-family: arial, sans-serif;
+	font-size: 22px;
+	color: #003366;
+	font-weight: normal;
+	letter-spacing: 4px;
+}
+
+h2
+{
+	font-family: arial, sans-serif;
+	font-size: 15px;
+	color: #333333;
+	font-weight: bold;
+	letter-spacing: 1px;
+	border-color: #CCCCCC;
+	border-width: 0 0 1px 0;
+	border-style: solid solid solid solid;
+
+}
+
+h3
+{
+	font-family: verdana, sans-serif;
+	font-size: 12px;
+	color: #333333;
+	font-weight: bold;
+}
+
+h4
+{
+	font-family: verdana, sans-serif;
+	font-size: 11px;
+	color: #333333;
+	font-weight: bold;
+}
+
+
+p
+{
+	font-family: georgia, serif;
+	font-size: 12px;
+	color: #333333;
+	line-height: 15px;
+}
+
+blockquote 
+{
+	font-family: georgia, serif;
+	font-size: 14px;
+	color: #333333;
+	line-height: 18px;
+    font-style:italic;
+}
+
+pre
+{
+    page-break-inside: avoid;
+	font-family: monospace;
+	font-size: 12px;
+	color: #333333;
+	line-height: 15px;
+	background-color: #EEE;
+	border: 1px solid #333;
+	padding: 5px;
+	margin-left: 30px;
+	margin-right: 30px;
+}
+
+ol
+{
+	color: #333333;
+	font-family: georgia, serif;
+	font-size: 12px;
+	line-height: 14px;
+}
+	
+ul
+{
+	color: #333333;
+	font-family: georgia, serif;
+	font-size: 12px;
+	line-height: 14px;
+}
+
+li
+{
+	font-family: georgia, serif;
+	color: #333333;
+	font-size: 12px;
+	margin-left: 0px;
+	margin-right: 0px;
+	margin-top: 6px;
+	margin-bottom: 0px;
+	line-height: 14px;
+}
+
+table
+{
+    caption-side:bottom;
+    page-break-inside: avoid;
+	background-color: #FFFFFF;
+	padding: 0px;
+	width: 80%;
+	border-color: #666666;
+	border-width: 1px;
+	border-style: solid;
+	margin: auto;
+}
+
+caption:before 
+{
+    content:"Table - ";
+}
+
+caption
+{
+	font-family: verdana, sans-serif;
+	font-size: 11px;
+    font-weight:bold;
+	color: #003366;
+    letter-spacing:2px;
+}
+
+th
+{
+	padding: 2px;
+	background-color: #EEEEEE;
+	font-family: georgia, serif;
+	font-size: 12px;
+	color: #333333;
+	text-align: left;
+	font-weight: bold;
+	vertical-align: middle;
+}
+
+td
+{
+	padding: 2px 2px 2px 10px;
+	background-color: #FFFFFF;
+	font-family: georgia, serif;
+	font-size: 12px;
+	color: #333333;
+	font-weight: normal;
+	border-top: solid 1px #DDDDDD;
+}
+
+img
+{
+	vertical-align: top;
+	text-align: left;
+	margin: auto 10px auto auto;
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/docs/phing_guide/book/css/FrameToc.css
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/docs/phing_guide/book/css/FrameToc.css	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/docs/phing_guide/book/css/FrameToc.css	(revision 19)
@@ -0,0 +1,68 @@
+/**
+ * {{{ Header
+ * -File        $Id: FrameToc.css 123 2006-09-14 20:19:08Z mrook $
+ * -License     LGPL (http://www.gnu.org/copyleft/lesser.html)
+ * -Copyright    2001, Entity
+ * -Author       author, email@example.com
+ * }}}
+ */
+
+/**
+ * This is the ToC (table of contents) CSS for a framed
+ * view of the documentaion
+ */
+
+body
+{
+	margin: 0px;
+	background: #EEEEEE;
+}
+
+a
+{
+	color: #003366;
+	text-decoration: none;
+} 
+a:visited
+{
+	color: #003366;
+	text-decoration: none;
+} 
+a:active { color: #ffffff; } 
+a:hover { color: #000000; } 
+
+h1
+{
+	page-break-before: auto;
+	font-family: arial, sans-serif;
+	font-size: 14px;
+	color: #FFFFFF;
+	font-weight: bold;
+	letter-spacing: 2px;
+	background-color: #FF3300;
+	padding: 5px;
+	background-position: 0px 0px;
+}
+
+ul
+{
+	color: #333333;
+	font-family: georgia, serif;
+	font-size: 12px;
+	line-height: 14px;
+	margin: 0 0 0 20px;
+	padding: 0px;
+}
+
+li
+{
+	font-family: arial;
+	color: #333333;
+	font-size: 11px;
+	margin-left: 0px;
+	margin-right: 0px;
+	margin-top: 5px;
+	margin-bottom: 0px;
+	line-height: 14px;
+    list-style-type: square;
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/docs/phing_guide/book/frame/DocFrame.html
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/docs/phing_guide/book/frame/DocFrame.html	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/docs/phing_guide/book/frame/DocFrame.html	(revision 19)
@@ -0,0 +1,13 @@
+<html>
+<head>
+	<title> Documentation Frame </title> 
+	<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+	<link rel="Stylesheet" rev="Stylesheet" href="css/Documentation.css" type="text/css" media="All" charset="iso-8859-1">
+</head>
+
+<frameset cols="200,*" frameborder="YES" border="1" framespacing="5">
+<frame src="../toc/FrameToC.html" name="ToC" scrolling="auto" marginheight="0" marginwidth="0" frameborder="5" />
+<frame src="TitlePage.html" name="Content" scrolling="auto" marginheight="0" marginwidth="0" frameborder="0" />
+</frameset>
+
+</html>
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/docs/phing_guide/book/frame/NavTop.html
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/docs/phing_guide/book/frame/NavTop.html	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/docs/phing_guide/book/frame/NavTop.html	(revision 19)
@@ -0,0 +1,67 @@
+<!--
+// {{{ Header
+-File         $Id: NavTop.html 123 2006-09-14 20:19:08Z mrook $
+-License      GNU FDL (http://www.gnu.org/copyleft/fdl.html)
+-Copyright    2002, turing
+-Author       alex black, enigma@turingstudio.com
+// }}}
+-->
+
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/2000/REC-xhtml1-20000126/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+	<title> Documentation Nav </title> 
+	<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
+
+<style type="text/css" media="All">
+body
+{
+	margin: 0px;
+	background: #003366;
+}
+
+A
+{
+	color: #FFFFFF;
+	font-family: arial, sans-serif;;
+	font-size: 11px;
+	font-weight: bold;
+} 
+A:active { color: #99CC66; } 
+A:hover { color: #dddddd; } 
+			 
+
+.ToCLabel
+{
+	page-break-before: auto;
+	font-family: arial, sans-serif;
+	font-size: 14px;
+	color: #FFFFFF;
+	font-weight: bold;
+	letter-spacing: 2px;
+	padding: 5px;
+	background-position: 0px 0px;
+}
+</style>
+</head>
+<body>
+
+<script type="text/javascript" language="Javascript" charset="iso-8859-1" src="../js/Chapters.js"></script>
+<script type="text/javascript" language="Javascript" charset="iso-8859-1" src="../js/BookNav.js"></script>
+
+<table border="0" cellpadding="0" cellspacing="0" width="100%">
+<tr>
+<td valign="top" class="ToCLabel">
+Table of Contents
+</td>
+<td valign="middle" align="right">
+<a href="javascript:GoBack();">Previous Chapter</a>
+&nbsp;&nbsp;&nbsp;
+<a href="javascript:GoNext();">Next Chapter</a>
+&nbsp;&nbsp;&nbsp;
+</td>
+</tr>
+</table>
+
+</body>
+</html>
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/docs/phing_guide/book/frame/TitlePage.html
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/docs/phing_guide/book/frame/TitlePage.html	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/docs/phing_guide/book/frame/TitlePage.html	(revision 19)
@@ -0,0 +1,26 @@
+<!--
+-File         $Id: TitlePage.html 123 2006-09-14 20:19:08Z mrook $
+-License      GNU FDL (http://www.gnu.org/copyleft/fdl.html)
+-Copyright    2002, turing
+-Author       alex black, enigma@turingstudio.com
+-->
+<!--
+REMOVED UNTIL PHP5 libxml2 support includes loadHTML() method:
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/2000/REC-xhtml1-20000126/DTD/xhtml1-strict.dtd"
+<html xmlns="http://www.w3.org/1999/xhtml"
+-->
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/2000/REC-xhtml1-20000126/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+	<title> Phing Guide </title> 
+	<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
+	<link rel="Stylesheet" rev="Stylesheet" href="../css/Documentation.css" type="text/css" media="All" charset="iso-8859-1" />
+</head>
+<body>
+<p align="center"><img src="../images/logo.png" width="211" height="74" border="0" /></p>
+<h1 align="center">Phing 2 - User Guide</h1>
+
+  <p align="center"><em>Andreas Aderhold, Alex Black, Manuel Holtgrewe, Hans Lellelid, Michiel Rook</em></p>
+
+</body>
+</html>
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/docs/phing_guide/book/images/README.txt
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/docs/phing_guide/book/images/README.txt	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/docs/phing_guide/book/images/README.txt	(revision 19)
@@ -0,0 +1,3 @@
+Place all images in this directory.
+
+Do not place images in the chapters/ directory.
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/docs/phing_guide/book/index.html
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/docs/phing_guide/book/index.html	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/docs/phing_guide/book/index.html	(revision 19)
@@ -0,0 +1,13 @@
+<html>
+<head>
+	<title> Documentation Frame </title> 
+	<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+	<link rel="Stylesheet" rev="Stylesheet" href="css/Documentation.css" type="text/css" media="All" charset="iso-8859-1">
+</head>
+
+<frameset rows="30,*" frameborder="NO" border="0" framespacing="0">
+<frame src="frame/NavTop.html" name="Nav" scrolling="auto" marginheight="0" marginwidth="0" frameborder="5" />
+<frame src="frame/DocFrame.html" name="ContentAndToC" scrolling="auto" marginheight="0" marginwidth="0" frameborder="0" />
+</frameset>
+
+</html>
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/docs/phing_guide/book/js/BookNav.js
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/docs/phing_guide/book/js/BookNav.js	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/docs/phing_guide/book/js/BookNav.js	(revision 19)
@@ -0,0 +1,68 @@
+/**
+ * This function checks the href of the content
+ * frame against a known list of chapters.
+ * 
+ * If the href is found, the index to that href in
+ * the Chapters array is returned, if not null.
+ * 
+ * @author  alex, alex@binarycloud.com
+ */
+function GetCurrentChapter() {
+
+    var ContentLocation = top.ContentAndToC.Content.location.href;
+    var CurrentChapter = null;
+
+    for (i=0; i < Chapters.length; i++) {
+        if (ContentLocation.indexOf(Chapters[i][0]) != -1) {
+            CurrentChapter = i;
+        }
+    }
+
+    return CurrentChapter;
+}
+
+/**
+ * This function gets the current chapter and
+ * sets the Content href to the previous
+ * chapter. If the current chapter is "0",
+ * the href is set to the Standard ToC,
+ * (index.html).
+ * 
+ * @author  alex, alex@binarycloud.com
+ */
+function GoBack() {
+
+    var CurrentChapter = GetCurrentChapter();
+
+    if (CurrentChapter == 0) {
+        top.ContentAndToC.Content.location = "../toc/ToC.html";
+    } else {
+        top.ContentAndToC.Content.location = "../"+Chapters[CurrentChapter-1][0];
+    }
+
+}
+
+/**
+ * This function gets the current chapter
+ * and sets the content href to the next
+ * chapter. If the href is "index.html"
+ * we know we're on the standard ToC, so
+ * the href should be set to the first
+ * chapter (0). If we're on the last
+ * chapter, we return to the standard
+ * ToC.
+ * 
+ * @author  alex, alex@binarycloud.com
+ */
+function GoNext() {
+
+    var CurrentChapter = GetCurrentChapter();
+
+    if (CurrentChapter == Chapters.length-1) {
+        top.ContentAndToC.Content.location = "../toc/ToC.html";
+    } else if (CurrentChapter == null) {
+        top.ContentAndToC.Content.location = "../"+Chapters[0][0];
+    } else {
+        top.ContentAndToC.Content.location = "../"+Chapters[CurrentChapter+1][0];
+    }
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/docs/phing_guide/book/js/Chapters.js
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/docs/phing_guide/book/js/Chapters.js	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/docs/phing_guide/book/js/Chapters.js	(revision 19)
@@ -0,0 +1,16 @@
+var Chapters = new Array(new Array('chapters/AboutThisBook.html','About this book'),
+new Array('chapters/Introduction.html','Introduction'),
+new Array('chapters/Setup.html','Setting-Up Phing'),
+new Array('chapters/GettingStarted.html','Getting Started'),
+new Array('chapters/ProjectComponents.html','Project Components'),
+new Array('chapters/ExtendingPhing.html','Extending Phing'),
+new Array('chapters/appendixes/AppendixA-FactSheet.html','Appendix A: Fact Sheet'),
+new Array('chapters/appendixes/AppendixB-CoreTasks.html','Appendix B: Core Tasks'),
+new Array('chapters/appendixes/AppendixC-OptionalTasks.html','Appendix C: Optional Tasks'),
+new Array('chapters/appendixes/AppendixD-CoreTypes.html','Appendix D: Core Types'),
+new Array('chapters/appendixes/AppendixD2-CoreFilters.html','Appendix D-2: Core Filters'),
+new Array('chapters/appendixes/AppendixD3-CoreMappers.html','Appendix D-3: Core Mappers'),
+new Array('chapters/appendixes/AppendixD4-CoreSelectors.html','Appendix D: Core Selectors'),
+new Array('chapters/appendixes/AppendixE-ProjectComponents.html','Appendix E: Project Components'),
+new Array('chapters/appendixes/AppendixF-FileFormats.html','Appendix F: File Formats'),
+new Array('chapters/Bibliography.html','Bibliography'));
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/docs/phing_guide/book/toc/FrameToC.html
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/docs/phing_guide/book/toc/FrameToC.html	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/docs/phing_guide/book/toc/FrameToC.html	(revision 19)
@@ -0,0 +1,223 @@
+<!--
+-File         $Id: FrameToC.html 352 2008-02-06 15:26:43Z mrook $
+-License      GNU FDL (http://www.gnu.org/copyleft/fdl.html)
+-Copyright    2002, turing
+-Author       alex black, enigma@turingstudio.com
+-->
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/2000/REC-xhtml1-20000126/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+	<title> binarycloud contributor guide </title> 
+	<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
+	<link rel="Stylesheet" rev="Stylesheet" href="../css/FrameToc.css" type="text/css" media="All" charset="iso-8859-1" />
+</head>
+<body>
+
+<ul>
+<li><a href="../chapters/AboutThisBook.html" target="Content">About this book</a></li>
+<ul>
+<li><a href="../chapters/AboutThisBook.html#Authors" target="Content">Authors</a></li>
+<li><a href="../chapters/AboutThisBook.html#CVS" target="Content">CVS</a></li>
+<li><a href="../chapters/AboutThisBook.html#Copyright" target="Content">Copyright</a></li>
+<li><a href="../chapters/AboutThisBook.html#License" target="Content">License</a></li>
+</ul>
+</ul>
+<ul>
+<li><a href="../chapters/Introduction.html" target="Content">Introduction</a></li>
+<ul>
+<li><a href="../chapters/Introduction.html#WhatPhingIs" target="Content">What Phing Is</a></li>
+<li><a href="../chapters/Introduction.html#PhingAndBinarycloud" target="Content">Phing &amp; Binarycloud:
+  History</a></li>
+<li><a href="../chapters/Introduction.html#HowPhingWorks" target="Content">How Phing Works</a></li>
+<li><a href="../chapters/Introduction.html#HowCanIHelp" target="Content">Cool, so how can I help?</a></li>
+</ul>
+</ul>
+<ul>
+<li><a href="../chapters/Setup.html" target="Content">Setting-Up Phing</a></li>
+<ul>
+<li><a href="../chapters/Setup.html#SystemRequirements" target="Content">System Requirements</a></li>
+<li><a href="../chapters/Setup.html#ObtainingPhing" target="Content">Obtaining Phing</a></li>
+<li><a href="../chapters/Setup.html#Setup.PearInstall" target="Content">PEAR Install</a></li>
+<li><a href="../chapters/Setup.html#Setup.NonPearInstall" target="Content">Non-PEAR Install</a></li>
+<li><a href="../chapters/Setup.html#CallingPhing" target="Content">Calling Phing</a></li>
+</ul>
+</ul>
+<ul>
+<li><a href="../chapters/GettingStarted.html" target="Content">Getting Started</a></li>
+<ul>
+<li><a href="../chapters/GettingStarted.html#XMLAndPhing" target="Content">XML And Phing</a></li>
+<li><a href="../chapters/GettingStarted.html#WritingASimpleBuildfile" target="Content">Writing A Simple Buildfile</a></li>
+<li><a href="../chapters/GettingStarted.html#ComplexBuildfile" target="Content">More Complex Buildfile</a></li>
+</ul>
+</ul>
+<ul>
+<li><a href="../chapters/ProjectComponents.html" target="Content">Project Components</a></li>
+<ul>
+<li><a href="../chapters/ProjectComponents.html#Projects" target="Content">Projects</a></li>
+<li><a href="../chapters/ProjectComponents.html#ComponentsInGeneral" target="Content">Project Components in General</a></li>
+<li><a href="../chapters/ProjectComponents.html#Targets" target="Content">Targets</a></li>
+<li><a href="../chapters/ProjectComponents.html#Tasks" target="Content">Tasks</a></li>
+<li><a href="../chapters/ProjectComponents.html#Types" target="Content">Types</a></li>
+<li><a href="../chapters/ProjectComponents.html#BasicTypes" target="Content">Basic Types</a></li>
+<li><a href="../chapters/ProjectComponents.html#Conditions" target="Content">Conditions</a></li>
+</ul>
+</ul>
+<ul>
+<li><a href="../chapters/ExtendingPhing.html" target="Content">Extending Phing</a></li>
+<ul>
+<li><a href="../chapters/ExtendingPhing.html#ExtensionPossibilities" target="Content">Extension Possibilities</a></li>
+<li><a href="../chapters/ExtendingPhing.html#SourceLayout" target="Content">Source Layout</a></li>
+<li><a href="../chapters/ExtendingPhing.html#SystemInitialization" target="Content">System Initialization</a></li>
+<li><a href="../chapters/ExtendingPhing.html#SystemServices" target="Content">System Services</a></li>
+<li><a href="../chapters/ExtendingPhing.html#BuildLifecycle" target="Content">Build Lifecycle</a></li>
+<li><a href="../chapters/ExtendingPhing.html#WritingTasks" target="Content">Writing Tasks</a></li>
+<li><a href="../chapters/ExtendingPhing.html#WritingTypes" target="Content">Writing Types</a></li>
+<li><a href="../chapters/ExtendingPhing.html#WritingMappers" target="Content">Writing Mappers</a></li>
+</ul>
+</ul>
+<ul>
+<li><a href="../chapters/appendixes/AppendixA-FactSheet.html" target="Content">Appendix A: Fact Sheet</a></li>
+<ul>
+<li><a href="../chapters/appendixes/AppendixA-FactSheet.html#BuiltInProperties" target="Content">Built-In Properties</a></li>
+<li><a href="../chapters/appendixes/AppendixA-FactSheet.html#CommandLineArguments" target="Content">Command Line Arguments</a></li>
+<li><a href="../chapters/appendixes/AppendixA-FactSheet.html#DistributionFileLayout" target="Content">Distribution File Layout</a></li>
+<li><a href="../chapters/appendixes/AppendixA-FactSheet.html#ProgramExitCodes" target="Content">Program Exit Codes</a></li>
+<li><a href="../chapters/appendixes/AppendixA-FactSheet.html#LGPLLicense" target="Content">The LGPL License</a></li>
+</ul>
+</ul>
+<ul>
+<li><a href="../chapters/appendixes/AppendixB-CoreTasks.html" target="Content">Appendix B: Core Tasks</a></li>
+<ul>
+<li><a href="../chapters/appendixes/AppendixB-CoreTasks.html#AdhocTaskdefTask" target="Content">AdhocTaskdefTask</a></li>
+<li><a href="../chapters/appendixes/AppendixB-CoreTasks.html#AdhocTypedefTask" target="Content">AdhocTypedefTask</a></li>
+<li><a href="../chapters/appendixes/AppendixB-CoreTasks.html#AppendTask" target="Content">AppendTask</a></li>
+<li><a href="../chapters/appendixes/AppendixB-CoreTasks.html#AvailableTask" target="Content">AvailableTask</a></li>
+<li><a href="../chapters/appendixes/AppendixB-CoreTasks.html#PhingCallTask" target="Content">PhingCallTask</a></li>
+<li><a href="../chapters/appendixes/AppendixB-CoreTasks.html#ConditionTask" target="Content">ConditionTask</a></li>
+<li><a href="../chapters/appendixes/AppendixB-CoreTasks.html#CopyTask" target="Content">CopyTask</a></li>
+<li><a href="../chapters/appendixes/AppendixB-CoreTasks.html#DeleteTask" target="Content"> DeleteTask</a></li>
+<li><a href="../chapters/appendixes/AppendixB-CoreTasks.html#EchoTask" target="Content">EchoTask</a></li>
+<li><a href="../chapters/appendixes/AppendixB-CoreTasks.html#ExecTask" target="Content">ExecTask</a></li>
+<li><a href="../chapters/appendixes/AppendixB-CoreTasks.html#ExitTask" target="Content">ExitTask</a></li>
+<li><a href="../chapters/appendixes/AppendixB-CoreTasks.html#ForeachTask" target="Content">ForeachTask</a></li>
+<li><a href="../chapters/appendixes/AppendixB-CoreTasks.html#IfTask" target="Content">IfTask</a></li>
+<li><a href="../chapters/appendixes/AppendixB-CoreTasks.html#IncludePathTask" target="Content">IncludePathTask</a></li>
+<li><a href="../chapters/appendixes/AppendixB-CoreTasks.html#InputTask" target="Content">InputTask</a></li>
+<li><a href="../chapters/appendixes/AppendixB-CoreTasks.html#MkdirTask" target="Content">MkdirTask</a></li>
+<li><a href="../chapters/appendixes/AppendixB-CoreTasks.html#MoveTask" target="Content">MoveTask</a></li>
+<li><a href="../chapters/appendixes/AppendixB-CoreTasks.html#PhingTask" target="Content">PhingTask</a></li>
+<li><a href="../chapters/appendixes/AppendixB-CoreTasks.html#PhpEvalTask" target="Content">PhpEvalTask</a></li>
+<li><a href="../chapters/appendixes/AppendixB-CoreTasks.html#PropertyTask" target="Content">PropertyTask</a></li>
+<li><a href="../chapters/appendixes/AppendixB-CoreTasks.html#PropertyPromptTask" target="Content">PropertyPromptTask</a></li>
+<li><a href="../chapters/appendixes/AppendixB-CoreTasks.html#ReflexiveTask" target="Content">ReflexiveTask</a></li>
+<li><a href="../chapters/appendixes/AppendixB-CoreTasks.html#ResolvePathTask" target="Content">ResolvePathTask</a></li>
+<li><a href="../chapters/appendixes/AppendixB-CoreTasks.html#TaskdefTask" target="Content">TaskdefTask</a></li>
+<li><a href="../chapters/appendixes/AppendixB-CoreTasks.html#TouchTask" target="Content">TouchTask</a></li>
+<li><a href="../chapters/appendixes/AppendixB-CoreTasks.html#TstampTask" target="Content">TstampTask</a></li>
+<li><a href="../chapters/appendixes/AppendixB-CoreTasks.html#TypedefTask" target="Content">TypedefTask</a></li>
+<li><a href="../chapters/appendixes/AppendixB-CoreTasks.html#UpToDateTask" target="Content">UpToDateTask</a></li>
+<li><a href="../chapters/appendixes/AppendixB-CoreTasks.html#XsltTask" target="Content">XsltTask</a></li>
+</ul>
+</ul>
+<ul>
+<li><a href="../chapters/appendixes/AppendixC-OptionalTasks.html" target="Content">Appendix C: Optional Tasks</a></li>
+<ul>
+<li><a href="../chapters/appendixes/AppendixC-OptionalTasks.html#DbDeployTask" target="Content">DbDeployTask</a></li>
+<li><a href="../chapters/appendixes/AppendixC-OptionalTasks.html#CoverageMergerTask" target="Content">CoverageMergerTask</a></li>
+<li><a href="../chapters/appendixes/AppendixC-OptionalTasks.html#CoverageReportTask" target="Content">CoverageReportTask</a></li>
+<li><a href="../chapters/appendixes/AppendixC-OptionalTasks.html#CoverageSetupTask" target="Content">CoverageSetupTask</a></li>
+<li><a href="../chapters/appendixes/AppendixC-OptionalTasks.html#IoncubeEncoderTask" target="Content">IoncubeEncoderTask</a></li>
+<li><a href="../chapters/appendixes/AppendixC-OptionalTasks.html#IoncubeLicenseTask" target="Content">IoncubeLicenseTask</a></li>
+<li><a href="../chapters/appendixes/AppendixC-OptionalTasks.html#PDOSQLExecTask" target="Content">PDOSQLExecTask</a></li>
+<li><a href="../chapters/appendixes/AppendixC-OptionalTasks.html#PearPackageTask" target="Content">PearPackageTask</a></li>
+<li><a href="../chapters/appendixes/AppendixC-OptionalTasks.html#PearPackage2Task" target="Content">PearPackage2Task</a></li>
+<li><a href="../chapters/appendixes/AppendixC-OptionalTasks.html#PhpCodeSnifferTask" target="Content">PhpCodeSnifferTask</a></li>
+<li><a href="../chapters/appendixes/AppendixC-OptionalTasks.html#PhpDocumentorTask" target="Content">PhpDocumentorTask</a></li>
+<li><a href="../chapters/appendixes/AppendixC-OptionalTasks.html#PhpDocumentorExternalTask" target="Content">PhpDocumentorExternalTask</a></li>
+<li><a href="../chapters/appendixes/AppendixC-OptionalTasks.html#PhpLintTask" target="Content">PhpLintTask</a></li>
+<li><a href="../chapters/appendixes/AppendixC-OptionalTasks.html#PHPUnitTask" target="Content">PHPUnitTask</a></li>
+<li><a href="../chapters/appendixes/AppendixC-OptionalTasks.html#PHPUnitReport" target="Content">PHPUnitReport</a></li>
+<li><a href="../chapters/appendixes/AppendixC-OptionalTasks.html#SvnCheckoutTask" target="Content">SvnCheckoutTask</a></li>
+<li><a href="../chapters/appendixes/AppendixC-OptionalTasks.html#SvnExportTask" target="Content">SvnExportTask</a></li>
+<li><a href="../chapters/appendixes/AppendixC-OptionalTasks.html#SvnLastRevisionTask" target="Content">SvnLastRevisionTask</a></li>
+<li><a href="../chapters/appendixes/AppendixC-OptionalTasks.html#SvnUpdateTask" target="Content">SvnUpdateTask</a></li>
+<li><a href="../chapters/appendixes/AppendixC-OptionalTasks.html#TarTask" target="Content">TarTask</a></li>
+<li><a href="../chapters/appendixes/AppendixC-OptionalTasks.html#UntarTask" target="Content">UntarTask</a></li>
+<li><a href="../chapters/appendixes/AppendixC-OptionalTasks.html#UnzipTask" target="Content">UnzipTask</a></li>
+<li><a href="../chapters/appendixes/AppendixC-OptionalTasks.html#XmlLintTask" target="Content">XmlLintTask</a></li>
+<li><a href="../chapters/appendixes/AppendixC-OptionalTasks.html#ZendCodeAnalyzerTask" target="Content">ZendCodeAnalyzerTask</a></li>
+<li><a href="../chapters/appendixes/AppendixC-OptionalTasks.html#ZipTask" target="Content">ZipTask</a></li>
+</ul>
+</ul>
+<ul>
+<li><a href="../chapters/appendixes/AppendixD-CoreTypes.html" target="Content">Appendix D: Core Types</a></li>
+<ul>
+<li><a href="../chapters/appendixes/AppendixD-CoreTypes.html#FileList" target="Content">FileList</a></li>
+<li><a href="../chapters/appendixes/AppendixD-CoreTypes.html#Fileset" target="Content">FileSet</a></li>
+<li><a href="../chapters/appendixes/AppendixD-CoreTypes.html#Path" target="Content">Path / Classpath</a></li>
+</ul>
+</ul>
+<ul>
+<li><a href="../chapters/appendixes/AppendixD2-CoreFilters.html" target="Content">Appendix D-2: Core Filters</a></li>
+<ul>
+<li><a href="../chapters/appendixes/AppendixD2-CoreFilters.html#PhingFilterReader" target="Content">PhingFilterReader</a></li>
+<li><a href="../chapters/appendixes/AppendixD2-CoreFilters.html#ExpandProperties" target="Content">ExpandProperties</a></li>
+<li><a href="../chapters/appendixes/AppendixD2-CoreFilters.html#HeadFilter" target="Content">HeadFilter</a></li>
+<li><a href="../chapters/appendixes/AppendixD2-CoreFilters.html#LineContains" target="Content">Line Contains</a></li>
+<li><a href="../chapters/appendixes/AppendixD2-CoreFilters.html#LineContainsRegexp" target="Content">LineContainsRegexp</a></li>
+<li><a href="../chapters/appendixes/AppendixD2-CoreFilters.html#PrefixLines" target="Content">PrefixLines</a></li>
+<li><a href="../chapters/appendixes/AppendixD2-CoreFilters.html#ReplaceTokens" target="Content">ReplaceTokens</a></li>
+<li><a href="../chapters/appendixes/AppendixD2-CoreFilters.html#ReplaceRegexp" target="Content">ReplaceRegexp</a></li>
+<li><a href="../chapters/appendixes/AppendixD2-CoreFilters.html#StripLineBreaks" target="Content">StripLineBreaks</a></li>
+<li><a href="../chapters/appendixes/AppendixD2-CoreFilters.html#StripLineComments" target="Content">StripLineComments</a></li>
+<li><a href="../chapters/appendixes/AppendixD2-CoreFilters.html#StripPhpComments" target="Content">StripPhpComments</a></li>
+<li><a href="../chapters/appendixes/AppendixD2-CoreFilters.html#StripWhitespace" target="Content">StripWhitespace</a></li>
+<li><a href="../chapters/appendixes/AppendixD2-CoreFilters.html#TabToSpaces" target="Content">TabToSpaces</a></li>
+<li><a href="../chapters/appendixes/AppendixD2-CoreFilters.html#TailFilter" target="Content">TailFilter</a></li>
+<li><a href="../chapters/appendixes/AppendixD2-CoreFilters.html#TidyFilter" target="Content">TidyFilter</a></li>
+<li><a href="../chapters/appendixes/AppendixD2-CoreFilters.html#XincludeFilter" target="Content">XincludeFilter</a></li>
+<li><a href="../chapters/appendixes/AppendixD2-CoreFilters.html#XsltFilter" target="Content">XsltFilter</a></li>
+</ul>
+</ul>
+<ul>
+<li><a href="../chapters/appendixes/AppendixD3-CoreMappers.html" target="Content">Appendix D-3: Core Mappers</a></li>
+<ul>
+<li><a href="../chapters/appendixes/AppendixD3-CoreMappers.html#FlattenMapper" target="Content">FlattenMapper</a></li>
+<li><a href="../chapters/appendixes/AppendixD3-CoreMappers.html#GlobMapper" target="Content">GlobMapper</a></li>
+<li><a href="../chapters/appendixes/AppendixD3-CoreMappers.html#IdentityMapper" target="Content">IdentityMapper</a></li>
+<li><a href="../chapters/appendixes/AppendixD3-CoreMappers.html#MergeMapper" target="Content">MergeMapper</a></li>
+<li><a href="../chapters/appendixes/AppendixD3-CoreMappers.html#RegexpMapper" target="Content">RegexpMapper</a></li>
+</ul>
+</ul>
+<ul>
+<li><a href="../chapters/appendixes/AppendixD4-CoreSelectors.html" target="Content">Appendix D: Core Selectors</a></li>
+<ul></ul>
+</ul>
+<ul>
+<li><a href="../chapters/appendixes/AppendixE-ProjectComponents.html" target="Content">Appendix E: Project Components</a></li>
+<ul>
+<li><a href="../chapters/appendixes/AppendixE-ProjectComponents.html#Project" target="Content">Phing Projects</a></li>
+<li><a href="../chapters/appendixes/AppendixE-ProjectComponents.html#Target" target="Content">Targets</a></li>
+</ul>
+</ul>
+<ul>
+<li><a href="../chapters/appendixes/AppendixF-FileFormats.html" target="Content">Appendix F: File Formats</a></li>
+<ul>
+<li><a href="../chapters/appendixes/AppendixF-FileFormats.html#BuildFileFormat" target="Content">Build File Format</a></li>
+<li><a href="../chapters/appendixes/AppendixF-FileFormats.html#PropertyFileFormat" target="Content">Property File Format</a></li>
+</ul>
+</ul>
+<ul>
+<li><a href="../chapters/Bibliography.html" target="Content">Bibliography</a></li>
+<ul>
+<li><a href="../chapters/Bibliography.html#InternationalStandards" target="Content">International Standards</a></li>
+<li><a href="../chapters/Bibliography.html#licenses" target="Content">Licenses</a></li>
+<li><a href="../chapters/Bibliography.html#os-projects" target="Content">Open Source Projects</a></li>
+<li><a href="../chapters/Bibliography.html#Manuals" target="Content">Manuals</a></li>
+<li><a href="../chapters/Bibliography.html#OtherResouces" target="Content">Other Resources</a></li>
+</ul>
+</ul>
+
+</body>
+</html>
+<!-- $Id -->
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/docs/phing_guide/book/toc/ToC.html
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/docs/phing_guide/book/toc/ToC.html	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/docs/phing_guide/book/toc/ToC.html	(revision 19)
@@ -0,0 +1,209 @@
+<ul>
+<li><a href="../chapters/AboutThisBook.html">About this book</a></li>
+<ul>
+<li><a href="../chapters/AboutThisBook.html#Authors">Authors</a></li>
+<li><a href="../chapters/AboutThisBook.html#CVS">CVS</a></li>
+<li><a href="../chapters/AboutThisBook.html#Copyright">Copyright</a></li>
+<li><a href="../chapters/AboutThisBook.html#License">License</a></li>
+</ul>
+</ul>
+<ul>
+<li><a href="../chapters/Introduction.html">Introduction</a></li>
+<ul>
+<li><a href="../chapters/Introduction.html#WhatPhingIs">What Phing Is</a></li>
+<li><a href="../chapters/Introduction.html#PhingAndBinarycloud">Phing &amp; Binarycloud:
+  History</a></li>
+<li><a href="../chapters/Introduction.html#HowPhingWorks">How Phing Works</a></li>
+<li><a href="../chapters/Introduction.html#HowCanIHelp">Cool, so how can I help?</a></li>
+</ul>
+</ul>
+<ul>
+<li><a href="../chapters/Setup.html">Setting-Up Phing</a></li>
+<ul>
+<li><a href="../chapters/Setup.html#SystemRequirements">System Requirements</a></li>
+<li><a href="../chapters/Setup.html#ObtainingPhing">Obtaining Phing</a></li>
+<li><a href="../chapters/Setup.html#Setup.PearInstall">PEAR Install</a></li>
+<li><a href="../chapters/Setup.html#Setup.NonPearInstall">Non-PEAR Install</a></li>
+<li><a href="../chapters/Setup.html#CallingPhing">Calling Phing</a></li>
+</ul>
+</ul>
+<ul>
+<li><a href="../chapters/GettingStarted.html">Getting Started</a></li>
+<ul>
+<li><a href="../chapters/GettingStarted.html#XMLAndPhing">XML And Phing</a></li>
+<li><a href="../chapters/GettingStarted.html#WritingASimpleBuildfile">Writing A Simple Buildfile</a></li>
+<li><a href="../chapters/GettingStarted.html#ComplexBuildfile">More Complex Buildfile</a></li>
+</ul>
+</ul>
+<ul>
+<li><a href="../chapters/ProjectComponents.html">Project Components</a></li>
+<ul>
+<li><a href="../chapters/ProjectComponents.html#Projects">Projects</a></li>
+<li><a href="../chapters/ProjectComponents.html#ComponentsInGeneral">Project Components in General</a></li>
+<li><a href="../chapters/ProjectComponents.html#Targets">Targets</a></li>
+<li><a href="../chapters/ProjectComponents.html#Tasks">Tasks</a></li>
+<li><a href="../chapters/ProjectComponents.html#Types">Types</a></li>
+<li><a href="../chapters/ProjectComponents.html#BasicTypes">Basic Types</a></li>
+<li><a href="../chapters/ProjectComponents.html#Conditions">Conditions</a></li>
+</ul>
+</ul>
+<ul>
+<li><a href="../chapters/ExtendingPhing.html">Extending Phing</a></li>
+<ul>
+<li><a href="../chapters/ExtendingPhing.html#ExtensionPossibilities">Extension Possibilities</a></li>
+<li><a href="../chapters/ExtendingPhing.html#SourceLayout">Source Layout</a></li>
+<li><a href="../chapters/ExtendingPhing.html#SystemInitialization">System Initialization</a></li>
+<li><a href="../chapters/ExtendingPhing.html#SystemServices">System Services</a></li>
+<li><a href="../chapters/ExtendingPhing.html#BuildLifecycle">Build Lifecycle</a></li>
+<li><a href="../chapters/ExtendingPhing.html#WritingTasks">Writing Tasks</a></li>
+<li><a href="../chapters/ExtendingPhing.html#WritingTypes">Writing Types</a></li>
+<li><a href="../chapters/ExtendingPhing.html#WritingMappers">Writing Mappers</a></li>
+</ul>
+</ul>
+<ul>
+<li><a href="../chapters/appendixes/AppendixA-FactSheet.html">Appendix A: Fact Sheet</a></li>
+<ul>
+<li><a href="../chapters/appendixes/AppendixA-FactSheet.html#BuiltInProperties">Built-In Properties</a></li>
+<li><a href="../chapters/appendixes/AppendixA-FactSheet.html#CommandLineArguments">Command Line Arguments</a></li>
+<li><a href="../chapters/appendixes/AppendixA-FactSheet.html#DistributionFileLayout">Distribution File Layout</a></li>
+<li><a href="../chapters/appendixes/AppendixA-FactSheet.html#ProgramExitCodes">Program Exit Codes</a></li>
+<li><a href="../chapters/appendixes/AppendixA-FactSheet.html#LGPLLicense">The LGPL License</a></li>
+</ul>
+</ul>
+<ul>
+<li><a href="../chapters/appendixes/AppendixB-CoreTasks.html">Appendix B: Core Tasks</a></li>
+<ul>
+<li><a href="../chapters/appendixes/AppendixB-CoreTasks.html#AdhocTaskdefTask">AdhocTaskdefTask</a></li>
+<li><a href="../chapters/appendixes/AppendixB-CoreTasks.html#AdhocTypedefTask">AdhocTypedefTask</a></li>
+<li><a href="../chapters/appendixes/AppendixB-CoreTasks.html#AppendTask">AppendTask</a></li>
+<li><a href="../chapters/appendixes/AppendixB-CoreTasks.html#AvailableTask">AvailableTask</a></li>
+<li><a href="../chapters/appendixes/AppendixB-CoreTasks.html#PhingCallTask">PhingCallTask</a></li>
+<li><a href="../chapters/appendixes/AppendixB-CoreTasks.html#ConditionTask">ConditionTask</a></li>
+<li><a href="../chapters/appendixes/AppendixB-CoreTasks.html#CopyTask">CopyTask</a></li>
+<li><a href="../chapters/appendixes/AppendixB-CoreTasks.html#DeleteTask"> DeleteTask</a></li>
+<li><a href="../chapters/appendixes/AppendixB-CoreTasks.html#EchoTask">EchoTask</a></li>
+<li><a href="../chapters/appendixes/AppendixB-CoreTasks.html#ExecTask">ExecTask</a></li>
+<li><a href="../chapters/appendixes/AppendixB-CoreTasks.html#ExitTask">ExitTask</a></li>
+<li><a href="../chapters/appendixes/AppendixB-CoreTasks.html#ForeachTask">ForeachTask</a></li>
+<li><a href="../chapters/appendixes/AppendixB-CoreTasks.html#IfTask">IfTask</a></li>
+<li><a href="../chapters/appendixes/AppendixB-CoreTasks.html#IncludePathTask">IncludePathTask</a></li>
+<li><a href="../chapters/appendixes/AppendixB-CoreTasks.html#InputTask">InputTask</a></li>
+<li><a href="../chapters/appendixes/AppendixB-CoreTasks.html#MkdirTask">MkdirTask</a></li>
+<li><a href="../chapters/appendixes/AppendixB-CoreTasks.html#MoveTask">MoveTask</a></li>
+<li><a href="../chapters/appendixes/AppendixB-CoreTasks.html#PhingTask">PhingTask</a></li>
+<li><a href="../chapters/appendixes/AppendixB-CoreTasks.html#PhpEvalTask">PhpEvalTask</a></li>
+<li><a href="../chapters/appendixes/AppendixB-CoreTasks.html#PropertyTask">PropertyTask</a></li>
+<li><a href="../chapters/appendixes/AppendixB-CoreTasks.html#PropertyPromptTask">PropertyPromptTask</a></li>
+<li><a href="../chapters/appendixes/AppendixB-CoreTasks.html#ReflexiveTask">ReflexiveTask</a></li>
+<li><a href="../chapters/appendixes/AppendixB-CoreTasks.html#ResolvePathTask">ResolvePathTask</a></li>
+<li><a href="../chapters/appendixes/AppendixB-CoreTasks.html#TaskdefTask">TaskdefTask</a></li>
+<li><a href="../chapters/appendixes/AppendixB-CoreTasks.html#TouchTask">TouchTask</a></li>
+<li><a href="../chapters/appendixes/AppendixB-CoreTasks.html#TstampTask">TstampTask</a></li>
+<li><a href="../chapters/appendixes/AppendixB-CoreTasks.html#TypedefTask">TypedefTask</a></li>
+<li><a href="../chapters/appendixes/AppendixB-CoreTasks.html#UpToDateTask">UpToDateTask</a></li>
+<li><a href="../chapters/appendixes/AppendixB-CoreTasks.html#XsltTask">XsltTask</a></li>
+</ul>
+</ul>
+<ul>
+<li><a href="../chapters/appendixes/AppendixC-OptionalTasks.html">Appendix C: Optional Tasks</a></li>
+<ul>
+<li><a href="../chapters/appendixes/AppendixC-OptionalTasks.html#DbDeployTask">DbDeployTask</a></li>
+<li><a href="../chapters/appendixes/AppendixC-OptionalTasks.html#CoverageMergerTask">CoverageMergerTask</a></li>
+<li><a href="../chapters/appendixes/AppendixC-OptionalTasks.html#CoverageReportTask">CoverageReportTask</a></li>
+<li><a href="../chapters/appendixes/AppendixC-OptionalTasks.html#CoverageSetupTask">CoverageSetupTask</a></li>
+<li><a href="../chapters/appendixes/AppendixC-OptionalTasks.html#IoncubeEncoderTask">IoncubeEncoderTask</a></li>
+<li><a href="../chapters/appendixes/AppendixC-OptionalTasks.html#IoncubeLicenseTask">IoncubeLicenseTask</a></li>
+<li><a href="../chapters/appendixes/AppendixC-OptionalTasks.html#PDOSQLExecTask">PDOSQLExecTask</a></li>
+<li><a href="../chapters/appendixes/AppendixC-OptionalTasks.html#PearPackageTask">PearPackageTask</a></li>
+<li><a href="../chapters/appendixes/AppendixC-OptionalTasks.html#PearPackage2Task">PearPackage2Task</a></li>
+<li><a href="../chapters/appendixes/AppendixC-OptionalTasks.html#PhpCodeSnifferTask">PhpCodeSnifferTask</a></li>
+<li><a href="../chapters/appendixes/AppendixC-OptionalTasks.html#PhpDocumentorTask">PhpDocumentorTask</a></li>
+<li><a href="../chapters/appendixes/AppendixC-OptionalTasks.html#PhpDocumentorExternalTask">PhpDocumentorExternalTask</a></li>
+<li><a href="../chapters/appendixes/AppendixC-OptionalTasks.html#PhpLintTask">PhpLintTask</a></li>
+<li><a href="../chapters/appendixes/AppendixC-OptionalTasks.html#PHPUnitTask">PHPUnitTask</a></li>
+<li><a href="../chapters/appendixes/AppendixC-OptionalTasks.html#PHPUnitReport">PHPUnitReport</a></li>
+<li><a href="../chapters/appendixes/AppendixC-OptionalTasks.html#SvnCheckoutTask">SvnCheckoutTask</a></li>
+<li><a href="../chapters/appendixes/AppendixC-OptionalTasks.html#SvnExportTask">SvnExportTask</a></li>
+<li><a href="../chapters/appendixes/AppendixC-OptionalTasks.html#SvnLastRevisionTask">SvnLastRevisionTask</a></li>
+<li><a href="../chapters/appendixes/AppendixC-OptionalTasks.html#SvnUpdateTask">SvnUpdateTask</a></li>
+<li><a href="../chapters/appendixes/AppendixC-OptionalTasks.html#TarTask">TarTask</a></li>
+<li><a href="../chapters/appendixes/AppendixC-OptionalTasks.html#UntarTask">UntarTask</a></li>
+<li><a href="../chapters/appendixes/AppendixC-OptionalTasks.html#UnzipTask">UnzipTask</a></li>
+<li><a href="../chapters/appendixes/AppendixC-OptionalTasks.html#XmlLintTask">XmlLintTask</a></li>
+<li><a href="../chapters/appendixes/AppendixC-OptionalTasks.html#ZendCodeAnalyzerTask">ZendCodeAnalyzerTask</a></li>
+<li><a href="../chapters/appendixes/AppendixC-OptionalTasks.html#ZipTask">ZipTask</a></li>
+</ul>
+</ul>
+<ul>
+<li><a href="../chapters/appendixes/AppendixD-CoreTypes.html">Appendix D: Core Types</a></li>
+<ul>
+<li><a href="../chapters/appendixes/AppendixD-CoreTypes.html#FileList">FileList</a></li>
+<li><a href="../chapters/appendixes/AppendixD-CoreTypes.html#Fileset">FileSet</a></li>
+<li><a href="../chapters/appendixes/AppendixD-CoreTypes.html#Path">Path / Classpath</a></li>
+</ul>
+</ul>
+<ul>
+<li><a href="../chapters/appendixes/AppendixD2-CoreFilters.html">Appendix D-2: Core Filters</a></li>
+<ul>
+<li><a href="../chapters/appendixes/AppendixD2-CoreFilters.html#PhingFilterReader">PhingFilterReader</a></li>
+<li><a href="../chapters/appendixes/AppendixD2-CoreFilters.html#ExpandProperties">ExpandProperties</a></li>
+<li><a href="../chapters/appendixes/AppendixD2-CoreFilters.html#HeadFilter">HeadFilter</a></li>
+<li><a href="../chapters/appendixes/AppendixD2-CoreFilters.html#LineContains">Line Contains</a></li>
+<li><a href="../chapters/appendixes/AppendixD2-CoreFilters.html#LineContainsRegexp">LineContainsRegexp</a></li>
+<li><a href="../chapters/appendixes/AppendixD2-CoreFilters.html#PrefixLines">PrefixLines</a></li>
+<li><a href="../chapters/appendixes/AppendixD2-CoreFilters.html#ReplaceTokens">ReplaceTokens</a></li>
+<li><a href="../chapters/appendixes/AppendixD2-CoreFilters.html#ReplaceRegexp">ReplaceRegexp</a></li>
+<li><a href="../chapters/appendixes/AppendixD2-CoreFilters.html#StripLineBreaks">StripLineBreaks</a></li>
+<li><a href="../chapters/appendixes/AppendixD2-CoreFilters.html#StripLineComments">StripLineComments</a></li>
+<li><a href="../chapters/appendixes/AppendixD2-CoreFilters.html#StripPhpComments">StripPhpComments</a></li>
+<li><a href="../chapters/appendixes/AppendixD2-CoreFilters.html#StripWhitespace">StripWhitespace</a></li>
+<li><a href="../chapters/appendixes/AppendixD2-CoreFilters.html#TabToSpaces">TabToSpaces</a></li>
+<li><a href="../chapters/appendixes/AppendixD2-CoreFilters.html#TailFilter">TailFilter</a></li>
+<li><a href="../chapters/appendixes/AppendixD2-CoreFilters.html#TidyFilter">TidyFilter</a></li>
+<li><a href="../chapters/appendixes/AppendixD2-CoreFilters.html#XincludeFilter">XincludeFilter</a></li>
+<li><a href="../chapters/appendixes/AppendixD2-CoreFilters.html#XsltFilter">XsltFilter</a></li>
+</ul>
+</ul>
+<ul>
+<li><a href="../chapters/appendixes/AppendixD3-CoreMappers.html">Appendix D-3: Core Mappers</a></li>
+<ul>
+<li><a href="../chapters/appendixes/AppendixD3-CoreMappers.html#FlattenMapper">FlattenMapper</a></li>
+<li><a href="../chapters/appendixes/AppendixD3-CoreMappers.html#GlobMapper">GlobMapper</a></li>
+<li><a href="../chapters/appendixes/AppendixD3-CoreMappers.html#IdentityMapper">IdentityMapper</a></li>
+<li><a href="../chapters/appendixes/AppendixD3-CoreMappers.html#MergeMapper">MergeMapper</a></li>
+<li><a href="../chapters/appendixes/AppendixD3-CoreMappers.html#RegexpMapper">RegexpMapper</a></li>
+</ul>
+</ul>
+<ul>
+<li><a href="../chapters/appendixes/AppendixD4-CoreSelectors.html">Appendix D: Core Selectors</a></li>
+<ul></ul>
+</ul>
+<ul>
+<li><a href="../chapters/appendixes/AppendixE-ProjectComponents.html">Appendix E: Project Components</a></li>
+<ul>
+<li><a href="../chapters/appendixes/AppendixE-ProjectComponents.html#Project">Phing Projects</a></li>
+<li><a href="../chapters/appendixes/AppendixE-ProjectComponents.html#Target">Targets</a></li>
+</ul>
+</ul>
+<ul>
+<li><a href="../chapters/appendixes/AppendixF-FileFormats.html">Appendix F: File Formats</a></li>
+<ul>
+<li><a href="../chapters/appendixes/AppendixF-FileFormats.html#BuildFileFormat">Build File Format</a></li>
+<li><a href="../chapters/appendixes/AppendixF-FileFormats.html#PropertyFileFormat">Property File Format</a></li>
+</ul>
+</ul>
+<ul>
+<li><a href="../chapters/Bibliography.html">Bibliography</a></li>
+<ul>
+<li><a href="../chapters/Bibliography.html#InternationalStandards">International Standards</a></li>
+<li><a href="../chapters/Bibliography.html#licenses">Licenses</a></li>
+<li><a href="../chapters/Bibliography.html#os-projects">Open Source Projects</a></li>
+<li><a href="../chapters/Bibliography.html#Manuals">Manuals</a></li>
+<li><a href="../chapters/Bibliography.html#OtherResouces">Other Resources</a></li>
+</ul>
+</ul>
+
+
+</body>
+</html>
+<!-- $Id -->
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/docs/phing_guide/build.xml
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/docs/phing_guide/build.xml	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/docs/phing_guide/build.xml	(revision 19)
@@ -0,0 +1,171 @@
+<project name="phing_guide" default="main" basedir=".">
+
+  <!-- ================================================================ -->
+  <!-- M A I N  T A R G E T                                             -->
+  <!-- ================================================================ -->
+	<target
+		name="main"
+		description="==>build phing_guide">
+		
+		<!-- <phingcall target="normalize_linebreaks"/> -->
+		<phingcall target="remove_old_toc"/>
+		<phingcall target="gen_standard_toc"/>
+		<phingcall target="gen_frame_toc"/>
+		<phingcall target="gen_chapter_js"/>
+		
+		<!-- the next step here would be to create a PDF -->
+		     
+	</target>
+	
+	<!--
+	##==============================================
+	## Normalize line breaks to ensure a good
+	## conversion
+	##
+	## @author  alex black, enigma@turingstudio.com
+	## @revision $Revision: 1.6 $
+	##==============================================	
+	-->
+	<target name="normalize_linebreaks"
+			description="==>normalize linebreaks (make them unix)">
+		<!-- use replaceregexp filter to handle the normalization -->
+
+		<echo message="/----------------------------------\"/>
+		<echo message="| NORMALIZING LINE BREAKS          |"/>
+		<echo message="\----------------------------------/"/>
+		     
+		<reflexive>
+			<fileset dir=".">
+				<include name="**/*.html"/>
+			</fileset>
+			<filterchain>
+				<replaceregexp>
+					<regexp pattern="\r\n" replace="\n"/>
+					<regexp pattern="\r" replace="\n"/>
+				</replaceregexp>
+			</filterchain>
+		</reflexive>
+		
+	</target>
+	
+	<!--
+    ##==============================================
+	## Kill any old ToC
+	##
+	## @author  alex black, enigma@turingstudio.com
+	##==============================================	
+	-->
+	<target 
+		name="remove_old_toc" 
+		description="==> deletes the old table of contents file.">
+			
+		<echo message="/----------------------------------\"/>
+		<echo message="|      REMOVING OLD TOC FILES      |"/>
+		<echo message="\----------------------------------/"/>
+
+		<delete file="book/toc/ToC.html"/>
+		<delete file="book/toc/FrameToC.html"/>
+		<delete file="book/js/Chapters.js"/>
+
+	</target>
+	
+	<!--	
+	##==============================================
+	## generate a standard Toc
+	##
+	## @author  alex black, enigma@turingstudio.com
+	##==============================================	
+	-->
+	<target
+		name="gen_standard_toc"
+		description="==>generate a standard Toc">
+
+		<echo message="/----------------------------------\"/>
+		<echo message="| GENERATE STD TABLE OF CONTENTS   |"/>
+		<echo message="\----------------------------------/"/>		
+		
+		<append destFile="book/toc/ToC.html">					
+			<filterchain>
+				<xsltfilter style="../docsystem/xsl/Toc.xsl" html="yes">
+					<param name="mode" expression="standard"/>
+					<param name="file_name" expression="%{task.append.current_file}"/>
+				</xsltfilter>
+			</filterchain>
+			<filelist dir="book/" listfile="book/PhingGuide.book"/>			
+		</append>
+		
+		
+		<append file="../docsystem/html/StandardToCBottom.html" destFile="book/toc/ToC.html"/>				
+		 
+	</target>
+	
+	<!--
+	##==============================================
+	## generate a frame Toc
+	##
+	## @author  alex black, enigma@turingstudio.com
+	##==============================================	
+	-->
+	<target name="gen_frame_toc"
+			description="==>generate table of contents for frame">
+		
+		<echo message="/----------------------------------\"/>
+		<echo message="| GENERATE FRAME TABLE OF CONTENTS |"/>
+		<echo message="\----------------------------------/"/>
+		
+		<append file="../docsystem/html/FrameToCTop.html" destFile="book/toc/FrameToC.html"/>
+			
+		<append destFile="book/toc/FrameToC.html">					
+			<filterchain>
+				<xsltfilter style="../docsystem/xsl/Toc.xsl" html="yes">
+					<param name="mode" expression="frame"/>
+					<param name="file_name" expression="%{task.append.current_file}"/>
+				</xsltfilter>
+			</filterchain>
+			<filelist dir="book/" listfile="book/PhingGuide.book"/>			
+		</append>
+									
+		<append file="../docsystem/html/FrameToCBottom.html" destFile="book/toc/FrameToC.html"/>				
+	
+	</target>
+	
+	<!--	
+	##==============================================
+	## generate chapter JS array
+	##
+	## @author  alex black, enigma@turingstudio.com
+	##==============================================	
+	-->
+	<target name="gen_chapter_js"
+			description="==>generate the javascript">
+
+		<echo message="/----------------------------------\"/>
+		<echo message="| GENERATE CHAPTER JAVASCRIPT      |"/>
+		<echo message="\----------------------------------/"/>
+		
+		<append text="var Chapters = new Array(" destFile="book/js/Chapters.js"/>
+		
+		<append destFile="book/js/Chapters.js">					
+			<filterchain>
+				<xsltfilter style="../docsystem/xsl/Chapters.xsl" html="yes">
+					<param name="mode" expression="${process.xslt.mode}"/>
+					<param name="file_name" expression="%{task.append.current_file}"/>
+				</xsltfilter>
+			</filterchain>
+			<filelist dir="book/" listfile="book/PhingGuide.book"/>			
+		</append>
+				
+		<append text=");" destFile="book/js/Chapters.js"/>				
+		
+		<!-- remove the trailing ',' because the XSLT does not (and this will trigger jscript errors) -->
+		<reflexive file="book/js/Chapters.js">
+			<filterchain>
+				<replaceregexp>
+					<regexp pattern="\),[\s]+\);" replace="));"/>
+				</replaceregexp>
+			</filterchain>
+		</reflexive>
+			
+	</target>
+	
+</project>
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/docs/phing_guide/langs/de/README.txt
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/docs/phing_guide/langs/de/README.txt	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/docs/phing_guide/langs/de/README.txt	(revision 19)
@@ -0,0 +1,1 @@
+This is a placeholder for the german translation tree.
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/docs/phing_guide/langs/fr/README.txt
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/docs/phing_guide/langs/fr/README.txt	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/docs/phing_guide/langs/fr/README.txt	(revision 19)
@@ -0,0 +1,1 @@
+This is a placeholder for the french translation tree.
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/docs/phing_guide/langs/pt_BR/README.txt
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/docs/phing_guide/langs/pt_BR/README.txt	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/docs/phing_guide/langs/pt_BR/README.txt	(revision 19)
@@ -0,0 +1,1 @@
+This is a placeholder for the brazilian portuguese translation tree.
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/etc/VERSION.TXT
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/etc/VERSION.TXT	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/etc/VERSION.TXT	(revision 19)
@@ -0,0 +1,1 @@
+Phing 2.3 BRANCH (2.3dev)
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/etc/coverage-frames.xsl
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/etc/coverage-frames.xsl	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/etc/coverage-frames.xsl	(revision 19)
@@ -0,0 +1,668 @@
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"
+    xmlns:exsl="http://exslt.org/common"
+    xmlns:date="http://exslt.org/dates-and-times"
+    extension-element-prefixes="exsl date">
+<xsl:output method="html" indent="yes"/>
+<xsl:decimal-format decimal-separator="." grouping-separator="," />
+<!--
+    Copyright  2001-2004 The Apache Software Foundation
+   
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+   
+         http://www.apache.org/licenses/LICENSE-2.0
+   
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+   
+-->
+
+<!--
+
+ Sample stylesheet to be used with Xdebug/Phing code coverage output.
+ Based on JProbe stylesheets from Apache Ant.
+
+ It creates a set of HTML files a la javadoc where you can browse easily
+ through all packages and classes.
+
+ @author Michiel Rook <a href="mailto:michiel.rook@gmail.com"/>
+ @author Stephane Bailliez <a href="mailto:sbailliez@apache.org"/>
+
+-->
+
+<!-- default output directory is current directory -->
+<xsl:param name="output.dir" select="'.'"/>
+
+<!-- ======================================================================
+    Root element
+    ======================================================================= -->
+<xsl:template match="/snapshot">
+    <!-- create the index.html -->
+    <exsl:document href="efile://{$output.dir}/index.html">
+        <xsl:call-template name="index.html"/>
+    </exsl:document>
+
+    <!-- create the stylesheet.css -->
+    <exsl:document href="efile://{$output.dir}/stylesheet.css">
+        <xsl:call-template name="stylesheet.css"/>
+    </exsl:document>
+
+    <!-- create the overview-packages.html at the root -->
+    <exsl:document href="efile://{$output.dir}/overview-summary.html">
+        <xsl:apply-templates select="." mode="overview.packages"/>
+    </exsl:document>
+
+    <!-- create the all-packages.html at the root -->
+    <exsl:document href="efile://{$output.dir}/overview-frame.html">
+        <xsl:apply-templates select="." mode="all.packages"/>
+    </exsl:document>
+
+    <!-- create the all-classes.html at the root -->
+    <exsl:document href="efile://{$output.dir}/allclasses-frame.html">
+        <xsl:apply-templates select="." mode="all.classes"/>
+    </exsl:document>
+
+    <!-- process all packages -->
+    <xsl:apply-templates select="./package" mode="write"/>
+</xsl:template>
+
+<!-- =======================================================================
+    Frameset definition. Entry point for the report.
+    3 frames: packageListFrame, classListFrame, classFrame
+    ======================================================================= -->
+<xsl:template name="index.html">
+<html>
+    <head><title>Coverage Results.</title></head>
+    <frameset cols="20%,80%">
+        <frameset rows="30%,70%">
+            <frame src="overview-frame.html" name="packageListFrame"/>
+            <frame src="allclasses-frame.html" name="classListFrame"/>
+        </frameset>
+        <frame src="overview-summary.html" name="classFrame"/>
+    </frameset>
+    <noframes>
+        <h2>Frame Alert</h2>
+        <p>
+        This document is designed to be viewed using the frames feature. If you see this message, you are using a non-frame-capable web client.
+        </p>
+    </noframes>
+</html>
+</xsl:template>
+
+<!-- =======================================================================
+    Stylesheet CSS used
+    ======================================================================= -->
+<!-- this is the stylesheet css to use for nearly everything -->
+<xsl:template name="stylesheet.css">
+    .bannercell {
+      border: 0px;
+      padding: 0px;
+    }
+    body {
+      margin-left: 10;
+      margin-right: 10;
+      background-color:#FFFFFF;
+      font-family: verdana,arial,sanserif;
+      color:#000000;
+    }
+    a {
+      color: #003399;
+    }
+    a:hover {
+      color: #888888;
+    }
+    .a td {
+      background: #efefef;
+    }
+    .b td {
+      background: #fff;
+    }
+    th, td {
+      text-align: left;
+      vertical-align: top;
+    }
+    th {
+      font-weight:bold;
+      background: #ccc;
+      color: black;
+    }
+    table, th, td {
+      font-size: 12px;
+      border: none
+    }
+    table.log tr td, tr th {
+    }
+    h2 {
+      font-weight:bold;
+      font-size: 12px;
+      margin-bottom: 5;
+    }
+    h3 {
+      font-size:100%;
+      font-weight: 12px;
+       background: #DFDFDF
+      color: white;
+      text-decoration: none;
+      padding: 5px;
+      margin-right: 2px;
+      margin-left: 2px;
+      margin-bottom: 0;
+    }
+    .small {
+       font-size: 9px;
+    }
+TD.empty {
+    FONT-SIZE: 2px; BACKGROUND: #c0c0c0; BORDER:#9c9c9c 1px solid;
+    color: #c0c0c0;
+}
+TD.fullcover {
+    FONT-SIZE: 2px; BACKGROUND: #00df00; BORDER:#9c9c9c 1px solid;
+    color: #00df00;
+}
+TD.covered {
+    FONT-SIZE: 2px; BACKGROUND: #00df00; BORDER-LEFT:#9c9c9c 1px solid;BORDER-TOP:#9c9c9c 1px solid;BORDER-BOTTOM:#9c9c9c 1px solid;
+    color: #00df00;
+}
+TD.uncovered {
+    FONT-SIZE: 2px; BACKGROUND: #df0000; BORDER:#9c9c9c 1px solid;
+    color: #df0000;
+}
+PRE.srcLine {
+  BACKGROUND: #ffffff; MARGIN-TOP: 0px; MARGIN-BOTTOM: 0px; 
+}
+PRE.srcLineHighLight {
+  BACKGROUND: #F0C8C8; MARGIN-TOP: 0px; MARGIN-BOTTOM: 0px; 
+}
+td.lineCount, td.coverageCount {
+      BACKGROUND: #F0F0F0; PADDING-RIGHT: 3px;
+      text-align: right;
+}
+td.lineCountHighlight {
+      background: #C8C8F0; PADDING-RIGHT: 3px;
+      text-align: right;
+}
+td.coverageCountHighlight {
+      background: #F0C8C8; PADDING-RIGHT: 3px;
+      text-align: right;
+}
+td.srcLineHighlight {
+      background: #F0C8C8;
+}
+td.srcLine {
+      background: #C8C8F0;
+}
+TD.srcLineClassStart {
+   WIDTH: 100%; BORDER-TOP:#dcdcdc 1px solid; FONT-WEIGHT: bold;    
+}
+.srcLine , .srcLine ol, .srcLine ol li {margin: 0;}
+.srcLine .de1, .srcLine .de2 {font-family: 'Courier New', Courier, monospace; font-weight: normal;}
+.srcLine .imp {font-weight: bold; color: red;}
+.srcLine .kw1 {color: #b1b100;}
+.srcLine .kw2 {color: #000000; font-weight: bold;}
+.srcLine .kw3 {color: #000066;}
+.srcLine .co1 {color: #808080; font-style: italic;}
+.srcLine .co2 {color: #808080; font-style: italic;}
+.srcLine .coMULTI {color: #808080; font-style: italic;}
+.srcLine .es0 {color: #000099; font-weight: bold;}
+.srcLine .br0 {color: #66cc66;}
+.srcLine .st0 {color: #ff0000;}
+.srcLine .nu0 {color: #cc66cc;}
+.srcLine .me1 {color: #006600;}
+.srcLine .me2 {color: #006600;}
+.srcLine .re0 {color: #0000ff;}
+</xsl:template>
+
+<!-- =======================================================================
+    List of all classes in all packages
+    This will be the first page in the classListFrame
+    ======================================================================= -->
+<xsl:template match="snapshot" mode="all.classes">
+    <html>
+        <head>
+            <xsl:call-template name="create.stylesheet.link"/>
+        </head>
+        <body>
+            <h2>All Classes</h2>
+            <table width="100%">
+                <xsl:for-each select="package/class">
+                    <xsl:sort select="@name"/>
+                    <xsl:variable name="package.name" select="(ancestor::package)[last()]/@name"/>
+                    <xsl:variable name="link">
+                        <xsl:if test="not($package.name='')">
+                            <xsl:value-of select="translate($package.name,'.','/')"/><xsl:text>/</xsl:text>
+                        </xsl:if><xsl:value-of select="@name"/><xsl:text>.html</xsl:text>
+                    </xsl:variable>
+                    <tr>
+                        <td nowrap="nowrap">
+                            <a target="classFrame" href="{$link}"><xsl:value-of select="@name"/></a>
+                            <xsl:choose>
+								<xsl:when test="@totalcount=0">
+									<i> (-)</i>
+								</xsl:when>
+								<xsl:otherwise>
+									<i> (<xsl:value-of select="format-number(@totalcovered div @totalcount, '0.0%')"/>)</i>
+								</xsl:otherwise>
+							</xsl:choose>
+                        </td>
+                    </tr>
+                </xsl:for-each>
+            </table>
+        </body>
+    </html>
+</xsl:template>
+
+<!-- list of all packages -->
+<xsl:template match="snapshot" mode="all.packages">
+    <html>
+        <head>
+            <xsl:call-template name="create.stylesheet.link"/>
+        </head>
+        <body>
+            <h2><a href="overview-summary.html" target="classFrame">Overview</a></h2>
+            <h2>All Packages</h2>
+            <table width="100%">
+                <xsl:for-each select="package">
+                    <xsl:sort select="@name" order="ascending"/>
+                    <tr>
+                        <td nowrap="nowrap">
+                            <a href="{translate(@name,'.','/')}/package-summary.html" target="classFrame">
+                                <xsl:value-of select="@name"/>
+                            </a>
+                        </td>
+                    </tr>
+                </xsl:for-each>
+            </table>
+        </body>
+    </html>
+</xsl:template>
+
+<!-- overview of statistics in packages -->
+<xsl:template match="snapshot" mode="overview.packages">
+    <html>
+        <head>
+            <xsl:call-template name="create.stylesheet.link"/>
+        </head>
+        <body onload="open('allclasses-frame.html','classListFrame')">
+        <xsl:call-template name="pageHeader"/>
+        <table class="log" cellpadding="5" cellspacing="0" width="100%">
+            <tr class="a">
+                <td class="small">Packages: <xsl:value-of select="count(package)"/></td>
+                <td class="small">Classes: <xsl:value-of select="count(package/class)"/></td>
+                <td class="small">Methods: <xsl:value-of select="@methodcount"/></td>
+                <td class="small">LOC: <xsl:value-of select="count(package/class/sourcefile/sourceline)"/></td>
+                <td class="small">Statements: <xsl:value-of select="@statementcount"/></td>
+            </tr>
+        </table>        
+        <br/>
+
+        <table class="log" cellpadding="5" cellspacing="0" width="100%">
+            <tr>
+                <th width="100%" nowrap="nowrap"></th>
+                <th>Statements</th>
+                <th>Methods</th>
+                <th width="350" colspan="2" nowrap="nowrap">Total coverage</th>
+            </tr>
+            <tr class="a">
+        	<td><b>Project</b></td>
+                <xsl:call-template name="stats.formatted"/>
+            </tr>
+            <tr>
+                <td colspan="3"><br/></td>
+            </tr>
+            <tr>
+                <th width="100%">Packages</th>
+                <th>Statements</th>
+                <th>Methods</th>
+                <th width="350" colspan="2" nowrap="nowrap">Total coverage</th>
+            </tr>
+            <!-- display packages and sort them via their coverage rate -->
+            <xsl:for-each select="package">
+                <xsl:sort data-type="number" select="@totalcovered div @totalcount"/>
+                <tr>
+                  <xsl:call-template name="alternate-row"/>
+                    <td><a href="{translate(@name,'.','/')}/package-summary.html"><xsl:value-of select="@name"/></a></td>
+                    <xsl:call-template name="stats.formatted"/>
+                </tr>
+            </xsl:for-each>
+        </table>
+        <xsl:call-template name="pageFooter"/>
+        </body>
+        </html>
+</xsl:template>
+
+<!--
+ detailed info for a package. It will output the list of classes
+, the summary page, and the info for each class
+-->
+<xsl:template match="package" mode="write">
+    <xsl:variable name="package.dir">
+        <xsl:if test="not(@name = '')"><xsl:value-of select="translate(@name,'.','/')"/></xsl:if>
+        <xsl:if test="@name = ''">.</xsl:if>
+    </xsl:variable>
+
+    <!-- create a classes-list.html in the package directory -->
+    <exsl:document href="efile://{$output.dir}/{$package.dir}/package-frame.html">
+        <xsl:apply-templates select="." mode="classes.list"/>
+    </exsl:document>
+
+    <!-- create a package-summary.html in the package directory -->
+    <exsl:document href="efile://{$output.dir}/{$package.dir}/package-summary.html">
+        <xsl:apply-templates select="." mode="package.summary"/>
+    </exsl:document>
+
+    <!-- for each class, creates a @name.html -->
+    <xsl:for-each select="class">
+        <exsl:document href="efile://{$output.dir}/{$package.dir}/{@name}.html">
+            <xsl:apply-templates select="." mode="class.details"/>
+        </exsl:document>
+    </xsl:for-each>
+</xsl:template>
+
+<!-- list of classes in a package -->
+<xsl:template match="package" mode="classes.list">
+    <html>
+        <HEAD>
+            <xsl:call-template name="create.stylesheet.link">
+                <xsl:with-param name="package.name" select="@name"/>
+            </xsl:call-template>
+        </HEAD>
+        <BODY>
+            <table width="100%">
+                <tr>
+                    <td nowrap="nowrap">
+                        <H2><a href="package-summary.html" target="classFrame"><xsl:value-of select="@name"/></a></H2>
+                    </td>
+                </tr>
+            </table>
+
+            <H2>Classes</H2>
+            <TABLE WIDTH="100%">
+                <xsl:for-each select="class">
+                    <xsl:sort select="@name"/>
+                    <tr>
+                        <td nowrap="nowrap">
+                            <a href="{@name}.html" target="classFrame"><xsl:value-of select="@name"/></a>
+                            <xsl:choose>
+								<xsl:when test="@totalcount=0">
+									<i> (-)</i>
+								</xsl:when>
+								<xsl:otherwise>
+                            		<i>(<xsl:value-of select="format-number(@totalcovered div @totalcount, '0.0%')"/>)</i>
+                            	</xsl:otherwise>
+                            </xsl:choose>
+                        </td>
+                    </tr>
+                </xsl:for-each>
+            </TABLE>
+        </BODY>
+    </html>
+</xsl:template>
+
+<!-- summary of a package -->
+<xsl:template match="package" mode="package.summary">
+    <HTML>
+        <HEAD>
+            <xsl:call-template name="create.stylesheet.link">
+                <xsl:with-param name="package.name" select="@name"/>
+            </xsl:call-template>
+        </HEAD>
+        <!-- when loading this package, it will open the classes into the frame -->
+        <BODY onload="open('package-frame.html','classListFrame')">
+            <xsl:call-template name="pageHeader"/>
+            <table class="log" cellpadding="5" cellspacing="0" width="100%">
+                <tr class="a">
+                    <td class="small">Classes: <xsl:value-of select="count(class)"/></td>
+                    <td class="small">Methods: <xsl:value-of select="@methodcount"/></td>
+                    <td class="small">LOC: <xsl:value-of select="count(class/sourcefile/sourceline)"/></td>
+                    <td class="small">Statements: <xsl:value-of select="@statementcount"/></td>
+                </tr>
+            </table>        
+            <br/>
+
+            <table class="log" cellpadding="5" cellspacing="0" width="100%">
+                <tr>
+                    <th width="100%">Package</th>
+                    <th>Statements</th>
+                    <th>Methods</th>
+                    <th width="350" colspan="2" nowrap="nowrap">Total coverage</th>
+                </tr>
+                <xsl:apply-templates select="." mode="stats"/>
+
+                <xsl:if test="count(class) &gt; 0">
+                    <tr>
+                        <td colspan="3"><br/></td>
+                    </tr>
+                    <tr>
+                        <th width="100%">Classes</th>
+                        <th>Statements</th>
+                        <th>Methods</th>
+                        <th width="350" colspan="2" nowrap="nowrap">Total coverage</th>
+                    </tr>
+                    <xsl:apply-templates select="class" mode="stats">
+                        <xsl:sort data-type="number" select="@totalcovered div @totalcount"/>
+                    </xsl:apply-templates>
+                </xsl:if>
+            </table>
+            <xsl:call-template name="pageFooter"/>
+        </BODY>
+    </HTML>
+</xsl:template>
+
+<!-- details of a class -->
+<xsl:template match="class" mode="class.details">
+    <xsl:variable name="package.name" select="(ancestor::package)[last()]/@name"/>
+    <HTML>
+        <HEAD>
+            <xsl:call-template name="create.stylesheet.link">
+                <xsl:with-param name="package.name" select="$package.name"/>
+            </xsl:call-template>
+        </HEAD>
+        <BODY>
+            <xsl:call-template name="pageHeader"/>
+            <table class="log" cellpadding="5" cellspacing="0" width="100%">
+                <tr class="a">
+                    <td class="small">Methods: <xsl:value-of select="@methodcount"/></td>
+                    <td class="small">LOC: <xsl:value-of select="count(sourcefile/sourceline)"/></td>
+                    <td class="small">Statements: <xsl:value-of select="@statementcount"/></td>
+                </tr>
+            </table>        
+            <br/>
+
+            <!-- class summary -->
+            <table class="log" cellpadding="5" cellspacing="0" width="100%">
+                <tr>
+                    <th width="100%">Source file</th>
+                    <th>Statements</th>
+                    <th>Methods</th>
+                    <th width="250" colspan="2" nowrap="nowrap">Total coverage</th>
+                </tr>
+                <tr>
+                    <xsl:call-template name="alternate-row"/>
+                    <td><xsl:value-of select="sourcefile/@name"/></td>
+                    <xsl:call-template name="stats.formatted"/>
+                </tr>
+            </table>
+            <table cellspacing="0" cellpadding="0" width="100%">
+                <xsl:apply-templates select="sourcefile/sourceline"/>
+            </table>
+            <br/>
+            <xsl:call-template name="pageFooter"/>
+        </BODY>
+    </HTML>
+
+</xsl:template>
+
+<!-- Page Header -->
+<xsl:template name="pageHeader">
+  <!-- jakarta logo -->
+  <table border="0" cellpadding="0" cellspacing="0" width="100%">
+  <tr>
+    <td class="bannercell" rowspan="2">
+      <a href="http://phing.info/">
+      <img src="http://phing.info/images/phing.gif" alt="http://phing.info/" align="left" border="0"/>
+      </a>
+    </td>
+        <td style="text-align:right"><h2>Source Code Coverage</h2></td>
+        </tr>
+        <tr>
+        <td style="text-align:right">Designed for use with <a href='http://pear.php.net/package/PHPUnit2'>PHPUnit2</a>, <a href='http://www.xdebug.org/'>Xdebug</a> and <a href='http://phing.info/'>Phing</a>.</td>
+        </tr>
+  </table>
+    <hr size="1"/>
+</xsl:template>
+
+<!-- Page Footer -->
+<xsl:template name="pageFooter">
+    <table width="100%">
+      <tr><td><hr noshade="yes" size="1"/></td></tr>
+      <tr><td class="small">Report generated at <xsl:value-of select="date:date-time()"/></td></tr>
+    </table>
+</xsl:template>
+
+<xsl:template match="package" mode="stats">
+    <tr>
+      <xsl:call-template name="alternate-row"/>
+        <td><xsl:value-of select="@name"/></td>
+        <xsl:call-template name="stats.formatted"/>
+    </tr>
+</xsl:template>
+
+<xsl:template match="class" mode="stats">
+    <tr>
+      <xsl:call-template name="alternate-row"/>
+        <td><a href="{@name}.html" target="classFrame"><xsl:value-of select="@name"/></a></td>
+        <xsl:call-template name="stats.formatted"/>
+    </tr>
+</xsl:template>
+
+<xsl:template name="stats.formatted">
+    <xsl:choose>
+        <xsl:when test="@statementcount=0">
+            <td>-</td>
+        </xsl:when>
+        <xsl:otherwise>
+            <td>
+            <xsl:value-of select="format-number(@statementscovered div @statementcount,'0.0%')"/>
+            </td>
+        </xsl:otherwise>
+    </xsl:choose>
+    <xsl:choose>
+        <xsl:when test="@methodcount=0">
+            <td>-</td>
+        </xsl:when>
+        <xsl:otherwise>
+            <td>
+            <xsl:value-of select="format-number(@methodscovered div @methodcount,'0.0%')"/>
+            </td>
+        </xsl:otherwise>
+    </xsl:choose>
+    <xsl:choose>
+        <xsl:when test="@totalcount=0">
+            <td>-</td>
+            <td>
+            <table cellspacing="0" cellpadding="0" border="0" width="100%" style="display: inline">
+                <tr>
+                    <td class="empty" width="200" height="12">&#160;</td>
+                </tr>
+            </table>
+            </td>
+        </xsl:when>
+        <xsl:otherwise>
+            <td>
+            <xsl:value-of select="format-number(@totalcovered div @totalcount,'0.0%')"/>
+            </td>
+            <td>
+            <xsl:variable name="leftwidth"><xsl:value-of select="format-number((@totalcovered * 200) div @totalcount,'0')"/></xsl:variable>
+            <xsl:variable name="rightwidth"><xsl:value-of select="format-number(200 - (@totalcovered * 200) div @totalcount,'0')"/></xsl:variable>
+            <table cellspacing="0" cellpadding="0" border="0" width="100%" style="display: inline">
+                <tr>
+                    <xsl:choose>
+                        <xsl:when test="$leftwidth=200">
+                            <td class="fullcover" width="200" height="12">&#160;</td>
+                        </xsl:when>
+                        <xsl:otherwise>
+                            <xsl:if test="not($leftwidth=0)">
+                                <td class="covered" width="{$leftwidth}" height="12">&#160;</td>
+                            </xsl:if>
+                            <xsl:if test="not($rightwidth=0)">
+                                <td class="uncovered" width="{$rightwidth}" height="12">&#160;</td>
+                            </xsl:if>
+                        </xsl:otherwise>
+                    </xsl:choose>
+                </tr>
+            </table>
+            </td>
+        </xsl:otherwise>
+    </xsl:choose>
+</xsl:template>
+
+<xsl:template match="sourceline">
+    <tr>
+        <xsl:if test="@coveredcount>0">
+            <td class="lineCountHighlight"><xsl:value-of select="position()"/></td>
+            <td class="lineCountHighlight"><xsl:value-of select="@coveredcount"/></td>
+        </xsl:if>
+        <xsl:if test="@coveredcount&lt;0">
+            <td class="lineCountHighlight"><xsl:value-of select="position()"/></td>
+            <td class="coverageCountHighlight">0</td>
+        </xsl:if>
+        <xsl:if test="@coveredcount=0">
+            <td class="lineCount"><xsl:value-of select="position()"/></td>
+            <td class="coverageCount"></td>
+        </xsl:if>
+        <td>
+            <xsl:if test="@startclass=1">
+            	<xsl:attribute name="class">srcLineClassStart</xsl:attribute>
+            </xsl:if>
+            <xsl:if test="@coveredcount>0">
+                <pre class="srcLine"><xsl:value-of select="."/></pre>
+            </xsl:if>
+            <xsl:if test="@coveredcount&lt;0">
+                <pre class="srcLineHighlight"><xsl:value-of select="."/></pre>
+            </xsl:if>
+            <xsl:if test="@coveredcount=0">
+                <pre class="srcLine"><xsl:value-of select="."/></pre>
+            </xsl:if>
+        </td>
+    </tr>
+</xsl:template>
+
+<!--
+    transform string like a.b.c to ../../../
+    @param path the path to transform into a descending directory path
+-->
+<xsl:template name="path">
+    <xsl:param name="path"/>
+    <xsl:if test="contains($path,'.')">
+        <xsl:text>../</xsl:text>
+        <xsl:call-template name="path">
+            <xsl:with-param name="path"><xsl:value-of select="substring-after($path,'.')"/></xsl:with-param>
+        </xsl:call-template>
+    </xsl:if>
+    <xsl:if test="not(contains($path,'.')) and not($path = '')">
+        <xsl:text>../</xsl:text>
+    </xsl:if>
+</xsl:template>
+
+
+<!-- create the link to the stylesheet based on the package name -->
+<xsl:template name="create.stylesheet.link">
+    <xsl:param name="package.name"/>
+    <LINK REL ="stylesheet" TYPE="text/css" TITLE="Style"><xsl:attribute name="href"><xsl:if test="not($package.name = 'unnamed package')"><xsl:call-template name="path"><xsl:with-param name="path" select="$package.name"/></xsl:call-template></xsl:if>stylesheet.css</xsl:attribute></LINK>
+</xsl:template>
+
+<!-- alternated row style -->
+<xsl:template name="alternate-row">
+<xsl:attribute name="class">
+  <xsl:if test="position() mod 2 = 1">a</xsl:if>
+  <xsl:if test="position() mod 2 = 0">b</xsl:if>
+</xsl:attribute>
+</xsl:template>
+
+</xsl:stylesheet>
+
+
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/etc/log.xsl
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/etc/log.xsl	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/etc/log.xsl	(revision 19)
@@ -0,0 +1,216 @@
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
+<xsl:output method="html" indent="yes" encoding="US-ASCII"/>
+<!--
+    Copyright  2000-2004 The Apache Software Foundation
+   
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+   
+         http://www.apache.org/licenses/LICENSE-2.0
+   
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+   
+-->
+ 
+<!--
+
+  The purpose have this XSL is to provide a nice way to look at the output
+  from the Ant XmlLogger (ie: ant -listener org.apache.tools.ant.XmlLogger )
+  
+  @author <a href="mailto:michiel.rook@gmail.com>Michiel Rook</a>
+  @author <a href="mailto:sbailliez@apache.org">Stephane Bailliez</a>
+  
+-->
+<xsl:decimal-format decimal-separator="." grouping-separator="," />
+
+<xsl:template match="/">
+<html>
+  <head>
+    <title>Phing Build Log</title>
+    <style type="text/css">
+    .bannercell {
+      border: 0px;
+      padding: 0px;
+    }
+    body {
+      margin: 0;
+      font:normal 100% arial,helvetica,sanserif;
+      background-color:#FFFFFF;
+      color:#000000;
+    }
+    table.status {
+      font:bold 80% arial,helvetica,sanserif;
+      background-color:#525D76;
+      color:#ffffff;
+    }
+    table.log tr td, tr th {
+      font-size: 80%;
+    }
+    .error {
+      color:red;
+    }
+    .warn {
+      color:brown;
+    }
+    .info {
+      color:gray;
+    }
+    .debug{
+      color:gray;
+    }
+    .failed {
+      font-size:80%;
+      background-color: red;
+      color:#FFFFFF;
+      font-weight: bold
+    }
+    .complete {
+      font-size:80%;
+      background-color: #525D76;
+      color:#FFFFFF;
+      font-weight: bold
+    }
+    .a td { 
+      background: #efefef;
+    }
+    .b td { 
+      background: #fff;
+    }
+    th, td {
+      text-align: left;
+      vertical-align: top;
+    }
+    th {
+      background: #ccc;
+      color: black;
+    }
+    table, th, td {
+      border: none
+    }
+    h3 {
+      font:bold 80% arial,helvetica,sanserif;
+      background: #525D76;
+      color: white;
+      text-decoration: none;
+      padding: 5px;
+      margin-right: 2px;
+      margin-left: 2px;
+      margin-bottom: 0;
+    }
+    a {
+      color: #003399;
+    }
+    a:hover {
+      color: #888888;
+    }
+    </style>
+  </head>
+  <body>
+    <!-- jakarta logo -->
+    <table border="0" cellpadding="0" cellspacing="0" width="100%">
+    <tr>
+      <td valign="top" class="bannercell">
+        <a href="http://phing.info/">
+        <img src="http://phing.info/images/phing.gif" alt="http://phing.info/" align="left" border="0"/>
+        </a>
+      </td>
+      <td style="text-align:right;vertical-align:bottom">
+        <a href="http://phing.info/">Phing</a>
+      </td>
+    </tr>
+    </table>
+      
+    <table border="0" width="100%">
+    <tr><td><hr noshade="yes" size="1"/></td></tr>
+    </table>
+
+    <xsl:apply-templates select="build"/>
+
+    <!-- FOOTER -->
+    <table width="100%">
+      <tr><td><hr noshade="yes" size="1"/></td></tr>
+      <tr><td>
+      <div align="center"><font color="#525D76" size="-1"><em>
+      <a href="http://phing.info/">Phing</a>
+      </em></font></div>
+      </td></tr>
+    </table>
+  </body>
+</html>
+</xsl:template>
+
+<xsl:template match="build">
+  <!-- build status -->
+  <table width="100%">
+    <xsl:attribute name="class">
+      <xsl:if test="@error">failed</xsl:if>
+      <xsl:if test="not(@error)">complete</xsl:if>
+    </xsl:attribute>
+    <tr>
+      <xsl:if test="@error">
+        <td nowrap="yes">Build Failed</td> 
+      </xsl:if>
+      <xsl:if test="not(@error)">
+        <td nowrap="yes">Build Complete</td>
+      </xsl:if>
+        <td style="text-align:right" nowrap="yes">Total Time: <xsl:value-of select="@time"/></td>
+    </tr>
+    <tr>
+      <td colspan="2">
+        <xsl:if test="@error">
+          <tt><xsl:value-of select="@error"/></tt><br/>
+          <i style="font-size:80%">See the <a href="#stacktrace" alt="Click for details">stacktrace</a>.</i>
+        </xsl:if>
+      </td>
+    </tr>
+  </table>
+  <table border="1" cellspacing="2" cellpadding="3" width="100%" style="font-size:80%">
+    <tr class="a"><td width="1">phing.file</td><td><xsl:value-of select="substring-after(//message[contains(text(),'phing.file')], '->')"/></td></tr>
+    <tr class="b"><td width="1">phing.version</td><td><xsl:value-of select="substring-after(//message[contains(text(),'phing.version')], '->')"/></td></tr>
+  </table>
+  <!-- build information -->
+  <h3>Build events</h3>
+  <table class="log" border="1" cellspacing="2" cellpadding="3" width="100%">
+  <tr>
+    <th nowrap="yes" align="left" width="1%">target</th>
+    <th nowrap="yes" align="left" width="1%">task</th>
+    <th nowrap="yes" align="left">message</th>
+  </tr>
+  <xsl:apply-templates select=".//message[@priority != 'debug']"/>
+  </table>
+  <p>
+  <!-- stacktrace -->
+  <xsl:if test="stacktrace">
+  <a name="stacktrace"/>
+  <h3>Error details</h3>
+  <table width="100%">
+    <tr><td>
+      <pre><xsl:value-of select="stacktrace"/></pre>
+    </td></tr>
+  </table>
+  </xsl:if>
+  </p>
+</xsl:template>
+
+<!-- report every message but those with debug priority -->
+<xsl:template match="message[@priority!='debug']">
+  <tr valign="top">
+    <!-- alternated row style -->
+    <xsl:attribute name="class">
+      <xsl:if test="position() mod 2 = 1">a</xsl:if>
+      <xsl:if test="position() mod 2 = 0">b</xsl:if>
+    </xsl:attribute>
+    <td nowrap="yes" width="1%"><xsl:value-of select="../../@name"/></td>
+    <td nowrap="yes" style="text-align:right" width="1%">[ <xsl:value-of select="../@name"/> ]</td>
+    <td class="{@priority}" nowrap="yes">
+            <xsl:value-of select="text()"/>
+    </td>
+  </tr>
+</xsl:template>
+
+</xsl:stylesheet>
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/etc/phpunit2-frames.xsl
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/etc/phpunit2-frames.xsl	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/etc/phpunit2-frames.xsl	(revision 19)
@@ -0,0 +1,678 @@
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"
+    xmlns:exsl="http://exslt.org/common"
+    xmlns:str="http://exslt.org/strings"
+    xmlns:date="http://exslt.org/dates-and-times"
+    extension-element-prefixes="exsl str date">
+<xsl:include href="str.replace.function.xsl"/>
+<xsl:output method="html" indent="yes" encoding="US-ASCII"/>
+<xsl:decimal-format decimal-separator="." grouping-separator=","/>
+<!--
+   Copyright 2001-2004 The Apache Software Foundation
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+ -->
+
+<!--
+
+ Sample stylesheet to be used with Phing/PHPUnit2 output.
+ Based on JUnit stylesheets from Apache Ant.
+
+ It creates a set of HTML files a la javadoc where you can browse easily
+ through all packages and classes.
+
+ @author Michiel Rook <a href="mailto:michiel.rook@gmail.com"/>
+ @author Stephane Bailliez <a href="mailto:sbailliez@apache.org"/>
+ @author Erik Hatcher <a href="mailto:ehatcher@apache.org"/>
+ @author Martijn Kruithof <a href="mailto:martijn@kruithof.xs4all.nl"/>
+
+-->
+<xsl:param name="output.dir" select="'.'"/>
+
+
+<xsl:template match="testsuites">
+    <!-- create the index.html -->
+    <exsl:document href="efile://{$output.dir}/index.html">
+        <xsl:call-template name="index.html"/>
+    </exsl:document>
+
+    <!-- create the stylesheet.css -->
+    <exsl:document href="efile://{$output.dir}/stylesheet.css">
+        <xsl:call-template name="stylesheet.css"/>
+    </exsl:document>
+
+    <!-- create the overview-packages.html at the root -->
+    <exsl:document href="efile://{$output.dir}/overview-summary.html">
+        <xsl:apply-templates select="." mode="overview.packages"/>
+    </exsl:document>
+
+    <!-- create the all-packages.html at the root -->
+    <exsl:document href="efile://{$output.dir}/overview-frame.html">
+        <xsl:apply-templates select="." mode="all.packages"/>
+    </exsl:document>
+
+    <!-- create the all-classes.html at the root -->
+    <exsl:document href="efile://{$output.dir}/allclasses-frame.html">
+        <xsl:apply-templates select="." mode="all.classes"/>
+    </exsl:document>
+
+    <!-- process all packages -->
+    <xsl:for-each select="./testsuite[not(./@package = preceding-sibling::testsuite/@package)]">
+        <xsl:call-template name="package">
+            <xsl:with-param name="name" select="@package"/>
+        </xsl:call-template>
+    </xsl:for-each>
+</xsl:template>
+
+
+<xsl:template name="package">
+    <xsl:param name="name"/>
+    <xsl:variable name="package.dir">
+        <xsl:if test="not($name = '')"><xsl:value-of select="translate($name,'.','/')"/></xsl:if>
+        <xsl:if test="$name = ''">.</xsl:if>
+    </xsl:variable>
+    <!--Processing package <xsl:value-of select="@name"/> in <xsl:value-of select="$output.dir"/> -->
+    <!-- create a classes-list.html in the package directory -->
+    <exsl:document href="efile://{$output.dir}/{$package.dir}/package-frame.html">
+        <xsl:call-template name="classes.list">
+            <xsl:with-param name="name" select="$name"/>
+        </xsl:call-template>
+    </exsl:document>
+
+    <!-- create a package-summary.html in the package directory -->
+    <exsl:document href="efile://{$output.dir}/{$package.dir}/package-summary.html">
+        <xsl:call-template name="package.summary">
+            <xsl:with-param name="name" select="$name"/>
+        </xsl:call-template>
+    </exsl:document>
+
+    <!-- for each class, creates a @name.html -->
+    <!-- @bug there will be a problem with inner classes having the same name, it will be overwritten -->
+    <xsl:for-each select="/testsuites/testsuite[@package = $name]">
+        <exsl:document href="efile://{$output.dir}/{$package.dir}/{@name}.html">
+            <xsl:apply-templates select="." mode="class.details"/>
+        </exsl:document>
+        <xsl:if test="string-length(./system-out)!=0">
+            <exsl:document href="efile://{$output.dir}/{$package.dir}/{@name}-out.txt">
+                <xsl:value-of select="./system-out" />
+            </exsl:document>
+        </xsl:if>
+        <xsl:if test="string-length(./system-err)!=0">
+            <exsl:document href="efile://{$output.dir}/{$package.dir}/{@name}-err.txt">
+                <xsl:value-of select="./system-err" />
+            </exsl:document>
+        </xsl:if>
+    </xsl:for-each>
+</xsl:template>
+
+<xsl:template name="index.html">
+<html>
+    <head>
+        <title>Unit Test Results.</title>
+    </head>
+    <frameset cols="20%,80%">
+        <frameset rows="30%,70%">
+            <frame src="overview-frame.html" name="packageListFrame"/>
+            <frame src="allclasses-frame.html" name="classListFrame"/>
+        </frameset>
+        <frame src="overview-summary.html" name="classFrame"/>
+        <noframes>
+            <h2>Frame Alert</h2>
+            <p>
+                This document is designed to be viewed using the frames feature. If you see this message, you are using a non-frame-capable web client.
+            </p>
+        </noframes>
+    </frameset>
+</html>
+</xsl:template>
+
+<!-- this is the stylesheet css to use for nearly everything -->
+<xsl:template name="stylesheet.css">
+body {
+    font-family: verdana,arial,helvetica;
+    color:#000000;
+    font-size: 12px;
+}
+table tr td, table tr th {
+    font-family: verdana,arial,helvetica;
+    font-size: 12px;
+}
+table.details tr th{
+    font-family: verdana,arial,helvetica;
+    font-weight: bold;
+    text-align:left;
+    background:#a6caf0;
+}
+table.details tr td{
+    background:#eeeee0;
+}
+
+p {
+    line-height:1.5em;
+    margin-top:0.5em; margin-bottom:1.0em;
+    font-size: 12px;
+}
+h1 {
+    margin: 0px 0px 5px;
+    font-family: verdana,arial,helvetica;
+}
+h2 {
+    margin-top: 1em; margin-bottom: 0.5em;
+    font-family: verdana,arial,helvetica;
+}
+h3 {
+    margin-bottom: 0.5em;
+    font-family: verdana,arial,helvetica;
+}
+h4 {
+    margin-bottom: 0.5em;
+    font-family: verdana,arial,helvetica;
+}
+h5 {
+    margin-bottom: 0.5em;
+    font-family: verdana,arial,helvetica;
+}
+h6 {
+    margin-bottom: 0.5em;
+    font-family: verdana,arial,helvetica;
+}
+.Error {
+    font-weight:bold; color:red;
+}
+.Failure {
+    font-weight:bold; color:purple;
+}
+.small {
+   font-size: 9px;
+}
+a {
+  color: #003399;
+}
+a:hover {
+  color: #888888;
+}
+</xsl:template>
+
+
+<!-- ======================================================================
+    This page is created for every testsuite class.
+    It prints a summary of the testsuite and detailed information about
+    testcase methods.
+     ====================================================================== -->
+<xsl:template match="testsuite" mode="class.details">
+    <xsl:variable name="package.name" select="@package"/>
+    <xsl:variable name="class.name"><xsl:if test="not($package.name = '')"><xsl:value-of select="$package.name"/>.</xsl:if><xsl:value-of select="@name"/></xsl:variable>
+    <html>
+        <head>
+          <title>Unit Test Results: <xsl:value-of select="$class.name"/></title>
+            <xsl:call-template name="create.stylesheet.link">
+                <xsl:with-param name="package.name" select="$package.name"/>
+            </xsl:call-template>
+        </head>
+        <body>
+            <xsl:call-template name="pageHeader"/>
+            <h3>Class <xsl:value-of select="$class.name"/></h3>
+
+
+            <table class="details" border="0" cellpadding="5" cellspacing="2" width="95%">
+                <xsl:call-template name="testsuite.test.header"/>
+                <xsl:apply-templates select="." mode="print.test"/>
+            </table>
+
+            <h2>Tests</h2>
+            <table class="details" border="0" cellpadding="5" cellspacing="2" width="95%">
+        <xsl:call-template name="testcase.test.header"/>
+              <!--
+              test can even not be started at all (failure to load the class)
+              so report the error directly
+              -->
+                <xsl:if test="./error">
+                    <tr class="Error">
+                        <td colspan="4"><xsl:apply-templates select="./error"/></td>
+                    </tr>
+                </xsl:if>
+                <xsl:apply-templates select="./testcase | ./testsuite/testcase" mode="print.test"/>
+            </table>
+            <xsl:call-template name="pageFooter"/>
+        </body>
+    </html>
+</xsl:template>
+
+<!-- ======================================================================
+    This page is created for every package.
+    It prints the name of all classes that belongs to this package.
+    @param name the package name to print classes.
+     ====================================================================== -->
+<!-- list of classes in a package -->
+<xsl:template name="classes.list">
+    <xsl:param name="name"/>
+    <html>
+        <head>
+            <title>Unit Test Classes: <xsl:value-of select="$name"/></title>
+            <xsl:call-template name="create.stylesheet.link">
+                <xsl:with-param name="package.name" select="$name"/>
+            </xsl:call-template>
+        </head>
+        <body>
+            <table width="100%">
+                <tr>
+                    <td nowrap="nowrap">
+                        <h2><a href="package-summary.html" target="classFrame">
+                            <xsl:value-of select="$name"/>
+                            <xsl:if test="$name = ''">&lt;none&gt;</xsl:if>
+                        </a></h2>
+                    </td>
+                </tr>
+            </table>
+
+            <h2>Classes</h2>
+            <table width="100%">
+                <xsl:for-each select="/testsuites/testsuite[./@package = $name]">
+                    <xsl:sort select="@name"/>
+                    <tr>
+                        <td nowrap="nowrap">
+                            <a href="{@name}.html" target="classFrame"><xsl:value-of select="@name"/></a>
+                        </td>
+                    </tr>
+                </xsl:for-each>
+            </table>
+        </body>
+    </html>
+</xsl:template>
+
+
+<!--
+    Creates an all-classes.html file that contains a link to all package-summary.html
+    on each class.
+-->
+<xsl:template match="testsuites" mode="all.classes">
+    <html>
+        <head>
+            <title>All Unit Test Classes</title>
+            <xsl:call-template name="create.stylesheet.link">
+                <xsl:with-param name="package.name"/>
+            </xsl:call-template>
+        </head>
+        <body>
+            <h2>Classes</h2>
+            <table width="100%">
+                <xsl:apply-templates select="testsuite" mode="all.classes">
+                    <xsl:sort select="@name"/>
+                </xsl:apply-templates>
+            </table>
+        </body>
+    </html>
+</xsl:template>
+
+<xsl:template match="testsuite" mode="all.classes">
+    <xsl:variable name="package.name" select="@package"/>
+    <tr>
+        <td nowrap="nowrap">
+            <a target="classFrame">
+                <xsl:attribute name="href">
+                    <xsl:if test="not($package.name='')">
+                        <xsl:value-of select="translate($package.name,'.','/')"/><xsl:text>/</xsl:text>
+                    </xsl:if><xsl:value-of select="@name"/><xsl:text>.html</xsl:text>
+                </xsl:attribute>
+                <xsl:value-of select="@name"/>
+            </a>
+        </td>
+    </tr>
+</xsl:template>
+
+
+<!--
+    Creates an html file that contains a link to all package-summary.html files on
+    each package existing on testsuites.
+    @bug there will be a problem here, I don't know yet how to handle unnamed package :(
+-->
+<xsl:template match="testsuites" mode="all.packages">
+    <html>
+        <head>
+            <title>All Unit Test Packages</title>
+            <xsl:call-template name="create.stylesheet.link">
+                <xsl:with-param name="package.name"/>
+            </xsl:call-template>
+        </head>
+        <body>
+            <h2><a href="overview-summary.html" target="classFrame">Home</a></h2>
+            <h2>Packages</h2>
+            <table width="100%">
+                <xsl:apply-templates select="testsuite[not(./@package = preceding-sibling::testsuite/@package)]" mode="all.packages">
+                    <xsl:sort select="@package"/>
+                </xsl:apply-templates>
+            </table>
+        </body>
+    </html>
+</xsl:template>
+
+<xsl:template match="testsuite" mode="all.packages">
+    <tr>
+        <td nowrap="nowrap">
+            <a href="./{translate(@package,'.','/')}/package-summary.html" target="classFrame">
+                <xsl:value-of select="@package"/>
+                <xsl:if test="@package = ''">&lt;none&gt;</xsl:if>
+            </a>
+        </td>
+    </tr>
+</xsl:template>
+
+
+<xsl:template match="testsuites" mode="overview.packages">
+    <html>
+        <head>
+            <title>Unit Test Results: Summary</title>
+            <xsl:call-template name="create.stylesheet.link">
+                <xsl:with-param name="package.name"/>
+            </xsl:call-template>
+        </head>
+        <body>
+        <xsl:attribute name="onload">open('allclasses-frame.html','classListFrame')</xsl:attribute>
+        <xsl:call-template name="pageHeader"/>
+        <h2>Summary</h2>
+        <xsl:variable name="testCount" select="sum(testsuite/@tests)"/>
+        <xsl:variable name="errorCount" select="sum(testsuite/@errors)"/>
+        <xsl:variable name="failureCount" select="sum(testsuite/@failures)"/>
+        <xsl:variable name="timeCount" select="sum(testsuite/@time)"/>
+        <xsl:variable name="successRate" select="($testCount - $failureCount - $errorCount) div $testCount"/>
+        <table class="details" border="0" cellpadding="5" cellspacing="2" width="95%">
+        <tr valign="top">
+            <th>Tests</th>
+            <th>Failures</th>
+            <th>Errors</th>
+            <th>Success rate</th>
+            <th>Time</th>
+        </tr>
+        <tr valign="top">
+            <xsl:attribute name="class">
+                <xsl:choose>
+                    <xsl:when test="$errorCount &gt; 0">Error</xsl:when>
+                    <xsl:when test="$failureCount &gt; 0">Failure</xsl:when>
+                    <xsl:otherwise>Pass</xsl:otherwise>
+                </xsl:choose>
+            </xsl:attribute>
+            <td><xsl:value-of select="$testCount"/></td>
+            <td><xsl:value-of select="$failureCount"/></td>
+            <td><xsl:value-of select="$errorCount"/></td>
+            <td>
+                <xsl:call-template name="display-percent">
+                    <xsl:with-param name="value" select="$successRate"/>
+                </xsl:call-template>
+            </td>
+            <td>
+                <xsl:call-template name="display-time">
+                    <xsl:with-param name="value" select="$timeCount"/>
+                </xsl:call-template>
+            </td>
+
+        </tr>
+        </table>
+        <table border="0" width="95%">
+        <tr>
+        <td style="text-align: justify;">
+        Note: <em>failures</em> are anticipated and checked for with assertions while <em>errors</em> are unanticipated.
+        </td>
+        </tr>
+        </table>
+
+        <h2>Packages</h2>
+        <table class="details" border="0" cellpadding="5" cellspacing="2" width="95%">
+            <xsl:call-template name="testsuite.test.header"/>
+            <xsl:for-each select="testsuite[not(./@package = preceding-sibling::testsuite/@package)]">
+                <xsl:sort select="@package" order="ascending"/>
+                <!-- get the node set containing all testsuites that have the same package -->
+                <xsl:variable name="insamepackage" select="/testsuites/testsuite[./@package = current()/@package]"/>
+                <tr valign="top">
+                    <!-- display a failure if there is any failure/error in the package -->
+                    <xsl:attribute name="class">
+                        <xsl:choose>
+                            <xsl:when test="sum($insamepackage/@errors) &gt; 0">Error</xsl:when>
+                            <xsl:when test="sum($insamepackage/@failures) &gt; 0">Failure</xsl:when>
+                            <xsl:otherwise>Pass</xsl:otherwise>
+                        </xsl:choose>
+                    </xsl:attribute>
+                    <td><a href="./{translate(@package,'.','/')}/package-summary.html">
+                        <xsl:value-of select="@package"/>
+                        <xsl:if test="@package = ''">&lt;none&gt;</xsl:if>
+                    </a></td>
+                    <td><xsl:value-of select="sum($insamepackage/@tests)"/></td>
+                    <td><xsl:value-of select="sum($insamepackage/@errors)"/></td>
+                    <td><xsl:value-of select="sum($insamepackage/@failures)"/></td>
+                    <td>
+                    <xsl:call-template name="display-time">
+                        <xsl:with-param name="value" select="sum($insamepackage/@time)"/>
+                    </xsl:call-template>
+                    </td>
+                </tr>
+            </xsl:for-each>
+        </table>
+        <xsl:call-template name="pageFooter"/>
+        </body>
+        </html>
+</xsl:template>
+
+
+<xsl:template name="package.summary">
+    <xsl:param name="name"/>
+    <html>
+        <head>
+            <xsl:call-template name="create.stylesheet.link">
+                <xsl:with-param name="package.name" select="$name"/>
+            </xsl:call-template>
+        </head>
+        <body>
+            <xsl:attribute name="onload">open('package-frame.html','classListFrame')</xsl:attribute>
+            <xsl:call-template name="pageHeader"/>
+            <h3>Package <xsl:value-of select="$name"/></h3>
+
+            <!--table border="0" cellpadding="5" cellspacing="2" width="95%">
+                <xsl:call-template name="class.metrics.header"/>
+                <xsl:apply-templates select="." mode="print.metrics"/>
+            </table-->
+
+            <xsl:variable name="insamepackage" select="/testsuites/testsuite[./@package = $name]"/>
+            <xsl:if test="count($insamepackage) &gt; 0">
+                <h2>Classes</h2>
+                <p>
+                <table class="details" border="0" cellpadding="5" cellspacing="2" width="95%">
+                    <xsl:call-template name="testsuite.test.header"/>
+                    <xsl:apply-templates select="$insamepackage" mode="print.test">
+                        <xsl:sort select="@name"/>
+                    </xsl:apply-templates>
+                </table>
+                </p>
+            </xsl:if>
+            <xsl:call-template name="pageFooter"/>
+        </body>
+    </html>
+</xsl:template>
+
+
+<!--
+    transform string like a.b.c to ../../../
+    @param path the path to transform into a descending directory path
+-->
+<xsl:template name="path">
+    <xsl:param name="path"/>
+    <xsl:if test="contains($path,'.')">
+        <xsl:text>../</xsl:text>
+        <xsl:call-template name="path">
+            <xsl:with-param name="path"><xsl:value-of select="substring-after($path,'.')"/></xsl:with-param>
+        </xsl:call-template>
+    </xsl:if>
+    <xsl:if test="not(contains($path,'.')) and not($path = '')">
+        <xsl:text>../</xsl:text>
+    </xsl:if>
+</xsl:template>
+
+
+<!-- create the link to the stylesheet based on the package name -->
+<xsl:template name="create.stylesheet.link">
+    <xsl:param name="package.name"/>
+    <link rel="stylesheet" type="text/css" title="Style"><xsl:attribute name="href"><xsl:if test="not($package.name = 'unnamed package')"><xsl:call-template name="path"><xsl:with-param name="path" select="$package.name"/></xsl:call-template></xsl:if>stylesheet.css</xsl:attribute></link>
+</xsl:template>
+
+
+<!-- Page HEADER -->
+<xsl:template name="pageHeader">
+    <h1>Unit Test Results</h1>
+    <table width="100%">
+    <tr>
+        <td align="left"></td>
+        <td align="right">Designed for use with <a href='http://pear.php.net/package/PHPUnit2'>PHPUnit2</a> and <a href='http://phing.info/'>Phing</a>.</td>
+    </tr>
+    </table>
+    <hr size="1"/>
+</xsl:template>
+
+<!-- Page Footer -->
+<xsl:template name="pageFooter">
+    <table width="100%">
+      <tr><td><hr noshade="yes" size="1"/></td></tr>
+      <tr><td class="small">Report generated at <xsl:value-of select="date:date-time()"/></td></tr>
+    </table>
+</xsl:template>
+
+<!-- class header -->
+<xsl:template name="testsuite.test.header">
+    <tr valign="top">
+        <th width="80%">Name</th>
+        <th>Tests</th>
+        <th>Errors</th>
+        <th>Failures</th>
+        <th nowrap="nowrap">Time(s)</th>
+    </tr>
+</xsl:template>
+
+<!-- method header -->
+<xsl:template name="testcase.test.header">
+    <tr valign="top">
+        <th>Name</th>
+        <th>Status</th>
+        <th width="80%">Type</th>
+        <th nowrap="nowrap">Time(s)</th>
+    </tr>
+</xsl:template>
+
+
+<!-- class information -->
+<xsl:template match="testsuite" mode="print.test">
+    <tr valign="top">
+        <xsl:attribute name="class">
+            <xsl:choose>
+                <xsl:when test="@errors[.&gt; 0]">Error</xsl:when>
+                <xsl:when test="@failures[.&gt; 0]">Failure</xsl:when>
+                <xsl:otherwise>Pass</xsl:otherwise>
+            </xsl:choose>
+        </xsl:attribute>
+        <td><a href="{@name}.html"><xsl:value-of select="@name"/></a></td>
+        <td><xsl:apply-templates select="@tests"/></td>
+        <td><xsl:apply-templates select="@errors"/></td>
+        <td><xsl:apply-templates select="@failures"/></td>
+        <td><xsl:call-template name="display-time">
+                <xsl:with-param name="value" select="@time"/>
+            </xsl:call-template>
+        </td>
+    </tr>
+</xsl:template>
+
+<xsl:template match="testcase" mode="print.test">
+    <tr valign="top">
+        <xsl:attribute name="class">
+            <xsl:choose>
+                <xsl:when test="error">Error</xsl:when>
+                <xsl:when test="failure">Failure</xsl:when>
+                <xsl:otherwise>TableRowColor</xsl:otherwise>
+            </xsl:choose>
+        </xsl:attribute>
+        <td><xsl:value-of select="@name"/></td>
+        <xsl:choose>
+            <xsl:when test="failure">
+                <td>Failure</td>
+                <td><xsl:apply-templates select="failure"/></td>
+            </xsl:when>
+            <xsl:when test="error">
+                <td>Error</td>
+                <td><xsl:apply-templates select="error"/></td>
+            </xsl:when>
+            <xsl:otherwise>
+                <td>Success</td>
+                <td></td>
+            </xsl:otherwise>
+        </xsl:choose>
+        <td>
+            <xsl:call-template name="display-time">
+                <xsl:with-param name="value" select="@time"/>
+            </xsl:call-template>
+        </td>
+    </tr>
+</xsl:template>
+
+
+<!-- Note : the below template error and failure are the same style
+            so just call the same style store in the toolkit template -->
+<xsl:template match="failure">
+    <xsl:call-template name="display-failures"/>
+</xsl:template>
+
+<xsl:template match="error">
+    <xsl:call-template name="display-failures"/>
+</xsl:template>
+
+<!-- Style for the error and failure in the testcase template -->
+<xsl:template name="display-failures">
+    <xsl:choose>
+        <xsl:when test="not(@message)">N/A</xsl:when>
+        <xsl:otherwise>
+            <xsl:value-of select="@message"/>
+        </xsl:otherwise>
+    </xsl:choose>
+    <!-- display the stacktrace -->
+    <br/><br/>
+    <code>
+        <xsl:call-template name="br-replace">
+            <xsl:with-param name="word" select="."/>
+        </xsl:call-template>
+    </code>
+</xsl:template>
+
+<!--
+    template that will convert a carriage return into a br tag
+    @param word the text from which to convert CR to BR tag
+-->
+<xsl:template name="br-replace">
+    <xsl:param name="word"/>
+    <xsl:choose>
+         <xsl:when test="contains($word,'&#x0A;')">
+             <xsl:value-of select="substring-before($word,'&#x0A;')"/>
+             <br />
+             <xsl:call-template name="br-replace">
+                 <xsl:with-param name="word" select="substring-after($word,'&#x0A;')"/>
+             </xsl:call-template>
+         </xsl:when>
+         <xsl:otherwise>
+             <xsl:value-of select="$word"/>
+         </xsl:otherwise>
+    </xsl:choose>
+</xsl:template>
+
+<xsl:template name="display-time">
+    <xsl:param name="value"/>
+    <xsl:value-of select="format-number($value,'0.000')"/>
+</xsl:template>
+
+<xsl:template name="display-percent">
+    <xsl:param name="value"/>
+    <xsl:value-of select="format-number($value,'0.00%')"/>
+</xsl:template>
+</xsl:stylesheet>
+
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/etc/phpunit2-noframes.xsl
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/etc/phpunit2-noframes.xsl	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/etc/phpunit2-noframes.xsl	(revision 19)
@@ -0,0 +1,437 @@
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"
+    xmlns:exsl="http://exslt.org/common"
+    xmlns:str="http://exslt.org/strings"
+    xmlns:date="http://exslt.org/dates-and-times"
+    extension-element-prefixes="exsl str date">
+<xsl:include href="str.replace.function.xsl"/>
+<xsl:output method="html" indent="yes" encoding="US-ASCII"
+  doctype-public="-//W3C//DTD HTML 4.01 Transitional//EN" />
+<xsl:decimal-format decimal-separator="." grouping-separator="," />
+<!--
+   Copyright 2001-2004 The Apache Software Foundation
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+ -->
+ 
+<!--
+ 
+ Sample stylesheet to be used with Phing/PHPUnit2 output.
+ Based on JUnit stylesheets from Apache Ant.
+ 
+ It creates a non-framed report that can be useful to send via
+ e-mail or such.
+ 
+ @author Michiel Rook <a href="mailto:michiel.rook@gmail.com"/>
+ @author Stephane Bailliez <a href="mailto:sbailliez@apache.org"/>
+ @author Erik Hatcher <a href="mailto:ehatcher@apache.org"/>
+ 
+-->
+<xsl:template match="testsuites">
+    <html>
+        <head>
+            <title>Unit Test Results</title>
+    <style type="text/css">
+    body {
+        font-family: verdana,arial,helvetica;
+        color:#000000;
+        font-size: 12px;
+    }
+    table tr td, table tr th {
+        font-family: verdana,arial,helvetica;
+        font-size: 12px;
+    }
+    table.details tr th{
+        font-family: verdana,arial,helvetica;
+        font-weight: bold;
+        text-align:left;
+        background:#a6caf0;
+    }
+    table.details tr td{
+        background:#eeeee0;
+    }
+
+    p {
+        line-height:1.5em;
+        margin-top:0.5em; margin-bottom:1.0em;
+        font-size: 12px;
+    }
+    h1 {
+        margin: 0px 0px 5px;
+        font-family: verdana,arial,helvetica;
+    }
+    h2 {
+        margin-top: 1em; margin-bottom: 0.5em;
+        font-family: verdana,arial,helvetica;
+    }
+    h3 {
+        margin-bottom: 0.5em;
+        font-family: verdana,arial,helvetica;
+    }
+    h4 {
+        margin-bottom: 0.5em;
+        font-family: verdana,arial,helvetica;
+    }
+    h5 {
+        margin-bottom: 0.5em;
+        font-family: verdana,arial,helvetica;
+    }
+    h6 {
+        margin-bottom: 0.5em;
+        font-family: verdana,arial,helvetica;
+    }
+    .Error {
+        font-weight:bold; color:red;
+    }
+    .Failure {
+        font-weight:bold; color:purple;
+    }
+    .small {
+       font-size: 9px;
+    }
+    a {
+      color: #003399;
+    }
+    a:hover {
+      color: #888888;
+    }
+    </style>
+        </head>
+        <body>
+            <a name="top"></a>
+            <xsl:call-template name="pageHeader"/>  
+            
+            <!-- Summary part -->
+            <xsl:call-template name="summary"/>
+            <hr size="1" width="95%" align="left"/>
+            
+            <!-- Package List part -->
+            <xsl:call-template name="packagelist"/>
+            <hr size="1" width="95%" align="left"/>
+            
+            <!-- For each package create its part -->
+            <xsl:call-template name="packages"/>
+            <hr size="1" width="95%" align="left"/>
+            
+            <!-- For each class create the  part -->
+            <xsl:call-template name="classes"/>
+            
+            <xsl:call-template name="pageFooter"/>  
+        </body>
+    </html>
+</xsl:template>
+    
+    
+    
+    <!-- ================================================================== -->
+    <!-- Write a list of all packages with an hyperlink to the anchor of    -->
+    <!-- of the package name.                                               -->
+    <!-- ================================================================== -->
+    <xsl:template name="packagelist">   
+        <h2>Packages</h2>
+        Note: package statistics are not computed recursively, they only sum up all of its testsuites numbers.
+        <table class="details" border="0" cellpadding="5" cellspacing="2" width="95%">
+            <xsl:call-template name="testsuite.test.header"/>
+            <!-- list all packages recursively -->
+            <xsl:for-each select="./testsuite[not(./@package = preceding-sibling::testsuite/@package)]">
+                <xsl:sort select="@package"/>
+                <xsl:variable name="testsuites-in-package" select="/testsuites/testsuite[./@package = current()/@package]"/>
+                <xsl:variable name="testCount" select="sum($testsuites-in-package/@tests)"/>
+                <xsl:variable name="errorCount" select="sum($testsuites-in-package/@errors)"/>
+                <xsl:variable name="failureCount" select="sum($testsuites-in-package/@failures)"/>
+                <xsl:variable name="timeCount" select="sum($testsuites-in-package/@time)"/>
+                
+                <!-- write a summary for the package -->
+                <tr valign="top">
+                    <!-- set a nice color depending if there is an error/failure -->
+                    <xsl:attribute name="class">
+                        <xsl:choose>
+                            <xsl:when test="$failureCount &gt; 0">Failure</xsl:when>
+                            <xsl:when test="$errorCount &gt; 0">Error</xsl:when>
+                        </xsl:choose>
+                    </xsl:attribute>
+                    <td><a href="#{@package}"><xsl:value-of select="@package"/></a></td>
+                    <td><xsl:value-of select="$testCount"/></td>
+                    <td><xsl:value-of select="$errorCount"/></td>
+                    <td><xsl:value-of select="$failureCount"/></td>
+                    <td>
+                    <xsl:call-template name="display-time">
+                        <xsl:with-param name="value" select="$timeCount"/>
+                    </xsl:call-template>
+                    </td>
+                </tr>
+            </xsl:for-each>
+        </table>        
+    </xsl:template>
+    
+    
+    <!-- ================================================================== -->
+    <!-- Write a package level report                                       -->
+    <!-- It creates a table with values from the document:                  -->
+    <!-- Name | Tests | Errors | Failures | Time                            -->
+    <!-- ================================================================== -->
+    <xsl:template name="packages">
+        <!-- create an anchor to this package name -->
+        <xsl:for-each select="/testsuites/testsuite[not(./@package = preceding-sibling::testsuite/@package)]">
+            <xsl:sort select="@package"/>
+                <a name="{@package}"></a>
+                <h3>Package <xsl:value-of select="@package"/></h3>
+                
+                <table class="details" border="0" cellpadding="5" cellspacing="2" width="95%">
+                    <xsl:call-template name="testsuite.test.header"/>
+            
+                    <!-- match the testsuites of this package -->
+                    <xsl:apply-templates select="/testsuites/testsuite[./@package = current()/@package]" mode="print.test"/>
+                </table>
+                <a href="#top">Back to top</a>
+                <p/>
+                <p/>
+        </xsl:for-each>
+    </xsl:template>
+    
+    <xsl:template name="classes">
+        <xsl:for-each select="testsuite">
+            <xsl:sort select="@name"/>
+            <!-- create an anchor to this class name -->
+            <a name="{@name}"></a>
+            <h3>TestCase <xsl:value-of select="@name"/></h3>
+            
+            <table class="details" border="0" cellpadding="5" cellspacing="2" width="95%">
+              <xsl:call-template name="testcase.test.header"/>
+              <!--
+              test can even not be started at all (failure to load the class)
+              so report the error directly
+              -->
+                <xsl:if test="./error">
+                    <tr class="Error">
+                        <td colspan="4"><xsl:apply-templates select="./error"/></td>
+                    </tr>
+                </xsl:if>
+                <xsl:apply-templates select="./testcase | ./testsuite/testcase" mode="print.test"/>
+            </table>
+            <p/>
+            
+            <a href="#top">Back to top</a>
+        </xsl:for-each>
+    </xsl:template>
+    
+    <xsl:template name="summary">
+        <h2>Summary</h2>
+        <xsl:variable name="testCount" select="sum(testsuite/@tests)"/>
+        <xsl:variable name="errorCount" select="sum(testsuite/@errors)"/>
+        <xsl:variable name="failureCount" select="sum(testsuite/@failures)"/>
+        <xsl:variable name="timeCount" select="sum(testsuite/@time)"/>
+        <xsl:variable name="successRate" select="($testCount - $failureCount - $errorCount) div $testCount"/>
+        <table class="details" border="0" cellpadding="5" cellspacing="2" width="95%">
+        <tr valign="top">
+            <th>Tests</th>
+            <th>Failures</th>
+            <th>Errors</th>
+            <th>Success rate</th>
+            <th>Time</th>
+        </tr>
+        <tr valign="top">
+            <xsl:attribute name="class">
+                <xsl:choose>
+                    <xsl:when test="$failureCount &gt; 0">Failure</xsl:when>
+                    <xsl:when test="$errorCount &gt; 0">Error</xsl:when>
+                </xsl:choose>
+            </xsl:attribute>
+            <td><xsl:value-of select="$testCount"/></td>
+            <td><xsl:value-of select="$failureCount"/></td>
+            <td><xsl:value-of select="$errorCount"/></td>
+            <td>
+                <xsl:call-template name="display-percent">
+                    <xsl:with-param name="value" select="$successRate"/>
+                </xsl:call-template>
+            </td>
+            <td>
+                <xsl:call-template name="display-time">
+                    <xsl:with-param name="value" select="$timeCount"/>
+                </xsl:call-template>
+            </td>
+
+        </tr>
+        </table>
+        <table border="0" width="95%">
+        <tr>
+        <td style="text-align: justify;">
+        Note: <i>failures</i> are anticipated and checked for with assertions while <i>errors</i> are unanticipated.
+        </td>
+        </tr>
+        </table>
+    </xsl:template>
+      
+<!-- Page HEADER -->
+<xsl:template name="pageHeader">
+    <h1>Unit Test Results</h1>
+    <table width="100%">
+    <tr>
+        <td align="left"></td>
+        <td align="right">Designed for use with <a href='http://pear.php.net/package/PHPUnit2'>PHPUnit2</a> and <a href='http://phing.info/'>Phing</a>.</td>
+    </tr>
+    </table>
+    <hr size="1"/>
+</xsl:template>
+
+<!-- Page Footer -->
+<xsl:template name="pageFooter">
+    <table width="100%">
+      <tr><td><hr noshade="yes" size="1"/></td></tr>
+      <tr><td class="small">Report generated at <xsl:value-of select="date:date-time()"/></td></tr>
+    </table>
+</xsl:template>
+
+<xsl:template match="testsuite" mode="header">
+    <tr valign="top">
+        <th width="80%">Name</th>
+        <th>Tests</th>
+        <th>Errors</th>
+        <th>Failures</th>
+        <th nowrap="nowrap">Time(s)</th>
+    </tr>
+</xsl:template>
+
+<!-- class header -->
+<xsl:template name="testsuite.test.header">
+    <tr valign="top">
+        <th width="80%">Name</th>
+        <th>Tests</th>
+        <th>Errors</th>
+        <th>Failures</th>
+        <th nowrap="nowrap">Time(s)</th>
+    </tr>
+</xsl:template>
+
+<!-- method header -->
+<xsl:template name="testcase.test.header">
+    <tr valign="top">
+        <th>Name</th>
+        <th>Status</th>
+        <th width="80%">Type</th>
+        <th nowrap="nowrap">Time(s)</th>
+    </tr>
+</xsl:template>
+
+
+<!-- class information -->
+<xsl:template match="testsuite" mode="print.test">
+    <tr valign="top">
+        <!-- set a nice color depending if there is an error/failure -->
+        <xsl:attribute name="class">
+            <xsl:choose>
+                <xsl:when test="@failures[.&gt; 0]">Failure</xsl:when>
+                <xsl:when test="@errors[.&gt; 0]">Error</xsl:when>
+            </xsl:choose>
+        </xsl:attribute>
+    
+        <!-- print testsuite information -->
+        <td><a href="#{@name}"><xsl:value-of select="@name"/></a></td>
+        <td><xsl:value-of select="@tests"/></td>
+        <td><xsl:value-of select="@errors"/></td>
+        <td><xsl:value-of select="@failures"/></td>
+        <td>
+            <xsl:call-template name="display-time">
+                <xsl:with-param name="value" select="@time"/>
+            </xsl:call-template>
+        </td>
+    </tr>
+</xsl:template>
+
+<xsl:template match="testcase" mode="print.test">
+    <tr valign="top">
+        <xsl:attribute name="class">
+            <xsl:choose>
+                <xsl:when test="failure | error">Error</xsl:when>
+            </xsl:choose>
+        </xsl:attribute>
+        <td><xsl:value-of select="@name"/></td>
+        <xsl:choose>
+            <xsl:when test="failure">
+                <td>Failure</td>
+                <td><xsl:apply-templates select="failure"/></td>
+            </xsl:when>
+            <xsl:when test="error">
+                <td>Error</td>
+                <td><xsl:apply-templates select="error"/></td>
+            </xsl:when>
+            <xsl:otherwise>
+                <td>Success</td>
+                <td></td>
+            </xsl:otherwise>
+        </xsl:choose>
+        <td>
+            <xsl:call-template name="display-time">
+                <xsl:with-param name="value" select="@time"/>
+            </xsl:call-template>
+        </td>
+    </tr>
+</xsl:template>
+
+
+<xsl:template match="failure">
+    <xsl:call-template name="display-failures"/>
+</xsl:template>
+
+<xsl:template match="error">
+    <xsl:call-template name="display-failures"/>
+</xsl:template>
+
+<!-- Style for the error and failure in the tescase template -->
+<xsl:template name="display-failures">
+    <xsl:choose>
+        <xsl:when test="not(@message)">N/A</xsl:when>
+        <xsl:otherwise>
+            <xsl:value-of select="@message"/>
+        </xsl:otherwise>
+    </xsl:choose>
+    <!-- display the stacktrace -->
+    <code>
+        <br/><br/>
+        <xsl:call-template name="br-replace">
+            <xsl:with-param name="word" select="."/>
+        </xsl:call-template>
+    </code>
+</xsl:template>
+
+<!--
+    template that will convert a carriage return into a br tag
+    @param word the text from which to convert CR to BR tag
+-->
+<xsl:template name="br-replace">
+    <xsl:param name="word"/>
+    <xsl:choose>
+         <xsl:when test="contains($word,'&#x0A;')">
+             <xsl:value-of select="substring-before($word,'&#x0A;')"/>
+             <br />
+             <xsl:call-template name="br-replace">
+                 <xsl:with-param name="word" select="substring-after($word,'&#x0A;')"/>
+             </xsl:call-template>
+         </xsl:when>
+         <xsl:otherwise>
+             <xsl:value-of select="$word"/>
+         </xsl:otherwise>
+    </xsl:choose>
+</xsl:template>
+
+<xsl:template name="display-time">
+    <xsl:param name="value"/>
+    <xsl:value-of select="format-number($value,'0.000')"/>
+</xsl:template>
+
+<xsl:template name="display-percent">
+    <xsl:param name="value"/>
+    <xsl:value-of select="format-number($value,'0.00%')"/>
+</xsl:template>
+
+</xsl:stylesheet>
+
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/etc/str.replace.function.xsl
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/etc/str.replace.function.xsl	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/etc/str.replace.function.xsl	(revision 19)
@@ -0,0 +1,105 @@
+<?xml version="1.0"?>
+<xsl:stylesheet version="1.0"
+                xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+                xmlns:str="http://exslt.org/strings"
+                xmlns:func="http://exslt.org/functions"
+                xmlns:exsl="http://exslt.org/common"
+                extension-element-prefixes="str exsl func">
+
+<func:function name="str:replace">
+	<xsl:param name="string" select="''" />
+   <xsl:param name="search" select="/.." />
+   <xsl:param name="replace" select="/.." />
+   <xsl:choose>
+      <xsl:when test="not($string)">
+        <func:result select="/.." />
+      </xsl:when>
+      <xsl:when test="function-available('exsl:node-set')">
+         <!-- this converts the search and replace arguments to node sets
+              if they are one of the other XPath types -->
+         <xsl:variable name="search-nodes-rtf">
+           <xsl:copy-of select="$search" />
+         </xsl:variable>
+         <xsl:variable name="replace-nodes-rtf">
+           <xsl:copy-of select="$replace" />
+         </xsl:variable>
+         <xsl:variable name="replacements-rtf">
+            <xsl:for-each select="exsl:node-set($search-nodes-rtf)/node()">
+               <xsl:variable name="pos" select="position()" />
+               <replace search="{.}">
+                  <xsl:copy-of select="exsl:node-set($replace-nodes-rtf)/node()[$pos]" />
+               </replace>
+            </xsl:for-each>
+         </xsl:variable>
+         <xsl:variable name="sorted-replacements-rtf">
+            <xsl:for-each select="exsl:node-set($replacements-rtf)/replace">
+               <xsl:sort select="string-length(@search)" data-type="number" order="descending" />
+               <xsl:copy-of select="." />
+            </xsl:for-each>
+         </xsl:variable>
+         <xsl:variable name="result">
+           <xsl:choose>
+              <xsl:when test="not($search)">
+                <xsl:value-of select="$string" />
+              </xsl:when>
+             <xsl:otherwise>
+               <xsl:call-template name="str:_replace">
+                  <xsl:with-param name="string" select="$string" />
+                  <xsl:with-param name="replacements" select="exsl:node-set($sorted-replacements-rtf)/replace" />
+               </xsl:call-template>
+             </xsl:otherwise>
+           </xsl:choose>
+         </xsl:variable>
+         <func:result select="exsl:node-set($result)/node()" />
+      </xsl:when>
+      <xsl:otherwise>
+         <xsl:message terminate="yes">
+            ERROR: function implementation of str:replace() relies on exsl:node-set().
+         </xsl:message>
+      </xsl:otherwise>
+   </xsl:choose>
+</func:function>
+
+<xsl:template name="str:_replace">
+  <xsl:param name="string" select="''" />
+  <xsl:param name="replacements" select="/.." />
+  <xsl:choose>
+    <xsl:when test="not($string)" />
+    <xsl:when test="not($replacements)">
+      <xsl:value-of select="$string" />
+    </xsl:when>
+    <xsl:otherwise>
+      <xsl:variable name="replacement" select="$replacements[1]" />
+      <xsl:variable name="search" select="$replacement/@search" />
+      <xsl:choose>
+        <xsl:when test="not(string($search))">
+          <xsl:value-of select="substring($string, 1, 1)" />
+          <xsl:copy-of select="$replacement/node()" />
+          <xsl:call-template name="str:_replace">
+            <xsl:with-param name="string" select="substring($string, 2)" />
+            <xsl:with-param name="replacements" select="$replacements" />
+          </xsl:call-template>
+        </xsl:when>
+        <xsl:when test="contains($string, $search)">
+          <xsl:call-template name="str:_replace">
+            <xsl:with-param name="string" select="substring-before($string, $search)" />
+            <xsl:with-param name="replacements" select="$replacements[position() > 1]" />
+          </xsl:call-template>      
+          <xsl:copy-of select="$replacement/node()" />
+          <xsl:call-template name="str:_replace">
+            <xsl:with-param name="string" select="substring-after($string, $search)" />
+            <xsl:with-param name="replacements" select="$replacements" />
+          </xsl:call-template>
+        </xsl:when>
+        <xsl:otherwise>
+          <xsl:call-template name="str:_replace">
+            <xsl:with-param name="string" select="$string" />
+            <xsl:with-param name="replacements" select="$replacements[position() > 1]" />
+          </xsl:call-template>
+        </xsl:otherwise>
+      </xsl:choose>
+    </xsl:otherwise>
+  </xsl:choose>
+</xsl:template>
+
+</xsl:stylesheet>
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/pear/BuildPhingPEARPackageTask.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/pear/BuildPhingPEARPackageTask.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/pear/BuildPhingPEARPackageTask.php	(revision 19)
@@ -0,0 +1,270 @@
+<?php
+/*
+ *  $Id: BuildPhingPEARPackageTask.php 365 2008-05-11 02:51:40Z hans $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+require_once 'phing/tasks/system/MatchingTask.php';
+include_once 'phing/types/FileSet.php';
+include_once 'phing/tasks/ext/pearpackage/Fileset.php';
+
+/**
+ *
+ * @author   Hans Lellelid <hans@xmpl.org>
+ * @package  phing.tasks.ext
+ * @version  $Revision$
+ */
+class BuildPhingPEARPackageTask extends MatchingTask {
+
+    /** Base directory for reading files. */
+    private $dir;
+
+	private $version;
+	private $state = 'stable';
+	private $notes;
+	
+	private $filesets = array();
+	
+    /** Package file */
+    private $packageFile;
+
+    public function init() {
+        include_once 'PEAR/PackageFileManager2.php';
+        if (!class_exists('PEAR_PackageFileManager2')) {
+            throw new BuildException("You must have installed PEAR_PackageFileManager2 (PEAR_PackageFileManager >= 1.6.0) in order to create a PEAR package.xml file.");
+        }
+    }
+
+    private function setOptions($pkg){
+
+		$options['baseinstalldir'] = 'phing';
+        $options['packagedirectory'] = $this->dir->getAbsolutePath();
+
+        if (empty($this->filesets)) {
+			throw new BuildException("You must use a <fileset> tag to specify the files to include in the package.xml");
+		}
+
+		$options['filelistgenerator'] = 'Fileset';
+
+		// Some PHING-specific options needed by our Fileset reader
+		$options['phing_project'] = $this->getProject();
+		$options['phing_filesets'] = $this->filesets;
+		
+		if ($this->packageFile !== null) {
+            // create one w/ full path
+            $f = new PhingFile($this->packageFile->getAbsolutePath());
+            $options['packagefile'] = $f->getName();
+            // must end in trailing slash
+            $options['outputdirectory'] = $f->getParent() . DIRECTORY_SEPARATOR;
+            $this->log("Creating package file: " . $f->getPath(), Project::MSG_INFO);
+        } else {
+            $this->log("Creating [default] package.xml file in base directory.", Project::MSG_INFO);
+        }
+		
+		// add install exceptions
+		$options['installexceptions'] = array(	'bin/phing.php' => '/',
+												'bin/pear-phing' => '/',
+												'bin/pear-phing.bat' => '/',
+												);
+
+		$options['dir_roles'] = array(	'phing_guide' => 'doc',
+										'etc' => 'data',
+										'example' => 'doc');
+
+		$options['exceptions'] = array(	'bin/pear-phing.bat' => 'script',
+										'bin/pear-phing' => 'script',
+										'CREDITS' => 'doc',
+										'CHANGELOG' => 'doc',
+										'README' => 'doc',
+										'TODO' => 'doc');
+
+		$pkg->setOptions($options);
+
+    }
+
+    /**
+     * Main entry point.
+     * @return void
+     */
+    public function main() {
+
+        if ($this->dir === null) {
+            throw new BuildException("You must specify the \"dir\" attribute for PEAR package task.");
+        }
+
+		if ($this->version === null) {
+            throw new BuildException("You must specify the \"version\" attribute for PEAR package task.");
+        }
+
+		$package = new PEAR_PackageFileManager2();
+
+		$this->setOptions($package);
+
+		// the hard-coded stuff
+		$package->setPackage('phing');
+		$package->setSummary('PHP5 project build system based on Apache Ant');
+		$package->setDescription('PHing Is Not GNU make; it\'s a project build system based on Apache Ant. 
+You can do anything with it that you could do with a traditional build system like GNU make, and its use of 
+simple XML build files and extensible PHP "task" classes make it an easy-to-use and highly flexible build framework. 
+Features include file transformations (e.g. token replacement, XSLT transformation, Smarty template transformations, 
+etc.), file system operations, interactive build support, SQL execution, and much more.');
+		$package->setChannel('pear.phing.info');
+		$package->setPackageType('php');
+
+		$package->setReleaseVersion($this->version);
+		$package->setAPIVersion($this->version);
+		
+		$package->setReleaseStability($this->state);
+		$package->setAPIStability($this->state);
+		
+		$package->setNotes($this->notes);
+		
+		$package->setLicense('LGPL', 'http://www.gnu.org/licenses/lgpl.html');
+		
+		// Add package maintainers
+		$package->addMaintainer('lead', 'hans', 'Hans Lellelid', 'hans@xmpl.org');
+		$package->addMaintainer('lead', 'mrook', 'Michiel Rook', 'michiel.rook@gmail.com');
+		
+		
+		
+		// (wow ... this is a poor design ...)
+		//
+		// note that the order of the method calls below is creating
+		// sub-"release" sections which have specific rules.  This replaces
+		// the platformexceptions system in the older version of PEAR's package.xml
+		//
+		// Programmatically, I feel the need to re-iterate that this API for PEAR_PackageFileManager
+		// seems really wrong.  Sub-sections should be encapsulated in objects instead of having
+		// a "flat" API that does not represent the structure being created....
+		
+		
+		// creating a sub-section for 'windows'
+			$package->addRelease();
+			$package->setOSInstallCondition('windows');
+			$package->addInstallAs('bin/phing.php', 'phing.php');
+			$package->addInstallAs('bin/pear-phing.bat', 'phing.bat');
+			$package->addIgnoreToRelease('bin/pear-phing');
+		
+		// creating a sub-section for non-windows
+			$package->addRelease();
+			//$package->setOSInstallCondition('(*ix|*ux|darwin*|*BSD|SunOS*)');
+			$package->addInstallAs('bin/phing.php', 'phing.php');
+			$package->addInstallAs('bin/pear-phing', 'phing');
+			$package->addIgnoreToRelease('bin/pear-phing.bat');
+		
+
+		// "core" dependencies
+		$package->setPhpDep('5.1.0');
+		$package->setPearinstallerDep('1.4.0');
+		
+		// "package" dependencies
+		$package->addPackageDepWithChannel( 'optional', 'VersionControl_SVN', 'pear.php.net', '0.3.0alpha1');
+		$package->addPackageDepWithChannel( 'optional', 'PHPUnit', 'pear.phpunit.de', '2.3.0');
+		$package->addPackageDepWithChannel( 'optional', 'PhpDocumentor', 'pear.php.net', '1.3.0RC3');
+		$package->addPackageDepWithChannel( 'optional', 'Xdebug', 'pear.php.net', '2.0.0beta2');
+		$package->addPackageDepWithChannel( 'optional', 'Archive_Tar', 'pear.php.net', '1.3.0');
+		$package->addPackageDepWithChannel( 'optional', 'PEAR_PackageFileManager', 'pear.php.net', '1.5.2');
+
+		// now add the replacements ....
+		$package->addReplacement('Phing.php', 'pear-config', '@DATA-DIR@', 'data_dir');
+		$package->addReplacement('bin/pear-phing.bat', 'pear-config', '@PHP-BIN@', 'php_bin');
+		$package->addReplacement('bin/pear-phing.bat', 'pear-config', '@BIN-DIR@', 'bin_dir');
+		$package->addReplacement('bin/pear-phing.bat', 'pear-config', '@PEAR-DIR@', 'php_dir');
+		$package->addReplacement('bin/pear-phing', 'pear-config', '@PHP-BIN@', 'php_bin');
+		$package->addReplacement('bin/pear-phing', 'pear-config', '@BIN-DIR@', 'bin_dir');
+		$package->addReplacement('bin/pear-phing', 'pear-config', '@PEAR-DIR@', 'php_dir');
+		
+		// now we run this weird generateContents() method that apparently 
+		// is necessary before we can add replacements ... ?
+		$package->generateContents();
+		
+        $e = $package->writePackageFile();
+
+        if (PEAR::isError($e)) {
+            throw new BuildException("Unable to write package file.", new Exception($e->getMessage()));
+        }
+
+    }
+
+    /**
+     * Used by the PEAR_PackageFileManager_PhingFileSet lister.
+     * @return array FileSet[]
+     */
+    public function getFileSets() {
+        return $this->filesets;
+    }
+
+    // -------------------------------
+    // Set properties from XML
+    // -------------------------------
+
+    /**
+     * Nested creator, creates a FileSet for this task
+     *
+     * @return FileSet The created fileset object
+     */
+    function createFileSet() {
+        $num = array_push($this->filesets, new FileSet());
+        return $this->filesets[$num-1];
+    }
+
+	/**
+     * Set the version we are building.
+     * @param string $v
+     * @return void
+     */
+	public function setVersion($v){
+		$this->version = $v;
+	}
+
+	/**
+     * Set the state we are building.
+     * @param string $v
+     * @return void
+     */
+	public function setState($v) {
+		$this->state = $v;
+	}
+	
+	/**
+	 * Sets release notes field.
+	 * @param string $v
+	 * @return void
+	 */
+	public function setNotes($v) {
+		$this->notes = $v;
+	}
+    /**
+     * Sets "dir" property from XML.
+     * @param PhingFile $f
+     * @return void
+     */
+    public function setDir(PhingFile $f) {
+        $this->dir = $f;
+    }
+
+    /**
+     * Sets the file to use for generated package.xml
+     */
+    public function setDestFile(PhingFile $f) {
+        $this->packageFile = $f;
+    }
+
+}
+
+
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/pear/build.xml
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/pear/build.xml	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/pear/build.xml	(revision 19)
@@ -0,0 +1,156 @@
+<?xml version="1.0"?>
+<!--
+	This build file packages the phing files, builds a package.xml (version 2) for installation
+	using PEAR and creates the TAR and TGZ files.
+-->	
+<project name="phing" basedir="." default="main">
+	
+	<property name="phingpkg.home" value=".."/>
+	<property name="build.base.dir" value="build"/>
+	<property name="pkgname" value="phing-${version}"/>		
+	<property name="build.src.dir" value="${build.base.dir}/${pkgname}"/>
+	
+	<!-- some default properties -->
+	<property name="notes">This is the latest release of Phing.</property>
+	<property name="state" value="beta"/>
+	
+	<taskdef
+    name="pear-package"
+    classname="BuildPhingPEARPackageTask" classpath="."/>
+
+	<fileset dir="${phingpkg.home}/classes/phing" id="classes">
+		<include name="**"/>
+	</fileset>
+
+	<fileset dir="${phingpkg.home}/docs" id="docs">
+		<include name="example/**"/>
+		<include name="phing_guide/book/**"/>
+	</fileset>
+
+	<fileset dir="${phingpkg.home}" id="etc">
+		<include name="etc/**"/>
+	</fileset>
+	
+	<fileset dir="${phingpkg.home}" id="etc-no-version">
+		<include name="etc/**"/>
+		<exclude name="etc/VERSION.TXT"/>
+	</fileset>
+	
+	<fileset dir="${phingpkg.home}" id="scripts">
+		<include name="bin/pear-*"/>
+		<include name="bin/phing.php"/>
+	</fileset>
+
+	<fileset dir="${phingpkg.home}" id="misc">
+		<include name="CHANGELOG"/>
+		<include name="CREDITS"/>
+		<include name="README"/>
+		<include name="TODO"/>
+		<exclude name="INSTALL*"/>
+	</fileset>
+
+	<!--
+		==============================================
+		Main entry point
+		==============================================
+	-->				
+	<target name="main" if="version" depends="versioncheck,copy-files,create-package-xml,tar"/>
+
+	<!--
+	 ===================================================================
+	 Target: checks if language was given, otherwise fail
+	 ===================================================================
+	-->
+	<target name="versioncheck" unless="version">
+		<echo message="====================================================="/>
+		<echo message="Version not specified. You must enter a version. In"/>
+		<echo message="the future you can add this to build.properties or"/>
+		<echo message="enter it on the command line: "/>
+		<echo message=" "/>
+		<echo message="-Dversion=2.0.0b1"/>
+		<echo message="====================================================="/>	
+		<input propertyname="version" promptChar=":">Phing version for package</input>
+		
+		<property name="pkgname" value="phing-${version}" override="true"/>		
+		<property name="build.src.dir" value="${build.base.dir}/${pkgname}" override="true"/>
+		
+	</target>
+	
+	<!--
+		==============================================
+		Copy the desired files into the build/ dir
+		making sure to put them in the directory
+		structure that will be needed for PEAR install
+		==============================================
+	-->	
+	<target name="copy-files">
+	
+		<echo>-----------------------------</echo>
+		<echo>| Creating directory layout |</echo>
+		<echo>-----------------------------</echo>
+		
+		<delete dir="${build.base.dir}"/>
+		
+		<copy todir="${build.src.dir}">
+			<fileset refid="classes"/>
+			<fileset refid="docs"/>
+			<fileset refid="etc-no-version"/>
+			<fileset refid="scripts"/>
+			<fileset refid="misc"/>
+		</copy>
+		
+		<append destFile="${build.src.dir}/etc/VERSION.TXT">Phing version ${version}</append>
+		
+		<chmod file="${build.src.dir}/bin/pear-phing" mode="755"/>
+		
+	</target>
+	
+	<!--
+		==============================================
+		Create a PEAR package.xml which will guide the
+		installation.
+		==============================================
+	-->	
+	<target name="create-package-xml" depends="versioncheck" if="version">
+	
+		<echo>-----------------------------</echo>
+		<echo>| Creating PEAR package.xml |</echo>
+		<echo>-----------------------------</echo>
+		<echo></echo>
+		<echo>... (This step may take some time) ...</echo>
+		
+		<delete	file="${tarfile}"/>
+		<pear-package dir="${build.src.dir}" destFile="${build.base.dir}/package.xml" version="${version}" state="${state}" notes="${notes}">
+			
+			<fileset refid="classes"/>
+			<fileset refid="docs"/>
+			<fileset refid="etc"/>
+			<fileset refid="misc"/>
+			<fileset refid="scripts"/>
+			
+		</pear-package>
+		
+	</target>
+	
+	<!--
+		==============================================
+		Create a tar.gz of the files, which will be 
+		installed by pear package manager.
+		==============================================
+	-->
+	<target name="tar">
+		<echo>-----------------------------</echo>
+		<echo>| Creating TAR packages     |</echo>
+		<echo>-----------------------------</echo>	
+		
+		<property name="tgzfile" value="${build.base.dir}/${pkgname}.tgz"/>
+		<delete	file="${tgzfile}"/>
+		<tar compression="gzip" destFile="${tgzfile}" basedir="${build.base.dir}" />
+		
+		<property name="tarfile" value="${build.base.dir}/${pkgname}.tar"/>
+		<delete	file="${tarfile}"/>
+		<tar compression="none" destFile="${tarfile}" basedir="${build.base.dir}" />
+		
+	</target>
+	
+</project>
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/test/build.xml
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/test/build.xml	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/test/build.xml	(revision 19)
@@ -0,0 +1,75 @@
+<?xml version="1.0"?>
+
+<project name="Phing Build Tests" default="phpunit" basedir=".">
+	
+	<!--
+		=========================================================================================
+		Global Properties
+		~~~~~~~~~~~~~~~~~
+		
+		=========================================================================================					
+	-->
+	<property name="tests.dir" value="./tests"/>
+	<property name="tests.phpunit.dir" value="."/>
+	<property name="tests.reports.dir" value="${tests.phpunit.dir}/reports"/>
+	<property file="./test.properties" />
+
+	<!--
+		=========================================================================================
+		PHPUnit2 Targets
+		~~~~~~~~~~~~~~~~
+		
+		=========================================================================================					
+	-->
+
+	<property name="test.class" value="${test}"/>
+	
+	<resolvepath propertyName="tests.dir.resolved" file="${tests.phpunit.dir}"/>
+	<resolvepath propertyName="tests.classes.dir.resolved" file="${tests.phpunit.dir}/classes"/>
+	<resolvepath propertyName="phing.classes.dir.resolved" file="../classes"/>
+	
+	<path id="incthis">
+		<pathelement dir="${tests.dir.resolved}"/>
+		<pathelement dir="${tests.classes.dir.resolved}"/>
+		<pathelement dir="${phing.classes.dir.resolved}"/>
+	</path>
+	
+	<target name="configure">
+		<echo>-------------------------------------------------</echo>
+		<echo> +++++ Running Phing  unit tests</echo>
+		<echo>-------------------------------------------------</echo>
+		<adhoc><![CDATA[
+			// Cannot use __FILE__ because that is the AdhocTask not this build.xml file
+			define('PHING_TEST_BASE', dirname($this->getProject()->getProperty('phing.file')));
+		]]></adhoc>
+		
+		<!-- startup will have changed the include_path, so set it back now -->
+		<includepath classpathRef="incthis"/>
+			
+		<fileset dir="${tests.classes.dir.resolved}" id="relevant-tests">
+			<include name="**/*${test.class}Test.php"/>
+		</fileset>
+	</target>
+
+	<target name="reports" depends="configure">
+		<phpunit2 haltonerror="true" haltonfailure="false" printsummary="true">
+			<formatter type="xml" usefile="true" todir="${tests.reports.dir}" outfile="test-results.xml" />
+			<formatter type="plain" usefile="false"/>
+			<batchtest>
+				<fileset refid="relevant-tests"/>
+			</batchtest>
+		</phpunit2>
+		<phpunit2report format="noframes" todir="${tests.reports.dir}" infile="${tests.reports.dir}/test-results.xml" styledir="${tests.phpunit.dir}/etc/xsl"/>
+	</target>
+	
+	<!-- run the insert-sql target of the build.xml unless we are doing this for one specific test -->
+	<target name="initialize" unless="test">
+		<!--
+		<phing phingFile="build.xml" target="insert-sql"/>
+		-->
+		<property name="test.class" value="" override="true"/>
+	</target>
+	
+	<target name="phpunit" depends="initialize,reports" description="Executes the PHPUnit2 test suite"/>
+	
+</project>
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/test/classes/example/tasks/TaskdefTestSimpleTask.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/test/classes/example/tasks/TaskdefTestSimpleTask.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/test/classes/example/tasks/TaskdefTestSimpleTask.php	(revision 19)
@@ -0,0 +1,47 @@
+<?php
+
+/*
+ * $Id: TaskdefTestSimpleTask.php 144 2007-02-05 15:19:00Z hans $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+ 
+require_once 'phing/Task.php';
+
+class TaskdefTestSimpleTask extends Task {
+
+    private $echo;
+    
+    /**
+     * @return TestEcho
+     */
+    public function createEcho() {
+        $this->echo = new TestEcho();
+        return $this->echo;
+    }
+    
+    public function main() {
+        $this->log("simpletask: " . $echo->message, Project::MSG_INFO);
+    }
+
+}
+
+class TestEcho {
+    public $message;
+    public function setMessage($s) {$this->message = $s;}
+}
+
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/test/classes/example/types/TypedefTestType.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/test/classes/example/types/TypedefTestType.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/test/classes/example/types/TypedefTestType.php	(revision 19)
@@ -0,0 +1,28 @@
+<?php
+
+/*
+ * $Id: TypedefTestType.php 123 2006-09-14 20:19:08Z mrook $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+ 
+require_once 'phing/types/DataType.php';
+
+class TypedefTestType extends DataType {
+
+}
+
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/test/classes/phing/BuildFileTest.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/test/classes/phing/BuildFileTest.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/test/classes/phing/BuildFileTest.php	(revision 19)
@@ -0,0 +1,403 @@
+<?php
+
+/*
+ *  $Id: BuildFileTest.php 227 2007-08-28 02:17:00Z hans $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+ 
+require_once 'PHPUnit2/Framework/TestCase.php';
+require_once 'phing/BuildListener.php';
+require_once 'phing/system/io/PhingFile.php';
+
+/**
+ * A BuildFileTest is a TestCase which executes targets from an Ant buildfile 
+ * for testing.
+ * 
+ * This class provides a number of utility methods for particular build file 
+ * tests which extend this class. 
+ * 
+ * @author Nico Seessle <nico@seessle.de>
+ * @author Conor MacNeill
+ */
+abstract class BuildFileTest extends PHPUnit2_Framework_TestCase { 
+    
+    protected $project;
+    
+    /**
+     * @var array Array of log BuildEvent objects.
+     */
+    public $logBuffer = array();
+    
+    private $outBuffer;
+    private $errBuffer;
+    private $buildException;
+    
+    /**
+     * Asserts that the log buffer contains specified message at specified priority.
+     * @param string $$expected Message subsctring
+     * @param int $priority Message priority (default: any)
+     * @param string $errmsg The error message to display.
+     */
+    protected function assertInLogs($expected, $priority = null, $errormsg = "Expected to find '%s' in logs: %s")
+    {
+    	foreach($this->logBuffer as $log) {
+    		if (false !== stripos($log, $expected)) {
+    			return;
+    		}
+    	}
+    	$this->fail(sprintf($errormsg, $expected, var_export($this->logBuffer,true)));
+    }
+    
+    /**
+     *  run a target, expect for any build exception 
+     *
+     *@param  target target to run
+     *@param  cause  information string to reader of report
+     */    
+    protected function expectBuildException($target, $cause) { 
+        $this->expectSpecificBuildException($target, $cause, null);
+    }
+
+    /**
+     * Assert that only the given message has been logged with a
+     * priority &gt;= INFO when running the given target.
+     */
+    protected function expectLog($target, $log) { 
+        $this->executeTarget($target);
+        $this->assertInLogs($log);
+    }
+
+    /**
+     * Assert that the given message has been logged with a priority
+     * &gt;= INFO when running the given target.
+     */
+    protected function expectLogContaining($target, $log) { 
+        $this->executeTarget($target);
+        $this->assertInLogs($log);
+    }
+
+    /**
+     * Assert that the given message has been logged with a priority
+     * &gt;= DEBUG when running the given target.
+     */
+    protected function expectDebuglog($target, $log) { 
+        $this->executeTarget($target);
+        $this->assertInLogs($log, Project::MSG_DEBUG);
+    }
+
+    /**
+     *  execute the target, verify output matches expectations
+     *
+     *@param  target  target to execute
+     *@param  output  output to look for
+     */
+    
+    protected function expectOutput($target, $output) { 
+        $this->executeTarget($target);
+        $realOutput = $this->getOutput();
+        $this->assertEquals($output, $realOutput);
+    }
+
+    /**
+     *  execute the target, verify output matches expectations
+     *  and that we got the named error at the end
+     *@param  target  target to execute
+     *@param  output  output to look for
+     *@param  error   Description of Parameter
+     */
+     
+    protected function expectOutputAndError($target, $output, $error) { 
+        $this->executeTarget($target);
+        $realOutput = $this->getOutput();
+        $this->assertEquals($output, $realOutput);
+        $realError = $this->getError();
+        $this->assertEquals($error, $realError);
+    }
+
+    protected function getOutput() {
+        return $this->cleanBuffer($this->outBuffer);
+    }
+     
+    protected function getError() {
+        return $this->cleanBuffer($this->errBuffer);
+    }
+        
+    protected function getBuildException() {
+        return $this->buildException;
+    }
+
+    private function cleanBuffer($buffer) {
+        $cleanedBuffer = "";
+        $cr = false;
+        for ($i = 0, $bufflen=strlen($buffer); $i < $bufflen; $i++) { 
+            $ch = $buffer{$i};
+            if ($ch == "\r") {
+                $cr = true;
+                continue;
+            }
+
+            if (!$cr) { 
+                $cleanedBuffer.= $ch;
+            } else { 
+                if ($ch == "\n") {
+                    $cleanedBuffer .= $ch;
+                } else {
+                    $cleanedBuffer .= "\r" . $ch;
+                }
+            }
+        }
+        return $cleanedBuffer;
+    }
+    
+    /**
+     *  set up to run the named project
+     *
+     * @param  filename name of project file to run
+     * @throws BuildException
+     */    
+    protected function configureProject($filename) { 
+        $this->logBuffer = "";
+        $this->fullLogBuffer = "";
+        $this->project = new Project();
+        $this->project->init();
+        $f = new PhingFile($filename);
+        $this->project->setUserProperty( "phing.file" , $f->getAbsolutePath() );
+        $this->project->addBuildListener(new PhingTestListener($this));
+        ProjectConfigurator::configureProject($this->project, new PhingFile($filename));
+    }
+    
+    /**
+     *  execute a target we have set up
+     * @pre configureProject has been called
+     * @param string $targetName  target to run
+     */    
+    protected function executeTarget($targetName) { 
+        
+            $this->outBuffer = "";
+            $this->errBuffer = "";
+            $this->logBuffer = "";
+            $this->fullLogBuffer = "";
+            $this->buildException = null;
+            $this->project->executeTarget($targetName);
+               
+    }
+    
+    /**
+     * Get the project which has been configured for a test.
+     *
+     * @return the Project instance for this test.
+     */
+    protected function getProject() {
+        return $this->project;
+    }
+
+    /**
+     * get the directory of the project
+     * @return the base dir of the project
+     */
+    protected function getProjectDir() {
+        return $this->project->getBaseDir();
+    }
+
+    /**
+     *  run a target, wait for a build exception 
+     *
+     *@param  target target to run
+     *@param  cause  information string to reader of report
+     *@param  msg    the message value of the build exception we are waiting for
+              set to null for any build exception to be valid
+     */    
+    protected function expectSpecificBuildException($target, $cause, $msg) { 
+        try {
+            $this->executeTarget($target);
+        } catch (BuildException $ex) {
+            $this->buildException = $ex;
+            if (($msg !== null) && (!$ex->getMessage() == $msg)) {
+                $this->fail("Should throw BuildException because '" . $cause
+                        . "' with message '" . $msg
+                        . "' (actual message '" . $ex->getMessage() . "' instead)");
+            }
+            return;
+        }
+        $this->fail("Should throw BuildException because: " . $cause);
+    }
+    
+    /**
+     *  run a target, expect an exception string
+     *  containing the substring we look for (case sensitive match)
+     *
+     *@param  target target to run
+     *@param  cause  information string to reader of report
+     *@param  msg    the message value of the build exception we are waiting for
+     *@param  contains  substring of the build exception to look for
+     */
+    protected function expectBuildExceptionContaining($target, $cause, $contains) { 
+        try {
+            $this->executeTarget($target);
+        } catch (BuildException $ex) {
+            $this->buildException = $ex;
+            if ((null != $contains) && (false === strpos($ex->getMessage(), $contains))) {
+                $this->fail("Should throw BuildException because '" . $cause . "' with message containing '" . $contains . "' (actual message '" . $ex->getMessage() . "' instead)");
+            }
+            return;
+        }
+        $this->fail("Should throw BuildException because: " . $cause);
+    }
+    
+
+    /**
+     * call a target, verify property is as expected
+     *
+     * @param target build file target
+     * @param property property name
+     * @param value expected value
+     */
+
+    protected function expectPropertySet($target, $property, $value = "true") {
+        $this->executeTarget($target);
+        $this->assertPropertyEquals($property, $value);
+    }
+
+    /**
+     * assert that a property equals a value; comparison is case sensitive.
+     * @param property property name
+     * @param value expected value
+     */
+    protected function assertPropertyEquals($property, $value) {
+        $result = $this->project->getProperty($property);
+        $this->assertEquals("property " . $property,$value,$result);
+    }
+
+    /**
+     * assert that a property equals &quot;true&quot;
+     * @param property property name
+     */
+    protected function assertPropertySet($property) {
+        $this->assertPropertyEquals($property, "true");
+    }
+
+    /**
+     * assert that a property is null
+     * @param property property name
+     */
+    protected function assertPropertyUnset($property) {
+        $this->assertPropertyEquals($property, null);
+    }
+
+
+    /**
+     * call a target, verify property is null
+     * @param target build file target
+     * @param property property name
+     */
+    protected function expectPropertyUnset($target, $property) {
+        $this->expectPropertySet($target, $property, null);
+    }
+
+    /**
+     * Retrieve a resource from the caller classloader to avoid
+     * assuming a vm working directory. The resource path must be
+     * relative to the package name or absolute from the root path.
+     * @param resource the resource to retrieve its url.
+     * @throws AssertionFailureException if resource is not found.
+     */
+    protected function getResource($resource){
+        throw new BuildException("getResource() not yet implemented");
+        //$url = ggetClass().getResource(resource);
+        //assertNotNull("Could not find resource :" + resource, url);
+        //return url;
+    }    
+
+
+
+}
+
+/**
+ * our own personal build listener
+ */
+class PhingTestListener implements BuildListener {
+
+    private $parent;
+
+    public function __construct($parent) {
+    	$this->parent = $parent;
+    }
+
+    /**
+     *  Fired before any targets are started.
+     */
+    public function buildStarted(BuildEvent $event) {
+    }
+
+    /**
+     *  Fired after the last target has finished. This event
+     *  will still be thrown if an error occured during the build.
+     *
+     *  @see BuildEvent#getException()
+     */
+    public function buildFinished(BuildEvent $event) {
+    }
+
+    /**
+     *  Fired when a target is started.
+     *
+     *  @see BuildEvent#getTarget()
+     */
+    public function targetStarted(BuildEvent $event) {
+        //System.out.println("targetStarted " + event.getTarget().getName());
+    }
+
+    /**
+     *  Fired when a target has finished. This event will
+     *  still be thrown if an error occured during the build.
+     *
+     *  @see BuildEvent#getException()
+     */
+    public function targetFinished(BuildEvent $event) {
+        //System.out.println("targetFinished " + event.getTarget().getName());
+    }
+
+    /**
+     *  Fired when a task is started.
+     *
+     *  @see BuildEvent#getTask()
+     */
+    public function taskStarted(BuildEvent $event) {
+        //System.out.println("taskStarted " + event.getTask().getTaskName());
+    }
+
+    /**
+     *  Fired when a task has finished. This event will still
+     *  be throw if an error occured during the build.
+     *
+     *  @see BuildEvent#getException()
+     */
+    public function taskFinished(BuildEvent $event) {
+        //System.out.println("taskFinished " + event.getTask().getTaskName());
+    }
+
+    /**
+     *  Fired whenever a message is logged.
+     *
+     *  @see BuildEvent#getMessage()
+     *  @see BuildEvent#getPriority()
+     */
+    public function messageLogged(BuildEvent $event) {        
+        $this->parent->logBuffer[] = $event->getMessage();
+    }
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/test/classes/phing/IntrospectionHelperTest.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/test/classes/phing/IntrospectionHelperTest.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/test/classes/phing/IntrospectionHelperTest.php	(revision 19)
@@ -0,0 +1,406 @@
+<?php
+/*
+ *  $Id: IntrospectionHelperTest.php 123 2006-09-14 20:19:08Z mrook $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+require_once 'PHPUnit2/Framework/TestCase.php';
+include_once 'phing/tasks/system/condition/OsCondition.php';
+
+/**
+ * testcases for phing.IntrospectionHelper.
+ * 
+ * @author Hans Lellelid <hans@xmpl.org> (Phing)
+ * @author Stefan Bodewig <stefan.bodewig@epost.de> (Ant)
+ * @version $Revision: 1.6 $
+ */
+class IntrospectionHelperTest extends PHPUnit2_Framework_TestCase {
+
+    /** @var Project */
+    private $p;
+    
+    public function setUp() {
+        $this->p = new Project();
+        $this->p->setBasedir(DIRECTORY_SEPARATOR);
+    }
+    
+    /**
+     *
+     * @throws BuildException
+     */
+    public function testAddText()  {
+        $ih = IntrospectionHelper::getHelper('Exception');
+        try {
+            $ih->addText($this->p, new Exception(), "test");
+            $this->fail("Exception doesn\'t support addText");
+        } catch (BuildException $be) {
+        }
+
+        $ih = IntrospectionHelper::getHelper('IHProjectComponent');
+        $ih->addText($this->p, new IHProjectComponent(), "test");
+    }
+
+    public function testSupportsCharacters() {
+        $ih = IntrospectionHelper::getHelper('Exception');
+        $this->assertTrue(!$ih->supportsCharacters(), "String doesn\'t support addText");
+        $ih = IntrospectionHelper::getHelper('IHProjectComponent');
+        $this->assertTrue($ih->supportsCharacters(), "IHProjectComponent supports addText");
+    }    
+    
+    public function testElementCreators() {
+        
+        try {
+            $ihtmp = IntrospectionHelper::getHelper('IHCreatorFail1');
+            $this->fail("create cannot take param");
+        } catch (BuildException $be) {}
+
+        try {
+            $ihtmp = IntrospectionHelper::getHelper('IHCreatorFail2');
+            $this->fail("no class hint for add");
+        } catch (BuildException $be) {}
+
+        try {
+            $ihtmp = IntrospectionHelper::getHelper('IHCreatorFail3');
+            $this->fail("no class hint for addconfigured");
+        } catch (BuildException $be) {}
+        
+        $ih = IntrospectionHelper::getHelper('IHProjectComponent');
+        $this->assertEquals("test", $ih->createElement($this->p, new IHProjectComponent(), "one"));
+       
+    }
+    
+    /*
+    public function testGetNestedElements() {
+        Hashtable h = new Hashtable();
+        h.put("six", java.lang.String.class);
+        h.put("thirteen", java.lang.StringBuffer.class);
+        h.put("fourteen", java.lang.StringBuffer.class);
+        h.put("fifteen", java.lang.StringBuffer.class);
+        IntrospectionHelper $ih = IntrospectionHelper::getHelper(get_class($this));
+        Enumeration enum = ih.getNestedElements();
+        while (enum.hasMoreElements()) {
+            String name = (String) enum.nextElement();
+            Class expect = (Class) h.get(name);
+            assertNotNull("Support for "+name+" in IntrospectioNHelperTest?",
+                          expect);
+            $this->assertEquals("Return type of "+name, expect, ih.getElementType(name));
+            h.remove(name);
+        }
+        $this->assertTrue("Found all", h.isEmpty());
+    }
+
+    public function createOne() {
+        return "test";
+    }
+    /*
+    public function testAttributeSetters() {
+        $ih = IntrospectionHelper::getHelper(get_class($this));
+        try {
+            $ih->setAttribute($p, $this, "one", "test");
+            $this->fail("setOne doesn't exist");
+        } catch (BuildException $be) {
+        }
+        try {
+            $ih->setAttribute($p, $this, "two", "test");
+            $this->fail("setTwo returns non void");
+        } catch (BuildException be) {
+        }
+        try {
+            ih.setAttribute(p, this, "three", "test");
+            $this->fail("setThree takes no args");
+        } catch (BuildException be) {
+        }
+        try {
+            ih.setAttribute(p, this, "four", "test");
+            $this->fail("setFour takes two args");
+        } catch (BuildException be) {
+        }
+        try {
+            ih.setAttribute(p, this, "five", "test");
+            $this->fail("setFive takes array arg");
+        } catch (BuildException be) {
+        }
+        try {
+            ih.setAttribute(p, this, "six", "test");
+            $this->fail("Project doesn't have a String constructor");
+        } catch (BuildException be) {
+        }
+        ih.setAttribute(p, this, "seven", "2");
+        try {
+            ih.setAttribute(p, this, "seven", "3");
+            $this->fail("2 shouldn't be equals to three");
+        } catch (BuildException be) {
+            $this->assertTrue(be.getException() instanceof AssertionFailedError);
+        }
+        ih.setAttribute(p, this, "eight", "2");
+        try {
+            ih.setAttribute(p, this, "eight", "3");
+            $this->fail("2 shouldn't be equals to three - as int");
+        } catch (BuildException be) {
+            $this->assertTrue(be.getException() instanceof AssertionFailedError);
+        }
+        ih.setAttribute(p, this, "nine", "2");
+        try {
+            ih.setAttribute(p, this, "nine", "3");
+            $this->fail("2 shouldn't be equals to three - as Integer");
+        } catch (BuildException be) {
+            $this->assertTrue(be.getException() instanceof AssertionFailedError);
+        }
+        ih.setAttribute(p, this, "ten", "2");
+        try {
+            ih.setAttribute(p, this, "ten", "3");
+            $this->fail(projectBasedir+"2 shouldn't be equals to "+projectBasedir+"3");
+        } catch (BuildException be) {
+            $this->assertTrue(be.getException() instanceof AssertionFailedError);
+        }
+        ih.setAttribute(p, this, "eleven", "2");
+        try {
+            ih.setAttribute(p, this, "eleven", "on");
+            $this->fail("on shouldn't be false");
+        } catch (BuildException be) {
+            $this->assertTrue(be.getException() instanceof AssertionFailedError);
+        }
+        ih.setAttribute(p, this, "twelve", "2");
+        try {
+            ih.setAttribute(p, this, "twelve", "on");
+            $this->fail("on shouldn't be false");
+        } catch (BuildException be) {
+            $this->assertTrue(be.getException() instanceof AssertionFailedError);
+        }
+        ih.setAttribute(p, this, "thirteen", "org.apache.tools.ant.Project");
+        try {
+            ih.setAttribute(p, this, "thirteen", "org.apache.tools.ant.ProjectHelper");
+            $this->fail("org.apache.tools.ant.Project shouldn't be equal to org.apache.tools.ant.ProjectHelper");
+        } catch (BuildException be) {
+            $this->assertTrue(be.getException() instanceof AssertionFailedError);
+        }
+        try {
+            ih.setAttribute(p, this, "thirteen", "org.apache.tools.ant.Project2");
+            $this->fail("org.apache.tools.ant.Project2 doesn't exist");
+        } catch (BuildException be) {
+            $this->assertTrue(be.getException() instanceof ClassNotFoundException);
+        }
+        ih.setAttribute(p, this, "fourteen", "2");
+        try {
+            ih.setAttribute(p, this, "fourteen", "on");
+            $this->fail("2 shouldn't be equals to three - as StringBuffer");
+        } catch (BuildException be) {
+            $this->assertTrue(be.getException() instanceof AssertionFailedError);
+        }
+        ih.setAttribute(p, this, "fifteen", "abcd");
+        try {
+            ih.setAttribute(p, this, "fifteen", "on");
+            $this->fail("o shouldn't be equal to a");
+        } catch (BuildException be) {
+            $this->assertTrue(be.getException() instanceof AssertionFailedError);
+        }
+        ih.setAttribute(p, this, "sixteen", "abcd");
+        try {
+            ih.setAttribute(p, this, "sixteen", "on");
+            $this->fail("o shouldn't be equal to a");
+        } catch (BuildException be) {
+            $this->assertTrue(be.getException() instanceof AssertionFailedError);
+        }
+        ih.setAttribute(p, this, "seventeen", "17");
+        try {
+            ih.setAttribute(p, this, "seventeen", "3");
+            $this->fail("17 shouldn't be equals to three");
+        } catch (BuildException be) {
+            $this->assertTrue(be.getException() instanceof AssertionFailedError);
+        }
+        ih.setAttribute(p, this, "eightteen", "18");
+        try {
+            ih.setAttribute(p, this, "eightteen", "3");
+            $this->fail("18 shouldn't be equals to three");
+        } catch (BuildException be) {
+            $this->assertTrue(be.getException() instanceof AssertionFailedError);
+        }
+        ih.setAttribute(p, this, "nineteen", "19");
+        try {
+            ih.setAttribute(p, this, "nineteen", "3");
+            $this->fail("19 shouldn't be equals to three");
+        } catch (BuildException be) {
+            $this->assertTrue(be.getException() instanceof AssertionFailedError);
+        }
+    }
+
+    public void testGetAttributes() {
+        Hashtable h = new Hashtable();
+        h.put("seven", java.lang.String.class);
+        h.put("eight", java.lang.Integer.TYPE);
+        h.put("nine", java.lang.Integer.class);
+        h.put("ten", java.io.File.class);
+        h.put("eleven", java.lang.Boolean.TYPE);
+        h.put("twelve", java.lang.Boolean.class);
+        h.put("thirteen", java.lang.Class.class);
+        h.put("fourteen", java.lang.StringBuffer.class);
+        h.put("fifteen", java.lang.Character.TYPE);
+        h.put("sixteen", java.lang.Character.class);
+        h.put("seventeen", java.lang.Byte.TYPE);
+        h.put("eightteen", java.lang.Short.TYPE);
+        h.put("nineteen", java.lang.Double.TYPE);
+
+        h.put("name", java.lang.String.class);
+
+        IntrospectionHelper $ih = IntrospectionHelper::getHelper(get_class($this));
+        Enumeration enum = ih.getAttributes();
+        while (enum.hasMoreElements()) {
+            String name = (String) enum.nextElement();
+            Class expect = (Class) h.get(name);
+            assertNotNull("Support for "+name+" in IntrospectionHelperTest?",
+                          expect);
+            $this->assertEquals("Type of "+name, expect, ih.getAttributeType(name));
+            h.remove(name);
+        }
+        h.remove("name");
+        $this->assertTrue("Found all", h.isEmpty());
+    }
+
+    public function setTwo($s) {
+        return 0;
+    }
+
+    public void setThree() {}
+
+    public void setFour(String s1, String s2) {}
+
+    public void setFive(String[] s) {}
+
+    public void setSix(Project p) {}
+
+    public void setSeven(String s) {
+        $this->assertEquals("2", s);
+    }
+
+    public void setEight(int i) {
+        $this->assertEquals(2, i);
+    }
+
+    public void setNine(Integer i) {
+        $this->assertEquals(2, i.intValue());
+    }
+
+    public void setTen(File f) {
+        if (Os.isFamily("unix")) { 
+            $this->assertEquals(projectBasedir+"2", f.getAbsolutePath());
+        } else if (Os.isFamily("netware")) {
+            $this->assertEquals(projectBasedir+"2", f.getAbsolutePath().toLowerCase(Locale.US));
+        } else {
+            $this->assertEquals(":"+projectBasedir+"2", f.getAbsolutePath().toLowerCase(Locale.US).substring(1));
+        }
+    }
+
+    public void setEleven(boolean b) {
+        $this->assertTrue(!b);
+    }
+
+    public void setTwelve(Boolean b) {
+        $this->assertTrue(!b.booleanValue());
+    }
+
+    public void setThirteen(Class c) {
+        $this->assertEquals(Project.class, c);
+    }
+
+    public void setFourteen(StringBuffer sb) {
+        $this->assertEquals("2", sb.toString());
+    }
+
+    public void setFifteen(char c) {
+        $this->assertEquals(c, 'a');
+    }
+
+    public void setSixteen(Character c) {
+        $this->assertEquals(c.charValue(), 'a');
+    }
+
+    public void setSeventeen(byte b) {
+        $this->assertEquals(17, b);
+    }
+
+    public void setEightteen(short s) {
+        $this->assertEquals(18, s);
+    }
+
+    public void setNineteen(double d) {
+        $this->assertEquals(19, d, 1e-6);
+    }
+    */
+}// IntrospectionHelperTest
+
+// These are sample project components
+
+class IHProjectComponent {
+
+    public function addText($text) {        
+    }
+    
+    public function createOne() {
+        return "test";
+    }    
+}
+
+
+// These classes force failure
+// 
+
+class IHCreatorFail1 {
+    /**
+     * cannot take param!
+     */
+    function createBlah($param) {    
+    }
+}
+
+class IHCreatorFail2 {
+
+    /**
+     * no class hint!
+     */
+    function addBlah($blah) {
+    }
+}
+
+class IHCreatorFail3 {
+
+    /**
+     * no class hint!
+     */
+    function addConfiguredBlah($blah) {
+    }    
+}
+
+
+class IHFail4 {
+
+    /**
+     * 2 params!
+     */
+    function setBlah($blah, $blah2) {
+    }
+}
+
+class IHFail5 {
+
+    /**
+     * no params!
+     */
+    function setBlah() {
+    }
+    
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/test/classes/phing/filters/LineContainsTest.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/test/classes/phing/filters/LineContainsTest.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/test/classes/phing/filters/LineContainsTest.php	(revision 19)
@@ -0,0 +1,50 @@
+<?php
+
+/*
+ *  $Id: LineContainsTest.php 123 2006-09-14 20:19:08Z mrook $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+require_once 'phing/BuildFileTest.php'; 
+include_once 'phing/util/FileUtils.php';
+
+/**
+ * @author <a href="mailto:stefan.bodewig@epost.de">Stefan Bodewig</a>
+ */
+class LineContainsTest extends BuildFileTest {
+    
+    protected $fu;
+    
+    public function setUp() { 
+        $this->configureProject(PHING_TEST_BASE . "/etc/filters/linecontains.xml");
+        $this->fu = new FileUtils();
+    }
+    
+    public function tearDown() { 
+        $this->executeTarget("cleanup");
+    }
+    
+    public function testLineContains() { 
+        $this->executeTarget("testLineContains");
+        
+        $expected = $this->getProject()->resolveFile("expected/linecontains.test");
+        $result = $this->getProject()->resolveFile("result/linecontains.test");
+        $this->assertTrue($this->fu->contentEquals($expected, $result), "Files don't match!");
+    }
+    
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/test/classes/phing/system/FileOutputStreamTest.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/test/classes/phing/system/FileOutputStreamTest.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/test/classes/phing/system/FileOutputStreamTest.php	(revision 19)
@@ -0,0 +1,93 @@
+<?php
+
+/*
+ *  $Id: CommandlineTest.php 123 2006-09-14 20:19:08Z mrook $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+
+require_once 'PHPUnit2/Framework/TestCase.php';
+include_once 'phing/system/io/FileOutputStream.php';
+
+/**
+ * Unit test for FileOutputStream.
+ *
+ * @author Hans Lellelid <hans@xmpl.org>
+ * @package phing.system
+ */
+class FileOutputStreamTest extends PHPUnit2_Framework_TestCase {
+
+	/**
+	 * @var FileOutputStream
+	 */
+    private $outStream;
+    
+    public function setUp() {
+		$this->tmpFile = new PhingFile("tmp/" . get_class($this) . ".txt");
+        $this->outStream = new FileOutputStream($this->tmpFile);
+    }
+    
+    public function tearDown() {
+    	FileSystem::unlink($this->tmpFile->getAbsolutePath());
+    }
+    
+    public function assertFileContents($contents)
+    {
+    	$actual = file_get_contents($this->tmpFile->getAbsolutePath());
+    	$this->assertEquals($contents, $actual, "Expected file contents to match; expected '" . $contents . "', actual '" . $actual . "'");
+    }
+    
+    public function testWrite() {
+    	
+    	$string = "0123456789";
+    	$this->outStream->write($string);
+    	
+    	$this->assertFileContents($string);
+
+    	$newstring = $string;
+    	
+    	// check offset (no len)
+    	$this->outStream->write($string, 1);
+    	$this->outStream->flush();
+    	$newstring .= '123456789';
+    	$this->assertFileContents($newstring);
+    	
+    	// check len (no offset)
+    	$this->outStream->write($string, 0, 3);
+    	$this->outStream->flush();
+    	$newstring .= '012';
+    	$this->assertFileContents($newstring);
+
+    	
+    }
+    
+    public function testFlush() {
+    
+    	$this->outStream->write("Some data");
+		$this->outStream->flush();
+		$this->outStream->close();
+
+		try {
+			$this->outStream->flush();
+			$this->fail("Expected IOException when attempting to flush a closed stream.");
+		} catch (IOException $ioe) {
+			// exception is expected
+		}
+    }
+    
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/test/classes/phing/tasks/PropertyTaskTest.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/test/classes/phing/tasks/PropertyTaskTest.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/test/classes/phing/tasks/PropertyTaskTest.php	(revision 19)
@@ -0,0 +1,76 @@
+<?php
+
+/*
+ *  $Id: PropertyTaskTest.php 123 2006-09-14 20:19:08Z mrook $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+ 
+require_once 'phing/BuildFileTest.php';
+
+/**
+ * @author Hans Lellelid (Phing)
+ * @author Conor MacNeill (Ant)
+ */
+class PropertyTaskTest extends BuildFileTest { 
+        
+    public function setUp() { 
+        $this->configureProject(PHING_TEST_BASE . "/etc/tasks/property.xml");
+    }
+        
+
+    public function test1() { 
+        // should get no output at all
+        $this->expectOutputAndError("test1", "", "");
+    }
+
+    public function test2() { 
+        $this->expectLog("test2", "testprop1=aa, testprop3=xxyy, testprop4=aazz");
+    }
+    
+    public function test3() {        
+        try {
+            $this->executeTarget("test3");
+        } catch (BuildException $e) {
+            $this->assertTrue(strpos($e->getMessage(), "was circularly defined") !== false, "Circular definition not detected - ");
+            return;                     
+        }
+        $this->fail("Did not throw exception on circular exception");          
+    }
+    
+    
+    public function test4() { 
+        $this->expectLog("test4", "http.url is http://localhost:999");
+    }
+    
+    public function testPrefixSuccess() {
+        $this->executeTarget("prefix.success");
+        $this->assertEquals("80", $this->project->getProperty("server1.http.port"));
+    }
+    
+    
+    public function testPrefixFailure() {
+       try {
+            $this->executeTarget("prefix.fail");
+        } catch (BuildException $e) {
+            $this->assertTrue(strpos($e->getMessage(), "Prefix is only valid") !== false, "Prefix allowed on non-resource/file load - ");
+            return;                     
+        }
+        $this->fail("Did not throw exception on invalid use of prefix");
+    }
+    
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/test/classes/phing/tasks/TypedefTaskTest.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/test/classes/phing/tasks/TypedefTaskTest.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/test/classes/phing/tasks/TypedefTaskTest.php	(revision 19)
@@ -0,0 +1,67 @@
+<?php
+/*
+ *  $Id: TypedefTaskTest.php 227 2007-08-28 02:17:00Z hans $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+ 
+require_once 'phing/BuildFileTest.php';
+
+/**
+ * @author Hans Lellelid <hans@xmpl.org> (Phing)
+ * @author Stefan Bodewig <stefan.bodewig@epost.de> (Ant)
+ * @version $Revision: 1.5 $
+ */
+class TypedefTaskTest extends BuildFileTest { 
+        
+    public function setUp() { 
+        $this->configureProject(PHING_TEST_BASE . "/etc/tasks/typedef.xml");
+    }
+    
+    public function testEmpty() { 
+        $this->expectBuildException("empty", "required argument not specified");
+    }
+
+    public function testNoName() { 
+        $this->expectBuildException("noName", "required argument not specified");
+    }
+
+    public function testNoClassname() { 
+        $this->expectBuildException("noClassname", "required argument not specified");
+    }
+
+    public function testClassNotFound() { 
+        $this->expectBuildException("classNotFound", "classname specified doesn't exist");
+    }
+
+    public function testGlobal() {
+        $this->expectLog("testGlobal", "Adding reference: global -> TypedefTestType");
+        $refs = $this->project->getReferences();
+        $ref = $refs["global"];
+        $this->assertNotNull("ref is not null", $ref);
+        $this->assertEquals("TypedefTestType", get_class($ref));
+    }
+
+    public function testLocal() {
+        $this->expectLog("testLocal", "Adding reference: local -> TypedefTestType");
+        $refs = $this->project->getReferences();
+        $ref = $refs["local"];
+        $this->assertNotNull("ref is not null", $ref);
+        $this->assertEquals("TypedefTestType", get_class($ref));
+    }
+
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/test/classes/phing/tasks/condition/ContainsConditionTest.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/test/classes/phing/tasks/condition/ContainsConditionTest.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/test/classes/phing/tasks/condition/ContainsConditionTest.php	(revision 19)
@@ -0,0 +1,45 @@
+<?php
+
+/*
+ *  $Id: ContainsConditionTest.php 123 2006-09-14 20:19:08Z mrook $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+require_once 'PHPUnit2/Framework/TestCase.php';
+include_once 'phing/tasks/system/condition/ContainsCondition.php';
+
+/**
+ * Testcase for the &lt;contains&gt; condition.
+ *
+ * @author Hans Lellelid <hans@xmpl.org> (Phing)
+ * @author Stefan Bodewig <stefan.bodewig@epost.de> (Ant)
+ * @version $Revision: 1.3 $
+ */
+class ContainsConditionTest extends PHPUnit2_Framework_TestCase {
+
+    public function testCaseSensitive() {
+        $con = new ContainsCondition();
+        $con->setString("abc");
+        $con->setSubstring("A");
+        $this->assertTrue(!$con->evaluate());
+
+        $con->setCaseSensitive(false);
+        $this->assertTrue($con->evaluate());
+    }
+
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/test/classes/phing/tasks/condition/EqualsConditionTest.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/test/classes/phing/tasks/condition/EqualsConditionTest.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/test/classes/phing/tasks/condition/EqualsConditionTest.php	(revision 19)
@@ -0,0 +1,58 @@
+<?php
+
+/*
+ *  $Id: EqualsConditionTest.php 123 2006-09-14 20:19:08Z mrook $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+require_once 'PHPUnit2/Framework/TestCase.php';
+include_once 'phing/tasks/system/condition/EqualsCondition.php';
+
+/**
+ * Testcase for the &lt;equals&gt; condition.
+ * 
+ * @author Hans Lellelid <hans@xmpl.org> (Phing)
+ * @author Stefan Bodewig <stefan.bodewig@epost.de> (Ant)
+ * @version $Revision: 1.4 $
+ */
+class EqualsConditionTest extends PHPUnit2_Framework_TestCase {
+
+    public function testTrim() {
+        $eq = new EqualsCondition();
+        $eq->setArg1("a");
+        $eq->setArg2(" a");
+        $this->assertTrue(!$eq->evaluate());
+
+        $eq->setTrim(true);
+        $this->assertTrue($eq->evaluate());
+
+        $eq->setArg2("a\t");
+        $this->assertTrue($eq->evaluate());
+    }
+
+    public function testCaseSensitive() {
+        $eq = new EqualsCondition();
+        $eq->setArg1("a");
+        $eq->setArg2("A");
+        $this->assertTrue(!$eq->evaluate());
+
+        $eq->setCasesensitive(false);
+        $this->assertTrue($eq->evaluate());
+    }
+
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/test/classes/phing/types/AbstractFileSetTest.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/test/classes/phing/types/AbstractFileSetTest.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/test/classes/phing/types/AbstractFileSetTest.php	(revision 19)
@@ -0,0 +1,189 @@
+<?php
+
+/*
+ *  $Id: AbstractFileSetTest.php 123 2006-09-14 20:19:08Z mrook $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+ 
+require_once 'phing/BuildFileTest.php';
+require_once 'PHPUnit2/Framework/TestCase.php';
+include_once 'phing/types/FileSet.php';
+
+/**
+ * Unit tests for AbstractFileSet.
+ * 
+ * @author Hans Lellelid <hans@xmpl.org>
+ * @version $Revision: 1.3 $
+ * @package phing.types
+ */
+abstract class AbstractFileSetTest extends PHPUnit2_Framework_TestCase {
+
+    private $project;
+    
+    public function setUp() {
+        $this->project = new Project();
+        $this->project->setBasedir(PHING_TEST_BASE);
+    }
+
+    protected abstract function getInstance();
+
+    protected final function getProject() {
+        return $this->project;
+    }
+
+    public final function testEmptyElementIfIsReference() {
+        $f = $this->getInstance();
+        $f->setIncludes("**/*.php");
+        try {
+            $f->setRefid(new Reference("dummyref"));
+            $this->fail("Can add reference to "
+                 . $f->getDataTypeName()
+                 . " with elements from setIncludes");
+        } catch (BuildException $be) {
+            $this->assertEquals("You must not specify more than one attribute "
+                         . "when using refid", $be->getMessage());
+        }
+
+        $f = $this->getInstance();
+        $f->createPatternSet();
+        try {
+            $f->setRefid(new Reference("dummyref"));
+            $this->fail("Can add reference to "
+                 . $f->getDataTypeName()
+                 . " with nested patternset element.");
+        } catch (BuildException $be) {
+            $this->assertEquals("You must not specify nested elements when "
+                         . "using refid", $be->getMessage());
+        }
+
+        $f = $this->getInstance();
+        $f->createInclude();
+        try {
+            $f->setRefid(new Reference("dummyref"));
+            $this->fail("Can add reference to "
+                 . $f->getDataTypeName()
+                 . " with nested include element.");
+        } catch (BuildException $be) {
+            $this->assertEquals("You must not specify more than one attribute "
+                         . "when using refid", $be->getMessage());
+        }
+
+        $f = $this->getInstance();
+        $f->setRefid(new Reference("dummyref"));
+        try {
+            $f->setIncludes("**/*.java");
+            $this->fail("Can set includes in "
+                 . $f.getDataTypeName()
+                 . " that is a reference.");
+        } catch (BuildException $be) {
+            $this->assertEquals("You must not specify more than one attribute "
+                         . "when using refid", $be->getMessage());
+        }
+        
+        try {
+            $f->setIncludesfile(new PhingFile("/a"));
+            $this->fail("Can set includesfile in "
+                 . $f->getDataTypeName()
+                 . " that is a reference.");
+        } catch (BuildException $be) {
+            $this->assertEquals("You must not specify more than one attribute "
+                         . "when using refid", $be->getMessage());
+        }
+ 
+        try {
+            $f->setExcludes("**/*.java");
+            $this->fail("Can set excludes in "
+                 . $f->getDataTypeName()
+                 . " that is a reference.");
+        } catch (BuildException $be) {
+            $this->assertEquals("You must not specify more than one attribute "
+                         . "when using refid", $be->getMessage());
+        }
+ 
+        try {
+            $f->setExcludesfile(new PhingFile("/a"));
+            $this->fail("Can set excludesfile in "
+                 . $f->getDataTypeName()
+                 . " that is a reference.");
+        } catch (BuildException $be) {
+            $this->assertEquals("You must not specify more than one attribute "
+                         . "when using refid", $be->getMessage());
+        }
+ 
+        try {
+            $f->setDir($this->project->resolveFile("."));
+            $this->fail("Can set dir in "
+                 . $f->getDataTypeName()
+                 . " that is a reference.");
+        } catch (BuildException $be) {
+            $this->assertEquals("You must not specify more than one attribute "
+                         . "when using refid", $be->getMessage());
+        }
+ 
+        try {
+            $f->createInclude();
+            $this->fail("Can add nested include in "
+                 . $f->getDataTypeName()
+                 . " that is a reference.");
+        } catch (BuildException $be) {
+            $this->assertEquals("You must not specify nested elements when using "
+                         . "refid", $be->getMessage());
+        }
+        
+        try {
+            $f->createExclude();
+            $this->fail("Can add nested exclude in "
+                 . $f->getDataTypeName()
+                 . " that is a reference.");
+        } catch (BuildException $be) {
+            $this->assertEquals("You must not specify nested elements when using "
+                         . "refid", $be->getMessage());
+        }
+        
+        try {
+            $f->createIncludesFile();
+            $this->fail("Can add nested includesfile in "
+                 . $f->getDataTypeName()
+                 . " that is a reference.");
+        } catch (BuildException $be) {
+            $this->assertEquals("You must not specify nested elements when using "
+                         . "refid", $be->getMessage());
+        }
+        try {
+            $f->createExcludesFile();
+            $this->fail("Can add nested excludesfile in "
+                 . $f->getDataTypeName()
+                 . " that is a reference.");
+        } catch (BuildException $be) {
+            $this->assertEquals("You must not specify nested elements when using "
+                         . "refid", $be->getMessage());
+        }
+        try {
+            $f->createPatternSet();
+            $this->fail("Can add nested patternset in "
+                 . $f->getDataTypeName()
+                 . " that is a reference.");
+        } catch (BuildException $be) {
+            $this->assertEquals("You must not specify nested elements when using "
+                         . "refid", $be->getMessage());
+        }
+        
+    }   
+    
+    
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/test/classes/phing/types/CommandlineTest.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/test/classes/phing/types/CommandlineTest.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/test/classes/phing/types/CommandlineTest.php	(revision 19)
@@ -0,0 +1,80 @@
+<?php
+
+/*
+ *  $Id: CommandlineTest.php 123 2006-09-14 20:19:08Z mrook $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+
+require_once 'PHPUnit2/Framework/TestCase.php';
+include_once 'phing/types/Commandline.php';
+
+
+/**
+ * Unit test for mappers.
+ *
+ * @author Hans Lellelid <hans@xmpl.org>
+ * @author Stefan Bodewig <stefan.bodewig@epost.de> (Ant)
+ * @package propel.types
+ */
+class CommandlineTest extends PHPUnit2_Framework_TestCase {
+
+    private $cmd;
+    
+    //private $project;
+
+    public function setUp() {
+        $this->cmd = new Commandline();
+    }
+    
+    public function testTranslateCommandline() {
+                
+        $cmd2 = "cvs -d:pserver:hans@xmpl.org:/cvs commit -m\"added a new test file for 'fun'\" Test.php";
+        $cmd3 = "cvs -d:pserver:hans@xmpl.org:/cvs  commit   -m 'added a new test file for fun' Test.php";
+        
+        
+        // This should work fine; we expect 5 args
+        $cmd1 = "cvs -d:pserver:hans@xmpl.org:/cvs commit -m \"added a new test file\" Test.php";
+        $c = new Commandline($cmd1);
+        $this->assertEquals(5, count($c->getArguments()));
+        
+        // This has some extra space, but we expect same number of args        
+        $cmd2 = "cvs -d:pserver:hans@xmpl.org:/cvs   commit  -m \"added a new test file\"    Test.php";
+        $c2 = new Commandline($cmd2);
+        $this->assertEquals(5, count($c->getArguments()));
+                
+        // nested quotes should not be a problem either
+        $cmd3 = "cvs -d:pserver:hans@xmpl.org:/cvs   commit  -m \"added a new test file for 'fun'\"    Test.php";
+        $c3 = new Commandline($cmd3);
+        $this->assertEquals(5, count($c->getArguments()));
+        $args = $c3->getArguments();
+        $this->assertEquals("added a new test file for 'fun'", $args[3]);
+        
+        // now try unbalanced quotes -- this should fail
+        $cmd4 = "cvs -d:pserver:hans@xmpl.org:/cvs   commit  -m \"added a new test file for 'fun' Test.php";        
+        try {
+            $c4 = new Commandline($cmd4);
+            $this->fail("Should throw BuildException because 'unbalanced quotes'");
+        } catch (BuildException $be) {
+            if (false === strpos($be->getMessage(), "unbalanced quotes")) {
+                $this->fail("Should throw BuildException because 'unbalanced quotes'");
+            }
+        }
+    }
+    
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/test/classes/phing/types/FileSetTest.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/test/classes/phing/types/FileSetTest.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/test/classes/phing/types/FileSetTest.php	(revision 19)
@@ -0,0 +1,39 @@
+<?php
+
+/*
+ *  $Id: FileSetTest.php 123 2006-09-14 20:19:08Z mrook $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+ 
+require_once 'phing/types/AbstractFileSetTest.php';
+include_once 'phing/types/FileSet.php';
+
+/**
+ * Unit tests for FileSet -- including Selectors.
+ * 
+ * @author Hans Lellelid <hans@xmpl.org>
+ * @version $Revision: 1.1 $
+ * @package phing.types
+ */
+class FileSetTest extends AbstractFileSetTest {
+
+    protected function getInstance() {
+        return new FileSet();
+    }    
+    
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/test/classes/phing/types/MapperTest.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/test/classes/phing/types/MapperTest.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/test/classes/phing/types/MapperTest.php	(revision 19)
@@ -0,0 +1,160 @@
+<?php
+
+/*
+ *  $Id: MapperTest.php 123 2006-09-14 20:19:08Z mrook $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+require_once 'PHPUnit2/Framework/TestCase.php';
+include_once 'phing/BuildFileTest.php';
+include_once 'phing/types/Mapper.php';
+include_once 'phing/Project.php';
+include_once 'phing/types/Reference.php';
+
+/**
+ * Unit test for mappers.
+ *
+ * @author Hans Lellelid <hans@xmpl.org>
+ * @author Stefan Bodewig <stefan.bodewig@epost.de> (Ant)
+ * @package phing.types
+ */
+class MapperTest extends PHPUnit2_Framework_TestCase {
+
+    private $project;
+
+    public function setUp() {
+        $this->project = new Project();                    
+        $this->project->setBasedir(dirname(__FILE__));
+    }
+
+    public function testEmptyElementIfIsReference() {
+        $m = new Mapper($this->project);
+        $m->setFrom("*.java");
+        try {
+            $m->setRefid(new Reference("dummyref"));
+            $this->fail("Can add reference to Mapper with from attribute set");
+        } catch (BuildException $be) {
+            $this->assertEquals("You must not specify more than one attribute when using refid", $be->getMessage());
+        }
+
+        $m = new Mapper($this->project);
+        $m->setRefid(new Reference("dummyref"));
+        try {
+            $m->setFrom("*.java");
+            $this->fail("Can set from in Mapper that is a reference.");
+        } catch (BuildException $be) {
+            $this->assertEquals("You must not specify more than one attribute when using refid", $be->getMessage());
+        }
+
+        $m = new Mapper($this->project);
+        $m->setRefid(new Reference("dummyref"));
+        try {
+            $m->setTo("*.java");
+            $this->fail("Can set to in Mapper that is a reference.");
+        } catch (BuildException $be) {
+            $this->assertEquals("You must not specify more than one attribute when using refid", $be->getMessage());
+        }
+        try {
+            $m = new Mapper($this->project);
+            $m->setRefid(new Reference("dummyref"));
+            $m->setType("glob");
+            $this->fail("Can set type in Mapper that is a reference.");
+        } catch (BuildException $be) {
+            $this->assertEquals("You must not specify more than one attribute when using refid", $be->getMessage());
+        }
+    }
+
+    public function testCircularReferenceCheck() {
+        $m = new Mapper($this->project);
+        $this->project->addReference("dummy", $m);
+        $m->setRefid(new Reference("dummy"));
+        try {
+            $m->getImplementation();
+            $this->fail("Can make Mapper a Reference to itself.");
+        } catch (BuildException $be) {
+            $this->assertEquals("This data type contains a circular reference.", $be->getMessage());
+        }
+
+        // dummy1 --> dummy2 --> dummy3 --> dummy1
+        $m1 = new Mapper($this->project);
+        $this->project->addReference("dummy1", $m1);
+        $m1->setRefid(new Reference("dummy2"));
+        $m2 = new Mapper($this->project);
+        $this->project->addReference("dummy2", $m2);
+        $m2->setRefid(new Reference("dummy3"));
+        $m3 = new Mapper($this->project);
+        $this->project->addReference("dummy3", $m3);
+        $m3->setRefid(new Reference("dummy1"));
+        try {
+            $m1->getImplementation();
+            $this->fail("Can make circular reference.");
+        } catch (BuildException $be) {
+            $this->assertEquals("This data type contains a circular reference.", $be->getMessage());
+        }
+
+        // dummy1 --> dummy2 --> dummy3 
+        // (which holds a glob mapper from "*.java" to "*.class"
+        $m1 = new Mapper($this->project);
+        $this->project->addReference("dummy1", $m1);
+        $m1->setRefid(new Reference("dummy2"));
+        $m2 = new Mapper($this->project);
+        $this->project->addReference("dummy2", $m2);
+        $m2->setRefid(new Reference("dummy3"));
+        $m3 = new Mapper($this->project);
+        $this->project->addReference("dummy3", $m3);
+        
+        $m3->setType("glob");
+        $m3->setFrom("*.java");
+        $m3->setTo("*.class");
+                
+        $fmm = $m1->getImplementation();
+        $this->assertTrue($fmm instanceof GlobMapper, "Should be instance of GlobMapper");
+        $result = $fmm->main("a.java");
+        $this->assertEquals(1, count($result));
+        $this->assertEquals("a.class", $result[0]);
+    }
+
+    public function testCopyTaskWithTwoFilesets() {
+        $t = new TaskdefForCopyTest("test1");
+        try {
+            $t->setUp();
+            $t->test1();
+            $t->tearDown();
+        } catch(Exception $e) {
+            $t->tearDown();
+            throw $e;
+        }        
+    }
+    
+}
+
+
+class TaskdefForCopyTest extends BuildFileTest {
+
+    public function setUp() {
+        $this->configureProject(PHING_TEST_BASE . "/etc/types/mapper.xml");
+    }
+
+    public function tearDown() {
+        $this->executeTarget("cleanup");
+    }
+
+    public function test1() { 
+        $this->executeTarget("test1");
+    }
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/test/etc/filters/expected/linecontains.test
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/test/etc/filters/expected/linecontains.test	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/test/etc/filters/expected/linecontains.test	(revision 19)
@@ -0,0 +1,1 @@
+This is line 2 with beta.
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/test/etc/filters/gettext.xml
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/test/etc/filters/gettext.xml	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/test/etc/filters/gettext.xml	(revision 19)
@@ -0,0 +1,26 @@
+<?xml version="1.0"?>
+<project default="cleanup" basedir=".">
+
+ <target name="init">
+    <mkdir dir="result" />
+  </target>
+
+  <target name="cleanup">
+    <delete dir="result" />
+  </target>
+  
+  <target name="testTranslate" depends="init">
+    <copy todir="result" overwrite="true">
+      <fileset dir="gettext">
+	  	<include name="*.php"/>
+	  </fileset>
+      <filterchain>
+        <filterreader classname="phing.filters.TranslateGettext">
+          <param type="locale" value="fr_FR"/>
+		  <param type="dir" value="gettext/"/>
+        </filterreader>
+      </filterchain>
+    </copy>
+  </target>
+
+</project>
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/test/etc/filters/gettext/fr_FR.po
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/test/etc/filters/gettext/fr_FR.po	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/test/etc/filters/gettext/fr_FR.po	(revision 19)
@@ -0,0 +1,44 @@
+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
+# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
+#
+#, fuzzy
+msgid ""
+msgstr ""
+"Project-Id-Version: PACKAGE VERSION\n"
+"POT-Creation-Date: 2003-11-20 13:16-0500\n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
+"Language-Team: LANGUAGE <LL@li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=ISO-8859-1\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+#: sample.php:4
+msgid "Nag is not properly configured"
+msgstr "L'application Nag n'est pas configurée correctement"
+
+#: sample.php:39
+msgid "Some of Nag's configuration files are missing:"
+msgstr "Certains fichiers de configuration de Nag manquent :"
+
+#: sample.php:44
+msgid ""
+"This is the main Nag configuration file. It contains options for all Nag "
+"scripts."
+msgstr "Le fichier de configuration principal de Nag. Il contient des options "
+"applicables à tous les scripts de Nag."
+
+#: sample.php:51
+msgid "This file contains preferences for Nag."
+msgstr "Ce fichier contient des préférences pour Nag."
+
+#: sample.php:58
+msgid ""
+"This file controls the stylesheet that is used to set colors and fonts in "
+"addition to or overriding Horde defaults."
+msgstr ""
+"Ce fichier définit la feuille de style utilisée pour ajouter des définitions "
+"de couleurs ou de polices de caractères aux définitions fournies par Horde, "
+"ou pour redéfinir certaines de celles-ci."
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/test/etc/filters/gettext/sample.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/test/etc/filters/gettext/sample.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/test/etc/filters/gettext/sample.php	(revision 19)
@@ -0,0 +1,64 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "DTD/xhtml1-transitional.dtd">
+<html>
+<head>
+<title><?php echo _("Nag is not properly configured") ?></title>
+<style type="text/css">
+<!--
+body {
+        font-family: Geneva,Arial,Helvetica,sans-serif;
+        font-size: 9pt;
+        background-color: #222244;
+        color: black;
+}
+
+.smallheader {
+        color: #ccccee;
+        background-color: #444466;
+        font-family: Geneva,Arial,Helvetica,sans-serif;
+        font-size: 9pt;
+}
+
+.light {
+        color: white;
+        font-family: Geneva,Arial,Helvetica,sans-serif;
+        font-size: 9pt;
+}
+
+.header {
+        color: #ccccee;
+        background-color: #444466;
+        font-family: Verdana,Helvetica,sans-serif;
+        font-weight: bold;
+        font-size: 13pt;
+}
+-->
+</style>
+</head>
+<body>
+<table border="0" align="center" width="500" cellpadding="2" cellspacing="4">
+<tr><td colspan="2" class="header"><b><?php echo _("Some of Nag's configuration files are missing:") ?></b></td></tr>
+
+<?php if (!@is_readable('./config/conf.php')): ?>
+<tr>
+  <td align="right" class="smallheader"><b>conf.php</b></td>
+  <td class="light"><?php echo _("This is the main Nag configuration file. It contains options for all Nag scripts.") ?></td>
+</tr>
+<?php endif; ?>
+
+<?php if (!@is_readable('./config/prefs.php')): ?>
+<tr>
+  <td align="right" class="smallheader"><b>prefs.php</b></td>
+  <td class="light"><?php echo _("This file contains preferences for Nag.") ?></td>
+</tr>
+<?php endif; ?>
+
+<?php if (!@is_readable('./config/html.php')): ?>
+<tr>
+  <td align="right" class="smallheader"><b>html.php</b></td>
+  <td class="light"><?php echo gettext("This file controls the stylesheet that is used to set colors and fonts in addition to or overriding Horde defaults.") ?></td>
+</tr>
+<?php endif; ?>
+
+</table>
+</body>
+</html>
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/test/etc/filters/input/linecontains.test
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/test/etc/filters/input/linecontains.test	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/test/etc/filters/input/linecontains.test	(revision 19)
@@ -0,0 +1,3 @@
+This is line 1 with alpha.
+This is line 2 with beta.
+This is line 3 with gamma.
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/test/etc/filters/linecontains.xml
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/test/etc/filters/linecontains.xml	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/test/etc/filters/linecontains.xml	(revision 19)
@@ -0,0 +1,23 @@
+<?xml version="1.0"?>
+<project default="cleanup" basedir=".">
+
+  <target name="init">
+    <mkdir dir="result" />
+  </target>
+
+  <target name="cleanup">
+    <delete dir="result" />
+  </target>
+
+  <target name="testLineContains" depends="init">
+    <copy todir="result">
+      <fileset dir="input"/>
+      <filterchain>
+        <filterreader classname="phing.filters.LineContains">
+          <param type="contains" value="beta"/>
+        </filterreader>
+      </filterchain>
+    </copy>
+  </target>
+
+</project>
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/test/etc/resources/sample.txt
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/test/etc/resources/sample.txt	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/test/etc/resources/sample.txt	(revision 19)
@@ -0,0 +1,10 @@
+Texas Funeral broke up
+
+After over 7 years together Texas Funeral (formerly Rapture) pulled the plug and unanimously broke up in peace.
+
+Despite all the little ups and downs we had during the past seven years it was always a joy and ultimate thrill for us playing and writing music together. Given the fact that nobody in the band could play an instrument when we first started in late 1997, we are very proud of what we achieved all those years of making music. But eventually every band runs its course and the time comes to break up before the music gets compromised. As positive thinking beings we realize that with each crisis there's another chance. All of us are going to continue with making and playing music giving it a fresh start in different bands or projects. So watch out.
+
+We thank all our loved ones, fans, friends, and people involved in, or somehow related to the band for their everlasting awesome support and love during the years. We hope we brought you some fun and pleasure listening to our music and having a good time at our concerts.
+
+Love, Peace, and Rock'n'Roll
+Markus, Short, Andi, George
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/test/etc/taskcontainer.xml
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/test/etc/taskcontainer.xml	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/test/etc/taskcontainer.xml	(revision 19)
@@ -0,0 +1,13 @@
+<project default="dont-run-this">
+  <target name="dont-run-this">
+    <fail>This build file is supposed to be run by a Unit test</fail>
+  </target>
+
+  <target name="testPropertyExpansion">
+    <sequential>
+      <property name="foo" value="it worked"/>
+      <echo message="As attribute: ${foo}"/>
+      <echo>As nested text: ${foo}</echo>
+    </sequential>
+  </target>
+</project>
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/test/etc/tasks/InputTask.xml
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/test/etc/tasks/InputTask.xml	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/test/etc/tasks/InputTask.xml	(revision 19)
@@ -0,0 +1,22 @@
+<?xml version="1.0"?>
+<project name="prompt_test" default="main" basedir=".">
+    <target
+        name="main"
+        description="==>test prompt">
+       
+    <property name="documentRoot" value="/usr/apache/htdocs/sample"/>
+   
+    <echo>HTML pages installing to: ${documentRoot}</echo>
+    <echo>PHP classes installing to: ${servletDirectory}</echo>
+   
+    <input propertyname="documentRoot">Enter value for web application document root</input> 
+
+    <input propertyname="servletDirectory"
+       defaultValue="/usr/servlets" promptChar="?">Where should PHP classes install</input>
+	   
+	<echo>HTML pages installed to ${documentRoot}</echo>
+	<echo>PHP classes installed to ${servletDirectory}</echo>
+
+    </target>
+
+</project>
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/test/etc/tasks/adhoc.xml
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/test/etc/tasks/adhoc.xml	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/test/etc/tasks/adhoc.xml	(revision 19)
@@ -0,0 +1,27 @@
+<?xml version="1.0"?>
+<project name="adhoc-test" default="main" basedir=".">
+	
+    <target
+        name="main"
+        description="==>test AdhocTask ">
+		
+		<adhoc-task name="foo"><![CDATA[
+
+			class FooTest extends Task {
+				private $bar;
+				
+				function setBar($bar) {
+					$this->bar = $bar;
+				}
+				
+				function main() {
+					$this->log("In FooTest: " . $this->bar);
+				}
+			}
+
+		]]></adhoc-task>
+	
+		<foo bar="B.L.I.N.G"/>
+	</target>
+
+</project>
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/test/etc/tasks/cvs.xml
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/test/etc/tasks/cvs.xml	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/test/etc/tasks/cvs.xml	(revision 19)
@@ -0,0 +1,16 @@
+<?xml version="1.0"?>
+<project name="cvs_test" default="main" basedir=".">
+
+    <target
+        name="main"
+        description="==>test Cvs and CvsPass ">
+		
+		<!-- create a password file -->
+		<cvspass cvsRoot=":pserver:guest@cvs.tigris.org:/cvs" passfile="cvspass" password="guest"/>
+		
+		<!-- use the just-created password file -->
+		<cvs cvsRoot=":pserver:guest@cvs.tigris.org:/cvs" module="phing" passFile="cvspass" />
+	<delete dir="phing"/>		
+	</target>
+
+</project>
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/test/etc/tasks/pearpackage.xml
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/test/etc/tasks/pearpackage.xml	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/test/etc/tasks/pearpackage.xml	(revision 19)
@@ -0,0 +1,59 @@
+<?xml version="1.0"?>
+	
+<project name="pear-package-test" basedir="." default="main">
+
+	<taskdef name="pkg" classname="phing.tasks.ext.PearPackageTask"/>
+	
+	<target name="main">	
+	
+	<echo>-----------------------------</echo>
+	<echo>| Creating PEAR package.xml |</echo>
+	<echo>-----------------------------</echo>
+	<echo></echo>
+	<echo>This could take some time ...</echo>
+	
+	<pkg name="phing" dir="../../..">
+		
+		<fileset dir="../../..">
+			<exclude name="test/**"/>
+		</fileset>		
+		
+		<!-- Set the simple options -->
+		<option name="description">Test description.</option>
+		<option name="summary">Test summary.</option>
+		<option name="version" value="2.0.0b1"/>
+		<option name="state" value="beta"/>
+		
+		<mapping name="maintainers">
+			<element>
+				<element key="handle" value="hlellelid"/>
+				<element key="name" value="Hans"/>
+				<element key="email" value="hans@xmpl.org"/>
+				<element key="role" value="lead"/>
+			</element>
+			<element>
+				<element key="handle" value="jsmith"/>
+				<element key="name" value="John"/>
+				<element key="email" value="jsmith@xmpl.org"/>
+				<element key="role" value="developer"/>
+			</element>
+		</mapping>
+		
+		<!-- Set the complex options -->
+		<mapping name="installexceptions">
+			<element key="bin/phing.sh" value="/"/>
+			<element key="bin/phing.bat" value="/"/>
+		</mapping>		
+		<mapping name="dir_roles">
+			<element key="docs" value="doc"/>
+		</mapping>
+		<mapping name="exceptions">
+			<element key="INSTALL.UNIX" value="doc"/>
+			<element key="INSTALL.WINDOWS" value="doc"/>
+			<element key="CHANGELOG" value="doc"/>
+		</mapping>
+		
+	</pkg>
+	</target>
+
+</project>
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/test/etc/tasks/property.xml
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/test/etc/tasks/property.xml	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/test/etc/tasks/property.xml	(revision 19)
@@ -0,0 +1,33 @@
+<?xml version="1.0"?>
+
+<project name="property-test" basedir="." default="test1">
+
+  <target name="test1">
+    <property environment="testenv"/>
+  </target>
+
+  <target name="test2">
+    <property name="testprop1" value="aa"/>
+    <property file="property1.properties"/>
+    <echo message="testprop1=${testprop1}, testprop3=${testprop3}, testprop4=${testprop4}"/>
+  </target>
+
+  <target name="test3">
+    <property file="property2.properties"/>
+  </target>
+
+  <target name="test4">
+    <property name="http.port" value="999" />
+    <property file="property3.properties"/>
+    <echo message="http.url is ${http.url}"/>
+  </target>
+  
+  <target name="prefix.success">
+    <property file="property3.properties" prefix="server1"/>
+  </target>
+
+  <target name="prefix.fail">
+    <property name="someprop" value="value" prefix="prefix"/>
+  </target>
+
+</project>
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/test/etc/tasks/property1.properties
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/test/etc/tasks/property1.properties	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/test/etc/tasks/property1.properties	(revision 19)
@@ -0,0 +1,3 @@
+testprop2=xx
+testprop3=${testprop2}yy
+testprop4=${testprop1}zz
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/test/etc/tasks/property2.properties
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/test/etc/tasks/property2.properties	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/test/etc/tasks/property2.properties	(revision 19)
@@ -0,0 +1,3 @@
+testprop1=aa${testprop2}bb
+testprop2=cc${testprop1}dd
+
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/test/etc/tasks/property3.properties
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/test/etc/tasks/property3.properties	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/test/etc/tasks/property3.properties	(revision 19)
@@ -0,0 +1,4 @@
+http.port = 80
+http.url = http://localhost:${http.port}
+
+
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/test/etc/tasks/propertyprompt.xml
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/test/etc/tasks/propertyprompt.xml	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/test/etc/tasks/propertyprompt.xml	(revision 19)
@@ -0,0 +1,23 @@
+<?xml version="1.0"?>
+<project name="prompt_test" default="main" basedir=".">
+
+	<target
+		name="main"
+		description="==>test PropertyPromptTask">
+		
+	<property name="documentRoot" value="/usr/apache/htdocs/sample"/>
+	
+	<echo>HTML/JSP pages installing to: ${documentRoot}</echo>
+	<echo>Servlet code installing to: ${servletDirectory}</echo>
+	
+	<propertyprompt propertyname="documentRoot" 
+       promptcharacter=":">Enter value for web application document root</propertyprompt>		     
+	   		
+	<propertyprompt propertyname="servletDirectory" 
+       defaultvalue="/usr/servlets">Where should servlet classes install</propertyprompt>
+	<echo>HTML/JSP pages installed to ${documentRoot}</echo>
+	<echo>Servlet pages installed to ${servletDirectory}</echo>
+	
+	</target>
+
+</project>
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/test/etc/tasks/sql.xml
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/test/etc/tasks/sql.xml	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/test/etc/tasks/sql.xml	(revision 19)
@@ -0,0 +1,22 @@
+<?xml version="1.0"?>
+
+<!-- This is a test script for the SQLExec task.  You will
+	want to modify this for your DB information; the alternative
+	would be to add many INPUT tasks, but I prefer to keep it simple
+	for now. -->
+	
+<project name="sql-test" basedir="." default="main">
+
+	<target name="main">	
+		<sql 	  
+		 url="mysql://localhost/bookstore"
+		 userid="root" 
+		 password="" 
+		 print="true">
+			INSERT INTO author (first_name, last_name) VALUES ('Edward', 'White');
+			SELECT * FROM author;
+			DELETE FROM author WHERE first_name = 'Edward' AND last_name = 'White';
+		</sql>  
+	</target>
+
+</project>
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/test/etc/tasks/typedef.xml
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/test/etc/tasks/typedef.xml	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/test/etc/tasks/typedef.xml	(revision 19)
@@ -0,0 +1,44 @@
+<?xml version="1.0"?>
+
+<project name="test" basedir="." default="invalid">
+
+  <target name="invalid">
+    <fail>This file should only be run via a testcase</fail>
+  </target>
+
+  <target name="empty">
+    <typedef />
+  </target>
+
+  <target name="noClassname">
+    <typedef name="dummy" />
+  </target>
+
+  <target name="noName">
+    <typedef classname="example.types.TypedefTestType"/>
+  </target>
+
+  <target name="classNotFound">
+    <typedef name="" classname="oops"/>
+  </target>
+
+  <path id="testclasses">
+    <pathelement dir="../../classes" />
+  </path>
+
+  <typedef name="global" classname="example.types.TypedefTestType">
+    <classpath refid="testclasses" />
+  </typedef>
+
+  <target name="testGlobal">
+    <global id="global" />
+  </target>
+
+  <target name="testLocal">
+    <typedef name="local" classname="example.types.TypedefTestType">
+      <classpath refid="testclasses" />
+    </typedef>
+    <local id="local" />
+  </target>
+
+</project>
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/test/etc/tokensources/build.xml
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/test/etc/tokensources/build.xml	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/test/etc/tokensources/build.xml	(revision 19)
@@ -0,0 +1,45 @@
+<?xml version="1.0" ?>
+
+<project name="tests.tokensource" basedir="." default="main">
+
+    <target name="main" >
+        <echo msg="Testing" />
+
+        <!-- Test calling ReplaceTokens normally -->
+        <copy todir=".">
+            <fileset dir=".">
+                <include name="test.txt" />
+            </fileset>
+            
+            <mapper type="glob" from="*.txt" to="*.new1.txt" />
+
+            <filterchain>
+                <replacetokens>
+                    <tokensource classname="phing.filters.util.IniFileTokenReader">
+                        <param name="file" value="tokens.ini" />
+                    </tokensource>
+                </replacetokens>
+            </filterchain>
+        </copy>
+        <!-- Test calling ReplaceTokens with FilterReader -->
+        <copy todir=".">
+            <fileset dir=".">
+                <include name="test.txt" />
+            </fileset>
+            
+            <mapper type="glob" from="*.txt" to="*.new2.txt" />
+
+            <filterchain>
+                <filterreader classname="phing.filters.ReplaceTokens">
+                    <param type="tokensource">
+                        <!-- Used by TokenSource -->
+                        <param name="classname" value="phing.filters.util.IniFileTokenReader" />
+                        <!-- Given to the TokenReader -->
+                        <param name="file" value="tokens.ini" />
+                    </param>
+                </filterreader>
+            </filterchain>
+
+        </copy>
+    </target>
+</project>
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/test/etc/tokensources/test.txt
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/test/etc/tokensources/test.txt	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/test/etc/tokensources/test.txt	(revision 19)
@@ -0,0 +1,5 @@
+@DARL@
+
+@Hello@
+
+@DARL2@
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/test/etc/tokensources/tokens.ini
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/test/etc/tokensources/tokens.ini	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/test/etc/tokensources/tokens.ini	(revision 19)
@@ -0,0 +1,6 @@
+[en]
+DARL=darl
+Hello=Hi
+
+[de]
+DARL2=dahorl
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/test/etc/types/fileset.xml
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/test/etc/types/fileset.xml	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/test/etc/types/fileset.xml	(revision 19)
@@ -0,0 +1,48 @@
+<?xml version="1.0"?>
+
+<project name="fileset-test" basedir="." default="main">
+
+  <target name="main">
+  	<phingcall target="setup"/>
+	<phingcall target="test"/>
+	<phingcall target="cleanup"/>
+  </target>
+  
+  <!-- perform initialization, e.g. touch files to make them newer, etc. -->
+  <target name="setup">  
+  	<mkdir dir="copytest" />
+  </target>
+  
+  <selector id="myfiles">
+  	<and>
+		<filename name="**"/>
+		<present targetdir="C:\sandbox\phing" present="srconly"/>
+	</and>
+  </selector>
+  
+  <target name="test">
+  	
+	<copy todir="C:\sandbox\phing\build">
+		<fileset dir="C:\sandbox\phing">
+			<include name="**/*.properties"/>
+			<exclude name="build/**"/>
+		</fileset>
+		<mapper type="glob" from="*.properties" to="*.props"/>
+	</copy>
+	
+	<copy todir="copytest" verbose="true">
+		<fileset dir="C:\sandbox\phing\build">
+			<and>
+				<filename name="**"/>
+				<present targetdir="C:\sandbox\phing" present="srconly"/>
+			</and>
+		</fileset>
+	</copy>
+  
+  </target>
+  
+  <target name="cleanup">
+  	<delete dir="copytest"/>
+  </target>
+
+</project>
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/test/etc/types/fileset/a.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/test/etc/types/fileset/a.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/test/etc/types/fileset/a.php	(revision 19)
@@ -0,0 +1,1 @@
+<?php echo "This file contains something." ?>
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/test/etc/types/fileset/b.phps
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/test/etc/types/fileset/b.phps	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/test/etc/types/fileset/b.phps	(revision 19)
@@ -0,0 +1,1 @@
+<?php echo "something this also contains" ?>
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/test/etc/types/fileset/e.txt
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/test/etc/types/fileset/e.txt	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/test/etc/types/fileset/e.txt	(revision 19)
@@ -0,0 +1,1 @@
+This file contains something.
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/test/etc/types/mapper.xml
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/test/etc/types/mapper.xml	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/test/etc/types/mapper.xml	(revision 19)
@@ -0,0 +1,22 @@
+<?xml version="1.0"?>
+
+<project name="copy-test" basedir="." default="test1">
+
+  <target name="test1">
+    <mkdir dir="copytest" />
+    <copy todir="copytest">
+      <fileset dir="../../../classes">
+        <include name="**/tasks/system/*.php" />
+      </fileset>
+      <fileset dir="../../classes">
+        <include name="**/tasks/*.php" />
+      </fileset>
+      <mapper type="flatten" />
+    </copy>
+  </target>
+
+  <target name="cleanup">
+    <delete dir="copytest" />
+  </target>
+
+</project>
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/test/etc/xsl/coverage-frames.xsl
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/test/etc/xsl/coverage-frames.xsl	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/test/etc/xsl/coverage-frames.xsl	(revision 19)
@@ -0,0 +1,636 @@
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"
+    xmlns:exsl="http://exslt.org/common"
+    xmlns:date="http://exslt.org/dates-and-times"
+    extension-element-prefixes="exsl date">
+<xsl:output method="html" indent="yes"/>
+<xsl:decimal-format decimal-separator="." grouping-separator="," />
+<!--
+    Copyright  2001-2004 The Apache Software Foundation
+   
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+   
+         http://www.apache.org/licenses/LICENSE-2.0
+   
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+   
+-->
+
+<!--
+
+ Sample stylesheet to be used with Xdebug/Phing code coverage output.
+ Based on JProbe stylesheets from Apache Ant.
+
+ It creates a set of HTML files a la javadoc where you can browse easily
+ through all packages and classes.
+
+ @author Michiel Rook <a href="mailto:michiel@trendserver.nl"/>
+ @author Stephane Bailliez <a href="mailto:sbailliez@apache.org"/>
+
+-->
+
+<!-- default output directory is current directory -->
+<xsl:param name="output.dir" select="'.'"/>
+
+<!-- ======================================================================
+    Root element
+    ======================================================================= -->
+<xsl:template match="/snapshot">
+    <!-- create the index.html -->
+    <exsl:document href="efile://{$output.dir}/index.html">
+        <xsl:call-template name="index.html"/>
+    </exsl:document>
+
+    <!-- create the stylesheet.css -->
+    <exsl:document href="efile://{$output.dir}/stylesheet.css">
+        <xsl:call-template name="stylesheet.css"/>
+    </exsl:document>
+
+    <!-- create the overview-packages.html at the root -->
+    <exsl:document href="efile://{$output.dir}/overview-summary.html">
+        <xsl:apply-templates select="." mode="overview.packages"/>
+    </exsl:document>
+
+    <!-- create the all-packages.html at the root -->
+    <exsl:document href="efile://{$output.dir}/overview-frame.html">
+        <xsl:apply-templates select="." mode="all.packages"/>
+    </exsl:document>
+
+    <!-- create the all-classes.html at the root -->
+    <exsl:document href="efile://{$output.dir}/allclasses-frame.html">
+        <xsl:apply-templates select="." mode="all.classes"/>
+    </exsl:document>
+
+    <!-- process all packages -->
+    <xsl:apply-templates select="./package" mode="write"/>
+</xsl:template>
+
+<!-- =======================================================================
+    Frameset definition. Entry point for the report.
+    3 frames: packageListFrame, classListFrame, classFrame
+    ======================================================================= -->
+<xsl:template name="index.html">
+<html>
+    <head><title>Coverage Results.</title></head>
+    <frameset cols="20%,80%">
+        <frameset rows="30%,70%">
+            <frame src="overview-frame.html" name="packageListFrame"/>
+            <frame src="allclasses-frame.html" name="classListFrame"/>
+        </frameset>
+        <frame src="overview-summary.html" name="classFrame"/>
+    </frameset>
+    <noframes>
+        <h2>Frame Alert</h2>
+        <p>
+        This document is designed to be viewed using the frames feature. If you see this message, you are using a non-frame-capable web client.
+        </p>
+    </noframes>
+</html>
+</xsl:template>
+
+<!-- =======================================================================
+    Stylesheet CSS used
+    ======================================================================= -->
+<!-- this is the stylesheet css to use for nearly everything -->
+<xsl:template name="stylesheet.css">
+    .bannercell {
+      border: 0px;
+      padding: 0px;
+    }
+    body {
+      margin-left: 10;
+      margin-right: 10;
+      background-color:#FFFFFF;
+      font-family: verdana,arial,sanserif;
+      color:#000000;
+    }
+    a {
+      color: #003399;
+    }
+    a:hover {
+      color: #888888;
+    }
+    .a td {
+      background: #efefef;
+    }
+    .b td {
+      background: #fff;
+    }
+    th, td {
+      text-align: left;
+      vertical-align: top;
+    }
+    th {
+      font-weight:bold;
+      background: #ccc;
+      color: black;
+    }
+    table, th, td {
+      font-size: 12px;
+      border: none
+    }
+    table.log tr td, tr th {
+    }
+    h2 {
+      font-weight:bold;
+      font-size: 12px;
+      margin-bottom: 5;
+    }
+    h3 {
+      font-size:100%;
+      font-weight: 12px;
+       background: #DFDFDF
+      color: white;
+      text-decoration: none;
+      padding: 5px;
+      margin-right: 2px;
+      margin-left: 2px;
+      margin-bottom: 0;
+    }
+    .small {
+       font-size: 9px;
+    }
+TD.empty {
+    FONT-SIZE: 2px; BACKGROUND: #c0c0c0; BORDER:#9c9c9c 1px solid;
+    color: #c0c0c0;
+}
+TD.fullcover {
+    FONT-SIZE: 2px; BACKGROUND: #00df00; BORDER:#9c9c9c 1px solid;
+    color: #00df00;
+}
+TD.covered {
+    FONT-SIZE: 2px; BACKGROUND: #00df00; BORDER-LEFT:#9c9c9c 1px solid;BORDER-TOP:#9c9c9c 1px solid;BORDER-BOTTOM:#9c9c9c 1px solid;
+    color: #00df00;
+}
+TD.uncovered {
+    FONT-SIZE: 2px; BACKGROUND: #df0000; BORDER:#9c9c9c 1px solid;
+    color: #df0000;
+}
+PRE.srcLine {
+  BACKGROUND: #ffffff; MARGIN-TOP: 0px; MARGIN-BOTTOM: 0px; 
+}
+td.lineCount, td.coverageCount {
+      BACKGROUND: #F0F0F0; PADDING-RIGHT: 3px;
+      text-align: right;
+}
+td.lineCountHighlight {
+      background: #C8C8F0; PADDING-RIGHT: 3px;
+      text-align: right;
+}
+td.coverageCountHighlight {
+      background: #F0C8C8; PADDING-RIGHT: 3px;
+      text-align: right;
+}
+span.srcLineHighlight {
+      background: #F0C8C8;
+}
+span.srcLine {
+      background: #C8C8F0;
+}
+TD.srcLineClassStart {
+   WIDTH: 100%; BORDER-TOP:#dcdcdc 1px solid; FONT-WEIGHT: bold;    
+}
+.srcLine , .srcLine ol, .srcLine ol li {margin: 0;}
+.srcLine .de1, .srcLine .de2 {font-family: 'Courier New', Courier, monospace; font-weight: normal;}
+.srcLine .imp {font-weight: bold; color: red;}
+.srcLine .kw1 {color: #b1b100;}
+.srcLine .kw2 {color: #000000; font-weight: bold;}
+.srcLine .kw3 {color: #000066;}
+.srcLine .co1 {color: #808080; font-style: italic;}
+.srcLine .co2 {color: #808080; font-style: italic;}
+.srcLine .coMULTI {color: #808080; font-style: italic;}
+.srcLine .es0 {color: #000099; font-weight: bold;}
+.srcLine .br0 {color: #66cc66;}
+.srcLine .st0 {color: #ff0000;}
+.srcLine .nu0 {color: #cc66cc;}
+.srcLine .me1 {color: #006600;}
+.srcLine .me2 {color: #006600;}
+.srcLine .re0 {color: #0000ff;}
+</xsl:template>
+
+<!-- =======================================================================
+    List of all classes in all packages
+    This will be the first page in the classListFrame
+    ======================================================================= -->
+<xsl:template match="snapshot" mode="all.classes">
+    <html>
+        <head>
+            <xsl:call-template name="create.stylesheet.link"/>
+        </head>
+        <body>
+            <h2>All Classes</h2>
+            <table width="100%">
+                <xsl:for-each select="package/class">
+                    <xsl:sort select="@name"/>
+                    <xsl:variable name="package.name" select="(ancestor::package)[last()]/@name"/>
+                    <xsl:variable name="link">
+                        <xsl:if test="not($package.name='')">
+                            <xsl:value-of select="translate($package.name,'.','/')"/><xsl:text>/</xsl:text>
+                        </xsl:if><xsl:value-of select="@name"/><xsl:text>.html</xsl:text>
+                    </xsl:variable>
+                    <tr>
+                        <td nowrap="nowrap">
+                            <a target="classFrame" href="{$link}"><xsl:value-of select="@name"/></a>
+                            <xsl:choose>
+								<xsl:when test="@methodcount=0">
+									<i> (-)</i>
+								</xsl:when>
+								<xsl:otherwise>
+									<i> (<xsl:value-of select="format-number(@methodscovered div @methodcount, '0.0%')"/>)</i>
+								</xsl:otherwise>
+							</xsl:choose>
+                        </td>
+                    </tr>
+                </xsl:for-each>
+            </table>
+        </body>
+    </html>
+</xsl:template>
+
+<!-- list of all packages -->
+<xsl:template match="snapshot" mode="all.packages">
+    <html>
+        <head>
+            <xsl:call-template name="create.stylesheet.link"/>
+        </head>
+        <body>
+            <h2><a href="overview-summary.html" target="classFrame">Overview</a></h2>
+            <h2>All Packages</h2>
+            <table width="100%">
+                <xsl:for-each select="package">
+                    <xsl:sort select="@name" order="ascending"/>
+                    <tr>
+                        <td nowrap="nowrap">
+                            <a href="{translate(@name,'.','/')}/package-summary.html" target="classFrame">
+                                <xsl:value-of select="@name"/>
+                            </a>
+                        </td>
+                    </tr>
+                </xsl:for-each>
+            </table>
+        </body>
+    </html>
+</xsl:template>
+
+<!-- overview of statistics in packages -->
+<xsl:template match="snapshot" mode="overview.packages">
+    <html>
+        <head>
+            <xsl:call-template name="create.stylesheet.link"/>
+        </head>
+        <body onload="open('allclasses-frame.html','classListFrame')">
+        <xsl:call-template name="pageHeader"/>
+        <table class="log" cellpadding="5" cellspacing="0" width="100%">
+            <tr class="a">
+                <td class="small">Packages: <xsl:value-of select="count(package)"/></td>
+                <td class="small">Classes: <xsl:value-of select="count(package/class)"/></td>
+                <td class="small">Methods: <xsl:value-of select="@methodcount"/></td>
+                <td class="small">LOC: <xsl:value-of select="count(package/class/sourcefile/sourceline)"/></td>
+            </tr>
+        </table>        
+        <br/>
+
+        <table class="log" cellpadding="5" cellspacing="0" width="100%">
+            <tr>
+                <th width="100%" nowrap="nowrap"></th>
+                <th width="350" colspan="2" nowrap="nowrap">Methods covered</th>
+            </tr>
+            <tr class="a">
+        <td>Total coverage</td>
+                <xsl:call-template name="stats.formatted"/>
+            </tr>
+            <tr>
+                <td colspan="3"><br/></td>
+            </tr>
+            <tr>
+                <th width="100%">Packages</th>
+                <th width="350" colspan="2" nowrap="nowrap">Methods covered</th>
+            </tr>
+            <!-- display packages and sort them via their coverage rate -->
+            <xsl:for-each select="package">
+                <xsl:sort data-type="number" select="@methodscovered div @methodcount"/>
+                <tr>
+                  <xsl:call-template name="alternate-row"/>
+                    <td><a href="{translate(@name,'.','/')}/package-summary.html"><xsl:value-of select="@name"/></a></td>
+                    <xsl:call-template name="stats.formatted"/>
+                </tr>
+            </xsl:for-each>
+        </table>
+        <xsl:call-template name="pageFooter"/>
+        </body>
+        </html>
+</xsl:template>
+
+<!--
+ detailed info for a package. It will output the list of classes
+, the summary page, and the info for each class
+-->
+<xsl:template match="package" mode="write">
+    <xsl:variable name="package.dir">
+        <xsl:if test="not(@name = '')"><xsl:value-of select="translate(@name,'.','/')"/></xsl:if>
+        <xsl:if test="@name = ''">.</xsl:if>
+    </xsl:variable>
+
+    <!-- create a classes-list.html in the package directory -->
+    <exsl:document href="efile://{$output.dir}/{$package.dir}/package-frame.html">
+        <xsl:apply-templates select="." mode="classes.list"/>
+    </exsl:document>
+
+    <!-- create a package-summary.html in the package directory -->
+    <exsl:document href="efile://{$output.dir}/{$package.dir}/package-summary.html">
+        <xsl:apply-templates select="." mode="package.summary"/>
+    </exsl:document>
+
+    <!-- for each class, creates a @name.html -->
+    <xsl:for-each select="class">
+        <exsl:document href="efile://{$output.dir}/{$package.dir}/{@name}.html">
+            <xsl:apply-templates select="." mode="class.details"/>
+        </exsl:document>
+    </xsl:for-each>
+</xsl:template>
+
+<!-- list of classes in a package -->
+<xsl:template match="package" mode="classes.list">
+    <html>
+        <HEAD>
+            <xsl:call-template name="create.stylesheet.link">
+                <xsl:with-param name="package.name" select="@name"/>
+            </xsl:call-template>
+        </HEAD>
+        <BODY>
+            <table width="100%">
+                <tr>
+                    <td nowrap="nowrap">
+                        <H2><a href="package-summary.html" target="classFrame"><xsl:value-of select="@name"/></a></H2>
+                    </td>
+                </tr>
+            </table>
+
+            <H2>Classes</H2>
+            <TABLE WIDTH="100%">
+                <xsl:for-each select="class">
+                    <xsl:sort select="@name"/>
+                    <tr>
+                        <td nowrap="nowrap">
+                            <a href="{@name}.html" target="classFrame"><xsl:value-of select="@name"/></a>
+                            <xsl:choose>
+								<xsl:when test="@methodcount=0">
+									<i> (-)</i>
+								</xsl:when>
+								<xsl:otherwise>
+                            		<i>(<xsl:value-of select="format-number(@methodscovered div @methodcount, '0.0%')"/>)</i>
+                            	</xsl:otherwise>
+                            </xsl:choose>
+                        </td>
+                    </tr>
+                </xsl:for-each>
+            </TABLE>
+        </BODY>
+    </html>
+</xsl:template>
+
+<!-- summary of a package -->
+<xsl:template match="package" mode="package.summary">
+    <HTML>
+        <HEAD>
+            <xsl:call-template name="create.stylesheet.link">
+                <xsl:with-param name="package.name" select="@name"/>
+            </xsl:call-template>
+        </HEAD>
+        <!-- when loading this package, it will open the classes into the frame -->
+        <BODY onload="open('package-frame.html','classListFrame')">
+            <xsl:call-template name="pageHeader"/>
+            <table class="log" cellpadding="5" cellspacing="0" width="100%">
+                <tr class="a">
+                    <td class="small">Classes: <xsl:value-of select="count(class)"/></td>
+                    <td class="small">Methods: <xsl:value-of select="@methodcount"/></td>
+                    <td class="small">LOC: <xsl:value-of select="count(class/sourcefile/sourceline)"/></td>
+                </tr>
+            </table>        
+            <br/>
+
+            <table class="log" cellpadding="5" cellspacing="0" width="100%">
+                <tr>
+                    <th width="100%">Package</th>
+                    <th width="350" colspan="2" nowrap="nowrap">Methods covered</th>
+                </tr>
+                <xsl:apply-templates select="." mode="stats"/>
+
+                <xsl:if test="count(class) &gt; 0">
+                    <tr>
+                        <td colspan="3"><br/></td>
+                    </tr>
+                    <tr>
+                        <th width="100%">Classes</th>
+                        <th width="350" colspan="2" nowrap="nowrap">Methods covered</th>
+                    </tr>
+                    <xsl:apply-templates select="class" mode="stats">
+                        <xsl:sort data-type="number" select="@methodscovered div @methodcount"/>
+                    </xsl:apply-templates>
+                </xsl:if>
+            </table>
+            <xsl:call-template name="pageFooter"/>
+        </BODY>
+    </HTML>
+</xsl:template>
+
+<!-- details of a class -->
+<xsl:template match="class" mode="class.details">
+    <xsl:variable name="package.name" select="(ancestor::package)[last()]/@name"/>
+    <HTML>
+        <HEAD>
+            <xsl:call-template name="create.stylesheet.link">
+                <xsl:with-param name="package.name" select="$package.name"/>
+            </xsl:call-template>
+        </HEAD>
+        <BODY>
+            <xsl:call-template name="pageHeader"/>
+            <table class="log" cellpadding="5" cellspacing="0" width="100%">
+                <tr class="a">
+                    <td class="small">Methods: <xsl:value-of select="@methodcount"/></td>
+                    <td class="small">LOC: <xsl:value-of select="count(sourcefile/sourceline)"/></td>
+                </tr>
+            </table>        
+            <br/>
+
+            <!-- class summary -->
+            <table class="log" cellpadding="5" cellspacing="0" width="100%">
+                <tr>
+                    <th width="100%">Source file</th>
+                    <th width="250" colspan="2" nowrap="nowrap">Methods covered</th>
+                </tr>
+                <tr>
+                    <xsl:call-template name="alternate-row"/>
+                    <td><xsl:value-of select="sourcefile/@name"/></td>
+                    <xsl:call-template name="stats.formatted"/>
+                </tr>
+            </table>
+            <table cellspacing="0" cellpadding="0" width="100%">
+                <xsl:apply-templates select="sourcefile/sourceline"/>
+            </table>
+            <br/>
+            <xsl:call-template name="pageFooter"/>
+        </BODY>
+    </HTML>
+
+</xsl:template>
+
+<!-- Page Header -->
+<xsl:template name="pageHeader">
+  <!-- jakarta logo -->
+  <table border="0" cellpadding="0" cellspacing="0" width="100%">
+  <tr>
+    <td class="bannercell" rowspan="2">
+      <a href="http://phing.info/">
+      <img src="http://phing.info/images/phing.gif" alt="http://phing.info/" align="left" border="0"/>
+      </a>
+    </td>
+        <td style="text-align:right"><h2>Source Code Coverage</h2></td>
+        </tr>
+        <tr>
+        <td style="text-align:right">Designed for use with <a href='http://pear.php.net/package/PHPUnit2'>PHPUnit2</a>, <a href='http://www.xdebug.org/'>Xdebug</a> and <a href='http://phing.info/'>Phing</a>.</td>
+        </tr>
+  </table>
+    <hr size="1"/>
+</xsl:template>
+
+<!-- Page Footer -->
+<xsl:template name="pageFooter">
+    <table width="100%">
+      <tr><td><hr noshade="yes" size="1"/></td></tr>
+      <tr><td class="small">Report generated at <xsl:value-of select="date:date-time()"/></td></tr>
+    </table>
+</xsl:template>
+
+<xsl:template match="package" mode="stats">
+    <tr>
+      <xsl:call-template name="alternate-row"/>
+        <td><xsl:value-of select="@name"/></td>
+        <xsl:call-template name="stats.formatted"/>
+    </tr>
+</xsl:template>
+
+<xsl:template match="class" mode="stats">
+    <tr>
+      <xsl:call-template name="alternate-row"/>
+        <td><a href="{@name}.html" target="classFrame"><xsl:value-of select="@name"/></a></td>
+        <xsl:call-template name="stats.formatted"/>
+    </tr>
+</xsl:template>
+
+<xsl:template name="stats.formatted">
+    <xsl:choose>
+        <xsl:when test="@methodcount=0">
+            <td>-</td>
+            <td>
+            <table cellspacing="0" cellpadding="0" border="0" width="100%" style="display: inline">
+                <tr>
+                    <td class="empty" width="200" height="12">&#160;</td>
+                </tr>
+            </table>
+            </td>
+        </xsl:when>
+        <xsl:otherwise>
+            <td>
+            <xsl:value-of select="format-number(@methodscovered div @methodcount,'0.0%')"/>
+            </td>
+            <td>
+            <xsl:variable name="leftwidth"><xsl:value-of select="format-number((@methodscovered * 200) div @methodcount,'0')"/></xsl:variable>
+            <xsl:variable name="rightwidth"><xsl:value-of select="format-number(200 - (@methodscovered * 200) div @methodcount,'0')"/></xsl:variable>
+            <table cellspacing="0" cellpadding="0" border="0" width="100%" style="display: inline">
+                <tr>
+                    <xsl:choose>
+                        <xsl:when test="$leftwidth=200">
+                            <td class="fullcover" width="200" height="12">&#160;</td>
+                        </xsl:when>
+                        <xsl:otherwise>
+                            <xsl:if test="not($leftwidth=0)">
+                                <td class="covered" width="{$leftwidth}" height="12">&#160;</td>
+                            </xsl:if>
+                            <xsl:if test="not($rightwidth=0)">
+                                <td class="uncovered" width="{$rightwidth}" height="12">&#160;</td>
+                            </xsl:if>
+                        </xsl:otherwise>
+                    </xsl:choose>
+                </tr>
+            </table>
+            </td>
+        </xsl:otherwise>
+    </xsl:choose>
+</xsl:template>
+
+<xsl:template match="sourceline">
+    <tr>
+        <xsl:if test="@coveredcount>0">
+            <td class="lineCountHighlight"><xsl:value-of select="position()"/></td>
+            <td class="lineCountHighlight"><xsl:value-of select="@coveredcount"/></td>
+        </xsl:if>
+        <xsl:if test="@coveredcount&lt;0">
+            <td class="lineCountHighlight"><xsl:value-of select="position()"/></td>
+            <td class="coverageCountHighlight">0</td>
+        </xsl:if>
+        <xsl:if test="@coveredcount=0">
+            <td class="lineCount"><xsl:value-of select="position()"/></td>
+            <td class="coverageCount"></td>
+        </xsl:if>
+        <td>
+        	<xsl:if test="@startclass=1">        	
+            	<xsl:attribute name="class">srcLineClassStart</xsl:attribute>
+            </xsl:if>
+            <xsl:if test="@coveredcount>0">
+                <span class="srcLine">
+                <pre class="srcLine"><xsl:value-of select="." disable-output-escaping="yes"/></pre>
+                </span>
+            </xsl:if>
+            <xsl:if test="@coveredcount&lt;0">
+                <span class="srcLineHighlight">
+                <pre class="srcLine"><xsl:value-of select="." disable-output-escaping="yes"/></pre>
+                </span>
+            </xsl:if>
+            <xsl:if test="@coveredcount=0">
+                <pre class="srcLine"><xsl:value-of select="." disable-output-escaping="yes"/></pre>
+            </xsl:if>
+        </td>
+    </tr>
+</xsl:template>
+
+<!--
+    transform string like a.b.c to ../../../
+    @param path the path to transform into a descending directory path
+-->
+<xsl:template name="path">
+    <xsl:param name="path"/>
+    <xsl:if test="contains($path,'.')">
+        <xsl:text>../</xsl:text>
+        <xsl:call-template name="path">
+            <xsl:with-param name="path"><xsl:value-of select="substring-after($path,'.')"/></xsl:with-param>
+        </xsl:call-template>
+    </xsl:if>
+    <xsl:if test="not(contains($path,'.')) and not($path = '')">
+        <xsl:text>../</xsl:text>
+    </xsl:if>
+</xsl:template>
+
+
+<!-- create the link to the stylesheet based on the package name -->
+<xsl:template name="create.stylesheet.link">
+    <xsl:param name="package.name"/>
+    <LINK REL ="stylesheet" TYPE="text/css" TITLE="Style"><xsl:attribute name="href"><xsl:if test="not($package.name = 'unnamed package')"><xsl:call-template name="path"><xsl:with-param name="path" select="$package.name"/></xsl:call-template></xsl:if>stylesheet.css</xsl:attribute></LINK>
+</xsl:template>
+
+<!-- alternated row style -->
+<xsl:template name="alternate-row">
+<xsl:attribute name="class">
+  <xsl:if test="position() mod 2 = 1">a</xsl:if>
+  <xsl:if test="position() mod 2 = 0">b</xsl:if>
+</xsl:attribute>
+</xsl:template>
+
+</xsl:stylesheet>
+
+
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/test/etc/xsl/log.xsl
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/test/etc/xsl/log.xsl	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/test/etc/xsl/log.xsl	(revision 19)
@@ -0,0 +1,216 @@
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
+<xsl:output method="html" indent="yes" encoding="US-ASCII"/>
+<!--
+    Copyright  2000-2004 The Apache Software Foundation
+   
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+   
+         http://www.apache.org/licenses/LICENSE-2.0
+   
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+   
+-->
+ 
+<!--
+
+  The purpose have this XSL is to provide a nice way to look at the output
+  from the Ant XmlLogger (ie: ant -listener org.apache.tools.ant.XmlLogger )
+  
+  @author <a href="mailto:michiel@trendserver.nl>Michiel Rook</a>
+  @author <a href="mailto:sbailliez@apache.org">Stephane Bailliez</a>
+  
+-->
+<xsl:decimal-format decimal-separator="." grouping-separator="," />
+
+<xsl:template match="/">
+<html>
+  <head>
+    <title>Phing Build Log</title>
+    <style type="text/css">
+    .bannercell {
+      border: 0px;
+      padding: 0px;
+    }
+    body {
+      margin: 0;
+      font:normal 100% arial,helvetica,sanserif;
+      background-color:#FFFFFF;
+      color:#000000;
+    }
+    table.status {
+      font:bold 80% arial,helvetica,sanserif;
+      background-color:#525D76;
+      color:#ffffff;
+    }
+    table.log tr td, tr th {
+      font-size: 80%;
+    }
+    .error {
+      color:red;
+    }
+    .warn {
+      color:brown;
+    }
+    .info {
+      color:gray;
+    }
+    .debug{
+      color:gray;
+    }
+    .failed {
+      font-size:80%;
+      background-color: red;
+      color:#FFFFFF;
+      font-weight: bold
+    }
+    .complete {
+      font-size:80%;
+      background-color: #525D76;
+      color:#FFFFFF;
+      font-weight: bold
+    }
+    .a td { 
+      background: #efefef;
+    }
+    .b td { 
+      background: #fff;
+    }
+    th, td {
+      text-align: left;
+      vertical-align: top;
+    }
+    th {
+      background: #ccc;
+      color: black;
+    }
+    table, th, td {
+      border: none
+    }
+    h3 {
+      font:bold 80% arial,helvetica,sanserif;
+      background: #525D76;
+      color: white;
+      text-decoration: none;
+      padding: 5px;
+      margin-right: 2px;
+      margin-left: 2px;
+      margin-bottom: 0;
+    }
+    a {
+      color: #003399;
+    }
+    a:hover {
+      color: #888888;
+    }
+    </style>
+  </head>
+  <body>
+    <!-- jakarta logo -->
+    <table border="0" cellpadding="0" cellspacing="0" width="100%">
+    <tr>
+      <td valign="top" class="bannercell">
+        <a href="http://phing.info/">
+        <img src="http://phing.info/images/phing.gif" alt="http://phing.info/" align="left" border="0"/>
+        </a>
+      </td>
+      <td style="text-align:right;vertical-align:bottom">
+        <a href="http://phing.info/">Phing</a>
+      </td>
+    </tr>
+    </table>
+      
+    <table border="0" width="100%">
+    <tr><td><hr noshade="yes" size="1"/></td></tr>
+    </table>
+
+    <xsl:apply-templates select="build"/>
+
+    <!-- FOOTER -->
+    <table width="100%">
+      <tr><td><hr noshade="yes" size="1"/></td></tr>
+      <tr><td>
+      <div align="center"><font color="#525D76" size="-1"><em>
+      <a href="http://phing.info/">Phing</a>
+      </em></font></div>
+      </td></tr>
+    </table>
+  </body>
+</html>
+</xsl:template>
+
+<xsl:template match="build">
+  <!-- build status -->
+  <table width="100%">
+    <xsl:attribute name="class">
+      <xsl:if test="@error">failed</xsl:if>
+      <xsl:if test="not(@error)">complete</xsl:if>
+    </xsl:attribute>
+    <tr>
+      <xsl:if test="@error">
+        <td nowrap="yes">Build Failed</td> 
+      </xsl:if>
+      <xsl:if test="not(@error)">
+        <td nowrap="yes">Build Complete</td>
+      </xsl:if>
+        <td style="text-align:right" nowrap="yes">Total Time: <xsl:value-of select="@time"/></td>
+    </tr>
+    <tr>
+      <td colspan="2">
+        <xsl:if test="@error">
+          <tt><xsl:value-of select="@error"/></tt><br/>
+          <i style="font-size:80%">See the <a href="#stacktrace" alt="Click for details">stacktrace</a>.</i>
+        </xsl:if>
+      </td>
+    </tr>
+  </table>
+  <table border="1" cellspacing="2" cellpadding="3" width="100%" style="font-size:80%">
+    <tr class="a"><td width="1">phing.file</td><td><xsl:value-of select="substring-after(//message[contains(text(),'phing.file')], '->')"/></td></tr>
+    <tr class="b"><td width="1">phing.version</td><td><xsl:value-of select="substring-after(//message[contains(text(),'phing.version')], '->')"/></td></tr>
+  </table>
+  <!-- build information -->
+  <h3>Build events</h3>
+  <table class="log" border="1" cellspacing="2" cellpadding="3" width="100%">
+  <tr>
+    <th nowrap="yes" align="left" width="1%">target</th>
+    <th nowrap="yes" align="left" width="1%">task</th>
+    <th nowrap="yes" align="left">message</th>
+  </tr>
+  <xsl:apply-templates select=".//message[@priority != 'debug']"/>
+  </table>
+  <p>
+  <!-- stacktrace -->
+  <xsl:if test="stacktrace">
+  <a name="stacktrace"/>
+  <h3>Error details</h3>
+  <table width="100%">
+    <tr><td>
+      <pre><xsl:value-of select="stacktrace"/></pre>
+    </td></tr>
+  </table>
+  </xsl:if>
+  </p>
+</xsl:template>
+
+<!-- report every message but those with debug priority -->
+<xsl:template match="message[@priority!='debug']">
+  <tr valign="top">
+    <!-- alternated row style -->
+    <xsl:attribute name="class">
+      <xsl:if test="position() mod 2 = 1">a</xsl:if>
+      <xsl:if test="position() mod 2 = 0">b</xsl:if>
+    </xsl:attribute>
+    <td nowrap="yes" width="1%"><xsl:value-of select="../../@name"/></td>
+    <td nowrap="yes" style="text-align:right" width="1%">[ <xsl:value-of select="../@name"/> ]</td>
+    <td class="{@priority}" nowrap="yes">
+            <xsl:value-of select="text()"/>
+    </td>
+  </tr>
+</xsl:template>
+
+</xsl:stylesheet>
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/test/etc/xsl/phpunit2-noframes.xsl
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/test/etc/xsl/phpunit2-noframes.xsl	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/test/etc/xsl/phpunit2-noframes.xsl	(revision 19)
@@ -0,0 +1,438 @@
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"
+    xmlns:exsl="http://exslt.org/common"
+    xmlns:str="http://exslt.org/strings"
+    xmlns:date="http://exslt.org/dates-and-times"
+    extension-element-prefixes="exsl str date">
+<xsl:include href="str.replace.function.xsl"/>
+<xsl:output method="html" indent="yes" encoding="US-ASCII"
+  doctype-public="-//W3C//DTD HTML 4.01 Transitional//EN" />
+<xsl:decimal-format decimal-separator="." grouping-separator="," />
+<!--
+   Copyright 2001-2004 The Apache Software Foundation
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+ -->
+ 
+<!--
+ 
+ Sample stylesheet to be used with Phing/PHPUnit2 output.
+ Based on JUnit stylesheets from Apache Ant.
+ 
+ It creates a non-framed report that can be useful to send via
+ e-mail or such.
+ 
+ @author Michiel Rook <a href="mailto:michiel@trendserver.nl"/>
+ @author Stephane Bailliez <a href="mailto:sbailliez@apache.org"/>
+ @author Erik Hatcher <a href="mailto:ehatcher@apache.org"/>
+ 
+-->
+<xsl:template match="testsuites">
+    <html>
+        <head>
+            <title>Unit Test Results</title>
+    <style type="text/css">
+    body {
+        font-family: verdana,arial,helvetica;
+        color:#000000;
+        font-size: 12px;
+    }
+    table tr td, table tr th {
+        font-family: verdana,arial,helvetica;
+        font-size: 12px;
+    }
+    table.details tr th{
+        font-family: verdana,arial,helvetica;
+        font-weight: bold;
+        text-align:left;
+        background:#a6caf0;
+    }
+    table.details tr td{
+        background:#eeeee0;
+    }
+
+    p {
+        line-height:1.5em;
+        margin-top:0.5em; margin-bottom:1.0em;
+        font-size: 12px;
+    }
+    h1 {
+        margin: 0px 0px 5px;
+        font-family: verdana,arial,helvetica;
+    }
+    h2 {
+        margin-top: 1em; margin-bottom: 0.5em;
+        font-family: verdana,arial,helvetica;
+    }
+    h3 {
+        margin-bottom: 0.5em;
+        font-family: verdana,arial,helvetica;
+    }
+    h4 {
+        margin-bottom: 0.5em;
+        font-family: verdana,arial,helvetica;
+    }
+    h5 {
+        margin-bottom: 0.5em;
+        font-family: verdana,arial,helvetica;
+    }
+    h6 {
+        margin-bottom: 0.5em;
+        font-family: verdana,arial,helvetica;
+    }
+    .Error {
+        font-weight:bold; color:red;
+    }
+    .Failure {
+        font-weight:bold; color:purple;
+    }
+    .small {
+       font-size: 9px;
+    }
+    a {
+      color: #003399;
+    }
+    a:hover {
+      color: #888888;
+    }
+    </style>
+        </head>
+        <body>
+            <a name="top"></a>
+            <xsl:call-template name="pageHeader"/>  
+            
+            <!-- Summary part -->
+            <xsl:call-template name="summary"/>
+            <hr size="1" width="95%" align="left"/>
+            
+            <!-- Package List part -->
+            <xsl:call-template name="packagelist"/>
+            <hr size="1" width="95%" align="left"/>
+            
+            <!-- For each package create its part -->
+            <xsl:call-template name="packages"/>
+            <hr size="1" width="95%" align="left"/>
+            
+            <!-- For each class create the  part -->
+            <xsl:call-template name="classes"/>
+            
+            <xsl:call-template name="pageFooter"/>  
+        </body>
+    </html>
+</xsl:template>
+    
+    
+    
+    <!-- ================================================================== -->
+    <!-- Write a list of all packages with an hyperlink to the anchor of    -->
+    <!-- of the package name.                                               -->
+    <!-- ================================================================== -->
+    <xsl:template name="packagelist">   
+        <h2>Packages</h2>
+        Note: package statistics are not computed recursively, they only sum up all of its testsuites numbers.
+        <table class="details" border="0" cellpadding="5" cellspacing="2" width="95%">
+            <xsl:call-template name="testsuite.test.header"/>
+            <!-- list all packages recursively -->
+            <xsl:for-each select="./testsuite[not(./@package = preceding-sibling::testsuite/@package)]">
+                <xsl:sort select="@package"/>
+                <xsl:variable name="testsuites-in-package" select="/testsuites/testsuite[./@package = current()/@package]"/>
+                <xsl:variable name="testCount" select="sum($testsuites-in-package/@tests)"/>
+                <xsl:variable name="errorCount" select="sum($testsuites-in-package/@errors)"/>
+                <xsl:variable name="failureCount" select="sum($testsuites-in-package/@failures)"/>
+                <xsl:variable name="timeCount" select="sum($testsuites-in-package/@time)"/>
+                
+                <!-- write a summary for the package -->
+                <tr valign="top">
+                    <!-- set a nice color depending if there is an error/failure -->
+                    <xsl:attribute name="class">
+                        <xsl:choose>
+                            <xsl:when test="$failureCount &gt; 0">Failure</xsl:when>
+                            <xsl:when test="$errorCount &gt; 0">Error</xsl:when>
+                        </xsl:choose>
+                    </xsl:attribute>
+                    <td><a href="#{@package}"><xsl:value-of select="@package"/></a></td>
+                    <td><xsl:value-of select="$testCount"/></td>
+                    <td><xsl:value-of select="$errorCount"/></td>
+                    <td><xsl:value-of select="$failureCount"/></td>
+                    <td>
+                    <xsl:call-template name="display-time">
+                        <xsl:with-param name="value" select="$timeCount"/>
+                    </xsl:call-template>
+                    </td>
+                </tr>
+            </xsl:for-each>
+        </table>        
+    </xsl:template>
+    
+    
+    <!-- ================================================================== -->
+    <!-- Write a package level report                                       -->
+    <!-- It creates a table with values from the document:                  -->
+    <!-- Name | Tests | Errors | Failures | Time                            -->
+    <!-- ================================================================== -->
+    <xsl:template name="packages">
+        <!-- create an anchor to this package name -->
+        <xsl:for-each select="/testsuites/testsuite[not(./@package = preceding-sibling::testsuite/@package)]">
+            <xsl:sort select="@package"/>
+                <a name="{@package}"></a>
+                <h3>Package <xsl:value-of select="@package"/></h3>
+                
+                <table class="details" border="0" cellpadding="5" cellspacing="2" width="95%">
+                    <xsl:call-template name="testsuite.test.header"/>
+            
+                    <!-- match the testsuites of this package -->
+                    <xsl:apply-templates select="/testsuites/testsuite[./@package = current()/@package]" mode="print.test"/>
+                </table>
+                <a href="#top">Back to top</a>
+                <p/>
+                <p/>
+        </xsl:for-each>
+    </xsl:template>
+    
+    <xsl:template name="classes">
+        <xsl:for-each select="testsuite">
+            <xsl:sort select="@name"/>
+            <!-- create an anchor to this class name -->
+            <a name="{@name}"></a>
+            <h3>TestCase <xsl:value-of select="@name"/></h3>
+            
+            <table class="details" border="0" cellpadding="5" cellspacing="2" width="95%">
+              <xsl:call-template name="testcase.test.header"/>
+              <!--
+              test can even not be started at all (failure to load the class)
+              so report the error directly
+              -->
+                <xsl:if test="./error">
+                    <tr class="Error">
+                        <td colspan="4"><xsl:apply-templates select="./error"/></td>
+                    </tr>
+                </xsl:if>
+                <xsl:apply-templates select="./testcase" mode="print.test"/>
+            </table>
+            <p/>
+            
+            <a href="#top">Back to top</a>
+        </xsl:for-each>
+    </xsl:template>
+    
+    <xsl:template name="summary">
+        <h2>Summary</h2>
+        <xsl:variable name="testCount" select="sum(testsuite/@tests)"/>
+        <xsl:variable name="errorCount" select="sum(testsuite/@errors)"/>
+        <xsl:variable name="failureCount" select="sum(testsuite/@failures)"/>
+        <xsl:variable name="timeCount" select="sum(testsuite/@time)"/>
+        <xsl:variable name="successRate" select="($testCount - $failureCount - $errorCount) div $testCount"/>
+        <table class="details" border="0" cellpadding="5" cellspacing="2" width="95%">
+        <tr valign="top">
+            <th>Tests</th>
+            <th>Failures</th>
+            <th>Errors</th>
+            <th>Success rate</th>
+            <th>Time</th>
+        </tr>
+        <tr valign="top">
+            <xsl:attribute name="class">
+                <xsl:choose>
+                    <xsl:when test="$failureCount &gt; 0">Failure</xsl:when>
+                    <xsl:when test="$errorCount &gt; 0">Error</xsl:when>
+                </xsl:choose>
+            </xsl:attribute>
+            <td><xsl:value-of select="$testCount"/></td>
+            <td><xsl:value-of select="$failureCount"/></td>
+            <td><xsl:value-of select="$errorCount"/></td>
+            <td>
+                <xsl:call-template name="display-percent">
+                    <xsl:with-param name="value" select="$successRate"/>
+                </xsl:call-template>
+            </td>
+            <td>
+                <xsl:call-template name="display-time">
+                    <xsl:with-param name="value" select="$timeCount"/>
+                </xsl:call-template>
+            </td>
+
+        </tr>
+        </table>
+        <table border="0" width="95%">
+        <tr>
+        <td style="text-align: justify;">
+        Note: <i>failures</i> are anticipated and checked for with assertions while <i>errors</i> are unanticipated.
+        </td>
+        </tr>
+        </table>
+    </xsl:template>
+      
+<!-- Page HEADER -->
+<xsl:template name="pageHeader">
+    <h1>Unit Test Results</h1>
+    <table width="100%">
+    <tr>
+        <td align="left"></td>
+        <td align="right">Designed for use with <a href='http://pear.php.net/package/PHPUnit2'>PHPUnit2</a> and <a href='http://phing.info/'>Phing</a>.</td>
+    </tr>
+    </table>
+    <hr size="1"/>
+</xsl:template>
+
+<!-- Page Footer -->
+<xsl:template name="pageFooter">
+    <table width="100%">
+      <tr><td><hr noshade="yes" size="1"/></td></tr>
+      <tr><td class="small">Report generated at <xsl:value-of select="date:date-time()"/></td></tr>
+    </table>
+</xsl:template>
+
+<xsl:template match="testsuite" mode="header">
+    <tr valign="top">
+        <th width="80%">Name</th>
+        <th>Tests</th>
+        <th>Errors</th>
+        <th>Failures</th>
+        <th nowrap="nowrap">Time(s)</th>
+    </tr>
+</xsl:template>
+
+<!-- class header -->
+<xsl:template name="testsuite.test.header">
+    <tr valign="top">
+        <th width="80%">Name</th>
+        <th>Tests</th>
+        <th>Errors</th>
+        <th>Failures</th>
+        <th nowrap="nowrap">Time(s)</th>
+    </tr>
+</xsl:template>
+
+<!-- method header -->
+<xsl:template name="testcase.test.header">
+    <tr valign="top">
+        <th>Name</th>
+        <th>Status</th>
+        <th width="80%">Type</th>
+        <th nowrap="nowrap">Time(s)</th>
+    </tr>
+</xsl:template>
+
+
+<!-- class information -->
+<xsl:template match="testsuite" mode="print.test">
+    <tr valign="top">
+        <!-- set a nice color depending if there is an error/failure -->
+        <xsl:attribute name="class">
+            <xsl:choose>
+                <xsl:when test="@failures[.&gt; 0]">Failure</xsl:when>
+                <xsl:when test="@errors[.&gt; 0]">Error</xsl:when>
+            </xsl:choose>
+        </xsl:attribute>
+    
+        <!-- print testsuite information -->
+        <td><a href="#{@name}"><xsl:value-of select="@name"/></a></td>
+        <td><xsl:value-of select="@tests"/></td>
+        <td><xsl:value-of select="@errors"/></td>
+        <td><xsl:value-of select="@failures"/></td>
+        <td>
+            <xsl:call-template name="display-time">
+                <xsl:with-param name="value" select="@time"/>
+            </xsl:call-template>
+        </td>
+    </tr>
+</xsl:template>
+
+<xsl:template match="testcase" mode="print.test">
+    <tr valign="top">
+        <xsl:attribute name="class">
+            <xsl:choose>
+                <xsl:when test="failure | error">Error</xsl:when>
+            </xsl:choose>
+        </xsl:attribute>
+        <td><xsl:value-of select="@name"/></td>
+        <xsl:choose>
+            <xsl:when test="failure">
+                <td>Failure</td>
+                <td><xsl:apply-templates select="failure"/></td>
+            </xsl:when>
+            <xsl:when test="error">
+                <td>Error</td>
+                <td><xsl:apply-templates select="error"/></td>
+            </xsl:when>
+            <xsl:otherwise>
+                <td>Success</td>
+                <td></td>
+            </xsl:otherwise>
+        </xsl:choose>
+        <td>
+            <xsl:call-template name="display-time">
+                <xsl:with-param name="value" select="@time"/>
+            </xsl:call-template>
+        </td>
+    </tr>
+</xsl:template>
+
+
+<xsl:template match="failure">
+    <xsl:call-template name="display-failures"/>
+</xsl:template>
+
+<xsl:template match="error">
+    <xsl:call-template name="display-failures"/>
+</xsl:template>
+
+<!-- Style for the error and failure in the tescase template -->
+<xsl:template name="display-failures">
+    <xsl:choose>
+        <xsl:when test="not(@message)">N/A</xsl:when>
+        <xsl:otherwise>
+            <xsl:value-of select="@message"/>
+        </xsl:otherwise>
+    </xsl:choose>
+    <!-- display the stacktrace -->
+    <code>
+        <br/><br/>
+		<xsl:value-of select="."/>
+        <xsl:call-template name="br-replace">
+            <xsl:with-param name="word" select="."/>
+        </xsl:call-template>
+    </code>
+    <!-- the later is better but might be problematic for non-21" monitors... -->
+    <!--pre><xsl:value-of select="."/></pre-->
+</xsl:template>
+
+<xsl:template name="JS-escape">
+    <xsl:param name="string"/>
+    <xsl:param name="tmp1" select="str:replace(string($string),'\','\\')"/>
+    <xsl:param name="tmp2" select="str:replace(string($tmp1),&quot;'&quot;,&quot;\&apos;&quot;)"/>
+    <xsl:value-of select="$tmp2"/>
+</xsl:template>
+
+
+<!--
+    template that will convert a carriage return into a br tag
+    @param word the text from which to convert CR to BR tag
+-->
+<xsl:template name="br-replace">
+    <xsl:param name="word"/>
+    <xsl:param name="br"><br/></xsl:param>
+    <xsl:value-of select='str:replace(string($word),"&#xA;",$br)'/>
+</xsl:template>
+
+<xsl:template name="display-time">
+    <xsl:param name="value"/>
+    <xsl:value-of select="format-number($value,'0.000')"/>
+</xsl:template>
+
+<xsl:template name="display-percent">
+    <xsl:param name="value"/>
+    <xsl:value-of select="format-number($value,'0.00%')"/>
+</xsl:template>
+
+</xsl:stylesheet>
+
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/test/etc/xsl/str.replace.function.xsl
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/test/etc/xsl/str.replace.function.xsl	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/test/etc/xsl/str.replace.function.xsl	(revision 19)
@@ -0,0 +1,105 @@
+<?xml version="1.0"?>
+<xsl:stylesheet version="1.0"
+                xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+                xmlns:str="http://exslt.org/strings"
+                xmlns:func="http://exslt.org/functions"
+                xmlns:exsl="http://exslt.org/common"
+                extension-element-prefixes="str exsl func">
+
+<func:function name="str:replace">
+	<xsl:param name="string" select="''" />
+   <xsl:param name="search" select="/.." />
+   <xsl:param name="replace" select="/.." />
+   <xsl:choose>
+      <xsl:when test="not($string)">
+        <func:result select="/.." />
+      </xsl:when>
+      <xsl:when test="function-available('exsl:node-set')">
+         <!-- this converts the search and replace arguments to node sets
+              if they are one of the other XPath types -->
+         <xsl:variable name="search-nodes-rtf">
+           <xsl:copy-of select="$search" />
+         </xsl:variable>
+         <xsl:variable name="replace-nodes-rtf">
+           <xsl:copy-of select="$replace" />
+         </xsl:variable>
+         <xsl:variable name="replacements-rtf">
+            <xsl:for-each select="exsl:node-set($search-nodes-rtf)/node()">
+               <xsl:variable name="pos" select="position()" />
+               <replace search="{.}">
+                  <xsl:copy-of select="exsl:node-set($replace-nodes-rtf)/node()[$pos]" />
+               </replace>
+            </xsl:for-each>
+         </xsl:variable>
+         <xsl:variable name="sorted-replacements-rtf">
+            <xsl:for-each select="exsl:node-set($replacements-rtf)/replace">
+               <xsl:sort select="string-length(@search)" data-type="number" order="descending" />
+               <xsl:copy-of select="." />
+            </xsl:for-each>
+         </xsl:variable>
+         <xsl:variable name="result">
+           <xsl:choose>
+              <xsl:when test="not($search)">
+                <xsl:value-of select="$string" />
+              </xsl:when>
+             <xsl:otherwise>
+               <xsl:call-template name="str:_replace">
+                  <xsl:with-param name="string" select="$string" />
+                  <xsl:with-param name="replacements" select="exsl:node-set($sorted-replacements-rtf)/replace" />
+               </xsl:call-template>
+             </xsl:otherwise>
+           </xsl:choose>
+         </xsl:variable>
+         <func:result select="exsl:node-set($result)/node()" />
+      </xsl:when>
+      <xsl:otherwise>
+         <xsl:message terminate="yes">
+            ERROR: function implementation of str:replace() relies on exsl:node-set().
+         </xsl:message>
+      </xsl:otherwise>
+   </xsl:choose>
+</func:function>
+
+<xsl:template name="str:_replace">
+  <xsl:param name="string" select="''" />
+  <xsl:param name="replacements" select="/.." />
+  <xsl:choose>
+    <xsl:when test="not($string)" />
+    <xsl:when test="not($replacements)">
+      <xsl:value-of select="$string" />
+    </xsl:when>
+    <xsl:otherwise>
+      <xsl:variable name="replacement" select="$replacements[1]" />
+      <xsl:variable name="search" select="$replacement/@search" />
+      <xsl:choose>
+        <xsl:when test="not(string($search))">
+          <xsl:value-of select="substring($string, 1, 1)" />
+          <xsl:copy-of select="$replacement/node()" />
+          <xsl:call-template name="str:_replace">
+            <xsl:with-param name="string" select="substring($string, 2)" />
+            <xsl:with-param name="replacements" select="$replacements" />
+          </xsl:call-template>
+        </xsl:when>
+        <xsl:when test="contains($string, $search)">
+          <xsl:call-template name="str:_replace">
+            <xsl:with-param name="string" select="substring-before($string, $search)" />
+            <xsl:with-param name="replacements" select="$replacements[position() > 1]" />
+          </xsl:call-template>      
+          <xsl:copy-of select="$replacement/node()" />
+          <xsl:call-template name="str:_replace">
+            <xsl:with-param name="string" select="substring-after($string, $search)" />
+            <xsl:with-param name="replacements" select="$replacements" />
+          </xsl:call-template>
+        </xsl:when>
+        <xsl:otherwise>
+          <xsl:call-template name="str:_replace">
+            <xsl:with-param name="string" select="$string" />
+            <xsl:with-param name="replacements" select="$replacements[position() > 1]" />
+          </xsl:call-template>
+        </xsl:otherwise>
+      </xsl:choose>
+    </xsl:otherwise>
+  </xsl:choose>
+</xsl:template>
+
+</xsl:stylesheet>
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/test/run-tests.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/test/run-tests.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/phing/test/run-tests.php	(revision 19)
@@ -0,0 +1,85 @@
+<?php
+
+// Set up environment (include_path, etc.) for running these tests
+define('PHPUnit2_MAIN_METHOD', "don't let PHPUnit try to auto-invoke anything!");
+
+include_once 'PHPUnit2/TextUI/TestRunner.php';
+include_once 'PHPUnit2/Framework/TestSuite.php';
+
+// Probably should use PHING_HOME here instead of assuming that test/ is still subdir.
+ini_set('include_path', realpath(dirname(__FILE__) . '/classes') . PATH_SEPARATOR . realpath(dirname(__FILE__) . '/../classes') . PATH_SEPARATOR . ini_get('include_path'));
+
+define('PHING_TEST_BASE', dirname(__FILE__));
+
+// STARTUP PHING
+require_once 'phing/Phing.php';
+
+Phing::startup();
+
+
+// For now just add all classes to here -- this is ugly, but
+// we don't need to pollute the test structure with AllTest classes
+// yet ...
+
+
+// ----------------------------------------------------------
+// core
+// ----------------------------------------------------------
+
+$coreSuite = new PHPUnit2_Framework_TestSuite("Phing Core");
+include_once 'phing/IntrospectionHelperTest.php';
+$coreSuite->addTestSuite(new ReflectionClass('IntrospectionHelperTest'));
+
+
+// ----------------------------------------------------------
+// types
+// ----------------------------------------------------------
+
+$typesSuite = new PHPUnit2_Framework_TestSuite("Phing Types");
+
+include_once 'phing/types/MapperTest.php';
+$typesSuite->addTestSuite(new ReflectionClass('MapperTest'));
+
+include_once 'phing/filters/LineContainsTest.php';
+$typesSuite->addTestSuite(new ReflectionClass('LineContainsTest'));
+
+include_once 'phing/types/CommandlineTest.php';
+$typesSuite->addTestSuite(new ReflectionClass('CommandlineTest'));
+
+include_once 'phing/types/FileSetTest.php';
+$typesSuite->addTestSuite(new ReflectionClass('FileSetTest'));
+
+// ----------------------------------------------------------
+// tasks
+// ----------------------------------------------------------
+
+$tasksSuite = new PHPUnit2_Framework_TestSuite("Phing Tasks");
+
+include_once 'phing/tasks/TypedefTaskTest.php';
+$tasksSuite->addTestSuite(new ReflectionClass('TypedefTaskTest'));
+
+
+// Conditions
+include_once 'phing/tasks/condition/ContainsConditionTest.php';
+include_once 'phing/tasks/condition/EqualsConditionTest.php';
+$tasksSuite->addTestSuite(new ReflectionClass('ContainsConditionTest'));
+$tasksSuite->addTestSuite(new ReflectionClass('EqualsConditionTest'));
+
+include_once 'phing/tasks/PropertyTaskTest.php';
+$tasksSuite->addTestSuite(new ReflectionClass('PropertyTaskTest'));
+
+
+ 
+$suite = new PHPUnit2_Framework_TestSuite('Phing Tests');
+$suite->addTest($coreSuite);
+$suite->addTest($typesSuite);
+$suite->addTest($tasksSuite);
+
+
+
+// Run it!
+PHPUnit2_TextUI_TestRunner::run($suite);
+
+
+// SHUTDOWN PHING
+Phing::shutdown();
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/bin/propel-gen
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/bin/propel-gen	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/bin/propel-gen	(revision 19)
@@ -0,0 +1,67 @@
+#!/bin/sh
+# Shell wrapper for Propel generator
+# $Id$
+#
+# This script will do the following:
+# - check for PHING_COMMAND env, if found, use it.
+#   - if not found assume php is on the path
+# - check for PROPEL_GEN_HOME evn, if found use it
+#   - if not look for it
+
+if [ -z "$PROPEL_GEN_HOME" ] ; then
+
+  # echo "WARNING: PROPEL_GEN_HOME environment not set. Attempting to guess."
+
+  # try to find Propel
+  if [ -d /opt/propel/generator ] ; then 
+    PROPEL_GEN_HOME=/opt/propel/generator
+  fi
+
+  if [ -d "${HOME}/opt/propel/generator" ] ; then 
+    PROPEL_GEN_HOME="${HOME}/opt/propel/generator"
+  fi
+
+  if [ -d "/usr/local/propel/generator" ] ; then 
+    PROPEL_GEN_HOME="/usr/local/propel/generator"
+  fi
+
+  if [ -d "${HOME}/usr/propel/generator" ] ; then 
+    PROPEL_GEN_HOME="${HOME}/usr/propel/generator"
+  fi
+  
+  ## resolve links - $0 may be a link to phing's home
+  PRG="$0"
+  progname=`basename "$0"`
+  saveddir=`pwd`
+
+  # need this for relative symlinks
+  dirname_prg=`dirname "$PRG"`
+  cd "$dirname_prg"
+  
+  while [ -h "$PRG" ] ; do
+    ls=`ls -ld "$PRG"`
+    link=`expr "$ls" : '.*-> \(.*\)$'`
+    if expr "$link" : '/.*' > /dev/null; then
+	PRG="$link"
+    else
+	PRG=`dirname "$PRG"`"/$link"
+    fi
+  done
+  
+  PROPEL_GEN_HOME=`dirname "$PRG"`/..
+
+  cd "$saveddir"
+
+  # make it fully qualified
+  PROPEL_GEN_HOME=`cd "$PROPEL_GEN_HOME" && pwd`
+  
+  # make it available in PHP via getenv("PROPEL_GEN_HOME")
+  export PROPEL_GEN_HOME
+fi
+
+if (test -z "$PHING_COMMAND") ; then
+	# echo "WARNING: PHING_COMMAND environment not set. (Assuming phing on PATH)"
+	export PHING_COMMAND="phing"
+fi
+
+$PHING_COMMAND -f $PROPEL_GEN_HOME/build.xml -Dusing.propel-gen=true -Dproject.dir=$*
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/bin/propel-gen.bat
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/bin/propel-gen.bat	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/bin/propel-gen.bat	(revision 19)
@@ -0,0 +1,47 @@
+@echo off
+
+rem *********************************************************************
+rem ** The Propel generator convenience script for Windows based systems
+rem ** $Id$
+rem *********************************************************************
+
+rem This script will do the following:
+rem - check for PHING_COMMAND env, if found, use it.
+rem   - if not found detect php, if found use it, otherwise err and terminate
+rem - check for PROPEL_GEN_HOME evn, if found use it
+rem   - if not found error and leave
+
+if "%OS%"=="Windows_NT" @setlocal
+
+rem %~dp0 is expanded pathname of the current script under NT
+set DEFAULT_PROPEL_GEN_HOME=%~dp0..
+
+goto init
+goto cleanup
+
+:init
+
+if "%PROPEL_GEN_HOME%" == "" set PROPEL_GEN_HOME=%DEFAULT_PROPEL_GEN_HOME%
+set DEFAULT_PROPEL_GEN_HOME=
+
+if "%PHING_COMMAND%" == "" goto no_phingcommand
+
+goto run
+goto cleanup
+
+:run
+%PHING_COMMAND% -f "%PROPEL_GEN_HOME%\build.xml" -Dusing.propel-gen=true -Dproject.dir=%*
+goto cleanup
+
+:no_phingcommand
+REM echo ------------------------------------------------------------------------
+REM echo WARNING: Set environment var PHING_COMMAND to the location of your phing
+REM echo          executable (e.g. C:\PHP\phing.bat). 
+REM echo Proceeding with assumption that phing.bat is on Path
+REM echo ------------------------------------------------------------------------
+set PHING_COMMAND=phing.bat
+goto init
+
+:cleanup
+if "%OS%"=="Windows_NT" @endlocal
+REM pause
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/build-propel.xml
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/build-propel.xml	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/build-propel.xml	(revision 19)
@@ -0,0 +1,549 @@
+<project name="propel" default="main" basedir=".">
+
+  <!--
+    Note - You should not have to edit this file.
+
+    Instead, if calling build-propel.xml directly, edit the build.properties
+    that is in the same directory. If calling build-propel.xml via another
+    build file, you can also use the build.properties in the same directory,
+    or set the property propel.contextProperties to the file
+    to use in place of build.properties (e.g. project.properties).
+  -->
+
+  <property name="build.properties" value="build.properties"/>
+  <property name="propel.contextProperties" value="./${build.properties}"/>
+  <property name="propel.home" value="."/>
+
+  <available file="${propel.home}/build.properties" property="globalBuildPopertiesExists"/>
+
+  <if>
+  	<and>
+  		<isset property="globalBuildPopertiesExists"/>
+  	</and>
+  	<then>
+	    <property file="${propel.home}/build.properties"/>
+	</then>
+  </if>
+
+  <!--
+    The default.properties file will map old properties to the new ones along
+    with setting the corret defaults.
+  -->
+  <property file="${propel.home}/default.properties"/>
+
+  <!--
+    Do forward declarations of all of our tasks to
+    centralize them and clean up the targets.
+  -->
+
+  <path id="propelclasses">
+    <pathelement dir="${propel.home}/classes/"/>
+  </path>
+
+  <taskdef
+    name="propel-data-model"
+    classname="propel.phing.PropelDataModelTemplateTask" classpathRef="propelclasses"/>
+  <taskdef
+    name="propel-om"
+    classname="propel.phing.PropelOMTask" classpathRef="propelclasses"/>
+  <taskdef
+    name="propel-data-dtd"
+    classname="propel.phing.PropelDataDTDTask" classpathRef="propelclasses"/>
+  <taskdef
+    name="propel-data-dump"
+    classname="propel.phing.PropelDataDumpTask" classpathRef="propelclasses"/>
+  <taskdef
+    name="propel-data-sql"
+    classname="propel.phing.PropelDataSQLTask" classpathRef="propelclasses"/>
+   <taskdef
+    name="propel-creole-transform"
+    classname="propel.phing.PropelCreoleTransformTask" classpathRef="propelclasses"/>
+   <taskdef
+    name="propel-schema-reverse"
+    classname="propel.phing.PropelSchemaReverseTask" classpathRef="propelclasses"/>
+
+  <taskdef
+    name="propel-sql"
+    classname="propel.phing.PropelSQLTask" classpathRef="propelclasses"/>
+  <taskdef
+    name="propel-sql-exec"
+    classname="propel.phing.PropelSQLExec" classpathRef="propelclasses"/>
+  <taskdef
+    name="propel-graphviz"
+    classname="propel.phing.PropelGraphvizTask" classpathRef="propelclasses"/>
+  <taskdef
+    name="propel-convert-conf"
+    classname="propel.phing.PropelConvertConfTask" classpathRef="propelclasses"/>
+
+  <!-- ================================================================ -->
+  <!-- M A I N  T A R G E T                                             -->
+  <!-- ================================================================ -->
+  <!-- This default target will run all the targets that generate       -->
+  <!-- source. You will probably only run this target once then         -->
+  <!-- call individual targets as necessary to update your sources      -->
+  <!-- when you change your XML schema.                                 -->
+  <!-- ================================================================ -->
+
+  <target
+    name="main"
+  	depends="mysqli-check"
+    description="==> generates sql + om classes">
+
+    <phingcall target="sql"/>
+    <phingcall target="om"/>
+    <phingcall target="convert-conf"/>
+  </target>
+
+  <!-- ================================================================ -->
+  <!-- C H E C K  R U N  O N L Y  O N  S C H E M A  C H A N G E         -->
+  <!-- ================================================================ -->
+  <!-- Maps the propel.runOnlyOnSchemaChange to                         -->
+  <!-- propel.internal.runOnlyOnSchemaChange                            -->
+  <!-- ================================================================ -->
+
+  <target name="check-run-only-on-schema-change">
+    <condition property="propel.internal.runOnlyOnSchemaChange">
+      <equals arg1="${propel.runOnlyOnSchemaChange}" arg2="true"/>
+    </condition>
+  </target>
+
+  <!-- ================================================================ -->
+  <!-- G E N E R A T E  P R O J E C T  S Q L                            -->
+  <!-- ================================================================ -->
+  <!-- Generate the SQL for your project, These are in addition         -->
+  <!-- to the base Turbine tables! The tables you require for your      -->
+  <!-- project should be specified in project-schema.xml.               -->
+  <!-- ================================================================ -->
+
+  <target
+    name="sql-check"
+    depends="check-run-only-on-schema-change"
+    if="propel.internal.runOnlyOnSchemaChange">
+    <uptodate
+      property="propel.internal.sql.uptodate"
+      targetfile="${propel.sql.dir}/${propel.schema.default.basename}.sql">
+      <srcfiles dir="${propel.schema.dir}" includes="**/${propel.schema.default.basename}.xml" />
+    </uptodate>
+  </target>
+
+  <!--	temporary target to check whether postgres is being used with identifier quoting ON.
+		If so, a warning is issued, since identifier quoting is only paritally implemented & this point.  -->
+  <target name="pgsql-quoting-check">
+  	<if>
+  		<and>
+			<equals arg1="${propel.database}" arg2="pgsql"/>
+			<equals arg1="${propel.disableIdentifierQuoting}" arg2=""/>
+		</and>
+		<then>
+			<warn>ATTENTION: It appears you are using PostgreSQL and you have identifier-quoting turned on.</warn>
+			<warn>It is suggested that you disable identifier quoting when using PostgreSQL -- especially if you</warn>
+			<warn>have case-sensitive columns in your database.</warn>
+			<warn></warn>
+			<warn>To disable identifier quoting, add the following property to your build.properties (or specify</warn>
+			<warn>it using -D on commandline):</warn>
+			<warn></warn>
+			<warn>propel.disableIdentifierQuoting=true</warn>
+			<warn></warn>
+			<warn>You can ignore this warning if you understand the issues related to case-sensitivity and Propel's</warn>
+			<warn>DDL-only implementation of identifier quoting.</warn>
+		</then>
+	</if>
+  </target>
+
+	  <!--	temporary target to check whether mysqli is being used
+			If so, a warning is issued, since this is deprecated  -->
+	  <target name="mysqli-check">
+	  	<if>
+	  		<and>
+				<equals arg1="${propel.database}" arg2="mysqli"/>
+			</and>
+			<then>
+				<warn>ATTENTION: It appears you are using the mysqli driver.</warn>
+				<warn></warn>
+				<warn>This driver is no longer supported by Propel because Propel now uses PDO for database connections.</warn>
+				<warn>Please use mysqli driver instead.</warn>
+				<fail>Use 'mysql' instead of 'mysqli' for your propel.database property.</fail>
+			</then>
+		</if>
+	  </target>
+	
+  <target
+    name="sql"
+    depends="sql-check,pgsql-quoting-check,mysqli-check"
+    unless="propel.internal.sql.uptodate"
+    description="==> generates the SQL for your project">
+
+    <echo message="+------------------------------------------+"/>
+    <echo message="|                                          |"/>
+    <echo message="| Generating SQL for YOUR Propel project!  |"/>
+    <echo message="|                                          |"/>
+    <echo message="+------------------------------------------+"/>
+
+    <phingcall target="sql-template"/>
+
+  </target>
+
+  <target name="sql-template">
+    <propel-sql
+	  validate="${propel.schema.validate}"
+	  xsd="${propel.schema.xsd.file}"
+	  xsl="${propel.schema.xsl.file}"
+      outputDirectory="${propel.sql.dir}"
+      sqldbmap="${propel.sql.dir}/sqldb.map"
+      targetDatabase="${propel.database}"
+      packageObjectModel="${propel.packageObjectModel}"
+      url="${propel.database.url}"
+      userId="${propel.database.user}"
+      password="${propel.database.password}"
+      >
+      <mapper type="glob" from="${propel.sql.mapper.from}" to="${propel.sql.mapper.to}"/>
+      <schemafileset dir="${propel.schema.dir}"
+        includes="${propel.schema.sql.includes}"
+        excludes="${propel.schema.sql.excludes}"
+      />
+    </propel-sql>
+  </target>
+
+  <!-- ================================================================ -->
+  <!-- C R E A T E  T A R G E T  D A T A B A S E                        -->
+  <!-- ================================================================ -->
+  <!-- Create the target database by executing a generated script       -->
+  <!-- that is capable of performing the task.                          -->
+  <!-- ================================================================ -->
+
+  <target name="create-db-check">
+    <condition property="propel.internal.manualCreation">
+      <equals arg1="${propel.database.manualCreation}" arg2="true"/>
+    </condition>
+  </target>
+
+  <target
+    name="create-db"
+    unless="propel.internal.manualCreation"
+    depends="create-db-check,mysqli-check"
+    description="==> generates the target database">
+
+	<fail message="create-db target temporarily disabled, while we replace creole components."/>
+
+	<!--
+    <propel-data-model
+	  validate="${propel.schema.validate}"
+	  xsd="${propel.schema.xsd.file}"
+	  xsl="${propel.schema.xsl.file}"
+      controlTemplate="${propel.template.sqlDbInit}"
+      outputDirectory="${propel.sql.dir}"
+      outputFile="create-db.sql"
+      targetDatabase="${propel.database}"
+      dbEncoding="${propel.database.encoding}"
+      templatePath="${propel.templatePath}"
+      packageObjectModel="${propel.packageObjectModel}"
+      >
+      <schemafileset dir="${propel.schema.dir}"
+        includes="${propel.schema.create-db.includes}"
+        excludes="${propel.schema.create-db.excludes}"
+      />
+    </propel-data-model>
+
+    <echo message="Executing the create-db.sql script ..."/>
+
+    <sql
+      autocommit="true"
+      driver="${propel.database.driver}"
+      onerror="continue"
+      src="${propel.sql.dir}/create-db.sql"
+      url="${propel.database.createUrl}"
+    />
+    -->
+  </target>
+
+  <!-- ================================================================ -->
+  <!-- I N S E R T  S I N G L E  S Q L  F I L E S                       -->
+  <!-- ================================================================ -->
+
+  <target
+    name="insert-sql"
+    description="==> inserts the generated sql ">
+
+    <propel-sql-exec
+      autocommit="true"
+      onerror="continue"
+      sqldbmap="${propel.sql.dir}/sqldb.map"
+      srcDir="${propel.sql.dir}"
+      url="${propel.database.buildUrl}"
+      userId="${propel.database.user}"
+      password="${propel.database.password}"
+    />
+  </target>
+
+  <!-- ================================================================ -->
+  <!-- C R E O L E   T O   X M L                                        -->
+  <!-- ================================================================ -->
+
+  <target
+    name="creole"
+    description="==> generate xml schema from Creole metadata">
+
+    <echo message="+-----------------------------------------------+"/>
+    <echo message="|                                               |"/>
+    <echo message="| Generating XML from Creole connection !       |"/>
+    <echo message="|                                               |"/>
+    <echo message="+-----------------------------------------------+"/>
+
+    <propel-creole-transform
+      dbDriver="${propel.database.creole.driver}"
+      dbSchema="${propel.database.schema}"
+      dbEncoding="${propel.database.encoding}"
+      dbUrl="${propel.database.creole.url}"
+      outputFile="${propel.schema.dir}/${propel.default.schema.basename}.xml"
+      samePhpName="${propel.samePhpName}"
+      addVendorInfo="${propel.addVendorInfo}"
+      addValidators="${propel.addValidators}"
+    />
+
+  </target>
+  
+  <!-- ================================================================ -->
+  <!-- N E W   R E V E R S E   T O   X M L                              -->
+  <!-- ================================================================ -->
+
+  <target
+    name="reverse"
+    description="==> generate xml schema from reverse-engineered database (new)">
+
+    <echo message="+-----------------------------------------------+"/>
+    <echo message="|                                               |"/>
+    <echo message="| Generating XML from PDO connection !          |"/>
+    <echo message="|                                               |"/>
+    <echo message="+-----------------------------------------------+"/>
+
+    <propel-schema-reverse
+      databaseName="${propel.project}"
+      dbSchema="${propel.database.schema}"
+      dbEncoding="${propel.database.encoding}"
+      url="${propel.database.buildUrl}"
+      userId="${propel.database.user}"
+      password="${propel.database.password}"
+      outputFile="${propel.schema.dir}/${propel.default.schema.basename}.xml"
+      samePhpName="${propel.samePhpName}"
+      addVendorInfo="${propel.addVendorInfo}"
+      addValidators="${propel.addValidators}"
+    />
+
+  </target>
+
+
+  <!-- ================================================================ -->
+  <!-- Generate SQL from XML data file                                  -->
+  <!-- ================================================================ -->
+
+  <target
+    name="datasql"
+    description="==> generates sql from data xml">
+
+    <echo message="+-----------------------------------------------+"/>
+    <echo message="|                                               |"/>
+    <echo message="| Generating SQL from data XML !                |"/>
+    <echo message="|                                               |"/>
+    <echo message="+-----------------------------------------------+"/>
+
+    <propel-data-sql
+	  validate="${propel.schema.validate}"
+	  xsd="${propel.schema.xsd.file}"
+	  xsl="${propel.schema.xsl.file}"
+      outputDirectory="${propel.sql.dir}"
+      sqldbmap="${propel.sql.dir}/sqldb.map"
+      dbEncoding="${propel.database.encoding}"
+      targetDatabase="${propel.database}"
+      datadbmap="${propel.schema.dir}/datadb.map"
+      srcDir="${propel.schema.dir}"
+      >
+      <mapper type="glob" from="${propel.datasql.mapper.from}" to="${propel.datasql.mapper.to}"/>
+      <schemafileset dir="${propel.schema.dir}"
+        includes="${propel.schema.datadtd.includes}"
+        excludes="${propel.schema.datadtd.excludes}"
+      />
+    </propel-data-sql>
+  </target>
+
+  <!-- ================================================================ -->
+  <!-- Dump data from database into xml file                            -->
+  <!-- ================================================================ -->
+
+  <target
+    name="datadump"
+    description="==> dump data from database into xml file">
+
+    <echo message="+-----------------------------------------------+"/>
+    <echo message="|                                               |"/>
+    <echo message="| Dumping the data from database into XML       |"/>
+    <echo message="|                                               |"/>
+    <echo message="+-----------------------------------------------+"/>
+
+    <propel-data-dump
+	  validate="${propel.schema.validate}"
+	  xsd="${propel.schema.xsd.file}"
+	  xsl="${propel.schema.xsl.file}"
+      targetDatabase="${propel.database}"
+      datadbmap="${propel.schema.dir}/datadb.map"
+      databaseDriver="${propel.database.driver}"
+      dbEncoding="${propel.database.encoding}"
+      databaseUrl="${propel.database.url}"
+      databaseUser="${propel.database.user}"
+      databasePassword="${propel.database.password}"
+      outputDirectory="${propel.schema.dir}">
+      <mapper type="glob" from="${propel.datadump.mapper.from}" to="${propel.datadump.mapper.to}"/>
+      <schemafileset dir="${propel.schema.dir}"
+        includes="${propel.schema.datadtd.includes}"
+        excludes="${propel.schema.datadtd.excludes}"
+      />
+     </propel-data-dump>
+  </target>
+
+  <!-- ================================================================ -->
+  <!-- G E N E R A T E  P R O J E C T  D A T A  D T D                   -->
+  <!-- ================================================================ -->
+  <!-- Generate the DATA DTD for your project                           -->
+  <!-- ================================================================ -->
+
+  <target
+    name="datadtd"
+    description="==> generates the DATA DTD for your project">
+
+    <echo message="+-----------------------------------------------+"/>
+    <echo message="|                                               |"/>
+    <echo message="| Generating Data DTD for YOUR Propel project!  |"/>
+    <echo message="|                                               |"/>
+    <echo message="+-----------------------------------------------+"/>
+
+    <propel-data-dtd
+	  validate="${propel.schema.validate}"
+	  xsd="${propel.schema.xsd.file}"
+	  xsl="${propel.schema.xsl.file}"
+      targetDatabase="${propel.database}"
+      outputDirectory="${propel.output.dir}"
+      templatePath="${propel.templatePath}">
+      <!-- TODO: add properties for the mapper type, from, and to -->
+      <mapper type="glob" from="${propel.datadtd.mapper.from}" to="${propel.datadtd.mapper.to}"/>
+      <schemafileset dir="${propel.schema.dir}"
+        includes="${propel.schema.datadtd.includes}"
+        excludes="${propel.schema.datadtd.excludes}"
+      />
+    </propel-data-dtd>
+  </target>
+
+  <!-- ================================================================ -->
+  <!-- G E N E R A T E  P R O J E C T  P E E R  B A S E D  O M          -->
+  <!-- ================================================================ -->
+  <!-- Generate the Peer-based object model for your project.           -->
+  <!-- These are in addition to the base Propel OM!                     -->
+  <!-- ================================================================ -->
+
+  <target
+    name="om-check"
+    depends="check-run-only-on-schema-change"
+    if="propel.internal.runOnlyOnSchemaChange">
+    <uptodate
+      property="propel.internal.om.uptodate"
+      targetfile="${propel.php.dir}/report.${propel.project}.om.generation">
+      <srcfiles dir="${propel.schema.dir}" includes="**/${propel.schema.om.includes}.xml" />
+    </uptodate>
+  </target>
+
+  <target
+    name="om"
+    depends="om-check,mysqli-check"
+    unless="propel.internal.om.uptodate"
+    description="==> generates the Peer-based object model for your project">
+
+    <echo message="+------------------------------------------+"/>
+    <echo message="|                                          |"/>
+    <echo message="| Generating Peer-based Object Model for   |"/>
+    <echo message="| YOUR Propel project!                     |"/>
+    <echo message="|                                          |"/>
+    <echo message="+------------------------------------------+"/>
+
+    <phingcall target="om-template"/>
+    <!--<phingcall target="om-tar"/>-->
+  </target>
+
+  <target name="om-template">
+    <propel-om
+	  validate="${propel.schema.validate}"
+	  xsd="${propel.schema.xsd.file}"
+	  xsl="${propel.schema.xsl.file}"
+      outputDirectory="${propel.php.dir}"
+      targetDatabase="${propel.database}"
+      targetPackage="${propel.targetPackage}"
+      targetPlatform="${propel.targetPlatform}"
+      packageObjectModel="${propel.packageObjectModel}"
+      >
+      <schemafileset dir="${propel.schema.dir}"
+        includes="${propel.schema.om.includes}"
+        excludes="${propel.schema.om.excludes}"
+      />
+    </propel-om>
+  </target>
+
+  <!-- ================================================================== -->
+  <!-- X M L   R U N T I M E   C O N F   T O   P H P   A R R A Y          -->
+  <!-- ================================================================== -->
+
+  <target
+    name="convert-conf"
+    description="==> converts properties file to PHP array">
+
+    <echo message="+------------------------------------------+"/>
+    <echo message="|                                          |"/>
+    <echo message="| Converting runtime config file to an     |"/>
+    <echo message="| array dump for improved performance.     |"/>
+    <echo message="|                                          |"/>
+    <echo message="+------------------------------------------+"/>
+
+
+	<echo>Output file: ${propel.runtime.phpconf.file}</echo>
+	<echo>XMLFile: ${propel.conf.dir}/${propel.runtime.conf.file}</echo>
+
+    <propel-convert-conf
+      targetDatabase="${propel.database}"
+      xsd="${propel.schema.xsd.file}"
+	  xsl="${propel.schema.xsl.file}"
+      xmlConfFile="${propel.conf.dir}/${propel.runtime.conf.file}"
+      outputDirectory="${propel.phpconf.dir}"
+      outputFile="${propel.runtime.phpconf.file}"
+      packageObjectModel="${propel.packageObjectModel}"
+      outputClassmapFile="${propel.runtime.phpconf-classmap.file}">
+      <schemafileset dir="${propel.schema.dir}"
+        includes="${propel.schema.sql.includes}"
+        excludes="${propel.schema.sql.excludes}"
+      />
+     </propel-convert-conf>
+
+  </target>
+
+  <target
+    name="graphviz"
+    depends="sql-check"
+    description="==> generates Graphviz file for your project">
+
+    <echo message="+------------------------------------------+"/>
+    <echo message="|                                          |"/>
+    <echo message="| Generating Graphiz for YOUR Propel       |"/>
+    <echo message="| project!                                 |"/>
+    <echo message="|                                          |"/>
+    <echo message="+------------------------------------------+"/>
+
+    <propel-graphviz
+      outputDirectory="${propel.graph.dir}"
+      targetDatabase="${propel.database}"
+      sqldbmap="${propel.sql.dir}/sqldb.map"
+      packageObjectModel="${propel.packageObjectModel}">
+      <mapper type="glob" from="${propel.sql.mapper.from}" to="${propel.sql.mapper.to}"/>
+      <schemafileset dir="${propel.schema.dir}"
+        includes="${propel.schema.sql.includes}"
+        excludes="${propel.schema.sql.excludes}"
+      />
+    </propel-graphviz>
+  </target>
+
+
+</project>
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/build.properties-sample
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/build.properties-sample	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/build.properties-sample	(revision 19)
@@ -0,0 +1,194 @@
+# -------------------------------------------------------------------
+#
+# P R O P E L  C O N F I G U R A T I O N  F I L E
+#
+# -------------------------------------------------------------------
+# This file contains some example properties.  Ideally properties
+# should be specified in the project-specific build.properties file;
+# however, this file can be used to specify non-default properties 
+# that you would like to use accross all of your Propel projects.
+# -------------------------------------------------------------------
+#
+
+propel.home = .
+
+# -------------------------------------------------------------------
+#
+#  P R O J E C T
+#
+# -------------------------------------------------------------------
+# This is the name of your Propel project. The name of your Propel
+# project is used (by default) to determine where the generator will
+# find needed configuration files and will place resuilting build
+# files. E.g. if your project is named 'killerapp', Propel will 
+# look here for schema.xml and runtime-conf.xml files:
+# 
+#   projects/killerapp/
+#
+# -------------------------------------------------------------------
+
+# You can set this here, but it's preferrable to set this in a 
+# project-specific build.properties file.
+#
+# propel.project = bookstore
+
+# -------------------------------------------------------------------
+#
+#  T A R G E T  D A T A B A S E
+#
+# -------------------------------------------------------------------
+# This is the target database, only considered when generating
+# the SQL for your Propel project. Your possible choices are:
+#
+#   mssql, mysql, oracle, pgsql, sqlite
+# -------------------------------------------------------------------
+
+# You can set this here, but it's preferrable to set this in a 
+# project-specific build.properties file.
+#
+# propel.database = mysql
+
+# -------------------------------------------------------------------
+#
+#  O B J E C T  M O D E L  I N F O R M A T I O N
+#
+# -------------------------------------------------------------------
+# These settings will allow you to customize the way your
+# Peer-based object model is created.
+# -------------------------------------------------------------------
+# addGenericAccessors
+#   If true, Propel adds methods to get database fields by name/position.
+#
+# addGenericMutators
+#   If true, Propel adds methods to set database fields by name/position.
+#
+# addSaveMethod
+#   If true, Propel adds tracking code to determine how to save objects.
+#
+# addTimeStamp
+#   If true, Propel true puts time stamps in phpdoc of generated om files.
+#
+# basePrefix
+#   A string to pre-pend to the file names of base data and peer objects.
+#
+# complexObjectModel
+#   If true, Propel generates data objects with collection support and 
+#   methods to easily retreive foreign key relationships.
+#
+# targetPackage
+#   Sets the PHP "package" the om files will generated to, e.g. 
+#   "com.company.project.om".
+#
+# targetPlatform
+#   Sets whether Propel is building classes for php5 (default) 
+#   or php4 (experimental).
+#
+# packageObjectModel
+#   Sets whether Propel is packaging ObjectModel fro several 
+#   [package].schema.xml files. The <database package="packageName">
+#   attribute has to be set then. (warning: this is experimental!)
+#
+# -------------------------------------------------------------------
+
+# classes will be put in (and  included from) this directory
+# e.g. if package is "bookstore" then om will expect include('bookstore/Book.php'); to work.
+# use dot-path notation -- e.g. my.bookstore -> my/bookstore.
+#
+propel.targetPackage = ${propel.project}
+
+propel.addGenericAccessors = false
+propel.addGenericMutators = false
+propel.addSaveMethod = true
+propel.addTimeStamp = true
+propel.basePrefix = Base
+propel.complexObjectModel = true
+propel.targetPlatform = php5
+propel.packageObjectModel = false
+
+# -------------------------------------------------------------------
+#
+#  D B   C O N N E C T I O N   S E T T I N G S
+#
+# -------------------------------------------------------------------
+# Creole connection settings. These connection settings are used by
+# build tagets that perform database operations (e.g. 'insert-sql',
+# 'creole').
+#
+# You can set them here, but it's preferrable to set these properties
+# in a project-specific build.properties file.
+#
+
+# If you want to use a custom driver, specify it below, otherwise
+# leave it blank or comment it out to use Creole stock driver.
+#
+# propel.database.driver = creole.drivers.sqlite.SQLiteConnection
+
+# Note that if you do not wish to specify the database (e.g. if you
+# are using multiple databses) you can use the @DB@ token which
+# will be replaced with a database at runtime.
+#
+# propel.database.url = mysql://root@localhost/bookstore
+
+# For MySQL or Oracle, you also need to specify username & password 
+# propel.database.user = [db username]
+# propel.database.password = [db password]
+
+# Use the URL below to specify a DSN to used to create the database.
+# Note that this URL should not contain the database name, as you will
+# get an error if the database does not exist.
+# (This does not apply to SQLite since the databse is automatically created
+# when the connection is made -- if it does not already exist.)
+#
+# propel.database.createUrl = mysql://root@localhost/
+
+
+# -------------------------------------------------------------------
+#
+# C R E O L E  TO  X M L
+#
+# -------------------------------------------------------------------
+# These settings only applies to the 'creole' target.  
+# -------------------------------------------------------------------
+#
+# samePhpName 
+#   If true, the Creole task will set the phpName attribute for the 
+#   tables and columns to be the same as SQL name.
+#
+# addVendorInfo 
+#   If true, the Creole task will add vendor specific information 
+#   to the database schema
+#
+# addValidators 
+#   Bitfield like option to turn on/off addition of Validator and 
+#   Rule tags to the schema. Uses a boolean syntax like in php.ini.
+#   Allowed tokens are: 
+#      none       add no validators)
+#      all        add all validators)
+#      maxlength  add maxlengths for string type columns)
+#      maxvalue   add maxvalue for numeric columns)
+#      type       add notmatch validators for numeric columns)
+#      required   add required validators for required columns)
+#      unique     add unique validators for unique indexes)
+#   Allowed operators are: 
+#      &          bitwise AND 
+#      |          bitwise OR
+#      ~          bitwise NOT
+#
+# -------------------------------------------------------------------
+
+# propel.samePhpName = false
+# propel.addVendorInfo=true
+# propel.addValidators=none
+
+
+# -------------------------------------------------------------------
+#
+#  D A T A B A S E   B U I L D   C O N F I G
+#
+# -------------------------------------------------------------------
+# Some databases provide some configuration options that can be set
+# in this script.  
+#
+# === MySQL
+# propel.mysql.tableType
+#   Use this property to set the table type of generated tables (e.g. InnoDB, MyISAM).
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/build.xml
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/build.xml	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/build.xml	(revision 19)
@@ -0,0 +1,188 @@
+<!--
+    Use this file to faciliate easy per-project building.
+    
+    Simply create a build.properties file in your project directory,
+    for example ./projects/bookstore/build.properties, that contains
+    any needed (i.e. to override) values for that project.
+    
+    Call this build script and specify the name of the project and
+    (optionally) the name of the target you wish to execute (default is
+    'main' target) of build-propel.xml.
+
+    Normal use:
+    $> phing   -Dproject=bookstore
+    
+    Specific target: 
+    $> phing -Dproject=bookstore -Dtarget=insert-sql
+
+-->
+<project name="propel-project-builder" default="main" basedir=".">
+
+<!-- in case ${project.dir} was specified on command line, we set the project.dir
+     property here.  If it wasn't set, then this will be bogus, but it will
+     be overridden by the "set-project-dir" target. -->    
+<resolvepath propertyName="propel.project.dir" file="${project.dir}" dir="${application.startdir}"/>
+
+<!-- set a default target if none provided -->
+<property name="target" value="main"/>
+
+<!-- Set a default name for the build.properties file.
+		This allows for overriding the name of the build.properties file; however,
+		Propel still expects to find the file in the ${propel.project.dir}.
+ -->
+<property name="build.properties" value="build.properties"/>
+	
+<target name="check-buildprops-exists">
+  <available file="${propel.project.dir}/${build.properties}" property="projBuildPopertiesExists"/>  
+</target>
+
+<target name="check-buildprops" unless="projBuildPopertiesExists" depends="check-buildprops-exists">
+		<echo message="====================================================="/>
+		<echo message="Could not open ${build.properties} file:"/>
+		<echo message="		${propel.project.dir}/${build.properties}"/>
+		<echo message=" "/>
+		<echo message="Make sure that '${propel.project.dir}' is a valid path"/>
+		<echo message="and that it contains a ${build.properties} file."/>
+		<echo message="====================================================="/>	
+		
+		<fail message="Missing configuration file (see description above)."/>
+</target>
+
+<target name="check-project-or-dir-set">
+  <condition property="projectOrDirSet">
+  		<or>
+			<isset property="project"/>
+			<isset property="project.dir"/>
+		</or>
+  </condition>
+</target>
+
+<target name="check-buildprops-for-propel-gen" if="using.propel-gen" unless="projBuildPopertiesExists" depends="check-buildprops-exists">
+	<echo message="=========================================================="/>
+	<echo message="Could not open ${build.properties} file:"/>
+	<echo message="		${propel.project.dir}/${build.properties}"/>
+	<echo message=" "/>
+	<echo message="Project directory not specified or invalid. You must "/>
+	<echo message="specify the path to your project directory and your "/>
+	<echo message="project directory must contain your ${build.properties} "/>
+	<echo message="and schema.xml files.                                "/>
+	<echo message=" "/>
+	<echo message="Usage: "/>
+	<echo message=" "/>
+	<echo message="$&gt; propel-gen /path/to/projectdir [target]"/>
+	<echo message=" "/>
+	<echo message="=========================================================="/>	
+	<fail message="No project directory specified."/>
+</target>
+
+<target name="check-project-set" unless="projectOrDirSet" depends="check-project-or-dir-set">
+		<echo message="====================================================="/>
+		<echo message="Project not specified. You must enter a project name. "/>
+		<echo message="In the future you can enter it on the command line: "/>
+		<echo message=" "/>
+		<echo message="-Dproject=bookstore"/>
+		<echo message=" "/>
+		<echo message="This will attempt to find your project directory in"/>
+		<echo message="the default directory (./projects/bookstore)."/>
+		<echo message=" "/>
+		<echo message="You can also avoid this message and specicfy a custom "/>
+		<echo message="directory, using the project.dir property:"/>
+		<echo message=" "/>
+		<echo message="-Dproject.dir=/path/to/bookstore"/>
+		<echo message="====================================================="/>	
+		<input propertyname="project" promptChar=":">Project name</input>
+		<property name="propel.project" value="${project}" override="true"/>
+</target>
+
+<target name="set-project-dir" unless="project.dir" depends="check-project-set">
+	<echo>No project.dir was specified, using default path: ./projects/${project}</echo>
+	<property name="propel.project.dir" value="./projects/${project}" override="true"/>
+</target>
+
+<target name="configure" depends="set-project-dir,check-buildprops-for-propel-gen,check-buildprops">
+	<if>
+		<isset property="additional.properties"/>
+		<then>
+			<echo>Processing additional properties file: ${additional.properties}</echo>
+			<resolvepath propertyName="additional.properties.resolved" file="${additional.properties}" dir="${application.startdir}"/>
+			<property file="${additional.properties.resolved}"/>
+		</then>
+	</if>
+	<echo msg="Loading project-specific props from ${propel.project.dir}/${build.properties}"/>
+	<property file="${propel.project.dir}/${build.properties}"/>
+</target>
+
+<target name="main" depends="configure" description="The main target. Includes project-specific build.properties and calls the build-propel.xml script">
+
+ <phing phingfile="./build-propel.xml" target="${target}"/>
+ 
+</target>
+
+<!-- 
+ Convenience mappings to build-propel.xml main targets 
+ 
+ This makes it possible to use this buildfile w/o needing to specify
+ target as a property, e.g.:
+ 
+ $> phing -Dproject=bookstore insert-sql
+ 
+ The main reason for this is just consistency w/ old build-propel.xml file
+ (primarily for documentation & user confusion avoidance reasons).  There are relatively
+ few & infrequently changing main targets of build-propel.xml, so it's a non-
+ issue as far as maintenance is concerned.
+-->
+
+<target name="convert-conf" depends="configure">
+	<phing phingfile="build-propel.xml" target="convert-conf"/>
+</target>
+
+<target name="create-db" depends="configure">
+	<phing phingfile="build-propel.xml" target="create-db"/>
+</target>
+
+<target name="creole" depends="configure">
+	<phing phingfile="build-propel.xml" target="creole"/>
+</target>
+
+<target name="reverse" depends="configure">
+	<phing phingfile="build-propel.xml" target="reverse"/>
+</target>
+
+<target name="datadtd" depends="configure">
+	<phing phingfile="build-propel.xml" target="datadtd"/>
+</target>
+
+<target name="datadump" depends="configure">
+	<phing phingfile="build-propel.xml" target="datadump"/>
+</target>
+
+<target name="datasql" depends="configure">
+	<phing phingfile="build-propel.xml" target="datasql"/>
+</target>
+
+<target name="insert-sql" depends="configure">
+	<phing phingfile="build-propel.xml" target="insert-sql"/>
+</target>
+
+<target name="om" depends="configure">
+	<phing phingfile="build-propel.xml" target="om"/>
+</target>
+
+<target name="new-om" depends="configure">
+	<phing phingfile="build-propel.xml" target="new-om"/>
+</target>
+
+<target name="sql" depends="configure">
+	<phing phingfile="build-propel.xml" target="sql"/>
+</target>
+
+<target name="old-sql" depends="configure">
+	<phing phingfile="build-propel.xml" target="old-sql"/>
+</target>
+
+<target name="graphviz" depends="configure">
+	<phing phingfile="build-propel.xml" target="graphviz"/>
+</target>
+
+
+</project>
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/build.xml-local
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/build.xml-local	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/build.xml-local	(revision 19)
@@ -0,0 +1,124 @@
+<!--
+    Use this file to faciliate easy per-project building.
+    
+    Simply create a build.properties file in this directory,
+    that contains any needed (i.e. to override) values for this project.
+    
+    Call this build script and specify the name of the project and
+    (optionally) the name of the target you wish to execute (default is
+    'main' target) of build-propel.xml.
+
+    Normal use:
+    $> phing
+    
+    Specific target: 
+    $> phing -Dtarget=insert-sql
+
+-->
+<project name="propel-project-builder" default="main" basedir=".">
+
+<!-- set to this dir -->    
+<property name="project.dir" value="."/>
+
+<!-- set a default target if none provided -->
+<property name="target" value="main"/>
+
+<target name="buildpropescheck">
+  <available file="./build.properties" property="projBuildPopertiesExists"/>  
+</target>
+
+<target name="init">
+	<echo msg="Loading project-specific props from ./build.properties"/>
+	<property file="./build.properties"/>
+</target>
+
+<target name="checkproject" unless="propel.project">
+    <fail msg="Build failed. Please make sure that propel.project is set to your project-name in local build.properties"/>
+</target>
+<target name="checkhome" unless="propel.home">
+    <fail msg="Build failed. Please make sure that propel.home is set to the propel-generator-dir in local build.properties"/>
+</target>
+<target name="checkschemadir" unless="propel.schema.dir">
+    <fail msg="Build failed. Please make sure that propel.schema.dir is set to '.' in local build.properties"/>
+</target>
+<target name="checkconfdir" unless="propel.conf.dir">
+    <fail msg="Build failed. Please make sure that propel.conf.dir is set to '.' in local build.properties"/>
+</target>
+<target name="checkoutputdir" unless="propel.output.dir">
+    <fail msg="Build failed. Please make sure that propel.output.dir is set to a directory of your choice (e.g. './build/') local build.properties"/>
+</target>
+<target name="configure" depends="init,checkproject,checkhome,checkschemadir,checkconfdir,checkoutputdir">
+    <property name="project" value="{$propel.project}"/>
+</target>
+
+<target name="main" depends="configure" 
+  description="The main target. Includes project-specific build.properties and calls the build-propel.xml script">	
+
+ <phing phingfile="${propel.home}/build-propel.xml" target="${target}"/>
+ 
+</target>
+
+<!-- 
+ Convenience mappings to build-propel.xml main targets 
+ 
+ This makes it possible to use this buildfile w/o needing to specify
+ target as a property, e.g.:
+ 
+ $> phing -Dproject=bookstore insert-sql
+ 
+ The main reason for this is just consistency w/ old build-propel.xml file
+ (primarily for documentation & user confusion avoidance reasons).  There are relatively
+ few & infrequently changing main targets of build-propel.xml, so it's a non-
+ issue as far as maintenance is concerned.
+-->
+
+<target name="convert-props" depends="configure">
+	<phing phingfile="${propel.home}/build-propel.xml" target="convert-props"/>
+</target>
+
+<target name="create-db" depends="configure">
+	<phing phingfile="${propel.home}/build-propel.xml" target="create-db"/>
+</target>
+
+<target name="creole" depends="configure">
+	<phing phingfile="${propel.home}/build-propel.xml" target="creole"/>
+</target>
+
+<target name="datadtd" depends="configure">
+	<phing phingfile="${propel.home}/build-propel.xml" target="datadtd"/>
+</target>
+
+<target name="datadump" depends="configure">
+	<phing phingfile="${propel.home}/build-propel.xml" target="datadump"/>
+</target>
+
+<target name="datasql" depends="configure">
+	<phing phingfile="${propel.home}/build-propel.xml" target="datasql"/>
+</target>
+
+<target name="insert-sql" depends="configure">
+	<phing phingfile="${propel.home}/build-propel.xml" target="insert-sql"/>
+</target>
+
+<target name="om" depends="configure">
+	<phing phingfile="${propel.home}/build-propel.xml" target="om"/>
+</target>
+
+<target name="new-om" depends="configure">
+	<phing phingfile="${propel.home}/build-propel.xml" target="new-om"/>
+</target>
+
+<target name="sql" depends="configure">
+	<phing phingfile="${propel.home}/build-propel.xml" target="sql"/>
+</target>
+
+<target name="old-sql" depends="configure">
+	<phing phingfile="${propel.home}/build-propel.xml" target="old-sql"/>
+</target>
+
+<target name="graphviz" depends="configure">
+	<phing phingfile="${propel.home}/build-propel.xml" target="graphviz"/>
+</target>
+
+
+</project>
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/EngineException.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/EngineException.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/EngineException.php	(revision 19)
@@ -0,0 +1,33 @@
+<?php
+/*
+ *  $Id: EngineException.php 521 2007-01-05 13:29:36Z heltem $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://propel.phpdb.org>.
+ */
+
+require_once 'phing/BuildException.php';
+
+/**
+ * The base class of all exceptions thrown by the engine.
+ *
+ * @author     Hans Lellelid <hans@xmpl.org> (Propel)
+ * @author     Daniel Rall <dlr@collab.net> (Torque)
+ * @author     Jason van Zyl <jvz@apache.org> (Torque)
+ * @version    $Revision: 521 $
+ * @package    propel.engine
+ */
+class EngineException extends BuildException {}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/GeneratorConfig.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/GeneratorConfig.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/GeneratorConfig.php	(revision 19)
@@ -0,0 +1,211 @@
+<?php
+
+/*
+ *  $Id: GeneratorConfig.php 989 2008-03-11 14:29:30Z heltem $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://propel.phpdb.org>.
+ */
+
+/**
+ * A class that holds build properties and provide a class loading mechanism for the generator.
+ *
+ * @author     Hans Lellelid <hans@xmpl.org>
+ * @package    propel.engine
+ */
+class GeneratorConfig {
+
+	/**
+	 * The build properties.
+	 *
+	 * @var        array
+	 */
+	private $buildProperties = array();
+
+	/**
+	 * Construct a new GeneratorConfig.
+	 * @param      mixed $props Array or Iterator
+	 */
+	public function __construct($props = null)
+	{
+		if ($props) $this->setBuildProperties($props);
+	}
+
+	/**
+	 * Gets the build properties.
+	 * @return     array
+	 */
+	public function getBuildProperties()
+	{
+		return $this->buildProperties;
+	}
+
+	/**
+	 * Parses the passed-in properties, renaming and saving eligible properties in this object.
+	 *
+	 * Renames the propel.xxx properties to just xxx and renames any xxx.yyy properties
+	 * to xxxYyy as PHP doesn't like the xxx.yyy syntax.
+	 *
+	 * @param      mixed $props Array or Iterator
+	 */
+	public function setBuildProperties($props)
+	{
+		$this->buildProperties = array();
+
+		$renamedPropelProps = array();
+		foreach ($props as $key => $propValue) {
+			if (strpos($key, "propel.") === 0) {
+				$newKey = substr($key, strlen("propel."));
+				$j = strpos($newKey, '.');
+				while ($j !== false) {
+					$newKey =  substr($newKey, 0, $j) . ucfirst(substr($newKey, $j + 1));
+					$j = strpos($newKey, '.');
+				}
+				$this->setBuildProperty($newKey, $propValue);
+			}
+		}
+	}
+
+	/**
+	 * Gets a specific propel (renamed) property from the build.
+	 *
+	 * @param      string $name
+	 * @return     mixed
+	 */
+	public function getBuildProperty($name)
+	{
+		return isset($this->buildProperties[$name]) ? $this->buildProperties[$name] : null;
+	}
+
+	/**
+	 * Sets a specific propel (renamed) property from the build.
+	 *
+	 * @param      string $name
+	 * @param      mixed $value
+	 */
+	public function setBuildProperty($name, $value)
+	{
+		$this->buildProperties[$name] = $value;
+	}
+
+	/**
+	 * Resolves and returns the class name based on the specified property value.
+	 *
+	 * @param      string $propname The name of the property that holds the class path (dot-path notation).
+	 * @return     string The class name.
+	 * @throws     BuildException If the classname cannot be determined or class cannot be loaded.
+	 */
+	public function getClassname($propname)
+	{
+		$classpath = $this->getBuildProperty($propname);
+		if (empty($classpath)) {
+			throw new BuildException("Unable to find class path for '$propname' property.");
+		}
+
+		// This is a slight hack to workaround camel case inconsistencies for the DDL classes.
+		// Basically, we want to turn ?.?.?.sqliteDDLBuilder into ?.?.?.SqliteDDLBuilder
+		$lastdotpos = strrpos($classpath, '.');
+		if ($lastdotpos !== null) {
+			$classpath{$lastdotpos+1} = strtoupper($classpath{$lastdotpos+1});
+		} else {
+			$classpath = ucfirst($classpath);
+		}
+
+		if (empty($classpath)) {
+			throw new BuildException("Unable to find class path for '$propname' property.");
+		}
+
+		$clazz = Phing::import($classpath);
+
+		return $clazz;
+	}
+
+	/**
+	 * Resolves and returns the builder class name.
+	 *
+	 * @param      string $type
+	 * @return     string The class name.
+	 */
+	public function getBuilderClassname($type)
+	{
+		$propname = 'builder' . ucfirst(strtolower($type)) . 'Class';
+		return $this->getClassname($propname);
+	}
+
+	/**
+	 * Creates and configures a new Platform class.
+	 *
+	 * @param      PDO $con
+	 * @return     Platform
+	 */
+	public function getConfiguredPlatform(PDO $con = null)
+	{
+		$clazz = $this->getClassname("platformClass");
+		$platform = new $clazz();
+
+		if (!$platform instanceof Platform) {
+			throw new BuildException("Specified platform class ($clazz) does not implement Platform interface.", $this->getLocation());
+		}
+
+		$platform->setConnection($con);
+		$platform->setGeneratorConfig($this);
+		return $platform;
+	}
+
+	/**
+	 * Creates and configures a new SchemaParser class for specified platform.
+	 * @param      PDO $con
+	 * @return     SchemaParser
+	 */
+	public function getConfiguredSchemaParser(PDO $con = null)
+	{
+		$clazz = $this->getClassname("reverseParserClass");
+		$parser = new $clazz();
+		if (!$parser instanceof SchemaParser) {
+			throw new BuildException("Specified platform class ($clazz) does implement SchemaParser interface.", $this->getLocation());
+		}
+		$parser->setConnection($con);
+		$parser->setGeneratorConfig($this);
+		return $parser;
+	}
+
+	/**
+	 * Gets a configured data model builder class for specified table and based on type.
+	 *
+	 * @param      Table $table
+	 * @param      string $type The type of builder ('ddl', 'sql', etc.)
+	 * @return     DataModelBuilder
+	 */
+	public function getConfiguredBuilder(Table $table, $type, $cache = true)
+	{
+		$classname = $this->getBuilderClassname($type);
+		$builder = new $classname($table);
+		$builder->setGeneratorConfig($this);
+		return $builder;
+	}
+
+	/**
+	 * Gets a configured Pluralizer class.
+	 *
+	 * @return     Pluralizer
+	 */
+	public function getConfiguredPluralizer()
+	{
+		$classname = $this->getBuilderClassname('pluralizer');
+		$pluralizer = new $classname();
+		return $pluralizer;
+	}
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/builder/DataModelBuilder.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/builder/DataModelBuilder.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/builder/DataModelBuilder.php	(revision 19)
@@ -0,0 +1,514 @@
+<?php
+
+/*
+ *  $Id: DataModelBuilder.php 989 2008-03-11 14:29:30Z heltem $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://propel.phpdb.org>.
+ */
+
+
+/**
+ * This is the base class for any builder class that is using the data model.
+ *
+ * This could be extended by classes that build SQL DDL, PHP classes, configuration
+ * files, input forms, etc.
+ *
+ * The GeneratorConfig needs to be set on this class in order for the builders
+ * to be able to access the propel generator build properties.  You should be
+ * safe if you always use the GeneratorConfig to get a configured builder class
+ * anyway.
+ *
+ * @author     Hans Lellelid <hans@xmpl.org>
+ * @package    propel.engine.builder
+ */
+abstract class DataModelBuilder {
+
+	/**
+	 * The current table.
+	 * @var        Table
+	 */
+	private $table;
+
+	/**
+	 * The generator config object holding build properties, etc.
+	 *
+	 * @var        GeneratorConfig
+	 */
+	private $generatorConfig;
+
+	/**
+	 * An array of warning messages that can be retrieved for display (e.g. as part of phing build process).
+	 * @var        array string[]
+	 */
+	private $warnings = array();
+
+	/**
+	 * Peer builder class for current table.
+	 * @var        DataModelBuilder
+	 */
+	private $peerBuilder;
+
+	/**
+	 * Stub Peer builder class for current table.
+	 * @var        DataModelBuilder
+	 */
+	private $stubPeerBuilder;
+
+	/**
+	 * Object builder class for current table.
+	 * @var        DataModelBuilder
+	 */
+	private $objectBuilder;
+
+	/**
+	 * Stub Object builder class for current table.
+	 * @var        DataModelBuilder
+	 */
+	private $stubObjectBuilder;
+
+	/**
+	 * MapBuilder builder class for current table.
+	 * @var        DataModelBuilder
+	 */
+	private $mapBuilderBuilder;
+
+	/**
+	 * Stub Interface builder class for current table.
+	 * @var        DataModelBuilder
+	 */
+	private $interfaceBuilder;
+
+	/**
+	 * Stub child object for current table.
+	 * @var        DataModelBuilder
+	 */
+	private $multiExtendObjectBuilder;
+
+	/**
+	 * Node object builder for current table.
+	 * @var        DataModelBuilder
+	 */
+	private $nodeBuilder;
+
+	/**
+	 * Node peer builder for current table.
+	 * @var        DataModelBuilder
+	 */
+	private $nodePeerBuilder;
+
+	/**
+	 * Stub node object builder for current table.
+	 * @var        DataModelBuilder
+	 */
+	private $stubNodeBuilder;
+
+	/**
+	 * Stub node peer builder for current table.
+	 * @var        DataModelBuilder
+	 */
+	private $stubNodePeerBuilder;
+
+	/**
+	 * NestedSet object builder for current table.
+	 * @var        DataModelBuilder
+	 */
+	private $nestedSetBuilder;
+
+	/**
+	 * NestedSet peer builder for current table.
+	 * @var        DataModelBuilder
+	 */
+	private $nestedSetPeerBuilder;
+
+	/**
+	 * The DDL builder for current table.
+	 * @var        DDLBuilder
+	 */
+	private $ddlBuilder;
+
+	/**
+	 * The Data-SQL builder for current table.
+	 * @var        DataSQLBuilder
+	 */
+	private $dataSqlBuilder;
+
+	/**
+	 * The Pluralizer class to use.
+	 * @var        Pluralizer
+	 */
+	private $pluralizer;
+
+
+	/**
+	 * Creates new instance of DataModelBuilder subclass.
+	 * @param      Table $table The Table which we are using to build [OM, DDL, etc.].
+	 */
+	public function __construct(Table $table)
+	{
+		$this->table = $table;
+	}
+
+	/**
+	 * Returns new or existing Peer builder class for this table.
+	 * @return     PeerBuilder
+	 */
+	public function getPeerBuilder()
+	{
+		if (!isset($this->peerBuilder)) {
+			$this->peerBuilder = $this->getGeneratorConfig()->getConfiguredBuilder($this->getTable(), 'peer');
+		}
+		return $this->peerBuilder;
+	}
+
+	/**
+	 * Returns new or existing Pluralizer class.
+	 * @return     Pluralizer
+	 */
+	public function getPluralizer()
+	{
+		if (!isset($this->pluralizer)) {
+			$this->pluralizer = $this->getGeneratorConfig()->getConfiguredPluralizer();
+		}
+		return $this->pluralizer;
+	}
+
+	/**
+	 * Returns new or existing stub Peer builder class for this table.
+	 * @return     PeerBuilder
+	 */
+	public function getStubPeerBuilder()
+	{
+		if (!isset($this->stubPeerBuilder)) {
+			$this->stubPeerBuilder = $this->getGeneratorConfig()->getConfiguredBuilder($this->getTable(), 'peerstub');
+		}
+		return $this->stubPeerBuilder;
+	}
+
+	/**
+	 * Returns new or existing Object builder class for this table.
+	 * @return     ObjectBuilder
+	 */
+	public function getObjectBuilder()
+	{
+		if (!isset($this->objectBuilder)) {
+			$this->objectBuilder = $this->getGeneratorConfig()->getConfiguredBuilder($this->getTable(), 'object');
+		}
+		return $this->objectBuilder;
+	}
+
+	/**
+	 * Returns new or existing stub Object builder class for this table.
+	 * @return     ObjectBuilder
+	 */
+	public function getStubObjectBuilder()
+	{
+		if (!isset($this->stubObjectBuilder)) {
+			$this->stubObjectBuilder = $this->getGeneratorConfig()->getConfiguredBuilder($this->getTable(), 'objectstub');
+		}
+		return $this->stubObjectBuilder;
+	}
+
+	/**
+	 * Returns new or existing MapBuilder builder class for this table.
+	 * @return     ObjectBuilder
+	 */
+	public function getMapBuilderBuilder()
+	{
+		if (!isset($this->mapBuilderBuilder)) {
+			$this->mapBuilderBuilder = $this->getGeneratorConfig()->getConfiguredBuilder($this->getTable(), 'mapbuilder');
+		}
+		return $this->mapBuilderBuilder;
+	}
+
+	/**
+	 * Returns new or existing stub Interface builder class for this table.
+	 * @return     ObjectBuilder
+	 */
+	public function getInterfaceBuilder()
+	{
+		if (!isset($this->interfaceBuilder)) {
+			$this->interfaceBuilder = $this->getGeneratorConfig()->getConfiguredBuilder($this->getTable(), 'interface');
+		}
+		return $this->interfaceBuilder;
+	}
+
+	/**
+	 * Returns new or existing stub child object builder class for this table.
+	 * @return     ObjectBuilder
+	 */
+	public function getMultiExtendObjectBuilder()
+	{
+		if (!isset($this->multiExtendObjectBuilder)) {
+			$this->multiExtendObjectBuilder = $this->getGeneratorConfig()->getConfiguredBuilder($this->getTable(), 'objectmultiextend');
+		}
+		return $this->multiExtendObjectBuilder;
+	}
+
+	/**
+	 * Returns new or existing node Object builder class for this table.
+	 * @return     ObjectBuilder
+	 */
+	public function getNodeBuilder()
+	{
+		if (!isset($this->nodeBuilder)) {
+			$this->nodeBuilder = $this->getGeneratorConfig()->getConfiguredBuilder($this->getTable(), 'node');
+		}
+		return $this->nodeBuilder;
+	}
+
+	/**
+	 * Returns new or existing node Peer builder class for this table.
+	 * @return     PeerBuilder
+	 */
+	public function getNodePeerBuilder()
+	{
+		if (!isset($this->nodePeerBuilder)) {
+			$this->nodePeerBuilder = $this->getGeneratorConfig()->getConfiguredBuilder($this->getTable(), 'nodepeer');
+		}
+		return $this->nodePeerBuilder;
+	}
+
+	/**
+	 * Returns new or existing stub node Object builder class for this table.
+	 * @return     ObjectBuilder
+	 */
+	public function getStubNodeBuilder()
+	{
+		if (!isset($this->stubNodeBuilder)) {
+			$this->stubNodeBuilder = $this->getGeneratorConfig()->getConfiguredBuilder($this->getTable(), 'nodestub');
+		}
+		return $this->stubNodeBuilder;
+	}
+
+	/**
+	 * Returns new or existing stub node Peer builder class for this table.
+	 * @return     PeerBuilder
+	 */
+	public function getStubNodePeerBuilder()
+	{
+		if (!isset($this->stubNodePeerBuilder)) {
+			$this->stubNodePeerBuilder = $this->getGeneratorConfig()->getConfiguredBuilder($this->getTable(), 'nodepeerstub');
+		}
+		return $this->stubNodePeerBuilder;
+	}
+
+	/**
+	 * Returns new or existing nested set object builder class for this table.
+	 * @return     ObjectBuilder
+	 */
+	public function getNestedSetBuilder()
+	{
+		if (!isset($this->nestedSetBuilder)) {
+			$this->nestedSetBuilder = $this->getGeneratorConfig()->getConfiguredBuilder($this->getTable(), 'nestedset');
+		}
+		return $this->nestedSetBuilder;
+	}
+
+	/**
+	 * Returns new or existing nested set Peer builder class for this table.
+	 * @return     PeerBuilder
+	 */
+	public function getNestedSetPeerBuilder()
+	{
+		if (!isset($this->nestedSetPeerBuilder)) {
+			$this->nestedSetPeerBuilder = $this->getGeneratorConfig()->getConfiguredBuilder($this->getTable(), 'nestedsetpeer');
+		}
+		return $this->nestedSetPeerBuilder;
+	}
+
+	/**
+	 * Returns new or existing ddl builder class for this table.
+	 * @return     DDLBuilder
+	 */
+	public function getDDLBuilder()
+	{
+		if (!isset($this->ddlBuilder)) {
+			$this->ddlBuilder = $this->getGeneratorConfig()->getConfiguredBuilder($this->getTable(), 'ddl');
+		}
+		return $this->ddlBuilder;
+	}
+
+	/**
+	 * Returns new or existing data sql builder class for this table.
+	 * @return     DataSQLBuilder
+	 */
+	public function getDataSQLBuilder()
+	{
+		if (!isset($this->dataSqlBuilder)) {
+			$this->dataSqlBuilder = $this->getGeneratorConfig()->getConfiguredBuilder($this->getTable(), 'datasql');
+		}
+		return $this->dataSqlBuilder;
+	}
+
+	/**
+	 * Convenience method to return a NEW Peer class builder instance
+	 * .
+	 * This is used very frequently from the peer and object builders to get
+	 * a peer builder for a RELATED table.
+	 *
+	 * @param      Table $table
+	 * @return     PeerBuilder
+	 */
+	public function getNewPeerBuilder(Table $table)
+	{
+		return $this->getGeneratorConfig()->getConfiguredBuilder($table, 'peer');
+	}
+
+	/**
+	 * Convenience method to return a NEW Object class builder instance.
+	 *
+	 * This is used very frequently from the peer and object builders to get
+	 * an object builder for a RELATED table.
+	 *
+	 * @param      Table $table
+	 * @return     ObjectBuilder
+	 */
+	public function getNewObjectBuilder(Table $table)
+	{
+		return $this->getGeneratorConfig()->getConfiguredBuilder($table, 'object');
+	}
+
+	/**
+	 * Gets the GeneratorConfig object.
+	 *
+	 * @return     GeneratorConfig
+	 */
+	public function getGeneratorConfig()
+	{
+		return $this->generatorConfig;
+	}
+
+	/**
+	 * Get a specific [name transformed] build property.
+	 *
+	 * @param      string $name
+	 * @return     string
+	 */
+	public function getBuildProperty($name)
+	{
+		if ($this->getGeneratorConfig()) {
+			return $this->getGeneratorConfig()->getBuildProperty($name);
+		}
+		return null; // just to be explicit
+	}
+
+	/**
+	 * Sets the GeneratorConfig object.
+	 *
+	 * @param      GeneratorConfig $v
+	 */
+	public function setGeneratorConfig(GeneratorConfig $v)
+	{
+		$this->generatorConfig = $v;
+	}
+
+	/**
+	 * Sets the table for this builder.
+	 * @param      Table $table
+	 */
+	public function setTable(Table $table)
+	{
+		$this->table = $table;
+	}
+
+	/**
+	 * Returns the current Table object.
+	 * @return     Table
+	 */
+	public function getTable()
+	{
+		return $this->table;
+	}
+
+	/**
+	 * Convenience method to returns the Platform class for this table (database).
+	 * @return     Platform
+	 */
+	public function getPlatform()
+	{
+		if ($this->getTable() && $this->getTable()->getDatabase()) {
+			return $this->getTable()->getDatabase()->getPlatform();
+		}
+	}
+
+	/**
+	 * Convenience method to returns the database for current table.
+	 * @return     Database
+	 */
+	public function getDatabase()
+	{
+		if ($this->getTable()) {
+			return $this->getTable()->getDatabase();
+		}
+	}
+
+	/**
+	 * Pushes a message onto the stack of warnings.
+	 * @param      string $msg The warning message.
+	 */
+	protected function warn($msg)
+	{
+		$this->warnings[] = $msg;
+	}
+
+	/**
+	 * Gets array of warning messages.
+	 * @return     array string[]
+	 */
+	public function getWarnings()
+	{
+		return $this->warnings;
+	}
+
+	/**
+	 * Wraps call to Platform->quoteIdentifier() with a check to see whether quoting is enabled.
+	 *
+	 * All subclasses should call this quoteIdentifier() method rather than calling the Platform
+	 * method directly.  This method is used by both DataSQLBuilder and DDLBuilder, and potentially
+	 * in the OM builders also, which is why it is defined in this class.
+	 *
+	 * @param      string $text The text to quote.
+	 * @return     string Quoted text.
+	 */
+	public function quoteIdentifier($text)
+	{
+		if (!$this->getBuildProperty('disableIdentifierQuoting')) {
+			return $this->getPlatform()->quoteIdentifier($text);
+		}
+		return $text;
+	}
+
+	/**
+	 * Returns the name of the current class being built, with a possible prefix.
+	 * @return     string
+	 * @see        OMBuilder#getClassname()
+	 */
+	public function prefixClassname($identifier)
+	{
+		return $this->getBuildProperty('classPrefix') . $identifier;
+	}
+
+	/**
+	 * Returns the name of the current table being built, with a possible prefix.
+	 * @return     string
+	 */
+	public function prefixTablename($identifier)
+	{
+		return $this->getBuildProperty('tablePrefix') . $identifier;
+	}
+
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/builder/om/ClassTools.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/builder/om/ClassTools.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/builder/om/ClassTools.php	(revision 19)
@@ -0,0 +1,131 @@
+<?php
+/*
+ *  $Id: ClassTools.php 989 2008-03-11 14:29:30Z heltem $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://propel.phpdb.org>.
+ */
+
+
+ /**
+  * Tools to support class & package inclusion and referencing.
+  *
+  * @author     Hans Lellelid <hans@xmpl.org>
+  * @version    $Revision: 989 $
+  * @package    propel.engine.builder.om
+  */
+class ClassTools {
+
+	/**
+	 * Gets just classname, given a dot-path to class.
+	 * @param      string $qualifiedName
+	 * @return     string
+	 */
+	public static function classname($qualifiedName)
+	{
+		$pos = strrpos($qualifiedName, '.');
+		if ($pos === false) {
+			return $qualifiedName;  // there is no '.' in the qualifed name
+		} else {
+			return substr($qualifiedName, $pos + 1); // start just after '.'
+		}
+	}
+
+	/**
+	 * Gets the path to be used in include()/require() statement.
+	 *
+	 * Supports multiple function signatures:
+	 *
+	 * (1) getFilePath($dotPathClass);
+	 * (2) getFilePath($dotPathPrefix, $className);
+	 * (3) getFilePath($dotPathPrefix, $className, $extension);
+	 *
+	 * @param      string $path dot-path to class or to package prefix.
+	 * @param      string $classname class name
+	 * @param      string $extension The extension to use on the file.
+	 * @return     string The constructed file path.
+	 */
+	public static function getFilePath($path, $classname = null, $extension = '.php')
+	{
+		$path = strtr(ltrim($path, '.'), '.', '/');
+		if ($classname !== null) {
+			if ($path !== "") { $path .= '/'; }
+			return $path . $classname . $extension;
+		} else {
+			return $path . $extension;
+		}
+	}
+
+	/**
+	 * Gets the basePeer path if specified for table/db.
+	 * If not, will return 'propel.util.BasePeer'
+	 * @return     string
+	 */
+	public static function getBasePeer(Table $table) {
+		$class = $table->getBasePeer();
+		if ($class === null) {
+			$class = "propel.util.BasePeer";
+		}
+		return $class;
+	}
+
+	/**
+	 * Gets the baseClass path if specified for table/db.
+	 * If not, will return 'propel.om.BaseObject'
+	 * @return     string
+	 */
+	public static function getBaseClass(Table $table) {
+		$class = $table->getBaseClass();
+		if ($class === null) {
+			$class = "propel.om.BaseObject";
+		}
+		return $class;
+	}
+
+	/**
+	 * Gets the interface path if specified for table.
+	 * If not, will return 'propel.om.Persistent'.
+	 * @return     string
+	 */
+	public static function getInterface(Table $table) {
+		$interface = $table->getInterface();
+		if ($interface === null && !$table->isReadOnly()) {
+			$interface = "propel.om.Persistent";
+		}
+		return $interface;
+	}
+
+	/**
+	 * Gets a list of PHP reserved words.
+	 *
+	 * @return     array string[]
+	 */
+	public static function getPhpReservedWords()
+	{
+		return array(
+			'and', 'or', 'xor', 'exception', '__FILE__', '__LINE__',
+			'array', 'as', 'break', 'case', 'class', 'const', 'continue',
+			'declare', 'default', 'die', 'do', 'echo', 'else', 'elseif', 'empty',
+			'enddeclare', 'endfor', 'endforeach', 'endif', 'endswitch', 'endwhile',
+			'eval', 'exit', 'extends', 'for', 'foreach', 'function', 'global',
+			'if', 'include', 'include_once', 'isset', 'list', 'new', 'print', 'require',
+			'require_once', 'return', 'static', 'switch', 'unset', 'use', 'var', 'while',
+			'__FUNCTION__', '__CLASS__', '__METHOD__', 'final', 'php_user_filter', 'interface',
+			'implements', 'extends', 'public', 'protected', 'private', 'abstract', 'clone', 'try', 'catch',
+			'throw', 'this', 'namespace'
+		);
+	}
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/builder/om/OMBuilder.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/builder/om/OMBuilder.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/builder/om/OMBuilder.php	(revision 19)
@@ -0,0 +1,207 @@
+<?php
+
+/*
+ *  $Id: OMBuilder.php 989 2008-03-11 14:29:30Z heltem $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://propel.phpdb.org>.
+ */
+
+require_once 'propel/engine/builder/DataModelBuilder.php';
+
+/**
+ * Baseclass for OM-building classes.
+ *
+ * OM-building classes are those that build a PHP (or other) class to service
+ * a single table.  This includes Peer classes, Entity classes, Map classes,
+ * Node classes, Nested Set classes, etc.
+ *
+ * @author     Hans Lellelid <hans@xmpl.org>
+ * @package    propel.engine.builder.om
+ */
+abstract class OMBuilder extends DataModelBuilder {
+
+	/**
+	 * Builds the PHP source for current class and returns it as a string.
+	 *
+	 * This is the main entry point and defines a basic structure that classes should follow.
+	 * In most cases this method will not need to be overridden by subclasses.  This method
+	 * does assume that the output language is PHP code, so it will need to be overridden if
+	 * this is not the case.
+	 *
+	 * @return     string The resulting PHP sourcecode.
+	 */
+	public function build()
+	{
+		$this->validateModel();
+
+		$script = "<" . "?php\n"; // intentional concatenation
+		$this->addIncludes($script);
+		$this->addClassOpen($script);
+		$this->addClassBody($script);
+		$this->addClassClose($script);
+		return $script;
+	}
+
+	/**
+	 * Validates the current table to make sure that it won't
+	 * result in generated code that will not parse.
+	 *
+	 * This method may emit warnings for code which may cause problems
+	 * and will throw exceptions for errors that will definitely cause
+	 * problems.
+	 */
+	protected function validateModel()
+	{
+		// Validation is currently only implemented in the subclasses.
+	}
+
+	/**
+	 * Creates a $obj = new Book(); code snippet. Can be used by frameworks, for instance, to
+	 * extend this behavior, e.g. initialize the object after creating the instance or so.
+	 *
+	 * @return     string Some code
+	 */
+	public function buildObjectInstanceCreationCode($objName, $clsName)
+	{
+		return "$objName = new $clsName();";
+	}
+
+	/**
+	 * Returns the qualified (prefixed) classname that is being built by the current class.
+	 * This method must be implemented by child classes.
+	 * @return     string
+	 */
+	abstract public function getUnprefixedClassname();
+
+	/**
+	 * Returns the prefixed clasname that is being built by the current class.
+	 * @return     string
+	 * @see        DataModelBuilder#prefixClassname()
+	 */
+	public function getClassname()
+	{
+		return $this->prefixClassname($this->getUnprefixedClassname());
+	}
+	/**
+	 * Gets the dot-path representation of current class being built.
+	 * @return     string
+	 */
+	public function getClasspath()
+	{
+		if ($this->getPackage()) {
+			$path = $this->getPackage() . '.' . $this->getClassname();
+		} else {
+			$path = $this->getClassname();
+		}
+		return $path;
+	}
+
+	/**
+	 * Gets the full path to the file for the current class.
+	 * @return     string
+	 */
+	public function getClassFilePath()
+	{
+		return ClassTools::getFilePath($this->getPackage(), $this->getClassname());
+	}
+
+	/**
+	 * Gets package name for this table.
+	 * This is overridden by child classes that have different packages.
+	 * @return     string
+	 */
+	public function getPackage()
+	{
+		$pkg = ($this->getTable()->getPackage() ? $this->getTable()->getPackage() : $this->getDatabase()->getPackage());
+		if (!$pkg) {
+			$pkg = $this->getBuildProperty('targetPackage');
+		}
+		return $pkg;
+	}
+
+	/**
+	 * Returns filesystem path for current package.
+	 * @return     string
+	 */
+	public function getPackagePath()
+	{
+		return strtr($this->getPackage(), '.', '/');
+	}
+
+	/**
+	 * Shortcut method to return the [stub] peer classname for current table.
+	 * This is the classname that is used whenever object or peer classes want
+	 * to invoke methods of the peer classes.
+	 * @return     string (e.g. 'MyPeer')
+	 * @see        StubPeerBuilder::getClassname()
+	 */
+	public function getPeerClassname() {
+		return $this->getStubPeerBuilder()->getClassname();
+	}
+
+	/**
+	 * Returns the object classname for current table.
+	 * This is the classname that is used whenever object or peer classes want
+	 * to invoke methods of the object classes.
+	 * @return     string (e.g. 'My')
+	 * @see        StubPeerBuilder::getClassname()
+	 */
+	public function getObjectClassname() {
+		return $this->getStubObjectBuilder()->getClassname();
+	}
+
+	/**
+	 * Get the column constant name (e.g. PeerName::COLUMN_NAME).
+	 *
+	 * @param      Column $col The column we need a name for.
+	 * @param      string $classname The Peer classname to use.
+	 *
+	 * @return     string If $classname is provided, then will return $classname::COLUMN_NAME; if not, then the peername is looked up for current table to yield $currTablePeer::COLUMN_NAME.
+	 */
+	public function getColumnConstant($col, $classname = null)
+	{
+		if ($col === null) {
+			$e = new Exception("No col specified.");
+			print $e;
+			throw $e;
+		}
+		if ($classname === null) {
+			$classname = $this->getPeerClassname();
+		}
+		// was it overridden in schema.xml ?
+		if ($col->getPeerName()) {
+			$const = strtoupper($col->getPeerName());
+		} else {
+			$const = strtoupper($col->getName());
+		}
+		return $classname.'::'.$const;
+	}
+
+	/**
+	 * Gets the basePeer path if specified for table/db.
+	 * If not, will return 'propel.util.BasePeer'
+	 * @return     string
+	 */
+	public function getBasePeer(Table $table) {
+		$class = $table->getBasePeer();
+		if ($class === null) {
+			$class = "propel.util.BasePeer";
+		}
+		return $class;
+	}
+
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/builder/om/ObjectBuilder.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/builder/om/ObjectBuilder.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/builder/om/ObjectBuilder.php	(revision 19)
@@ -0,0 +1,151 @@
+<?php
+
+/*
+ *  $Id: ObjectBuilder.php 842 2007-12-02 16:28:20Z heltem $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://propel.phpdb.org>.
+ */
+
+require_once 'propel/engine/builder/om/OMBuilder.php';
+
+/**
+ * Base class for Peer-building classes.
+ *
+ * This class is designed so that it can be extended by a PHP4PeerBuilder in addition
+ * to the "standard" PHP5PeerBuilder and PHP5ComplexOMPeerBuilder.  Hence, this class
+ * should not have any actual template code in it -- simply basic logic & utility
+ * methods.
+ *
+ * @author     Hans Lellelid <hans@xmpl.org>
+ * @package    propel.engine.builder.om
+ */
+abstract class ObjectBuilder extends OMBuilder {
+
+	/**
+	 * Constructs a new PeerBuilder subclass.
+	 */
+	public function __construct(Table $table) {
+		parent::__construct($table);
+	}
+
+	/**
+	 * This method adds the contents of the generated class to the script.
+	 *
+	 * This method is abstract and should be overridden by the subclasses.
+	 *
+	 * Hint: Override this method in your subclass if you want to reorganize or
+	 * drastically change the contents of the generated peer class.
+	 *
+	 * @param      string &$script The script will be modified in this method.
+	 */
+	abstract protected function addClassBody(&$script);
+
+	/**
+	 * Adds the getter methods for the column values.
+	 * This is here because it is probably generic enough to apply to templates being generated
+	 * in different langauges (e.g. PHP4 and PHP5).
+	 * @param      string &$script The script will be modified in this method.
+	 */
+	protected function addColumnAccessorMethods(&$script)
+	{
+		$table = $this->getTable();
+
+		foreach ($table->getColumns() as $col) {
+
+			// if they're not using the DateTime class than we will generate "compatibility" accessor method
+			if ($col->getType() === PropelTypes::DATE || $col->getType() === PropelTypes::TIME || $col->getType() === PropelTypes::TIMESTAMP) {
+				$this->addTemporalAccessor($script, $col);
+			} else {
+				$this->addDefaultAccessor($script, $col);
+			}
+
+			if ($col->isLazyLoad()) {
+				$this->addLazyLoader($script, $col);
+			}
+		}
+	}
+
+	/**
+	 * Adds the mutator (setter) methods for setting column values.
+	 * This is here because it is probably generic enough to apply to templates being generated
+	 * in different langauges (e.g. PHP4 and PHP5).
+	 * @param      string &$script The script will be modified in this method.
+	 */
+	protected function addColumnMutatorMethods(&$script)
+	{
+		foreach ($this->getTable()->getColumns() as $col) {
+
+			if ($col->isLobType()) {
+				$this->addLobMutator($script, $col);
+			} elseif ($col->getType() === PropelTypes::DATE || $col->getType() === PropelTypes::TIME || $col->getType() === PropelTypes::TIMESTAMP) {
+				$this->addTemporalMutator($script, $col);
+			} else {
+				$this->addDefaultMutator($script, $col);
+			}
+		}
+	}
+
+
+	/**
+	 * Gets the baseClass path if specified for table/db.
+	 * If not, will return 'propel.om.BaseObject'
+	 * @return     string
+	 */
+	protected function getBaseClass() {
+		$class = $this->getTable()->getBaseClass();
+		if ($class === null) {
+			$class = "propel.om.BaseObject";
+		}
+		return $class;
+	}
+
+	/**
+	 * Gets the interface path if specified for current table.
+	 * If not, will return 'propel.om.Persistent'.
+	 * @return     string
+	 */
+	protected function getInterface() {
+		$interface = $this->getTable()->getInterface();
+		if ($interface === null && !$this->getTable()->isReadOnly()) {
+			$interface = "propel.om.Persistent";
+		}
+		return $interface;
+	}
+
+	/**
+	 * Whether to add the generic mutator methods (setByName(), setByPosition(), fromArray()).
+	 * This is based on the build property propel.addGenericMutators, and also whether the
+	 * table is read-only or an alias.
+	 */
+	protected function isAddGenericMutators()
+	{
+		$table = $this->getTable();
+		return (!$table->isAlias() && $this->getBuildProperty('addGenericMutators') && !$table->isReadOnly());
+	}
+
+	/**
+	 * Whether to add the generic accessor methods (getByName(), getByPosition(), toArray()).
+	 * This is based on the build property propel.addGenericAccessors, and also whether the
+	 * table is an alias.
+	 */
+	protected function isAddGenericAccessors()
+	{
+		$table = $this->getTable();
+		return (!$table->isAlias() && $this->getBuildProperty('addGenericAccessors'));
+	}
+
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/builder/om/PeerBuilder.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/builder/om/PeerBuilder.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/builder/om/PeerBuilder.php	(revision 19)
@@ -0,0 +1,278 @@
+<?php
+
+/*
+ *  $Id: PeerBuilder.php 989 2008-03-11 14:29:30Z heltem $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://propel.phpdb.org>.
+ */
+
+require_once 'propel/engine/builder/om/OMBuilder.php';
+
+/**
+ * Base class for Peer-building classes.
+ *
+ * This class is designed so that it can be extended by a PHP4PeerBuilder in addition
+ * to the "standard" PHP5PeerBuilder and PHP5ComplexOMPeerBuilder.  Hence, this class
+ * should not have any actual template code in it -- simply basic logic & utility
+ * methods.
+ *
+ * @author     Hans Lellelid <hans@xmpl.org>
+ * @package    propel.engine.builder.om
+ */
+abstract class PeerBuilder extends OMBuilder {
+
+	protected $basePeerClass;
+	protected $basePeerClassname;
+
+	/**
+	 * Constructs a new PeerBuilder subclass.
+	 */
+	public function __construct(Table $table) {
+		parent::__construct($table);
+		$this->basePeerClassname = $this->basePeerClass = $this->getBasePeer($table);
+		$pos = strrpos($this->basePeerClassname, '.');
+		if ($pos !== false) {
+			$this->basePeerClassname = substr($this->basePeerClassname, $pos + 1);
+		}
+	}
+
+	/**
+	 * Adds the addSelectColumns(), doCount(), etc. methods.
+	 * @param      string &$script The script will be modified in this method.
+	 */
+	protected function addSelectMethods(&$script)
+	{
+		$this->addAddSelectColumns($script);
+
+		$this->addDoCount($script);
+
+		// consider refactoring the doSelect stuff
+		// into a top-level method
+		$this->addDoSelectOne($script);
+		$this->addDoSelect($script);
+		$this->addDoSelectStmt($script);	 // <-- there's PDO code in here
+
+		$this->addAddInstanceToPool($script);
+		$this->addRemoveInstanceFromPool($script);
+		$this->addGetInstanceFromPool($script);
+		$this->addClearInstancePool($script);
+
+		$this->addGetPrimaryKeyHash($script);
+		$this->addPopulateObjects($script); // <-- there's PDO code in here
+
+	}
+
+	/**
+	 * Adds the correct getOMClass() method, depending on whether this table uses inheritance.
+	 * @param      string &$script The script will be modified in this method.
+	 */
+	protected function addGetOMClassMethod(&$script)
+	{
+		$table = $this->getTable();
+		if ($table->getChildrenColumn()) {
+			if ($table->isAbstract()) {
+				$this->addGetOMClass_Inheritance_Abstract($script);
+			} else {
+				$this->addGetOMClass_Inheritance($script);
+			}
+		} else {
+			if ($table->isAbstract()) {
+				$this->addGetOMClass_NoInheritance_Abstract($script);
+			} else {
+				$this->addGetOMClass_NoInheritance($script);
+			}
+		}
+	}
+
+	/**
+	 * Adds the doInsert(), doUpdate(), doDeleteAll(), doValidate(), etc. methods.
+	 * @param      string &$script The script will be modified in this method.
+	 */
+	protected function addUpdateMethods(&$script)
+	{
+		$this->addDoInsert($script);
+		$this->addDoUpdate($script);
+		$this->addDoDeleteAll($script);
+		$this->addDoDelete($script);
+		if ($this->isDeleteCascadeEmulationNeeded()) {
+			$this->addDoOnDeleteCascade($script);
+		}
+		if ($this->isDeleteSetNullEmulationNeeded()) {
+			$this->addDoOnDeleteSetNull($script);
+		}
+		$this->addDoValidate($script);
+	}
+
+	/**
+	 * Adds the retrieveByPK() (and possibly retrieveByPKs()) method(s) appropriate for this class.
+	 * @param      string &$script The script will be modified in this method.
+	 */
+	protected function addRetrieveByPKMethods(&$script)
+	{
+		if (count($this->getTable()->getPrimaryKey()) === 1) {
+			$this->addRetrieveByPK_SinglePK($script);
+			$this->addRetrieveByPKs_SinglePK($script);
+		} else {
+			$this->addRetrieveByPK_MultiPK($script);
+		}
+	}
+
+	/**
+	 * This method adds the contents of the generated class to the script.
+	 *
+	 * This method contains the high-level logic that determines which methods
+	 * get generated.
+	 *
+	 * Hint: Override this method in your subclass if you want to reorganize or
+	 * drastically change the contents of the generated peer class.
+	 *
+	 * @param      string &$script The script will be modified in this method.
+	 */
+	protected function addClassBody(&$script)
+	{
+
+		$table = $this->getTable();
+
+		if (!$table->isAlias()) {
+			$this->addConstantsAndAttributes($script);
+		}
+
+		$this->addGetMapBuilder($script);
+
+		$this->addTranslateFieldName($script);
+		$this->addGetFieldNames($script);
+
+		if (!$table->isAlias()) {
+			$this->addAlias($script); // alias() utility method (deprecated?)
+			$this->addSelectMethods($script);
+			$this->addGetTableMap($script);
+		}
+
+		$this->addGetOMClassMethod($script);
+
+		// add the insert, update, delete, validate etc. methods
+		if (!$table->isAlias() && !$table->isReadOnly()) {
+			$this->addUpdateMethods($script);
+		}
+
+		if (count($table->getPrimaryKey()) > 0) {
+			$this->addRetrieveByPKMethods($script);
+		}
+	}
+
+	/**
+	 * Whether the platform in use requires ON DELETE CASCADE emulation and whether there are references to this table.
+	 * @return     boolean
+	 */
+	protected function isDeleteCascadeEmulationNeeded()
+	{
+		$table = $this->getTable();
+		if ((!$this->getPlatform()->supportsNativeDeleteTrigger() || $this->getBuildProperty('emulateForeignKeyConstraints')) && count($table->getReferrers()) > 0) {
+			foreach ($table->getReferrers() as $fk) {
+				if ($fk->getOnDelete() == ForeignKey::CASCADE) {
+					return true;
+				}
+			}
+		}
+		return false;
+	}
+
+	/**
+	 * Whether the platform in use requires ON DELETE SETNULL emulation and whether there are references to this table.
+	 * @return     boolean
+	 */
+	protected function isDeleteSetNullEmulationNeeded()
+	{
+		$table = $this->getTable();
+		if ((!$this->getPlatform()->supportsNativeDeleteTrigger() || $this->getBuildProperty('emulateForeignKeyConstraints')) && count($table->getReferrers()) > 0) {
+			foreach ($table->getReferrers() as $fk) {
+				if ($fk->getOnDelete() == ForeignKey::SETNULL) {
+					return true;
+				}
+			}
+		}
+		return false;
+	}
+
+	/**
+	 * Whether to add the generic mutator methods (setByName(), setByPosition(), fromArray()).
+	 * This is based on the build property propel.addGenericMutators, and also whether the
+	 * table is read-only or an alias.
+	 * @return     boolean
+	 */
+	protected function isAddGenericMutators()
+	{
+		$table = $this->getTable();
+		return (!$table->isAlias() && $this->getBuildProperty('addGenericMutators') && !$table->isReadOnly());
+	}
+
+	/**
+	 * Whether to add the generic accessor methods (getByName(), getByPosition(), toArray()).
+	 * This is based on the build property propel.addGenericAccessors, and also whether the
+	 * table is an alias.
+	 * @return     boolean
+	 */
+	protected function isAddGenericAccessors()
+	{
+		$table = $this->getTable();
+		return (!$table->isAlias() && $this->getBuildProperty('addGenericAccessors'));
+	}
+
+	/**
+	 * Returns the retrieveByPK method name to use for this table.
+	 * If the table is an alias then the method name looks like "retrieveTablenameByPK"
+	 * otherwise simply "retrieveByPK".
+	 * @return     string
+	 */
+	public function getRetrieveMethodName()
+	{
+		if ($this->getTable()->isAlias()) {
+			$retrieveMethod = "retrieve" . $this->getTable()->getPhpName() . "ByPK";
+		} else {
+			$retrieveMethod = "retrieveByPK";
+		}
+		return $retrieveMethod;
+	}
+
+
+	/**
+	 * COMPATIBILITY: Get the column constant name (e.g. PeerName::COLUMN_NAME).
+	 *
+	 * This method exists simply because it belonged to the 'PeerBuilder' that this
+	 * class is replacing (because of name conflict more than actual functionality overlap).
+	 * When the new builder model is finished this method will be removed.
+	 *
+	 * @param      Column $col The column we need a name for.
+	 * @param      string $phpName The PHP Name of the peer class. The 'Peer' is appended automatically.
+	 *
+	 * @return     string If $phpName is provided, then will return {$phpName}Peer::COLUMN_NAME; if not, just COLUMN_NAME.
+	 * @deprecated
+	 */
+	public static function getColumnName(Column $col, $phpName = null) {
+		// was it overridden in schema.xml ?
+		if ($col->getPeerName()) {
+			$const = strtoupper($col->getPeerName());
+		} else {
+			$const = strtoupper($col->getName());
+		}
+		if ($phpName !== null) {
+			return $phpName . 'Peer::' . $const;
+		} else {
+			return $const;
+		}
+	}
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/builder/om/php5/PHP5ExtensionNodeBuilder.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/builder/om/php5/PHP5ExtensionNodeBuilder.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/builder/om/php5/PHP5ExtensionNodeBuilder.php	(revision 19)
@@ -0,0 +1,122 @@
+<?php
+
+/*
+ *  $Id: PHP5ExtensionNodeBuilder.php 521 2007-01-05 13:29:36Z heltem $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://propel.phpdb.org>.
+ */
+
+require_once 'propel/engine/builder/om/ObjectBuilder.php';
+
+/**
+ * Generates the empty PHP5 stub node object class for user object model (OM).
+ *
+ * This class produces the empty stub class that can be customized with application
+ * business logic, custom behavior, etc.
+ *
+ * This class replaces the ExtensionNode.tpl, with the intent of being easier for users
+ * to customize (through extending & overriding).
+ *
+ * @author     Hans Lellelid <hans@xmpl.org>
+ * @package    propel.engine.builder.om.php5
+ */
+class PHP5ExtensionNodeBuilder extends ObjectBuilder {
+
+	/**
+	 * Returns the name of the current class being built.
+	 * @return     string
+	 */
+	public function getUnprefixedClassname()
+	{
+		return $this->getTable()->getPhpName() . 'Node';
+	}
+
+	/**
+	 * Adds the include() statements for files that this class depends on or utilizes.
+	 * @param      string &$script The script will be modified in this method.
+	 */
+	protected function addIncludes(&$script)
+	{
+		$script .= "
+require '".$this->getNodeBuilder()->getClassFilePath()."';
+";
+	} // addIncludes()
+
+	/**
+	 * Adds class phpdoc comment and openning of class.
+	 * @param      string &$script The script will be modified in this method.
+	 */
+	protected function addClassOpen(&$script)
+	{
+
+		$table = $this->getTable();
+		$tableName = $table->getName();
+		$tableDesc = $table->getDescription();
+
+		$baseClassname = $this->getNodeBuilder()->getClassname();
+
+		$script .= "
+
+/**
+ * Skeleton subclass for representing a node from the '$tableName' table.
+ *
+ * $tableDesc
+ *";
+		if ($this->getBuildProperty('addTimeStamp')) {
+			$now = strftime('%c');
+			$script .= "
+ * This class was autogenerated by Propel " . $this->getBuildProperty('version') . " on:
+ *
+ * $now
+ *";
+		}
+		$script .= "
+ * You should add additional methods to this class to meet the
+ * application requirements.  This class will only be generated as
+ * long as it does not already exist in the output directory.
+ *
+ * @package    ".$this->getPackage()."
+ */
+class ".$this->getClassname()." extends $baseClassname {
+";
+	}
+
+	/**
+	 * Specifies the methods that are added as part of the stub object class.
+	 *
+	 * By default there are no methods for the empty stub classes; override this method
+	 * if you want to change that behavior.
+	 *
+	 * @see        ObjectBuilder::addClassBody()
+	 */
+	protected function addClassBody(&$script)
+	{
+		// there is no class body
+	}
+
+	/**
+	 * Closes class.
+	 * @param      string &$script The script will be modified in this method.
+	 */
+	protected function addClassClose(&$script)
+	{
+		$script .= "
+} // " . $this->getClassname() . "
+";
+	}
+
+} // PHP5ExtensionObjectBuilder
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/builder/om/php5/PHP5ExtensionNodePeerBuilder.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/builder/om/php5/PHP5ExtensionNodePeerBuilder.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/builder/om/php5/PHP5ExtensionNodePeerBuilder.php	(revision 19)
@@ -0,0 +1,123 @@
+<?php
+
+/*
+ *  $Id: PHP5ExtensionNodePeerBuilder.php 521 2007-01-05 13:29:36Z heltem $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://propel.phpdb.org>.
+ */
+
+require_once 'propel/engine/builder/om/PeerBuilder.php';
+
+/**
+ * Generates the empty PHP5 stub node peer class for user object model (OM).
+ *
+ * This class produces the empty stub class that can be customized with application
+ * business logic, custom behavior, etc.
+ *
+ * This class replaces the ExtensionNodePeer.tpl, with the intent of being easier for users
+ * to customize (through extending & overriding).
+ *
+ * @author     Hans Lellelid <hans@xmpl.org>
+ * @package    propel.engine.builder.om.php5
+ */
+class PHP5ExtensionNodePeerBuilder extends PeerBuilder {
+
+	/**
+	 * Returns the name of the current class being built.
+	 * @return     string
+	 */
+	public function getUnprefixedClassname()
+	{
+		return $this->getStubNodeBuilder()->getClassname() . 'Peer';
+	}
+
+	/**
+	 * Adds the include() statements for files that this class depends on or utilizes.
+	 * @param      string &$script The script will be modified in this method.
+	 */
+	protected function addIncludes(&$script)
+	{
+		$script .="
+require '".$this->getNodePeerBuilder()->getClassFilePath()."';
+";
+	} // addIncludes()
+
+	/**
+	 * Adds class phpdoc comment and openning of class.
+	 * @param      string &$script The script will be modified in this method.
+	 */
+	protected function addClassOpen(&$script)
+	{
+
+		$table = $this->getTable();
+		$tableName = $table->getName();
+		$tableDesc = $table->getDescription();
+
+		$baseClassname = $this->getNodePeerBuilder()->getClassname();
+
+		$script .= "
+
+/**
+ * Skeleton subclass for performing query and update operations on nodes of the '$tableName' table.
+ *
+ * $tableDesc
+ *";
+		if ($this->getBuildProperty('addTimeStamp')) {
+			$now = strftime('%c');
+			$script .= "
+ * This class was autogenerated by Propel " . $this->getBuildProperty('version') . " on:
+ *
+ * $now
+ *";
+		}
+		$script .= "
+ * You should add additional methods to this class to meet the
+ * application requirements.  This class will only be generated as
+ * long as it does not already exist in the output directory.
+ *
+ * @package    ".$this->getPackage()."
+ */
+class ".$this->getClassname()." extends $baseClassname {
+";
+	}
+
+		/**
+	 * Specifies the methods that are added as part of the stub peer class.
+	 *
+	 * By default there are no methods for the empty stub classes; override this method
+	 * if you want to change that behavior.
+	 *
+	 * @see        ObjectBuilder::addClassBody()
+	 */
+
+	protected function addClassBody(&$script)
+	{
+		// there is no class body
+	}
+
+	/**
+	 * Closes class.
+	 * @param      string &$script The script will be modified in this method.
+	 */
+	protected function addClassClose(&$script)
+	{
+		$script .= "
+} // " . $this->getClassname() . "
+";
+	}
+
+} // PHP5ExtensionPeerBuilder
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/builder/om/php5/PHP5ExtensionObjectBuilder.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/builder/om/php5/PHP5ExtensionObjectBuilder.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/builder/om/php5/PHP5ExtensionObjectBuilder.php	(revision 19)
@@ -0,0 +1,166 @@
+<?php
+
+/*
+ *  $Id: PHP5ExtensionObjectBuilder.php 974 2008-02-20 21:53:11Z hans $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://propel.phpdb.org>.
+ */
+
+require_once 'propel/engine/builder/om/ObjectBuilder.php';
+
+/**
+ * Generates the empty PHP5 stub object class for user object model (OM).
+ *
+ * This class produces the empty stub class that can be customized with application
+ * business logic, custom behavior, etc.
+ *
+ * This class replaces the ExtensionObject.tpl, with the intent of being easier for users
+ * to customize (through extending & overriding).
+ *
+ * @author     Hans Lellelid <hans@xmpl.org>
+ * @package    propel.engine.builder.om.php5
+ */
+class PHP5ExtensionObjectBuilder extends ObjectBuilder {
+
+	/**
+	 * Returns the name of the current class being built.
+	 * @return     string
+	 */
+	public function getUnprefixedClassname()
+	{
+		return $this->getTable()->getPhpName();
+	}
+
+	/**
+	 * Adds the include() statements for files that this class depends on or utilizes.
+	 * @param      string &$script The script will be modified in this method.
+	 */
+	protected function addIncludes(&$script)
+	{
+		switch($this->getTable()->treeMode()) {
+			case 'NestedSet':
+				$requiredClassFilePath = $this->getNestedSetBuilder()->getClassFilePath();
+			break;
+
+			case 'MaterializedPath':
+			case "AdjacencyList":
+			default:
+				$requiredClassFilePath = $this->getObjectBuilder()->getClassFilePath();
+			break;
+		}
+
+		$script .="
+require '".$requiredClassFilePath."';
+";
+	} // addIncludes()
+
+	/**
+	 * Adds class phpdoc comment and openning of class.
+	 * @param      string &$script The script will be modified in this method.
+	 */
+	protected function addClassOpen(&$script)
+	{
+
+		$table = $this->getTable();
+		$tableName = $table->getName();
+		$tableDesc = $table->getDescription();
+
+		switch($table->treeMode()) {
+			case 'NestedSet':
+				$baseClassname = $this->getNestedSetBuilder()->getClassname();
+			break;
+
+			case 'MaterializedPath':
+			case "AdjacencyList":
+			default:
+				$baseClassname = $this->getObjectBuilder()->getClassname();
+			break;
+		}
+
+		$script .= "
+
+/**
+ * Skeleton subclass for representing a row from the '$tableName' table.
+ *
+ * $tableDesc
+ *";
+		if ($this->getBuildProperty('addTimeStamp')) {
+			$now = strftime('%c');
+			$script .= "
+ * This class was autogenerated by Propel " . $this->getBuildProperty('version') . " on:
+ *
+ * $now
+ *";
+		}
+		$script .= "
+ * You should add additional methods to this class to meet the
+ * application requirements.  This class will only be generated as
+ * long as it does not already exist in the output directory.
+ *
+ * @package    ".$this->getPackage()."
+ */
+".($table->isAbstract() ? "abstract " : "")."class ".$this->getClassname()." extends $baseClassname {
+";
+	}
+
+	/**
+	 * Specifies the methods that are added as part of the stub object class.
+	 *
+	 * By default there are no methods for the empty stub classes; override this method
+	 * if you want to change that behavior.
+	 *
+	 * @see        ObjectBuilder::addClassBody()
+	 */
+	protected function addClassBody(&$script)
+	{
+		$this->addConstructor($script);
+	}
+
+		/**
+	 * Adds the applyDefaults() method, which is called from the constructor.
+	 * @param      string &$script The script will be modified in this method.
+	 * @see        addConstructor()
+	 */
+	protected function addConstructor(&$script)
+	{
+		$table = $this->getTable();
+		$script .= "
+	/**
+	 * Initializes internal state of ".$this->getClassname()." object.
+	 * @see        parent::__construct()
+	 */
+	public function __construct()
+	{
+		// Make sure that parent constructor is always invoked, since that
+		// is where any default values for this object are set.
+		parent::__construct();
+	}
+";
+	}
+
+	/**
+	 * Closes class.
+	 * @param      string &$script The script will be modified in this method.
+	 */
+	protected function addClassClose(&$script)
+	{
+		$script .= "
+} // " . $this->getClassname() . "
+";
+	}
+
+} // PHP5ExtensionObjectBuilder
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/builder/om/php5/PHP5ExtensionPeerBuilder.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/builder/om/php5/PHP5ExtensionPeerBuilder.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/builder/om/php5/PHP5ExtensionPeerBuilder.php	(revision 19)
@@ -0,0 +1,145 @@
+<?php
+
+/*
+ *  $Id: PHP5ExtensionPeerBuilder.php 521 2007-01-05 13:29:36Z heltem $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://propel.phpdb.org>.
+ */
+
+require_once 'propel/engine/builder/om/PeerBuilder.php';
+
+/**
+ * Generates the empty PHP5 stub peer class for user object model (OM).
+ *
+ * This class produces the empty stub class that can be customized with application
+ * business logic, custom behavior, etc.
+ *
+ * This class replaces the ExtensionPeer.tpl, with the intent of being easier for users
+ * to customize (through extending & overriding).
+ *
+ * @author     Hans Lellelid <hans@xmpl.org>
+ * @package    propel.engine.builder.om.php5
+ */
+class PHP5ExtensionPeerBuilder extends PeerBuilder {
+
+	/**
+	 * Returns the name of the current class being built.
+	 * @return     string
+	 */
+	public function getUnprefixedClassname()
+	{
+		return $this->getStubObjectBuilder()->getUnprefixedClassname() . 'Peer';
+	}
+
+	/**
+	 * Adds the include() statements for files that this class depends on or utilizes.
+	 * @param      string &$script The script will be modified in this method.
+	 */
+	protected function addIncludes(&$script)
+	{
+		switch($this->getTable()->treeMode()) {
+			case 'NestedSet':
+				$requiredClassFilePath = $this->getNestedSetPeerBuilder()->getClassFilePath();
+			break;
+
+			case 'MaterializedPath':
+			case "AdjacencyList":
+			default:
+				$requiredClassFilePath = $this->getPeerBuilder()->getClassFilePath();
+			break;
+		}
+
+		$script .="
+require '".$requiredClassFilePath."';
+";
+	} // addIncludes()
+
+	/**
+	 * Adds class phpdoc comment and openning of class.
+	 * @param      string &$script The script will be modified in this method.
+	 */
+	protected function addClassOpen(&$script)
+	{
+		$table = $this->getTable();
+		$tableName = $table->getName();
+		$tableDesc = $table->getDescription();
+
+		switch($table->treeMode()) {
+			case 'NestedSet':
+				$baseClassname = $this->getNestedSetPeerBuilder()->getClassname();
+			break;
+
+			case 'MaterializedPath':
+			case "AdjacencyList":
+			default:
+				$baseClassname = $this->getPeerBuilder()->getClassname();
+			break;
+		}
+
+		$script .= "
+
+/**
+ * Skeleton subclass for performing query and update operations on the '$tableName' table.
+ *
+ * $tableDesc
+ *";
+		if ($this->getBuildProperty('addTimeStamp')) {
+			$now = strftime('%c');
+			$script .= "
+ * This class was autogenerated by Propel " . $this->getBuildProperty('version') . " on:
+ *
+ * $now
+ *";
+		}
+		$script .= "
+ * You should add additional methods to this class to meet the
+ * application requirements.  This class will only be generated as
+ * long as it does not already exist in the output directory.
+ *
+ * @package    ".$this->getPackage()."
+ */
+class ".$this->getClassname()." extends $baseClassname {
+";
+	}
+
+		/**
+	 * Specifies the methods that are added as part of the stub peer class.
+	 *
+	 * By default there are no methods for the empty stub classes; override this method
+	 * if you want to change that behavior.
+	 *
+	 * @see        ObjectBuilder::addClassBody()
+	 */
+
+	protected function addClassBody(&$script)
+	{
+		// there is no class body
+	}
+
+	/**
+	 * Closes class.
+	 * @param      string &$script The script will be modified in this method.
+	 */
+	protected function addClassClose(&$script)
+	{
+		$script .= "
+} // " . $this->getClassname() . "
+";
+	}
+
+
+} // PHP5ExtensionPeerBuilder
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/builder/om/php5/PHP5InterfaceBuilder.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/builder/om/php5/PHP5InterfaceBuilder.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/builder/om/php5/PHP5InterfaceBuilder.php	(revision 19)
@@ -0,0 +1,119 @@
+<?php
+
+/*
+ *  $Id: PHP5InterfaceBuilder.php 521 2007-01-05 13:29:36Z heltem $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://propel.phpdb.org>.
+ */
+
+require_once 'propel/engine/builder/om/ObjectBuilder.php';
+
+/**
+ * Generates the empty PHP5 stub interface for user object model (OM).
+ *
+ * This class produces the empty stub interface when the interface="" attribute is used
+ * in the the schema xml.
+ *
+ * This class replaces the Interface.tpl, with the intent of being easier for users
+ * to customize (through extending & overriding).
+ *
+ * @author     Hans Lellelid <hans@xmpl.org>
+ * @package    propel.engine.builder.om.php5
+ */
+class PHP5InterfaceBuilder extends ObjectBuilder {
+
+	/**
+	 * Returns the name of the current class being built.
+	 * @return     string
+	 */
+	public function getUnprefixedClassname()
+	{
+		return ClassTools::classname($this->getInterface());
+	}
+
+	/**
+	 * Adds the include() statements for files that this class depends on or utilizes.
+	 * @param      string &$script The script will be modified in this method.
+	 */
+	protected function addIncludes(&$script)
+	{
+
+	} // addIncludes()
+
+	/**
+	 * Adds class phpdoc comment and openning of class.
+	 * @param      string &$script The script will be modified in this method.
+	 */
+	protected function addClassOpen(&$script)
+	{
+
+		$table = $this->getTable();
+		$tableName = $table->getName();
+		$tableDesc = $table->getDescription();
+
+		$baseClassname = $this->getObjectBuilder()->getClassname();
+
+		$script .= "
+/**
+ * This is an interface that should be filled with the public api of the $tableName objects.
+ *
+ * $tableDesc
+ *";
+		if ($this->getBuildProperty('addTimeStamp')) {
+			$now = strftime('%c');
+			$script .= "
+ * This class was autogenerated by Propel " . $this->getBuildProperty('version') . " on:
+ *
+ * $now
+ *";
+		}
+		$script .= "
+ * You should add additional method declarations to this interface to meet the
+ * application requirements.  This interface will only be generated as
+ * long as it does not already exist in the output directory.
+ *
+ * @package    ".$this->getPackage()."
+ */
+interface ".$this->getClassname()." {
+";
+	}
+
+	/**
+	 * Specifies the methods that are added as part of the stub object class.
+	 *
+	 * By default there are no methods for the empty stub classes; override this method
+	 * if you want to change that behavior.
+	 *
+	 * @see        ObjectBuilder::addClassBody()
+	 */
+	protected function addClassBody(&$script)
+	{
+		// there is no class body
+	}
+
+	/**
+	 * Closes class.
+	 * @param      string &$script The script will be modified in this method.
+	 */
+	protected function addClassClose(&$script)
+	{
+		$script .= "
+} // " . $this->getClassname() . "
+";
+	}
+
+} // PHP5ExtensionObjectBuilder
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/builder/om/php5/PHP5MapBuilderBuilder.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/builder/om/php5/PHP5MapBuilderBuilder.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/builder/om/php5/PHP5MapBuilderBuilder.php	(revision 19)
@@ -0,0 +1,295 @@
+<?php
+
+/*
+ *  $Id: PHP5MapBuilderBuilder.php 989 2008-03-11 14:29:30Z heltem $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://propel.phpdb.org>.
+ */
+
+require_once 'propel/engine/builder/om/OMBuilder.php';
+
+/**
+ * Generates the PHP5 map builder class for user object model (OM).
+ *
+ * This class replaces the MapBuilder.tpl, with the intent of being easier for users
+ * to customize (through extending & overriding).
+ *
+ * @author     Hans Lellelid <hans@xmpl.org>
+ * @package    propel.engine.builder.om.php5
+ */
+class PHP5MapBuilderBuilder extends OMBuilder {
+
+	/**
+	 * Gets the package for the map builder classes.
+	 * @return     string
+	 */
+	public function getPackage()
+	{
+		return parent::getPackage() . '.map';
+	}
+
+	/**
+	 * Returns the name of the current class being built.
+	 * @return     string
+	 */
+	public function getUnprefixedClassname()
+	{
+		return $this->getTable()->getPhpName() . 'MapBuilder';
+	}
+
+	/**
+	 * Adds the include() statements for files that this class depends on or utilizes.
+	 * @param      string &$script The script will be modified in this method.
+	 */
+	protected function addIncludes(&$script)
+	{
+	} // addIncludes()
+
+	/**
+	 * Adds class phpdoc comment and openning of class.
+	 * @param      string &$script The script will be modified in this method.
+	 */
+	protected function addClassOpen(&$script)
+	{
+		$table = $this->getTable();
+		$script .= "
+
+/**
+ * This class adds structure of '".$table->getName()."' table to '".$table->getDatabase()->getName()."' DatabaseMap object.
+ *
+ *";
+		if ($this->getBuildProperty('addTimeStamp')) {
+			$now = strftime('%c');
+			$script .= "
+ * This class was autogenerated by Propel " . $this->getBuildProperty('version') . " on:
+ *
+ * $now
+ *";
+		}
+		$script .= "
+ *
+ * These statically-built map classes are used by Propel to do runtime db structure discovery.
+ * For example, the createSelectSql() method checks the type of a given column used in an
+ * ORDER BY clause to know whether it needs to apply SQL to make the ORDER BY case-insensitive
+ * (i.e. if it's a text column type).
+ *
+ * @package    ".$this->getPackage()."
+ */
+class ".$this->getClassname()." implements MapBuilder {
+";
+	}
+
+	/**
+	 * Specifies the methods that are added as part of the map builder class.
+	 * This can be overridden by subclasses that wish to add more methods.
+	 * @see        ObjectBuilder::addClassBody()
+	 */
+	protected function addClassBody(&$script)
+	{
+		$this->addConstants($script);
+		$this->addAttributes($script);
+
+		$this->addIsBuilt($script);
+		$this->addGetDatabaseMap($script);
+		$this->addDoBuild($script);
+	}
+
+	/**
+	 * Adds any constants needed for this MapBuilder class.
+	 * @param      string &$script The script will be modified in this method.
+	 */
+	protected function addConstants(&$script)
+	{
+		$script .= "
+	/**
+	 * The (dot-path) name of this class
+	 */
+	const CLASS_NAME = '".$this->getClasspath()."';
+";
+	}
+
+	/**
+	 * Adds any attributes needed for this MapBuilder class.
+	 * @param      string &$script The script will be modified in this method.
+	 */
+	protected function addAttributes(&$script)
+	{
+		$script .= "
+	/**
+	 * The database map.
+	 */
+	private \$dbMap;
+";
+	}
+
+	/**
+	 * Closes class.
+	 * @param      string &$script The script will be modified in this method.
+	 */
+	protected function addClassClose(&$script)
+	{
+		$script .= "
+} // " . $this->getClassname() . "
+";
+	}
+
+	/**
+	 * Adds the method that indicates whether this map has already been built.
+	 * @param      string &$script The script will be modified in this method.
+	 */
+	protected function addIsBuilt(&$script)
+	{
+		$script .= "
+	/**
+	 * Tells us if this DatabaseMapBuilder is built so that we
+	 * don't have to re-build it every time.
+	 *
+	 * @return     boolean true if this DatabaseMapBuilder is built, false otherwise.
+	 */
+	public function isBuilt()
+	{
+		return (\$this->dbMap !== null);
+	}
+";
+	}
+
+	/**
+	 * Adds the DatabaseMap accessor method.
+	 * @param      string &$script The script will be modified in this method.
+	 */
+	protected function addGetDatabaseMap(&$script)
+	{
+		$script .= "
+	/**
+	 * Gets the databasemap this map builder built.
+	 *
+	 * @return     the databasemap
+	 */
+	public function getDatabaseMap()
+	{
+		return \$this->dbMap;
+	}
+";
+	}
+
+	/**
+	 * Adds the main doBuild() method to the map builder class.
+	 * @param      string &$script The script will be modified in this method.
+	 */
+	protected function addDoBuild(&$script)
+	{
+
+		$table = $this->getTable();
+		$platform = $this->getPlatform();
+		$ddlBuilder = $this->getDDLBuilder();
+
+		$script .= "
+	/**
+	 * The doBuild() method builds the DatabaseMap
+	 *
+	 * @return     void
+	 * @throws     PropelException
+	 */
+	public function doBuild()
+	{
+		\$this->dbMap = Propel::getDatabaseMap(".$this->getPeerClassname()."::DATABASE_NAME);
+
+		\$tMap = \$this->dbMap->addTable(".$this->getPeerClassname()."::TABLE_NAME);
+		\$tMap->setPhpName('".$table->getPhpName()."');
+		\$tMap->setClassname('" . $this->getObjectClassname() . "');
+";
+		if ($table->getIdMethod() == "native") {
+			$script .= "
+		\$tMap->setUseIdGenerator(true);
+";
+		} else {
+			$script .= "
+		\$tMap->setUseIdGenerator(false);
+";
+		}
+
+		if ($table->getIdMethodParameters()) {
+			$params = $table->getIdMethodParameters();
+			$imp = $params[0];
+			$script .= "
+		\$tMap->setPrimaryKeyMethodInfo('".$imp->getValue()."');
+";
+		} elseif ($table->getIdMethod() == IDMethod::NATIVE && ($platform->getNativeIdMethod() == Platform::SEQUENCE || $platform->getNativeIdMethod() == Platform::SERIAL)) {
+			$script .= "
+		\$tMap->setPrimaryKeyMethodInfo('".$this->prefixTablename($ddlBuilder->getSequenceName())."');
+";
+		}
+
+		// Add columns to map
+		foreach ($table->getColumns() as $col) {
+			$cfc=$col->getPhpName();
+			$cup=strtoupper($col->getName());
+			if (!$col->getSize()) {
+				$size = "null";
+			} else {
+				$size = $col->getSize();
+			}
+			if ($col->isPrimaryKey()) {
+				if ($col->isForeignKey()) {
+					foreach ($col->getForeignKeys() as $fk) {
+						$script .= "
+		\$tMap->addForeignPrimaryKey('$cup', '$cfc', '".$col->getType()."' , '".$fk->getForeignTableName()."', '".strtoupper($fk->getMappedForeignColumn($col->getName()))."', ".($col->isNotNull() ? 'true' : 'false').", ".$size.");
+";
+					}
+				} else {
+					$script .= "
+		\$tMap->addPrimaryKey('$cup', '$cfc', '".$col->getType()."', ".var_export($col->isNotNull(), true).", ".$size.");
+";
+				}
+			} else {
+				if ($col->isForeignKey()) {
+					foreach ($col->getForeignKeys() as $fk) {
+						$script .= "
+		\$tMap->addForeignKey('$cup', '$cfc', '".$col->getType()."', '".$fk->getForeignTableName()."', '".strtoupper($fk->getMappedForeignColumn($col->getName()))."', ".($col->isNotNull() ? 'true' : 'false').", ".$size.");
+";
+					}
+			} else {
+					$script .= "
+		\$tMap->addColumn('$cup', '$cfc', '".$col->getType()."', ".var_export($col->isNotNull(), true).", ".$size.");
+";
+				}
+			} // if col-is prim key
+		} // foreach
+
+		foreach ($table->getValidators() as $val) {
+			$col = $val->getColumn();
+			$cup = strtoupper($col->getName());
+			foreach ($val->getRules() as $rule) {
+				if ($val->getTranslate() !== Validator::TRANSLATE_NONE) {
+					$script .= "
+		\$tMap->addValidator('$cup', '".$rule->getName()."', '".$rule->getClass()."', '".str_replace("'", "\'", $rule->getValue())."', ".$val->getTranslate()."('".str_replace("'", "\'", $rule->getMessage())."'));
+";
+				} else {
+					$script .= "
+		\$tMap->addValidator('$cup', '".$rule->getName()."', '".$rule->getClass()."', '".str_replace("'", "\'", $rule->getValue())."', '".str_replace("'", "\'", $rule->getMessage())."');
+";
+				} // if ($rule->getTranslation() ...
+  			} // foreach rule
+		}  // foreach validator
+
+		$script .= "
+	} // doBuild()
+";
+
+	}
+
+} // PHP5ExtensionPeerBuilder
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/builder/om/php5/PHP5MultiExtendObjectBuilder.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/builder/om/php5/PHP5MultiExtendObjectBuilder.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/builder/om/php5/PHP5MultiExtendObjectBuilder.php	(revision 19)
@@ -0,0 +1,202 @@
+<?php
+
+/*
+ *  $Id: PHP5MultiExtendObjectBuilder.php 977 2008-02-25 18:45:38Z hans $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://propel.phpdb.org>.
+ */
+
+require_once 'propel/engine/builder/om/ObjectBuilder.php';
+
+/**
+ * Generates the empty PHP5 stub object class for use with inheritance in the user object model (OM).
+ *
+ * This class produces the empty stub class that can be customized with application
+ * business logic, custom behavior, etc.
+ *
+ * This class replaces the MultiExtendObject.tpl, with the intent of being easier for users
+ * to customize (through extending & overriding).
+ *
+ * @author     Hans Lellelid <hans@xmpl.org>
+ * @package    propel.engine.builder.om.php5
+ */
+class PHP5MultiExtendObjectBuilder extends ObjectBuilder {
+
+	/**
+	 * The current child "object" we are operating on.
+	 */
+	private $child;
+
+	/**
+	 * Returns the name of the current class being built.
+	 * @return     string
+	 */
+	public function getUnprefixedClassname()
+	{
+		return $this->getChild()->getClassname();
+	}
+
+	/**
+	 * Override method to return child package, if specified.
+	 * @return     string
+	 */
+	public function getPackage()
+	{
+		return ($this->child->getPackage() ? $this->child->getPackage() : parent::getPackage());
+	}
+
+	/**
+	 * Set the child object that we're operating on currrently.
+	 * @param      $child Inheritance
+	 */
+	public function setChild(Inheritance $child)
+	{
+		$this->child = $child;
+	}
+
+	/**
+	 * Returns the child object we're operating on currently.
+	 * @return     Inheritance
+	 * @throws     BuildException - if child was not set.
+	 */
+	public function getChild()
+	{
+		if (!$this->child) {
+			throw new BuildException("The PHP5MultiExtendObjectBuilder needs to be told which child class to build (via setChild() method) before it can build the stub class.");
+		}
+		return $this->child;
+	}
+
+	/**
+	 * Returns classpath to parent class.
+	 * @return     string
+	 */
+	protected function getParentClasspath()
+	{
+		if ($this->getChild()->getAncestor()) {
+			return $this->getChild()->getAncestor();
+		} else {
+			return $this->getObjectBuilder()->getClasspath();
+		}
+	}
+
+	/**
+	 * Returns classname of parent class.
+	 * @return     string
+	 */
+	protected function getParentClassname()
+	{
+		return ClassTools::classname($this->getParentClasspath());
+	}
+
+	/**
+	 * Gets the file path to the parent class.
+	 * @return     string
+	 */
+	protected function getParentClassFilePath()
+	{
+		return ClassTools::getFilePath($this->getParentClasspath());
+	}
+
+	/**
+	 * Adds the include() statements for files that this class depends on or utilizes.
+	 * @param      string &$script The script will be modified in this method.
+	 */
+	protected function addIncludes(&$script)
+	{
+	} // addIncludes()
+
+	/**
+	 * Adds class phpdoc comment and openning of class.
+	 * @param      string &$script The script will be modified in this method.
+	 */
+	protected function addClassOpen(&$script)
+	{
+
+		$table = $this->getTable();
+		$tableName = $table->getName();
+		$tableDesc = $table->getDescription();
+
+		$baseClassname = $this->getObjectBuilder()->getClassname();
+
+		$script .= "
+
+/**
+ * Skeleton subclass for representing a row from one of the subclasses of the '$tableName' table.
+ *
+ * $tableDesc
+ *";
+		if ($this->getBuildProperty('addTimeStamp')) {
+			$now = strftime('%c');
+			$script .= "
+ * This class was autogenerated by Propel " . $this->getBuildProperty('version') . " on:
+ *
+ * $now
+ *";
+		}
+		$script .= "
+ * You should add additional methods to this class to meet the
+ * application requirements.  This class will only be generated as
+ * long as it does not already exist in the output directory.
+ *
+ * @package    ".$this->getPackage()."
+ */
+class ".$this->getClassname()." extends ".$this->getParentClassname()." {
+";
+	}
+
+	/**
+	 * Specifies the methods that are added as part of the stub object class.
+	 *
+	 * By default there are no methods for the empty stub classes; override this method
+	 * if you want to change that behavior.
+	 *
+	 * @see        ObjectBuilder::addClassBody()
+	 */
+	protected function addClassBody(&$script)
+	{
+		$child = $this->getChild();
+		$col = $child->getColumn();
+		$cfc = $col->getPhpName();
+
+		$const = "CLASSKEY_".strtoupper($child->getKey());
+
+		$script .= "
+	/**
+	 * Constructs a new ".$this->getChild()->getClassname()." class, setting the ".$col->getName()." column to ".$this->getPeerClassname()."::$const.
+	 */
+	public function __construct()
+	{";
+		$script .= "
+		parent::__construct();
+		\$this->set$cfc(".$this->getPeerClassname()."::CLASSKEY_".strtoupper($child->getKey()).");
+	}
+";
+	}
+
+	/**
+	 * Closes class.
+	 * @param      string &$script The script will be modified in this method.
+	 */
+	protected function addClassClose(&$script)
+	{
+		$script .= "
+} // " . $this->getClassname() . "
+";
+	}
+
+} // PHP5ExtensionObjectBuilder
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/builder/om/php5/PHP5NestedSetBuilder.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/builder/om/php5/PHP5NestedSetBuilder.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/builder/om/php5/PHP5NestedSetBuilder.php	(revision 19)
@@ -0,0 +1,1145 @@
+<?php
+/*
+ *  $Id: PHP5NestedSetBuilder.php 1071 2008-08-06 14:40:43Z heltem $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://propel.phpdb.org>.
+ */
+
+require_once 'propel/engine/builder/om/ObjectBuilder.php';
+
+/**
+ * Generates a PHP5 tree node Object class for user object model (OM) using Nested Set way.
+ *
+ * This class produces the base tree node object class (e.g. BaseMyTableNestedSet) which contains all
+ * the custom-built accessor and setter methods.
+ *
+ * @author     Heltem <heltem@o2php.com>
+ * @package    propel.engine.builder.om.php5
+ */
+class PHP5NestedSetBuilder extends ObjectBuilder {
+
+	/**
+	 * Gets the package for the [base] object classes.
+	 * @return     string
+	 */
+	public function getPackage()
+	{
+		return parent::getPackage() . ".om";
+	}
+
+	/**
+	 * Returns the name of the current class being built.
+	 * @return     string
+	 */
+	public function getUnprefixedClassname()
+	{
+		return $this->getBuildProperty('basePrefix') . $this->getStubObjectBuilder()->getUnprefixedClassname() . 'NestedSet';
+	}
+
+	/**
+	 * Adds the include() statements for files that this class depends on or utilizes.
+	 * @param      string &$script The script will be modified in this method.
+	 */
+	protected function addIncludes(&$script)
+	{
+		$script .="
+require '".$this->getObjectBuilder()->getClassFilePath()."';
+";
+	} // addIncludes()
+
+	/**
+	 * Adds class phpdoc comment and openning of class.
+	 * @param      string &$script The script will be modified in this method.
+	 */
+	protected function addClassOpen(&$script)
+	{
+
+		$table = $this->getTable();
+		$tableName = $table->getName();
+		$tableDesc = $table->getDescription();
+
+		$script .= "
+/**
+ * Base class that represents a row from the '$tableName' table.
+ *
+ * $tableDesc
+ *";
+		if ($this->getBuildProperty('addTimeStamp')) {
+			$now = strftime('%c');
+			$script .= "
+ * This class was autogenerated by Propel " . $this->getBuildProperty('version') . " on:
+ *
+ * $now
+ *";
+		}
+		$script .= "
+ * @package    ".$this->getPackage()."
+ */
+abstract class ".$this->getClassname()." extends ".$this->getObjectBuilder()->getClassname()." implements NodeObject {
+";
+	}
+
+	/**
+	 * Specifies the methods that are added as part of the basic OM class.
+	 * This can be overridden by subclasses that wish to add more methods.
+	 * @see        ObjectBuilder::addClassBody()
+	 */
+	protected function addClassBody(&$script)
+	{
+		$table = $this->getTable();
+
+		$this->addAttributes($script);
+
+		$this->addGetIterator($script);
+
+		$this->addSave($script);
+		$this->addDelete($script);
+
+		$this->addMakeRoot($script);
+
+		$this->addGetLevel($script);
+		$this->addGetPath($script);
+
+		$this->addGetNumberOfChildren($script);
+		$this->addGetNumberOfDescendants($script);
+
+		$this->addGetChildren($script);
+		$this->addGetDescendants($script);
+
+		$this->addSetLevel($script);
+
+		$this->addSetChildren($script);
+		$this->addSetParentNode($script);
+		$this->addSetPrevSibling($script);
+		$this->addSetNextSibling($script);
+
+		$this->addIsRoot($script);
+		$this->addIsLeaf($script);
+		$this->addIsEqualTo($script);
+
+		$this->addHasParent($script);
+		$this->addHasChildren($script);
+		$this->addHasPrevSibling($script);
+		$this->addHasNextSibling($script);
+
+		$this->addRetrieveParent($script);
+		$this->addRetrieveFirstChild($script);
+		$this->addRetrieveLastChild($script);
+		$this->addRetrievePrevSibling($script);
+		$this->addRetrieveNextSibling($script);
+
+		$this->addInsertAsFirstChildOf($script);
+		$this->addInsertAsLastChildOf($script);
+
+		$this->addInsertAsPrevSiblingOf($script);
+		$this->addInsertAsNextSiblingOf($script);
+
+		$this->addMoveToFirstChildOf($script);
+		$this->addMoveToLastChildOf($script);
+
+		$this->addMoveToPrevSiblingOf($script);
+		$this->addMoveToNextSiblingOf($script);
+
+		$this->addInsertAsParentOf($script);
+
+		$this->addGetLeft($script);
+		$this->addGetRight($script);
+		$this->addGetScopeId($script);
+
+		$this->addSetLeft($script);
+		$this->addSetRight($script);
+		$this->addSetScopeId($script);
+	}
+
+	/**
+	 * Closes class.
+	 * @param      string &$script The script will be modified in this method.
+	 */
+	protected function addClassClose(&$script)
+	{
+		$script .= "
+} // " . $this->getClassname() . "
+";
+	}
+
+
+	/**
+	 * Adds class attributes.
+	 * @param      string &$script The script will be modified in this method.
+	 */
+	protected function addAttributes(&$script)
+	{
+		$objectClassName = $this->getStubObjectBuilder()->getClassname();
+		$script .= "
+	/**
+	 * Store level of node
+	 * @var        int
+	 */
+	protected \$level = null;
+
+	/**
+	 * Store if node has prev sibling
+	 * @var        bool
+	 */
+	protected \$hasPrevSibling = null;
+
+	/**
+	 * Store node if has prev sibling
+	 * @var        $objectClassName
+	 */
+	protected \$prevSibling = null;
+
+	/**
+	 * Store if node has next sibling
+	 * @var        bool
+	 */
+	protected \$hasNextSibling = null;
+
+	/**
+	 * Store node if has next sibling
+	 * @var        $objectClassName
+	 */
+	protected \$nextSibling = null;
+
+	/**
+	 * Store if node has parent node
+	 * @var        bool
+	 */
+	protected \$hasParentNode = null;
+
+	/**
+	 * The parent node for this node.
+	 * @var        $objectClassName
+	 */
+	protected \$parentNode = null;
+
+	/**
+	 * Store children of the node
+	 * @var        array
+	 */
+	protected \$_children = null;
+";
+	}
+
+	protected function addGetIterator(&$script)
+	{
+		$script .= "
+	/**
+	 * Returns a pre-order iterator for this node and its children.
+	 *
+	 * @return     NodeIterator
+	 */
+	public function getIterator()
+	{
+		return new NestedSetRecursiveIterator(\$this);
+	}
+";
+	}
+
+	protected function addSave(&$script)
+	{
+		$peerClassname = $this->getStubPeerBuilder()->getClassname();
+		$script .= "
+	/**
+	 * Saves modified object data to the datastore.
+	 * If object is saved without left/right values, set them as undefined (0)
+	 *
+	 * @param      PropelPDO Connection to use.
+	 * @return     int The number of rows affected by this insert/update and any referring fk objects' save() operations.
+	 *                 May be unreliable with parent/children/brother changes
+	 * @throws     PropelException
+	 */
+	public function save(PropelPDO \$con = null)
+	{
+		\$left = \$this->getLeftValue();
+		\$right = \$this->getRightValue();
+		if (empty(\$left) || empty(\$right)) {
+			\$root = $peerClassname::retrieveRoot(\$con);
+			$peerClassname::insertAsLastChildOf(\$root, \$this, \$con);
+		}
+
+		return parent::save(\$con);
+	}
+";
+	}
+
+	protected function addDelete(&$script)
+	{
+		$peerClassname = $this->getStubPeerBuilder()->getClassname();
+		$script .= "
+	/**
+	 * Removes this object and all descendants from datastore.
+	 *
+	 * @param      PropelPDO Connection to use.
+	 * @return     void
+	 * @throws     PropelException
+	 */
+	public function delete(PropelPDO \$con = null)
+	{
+		// delete node first
+		parent::delete(\$con);
+
+		// delete descendants and then shift tree
+		$peerClassname::deleteDescendants(\$this, \$con);
+	}
+";
+	}
+
+	protected function addMakeRoot(&$script)
+	{
+		$objectClassName = $this->getStubObjectBuilder()->getClassname();
+		$peerClassname = $this->getStubPeerBuilder()->getClassname();
+		$script .= "
+	/**
+	 * Sets node properties to make it a root node.
+	 *
+	 * @return     $objectClassName The current object (for fluent API support)
+	 * @throws     PropelException
+	 */
+	public function makeRoot()
+	{
+		$peerClassname::createRoot(\$this);
+		return \$this;
+	}
+";
+	}
+
+	protected function addGetLevel(&$script)
+	{
+		$peerClassname = $this->getStubPeerBuilder()->getClassname();
+		$script .= "
+	/**
+	 * Gets the level if set, otherwise calculates this and returns it
+	 *
+	 * @param      PropelPDO Connection to use.
+	 * @return     int
+	 */
+	public function getLevel(PropelPDO \$con = null)
+	{
+		if (null === \$this->level) {
+			\$this->level = $peerClassname::getLevel(\$this, \$con);
+		}
+		return \$this->level;
+	}
+";
+	}
+
+	protected function addSetLevel(&$script)
+	{
+		$objectClassName = $this->getStubObjectBuilder()->getClassname();
+		$script .= "
+	/**
+	 * Sets the level of the node in the tree
+	 *
+	 * @param      int \$v new value
+	 * @return     $objectClassName The current object (for fluent API support)
+	 */
+	public function setLevel(\$level)
+	{
+		\$this->level = \$level;
+		return \$this;
+	}
+";
+	}
+
+	protected function addSetChildren(&$script)
+	{
+		$objectClassName = $this->getStubObjectBuilder()->getClassname();
+		$script .= "
+	/**
+	 * Sets the children array of the node in the tree
+	 *
+	 * @param      array of $objectClassName \$children	array of Propel node object
+	 * @return     $objectClassName The current object (for fluent API support)
+	 */
+	public function setChildren(array \$children)
+	{
+		\$this->_children = \$children;
+		return \$this;
+	}
+";
+	}
+
+	protected function addSetParentNode(&$script)
+	{
+		$objectClassName = $this->getStubObjectBuilder()->getClassname();
+		$peerClassname = $this->getStubPeerBuilder()->getClassname();
+		$script .= "
+	/**
+	 * Sets the parentNode of the node in the tree
+	 *
+	 * @param      $objectClassName \$parent Propel node object
+	 * @return     $objectClassName The current object (for fluent API support)
+	 */
+	public function setParentNode(NodeObject \$parent = null)
+	{
+		\$this->parentNode = (true === (\$this->hasParentNode = $peerClassname::isValid(\$parent))) ? \$parent : null;
+		return \$this;
+	}
+";
+	}
+
+	protected function addSetPrevSibling(&$script)
+	{
+		$objectClassName = $this->getStubObjectBuilder()->getClassname();
+		$peerClassname = $this->getStubPeerBuilder()->getClassname();
+		$script .= "
+	/**
+	 * Sets the previous sibling of the node in the tree
+	 *
+	 * @param      $objectClassName \$node Propel node object
+	 * @return     $objectClassName The current object (for fluent API support)
+	 */
+	public function setPrevSibling(NodeObject \$node = null)
+	{
+		\$this->prevSibling = \$node;
+		\$this->hasPrevSibling = $peerClassname::isValid(\$node);
+		return \$this;
+	}
+";
+	}
+
+	protected function addSetNextSibling(&$script)
+	{
+		$objectClassName = $this->getStubObjectBuilder()->getClassname();
+		$peerClassname = $this->getStubPeerBuilder()->getClassname();
+		$script .= "
+	/**
+	 * Sets the next sibling of the node in the tree
+	 *
+	 * @param      $objectClassName \$node Propel node object
+	 * @return     $objectClassName The current object (for fluent API support)
+	 */
+	public function setNextSibling(NodeObject \$node = null)
+	{
+		\$this->nextSibling = \$node;
+		\$this->hasNextSibling = $peerClassname::isValid(\$node);
+		return \$this;
+	}
+";
+	}
+
+	protected function addGetPath(&$script)
+	{
+		$peerClassname = $this->getStubPeerBuilder()->getClassname();
+		$script .= "
+	/**
+	 * Get the path to the node in the tree
+	 *
+	 * @param      PropelPDO Connection to use.
+	 * @return     array
+	 */
+	public function getPath(PropelPDO \$con = null)
+	{
+		return $peerClassname::getPath(\$this, \$con);
+	}
+";
+	}
+
+	protected function addGetNumberOfChildren(&$script)
+	{
+		$peerClassname = $this->getStubPeerBuilder()->getClassname();
+		$script .= "
+	/**
+	 * Gets the number of children for the node (direct descendants)
+	 *
+	 * @param      PropelPDO Connection to use.
+	 * @return     int
+	 */
+	public function getNumberOfChildren(PropelPDO \$con = null)
+	{
+		return $peerClassname::getNumberOfChildren(\$this, \$con);
+	}
+";
+	}
+
+	protected function addGetNumberOfDescendants(&$script)
+	{
+		$peerClassname = $this->getStubPeerBuilder()->getClassname();
+		$script .= "
+	/**
+	 * Gets the total number of descendants for the node
+	 *
+	 * @param      PropelPDO Connection to use.
+	 * @return     int
+	 */
+	public function getNumberOfDescendants(PropelPDO \$con = null)
+	{
+		return $peerClassname::getNumberOfDescendants(\$this, \$con);
+	}
+";
+	}
+
+	protected function addGetChildren(&$script)
+	{
+		$peerClassname = $this->getStubPeerBuilder()->getClassname();
+		$script .= "
+	/**
+	 * Gets the children for the node
+	 *
+	 * @param      PropelPDO Connection to use.
+	 * @return     array
+	 */
+	public function getChildren(PropelPDO \$con = null)
+	{
+		\$this->getLevel();
+
+		if (is_array(\$this->_children)) {
+			return \$this->_children;
+		}
+
+		return $peerClassname::retrieveChildren(\$this, \$con);
+	}
+";
+	}
+
+	protected function addGetDescendants(&$script)
+	{
+		$peerClassname = $this->getStubPeerBuilder()->getClassname();
+		$script .= "
+	/**
+	 * Gets the descendants for the node
+	 *
+	 * @param      PropelPDO Connection to use.
+	 * @return     array
+	 */
+	public function getDescendants(PropelPDO \$con = null)
+	{
+		\$this->getLevel();
+		if (is_array(\$this->_children)) {
+			return \$this->_children;
+		}
+
+		return $peerClassname::retrieveDescendants(\$this, \$con);
+	}
+";
+	}
+
+	protected function addIsRoot(&$script)
+	{
+		$peerClassname = $this->getStubPeerBuilder()->getClassname();
+		$script .= "
+	/**
+	 * Returns true if node is the root node of the tree.
+	 *
+	 * @return     bool
+	 */
+	public function isRoot()
+	{
+		return $peerClassname::isRoot(\$this);
+	}
+";
+	}
+
+	protected function addIsLeaf(&$script)
+	{
+		$peerClassname = $this->getStubPeerBuilder()->getClassname();
+		$script .= "
+	/**
+	 * Return true if the node is a leaf node
+	 *
+	 * @return     bool
+	 */
+	public function isLeaf()
+	{
+		return $peerClassname::isLeaf(\$this);
+	}
+";
+	}
+
+	protected function addIsEqualTo(&$script)
+	{
+		$peerClassname = $this->getStubPeerBuilder()->getClassname();
+		$script .= "
+	/**
+	 * Tests if object is equal to \$node
+	 *
+	 * @param      object \$node		Propel object for node to compare to
+	 * @return     bool
+	 */
+	public function isEqualTo(NodeObject \$node)
+	{
+		return $peerClassname::isEqualTo(\$this, \$node);
+	}
+";
+	}
+
+	protected function addHasParent(&$script)
+	{
+		$peerClassname = $this->getStubPeerBuilder()->getClassname();
+		$script .= "
+	/**
+	 * Tests if object has an ancestor
+	 *
+	 * @param      PropelPDO \$con Connection to use.
+	 * @return     bool
+	 */
+	public function hasParent(PropelPDO \$con = null)
+	{
+		if (null === \$this->hasParentNode) {
+			$peerClassname::hasParent(\$this, \$con);
+		}
+		return \$this->hasParentNode;
+	}
+";
+	}
+
+	protected function addHasChildren(&$script)
+	{
+		$peerClassname = $this->getStubPeerBuilder()->getClassname();
+		$script .= "
+	/**
+	 * Determines if the node has children / descendants
+	 *
+	 * @return     bool
+	 */
+	public function hasChildren()
+	{
+		return  $peerClassname::hasChildren(\$this);
+	}
+";
+	}
+
+	protected function addHasPrevSibling(&$script)
+	{
+		$peerClassname = $this->getStubPeerBuilder()->getClassname();
+		$script .= "
+	/**
+	 * Determines if the node has previous sibling
+	 *
+	 * @param      PropelPDO \$con Connection to use.
+	 * @return     bool
+	 */
+	public function hasPrevSibling(PropelPDO \$con = null)
+	{
+		if (null === \$this->hasPrevSibling) {
+			$peerClassname::hasPrevSibling(\$this, \$con);
+		}
+		return \$this->hasPrevSibling;
+	}
+";
+	}
+
+	protected function addHasNextSibling(&$script)
+	{
+		$peerClassname = $this->getStubPeerBuilder()->getClassname();
+		$script .= "
+	/**
+	 * Determines if the node has next sibling
+	 *
+	 * @param      PropelPDO \$con Connection to use.
+	 * @return     bool
+	 */
+	public function hasNextSibling(PropelPDO \$con = null)
+	{
+		if (null === \$this->hasNextSibling) {
+			$peerClassname::hasNextSibling(\$this, \$con);
+		}
+		return \$this->hasNextSibling;
+	}
+";
+	}
+
+	protected function addRetrieveParent(&$script)
+	{
+		$peerClassname = $this->getStubPeerBuilder()->getClassname();
+		$script .= "
+	/**
+	 * Gets ancestor for the given node if it exists
+	 *
+	 * @param      PropelPDO \$con Connection to use.
+	 * @return     mixed 		Propel object if exists else false
+	 */
+	public function retrieveParent(PropelPDO \$con = null)
+	{
+		if (null === \$this->hasParentNode) {
+			\$this->parentNode = $peerClassname::retrieveParent(\$this, \$con);
+			\$this->hasParentNode = $peerClassname::isValid(\$this->parentNode);
+		}
+		return \$this->parentNode;
+	}
+";
+	}
+
+	protected function addRetrieveFirstChild(&$script)
+	{
+		$peerClassname = $this->getStubPeerBuilder()->getClassname();
+		$script .= "
+	/**
+	 * Gets first child if it exists
+	 *
+	 * @param      PropelPDO \$con Connection to use.
+	 * @return     mixed 		Propel object if exists else false
+	 */
+	public function retrieveFirstChild(PropelPDO \$con = null)
+	{
+		if (\$this->hasChildren(\$con)) {
+			if (is_array(\$this->_children)) {
+				return \$this->_children[0];
+			}
+
+			return $peerClassname::retrieveFirstChild(\$this, \$con);
+		}
+		return false;
+	}
+";
+	}
+
+	protected function addRetrieveLastChild(&$script)
+	{
+		$peerClassname = $this->getStubPeerBuilder()->getClassname();
+		$script .= "
+	/**
+	 * Gets last child if it exists
+	 *
+	 * @param      PropelPDO \$con Connection to use.
+	 * @return     mixed 		Propel object if exists else false
+	 */
+	public function retrieveLastChild(PropelPDO \$con = null)
+	{
+		if (\$this->hasChildren(\$con)) {
+			if (is_array(\$this->_children)) {
+				\$last = count(\$this->_children) - 1;
+				return \$this->_children[\$last];
+			}
+
+			return $peerClassname::retrieveLastChild(\$this, \$con);
+		}
+		return false;
+	}
+";
+	}
+
+	protected function addRetrievePrevSibling(&$script)
+	{
+		$script .= "
+	/**
+	 * Gets prev sibling for the given node if it exists
+	 *
+	 * @param      PropelPDO \$con Connection to use.
+	 * @return     mixed 		Propel object if exists else false
+	 */
+	public function retrievePrevSibling(PropelPDO \$con = null)
+	{
+		if (\$this->hasPrevSibling(\$con)) {
+			return \$this->prevSibling;
+		}
+		return \$this->hasPrevSibling;
+	}
+";
+	}
+
+	protected function addRetrieveNextSibling(&$script)
+	{
+		$script .= "
+	/**
+	 * Gets next sibling for the given node if it exists
+	 *
+	 * @param      PropelPDO \$con Connection to use.
+	 * @return     mixed 		Propel object if exists else false
+	 */
+	public function retrieveNextSibling(PropelPDO \$con = null)
+	{
+		if (\$this->hasNextSibling(\$con)) {
+			return \$this->nextSibling;
+		}
+		return \$this->hasNextSibling;
+	}
+";
+	}
+
+	protected function addInsertAsFirstChildOf(&$script)
+	{
+		$objectClassName = $this->getStubObjectBuilder()->getClassname();
+		$peerClassname = $this->getStubPeerBuilder()->getClassname();
+		$script .= "
+	/**
+	 * Inserts as first child of given destination node \$parent
+	 *
+	 * @param      $objectClassName \$parent	Propel object for destination node
+	 * @param      PropelPDO \$con Connection to use.
+	 * @return     $objectClassName The current object (for fluent API support)
+	 * @throws     PropelException - if this object already exists
+	 */
+	public function insertAsFirstChildOf(NodeObject \$parent, PropelPDO \$con = null)
+	{
+		if (!\$this->isNew())
+		{
+			throw new PropelException(\"$objectClassName must be new.\");
+		}
+		$peerClassname::insertAsFirstChildOf(\$this, \$parent, \$con);
+		return \$this;
+	}
+";
+	}
+
+	protected function addInsertAsLastChildOf(&$script)
+	{
+		$objectClassName = $this->getStubObjectBuilder()->getClassname();
+		$peerClassname = $this->getStubPeerBuilder()->getClassname();
+		$script .= "
+	/**
+	 * Inserts as last child of given destination node \$parent
+	 *
+	 * @param      $objectClassName \$parent	Propel object for destination node
+	 * @param      PropelPDO \$con Connection to use.
+	 * @return     $objectClassName The current object (for fluent API support)
+	 * @throws     PropelException - if this object already exists
+	 */
+	public function insertAsLastChildOf(NodeObject \$parent, PropelPDO \$con = null)
+	{
+		if (!\$this->isNew())
+		{
+			throw new PropelException(\"$objectClassName must be new.\");
+		}
+		$peerClassname::insertAsLastChildOf(\$this, \$parent, \$con);
+		return \$this;
+	}
+";
+	}
+
+	protected function addInsertAsPrevSiblingOf(&$script)
+	{
+		$objectClassName = $this->getStubObjectBuilder()->getClassname();
+		$peerClassname = $this->getStubPeerBuilder()->getClassname();
+		$script .= "
+	/**
+	 * Inserts \$node as previous sibling to given destination node \$dest
+	 *
+	 * @param      $objectClassName \$dest	Propel object for destination node
+	 * @param      PropelPDO \$con Connection to use.
+	 * @return     $objectClassName The current object (for fluent API support)
+	 * @throws     PropelException - if this object already exists
+	 */
+	public function insertAsPrevSiblingOf(NodeObject \$dest, PropelPDO \$con = null)
+	{
+		if (!\$this->isNew())
+		{
+			throw new PropelException(\"$objectClassName must be new.\");
+		}
+		$peerClassname::insertAsPrevSiblingOf(\$this, \$dest, \$con);
+		return \$this;
+	}
+";
+	}
+
+	protected function addInsertAsNextSiblingOf(&$script)
+	{
+		$objectClassName = $this->getStubObjectBuilder()->getClassname();
+		$peerClassname = $this->getStubPeerBuilder()->getClassname();
+		$script .= "
+	/**
+	 * Inserts \$node as next sibling to given destination node \$dest
+	 *
+	 * @param      $objectClassName \$dest	Propel object for destination node
+	 * @param      PropelPDO \$con Connection to use.
+	 * @return     $objectClassName The current object (for fluent API support)
+	 * @throws     PropelException - if this object already exists
+	 */
+	public function insertAsNextSiblingOf(NodeObject \$dest, PropelPDO \$con = null)
+	{
+		if (!\$this->isNew())
+		{
+			throw new PropelException(\"$objectClassName must be new.\");
+		}
+		$peerClassname::insertAsNextSiblingOf(\$this, \$dest, \$con);
+		return \$this;
+	}
+";
+	}
+
+	protected function addMoveToFirstChildOf(&$script)
+	{
+		$objectClassName = $this->getStubObjectBuilder()->getClassname();
+		$peerClassname = $this->getStubPeerBuilder()->getClassname();
+		$script .= "
+	/**
+	 * Moves node to be first child of \$parent
+	 *
+	 * @param      $objectClassName \$parent	Propel object for destination node
+	 * @param      PropelPDO \$con Connection to use.
+	 * @return     $objectClassName The current object (for fluent API support)
+	 */
+	public function moveToFirstChildOf(NodeObject \$parent, PropelPDO \$con = null)
+	{
+		if (\$this->isNew())
+		{
+			throw new PropelException(\"$objectClassName must exist in tree.\");
+		}
+		$peerClassname::moveToFirstChildOf(\$parent, \$this, \$con);
+		return \$this;
+	}
+";
+	}
+
+	protected function addMoveToLastChildOf(&$script)
+	{
+		$objectClassName = $this->getStubObjectBuilder()->getClassname();
+		$peerClassname = $this->getStubPeerBuilder()->getClassname();
+		$script .= "
+	/**
+	 * Moves node to be last child of \$parent
+	 *
+	 * @param      $objectClassName \$parent	Propel object for destination node
+	 * @param      PropelPDO \$con Connection to use.
+	 * @return     $objectClassName The current object (for fluent API support)
+	 */
+	public function moveToLastChildOf(NodeObject \$parent, PropelPDO \$con = null)
+	{
+		if (\$this->isNew())
+		{
+			throw new PropelException(\"$objectClassName must exist in tree.\");
+		}
+		$peerClassname::moveToLastChildOf(\$parent, \$this, \$con);
+		return \$this;
+	}
+";
+	}
+
+	protected function addMoveToPrevSiblingOf(&$script)
+	{
+		$objectClassName = $this->getStubObjectBuilder()->getClassname();
+		$peerClassname = $this->getStubPeerBuilder()->getClassname();
+		$script .= "
+	/**
+	 * Moves node to be prev sibling to \$dest
+	 *
+	 * @param      $objectClassName \$dest	Propel object for destination node
+	 * @param      PropelPDO \$con Connection to use.
+	 * @return     $objectClassName The current object (for fluent API support)
+	 */
+	public function moveToPrevSiblingOf(NodeObject \$dest, PropelPDO \$con = null)
+	{
+		if (\$this->isNew())
+		{
+			throw new PropelException(\"$objectClassName must exist in tree.\");
+		}
+		$peerClassname::moveToPrevSiblingOf(\$dest, \$this, \$con);
+		return \$this;
+	}
+";
+	}
+
+	protected function addMoveToNextSiblingOf(&$script)
+	{
+		$objectClassName = $this->getStubObjectBuilder()->getClassname();
+		$peerClassname = $this->getStubPeerBuilder()->getClassname();
+		$script .= "
+	/**
+	 * Moves node to be next sibling to \$dest
+	 *
+	 * @param      $objectClassName \$dest	Propel object for destination node
+	 * @param      PropelPDO \$con Connection to use.
+	 * @return     $objectClassName The current object (for fluent API support)
+	 */
+	public function moveToNextSiblingOf(NodeObject \$dest, PropelPDO \$con = null)
+	{
+		if (\$this->isNew())
+		{
+			throw new PropelException(\"$objectClassName must exist in tree.\");
+		}
+		$peerClassname::moveToNextSiblingOf(\$dest, \$this, \$con);
+		return \$this;
+	}
+";
+	}
+
+	protected function addInsertAsParentOf(&$script)
+	{
+		$objectClassName = $this->getStubObjectBuilder()->getClassname();
+		$peerClassname = $this->getStubPeerBuilder()->getClassname();
+		$script .= "
+	/**
+	 * Inserts node as parent of given node.
+	 *
+	 * @param      $objectClassName \$node Propel object for destination node
+	 * @param      PropelPDO \$con	Connection to use.
+	 * @return     $objectClassName The current object (for fluent API support)
+	 */
+	public function insertAsParentOf(NodeObject \$node, PropelPDO \$con = null)
+	{
+		$peerClassname::insertAsParentOf(\$this, \$node, \$con);
+		return \$this;
+	}
+";
+	}
+
+	protected function addGetLeft(&$script)
+	{
+		$table = $this->getTable();
+
+		foreach ($table->getColumns() as $col) {
+			if ($col->isNestedSetLeftKey()) {
+				$left_col_getter_name = 'get'.$col->getPhpName();
+				break;
+			}
+		}
+
+		$script .= "
+	/**
+	 * Wraps the getter for the left value
+	 *
+	 * @return     int
+	 */
+	public function getLeftValue()
+	{
+		return \$this->$left_col_getter_name();
+	}
+";
+	}
+
+	protected function addGetRight(&$script)
+	{
+		$table = $this->getTable();
+
+		foreach ($table->getColumns() as $col) {
+			if ($col->isNestedSetRightKey()) {
+				$right_col_getter_name = 'get'.$col->getPhpName();
+				break;
+			}
+		}
+
+		$script .= "
+	/**
+	 * Wraps the getter for the right value
+	 *
+	 * @return     int
+	 */
+	public function getRightValue()
+	{
+		return \$this->$right_col_getter_name();
+	}
+";
+	}
+
+	protected function addGetScopeId(&$script)
+	{
+		$table = $this->getTable();
+
+		$scope_col_getter_name = null;
+		foreach ($table->getColumns() as $col) {
+			if ($col->isTreeScopeKey()) {
+				$scope_col_getter_name = 'get'.$col->getPhpName();
+				break;
+			}
+		}
+
+		$script .= "
+	/**
+	 * Wraps the getter for the scope value
+	 *
+	 * @return     int
+	 */
+	public function getScopeIdValue()
+	{";
+		if ($scope_col_getter_name) {
+			$script .= "
+		return \$this->$scope_col_getter_name();";
+		}
+		$script .= "
+	}
+";
+	}
+
+	protected function addSetLeft(&$script)
+	{
+		$objectClassName = $this->getStubObjectBuilder()->getClassname();
+		$table = $this->getTable();
+
+		foreach ($table->getColumns() as $col) {
+			if ($col->isNestedSetLeftKey()) {
+				$left_col_setter_name = 'set'.$col->getPhpName();
+				break;
+			}
+		}
+
+		$script .= "
+	/**
+	 * Set the value left column
+	 *
+	 * @param      int \$v new value
+	 * @return     $objectClassName The current object (for fluent API support)
+	 */
+	public function setLeftValue(\$v)
+	{
+		\$this->$left_col_setter_name(\$v);
+		return \$this;
+	}
+";
+	}
+
+	protected function addSetRight(&$script)
+	{
+		$objectClassName = $this->getStubObjectBuilder()->getClassname();
+		$table = $this->getTable();
+
+		foreach ($table->getColumns() as $col) {
+			if ($col->isNestedSetRightKey()) {
+				$right_col_setter_name = 'set'.$col->getPhpName();
+				break;
+			}
+		}
+
+		$script .= "
+	/**
+	 * Set the value of right column
+	 *
+	 * @param      int \$v new value
+	 * @return     $objectClassName The current object (for fluent API support)
+	 */
+	public function setRightValue(\$v)
+	{
+		\$this->$right_col_setter_name(\$v);
+		return \$this;
+	}
+";
+	}
+
+	protected function addSetScopeId(&$script)
+	{
+		$objectClassName = $this->getStubObjectBuilder()->getClassname();
+		$table = $this->getTable();
+
+		$scope_col_setter_name = null;
+		foreach ($table->getColumns() as $col) {
+			if ($col->isTreeScopeKey()) {
+				$scope_col_setter_name = 'set'.$col->getPhpName();
+				break;
+			}
+		}
+
+		$script .= "
+	/**
+	 * Set the value of scope column
+	 *
+	 * @param      int \$v new value
+	 * @return     $objectClassName The current object (for fluent API support)
+	 */
+	public function setScopeIdValue(\$v)
+	{";
+		if ($scope_col_setter_name) {
+			$script .= "
+		\$this->$scope_col_setter_name(\$v);";
+		}
+		$script .= "
+		return \$this;
+	}
+";
+
+	}
+
+} // PHP5NestedSetBuilder
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/builder/om/php5/PHP5NestedSetPeerBuilder.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/builder/om/php5/PHP5NestedSetPeerBuilder.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/builder/om/php5/PHP5NestedSetPeerBuilder.php	(revision 19)
@@ -0,0 +1,1732 @@
+<?php
+
+/*
+ *  $Id: PHP5NestedSetPeerBuilder.php 1065 2008-07-07 17:27:08Z heltem $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://propel.phpdb.org>.
+ */
+
+require_once 'propel/engine/builder/om/PeerBuilder.php';
+
+/**
+ * Generates a PHP5 tree nested set Peer class for user object model (OM).
+ *
+ * This class produces the base tree nested set object class (e.g. BaseMyTable) which contains all
+ * the custom-built accessor and setter methods.
+ *
+ * This class replaces the Node.tpl, with the intent of being easier for users
+ * to customize (through extending & overriding).
+ *
+ * @author     heltem <heltem@o2php.com>
+ * @package    propel.engine.builder.om.php5
+ */
+class PHP5NestedSetPeerBuilder extends PeerBuilder {
+
+	/**
+	 * Gets the package for the [base] object classes.
+	 * @return     string
+	 */
+	public function getPackage()
+	{
+		return parent::getPackage() . ".om";
+	}
+
+	/**
+	 * Returns the name of the current class being built.
+	 * @return     string
+	 */
+	public function getUnprefixedClassname()
+	{
+		return $this->getBuildProperty('basePrefix') . $this->getStubObjectBuilder()->getUnprefixedClassname() . 'NestedSetPeer';
+	}
+
+	/**
+	 * Adds the include() statements for files that this class depends on or utilizes.
+	 * @param      string &$script The script will be modified in this method.
+	 */
+	protected function addIncludes(&$script)
+	{
+		$script .="
+require '".$this->getPeerBuilder()->getClassFilePath()."';
+";
+	} // addIncludes()
+
+	/**
+	 * Adds class phpdoc comment and openning of class.
+	 * @param      string &$script The script will be modified in this method.
+	 */
+	protected function addClassOpen(&$script)
+	{
+
+		$table = $this->getTable();
+		$tableName = $table->getName();
+		$tableDesc = $table->getDescription();
+
+		$script .= "
+/**
+ * Base static class for performing query operations on the tree contained by the '$tableName' table.
+ *
+ * $tableDesc
+ *";
+		if ($this->getBuildProperty('addTimeStamp')) {
+			$now = strftime('%c');
+			$script .= "
+ * This class was autogenerated by Propel " . $this->getBuildProperty('version') . " on:
+ *
+ * $now
+ *";
+		}
+		$script .= "
+ * @package    ".$this->getPackage()."
+ */
+abstract class ".$this->getClassname()." extends ".$this->getPeerBuilder()->getClassName()." implements NodePeer {
+";
+	}
+
+	/**
+	 * Specifies the methods that are added as part of the basic OM class.
+	 * This can be overridden by subclasses that wish to add more methods.
+	 * @see        ObjectBuilder::addClassBody()
+	 */
+	protected function addClassBody(&$script)
+	{
+		$table = $this->getTable();
+
+		// FIXME
+		// - Probably the build needs to be customized for supporting
+		// tables that are "aliases".  -- definitely a fringe usecase, though.
+
+		$this->addConstants($script);
+
+		$this->addCreateRoot($script);
+
+		$this->addRetrieveRoot($script);
+
+		$this->addInsertAsFirstChildOf($script);
+		$this->addInsertAsLastChildOf($script);
+		$this->addInsertAsPrevSiblingOf($script);
+		$this->addInsertAsNextSiblingOf($script);
+		$this->addInsertAsParentOf($script);
+
+		$this->addInsertRoot($script);
+		$this->addInsertParent($script);
+
+		$this->addDeleteRoot($script);
+		$this->addDeleteNode($script);
+
+		$this->addMoveToFirstChildOf($script);
+		$this->addMoveToLastChildOf($script);
+		$this->addMoveToPrevSiblingOf($script);
+		$this->addMoveToNextSiblingOf($script);
+
+		$this->addRetrieveFirstChild($script);
+		$this->addRetrieveLastChild($script);
+		$this->addRetrievePrevSibling($script);
+		$this->addRetrieveNextSibling($script);
+
+		$this->addRetrieveTree($script);
+		$this->addRetrieveBranch($script);
+		$this->addRetrieveChildren($script);
+		$this->addRetrieveDescendants($script);
+		$this->addRetrieveSiblings($script);
+		$this->addRetrieveParent($script);
+
+		$this->addGetLevel($script);
+		$this->addGetNumberOfChildren($script);
+		$this->addGetNumberOfDescendants($script);
+		$this->addGetPath($script);
+
+		$this->addIsValid($script);
+		$this->addIsRoot($script);
+		$this->addIsLeaf($script);
+		$this->addIsChildOf($script);
+		$this->addIsChildOfOrSiblingTo($script);
+		$this->addIsEqualTo($script);
+
+		$this->addHasParent($script);
+		$this->addHasPrevSibling($script);
+		$this->addHasNextSibling($script);
+		$this->addHasChildren($script);
+
+		$this->addDeleteDescendants($script);
+
+		$this->addGetNode($script);
+
+		$this->addHydrateDescendants($script);
+		$this->addHydrateChildren($script);
+
+		$this->addShiftRParent($script);
+		$this->addUpdateLoadedNode($script);
+		$this->addUpdateDBNode($script);
+
+		$this->addShiftRLValues($script);
+		$this->addShiftRLRange($script);
+	}
+
+	/**
+	 * Closes class.
+	 * @param      string &$script The script will be modified in this method.
+	 */
+	protected function addClassClose(&$script)
+	{
+		$script .= "
+} // " . $this->getClassname() . "
+";
+	}
+
+	protected function addConstants(&$script)
+	{
+		$table = $this->getTable();
+		$tableName = $table->getName();
+
+		$colname = array();
+
+		foreach ($table->getColumns() as $col) {
+			if ($col->isNestedSetLeftKey()) {
+				$colname['left'] = $this->prefixTablename($tableName) . '.' . strtoupper($col->getName());
+			}
+
+			if ($col->isNestedSetRightKey()) {
+				$colname['right'] = $this->prefixTablename($tableName) . '.' . strtoupper($col->getName());
+			}
+
+			if ($col->isTreeScopeKey()) {
+				$colname['scope'] = $this->prefixTablename($tableName) . '.' . strtoupper($col->getName());
+			}
+
+			if (3 == count($colname)) {
+				break;
+			}
+		}
+
+		if(!isset($colname['left'])) {
+			throw new EngineException("One column must have nestedSetLeftKey attribute set to true for [" . $table->getName() . "] table");
+		}
+
+		if(!isset($colname['right'])) {
+			throw new EngineException("One column must have nestedSetRightKey attribute set to true for [" . $table->getName() . "] table");
+		}
+
+		$colname['scope'] = isset($colname['scope']) ? $colname['scope'] : null;
+
+		$script .= "
+	/**
+	 * Left column for the set
+	 */
+	const LEFT_COL = " . var_export($colname['left'], true) . ";
+
+	/**
+	 * Right column for the set
+	 */
+	const RIGHT_COL = " . var_export($colname['right'], true) . ";
+
+	/**
+	 * Scope column for the set
+	 */
+	const SCOPE_COL = " . var_export($colname['scope'], true) . ";
+";
+	}
+
+	protected function addCreateRoot(&$script)
+	{
+		$objectClassname = $this->getStubObjectBuilder()->getClassname();
+		$peerClassname = $this->getStubPeerBuilder()->getClassname();
+		$script .= "
+	/**
+	 * Creates the supplied node as the root node.
+	 *
+	 * @param      $objectClassname \$node	Propel object for model
+	 * @throws     PropelException
+	 */
+	public static function createRoot(NodeObject \$node)
+	{
+		if (\$node->getLeftValue()) {
+			throw new PropelException('Cannot turn an existing node into a root node.');
+		}
+
+		\$node->setLeftValue(1);
+		\$node->setRightValue(2);
+	}
+";
+	}
+
+	protected function addRetrieveRoot(&$script)
+	{
+		$objectClassname = $this->getStubObjectBuilder()->getClassname();
+		$peerClassname = $this->getStubPeerBuilder()->getClassname();
+		$script .= "
+	/**
+	 * Returns the root node for a given scope id
+	 *
+	 * @param      int \$scopeId		Scope id to determine which root node to return
+	 * @param      PropelPDO \$con	Connection to use.
+	 * @return     $objectClassname			Propel object for root node
+	 */
+	public static function retrieveRoot(\$scopeId = null, PropelPDO \$con = null)
+	{
+		\$c = new Criteria($peerClassname::DATABASE_NAME);
+
+		\$c->add(self::LEFT_COL, 1, Criteria::EQUAL);
+
+		if (self::SCOPE_COL) {
+			\$c->add(self::SCOPE_COL, \$scopeId, Criteria::EQUAL);
+		}
+
+		return $peerClassname::doSelectOne(\$c, \$con);
+	}
+";
+	}
+
+	protected function addInsertAsFirstChildOf(&$script)
+	{
+		$objectClassname = $this->getStubObjectBuilder()->getClassname();
+		$peerClassname = $this->getStubPeerBuilder()->getClassname();
+		$script .= "
+	/**
+	 * Inserts \$child as first child of given \$parent node
+	 *
+	 * @param      $objectClassname \$child	Propel object for child node
+	 * @param      $objectClassname \$parent	Propel object for parent node
+	 * @param      PropelPDO \$con	Connection to use.
+	 * @return     void
+	 */
+	public static function insertAsFirstChildOf(NodeObject \$child, NodeObject \$parent, PropelPDO \$con = null)
+	{
+		// Update \$child node properties
+		\$child->setLeftValue(\$parent->getLeftValue() + 1);
+		\$child->setRightValue(\$parent->getLeftValue() + 2);
+		\$child->setParentNode(\$parent);
+
+		\$sidv = null;
+		if (self::SCOPE_COL) {
+			\$child->setScopeIdValue(\$sidv = \$parent->getScopeIdValue());
+		}
+
+		// Update database nodes
+		self::shiftRLValues(\$child->getLeftValue(), 2, \$con, \$sidv);
+
+		// Update all loaded nodes
+		self::updateLoadedNode(\$parent, 2, \$con);
+	}
+";
+	}
+
+	protected function addInsertAsLastChildOf(&$script)
+	{
+		$objectClassname = $this->getStubObjectBuilder()->getClassname();
+		$peerClassname = $this->getStubPeerBuilder()->getClassname();
+		$script .= "
+	/**
+	 * Inserts \$child as last child of destination node \$parent
+	 *
+	 * @param      $objectClassname \$child		Propel object for child node
+	 * @param      $objectClassname \$parent	Propel object for parent node
+	 * @param      PropelPDO \$con	Connection to use.
+	 * @return     void
+	 */
+	public static function insertAsLastChildOf(NodeObject \$child, NodeObject \$parent, PropelPDO \$con = null)
+	{
+		// Update \$child node properties
+		\$child->setLeftValue(\$parent->getRightValue());
+		\$child->setRightValue(\$parent->getRightValue() + 1);
+		\$child->setParentNode(\$parent);
+
+		\$sidv = null;
+		if (self::SCOPE_COL) {
+			\$child->setScopeIdValue(\$sidv = \$parent->getScopeIdValue());
+		}
+
+		// Update database nodes
+		self::shiftRLValues(\$child->getLeftValue(), 2, \$con, \$sidv);
+
+		// Update all loaded nodes
+		self::updateLoadedNode(\$parent, 2, \$con);
+	}
+";
+	}
+
+	protected function addInsertAsPrevSiblingOf(&$script)
+	{
+		$objectClassname = $this->getStubObjectBuilder()->getClassname();
+		$peerClassname = $this->getStubPeerBuilder()->getClassname();
+		$script .= "
+	/**
+	 * Inserts \$sibling as previous sibling to destination node \$node
+	 *
+	 * @param      $objectClassname \$node		Propel object for destination node
+	 * @param      $objectClassname \$sibling	Propel object for source node
+	 * @param      PropelPDO \$con	Connection to use.
+	 * @return     void
+	 */
+	public static function insertAsPrevSiblingOf(NodeObject \$node, NodeObject \$sibling, PropelPDO \$con = null)
+	{
+		if (\$sibling->isRoot()) {
+			throw new PropelException('Root nodes cannot have siblings');
+		}
+
+		\$node->setLeftValue(\$sibling->getLeftValue());
+		\$node->setRightValue(\$sibling->getLeftValue() + 1);
+		\$node->setParentNode(\$sibling->retrieveParent());
+
+		\$sidv = null;
+		if (self::SCOPE_COL) {
+			\$node->setScopeIdValue(\$sidv = \$sibling->getScopeIdValue());
+		}
+
+		// Update database nodes
+		self::shiftRLValues(\$node->getLeftValue(), 2, \$con, \$sidv);
+
+		// Update all loaded nodes
+		self::updateLoadedNode(\$sibling->retrieveParent(), 2, \$con);
+	}
+";
+	}
+
+	protected function addInsertAsNextSiblingOf(&$script)
+	{
+		$objectClassname = $this->getStubObjectBuilder()->getClassname();
+		$peerClassname = $this->getStubPeerBuilder()->getClassname();
+		$script .= "
+	/**
+	 * Inserts \$sibling as next sibling to destination node \$node
+	 *
+	 * @param      $objectClassname \$node		Propel object for destination node
+	 * @param      $objectClassname \$sibling	Propel object for source node
+	 * @param      PropelPDO \$con	Connection to use.
+	 * @return     void
+	 */
+	public static function insertAsNextSiblingOf(NodeObject \$node, NodeObject \$sibling, PropelPDO \$con = null)
+	{
+		if (\$sibling->isRoot()) {
+			throw new PropelException('Root nodes cannot have siblings');
+		}
+
+		\$node->setLeftValue(\$sibling->getRightValue() + 1);
+		\$node->setRightValue(\$sibling->getRightValue() + 2);
+		\$node->setParentNode(\$sibling->retrieveParent());
+
+		\$sidv = null;
+		if (self::SCOPE_COL) {
+			\$node->setScopeIdValue(\$sidv = \$sibling->getScopeIdValue());
+		}
+
+		// Update database nodes
+		self::shiftRLValues(\$node->getLeftValue(), 2, \$con, \$sidv);
+
+		// Update all loaded nodes
+		self::updateLoadedNode(\$sibling->retrieveParent(), 2, \$con);
+	}
+";
+	}
+
+	protected function addInsertAsParentOf(&$script)
+	{
+		$objectClassname = $this->getStubObjectBuilder()->getClassname();
+		$peerClassname = $this->getStubPeerBuilder()->getClassname();
+		$script .= "
+	/**
+	 * Inserts \$parent as parent of given node.
+	 *
+	 * @param      $objectClassname \$parent	Propel object for given parent node
+	 * @param      $objectClassname \$node	Propel object for given destination node
+	 * @param      PropelPDO \$con	Connection to use.
+	 * @return     void
+	 */
+	public static function insertAsParentOf(NodeObject \$parent, NodeObject \$node, PropelPDO \$con = null)
+	{
+		\$sidv = null;
+		if (self::SCOPE_COL) {
+			\$sidv = \$node->getScopeIdValue();
+		}
+
+		self::shiftRLValues(\$node->getLeftValue(), 1, \$con, \$sidv);
+		self::shiftRLValues(\$node->getRightValue() + 2, 1, \$con, \$sidv);
+
+		if (self::SCOPE_COL) {
+			\$parent->setScopeIdValue(\$sidv);
+		}
+
+		\$parent->setLeftValue(\$node->getLeftValue());
+		\$parent->setRightValue(\$node->getRightValue() + 2);
+
+		\$previous_parent = \$node->retrieveParent();
+		\$parent->setParentNode(\$previous_parent);
+		\$node->setParentNode(\$parent);
+
+		\$node->save(\$con);
+
+		// Update all loaded nodes
+		self::updateLoadedNode(\$previous_parent, 2, \$con);
+	}
+";
+	}
+
+	protected function addInsertRoot(&$script)
+	{
+		$objectClassname = $this->getStubObjectBuilder()->getClassname();
+		$peerClassname = $this->getStubPeerBuilder()->getClassname();
+		$script .= "
+	/**
+	 * Inserts \$node as root node
+	 *
+	 * @param      $objectClassname \$node	Propel object as root node
+	 * @param      PropelPDO \$con	Connection to use.
+	 * @return     void
+	 */
+	public static function insertRoot(NodeObject \$node, PropelPDO \$con = null)
+	{
+		\$sidv = null;
+		if (self::SCOPE_COL) {
+			\$sidv = \$node->getScopeIdValue();
+		}
+
+		$peerClassname::insertAsParentOf($peerClassname::retrieveRoot(\$sidv, \$con), \$node, \$con);
+	}
+";
+	}
+
+	protected function addInsertParent(&$script)
+	{
+		$objectClassname = $this->getStubObjectBuilder()->getClassname();
+		$peerClassname = $this->getStubPeerBuilder()->getClassname();
+		$script .= "
+	/**
+	 * Inserts \$parent as parent to destination node \$child
+	 *
+	 * @deprecated 1.3 - 2007/11/06
+	 * @see        insertAsParentOf()
+	 * @param      $objectClassname \$child	Propel object to become child node
+	 * @param      $objectClassname \$parent	Propel object as parent node
+	 * @param      PropelPDO \$con	Connection to use.
+	 * @return     void
+	 */
+	public static function insertParent(NodeObject \$child, NodeObject \$parent, PropelPDO \$con = null)
+	{
+		self::insertAsParentOf(\$parent, \$child, \$con);
+	}
+";
+	}
+
+	protected function addDeleteRoot(&$script)
+	{
+		$peerClassname = $this->getStubPeerBuilder()->getClassname();
+		$script .= "
+	/**
+	 * Delete root node
+	 *
+	 * @param      PropelPDO \$con	Connection to use.
+	 * @return     boolean		Deletion status
+	 */
+	public static function deleteRoot(\$scopeId = null, PropelPDO \$con = null)
+	{
+		if (!self::SCOPE_COL) {
+			\$scopeId = null;
+		}
+		\$root = $peerClassname::retrieveRoot(\$scopeId, \$con);
+		if ($peerClassname::getNumberOfChildren(\$root) == 1) {
+			return $peerClassname::deleteNode(\$root, \$con);
+		} else {
+			return false;
+		}
+	}
+";
+	}
+
+	protected function addDeleteNode(&$script)
+	{
+		$objectClassname = $this->getStubObjectBuilder()->getClassname();
+		$peerClassname = $this->getStubPeerBuilder()->getClassname();
+		$script .= "
+	/**
+	 * Delete \$dest node
+	 *
+	 * @param      $objectClassname \$dest	Propel object node to delete
+	 * @param      PropelPDO \$con	Connection to use.
+	 * @return     boolean		Deletion status
+	 */
+	public static function deleteNode(NodeObject \$dest, PropelPDO \$con = null)
+	{
+		if (\$dest->getLeftValue() == 1) {
+			// deleting root implies conditions (see deleteRoot() method)
+			return $peerClassname::deleteRoot(\$con);
+		}
+
+		\$sidv = null;
+		if (self::SCOPE_COL) {
+			\$sidv = \$dest->getScopeIdValue();
+		}
+
+		self::shiftRLRange(\$dest->getLeftValue(), \$dest->getRightValue(), -1, \$con, \$sidv);
+		self::shiftRLValues(\$dest->getRightValue() + 1, -2, \$con, \$sidv);
+		return \$dest->delete(\$con);
+	}
+";
+	}
+
+	protected function addMoveToFirstChildOf(&$script)
+	{
+		$objectClassname = $this->getStubObjectBuilder()->getClassname();
+		$peerClassname = $this->getStubPeerBuilder()->getClassname();
+		$script .= "
+	/**
+	 * Moves \$child to be first child of \$parent
+	 *
+	 * @param      $objectClassname \$parent	Propel object for parent node
+	 * @param      $objectClassname \$child		Propel object for child node
+	 * @param      PropelPDO \$con	Connection to use.
+	 * @return     void
+	 */
+	public static function moveToFirstChildOf(NodeObject \$parent, NodeObject \$child, PropelPDO \$con = null)
+	{
+		if (\$parent->getScopeIdValue() != \$child->getScopeIdValue()) {
+			throw new PropelException('Moving nodes across trees is not supported');
+		}
+		\$destLeft = \$parent->getLeftValue() + 1;
+		self::updateDBNode(\$child, \$destLeft, \$con);
+
+		// Update all loaded nodes
+		self::updateLoadedNode(\$parent, 2, \$con);
+	}
+";
+	}
+
+	protected function addMoveToLastChildOf(&$script)
+	{
+		$objectClassname = $this->getStubObjectBuilder()->getClassname();
+		$peerClassname = $this->getStubPeerBuilder()->getClassname();
+		$script .= "
+	/**
+	 * Moves \$child to be last child of \$parent
+	 *
+	 * @param      $objectClassname \$parent	Propel object for parent node
+	 * @param      $objectClassname \$child		Propel object for child node
+	 * @param      PropelPDO \$con	Connection to use.
+	 * @return     void
+	 */
+	public static function moveToLastChildOf(NodeObject \$parent, NodeObject \$child, PropelPDO \$con = null)
+	{
+		if (\$parent->getScopeIdValue() != \$child->getScopeIdValue()) {
+			throw new PropelException('Moving nodes across trees is not supported');
+		}
+		\$destLeft = \$parent->getRightValue();
+		self::updateDBNode(\$child, \$destLeft, \$con);
+
+		// Update all loaded nodes
+		self::updateLoadedNode(\$parent, 2, \$con);
+	}
+";
+	}
+
+	protected function addMoveToPrevSiblingOf(&$script)
+	{
+		$objectClassname = $this->getStubObjectBuilder()->getClassname();
+		$peerClassname = $this->getStubPeerBuilder()->getClassname();
+		$script .= "
+	/**
+	 * Moves \$node to be prev sibling to \$dest
+	 *
+	 * @param      $objectClassname \$dest	Propel object for destination node
+	 * @param      $objectClassname \$node	Propel object for source node
+	 * @param      PropelPDO \$con	Connection to use.
+	 * @return     void
+	 */
+	public static function moveToPrevSiblingOf(NodeObject \$dest, NodeObject \$node, PropelPDO \$con = null)
+	{
+		if (\$dest->getScopeIdValue() != \$node->getScopeIdValue()) {
+			throw new PropelException('Moving nodes across trees is not supported');
+		}
+		\$destLeft = \$dest->getLeftValue();
+		self::updateDBNode(\$node, \$destLeft, \$con);
+
+		// Update all loaded nodes
+		self::updateLoadedNode(\$dest->retrieveParent(), 2, \$con);
+	}
+";
+	}
+
+	protected function addMoveToNextSiblingOf(&$script)
+	{
+		$objectClassname = $this->getStubObjectBuilder()->getClassname();
+		$peerClassname = $this->getStubPeerBuilder()->getClassname();
+		$script .= "
+	/**
+	 * Moves \$node to be next sibling to \$dest
+	 *
+	 * @param      $objectClassname \$dest	Propel object for destination node
+	 * @param      $objectClassname \$node	Propel object for source node
+	 * @param      PropelPDO \$con	Connection to use.
+	 * @return     void
+	 */
+	public static function moveToNextSiblingOf(NodeObject \$dest, NodeObject \$node, PropelPDO \$con = null)
+	{
+		if (\$dest->getScopeIdValue() != \$node->getScopeIdValue()) {
+			throw new PropelException('Moving nodes across trees is not supported');
+		}
+		\$destLeft = \$dest->getRightValue();
+		\$destLeft = \$destLeft + 1;
+		self::updateDBNode(\$node, \$destLeft, \$con);
+
+		// Update all loaded nodes
+		self::updateLoadedNode(\$dest->retrieveParent(), 2, \$con);
+	}
+";
+	}
+
+	protected function addRetrieveFirstChild(&$script)
+	{
+		$objectClassname = $this->getStubObjectBuilder()->getClassname();
+		$peerClassname = $this->getStubPeerBuilder()->getClassname();
+		$script .= "
+	/**
+	 * Gets first child for the given node if it exists
+	 *
+	 * @param      $objectClassname \$node	Propel object for src node
+	 * @param      PropelPDO \$con	Connection to use.
+	 * @return     mixed 		Propel object if exists else false
+	 */
+	public static function retrieveFirstChild(NodeObject \$node, PropelPDO \$con = null)
+	{
+		\$c = new Criteria($peerClassname::DATABASE_NAME);
+		\$c->add(self::LEFT_COL, \$node->getLeftValue() + 1, Criteria::EQUAL);
+		if (self::SCOPE_COL) {
+			\$c->add(self::SCOPE_COL, \$node->getScopeIdValue(), Criteria::EQUAL);
+		}
+
+		return $peerClassname::doSelectOne(\$c, \$con);
+	}
+";
+	}
+
+	protected function addRetrieveLastChild(&$script)
+	{
+		$objectClassname = $this->getStubObjectBuilder()->getClassname();
+		$peerClassname = $this->getStubPeerBuilder()->getClassname();
+		$script .= "
+	/**
+	 * Gets last child for the given node if it exists
+	 *
+	 * @param      $objectClassname \$node	Propel object for src node
+	 * @param      PropelPDO \$con	Connection to use.
+	 * @return     mixed 		Propel object if exists else false
+	 */
+	public static function retrieveLastChild(NodeObject \$node, PropelPDO \$con = null)
+	{
+		\$c = new Criteria($peerClassname::DATABASE_NAME);
+		\$c->add(self::RIGHT_COL, \$node->getRightValue() - 1, Criteria::EQUAL);
+		if (self::SCOPE_COL) {
+			\$c->add(self::SCOPE_COL, \$node->getScopeIdValue(), Criteria::EQUAL);
+		}
+
+		return $peerClassname::doSelectOne(\$c, \$con);
+	}
+";
+	}
+
+	protected function addRetrievePrevSibling(&$script)
+	{
+		$objectClassname = $this->getStubObjectBuilder()->getClassname();
+		$peerClassname = $this->getStubPeerBuilder()->getClassname();
+		$script .= "
+	/**
+	 * Gets prev sibling for the given node if it exists
+	 *
+	 * @param      $objectClassname \$node	Propel object for src node
+	 * @param      PropelPDO \$con	Connection to use.
+	 * @return     mixed 		Propel object if exists else null
+	 */
+	public static function retrievePrevSibling(NodeObject \$node, PropelPDO \$con = null)
+	{
+		\$c = new Criteria($peerClassname::DATABASE_NAME);
+		\$c->add(self::RIGHT_COL, \$node->getLeftValue() - 1, Criteria::EQUAL);
+		if (self::SCOPE_COL) {
+			\$c->add(self::SCOPE_COL, \$node->getScopeIdValue(), Criteria::EQUAL);
+		}
+		\$prevSibling = $peerClassname::doSelectOne(\$c, \$con);
+		\$node->setPrevSibling(\$prevSibling);
+		return \$prevSibling;
+	}
+";
+	}
+
+	protected function addRetrieveNextSibling(&$script)
+	{
+		$objectClassname = $this->getStubObjectBuilder()->getClassname();
+		$peerClassname = $this->getStubPeerBuilder()->getClassname();
+		$script .= "
+	/**
+	 * Gets next sibling for the given node if it exists
+	 *
+	 * @param      $objectClassname \$node	Propel object for src node
+	 * @param      PropelPDO \$con	Connection to use.
+	 * @return     mixed 		Propel object if exists else false
+	 */
+	public static function retrieveNextSibling(NodeObject \$node, PropelPDO \$con = null)
+	{
+		\$c = new Criteria($peerClassname::DATABASE_NAME);
+		\$c->add(self::LEFT_COL, \$node->getRightValue() + 1, Criteria::EQUAL);
+		if (self::SCOPE_COL) {
+			\$c->add(self::SCOPE_COL, \$node->getScopeIdValue(), Criteria::EQUAL);
+		}
+		\$nextSibling = $peerClassname::doSelectOne(\$c, \$con);
+		\$node->setNextSibling(\$nextSibling);
+		return \$nextSibling;
+	}
+";
+	}
+
+	protected function addRetrieveTree(&$script)
+	{
+		$peerClassname = $this->getStubPeerBuilder()->getClassname();
+		$script .= "
+	/**
+	 * Retrieves the entire tree from root
+	 *
+	 * @param      PropelPDO \$con	Connection to use.
+	 */
+	public static function retrieveTree(\$scopeId = null, PropelPDO \$con = null)
+	{
+		\$c = new Criteria($peerClassname::DATABASE_NAME);
+		\$c->addAscendingOrderByColumn(self::LEFT_COL);
+		if (self::SCOPE_COL) {
+			\$c->add(self::SCOPE_COL, \$scopeId, Criteria::EQUAL);
+		}
+		\$stmt = $peerClassname::doSelectStmt(\$c, \$con);
+		if (false !== (\$row = \$stmt->fetch(PDO::FETCH_NUM))) {
+			\$omClass = $peerClassname::getOMClass(\$row, 0);
+			\$cls = substr('.'.\$omClass, strrpos('.'.\$omClass, '.') + 1);
+
+			" . $this->buildObjectInstanceCreationCode('$root', '$cls') . "
+			\$root->hydrate(\$row);
+			\$root->setLevel(0);
+			$peerClassname::hydrateDescendants(\$root, \$stmt);
+			$peerClassname::addInstanceToPool(\$root);
+			
+			\$stmt->closeCursor();
+			return \$root;
+		}
+		return false;
+	}
+";
+	}
+
+	protected function addRetrieveBranch(&$script)
+	{
+		$objectClassname = $this->getStubObjectBuilder()->getClassname();
+		$peerClassname = $this->getStubPeerBuilder()->getClassname();
+		$script .= "
+	/**
+	 * Retrieves the entire tree from parent \$node
+	 *
+	 * @param      $objectClassname \$node	Propel object for parent node
+	 * @param      PropelPDO \$con	Connection to use.
+	 */
+	public static function retrieveBranch(NodeObject \$node, PropelPDO \$con = null)
+	{
+		return $peerClassname::retrieveDescendants(\$node, \$con);
+	}
+";
+	}
+
+	protected function addRetrieveChildren(&$script)
+	{
+		$objectClassname = $this->getStubObjectBuilder()->getClassname();
+		$peerClassname = $this->getStubPeerBuilder()->getClassname();
+		$script .= "
+	/**
+	 * Gets direct children for the node
+	 *
+	 * @param      $objectClassname \$node	Propel object for parent node
+	 * @param      PropelPDO \$con	Connection to use.
+	 */
+	public static function retrieveChildren(NodeObject \$node, PropelPDO \$con = null)
+	{
+		\$c = new Criteria($peerClassname::DATABASE_NAME);
+		\$c->addAscendingOrderByColumn(self::LEFT_COL);
+		if (self::SCOPE_COL) {
+			\$c->add(self::SCOPE_COL, \$node->getScopeIdValue(), Criteria::EQUAL);
+		}
+		\$c->add(self::LEFT_COL, \$node->getLeftValue(), Criteria::GREATER_THAN);
+		\$c->addAnd(self::RIGHT_COL, \$node->getRightValue(), Criteria::LESS_THAN);
+		\$stmt = $peerClassname::doSelectStmt(\$c, \$con);
+
+		return $peerClassname::hydrateChildren(\$node, \$stmt);
+	}
+";
+	}
+
+	protected function addRetrieveDescendants(&$script)
+	{
+		$objectClassname = $this->getStubObjectBuilder()->getClassname();
+		$peerClassname = $this->getStubPeerBuilder()->getClassname();
+		$script .= "
+	/**
+	 * Gets all descendants for the node
+	 *
+	 * @param      $objectClassname \$node	Propel object for parent node
+	 * @param      PropelPDO \$con	Connection to use.
+	 */
+	public static function retrieveDescendants(NodeObject \$node, PropelPDO \$con = null)
+	{
+		\$c = new Criteria($peerClassname::DATABASE_NAME);
+		\$c->addAscendingOrderByColumn(self::LEFT_COL);
+		if (self::SCOPE_COL) {
+			\$c->add(self::SCOPE_COL, \$node->getScopeIdValue(), Criteria::EQUAL);
+		}
+		\$c->add(self::LEFT_COL, \$node->getLeftValue(), Criteria::GREATER_THAN);
+		\$c->addAnd(self::RIGHT_COL, \$node->getRightValue(), Criteria::LESS_THAN);
+		\$stmt = $peerClassname::doSelectStmt(\$c, \$con);
+
+		return $peerClassname::hydrateDescendants(\$node, \$stmt);
+	}
+";
+	}
+
+	protected function addRetrieveSiblings(&$script)
+	{
+		$objectClassname = $this->getStubObjectBuilder()->getClassname();
+		$peerClassname = $this->getStubPeerBuilder()->getClassname();
+		$script .= "
+	/**
+	 * Gets all siblings for the node
+	 *
+	 * @param      $objectClassname \$node	Propel object for src node
+	 * @param      PropelPDO \$con	Connection to use.
+	 */
+	public static function retrieveSiblings(NodeObject \$node, PropelPDO \$con = null)
+	{
+		\$parent = $peerClassname::retrieveParent(\$node, \$con);
+		\$siblings = $peerClassname::retrieveChildren(\$parent, \$con);
+
+		return \$siblings;
+	}
+";
+	}
+
+	protected function addRetrieveParent(&$script)
+	{
+		$objectClassname = $this->getStubObjectBuilder()->getClassname();
+		$peerClassname = $this->getStubPeerBuilder()->getClassname();
+		$script .= "
+	/**
+	 * Gets immediate ancestor for the given node if it exists
+	 *
+	 * @param      $objectClassname \$node	Propel object for src node
+	 * @param      PropelPDO \$con	Connection to use.
+	 * @return     mixed 		Propel object if exists else null
+	 */
+	public static function retrieveParent(NodeObject \$node, PropelPDO \$con = null)
+	{
+		\$c = new Criteria($peerClassname::DATABASE_NAME);
+		\$c1 = \$c->getNewCriterion(self::LEFT_COL, \$node->getLeftValue(), Criteria::LESS_THAN);
+		\$c2 = \$c->getNewCriterion(self::RIGHT_COL, \$node->getRightValue(), Criteria::GREATER_THAN);
+
+		\$c1->addAnd(\$c2);
+
+		\$c->add(\$c1);
+		if (self::SCOPE_COL) {
+			\$c->add(self::SCOPE_COL, \$node->getScopeIdValue(), Criteria::EQUAL);
+		}
+		\$c->addAscendingOrderByColumn(self::RIGHT_COL);
+
+		\$parent = $peerClassname::doSelectOne(\$c, \$con);
+
+		\$node->setParentNode(\$parent);
+
+		return \$parent;
+	}
+";
+	}
+
+	protected function addGetLevel(&$script)
+	{
+		$objectClassname = $this->getStubObjectBuilder()->getClassname();
+		$peerClassname = $this->getStubPeerBuilder()->getClassname();
+		$script .= "
+	/**
+	 * Gets level for the given node
+	 *
+	 * @param      $objectClassname \$node	Propel object for src node
+	 * @param      PropelPDO \$con	Connection to use.
+	 * @return     int			Level for the given node
+	 */
+	public static function getLevel(NodeObject \$node, PropelPDO \$con = null)
+	{
+		if (\$con === null) {
+			\$con = Propel::getConnection($peerClassname::DATABASE_NAME, Propel::CONNECTION_READ);
+		}
+
+		\$sql = \"SELECT COUNT(*) AS level FROM \" . self::TABLE_NAME . \" WHERE \" . self::LEFT_COL . \" < :left AND \" . self::RIGHT_COL . \" > :right\";
+
+		if (self::SCOPE_COL) {
+			\$sql .= ' AND ' . self::SCOPE_COL . ' = :scope';
+		}
+
+		\$stmt = \$con->prepare(\$sql);
+		\$stmt->bindValue(':left', \$node->getLeftValue(), PDO::PARAM_INT);
+		\$stmt->bindValue(':right', \$node->getRightValue(), PDO::PARAM_INT);
+		if (self::SCOPE_COL) {
+			\$stmt->bindValue(':scope', \$node->getScopeIdValue());
+		}
+		\$stmt->execute();
+		\$row = \$stmt->fetch();
+		return \$row['level'];
+	}
+";
+	}
+
+	protected function addGetNumberOfChildren(&$script)
+	{
+		$objectClassname = $this->getStubObjectBuilder()->getClassname();
+		$peerClassname = $this->getStubPeerBuilder()->getClassname();
+		$script .= "
+	/**
+	 * Gets number of direct children for given node
+	 *
+	 * @param      $objectClassname \$node	Propel object for src node
+	 * @param      PropelPDO \$con	Connection to use.
+	 * @return     int			Level for the given node
+	 */
+	public static function getNumberOfChildren(NodeObject \$node, PropelPDO \$con = null)
+	{
+		\$children = $peerClassname::retrieveChildren(\$node);
+		return count(\$children);
+	}
+";
+	}
+
+	protected function addGetNumberOfDescendants(&$script)
+	{
+		$objectClassname = $this->getStubObjectBuilder()->getClassname();
+		$peerClassname = $this->getStubPeerBuilder()->getClassname();
+		$script .= "
+	/**
+	 * Gets number of descendants for given node
+	 *
+	 * @param      $objectClassname \$node	Propel object for src node
+	 * @param      PropelPDO \$con	Connection to use.
+	 * @return     int			Level for the given node
+	 */
+	public static function getNumberOfDescendants(NodeObject \$node, PropelPDO \$con = null)
+	{
+		\$right = \$node->getRightValue();
+		\$left = \$node->getLeftValue();
+		\$num = (\$right - \$left - 1) / 2;
+		return \$num;
+	}
+";
+	}
+
+	protected function addGetPath(&$script)
+	{
+		$objectClassname = $this->getStubObjectBuilder()->getClassname();
+		$peerClassname = $this->getStubPeerBuilder()->getClassname();
+		$script .= "
+	/**
+	 * Returns path to a specific node as an array, useful to create breadcrumbs
+	 *
+	 * @param      $objectClassname \$node	Propel object of node to create path to
+	 * @param      PropelPDO \$con	Connection to use.
+	 * @return     array			Array in order of heirarchy
+	 */
+	public static function getPath(NodeObject \$node, PropelPDO \$con = null)
+	{
+		\$path = array();
+		\$path[] = \$node;
+
+		while (\$parent = \$node->retrieveParent()) {
+			\$path[] = \$parent;
+			\$node = \$parent;
+		}
+
+		return array_reverse(\$path);
+	}
+";
+	}
+
+	protected function addIsValid(&$script)
+	{
+		$objectClassname = $this->getStubObjectBuilder()->getClassname();
+		$peerClassname = $this->getStubPeerBuilder()->getClassname();
+		$script .= "
+	/**
+	 * Tests if node is valid
+	 *
+	 * @param      $objectClassname \$node	Propel object for src node
+	 * @return     bool
+	 */
+	public static function isValid(NodeObject \$node = null)
+	{
+		if (is_object(\$node) && \$node->getRightValue() > \$node->getLeftValue()) {
+			return true;
+		} else {
+			return false;
+		}
+	}
+";
+	}
+
+	protected function addIsRoot(&$script)
+	{
+		$objectClassname = $this->getStubObjectBuilder()->getClassname();
+		$peerClassname = $this->getStubPeerBuilder()->getClassname();
+		$script .= "
+	/**
+	 * Tests if node is a root
+	 *
+	 * @param      $objectClassname \$node	Propel object for src node
+	 * @return     bool
+	 */
+	public static function isRoot(NodeObject \$node)
+	{
+		return (\$node->getLeftValue()==1);
+	}
+";
+	}
+
+	protected function addIsLeaf(&$script)
+	{
+		$objectClassname = $this->getStubObjectBuilder()->getClassname();
+		$peerClassname = $this->getStubPeerBuilder()->getClassname();
+		$script .= "
+	/**
+	 * Tests if node is a leaf
+	 *
+	 * @param      $objectClassname \$node	Propel object for src node
+	 * @return     bool
+	 */
+	public static function isLeaf(NodeObject \$node)
+	{
+		return ((\$node->getRightValue()-\$node->getLeftValue())==1);
+	}
+";
+	}
+
+	protected function addIsChildOf(&$script)
+	{
+		$objectClassname = $this->getStubObjectBuilder()->getClassname();
+		$peerClassname = $this->getStubPeerBuilder()->getClassname();
+		$script .= "
+	/**
+	 * Tests if \$child is a child of \$parent
+	 *
+	 * @param      $objectClassname \$child	Propel object for node
+	 * @param      $objectClassname \$parent	Propel object for node
+	 * @return     bool
+	 */
+	public static function isChildOf(NodeObject \$child, NodeObject \$parent)
+	{
+		return ((\$child->getLeftValue()>\$parent->getLeftValue()) && (\$child->getRightValue()<\$parent->getRightValue()));
+	}
+";
+	}
+
+	protected function addIsChildOfOrSiblingTo(&$script)
+	{
+		$objectClassname = $this->getStubObjectBuilder()->getClassname();
+		$peerClassname = $this->getStubPeerBuilder()->getClassname();
+		$script .= "
+	/**
+	 * Tests if \$node1 is a child of or equal to \$node2
+	 *
+	 * @deprecated 1.3 - 2007/11/09
+	 * @param      $objectClassname \$node1		Propel object for node
+	 * @param      $objectClassname \$node2		Propel object for node
+	 * @return     bool
+	 */
+	public static function isChildOfOrSiblingTo(NodeObject \$node1, NodeObject \$node2)
+	{
+		return ((\$node1->getLeftValue()>=\$node2->getLeftValue()) and (\$node1->getRightValue()<=\$node2->getRightValue()));
+	}
+";
+	}
+
+	protected function addIsEqualTo(&$script)
+	{
+		$objectClassname = $this->getStubObjectBuilder()->getClassname();
+		$peerClassname = $this->getStubPeerBuilder()->getClassname();
+		$script .= "
+	/**
+	 * Tests if \$node1 is equal to \$node2
+	 *
+	 * @param      $objectClassname \$node1		Propel object for node
+	 * @param      $objectClassname \$node2		Propel object for node
+	 * @return     bool
+	 */
+	public static function isEqualTo(NodeObject \$node1, NodeObject \$node2)
+	{
+		\$also = true;
+		if (self::SCOPE_COL) {
+			\$also = (\$node1->getScopeIdValue() === \$node2->getScopeIdValue());
+		}
+		return \$node1->getLeftValue() == \$node2->getLeftValue() && \$node1->getRightValue() == \$node2->getRightValue() && \$also;
+	}
+";
+	}
+
+	protected function addHasParent(&$script)
+	{
+		$objectClassname = $this->getStubObjectBuilder()->getClassname();
+		$peerClassname = $this->getStubPeerBuilder()->getClassname();
+		$script .= "
+	/**
+	 * Tests if \$node has an ancestor
+	 *
+	 * @param      $objectClassname \$node		Propel object for node
+	 * @param      PropelPDO \$con		Connection to use.
+	 * @return     bool
+	 */
+	public static function hasParent(NodeObject \$node, PropelPDO \$con = null)
+	{
+		return $peerClassname::isValid($peerClassname::retrieveParent(\$node, \$con));
+	}
+";
+	}
+
+	protected function addHasPrevSibling(&$script)
+	{
+		$objectClassname = $this->getStubObjectBuilder()->getClassname();
+		$peerClassname = $this->getStubPeerBuilder()->getClassname();
+		$script .= "
+	/**
+	 * Tests if \$node has prev sibling
+	 *
+	 * @param      $objectClassname \$node		Propel object for node
+	 * @param      PropelPDO \$con		Connection to use.
+	 * @return     bool
+	 */
+	public static function hasPrevSibling(NodeObject \$node, PropelPDO \$con = null)
+	{
+		return $peerClassname::isValid($peerClassname::retrievePrevSibling(\$node, \$con));
+	}
+";
+	}
+
+	protected function addHasNextSibling(&$script)
+	{
+		$objectClassname = $this->getStubObjectBuilder()->getClassname();
+		$peerClassname = $this->getStubPeerBuilder()->getClassname();
+		$script .= "
+	/**
+	 * Tests if \$node has next sibling
+	 *
+	 * @param      $objectClassname \$node		Propel object for node
+	 * @param      PropelPDO \$con		Connection to use.
+	 * @return     bool
+	 */
+	public static function hasNextSibling(NodeObject \$node, PropelPDO \$con = null)
+	{
+		return $peerClassname::isValid($peerClassname::retrieveNextSibling(\$node, \$con));
+	}
+";
+	}
+
+	protected function addHasChildren(&$script)
+	{
+		$objectClassname = $this->getStubObjectBuilder()->getClassname();
+		$peerClassname = $this->getStubPeerBuilder()->getClassname();
+		$script .= "
+	/**
+	 * Tests if \$node has children
+	 *
+	 * @param      $objectClassname \$node		Propel object for node
+	 * @return     bool
+	 */
+	public static function hasChildren(NodeObject \$node)
+	{
+		return ((\$node->getRightValue()-\$node->getLeftValue())>1);
+	}
+";
+	}
+
+	protected function addDeleteDescendants(&$script)
+	{
+		$objectClassname = $this->getStubObjectBuilder()->getClassname();
+		$peerClassname = $this->getStubPeerBuilder()->getClassname();
+		$script .= "
+	/**
+	 * Deletes \$node and all of its descendants
+	 *
+	 * @param      $objectClassname \$node		Propel object for source node
+	 * @param      PropelPDO \$con		Connection to use.
+	 */
+	public static function deleteDescendants(NodeObject \$node, PropelPDO \$con = null)
+	{
+		\$left = \$node->getLeftValue();
+		\$right = \$node->getRightValue();
+
+		\$c = new Criteria($peerClassname::DATABASE_NAME);
+		\$c1 = \$c->getNewCriterion(self::LEFT_COL, \$left, Criteria::GREATER_THAN);
+		\$c2 = \$c->getNewCriterion(self::RIGHT_COL, \$right, Criteria::LESS_THAN);
+
+		\$c1->addAnd(\$c2);
+
+		\$c->add(\$c1);
+		if (self::SCOPE_COL) {
+			\$c->add(self::SCOPE_COL, \$node->getScopeIdValue(), Criteria::EQUAL);
+		}
+		\$c->addAscendingOrderByColumn(self::RIGHT_COL);
+
+		\$result = $peerClassname::doDelete(\$c, \$con);
+
+		self::shiftRLValues(\$right + 1, \$left - \$right -1, \$con, \$node->getScopeIdValue());
+
+		return \$result;
+	}
+";
+	}
+
+	protected function addGetNode(&$script)
+	{
+		$objectClassname = $this->getStubObjectBuilder()->getClassname();
+		$peerClassname = $this->getStubPeerBuilder()->getClassname();
+		$script .= "
+	/**
+	 * Returns a node given its primary key or the node itself
+	 *
+	 * @param      int/$objectClassname \$node	Primary key/instance of required node
+	 * @param      PropelPDO \$con		Connection to use.
+	 * @return     object		Propel object for model
+	 */
+	public static function getNode(\$node, PropelPDO \$con = null)
+	{
+		if (is_object(\$node)) {
+			return \$node;
+		} else {
+			\$object = $peerClassname::retrieveByPK(\$node, \$con);
+			\$rtn = is_object(\$object) ? \$object : false;
+			return \$rtn;
+		}
+	}
+";
+	}
+
+	protected function addHydrateDescendants(&$script)
+	{
+		$objectClassname = $this->getStubObjectBuilder()->getClassname();
+		$peerClassname = $this->getStubPeerBuilder()->getClassname();
+		$table = $this->getTable();
+		$script .= "
+	/**
+	 * Hydrate recursively the descendants of the given node
+	 * @param      $objectClassname \$node	Propel object for src node
+	 * @param      PDOStatement \$stmt	Executed PDOStatement
+	 */
+	protected static function hydrateDescendants(NodeObject \$node, PDOStatement \$stmt)
+	{
+		\$descendants = array();
+		\$children = array();
+		\$prevSibling = null;
+";
+
+		if (!$table->getChildrenColumn()) {
+			$script .= "
+		// set the class once to avoid overhead in the loop
+		\$cls = $peerClassname::getOMClass();
+		\$cls = substr('.'.\$cls, strrpos('.'.\$cls, '.') + 1);
+";
+		}
+
+		$script .= "
+		while (\$row = \$stmt->fetch(PDO::FETCH_NUM)) {
+			\$key = ".$peerClassname."::getPrimaryKeyHashFromRow(\$row, 0);
+			if (null === (\$child = ".$peerClassname."::getInstanceFromPool(\$key))) {";
+
+		if ($table->getChildrenColumn()) {
+			$script .= "
+				// class must be set each time from the record row
+				\$cls = ".$peerClassname."::getOMClass(\$row, 0);
+				\$cls = substr('.'.\$cls, strrpos('.'.\$cls, '.') + 1);
+";
+		}
+
+		$script .= "
+				" . $this->buildObjectInstanceCreationCode('$child', '$cls') . "
+				\$child->hydrate(\$row);
+			}
+
+			\$child->setLevel(\$node->getLevel() + 1);
+			\$child->setParentNode(\$node);
+			if (!empty(\$prevSibling)) {
+				\$child->setPrevSibling(\$prevSibling);
+				\$prevSibling->setNextSibling(\$child);
+			}
+
+			if (\$child->hasChildren()) {
+				\$descendants = array_merge(\$descendants, $peerClassname::hydrateDescendants(\$child, \$stmt));
+			} else {
+				\$child->setChildren(array());
+			}
+
+			\$children[] = \$child;
+			\$descendants[] = \$child;
+			\$prevSibling = \$child;
+
+			$peerClassname::addInstanceToPool(\$child);
+			if (\$child->getRightValue() + 1 == \$node->getRightValue()) {
+				\$child->setNextSibling(null);
+				break;
+			}
+		}
+		\$node->setChildren(\$children);
+		return \$descendants;
+	}
+";
+	}
+
+	protected function addHydrateChildren(&$script)
+	{
+		$objectClassname = $this->getStubObjectBuilder()->getClassname();
+		$peerClassname = $this->getStubPeerBuilder()->getClassname();
+		$table = $this->getTable();
+		$script .= "
+	/**
+	 * Hydrate the children of the given node
+	 * @param      $objectClassname \$node Propel object for src node
+	 * @param      PDOStatement \$stmt Executed PDOStatement
+	 */
+	protected static function hydrateChildren(NodeObject \$node, PDOStatement \$stmt)
+	{
+		\$children = array();
+		\$prevRight = 0;
+";
+
+		if (!$table->getChildrenColumn()) {
+			$script .= "
+		// set the class once to avoid overhead in the loop
+		\$cls = $peerClassname::getOMClass();
+		\$cls = substr('.'.\$cls, strrpos('.'.\$cls, '.') + 1);
+";
+		}
+
+		$script .= "
+		while (\$row = \$stmt->fetch(PDO::FETCH_NUM)) {
+			\$key = ".$peerClassname."::getPrimaryKeyHashFromRow(\$row, 0);
+			if (null === (\$child = ".$peerClassname."::getInstanceFromPool(\$key))) {";
+			
+		if ($table->getChildrenColumn()) {
+			$script .= "
+				// class must be set each time from the record row
+				\$cls = ".$peerClassname."::getOMClass(\$row, 0);
+				\$cls = substr('.'.\$cls, strrpos('.'.\$cls, '.') + 1);
+";
+		}
+
+		$script .= "
+				" . $this->buildObjectInstanceCreationCode('$child', '$cls') . "
+				\$child->hydrate(\$row);
+			}
+
+			\$child->setLevel(\$node->getLevel() + 1);
+
+			if (\$child->getRightValue() > \$prevRight) {
+				\$children[] = \$child;
+				\$prevRight = \$child->getRightValue();
+			}
+
+			if (\$child->getRightValue() + 1 == \$node->getRightValue()) {
+				break;
+			}
+		}
+		\$node->setChildren(\$children);
+		return \$children;
+	}
+";
+	}
+
+	/**
+	 * @deprecated 1.3 - 2008/03/11
+	 * Won't be fixed, defect by design
+	 * Never trust it
+	 */
+	protected function addShiftRParent(&$script)
+	{
+		$objectClassname = $this->getStubObjectBuilder()->getClassname();
+		$peerClassname = $this->getStubPeerBuilder()->getClassname();
+		$script .= "
+	/**
+	 * Adds '\$delta' to all parent R values.
+	 * '\$delta' can also be negative.
+	 *
+	 * @deprecated 1.3 - 2008/03/11
+	 * @param      $objectClassname \$node	Propel object for parent node
+	 * @param      int \$delta	Value to be shifted by, can be negative
+	 * @param      PropelPDO \$con		Connection to use.
+	 */
+	protected static function shiftRParent(NodeObject \$node, \$delta, PropelPDO \$con = null)
+	{
+		if (\$node->hasParent(\$con)) {
+			\$parent = \$node->retrieveParent();
+			self::shiftRParent(\$parent, \$delta, \$con);
+		}
+		\$node->setRightValue(\$node->getRightValue() + \$delta);
+	}
+";
+	}
+
+	protected function addUpdateLoadedNode(&$script)
+	{
+		$objectClassname = $this->getStubObjectBuilder()->getClassname();
+		$peerClassname = $this->getStubPeerBuilder()->getClassname();
+		$table = $this->getTable();
+
+		$script .= "
+	/**
+	 * Reload all already loaded nodes to sync them with updated db
+	 *
+	 * @param      $objectClassname \$node	Propel object for parent node
+	 * @param      int \$delta	Value to be shifted by, can be negative
+	 * @param      PropelPDO \$con		Connection to use.
+	 */
+	protected static function updateLoadedNode(NodeObject \$node, \$delta, PropelPDO \$con = null)
+	{
+		if (Propel::isInstancePoolingEnabled()) {
+			\$keys = array();
+			foreach (self::\$instances as \$obj) {
+				\$keys[] = \$obj->getPrimaryKey();
+			}
+
+			if (!empty(\$keys)) {
+				// We don't need to alter the object instance pool; we're just modifying these ones
+				// already in the pool.
+				\$criteria = new Criteria(self::DATABASE_NAME);";
+		if (count($table->getPrimaryKey()) === 1) {
+			$pkey = $table->getPrimaryKey();
+			$col = array_shift($pkey);
+			$script .= "
+				\$criteria->add(".$this->getColumnConstant($col).", \$keys, Criteria::IN);
+";
+		} else {
+			$fields = array();
+			foreach ($table->getPrimaryKey() as $k => $col) {
+				$fields[] = $this->getColumnConstant($col);
+			};
+			$script .= "
+
+				// Loop on each instances in pool
+				foreach (\$keys as \$values) {
+				  // Create initial Criterion
+					\$cton = \$criteria->getNewCriterion(" . $fields[0] . ", \$values[0]);";
+			unset($fields[0]);
+			foreach ($fields as $k => $col) {
+				$script .= "
+
+					// Create next criterion
+					\$nextcton = \$criteria->getNewCriterion(" . $col . ", \$values[$k]);
+					// And merge it with the first
+					\$cton->addAnd(\$nextcton);";
+			}
+			$script .= "
+
+					// Add final Criterion to Criteria
+					\$criteria->addOr(\$cton);
+				}";
+			}
+
+			$script .= "
+				\$stmt = $peerClassname::doSelectStmt(\$criteria, \$con);
+				while (\$row = \$stmt->fetch(PDO::FETCH_NUM)) {
+					\$key = $peerClassname::getPrimaryKeyHashFromRow(\$row, 0);
+					if (null !== (\$object = $peerClassname::getInstanceFromPool(\$key))) {";
+			$n = 0;
+			foreach ($table->getColumns() as $col) {
+				if ($col->isNestedSetLeftKey()) {
+					$script .= "
+						\$object->setLeftValue(\$row[$n]);";
+				} else if ($col->isNestedSetRightKey()) {
+					$script .= "
+						\$object->setRightValue(\$row[$n]);";
+				}
+				$n++;
+			}
+			$script .= "
+					}
+				}
+				\$stmt->closeCursor();
+			}
+		}
+	}
+";
+	}
+
+	protected function addUpdateDBNode(&$script)
+	{
+		$objectClassname = $this->getStubObjectBuilder()->getClassname();
+		$script .= "
+	/**
+	 * Move \$node and its children to location \$destLeft and updates rest of tree
+	 *
+	 * @param      $objectClassname \$node Propel object for node to update
+	 * @param      int	\$destLeft Destination left value
+	 * @param      PropelPDO \$con		Connection to use.
+	 */
+	protected static function updateDBNode(NodeObject \$node, \$destLeft, PropelPDO \$con = null)
+	{
+		\$left = \$node->getLeftValue();
+		\$right = \$node->getRightValue();
+
+		\$treeSize = \$right - \$left +1;
+
+		self::shiftRLValues(\$destLeft, \$treeSize, \$con, \$node->getScopeIdValue());
+
+		if (\$left >= \$destLeft) { // src was shifted too?
+			\$left += \$treeSize;
+			\$right += \$treeSize;
+		}
+
+		// now there's enough room next to target to move the subtree
+		self::shiftRLRange(\$left, \$right, \$destLeft - \$left, \$con, \$node->getScopeIdValue());
+
+		// correct values after source
+		self::shiftRLValues(\$right + 1, -\$treeSize, \$con, \$node->getScopeIdValue());
+	}
+";
+	}
+
+	protected function addShiftRLValues(&$script)
+	{
+		$peerClassname = $this->getStubPeerBuilder()->getClassname();
+		$script .= "
+	/**
+	 * Adds '\$delta' to all L and R values that are >= '\$first'. '\$delta' can also be negative.
+	 *
+	 * @param      int \$first		First node to be shifted
+	 * @param      int \$delta		Value to be shifted by, can be negative
+	 * @param      PropelPDO \$con		Connection to use.
+	 */
+	protected static function shiftRLValues(\$first, \$delta, PropelPDO \$con = null, \$scopeId = null)
+	{
+		if (\$con === null) {
+			\$con = Propel::getConnection($peerClassname::DATABASE_NAME, Propel::CONNECTION_WRITE);
+		}
+
+		\$leftUpdateCol = substr(self::LEFT_COL, strrpos(self::LEFT_COL, '.') + 1);
+		\$rightUpdateCol = substr(self::RIGHT_COL, strrpos(self::RIGHT_COL, '.') + 1);
+
+		// Shift left column values
+		\$whereCriteria = new Criteria($peerClassname::DATABASE_NAME);
+		\$criterion = \$whereCriteria->getNewCriterion(
+			self::LEFT_COL,
+			\$first,
+			Criteria::GREATER_EQUAL);
+
+		if (self::SCOPE_COL) {
+			\$criterion->addAnd(
+				\$whereCriteria->getNewCriterion(
+					self::SCOPE_COL,
+					\$scopeId,
+					Criteria::EQUAL));
+		}
+		\$whereCriteria->add(\$criterion);
+
+		\$valuesCriteria = new Criteria($peerClassname::DATABASE_NAME);
+		\$valuesCriteria->add(
+			self::LEFT_COL,
+			array('raw' => \$leftUpdateCol . ' + ?', 'value' => \$delta),
+			Criteria::CUSTOM_EQUAL);
+
+		{$this->basePeerClassname}::doUpdate(\$whereCriteria, \$valuesCriteria, \$con);
+
+		// Shift right column values
+		\$whereCriteria = new Criteria($peerClassname::DATABASE_NAME);
+		\$criterion = \$whereCriteria->getNewCriterion(
+			self::RIGHT_COL,
+			\$first,
+			Criteria::GREATER_EQUAL);
+
+		if (self::SCOPE_COL) {
+			\$criterion->addAnd(
+				\$whereCriteria->getNewCriterion(
+					self::SCOPE_COL,
+					\$scopeId,
+					Criteria::EQUAL));
+		}
+		\$whereCriteria->add(\$criterion);
+
+		\$valuesCriteria = new Criteria($peerClassname::DATABASE_NAME);
+		\$valuesCriteria->add(
+		  self::RIGHT_COL,
+			array('raw' => \$rightUpdateCol . ' + ?', 'value' => \$delta),
+			Criteria::CUSTOM_EQUAL);
+
+		{$this->basePeerClassname}::doUpdate(\$whereCriteria, \$valuesCriteria, \$con);
+	}
+";
+	}
+
+	protected function addShiftRLRange(&$script)
+	{
+		$peerClassname = $this->getStubPeerBuilder()->getClassname();
+		$script .= "
+	/**
+	 * Adds '\$delta' to all L and R values that are >= '\$first' and <= '\$last'.
+	 * '\$delta' can also be negative.
+	 *
+	 * @param      int \$first	First node to be shifted (L value)
+	 * @param      int \$last	Last node to be shifted (L value)
+	 * @param      int \$delta	Value to be shifted by, can be negative
+	 * @param      PropelPDO \$con		Connection to use.
+	 * @return     array 		Shifted L and R values
+	 */
+	protected static function shiftRLRange(\$first, \$last, \$delta, PropelPDO \$con = null, \$scopeId = null)
+	{
+		if (\$con === null) {
+			\$con = Propel::getConnection($peerClassname::DATABASE_NAME, Propel::CONNECTION_WRITE);
+		}
+
+		\$leftUpdateCol = substr(self::LEFT_COL, strrpos(self::LEFT_COL, '.') + 1);
+		\$rightUpdateCol = substr(self::RIGHT_COL, strrpos(self::RIGHT_COL, '.') + 1);
+
+		// Shift left column values
+		\$whereCriteria = new Criteria($peerClassname::DATABASE_NAME);
+		\$criterion = \$whereCriteria->getNewCriterion(self::LEFT_COL, \$first, Criteria::GREATER_EQUAL);
+		\$criterion->addAnd(\$whereCriteria->getNewCriterion(self::LEFT_COL, \$last, Criteria::LESS_EQUAL));
+		if (self::SCOPE_COL) {
+			\$criterion->addAnd(\$whereCriteria->getNewCriterion(self::SCOPE_COL, \$scopeId, Criteria::EQUAL));
+		}
+		\$whereCriteria->add(\$criterion);
+
+		\$valuesCriteria = new Criteria($peerClassname::DATABASE_NAME);
+		\$valuesCriteria->add(
+			self::LEFT_COL,
+			array('raw' => \$leftUpdateCol . ' + ?', 'value' => \$delta),
+			Criteria::CUSTOM_EQUAL);
+
+		{$this->basePeerClassname}::doUpdate(\$whereCriteria, \$valuesCriteria, \$con);
+
+		// Shift right column values
+		\$whereCriteria = new Criteria($peerClassname::DATABASE_NAME);
+		\$criterion = \$whereCriteria->getNewCriterion(self::RIGHT_COL, \$first, Criteria::GREATER_EQUAL);
+		\$criterion->addAnd(\$whereCriteria->getNewCriterion(self::RIGHT_COL, \$last, Criteria::LESS_EQUAL));
+		if (self::SCOPE_COL) {
+			\$criterion->addAnd(\$whereCriteria->getNewCriterion(self::SCOPE_COL, \$scopeId, Criteria::EQUAL));
+		}
+		\$whereCriteria->add(\$criterion);
+
+		\$valuesCriteria = new Criteria($peerClassname::DATABASE_NAME);
+		\$valuesCriteria->add(
+			self::RIGHT_COL,
+			array('raw' => \$rightUpdateCol . ' + ?', 'value' => \$delta),
+			Criteria::CUSTOM_EQUAL);
+
+		{$this->basePeerClassname}::doUpdate(\$whereCriteria, \$valuesCriteria, \$con);
+
+		return array('left' => \$first + \$delta, 'right' => \$last + \$delta);
+	}
+";
+	}
+
+} // PHP5NestedSetPeerBuilder
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/builder/om/php5/PHP5NodeBuilder.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/builder/om/php5/PHP5NodeBuilder.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/builder/om/php5/PHP5NodeBuilder.php	(revision 19)
@@ -0,0 +1,1110 @@
+<?php
+
+/*
+ *  $Id: PHP5NodeBuilder.php 1067 2008-08-06 07:37:21Z ron $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://propel.phpdb.org>.
+ */
+
+require_once 'propel/engine/builder/om/ObjectBuilder.php';
+
+/**
+ * Generates a PHP5 tree node Object class for user object model (OM).
+ *
+ * This class produces the base tree node object class (e.g. BaseMyTable) which contains all
+ * the custom-built accessor and setter methods.
+ *
+ * This class replaces the Node.tpl, with the intent of being easier for users
+ * to customize (through extending & overriding).
+ *
+ * @author     Hans Lellelid <hans@xmpl.org>
+ * @package    propel.engine.builder.om.php5
+ */
+class PHP5NodeBuilder extends ObjectBuilder {
+
+	/**
+	 * Gets the package for the [base] object classes.
+	 * @return     string
+	 */
+	public function getPackage()
+	{
+		return parent::getPackage() . ".om";
+	}
+
+	/**
+	 * Returns the name of the current class being built.
+	 * @return     string
+	 */
+	public function getUnprefixedClassname()
+	{
+		return $this->getBuildProperty('basePrefix') . $this->getStubNodeBuilder()->getUnprefixedClassname();
+	}
+
+	/**
+	 * Adds the include() statements for files that this class depends on or utilizes.
+	 * @param      string &$script The script will be modified in this method.
+	 */
+	protected function addIncludes(&$script)
+	{
+	} // addIncludes()
+
+	/**
+	 * Adds class phpdoc comment and openning of class.
+	 * @param      string &$script The script will be modified in this method.
+	 */
+	protected function addClassOpen(&$script)
+	{
+
+		$table = $this->getTable();
+		$tableName = $table->getName();
+		$tableDesc = $table->getDescription();
+
+		$script .= "
+/**
+ * Base class that represents a row from the '$tableName' table.
+ *
+ * $tableDesc
+ *";
+		if ($this->getBuildProperty('addTimeStamp')) {
+			$now = strftime('%c');
+			$script .= "
+ * This class was autogenerated by Propel " . $this->getBuildProperty('version') . " on:
+ *
+ * $now
+ *";
+		}
+		$script .= "
+ * @package    ".$this->getPackage()."
+ */
+abstract class ".$this->getClassname()." implements IteratorAggregate {
+";
+	}
+
+	/**
+	 * Specifies the methods that are added as part of the basic OM class.
+	 * This can be overridden by subclasses that wish to add more methods.
+	 * @see        ObjectBuilder::addClassBody()
+	 */
+	protected function addClassBody(&$script)
+	{
+		$table = $this->getTable();
+
+		$this->addAttributes($script);
+
+		$this->addConstructor($script);
+
+		$this->addCallOverload($script);
+		$this->addSetIteratorOptions($script);
+		$this->addGetIterator($script);
+
+		$this->addGetNodeObj($script);
+		$this->addGetNodePath($script);
+		$this->addGetNodeIndex($script);
+		$this->addGetNodeLevel($script);
+
+		$this->addHasChildNode($script);
+		$this->addGetChildNodeAt($script);
+		$this->addGetFirstChildNode($script);
+		$this->addGetLastChildNode($script);
+		$this->addGetSiblingNode($script);
+
+		$this->addGetParentNode($script);
+		$this->addGetAncestors($script);
+		$this->addIsRootNode($script);
+
+		$this->addSetNew($script);
+		$this->addSetDeleted($script);
+		$this->addAddChildNode($script);
+		$this->addMoveChildNode($script);
+		$this->addSave($script);
+
+		$this->addDelete($script);
+		$this->addEquals($script);
+
+		$this->addAttachParentNode($script);
+		$this->addAttachChildNode($script);
+		$this->addDetachParentNode($script);
+		$this->addDetachChildNode($script);
+		$this->addShiftChildNodes($script);
+		$this->addInsertNewChildNode($script);
+
+		$this->addAdjustStatus($script);
+		$this->addAdjustNodePath($script);
+
+	}
+
+	/**
+	 * Closes class.
+	 * @param      string &$script The script will be modified in this method.
+	 */
+	protected function addClassClose(&$script)
+	{
+		$script .= "
+} // " . $this->getClassname() . "
+";
+	}
+
+
+	/**
+	 * Adds class attributes.
+	 * @param      string &$script The script will be modified in this method.
+	 */
+	protected function addAttributes(&$script)
+	{
+		$script .= "
+	/**
+	 * @var        ".$this->getStubObjectBuilder()->getClassname()." object wrapped by this node.
+	 */
+	protected \$obj = null;
+
+	/**
+	 * The parent node for this node.
+	 * @var        ".$this->getStubNodeBuilder()->getClassname()."
+	 */
+	protected \$parentNode = null;
+
+	/**
+	 * Array of child nodes for this node. Nodes indexes are one-based.
+	 * @var        array
+	 */
+	protected \$childNodes = array();
+";
+	}
+
+	/**
+	 * Adds the constructor.
+	 * @param      string &$script The script will be modified in this method.
+	 */
+	protected function addConstructor(&$script)
+	{
+		$script .= "
+	/**
+	 * Constructor.
+	 *
+	 * @param      ".$this->getStubObjectBuilder()->getClassname()." \$obj Object wrapped by this node.
+	 */
+	public function __construct(\$obj = null)
+	{
+		if (\$obj !== null) {
+			\$this->obj = \$obj;
+		} else {
+			\$setNodePath = 'set' . ".$this->getStubNodePeerBuilder()->getClassname()."::NPATH_PHPNAME;
+			\$this->obj = new ".$this->getStubObjectBuilder()->getClassname()."();
+			\$this->obj->\$setNodePath('0');
+		}
+	}
+";
+	}
+
+
+
+	protected function addCallOverload(&$script)
+	{
+		$script .= "
+	/**
+	 * Convenience overload for wrapped object methods.
+	 *
+	 * @param      string Method name to call on wrapped object.
+	 * @param      mixed Parameter accepted by wrapped object set method.
+	 * @return     mixed Return value of wrapped object method.
+	 * @throws     PropelException Fails if method is not defined for wrapped object.
+	 */
+	public function __call(\$name, \$parms)
+	{
+		if (method_exists(\$this->obj, \$name))
+			return call_user_func_array(array(\$this->obj, \$name), \$parms);
+		else
+			throw new PropelException('get method not defined: \$name');
+	}
+";
+	}
+
+	protected function addSetIteratorOptions(&$script)
+	{
+		$script .= "
+
+	/**
+	 * Sets the default options for iterators created from this object.
+	 * The options are specified in map format. The following options
+	 * are supported by all iterators. Some iterators may support other
+	 * options:
+	 *
+	 *   \"querydb\" - True if nodes should be retrieved from database.
+	 *   \"con\" - Connection to use if retrieving from database.
+	 *
+	 * @param      string Type of iterator to use (\"pre\", \"post\", \"level\").
+	 * @param      array Map of option name => value.
+	 * @return     void
+	 * @todo       Implement other iterator types (i.e. post-order, level, etc.)
+	 */
+	public function setIteratorOptions(\$type, \$opts)
+	{
+		\$this->itType = \$type;
+		\$this->itOpts = \$opts;
+	}
+";
+	}
+
+	protected function addGetIterator(&$script)
+	{
+		$script .= "
+	/**
+	 * Returns a pre-order iterator for this node and its children.
+	 *
+	 * @param      string Type of iterator to use (\"pre\", \"post\", \"level\")
+	 * @param      array Map of option name => value.
+	 * @return     NodeIterator
+	 */
+	public function getIterator(\$type = null, \$opts = null)
+	{
+		if (\$type === null)
+			\$type = (isset(\$this->itType) ? \$this->itType : 'Pre');
+
+		if (\$opts === null)
+			\$opts = (isset(\$this->itOpts) ? \$this->itOpts : array());
+
+		\$itclass = ucfirst(strtolower(\$type)) . 'OrderNodeIterator';
+
+";
+		$script .= "
+	}
+";
+	}
+
+	protected function addGetNodeObj(&$script)
+	{
+		$script .= "
+	/**
+	 * Returns the object wrapped by this class.
+	 * @return     ".$this->getStubObjectBuilder()->getClassname()."
+	 */
+	public function getNodeObj()
+	{
+		return \$this->obj;
+	}
+";
+	}
+
+	protected function addGetNodePath(&$script)
+	{
+		$script .= "
+	/**
+	 * Convenience method for retrieving nodepath.
+	 * @return     string
+	 */
+	public function getNodePath()
+	{
+		\$getNodePath = 'get' . ".$this->getStubNodePeerBuilder()->getClassname()."::NPATH_PHPNAME;
+		return \$this->obj->\$getNodePath();
+	}
+";
+	}
+
+	protected function addGetNodeIndex(&$script)
+	{
+		$script .= "
+	/**
+	 * Returns one-based node index among siblings.
+	 * @return     int
+	 */
+	public function getNodeIndex()
+	{
+		\$npath =& \$this->getNodePath();
+		\$sep = strrpos(\$npath, ".$this->getStubNodePeerBuilder()->getClassname()."::NPATH_SEP);
+		return (int) (\$sep !== false ? substr(\$npath, \$sep+1) : \$npath);
+	}
+";
+	}
+
+	protected function addGetNodeLevel(&$script)
+	{
+		$script .= "
+	/**
+	 * Returns one-based node level within tree (root node is level 1).
+	 * @return     int
+	 */
+	public function getNodeLevel()
+	{
+		return (substr_count(\$this->getNodePath(), ".$this->getStubNodePeerBuilder()->getClassname()."::NPATH_SEP) + 1);
+	}
+";
+	}
+
+	protected function addHasChildNode(&$script)
+	{
+		$script .= "
+	/**
+	 * Returns true if specified node is a child of this node. If recurse is
+	 * true, checks if specified node is a descendant of this node.
+	 *
+	 * @param      ".$this->getStubNodeBuilder()->getClassname()." Node to look for.
+	 * @param      boolean True if strict comparison should be used.
+	 * @param      boolean True if all descendants should be checked.
+	 * @return     boolean
+	 */
+	public function hasChildNode(\$node, \$strict = false, \$recurse = false)
+	{
+		foreach (\$this->childNodes as \$childNode)
+		{
+			if (\$childNode->equals(\$node, \$strict))
+				return true;
+
+			if (\$recurse && \$childNode->hasChildNode(\$node, \$recurse))
+				return true;
+		}
+
+		return false;
+	}
+";
+	}
+
+	protected function addGetChildNodeAt(&$script)
+	{
+		$script .= "
+	/**
+	 * Returns child node at one-based index. Retrieves from database if not
+	 * loaded yet.
+	 *
+	 * @param      int One-based child node index.
+	 * @param      boolean True if child should be retrieved from database.
+	 * @param      PropelPDO Connection to use if retrieving from database.
+	 * @return     ".$this->getStubNodeBuilder()->getClassname()."
+	 */
+	public function getChildNodeAt(\$i, \$querydb = false, PropelPDO \$con = null)
+	{
+		if (\$querydb &&
+			!\$this->obj->isNew() &&
+			!\$this->obj->isDeleted() &&
+			!isset(\$this->childNodes[\$i]))
+		{
+			\$criteria = new Criteria(".$this->getStubPeerBuilder()->getClassname()."::DATABASE_NAME);
+			\$criteria->add(".$this->getStubNodePeerBuilder()->getClassname()."::NPATH_COLNAME, \$this->getNodePath() . ".$this->getStubNodePeerBuilder()->getClassname()."::NPATH_SEP . \$i, Criteria::EQUAL);
+
+			if (\$childObj = ".$this->getStubPeerBuilder()->getClassname()."::doSelectOne(\$criteria, \$con))
+				\$this->attachChildNode(new ".$this->getStubNodeBuilder()->getClassname()."(\$childObj));
+		}
+
+		return (isset(\$this->childNodes[\$i]) ? \$this->childNodes[\$i] : null);
+	}
+";
+	}
+
+	protected function addGetFirstChildNode(&$script)
+	{
+		$script .= "
+	/**
+	 * Returns first child node (if any). Retrieves from database if not loaded yet.
+	 *
+	 * @param      boolean True if child should be retrieved from database.
+	 * @param      PropelPDO Connection to use if retrieving from database.
+	 * @return     ".$this->getStubNodeBuilder()->getClassname()."
+	 */
+	public function getFirstChildNode(\$querydb = false, PropelPDO \$con = null)
+	{
+		return \$this->getChildNodeAt(1, \$querydb, \$con);
+	}
+";
+	}
+
+	protected function addGetLastChildNode(&$script)
+	{
+		$peerClassname = $this->getStubPeerBuilder()->getClassname();
+		$nodePeerClassname = $this->getStubNodePeerBuilder()->getClassname();
+
+		$script .= "
+	/**
+	 * Returns last child node (if any).
+	 *
+	 * @param      boolean True if child should be retrieved from database.
+	 * @param      PropelPDO Connection to use if retrieving from database.
+	 */
+	public function getLastChildNode(\$querydb = false, PropelPDO \$con = null)
+	{
+		\$lastNode = null;
+
+		if (\$this->obj->isNew() || \$this->obj->isDeleted())
+		{
+			end(\$this->childNodes);
+			\$lastNode = (count(\$this->childNodes) ? current(\$this->childNodes) : null);
+		}
+		else if (\$querydb)
+		{
+			\$db = Propel::getDb($peerClassname::DATABASE_NAME);
+			\$criteria = new Criteria($peerClassname::DATABASE_NAME);
+			\$criteria->add($nodePeerClassname::NPATH_COLNAME, \$this->getNodePath() . $nodePeerClassname::NPATH_SEP . '%', Criteria::LIKE);
+			\$criteria->addAnd($nodePeerClassname::NPATH_COLNAME, \$this->getNodePath() . $nodePeerClassname::NPATH_SEP . '%' . $nodePeerClassname::NPATH_SEP . '%', Criteria::NOT_LIKE);
+			\$criteria->addAsColumn('npathlen', \$db->strLength($nodePeerClassname::NPATH_COLNAME));
+			\$criteria->addDescendingOrderByColumn('npathlen');
+			\$criteria->addDescendingOrderByColumn($nodePeerClassname::NPATH_COLNAME);
+
+			\$lastObj = $peerClassname::doSelectOne(\$criteria, \$con);
+
+			if (\$lastObj !== null)
+			{
+				\$lastNode = new ".$this->getStubNodeBuilder()->getClassname()."(\$lastObj);
+
+				end(\$this->childNodes);
+				\$endNode = (count(\$this->childNodes) ? current(\$this->childNodes) : null);
+
+				if (\$endNode)
+				{
+					if (\$endNode->getNodePath() > \$lastNode->getNodePath())
+						throw new PropelException('Cached child node inconsistent with database.');
+					else if (\$endNode->getNodePath() == \$lastNode->getNodePath())
+						\$lastNode = \$endNode;
+					else
+						\$this->attachChildNode(\$lastNode);
+				}
+				else
+				{
+					\$this->attachChildNode(\$lastNode);
+				}
+			}
+		}
+
+		return \$lastNode;
+	}
+";
+	}
+
+	protected function addGetSiblingNode(&$script)
+	{
+		$script .= "
+	/**
+	 * Returns next (or previous) sibling node or null. Retrieves from database if
+	 * not loaded yet.
+	 *
+	 * @param      boolean True if previous sibling should be returned.
+	 * @param      boolean True if sibling should be retrieved from database.
+	 * @param      PropelPDO Connection to use if retrieving from database.
+	 * @return     ".$this->getStubNodeBuilder()->getClassname()."
+	 */
+	public function getSiblingNode(\$prev = false, \$querydb = false, PropelPDO \$con = null)
+	{
+		\$nidx = \$this->getNodeIndex();
+
+		if (\$this->isRootNode())
+		{
+			return null;
+		}
+		else if (\$prev)
+		{
+			if (\$nidx > 1 && (\$parentNode = \$this->getParentNode(\$querydb, \$con)))
+				return \$parentNode->getChildNodeAt(\$nidx-1, \$querydb, \$con);
+			else
+				return null;
+		}
+		else
+		{
+			if (\$parentNode = \$this->getParentNode(\$querydb, \$con))
+				return \$parentNode->getChildNodeAt(\$nidx+1, \$querydb, \$con);
+			else
+				return null;
+		}
+	}
+";
+	}
+
+	protected function addGetParentNode(&$script)
+	{
+		$peerClassname = $this->getStubPeerBuilder()->getClassname();
+		$nodePeerClassname = $this->getStubNodePeerBuilder()->getClassname();
+
+		$script .= "
+	/**
+	 * Returns parent node. Loads from database if not cached yet.
+	 *
+	 * @param      boolean True if parent should be retrieved from database.
+	 * @param      PropelPDO Connection to use if retrieving from database.
+	 * @return     ".$this->getStubNodeBuilder()->getClassname()."
+	 */
+	public function getParentNode(\$querydb = true, PropelPDO \$con = null)
+	{
+		if (\$querydb &&
+			\$this->parentNode === null &&
+			!\$this->isRootNode() &&
+			!\$this->obj->isNew() &&
+			!\$this->obj->isDeleted())
+		{
+			\$npath =& \$this->getNodePath();
+			\$sep = strrpos(\$npath, $nodePeerClassname::NPATH_SEP);
+			\$ppath = substr(\$npath, 0, \$sep);
+
+			\$criteria = new Criteria($peerClassname::DATABASE_NAME);
+			\$criteria->add($nodePeerClassname::NPATH_COLNAME, \$ppath, Criteria::EQUAL);
+
+			if (\$parentObj = $peerClassname::doSelectOne(\$criteria, \$con))
+			{
+				\$parentNode = new ".$this->getStubNodeBuilder()->getClassname()."(\$parentObj);
+				\$parentNode->attachChildNode(\$this);
+			}
+		}
+
+		return \$this->parentNode;
+	}
+";
+	}
+
+	protected function addGetAncestors(&$script)
+	{
+		$script .= "
+	/**
+	 * Returns an array of all ancestor nodes, starting with the root node
+	 * first.
+	 *
+	 * @param      boolean True if ancestors should be retrieved from database.
+	 * @param      PropelPDO Connection to use if retrieving from database.
+	 * @return     array
+	 */
+	public function getAncestors(\$querydb = false, PropelPDO \$con = null)
+	{
+		\$ancestors = array();
+		\$parentNode = \$this;
+
+		while (\$parentNode = \$parentNode->getParentNode(\$querydb, \$con))
+			array_unshift(\$ancestors, \$parentNode);
+
+		return \$ancestors;
+	}
+";
+	}
+
+	protected function addIsRootNode(&$script)
+	{
+		$script .= "
+	/**
+	 * Returns true if node is the root node of the tree.
+	 * @return     boolean
+	 */
+	public function isRootNode()
+	{
+		return (\$this->getNodePath() === '1');
+	}
+";
+	}
+
+	protected function addSetNew(&$script)
+	{
+		$script .= "
+	/**
+	 * Changes the state of the object and its descendants to 'new'.
+	 * Also changes the node path to '0' to indicate that it is not a
+	 * stored node.
+	 *
+	 * @param      boolean
+	 * @return     void
+	 */
+	public function setNew(\$b)
+	{
+		\$this->adjustStatus('new', \$b);
+		\$this->adjustNodePath(\$this->getNodePath(), '0');
+	}
+";
+	}
+
+	protected function addSetDeleted(&$script)
+	{
+		$script .= "
+	/**
+	 * Changes the state of the object and its descendants to 'deleted'.
+	 *
+	 * @param      boolean
+	 * @return     void
+	 */
+	public function setDeleted(\$b)
+	{
+		\$this->adjustStatus('deleted', \$b);
+	}
+";
+	}
+
+	protected function addAddChildNode(&$script)
+	{
+		$peerClassname = $this->getStubPeerBuilder()->getClassname();
+		$nodePeerClassname = $this->getStubNodePeerBuilder()->getClassname();
+
+		$script .= "
+	/**
+	 * Adds the specified node (and its children) as a child to this node. If a
+	 * valid \$beforeNode is specified, the node will be inserted in front of
+	 * \$beforeNode. If \$beforeNode is not specified the node will be appended to
+	 * the end of the child nodes.
+	 *
+	 * @param      ".$this->getStubNodeBuilder()->getClassname()." Node to add.
+	 * @param      ".$this->getStubNodeBuilder()->getClassname()." Node to insert before.
+	 * @param      PropelPDO Connection to use.
+	 */
+	public function addChildNode(\$node, \$beforeNode = null, PropelPDO \$con = null)
+	{
+		if (\$this->obj->isNew() && !\$node->obj->isNew())
+			throw new PropelException('Cannot add stored nodes to a new node.');
+
+		if (\$this->obj->isDeleted() || \$node->obj->isDeleted())
+			throw new PropelException('Cannot add children in a deleted state.');
+
+		if (\$this->hasChildNode(\$node))
+			throw new PropelException('Node is already a child of this node.');
+
+		if (\$beforeNode && !\$this->hasChildNode(\$beforeNode))
+			throw new PropelException('Invalid beforeNode.');
+
+		if (\$con === null)
+			\$con = Propel::getConnection($peerClassname::DATABASE_NAME, Propel::CONNECTION_WRITE);
+		
+		if (!\$this->obj->isNew()) \$con->beginTransaction();
+		
+		try {	
+			if (\$beforeNode)
+			{
+				// Inserting before a node.
+				\$childIdx = \$beforeNode->getNodeIndex();
+				\$this->shiftChildNodes(1, \$beforeNode->getNodeIndex(), \$con);
+			}
+			else
+			{
+				// Appending child node.
+				if (\$lastNode = \$this->getLastChildNode(true, \$con))
+					\$childIdx = \$lastNode->getNodeIndex()+1;
+				else
+					\$childIdx = 1;
+			}
+
+			// Add the child (and its children) at the specified index.
+
+			if (!\$this->obj->isNew() && \$node->obj->isNew())
+			{
+				\$this->insertNewChildNode(\$node, \$childIdx, \$con);
+			}
+			else
+			{
+				// \$this->isNew() && \$node->isNew() ||
+				// !\$this->isNew() && !node->isNew()
+
+				\$srcPath = \$node->getNodePath();
+				\$dstPath = \$this->getNodePath() . $nodePeerClassname::NPATH_SEP . \$childIdx;
+
+				if (!\$node->obj->isNew())
+				{
+					$nodePeerClassname::moveNodeSubTree(\$srcPath, \$dstPath, \$con);
+					\$parentNode = \$node->getParentNode(true, \$con);
+				}
+				else
+				{
+					\$parentNode = \$node->getParentNode();
+				}
+
+				if (\$parentNode)
+				{
+					\$parentNode->detachChildNode(\$node);
+					\$parentNode->shiftChildNodes(-1, \$node->getNodeIndex()+1, \$con);
+				}
+
+				\$node->adjustNodePath(\$srcPath, \$dstPath);
+			}
+
+			if (!\$this->obj->isNew()) \$con->commit();
+
+			\$this->attachChildNode(\$node);
+
+		} catch (SQLException \$e) {
+			if (!\$this->obj->isNew()) \$con->rollBack();
+			throw new PropelException(\$e);
+		}
+	}
+";
+	}
+
+	protected function addMoveChildNode(&$script)
+	{
+		$script .= "
+	/**
+	 * Moves the specified child node in the specified direction.
+	 *
+	 * @param      ".$this->getStubNodeBuilder()->getClassname()." Node to move.
+	 * @param      int Number of spaces to move among siblings (may be negative).
+	 * @param      PropelPDO Connection to use.
+	 * @throws     PropelException
+	 */
+	public function moveChildNode(\$node, \$direction, PropelPDO \$con = null)
+	{
+		throw new PropelException('moveChildNode() not implemented yet.');
+	}
+";
+	}
+
+
+	protected function addSave(&$script)
+	{
+
+		$nodePeerClassname = $this->getStubNodePeerBuilder()->getClassname();
+		$script .= "
+	/**
+	 * Saves modified object data to the datastore.
+	 *
+	 * @param      boolean If true, descendants will be saved as well.
+	 * @param      PropelPDO Connection to use.
+	 */
+	public function save(\$recurse = false, PropelPDO \$con = null)
+	{
+		if (\$this->obj->isDeleted())
+			throw new PropelException('Cannot save deleted node.');
+
+		if (substr(\$this->getNodePath(), 0, 1) == '0')
+			throw new PropelException('Cannot save unattached node.');
+
+		if (\$this->obj->isColumnModified($nodePeerClassname::NPATH_COLNAME))
+			throw new PropelException('Cannot save manually modified node path.');
+
+		\$this->obj->save(\$con);
+
+		if (\$recurse)
+		{
+			foreach (\$this->childNodes as \$childNode)
+				\$childNode->save(\$recurse, \$con);
+		}
+	}
+";
+	}
+
+
+	protected function addDelete(&$script)
+	{
+		$nodePeerClassname = $this->getStubNodePeerBuilder()->getClassname();
+		$script .= "
+	/**
+	 * Removes this object and all descendants from datastore.
+	 *
+	 * @param      PropelPDO Connection to use.
+	 * @return     void
+	 * @throws     PropelException
+	 */
+	public function delete(PropelPDO \$con = null)
+	{
+		if (\$this->obj->isDeleted())
+			throw new PropelException('This node has already been deleted.');
+
+		if (!\$this->obj->isNew())
+		{
+			$nodePeerClassname::deleteNodeSubTree(\$this->getNodePath(), \$con);
+		}
+
+		if (\$parentNode = \$this->getParentNode(true, \$con))
+		{
+			\$parentNode->detachChildNode(\$this);
+			\$parentNode->shiftChildNodes(-1, \$this->getNodeIndex()+1, \$con);
+		}
+
+		\$this->setDeleted(true);
+	}
+";
+	}
+
+	protected function addEquals(&$script)
+	{
+		$nodeClassname = $this->getStubNodeBuilder()->getClassname();
+		$script .= "
+	/**
+	 * Compares the object wrapped by this node with that of another node. Use
+	 * this instead of equality operators to prevent recursive dependency
+	 * errors.
+	 *
+	 * @param      $nodeClassname Node to compare.
+	 * @param      boolean True if strict comparison should be used.
+	 * @return     boolean
+	 */
+	public function equals(\$node, \$strict = false)
+	{
+		if (\$strict) {
+			return (\$this->obj === \$node->obj);
+		} else {
+			return (\$this->obj == \$node->obj);
+		}
+	}
+";
+	}
+
+	protected function addAttachParentNode(&$script)
+	{
+		$nodeClassname = $this->getStubNodeBuilder()->getClassname();
+		$script .= "
+	/**
+	 * This method is used internally when constructing the tree structure
+	 * from the database. To set the parent of a node, you should call
+	 * addChildNode() on the parent.
+	 *
+	 * @param      $nodeClassname Parent node to attach.
+	 * @return     void
+	 * @throws     PropelException
+	 */
+	public function attachParentNode(\$node)
+	{
+		if (!\$node->hasChildNode(\$this, true))
+			throw new PropelException('Failed to attach parent node for non-child.');
+
+		\$this->parentNode = \$node;
+	}
+";
+	}
+
+
+	protected function addAttachChildNode(&$script)
+	{
+		$nodeClassname = $this->getStubNodeBuilder()->getClassname();
+		$nodePeerClassname = $this->getStubNodePeerBuilder()->getClassname();
+		$script .= "
+	/**
+	 * This method is used internally when constructing the tree structure
+	 * from the database. To add a child to a node you should call the
+	 * addChildNode() method instead.
+	 *
+	 * @param      $nodeClassname Child node to attach.
+	 * @return     void
+	 * @throws     PropelException
+	 */
+	public function attachChildNode(\$node)
+	{
+		if (\$this->hasChildNode(\$node))
+			throw new PropelException('Failed to attach child node. Node already exists.');
+
+		if (\$this->obj->isDeleted() || \$node->obj->isDeleted())
+			throw new PropelException('Failed to attach node in deleted state.');
+
+		if (\$this->obj->isNew() && !\$node->obj->isNew())
+			throw new PropelException('Failed to attach non-new child to new node.');
+
+		if (!\$this->obj->isNew() && \$node->obj->isNew())
+			throw new PropelException('Failed to attach new child to non-new node.');
+
+		if (\$this->getNodePath() . $nodePeerClassname::NPATH_SEP . \$node->getNodeIndex() != \$node->getNodePath())
+			throw new PropelException('Failed to attach child node. Node path mismatch.');
+
+		\$this->childNodes[\$node->getNodeIndex()] = \$node;
+		ksort(\$this->childNodes);
+
+		\$node->attachParentNode(\$this);
+	}
+";
+	}
+
+	protected function addDetachParentNode(&$script)
+	{
+		$nodeClassname = $this->getStubNodeBuilder()->getClassname();
+		$script .= "
+	/**
+	 * This method is used internally when deleting nodes. It is used to break
+	 * the link to this node's parent.
+	 * @param      $nodeClassname Parent node to detach from.
+	 * @return     void
+	 * @throws     PropelException
+	 */
+	public function detachParentNode(\$node)
+	{
+		if (!\$node->hasChildNode(\$this, true))
+			throw new PropelException('Failed to detach parent node from non-child.');
+
+		unset(\$node->childNodes[\$this->getNodeIndex()]);
+		\$this->parentNode = null;
+	}
+";
+	}
+
+	protected function addDetachChildNode(&$script)
+	{
+		$script .= "
+	/**
+	 * This method is used internally when deleting nodes. It is used to break
+	 * the link to this between this node and the specified child.
+	 * @param      ".$this->getStubNodeBuilder()->getClassname()." Child node to detach.
+	 * @return     void
+	 * @throws     PropelException
+	 */
+	public function detachChildNode(\$node)
+	{
+		if (!\$this->hasChildNode(\$node, true))
+			throw new PropelException('Failed to detach non-existent child node.');
+
+		unset(\$this->childNodes[\$node->getNodeIndex()]);
+		\$node->parentNode = null;
+	}
+";
+	}
+
+	protected function addShiftChildNodes(&$script)
+	{
+		$peerClassname = $this->getStubPeerBuilder()->getClassname();
+		$nodePeerClassname = $this->getStubNodePeerBuilder()->getClassname();
+
+		$script .= "
+	/**
+	 * Shifts child nodes in the specified direction and offset index. This
+	 * method assumes that there is already space available in the
+	 * direction/offset indicated.
+	 *
+	 * @param      int Direction/# spaces to shift. 1=leftshift, 1=rightshift
+	 * @param      int Node index to start shift at.
+	 * @param      PropelPDO The connection to be used.
+	 * @return     void
+	 * @throws     PropelException
+	 */
+	protected function shiftChildNodes(\$direction, \$offsetIdx, PropelPDO \$con)
+	{
+		if (\$this->obj->isDeleted())
+			throw new PropelException('Cannot shift nodes for deleted object');
+
+		\$lastNode = \$this->getLastChildNode(true, \$con);
+		\$lastIdx = (\$lastNode !== null ? \$lastNode->getNodeIndex() : 0);
+
+		if (\$lastNode === null || \$offsetIdx > \$lastIdx)
+			return;
+
+		if (\$con === null)
+			\$con = Propel::getConnection($peerClassname::DATABASE_NAME);
+
+		if (!\$this->obj->isNew())
+		{
+			// Shift nodes in database.
+			
+			\$con->beginTransaction();
+			
+			try {
+				\$n = \$lastIdx - \$offsetIdx + 1;
+				\$i = \$direction < 1 ? \$offsetIdx : \$lastIdx;
+
+				while (\$n--)
+				{
+					\$srcPath = \$this->getNodePath() . $nodePeerClassname::NPATH_SEP . \$i;			  // 1.2.2
+					\$dstPath = \$this->getNodePath() . $nodePeerClassname::NPATH_SEP . (\$i+\$direction); // 1.2.3
+
+					$nodePeerClassname::moveNodeSubTree(\$srcPath, \$dstPath, \$con);
+
+					\$i -= \$direction;
+				}
+
+				\$con->commit();
+
+			} catch (SQLException \$e) {
+				\$con->rollBack();
+				throw new PropelException(\$e);
+			}
+		}
+
+		// Shift the in-memory objects.
+
+		\$n = \$lastIdx - \$offsetIdx + 1;
+		\$i = \$direction < 1 ? \$offsetIdx : \$lastIdx;
+
+		while (\$n--)
+		{
+			if (isset(\$this->childNodes[\$i]))
+			{
+				\$srcPath = \$this->getNodePath() . $nodePeerClassname::NPATH_SEP . \$i;			  // 1.2.2
+				\$dstPath = \$this->getNodePath() . $nodePeerClassname::NPATH_SEP . (\$i+\$direction); // 1.2.3
+
+				\$this->childNodes[\$i+\$direction] = \$this->childNodes[\$i];
+				\$this->childNodes[\$i+\$direction]->adjustNodePath(\$srcPath, \$dstPath);
+
+				unset(\$this->childNodes[\$i]);
+			}
+
+			\$i -= \$direction;
+		}
+
+		ksort(\$this->childNodes);
+	}
+";
+	}
+
+	protected function addInsertNewChildNode(&$script)
+	{
+		$peerClassname = $this->getStubPeerBuilder()->getClassname();
+		$nodePeerClassname = $this->getStubNodePeerBuilder()->getClassname();
+		$nodeClassname = $this->getStubNodePeerBuilder()->getClassname();
+
+		$script .= "
+	/**
+	 * Inserts the node and its children at the specified childIdx.
+	 *
+	 * @param      $nodeClassname Node to insert.
+	 * @param      int One-based child index to insert at.
+	 * @param      PropelPDO Connection to use.
+	 * @param      void
+	 */
+	protected function insertNewChildNode(\$node, \$childIdx, PropelPDO \$con)
+	{
+		if (!\$node->obj->isNew())
+			throw new PropelException('Failed to insert non-new node.');
+
+		\$setNodePath = 'set' . $nodePeerClassname::NPATH_PHPNAME;
+
+		\$node->obj->\$setNodePath(\$this->getNodePath() . $nodePeerClassname::NPATH_SEP . \$childIdx);
+		\$node->obj->save(\$con);
+
+		\$i = 1;
+		foreach (\$node->childNodes as \$childNode)
+			\$node->insertNewChildNode(\$childNode, \$i++, \$con);
+	}
+";
+	}
+
+	protected function addAdjustStatus(&$script)
+	{
+		$script .= "
+	/**
+	 * Adjust new/deleted status of node and all children.
+	 *
+	 * @param      string Status to change ('New' or 'Deleted')
+	 * @param      boolean Value for status.
+	 * @return     void
+	 */
+	protected function adjustStatus(\$status, \$b)
+	{
+		\$setStatus = 'set' . \$status;
+
+		\$this->obj->\$setStatus(\$b);
+
+		foreach (\$this->childNodes as \$childNode)
+			\$childNode->obj->\$setStatus(\$b);
+	}
+";
+	}
+
+	protected function addAdjustNodePath(&$script)
+	{
+		$nodePeerClassname = $this->getStubNodePeerBuilder()->getClassname();
+		$script .= "
+	/**
+	 * Adjust path of node and all children. This is used internally when
+	 * inserting/moving nodes.
+	 *
+	 * @param      string Section of old path to change.
+	 * @param      string New section to replace old path with.
+	 * @return     void
+	 */
+	protected function adjustNodePath(\$oldBasePath, \$newBasePath)
+	{
+		\$setNodePath = 'set' . $nodePeerClassname::NPATH_PHPNAME;
+
+		\$this->obj->\$setNodePath(\$newBasePath .  substr(\$this->getNodePath(), strlen(\$oldBasePath)));
+		\$this->obj->resetModified($nodePeerClassname::NPATH_COLNAME);
+
+		foreach (\$this->childNodes as \$childNode)
+			\$childNode->adjustNodePath(\$oldBasePath, \$newBasePath);
+	}
+";
+	}
+
+} // PHP5NodeObjectBuilder
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/builder/om/php5/PHP5NodePeerBuilder.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/builder/om/php5/PHP5NodePeerBuilder.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/builder/om/php5/PHP5NodePeerBuilder.php	(revision 19)
@@ -0,0 +1,765 @@
+<?php
+
+/*
+ *  $Id: PHP5NodePeerBuilder.php 1067 2008-08-06 07:37:21Z ron $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://propel.phpdb.org>.
+ */
+
+require_once 'propel/engine/builder/om/PeerBuilder.php';
+
+/**
+ * Generates a PHP5 tree node Peer class for user object model (OM).
+ *
+ * This class produces the base tree node object class (e.g. BaseMyTable) which contains all
+ * the custom-built accessor and setter methods.
+ *
+ * This class replaces the Node.tpl, with the intent of being easier for users
+ * to customize (through extending & overriding).
+ *
+ * @author     Hans Lellelid <hans@xmpl.org>
+ * @package    propel.engine.builder.om.php5
+ */
+class PHP5NodePeerBuilder extends PeerBuilder {
+
+	/**
+	 * Gets the package for the [base] object classes.
+	 * @return     string
+	 */
+	public function getPackage()
+	{
+		return parent::getPackage() . ".om";
+	}
+
+	/**
+	 * Returns the name of the current class being built.
+	 * @return     string
+	 */
+	public function getUnprefixedClassname()
+	{
+		return $this->getBuildProperty('basePrefix') . $this->getStubNodePeerBuilder()->getUnprefixedClassname();
+	}
+
+	/**
+	 * Adds the include() statements for files that this class depends on or utilizes.
+	 * @param      string &$script The script will be modified in this method.
+	 */
+	protected function addIncludes(&$script)
+	{
+	} // addIncludes()
+
+	/**
+	 * Adds class phpdoc comment and openning of class.
+	 * @param      string &$script The script will be modified in this method.
+	 */
+	protected function addClassOpen(&$script)
+	{
+
+		$table = $this->getTable();
+		$tableName = $table->getName();
+		$tableDesc = $table->getDescription();
+
+		$script .= "
+/**
+ * Base  static class for performing query operations on the tree contained by the '$tableName' table.
+ *
+ * $tableDesc
+ *";
+		if ($this->getBuildProperty('addTimeStamp')) {
+			$now = strftime('%c');
+			$script .= "
+ * This class was autogenerated by Propel " . $this->getBuildProperty('version') . " on:
+ *
+ * $now
+ *";
+		}
+		$script .= "
+ * @package    ".$this->getPackage()."
+ */
+abstract class ".$this->getClassname()." {
+";
+	}
+
+	/**
+	 * Specifies the methods that are added as part of the basic OM class.
+	 * This can be overridden by subclasses that wish to add more methods.
+	 * @see        ObjectBuilder::addClassBody()
+	 */
+	protected function addClassBody(&$script)
+	{
+		$table = $this->getTable();
+
+		// FIXME
+		// - Probably the build needs to be customized for supporting
+		// tables that are "aliases".  -- definitely a fringe usecase, though.
+
+		$this->addConstants($script);
+
+		$this->addIsCodeBase($script);
+
+		$this->addRetrieveMethods($script);
+
+		$this->addCreateNewRootNode($script);
+		$this->addInsertNewRootNode($script);
+		$this->addMoveNodeSubTree($script);
+		$this->addDeleteNodeSubTree($script);
+
+		$this->addBuildFamilyCriteria($script);
+		$this->addBuildTree($script);
+
+		$this->addPopulateNodes($script);
+
+	}
+
+	/**
+	 * Closes class.
+	 * @param      string &$script The script will be modified in this method.
+	 */
+	protected function addClassClose(&$script)
+	{
+		$script .= "
+} // " . $this->getClassname() . "
+";
+	}
+
+	protected function addConstants(&$script)
+	{
+		$table = $this->getTable();
+
+		$npath_colname = '';
+		$npath_phpname = '';
+		$npath_len = 0;
+		$npath_sep = '';
+		foreach ($table->getColumns() as $col) {
+			if ($col->isNodeKey()) {
+				$npath_colname = $table->getName() . '.' . strtoupper($col->getName());
+				$npath_phpname = $col->getPhpName();
+				$npath_len = $col->getSize();
+				$npath_sep = $col->getNodeKeySep();
+				break;
+			}
+		}
+		$script .= "
+	const NPATH_COLNAME = '$npath_colname';
+	const NPATH_PHPNAME = '$npath_phpname';
+	const NPATH_SEP		= '$npath_sep';
+	const NPATH_LEN		= $npath_len;
+";
+	}
+
+
+	protected function addIsCodeBase(&$script)
+	{
+		$peerClassname = $this->getStubPeerBuilder()->getClassname();
+		$nodePeerClassname = $this->getStubNodePeerBuilder()->getClassname();
+
+		$script .= "
+	/**
+	 * Temp function for CodeBase hacks that will go away.
+	 */
+	public static function isCodeBase(\$con = null)
+	{
+		if (\$con === null)
+			\$con = Propel::getConnection($peerClassname::DATABASE_NAME);
+
+		return (get_class(\$con) == 'ODBCConnection' &&
+				get_class(\$con->getAdapter()) == 'CodeBaseAdapter');
+	}
+";
+	}
+
+
+	protected function addCreateNewRootNode(&$script)
+	{
+		$peerClassname = $this->getStubPeerBuilder()->getClassname();
+		$objectClassname = $this->getStubObjectBuilder()->getClassname();
+
+		$nodePeerClassname = $this->getStubNodePeerBuilder()->getClassname();
+		$nodeObjectClassname = $this->getStubNodeBuilder()->getClassname();
+
+		$script .= "
+	/**
+	 * Create a new Node at the top of tree. This method will destroy any
+	 * existing root node (along with its children).
+	 *
+	 * Use at your own risk!
+	 *
+	 * @param      $objectClassname Object wrapped by new node.
+	 * @param      PropelPDO Connection to use.
+	 * @return     $nodeObjectClassname
+	 * @throws     PropelException
+	 */
+	public static function createNewRootNode(\$obj, PropelPDO \$con = null)
+	{
+		if (\$con === null)
+			\$con = Propel::getConnection($peerClassname::DATABASE_NAME, Propel::CONNECTION_WRITE);
+		
+		\$con->beginTransaction();
+		
+		try {
+			self::deleteNodeSubTree('1', \$con);
+
+			\$setNodePath = 'set' . self::NPATH_PHPNAME;
+
+			\$obj->\$setNodePath('1');
+			\$obj->save(\$con);
+
+			\$con->commit();
+		} catch (PropelException \$e) {
+			\$con->rollBack();
+			throw \$e;
+		}
+
+		return new $nodeObjectClassname(\$obj);
+	}
+";
+	}
+
+	protected function addInsertNewRootNode(&$script)
+	{
+		$peerClassname = $this->getStubPeerBuilder()->getClassname();
+		$objectClassname = $this->getStubObjectBuilder()->getClassname();
+
+		$nodePeerClassname = $this->getStubNodePeerBuilder()->getClassname();
+		$nodeObjectClassname = $this->getStubNodeBuilder()->getClassname();
+
+		$script .= "
+	/**
+	 * Inserts a new Node at the top of tree. Any existing root node (along with
+	 * its children) will be made a child of the new root node. This is a
+	 * safer alternative to createNewRootNode().
+	 *
+	 * @param      $objectClassname Object wrapped by new node.
+	 * @param      PropelPDO Connection to use.
+	 * @return     $nodeObjectClassname
+	 * @throws     PropelException
+	 */
+	public static function insertNewRootNode(\$obj, PropelPDO \$con = null)
+	{
+		if (\$con === null)
+			\$con = Propel::getConnection($peerClassname::DATABASE_NAME, Propel::CONNECTION_WRITE);
+		
+		\$con->beginTransaction();
+		try {
+			// Move root tree to an invalid node path.
+			$nodePeerClassname::moveNodeSubTree('1', '0', \$con);
+
+			\$setNodePath = 'set' . self::NPATH_PHPNAME;
+
+			// Insert the new root node.
+			\$obj->\$setNodePath('1');
+			\$obj->save(\$con);
+
+			// Move the old root tree as a child of the new root.
+			$nodePeerClassname::moveNodeSubTree('0', '1' . self::NPATH_SEP . '1', \$con);
+
+			\$con->commit();
+		} catch (PropelException \$e) {
+			\$con->rollBack();
+			throw \$e;
+		}
+
+		return new $nodeObjectClassname(\$obj);
+	}
+";
+	}
+
+	/**
+	 * Adds the methods for retrieving nodes.
+	 */
+	protected function addRetrieveMethods(&$script)
+	{
+		$this->addRetrieveNodes($script);
+		$this->addRetrieveNodeByPK($script);
+		$this->addRetrieveNodeByNP($script);
+		$this->addRetrieveRootNode($script);
+
+	}
+
+	protected function addRetrieveNodes(&$script)
+	{
+		$peerClassname = $this->getStubPeerBuilder()->getClassname();
+		$nodePeerClassname = $this->getStubNodePeerBuilder()->getClassname();
+
+		$script .= "
+	/**
+	 * Retrieves an array of tree nodes based on specified criteria. Optionally
+	 * includes all parent and/or child nodes of the matching nodes.
+	 *
+	 * @param      Criteria Criteria to use.
+	 * @param      boolean True if ancestors should also be retrieved.
+	 * @param      boolean True if descendants should also be retrieved.
+	 * @param      PropelPDO Connection to use.
+	 * @return     array Array of root nodes.
+	 */
+	public static function retrieveNodes(\$criteria, \$ancestors = false, \$descendants = false, PropelPDO \$con = null)
+	{
+		\$criteria = $nodePeerClassname::buildFamilyCriteria(\$criteria, \$ancestors, \$descendants);
+		\$stmt = ".$this->getStubPeerBuilder()->getClassname()."::doSelectStmt(\$criteria, \$con);
+		return self::populateNodes(\$stmt, \$criteria);
+	}
+";
+	}
+
+	protected function addRetrieveNodeByPK(&$script)
+	{
+		$peerClassname = $this->getStubPeerBuilder()->getClassname();
+		$objectClassname = $this->getStubObjectBuilder()->getClassname();
+
+		$nodePeerClassname = $this->getStubNodePeerBuilder()->getClassname();
+		$nodeObjectClassname = $this->getStubNodeBuilder()->getClassname();
+
+		$script .= "
+	/**
+	 * Retrieves a tree node based on a primary key. Optionally includes all
+	 * parent and/or child nodes of the matching node.
+	 *
+	 * @param      mixed $objectClassname primary key (array for composite keys)
+	 * @param      boolean True if ancestors should also be retrieved.
+	 * @param      boolean True if descendants should also be retrieved.
+	 * @param      PropelPDO Connection to use.
+	 * @return     $nodeObjectClassname
+	 */
+	public static function retrieveNodeByPK(\$pk, \$ancestors = false, \$descendants = false, PropelPDO \$con = null)
+	{
+		throw new PropelException('retrieveNodeByPK() not implemented yet.');
+	}
+";
+	}
+
+	protected function addRetrieveNodeByNP(&$script)
+	{
+		$peerClassname = $this->getStubPeerBuilder()->getClassname();
+		$objectClassname = $this->getStubObjectBuilder()->getClassname();
+
+		$nodePeerClassname = $this->getStubNodePeerBuilder()->getClassname();
+		$nodeObjectClassname = $this->getStubNodeBuilder()->getClassname();
+
+		$script .= "
+	/**
+	 * Retrieves a tree node based on a node path. Optionally includes all
+	 * parent and/or child nodes of the matching node.
+	 *
+	 * @param      string Node path to retrieve.
+	 * @param      boolean True if ancestors should also be retrieved.
+	 * @param      boolean True if descendants should also be retrieved.
+	 * @param      PropelPDO Connection to use.
+	 * @return     $objectClassname
+	 */
+	public static function retrieveNodeByNP(\$np, \$ancestors = false, \$descendants = false, PropelPDO \$con = null)
+	{
+		\$criteria = new Criteria($peerClassname::DATABASE_NAME);
+		\$criteria->add(self::NPATH_COLNAME, \$np, Criteria::EQUAL);
+		\$criteria = self::buildFamilyCriteria(\$criteria, \$ancestors, \$descendants);
+		\$stmt = $peerClassname::doSelectStmt(\$criteria, \$con);
+		\$nodes = self::populateNodes(\$stmt, \$criteria);
+		return (count(\$nodes) == 1 ? \$nodes[0] : null);
+	}
+";
+	}
+
+	protected function addRetrieveRootNode(&$script)
+	{
+		$script .= "
+	/**
+	 * Retrieves the root node.
+	 *
+	 * @param      string Node path to retrieve.
+	 * @param      boolean True if descendants should also be retrieved.
+	 * @param      PropelPDO Connection to use.
+	 * @return     ".$this->getStubNodeBuilder()->getClassname()."
+	 */
+	public static function retrieveRootNode(\$descendants = false, PropelPDO \$con = null)
+	{
+		return self::retrieveNodeByNP('1', false, \$descendants, \$con);
+	}
+";
+	}
+
+	protected function addMoveNodeSubTree(&$script)
+	{
+		$peerClassname = $this->getStubPeerBuilder()->getClassname();
+		$objectClassname = $this->getStubObjectBuilder()->getClassname();
+
+		$nodePeerClassname = $this->getStubNodePeerBuilder()->getClassname();
+		$nodeObjectClassname = $this->getStubNodeBuilder()->getClassname();
+
+		$script .= "
+	/**
+	 * Moves the node subtree at srcpath to the dstpath. This method is intended
+	 * for internal use by the BaseNode object. Note that it does not check for
+	 * preexisting nodes at the dstpath. It also does not update the  node path
+	 * of any Node objects that might currently be in memory.
+	 *
+	 * Use at your own risk!
+	 *
+	 * @param      string Source node path to move (root of the src subtree).
+	 * @param      string Destination node path to move to (root of the dst subtree).
+	 * @param      PropelPDO Connection to use.
+	 * @return     void
+	 * @throws     PropelException
+	 * @todo       This is currently broken for simulated 'onCascadeDelete's.
+	 * @todo       Need to abstract the SQL better. The CONCAT sql function doesn't
+	 *       seem to be standardized (i.e. mssql), so maybe it needs to be moved
+	 *       to DBAdapter.
+	 */
+	public static function moveNodeSubTree(\$srcPath, \$dstPath, PropelPDO \$con = null)
+	{
+		if (substr(\$dstPath, 0, strlen(\$srcPath)) == \$srcPath)
+			throw new PropelException('Cannot move a node subtree within itself.');
+
+		if (\$con === null)
+			\$con = Propel::getConnection($peerClassname::DATABASE_NAME, Propel::CONNECTION_WRITE);
+
+		/**
+		 * Example:
+		 * UPDATE table
+		 * SET npath = CONCAT('1.3', SUBSTRING(npath, 6, 74))
+		 * WHERE npath = '1.2.2' OR npath LIKE '1.2.2.%'
+		 */
+
+		\$npath = $nodePeerClassname::NPATH_COLNAME;
+		//the following dot isn`t mean`t a nodeKeySeperator
+		\$setcol = substr(\$npath, strrpos(\$npath, '.')+1);
+		\$setcollen = $nodePeerClassname::NPATH_LEN;
+		\$db = Propel::getDb($peerClassname::DATABASE_NAME);
+
+		// <hack>
+		if ($nodePeerClassname::isCodeBase(\$con))
+		{
+			// This is a hack to get CodeBase working. It will eventually be removed.
+			// It is a workaround for the following CodeBase bug:
+			//   -Prepared statement parameters cannot be embedded in SQL functions (i.e. CONCAT)
+			\$sql = \"UPDATE \" . $peerClassname::TABLE_NAME . \" \" .
+				   \"SET \$setcol=\" . \$db->concatString(\"'\$dstPath'\", \$db->subString(\$npath, strlen(\$srcPath)+1, \$setcollen)) . \" \" .
+				   \"WHERE \$npath = '\$srcPath' OR \$npath LIKE '\" . \$srcPath . $nodePeerClassname::NPATH_SEP . \"%'\";
+
+			\$con->executeUpdate(\$sql);
+		}
+		else
+		{
+		// </hack>
+			\$sql = \"UPDATE \" . $peerClassname::TABLE_NAME . \" \" .
+				   \"SET \$setcol=\" . \$db->concatString('?', \$db->subString(\$npath, '?', '?')) . \" \" .
+				   \"WHERE \$npath = ? OR \$npath LIKE ?\";
+
+			\$stmt = \$con->prepare(\$sql);
+			\$stmt->bindValue(1, \$dstPath); // string
+			\$srcPathPlus1 = strlen(\$srcPath)+1;
+			\$stmt->bindValue(2, \$srcPathPlus1); // int
+			\$stmt->bindValue(3, \$setcollen);// int
+			\$stmt->bindValue(4, \$srcPath);// string
+			\$srcPathWC = \$srcPath . $nodePeerClassname::NPATH_SEP . '%';
+			\$stmt->bindValue(5, \$srcPathWC); // string
+			\$stmt->execute();			
+		// <hack>
+		}
+	}
+";
+	}
+
+	protected function addDeleteNodeSubTree(&$script)
+	{
+		$peerClassname = $this->getStubPeerBuilder()->getClassname();
+		$objectClassname = $this->getStubObjectBuilder()->getClassname();
+
+		$nodePeerClassname = $this->getStubNodePeerBuilder()->getClassname();
+		$nodeObjectClassname = $this->getStubNodeBuilder()->getClassname();
+
+		$script .= "
+	/**
+	 * Deletes the node subtree at the specified node path from the database.
+	 *
+	 * @param      string Node path to delete
+	 * @param      PropelPDO Connection to use.
+	 * @return     void
+	 * @throws     PropelException
+	 * @todo       This is currently broken for simulated 'onCascadeDelete's.
+	 */
+	public static function deleteNodeSubTree(\$nodePath, PropelPDO \$con = null)
+	{
+		if (\$con === null)
+			\$con = Propel::getConnection($peerClassname::DATABASE_NAME, Propel::CONNECTION_WRITE);
+
+		/**
+		 * DELETE FROM table
+		 * WHERE npath = '1.2.2' OR npath LIKE '1.2.2.%'
+		 */
+
+		\$criteria = new Criteria($peerClassname::DATABASE_NAME);
+		\$criteria->add($nodePeerClassname::NPATH_COLNAME, \$nodePath, Criteria::EQUAL);
+		\$criteria->addOr($nodePeerClassname::NPATH_COLNAME, \$nodePath . self::NPATH_SEP . '%', Criteria::LIKE);
+		{$this->basePeerClassname}::doDelete(\$criteria, \$con);
+	}
+";
+	}
+
+	protected function addBuildFamilyCriteria(&$script)
+	{
+		$peerClassname = $this->getStubPeerBuilder()->getClassname();
+		$objectClassname = $this->getStubObjectBuilder()->getClassname();
+
+		$nodePeerClassname = $this->getStubNodePeerBuilder()->getClassname();
+		$nodeObjectClassname = $this->getStubNodeBuilder()->getClassname();
+
+		$script .= "
+	/**
+	 * Builds the criteria needed to retrieve node ancestors and/or descendants.
+	 *
+	 * @param      Criteria Criteria to start with
+	 * @param      boolean True if ancestors should be retrieved.
+	 * @param      boolean True if descendants should be retrieved.
+	 * @return     Criteria
+	 */
+	public static function buildFamilyCriteria(\$criteria, \$ancestors = false, \$descendants = false)
+	{
+		/*
+			Example SQL to retrieve nodepath '1.2.3' with both ancestors and descendants:
+
+			SELECT L.NPATH, L.LABEL, test.NPATH, UCASE(L.NPATH)
+			FROM test L, test
+			WHERE test.NPATH='1.2.3' AND
+				 (L.NPATH=SUBSTRING(test.NPATH, 1, LENGTH(L.NPATH)) OR
+				  test.NPATH=SUBSTRING(L.NPATH, 1, LENGTH(test.NPATH)))
+			ORDER BY UCASE(L.NPATH) ASC
+		*/
+
+		if (\$criteria === null)
+			\$criteria = new Criteria($peerClassname::DATABASE_NAME);
+
+		if (!\$criteria->getSelectColumns())
+			$peerClassname::addSelectColumns(\$criteria);
+
+		\$db = Propel::getDb(\$criteria->getDbName());
+
+		if ((\$ancestors || \$descendants) && \$criteria->size())
+		{
+			// If we are retrieving ancestors/descendants, we need to do a
+			// self-join to locate them. The exception to this is if no search
+			// criteria is specified. In this case we're retrieving all nodes
+			// anyway, so there is no need to do a self-join.
+
+			// The left-side of the self-join will contain the columns we'll
+			// use to build node objects (target node records along with their
+			// ancestors and/or descendants). The right-side of the join will
+			// contain the target node records specified by the initial criteria.
+			// These are used to match the appropriate ancestor/descendant on
+			// the left.
+
+			// Specify an alias for the left-side table to use.
+			\$criteria->addAlias('L', $peerClassname::TABLE_NAME);
+
+			// Make sure we have select columns to begin with.
+			if (!\$criteria->getSelectColumns())
+				$peerClassname::addSelectColumns(\$criteria);
+
+			// Replace any existing columns for the right-side table with the
+			// left-side alias.
+			\$selectColumns = \$criteria->getSelectColumns();
+			\$criteria->clearSelectColumns();
+			foreach (\$selectColumns as \$colName)
+				\$criteria->addSelectColumn(str_replace($peerClassname::TABLE_NAME, 'L', \$colName));
+
+			\$a = null;
+			\$d = null;
+
+			\$npathL = $peerClassname::alias('L', $nodePeerClassname::NPATH_COLNAME);
+			\$npathR = $nodePeerClassname::NPATH_COLNAME;
+			\$npath_len = $nodePeerClassname::NPATH_LEN;
+
+			if (\$ancestors)
+			{
+				// For ancestors, match left-side node paths which are contained
+				// by right-side node paths.
+				\$a = \$criteria->getNewCriterion(\$npathL,
+								                \"\$npathL=\" . \$db->subString(\$npathR, 1, \$db->strLength(\$npathL), \$npath_len),
+								                Criteria::CUSTOM);
+			}
+
+			if (\$descendants)
+			{
+				// For descendants, match left-side node paths which contain
+				// right-side node paths.
+				\$d = \$criteria->getNewCriterion(\$npathR,
+								                \"\$npathR=\" . \$db->subString(\$npathL, 1, \$db->strLength(\$npathR), \$npath_len),
+								                Criteria::CUSTOM);
+			}
+
+			if (\$a)
+			{
+				if (\$d) \$a->addOr(\$d);
+				\$criteria->addAnd(\$a);
+			}
+			else if (\$d)
+			{
+				\$criteria->addAnd(\$d);
+			}
+
+			// Add the target node path column. This is used by populateNodes().
+			\$criteria->addSelectColumn(\$npathR);
+
+			// Sort by node path to speed up tree construction in populateNodes()
+			\$criteria->addAsColumn('npathlen', \$db->strLength(\$npathL));
+			\$criteria->addAscendingOrderByColumn('npathlen');
+			\$criteria->addAscendingOrderByColumn(\$npathL);
+		}
+		else
+		{
+			// Add the target node path column. This is used by populateNodes().
+			\$criteria->addSelectColumn($nodePeerClassname::NPATH_COLNAME);
+
+			// Sort by node path to speed up tree construction in populateNodes()
+			\$criteria->addAsColumn('npathlen', \$db->strLength($nodePeerClassname::NPATH_COLNAME));
+			\$criteria->addAscendingOrderByColumn('npathlen');
+			\$criteria->addAscendingOrderByColumn($nodePeerClassname::NPATH_COLNAME);
+		}
+
+		return \$criteria;
+	}
+";
+	}
+
+	protected function addBuildTree(&$script)
+	{
+		$peerClassname = $this->getStubPeerBuilder()->getClassname();
+		$objectClassname = $this->getStubObjectBuilder()->getClassname();
+
+		$nodePeerClassname = $this->getStubNodePeerBuilder()->getClassname();
+		$nodeObjectClassname = $this->getStubNodeBuilder()->getClassname();
+
+		$script .= "
+	/**
+	 * This method reconstructs as much of the tree structure as possible from
+	 * the given array of objects. Depending on how you execute your query, it
+	 * is possible for the ResultSet to contain multiple tree fragments (i.e.
+	 * subtrees). The array returned by this method will contain one entry
+	 * for each subtree root node it finds. The remaining subtree nodes are
+	 * accessible from the $nodeObjectClassname methods of the
+	 * subtree root nodes.
+	 *
+	 * @param      array Array of $nodeObjectClassname objects
+	 * @return     array Array of $nodeObjectClassname objects
+	 */
+	public static function buildTree(\$nodes)
+	{
+		// Subtree root nodes to return
+		\$rootNodes = array();
+
+		// Build the tree relations
+		foreach (\$nodes as \$node)
+		{
+			\$sep = strrpos(\$node->getNodePath(), $nodePeerClassname::NPATH_SEP);
+			\$parentPath = (\$sep !== false ? substr(\$node->getNodePath(), 0, \$sep) : '');
+			\$parentNode = null;
+
+			// Scan other nodes for parent.
+			foreach (\$nodes as \$pnode)
+			{
+				if (\$pnode->getNodePath() === \$parentPath)
+				{
+					\$parentNode = \$pnode;
+					break;
+				}
+			}
+
+			// If parent was found, attach as child, otherwise its a subtree root
+			if (\$parentNode)
+				\$parentNode->attachChildNode(\$node);
+			else
+				\$rootNodes[] = \$node;
+		}
+
+		return \$rootNodes;
+	}
+";
+	}
+
+	protected function addPopulateNodes(&$script)
+	{
+		$table = $this->getTable();
+
+		$peerClassname = $this->getStubPeerBuilder()->getClassname();
+		$objectClassname = $this->getStubObjectBuilder()->getClassname();
+
+		$nodePeerClassname = $this->getStubNodePeerBuilder()->getClassname();
+		$nodeObjectClassname = $this->getStubNodeBuilder()->getClassname();
+
+		$script .= "
+	/**
+	 * Populates the $objectClassname objects from the
+	 * specified ResultSet, wraps them in $nodeObjectClassname
+	 * objects and build the appropriate node relationships.
+	 * The array returned by this method will only include the initial targets
+	 * of the query, even if ancestors/descendants were also requested.
+	 * The ancestors/descendants will be cached in memory and are accessible via
+	 * the getNode() methods.
+	 *
+	 * @param      PDOStatement \$stmt	Executed PDOStatement
+	 * @param      Criteria
+	 * @return     array Array of $nodeObjectClassname objects.
+	 */
+	public static function populateNodes(PDOStatement \$stmt, \$criteria)
+	{
+		\$nodes = array();
+		\$targets = array();
+		\$targetfld = count(\$criteria->getSelectColumns());
+";
+
+		if (!$table->getChildrenColumn()) {
+			$script .= "
+		// set the class once to avoid overhead in the loop
+		\$cls = $peerClassname::getOMClass();
+		\$cls = substr('.'.\$cls, strrpos('.'.\$cls, '.') + 1);
+";
+		}
+
+		$script .= "
+		// populate the object(s)
+		foreach(\$stmt->fetchAll() AS \$row)
+		{
+			if (!isset(\$nodes[\$row[0]]))
+			{
+";
+		if ($table->getChildrenColumn()) {
+			$script .= "
+				// class must be set each time from the record row
+				\$cls = $peerClassname::getOMClass(\$row, 1);
+				\$cls = substr('.'.\$cls, strrpos('.'.\$cls, '.') + 1);
+";
+		}
+
+		$script .= "
+		" . $this->buildObjectInstanceCreationCode('$obj', '$cls') . "
+				\$obj->hydrate(\$row);
+
+				\$nodes[\$row[0]] = new $nodeObjectClassname(\$obj);
+			}
+
+			\$node = \$nodes[\$row[0]];
+
+			if (\$node->getNodePath() === \$row[\$targetfld])
+				\$targets[\$node->getNodePath()] = \$node;
+		}
+
+		$nodePeerClassname::buildTree(\$nodes);
+
+		return array_values(\$targets);
+	}
+";
+	}
+
+} // PHP5NodePeerBuilder
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/builder/om/php5/PHP5ObjectBuilder.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/builder/om/php5/PHP5ObjectBuilder.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/builder/om/php5/PHP5ObjectBuilder.php	(revision 19)
@@ -0,0 +1,4024 @@
+<?php
+
+/*
+ *  $Id: PHP5ObjectBuilder.php 1067 2008-08-06 07:37:21Z ron $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://propel.phpdb.org>.
+ */
+
+require_once 'propel/engine/builder/om/ObjectBuilder.php';
+
+/**
+ * Generates a PHP5 base Object class for user object model (OM).
+ *
+ * This class produces the base object class (e.g. BaseMyTable) which contains all
+ * the custom-built accessor and setter methods.
+ *
+ * @author     Hans Lellelid <hans@xmpl.org>
+ * @package    propel.engine.builder.om.php5
+ */
+class PHP5ObjectBuilder extends ObjectBuilder {
+
+	/**
+	 * Gets the package for the [base] object classes.
+	 * @return     string
+	 */
+	public function getPackage()
+	{
+		return parent::getPackage() . ".om";
+	}
+
+	/**
+	 * Returns the name of the current class being built.
+	 * @return     string
+	 */
+	public function getUnprefixedClassname()
+	{
+		return $this->getBuildProperty('basePrefix') . $this->getStubObjectBuilder()->getUnprefixedClassname();
+	}
+
+	/**
+	 * Validates the current table to make sure that it won't
+	 * result in generated code that will not parse.
+	 *
+	 * This method may emit warnings for code which may cause problems
+	 * and will throw exceptions for errors that will definitely cause
+	 * problems.
+	 */
+	protected function validateModel()
+	{
+		parent::validateModel();
+
+		$table = $this->getTable();
+
+		// Check to see whether any generated foreign key names
+		// will conflict with column names.
+
+		$colPhpNames = array();
+		$fkPhpNames = array();
+
+		foreach ($table->getColumns() as $col) {
+			$colPhpNames[] = $col->getPhpName();
+		}
+
+		foreach ($table->getForeignKeys() as $fk) {
+			$fkPhpNames[] = $this->getFKPhpNameAffix($fk, $plural = false);
+		}
+
+		$intersect = array_intersect($colPhpNames, $fkPhpNames);
+		if (!empty($intersect)) {
+			throw new EngineException("One or more of your column names for [" . $table->getName() . "] table conflict with foreign key names (" . implode(", ", $intersect) . ")");
+		}
+
+		// Check foreign keys to see if there are any foreign keys that
+		// are also matched with an inversed referencing foreign key
+		// (this is currently unsupported behavior)
+		// see: http://propel.phpdb.org/trac/ticket/549
+
+		foreach ($table->getForeignKeys() as $fk) {
+			if ($fk->isMatchedByInverseFK()) {
+				throw new EngineException("The 1:1 relationship expressed by foreign key " . $fk->getName() . " is defined in both directions; Propel does not currently support this (if you must have both foreign key constraints, consider adding this constraint with a custom SQL file.)" );
+			}
+		}
+	}
+
+	/**
+	 * Returns the appropriate formatter (from platform) for a date/time column.
+	 * @param      Column $col
+	 * @return     string
+	 */
+	protected function getTemporalFormatter(Column $col)
+	{
+		$fmt = null;
+		if ($col->getType() === PropelTypes::DATE) {
+			$fmt = $this->getPlatform()->getDateFormatter();
+		} elseif ($col->getType() === PropelTypes::TIME) {
+			$fmt = $this->getPlatform()->getTimeFormatter();
+		} elseif ($col->getType() === PropelTypes::TIMESTAMP) {
+			$fmt = $this->getPlatform()->getTimestampFormatter();
+		}
+		return $fmt;
+	}
+
+	/**
+	 * Returns the type-casted and stringified default value for the specified Column.
+	 * This only works for scalar default values currently.
+	 * @return     string The default value or 'NULL' if there is none.
+	 */
+	protected function getDefaultValueString(Column $col)
+	{
+		$defaultValue = var_export(null, true);
+		if (($val = $col->getPhpDefaultValue()) !== null) {
+			if ($col->isTemporalType()) {
+				$fmt = $this->getTemporalFormatter($col);
+				try {
+					if (!($this->getPlatform() instanceof MysqlPlatform &&
+					($val === '0000-00-00 00:00:00' || $val === '0000-00-00'))) {
+						// while technically this is not a default value of NULL,
+						// this seems to be closest in meaning.
+						$defDt = new DateTime($val);
+						$defaultValue = var_export($defDt->format($fmt), true);
+					}
+				} catch (Exception $x) {
+					throw new EngineException("Unable to parse default temporal value for " . $col->getFullyQualifiedName() . ": " .$this->getDefaultValueString($col), $x);
+				}
+			} else {
+				if ($col->isPhpPrimitiveType()) {
+					settype($val, $col->getPhpType());
+					$defaultValue = var_export($val, true);
+				} elseif ($col->isPhpObjectType()) {
+					$defaultValue = 'new '.$col->getPhpType().'(' . var_export($val, true) . ')';
+				} else {
+					throw new EngineException("Cannot get default value string for " . $col->getFullyQualifiedName());
+				}
+			}
+		}
+		return $defaultValue;
+	}
+
+	/**
+	 * Adds the include() statements for files that this class depends on or utilizes.
+	 * @param      string &$script The script will be modified in this method.
+	 */
+	protected function addIncludes(&$script)
+	{
+	} // addIncludes()
+
+	/**
+	 * Adds class phpdoc comment and openning of class.
+	 * @param      string &$script The script will be modified in this method.
+	 */
+	protected function addClassOpen(&$script)
+	{
+
+		$table = $this->getTable();
+		$tableName = $table->getName();
+		$tableDesc = $table->getDescription();
+		$interface = $this->getInterface();
+
+		$script .= "
+/**
+ * Base class that represents a row from the '$tableName' table.
+ *
+ * $tableDesc
+ *";
+		if ($this->getBuildProperty('addTimeStamp')) {
+			$now = strftime('%c');
+			$script .= "
+ * This class was autogenerated by Propel " . $this->getBuildProperty('version') . " on:
+ *
+ * $now
+ *";
+		}
+		$script .= "
+ * @package    ".$this->getPackage()."
+ */
+abstract class ".$this->getClassname()." extends ".ClassTools::classname($this->getBaseClass())." ";
+
+		$interface = ClassTools::getInterface($table);
+		if ($interface) {
+			$script .= " implements " . ClassTools::classname($interface);
+		}
+
+		$script .= " {
+
+";
+	}
+
+	/**
+	 * Specifies the methods that are added as part of the basic OM class.
+	 * This can be overridden by subclasses that wish to add more methods.
+	 * @see        ObjectBuilder::addClassBody()
+	 */
+	protected function addClassBody(&$script)
+	{
+		$table = $this->getTable();
+		if (!$table->isAlias()) {
+			$this->addConstants($script);
+			$this->addAttributes($script);
+		}
+
+		$this->addConstructor($script);
+		$this->addApplyDefaultValues($script);
+
+		$this->addColumnAccessorMethods($script);
+		$this->addColumnMutatorMethods($script);
+
+		$this->addHasOnlyDefaultValues($script);
+
+		$this->addHydrate($script);
+		$this->addEnsureConsistency($script);
+
+		$this->addManipulationMethods($script);
+		$this->addValidationMethods($script);
+
+		if ($this->isAddGenericAccessors()) {
+			$this->addGetByName($script);
+			$this->addGetByPosition($script);
+			$this->addToArray($script);
+		}
+
+		if ($this->isAddGenericMutators()) {
+			$this->addSetByName($script);
+			$this->addSetByPosition($script);
+			$this->addFromArray($script);
+		}
+
+		$this->addBuildCriteria($script);
+		$this->addBuildPkeyCriteria($script);
+		$this->addGetPrimaryKey($script);
+		$this->addSetPrimaryKey($script);
+
+		$this->addCopy($script);
+
+		if (!$table->isAlias()) {
+			$this->addGetPeer($script);
+		}
+
+		$this->addFKMethods($script);
+		$this->addRefFKMethods($script);
+		$this->addClearAllReferences($script);
+	}
+
+	/**
+	 * Closes class.
+	 * @param      string &$script The script will be modified in this method.
+	 */
+	protected function addClassClose(&$script)
+	{
+		$script .= "
+} // " . $this->getClassname() . "
+";
+	}
+
+	/**
+	 * Adds any constants to the class.
+	 * @param      string &$script The script will be modified in this method.
+	 */
+	protected function addConstants(&$script)
+	{
+		// nothing to do here any more
+		// fieldnameTypeConstants have been moved to class BasePeer [sv]
+	}
+
+	/**
+	 * Adds class attributes.
+	 * @param      string &$script The script will be modified in this method.
+	 */
+	protected function addAttributes(&$script)
+	{
+		$table = $this->getTable();
+
+		$script .= "
+	/**
+	 * The Peer class.
+	 * Instance provides a convenient way of calling static methods on a class
+	 * that calling code may not be able to identify.
+	 * @var        ".$this->getPeerClassname()."
+	 */
+	protected static \$peer;
+";
+		if (!$table->isAlias()) {
+			$this->addColumnAttributes($script);
+		}
+
+		foreach ($table->getForeignKeys() as $fk) {
+			$this->addFKAttributes($script, $fk);
+		}
+
+		foreach ($table->getReferrers() as $refFK) {
+			// if ($refFK->getTable()->getName() != $table->getName()) {
+			$this->addRefFKAttributes($script, $refFK);
+			// }
+		}
+
+		$this->addAlreadyInSaveAttribute($script);
+		$this->addAlreadyInValidationAttribute($script);
+	}
+
+	/**
+	 * Adds variables that store column values.
+	 * @param      string &$script The script will be modified in this method.
+	 * @see        addColumnNameConstants()
+	 */
+	protected function addColumnAttributes(&$script) {
+
+		$table = $this->getTable();
+
+		foreach ($table->getColumns() as $col) {
+			$this->addColumnAttributeComment($script, $col);
+			$this->addColumnAttributeDeclaration($script, $col);
+			if ($col->isLazyLoad() ) {
+				$this->addColumnAttributeLoaderComment($script, $col);
+				$this->addColumnAttributeLoaderDeclaration($script, $col);
+			}
+		}
+	}
+
+	/**
+	 * Add comment about the attribute (variable) that stores column values
+	 * @param      string &$script The script will be modified in this method.
+	 * @param      Column $col
+	 **/
+	protected function addColumnAttributeComment(&$script, Column $col) {
+		$cptype = $col->getPhpType();
+		$clo = strtolower($col->getName());
+
+		$script .= "
+	/**
+	 * The value for the $clo field.";
+		if ($col->getDefaultValue()) {
+			if ($col->getDefaultValue()->isExpression()) {
+				$script .= "
+	 * Note: this column has a database default value of: (expression) ".$col->getDefaultValue()->getValue();
+			} else {
+				$script .= "
+	 * Note: this column has a database default value of: ". $this->getDefaultValueString($col);
+			}
+		}
+		$script .= "
+	 * @var        $cptype
+	 */";
+	}
+
+	/**
+	 * Adds the declaration of a column value storage attribute
+	 * @param      string &$script The script will be modified in this method.
+	 * @param      Column $col
+	 **/
+	protected function addColumnAttributeDeclaration(&$script, Column $col) {
+		$clo = strtolower($col->getName());
+		$script .= "
+	protected \$" . $clo . ";
+";
+	}
+
+	/**
+	 * Adds the comment about the attribute keeping track if an attribute value has been loaded
+	 * @param      string &$script The script will be modified in this method.
+	 * @param      Column $col
+	 **/
+	protected function addColumnAttributeLoaderComment(&$script, Column $col) {
+		$script .= "
+	/**
+	 * Whether the lazy-loaded $clo value has been loaded from database.
+	 * This is necessary to avoid repeated lookups if $clo column is NULL in the db.
+	 * @var        boolean
+	 */";
+	}
+
+	/**
+	 * Adds the declaration of the attribute keeping track of an attribute's loaded state
+	 * @param      string &$script The script will be modified in this method.
+	 * @param      Column $col
+	 **/
+	protected function addColumnAttributeLoaderDeclaration(&$script, Column $col) {
+		$clo = strtolower($col->getName());
+		$script .= "
+	protected \$".$clo."_isLoaded = false;
+";
+	}
+
+	/**
+	 * Adds the getPeer() method.
+	 * This is a convenient, non introspective way of getting the Peer class for a particular object.
+	 * @param      string &$script The script will be modified in this method.
+	 */
+	protected function addGetPeer(&$script)
+	{
+		$this->addGetPeerComment($script);
+		$this->addGetPeerFunctionOpen($script);
+		$this->addGetPeerFunctionBody($script);
+		$this->addGetPeerFunctionClose($script);
+	}
+
+	/**
+	 * Add the comment for the getPeer method
+	 * @param      string &$script The script will be modified in this method.
+	 **/
+	protected function addGetPeerComment(&$script) {
+		$script .= "
+	/**
+	 * Returns a peer instance associated with this om.
+	 *
+	 * Since Peer classes are not to have any instance attributes, this method returns the
+	 * same instance for all member of this class. The method could therefore
+	 * be static, but this would prevent one from overriding the behavior.
+	 *
+	 * @return     ".$this->getPeerClassname()."
+	 */";
+	}
+
+	/**
+	 * Adds the function declaration (function opening) for the getPeer method
+	 * @param      string &$script The script will be modified in this method.
+	 **/
+	protected function addGetPeerFunctionOpen(&$script) {
+		$script .= "
+	public function getPeer()
+	{";
+	}
+
+	/**
+	 * Adds the body of the getPeer method
+	 * @param      string &$script The script will be modified in this method.
+	 **/
+	protected function addGetPeerFunctionBody(&$script) {
+		$script .= "
+		if (self::\$peer === null) {
+			" . $this->buildObjectInstanceCreationCode('self::$peer', $this->getPeerClassname()) . "
+		}
+		return self::\$peer;";
+	}
+
+	/**
+	 * Add the function close for the getPeer method
+	 * Note: this is just a } and the body ends with a return statement, so it's quite useless. But it's here anyway for consisency, cause there's a close function for all functions and in some other instances, they are useful
+	 * @param      string &$script The script will be modified in this method.
+	 **/
+	protected function addGetPeerFunctionClose(&$script) {
+		$script .= "
+	}
+";
+	}
+
+	/**
+	 * Adds the constructor for this object.
+	 * @param      string &$script The script will be modified in this method.
+	 * @see        addConstructor()
+	 */
+	protected function addConstructor(&$script)
+	{
+		$this->addConstructorComment($script);
+		$this->addConstructorOpen($script);
+		$this->addConstructorBody($script);
+		$this->addConstructorClose($script);
+	}
+
+	/**
+	 * Adds the comment for the constructor
+	 * @param      string &$script The script will be modified in this method.
+	 **/
+	protected function addConstructorComment(&$script) {
+		$script .= "
+	/**
+	 * Initializes internal state of ".$this->getClassname()." object.
+	 * @see        applyDefaults()
+	 */";
+	}
+
+	/**
+	 * Adds the function declaration for the constructor
+	 * @param      string &$script The script will be modified in this method.
+	 **/
+	protected function addConstructorOpen(&$script) {
+		$script .= "
+	public function __construct()
+	{";
+	}
+
+	/**
+	 * Adds the function body for the constructor
+	 * @param      string &$script The script will be modified in this method.
+	 **/
+	protected function addConstructorBody(&$script) {
+		$script .= "
+		parent::__construct();
+		\$this->applyDefaultValues();";
+	}
+
+	/**
+	 * Adds the function close for the constructor
+	 * @param      string &$script The script will be modified in this method.
+	 **/
+	protected function addConstructorClose(&$script) {
+		$script .= "
+	}
+";
+	}
+
+	/**
+	 * Adds the applyDefaults() method, which is called from the constructor.
+	 * @param      string &$script The script will be modified in this method.
+	 * @see        addConstructor()
+	 */
+	protected function addApplyDefaultValues(&$script)
+	{
+		$this->addApplyDefaultValuesComment($script);
+		$this->addApplyDefaultValuesOpen($script);
+		$this->addApplyDefaultValuesBody($script);
+		$this->addApplyDefaultValuesClose($script);
+	}
+
+	/**
+	 * Adds the comment for the applyDefaults method
+	 * @param      string &$script The script will be modified in this method.
+	 * @see        addApplyDefaultValues()
+	 **/
+	protected function addApplyDefaultValuesComment(&$script) {
+		$script .= "
+	/**
+	 * Applies default values to this object.
+	 * This method should be called from the object's constructor (or
+	 * equivalent initialization method).
+	 * @see        __construct()
+	 */";
+	}
+
+	/**
+	 * Adds the function declaration for the applyDefaults method
+	 * @param      string &$script The script will be modified in this method.
+	 * @see        addApplyDefaultValues()
+	 **/
+	protected function addApplyDefaultValuesOpen(&$script) {
+		 $script .= "
+	public function applyDefaultValues()
+	{";
+	}
+
+	/**
+	 * Adds the function body of the applyDefault method
+	 * @param      string &$script The script will be modified in this method.
+	 * @see        addApplyDefaultValues()
+	 **/
+	protected function addApplyDefaultValuesBody(&$script) {
+		$table = $this->getTable();
+		// FIXME - Apply support for PHP default expressions here
+		// see: http://propel.phpdb.org/trac/ticket/378
+
+		$colsWithDefaults = array();
+		foreach ($table->getColumns() as $col) {
+			$def = $col->getDefaultValue();
+			if ($def !== null && !$def->isExpression()) {
+				$colsWithDefaults[] = $col;
+			}
+		}
+
+		$colconsts = array();
+		foreach ($colsWithDefaults as $col) {
+			$clo = strtolower($col->getName());
+			$script .= "
+		\$this->".$clo." = ".$this->getDefaultValueString($col).";";
+
+		}
+	}
+
+
+	/**
+	 * Adds the function close for the applyDefaults method
+	 * @param      string &$script The script will be modified in this method.
+	 * @see        addApplyDefaultValues()
+	 **/
+	protected function addApplyDefaultValuesClose(&$script) {
+		$script .= "
+	}
+";
+	}
+
+	// --------------------------------------------------------------
+	//
+	// A C C E S S O R    M E T H O D S
+	//
+	// --------------------------------------------------------------
+
+	/**
+	 * Adds a date/time/timestamp getter method.
+	 * @param      string &$script The script will be modified in this method.
+	 * @param      Column $col The current column.
+	 * @see        parent::addColumnAccessors()
+	 */
+	protected function addTemporalAccessor(&$script, Column $col)
+	{
+		$this->addTemporalAccessorComment($script, $col);
+		$this->addTemporalAccessorOpen($script, $col);
+		$this->addTemporalAccessorBody($script, $col);
+		$this->addTemporalAccessorClose($script, $col);
+	} // addTemporalAccessor
+
+
+	/**
+	 * Adds the comment for a temporal accessor
+	 * @param      string &$script The script will be modified in this method.
+	 * @param      Column $col The current column.
+	 * @see        addTemporalAccessor
+	 **/
+	protected function addTemporalAccessorComment(&$script, Column $col) {
+		$clo = strtolower($col->getName());
+		$useDateTime = $this->getBuildProperty('useDateTimeClass');
+
+		$dateTimeClass = $this->getBuildProperty('dateTimeClass');
+		if (!$dateTimeClass) {
+			$dateTimeClass = 'DateTime';
+		}
+
+		$handleMysqlDate = false;
+		if ($this->getPlatform() instanceof MysqlPlatform) {
+			if ($col->getType() === PropelTypes::TIMESTAMP) {
+				$handleMysqlDate = true;
+				$mysqlInvalidDateString = '0000-00-00 00:00:00';
+			} elseif ($col->getType() === PropelTypes::DATE) {
+				$handleMysqlDate = true;
+				$mysqlInvalidDateString = '0000-00-00';
+			}
+			// 00:00:00 is a valid time, so no need to check for that.
+		}
+
+		$script .= "
+	/**
+	 * Get the [optionally formatted] temporal [$clo] column value.
+	 * ".$col->getDescription();
+		if (!$useDateTime) {
+			$script .= "
+	 * This accessor only only work with unix epoch dates.  Consider enabling the propel.useDateTimeClass
+	 * option in order to avoid converstions to integers (which are limited in the dates they can express).";
+		}
+		$script .= "
+	 *
+	 * @param      string \$format The date/time format string (either date()-style or strftime()-style).
+	 *							If format is NULL, then the raw ".($useDateTime ? 'DateTime object' : 'unix timestamp integer')." will be returned.";
+		if ($useDateTime) {
+			$script .= "
+	 * @return     mixed Formatted date/time value as string or $dateTimeClass object (if format is NULL), NULL if column is NULL" .($handleMysqlDate ? ', and 0 if column value is ' . $mysqlInvalidDateString : '');
+		} else {
+			$script .= "
+	 * @return     mixed Formatted date/time value as string or (integer) unix timestamp (if format is NULL), NULL if column is NULL".($handleMysqlDate ? ', and 0 if column value is ' . $mysqlInvalidDateString : '');
+		}
+		$script .= "
+	 * @throws     PropelException - if unable to parse/validate the date/time value.
+	 */";
+	}
+
+
+	/**
+	 * Adds the function declaration for a temporal accessor
+	 * @param      string &$script The script will be modified in this method.
+	 * @param      Column $col The current column.
+	 * @see        addTemporalAccessor
+	 **/
+	protected function addTemporalAccessorOpen(&$script, Column $col) {
+		$cfc = $col->getPhpName();
+
+		$defaultfmt = null;
+				$visibility = $col->getAccessorVisibility();
+
+		// Default date/time formatter strings are specified in build.properties
+		if ($col->getType() === PropelTypes::DATE) {
+			$defaultfmt = $this->getBuildProperty('defaultDateFormat');
+		} elseif ($col->getType() === PropelTypes::TIME) {
+			$defaultfmt = $this->getBuildProperty('defaultTimeFormat');
+		} elseif ($col->getType() === PropelTypes::TIMESTAMP) {
+			$defaultfmt = $this->getBuildProperty('defaultTimeStampFormat');
+		}
+		if (empty($defaultfmt)) { $defaultfmt = null; }
+
+		$script .= "
+	".$visibility." function get$cfc(\$format = ".var_export($defaultfmt, true)."";
+		if ($col->isLazyLoad()) $script .= ", \$con = null";
+		$script .= ")
+	{";
+	}
+
+	/**
+	 * Adds the body of the temporal accessor
+	 * @param      string &$script The script will be modified in this method.
+	 * @param      Column $col The current column.
+	 * @see        addTemporalAccessor
+	 **/
+	protected function addTemporalAccessorBody(&$script, Column $col) {
+		$cfc = $col->getPhpName();
+		$clo = strtolower($col->getName());
+
+		$useDateTime = $this->getBuildProperty('useDateTimeClass');
+
+		$dateTimeClass = $this->getBuildProperty('dateTimeClass');
+		if (!$dateTimeClass) {
+			$dateTimeClass = 'DateTime';
+		}
+
+		$defaultfmt = null;
+
+		// Default date/time formatter strings are specified in build.properties
+		if ($col->getType() === PropelTypes::DATE) {
+			$defaultfmt = $this->getBuildProperty('defaultDateFormat');
+		} elseif ($col->getType() === PropelTypes::TIME) {
+			$defaultfmt = $this->getBuildProperty('defaultTimeFormat');
+		} elseif ($col->getType() === PropelTypes::TIMESTAMP) {
+			$defaultfmt = $this->getBuildProperty('defaultTimeStampFormat');
+		}
+		if (empty($defaultfmt)) { $defaultfmt = null; }
+
+		$handleMysqlDate = false;
+		if ($this->getPlatform() instanceof MysqlPlatform) {
+			if ($col->getType() === PropelTypes::TIMESTAMP) {
+				$handleMysqlDate = true;
+				$mysqlInvalidDateString = '0000-00-00 00:00:00';
+			} elseif ($col->getType() === PropelTypes::DATE) {
+				$handleMysqlDate = true;
+				$mysqlInvalidDateString = '0000-00-00';
+			}
+			// 00:00:00 is a valid time, so no need to check for that.
+		}
+
+		if ($col->isLazyLoad()) {
+			$script .= "
+		if (!\$this->".$clo."_isLoaded && \$this->$clo === null && !\$this->isNew()) {
+			\$this->load$cfc(\$con);
+		}
+";
+		}
+		$script .= "
+		if (\$this->$clo === null) {
+			return null;
+		}
+
+";
+		if ($handleMysqlDate) {
+			$script .= "
+		if (\$this->$clo === '$mysqlInvalidDateString') {
+			// while technically this is not a default value of NULL,
+			// this seems to be closest in meaning.
+			return null;
+		} else {
+			try {
+				\$dt = new $dateTimeClass(\$this->$clo);
+			} catch (Exception \$x) {
+				throw new PropelException(\"Internally stored date/time/timestamp value could not be converted to $dateTimeClass: \" . var_export(\$this->$clo, true), \$x);
+			}
+		}
+";
+		} else {
+			$script .= "
+
+		try {
+			\$dt = new $dateTimeClass(\$this->$clo);
+		} catch (Exception \$x) {
+			throw new PropelException(\"Internally stored date/time/timestamp value could not be converted to $dateTimeClass: \" . var_export(\$this->$clo, true), \$x);
+		}
+";
+		} // if handleMyqlDate
+
+		$script .= "
+		if (\$format === null) {";
+		if ($useDateTime) {
+			$script .= "
+			// Because propel.useDateTimeClass is TRUE, we return a $dateTimeClass object.
+			return \$dt;";
+		} else {
+			$script .= "
+			// We cast here to maintain BC in API; obviously we will lose data if we're dealing with pre-/post-epoch dates.
+			return (int) \$dt->format('U');";
+		}
+		$script .= "
+		} elseif (strpos(\$format, '%') !== false) {
+			return strftime(\$format, \$dt->format('U'));
+		} else {
+			return \$dt->format(\$format);
+		}";
+	}
+
+
+	/**
+	 * Adds the body of the temporal accessor
+	 * @param      string &$script The script will be modified in this method.
+	 * @param      Column $col The current column.
+	 * @see        addTemporalAccessorClose
+	 **/
+	protected function addTemporalAccessorClose(&$script, Column $col) {
+		$script .= "
+	}
+";
+	}
+
+	/**
+	 * Adds a normal (non-temporal) getter method.
+	 * @param      string &$script The script will be modified in this method.
+	 * @param      Column $col The current column.
+	 * @see        parent::addColumnAccessors()
+	 */
+	protected function addDefaultAccessor(&$script, Column $col)
+	{
+		$this->addDefaultAccessorComment($script, $col);
+		$this->addDefaultAccessorOpen($script, $col);
+		$this->addDefaultAccessorBody($script, $col);
+		$this->addDefaultAccessorClose($script, $col);
+	}
+
+	/**
+	 * Add the comment for a default accessor method (a getter)
+	 * @param      string &$script The script will be modified in this method.
+	 * @param      Column $col The current column.
+	 * @see        addDefaultAccessor()
+	 **/
+	protected function addDefaultAccessorComment(&$script, Column $col) {
+		$clo=strtolower($col->getName());
+
+		$script .= "
+	/**
+	 * Get the [$clo] column value.
+	 * ".$col->getDescription();
+		if ($col->isLazyLoad()) {
+			$script .= "
+	 * @param      PropelPDO An optional PropelPDO connection to use for fetching this lazy-loaded column.";
+		}
+		$script .= "
+	 * @return     ".$col->getPhpType()."
+	 */";
+	}
+
+	/**
+	 * Adds the function declaration for a default accessor
+	 * @param      string &$script The script will be modified in this method.
+	 * @param      Column $col The current column.
+	 * @see        addDefaultAccessor()
+	 **/
+	protected function addDefaultAccessorOpen(&$script, Column $col) {
+		$cfc = $col->getPhpName();
+		$visibility = $col->getAccessorVisibility();
+
+		$script .= "
+	".$visibility." function get$cfc(";
+		if ($col->isLazyLoad()) $script .= "PropelPDO \$con = null";
+		$script .= ")
+	{";
+	}
+
+	/**
+	 * Adds the function body for a default accessor method
+	 * @param      string &$script The script will be modified in this method.
+	 * @param      Column $col The current column.
+	 * @see        addDefaultAccessor()
+	 **/
+	protected function addDefaultAccessorBody(&$script, Column $col) {
+		$cfc = $col->getPhpName();
+		$clo = strtolower($col->getName());
+		if ($col->isLazyLoad()) {
+			$script .= "
+		if (!\$this->".$clo."_isLoaded && \$this->$clo === null && !\$this->isNew()) {
+			\$this->load$cfc(\$con);
+		}
+";
+		}
+
+		$script .= "
+		return \$this->$clo;";
+	}
+
+	/**
+	 * Adds the function close for a default accessor method
+	 * @param      string &$script The script will be modified in this method.
+	 * @param      Column $col The current column.
+	 * @see        addDefaultAccessor()
+	 **/
+	protected function addDefaultAccessorClose(&$script, Column $col) {
+		$script .= "
+	}
+";
+	}
+
+	/**
+	 * Adds the lazy loader method.
+	 * @param      string &$script The script will be modified in this method.
+	 * @param      Column $col The current column.
+	 * @see        parent::addColumnAccessors()
+	 */
+	protected function addLazyLoader(&$script, Column $col)
+	{
+		$this->addLazyLoaderComment($script, $col);
+		$this->addLazyLoaderOpen($script, $col);
+		$this->addLazyLoaderBody($script, $col);
+		$this->addLazyLoaderClose($script, $col);
+	}
+
+	/**
+	 * Adds the comment for the lazy loader method
+	 * @param      string &$script The script will be modified in this method.
+	 * @param      Column $col The current column.
+	 * @see        addLazyLoader()
+	 **/
+	protected function addLazyLoaderComment(&$script, Column $col) {
+		$clo = strtolower($col->getName());
+
+		$script .= "
+	/**
+	 * Load the value for the lazy-loaded [$clo] column.
+	 *
+	 * This method performs an additional query to return the value for
+	 * the [$clo] column, since it is not populated by
+	 * the hydrate() method.
+	 *
+	 * @param      \$con PropelPDO (optional) The PropelPDO connection to use.
+	 * @return     void
+	 * @throws     PropelException - any underlying error will be wrapped and re-thrown.
+	 */";
+	}
+
+	/**
+	 * Adds the function declaration for the lazy loader method
+	 * @param      string &$script The script will be modified in this method.
+	 * @param      Column $col The current column.
+	 * @see        addLazyLoader()
+	 **/
+	protected function addLazyLoaderOpen(&$script, Column $col) {
+		$cfc = $col->getPhpName();
+		$script .= "
+	protected function load$cfc(PropelPDO \$con = null)
+	{";
+	}
+
+	/**
+	 * Adds the function body for the lazy loader method
+	 * @param      string &$script The script will be modified in this method.
+	 * @param      Column $col The current column.
+	 * @see        addLazyLoader()
+	 **/
+	protected function addLazyLoaderBody(&$script, Column $col) {
+		$platform = $this->getPlatform();
+		$clo = strtolower($col->getName());
+
+		$script .= "
+		\$c = \$this->buildPkeyCriteria();
+		\$c->addSelectColumn(".$this->getColumnConstant($col).");
+		try {
+			\$stmt = ".$this->getPeerClassname()."::doSelectStmt(\$c, \$con);
+			\$row = \$stmt->fetch(PDO::FETCH_NUM);
+			\$stmt->closeCursor();";
+
+		if ($col->isLobType() && !$platform->hasStreamBlobImpl()) {
+			$script .= "
+			if (\$row[0] !== null) {
+				\$this->$clo = fopen('php://memory', 'r+');
+				fwrite(\$this->$clo, \$row[0]);
+				rewind(\$this->$clo);
+			} else {
+				\$this->$clo = null;
+			}";
+		} elseif ($col->isPhpPrimitiveType()) {
+			$script .= "
+			\$this->$clo = (\$row[0] !== null) ? (".$col->getPhpType().") \$row[0] : null;";
+		} elseif ($col->isPhpObjectType()) {
+			$script .= "
+			\$this->$clo = (\$row[0] !== null) ? new ".$col->getPhpType()."(\$row[0]) : null;";
+		} else {
+			$script .= "
+			\$this->$clo = \$row[0];";
+		}
+
+		$script .= "
+			\$this->".$clo."_isLoaded = true;
+		} catch (Exception \$e) {
+			throw new PropelException(\"Error loading value for [$clo] column on demand.\", \$e);
+		}";
+	}
+
+	/**
+	 * Adds the function close for the lazy loader
+	 * @param      string &$script The script will be modified in this method.
+	 * @param      Column $col The current column.
+	 * @see        addLazyLoader()
+	 **/
+	protected function addLazyLoaderClose(&$script, Column $col) {
+		$script .= "
+	}";
+	} // addLazyLoader()
+
+	// --------------------------------------------------------------
+	//
+	// M U T A T O R    M E T H O D S
+	//
+	// --------------------------------------------------------------
+
+	/**
+	 * Adds the open of the mutator (setter) method for a column.
+	 * @param      string &$script The script will be modified in this method.
+	 * @param      Column $col The current column.
+	 */
+	protected function addMutatorOpen(&$script, Column $col)
+	{
+		$this->addMutatorComment($script, $col);
+		$this->addMutatorOpenOpen($script, $col);
+		$this->addMutatorOpenBody($script, $col);
+	}
+
+	/**
+	 * Adds the comment for a mutator
+	 * @param      string &$script The script will be modified in this method.
+	 * @param      Column $col The current column.
+	 * @see        addMutatorOpen()
+	 **/
+	protected function addMutatorComment(&$script, Column $col) {
+		$clo = strtolower($col->getName());
+		$script .= "
+	/**
+	 * Set the value of [$clo] column.
+	 * ".$col->getDescription()."
+	 * @param      ".$col->getPhpType()." \$v new value
+	 * @return     ".$this->getObjectClassname()." The current object (for fluent API support)
+	 */";
+	}
+
+	/**
+	 * Adds the mutator function declaration
+	 * @param      string &$script The script will be modified in this method.
+	 * @param      Column $col The current column.
+	 * @see        addMutatorOpen()
+	 **/
+	protected function addMutatorOpenOpen(&$script, Column $col) {
+		$cfc = $col->getPhpName();
+		$visibility = $col->getMutatorVisibility();
+
+		$script .= "
+	".$visibility." function set$cfc(\$v)
+	{";
+	}
+
+	/**
+	 * Adds the mutator open body part
+	 * @param      string &$script The script will be modified in this method.
+	 * @param      Column $col The current column.
+	 * @see        addMutatorOpen()
+	 **/
+	protected function addMutatorOpenBody(&$script, Column $col) {
+		$clo = strtolower($col->getName());
+				$cfc = $col->getPhpName();
+		if ($col->isLazyLoad()) {
+			$script .= "
+		// explicitly set the is-loaded flag to true for this lazy load col;
+		// it doesn't matter if the value is actually set or not (logic below) as
+		// any attempt to set the value means that no db lookup should be performed
+		// when the get$cfc() method is called.
+		\$this->".$clo."_isLoaded = true;
+";
+		}
+	}
+
+	/**
+	 * Adds the close of the mutator (setter) method for a column.
+	 *
+	 * @param      string &$script The script will be modified in this method.
+	 * @param      Column $col The current column.
+	 */
+	protected function addMutatorClose(&$script, Column $col)
+	{
+		$this->addMutatorCloseBody($script, $col);
+		$this->addMutatorCloseClose($script, $col);
+	}
+
+	/**
+	 * Adds the body of the close part of a mutator
+	 * @param      string &$script The script will be modified in this method.
+	 * @param      Column $col The current column.
+	 * @see        addMutatorClose()
+	 **/
+	protected function addMutatorCloseBody(&$script, Column $col) {
+		$table = $this->getTable();
+		$cfc = $col->getPhpName();
+		$clo = strtolower($col->getName());
+
+		if ($col->isForeignKey()) {
+
+			foreach ($col->getForeignKeys() as $fk) {
+
+				$tblFK =  $table->getDatabase()->getTable($fk->getForeignTableName());
+				$colFK = $tblFK->getColumn($fk->getMappedForeignColumn($col->getName()));
+
+				$varName = $this->getFKVarName($fk);
+
+				$script .= "
+		if (\$this->$varName !== null && \$this->".$varName."->get".$colFK->getPhpName()."() !== \$v) {
+			\$this->$varName = null;
+		}
+";
+			} // foreach fk
+		} /* if col is foreign key */
+
+		foreach ($col->getReferrers() as $refFK) {
+
+			$tblFK = $this->getDatabase()->getTable($refFK->getForeignTableName());
+
+			if ( $tblFK->getName() != $table->getName() ) {
+
+				foreach ($col->getForeignKeys() as $fk) {
+
+					$tblFK = $table->getDatabase()->getTable($fk->getForeignTableName());
+					$colFK = $tblFK->getColumn($fk->getMappedForeignColumn($col->getName()));
+
+					if ($refFK->isLocalPrimaryKey()) {
+						$varName = $this->getPKRefFKVarName($refFK);
+						$script .= "
+		// update associated ".$tblFK->getPhpName()."
+		if (\$this->$varName !== null) {
+			\$this->{$varName}->set".$colFK->getPhpName()."(\$v);
+		}
+";
+					} else {
+						$collName = $this->getRefFKCollVarName($refFK);
+						$script .= "
+
+		// update associated ".$tblFK->getPhpName()."
+		if (\$this->$collName !== null) {
+			foreach (\$this->$collName as \$referrerObject) {
+				  \$referrerObject->set".$colFK->getPhpName()."(\$v);
+			  }
+		  }
+";
+					} // if (isLocalPrimaryKey
+				} // foreach col->getPrimaryKeys()
+			} // if tablFk != table
+
+		} // foreach
+	}
+
+	/**
+	 * Adds the close for the mutator close
+	 * @param      string &$script The script will be modified in this method.
+	 * @param      Column $col The current column.
+	 * @see        addMutatorClose()
+	 **/
+	protected function addMutatorCloseClose(&$script, Column $col) {
+		$cfc = $col->getPhpName();
+		$script .= "
+		return \$this;
+	} // set$cfc()
+";
+	}
+
+	/**
+	 * Adds a setter for BLOB columns.
+	 * @param      string &$script The script will be modified in this method.
+	 * @param      Column $col The current column.
+	 * @see        parent::addColumnMutators()
+	 */
+	protected function addLobMutator(&$script, Column $col)
+	{
+		$this->addMutatorOpen($script, $col);
+		$clo = strtolower($col->getName());
+		$script .= "
+		// Because BLOB columns are streams in PDO we have to assume that they are
+		// always modified when a new value is passed in.  For example, the contents
+		// of the stream itself may have changed externally.
+		if (!is_resource(\$v)) {
+			\$this->$clo = fopen('php://memory', 'r+');
+			fwrite(\$this->$clo, \$v);
+			rewind(\$this->$clo);
+		} else { // it's already a stream
+			\$this->$clo = \$v;
+		}
+		\$this->modifiedColumns[] = ".$this->getColumnConstant($col).";
+";
+		$this->addMutatorClose($script, $col);
+	} // addLobMutatorSnippet
+
+	/**
+	 * Adds a setter method for date/time/timestamp columns.
+	 * @param      string &$script The script will be modified in this method.
+	 * @param      Column $col The current column.
+	 * @see        parent::addColumnMutators()
+	 */
+	protected function addTemporalMutator(&$script, Column $col)
+	{
+		$cfc = $col->getPhpName();
+		$clo = strtolower($col->getName());
+		$visibility = $col->getMutatorVisibility();
+
+		$dateTimeClass = $this->getBuildProperty('dateTimeClass');
+		if (!$dateTimeClass) {
+			$dateTimeClass = 'DateTime';
+		}
+
+		$script .= "
+	/**
+	 * Sets the value of [$clo] column to a normalized version of the date/time value specified.
+	 * ".$col->getDescription()."
+	 * @param      mixed \$v string, integer (timestamp), or DateTime value.  Empty string will
+	 *						be treated as NULL for temporal objects.
+	 * @return     ".$this->getObjectClassname()." The current object (for fluent API support)
+	 */
+	".$visibility." function set$cfc(\$v)
+	{";
+		if ($col->isLazyLoad()) {
+			$script .= "
+		// explicitly set the is-loaded flag to true for this lazy load col;
+		// it doesn't matter if the value is actually set or not (logic below) as
+		// any attempt to set the value means that no db lookup should be performed
+		// when the get$cfc() method is called.
+		\$this->".$clo."_isLoaded = true;
+";
+		}
+
+		$fmt = var_export($this->getTemporalFormatter($col), true);
+
+		$script .= "
+		// we treat '' as NULL for temporal objects because DateTime('') == DateTime('now')
+		// -- which is unexpected, to say the least.
+		if (\$v === null || \$v === '') {
+			\$dt = null;
+		} elseif (\$v instanceof DateTime) {
+			\$dt = \$v;
+		} else {
+			// some string/numeric value passed; we normalize that so that we can
+			// validate it.
+			try {
+				if (is_numeric(\$v)) { // if it's a unix timestamp
+					\$dt = new $dateTimeClass('@'.\$v, new DateTimeZone('UTC'));
+					// We have to explicitly specify and then change the time zone because of a
+					// DateTime bug: http://bugs.php.net/bug.php?id=43003
+					\$dt->setTimeZone(new DateTimeZone(date_default_timezone_get()));
+				} else {
+					\$dt = new $dateTimeClass(\$v);
+				}
+			} catch (Exception \$x) {
+				throw new PropelException('Error parsing date/time value: ' . var_export(\$v, true), \$x);
+			}
+		}
+
+		if ( \$this->$clo !== null || \$dt !== null ) {
+			// (nested ifs are a little easier to read in this case)
+
+			\$currNorm = (\$this->$clo !== null && \$tmpDt = new $dateTimeClass(\$this->$clo)) ? \$tmpDt->format($fmt) : null;
+			\$newNorm = (\$dt !== null) ? \$dt->format($fmt) : null;
+
+			if ( (\$currNorm !== \$newNorm) // normalized values don't match ";
+
+		if (($def = $col->getDefaultValue()) !== null && !$def->isExpression()) {
+			$defaultValue = $this->getDefaultValueString($col);
+			$script .= "
+					|| (\$dt->format($fmt) === $defaultValue) // or the entered value matches the default";
+		}
+
+		$script .= "
+					)
+			{
+				\$this->$clo = (\$dt ? \$dt->format($fmt) : null);
+				\$this->modifiedColumns[] = ".$this->getColumnConstant($col).";
+			}
+		} // if either are not null
+";
+		$this->addMutatorClose($script, $col);
+	}
+
+	/**
+	 * Adds setter method for "normal" columns.
+	 * @param      string &$script The script will be modified in this method.
+	 * @param      Column $col The current column.
+	 * @see        parent::addColumnMutators()
+	 */
+	protected function addDefaultMutator(&$script, Column $col)
+	{
+		$clo = strtolower($col->getName());
+
+		$this->addMutatorOpen($script, $col);
+
+		// Perform type-casting to ensure that we can use type-sensitive
+		// checking in muators.
+		if ($col->isPhpPrimitiveType()) {
+			$script .= "
+		if (\$v !== null) {
+			\$v = (".$col->getPhpType().") \$v;
+		}
+";
+		}
+
+		$script .= "
+		if (\$this->$clo !== \$v";
+		if (($def = $col->getDefaultValue()) !== null && !$def->isExpression()) {
+			$defaultValue = $this->getDefaultValueString($col);
+			$script .= " || \$v === $defaultValue";
+		}
+		$script .= ") {
+			\$this->$clo = \$v;
+			\$this->modifiedColumns[] = ".$this->getColumnConstant($col).";
+		}
+";
+		$this->addMutatorClose($script, $col);
+	}
+
+	/**
+	 * Adds the hasOnlyDefaultValues() method.
+	 * @param      string &$script The script will be modified in this method.
+	 */
+	protected function addHasOnlyDefaultValues(&$script)
+	{
+		$this->addHasOnlyDefaultValuesComment($script);
+		$this->addHasOnlyDefaultValuesOpen($script);
+		$this->addHasOnlyDefaultValuesBody($script);
+		$this->addHasOnlyDefaultValuesClose($script);
+	}
+
+	/**
+	 * Adds the comment for the hasOnlyDefaultValues method
+	 * @param      string &$script The script will be modified in this method.
+	 * @see        addHasOnlyDefaultValues
+	 **/
+	protected function addHasOnlyDefaultValuesComment(&$script) {
+		$script .= "
+	/**
+	 * Indicates whether the columns in this object are only set to default values.
+	 *
+	 * This method can be used in conjunction with isModified() to indicate whether an object is both
+	 * modified _and_ has some values set which are non-default.
+	 *
+	 * @return     boolean Whether the columns in this object are only been set with default values.
+	 */";
+	}
+
+	/**
+	 * Adds the function declaration for the hasOnlyDefaultValues method
+	 * @param      string &$script The script will be modified in this method.
+	 * @see        addHasOnlyDefaultValues
+	 **/
+	protected function addHasOnlyDefaultValuesOpen(&$script) {
+		$script .= "
+	public function hasOnlyDefaultValues()
+	{";
+	}
+
+	/**
+	 * Adds the function body for the hasOnlyDefaultValues method
+	 * @param      string &$script The script will be modified in this method.
+	 * @see        addHasOnlyDefaultValues
+	 **/
+	protected function addHasOnlyDefaultValuesBody(&$script) {
+		$table = $this->getTable();
+		$colsWithDefaults = array();
+		foreach ($table->getColumns() as $col) {
+			$def = $col->getDefaultValue();
+			if ($def !== null && !$def->isExpression()) {
+				$colsWithDefaults[] = $col;
+			}
+		}
+
+		$colconsts = array();
+		foreach ($colsWithDefaults as $col) {
+			$colconsts[] = $this->getColumnConstant($col);
+		}
+
+		$script .= "
+			// First, ensure that we don't have any columns that have been modified which aren't default columns.
+			if (array_diff(\$this->modifiedColumns, array(".implode(",", $colconsts)."))) {
+				return false;
+			}
+";
+		foreach ($colsWithDefaults as $col) {
+
+			$clo = strtolower($col->getName());
+			$def = $col->getDefaultValue();
+
+			$script .= "
+			if (\$this->$clo !== " . $this->getDefaultValueString($col).") {
+				return false;
+			}
+";
+		}
+	}
+
+	/**
+	 * Adds the function close for the hasOnlyDefaultValues method
+	 * @param      string &$script The script will be modified in this method.
+	 * @see        addHasOnlyDefaultValues
+	 **/
+	protected function addHasOnlyDefaultValuesClose(&$script) {
+		$script .= "
+		// otherwise, everything was equal, so return TRUE
+		return true;";
+		$script .= "
+	} // hasOnlyDefaultValues()
+";
+	}
+
+	/**
+	 * Adds the hydrate() method, which sets attributes of the object based on a ResultSet.
+	 * @param      string &$script The script will be modified in this method.
+	 */
+	protected function addHydrate(&$script)
+	{
+		$this->addHydrateComment($script);
+		$this->addHydrateOpen($script);
+		$this->addHydrateBody($script);
+		$this->addHydrateClose($script);
+	}
+
+	/**
+	 * Adds the comment for the hydrate method
+	 * @param      string &$script The script will be modified in this method.
+	 * @see        addHydrate()
+	 */
+	protected function addHydrateComment(&$script) {
+		$script .= "
+	/**
+	 * Hydrates (populates) the object variables with values from the database resultset.
+	 *
+	 * An offset (0-based \"start column\") is specified so that objects can be hydrated
+	 * with a subset of the columns in the resultset rows.  This is needed, for example,
+	 * for results of JOIN queries where the resultset row includes columns from two or
+	 * more tables.
+	 *
+	 * @param      array \$row The row returned by PDOStatement->fetch(PDO::FETCH_NUM)
+	 * @param      int \$startcol 0-based offset column which indicates which restultset column to start with.
+	 * @param      boolean \$rehydrate Whether this object is being re-hydrated from the database.
+	 * @return     int next starting column
+	 * @throws     PropelException  - Any caught Exception will be rewrapped as a PropelException.
+	 */";
+	}
+
+	/**
+	 * Adds the function declaration for the hydrate method
+	 * @param      string &$script The script will be modified in this method.
+	 * @see        addHydrate()
+	 */
+	protected function addHydrateOpen(&$script) {
+		$script .= "
+	public function hydrate(\$row, \$startcol = 0, \$rehydrate = false)
+	{";
+	}
+
+	/**
+	 * Adds the function body for the hydrate method
+	 * @param      string &$script The script will be modified in this method.
+	 * @see        addHydrate()
+	 */
+	protected function addHydrateBody(&$script) {
+		$table = $this->getTable();
+		$platform = $this->getPlatform();
+		$script .= "
+		try {
+";
+		$n = 0;
+		foreach ($table->getColumns() as $col) {
+			if (!$col->isLazyLoad()) {
+				$clo = strtolower($col->getName());
+				if ($col->isLobType() && !$platform->hasStreamBlobImpl()) {
+					$script .= "
+			if (\$row[\$startcol + $n] !== null) {
+				\$this->$clo = fopen('php://memory', 'r+');
+				fwrite(\$this->$clo, \$row[\$startcol + $n]);
+				rewind(\$this->$clo);
+			} else {
+				\$this->$clo = null;
+			}";
+				} elseif ($col->isPhpPrimitiveType()) {
+					$script .= "
+			\$this->$clo = (\$row[\$startcol + $n] !== null) ? (".$col->getPhpType().") \$row[\$startcol + $n] : null;";
+				} elseif ($col->isPhpObjectType()) {
+					$script .= "
+			\$this->$clo = (\$row[\$startcol + $n] !== null) ? new ".$col->getPhpType()."(\$row[\$startcol + $n]) : null;";
+				} else {
+					$script .= "
+			\$this->$clo = \$row[\$startcol + $n];";
+				}
+				$n++;
+			} // if col->isLazyLoad()
+		} /* foreach */
+
+		if ($this->getBuildProperty("addSaveMethod")) {
+			$script .= "
+			\$this->resetModified();
+";
+		}
+
+		$script .= "
+			\$this->setNew(false);
+
+			if (\$rehydrate) {
+				\$this->ensureConsistency();
+			}
+
+			// FIXME - using NUM_COLUMNS may be clearer.
+			return \$startcol + $n; // $n = ".$this->getPeerClassname()."::NUM_COLUMNS - ".$this->getPeerClassname()."::NUM_LAZY_LOAD_COLUMNS).
+
+		} catch (Exception \$e) {
+			throw new PropelException(\"Error populating ".$table->getPhpName()." object\", \$e);
+		}";
+	}
+
+	/**
+	 * Adds the function close for the hydrate method
+	 * @param      string &$script The script will be modified in this method.
+	 * @see        addHydrate()
+	 */
+	protected function addHydrateClose(&$script) {
+		$script .= "
+	}
+";
+	}
+
+	/**
+	 * Adds the buildPkeyCriteria method
+	 * @param      string &$script The script will be modified in this method.
+	 **/
+	protected function addBuildPkeyCriteria(&$script) {
+		$this->addBuildPkeyCriteriaComment($script);
+		$this->addBuildPkeyCriteriaOpen($script);
+		$this->addBuildPkeyCriteriaBody($script);
+		$this->addBuildPkeyCriteriaClose($script);
+	}
+
+	/**
+	 * Adds the comment for the buildPkeyCriteria method
+	 * @param      string &$script The script will be modified in this method.
+	 * @see        addBuildPkeyCriteria()
+	 **/
+	protected function addBuildPkeyCriteriaComment(&$script) {
+		$script .= "
+	/**
+	 * Builds a Criteria object containing the primary key for this object.
+	 *
+	 * Unlike buildCriteria() this method includes the primary key values regardless
+	 * of whether or not they have been modified.
+	 *
+	 * @return     Criteria The Criteria object containing value(s) for primary key(s).
+	 */";
+	}
+
+	/**
+	 * Adds the function declaration for the buildPkeyCriteria method
+	 * @param      string &$script The script will be modified in this method.
+	 * @see        addBuildPkeyCriteria()
+	 **/
+	protected function addBuildPkeyCriteriaOpen(&$script) {
+		$script .= "
+	public function buildPkeyCriteria()
+	{";
+	}
+
+	/**
+	 * Adds the function body for the buildPkeyCriteria method
+	 * @param      string &$script The script will be modified in this method.
+	 * @see        addBuildPkeyCriteria()
+	 **/
+	protected function addBuildPkeyCriteriaBody(&$script) {
+		$script .= "
+		\$criteria = new Criteria(".$this->getPeerClassname()."::DATABASE_NAME);
+";
+		foreach ($this->getTable()->getColumns() as $col) {
+			$clo = strtolower($col->getName());
+			if ($col->isPrimaryKey()) {
+				$script .= "
+		\$criteria->add(".$this->getColumnConstant($col).", \$this->$clo);";
+			}
+		}
+	}
+
+	/**
+	 * Adds the function close for the buildPkeyCriteria method
+	 * @param      string &$script The script will be modified in this method.
+	 * @see        addBuildPkeyCriteria()
+	 **/
+	protected function addBuildPkeyCriteriaClose(&$script) {
+		$script .= "
+
+		return \$criteria;
+	}
+";
+	}
+
+	/**
+	 * Adds the buildCriteria method
+	 * @param      string &$script The script will be modified in this method.
+	 **/
+	protected function addBuildCriteria(&$script)
+	{
+		$this->addBuildCriteriaComment($script);
+		$this->addBuildCriteriaOpen($script);
+		$this->addBuildCriteriaBody($script);
+		$this->addBuildCriteriaClose($script);
+	}
+
+	/**
+	 * Adds comment for the buildCriteria method
+	 * @param      string &$script The script will be modified in this method.
+	 * @see        addBuildCriteria()
+	 **/
+	protected function addBuildCriteriaComment(&$script) {
+		$script .= "
+	/**
+	 * Build a Criteria object containing the values of all modified columns in this object.
+	 *
+	 * @return     Criteria The Criteria object containing all modified values.
+	 */";
+	}
+
+	/**
+	 * Adds the function declaration of the buildCriteria method
+	 * @param      string &$script The script will be modified in this method.
+	 * @see        addBuildCriteria()
+	 **/
+	protected function addBuildCriteriaOpen(&$script) {
+		$script .= "
+	public function buildCriteria()
+	{";
+	}
+
+	/**
+	 * Adds the function body of the buildCriteria method
+	 * @param      string &$script The script will be modified in this method.
+	 * @see        addBuildCriteria()
+	 **/
+	protected function addBuildCriteriaBody(&$script) {
+		$script .= "
+		\$criteria = new Criteria(".$this->getPeerClassname()."::DATABASE_NAME);
+";
+		foreach ($this->getTable()->getColumns() as $col) {
+			$clo = strtolower($col->getName());
+			$script .= "
+		if (\$this->isColumnModified(".$this->getColumnConstant($col).")) \$criteria->add(".$this->getColumnConstant($col).", \$this->$clo);";
+		}
+	}
+
+	/**
+	 * Adds the function close of the buildCriteria method
+	 * @param      string &$script The script will be modified in this method.
+	 * @see        addBuildCriteria()
+	 **/
+	protected function addBuildCriteriaClose(&$script) {
+		$script .= "
+
+		return \$criteria;
+	}
+";
+	}
+
+	/**
+	 * Adds the toArray method
+	 * @param      string &$script The script will be modified in this method.
+	 **/
+	protected function addToArray(&$script)
+	{
+		$this->addToArrayComment($script);
+		$this->addToArrayOpen($script);
+		$this->addToArrayBody($script);
+		$this->addToArrayClose($script);
+	}
+
+	/**
+	 * Adds the comment of the toArray method
+	 * @param      string &$script The script will be modified in this method.
+	 * @see        addToArray()
+	 **/
+	protected function addToArrayComment(&$script) {
+		$script .= "
+	/**
+	 * Exports the object as an array.
+	 *
+	 * You can specify the key type of the array by passing one of the class
+	 * type constants.
+	 *
+	 * @param      string \$keyType (optional) One of the class type constants BasePeer::TYPE_PHPNAME, BasePeer::TYPE_STUDLYPHPNAME
+	 *                        BasePeer::TYPE_COLNAME, BasePeer::TYPE_FIELDNAME, BasePeer::TYPE_NUM. Defaults to BasePeer::TYPE_PHPNAME.
+	 * @param      boolean \$includeLazyLoadColumns (optional) Whether to include lazy loaded columns.  Defaults to TRUE.
+	 * @return     an associative array containing the field names (as keys) and field values
+	 */";
+	}
+
+	/**
+	 * Adds the function declaration of the toArray method
+	 * @param      string &$script The script will be modified in this method.
+	 * @see        addToArray()
+	 **/
+	protected function addToArrayOpen(&$script) {
+		$script .= "
+	public function toArray(\$keyType = BasePeer::TYPE_PHPNAME, \$includeLazyLoadColumns = true)
+	{";
+	}
+
+	/**
+	 * Adds the function body of the toArray method
+	 * @param      string &$script The script will be modified in this method.
+	 * @see        addToArray()
+	 **/
+	protected function addToArrayBody(&$script) {
+		$script .= "
+		\$keys = ".$this->getPeerClassname()."::getFieldNames(\$keyType);
+		\$result = array(";
+		foreach ($this->getTable()->getColumns() as $num => $col) {
+			if ($col->isLazyLoad()) {
+				 $script .= "
+			\$keys[$num] => (\$includeLazyLoadColumns) ? \$this->get".$col->getPhpName()."() : null,";
+			} else {
+				$script .= "
+			\$keys[$num] => \$this->get".$col->getPhpName()."(),";
+			}
+		}
+		$script .= "
+		);";
+	}
+
+	/**
+	 * Adds the function close of the toArray method
+	 * @param      string &$script The script will be modified in this method.
+	 * @see        addToArray()
+	 **/
+	protected function addToArrayClose(&$script) {
+		$script .= "
+		return \$result;
+	}
+";
+	} // addToArray()
+
+	/**
+	 * Adds the getByName method
+	 * @param      string &$script The script will be modified in this method.
+	 **/
+	protected function addGetByName(&$script)
+	{
+		$this->addGetByNameComment($script);
+		$this->addGetByNameOpen($script);
+		$this->addGetByNameBody($script);
+		$this->addGetByNameClose($script);
+	}
+
+	/**
+	 * Adds the comment for the getByName method
+	 * @param      string &$script The script will be modified in this method.
+	 * @see        addGetByName
+	 **/
+	protected function addGetByNameComment(&$script) {
+		$script .= "
+	/**
+	 * Retrieves a field from the object by name passed in as a string.
+	 *
+	 * @param      string \$name name
+	 * @param      string \$type The type of fieldname the \$name is of:
+	 *                     one of the class type constants BasePeer::TYPE_PHPNAME, BasePeer::TYPE_STUDLYPHPNAME
+	 *                     BasePeer::TYPE_COLNAME, BasePeer::TYPE_FIELDNAME, BasePeer::TYPE_NUM
+	 * @return     mixed Value of field.
+	 */";
+	}
+
+	/**
+	 * Adds the function declaration for the getByName method
+	 * @param      string &$script The script will be modified in this method.
+	 * @see        addGetByName
+	 **/
+	protected function addGetByNameOpen(&$script) {
+		$script .= "
+	public function getByName(\$name, \$type = BasePeer::TYPE_PHPNAME)
+	{";
+	}
+
+	/**
+	 * Adds the function body for the getByName method
+	 * @param      string &$script The script will be modified in this method.
+	 * @see        addGetByName
+	 **/
+	protected function addGetByNameBody(&$script) {
+		$script .= "
+		\$pos = ".$this->getPeerClassname()."::translateFieldName(\$name, \$type, BasePeer::TYPE_NUM);
+		\$field = \$this->getByPosition(\$pos);";
+	}
+
+	/**
+	 * Adds the function close for the getByName method
+	 * @param      string &$script The script will be modified in this method.
+	 * @see        addGetByName
+	 **/
+	protected function addGetByNameClose(&$script) {
+		$script .= "
+		return \$field;
+	}
+";
+	}
+
+	/**
+	 * Adds the getByPosition method
+	 * @param      string &$script The script will be modified in this method.
+	 **/
+	protected function addGetByPosition(&$script)
+	{
+		$this->addGetByPositionComment($script);
+		$this->addGetByPositionOpen($script);
+		$this->addGetByPositionBody($script);
+		$this->addGetByPositionClose($script);
+	}
+
+	/**
+	 * Adds comment for the getByPosition method
+	 * @param      string &$script The script will be modified in this method.
+	 * @see        addGetByPosition
+	 **/
+	protected function addGetByPositionComment(&$script) {
+		$script .= "
+	/**
+	 * Retrieves a field from the object by Position as specified in the xml schema.
+	 * Zero-based.
+	 *
+	 * @param      int \$pos position in xml schema
+	 * @return     mixed Value of field at \$pos
+	 */";
+	}
+
+	/**
+	 * Adds the function declaration for the getByPosition method
+	 * @param      string &$script The script will be modified in this method.
+	 * @see        addGetByPosition
+	 **/
+	protected function addGetByPositionOpen(&$script) {
+		$script .= "
+	public function getByPosition(\$pos)
+	{";
+	}
+
+	/**
+	 * Adds the function body for the getByPosition method
+	 * @param      string &$script The script will be modified in this method.
+	 * @see        addGetByPosition
+	 **/
+	protected function addGetByPositionBody(&$script) {
+		$table = $this->getTable();
+		$script .= "
+		switch(\$pos) {";
+		$i = 0;
+		foreach ($table->getColumns() as $col) {
+			$cfc = $col->getPhpName();
+			$cptype = $col->getPhpType();// not safe to use it because some methods may return objects (Blob)
+			$script .= "
+			case $i:
+				return \$this->get$cfc();
+				break;";
+			$i++;
+		} /* foreach */
+		$script .= "
+			default:
+				return null;
+				break;
+		} // switch()";
+	}
+
+	/**
+	 * Adds the function close for the getByPosition method
+	 * @param      string &$script The script will be modified in this method.
+	 * @see        addGetByPosition
+	 **/
+	protected function addGetByPositionClose(&$script) {
+		$script .= "
+	}
+";
+	}
+
+	protected function addSetByName(&$script)
+	{
+		$table = $this->getTable();
+		$script .= "
+	/**
+	 * Sets a field from the object by name passed in as a string.
+	 *
+	 * @param      string \$name peer name
+	 * @param      mixed \$value field value
+	 * @param      string \$type The type of fieldname the \$name is of:
+	 *                     one of the class type constants BasePeer::TYPE_PHPNAME, BasePeer::TYPE_STUDLYPHPNAME
+	 *                     BasePeer::TYPE_COLNAME, BasePeer::TYPE_FIELDNAME, BasePeer::TYPE_NUM
+	 * @return     void
+	 */
+	public function setByName(\$name, \$value, \$type = BasePeer::TYPE_PHPNAME)
+	{
+		\$pos = ".$this->getPeerClassname()."::translateFieldName(\$name, \$type, BasePeer::TYPE_NUM);
+		return \$this->setByPosition(\$pos, \$value);
+	}
+";
+	}
+
+	protected function addSetByPosition(&$script)
+	{
+		$table = $this->getTable();
+		$script .= "
+	/**
+	 * Sets a field from the object by Position as specified in the xml schema.
+	 * Zero-based.
+	 *
+	 * @param      int \$pos position in xml schema
+	 * @param      mixed \$value field value
+	 * @return     void
+	 */
+	public function setByPosition(\$pos, \$value)
+	{
+		switch(\$pos) {";
+		$i = 0;
+		foreach ($table->getColumns() as $col) {
+			$cfc = $col->getPhpName();
+			$cptype = $col->getPhpType();
+			$script .= "
+			case $i:
+				\$this->set$cfc(\$value);
+				break;";
+			$i++;
+		} /* foreach */
+		$script .= "
+		} // switch()
+	}
+";
+	} // addSetByPosition()
+
+	protected function addFromArray(&$script)
+	{
+		$table = $this->getTable();
+		$script .= "
+	/**
+	 * Populates the object using an array.
+	 *
+	 * This is particularly useful when populating an object from one of the
+	 * request arrays (e.g. \$_POST).  This method goes through the column
+	 * names, checking to see whether a matching key exists in populated
+	 * array. If so the setByName() method is called for that column.
+	 *
+	 * You can specify the key type of the array by additionally passing one
+	 * of the class type constants BasePeer::TYPE_PHPNAME, BasePeer::TYPE_STUDLYPHPNAME,
+	 * BasePeer::TYPE_COLNAME, BasePeer::TYPE_FIELDNAME, BasePeer::TYPE_NUM.
+	 * The default key type is the column's phpname (e.g. 'AuthorId')
+	 *
+	 * @param      array  \$arr     An array to populate the object from.
+	 * @param      string \$keyType The type of keys the array uses.
+	 * @return     void
+	 */
+	public function fromArray(\$arr, \$keyType = BasePeer::TYPE_PHPNAME)
+	{
+		\$keys = ".$this->getPeerClassname()."::getFieldNames(\$keyType);
+";
+		foreach ($table->getColumns() as $num => $col) {
+			$cfc = $col->getPhpName();
+			$cptype = $col->getPhpType();
+			$script .= "
+		if (array_key_exists(\$keys[$num], \$arr)) \$this->set$cfc(\$arr[\$keys[$num]]);";
+		} /* foreach */
+		$script .= "
+	}
+";
+	} // addFromArray
+
+	/**
+	 * Adds a delete() method to remove the object form the datastore.
+	 * @param      string &$script The script will be modified in this method.
+	 */
+	protected function addDelete(&$script)
+	{
+		$this->addDeleteComment($script);
+		$this->addDeleteOpen($script);
+		$this->addDeleteBody($script);
+		$this->addDeleteClose($script);
+	}
+
+	/**
+	 * Adds the comment for the delete function
+	 * @param      string &$script The script will be modified in this method.
+	 * @see        addDelete()
+	 **/
+	protected function addDeleteComment(&$script) {
+		$script .= "
+	/**
+	 * Removes this object from datastore and sets delete attribute.
+	 *
+	 * @param      PropelPDO \$con
+	 * @return     void
+	 * @throws     PropelException
+	 * @see        BaseObject::setDeleted()
+	 * @see        BaseObject::isDeleted()
+	 */";
+	}
+
+	/**
+	 * Adds the function declaration for the delete function
+	 * @param      string &$script The script will be modified in this method.
+	 * @see        addDelete()
+	 **/
+	protected function addDeleteOpen(&$script) {
+		$script .= "
+	public function delete(PropelPDO \$con = null)
+	{";
+	}
+
+	/**
+	 * Adds the function body for the delete function
+	 * @param      string &$script The script will be modified in this method.
+	 * @see        addDelete()
+	 **/
+	protected function addDeleteBody(&$script) {
+		$script .= "
+		if (\$this->isDeleted()) {
+			throw new PropelException(\"This object has already been deleted.\");
+		}
+
+		if (\$con === null) {
+			\$con = Propel::getConnection(".$this->getPeerClassname()."::DATABASE_NAME, Propel::CONNECTION_WRITE);
+		}
+		
+		\$con->beginTransaction();
+		try {
+			".$this->getPeerClassname()."::doDelete(\$this, \$con);
+			\$this->setDeleted(true);
+			\$con->commit();
+		} catch (PropelException \$e) {
+			\$con->rollBack();
+			throw \$e;
+		}";
+	}
+
+	/**
+	 * Adds the function close for the delete function
+	 * @param      string &$script The script will be modified in this method.
+	 * @see        addDelete()
+	 **/
+	protected function addDeleteClose(&$script) {
+		$script .= "
+	}
+";
+	} // addDelete()
+
+	/**
+	 * Adds a reload() method to re-fetch the data for this object from the database.
+	 * @param      string &$script The script will be modified in this method.
+	 */
+	protected function addReload(&$script)
+	{
+		$table = $this->getTable();
+		$script .= "
+	/**
+	 * Reloads this object from datastore based on primary key and (optionally) resets all associated objects.
+	 *
+	 * This will only work if the object has been saved and has a valid primary key set.
+	 *
+	 * @param      boolean \$deep (optional) Whether to also de-associated any related objects.
+	 * @param      PropelPDO \$con (optional) The PropelPDO connection to use.
+	 * @return     void
+	 * @throws     PropelException - if this object is deleted, unsaved or doesn't have pk match in db
+	 */
+	public function reload(\$deep = false, PropelPDO \$con = null)
+	{
+		if (\$this->isDeleted()) {
+			throw new PropelException(\"Cannot reload a deleted object.\");
+		}
+
+		if (\$this->isNew()) {
+			throw new PropelException(\"Cannot reload an unsaved object.\");
+		}
+
+		if (\$con === null) {
+			\$con = Propel::getConnection(".$this->getPeerClassname()."::DATABASE_NAME, Propel::CONNECTION_READ);
+		}
+
+		// We don't need to alter the object instance pool; we're just modifying this instance
+		// already in the pool.
+
+		\$stmt = ".$this->getPeerClassname()."::doSelectStmt(\$this->buildPkeyCriteria(), \$con);
+		\$row = \$stmt->fetch(PDO::FETCH_NUM);
+		\$stmt->closeCursor();
+		if (!\$row) {
+			throw new PropelException('Cannot find matching row in the database to reload object values.');
+		}
+		\$this->hydrate(\$row, 0, true); // rehydrate
+";
+
+		// support for lazy load columns
+		foreach ($table->getColumns() as $col) {
+			if ($col->isLazyLoad()) {
+				$clo = strtolower($col->getName());
+				$script .= "
+		// Reset the $clo lazy-load column
+		\$this->" . $clo . " = null;
+		\$this->".$clo."_isLoaded = false;
+";
+			}
+		}
+
+		$script .= "
+		if (\$deep) {  // also de-associate any related objects?
+";
+
+		foreach ($table->getForeignKeys() as $fk) {
+			$varName = $this->getFKVarName($fk);
+			$script .= "
+			\$this->".$varName." = null;";
+		}
+
+		foreach ($table->getReferrers() as $refFK) {
+			if ($refFK->isLocalPrimaryKey()) {
+				$script .= "
+			\$this->".$this->getPKRefFKVarName($refFK)." = null;
+";
+			} else {
+				$script .= "
+			\$this->".$this->getRefFKCollVarName($refFK)." = null;
+			\$this->".$this->getRefFKLastCriteriaVarName($refFK)." = null;
+";
+			}
+		}
+
+		$script .= "
+		} // if (deep)
+	}
+";
+	} // addReload()
+
+	/**
+	 * Adds the methods related to refreshing, saving and deleting the object.
+	 * @param      string &$script The script will be modified in this method.
+	 */
+	protected function addManipulationMethods(&$script)
+	{
+		$this->addReload($script);
+		$this->addDelete($script);
+		$this->addSave($script);
+		$this->addDoSave($script);
+	}
+
+	/**
+	 * Adds the methods related to validationg the object.
+	 * @param      string &$script The script will be modified in this method.
+	 */
+	protected function addValidationMethods(&$script)
+	{
+		$this->addValidationFailuresAttribute($script);
+		$this->addGetValidationFailures($script);
+		$this->addValidate($script);
+		$this->addDoValidate($script);
+	}
+
+	/**
+	 * Adds the $validationFailures attribute to store ValidationFailed objects.
+	 * @param      string &$script The script will be modified in this method.
+	 */
+	protected function addValidationFailuresAttribute(&$script)
+	{
+		$script .= "
+	/**
+	 * Array of ValidationFailed objects.
+	 * @var        array ValidationFailed[]
+	 */
+	protected \$validationFailures = array();
+";
+	}
+
+	/**
+	 * Adds the getValidationFailures() method.
+	 * @param      string &$script The script will be modified in this method.
+	 */
+	protected function addGetValidationFailures(&$script)
+	{
+		$script .= "
+	/**
+	 * Gets any ValidationFailed objects that resulted from last call to validate().
+	 *
+	 *
+	 * @return     array ValidationFailed[]
+	 * @see        validate()
+	 */
+	public function getValidationFailures()
+	{
+		return \$this->validationFailures;
+	}
+";
+	} // addGetValidationFailures()
+
+	/**
+	 * Adds the correct getPrimaryKey() method for this object.
+	 * @param      string &$script The script will be modified in this method.
+	 */
+	protected function addGetPrimaryKey(&$script)
+	{
+		$pkeys = $this->getTable()->getPrimaryKey();
+		if (count($pkeys) == 1) {
+			$this->addGetPrimaryKey_SinglePK($script);
+		} elseif (count($pkeys) > 1) {
+			$this->addGetPrimaryKey_MultiPK($script);
+		} else {
+			// no primary key -- this is deprecated, since we don't *need* this method anymore
+			$this->addGetPrimaryKey_NoPK($script);
+		}
+	}
+
+	/**
+	 * Adds the getPrimaryKey() method for tables that contain a single-column primary key.
+	 * @param      string &$script The script will be modified in this method.
+	 */
+	protected function addGetPrimaryKey_SinglePK(&$script)
+	{
+		$table = $this->getTable();
+		$pkeys = $table->getPrimaryKey();
+		$cptype = $pkeys[0]->getPhpType();
+
+		$script .= "
+	/**
+	 * Returns the primary key for this object (row).
+	 * @return     $cptype
+	 */
+	public function getPrimaryKey()
+	{
+		return \$this->get".$pkeys[0]->getPhpName()."();
+	}
+";
+	} // addetPrimaryKey_SingleFK
+
+	/**
+	 * Adds the setPrimaryKey() method for tables that contain a multi-column primary key.
+	 * @param      string &$script The script will be modified in this method.
+	 */
+	protected function addGetPrimaryKey_MultiPK(&$script)
+	{
+
+		$script .= "
+	/**
+	 * Returns the composite primary key for this object.
+	 * The array elements will be in same order as specified in XML.
+	 * @return     array
+	 */
+	public function getPrimaryKey()
+	{
+		\$pks = array();
+";
+		$i = 0;
+		foreach ($this->getTable()->getPrimaryKey() as $pk) {
+			$script .= "
+		\$pks[$i] = \$this->get".$pk->getPhpName()."();
+";
+			$i++;
+		} /* foreach */
+		$script .= "
+		return \$pks;
+	}
+";
+	} // addGetPrimaryKey_MultiFK()
+
+	/**
+	 * Adds the getPrimaryKey() method for objects that have no primary key.
+	 * This "feature" is dreprecated, since the getPrimaryKey() method is not required
+	 * by the Persistent interface (or used by the templates).  Hence, this method is also
+	 * deprecated.
+	 * @param      string &$script The script will be modified in this method.
+	 * @deprecated
+	 */
+	protected function addGetPrimaryKey_NoPK(&$script)
+	{
+		$script .= "
+	/**
+	 * Returns NULL since this table doesn't have a primary key.
+	 * This method exists only for BC and is deprecated!
+	 * @return     null
+	 */
+	public function getPrimaryKey()
+	{
+		return null;
+	}
+";
+	}
+	/**
+	 * Adds the correct setPrimaryKey() method for this object.
+	 * @param      string &$script The script will be modified in this method.
+	 */
+	protected function addSetPrimaryKey(&$script)
+	{
+		$pkeys = $this->getTable()->getPrimaryKey();
+		if (count($pkeys) == 1) {
+			$this->addSetPrimaryKey_SinglePK($script);
+		} elseif (count($pkeys) > 1) {
+			$this->addSetPrimaryKey_MultiPK($script);
+		} else {
+			// no primary key -- this is deprecated, since we don't *need* this method anymore
+			$this->addSetPrimaryKey_NoPK($script);
+		}
+	}
+
+	/**
+	 * Adds the setPrimaryKey() method for tables that contain a single-column primary key.
+	 * @param      string &$script The script will be modified in this method.
+	 */
+	protected function addSetPrimaryKey_SinglePK(&$script)
+	{
+
+		$pkeys = $this->getTable()->getPrimaryKey();
+		$col = $pkeys[0];
+		$clo=strtolower($col->getName());
+		$ctype = $col->getPhpType();
+
+		$script .= "
+	/**
+	 * Generic method to set the primary key ($clo column).
+	 *
+	 * @param      $ctype \$key Primary key.
+	 * @return     void
+	 */
+	public function setPrimaryKey(\$key)
+	{
+		\$this->set".$col->getPhpName()."(\$key);
+	}
+";
+	} // addSetPrimaryKey_SinglePK
+
+	/**
+	 * Adds the setPrimaryKey() method for tables that contain a multi-columnprimary key.
+	 * @param      string &$script The script will be modified in this method.
+	 */
+	protected function addSetPrimaryKey_MultiPK(&$script)
+	{
+
+		$script .="
+	/**
+	 * Set the [composite] primary key.
+	 *
+	 * @param      array \$keys The elements of the composite key (order must match the order in XML file).
+	 * @return     void
+	 */
+	public function setPrimaryKey(\$keys)
+	{
+";
+		$i = 0;
+		foreach ($this->getTable()->getPrimaryKey() as $pk) {
+			$pktype = $pk->getPhpType();
+			$script .= "
+		\$this->set".$pk->getPhpName()."(\$keys[$i]);
+";
+			$i++;
+		} /* foreach ($table->getPrimaryKey() */
+		$script .= "
+	}
+";
+	} // addSetPrimaryKey_MultiPK
+
+	/**
+	 * Adds the setPrimaryKey() method for objects that have no primary key.
+	 * This "feature" is dreprecated, since the setPrimaryKey() method is not required
+	 * by the Persistent interface (or used by the templates).  Hence, this method is also
+	 * deprecated.
+	 * @param      string &$script The script will be modified in this method.
+	 * @deprecated
+	 */
+	protected function addSetPrimaryKey_NoPK(&$script)
+	{
+		$script .="
+	/**
+	 * Dummy primary key setter.
+	 *
+	 * This function only exists to preserve backwards compatibility.  It is no longer
+	 * needed or required by the Persistent interface.  It will be removed in next BC-breaking
+	 * release of Propel.
+	 *
+	 * @deprecated
+	 */
+	 public function setPrimaryKey(\$pk)
+	 {
+		 // do nothing, because this object doesn't have any primary keys
+	 }
+";
+	}
+
+	// --------------------------------------------------------------------
+	// Complex OM Methods
+	// --------------------------------------------------------------------
+
+	/**
+	 * Convenience method to get the foreign Table object for an fkey.
+	 * @return     Table
+	 */
+	protected function getForeignTable(ForeignKey $fk)
+	{
+		return $this->getTable()->getDatabase()->getTable($fk->getForeignTableName());
+	}
+
+	/**
+	 * Gets the PHP method name affix to be used for fkeys for the current table (not referrers to this table).
+	 *
+	 * The difference between this method and the getRefFKPhpNameAffix() method is that in this method the
+	 * classname in the affix is the foreign table classname.
+	 *
+	 * @param      ForeignKey $fk The local FK that we need a name for.
+	 * @param      boolean $plural Whether the php name should be plural (e.g. initRelatedObjs() vs. addRelatedObj()
+	 * @return     string
+	 */
+	public function getFKPhpNameAffix(ForeignKey $fk, $plural = false)
+	{
+		if ($fk->getPhpName()) {
+			if ($plural) {
+				return $this->getPluralizer()->getPluralForm($fk->getPhpName());
+			} else {
+				return $fk->getPhpName();
+			}
+		} else {
+			$className = $this->getForeignTable($fk)->getPhpName();
+			if ($plural) {
+				$className = $this->getPluralizer()->getPluralForm($className);
+			}
+			return $className . $this->getRelatedBySuffix($fk, true);
+		}
+	}
+
+	/**
+	 * Gets the PHP method name affix to be used for referencing foreign key methods and variable names (e.g. set????(), $coll???).
+	 *
+	 * The difference between this method and the getFKPhpNameAffix() method is that in this method the
+	 * classname in the affix is the classname of the local fkey table.
+	 *
+	 * @param      ForeignKey $fk The referrer FK that we need a name for.
+	 * @param      boolean $plural Whether the php name should be plural (e.g. initRelatedObjs() vs. addRelatedObj()
+	 * @return     string
+	 */
+	public function getRefFKPhpNameAffix(ForeignKey $fk, $plural = false)
+	{
+		if ($fk->getRefPhpName()) {
+			if ($plural) {
+				return $this->getPluralizer()->getPluralForm($fk->getRefPhpName());
+			} else {
+				return $fk->getRefPhpName();
+			}
+		} else {
+			$className = $fk->getTable()->getPhpName();
+			if ($plural) {
+				$className = $this->getPluralizer()->getPluralForm($className);
+			}
+			return $className . $this->getRelatedBySuffix($fk);
+		}
+	}
+
+	/**
+	 * Gets the "RelatedBy*" suffix (if needed) that is attached to method and variable names.
+	 *
+	 * The related by suffix is based on the local columns of the foreign key.  If there is more than
+	 * one column in a table that points to the same foreign table, then a 'RelatedByLocalColName' suffix
+	 * will be appended.
+	 *
+	 * @return     string
+	 */
+	protected function getRelatedBySuffix(ForeignKey $fk, $columnCheck = false)
+	{
+		$relCol = "";
+		foreach ($fk->getLocalColumns() as $columnName) {
+			$column = $fk->getTable()->getColumn($columnName);
+			if (!$column) {
+				throw new Exception("Could not fetch column: $columnName in table " . $fk->getTable()->getName());
+			}
+
+			if ( count($column->getTable()->getForeignKeysReferencingTable($fk->getForeignTableName())) > 1
+			|| $fk->getForeignTableName() == $fk->getTable()->getName()) {
+				// if there are seeral foreign keys that point to the same table
+				// then we need to generate methods like getAuthorRelatedByColName()
+				// instead of just getAuthor().  Currently we are doing the same
+				// for self-referential foreign keys, to avoid confusion.
+				$relCol .= $column->getPhpName();
+			}
+		}
+
+		#var_dump($fk->getForeignTableName() . ' - ' .$fk->getTableName() . ' - ' . $this->getTable()->getName());
+
+		#$fk->getForeignTableName() != $this->getTable()->getName() &&
+		// @todo comment on it
+		if ($columnCheck && !$relCol && $fk->getTable()->getColumn($fk->getForeignTableName())) {
+			foreach ($fk->getLocalColumns() as $columnName) {
+				$column = $fk->getTable()->getColumn($columnName);
+				$relCol .= $column->getPhpName();
+			}
+		}
+
+
+		if ($relCol != "") {
+			$relCol = "RelatedBy" . $relCol;
+		}
+
+		return $relCol;
+	}
+
+	/**
+	 * Constructs variable name for fkey-related objects.
+	 * @param      ForeignKey $fk
+	 * @return     string
+	 */
+	protected function getFKVarName(ForeignKey $fk)
+	{
+		return 'a' . $this->getFKPhpNameAffix($fk, $plural = false);
+	}
+
+	/**
+	 * Constructs variable name for objects which referencing current table by specified foreign key.
+	 * @param      ForeignKey $fk
+	 * @return     string
+	 */
+	protected function getRefFKCollVarName(ForeignKey $fk)
+	{
+		return 'coll' . $this->getRefFKPhpNameAffix($fk, $plural = true);
+	}
+
+	/**
+	 * Constructs variable name for single object which references current table by specified foreign key
+	 * which is ALSO a primary key (hence one-to-one relationship).
+	 * @param      ForeignKey $fk
+	 * @return     string
+	 */
+	protected function getPKRefFKVarName(ForeignKey $fk)
+	{
+		return 'single' . $this->getRefFKPhpNameAffix($fk, $plural = false);
+	}
+
+	/**
+	 * Gets variable name for the Criteria which was used to fetch the objects which
+	 * referencing current table by specified foreign key.
+	 * @param      ForeignKey $fk
+	 * @return     string
+	 */
+	protected function getRefFKLastCriteriaVarName(ForeignKey $fk)
+	{
+		return 'last' . $this->getRefFKPhpNameAffix($fk, $plural = false) . 'Criteria';
+	}
+
+	// ----------------------------------------------------------------
+	//
+	// F K    M E T H O D S
+	//
+	// ----------------------------------------------------------------
+
+	/**
+	 * Adds the methods that get & set objects related by foreign key to the current object.
+	 * @param      string &$script The script will be modified in this method.
+	 */
+	protected function addFKMethods(&$script)
+	{
+		foreach ($this->getTable()->getForeignKeys() as $fk) {
+			$this->addFKMutator($script, $fk);
+			$this->addFKAccessor($script, $fk);
+		} // foreach fk
+	}
+
+	/**
+	 * Adds the class attributes that are needed to store fkey related objects.
+	 * @param      string &$script The script will be modified in this method.
+	 */
+	protected function addFKAttributes(&$script, ForeignKey $fk)
+	{
+		$className = $this->getForeignTable($fk)->getPhpName();
+		$varName = $this->getFKVarName($fk);
+
+		$script .= "
+	/**
+	 * @var        $className
+	 */
+	protected $".$varName.";
+";
+	}
+
+	/**
+	 * Adds the mutator (setter) method for setting an fkey related object.
+	 * @param      string &$script The script will be modified in this method.
+	 */
+	protected function addFKMutator(&$script, ForeignKey $fk)
+	{
+		$table = $this->getTable();
+		$tblFK = $this->getForeignTable($fk);
+
+		$joinTableObjectBuilder = $this->getNewObjectBuilder($tblFK);
+
+		$className = $joinTableObjectBuilder->getObjectClassname();
+		$varName = $this->getFKVarName($fk);
+
+		$script .= "
+	/**
+	 * Declares an association between this object and a $className object.
+	 *
+	 * @param      $className \$v
+	 * @return     ".$this->getObjectClassname()." The current object (for fluent API support)
+	 * @throws     PropelException
+	 */
+	public function set".$this->getFKPhpNameAffix($fk, $plural = false)."($className \$v = null)
+	{";
+		foreach ($fk->getLocalColumns() as $columnName) {
+			$column = $table->getColumn($columnName);
+			$lfmap = $fk->getLocalForeignMapping();
+			$colFKName = $lfmap[$columnName];
+			$colFK = $tblFK->getColumn($colFKName);
+			$script .= "
+		if (\$v === null) {
+			\$this->set".$column->getPhpName()."(".$this->getDefaultValueString($column).");
+		} else {
+			\$this->set".$column->getPhpName()."(\$v->get".$colFK->getPhpName()."());
+		}
+";
+
+		} /* foreach local col */
+
+		$script .= "
+		\$this->$varName = \$v;
+";
+
+		// Now add bi-directional relationship binding, taking into account whether this is
+		// a one-to-one relationship.
+
+		if ($fk->isLocalPrimaryKey()) {
+			$script .= "
+		// Add binding for other direction of this 1:1 relationship.
+		if (\$v !== null) {
+			\$v->set".$this->getRefFKPhpNameAffix($fk, $plural = false)."(\$this);
+		}
+";
+		} else {
+			$script .= "
+		// Add binding for other direction of this n:n relationship.
+		// If this object has already been added to the $className object, it will not be re-added.
+		if (\$v !== null) {
+			\$v->add".$this->getRefFKPhpNameAffix($fk, $plural = false)."(\$this);
+		}
+";
+
+		}
+
+		$script .= "
+		return \$this;
+	}
+";
+	}
+
+	/**
+	 * Adds the accessor (getter) method for getting an fkey related object.
+	 * @param      string &$script The script will be modified in this method.
+	 */
+	protected function addFKAccessor(&$script, ForeignKey $fk)
+	{
+		$table = $this->getTable();
+
+		$varName = $this->getFKVarName($fk);
+
+		$and = "";
+		$comma = "";
+		$conditional = "";
+		$arglist = "";
+		$argsize = 0;
+		foreach ($fk->getLocalColumns() as $columnName) {
+			$column = $table->getColumn($columnName);
+			$cptype = $column->getPhpType();
+			$clo = strtolower($column->getName());
+
+			// FIXME: is this correct? what about negative numbers?
+			if ($cptype == "integer" || $cptype == "float" || $cptype == "double") {
+				$conditional .= $and . "\$this->". $clo ." > 0";
+			} elseif ($cptype == "string") {
+				$conditional .= $and . "(\$this->" . $clo ." !== \"\" && \$this->".$clo." !== null)";
+			} else {
+				$conditional .= $and . "\$this->" . $clo ." !== null";
+			}
+			$arglist .= $comma . "\$this->" . $clo;
+			$and = " && ";
+			$comma = ", ";
+			$argsize = $argsize + 1;
+		}
+
+		$pCollName = $this->getFKPhpNameAffix($fk, $plural = true);
+
+		$fkPeerBuilder = $this->getNewPeerBuilder($this->getForeignTable($fk));
+		$fkObjectBuilder = $this->getNewObjectBuilder($this->getForeignTable($fk))->getStubObjectBuilder();
+		$className = $fkObjectBuilder->getClassname(); // get the Classname that has maybe a prefix
+
+		$script .= "
+
+	/**
+	 * Get the associated $className object
+	 *
+	 * @param      PropelPDO Optional Connection object.
+	 * @return     $className The associated $className object.
+	 * @throws     PropelException
+	 */
+	public function get".$this->getFKPhpNameAffix($fk, $plural = false)."(PropelPDO \$con = null)
+	{";
+		$script .= "
+		if (\$this->$varName === null && ($conditional)) {";
+		$script .= "
+			\$this->$varName = ".$fkPeerBuilder->getPeerClassname()."::".$fkPeerBuilder->getRetrieveMethodName()."($arglist, \$con);";
+		if ($fk->isLocalPrimaryKey()) {
+			$script .= "
+			// Because this foreign key represents a one-to-one relationship, we will create a bi-directional association.
+			\$this->{$varName}->set".$this->getRefFKPhpNameAffix($fk, $plural = false)."(\$this);";
+		} else {
+			$script .= "
+			/* The following can be used additionally to
+			   guarantee the related object contains a reference
+			   to this object.  This level of coupling may, however, be
+			   undesirable since it could result in an only partially populated collection
+			   in the referenced object.
+			   \$this->{$varName}->add".$this->getRefFKPhpNameAffix($fk, $plural = true)."(\$this);
+			 */";
+		}
+
+		$script .= "
+		}
+		return \$this->$varName;
+	}
+";
+
+	} // addFKAccessor
+
+	/**
+	 * Adds a convenience method for setting a related object by specifying the primary key.
+	 * This can be used in conjunction with the getPrimaryKey() for systems where nothing is known
+	 * about the actual objects being related.
+	 * @param      string &$script The script will be modified in this method.
+	 */
+	protected function addFKByKeyMutator(&$script, ForeignKey $fk)
+	{
+		$table = $this->getTable();
+
+		#$className = $this->getForeignTable($fk)->getPhpName();
+		$methodAffix = $this->getFKPhpNameAffix($fk);
+		#$varName = $this->getFKVarName($fk);
+
+		$script .= "
+	/**
+	 * Provides convenient way to set a relationship based on a
+	 * key.  e.g.
+	 * <code>\$bar->setFooKey(\$foo->getPrimaryKey())</code>
+	 *";
+		if (count($fk->getLocalColumns()) > 1) {
+			$script .= "
+	 * Note: It is important that the xml schema used to create this class
+	 * maintains consistency in the order of related columns between
+	 * ".$table->getName()." and ". $tblFK->getName().".
+	 * If for some reason this is impossible, this method should be
+	 * overridden in <code>".$table->getPhpName()."</code>.";
+		}
+		$script .= "
+	 * @return     ".$this->getObjectClassname()." The current object (for fluent API support)
+	 * @throws     PropelException
+	 */
+	public function set".$methodAffix."Key(\$key)
+	{
+";
+		if (count($fk->getLocalColumns()) > 1) {
+			$i = 0;
+			foreach ($fk->getLocalColumns() as $colName) {
+				$col = $table->getColumn($colName);
+				$fktype = $col->getPhpType();
+				$script .= "
+			\$this->set".$col->getPhpName()."( ($fktype) \$key[$i] );
+";
+				$i++;
+			} /* foreach */
+		} else {
+			$lcols = $fk->getLocalColumns();
+			$colName = $lcols[0];
+			$col = $table->getColumn($colName);
+			$fktype = $col->getPhpType();
+			$script .= "
+		\$this->set".$col->getPhpName()."( ($fktype) \$key);
+";
+		}
+		$script .= "
+		return \$this;
+	}
+";
+	} // addFKByKeyMutator()
+
+	/**
+	 * Adds the method that fetches fkey-related (referencing) objects but also joins in data from another table.
+	 * @param      string &$script The script will be modified in this method.
+	 */
+	protected function addRefFKGetJoinMethods(&$script, ForeignKey $refFK)
+	{
+		$table = $this->getTable();
+		$tblFK = $refFK->getTable();
+		$join_behavior = $this->getGeneratorConfig()->getBuildProperty('useLeftJoinsInDoJoinMethods') ? 'Criteria::LEFT_JOIN' : 'Criteria::INNER_JOIN';
+
+		$peerClassname = $this->getStubPeerBuilder()->getClassname();
+		$relCol = $this->getRefFKPhpNameAffix($refFK, $plural=true);
+		$collName = $this->getRefFKCollVarName($refFK);
+		$lastCriteriaName = $this->getRefFKLastCriteriaVarName($refFK);
+
+		$fkPeerBuilder = $this->getNewPeerBuilder($tblFK);
+
+		$lastTable = "";
+		foreach ($tblFK->getForeignKeys() as $fk2) {
+
+			$tblFK2 = $this->getForeignTable($fk2);
+			$doJoinGet = !$tblFK2->isForReferenceOnly();
+
+			// it doesn't make sense to join in rows from the curent table, since we are fetching
+			// objects related to *this* table (i.e. the joined rows will all be the same row as current object)
+			if ($this->getTable()->getPhpName() == $tblFK2->getPhpName()) {
+				$doJoinGet = false;
+			}
+
+			$relCol2 = $this->getFKPhpNameAffix($fk2, $plural = false);
+
+			if ( $this->getRelatedBySuffix($refFK) != "" &&
+			($this->getRelatedBySuffix($refFK) == $this->getRelatedBySuffix($fk2))) {
+				$doJoinGet = false;
+			}
+
+			if ($doJoinGet) {
+				$script .= "
+
+	/**
+	 * If this collection has already been initialized with
+	 * an identical criteria, it returns the collection.
+	 * Otherwise if this ".$table->getPhpName()." is new, it will return
+	 * an empty collection; or if this ".$table->getPhpName()." has previously
+	 * been saved, it will retrieve related $relCol from storage.
+	 *
+	 * This method is protected by default in order to keep the public
+	 * api reasonable.  You can provide public methods for those you
+	 * actually need in ".$table->getPhpName().".
+	 */
+	public function get".$relCol."Join".$relCol2."(\$criteria = null, \$con = null, \$join_behavior = $join_behavior)
+	{";
+				$script .= "
+		if (\$criteria === null) {
+			\$criteria = new Criteria($peerClassname::DATABASE_NAME);
+		}
+		elseif (\$criteria instanceof Criteria)
+		{
+			\$criteria = clone \$criteria;
+		}
+
+		if (\$this->$collName === null) {
+			if (\$this->isNew()) {
+				\$this->$collName = array();
+			} else {
+";
+				foreach ($refFK->getForeignColumns() as $columnName) {
+					$column = $table->getColumn($columnName);
+					$flMap = $refFK->getForeignLocalMapping();
+					$colFKName = $flMap[$columnName];
+					$colFK = $tblFK->getColumn($colFKName);
+					if ($colFK === null) {
+						throw new EngineException("Column $colFKName not found in " . $tblFK->getName());
+					}
+					$clo = strtolower($column->getName());
+					$script .= "
+				\$criteria->add(".$fkPeerBuilder->getColumnConstant($colFK).", \$this->$clo);
+";
+				} // end foreach ($fk->getForeignColumns()
+
+				$script .= "
+				\$this->$collName = ".$fkPeerBuilder->getPeerClassname()."::doSelectJoin$relCol2(\$criteria, \$con, \$join_behavior);
+			}
+		} else {
+			// the following code is to determine if a new query is
+			// called for.  If the criteria is the same as the last
+			// one, just return the collection.
+";
+				foreach ($refFK->getForeignColumns() as $columnName) {
+					$column = $table->getColumn($columnName);
+					$flMap = $refFK->getForeignLocalMapping();
+					$colFKName = $flMap[$columnName];
+					$colFK = $tblFK->getColumn($colFKName);
+					$clo = strtolower($column->getName());
+					$script .= "
+			\$criteria->add(".$fkPeerBuilder->getColumnConstant($colFK).", \$this->$clo);
+";
+				} /* end foreach ($fk->getForeignColumns() */
+
+				$script .= "
+			if (!isset(\$this->$lastCriteriaName) || !\$this->".$lastCriteriaName."->equals(\$criteria)) {
+				\$this->$collName = ".$fkPeerBuilder->getPeerClassname()."::doSelectJoin$relCol2(\$criteria, \$con, \$join_behavior);
+			}
+		}
+		\$this->$lastCriteriaName = \$criteria;
+
+		return \$this->$collName;
+	}
+";
+			} /* end if ($doJoinGet) */
+
+		} /* end foreach ($tblFK->getForeignKeys() as $fk2) { */
+
+	} // function
+
+
+	// ----------------------------------------------------------------
+	//
+	// R E F E R R E R    F K    M E T H O D S
+	//
+	// ----------------------------------------------------------------
+
+	/**
+	 * Adds the attributes used to store objects that have referrer fkey relationships to this object.
+	 * <code>protected collVarName;</code>
+	 * <code>private lastVarNameCriteria = null;</code>
+	 * @param      string &$script The script will be modified in this method.
+	 */
+	protected function addRefFKAttributes(&$script, ForeignKey $refFK)
+	{
+		$joinedTableObjectBuilder = $this->getNewObjectBuilder($refFK->getTable());
+		$className = $joinedTableObjectBuilder->getObjectClassname();
+
+		if ($refFK->isLocalPrimaryKey()) {
+			$script .= "
+	/**
+	 * @var        $className one-to-one related $className object
+	 */
+	protected $".$this->getPKRefFKVarName($refFK).";
+";
+		} else {
+			$script .= "
+	/**
+	 * @var        array {$className}[] Collection to store aggregation of $className objects.
+	 */
+	protected $".$this->getRefFKCollVarName($refFK).";
+
+	/**
+	 * @var        Criteria The criteria used to select the current contents of ".$this->getRefFKCollVarName($refFK).".
+	 */
+	private $".$this->getRefFKLastCriteriaVarName($refFK)." = null;
+";
+		}
+	}
+
+	/**
+	 * Adds the methods for retrieving, initializing, adding objects that are related to this one by foreign keys.
+	 * @param      string &$script The script will be modified in this method.
+	 */
+	protected function addRefFKMethods(&$script)
+	{
+		foreach ($this->getTable()->getReferrers() as $refFK) {
+			if ($refFK->isLocalPrimaryKey()) {
+				$this->addPKRefFKGet($script, $refFK);
+				$this->addPKRefFKSet($script, $refFK);
+			} else {
+				$this->addRefFKClear($script, $refFK);
+				$this->addRefFKInit($script, $refFK);
+				$this->addRefFKGet($script, $refFK);
+				$this->addRefFKCount($script, $refFK);
+				$this->addRefFKAdd($script, $refFK);
+				$this->addRefFKGetJoinMethods($script, $refFK);
+			}
+		}
+	}
+
+	/**
+	 * Adds the method that clears the referrer fkey collection.
+	 * @param      string &$script The script will be modified in this method.
+	 */
+	protected function addRefFKClear(&$script, ForeignKey $refFK) {
+
+		$relCol = $this->getRefFKPhpNameAffix($refFK, $plural = true);
+		$collName = $this->getRefFKCollVarName($refFK);
+
+		$script .= "
+	/**
+	 * Clears out the $collName collection (array).
+	 *
+	 * This does not modify the database; however, it will remove any associated objects, causing
+	 * them to be refetched by subsequent calls to accessor method.
+	 *
+	 * @return     void
+	 * @see        add$relCol()
+	 */
+	public function clear$relCol()
+	{
+		\$this->$collName = null; // important to set this to NULL since that means it is uninitialized
+	}
+";
+	} // addRefererClear()
+
+	/**
+	 * Adds the method that initializes the referrer fkey collection.
+	 * @param      string &$script The script will be modified in this method.
+	 */
+	protected function addRefFKInit(&$script, ForeignKey $refFK) {
+
+		$relCol = $this->getRefFKPhpNameAffix($refFK, $plural = true);
+		$collName = $this->getRefFKCollVarName($refFK);
+
+		$script .= "
+	/**
+	 * Initializes the $collName collection (array).
+	 *
+	 * By default this just sets the $collName collection to an empty array (like clear$collName());
+	 * however, you may wish to override this method in your stub class to provide setting appropriate
+	 * to your application -- for example, setting the initial array to the values stored in database.
+	 *
+	 * @return     void
+	 */
+	public function init$relCol()
+	{
+		\$this->$collName = array();
+	}
+";
+	} // addRefererInit()
+
+	/**
+	 * Adds the method that adds an object into the referrer fkey collection.
+	 * @param      string &$script The script will be modified in this method.
+	 */
+	protected function addRefFKAdd(&$script, ForeignKey $refFK)
+	{
+		$tblFK = $refFK->getTable();
+
+		$joinedTableObjectBuilder = $this->getNewObjectBuilder($refFK->getTable());
+		$className = $joinedTableObjectBuilder->getObjectClassname();
+
+		$collName = $this->getRefFKCollVarName($refFK);
+
+		$script .= "
+	/**
+	 * Method called to associate a $className object to this object
+	 * through the $className foreign key attribute.
+	 *
+	 * @param      $className \$l $className
+	 * @return     void
+	 * @throws     PropelException
+	 */
+	public function add".$this->getRefFKPhpNameAffix($refFK, $plural = false)."($className \$l)
+	{
+		if (\$this->$collName === null) {
+			\$this->init".$this->getRefFKPhpNameAffix($refFK, $plural = true)."();
+		}
+		if (!in_array(\$l, \$this->$collName, true)) { // only add it if the **same** object is not already associated
+			array_push(\$this->$collName, \$l);
+			\$l->set".$this->getFKPhpNameAffix($refFK, $plural = false)."(\$this);
+		}
+	}
+";
+	} // addRefererAdd
+
+	/**
+	 * Adds the method that returns the size of the referrer fkey collection.
+	 * @param      string &$script The script will be modified in this method.
+	 */
+	protected function addRefFKCount(&$script, ForeignKey $refFK)
+	{
+		$table = $this->getTable();
+		$tblFK = $refFK->getTable();
+
+		$peerClassname = $this->getStubPeerBuilder()->getClassname();
+
+		$fkPeerBuilder = $this->getNewPeerBuilder($refFK->getTable());
+		$relCol = $this->getRefFKPhpNameAffix($refFK, $plural = true);
+
+		$collName = $this->getRefFKCollVarName($refFK);
+		$lastCriteriaName = $this->getRefFKLastCriteriaVarName($refFK);
+
+		$className = $fkPeerBuilder->getObjectClassname();
+
+		$script .= "
+	/**
+	 * Returns the number of related $className objects.
+	 *
+	 * @param      Criteria \$criteria
+	 * @param      boolean \$distinct
+	 * @param      PropelPDO \$con
+	 * @return     int Count of related $className objects.
+	 * @throws     PropelException
+	 */
+	public function count$relCol(Criteria \$criteria = null, \$distinct = false, PropelPDO \$con = null)
+	{";
+
+		$script .= "
+		if (\$criteria === null) {
+			\$criteria = new Criteria($peerClassname::DATABASE_NAME);
+		} else {
+			\$criteria = clone \$criteria;
+		}
+
+		if (\$distinct) {
+			\$criteria->setDistinct();
+		}
+
+		\$count = null;
+
+		if (\$this->$collName === null) {
+			if (\$this->isNew()) {
+				\$count = 0;
+			} else {
+";
+		foreach ($refFK->getLocalColumns() as $colFKName) {
+			// $colFKName is local to the referring table (i.e. foreign to this table)
+			$lfmap = $refFK->getLocalForeignMapping();
+			$localColumn = $this->getTable()->getColumn($lfmap[$colFKName]);
+			$colFK = $refFK->getTable()->getColumn($colFKName);
+			$clo = strtolower($localColumn->getName());
+			$script .= "
+				\$criteria->add(".$fkPeerBuilder->getColumnConstant($colFK).", \$this->$clo);
+";
+		} // end foreach ($fk->getForeignColumns()
+
+		$script .= "
+				\$count = ".$fkPeerBuilder->getPeerClassname()."::doCount(\$criteria, \$con);
+			}
+		} else {
+			// criteria has no effect for a new object
+			if (!\$this->isNew()) {
+				// the following code is to determine if a new query is
+				// called for.  If the criteria is the same as the last
+				// one, just return count of the collection.
+";
+		foreach ($refFK->getLocalColumns() as $colFKName) {
+			// $colFKName is local to the referring table (i.e. foreign to this table)
+			$lfmap = $refFK->getLocalForeignMapping();
+			$localColumn = $this->getTable()->getColumn($lfmap[$colFKName]);
+			$colFK = $refFK->getTable()->getColumn($colFKName);
+			$clo = strtolower($localColumn->getName());
+			$script .= "
+
+				\$criteria->add(".$fkPeerBuilder->getColumnConstant($colFK).", \$this->$clo);
+";
+		} // foreach ($fk->getForeignColumns()
+		$script .= "
+				if (!isset(\$this->$lastCriteriaName) || !\$this->".$lastCriteriaName."->equals(\$criteria)) {
+					\$count = ".$fkPeerBuilder->getPeerClassname()."::doCount(\$criteria, \$con);
+				} else {
+					\$count = count(\$this->$collName);
+				}
+			} else {
+				\$count = count(\$this->$collName);
+			}
+		}
+		\$this->$lastCriteriaName = \$criteria;
+		return \$count;
+	}
+";
+	} // addRefererCount
+
+	/**
+	 * Adds the method that returns the referrer fkey collection.
+	 * @param      string &$script The script will be modified in this method.
+	 */
+	protected function addRefFKGet(&$script, ForeignKey $refFK)
+	{
+		$table = $this->getTable();
+		$tblFK = $refFK->getTable();
+
+		$peerClassname = $this->getStubPeerBuilder()->getClassname();
+		$fkPeerBuilder = $this->getNewPeerBuilder($refFK->getTable());
+		$relCol = $this->getRefFKPhpNameAffix($refFK, $plural = true);
+
+		$collName = $this->getRefFKCollVarName($refFK);
+		$lastCriteriaName = $this->getRefFKLastCriteriaVarName($refFK);
+
+		$className = $fkPeerBuilder->getObjectClassname();
+
+		$script .= "
+	/**
+	 * Gets an array of $className objects which contain a foreign key that references this object.
+	 *
+	 * If this collection has already been initialized with an identical Criteria, it returns the collection.
+	 * Otherwise if this ".$this->getObjectClassname()." has previously been saved, it will retrieve
+	 * related $relCol from storage. If this ".$this->getObjectClassname()." is new, it will return
+	 * an empty collection or the current collection, the criteria is ignored on a new object.
+	 *
+	 * @param      PropelPDO \$con
+	 * @param      Criteria \$criteria
+	 * @return     array {$className}[]
+	 * @throws     PropelException
+	 */
+	public function get$relCol(\$criteria = null, PropelPDO \$con = null)
+	{";
+
+		$script .= "
+		if (\$criteria === null) {
+			\$criteria = new Criteria($peerClassname::DATABASE_NAME);
+		}
+		elseif (\$criteria instanceof Criteria)
+		{
+			\$criteria = clone \$criteria;
+		}
+
+		if (\$this->$collName === null) {
+			if (\$this->isNew()) {
+			   \$this->$collName = array();
+			} else {
+";
+		foreach ($refFK->getLocalColumns() as $colFKName) {
+			// $colFKName is local to the referring table (i.e. foreign to this table)
+			$lfmap = $refFK->getLocalForeignMapping();
+			$localColumn = $this->getTable()->getColumn($lfmap[$colFKName]);
+			$colFK = $refFK->getTable()->getColumn($colFKName);
+
+			$clo = strtolower($localColumn->getName());
+
+			$script .= "
+				\$criteria->add(".$fkPeerBuilder->getColumnConstant($colFK).", \$this->$clo);
+";
+		} // end foreach ($fk->getForeignColumns()
+
+		$script .= "
+				".$fkPeerBuilder->getPeerClassname()."::addSelectColumns(\$criteria);
+				\$this->$collName = ".$fkPeerBuilder->getPeerClassname()."::doSelect(\$criteria, \$con);
+			}
+		} else {
+			// criteria has no effect for a new object
+			if (!\$this->isNew()) {
+				// the following code is to determine if a new query is
+				// called for.  If the criteria is the same as the last
+				// one, just return the collection.
+";
+		foreach ($refFK->getLocalColumns() as $colFKName) {
+			// $colFKName is local to the referring table (i.e. foreign to this table)
+			$lfmap = $refFK->getLocalForeignMapping();
+			$localColumn = $this->getTable()->getColumn($lfmap[$colFKName]);
+			$colFK = $refFK->getTable()->getColumn($colFKName);
+			$clo = strtolower($localColumn->getName());
+			$script .= "
+
+				\$criteria->add(".$fkPeerBuilder->getColumnConstant($colFK).", \$this->$clo);
+";
+		} // foreach ($fk->getForeignColumns()
+		$script .= "
+				".$fkPeerBuilder->getPeerClassname()."::addSelectColumns(\$criteria);
+				if (!isset(\$this->$lastCriteriaName) || !\$this->".$lastCriteriaName."->equals(\$criteria)) {
+					\$this->$collName = ".$fkPeerBuilder->getPeerClassname()."::doSelect(\$criteria, \$con);
+				}
+			}
+		}
+		\$this->$lastCriteriaName = \$criteria;
+		return \$this->$collName;
+	}
+";
+	} // addRefererGet()
+
+	/**
+	 * Adds the method that gets a one-to-one related referrer fkey.
+	 * This is for one-to-one relationship special case.
+	 * @param      string &$script The script will be modified in this method.
+	 */
+	protected function addPKRefFKGet(&$script, ForeignKey $refFK)
+	{
+		$table = $this->getTable();
+		$tblFK = $refFK->getTable();
+
+		$joinedTableObjectBuilder = $this->getNewObjectBuilder($refFK->getTable());
+		$joinedTablePeerBuilder = $this->getNewObjectBuilder($refFK->getTable());
+		$className = $joinedTableObjectBuilder->getObjectClassname();
+
+		$varName = $this->getPKRefFKVarName($refFK);
+
+		$script .= "
+	/**
+	 * Gets a single $className object, which is related to this object by a one-to-one relationship.
+	 *
+	 * @param      PropelPDO \$con
+	 * @return     $className
+	 * @throws     PropelException
+	 */
+	public function get".$this->getRefFKPhpNameAffix($refFK, $plural = false)."(PropelPDO \$con = null)
+	{
+";
+		$script .= "
+		if (\$this->$varName === null && !\$this->isNew()) {";
+
+		$lfmap = $refFK->getLocalForeignMapping();
+
+		// remember: this object represents the foreign table,
+		// so we need foreign columns of the reffk to know the local columns
+		// that we need to set :)
+
+		$localcols = $refFK->getForeignColumns();
+
+		// we know that at least every column in the primary key of the foreign table
+		// is represented in this foreign key
+
+		$params = array();
+		foreach ($tblFK->getPrimaryKey() as $col) {
+			$localColumn = $table->getColumn($lfmap[$col->getName()]);
+			$clo = strtolower($localColumn->getName());
+			$params[] = "\$this->$clo";
+		}
+
+		$script .= "
+			\$this->$varName = ".$joinedTableObjectBuilder->getPeerClassname()."::retrieveByPK(".implode(", ", $params).", \$con);
+		}
+
+		return \$this->$varName;
+	}
+";
+	} // addPKRefFKGet()
+
+	/**
+	 * Adds the method that sets a one-to-one related referrer fkey.
+	 * This is for one-to-one relationships special case.
+	 * @param      string &$script The script will be modified in this method.
+	 * @param      ForeignKey $refFK The referencing foreign key.
+	 */
+	protected function addPKRefFKSet(&$script, ForeignKey $refFK)
+	{
+		$tblFK = $refFK->getTable();
+
+		$joinedTableObjectBuilder = $this->getNewObjectBuilder($refFK->getTable());
+		$className = $joinedTableObjectBuilder->getObjectClassname();
+
+		$varName = $this->getPKRefFKVarName($refFK);
+
+		$script .= "
+	/**
+	 * Sets a single $className object as related to this object by a one-to-one relationship.
+	 *
+	 * @param      $className \$l $className
+	 * @return     ".$this->getObjectClassname()." The current object (for fluent API support)
+	 * @throws     PropelException
+	 */
+	public function set".$this->getRefFKPhpNameAffix($refFK, $plural = false)."($className \$v)
+	{
+		\$this->$varName = \$v;
+
+		// Make sure that that the passed-in $className isn't already associated with this object
+		if (\$v->get".$this->getFKPhpNameAffix($refFK, $plural = false)."() === null) {
+			\$v->set".$this->getFKPhpNameAffix($refFK, $plural = false)."(\$this);
+		}
+
+		return \$this;
+	}
+";
+	} // addPKRefFKSet
+
+	// ----------------------------------------------------------------
+	//
+	// M A N I P U L A T I O N    M E T H O D S
+	//
+	// ----------------------------------------------------------------
+
+	/**
+	 * Adds the workhourse doSave() method.
+	 * @param      string &$script The script will be modified in this method.
+	 */
+	protected function addDoSave(&$script)
+	{
+		$table = $this->getTable();
+
+		$reloadOnUpdate = $table->isReloadOnUpdate();
+		$reloadOnInsert = $table->isReloadOnInsert();
+
+		$script .= "
+	/**
+	 * Performs the work of inserting or updating the row in the database.
+	 *
+	 * If the object is new, it inserts it; otherwise an update is performed.
+	 * All related objects are also updated in this method.
+	 *
+	 * @param      PropelPDO \$con";
+		if ($reloadOnUpdate || $reloadOnInsert) {
+			$script .= "
+	 * @param      boolean \$skipReload Whether to skip the reload for this object from database.";
+		}
+		$script .= "
+	 * @return     int The number of rows affected by this insert/update and any referring fk objects' save() operations.
+	 * @throws     PropelException
+	 * @see        save()
+	 */
+	protected function doSave(PropelPDO \$con".($reloadOnUpdate || $reloadOnInsert ? ", \$skipReload = false" : "").")
+	{
+		\$affectedRows = 0; // initialize var to track total num of affected rows
+		if (!\$this->alreadyInSave) {
+			\$this->alreadyInSave = true;
+";
+		if ($reloadOnInsert || $reloadOnUpdate) {
+			$script .= "
+			\$reloadObject = false;
+";
+		}
+
+		if (count($table->getForeignKeys())) {
+
+			$script .= "
+			// We call the save method on the following object(s) if they
+			// were passed to this object by their coresponding set
+			// method.  This object relates to these object(s) by a
+			// foreign key reference.
+";
+
+			foreach ($table->getForeignKeys() as $fk)
+			{
+				$aVarName = $this->getFKVarName($fk);
+				$script .= "
+			if (\$this->$aVarName !== null) {
+				if (\$this->".$aVarName."->isModified() || \$this->".$aVarName."->isNew()) {
+					\$affectedRows += \$this->".$aVarName."->save(\$con);
+				}
+				\$this->set".$this->getFKPhpNameAffix($fk, $plural = false)."(\$this->$aVarName);
+			}
+";
+			} // foreach foreign k
+		} // if (count(foreign keys))
+		
+		if ($table->hasAutoIncrementPrimaryKey() ) {
+		$script .= "
+			if (\$this->isNew() ) {
+				\$this->modifiedColumns[] = " . $this->getColumnConstant($table->getAutoIncrementPrimaryKey() ) . ";
+			}";
+		}
+
+		$script .= "
+
+			// If this object has been modified, then save it to the database.
+			if (\$this->isModified()";
+
+		$script .= ") {
+				if (\$this->isNew()) {
+					\$pk = ".$this->getPeerClassname()."::doInsert(\$this, \$con);";
+		if ($reloadOnInsert) {
+			$script .= "
+					if (!\$skipReload) {
+						\$reloadObject = true;
+					}";
+		}
+		$script .= "
+					\$affectedRows += 1; // we are assuming that there is only 1 row per doInsert() which
+										 // should always be true here (even though technically
+										 // BasePeer::doInsert() can insert multiple rows).
+";
+		if ($table->getIdMethod() != IDMethod::NO_ID_METHOD) {
+
+			if (count($pks = $table->getPrimaryKey())) {
+				foreach ($pks as $pk) {
+					if ($pk->isAutoIncrement()) {
+						$script .= "
+					\$this->set".$pk->getPhpName()."(\$pk);  //[IMV] update autoincrement primary key
+";
+					}
+				}
+			}
+		} // if (id method != "none")
+
+		$script .= "
+					\$this->setNew(false);
+				} else {";
+		if ($reloadOnUpdate) {
+			$script .= "
+					if (!\$skipReload) {
+						\$reloadObject = true;
+					}";
+		}
+		$script .= "
+					\$affectedRows += ".$this->getPeerClassname()."::doUpdate(\$this, \$con);
+				}
+";
+
+		// We need to rewind any LOB columns
+		foreach ($table->getColumns() as $col) {
+			$clo = strtolower($col->getName());
+			if ($col->isLobType()) {
+				$script .= "
+				// Rewind the $clo LOB column, since PDO does not rewind after inserting value.
+				if (\$this->$clo !== null && is_resource(\$this->$clo)) {
+					rewind(\$this->$clo);
+				}
+";
+			}
+		}
+
+		$script .= "
+				\$this->resetModified(); // [HL] After being saved an object is no longer 'modified'
+			}
+";
+
+		foreach ($table->getReferrers() as $refFK) {
+
+			if ($refFK->isLocalPrimaryKey()) {
+				$varName = $this->getPKRefFKVarName($refFK);
+				$script .= "
+			if (\$this->$varName !== null) {
+				if (!\$this->{$varName}->isDeleted()) {
+						\$affectedRows += \$this->{$varName}->save(\$con);
+				}
+			}
+";
+			} else {
+				$collName = $this->getRefFKCollVarName($refFK);
+				$script .= "
+			if (\$this->$collName !== null) {
+				foreach (\$this->$collName as \$referrerFK) {
+					if (!\$referrerFK->isDeleted()) {
+						\$affectedRows += \$referrerFK->save(\$con);
+					}
+				}
+			}
+";
+			} // if refFK->isLocalPrimaryKey()
+
+		} /* foreach getReferrers() */
+		$script .= "
+			\$this->alreadyInSave = false;
+";
+		if ($reloadOnInsert || $reloadOnUpdate) {
+			$script .= "
+			if (\$reloadObject) {
+				\$this->reload(\$con);
+			}
+";
+		}
+		$script .= "
+		}
+		return \$affectedRows;
+	} // doSave()
+";
+
+	}
+
+	/**
+	 * Adds the $alreadyInSave attribute, which prevents attempting to re-save the same object.
+	 * @param      string &$script The script will be modified in this method.
+	 */
+	protected function addAlreadyInSaveAttribute(&$script)
+	{
+		$script .= "
+	/**
+	 * Flag to prevent endless save loop, if this object is referenced
+	 * by another object which falls in this transaction.
+	 * @var        boolean
+	 */
+	protected \$alreadyInSave = false;
+";
+	}
+
+	/**
+	 * Adds the save() method.
+	 * @param      string &$script The script will be modified in this method.
+	 */
+	protected function addSave(&$script)
+	{
+		$this->addSaveComment($script);
+		$this->addSaveOpen($script);
+		$this->addSaveBody($script);
+		$this->addSaveClose($script);
+	}
+
+	/**
+	 * Adds the comment for the save method
+	 * @param      string &$script The script will be modified in this method.
+	 * @see        addSave()
+	 **/
+	protected function addSaveComment(&$script) {
+		$table = $this->getTable();
+		$reloadOnUpdate = $table->isReloadOnUpdate();
+		$reloadOnInsert = $table->isReloadOnInsert();
+
+		$script .= "
+	/**
+	 * Persists this object to the database.
+	 *
+	 * If the object is new, it inserts it; otherwise an update is performed.
+	 * All modified related objects will also be persisted in the doSave()
+	 * method.  This method wraps all precipitate database operations in a
+	 * single transaction.";
+		if ($reloadOnUpdate) {
+			$script .= "
+	 *
+	 * Since this table was configured to reload rows on update, the object will
+	 * be reloaded from the database if an UPDATE operation is performed (unless
+	 * the \$skipReload parameter is TRUE).";
+		}
+		if ($reloadOnInsert) {
+			$script .= "
+	 *
+	 * Since this table was configured to reload rows on insert, the object will
+	 * be reloaded from the database if an INSERT operation is performed (unless
+	 * the \$skipReload parameter is TRUE).";
+		}
+		$script .= "
+	 *
+	 * @param      PropelPDO \$con";
+		if ($reloadOnUpdate || $reloadOnInsert) {
+			$script .= "
+	 * @param      boolean \$skipReload Whether to skip the reload for this object from database.";
+		}
+		$script .= "
+	 * @return     int The number of rows affected by this insert/update and any referring fk objects' save() operations.
+	 * @throws     PropelException
+	 * @see        doSave()
+	 */";
+	}
+
+	/**
+	 * Adds the function declaration for the save method
+	 * @param      string &$script The script will be modified in this method.
+	 * @see        addSave()
+	 **/
+	protected function addSaveOpen(&$script) {
+		$table = $this->getTable();
+		$reloadOnUpdate = $table->isReloadOnUpdate();
+		$reloadOnInsert = $table->isReloadOnInsert();
+		$script .= "
+	public function save(PropelPDO \$con = null".($reloadOnUpdate || $reloadOnInsert ? ", \$skipReload = false" : "").")
+	{";
+	}
+
+	/**
+	 * Adds the function body for the save method
+	 * @param      string &$script The script will be modified in this method.
+	 * @see        addSave()
+	 **/
+	protected function addSaveBody(&$script) {
+		$table = $this->getTable();
+		$reloadOnUpdate = $table->isReloadOnUpdate();
+		$reloadOnInsert = $table->isReloadOnInsert();
+
+		$script .= "
+		if (\$this->isDeleted()) {
+			throw new PropelException(\"You cannot save an object that has been deleted.\");
+		}
+
+		if (\$con === null) {
+			\$con = Propel::getConnection(".$this->getPeerClassname()."::DATABASE_NAME, Propel::CONNECTION_WRITE);
+		}
+		
+		\$con->beginTransaction();
+		try {
+			\$affectedRows = \$this->doSave(\$con".($reloadOnUpdate || $reloadOnInsert ? ", \$skipReload" : "").");
+			\$con->commit();
+			".$this->getPeerClassname()."::addInstanceToPool(\$this);
+			return \$affectedRows;
+		} catch (PropelException \$e) {
+			\$con->rollBack();
+			throw \$e;
+		}";
+	}
+
+	/**
+	 * Adds the function close for the save method
+	 * @param      string &$script The script will be modified in this method.
+	 * @see        addSave()
+	 **/
+	protected function addSaveClose(&$script) {
+		$script .= "
+	}
+";
+	}
+
+	/**
+	 * Adds the $alreadyInValidation attribute, which prevents attempting to re-validate the same object.
+	 * @param      string &$script The script will be modified in this method.
+	 */
+	protected function addAlreadyInValidationAttribute(&$script)
+	{
+		$script .= "
+	/**
+	 * Flag to prevent endless validation loop, if this object is referenced
+	 * by another object which falls in this transaction.
+	 * @var        boolean
+	 */
+	protected \$alreadyInValidation = false;
+";
+	}
+
+	/**
+	 * Adds the validate() method.
+	 * @param      string &$script The script will be modified in this method.
+	 */
+	protected function addValidate(&$script)
+	{
+		$script .= "
+	/**
+	 * Validates the objects modified field values and all objects related to this table.
+	 *
+	 * If \$columns is either a column name or an array of column names
+	 * only those columns are validated.
+	 *
+	 * @param      mixed \$columns Column name or an array of column names.
+	 * @return     boolean Whether all columns pass validation.
+	 * @see        doValidate()
+	 * @see        getValidationFailures()
+	 */
+	public function validate(\$columns = null)
+	{
+		\$res = \$this->doValidate(\$columns);
+		if (\$res === true) {
+			\$this->validationFailures = array();
+			return true;
+		} else {
+			\$this->validationFailures = \$res;
+			return false;
+		}
+	}
+";
+	} // addValidate()
+
+	/**
+	 * Adds the workhourse doValidate() method.
+	 * @param      string &$script The script will be modified in this method.
+	 */
+	protected function addDoValidate(&$script)
+	{
+		$table = $this->getTable();
+
+		$script .= "
+	/**
+	 * This function performs the validation work for complex object models.
+	 *
+	 * In addition to checking the current object, all related objects will
+	 * also be validated.  If all pass then <code>true</code> is returned; otherwise
+	 * an aggreagated array of ValidationFailed objects will be returned.
+	 *
+	 * @param      array \$columns Array of column names to validate.
+	 * @return     mixed <code>true</code> if all validations pass; array of <code>ValidationFailed</code> objets otherwise.
+	 */
+	protected function doValidate(\$columns = null)
+	{
+		if (!\$this->alreadyInValidation) {
+			\$this->alreadyInValidation = true;
+			\$retval = null;
+
+			\$failureMap = array();
+";
+		if (count($table->getForeignKeys()) != 0) {
+			$script .= "
+
+			// We call the validate method on the following object(s) if they
+			// were passed to this object by their coresponding set
+			// method.  This object relates to these object(s) by a
+			// foreign key reference.
+";
+			foreach ($table->getForeignKeys() as $fk) {
+				$aVarName = $this->getFKVarName($fk);
+				$script .= "
+			if (\$this->".$aVarName." !== null) {
+				if (!\$this->".$aVarName."->validate(\$columns)) {
+					\$failureMap = array_merge(\$failureMap, \$this->".$aVarName."->getValidationFailures());
+				}
+			}
+";
+			} /* for () */
+		} /* if count(fkeys) */
+
+		$script .= "
+
+			if ((\$retval = ".$this->getPeerClassname()."::doValidate(\$this, \$columns)) !== true) {
+				\$failureMap = array_merge(\$failureMap, \$retval);
+			}
+
+";
+
+		foreach ($table->getReferrers() as $refFK) {
+			if ($refFK->isLocalPrimaryKey()) {
+				$varName = $this->getPKRefFKVarName($refFK);
+				$script .= "
+				if (\$this->$varName !== null) {
+					if (!\$this->".$varName."->validate(\$columns)) {
+						\$failureMap = array_merge(\$failureMap, \$this->".$varName."->getValidationFailures());
+					}
+				}
+";
+			} else {
+				$collName = $this->getRefFKCollVarName($refFK);
+				$script .= "
+				if (\$this->$collName !== null) {
+					foreach (\$this->$collName as \$referrerFK) {
+						if (!\$referrerFK->validate(\$columns)) {
+							\$failureMap = array_merge(\$failureMap, \$referrerFK->getValidationFailures());
+						}
+					}
+				}
+";
+			}
+		} /* foreach getReferrers() */
+
+		$script .= "
+
+			\$this->alreadyInValidation = false;
+		}
+
+		return (!empty(\$failureMap) ? \$failureMap : true);
+	}
+";
+	} // addDoValidate()
+
+	/**
+	 * Adds the ensureConsistency() method to ensure that internal state is correct.
+	 * @param      string &$script The script will be modified in this method.
+	 */
+	protected function addEnsureConsistency(&$script)
+	{
+		$table = $this->getTable();
+
+		$script .= "
+	/**
+	 * Checks and repairs the internal consistency of the object.
+	 *
+	 * This method is executed after an already-instantiated object is re-hydrated
+	 * from the database.  It exists to check any foreign keys to make sure that
+	 * the objects related to the current object are correct based on foreign key.
+	 *
+	 * You can override this method in the stub class, but you should always invoke
+	 * the base method from the overridden method (i.e. parent::ensureConsistency()),
+	 * in case your model changes.
+	 *
+	 * @throws     PropelException
+	 */
+	public function ensureConsistency()
+	{
+";
+		foreach ($table->getColumns() as $col) {
+
+			$clo=strtolower($col->getName());
+
+			if ($col->isForeignKey()) {
+				foreach ($col->getForeignKeys() as $fk) {
+
+					$tblFK = $table->getDatabase()->getTable($fk->getForeignTableName());
+					$colFK = $tblFK->getColumn($fk->getMappedForeignColumn($col->getName()));
+					$varName = $this->getFKVarName($fk);
+
+					$script .= "
+		if (\$this->".$varName." !== null && \$this->$clo !== \$this->".$varName."->get".$colFK->getPhpName()."()) {
+			\$this->$varName = null;
+		}";
+				} // foraech
+			} /* if col is foreign key */
+
+		} // foreach
+
+		$script .= "
+	} // ensureConsistency
+";
+	} // addCheckRelConsistency
+
+	/**
+	 * Adds the copy() method, which (in complex OM) includes the $deepCopy param for making copies of related objects.
+	 * @param      string &$script The script will be modified in this method.
+	 */
+	protected function addCopy(&$script)
+	{
+		$this->addCopyInto($script);
+
+		$table = $this->getTable();
+
+		$script .= "
+	/**
+	 * Makes a copy of this object that will be inserted as a new row in table when saved.
+	 * It creates a new object filling in the simple attributes, but skipping any primary
+	 * keys that are defined for the table.
+	 *
+	 * If desired, this method can also make copies of all associated (fkey referrers)
+	 * objects.
+	 *
+	 * @param      boolean \$deepCopy Whether to also copy all rows that refer (by fkey) to the current row.
+	 * @return     ".$this->getObjectClassname()." Clone of current object.
+	 * @throws     PropelException
+	 */
+	public function copy(\$deepCopy = false)
+	{
+		// we use get_class(), because this might be a subclass
+		\$clazz = get_class(\$this);
+		" . $this->buildObjectInstanceCreationCode('$copyObj', '$clazz') . "
+		\$this->copyInto(\$copyObj, \$deepCopy);
+		return \$copyObj;
+	}
+";
+	} // addCopy()
+
+	/**
+	 * Adds the copyInto() method, which takes an object and sets contents to match current object.
+	 * In complex OM this method includes the $deepCopy param for making copies of related objects.
+	 * @param      string &$script The script will be modified in this method.
+	 */
+	protected function addCopyInto(&$script)
+	{
+		$table = $this->getTable();
+
+		$script .= "
+	/**
+	 * Sets contents of passed object to values from current object.
+	 *
+	 * If desired, this method can also make copies of all associated (fkey referrers)
+	 * objects.
+	 *
+	 * @param      object \$copyObj An object of ".$this->getObjectClassname()." (or compatible) type.
+	 * @param      boolean \$deepCopy Whether to also copy all rows that refer (by fkey) to the current row.
+	 * @throws     PropelException
+	 */
+	public function copyInto(\$copyObj, \$deepCopy = false)
+	{
+";
+
+		$autoIncCols = array();
+		foreach ($table->getColumns() as $col) {
+			/* @var        $col Column */
+			if ($col->isAutoIncrement()) {
+				$autoIncCols[] = $col;
+			}
+		}
+
+		foreach ($table->getColumns() as $col) {
+			if (!in_array($col, $autoIncCols, true)) {
+				$script .= "
+		\$copyObj->set".$col->getPhpName()."(\$this->".strtolower($col->getName()).");
+";
+			}
+		} // foreach
+
+		// Avoid useless code by checking to see if there are any referrers
+		// to this table:
+		if (count($table->getReferrers()) > 0) {
+			$script .= "
+
+		if (\$deepCopy) {
+			// important: temporarily setNew(false) because this affects the behavior of
+			// the getter/setter methods for fkey referrer objects.
+			\$copyObj->setNew(false);
+";
+			foreach ($table->getReferrers() as $fk) {
+				//HL: commenting out self-referrential check below
+				//		it seems to work as expected and is probably desireable to have those referrers from same table deep-copied.
+				//if ( $fk->getTable()->getName() != $table->getName() ) {
+
+				if ($fk->isLocalPrimaryKey()) {
+
+					$afx = $this->getRefFKPhpNameAffix($fk, $plural = false);
+					$script .= "
+			\$relObj = \$this->get$afx();
+			if (\$relObj) {
+				\$copyObj->set$afx(\$relObj->copy(\$deepCopy));
+			}
+";
+				} else {
+
+					$script .= "
+			foreach (\$this->get".$this->getRefFKPhpNameAffix($fk, true)."() as \$relObj) {
+				if (\$relObj !== \$this) {  // ensure that we don't try to copy a reference to ourselves
+					\$copyObj->add".$this->getRefFKPhpNameAffix($fk)."(\$relObj->copy(\$deepCopy));
+				}
+			}
+";
+				}
+				// HL: commenting out close of self-referential check
+				// } /* if tblFK != table */
+			} /* foreach */
+			$script .= "
+		} // if (\$deepCopy)
+";
+		} /* if (count referrers > 0 ) */
+
+		$script .= "
+
+		\$copyObj->setNew(true);
+";
+
+		// Note: we're no longer resetting non-autoincrement primary keys to default values
+		// due to: http://propel.phpdb.org/trac/ticket/618
+		foreach ($autoIncCols as $col) {
+				$coldefval = $col->getPhpDefaultValue();
+				$coldefval = var_export($coldefval, true);
+				$script .= "
+		\$copyObj->set".$col->getPhpName() ."($coldefval); // this is a auto-increment column, so set to default value
+";
+		} // foreach
+		$script .= "
+	}
+";
+	} // addCopyInto()
+
+
+	/**
+	 * Adds clearAllReferencers() method which resets all the collections of referencing
+	 * fk objects.
+	 * @param      string &$script The script will be modified in this method.
+	 */
+	protected function addClearAllReferences(&$script)
+	{
+		$table = $this->getTable();
+		$script .= "
+	/**
+	 * Resets all collections of referencing foreign keys.
+	 *
+	 * This method is a user-space workaround for PHP's inability to garbage collect objects
+	 * with circular references.  This is currently necessary when using Propel in certain
+	 * daemon or large-volumne/high-memory operations.
+	 *
+	 * @param      boolean \$deep Whether to also clear the references on all associated objects.
+	 */
+	public function clearAllReferences(\$deep = false)
+	{
+		if (\$deep) {";
+		$vars = array();
+		foreach ($this->getTable()->getReferrers() as $refFK) {
+			if ($refFK->isLocalPrimaryKey()) {
+				$varName = $this->getPKRefFKVarName($refFK);
+				$vars[] = $varName;
+				$script .= "
+			if (\$this->$varName) {
+				\$this->{$varName}->clearAllReferences(\$deep);
+			}";
+			} else {
+				$varName = $this->getRefFKCollVarName($refFK);
+				$vars[] = $varName;
+				$script .= "
+			if (\$this->$varName) {
+				foreach ((array) \$this->$varName as \$o) {
+					\$o->clearAllReferences(\$deep);
+				}
+			}";
+			}
+		}
+
+		$script .= "
+		} // if (\$deep)
+";
+
+		foreach ($vars as $varName) {
+			$script .= "
+		\$this->$varName = null;";
+		}
+
+		foreach ($table->getForeignKeys() as $fk) {
+			$className = $this->getForeignTable($fk)->getPhpName();
+			$varName = $this->getFKVarName($fk);
+			$script .= "
+			\$this->$varName = null;";
+		}
+
+		$script .= "
+	}
+";
+	}
+
+} // PHP5ObjectBuilder
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/builder/om/php5/PHP5PeerBuilder.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/builder/om/php5/PHP5PeerBuilder.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/builder/om/php5/PHP5PeerBuilder.php	(revision 19)
@@ -0,0 +1,2652 @@
+<?php
+
+/*
+ *  $Id: PHP5PeerBuilder.php 1067 2008-08-06 07:37:21Z ron $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://propel.phpdb.org>.
+ */
+
+require_once 'propel/engine/builder/om/PeerBuilder.php';
+
+/**
+ * Generates a PHP5 base Peer class for user object model (OM).
+ *
+ * This class produces the base peer class (e.g. BaseMyPeer) which contains all
+ * the custom-built query and manipulator methods.
+ *
+ * @author     Hans Lellelid <hans@xmpl.org>
+ * @package    propel.engine.builder.om.php5
+ */
+class PHP5PeerBuilder extends PeerBuilder {
+
+	/**
+	 * Validates the current table to make sure that it won't
+	 * result in generated code that will not parse.
+	 *
+	 * This method may emit warnings for code which may cause problems
+	 * and will throw exceptions for errors that will definitely cause
+	 * problems.
+	 */
+	protected function validateModel()
+	{
+		parent::validateModel();
+
+		$table = $this->getTable();
+
+		// Check to see if any of the column constants are PHP reserved words.
+		$colConstants = array();
+
+		foreach ($table->getColumns() as $col) {
+			$colConstants[] = $this->getColumnName($col);
+		}
+
+		$reservedConstants = array_map('strtoupper', ClassTools::getPhpReservedWords());
+
+		$intersect = array_intersect($reservedConstants, $colConstants);
+		if (!empty($intersect)) {
+			throw new EngineException("One or more of your column names for [" . $table->getName() . "] table conflict with a PHP reserved word (" . implode(", ", $intersect) . ")");
+		}
+	}
+
+	/**
+	 * Returns the name of the current class being built.
+	 * @return     string
+	 */
+	public function getUnprefixedClassname()
+	{
+		return $this->getBuildProperty('basePrefix') . $this->getStubPeerBuilder()->getUnprefixedClassname();
+	}
+
+	/**
+	 * Gets the package for the [base] peer classes.
+	 * @return     string
+	 */
+	public function getPackage()
+	{
+		return parent::getPackage() . ".om";
+	}
+
+	/**
+	 * Adds the include() statements for files that this class depends on or utilizes.
+	 * @param      string &$script The script will be modified in this method.
+	 */
+	protected function addIncludes(&$script)
+	{
+	} // addIncludes()
+
+	/**
+	 * Adds class phpdoc comment and openning of class.
+	 * @param      string &$script The script will be modified in this method.
+	 */
+	protected function addClassOpen(&$script) {
+
+		$tableName = $this->getTable()->getName();
+		$tableDesc = $this->getTable()->getDescription();
+
+		$script .= "
+/**
+ * Base static class for performing query and update operations on the '$tableName' table.
+ *
+ * $tableDesc
+ *";
+		if ($this->getBuildProperty('addTimeStamp')) {
+			$now = strftime('%c');
+			$script .= "
+ * This class was autogenerated by Propel " . $this->getBuildProperty('version') . " on:
+ *
+ * $now
+ *";
+		}
+
+		$extendingPeerClass = '';
+		if ($this->basePeerClassname !== 'BasePeer') {
+			$extendingPeerClass = ' extends ' . $this->basePeerClassname;
+		}
+
+		$script .= "
+ * @package    ".$this->getPackage()."
+ */
+abstract class ".$this->getClassname(). $extendingPeerClass . " {
+";
+	}
+
+	/**
+	 * Closes class.
+	 * Adds closing brace at end of class and the static map builder registration code.
+	 * @param      string &$script The script will be modified in this method.
+	 * @see        addStaticMapBuilderRegistration()
+	 */
+	protected function addClassClose(&$script)
+	{
+		$script .= "
+} // " . $this->getClassname() . "
+";
+		$this->addStaticMapBuilderRegistration($script);
+	}
+
+	/**
+	 * Adds the static map builder registration code.
+	 * @param      string &$script The script will be modified in this method.
+	 */
+	protected function addStaticMapBuilderRegistration(&$script)
+	{
+		$table = $this->getTable();
+		$mapBuilderFile = $this->getMapBuilderBuilder()->getClassFilePath();
+
+		$script .= "
+// This is the static code needed to register the MapBuilder for this table with the main Propel class.
+//
+// NOTE: This static code cannot call methods on the ".$this->getPeerClassname()." class, because it is not defined yet.
+// If you need to use overridden methods, you can add this code to the bottom of the ".$this->getPeerClassname()." class:
+//
+// Propel::getDatabaseMap(".$this->getPeerClassname()."::DATABASE_NAME)->addTableBuilder(".$this->getPeerClassname()."::TABLE_NAME, ".$this->getPeerClassname()."::getMapBuilder());
+//
+// Doing so will effectively overwrite the registration below.
+
+Propel::getDatabaseMap(".$this->getClassname()."::DATABASE_NAME)->addTableBuilder(".$this->getClassname()."::TABLE_NAME, ".$this->getClassname()."::getMapBuilder());
+
+";
+	}
+
+	/**
+	 * Adds constant and variable declarations that go at the top of the class.
+	 * @param      string &$script The script will be modified in this method.
+	 * @see        addColumnNameConstants()
+	 */
+	protected function addConstantsAndAttributes(&$script)
+	{
+		$tableName = $this->prefixTableName($this->getTable()->getName());
+		$dbName = $this->getDatabase()->getName();
+		$script .= "
+	/** the default database name for this class */
+	const DATABASE_NAME = '$dbName';
+
+	/** the table name for this class */
+	const TABLE_NAME = '$tableName';
+
+	/** A class that can be returned by this peer. */
+	const CLASS_DEFAULT = '".$this->getStubObjectBuilder()->getClasspath()."';
+
+	/** The total number of columns. */
+	const NUM_COLUMNS = ".$this->getTable()->getNumColumns().";
+
+	/** The number of lazy-loaded columns. */
+	const NUM_LAZY_LOAD_COLUMNS = ".$this->getTable()->getNumLazyLoadColumns().";
+";
+		$this->addColumnNameConstants($script);
+		$this->addInheritanceColumnConstants($script);
+
+		$script .= "
+	/**
+	 * An identiy map to hold any loaded instances of ".$this->getObjectClassname()." objects.
+	 * This must be public so that other peer classes can access this when hydrating from JOIN
+	 * queries.
+	 * @var        array ".$this->getObjectClassname()."[]
+	 */
+	public static \$instances = array();
+
+	/**
+	 * The MapBuilder instance for this peer.
+	 * @var        MapBuilder
+	 */
+	private static \$mapBuilder = null;
+";
+
+		$this->addFieldNamesAttribute($script);
+		$this->addFieldKeysAttribute($script);
+
+	}
+
+	/**
+	 * Adds the COLUMN_NAME contants to the class definition.
+	 * @param      string &$script The script will be modified in this method.
+	 */
+	protected function addColumnNameConstants(&$script)
+	{
+		foreach ($this->getTable()->getColumns() as $col) {
+			$script .= "
+	/** the column name for the ".strtoupper($col->getName()) ." field */
+	const ".$this->getColumnName($col) ." = '".$this->prefixTablename($this->getTable()->getName()).".".strtoupper($col->getName())."';
+";
+		} // foreach
+	}
+
+	protected function addFieldNamesAttribute(&$script)
+	{
+		$table = $this->getTable();
+
+		$tableColumns = $table->getColumns();
+
+		$script .= "
+	/**
+	 * holds an array of fieldnames
+	 *
+	 * first dimension keys are the type constants
+	 * e.g. self::\$fieldNames[self::TYPE_PHPNAME][0] = 'Id'
+	 */
+	private static \$fieldNames = array (
+		BasePeer::TYPE_PHPNAME => array (";
+		foreach ($tableColumns as $col) {
+			$script .= "'".$col->getPhpName()."', ";
+		}
+		$script .= "),
+		BasePeer::TYPE_STUDLYPHPNAME => array (";
+		foreach ($tableColumns as $col) {
+			$script .= "'".$col->getStudlyPhpName()."', ";
+		}
+		$script .= "),
+		BasePeer::TYPE_COLNAME => array (";
+		foreach ($tableColumns as $col) {
+			$script .= $this->getColumnConstant($col, 'self').", ";
+		}
+		$script .= "),
+		BasePeer::TYPE_FIELDNAME => array (";
+		foreach ($tableColumns as $col) {
+			$script .= "'".$col->getName()."', ";
+		}
+		$script .= "),
+		BasePeer::TYPE_NUM => array (";
+		foreach ($tableColumns as $num => $col) {
+			$script .= "$num, ";
+		}
+		$script .= ")
+	);
+";
+	}
+
+	protected function addFieldKeysAttribute(&$script)
+	{
+		$table = $this->getTable();
+
+		$tableColumns = $table->getColumns();
+
+		$script .= "
+	/**
+	 * holds an array of keys for quick access to the fieldnames array
+	 *
+	 * first dimension keys are the type constants
+	 * e.g. self::\$fieldNames[BasePeer::TYPE_PHPNAME]['Id'] = 0
+	 */
+	private static \$fieldKeys = array (
+		BasePeer::TYPE_PHPNAME => array (";
+		foreach ($tableColumns as $num => $col) {
+			$script .= "'".$col->getPhpName()."' => $num, ";
+		}
+		$script .= "),
+		BasePeer::TYPE_STUDLYPHPNAME => array (";
+		foreach ($tableColumns as $num => $col) {
+			$script .= "'".$col->getStudlyPhpName()."' => $num, ";
+		}
+		$script .= "),
+		BasePeer::TYPE_COLNAME => array (";
+		foreach ($tableColumns as $num => $col) {
+			$script .= $this->getColumnConstant($col, 'self')." => $num, ";
+		}
+		$script .= "),
+		BasePeer::TYPE_FIELDNAME => array (";
+		foreach ($tableColumns as $num => $col) {
+			$script .= "'".$col->getName()."' => $num, ";
+		}
+		$script .= "),
+		BasePeer::TYPE_NUM => array (";
+		foreach ($tableColumns as $num => $col) {
+			$script .= "$num, ";
+		}
+		$script .= ")
+	);
+";
+	} // addFielKeysAttribute
+
+
+	protected function addGetFieldNames(&$script)
+	{
+		$script .= "
+	/**
+	 * Returns an array of field names.
+	 *
+	 * @param      string \$type The type of fieldnames to return:
+	 *                      One of the class type constants BasePeer::TYPE_PHPNAME, BasePeer::TYPE_STUDLYPHPNAME
+	 *                      BasePeer::TYPE_COLNAME, BasePeer::TYPE_FIELDNAME, BasePeer::TYPE_NUM
+	 * @return     array A list of field names
+	 */
+
+	static public function getFieldNames(\$type = BasePeer::TYPE_PHPNAME)
+	{
+		if (!array_key_exists(\$type, self::\$fieldNames)) {
+			throw new PropelException('Method getFieldNames() expects the parameter \$type to be one of the class constants BasePeer::TYPE_PHPNAME, BasePeer::TYPE_STUDLYPHPNAME, BasePeer::TYPE_COLNAME, BasePeer::TYPE_FIELDNAME, BasePeer::TYPE_NUM. ' . \$type . ' was given.');
+		}
+		return self::\$fieldNames[\$type];
+	}
+";
+
+	} // addGetFieldNames()
+
+	protected function addTranslateFieldName(&$script)
+	{
+		$script .= "
+	/**
+	 * Translates a fieldname to another type
+	 *
+	 * @param      string \$name field name
+	 * @param      string \$fromType One of the class type constants BasePeer::TYPE_PHPNAME, BasePeer::TYPE_STUDLYPHPNAME
+	 *                         BasePeer::TYPE_COLNAME, BasePeer::TYPE_FIELDNAME, BasePeer::TYPE_NUM
+	 * @param      string \$toType   One of the class type constants
+	 * @return     string translated name of the field.
+	 * @throws     PropelException - if the specified name could not be found in the fieldname mappings.
+	 */
+	static public function translateFieldName(\$name, \$fromType, \$toType)
+	{
+		\$toNames = self::getFieldNames(\$toType);
+		\$key = isset(self::\$fieldKeys[\$fromType][\$name]) ? self::\$fieldKeys[\$fromType][\$name] : null;
+		if (\$key === null) {
+			throw new PropelException(\"'\$name' could not be found in the field names of type '\$fromType'. These are: \" . print_r(self::\$fieldKeys[\$fromType], true));
+		}
+		return \$toNames[\$key];
+	}
+";
+	} // addTranslateFieldName()
+
+	/**
+	 * Adds the getMapBuilder() method.
+	 * @param      string &$script The script will be modified in this method.
+	 */
+	protected function addGetMapBuilder(&$script)
+	{
+		$script .= "
+	/**
+	 * Get a (singleton) instance of the MapBuilder for this peer class.
+	 * @return     MapBuilder The map builder for this peer
+	 */
+	public static function getMapBuilder()
+	{
+		if (self::\$mapBuilder === null) {
+			self::\$mapBuilder = new ".$this->getMapBuilderBuilder()->getClassname()."();
+		}
+		return self::\$mapBuilder;
+	}";
+	}
+
+	/**
+	 * Adds the CLASSKEY_* and CLASSNAME_* constants used for inheritance.
+	 * @param      string &$script The script will be modified in this method.
+	 */
+	public function addInheritanceColumnConstants(&$script)
+	{
+		if ($this->getTable()->getChildrenColumn()) {
+
+			$col = $this->getTable()->getChildrenColumn();
+			$cfc = $col->getPhpName();
+
+			if ($col->isEnumeratedClasses()) {
+
+				if ($col->isPhpPrimitiveNumericType()) $quote = "";
+				else $quote = '"';
+
+				foreach ($col->getChildren() as $child) {
+					$childBuilder = $this->getMultiExtendObjectBuilder();
+					$childBuilder->setChild($child);
+
+					$script .= "
+	/** A key representing a particular subclass */
+	const CLASSKEY_".strtoupper($child->getKey())." = '" . $child->getKey() . "';
+";
+
+					if (strtoupper($child->getClassname()) != strtoupper($child->getKey())) {
+						$script .= "
+	/** A key representing a particular subclass */
+	const CLASSKEY_".strtoupper($child->getClassname())." = '" . $child->getKey() . "';
+";
+					}
+
+					$script .= "
+	/** A class that can be returned by this peer. */
+	const CLASSNAME_".strtoupper($child->getKey())." = '". $childBuilder->getClasspath() . "';
+";
+				} /* foreach children */
+			} /* if col->isenumerated...() */
+		} /* if table->getchildrencolumn() */
+
+	} //
+
+	/**
+	 * Adds the alias() utility method.
+	 * @param      string &$script The script will be modified in this method.
+	 */
+	protected function addAlias(&$script)
+	{
+		$script .= "
+	/**
+	 * Convenience method which changes table.column to alias.column.
+	 *
+	 * Using this method you can maintain SQL abstraction while using column aliases.
+	 * <code>
+	 *		\$c->addAlias(\"alias1\", TablePeer::TABLE_NAME);
+	 *		\$c->addJoin(TablePeer::alias(\"alias1\", TablePeer::PRIMARY_KEY_COLUMN), TablePeer::PRIMARY_KEY_COLUMN);
+	 * </code>
+	 * @param      string \$alias The alias for the current table.
+	 * @param      string \$column The column name for current table. (i.e. ".$this->getPeerClassname()."::COLUMN_NAME).
+	 * @return     string
+	 */
+	public static function alias(\$alias, \$column)
+	{
+		return str_replace(".$this->getPeerClassname()."::TABLE_NAME.'.', \$alias.'.', \$column);
+	}
+";
+	} // addAliasMethod
+
+	/**
+	 * Adds the addSelectColumns() method.
+	 * @param      string &$script The script will be modified in this method.
+	 */
+	protected function addAddSelectColumns(&$script)
+	{
+		$script .= "
+	/**
+	 * Add all the columns needed to create a new object.
+	 *
+	 * Note: any columns that were marked with lazyLoad=\"true\" in the
+	 * XML schema will not be added to the select list and only loaded
+	 * on demand.
+	 *
+	 * @param      criteria object containing the columns to add.
+	 * @throws     PropelException Any exceptions caught during processing will be
+	 *		 rethrown wrapped into a PropelException.
+	 */
+	public static function addSelectColumns(Criteria \$criteria)
+	{
+";
+		foreach ($this->getTable()->getColumns() as $col) {
+			if (!$col->isLazyLoad()) {
+				$script .= "
+		\$criteria->addSelectColumn(".$this->getPeerClassname()."::".$this->getColumnName($col).");
+";
+			} // if !col->isLazyLoad
+		} // foreach
+		$script .="
+	}
+";
+	} // addAddSelectColumns()
+
+	/**
+	 * Adds the doCount() method.
+	 * @param      string &$script The script will be modified in this method.
+	 */
+	protected function addDoCount(&$script)
+	{
+		$script .= "
+	/**
+	 * Returns the number of rows matching criteria.
+	 *
+	 * @param      Criteria \$criteria
+	 * @param      boolean \$distinct Whether to select only distinct columns; deprecated: use Criteria->setDistinct() instead.
+	 * @param      PropelPDO \$con
+	 * @return     int Number of matching rows.
+	 */
+	public static function doCount(Criteria \$criteria, \$distinct = false, PropelPDO \$con = null)
+	{
+		// we may modify criteria, so copy it first
+		\$criteria = clone \$criteria;
+
+		// We need to set the primary table name, since in the case that there are no WHERE columns
+		// it will be impossible for the BasePeer::createSelectSql() method to determine which
+		// tables go into the FROM clause.
+		\$criteria->setPrimaryTableName(".$this->getPeerClassname()."::TABLE_NAME);
+
+		if (\$distinct && !in_array(Criteria::DISTINCT, \$criteria->getSelectModifiers())) {
+			\$criteria->setDistinct();
+		}
+
+		if (!\$criteria->hasSelectClause()) {
+			".$this->getPeerClassname()."::addSelectColumns(\$criteria);
+		}
+
+		\$criteria->clearOrderByColumns(); // ORDER BY won't ever affect the count
+		\$criteria->setDbName(self::DATABASE_NAME); // Set the correct dbName
+
+		if (\$con === null) {
+			\$con = Propel::getConnection(".$this->getPeerClassname()."::DATABASE_NAME, Propel::CONNECTION_READ);
+		}
+		// BasePeer returns a PDOStatement
+		\$stmt = ".$this->basePeerClassname."::doCount(\$criteria, \$con);
+
+		if (\$row = \$stmt->fetch(PDO::FETCH_NUM)) {
+			\$count = (int) \$row[0];
+		} else {
+			\$count = 0; // no rows returned; we infer that means 0 matches.
+		}
+		\$stmt->closeCursor();
+		return \$count;
+	}";
+	}
+
+	/**
+	 * Adds the doSelectOne() method.
+	 * @param      string &$script The script will be modified in this method.
+	 */
+	protected function addDoSelectOne(&$script)
+	{
+		$script .= "
+	/**
+	 * Method to select one object from the DB.
+	 *
+	 * @param      Criteria \$criteria object used to create the SELECT statement.
+	 * @param      PropelPDO \$con
+	 * @return     ".$this->getObjectClassname()."
+	 * @throws     PropelException Any exceptions caught during processing will be
+	 *		 rethrown wrapped into a PropelException.
+	 */
+	public static function doSelectOne(Criteria \$criteria, PropelPDO \$con = null)
+	{
+		\$critcopy = clone \$criteria;
+		\$critcopy->setLimit(1);
+		\$objects = ".$this->getPeerClassname()."::doSelect(\$critcopy, \$con);
+		if (\$objects) {
+			return \$objects[0];
+		}
+		return null;
+	}";
+	}
+
+	/**
+	 * Adds the doSelect() method.
+	 * @param      string &$script The script will be modified in this method.
+	 */
+	protected function addDoSelect(&$script)
+	{
+		$script .= "
+	/**
+	 * Method to do selects.
+	 *
+	 * @param      Criteria \$criteria The Criteria object used to build the SELECT statement.
+	 * @param      PropelPDO \$con
+	 * @return     array Array of selected Objects
+	 * @throws     PropelException Any exceptions caught during processing will be
+	 *		 rethrown wrapped into a PropelException.
+	 */
+	public static function doSelect(Criteria \$criteria, PropelPDO \$con = null)
+	{
+		return ".$this->getPeerClassname()."::populateObjects(".$this->getPeerClassname()."::doSelectStmt(\$criteria, \$con));
+	}";
+	}
+
+	/**
+	 * Adds the doSelectStmt() method.
+	 * @param      string &$script The script will be modified in this method.
+	 */
+	protected function addDoSelectStmt(&$script)
+	{
+
+		$script .= "
+	/**
+	 * Prepares the Criteria object and uses the parent doSelect() method to execute a PDOStatement.
+	 *
+	 * Use this method directly if you want to work with an executed statement durirectly (for example
+	 * to perform your own object hydration).
+	 *
+	 * @param      Criteria \$criteria The Criteria object used to build the SELECT statement.
+	 * @param      PropelPDO \$con The connection to use
+	 * @throws     PropelException Any exceptions caught during processing will be
+	 *		 rethrown wrapped into a PropelException.
+	 * @return     PDOStatement The executed PDOStatement object.
+	 * @see        ".$this->basePeerClassname."::doSelect()
+	 */
+	public static function doSelectStmt(Criteria \$criteria, PropelPDO \$con = null)
+	{
+		if (\$con === null) {
+			\$con = Propel::getConnection(".$this->getPeerClassname()."::DATABASE_NAME, Propel::CONNECTION_READ);
+		}
+
+		if (!\$criteria->hasSelectClause()) {
+			\$criteria = clone \$criteria;
+			".$this->getPeerClassname()."::addSelectColumns(\$criteria);
+		}
+
+		// Set the correct dbName
+		\$criteria->setDbName(self::DATABASE_NAME);
+
+		// BasePeer returns a PDOStatement
+		return ".$this->basePeerClassname."::doSelect(\$criteria, \$con);
+	}";
+	}
+
+	/**
+	 * Adds the PHP code to return a instance pool key for the passed-in primary key variable names.
+	 *
+	 * @param      array $pkphp An array of PHP var names / method calls representing complete pk.
+	 */
+	protected function getInstancePoolKeySnippet($pkphp)
+	{
+		$pkphp = (array) $pkphp; // make it an array if it is not.
+		$script = "";
+		if (count($pkphp) > 1) {
+			$script .= "serialize(array(";
+			$i = 0;
+			foreach ($pkphp as $pkvar) {
+				$script .= ($i++ ? ', ' : '') . "(string) $pkvar";
+			}
+			$script .= "))";
+		} else {
+			$script .= "(string) " . $pkphp[0];
+		}
+		return $script;
+	}
+
+	/**
+	 * Creates a convenience method to add objects to an instance pool.
+	 * @param      string &$script The script will be modified in this method.
+	 */
+	protected function addAddInstanceToPool(&$script)
+	{
+		$table = $this->getTable();
+		$script .= "
+	/**
+	 * Adds an object to the instance pool.
+	 *
+	 * Propel keeps cached copies of objects in an instance pool when they are retrieved
+	 * from the database.  In some cases -- especially when you override doSelect*()
+	 * methods in your stub classes -- you may need to explicitly add objects
+	 * to the cache in order to ensure that the same objects are always returned by doSelect*()
+	 * and retrieveByPK*() calls.
+	 *
+	 * @param      ".$this->getObjectClassname()." \$value A ".$this->getObjectClassname()." object.
+	 * @param      string \$key (optional) key to use for instance map (for performance boost if key was already calculated externally).
+	 */
+	public static function addInstanceToPool(".$this->getObjectClassname()." \$obj, \$key = null)
+	{
+		if (Propel::isInstancePoolingEnabled()) {
+			if (\$key === null) {";
+
+		$pks = $this->getTable()->getPrimaryKey();
+
+		$php = array();
+		foreach ($pks as $pk) {
+			$php[] = '$obj->get' . $pk->getPhpName() . '()';
+		}
+		$script .= "
+				\$key = ".$this->getInstancePoolKeySnippet($php).";";
+		$script .= "
+			} // if key === null
+			self::\$instances[\$key] = \$obj;
+		}
+	}
+";
+	} // addAddInstanceToPool()
+
+	/**
+	 *  Creates a convenience method to remove objects form an instance pool.
+	 * @param      string &$script The script will be modified in this method.
+	 */
+	protected function addRemoveInstanceFromPool(&$script)
+	{
+		$table = $this->getTable();
+		$script .= "
+	/**
+	 * Removes an object from the instance pool.
+	 *
+	 * Propel keeps cached copies of objects in an instance pool when they are retrieved
+	 * from the database.  In some cases -- especially when you override doDelete
+	 * methods in your stub classes -- you may need to explicitly remove objects
+	 * from the cache in order to prevent returning objects that no longer exist.
+	 *
+	 * @param      mixed \$value A ".$this->getObjectClassname()." object or a primary key value.
+	 */
+	public static function removeInstanceFromPool(\$value)
+	{";
+		$script .= "
+		if (Propel::isInstancePoolingEnabled() && \$value !== null) {";
+		$pks = $table->getPrimaryKey();
+
+		$script .= "
+			if (is_object(\$value) && \$value instanceof ".$this->getObjectClassname().") {";
+
+			$php = array();
+			foreach ($pks as $pk) {
+				$php[] = '$value->get' . $pk->getPhpName() . '()';
+			}
+			$script .= "
+				\$key = ".$this->getInstancePoolKeySnippet($php).";";
+
+		$script .= "
+			} elseif (".(count($pks) > 1 ? "is_array(\$value) && count(\$value) === " . count($pks) : "is_scalar(\$value)").") {
+				// assume we've been passed a primary key";
+
+		if (count($pks) > 1) {
+			$php = array();
+			for ($i=0; $i < count($pks); $i++) {
+				$php[] = "\$value[$i]";
+			}
+		} else {
+			$php = '$value';
+		}
+		$script .= "
+				\$key = ".$this->getInstancePoolKeySnippet($php).";";
+		$script .= "
+			} else {
+				\$e = new PropelException(\"Invalid value passed to removeInstanceFromPool().  Expected primary key or ".$this->getObjectClassname()." object; got \" . (is_object(\$value) ? get_class(\$value) . ' object.' : var_export(\$value,true)));
+				throw \$e;
+			}
+
+			unset(self::\$instances[\$key]);
+		}
+	} // removeInstanceFromPool()
+";
+	} // addRemoveFromInstancePool()
+
+	/**
+	 * Adds method to clear the instance pool.
+	 * @param      string &$script The script will be modified in this method.
+	 */
+	protected function addClearInstancePool(&$script)
+	{
+		$script .= "
+	/**
+	 * Clear the instance pool.
+	 *
+	 * @return     void
+	 */
+	public static function clearInstancePool()
+	{
+		self::\$instances = array();
+	}
+	";
+	}
+
+	/**
+	 * Adds method to get an the instance from the pool, given a key.
+	 * @param      string &$script The script will be modified in this method.
+	 */
+	protected function addGetInstanceFromPool(&$script)
+	{
+		$script .= "
+	/**
+	 * Retrieves a string version of the primary key from the DB resultset row that can be used to uniquely identify a row in this table.
+	 *
+	 * For tables with a single-column primary key, that simple pkey value will be returned.  For tables with
+	 * a multi-column primary key, a serialize()d version of the primary key will be returned.
+	 *
+	 * @param      string \$key The key (@see getPrimaryKeyHash()) for this instance.
+	 * @return     ".$this->getObjectClassname()." Found object or NULL if 1) no instance exists for specified key or 2) instance pooling has been disabled.
+	 * @see        getPrimaryKeyHash()
+	 */
+	public static function getInstanceFromPool(\$key)
+	{
+		if (Propel::isInstancePoolingEnabled()) {
+			if (isset(self::\$instances[\$key])) {
+				return self::\$instances[\$key];
+			}
+		}
+		return null; // just to be explicit
+	}
+	";
+	}
+
+	/**
+	 * Adds method to get a version of the primary key that can be used as a unique key for identifier map.
+	 * @param      string &$script The script will be modified in this method.
+	 */
+	protected function addGetPrimaryKeyHash(&$script)
+	{
+		$script .= "
+	/**
+	 * Retrieves a string version of the primary key from the DB resultset row that can be used to uniquely identify a row in this table.
+	 *
+	 * For tables with a single-column primary key, that simple pkey value will be returned.  For tables with
+	 * a multi-column primary key, a serialize()d version of the primary key will be returned.
+	 *
+	 * @param      array \$row PropelPDO resultset row.
+	 * @param      int \$startcol The 0-based offset for reading from the resultset row.
+	 * @return     string A string version of PK or NULL if the components of primary key in result array are all null.
+	 */
+	public static function getPrimaryKeyHashFromRow(\$row, \$startcol = 0)
+	{";
+
+		// We have to iterate through all the columns so that we know the offset of the primary
+		// key columns.
+		$n = 0;
+		$pk = array();
+		$cond = array();
+		foreach ($this->getTable()->getColumns() as $col) {
+			if (!$col->isLazyLoad()) {
+				if ($col->isPrimaryKey()) {
+					$part = "\$row[\$startcol + $n]";
+					$cond[] = $part . " === null";
+					$pk[] = $part;
+				}
+				$n++;
+			}
+		}
+
+		$script .= "
+		// If the PK cannot be derived from the row, return NULL.
+		if (".implode(' && ', $cond).") {
+			return null;
+		}
+		return ".$this->getInstancePoolKeySnippet($pk).";
+	}
+";
+	} // addGetPrimaryKeyHash
+
+	/**
+	 * Adds the populateObjects() method.
+	 * @param      string &$script The script will be modified in this method.
+	 */
+	protected function addPopulateObjects(&$script)
+	{
+		$table = $this->getTable();
+		$script .= "
+	/**
+	 * The returned array will contain objects of the default type or
+	 * objects that inherit from the default.
+	 *
+	 * @throws     PropelException Any exceptions caught during processing will be
+	 *		 rethrown wrapped into a PropelException.
+	 */
+	public static function populateObjects(PDOStatement \$stmt)
+	{
+		\$results = array();
+	";
+		if (!$table->getChildrenColumn()) {
+			$script .= "
+		// set the class once to avoid overhead in the loop
+		\$cls = ".$this->getPeerClassname()."::getOMClass();
+		\$cls = substr('.'.\$cls, strrpos('.'.\$cls, '.') + 1);";
+		}
+
+		$script .= "
+		// populate the object(s)
+		while (\$row = \$stmt->fetch(PDO::FETCH_NUM)) {
+			\$key = ".$this->getPeerClassname()."::getPrimaryKeyHashFromRow(\$row, 0);
+			if (null !== (\$obj = ".$this->getPeerClassname()."::getInstanceFromPool(\$key))) {
+				// We no longer rehydrate the object, since this can cause data loss.
+				// See http://propel.phpdb.org/trac/ticket/509
+				// \$obj->hydrate(\$row, 0, true); // rehydrate
+				\$results[] = \$obj;
+			} else {
+		";
+		if ($table->getChildrenColumn()) {
+			$script .= "
+				// class must be set each time from the record row
+				\$cls = ".$this->getPeerClassname()."::getOMClass(\$row, 0);
+				\$cls = substr('.'.\$cls, strrpos('.'.\$cls, '.') + 1);
+				" . $this->buildObjectInstanceCreationCode('$obj', '$cls') . "
+				\$obj->hydrate(\$row);
+				\$results[] = \$obj;
+				".$this->getPeerClassname()."::addInstanceToPool(\$obj, \$key);";
+		} else {
+			$script .= "
+				" . $this->buildObjectInstanceCreationCode('$obj', '$cls') . "
+				\$obj->hydrate(\$row);
+				\$results[] = \$obj;
+				".$this->getPeerClassname()."::addInstanceToPool(\$obj, \$key);";
+		}
+		$script .= "
+			} // if key exists
+		}
+		\$stmt->closeCursor();
+		return \$results;
+	}";
+	}
+
+	/**
+	 * Adds a getOMClass() for non-abstract tables that have inheritance.
+	 * @param      string &$script The script will be modified in this method.
+	 */
+	protected function addGetOMClass_Inheritance(&$script)
+	{
+		$col = $this->getTable()->getChildrenColumn();
+		$script .= "
+	/**
+	 * The returned Class will contain objects of the default type or
+	 * objects that inherit from the default.
+	 *
+	 * @param      array \$row PropelPDO result row.
+	 * @param      int \$colnum Column to examine for OM class information (first is 0).
+	 * @throws     PropelException Any exceptions caught during processing will be
+	 *		 rethrown wrapped into a PropelException.
+	 */
+	public static function getOMClass(\$row, \$colnum)
+	{
+		try {
+";
+		if ($col->isEnumeratedClasses()) {
+			$script .= "
+			\$omClass = null;
+			\$classKey = \$row[\$colnum + " . ($col->getPosition() - 1) . "];
+
+			switch(\$classKey) {
+";
+			foreach ($col->getChildren() as $child) {
+				$script .= "
+				case self::CLASSKEY_".strtoupper($child->getKey()).":
+					\$omClass = self::CLASSNAME_".strtoupper($child->getKey()).";
+					break;
+";
+			} /* foreach */
+			$script .= "
+				default:
+					\$omClass = self::CLASS_DEFAULT;
+";
+			$script .= "
+			} // switch
+";
+		} else { /* if not enumerated */
+			$script .= "
+			\$omClass = \$row[\$colnum + ".($col->getPosition()-1)."];
+			\$omClass = substr('.'.\$omClass, strrpos('.'.\$omClass, '.') + 1);
+";
+		}
+		$script .= "
+		} catch (Exception \$e) {
+			throw new PropelException('Unable to get OM class.', \$e);
+		}
+		return \$omClass;
+	}
+";
+	}
+
+	/**
+	 * Adds a getOMClass() signature for abstract tables that have inheritance.
+	 * @param      string &$script The script will be modified in this method.
+	 */
+	protected function addGetOMClass_Inheritance_Abstract(&$script)
+	{
+		$script .= "
+	/**
+	 * The returned Class will contain objects of the default type or
+	 * objects that inherit from the default.
+	 *
+	 * This method must be overridden by the stub subclass, because
+	 * ".$this->getObjectClassname()." is declared abstract in the schema.
+	 *
+	 * @param      ResultSet \$rs ResultSet with pointer to record containing om class.
+	 * @param      int \$colnum Column to examine for OM class information (first is 1).
+	 * @throws     PropelException Any exceptions caught during processing will be
+	 *		 rethrown wrapped into a PropelException.
+	 */
+	abstract public static function getOMClass();
+";
+	}
+
+	/**
+	 * Adds a getOMClass() for non-abstract tables that do note use inheritance.
+	 * @param      string &$script The script will be modified in this method.
+	 */
+	protected function addGetOMClass_NoInheritance(&$script)
+	{
+		$script .= "
+	/**
+	 * The class that the Peer will make instances of.
+	 *
+	 * This uses a dot-path notation which is tranalted into a path
+	 * relative to a location on the PHP include_path.
+	 * (e.g. path.to.MyClass -> 'path/to/MyClass.php')
+	 *
+	 * @return     string path.to.ClassName
+	 */
+	public static function getOMClass()
+	{
+		return ".$this->getPeerClassname()."::CLASS_DEFAULT;
+	}
+";
+	}
+
+	/**
+	 * Adds a getOMClass() signature for abstract tables that do not have inheritance.
+	 * @param      string &$script The script will be modified in this method.
+	 */
+	protected function addGetOMClass_NoInheritance_Abstract(&$script)
+	{
+		$script .= "
+	/**
+	 * The class that the Peer will make instances of.
+	 *
+	 * This method must be overridden by the stub subclass, because
+	 * ".$this->getObjectClassname()." is declared abstract in the schema.
+	 */
+	abstract public static function getOMClass();
+";
+	}
+
+	/**
+	 * Adds the doInsert() method.
+	 * @param      string &$script The script will be modified in this method.
+	 */
+	protected function addDoInsert(&$script)
+	{
+		$table = $this->getTable();
+		$script .= "
+	/**
+	 * Method perform an INSERT on the database, given a ".$this->getObjectClassname()." or Criteria object.
+	 *
+	 * @param      mixed \$values Criteria or ".$this->getObjectClassname()." object containing data that is used to create the INSERT statement.
+	 * @param      PropelPDO \$con the PropelPDO connection to use
+	 * @return     mixed The new primary key.
+	 * @throws     PropelException Any exceptions caught during processing will be
+	 *		 rethrown wrapped into a PropelException.
+	 */
+	public static function doInsert(\$values, PropelPDO \$con = null)
+	{
+		if (\$con === null) {
+			\$con = Propel::getConnection(".$this->getPeerClassname()."::DATABASE_NAME, Propel::CONNECTION_WRITE);
+		}
+
+		if (\$values instanceof Criteria) {
+			\$criteria = clone \$values; // rename for clarity
+		} else {
+			\$criteria = \$values->buildCriteria(); // build Criteria from ".$this->getObjectClassname()." object
+		}
+";
+
+		foreach ($table->getColumns() as $col) {
+			$cfc = $col->getPhpName();
+			if ($col->isPrimaryKey() && $col->isAutoIncrement() && $table->getIdMethod() != "none" && !$table->isAllowPkInsert()) {
+				$script .= "
+		if (\$criteria->containsKey(".$this->getColumnConstant($col).") && \$criteria->keyContainsValue(" . $this->getColumnConstant($col) . ") ) {
+			throw new PropelException('Cannot insert a value for auto-increment primary key ('.".$this->getColumnConstant($col).".')');
+		}
+";
+			}
+		}
+		$script .= "
+
+		// Set the correct dbName
+		\$criteria->setDbName(self::DATABASE_NAME);
+
+		try {
+			// use transaction because \$criteria could contain info
+			// for more than one table (I guess, conceivably)
+			\$con->beginTransaction();
+			\$pk = ".$this->basePeerClassname."::doInsert(\$criteria, \$con);
+			\$con->commit();
+		} catch(PropelException \$e) {
+			\$con->rollBack();
+			throw \$e;
+		}
+
+		return \$pk;
+	}
+";
+	}
+
+	/**
+	 * Adds the doUpdate() method.
+	 * @param      string &$script The script will be modified in this method.
+	 */
+	protected function addDoUpdate(&$script)
+	{
+		$table = $this->getTable();
+		$script .= "
+	/**
+	 * Method perform an UPDATE on the database, given a ".$this->getObjectClassname()." or Criteria object.
+	 *
+	 * @param      mixed \$values Criteria or ".$this->getObjectClassname()." object containing data that is used to create the UPDATE statement.
+	 * @param      PropelPDO \$con The connection to use (specify PropelPDO connection object to exert more control over transactions).
+	 * @return     int The number of affected rows (if supported by underlying database driver).
+	 * @throws     PropelException Any exceptions caught during processing will be
+	 *		 rethrown wrapped into a PropelException.
+	 */
+	public static function doUpdate(\$values, PropelPDO \$con = null)
+	{
+		if (\$con === null) {
+			\$con = Propel::getConnection(".$this->getPeerClassname()."::DATABASE_NAME, Propel::CONNECTION_WRITE);
+		}
+
+		\$selectCriteria = new Criteria(self::DATABASE_NAME);
+
+		if (\$values instanceof Criteria) {
+			\$criteria = clone \$values; // rename for clarity
+";
+		foreach ($table->getColumns() as $col) {
+			if ($col->isPrimaryKey()) {
+				$script .= "
+			\$comparison = \$criteria->getComparison(".$this->getColumnConstant($col).");
+			\$selectCriteria->add(".$this->getColumnConstant($col).", \$criteria->remove(".$this->getColumnConstant($col)."), \$comparison);
+";
+			}  /* if col is prim key */
+		} /* foreach */
+
+		$script .= "
+		} else { // \$values is ".$this->getObjectClassname()." object
+			\$criteria = \$values->buildCriteria(); // gets full criteria
+			\$selectCriteria = \$values->buildPkeyCriteria(); // gets criteria w/ primary key(s)
+		}
+
+		// set the correct dbName
+		\$criteria->setDbName(self::DATABASE_NAME);
+
+		return {$this->basePeerClassname}::doUpdate(\$selectCriteria, \$criteria, \$con);
+	}
+";
+	}
+
+	/**
+	 * Adds the doDeleteAll() method.
+	 * @param      string &$script The script will be modified in this method.
+	 */
+	protected function addDoDeleteAll(&$script)
+	{
+		$table = $this->getTable();
+		$script .= "
+	/**
+	 * Method to DELETE all rows from the ".$table->getName()." table.
+	 *
+	 * @return     int The number of affected rows (if supported by underlying database driver).
+	 */
+	public static function doDeleteAll(\$con = null)
+	{
+		if (\$con === null) {
+			\$con = Propel::getConnection(".$this->getPeerClassname()."::DATABASE_NAME, Propel::CONNECTION_WRITE);
+		}
+		\$affectedRows = 0; // initialize var to track total num of affected rows
+		try {
+			// use transaction because \$criteria could contain info
+			// for more than one table or we could emulating ON DELETE CASCADE, etc.
+			\$con->beginTransaction();
+			";
+		if ($this->isDeleteCascadeEmulationNeeded()) {
+			$script .="\$affectedRows += ".$this->getPeerClassname()."::doOnDeleteCascade(new Criteria(".$this->getPeerClassname()."::DATABASE_NAME), \$con);
+			";
+		}
+		if ($this->isDeleteSetNullEmulationNeeded()) {
+			$script .= $this->getPeerClassname() . "::doOnDeleteSetNull(new Criteria(".$this->getPeerClassname() . "::DATABASE_NAME), \$con);
+			";
+		}
+		$script .= "\$affectedRows += {$this->basePeerClassname}::doDeleteAll(".$this->getPeerClassname()."::TABLE_NAME, \$con);
+			\$con->commit();
+			return \$affectedRows;
+		} catch (PropelException \$e) {
+			\$con->rollBack();
+			throw \$e;
+		}
+	}
+";
+	}
+
+	/**
+	 * Adds the doDelete() method.
+	 * @param      string &$script The script will be modified in this method.
+	 */
+	protected function addDoDelete(&$script)
+	{
+		$table = $this->getTable();
+		$script .= "
+	/**
+	 * Method perform a DELETE on the database, given a ".$this->getObjectClassname()." or Criteria object OR a primary key value.
+	 *
+	 * @param      mixed \$values Criteria or ".$this->getObjectClassname()." object or primary key or array of primary keys
+	 *              which is used to create the DELETE statement
+	 * @param      PropelPDO \$con the connection to use
+	 * @return     int 	The number of affected rows (if supported by underlying database driver).  This includes CASCADE-related rows
+	 *				if supported by native driver or if emulated using Propel.
+	 * @throws     PropelException Any exceptions caught during processing will be
+	 *		 rethrown wrapped into a PropelException.
+	 */
+	 public static function doDelete(\$values, PropelPDO \$con = null)
+	 {
+		if (\$con === null) {
+			\$con = Propel::getConnection(".$this->getPeerClassname()."::DATABASE_NAME, Propel::CONNECTION_WRITE);
+		}
+
+		if (\$values instanceof Criteria) {
+			// invalidate the cache for all objects of this type, since we have no
+			// way of knowing (without running a query) what objects should be invalidated
+			// from the cache based on this Criteria.
+			".$this->getPeerClassname()."::clearInstancePool();
+
+			// rename for clarity
+			\$criteria = clone \$values;
+		} elseif (\$values instanceof ".$this->getObjectClassname().") {
+			// invalidate the cache for this single object
+			".$this->getPeerClassname()."::removeInstanceFromPool(\$values);";
+
+		if (count($table->getPrimaryKey()) > 0) {
+			$script .= "
+			// create criteria based on pk values
+			\$criteria = \$values->buildPkeyCriteria();";
+		} else {
+			$script .= "
+			// create criteria based on pk value
+			\$criteria = \$values->buildCriteria();";
+		}
+
+		$script .= "
+		} else {
+			// it must be the primary key
+
+
+
+			\$criteria = new Criteria(self::DATABASE_NAME);";
+
+		if (count($table->getPrimaryKey()) === 1) {
+			$pkey = $table->getPrimaryKey();
+			$col = array_shift($pkey);
+			$script .= "
+			\$criteria->add(".$this->getColumnConstant($col).", (array) \$values, Criteria::IN);
+
+			foreach ((array) \$values as \$singleval) {
+				// we can invalidate the cache for this single object
+				".$this->getPeerClassname()."::removeInstanceFromPool(\$singleval);
+			}";
+
+		} else {
+			$script .= "
+			// primary key is composite; we therefore, expect
+			// the primary key passed to be an array of pkey
+			// values
+			if (count(\$values) == count(\$values, COUNT_RECURSIVE)) {
+				// array is not multi-dimensional
+				\$values = array(\$values);
+			}
+
+			foreach (\$values as \$value) {
+";
+			$i=0;
+			foreach ($table->getPrimaryKey() as $col) {
+				if ($i == 0) {
+					$script .= "
+				\$criterion = \$criteria->getNewCriterion(".$this->getColumnConstant($col).", \$value[$i]);";
+				} else {
+					$script .= "
+				\$criterion->addAnd(\$criteria->getNewCriterion(".$this->getColumnConstant($col).", \$value[$i]));";
+				}
+				$i++;
+			}
+			$script .= "
+				\$criteria->addOr(\$criterion);
+
+				// we can invalidate the cache for this single PK
+				".$this->getPeerClassname()."::removeInstanceFromPool(\$value);
+			}";
+		} /* if count(table->getPrimaryKeys()) */
+
+		$script .= "
+		}
+
+		// Set the correct dbName
+		\$criteria->setDbName(self::DATABASE_NAME);
+
+		\$affectedRows = 0; // initialize var to track total num of affected rows
+
+		try {
+			// use transaction because \$criteria could contain info
+			// for more than one table or we could emulating ON DELETE CASCADE, etc.
+			\$con->beginTransaction();
+			";
+
+		if ($this->isDeleteCascadeEmulationNeeded()) {
+			$script .= "\$affectedRows += ".$this->getPeerClassname()."::doOnDeleteCascade(\$criteria, \$con);
+			";
+		}
+		if ($this->isDeleteSetNullEmulationNeeded()) {
+			$script .= $this->getPeerClassname() . "::doOnDeleteSetNull(\$criteria, \$con);
+			";
+		}
+
+		if ($this->isDeleteCascadeEmulationNeeded() || $this->isDeleteSetNullEmulationNeeded()) {
+			$script .= "
+				// Because this db requires some delete cascade/set null emulation, we have to
+				// clear the cached instance *after* the emulation has happened (since
+				// instances get re-added by the select statement contained therein).
+				if (\$values instanceof Criteria) {
+					".$this->getPeerClassname()."::clearInstancePool();
+				} else { // it's a PK or object
+					".$this->getPeerClassname()."::removeInstanceFromPool(\$values);
+				}
+			";
+		}
+
+		$script .= "
+			\$affectedRows += {$this->basePeerClassname}::doDelete(\$criteria, \$con);
+";
+		// Handle ON DELETE CASCADE for updating instance pool
+
+		foreach ($table->getReferrers() as $fk) {
+
+			// $fk is the foreign key in the other table, so localTableName will
+			// actually be the table name of other table
+			$tblFK = $fk->getTable();
+
+			$joinedTablePeerBuilder = $this->getNewPeerBuilder($tblFK);
+			$tblFKPackage = $joinedTablePeerBuilder->getStubPeerBuilder()->getPackage();
+
+			if (!$tblFK->isForReferenceOnly()) {
+				// we can't perform operations on tables that are
+				// not within the schema (i.e. that we have no map for, etc.)
+
+				$fkClassName = $joinedTablePeerBuilder->getObjectClassname();
+
+				// i'm not sure whether we can allow delete cascade for foreign keys
+				// within the same table?  perhaps we can?
+				if ( ($fk->getOnDelete() == ForeignKey::CASCADE || $fk->getOnDelete() == ForeignKey::SETNULL )
+				&& $tblFK->getName() != $table->getName()) {
+					$script .= "
+			// invalidate objects in ".$joinedTablePeerBuilder->getPeerClassname()." instance pool, since one or more of them may be deleted by ON DELETE CASCADE rule.
+			".$joinedTablePeerBuilder->getPeerClassname()."::clearInstancePool();
+";
+				} // if fk is on delete cascade
+
+			} // if (! for ref only)
+
+		} // foreach
+
+
+
+		$script .= "
+			\$con->commit();
+			return \$affectedRows;
+		} catch (PropelException \$e) {
+			\$con->rollBack();
+			throw \$e;
+		}
+	}
+";
+	}
+
+	/**
+	 * Adds the doOnDeleteCascade() method, which provides ON DELETE CASCADE emulation.
+	 * @param      string &$script The script will be modified in this method.
+	 */
+	protected function addDoOnDeleteCascade(&$script)
+	{
+		$table = $this->getTable();
+		$script .= "
+	/**
+	 * This is a method for emulating ON DELETE CASCADE for DBs that don't support this
+	 * feature (like MySQL or SQLite).
+	 *
+	 * This method is not very speedy because it must perform a query first to get
+	 * the implicated records and then perform the deletes by calling those Peer classes.
+	 *
+	 * This method should be used within a transaction if possible.
+	 *
+	 * @param      Criteria \$criteria
+	 * @param      PropelPDO \$con
+	 * @return     int The number of affected rows (if supported by underlying database driver).
+	 */
+	protected static function doOnDeleteCascade(Criteria \$criteria, PropelPDO \$con)
+	{
+		// initialize var to track total num of affected rows
+		\$affectedRows = 0;
+
+		// first find the objects that are implicated by the \$criteria
+		\$objects = ".$this->getPeerClassname()."::doSelect(\$criteria, \$con);
+		foreach (\$objects as \$obj) {
+";
+
+		foreach ($table->getReferrers() as $fk) {
+
+			// $fk is the foreign key in the other table, so localTableName will
+			// actually be the table name of other table
+			$tblFK = $fk->getTable();
+
+			$joinedTablePeerBuilder = $this->getNewPeerBuilder($tblFK);
+			$tblFKPackage = $joinedTablePeerBuilder->getStubPeerBuilder()->getPackage();
+
+			if (!$tblFK->isForReferenceOnly()) {
+				// we can't perform operations on tables that are
+				// not within the schema (i.e. that we have no map for, etc.)
+
+				$fkClassName = $joinedTablePeerBuilder->getObjectClassname();
+
+				// i'm not sure whether we can allow delete cascade for foreign keys
+				// within the same table?  perhaps we can?
+				if ( $fk->getOnDelete() == ForeignKey::CASCADE && $tblFK->getName() != $table->getName()) {
+
+					// backwards on purpose
+					$columnNamesF = $fk->getLocalColumns();
+					$columnNamesL = $fk->getForeignColumns();
+
+					$script .= "
+
+			// delete related $fkClassName objects
+			\$c = new Criteria(".$joinedTablePeerBuilder->getPeerClassname()."::DATABASE_NAME);
+			";
+					for ($x=0,$xlen=count($columnNamesF); $x < $xlen; $x++) {
+						$columnFK = $tblFK->getColumn($columnNamesF[$x]);
+						$columnL = $table->getColumn($columnNamesL[$x]);
+
+						$script .= "
+			\$c->add(".$joinedTablePeerBuilder->getColumnConstant($columnFK) .", \$obj->get".$columnL->getPhpName()."());";
+					}
+
+					$script .= "
+			\$affectedRows += ".$joinedTablePeerBuilder->getPeerClassname()."::doDelete(\$c, \$con);";
+
+				} // if cascade && fkey table name != curr table name
+
+			} // if not for ref only
+		} // foreach foreign keys
+		$script .= "
+		}
+		return \$affectedRows;
+	}
+";
+	} // end addDoOnDeleteCascade
+
+	/**
+	 * Adds the doOnDeleteSetNull() method, which provides ON DELETE SET NULL emulation.
+	 * @param      string &$script The script will be modified in this method.
+	 */
+	protected function addDoOnDeleteSetNull(&$script)
+	{
+		$table = $this->getTable();
+		$script .= "
+	/**
+	 * This is a method for emulating ON DELETE SET NULL DBs that don't support this
+	 * feature (like MySQL or SQLite).
+	 *
+	 * This method is not very speedy because it must perform a query first to get
+	 * the implicated records and then perform the deletes by calling those Peer classes.
+	 *
+	 * This method should be used within a transaction if possible.
+	 *
+	 * @param      Criteria \$criteria
+	 * @param      PropelPDO \$con
+	 * @return     void
+	 */
+	protected static function doOnDeleteSetNull(Criteria \$criteria, PropelPDO \$con)
+	{
+
+		// first find the objects that are implicated by the \$criteria
+		\$objects = ".$this->getPeerClassname()."::doSelect(\$criteria, \$con);
+		foreach (\$objects as \$obj) {
+";
+
+		// This logic is almost exactly the same as that in doOnDeleteCascade()
+		// it may make sense to refactor this, provided that thigns don't
+		// get too complicated.
+
+		foreach ($table->getReferrers() as $fk) {
+
+			// $fk is the foreign key in the other table, so localTableName will
+			// actually be the table name of other table
+			$tblFK = $fk->getTable();
+			$refTablePeerBuilder = $this->getNewPeerBuilder($tblFK);
+
+			if (!$tblFK->isForReferenceOnly()) {
+				// we can't perform operations on tables that are
+				// not within the schema (i.e. that we have no map for, etc.)
+
+				$fkClassName = $refTablePeerBuilder->getObjectClassname();
+
+				// i'm not sure whether we can allow delete setnull for foreign keys
+				// within the same table?  perhaps we can?
+				if ( $fk->getOnDelete() == ForeignKey::SETNULL &&
+				$fk->getTable()->getName() != $table->getName()) {
+
+					// backwards on purpose
+					$columnNamesF = $fk->getLocalColumns();
+					$columnNamesL = $fk->getForeignColumns(); // should be same num as foreign
+					$script .= "
+			// set fkey col in related $fkClassName rows to NULL
+			\$selectCriteria = new Criteria(".$this->getPeerClassname()."::DATABASE_NAME);
+			\$updateValues = new Criteria(".$this->getPeerClassname()."::DATABASE_NAME);";
+
+					for ($x=0,$xlen=count($columnNamesF); $x < $xlen; $x++) {
+						$columnFK = $tblFK->getColumn($columnNamesF[$x]);
+						$columnL = $table->getColumn($columnNamesL[$x]);
+						$script .= "
+			\$selectCriteria->add(".$refTablePeerBuilder->getColumnConstant($columnFK).", \$obj->get".$columnL->getPhpName()."());
+			\$updateValues->add(".$refTablePeerBuilder->getColumnConstant($columnFK).", null);
+";
+					}
+
+					$script .= "
+					{$this->basePeerClassname}::doUpdate(\$selectCriteria, \$updateValues, \$con); // use BasePeer because generated Peer doUpdate() methods only update using pkey
+";
+				} // if setnull && fkey table name != curr table name
+			} // if not for ref only
+		} // foreach foreign keys
+
+		$script .= "
+		}
+	}
+";
+	}
+
+	/**
+	 * Adds the doValidate() method.
+	 * @param      string &$script The script will be modified in this method.
+	 */
+	protected function addDoValidate(&$script)
+	{
+		$table = $this->getTable();
+		$script .= "
+	/**
+	 * Validates all modified columns of given ".$this->getObjectClassname()." object.
+	 * If parameter \$columns is either a single column name or an array of column names
+	 * than only those columns are validated.
+	 *
+	 * NOTICE: This does not apply to primary or foreign keys for now.
+	 *
+	 * @param      ".$this->getObjectClassname()." \$obj The object to validate.
+	 * @param      mixed \$cols Column name or array of column names.
+	 *
+	 * @return     mixed TRUE if all columns are valid or the error message of the first invalid column.
+	 */
+	public static function doValidate(".$this->getObjectClassname()." \$obj, \$cols = null)
+	{
+		\$columns = array();
+
+		if (\$cols) {
+			\$dbMap = Propel::getDatabaseMap(".$this->getPeerClassname()."::DATABASE_NAME);
+			\$tableMap = \$dbMap->getTable(".$this->getPeerClassname()."::TABLE_NAME);
+
+			if (! is_array(\$cols)) {
+				\$cols = array(\$cols);
+			}
+
+			foreach (\$cols as \$colName) {
+				if (\$tableMap->containsColumn(\$colName)) {
+					\$get = 'get' . \$tableMap->getColumn(\$colName)->getPhpName();
+					\$columns[\$colName] = \$obj->\$get();
+				}
+			}
+		} else {
+";
+		foreach ($table->getValidators() as $val) {
+			$col = $val->getColumn();
+			if (!$col->isAutoIncrement()) {
+				$script .= "
+		if (\$obj->isNew() || \$obj->isColumnModified(".$this->getColumnConstant($col)."))
+			\$columns[".$this->getColumnConstant($col)."] = \$obj->get".$col->getPhpName()."();
+";
+			} // if
+		} // foreach
+
+		$script .= "
+		}
+
+		return {$this->basePeerClassname}::doValidate(".$this->getPeerClassname()."::DATABASE_NAME, ".$this->getPeerClassname()."::TABLE_NAME, \$columns);
+	}
+";
+	} // end addDoValidate()
+
+	/**
+	 * Adds the retrieveByPK method for tables with single-column primary key.
+	 * @param      string &$script The script will be modified in this method.
+	 */
+	protected function addRetrieveByPK_SinglePK(&$script)
+	{
+		$table = $this->getTable();
+		$pks = $table->getPrimaryKey();
+		$col = $pks[0];
+
+		$script .= "
+	/**
+	 * Retrieve a single object by pkey.
+	 *
+	 * @param      ".$col->getPhpType()." \$pk the primary key.
+	 * @param      PropelPDO \$con the connection to use
+	 * @return     " .$this->getObjectClassname(). "
+	 */
+	public static function ".$this->getRetrieveMethodName()."(\$pk, PropelPDO \$con = null)
+	{
+
+		if (null !== (\$obj = ".$this->getPeerClassname()."::getInstanceFromPool(".$this->getInstancePoolKeySnippet('$pk')."))) {
+			return \$obj;
+		}
+
+		if (\$con === null) {
+			\$con = Propel::getConnection(".$this->getPeerClassname()."::DATABASE_NAME, Propel::CONNECTION_READ);
+		}
+
+		\$criteria = new Criteria(".$this->getPeerClassname()."::DATABASE_NAME);
+		\$criteria->add(".$this->getColumnConstant($col).", \$pk);
+
+		\$v = ".$this->getPeerClassname()."::doSelect(\$criteria, \$con);
+
+		return !empty(\$v) > 0 ? \$v[0] : null;
+	}
+";
+	}
+
+	/**
+	 * Adds the retrieveByPKs method for tables with single-column primary key.
+	 * @param      string &$script The script will be modified in this method.
+	 */
+	protected function addRetrieveByPKs_SinglePK(&$script)
+	{
+		$table = $this->getTable();
+		$script .= "
+	/**
+	 * Retrieve multiple objects by pkey.
+	 *
+	 * @param      array \$pks List of primary keys
+	 * @param      PropelPDO \$con the connection to use
+	 * @throws     PropelException Any exceptions caught during processing will be
+	 *		 rethrown wrapped into a PropelException.
+	 */
+	public static function ".$this->getRetrieveMethodName()."s(\$pks, PropelPDO \$con = null)
+	{
+		if (\$con === null) {
+			\$con = Propel::getConnection(".$this->getPeerClassname()."::DATABASE_NAME, Propel::CONNECTION_READ);
+		}
+
+		\$objs = null;
+		if (empty(\$pks)) {
+			\$objs = array();
+		} else {
+			\$criteria = new Criteria(".$this->getPeerClassname()."::DATABASE_NAME);";
+		$k1 = $table->getPrimaryKey();
+		$script .= "
+			\$criteria->add(".$this->getColumnConstant($k1[0]).", \$pks, Criteria::IN);";
+		$script .= "
+			\$objs = ".$this->getPeerClassname()."::doSelect(\$criteria, \$con);
+		}
+		return \$objs;
+	}
+";
+	}
+
+	/**
+	 * Adds the retrieveByPK method for tables with multi-column primary key.
+	 * @param      string &$script The script will be modified in this method.
+	 */
+	protected function addRetrieveByPK_MultiPK(&$script)
+	{
+		$table = $this->getTable();
+		$script .= "
+	/**
+	 * Retrieve object using using composite pkey values.
+	 * ";
+		foreach ($table->getPrimaryKey() as $col) {
+			$clo = strtolower($col->getName());
+			$cptype = $col->getPhpType();
+			$script .= "@param      $cptype $".$clo."
+	   ";
+		}
+		$script .= "
+	 * @param      PropelPDO \$con
+	 * @return     ".$this->getObjectClassname()."
+	 */
+	public static function ".$this->getRetrieveMethodName()."(";
+
+		$php = array();
+		foreach ($table->getPrimaryKey() as $col) {
+			$clo = strtolower($col->getName());
+			$php[] = '$' . $clo;
+		} /* foreach */
+
+		$script .= implode(', ', $php);
+
+		$script .= ", PropelPDO \$con = null) {
+		\$key = ".$this->getInstancePoolKeySnippet($php).";";
+ 		$script .= "
+ 		if (null !== (\$obj = ".$this->getPeerClassname()."::getInstanceFromPool(\$key))) {
+ 			return \$obj;
+		}
+
+		if (\$con === null) {
+			\$con = Propel::getConnection(".$this->getPeerClassname()."::DATABASE_NAME, Propel::CONNECTION_READ);
+		}
+		\$criteria = new Criteria(".$this->getPeerClassname()."::DATABASE_NAME);";
+		foreach ($table->getPrimaryKey() as $col) {
+			$clo = strtolower($col->getName());
+			$script .= "
+		\$criteria->add(".$this->getColumnConstant($col).", $".$clo.");";
+		}
+		$script .= "
+		\$v = ".$this->getPeerClassname()."::doSelect(\$criteria, \$con);
+
+		return !empty(\$v) ? \$v[0] : null;
+	}";
+	}
+
+	/**
+	 * Adds the getTableMap() method which is a convenience method for apps to get DB metadata.
+	 * @param      string &$script The script will be modified in this method.
+	 */
+	protected function addGetTableMap(&$script)
+	{
+		$script .= "
+	/**
+	 * Returns the TableMap related to this peer.
+	 * This method is not needed for general use but a specific application could have a need.
+	 * @return     TableMap
+	 * @throws     PropelException Any exceptions caught during processing will be
+	 *		 rethrown wrapped into a PropelException.
+	 */
+	public static function getTableMap()
+	{
+		return Propel::getDatabaseMap(self::DATABASE_NAME)->getTable(self::TABLE_NAME);
+	}
+";
+	}
+
+	/**
+	 * Adds the complex OM methods to the base addSelectMethods() function.
+	 * @param      string &$script The script will be modified in this method.
+	 * @see        PeerBuilder::addSelectMethods()
+	 */
+	protected function addSelectMethods(&$script)
+	{
+		$table = $this->getTable();
+
+		parent::addSelectMethods($script);
+
+		$this->addDoCountJoin($script);
+		$this->addDoSelectJoin($script);
+
+		$countFK = count($table->getForeignKeys());
+
+		$includeJoinAll = true;
+
+		foreach ($this->getTable()->getForeignKeys() as $fk) {
+			$tblFK = $table->getDatabase()->getTable($fk->getForeignTableName());
+			if ($tblFK->isForReferenceOnly()) {
+				$includeJoinAll = false;
+			}
+		}
+
+		if ($includeJoinAll) {
+			if ($countFK > 0) {
+				$this->addDoCountJoinAll($script);
+				$this->addDoSelectJoinAll($script);
+			}
+			if ($countFK > 1) {
+				$this->addDoCountJoinAllExcept($script);
+				$this->addDoSelectJoinAllExcept($script);
+			}
+		}
+
+	}
+
+	/**
+	 * Get the column offsets of the primary key(s) for specified table.
+	 *
+	 * @param      Table $tbl
+	 * @return     array int[] The column offsets of the primary key(s).
+	 */
+	protected function getPrimaryKeyColOffsets(Table $tbl)
+	{
+		$offsets = array();
+		$idx = 0;
+		foreach ($tbl->getColumns() as $col) {
+			if ($col->isPrimaryKey()) {
+				$offsets[] = $idx;
+			}
+			$idx++;
+		}
+		return $offsets;
+	}
+
+	/**
+	 * Adds the doSelectJoin*() methods.
+	 * @param      string &$script The script will be modified in this method.
+	 */
+	protected function addDoSelectJoin(&$script)
+	{
+		$table = $this->getTable();
+		$className = $this->getObjectClassname();
+		$countFK = count($table->getForeignKeys());
+		$join_behavior = $this->getJoinBehavior();
+
+		if ($countFK >= 1) {
+
+			foreach ($table->getForeignKeys() as $fk) {
+
+				$joinTable = $table->getDatabase()->getTable($fk->getForeignTableName());
+
+				if (!$joinTable->isForReferenceOnly()) {
+
+					// This condition is necessary because Propel lacks a system for
+					// aliasing the table if it is the same table.
+					if ( $fk->getForeignTableName() != $table->getName() ) {
+
+						$thisTableObjectBuilder = $this->getNewObjectBuilder($table);
+						$joinedTableObjectBuilder = $this->getNewObjectBuilder($joinTable);
+						$joinedTablePeerBuilder = $this->getNewPeerBuilder($joinTable);
+
+						$joinClassName = $joinedTableObjectBuilder->getObjectClassname();
+
+						$script .= "
+
+	/**
+	 * Selects a collection of $className objects pre-filled with their $joinClassName objects.
+	 * @param      Criteria  \$c
+	 * @param      PropelPDO \$con
+	 * @param      String    \$join_behavior the type of joins to use, defaults to $join_behavior
+	 * @return     array Array of $className objects.
+	 * @throws     PropelException Any exceptions caught during processing will be
+	 *		 rethrown wrapped into a PropelException.
+	 */
+	public static function doSelectJoin".$thisTableObjectBuilder->getFKPhpNameAffix($fk, $plural = false)."(Criteria \$c, \$con = null, \$join_behavior = $join_behavior)
+	{
+		\$c = clone \$c;
+
+		// Set the correct dbName if it has not been overridden
+		if (\$c->getDbName() == Propel::getDefaultDB()) {
+			\$c->setDbName(self::DATABASE_NAME);
+		}
+
+		".$this->getPeerClassname()."::addSelectColumns(\$c);
+		\$startcol = (".$this->getPeerClassname()."::NUM_COLUMNS - ".$this->getPeerClassname()."::NUM_LAZY_LOAD_COLUMNS);
+		".$joinedTablePeerBuilder->getPeerClassname()."::addSelectColumns(\$c);
+";
+
+						$lfMap = $fk->getLocalForeignMapping();
+						$left = array();
+						$right = array();
+						foreach ($fk->getLocalColumns() as $columnName ) {
+							array_push($left, $this->getColumnConstant($table->getColumn($columnName) ) );
+							array_push($right, $joinedTablePeerBuilder->getColumnConstant($joinTable->getColumn( $lfMap[$columnName] ) ) );
+						}
+						$script .= "
+		\$c->addJoin(array(";
+						foreach ($left as $lCol) {
+							$script .= $lCol;
+							if ($lCol != $left[count($left)]) {
+								$script .= ",";
+							}
+						}
+						$script .= "), array(";
+						foreach ($right as $rCol) {
+							$script .= $rCol;
+							if ($rCol != $right[count($right)]) {
+								$script .= ",";
+							}
+						}
+						$script .= "), \$join_behavior);
+		\$stmt = ".$this->basePeerClassname."::doSelect(\$c, \$con);
+		\$results = array();
+
+		while (\$row = \$stmt->fetch(PDO::FETCH_NUM)) {
+			\$key1 = ".$this->getPeerClassname()."::getPrimaryKeyHashFromRow(\$row, 0);
+			if (null !== (\$obj1 = ".$this->getPeerClassname()."::getInstanceFromPool(\$key1))) {
+				// We no longer rehydrate the object, since this can cause data loss.
+				// See http://propel.phpdb.org/trac/ticket/509
+				// \$obj1->hydrate(\$row, 0, true); // rehydrate
+			} else {
+";
+						if ($table->getChildrenColumn()) {
+							$script .= "
+				\$omClass = ".$this->getPeerClassname()."::getOMClass(\$row, 0);
+";
+						} else {
+							$script .= "
+				\$omClass = ".$this->getPeerClassname()."::getOMClass();
+";
+						}
+						$script .= "
+				\$cls = substr('.'.\$omClass, strrpos('.'.\$omClass, '.') + 1);
+				" . $this->buildObjectInstanceCreationCode('$obj1', '$cls') . "
+				\$obj1->hydrate(\$row);
+				".$this->getPeerClassname()."::addInstanceToPool(\$obj1, \$key1);
+			} // if \$obj1 already loaded
+
+			\$key2 = ".$joinedTablePeerBuilder->getPeerClassname()."::getPrimaryKeyHashFromRow(\$row, \$startcol);
+			if (\$key2 !== null) {
+				\$obj2 = ".$joinedTablePeerBuilder->getPeerClassname()."::getInstanceFromPool(\$key2);
+				if (!\$obj2) {
+";
+						if ($joinTable->getChildrenColumn()) {
+							$script .= "
+					\$omClass = ".$joinedTablePeerBuilder->getPeerClassname()."::getOMClass(\$row, \$startcol);
+";
+						} else {
+							$script .= "
+					\$omClass = ".$joinedTablePeerBuilder->getPeerClassname()."::getOMClass();
+";
+						}
+
+						$script .= "
+					\$cls = substr('.'.\$omClass, strrpos('.'.\$omClass, '.') + 1);
+					" . $this->buildObjectInstanceCreationCode('$obj2', '$cls') . "
+					\$obj2->hydrate(\$row, \$startcol);
+					".$joinedTablePeerBuilder->getPeerClassname()."::addInstanceToPool(\$obj2, \$key2);
+				} // if obj2 already loaded
+
+				// Add the \$obj1 (".$this->getObjectClassname().") to \$obj2 (".$joinedTablePeerBuilder->getObjectClassname().")
+				\$obj2->".($fk->isLocalPrimaryKey() ? 'set' : 'add') . $joinedTableObjectBuilder->getRefFKPhpNameAffix($fk, $plural = false)."(\$obj1);
+
+			} // if joined row was not null
+
+			\$results[] = \$obj1;
+		}
+		\$stmt->closeCursor();
+		return \$results;
+	}
+";
+					} // if fk table name != this table name
+				} // if ! is reference only
+			} // foreach column
+		} // if count(fk) > 1
+
+	} // addDoSelectJoin()
+
+	/**
+	 * Adds the doCountJoin*() methods.
+	 * @param      string &$script The script will be modified in this method.
+	 */
+	protected function addDoCountJoin(&$script)
+	{
+		$table = $this->getTable();
+		$className = $this->getObjectClassname();
+		$countFK = count($table->getForeignKeys());
+		$join_behavior = $this->getJoinBehavior();
+
+		if ($countFK >= 1) {
+
+			foreach ($table->getForeignKeys() as $fk) {
+
+				$joinTable = $table->getDatabase()->getTable($fk->getForeignTableName());
+
+				if (!$joinTable->isForReferenceOnly()) {
+
+					if ( $fk->getForeignTableName() != $table->getName() ) {
+
+						$thisTableObjectBuilder = $this->getNewObjectBuilder($table);
+						$joinedTableObjectBuilder = $this->getNewObjectBuilder($joinTable);
+						$joinedTablePeerBuilder = $this->getNewPeerBuilder($joinTable);
+
+						$joinClassName = $joinedTableObjectBuilder->getObjectClassname();
+
+						$script .= "
+
+	/**
+	 * Returns the number of rows matching criteria, joining the related ".$thisTableObjectBuilder->getFKPhpNameAffix($fk, $plural = false)." table
+	 *
+	 * @param      Criteria \$c
+	 * @param      boolean \$distinct Whether to select only distinct columns; deprecated: use Criteria->setDistinct() instead.
+	 * @param      PropelPDO \$con
+	 * @param      String    \$join_behavior the type of joins to use, defaults to $join_behavior
+	 * @return     int Number of matching rows.
+	 */
+	public static function doCountJoin".$thisTableObjectBuilder->getFKPhpNameAffix($fk, $plural = false)."(Criteria \$criteria, \$distinct = false, PropelPDO \$con = null, \$join_behavior = $join_behavior)
+	{
+		// we're going to modify criteria, so copy it first
+		\$criteria = clone \$criteria;
+
+		// We need to set the primary table name, since in the case that there are no WHERE columns
+		// it will be impossible for the BasePeer::createSelectSql() method to determine which
+		// tables go into the FROM clause.
+		\$criteria->setPrimaryTableName(".$this->getPeerClassname()."::TABLE_NAME);
+
+		if (\$distinct && !in_array(Criteria::DISTINCT, \$criteria->getSelectModifiers())) {
+			\$criteria->setDistinct();
+		}
+
+		if (!\$criteria->hasSelectClause()) {
+			".$this->getPeerClassname()."::addSelectColumns(\$criteria);
+		}
+		
+		\$criteria->clearOrderByColumns(); // ORDER BY won't ever affect the count
+		
+		// Set the correct dbName
+		\$criteria->setDbName(self::DATABASE_NAME);
+
+		if (\$con === null) {
+			\$con = Propel::getConnection(".$this->getPeerClassname()."::DATABASE_NAME, Propel::CONNECTION_READ);
+		}
+";
+
+						$lfMap = $fk->getLocalForeignMapping();
+						$left = array();
+						$right = array();
+						foreach ($fk->getLocalColumns() as $columnName ) {
+							array_push($left, $this->getColumnConstant($table->getColumn($columnName) ) );
+							array_push($right, $joinedTablePeerBuilder->getColumnConstant($joinTable->getColumn( $lfMap[$columnName] ) ) );
+						}
+						$script .= "
+		\$criteria->addJoin(array(";
+						foreach ($left as $lCol) {
+							$script .= $lCol;
+							if ($lCol != $left[count($left)]) {
+								$script .= ",";
+							}
+						}
+						$script .= "), array(";
+						foreach ($right as $rCol) {
+							$script .= $rCol;
+							if ($rCol != $right[count($right)]) {
+								$script .= ",";
+							}
+						}
+						$script .= "), \$join_behavior);
+		\$stmt = ".$this->basePeerClassname."::doCount(\$criteria, \$con);
+
+		if (\$row = \$stmt->fetch(PDO::FETCH_NUM)) {
+			\$count = (int) \$row[0];
+		} else {
+			\$count = 0; // no rows returned; we infer that means 0 matches.
+		}
+		\$stmt->closeCursor();
+		return \$count;
+	}
+";
+					} // if fk table name != this table name
+				} // if ! is reference only
+			} // foreach column
+		} // if count(fk) > 1
+
+	} // addDoCountJoin()
+
+	/**
+	 * Adds the doSelectJoinAll() method.
+	 * @param      string &$script The script will be modified in this method.
+	 */
+	protected function addDoSelectJoinAll(&$script)
+	{
+		$table = $this->getTable();
+		$className = $this->getObjectClassname();
+		$join_behavior = $this->getJoinBehavior();
+
+		$script .= "
+
+	/**
+	 * Selects a collection of $className objects pre-filled with all related objects.
+	 *
+	 * @param      Criteria  \$c
+	 * @param      PropelPDO \$con
+	 * @param      String    \$join_behavior the type of joins to use, defaults to $join_behavior
+	 * @return     array Array of $className objects.
+	 * @throws     PropelException Any exceptions caught during processing will be
+	 *		 rethrown wrapped into a PropelException.
+	 */
+	public static function doSelectJoinAll(Criteria \$c, \$con = null, \$join_behavior = $join_behavior)
+	{
+		\$c = clone \$c;
+
+		// Set the correct dbName if it has not been overridden
+		if (\$c->getDbName() == Propel::getDefaultDB()) {
+			\$c->setDbName(self::DATABASE_NAME);
+		}
+
+		".$this->getPeerClassname()."::addSelectColumns(\$c);
+		\$startcol2 = (".$this->getPeerClassname()."::NUM_COLUMNS - ".$this->getPeerClassname()."::NUM_LAZY_LOAD_COLUMNS);
+";
+		$index = 2;
+		foreach ($table->getForeignKeys() as $fk) {
+
+			// Want to cover this case, but the code is not there yet.
+			// Propel lacks a system for aliasing tables of the same name.
+			if ( $fk->getForeignTableName() != $table->getName() ) {
+				$joinTable = $table->getDatabase()->getTable($fk->getForeignTableName());
+				$new_index = $index + 1;
+
+				$joinedTablePeerBuilder = $this->getNewPeerBuilder($joinTable);
+				$joinClassName = $joinedTablePeerBuilder->getObjectClassname();
+
+				$script .= "
+		".$joinedTablePeerBuilder->getPeerClassname()."::addSelectColumns(\$c);
+		\$startcol$new_index = \$startcol$index + (".$joinedTablePeerBuilder->getPeerClassname()."::NUM_COLUMNS - ".$joinedTablePeerBuilder->getPeerClassname()."::NUM_LAZY_LOAD_COLUMNS);
+";
+				$index = $new_index;
+
+			} // if fk->getForeignTableName != table->getName
+		} // foreach [sub] foreign keys
+
+		foreach ($table->getForeignKeys() as $fk) {
+			// want to cover this case, but the code is not there yet.
+			if ( $fk->getForeignTableName() != $table->getName() ) {
+				$joinTable = $table->getDatabase()->getTable($fk->getForeignTableName());
+				$joinedTablePeerBuilder = $this->getNewPeerBuilder($joinTable);
+
+				$joinClassName = $joinedTablePeerBuilder->getObjectClassname();
+				$lfMap = $fk->getLocalForeignMapping();
+				$left = array();
+				$right = array();
+				foreach ($fk->getLocalColumns() as $columnName ) {
+					array_push($left, $this->getColumnConstant($table->getColumn($columnName) ) );
+					array_push($right, $joinedTablePeerBuilder->getColumnConstant($joinTable->getColumn( $lfMap[$columnName] ) ) );
+				}
+				$script .= "
+		\$c->addJoin(array(";
+				foreach ($left as $lCol) {
+					$script .= $lCol;
+					if ($lCol != $left[count($left)]) {
+						$script .= ",";
+					}
+				}
+				$script .= "), array(";
+				foreach ($right as $rCol) {
+					$script .= $rCol;
+					if ($rCol != $right[count($right)]) {
+						$script .= ",";
+					}
+				}
+				$script .= "), \$join_behavior);";
+			}
+		}
+
+		$script .= "
+		\$stmt = ".$this->basePeerClassname."::doSelect(\$c, \$con);
+		\$results = array();
+
+		while (\$row = \$stmt->fetch(PDO::FETCH_NUM)) {
+			\$key1 = ".$this->getPeerClassname()."::getPrimaryKeyHashFromRow(\$row, 0);
+			if (null !== (\$obj1 = ".$this->getPeerClassname()."::getInstanceFromPool(\$key1))) {
+				// We no longer rehydrate the object, since this can cause data loss.
+				// See http://propel.phpdb.org/trac/ticket/509
+				// \$obj1->hydrate(\$row, 0, true); // rehydrate
+			} else {";
+
+		if ($table->getChildrenColumn()) {
+			$script .= "
+				\$omClass = ".$this->getPeerClassname()."::getOMClass(\$row, 0);
+";
+		} else {
+			$script .= "
+				\$omClass = ".$this->getPeerClassname()."::getOMClass();
+";
+		}
+
+		$script .= "
+				\$cls = substr('.'.\$omClass, strrpos('.'.\$omClass, '.') + 1);
+				" . $this->buildObjectInstanceCreationCode('$obj1', '$cls') . "
+				\$obj1->hydrate(\$row);
+				".$this->getPeerClassname()."::addInstanceToPool(\$obj1, \$key1);
+			} // if obj1 already loaded
+";
+
+		$index = 1;
+		foreach ($table->getForeignKeys() as $fk ) {
+			// want to cover this case, but the code is not there yet.
+			// Why not? -because we'd have to alias the tables in the JOIN
+			if ( $fk->getForeignTableName() != $table->getName() ) {
+				$joinTable = $table->getDatabase()->getTable($fk->getForeignTableName());
+
+				$thisTableObjectBuilder = $this->getNewObjectBuilder($table);
+				$joinedTableObjectBuilder = $this->getNewObjectBuilder($joinTable);
+				$joinedTablePeerBuilder = $this->getNewPeerBuilder($joinTable);
+
+
+				$joinClassName = $joinedTableObjectBuilder->getObjectClassname();
+				$interfaceName = $joinClassName;
+
+				if ($joinTable->getInterface()) {
+					$interfaceName = $this->prefixClassname($joinTable->getInterface());
+				}
+
+				$index++;
+
+				$script .= "
+			// Add objects for joined $joinClassName rows
+
+			\$key$index = ".$joinedTablePeerBuilder->getPeerClassname()."::getPrimaryKeyHashFromRow(\$row, \$startcol$index);
+			if (\$key$index !== null) {
+				\$obj$index = ".$joinedTablePeerBuilder->getPeerClassname()."::getInstanceFromPool(\$key$index);
+				if (!\$obj$index) {
+";
+				if ($joinTable->getChildrenColumn()) {
+					$script .= "
+					\$omClass = ".$joinedTablePeerBuilder->getPeerClassname()."::getOMClass(\$row, \$startcol$index);
+";
+				} else {
+					$script .= "
+					\$omClass = ".$joinedTablePeerBuilder->getPeerClassname()."::getOMClass();
+";
+				} /* $joinTable->getChildrenColumn() */
+
+				$script .= "
+
+					\$cls = substr('.'.\$omClass, strrpos('.'.\$omClass, '.') + 1);
+					" . $this->buildObjectInstanceCreationCode('$obj' . $index, '$cls') . "
+					\$obj".$index."->hydrate(\$row, \$startcol$index);
+					".$joinedTablePeerBuilder->getPeerClassname()."::addInstanceToPool(\$obj$index, \$key$index);
+				} // if obj$index loaded
+
+				// Add the \$obj1 (".$this->getObjectClassname().") to the collection in \$obj".$index." (".$joinedTablePeerBuilder->getObjectClassname().")
+				".($fk->isLocalPrimaryKey() ?
+				"\$obj1->set".$joinedTablePeerBuilder->getObjectClassname()."(\$obj".$index.");" :
+				"\$obj".$index."->add".$joinedTableObjectBuilder->getRefFKPhpNameAffix($fk, $plural = false)."(\$obj1);")."
+			} // if joined row not null
+";
+
+			} // $fk->getForeignTableName() != $table->getName()
+		} //foreach foreign key
+
+		$script .= "
+			\$results[] = \$obj1;
+		}
+		\$stmt->closeCursor();
+		return \$results;
+	}
+";
+
+	} // end addDoSelectJoinAll()
+
+
+	/**
+	 * Adds the doCountJoinAll() method.
+	 * @param      string &$script The script will be modified in this method.
+	 */
+	protected function addDoCountJoinAll(&$script)
+	{
+		$table = $this->getTable();
+		$className = $this->getObjectClassname();
+		$join_behavior = $this->getJoinBehavior();
+
+		$script .= "
+
+	/**
+	 * Returns the number of rows matching criteria, joining all related tables
+	 *
+	 * @param      Criteria \$c
+	 * @param      boolean \$distinct Whether to select only distinct columns; deprecated: use Criteria->setDistinct() instead.
+	 * @param      PropelPDO \$con
+	 * @param      String    \$join_behavior the type of joins to use, defaults to $join_behavior
+	 * @return     int Number of matching rows.
+	 */
+	public static function doCountJoinAll(Criteria \$criteria, \$distinct = false, PropelPDO \$con = null, \$join_behavior = $join_behavior)
+	{
+		// we're going to modify criteria, so copy it first
+		\$criteria = clone \$criteria;
+
+		// We need to set the primary table name, since in the case that there are no WHERE columns
+		// it will be impossible for the BasePeer::createSelectSql() method to determine which
+		// tables go into the FROM clause.
+		\$criteria->setPrimaryTableName(".$this->getPeerClassname()."::TABLE_NAME);
+
+		if (\$distinct && !in_array(Criteria::DISTINCT, \$criteria->getSelectModifiers())) {
+			\$criteria->setDistinct();
+		}
+
+		if (!\$criteria->hasSelectClause()) {
+			".$this->getPeerClassname()."::addSelectColumns(\$criteria);
+		}
+		
+		\$criteria->clearOrderByColumns(); // ORDER BY won't ever affect the count
+		
+		// Set the correct dbName
+		\$criteria->setDbName(self::DATABASE_NAME);
+
+		if (\$con === null) {
+			\$con = Propel::getConnection(".$this->getPeerClassname()."::DATABASE_NAME, Propel::CONNECTION_READ);
+		}
+";
+
+		foreach ($table->getForeignKeys() as $fk) {
+			// want to cover this case, but the code is not there yet.
+			if ( $fk->getForeignTableName() != $table->getName() ) {
+				$joinTable = $table->getDatabase()->getTable($fk->getForeignTableName());
+				$joinedTablePeerBuilder = $this->getNewPeerBuilder($joinTable);
+
+				$joinClassName = $joinedTablePeerBuilder->getObjectClassname();
+
+				$lfMap = $fk->getLocalForeignMapping();
+				$left = array();
+				$right = array();
+				foreach ($fk->getLocalColumns() as $columnName ) {
+					array_push($left, $this->getColumnConstant($table->getColumn($columnName) ) );
+					array_push($right, $joinedTablePeerBuilder->getColumnConstant($joinTable->getColumn( $lfMap[$columnName] ) ) );
+				}
+				$script .= "
+		\$criteria->addJoin(array(";
+				foreach ($left as $lCol) {
+					$script .= $lCol;
+					if ($lCol != $left[count($left)]) {
+						$script .= ",";
+					}
+				}
+				$script .= "), array(";
+				foreach ($right as $rCol) {
+					$script .= $rCol;
+					if ($rCol != $right[count($right)]) {
+						$script .= ",";
+					}
+				}
+				$script .= "), \$join_behavior);";
+			} // if fk->getForeignTableName != table->getName
+		} // foreach [sub] foreign keys
+
+		$script .= "
+		\$stmt = ".$this->basePeerClassname."::doCount(\$criteria, \$con);
+
+		if (\$row = \$stmt->fetch(PDO::FETCH_NUM)) {
+			\$count = (int) \$row[0];
+		} else {
+			\$count = 0; // no rows returned; we infer that means 0 matches.
+		}
+		\$stmt->closeCursor();
+		return \$count;
+	}";
+	} // end addDoCountJoinAll()
+
+	/**
+	 * Adds the doSelectJoinAllExcept*() methods.
+	 * @param      string &$script The script will be modified in this method.
+	 */
+	protected function addDoSelectJoinAllExcept(&$script)
+	{
+		$table = $this->getTable();
+		$join_behavior = $this->getJoinBehavior();
+
+		// ------------------------------------------------------------------------
+		// doSelectJoinAllExcept*()
+		// ------------------------------------------------------------------------
+
+		// 2) create a bunch of doSelectJoinAllExcept*() methods
+		// -- these were existing in original Torque, so we should keep them for compatibility
+
+		$fkeys = $table->getForeignKeys();  // this sep assignment is necessary otherwise sub-loops over
+		// getForeignKeys() will cause this to only execute one time.
+		foreach ($fkeys as $fk ) {
+
+			$tblFK = $table->getDatabase()->getTable($fk->getForeignTableName());
+
+			$excludedTable = $table->getDatabase()->getTable($fk->getForeignTableName());
+
+			$thisTableObjectBuilder = $this->getNewObjectBuilder($table);
+			$excludedTableObjectBuilder = $this->getNewObjectBuilder($excludedTable);
+			$excludedTablePeerBuilder = $this->getNewPeerBuilder($excludedTable);
+
+			$excludedClassName = $excludedTableObjectBuilder->getObjectClassname();
+
+
+			$script .= "
+
+	/**
+	 * Selects a collection of ".$this->getObjectClassname()." objects pre-filled with all related objects except ".$thisTableObjectBuilder->getFKPhpNameAffix($fk).".
+	 *
+	 * @param      Criteria  \$c
+	 * @param      PropelPDO \$con
+	 * @param      String    \$join_behavior the type of joins to use, defaults to $join_behavior
+	 * @return     array Array of ".$this->getObjectClassname()." objects.
+	 * @throws     PropelException Any exceptions caught during processing will be
+	 *		 rethrown wrapped into a PropelException.
+	 */
+	public static function doSelectJoinAllExcept".$thisTableObjectBuilder->getFKPhpNameAffix($fk, $plural = false)."(Criteria \$c, \$con = null, \$join_behavior = $join_behavior)
+	{
+		\$c = clone \$c;
+
+		// Set the correct dbName if it has not been overridden
+		// \$c->getDbName() will return the same object if not set to another value
+		// so == check is okay and faster
+		if (\$c->getDbName() == Propel::getDefaultDB()) {
+			\$c->setDbName(self::DATABASE_NAME);
+		}
+
+		".$this->getPeerClassname()."::addSelectColumns(\$c);
+		\$startcol2 = (".$this->getPeerClassname()."::NUM_COLUMNS - ".$this->getPeerClassname()."::NUM_LAZY_LOAD_COLUMNS);
+";
+			$index = 2;
+			foreach ($table->getForeignKeys() as $subfk) {
+				// want to cover this case, but the code is not there yet.
+				// Why not? - because we would have to alias the tables in the join
+				if ( !($subfk->getForeignTableName() == $table->getName())) {
+					$joinTable = $table->getDatabase()->getTable($subfk->getForeignTableName());
+					$joinTablePeerBuilder = $this->getNewPeerBuilder($joinTable);
+					$joinClassName = $joinTablePeerBuilder->getObjectClassname();
+
+					if ($joinClassName != $excludedClassName) {
+						$new_index = $index + 1;
+						$script .= "
+		".$joinTablePeerBuilder->getPeerClassname()."::addSelectColumns(\$c);
+		\$startcol$new_index = \$startcol$index + (".$joinTablePeerBuilder->getPeerClassname()."::NUM_COLUMNS - ".$joinTablePeerBuilder->getPeerClassname()."::NUM_LAZY_LOAD_COLUMNS);
+";
+						$index = $new_index;
+					} // if joinClassName not excludeClassName
+				} // if subfk is not curr table
+			} // foreach [sub] foreign keys
+
+			foreach ($table->getForeignKeys() as $subfk) {
+				// want to cover this case, but the code is not there yet.
+				if ( $subfk->getForeignTableName() != $table->getName() ) {
+					$joinTable = $table->getDatabase()->getTable($subfk->getForeignTableName());
+					$joinTablePeerBuilder = $this->getNewPeerBuilder($joinTable);
+					$joinClassName = $joinTablePeerBuilder->getObjectClassname();
+
+					if ($joinClassName != $excludedClassName)
+					{
+						$lfMap = $subfk->getLocalForeignMapping();
+						$left = array();
+						$right = array();
+						foreach ($subfk->getLocalColumns() as $columnName ) {
+							array_push($left, $this->getColumnConstant($table->getColumn($columnName) ) );
+							array_push($right, $joinTablePeerBuilder->getColumnConstant($joinTable->getColumn( $lfMap[$columnName] ) ) );
+						}
+						$script .= "
+				\$c->addJoin(array(";
+						foreach ($left as $lCol) {
+							$script .= $lCol;
+							if ($lCol != $left[count($left)]) {
+								$script .= ",";
+							}
+						}
+						$script .= "), array(";
+						foreach ($right as $rCol) {
+							$script .= $rCol;
+							if ($rCol != $right[count($right)]) {
+								$script .= ",";
+							}
+						}
+						$script .= "), \$join_behavior);";
+					}
+				}
+			} // foreach fkeys
+			$script .= "
+
+		\$stmt = ".$this->basePeerClassname ."::doSelect(\$c, \$con);
+		\$results = array();
+
+		while (\$row = \$stmt->fetch(PDO::FETCH_NUM)) {
+			\$key1 = ".$this->getPeerClassname()."::getPrimaryKeyHashFromRow(\$row, 0);
+			if (null !== (\$obj1 = ".$this->getPeerClassname()."::getInstanceFromPool(\$key1))) {
+				// We no longer rehydrate the object, since this can cause data loss.
+				// See http://propel.phpdb.org/trac/ticket/509
+				// \$obj1->hydrate(\$row, 0, true); // rehydrate
+			} else {";
+			if ($table->getChildrenColumn()) {
+				$script .= "
+				\$omClass = ".$this->getPeerClassname()."::getOMClass(\$row, 0);
+";
+			} else {
+				$script .= "
+				\$omClass = ".$this->getPeerClassname()."::getOMClass();
+";
+			}
+
+			$script .= "
+				\$cls = substr('.'.\$omClass, strrpos('.'.\$omClass, '.') + 1);
+				" . $this->buildObjectInstanceCreationCode('$obj1', '$cls') . "
+				\$obj1->hydrate(\$row);
+				".$this->getPeerClassname()."::addInstanceToPool(\$obj1, \$key1);
+			} // if obj1 already loaded
+";
+
+			$index = 1;
+			foreach ($table->getForeignKeys() as $subfk ) {
+		  // want to cover this case, but the code is not there yet.
+		  if ( $subfk->getForeignTableName() != $table->getName() ) {
+
+		  	$joinTable = $table->getDatabase()->getTable($subfk->getForeignTableName());
+
+		  	$joinedTableObjectBuilder = $this->getNewObjectBuilder($joinTable);
+		  	$joinedTablePeerBuilder = $this->getNewPeerBuilder($joinTable);
+
+		  	$joinClassName = $joinedTableObjectBuilder->getObjectClassname();
+
+		  	$interfaceName = $joinClassName;
+		  	if ($joinTable->getInterface()) {
+		  		$interfaceName = $this->prefixClassname($joinTable->getInterface());
+		  	}
+
+		  	if ($joinClassName != $excludedClassName) {
+
+		  		$index++;
+
+		  		$script .= "
+				// Add objects for joined $joinClassName rows
+
+				\$key$index = ".$joinedTablePeerBuilder->getPeerClassname()."::getPrimaryKeyHashFromRow(\$row, \$startcol$index);
+				if (\$key$index !== null) {
+					\$obj$index = ".$joinedTablePeerBuilder->getPeerClassname()."::getInstanceFromPool(\$key$index);
+					if (!\$obj$index) {
+	";
+
+		  		if ($joinTable->getChildrenColumn()) {
+		  			$script .= "
+						\$omClass = ".$joinedTablePeerBuilder->getPeerClassname()."::getOMClass(\$row, \$startcol$index);
+";
+		  		} else {
+		  			$script .= "
+						\$omClass = ".$joinedTablePeerBuilder->getPeerClassname()."::getOMClass();
+";
+		  		} /* $joinTable->getChildrenColumn() */
+		  		$script .= "
+
+					\$cls = substr('.'.\$omClass, strrpos('.'.\$omClass, '.') + 1);
+					" . $this->buildObjectInstanceCreationCode('$obj' . $index, '$cls') . "
+					\$obj".$index."->hydrate(\$row, \$startcol$index);
+					".$joinedTablePeerBuilder->getPeerClassname()."::addInstanceToPool(\$obj$index, \$key$index);
+				} // if \$obj$index already loaded
+
+				// Add the \$obj1 (".$this->getObjectClassname().") to the collection in \$obj".$index." (".$joinedTablePeerBuilder->getObjectClassname().")
+				\$obj".$index."->".($fk->isLocalPrimaryKey() ? 'set' : 'add') . $joinedTableObjectBuilder->getRefFKPhpNameAffix($fk, $plural = false)."(\$obj1);
+
+			} // if joined row is not null
+";
+					} // if ($joinClassName != $excludedClassName) {
+		  } // $subfk->getForeignTableName() != $table->getName()
+			} // foreach
+			$script .= "
+			\$results[] = \$obj1;
+		}
+		\$stmt->closeCursor();
+		return \$results;
+	}
+";
+		} // foreach fk
+
+	} // addDoSelectJoinAllExcept
+
+	/**
+	 * Adds the doCountJoinAllExcept*() methods.
+	 * @param      string &$script The script will be modified in this method.
+	 */
+	protected function addDoCountJoinAllExcept(&$script)
+	{
+		$table = $this->getTable();
+		$join_behavior = $this->getJoinBehavior();
+
+		$fkeys = $table->getForeignKeys();  // this sep assignment is necessary otherwise sub-loops over
+		// getForeignKeys() will cause this to only execute one time.
+		foreach ($fkeys as $fk ) {
+
+			$tblFK = $table->getDatabase()->getTable($fk->getForeignTableName());
+
+			$excludedTable = $table->getDatabase()->getTable($fk->getForeignTableName());
+
+			$thisTableObjectBuilder = $this->getNewObjectBuilder($table);
+			$excludedTableObjectBuilder = $this->getNewObjectBuilder($excludedTable);
+			$excludedTablePeerBuilder = $this->getNewPeerBuilder($excludedTable);
+
+			$excludedClassName = $excludedTableObjectBuilder->getObjectClassname();
+
+			$script .= "
+
+	/**
+	 * Returns the number of rows matching criteria, joining the related ".$thisTableObjectBuilder->getFKPhpNameAffix($fk, $plural = false)." table
+	 *
+	 * @param      Criteria \$c
+	 * @param      boolean \$distinct Whether to select only distinct columns; deprecated: use Criteria->setDistinct() instead.
+	 * @param      PropelPDO \$con
+	 * @param      String    \$join_behavior the type of joins to use, defaults to $join_behavior
+	 * @return     int Number of matching rows.
+	 */
+	public static function doCountJoinAllExcept".$thisTableObjectBuilder->getFKPhpNameAffix($fk, $plural = false)."(Criteria \$criteria, \$distinct = false, PropelPDO \$con = null, \$join_behavior = $join_behavior)
+	{
+		// we're going to modify criteria, so copy it first
+		\$criteria = clone \$criteria;
+
+		// We need to set the primary table name, since in the case that there are no WHERE columns
+		// it will be impossible for the BasePeer::createSelectSql() method to determine which
+		// tables go into the FROM clause.
+		\$criteria->setPrimaryTableName(".$this->getPeerClassname()."::TABLE_NAME);
+		
+		if (\$distinct && !in_array(Criteria::DISTINCT, \$criteria->getSelectModifiers())) {
+			\$criteria->setDistinct();
+		}
+
+		if (!\$criteria->hasSelectClause()) {
+			".$this->getPeerClassname()."::addSelectColumns(\$criteria);
+		}
+		
+		\$criteria->clearOrderByColumns(); // ORDER BY should not affect count
+		
+		// Set the correct dbName
+		\$criteria->setDbName(self::DATABASE_NAME);
+
+		if (\$con === null) {
+			\$con = Propel::getConnection(".$this->getPeerClassname()."::DATABASE_NAME, Propel::CONNECTION_READ);
+		}
+	";
+
+			foreach ($table->getForeignKeys() as $subfk) {
+				// want to cover this case, but the code is not there yet.
+				if ( $subfk->getForeignTableName() != $table->getName() ) {
+					$joinTable = $table->getDatabase()->getTable($subfk->getForeignTableName());
+					$joinTablePeerBuilder = $this->getNewPeerBuilder($joinTable);
+					$joinClassName = $joinTablePeerBuilder->getObjectClassname();
+
+					if ($joinClassName != $excludedClassName)
+					{
+						$lfMap = $subfk->getLocalForeignMapping();
+						$left = array();
+						$right = array();
+						foreach ($subfk->getLocalColumns() as $columnName ) {
+							array_push($left, $this->getColumnConstant($table->getColumn($columnName) ) );
+							array_push($right, $joinTablePeerBuilder->getColumnConstant($joinTable->getColumn( $lfMap[$columnName] ) ) );
+						}
+						$script .= "
+				\$criteria->addJoin(array(";
+						foreach ($left as $lCol) {
+							$script .= $lCol;
+							if ($lCol != $left[count($left)]) {
+								$script .= ",";
+							}
+						}
+						$script .= "), array(";
+						foreach ($right as $rCol) {
+							$script .= $rCol;
+							if ($rCol != $right[count($right)]) {
+								$script .= ",";
+							}
+						}
+						$script .= "), \$join_behavior);";
+					}
+				}
+			} // foreach fkeys
+			$script .= "
+		\$stmt = ".$this->basePeerClassname."::doCount(\$criteria, \$con);
+
+		if (\$row = \$stmt->fetch(PDO::FETCH_NUM)) {
+			\$count = (int) \$row[0];
+		} else {
+			\$count = 0; // no rows returned; we infer that means 0 matches.
+		}
+		\$stmt->closeCursor();
+		return \$count;
+	}
+";
+		} // foreach fk
+
+	} // addDoCountJoinAllExcept
+
+	/**
+	 * returns the desired join behavior as set in the build properties
+	 * see trac ticket #588, #491
+	 *
+	 */
+	protected function getJoinBehavior()
+	{
+		return $this->getGeneratorConfig()->getBuildProperty('useLeftJoinsInDoJoinMethods') ? 'Criteria::LEFT_JOIN' : 'Criteria::INNER_JOIN';
+	}
+
+} // PHP5PeerBuilder
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/builder/sql/DDLBuilder.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/builder/sql/DDLBuilder.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/builder/sql/DDLBuilder.php	(revision 19)
@@ -0,0 +1,177 @@
+<?php
+
+/*
+ *  $Id: DDLBuilder.php 1067 2008-08-06 07:37:21Z ron $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://propel.phpdb.org>.
+ */
+
+require_once 'propel/engine/builder/DataModelBuilder.php';
+
+/**
+ * Baseclass for SQL DDL-building classes.
+ *
+ * DDL-building classes are those that build all the SQL DDL for a single table.
+ *
+ * @author     Hans Lellelid <hans@xmpl.org>
+ * @package    propel.engine.builder.sql
+ */
+abstract class DDLBuilder extends DataModelBuilder {
+
+	/**
+	 * Builds the SQL for current table and returns it as a string.
+	 *
+	 * This is the main entry point and defines a basic structure that classes should follow.
+	 * In most cases this method will not need to be overridden by subclasses.
+	 *
+	 * @return     string The resulting SQL DDL.
+	 */
+	public function build()
+	{
+		$script = "";
+		$this->addTable($script);
+		$this->addIndices($script);
+		$this->addForeignKeys($script);
+		return $script;
+	}
+
+	/**
+	 * Gets the name to use for creating a sequence for the current table.
+	 *
+	 * This will create a new name or use one specified in an id-method-parameter
+	 * tag, if specified.
+	 *
+	 * @return     string Sequence name for this table.
+	 */
+	public function getSequenceName()
+	{
+		$table = $this->getTable();
+		static $longNamesMap = array();
+		$result = null;
+		if ($table->getIdMethod() == IDMethod::NATIVE) {
+			$idMethodParams = $table->getIdMethodParameters();
+			$maxIdentifierLength = $table->getDatabase()->getPlatform()->getMaxColumnNameLength();
+			if (empty($idMethodParams)) {
+				if (strlen($table->getName() . "_SEQ") > $maxIdentifierLength) {
+					if (!isset($longNamesMap[$table->getName()])) {
+						$longNamesMap[$table->getName()] = strval(count($longNamesMap) + 1);
+					}
+					$result = substr($table->getName(), 0, $maxIdentifierLength - strlen("_SEQ_" . $longNamesMap[$table->getName()])) . "_SEQ_" . $longNamesMap[$table->getName()];
+				}
+				else {
+					$result = substr($table->getName(), 0, $maxIdentifierLength -4) . "_SEQ";
+				}
+			} else {
+				$result = substr($idMethodParams[0]->getValue(), 0, $maxIdentifierLength);
+			}
+		}
+		return $result;
+	}
+
+	/**
+	 * Builds the DDL SQL for a Column object.
+	 * @return     string
+	 */
+	public function getColumnDDL(Column $col)
+	{
+		$platform = $this->getPlatform();
+		$domain = $col->getDomain();
+
+		$sb = "";
+		$sb .= $this->quoteIdentifier($col->getName()) . " ";
+		$sb .= $domain->getSqlType();
+		if ($platform->hasSize($domain->getSqlType())) {
+			$sb .= $domain->printSize();
+		}
+		$sb .= " ";
+		$sb .= $col->getDefaultSetting() . " ";
+		$sb .= $col->getNotNullString() . " ";
+		$sb .= $col->getAutoIncrementString();
+
+		return trim($sb);
+	}
+
+	/**
+	 * Creates a delimiter-delimited string list of column names, quoted using quoteIdentifier().
+	 * @param      array Column[] or string[]
+	 * @param      string $delim The delimiter to use in separating the column names.
+	 * @return     string
+	 */
+	public function getColumnList($columns, $delim=',')
+	{
+		$list = array();
+		foreach ($columns as $col) {
+			if ($col instanceof Column) {
+				$col = $col->getName();
+			}
+			$list[] = $this->quoteIdentifier($col);
+		}
+		return implode($delim, $list);
+	}
+
+	/**
+	 * This function adds any _database_ start/initialization SQL.
+	 * This is designed to be called for a database, not a specific table, hence it is static.
+	 * @return     string The DDL is returned as astring.
+	 */
+	public static function getDatabaseStartDDL()
+	{
+		return '';
+	}
+
+	/**
+	 * This function adds any _database_ end/cleanup SQL.
+	 * This is designed to be called for a database, not a specific table, hence it is static.
+	 * @return     string The DDL is returned as astring.
+	 */
+	public static function getDatabaseEndDDL()
+	{
+		return '';
+	}
+
+	/**
+	 * Resets any static variables between building a SQL file for a database.
+	 *
+	 * Theoretically, Propel could build multiple .sql files for multiple databases; in
+	 * many cases we don't want static values to persist between these.  This method provides
+	 * a way to clear out static values between iterations, if the subclasses choose to implement
+	 * it.
+	 */
+	public static function reset()
+	{
+		// nothing by default
+	}
+
+	/**
+	 * Adds table definition.
+	 * @param      string &$script The script will be modified in this method.
+	 */
+	abstract protected function addTable(&$script);
+
+	/**
+	 * Adds index definitions.
+	 * @param      string &$script The script will be modified in this method.
+	 */
+	abstract protected function addIndices(&$script);
+
+	/**
+	 * Adds foreign key constraint definitions.
+	 * @param      string &$script The script will be modified in this method.
+	 */
+	abstract protected function addForeignKeys(&$script);
+
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/builder/sql/DataSQLBuilder.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/builder/sql/DataSQLBuilder.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/builder/sql/DataSQLBuilder.php	(revision 19)
@@ -0,0 +1,264 @@
+<?php
+
+/*
+ *  $Id: DataSQLBuilder.php 989 2008-03-11 14:29:30Z heltem $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://propel.phpdb.org>.
+ */
+
+require_once 'propel/engine/builder/DataModelBuilder.php';
+require_once 'propel/engine/database/model/PropelTypes.php';
+
+/**
+ * Baseclass for SQL data dump SQL building classes.
+ *
+ * @author     Hans Lellelid <hans@xmpl.org>
+ * @package    propel.engine.builder.sql
+ */
+abstract class DataSQLBuilder extends DataModelBuilder {
+
+	/**
+	 * Perform any reset between runs of this builder.
+	 *
+	 * This can be used, for example, to clear any stored start/end SQL.
+	 */
+	public static function reset()
+	{
+		// does nothing by default
+	}
+
+	/**
+	 * Gets any SQL to place at the start of all the row inserts.
+	 *
+	 * @return     string
+	 */
+	public static function getDatabaseStartSql()
+	{
+		return '';
+	}
+
+	/**
+	 * Gets any SQL to place at the end of all the row inserts.
+	 *
+	 * @return     string
+	 */
+	public static function getDatabaseEndSql()
+	{
+		return '';
+	}
+
+	/**
+	 * Gets any SQL to place before row inserts for a new table.
+	 *
+	 * @return     string
+	 */
+	public function getTableStartSql()
+	{
+		return '';
+	}
+
+	/**
+	 * Gets any SQL to place at the end of row inserts for a table.
+	 *
+	 * @return     string
+	 */
+	public function getTableEndSql()
+	{
+		return '';
+	}
+
+	/**
+	 * The main method in this class, returns the SQL for INSERTing data into a row.
+	 * @param      DataRow $row The row to process.
+	 * @return     string
+	 */
+	public function buildRowSql(DataRow $row)
+	{
+		$sql = "";
+		$platform = $this->getPlatform();
+		$table = $this->getTable();
+
+		$sql .= "INSERT INTO ".$this->quoteIdentifier($this->prefixTablename($this->getTable()->getName()))." (";
+
+		// add column names to SQL
+		$colNames = array();
+		foreach ($row->getColumnValues() as $colValue) {
+			$colNames[] = $this->quoteIdentifier($colValue->getColumn()->getName());
+		}
+
+		$sql .= implode(',', $colNames);
+
+		$sql .= ") VALUES (";
+
+		$colVals = array();
+		foreach ($row->getColumnValues() as $colValue) {
+			$colVals[] = $this->getColumnValueSql($colValue);
+		}
+
+		$sql .= implode(',', $colVals);
+		$sql .= ");
+";
+
+		return $sql;
+	}
+
+	/**
+	 * Gets the propertly escaped (and quoted) value for a column.
+	 * @param      ColumnValue $colValue
+	 * @return     mixed The proper value to be added to the string.
+	 */
+	protected function getColumnValueSql(ColumnValue $colValue)
+	{
+		$column = $colValue->getColumn();
+		$method = 'get' . $column->getPhpNative() . 'Sql';
+		return $this->$method($colValue->getValue());
+	}
+
+
+
+	/**
+	 * Gets a representation of a binary value suitable for use in a SQL statement.
+	 * Default behavior is true = 1, false = 0.
+	 * @param      boolean $value
+	 * @return     int
+	 */
+	protected function getBooleanSql($value)
+	{
+		return (int) $value;
+	}
+
+
+	/**
+	 * Gets a representation of a BLOB/LONGVARBINARY value suitable for use in a SQL statement.
+	 * @param      mixed $blob Blob object or string data.
+	 * @return     string
+	 */
+	protected function getBlobSql($blob)
+	{
+		// they took magic __toString() out of PHP5.0.0; this sucks
+		if (is_object($blob)) {
+			return $this->getPlatform()->quote($blob->__toString());
+		} else {
+			return $this->getPlatform()->quote($blob);
+		}
+	}
+
+	/**
+	 * Gets a representation of a CLOB/LONGVARCHAR value suitable for use in a SQL statement.
+	 * @param      mixed $clob Clob object or string data.
+	 * @return     string
+	 */
+	protected function getClobSql($clob)
+	{
+		// they took magic __toString() out of PHP5.0.0; this sucks
+		if (is_object($clob)) {
+			return $this->getPlatform()->quote($clob->__toString());
+		} else {
+			return $this->getPlatform()->quote($clob);
+		}
+	}
+
+	/**
+	 * Gets a representation of a date value suitable for use in a SQL statement.
+	 * @param      string $value
+	 * @return     string
+	 */
+	protected function getDateSql($value)
+	{
+		return "'" . date('Y-m-d', strtotime($value)) . "'";
+	}
+
+	/**
+	 * Gets a representation of a decimal value suitable for use in a SQL statement.
+	 * @param      double $value
+	 * @return     float
+	 */
+	protected function getDecimalSql($value)
+	{
+		return (float) $value;
+	}
+
+	/**
+	 * Gets a representation of a double value suitable for use in a SQL statement.
+	 * @param      double $value
+	 * @return     double
+	 */
+	protected function getDoubleSql($value)
+	{
+		return (double) $value;
+	}
+
+	/**
+	 * Gets a representation of a float value suitable for use in a SQL statement.
+	 * @param      float $value
+	 * @return     float
+	 */
+	protected function getFloatSql($value)
+	{
+		return (float) $value;
+	}
+
+	/**
+	 * Gets a representation of an integer value suitable for use in a SQL statement.
+	 * @param      int $value
+	 * @return     int
+	 */
+	protected function getIntSql($value)
+	{
+		return (int) $value;
+	}
+
+	/**
+	 * Gets a representation of a NULL value suitable for use in a SQL statement.
+	 * @return     null
+	 */
+	protected function getNullSql()
+	{
+		return 'NULL';
+	}
+
+	/**
+	 * Gets a representation of a string value suitable for use in a SQL statement.
+	 * @param      string $value
+	 * @return     string
+	 */
+	protected function getStringSql($value)
+	{
+		return $this->getPlatform()->quote($value);
+	}
+
+	/**
+	 * Gets a representation of a time value suitable for use in a SQL statement.
+	 * @param      string $value
+	 * @return     string
+	 */
+	protected function getTimeSql($paramIndex, $value)
+	{
+		return "'" . date('H:i:s', strtotime($value)) . "'";
+	}
+
+	/**
+	 * Gets a representation of a timestamp value suitable for use in a SQL statement.
+	 * @param      string $value
+	 * @return     string
+	 */
+	function getTimestampSql($value)
+	{
+		return "'" . date('Y-m-d H:i:s', strtotime($value)) . "'";
+	}
+
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/builder/sql/mssql/MssqlDDLBuilder.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/builder/sql/mssql/MssqlDDLBuilder.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/builder/sql/mssql/MssqlDDLBuilder.php	(revision 19)
@@ -0,0 +1,185 @@
+<?php
+
+/*
+ *  $Id: MssqlDDLBuilder.php 949 2008-01-30 22:41:59Z hans $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://propel.phpdb.org>.
+ */
+
+require_once 'propel/engine/builder/sql/DDLBuilder.php';
+
+/**
+ * The SQL DDL-building class for MS SQL Server.
+ *
+ *
+ * @author     Hans Lellelid <hans@xmpl.org>
+ * @package    propel.engine.builder.sql.pgsql
+ */
+class MssqlDDLBuilder extends DDLBuilder {
+
+	private static $dropCount = 0;
+
+	/**
+	 *
+	 * @see        parent::addDropStatement()
+	 */
+	protected function addDropStatements(&$script)
+	{
+		$table = $this->getTable();
+		$platform = $this->getPlatform();
+
+		foreach ($table->getForeignKeys() as $fk) {
+			$script .= "
+IF EXISTS (SELECT 1 FROM sysobjects WHERE type ='RI' AND name='".$fk->getName()."')
+	ALTER TABLE ".$this->quoteIdentifier($this->prefixTablename($table->getName()))." DROP CONSTRAINT ".$this->quoteIdentifier($fk->getName()).";
+";
+		}
+
+
+		self::$dropCount++;
+
+		$script .= "
+IF EXISTS (SELECT 1 FROM sysobjects WHERE type = 'U' AND name = '".$this->prefixTablename($table->getName())."')
+BEGIN
+	 DECLARE @reftable_".self::$dropCount." nvarchar(60), @constraintname_".self::$dropCount." nvarchar(60)
+	 DECLARE refcursor CURSOR FOR
+	 select reftables.name tablename, cons.name constraintname
+	  from sysobjects tables,
+		   sysobjects reftables,
+		   sysobjects cons,
+		   sysreferences ref
+	   where tables.id = ref.rkeyid
+		 and cons.id = ref.constid
+		 and reftables.id = ref.fkeyid
+		 and tables.name = '".$this->prefixTablename($table->getName())."'
+	 OPEN refcursor
+	 FETCH NEXT from refcursor into @reftable_".self::$dropCount.", @constraintname_".self::$dropCount."
+	 while @@FETCH_STATUS = 0
+	 BEGIN
+	   exec ('alter table '+@reftable_".self::$dropCount."+' drop constraint '+@constraintname_".self::$dropCount.")
+	   FETCH NEXT from refcursor into @reftable_".self::$dropCount.", @constraintname_".self::$dropCount."
+	 END
+	 CLOSE refcursor
+	 DEALLOCATE refcursor
+	 DROP TABLE ".$this->quoteIdentifier($this->prefixTablename($table->getName()))."
+END
+";
+	}
+
+	/**
+	 * @see        parent::addColumns()
+	 */
+	protected function addTable(&$script)
+	{
+		$table = $this->getTable();
+		$platform = $this->getPlatform();
+
+		$script .= "
+/* ---------------------------------------------------------------------- */
+/* ".$table->getName()."											*/
+/* ---------------------------------------------------------------------- */
+
+";
+
+		$this->addDropStatements($script);
+
+		$script .= "
+
+CREATE TABLE ".$this->quoteIdentifier($this->prefixTablename($table->getName()))."
+(
+	";
+
+		$lines = array();
+
+		foreach ($table->getColumns() as $col) {
+			$lines[] = $this->getColumnDDL($col);
+		}
+
+		if ($table->hasPrimaryKey()) {
+			$lines[] = "CONSTRAINT ".$this->quoteIdentifier($table->getName()."_PK") . " PRIMARY KEY (".$this->getColumnList($table->getPrimaryKey()).")";
+		}
+
+		foreach ($table->getUnices() as $unique ) {
+			$lines[] = "UNIQUE (".$this->getColumnList($unique->getColumns()).")";
+		}
+
+		$sep = ",
+	";
+		$script .= implode($sep, $lines);
+		$script .= "
+);
+";
+	}
+
+	/**
+	 * Adds CREATE INDEX statements for this table.
+	 * @see        parent::addIndices()
+	 */
+	protected function addIndices(&$script)
+	{
+		$table = $this->getTable();
+		$platform = $this->getPlatform();
+
+		foreach ($table->getIndices() as $index) {
+			$script .= "
+CREATE ";
+			if ($index->getIsUnique()) {
+				$script .= "UNIQUE";
+			}
+			$script .= "INDEX ".$this->quoteIdentifier($index->getName())." ON ".$this->quoteIdentifier($this->prefixTablename($table->getName()))." (".$this->getColumnList($index->getColumns()).");
+";
+		}
+	}
+
+	/**
+	 *
+	 * @see        parent::addForeignKeys()
+	 */
+	protected function addForeignKeys(&$script)
+	{
+		$table = $this->getTable();
+		$platform = $this->getPlatform();
+
+		foreach ($table->getForeignKeys() as $fk) {
+			$script .= "
+BEGIN
+ALTER TABLE ".$this->quoteIdentifier($this->prefixTablename($table->getName()))." ADD CONSTRAINT ".$this->quoteIdentifier($fk->getName())." FOREIGN KEY (".$this->getColumnList($fk->getLocalColumns()) .") REFERENCES ".$this->quoteIdentifier($this->prefixTablename($fk->getForeignTableName()))." (".$this->getColumnList($fk->getForeignColumns()).")";
+			if ($fk->hasOnUpdate()) {
+				if ($fk->getOnUpdate() == ForeignKey::SETNULL) { // there may be others that also won't work
+					// we have to skip this because it's unsupported.
+					$this->warn("MSSQL doesn't support the 'SET NULL' option for ON UPDATE (ignoring for ".$this->getColumnList($fk->getLocalColumns())." fk).");
+				} else {
+					$script .= " ON UPDATE ".$fk->getOnUpdate();
+				}
+
+			}
+			if ($fk->hasOnDelete()) {
+				if ($fk->getOnDelete() == ForeignKey::SETNULL) { // there may be others that also won't work
+					// we have to skip this because it's unsupported.
+					$this->warn("MSSQL doesn't support the 'SET NULL' option for ON DELETE (ignoring for ".$this->getColumnList($fk->getLocalColumns())." fk).");
+				} else {
+					$script .= " ON DELETE ".$fk->getOnDelete();
+				}
+			}
+			$script .= "
+END
+;
+";
+		}
+	}
+
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/builder/sql/mssql/MssqlDataSQLBuilder.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/builder/sql/mssql/MssqlDataSQLBuilder.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/builder/sql/mssql/MssqlDataSQLBuilder.php	(revision 19)
@@ -0,0 +1,48 @@
+<?php
+
+/*
+ *  $Id: MssqlDataSQLBuilder.php 521 2007-01-05 13:29:36Z heltem $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://propel.phpdb.org>.
+ */
+
+require_once 'propel/engine/builder/sql/DataSQLBuilder.php';
+
+/**
+ * MS SQL Server class for building data dump SQL.
+ *
+ * @author     Hans Lellelid <hans@xmpl.org>
+ * @package    propel.engine.builder.sql.mssql
+ */
+class MssqlDataSQLBuilder extends DataSQLBuilder {
+
+	/**
+	 *
+	 * @param      mixed $blob Blob object or string containing data.
+	 * @return     string
+	 */
+	protected function getBlobSql($blob)
+	{
+		// they took magic __toString() out of PHP5.0.0; this sucks
+		if (is_object($blob)) {
+			$blob = $blob->__toString();
+		}
+		$data = unpack("H*hex", $blob);
+		return '0x'.$data['hex']; // no surrounding quotes!
+	}
+
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/builder/sql/mysql/MysqlDDLBuilder.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/builder/sql/mysql/MysqlDDLBuilder.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/builder/sql/mysql/MysqlDDLBuilder.php	(revision 19)
@@ -0,0 +1,383 @@
+<?php
+
+/*
+ *  $Id: MysqlDDLBuilder.php 989 2008-03-11 14:29:30Z heltem $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://propel.phpdb.org>.
+ */
+
+require_once 'propel/engine/builder/sql/DDLBuilder.php';
+
+/**
+ * DDL Builder class for MySQL.
+ *
+ * @author     David Zï¿œlke
+ * @author     Hans Lellelid <hans@xmpl.org>
+ * @package    propel.engine.builder.sql.mysql
+ */
+class MysqlDDLBuilder extends DDLBuilder {
+
+	/**
+	 * Returns some header SQL that disables foreign key checking.
+	 * @return     string DDL
+	 */
+	public static function getDatabaseStartDDL()
+	{
+		$ddl = "
+# This is a fix for InnoDB in MySQL >= 4.1.x
+# It \"suspends judgement\" for fkey relationships until are tables are set.
+SET FOREIGN_KEY_CHECKS = 0;
+";
+		return $ddl;
+	}
+
+	/**
+	 * Returns some footer SQL that re-enables foreign key checking.
+	 * @return     string DDL
+	 */
+	public static function getDatabaseEndDDL()
+	{
+		$ddl = "
+# This restores the fkey checks, after having unset them earlier
+SET FOREIGN_KEY_CHECKS = 1;
+";
+		return $ddl;
+	}
+
+
+	/**
+	 *
+	 * @see        parent::addDropStatement()
+	 */
+	protected function addDropStatements(&$script)
+	{
+		$script .= "
+DROP TABLE IF EXISTS ".$this->quoteIdentifier($this->prefixTablename($this->getTable()->getName())).";
+";
+	}
+
+	/**
+	 * Builds the SQL for current table and returns it as a string.
+	 *
+	 * This is the main entry point and defines a basic structure that classes should follow.
+	 * In most cases this method will not need to be overridden by subclasses.
+	 *
+	 * @return     string The resulting SQL DDL.
+	 */
+	public function build()
+	{
+		$script = "";
+		$this->addTable($script);
+		return $script;
+	}
+
+	/**
+	 *
+	 * @see        parent::addColumns()
+	 */
+	protected function addTable(&$script)
+	{
+		$table = $this->getTable();
+		$platform = $this->getPlatform();
+
+		$script .= "
+#-----------------------------------------------------------------------------
+#-- ".$table->getName()."
+#-----------------------------------------------------------------------------
+";
+
+		$this->addDropStatements($script);
+
+		$script .= "
+
+CREATE TABLE ".$this->quoteIdentifier($this->prefixTablename($table->getName()))."
+(
+	";
+
+		$lines = array();
+
+		$databaseType = $this->getPlatform()->getDatabaseType();
+
+		foreach ($table->getColumns() as $col) {
+			$entry = $this->getColumnDDL($col);
+			$colinfo = $col->getVendorInfoForType($databaseType);
+			if ( $colinfo->hasParameter('Charset') ) {
+				$entry .= ' CHARACTER SET '.$platform->quote($colinfo->getParamter('Charset'));
+			}
+			if ( $colinfo->hasParameter('Collate') ) {
+				$entry .= ' COLLATE '.$platform->quote($colinfo->getParamter('Collate'));
+			}
+			if ($col->getDescription()) {
+				$entry .= " COMMENT ".$platform->quote($col->getDescription());
+			}
+			$lines[] = $entry;
+		}
+
+		if ($table->hasPrimaryKey()) {
+			$lines[] = "PRIMARY KEY (".$this->getColumnList($table->getPrimaryKey()).")";
+		}
+
+		$this->addIndicesLines($lines);
+		$this->addForeignKeysLines($lines);
+
+		$sep = ",
+	";
+		$script .= implode($sep, $lines);
+
+		$script .= "
+)";
+
+		$mysqlTableType = $this->getBuildProperty("mysqlTableType");
+		if (!$mysqlTableType) {
+			$vendorSpecific = $table->getVendorInfoForType($this->getPlatform()->getDatabaseType());
+			if ($vendorSpecific->hasParameter('Type')) {
+				$mysqlTableType = $vendorSpecific->getParameter('Type');
+			} elseif ($vendorSpecific->hasParameter('Engine')) {
+				$mysqlTableType = $vendorSpecific->getParameter('Engine');
+			} else {
+				$mysqlTableType = 'MyISAM';
+			}
+		}
+
+		$script .= "Type=$mysqlTableType";
+
+		$dbVendorSpecific = $table->getDatabase()->getVendorInfoForType($databaseType);
+		$tableVendorSpecific = $table->getVendorInfoForType($databaseType);
+		$vendorSpecific = $dbVendorSpecific->getMergedVendorInfo($tableVendorSpecific);
+
+		if ( $vendorSpecific->hasParameter('Charset') ) {
+			$script .= ' CHARACTER SET '.$platform->quote($vendorSpecific->getParameter('Charset'));
+		}
+		if ( $vendorSpecific->hasParameter('Collate') ) {
+			$script .= ' COLLATE '.$platform->quote($vendorSpecific->getParameter('Collate'));
+		}
+		if ( $vendorSpecific->hasParameter('Checksum') ) {
+			$script .= ' CHECKSUM='.$platform->quote($vendorSpecific->getParameter('Checksum'));
+		}
+		if ( $vendorSpecific->hasParameter('Pack_Keys') ) {
+			$script .= ' PACK_KEYS='.$platform->quote($vendorSpecific->getParameter('Pack_Keys'));
+		}
+		if ( $vendorSpecific->hasParameter('Delay_key_write') ) {
+			$script .= ' DELAY_KEY_WRITE='.$platform->quote($vendorSpecific->getParameter('Delay_key_write'));
+		}
+
+		if ($table->getDescription()) {
+			$script .= " COMMENT=".$platform->quote($table->getDescription());
+		}
+		$script .= ";
+";
+	}
+
+	/**
+	 * Creates a comma-separated list of column names for the index.
+	 * For MySQL unique indexes there is the option of specifying size, so we cannot simply use
+	 * the getColumnsList() method.
+	 * @param      Index $index
+	 * @return     string
+	 */
+	private function getIndexColumnList(Index $index)
+	{
+		$platform = $this->getPlatform();
+
+		$cols = $index->getColumns();
+		$list = array();
+		foreach ($cols as $col) {
+			$list[] = $this->quoteIdentifier($col) . ($index->hasColumnSize($col) ? '(' . $index->getColumnSize($col) . ')' : '');
+		}
+		return implode(', ', $list);
+	}
+
+	/**
+	 * Adds indexes
+	 */
+	protected function addIndicesLines(&$lines)
+	{
+		$table = $this->getTable();
+		$platform = $this->getPlatform();
+
+		foreach ($table->getUnices() as $unique) {
+			$lines[] = "UNIQUE KEY ".$this->quoteIdentifier($unique->getName())." (".$this->getIndexColumnList($unique).")";
+		}
+
+		foreach ($table->getIndices() as $index ) {
+			$vendorInfo = $index->getVendorInfoForType($platform->getDatabaseType());
+			$lines[] .= (($vendorInfo && $vendorInfo->getParameter('Index_type') == 'FULLTEXT') ? 'FULLTEXT ' : '') . "KEY " . $this->quoteIdentifier($index->getName()) . "(" . $this->getIndexColumnList($index) . ")";
+		}
+
+	}
+
+	/**
+	 * Adds foreign key declarations & necessary indexes for mysql (if they don't exist already).
+	 * @see        parent::addForeignKeys()
+	 */
+	protected function addForeignKeysLines(&$lines)
+	{
+		$table = $this->getTable();
+		$platform = $this->getPlatform();
+
+
+		$_indices = array();
+		$_previousColumns = array();
+
+		// we're building an array of indices here which is smart about multi-column indices.
+		// for example, if we have to indices foo(ColA) and bar(ColB, ColC), we have actually three indices already defined:
+		// ColA, ColB+ColC, and ColB (but not ColC!). This is because of the way SQL multi-column indices work.
+		// we will later match found, defined foreign key and referenced column definitions against this array to know
+		// whether we should create a new index for mysql or not
+		foreach ($table->getPrimaryKey() as $_primaryKeyColumn) {
+			// do the above for primary keys
+			$_previousColumns[] = $this->quoteIdentifier($_primaryKeyColumn->getName());
+			$_indices[] = implode(',', $_previousColumns);
+		}
+
+		$_tableIndices = array_merge($table->getIndices(), $table->getUnices());
+		foreach ($_tableIndices as $_index) {
+			// same procedure, this time for unices and indices
+			$_previousColumns = array();
+			$_indexColumns = $_index->getColumns();
+			foreach ($_indexColumns as $_indexColumn) {
+				$_previousColumns[] = $this->quoteIdentifier($_indexColumn);
+				$_indices[] = implode(',', $_previousColumns);
+			}
+		}
+
+		// we're determining which tables have foreign keys that point to this table, since MySQL needs an index on
+		// any column that is referenced by another table (yep, MySQL _is_ a PITA)
+		$counter = 0;
+		$allTables = $table->getDatabase()->getTables();
+		foreach ($allTables as $_table) {
+			foreach ($_table->getForeignKeys() as $_foreignKey) {
+				if ($_foreignKey->getForeignTableName() == $table->getName()) {
+					if (!in_array($this->getColumnList($_foreignKey->getForeignColumns()), $_indices)) {
+						// no matching index defined in the schema, so we have to create one
+						$lines[] = "INDEX ".$this->quoteIdentifier("I_referenced_".$_foreignKey->getName()."_".(++$counter))." (" .$this->getColumnList($_foreignKey->getForeignColumns()).")";
+					}
+				}
+			}
+		}
+
+		foreach ($table->getForeignKeys() as $fk) {
+
+			$indexName = $this->quoteIdentifier(substr_replace($fk->getName(), 'FI_',  strrpos($fk->getName(), 'FK_'), 3));
+
+			if (!in_array($this->getColumnList($fk->getLocalColumns()), $_indices)) {
+				// no matching index defined in the schema, so we have to create one. MySQL needs indices on any columns that serve as foreign keys. these are not auto-created prior to 4.1.2
+				$lines[] = "INDEX $indexName (".$this->getColumnList($fk->getLocalColumns()).")";
+			}
+			$str = "CONSTRAINT ".$this->quoteIdentifier($fk->getName())."
+		FOREIGN KEY (".$this->getColumnList($fk->getLocalColumns()).")
+		REFERENCES ".$this->quoteIdentifier($this->prefixTablename($fk->getForeignTableName())) . " (".$this->getColumnList($fk->getForeignColumns()).")";
+			if ($fk->hasOnUpdate()) {
+				$str .= "
+		ON UPDATE ".$fk->getOnUpdate();
+			}
+			if ($fk->hasOnDelete()) {
+				$str .= "
+		ON DELETE ".$fk->getOnDelete();
+			}
+			$lines[] = $str;
+		}
+
+	}
+
+	/**
+	 * Checks whether passed-in array of Column objects contains a column with specified name.
+	 * @param      array Column[] or string[]
+	 * @param      string $searchcol Column name to search for
+	 */
+	private function containsColname($columns, $searchcol)
+	{
+		foreach ($columns as $col) {
+			if ($col instanceof Column) {
+				$col = $col->getName();
+			}
+			if ($col == $searchcol) {
+				return true;
+			}
+		}
+		return false;
+	}
+
+	/**
+	 * Not used for MySQL since foreign keys are declared inside table declaration.
+	 * @see        addForeignKeysLines()
+	 */
+	protected function addForeignKeys(&$script)
+	{
+	}
+
+	/**
+	 * Not used for MySQL since indexes are declared inside table declaration.
+	 * @see        addIndicesLines()
+	 */
+	protected function addIndices(&$script)
+	{
+	}
+
+	/**
+	 * Builds the DDL SQL for a Column object.
+	 * @return     string
+	 */
+	public function getColumnDDL(Column $col)
+	{
+		$platform = $this->getPlatform();
+		$domain = $col->getDomain();
+		$sqlType = $domain->getSqlType();
+		$notNullString = $col->getNotNullString();
+		$defaultSetting = $col->getDefaultSetting();
+
+		// Special handling of TIMESTAMP/DATETIME types ...
+		// See: http://propel.phpdb.org/trac/ticket/538
+		if ($sqlType == 'DATETIME') {
+			$def = $domain->getDefaultValue();
+			if ($def && $def->isExpression()) { // DATETIME values can only have constant expressions
+				$sqlType = 'TIMESTAMP';
+			}
+		} elseif ($sqlType == 'DATE') {
+			$def = $domain->getDefaultValue();
+			if ($def && $def->isExpression()) { // DATE values don't support expressions in MySQL
+				throw new EngineException("DATE columns cannot have default *expressions* in MySQL.");
+			}
+		}
+
+		$sb = "";
+		$sb .= $this->quoteIdentifier($col->getName()) . " ";
+		$sb .= $sqlType;
+		if ($platform->hasSize($sqlType)) {
+			$sb .= $domain->printSize();
+		}
+		$sb .= " ";
+
+		if ($sqlType == 'TIMESTAMP') {
+			$notNullString = $col->getNotNullString();
+			$defaultSetting = $col->getDefaultSetting();
+			if ($notNullString == '') {
+				$notNullString = 'NULL';
+			}
+			if ($defaultSetting == '' && $notNullString == 'NOT NULL') {
+				$defaultSetting = 'DEFAULT CURRENT_TIMESTAMP';
+			}
+			$sb .= $notNullString . " " . $defaultSetting . " ";
+		} else {
+			$sb .= $defaultSetting . " ";
+			$sb .= $notNullString . " ";
+		}
+		$sb .= $col->getAutoIncrementString();
+
+		return trim($sb);
+	}
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/builder/sql/mysql/MysqlDataSQLBuilder.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/builder/sql/mysql/MysqlDataSQLBuilder.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/builder/sql/mysql/MysqlDataSQLBuilder.php	(revision 19)
@@ -0,0 +1,33 @@
+<?php
+
+/*
+ *  $Id: MysqlDataSQLBuilder.php 521 2007-01-05 13:29:36Z heltem $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://propel.phpdb.org>.
+ */
+
+require_once 'propel/engine/builder/sql/DataSQLBuilder.php';
+
+/**
+ * MySQL class for building data dump SQL.
+ *
+ * @author     Hans Lellelid <hans@xmpl.org>
+ * @package    propel.engine.builder.sql.mysql
+ */
+class MysqlDataSQLBuilder extends DataSQLBuilder {
+
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/builder/sql/oracle/OracleDDLBuilder.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/builder/sql/oracle/OracleDDLBuilder.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/builder/sql/oracle/OracleDDLBuilder.php	(revision 19)
@@ -0,0 +1,176 @@
+<?php
+
+/*
+ *  $Id: OracleDDLBuilder.php 1026 2008-04-09 10:11:19Z hans $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://propel.phpdb.org>.
+ */
+
+require_once 'propel/engine/builder/sql/DDLBuilder.php';
+
+/**
+ * The SQL DDL-building class for Oracle.
+ *
+ *
+ * @author     Hans Lellelid <hans@xmpl.org>
+ * @package    propel.engine.builder.sql.pgsql
+ */
+class OracleDDLBuilder extends DDLBuilder {
+
+	/**
+	 *
+	 * @see        parent::addDropStatement()
+	 */
+	protected function addDropStatements(&$script)
+	{
+		$table = $this->getTable();
+		$platform = $this->getPlatform();
+		$script .= "
+DROP TABLE ".$this->quoteIdentifier($this->prefixTablename($table->getName()))." CASCADE CONSTRAINTS;
+";
+		if ($table->getIdMethod() == "native") {
+			$script .= "
+DROP SEQUENCE ".$this->quoteIdentifier($this->prefixTablename($this->getSequenceName())).";
+";
+		}
+	}
+
+	/**
+	 *
+	 * @see        parent::addColumns()
+	 */
+	protected function addTable(&$script)
+	{
+		$table = $this->getTable();
+		$script .= "
+
+/* -----------------------------------------------------------------------
+   ".$table->getName()."
+   ----------------------------------------------------------------------- */
+";
+
+		$this->addDropStatements($script);
+
+		$script .= "
+
+CREATE TABLE ".$this->quoteIdentifier($this->prefixTablename($table->getName()))."
+(
+	";
+
+		$lines = array();
+
+		foreach ($table->getColumns() as $col) {
+			$lines[] = $this->getColumnDDL($col);
+		}
+
+		$sep = ",
+	";
+		$script .= implode($sep, $lines);
+		$script .= "
+);
+";
+		$this->addPrimaryKey($script);
+		$this->addSequences($script);
+
+	}
+
+	/**
+	 *
+	 *
+	 */
+	protected function addPrimaryKey(&$script)
+	{
+		$table = $this->getTable();
+		$platform = $this->getPlatform();
+		$tableName = $table->getName();
+		$length = strlen($tableName);
+		if ($length > 27) {
+			$length = 27;
+		}
+		if ( is_array($table->getPrimaryKey()) && count($table->getPrimaryKey()) ) {
+			$script .= "
+	ALTER TABLE ".$this->quoteIdentifier($this->prefixTablename($table->getName()))."
+		ADD CONSTRAINT ".$this->quoteIdentifier(substr($tableName,0,$length)."_PK")."
+	PRIMARY KEY (";
+			$delim = "";
+			foreach ($table->getPrimaryKey() as $col) {
+				$script .= $delim . $this->quoteIdentifier($col->getName());
+				$delim = ",";
+			}
+	$script .= ");
+";
+		}
+	}
+
+	/**
+	 * Adds CREATE SEQUENCE statements for this table.
+	 *
+	 */
+	protected function addSequences(&$script)
+	{
+		$table = $this->getTable();
+		$platform = $this->getPlatform();
+		if ($table->getIdMethod() == "native") {
+			$script .= "CREATE SEQUENCE ".$this->quoteIdentifier($this->prefixTablename($this->getSequenceName()))." INCREMENT BY 1 START WITH 1 NOMAXVALUE NOCYCLE NOCACHE ORDER;
+";
+		}
+	}
+
+
+	/**
+	 * Adds CREATE INDEX statements for this table.
+	 * @see        parent::addIndices()
+	 */
+	protected function addIndices(&$script)
+	{
+		$table = $this->getTable();
+		$platform = $this->getPlatform();
+		foreach ($table->getIndices() as $index) {
+			$script .= "CREATE ";
+			if ($index->getIsUnique()) {
+				$script .= "UNIQUE";
+			}
+			$script .= "INDEX ".$this->quoteIdentifier($index->getName()) ." ON ".$this->quoteIdentifier($this->prefixTablename($table->getName()))." (".$this->getColumnList($index->getColumns()).");
+";
+		}
+	}
+
+	/**
+	 *
+	 * @see        parent::addForeignKeys()
+	 */
+	protected function addForeignKeys(&$script)
+	{
+		$table = $this->getTable();
+		$platform = $this->getPlatform();
+		foreach ($table->getForeignKeys() as $fk) {
+			$script .= "
+ALTER TABLE ".$this->quoteIdentifier($this->prefixTablename($table->getName()))." ADD CONSTRAINT ".$this->quoteIdentifier($fk->getName())." FOREIGN KEY (".$this->getColumnList($fk->getLocalColumns()) .") REFERENCES ".$this->quoteIdentifier($this->prefixTablename($fk->getForeignTableName()))." (".$this->getColumnList($fk->getForeignColumns()).")";
+			if ($fk->hasOnUpdate()) {
+				$this->warn("ON UPDATE not yet implemented for Oracle builder.(ignoring for ".$this->getColumnList($fk->getLocalColumns())." fk).");
+				//$script .= " ON UPDATE ".$fk->getOnUpdate();
+			}
+			if ($fk->hasOnDelete()) {
+				$script .= " ON DELETE ".$fk->getOnDelete();
+			}
+			$script .= ";
+";
+		}
+	}
+
+
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/builder/sql/oracle/OracleDataSQLBuilder.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/builder/sql/oracle/OracleDataSQLBuilder.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/builder/sql/oracle/OracleDataSQLBuilder.php	(revision 19)
@@ -0,0 +1,34 @@
+<?php
+
+/*
+ *  $Id: OracleDataSQLBuilder.php 521 2007-01-05 13:29:36Z heltem $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://propel.phpdb.org>.
+ */
+
+require_once 'propel/engine/builder/sql/DataSQLBuilder.php';
+
+/**
+ * Oracle class for building data dump SQL.
+ *
+ * @author     Hans Lellelid <hans@xmpl.org>
+ * @package    propel.engine.builder.sql.oracle
+ */
+class OracleDataSQLBuilder extends DataSQLBuilder {
+
+
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/builder/sql/pgsql/PgsqlDDLBuilder.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/builder/sql/pgsql/PgsqlDDLBuilder.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/builder/sql/pgsql/PgsqlDDLBuilder.php	(revision 19)
@@ -0,0 +1,316 @@
+<?php
+
+/*
+ *  $Id: PgsqlDDLBuilder.php 1000 2008-03-15 21:22:47Z hans $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://propel.phpdb.org>.
+ */
+
+require_once 'propel/engine/builder/sql/DDLBuilder.php';
+
+/**
+ * The SQL DDL-building class for PostgreSQL.
+ *
+ *
+ * @author     Hans Lellelid <hans@xmpl.org>
+ * @package    propel.engine.builder.sql.pgsql
+ */
+class PgsqlDDLBuilder extends DDLBuilder {
+
+
+	/**
+	 * Array that keeps track of already
+	 * added schema names
+	 *
+	 * @var        Array of schema names
+	 */
+	protected static $addedSchemas = array();
+
+	/**
+	 * Queue of constraint SQL that will be added to script at the end.
+	 *
+	 * PostgreSQL seems (now?) to not like constraints for tables that don't exist,
+	 * so the solution is to queue up the statements and execute it at the end.
+	 *
+	 * @var        array
+	 */
+	protected static $queuedConstraints = array();
+
+	/**
+	 * Reset static vars between db iterations.
+	 */
+	public static function reset()
+	{
+		self::$addedSchemas = array();
+		self::$queuedConstraints = array();
+	}
+
+	/**
+	 * Returns all the ALTER TABLE ADD CONSTRAINT lines for inclusion at end of file.
+	 * @return     string DDL
+	 */
+	public static function getDatabaseEndDDL()
+	{
+		$ddl = implode("", self::$queuedConstraints);
+		return $ddl;
+	}
+
+	/**
+	 * Get the schema for the current table
+	 *
+	 * @author     Markus Lervik <markus.lervik@necora.fi>
+	 * @access     protected
+	 * @return     schema name if table has one, else
+	 *         null
+	 **/
+	protected function getSchema()
+	{
+		$table = $this->getTable();
+		$vi = $table->getVendorInfoForType($this->getPlatform()->getDatabaseType());
+		if ($vi->hasParameter('schema')) {
+			return $vi->getParameter('schema');
+		}
+		return null;
+	}
+
+	/**
+	 * Add a schema to the generated SQL script
+	 *
+	 * @author     Markus Lervik <markus.lervik@necora.fi>
+	 * @access     protected
+	 * @return     string with CREATE SCHEMA statement if
+	 *         applicable, else empty string
+	 **/
+	protected function addSchema()
+	{
+
+		$schemaName = $this->getSchema();
+
+		if ($schemaName !== null) {
+
+			if (!in_array($schemaName, self::$addedSchemas)) {
+		$platform = $this->getPlatform();
+				self::$addedSchemas[] = $schemaName;
+		return "\nCREATE SCHEMA " . $this->quoteIdentifier($schemaName) . ";\n";
+			}
+		}
+
+		return '';
+
+	}
+
+	/**
+	 *
+	 * @see        parent::addDropStatement()
+	 */
+	protected function addDropStatements(&$script)
+	{
+		$table = $this->getTable();
+		$platform = $this->getPlatform();
+
+		$script .= "
+DROP TABLE ".$this->quoteIdentifier($this->prefixTablename($table->getName()))." CASCADE;
+";
+
+		if ($table->getIdMethod() == IDMethod::NATIVE && $table->getIdMethodParameters()) {
+			$script .= "
+DROP SEQUENCE ".$this->quoteIdentifier($this->prefixTablename(strtolower($this->getSequenceName()))).";
+";
+		}
+	}
+
+	/**
+	 *
+	 * @see        parent::addColumns()
+	 */
+	protected function addTable(&$script)
+	{
+		$table = $this->getTable();
+		$platform = $this->getPlatform();
+
+		$script .= "
+-----------------------------------------------------------------------------
+-- ".$table->getName()."
+-----------------------------------------------------------------------------
+";
+
+		$script .= $this->addSchema();
+
+		$schemaName = $this->getSchema();
+		if ($schemaName !== null) {
+			$script .= "\nSET search_path TO " . $this->quoteIdentifier($schemaName) . ";\n";
+		}
+
+		$this->addDropStatements($script);
+		$this->addSequences($script);
+
+		$script .= "
+
+CREATE TABLE ".$this->quoteIdentifier($this->prefixTablename($table->getName()))."
+(
+	";
+
+		$lines = array();
+
+		foreach ($table->getColumns() as $col) {
+			/* @var $col Column */
+			$colDDL = $this->getColumnDDL($col);
+			if ($col->isAutoIncrement() && $table->getIdMethodParameters() == null) {
+				if ($col->getType() === PropelTypes::BIGINT) {
+					$colDDL = str_replace($col->getDomain()->getSqlType(), 'bigserial', $colDDL);
+				} else {
+					$colDDL = str_replace($col->getDomain()->getSqlType(), 'serial', $colDDL);
+				}
+			}
+			$lines[] = $colDDL;
+		}
+
+		if ($table->hasPrimaryKey()) {
+			$lines[] = "PRIMARY KEY (".$this->getColumnList($table->getPrimaryKey()).")";
+		}
+
+		foreach ($table->getUnices() as $unique ) {
+			$lines[] = "CONSTRAINT ".$this->quoteIdentifier($unique->getName())." UNIQUE (".$this->getColumnList($unique->getColumns()).")";
+		}
+
+		$sep = ",
+	";
+		$script .= implode($sep, $lines);
+		$script .= "
+);
+
+COMMENT ON TABLE ".$this->quoteIdentifier($this->prefixTablename($table->getName()))." IS " . $platform->quote($table->getDescription()).";
+
+";
+
+		$this->addColumnComments($script);
+
+		$script .= "\nSET search_path TO public;";
+
+	}
+
+	/**
+	 * Adds comments for the columns.
+	 *
+	 */
+	protected function addColumnComments(&$script)
+	{
+		$table = $this->getTable();
+		$platform = $this->getPlatform();
+
+		foreach ($this->getTable()->getColumns() as $col) {
+			if ( $col->getDescription() != '' ) {
+				$script .= "
+COMMENT ON COLUMN ".$this->quoteIdentifier($this->prefixTablename($table->getName())).".".$this->quoteIdentifier($col->getName())." IS ".$platform->quote($col->getDescription()) .";
+";
+			}
+		}
+	}
+
+	/**
+	 * Override to provide sequence names that conform to postgres' standard when
+	 * no id-method-parameter specified.
+	 *
+	 * @see        DataModelBuilder::getSequenceName()
+	 * @return     string
+	 */
+	public function getSequenceName()
+	{
+		$table = $this->getTable();
+		static $longNamesMap = array();
+		$result = null;
+		if ($table->getIdMethod() == IDMethod::NATIVE) {
+			$idMethodParams = $table->getIdMethodParameters();
+			if (empty($idMethodParams)) {
+				$result = null;
+				// We're going to ignore a check for max length (mainly
+				// because I'm not sure how Postgres would handle this w/ SERIAL anyway)
+				foreach ($table->getColumns() as $col) {
+					if ($col->isAutoIncrement()) {
+						$result = $table->getName() . '_' . $col->getName() . '_seq';
+						break; // there's only one auto-increment column allowed
+					}
+				}
+			} else {
+				$result = $idMethodParams[0]->getValue();
+			}
+		}
+		return $result;
+	}
+
+	/**
+	 * Adds CREATE SEQUENCE statements for this table.
+	 *
+	 */
+	protected function addSequences(&$script)
+	{
+		$table = $this->getTable();
+		$platform = $this->getPlatform();
+
+		if ($table->getIdMethod() == IDMethod::NATIVE && $table->getIdMethodParameters() != null) {
+			$script .= "
+CREATE SEQUENCE ".$this->quoteIdentifier($this->prefixTablename(strtolower($this->getSequenceName()))).";
+";
+		}
+	}
+
+
+	/**
+	 * Adds CREATE INDEX statements for this table.
+	 * @see        parent::addIndices()
+	 */
+	protected function addIndices(&$script)
+	{
+		$table = $this->getTable();
+		$platform = $this->getPlatform();
+
+		foreach ($table->getIndices() as $index) {
+			$script .= "
+CREATE ";
+			if ($index->getIsUnique()) {
+				$script .= "UNIQUE";
+			}
+			$script .= "INDEX ".$this->quoteIdentifier($index->getName())." ON ".$this->quoteIdentifier($this->prefixTablename($table->getName()))." (".$this->getColumnList($index->getColumns()).");
+";
+		}
+	}
+
+	/**
+	 *
+	 * @see        parent::addForeignKeys()
+	 */
+	protected function addForeignKeys(&$script)
+	{
+		$table = $this->getTable();
+		$platform = $this->getPlatform();
+
+		foreach ($table->getForeignKeys() as $fk) {
+			$privscript = "
+ALTER TABLE ".$this->quoteIdentifier($this->prefixTablename($table->getName()))." ADD CONSTRAINT ".$this->quoteIdentifier($fk->getName())." FOREIGN KEY (".$this->getColumnList($fk->getLocalColumns()) .") REFERENCES ".$this->quoteIdentifier($this->prefixTablename($fk->getForeignTableName()))." (".$this->getColumnList($fk->getForeignColumns()).")";
+			if ($fk->hasOnUpdate()) {
+				$privscript .= " ON UPDATE ".$fk->getOnUpdate();
+			}
+			if ($fk->hasOnDelete()) {
+				$privscript .= " ON DELETE ".$fk->getOnDelete();
+			}
+			$privscript .= ";
+";
+			self::$queuedConstraints[] = $privscript;
+		}
+	}
+
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/builder/sql/pgsql/PgsqlDataSQLBuilder.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/builder/sql/pgsql/PgsqlDataSQLBuilder.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/builder/sql/pgsql/PgsqlDataSQLBuilder.php	(revision 19)
@@ -0,0 +1,113 @@
+<?php
+
+/*
+ *  $Id: PgsqlDataSQLBuilder.php 989 2008-03-11 14:29:30Z heltem $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://propel.phpdb.org>.
+ */
+
+require_once 'propel/engine/builder/sql/DataSQLBuilder.php';
+
+/**
+ * PostgreSQL class for building data dump SQL.
+ *
+ * @author     Hans Lellelid <hans@xmpl.org>
+ * @package    propel.engine.builder.sql.pgsql
+ */
+class PgsqlDataSQLBuilder extends DataSQLBuilder {
+
+	/**
+	 * The largets serial value encountered this far.
+	 *
+	 * @var        int
+	 */
+	private $maxSeqVal;
+
+	/**
+	 * Construct a new PgsqlDataSQLBuilder object.
+	 *
+	 * @param      Table $table
+	 */
+	public function __construct(Table $table)
+	{
+		parent::__construct($table);
+	}
+
+	/**
+	 * The main method in this class, returns the SQL for INSERTing data into a row.
+	 * @param      DataRow $row The row to process.
+	 * @return     string
+	 */
+	public function buildRowSql(DataRow $row)
+	{
+		$sql = parent::buildRowSql($row);
+
+		$table = $this->getTable();
+
+		if ($table->hasAutoIncrementPrimaryKey() && $table->getIdMethod() == IDMethod::NATIVE) {
+			foreach ($row->getColumnValues() as $colValue) {
+				if ($colValue->getColumn()->isAutoIncrement()) {
+					if ($colValue->getValue() > $this->maxSeqVal) {
+						$this->maxSeqVal = $colValue->getValue();
+					}
+				}
+			}
+		}
+
+		return $sql;
+	}
+
+	public function getTableEndSql()
+	{
+		$table = $this->getTable();
+		$sql = "";
+		if ($table->hasAutoIncrementPrimaryKey() && $table->getIdMethod() == IDMethod::NATIVE) {
+			$seqname = $this->prefixTablename($this->getDDLBuilder()->getSequenceName());
+			$sql .= "SELECT pg_catalog.setval('$seqname', ".((int)$this->maxSeqVal).");
+";
+		}
+		return $sql;
+	}
+
+	/**
+	 * Get SQL value to insert for Postgres BOOLEAN column.
+	 * @param      boolean $value
+	 * @return     string The representation of boolean for Postgres ('t' or 'f').
+	 */
+	protected function getBooleanSql($value)
+	{
+		if ($value === 'f' || $value === 'false' || $value === "0") {
+			$value = false;
+		}
+		return ($value ? "'t'" : "'f'");
+	}
+
+	/**
+	 *
+	 * @param      mixed $blob Blob object or string containing data.
+	 * @return     string
+	 */
+	protected function getBlobSql($blob)
+	{
+		// they took magic __toString() out of PHP5.0.0; this sucks
+		if (is_object($blob)) {
+			$blob = $blob->__toString();
+		}
+		return "'" . pg_escape_bytea($blob) . "'";
+	}
+
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/builder/sql/sqlite/SqliteDDLBuilder.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/builder/sql/sqlite/SqliteDDLBuilder.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/builder/sql/sqlite/SqliteDDLBuilder.php	(revision 19)
@@ -0,0 +1,126 @@
+<?php
+
+/*
+ *  $Id: SqliteDDLBuilder.php 949 2008-01-30 22:41:59Z hans $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://propel.phpdb.org>.
+ */
+
+require_once 'propel/engine/builder/sql/DDLBuilder.php';
+
+/**
+ * The SQL DDL-building class for SQLite.
+ *
+ *
+ * @author     Hans Lellelid <hans@xmpl.org>
+ * @package    propel.engine.builder.sql.pgsql
+ */
+class SqliteDDLBuilder extends DDLBuilder {
+
+	/**
+	 *
+	 * @see        parent::addDropStatement()
+	 */
+	protected function addDropStatements(&$script)
+	{
+		$table = $this->getTable();
+		$platform = $this->getPlatform();
+
+		$script .= "
+DROP TABLE ".$this->quoteIdentifier($this->prefixTablename($table->getName())).";
+";
+	}
+
+	/**
+	 *
+	 * @see        parent::addColumns()
+	 */
+	protected function addTable(&$script)
+	{
+		$table = $this->getTable();
+		$platform = $this->getPlatform();
+
+		$script .= "
+-----------------------------------------------------------------------------
+-- ".$table->getName()."
+-----------------------------------------------------------------------------
+";
+
+		$this->addDropStatements($script);
+
+		$script .= "
+
+CREATE TABLE ".$this->quoteIdentifier($this->prefixTablename($table->getName()))."
+(
+	";
+
+		$lines = array();
+
+		foreach ($table->getColumns() as $col) {
+			$lines[] = $this->getColumnDDL($col);
+		}
+
+		foreach ($table->getUnices() as $unique ) {
+			$lines[] = "UNIQUE (".$this->getColumnList($unique->getColumns()).")";
+		}
+
+		$sep = ",
+	";
+		$script .= implode($sep, $lines);
+		$script .= "
+);
+";
+	}
+
+	/**
+	 * Adds CREATE INDEX statements for this table.
+	 * @see        parent::addIndices()
+	 */
+	protected function addIndices(&$script)
+	{
+		$table = $this->getTable();
+		$platform = $this->getPlatform();
+
+		foreach ($table->getIndices() as $index) {
+			$script .= "
+CREATE ";
+			if ($index->getIsUnique()) {
+				$script .= "UNIQUE";
+			}
+			$script .= "INDEX ".$this->quoteIdentifier($index->getName())." ON ".$this->quoteIdentifier($this->prefixTablename($table->getName()))." (".$this->getColumnList($index->getColumns()).");
+";
+		}
+	}
+
+	/**
+	 *
+	 * @see        parent::addForeignKeys()
+	 */
+	protected function addForeignKeys(&$script)
+	{
+		$table = $this->getTable();
+		$platform = $this->getPlatform();
+
+		foreach ($table->getForeignKeys() as $fk) {
+			$script .= "
+-- SQLite does not support foreign keys; this is just for reference
+-- FOREIGN KEY (".$this->getColumnList($fk->getLocalColumns()).") REFERENCES ".$this->prefixTablename($fk->getForeignTableName())." (".$this->getColumnList($fk->getForeignColumns()).")
+";
+		}
+	}
+
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/builder/sql/sqlite/SqliteDataSQLBuilder.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/builder/sql/sqlite/SqliteDataSQLBuilder.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/builder/sql/sqlite/SqliteDataSQLBuilder.php	(revision 19)
@@ -0,0 +1,47 @@
+<?php
+
+/*
+ *  $Id: SqliteDataSQLBuilder.php 521 2007-01-05 13:29:36Z heltem $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://propel.phpdb.org>.
+ */
+
+require_once 'propel/engine/builder/sql/DataSQLBuilder.php';
+
+/**
+ * SQLite class for building data dump SQL.
+ *
+ * @author     Hans Lellelid <hans@xmpl.org>
+ * @package    propel.engine.builder.sql.sqlite
+ */
+class SqliteDataSQLBuilder extends DataSQLBuilder {
+
+	/**
+	 * Returns string processed by sqlite_udf_encode_binary() to ensure that binary contents will be handled correctly by sqlite.
+	 * @param      mixed $blob Blob or string
+	 * @return     string encoded text
+	 */
+	protected function getBlobSql($blob)
+	{
+		// they took magic __toString() out of PHP5.0.0; this sucks
+		if (is_object($blob)) {
+			$blob = $blob->__toString();
+		}
+		return "'" . sqlite_udf_encode_binary($blob) . "'";
+	}
+
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/builder/util/DefaultEnglishPluralizer.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/builder/util/DefaultEnglishPluralizer.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/builder/util/DefaultEnglishPluralizer.php	(revision 19)
@@ -0,0 +1,43 @@
+<?php
+/*
+ *  $Id: DefaultEnglishPluralizer.php 842 2007-12-02 16:28:20Z heltem $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://propel.phpdb.org>.
+ */
+
+require_once 'propel/engine/builder/util/Pluralizer.php';
+
+/**
+ * The default Enlglish pluralizer class.
+ *
+ * @author     Hans Lellelid <hans@xmpl.org>
+ * @version    $Revision: 842 $
+ * @package    propel.engine.generator
+ */
+class DefaultEnglishPluralizer implements Pluralizer {
+
+	/**
+	 * Generate a plural name based on the passed in root.
+	 * @param      string $root The root that needs to be pluralized (e.g. Author)
+	 * @return     string The plural form of $root (e.g. Authors).
+	 */
+	public function getPluralForm($root)
+	{
+		return $root . 's';
+	}
+
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/builder/util/Pluralizer.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/builder/util/Pluralizer.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/builder/util/Pluralizer.php	(revision 19)
@@ -0,0 +1,38 @@
+<?php
+/*
+ *  $Id: Pluralizer.php 842 2007-12-02 16:28:20Z heltem $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://propel.phpdb.org>.
+ */
+
+/**
+ * The generic interface to create a plural form of a name.
+ *
+ * @author     Hans Lellelid <hans@xmpl.org>
+ * @version    $Revision: 842 $
+ * @package    propel.engine.generator
+ */
+interface Pluralizer {
+
+	/**
+	 * Generate a plural name based on the passed in root.
+	 * @param      string $root The root that needs to be pluralized (e.g. Author)
+	 * @return     string The plural form of $root.
+	 */
+	public function getPluralForm($root);
+
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/builder/util/transform/XmlToDataSQL.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/builder/util/transform/XmlToDataSQL.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/builder/util/transform/XmlToDataSQL.php	(revision 19)
@@ -0,0 +1,276 @@
+<?php
+
+/*
+ *  $Id: XmlToDataSQL.php 989 2008-03-11 14:29:30Z heltem $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://propel.phpdb.org>.
+ */
+
+require_once 'phing/parser/AbstractHandler.php';
+
+/**
+ * A Class that is used to parse an data dump XML file and create SQL using a DataSQLBuilder class.
+ *
+ * @author     Hans Lellelid <hans@xmpl.org> (Propel)
+ * @version    $Revision: 989 $
+ * @package    propel.engine.database.transform
+ */
+class XmlToDataSQL extends AbstractHandler {
+
+	/**
+	 * The GeneratorConfig associated with the build.
+	 *
+	 * @var        GeneratorConfig
+	 */
+	private $generatorConfig;
+
+	/**
+	 * The database.
+	 *
+	 * @var        Database
+	 */
+	private $database;
+
+	/**
+	 * The output writer for the SQL file.
+	 *
+	 * @var        Writer
+	 */
+	private $sqlWriter;
+
+	/**
+	 * The database (and output SQL file) encoding.
+	 *
+	 * Values will be converted to this encoding in the output file.
+	 *
+	 * @var        string
+	 */
+	private $encoding;
+
+	/**
+	 * The classname of the static class that will perform the building.
+	 *
+	 * This is needed because there are some pre/post methods that get called
+	 * on the static class.
+	 *
+	 * @var        string
+	 */
+	private $builderClazz;
+
+	/**
+	 * The name of the current table being processed.
+	 *
+	 * @var        string
+	 */
+	private $currTableName;
+
+	/**
+	 * The DataSQLBuilder for the current table.
+	 *
+	 * @var        DataSQLBuilder
+	 */
+	private $currBuilder;
+
+	/**
+	 * Expat Parser.
+	 *
+	 * @var        ExpatParser
+	 */
+	public $parser;
+
+	/**
+	 * Flag for enabing debug output to aid in parser tracing.
+	 */
+	const DEBUG = false;
+
+	/**
+	 * Construct new XmlToDataSQL class.
+	 *
+	 * This class is passed the Database object so that it knows what to expect from
+	 * the XML file.
+	 *
+	 * @param      Database $database
+	 * @param      GeneratorConfig $config
+	 * @param      string $encoding Database encoding
+	 */
+	public function __construct(Database $database, GeneratorConfig $config, $encoding = 'iso-8859-1')
+	{
+		$this->database = $database;
+		$this->generatorConfig = $config;
+		$this->encoding = $encoding;
+	}
+
+	/**
+	 * Transform the data dump input file into SQL and writes it to the output stream.
+	 *
+	 * @param      PhingFile $xmlFile
+	 * @param      Writer $out
+	 */
+	public function transform(PhingFile $xmlFile, Writer $out)
+	{
+		$this->sqlWriter = $out;
+
+		// Reset some vars just in case this is being run multiple times.
+		$this->currTableName = $this->currBuilder = null;
+
+		$this->builderClazz = $this->generatorConfig->getBuilderClassname('datasql');
+
+		try {
+			$fr = new FileReader($xmlFile);
+		} catch (Exception $e) {
+			throw new BuildException("XML File not found: " . $xmlFile->getAbsolutePath());
+		}
+
+		$br = new BufferedReader($fr);
+
+		$this->parser = new ExpatParser($br);
+		$this->parser->parserSetOption(XML_OPTION_CASE_FOLDING, 0);
+		$this->parser->setHandler($this);
+
+		try {
+			$this->parser->parse();
+		} catch (Exception $e) {
+			print $e->getMessage() . "\n";
+			$br->close();
+		}
+		$br->close();
+	}
+
+	/**
+	 * Handles opening elements of the xml file.
+	 */
+	public function startElement($name, $attributes)
+	{
+		try {
+			if ($name == "dataset") {
+				// Clear any start/end DLL
+				call_user_func(array($this->builderClazz, 'reset'));
+				$this->sqlWriter->write(call_user_func(array($this->builderClazz, 'getDatabaseStartSql')));
+			} else {
+
+				// we're processing a row of data
+				// where tag name is phpName e.g. <BookReader .... />
+
+				$table = $this->database->getTableByPhpName($name);
+
+				$columnValues = array();
+				foreach ($attributes as $name => $value) {
+					$col = $table->getColumnByPhpName($name);
+					$columnValues[] = new ColumnValue($col, iconv('utf-8',$this->encoding, $value));
+				}
+
+				$data = new DataRow($table, $columnValues);
+
+				if ($this->currTableName !== $table->getName()) {
+					// new table encountered
+
+					if ($this->currBuilder !== null) {
+						$this->sqlWriter->write($this->currBuilder->getTableEndSql());
+					}
+
+					$this->currTableName = $table->getName();
+					$this->currBuilder = $this->generatorConfig->getConfiguredBuilder($table, 'datasql');
+
+					$this->sqlWriter->write($this->currBuilder->getTableStartSql());
+				}
+
+				// Write the SQL
+				$this->sqlWriter->write($this->currBuilder->buildRowSql($data));
+
+			}
+
+		} catch (Exception $e) {
+			// Exceptions have traditionally not bubbled up nicely from the expat parser,
+			// so we also print the stack trace here.
+			print $e;
+			throw $e;
+		}
+	}
+
+
+	/**
+	 * Handles closing elements of the xml file.
+	 *
+	 * @param      $name The local name (without prefix), or the empty string if
+	 *         Namespace processing is not being performed.
+	 */
+	public function endElement($name)
+	{
+		if (self::DEBUG) {
+			print("endElement(" . $name . ") called\n");
+		}
+		if ($name == "dataset") {
+			if ($this->currBuilder !== null) {
+				$this->sqlWriter->write($this->currBuilder->getTableEndSql());
+			}
+			$this->sqlWriter->write(call_user_func(array($this->builderClazz, 'getDatabaseEndSql')));
+		}
+	}
+
+} // XmlToData
+
+/**
+ * "inner class"
+ * @package    propel.engine.database.transform
+ */
+class DataRow
+{
+	private $table;
+	private $columnValues;
+
+	public function __construct(Table $table, $columnValues)
+	{
+		$this->table = $table;
+		$this->columnValues = $columnValues;
+	}
+
+	public function getTable()
+	{
+		return $this->table;
+	}
+
+	public function getColumnValues()
+	{
+		return $this->columnValues;
+	}
+}
+
+/**
+ * "inner" class
+ * @package    propel.engine.database.transform
+ */
+class ColumnValue {
+
+	private $col;
+	private $val;
+
+	public function __construct(Column $col, $val)
+	{
+		$this->col = $col;
+		$this->val = $val;
+	}
+
+	public function getColumn()
+	{
+		return $this->col;
+	}
+
+	public function getValue()
+	{
+		return $this->val;
+	}
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/database/model/AppData.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/database/model/AppData.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/database/model/AppData.php	(revision 19)
@@ -0,0 +1,206 @@
+<?php
+/*
+ *  $Id: AppData.php 521 2007-01-05 13:29:36Z heltem $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://propel.phpdb.org>.
+ */
+
+include_once 'propel/engine/EngineException.php';
+include_once 'propel/engine/database/model/Database.php';
+
+/**
+ * A class for holding application data structures.
+ *
+ * @author     Hans Lellelid <hans@xmpl.org> (Propel)
+ * @author     Leon Messerschmidt <leon@opticode.co.za> (Torque)
+ * @author     John McNally <jmcnally@collab.net> (Torque)
+ * @author     Daniel Rall <dlr@finemaltcoding.com> (Torque)
+ * @version    $Revision: 521 $
+ * @package    propel.engine.database.model
+ */
+class AppData {
+
+	/**
+	 * The list of databases for this application.
+	 * @var        array Database[]
+	 */
+	private $dbList = array();
+
+	/**
+	 * The platform class for our database(s).
+	 * @var        string
+	 */
+	private $platform;
+
+	/**
+	 * Name of the database. Only one database definition
+	 * is allowed in one XML descriptor.
+	 */
+	private $name;
+
+	/**
+	 * Flag to ensure that initialization is performed only once.
+	 * @var        boolean
+	 */
+	private $isInitialized = false;
+
+	/**
+	 * Creates a new instance for the specified database type.
+	 *
+	 * @param      Platform $platform The platform class to use for any databases added to this application model.
+	 */
+	public function __construct(Platform $platform)
+	{
+		$this->platform = $platform;
+	}
+
+	/**
+	 * Set the name of the database.
+	 *
+	 * @param      name of the database.
+	 */
+	public function setName($name)
+	{
+		$this->name = $name;
+	}
+
+	/**
+	 * Get the name of the database.
+	 *
+	 * @return     String name
+	 */
+	public function getName()
+	{
+		return $this->name;
+	}
+
+	/**
+	 * Get the short name of the database (without the '-schema' postfix).
+	 *
+	 * @return     String name
+	 */
+	public function getShortName()
+	{
+		return str_replace("-schema", "", $this->name);
+	}
+
+	/**
+	 * Return an array of all databases
+	 *
+	 * @return     Array of Database objects
+	 */
+	public function getDatabases($doFinalInit = true)
+	{
+		// this is temporary until we'll have a clean solution
+		// for packaging datamodels/requiring schemas
+		if ($doFinalInit) {
+			$this->doFinalInitialization();
+		}
+		return $this->dbList;
+	}
+
+	/**
+	 * Returns whether this application has multiple databases.
+	 *
+	 * @return     boolean True if the application has multiple databases
+	 */
+	public function hasMultipleDatabases()
+	{
+		return (count($this->dbList) > 1);
+	}
+
+	/**
+	 * Return the database with the specified name.
+	 *
+	 * @param      name database name
+	 * @return     A Database object.  If it does not exist it returns null
+	 */
+	public function getDatabase($name = null, $doFinalInit = true)
+	{
+		// this is temporary until we'll have a clean solution
+		// for packaging datamodels/requiring schemas
+		if ($doFinalInit) {
+			$this->doFinalInitialization();
+		}
+
+		if ($name === null) {
+			return $this->dbList[0];
+		}
+
+		for ($i=0,$size=count($this->dbList); $i < $size; $i++) {
+			$db = $this->dbList[$i];
+			if ($db->getName() === $name) {
+				return $db;
+			}
+		}
+		return null;
+	}
+
+	/**
+	 * Add a database to the list and sets the AppData property to this
+	 * AppData
+	 *
+	 * @param      db the database to add
+	 */
+	public function addDatabase($db)
+	{
+		if ($db instanceof Database) {
+			$db->setAppData($this);
+			if ($db->getPlatform() === null) {
+				$db->setPlatform($this->platform);
+			}
+			$this->dbList[] = $db;
+			return $db;
+		} else {
+			// XML attributes array / hash
+			$d = new Database();
+			$d->loadFromXML($db);
+			return $this->addDatabase($d); // calls self w/ different param type
+		}
+
+	}
+
+	/**
+	 *
+	 * @return     void
+	 */
+	private function doFinalInitialization()
+	{
+		if (!$this->isInitialized) {
+			for ($i=0, $size=count($this->dbList); $i < $size; $i++) {
+				$this->dbList[$i]->doFinalInitialization();
+			}
+			$this->isInitialized = true;
+		}
+	}
+
+	/**
+	 * Creats a string representation of this AppData.
+	 * The representation is given in xml format.
+	 *
+	 * @return     string Representation in xml format
+	 */
+	public function toString()
+	{
+		$result = "<app-data>\n";
+		for ($i=0,$size=count($this->dbList); $i < $size; $i++) {
+			$result .= $this->dbList[$i]->toString();
+		}
+		$result .= "</app-data>";
+		return $result;
+	}
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/database/model/Column.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/database/model/Column.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/database/model/Column.php	(revision 19)
@@ -0,0 +1,1106 @@
+<?php
+/*
+ *  $Id: Column.php 989 2008-03-11 14:29:30Z heltem $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://propel.phpdb.org>.
+ */
+
+require_once 'propel/engine/database/model/XMLElement.php';
+include_once 'propel/engine/EngineException.php';
+include_once 'propel/engine/database/model/PropelTypes.php';
+include_once 'propel/engine/database/model/Inheritance.php';
+include_once 'propel/engine/database/model/Domain.php';
+include_once 'propel/engine/database/model/ColumnDefaultValue.php';
+
+/**
+ * A Class for holding data about a column used in an Application.
+ *
+ * @author     Hans Lellelid <hans@xmpl.org> (Propel)
+ * @author     Leon Messerschmidt <leon@opticode.co.za> (Torque)
+ * @author     Jason van Zyl <jvanzyl@apache.org> (Torque)
+ * @author     Jon S. Stevens <jon@latchkey.com> (Torque)
+ * @author     Daniel Rall <dlr@finemaltcoding.com> (Torque)
+ * @author     Byron Foster <byron_foster@yahoo.com> (Torque)
+ * @author     Bernd Goldschmidt <bgoldschmidt@rapidsoft.de>
+ * @version    $Revision: 989 $
+ * @package    propel.engine.database.model
+ */
+class Column extends XMLElement {
+
+	const DEFAULT_TYPE = "VARCHAR";
+	const DEFAULT_VISIBILITY = 'public';
+	public static $valid_visibilities = array('public', 'protected', 'private');
+
+	private $name;
+	private $description;
+	private $phpName = null;
+	private $phpNamingMethod;
+	private $isNotNull = false;
+	private $size;
+	private $namePrefix;
+	private $accessorVisibility;
+	private $mutatorVisibility;
+
+	/**
+	 * The name to use for the Peer constant that identifies this column.
+	 * (Will be converted to all-uppercase in the templates.)
+	 * @var        string
+	 */
+	private $peerName;
+
+	/**
+	 * Native PHP type (scalar or class name)
+	 * @var        string "string", "boolean", "int", "double"
+	 */
+	private $phpType;
+
+	/**
+	 * @var        Table
+	 */
+	private $parentTable;
+
+	private $position;
+	private $isPrimaryKey = false;
+	private $isNodeKey = false;
+	private $nodeKeySep;
+	private $isNestedSetLeftKey = false;
+	private $isNestedSetRightKey = false;
+	private $isTreeScopeKey = false;
+	private $isUnique = false;
+	private $isAutoIncrement = false;
+	private $isLazyLoad = false;
+	private $defaultValue;
+	private $referrers;
+
+	// only one type is supported currently, which assumes the
+	// column either contains the classnames or a key to
+	// classnames specified in the schema.  Others may be
+	// supported later.
+	private $inheritanceType;
+	private $isInheritance;
+	private $isEnumeratedClasses;
+	private $inheritanceList;
+	private $needsTransactionInPostgres; //maybe this can be retrieved from vendorSpecificInfo
+
+	/** class name to do input validation on this column */
+	private $inputValidator = null;
+
+	/**
+	 * @var        Domain The domain object associated with this Column.
+	 */
+	private $domain;
+
+	/**
+	 * Creates a new column and set the name
+	 *
+	 * @param      name column name
+	 */
+	public function __construct($name = null)
+	{
+		$this->name = $name;
+	}
+
+	/**
+	 * Return a comma delimited string listing the specified columns.
+	 *
+	 * @param      columns Either a list of <code>Column</code> objects, or
+	 * a list of <code>String</code> objects with column names.
+	 * @deprecated Use the DDLBuilder->getColumnList() method instead; this will be removed in 1.3
+	 */
+	public static function makeList($columns, Platform $platform)
+	{
+		$list = array();
+		foreach ($columns as $col) {
+			if ($col instanceof Column) {
+				$col = $col->getName();
+			}
+			$list[] = $platform->quoteIdentifier($col);
+		}
+		return implode(", ", $list);
+	}
+
+	/**
+	 * Sets up the Column object based on the attributes that were passed to loadFromXML().
+	 * @see        parent::loadFromXML()
+	 */
+	protected function setupObject()
+	{
+		try {
+			$dom = $this->getAttribute("domain");
+			if ($dom)  {
+				$this->getDomain()->copy($this->getTable()->getDatabase()->getDomain($dom));
+			} else {
+				$type = strtoupper($this->getAttribute("type"));
+				if ($type) {
+					$this->getDomain()->copy($this->getPlatform()->getDomainForType($type));
+				} else {
+					$this->getDomain()->copy($this->getPlatform()->getDomainForType(self::DEFAULT_TYPE));
+				}
+			}
+
+			$this->name = $this->getAttribute("name");
+			$this->phpName = $this->getAttribute("phpName");
+			$this->phpType = $this->getAttribute("phpType");
+
+			if ($this->getAttribute("prefix", null) !== null) {
+				$this->namePrefix = $this->getAttribute("prefix");
+			} elseif ($this->getTable()->getAttribute('columnPrefix', null) !== null) {
+				$this->namePrefix = $this->getTable()->getAttribute('columnPrefix');
+			} else {
+				$this->namePrefix = '';
+			}
+
+			// Accessor visibility
+			if ($this->getAttribute('accessorVisibility', null) !==  null) {
+				$this->setAccessorVisibility($this->getAttribute('accessorVisibility'));
+			} elseif ($this->getTable()->getAttribute('defaultAccessorVisibility', null) !== null) {
+				$this->setAccessorVisibility($this->getTable()->getAttribute('defaultAccessorVisibility'));
+			} elseif ($this->getTable()->getDatabase()->getAttribute('defaultAccessorVisibility', null) !== null) {
+				$this->setAccessorVisibility($this->getTable()->getDatabase()->getAttribute('defaultAccessorVisibility'));
+			} else {
+				$this->setAccessorVisibility(self::DEFAULT_VISIBILITY);
+			}
+
+			// Mutator visibility
+			if ($this->getAttribute('mutatorVisibility', null) !==  null) {
+				$this->setMutatorVisibility($this->getAttribute('mutatorVisibility'));
+			} elseif ($this->getTable()->getAttribute('defaultMutatorVisibility', null) !== null) {
+				$this->setMutatorVisibility($this->getTable()->getAttribute('defaultMutatorVisibility'));
+			} elseif ($this->getTable()->getDatabase()->getAttribute('defaultMutatorVisibility', null) !== null) {
+				$this->setMutatorVisibility($this->getTable()->getDatabase()->getAttribute('defaultMutatorVisibility'));
+			} else {
+				$this->setMutatorVisibility(self::DEFAULT_VISIBILITY);
+			}
+
+			$this->peerName = $this->getAttribute("peerName");
+
+			// retrieves the method for converting from specified name to a PHP name, defaulting to parent tables default method
+			$this->phpNamingMethod = $this->getAttribute("phpNamingMethod", $this->parentTable->getDatabase()->getDefaultPhpNamingMethod());
+
+			$this->isPrimaryKey = $this->booleanValue($this->getAttribute("primaryKey"));
+
+			$this->isNodeKey = $this->booleanValue($this->getAttribute("nodeKey"));
+			$this->nodeKeySep = $this->getAttribute("nodeKeySep", ".");
+
+			$this->isNestedSetLeftKey = $this->booleanValue($this->getAttribute("nestedSetLeftKey"));
+			$this->isNestedSetRightKey = $this->booleanValue($this->getAttribute("nestedSetRightKey"));
+			$this->isTreeScopeKey = $this->booleanValue($this->getAttribute("treeScopeKey"));
+
+			$this->isNotNull = ($this->booleanValue($this->getAttribute("required"), false) || $this->isPrimaryKey); // primary keys are required
+
+			//AutoIncrement/Sequences
+			$this->isAutoIncrement = $this->booleanValue($this->getAttribute("autoIncrement"));
+			$this->isLazyLoad = $this->booleanValue($this->getAttribute("lazyLoad"));
+
+			// Add type, size information to associated Domain object
+			$this->getDomain()->replaceSqlType($this->getAttribute("sqlType"));
+			$this->getDomain()->replaceSize($this->getAttribute("size"));
+			$this->getDomain()->replaceScale($this->getAttribute("scale"));
+
+			$defval = $this->getAttribute("defaultValue", $this->getAttribute("default"));
+			if ($defval !== null) {
+				$this->getDomain()->setDefaultValue(new ColumnDefaultValue($defval, ColumnDefaultValue::TYPE_VALUE));
+			} elseif ($this->getAttribute("defaultExpr") !== null) {
+				$this->getDomain()->setDefaultValue(new ColumnDefaultValue($this->getAttribute("defaultExpr"), ColumnDefaultValue::TYPE_EXPR));
+			}
+
+			$this->inheritanceType = $this->getAttribute("inheritance");
+			$this->isInheritance = ($this->inheritanceType !== null
+			&& $this->inheritanceType !== "false"); // here we are only checking for 'false', so don't
+			// use boleanValue()
+
+			$this->inputValidator = $this->getAttribute("inputValidator");
+			$this->description = $this->getAttribute("description");
+		} catch (Exception $e) {
+			throw new EngineException("Error setting up column " . var_export($this->getAttribute("name"), true) . ": " . $e->getMessage());
+		}
+	}
+
+	/**
+	 * Gets domain for this column, creating a new empty domain object if none is set.
+	 * @return     Domain
+	 */
+	public function getDomain()
+	{
+		if ($this->domain === null) {
+			$this->domain = new Domain();
+		}
+		return $this->domain;
+	}
+
+	/**
+	 * Returns table.column
+	 */
+	public function getFullyQualifiedName()
+	{
+		return ($this->parentTable->getName() . '.' . name);
+	}
+
+	/**
+	 * Get the name of the column
+	 */
+	public function getName()
+	{
+		return $this->name;
+	}
+
+	/**
+	 * Set the name of the column
+	 */
+	public function setName($newName)
+	{
+		$this->name = $newName;
+	}
+
+	/**
+	 * Get the description for the Table
+	 */
+	public function getDescription()
+	{
+		return $this->description;
+	}
+
+	/**
+	 * Set the description for the Table
+	 *
+	 * @param      newDescription description for the Table
+	 */
+	public function setDescription($newDescription)
+	{
+		$this->description = $newDescription;
+	}
+
+	/**
+	 * Get name to use in PHP sources
+	 * @return     string
+	 */
+	public function getPhpName()
+	{
+		if ($this->phpName === null) {
+			$inputs = array();
+			$inputs[] = $this->name;
+			$inputs[] = $this->phpNamingMethod;
+			$inputs[] = $this->namePrefix;
+			return NameFactory::generateName(NameFactory::PHP_GENERATOR, $inputs);
+		}
+		return $this->phpName;
+	}
+
+	/**
+	 * Set name to use in PHP sources
+	 */
+	public function setPhpName($phpName)
+	{
+		$this->phpName = $phpName;
+	}
+
+	/**
+	 * Get studly version of PHP name.
+	 *
+	 * The studly name is the PHP name with the first character lowercase.
+	 *
+	 * @return     string
+	 */
+	public function getStudlyPhpName()
+	{
+		$phpname = $this->getPhpName();
+		if (strlen($phpname) > 1) {
+			return strtolower(substr($phpname, 0, 1)) . substr($phpname, 1);
+		} else { // 0 or 1 chars (I suppose that's rare)
+			return strtolower($phpname);
+		}
+	}
+
+	/**
+	 * Get the visibility of the accessors of this column / attribute
+	 * @return     string
+	 */
+	public function getAccessorVisibility() {
+		if ($this->accessorVisibility !== null) {
+			return $this->accessorVisibility;
+		} else {
+			return self::DEFAULT_VISIBILITY;
+		}
+	}
+
+	/**
+	 * Set the visibility of the accessor methods for this column / attribute
+	 * @param      $newVisibility string
+	 */
+	public function setAccessorVisibility($newVisibility) {
+		if (in_array($newVisibility, self::$valid_visibilities)) {
+			$this->accessorVisibility = $newVisibility;
+		} else {
+			$this->accessorVisibility = self::DEFAULT_VISIBILITY;
+		}
+
+	}
+
+	/**
+	 * Get the visibility of the mutator of this column / attribute
+	 * @return     string
+	 */
+	public function getMutatorVisibility() {
+		if ($this->mutatorVisibility !== null) {
+			return $this->mutatorVisibility;
+		} else {
+			return self::DEFAULT_VISIBILITY;
+		}
+	}
+
+	/**
+	 * Set the visibility of the mutator methods for this column / attribute
+	 * @param      $newVisibility string
+	 */
+	public function setMutatorVisibility($newVisibility) {
+		if (in_array($newVisibility, self::$valid_visibilities)) {
+			$this->mutatorVisibility = $newVisibility;
+		} else {
+			$this->mutatorVisibility = self::DEFAULT_VISIBILITY;
+		}
+
+	}
+
+	/**
+	 * Get the Peer constant name that will identify this column.
+	 * @return     string
+	 */
+	public function getPeerName() {
+		return $this->peerName;
+	}
+
+	/**
+	 * Set the Peer constant name that will identify this column.
+	 * @param      $name string
+	 */
+	public function setPeerName($name) {
+		$this->peerName = $name;
+	}
+
+	/**
+	 * Get type to use in PHP sources.
+	 *
+	 * If no type has been specified, then uses results of getPhpNative().
+	 *
+	 * @return     string The type name.
+	 * @see        getPhpNative()
+	 */
+	public function getPhpType()
+	{
+		if ($this->phpType !== null) {
+			return $this->phpType;
+		}
+		return $this->getPhpNative();
+	}
+
+	/**
+	 * Get the location of this column within the table (one-based).
+	 * @return     int value of position.
+	 */
+	public function getPosition()
+	{
+		return $this->position;
+	}
+
+	/**
+	 * Get the location of this column within the table (one-based).
+	 * @param      int $v Value to assign to position.
+	 */
+	public function setPosition($v)
+	{
+		$this->position = $v;
+	}
+
+	/**
+	 * Set the parent Table of the column
+	 */
+	public function setTable(Table $parent)
+	{
+		$this->parentTable = $parent;
+	}
+
+	/**
+	 * Get the parent Table of the column
+	 */
+	public function getTable()
+	{
+		return $this->parentTable;
+	}
+
+	/**
+	 * Returns the Name of the table the column is in
+	 */
+	public function getTableName()
+	{
+		return $this->parentTable->getName();
+	}
+
+	/**
+	 * Adds a new inheritance definition to the inheritance list and set the
+	 * parent column of the inheritance to the current column
+	 * @param      mixed $inhdata Inheritance or XML data.
+	 */
+	public function addInheritance($inhdata)
+	{
+		if ($inhdata instanceof Inheritance) {
+			$inh = $inhdata;
+			$inh->setColumn($this);
+			if ($this->inheritanceList === null) {
+				$this->inheritanceList = array();
+				$this->isEnumeratedClasses = true;
+			}
+			$this->inheritanceList[] = $inh;
+			return $inh;
+		} else {
+			$inh = new Inheritance();
+			$inh->loadFromXML($inhdata);
+			return $this->addInheritance($inh);
+		}
+	}
+
+	/**
+	 * Get the inheritance definitions.
+	 */
+	public function getChildren()
+	{
+		return $this->inheritanceList;
+	}
+
+	/**
+	 * Determine if this column is a normal property or specifies a
+	 * the classes that are represented in the table containing this column.
+	 */
+	public function isInheritance()
+	{
+		return $this->isInheritance;
+	}
+
+	/**
+	 * Determine if possible classes have been enumerated in the xml file.
+	 */
+	public function isEnumeratedClasses()
+	{
+		return $this->isEnumeratedClasses;
+	}
+
+	/**
+	 * Return the isNotNull property of the column
+	 */
+	public function isNotNull()
+	{
+		return $this->isNotNull;
+	}
+
+	/**
+	 * Set the isNotNull property of the column
+	 */
+	public function setNotNull($status)
+	{
+		$this->isNotNull = (boolean) $status;
+	}
+
+	/**
+	 * Return NOT NULL String for this column
+	 *
+	 * @return     "NOT NULL" if null values are not allowed or an empty string.
+	 */
+	public function getNotNullString()
+	{
+		return $this->getTable()->getDatabase()->getPlatform()->getNullString($this->isNotNull());
+	}
+
+	/**
+	 * Set whether the column is a primary key or not.
+	 * @param      boolean $v
+	 */
+	public function setPrimaryKey($v)
+	{
+		$this->isPrimaryKey = (boolean) $v;
+	}
+
+	/**
+	 * Return true if the column is a primary key
+	 */
+	public function isPrimaryKey()
+	{
+		return $this->isPrimaryKey;
+	}
+
+	/**
+	 * Set if the column is the node key of a tree
+	 */
+	public function setNodeKey($nk)
+	{
+		$this->isNodeKey = (boolean) $nk;
+	}
+
+	/**
+	 * Return true if the column is a node key of a tree
+	 */
+	public function isNodeKey()
+	{
+		return $this->isNodeKey;
+	}
+
+	/**
+	 * Set if the column is the node key of a tree
+	 */
+	public function setNodeKeySep($sep)
+	{
+		$this->nodeKeySep = (string) $sep;
+	}
+
+	/**
+	 * Return true if the column is a node key of a tree
+	 */
+	public function getNodeKeySep()
+	{
+		return $this->nodeKeySep;
+	}
+
+	/**
+	 * Set if the column is the nested set left key of a tree
+	 */
+	public function setNestedSetLeftKey($nslk)
+	{
+		$this->isNestedSetLeftKey = (boolean) $nslk;
+	}
+
+	/**
+	 * Return true if the column is a nested set key of a tree
+	 */
+	public function isNestedSetLeftKey()
+	{
+		return $this->isNestedSetLeftKey;
+	}
+
+	/**
+	 * Set if the column is the nested set right key of a tree
+	 */
+	public function setNestedSetRightKey($nsrk)
+	{
+		$this->isNestedSetRightKey = (boolean) $nsrk;
+	}
+
+	/**
+	 * Return true if the column is a nested set right key of a tree
+	 */
+	public function isNestedSetRightKey()
+	{
+		return $this->isNestedSetRightKey;
+	}
+
+	/**
+	 * Set if the column is the scope key of a tree
+	 */
+	public function setTreeScopeKey($tsk)
+	{
+		$this->isTreeScopeKey = (boolean) $tsk;
+	}
+
+	/**
+	 * Return true if the column is a scope key of a tree
+	 * @return     boolean
+	 */
+	public function isTreeScopeKey()
+	{
+		return $this->isTreeScopeKey;
+	}
+
+	/**
+	 * Set true if the column is UNIQUE
+	 * @param      boolean $u
+	 */
+	public function setUnique($u)
+	{
+		$this->isUnique = $u;
+	}
+
+	/**
+	 * Get the UNIQUE property.
+	 * @return     boolean
+	 */
+	public function isUnique()
+	{
+		return $this->isUnique;
+	}
+
+	/**
+	 * Return true if the column requires a transaction in Postgres
+	 * @return     boolean
+	 */
+	public function requiresTransactionInPostgres()
+	{
+		return $this->needsTransactionInPostgres;
+	}
+
+	/**
+	 * Utility method to determine if this column is a foreign key.
+	 * @return     boolean
+	 */
+	public function isForeignKey()
+	{
+		return (count($this->getForeignKeys()) > 0);
+	}
+
+	/**
+	 * Whether this column is a part of more than one foreign key.
+	 * @return     boolean
+	 */
+	public function hasMultipleFK()
+	{
+		return (count($this->getForeignKeys()) > 1);
+	}
+
+	/**
+	 * Get the foreign key objects for this column (if it is a foreign key or part of a foreign key)
+	 * @return     array
+	 */
+	public function getForeignKeys()
+	{
+		return $this->parentTable->getColumnForeignKeys($this->name);
+	}
+
+	/**
+	 * Adds the foreign key from another table that refers to this column.
+	 */
+	public function addReferrer(ForeignKey $fk)
+	{
+		if ($this->referrers === null) {
+			$this->referrers = array();
+		}
+		$this->referrers[] = $fk;
+	}
+
+	/**
+	 * Get list of references to this column.
+	 */
+	public function getReferrers()
+	{
+		if ($this->referrers === null) {
+			$this->referrers = array();
+		}
+		return $this->referrers;
+	}
+
+	/**
+	 * Sets the domain up for specified Propel type.
+	 *
+	 * Calling this method will implicitly overwrite any previously set type,
+	 * size, scale (or other domain attributes).
+	 *
+	 * @param      string $propelType
+	 */
+	public function setDomainForType($propelType)
+	{
+		$this->getDomain()->copy($this->getPlatform()->getDomainForType($propelType));
+	}
+
+	/**
+	 * Sets the propel colunm type.
+	 * @param      string $propelType
+	 * @see        Domain::setType()
+	 */
+	public function setType($propelType)
+	{
+		$this->getDomain()->setType($propelType);
+		if ($propelType == PropelTypes::VARBINARY|| $propelType == PropelTypes::LONGVARBINARY || $propelType == PropelTypes::BLOB) {
+			$this->needsTransactionInPostgres = true;
+		}
+	}
+
+	/**
+	 * Returns the Propel column type as a string.
+	 * @return     string The constant representing Creole type: e.g. "VARCHAR".
+	 * @see        Domain::getType()
+	 */
+	public function getType()
+	{
+		return $this->getDomain()->getType();
+	}
+
+	/**
+	 * Returns the column PDO type integer for this column's Propel type.
+	 * @return     int The integer value representing PDO type param: e.g. PDO::PARAM_INT
+	 */
+	public function getPDOType()
+	{
+		return PropelTypes::getPDOType($this->getType());
+	}
+
+	/**
+	 * Returns the column type as given in the schema as an object
+	 */
+	public function getPropelType()
+	{
+		return $this->getType();
+	}
+
+	/**
+	 * Utility method to know whether column needs Blob/Lob handling.
+	 * @return     boolean
+	 */
+	public function isLobType()
+	{
+		return PropelTypes::isLobType($this->getType());
+	}
+
+	/**
+	 * Utility method to see if the column is text type.
+	 */
+	public function isTextType()
+	{
+		return PropelTypes::isTextType($this->getType());
+	}
+
+	/**
+	 * Utility method to see if the column is numeric type.
+	 * @return     boolean
+	 */
+	public function isNumericType()
+	{
+		return PropelTypes::isNumericType($this->getType());
+	}
+
+	/**
+	 * Utility method to know whether column is a temporal column.
+	 * @return     boolean
+	 */
+	public function isTemporalType()
+	{
+		return PropelTypes::isTemporalType($this->getType());
+	}
+
+	/**
+	 * @see        XMLElement::appendXml(DOMNode)
+	 */
+	public function appendXml(DOMNode $node)
+	{
+		$doc = ($node instanceof DOMDocument) ? $node : $node->ownerDocument;
+
+		$colNode = $node->appendChild($doc->createElement('column'));
+		$colNode->setAttribute('name', $this->name);
+
+		if ($this->phpName !== null) {
+			$colNode->setAttribute('phpName', $this->getPhpName());
+		}
+
+		$colNode->setAttribute('type', $this->getType());
+
+		$domain = $this->getDomain();
+
+		if ($domain->getSize() !== null) {
+			$colNode->setAttribute('size', $domain->getSize());
+		}
+
+		if ($domain->getScale() !== null) {
+			$colNode->setAttribute('scale', $domain->getScale());
+		}
+
+		if ($this->isPrimaryKey) {
+			$colNode->setAttribute('primaryKey', var_export($this->isPrimaryKey, true));
+		}
+
+		if ($this->isAutoIncrement) {
+			$colNode->setAttribute('autoIncrement', var_export($this->isAutoIncrement, true));
+		}
+
+		if ($this->isNotNull) {
+			$colNode->setAttribute('required', 'true');
+		} else {
+			$colNode->setAttribute('required', 'false');
+		}
+
+		if ($domain->getDefaultValue() !== null) {
+			$def = $domain->getDefaultValue();
+			if ($def->isExpression()) {
+				$colNode->setAttribute('defaultExpr', $def->getValue());
+			} else {
+				$colNode->setAttribute('defaultValue', $def->getValue());
+			}
+		}
+
+		if ($this->isInheritance()) {
+			$colNode->setAttribute('inheritance', $this->inheritanceType);
+			foreach ($this->inheritanceList as $inheritance) {
+				$inheritance->appendXml($colNode);
+			}
+		}
+
+		if ($this->isNodeKey()) {
+			$colNode->setAttribute('nodeKey', 'true');
+			if ($this->getNodeKeySep() !== null) {
+				$colNode->setAttribute('nodeKeySep', $this->nodeKeySep);
+			}
+		}
+
+		foreach ($this->vendorInfos as $vi) {
+			$vi->appendXml($colNode);
+		}
+	}
+
+	/**
+	 * Returns the size of the column
+	 * @return     string
+	 */
+	public function getSize()
+	{
+		return $this->domain->getSize();
+	}
+
+	/**
+	 * Set the size of the column
+	 * @param      string $newSize
+	 */
+	public function setSize($newSize)
+	{
+		$this->domain->setSize($newSize);
+	}
+
+	/**
+	 * Returns the scale of the column
+	 * @return     string
+	 */
+	public function getScale()
+	{
+		return $this->domain->getScale();
+	}
+
+	/**
+	 * Set the scale of the column
+	 * @param      string $newScale
+	 */
+	public function setScale($newScale)
+	{
+		$this->domain->setScale($newScale);
+	}
+
+	/**
+	 * Return the size in brackets for use in an sql
+	 * schema if the type is String.  Otherwise return an empty string
+	 */
+	public function printSize()
+	{
+		return $this->domain->printSize();
+	}
+
+	/**
+	 * Return a string that will give this column a default value.
+	 * @return     string
+	 */
+	public function getDefaultSetting()
+	{
+		$dflt = "";
+		$defaultValue = $this->getDefaultValue();
+		if ($defaultValue !== null) {
+			$dflt .= "default ";
+
+			if ($this->getDefaultValue()->isExpression()) {
+				$dflt .= $this->getDefaultValue()->getValue();
+			} else {
+				if ($this->isTextType()) {
+					$dflt .= $this->getPlatform()->quote($defaultValue->getValue());
+				} elseif ($this->getType() == PropelTypes::BOOLEAN) {
+					$dflt .= $this->getPlatform()->getBooleanString($defaultValue->getValue());
+				} else {
+					$dflt .= $defaultValue->getValue();
+				}
+			}
+		}
+		return $dflt;
+	}
+
+	/**
+	 * Set a string that will give this column a default value.
+	 */
+	public function setDefaultValue($def)
+	{
+		$this->domain->setDefaultValue($def);
+	}
+
+	/**
+	 * Get the default value object for this column.
+	 * @return     ColumnDefaultValue
+	 * @see        Domain::getDefaultValue()
+	 */
+	public function getDefaultValue()
+	{
+		return $this->domain->getDefaultValue();
+	}
+
+	/**
+	 * Get the default value suitable for use in PHP.
+	 * @return     mixed
+	 * @see        Domain::getPhpDefaultValue()
+	 */
+	public function getPhpDefaultValue()
+	{
+		return $this->domain->getPhpDefaultValue();
+	}
+
+	/**
+	 * Returns the class name to do input validation
+	 */
+	public function getInputValidator()
+	{
+		return $this->inputValidator;
+	}
+
+	/**
+	 * Return auto increment/sequence string for the target database. We need to
+	 * pass in the props for the target database!
+	 */
+	public function isAutoIncrement()
+	{
+		return $this->isAutoIncrement;
+	}
+
+	/**
+	 * Return auto increment/sequence string for the target database. We need to
+	 * pass in the props for the target database!
+	 */
+	public function isLazyLoad()
+	{
+		return $this->isLazyLoad;
+	}
+
+	/**
+	 * Gets the auto-increment string.
+	 * @return     string
+	 */
+	public function getAutoIncrementString()
+	{
+		if ($this->isAutoIncrement()&& IDMethod::NATIVE === $this->getTable()->getIdMethod()) {
+			return $this->getPlatform()->getAutoIncrement();
+		} elseif ($this->isAutoIncrement()) {
+			throw new EngineException("You have specified autoIncrement for column '" . $this->name . "' but you have not specified idMethod=\"native\" for table '" . $this->getTable()->getName() . "'.");
+		}
+		return "";
+	}
+
+	/**
+	 * Set the auto increment value.
+	 * Use isAutoIncrement() to find out if it is set or not.
+	 */
+	public function setAutoIncrement($value)
+	{
+		$this->isAutoIncrement = (boolean) $value;
+	}
+
+	/**
+	 * Set the column type from a string property
+	 * (normally a string from an sql input file)
+	 *
+	 * @deprecated Do not use; this will be removed in next release.
+	 */
+	public function setTypeFromString($typeName, $size)
+	{
+		$tn = strtoupper($typeName);
+		$this->setType($tn);
+
+		if ($size !== null) {
+			$this->size = $size;
+		}
+
+		if (strpos($tn, "CHAR") !== false) {
+			$this->domain->setType(PropelTypes::VARCHAR);
+		} elseif (strpos($tn, "INT") !== false) {
+			$this->domain->setType(PropelTypes::INTEGER);
+		} elseif (strpos($tn, "FLOAT") !== false) {
+			$this->domain->setType(PropelTypes::FLOAT);
+		} elseif (strpos($tn, "DATE") !== false) {
+			$this->domain->setType(PropelTypes::DATE);
+		} elseif (strpos($tn, "TIME") !== false) {
+			$this->domain->setType(PropelTypes::TIMESTAMP);
+		} else if (strpos($tn, "BINARY") !== false) {
+			$this->domain->setType(PropelTypes::LONGVARBINARY);
+		} else {
+			$this->domain->setType(PropelTypes::VARCHAR);
+		}
+	}
+
+	/**
+	 * Return a string representation of the native PHP type which corresponds
+	 * to the propel type of this column. Use in the generation of Base objects.
+	 *
+	 * @return     string PHP datatype used by propel.
+	 */
+	public function getPhpNative()
+	{
+		return PropelTypes::getPhpNative($this->getType());
+	}
+
+	/**
+	 * Returns true if the column's PHP native type is an boolean, int, long, float, double, string.
+	 * @return     boolean
+	 * @see        PropelTypes::isPhpPrimitiveType()
+	 */
+	public function isPhpPrimitiveType()
+	{
+		return PropelTypes::isPhpPrimitiveType($this->getPhpType());
+	}
+
+	/**
+	 * Return true if column's PHP native type is an boolean, int, long, float, double.
+	 * @return     boolean
+	 * @see        PropelTypes::isPhpPrimitiveNumericType()
+	 */
+	public function isPhpPrimitiveNumericType()
+	{
+		return PropelTypes::isPhpPrimitiveNumericType($this->getPhpType());
+	}
+
+	/**
+	 * Returns true if the column's PHP native type is a class name.
+	 * @return     boolean
+	 * @see        PropelTypes::isPhpObjectType()
+	 */
+	public function isPhpObjectType()
+	{
+		return PropelTypes::isPhpObjectType($this->getPhpType());
+	}
+
+	/**
+	 * Get the platform/adapter impl.
+	 *
+	 * @return     Platform
+	 */
+	public function getPlatform()
+	{
+		return $this->getTable()->getDatabase()->getPlatform();
+	}
+
+	/**
+	 *
+	 * @return     string
+	 * @deprecated Use DDLBuilder->getColumnDDL() instead; this will be removed in 1.3
+	 */
+	public function getSqlString()
+	{
+		$sb = "";
+		$sb .= $this->getPlatform()->quoteIdentifier($this->getName()) . " ";
+		$sb .= $this->getDomain()->getSqlType();
+		if ($this->getPlatform()->hasSize($this->getDomain()->getSqlType())) {
+			$sb .= $this->getDomain()->printSize();
+		}
+		$sb .= " ";
+		$sb .= $this->getDefaultSetting() . " ";
+		$sb .= $this->getNotNullString() . " ";
+		$sb .= $this->getAutoIncrementString();
+		return trim($sb);
+	}
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/database/model/ColumnDefaultValue.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/database/model/ColumnDefaultValue.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/database/model/ColumnDefaultValue.php	(revision 19)
@@ -0,0 +1,101 @@
+<?php
+/*
+ *  $Id: ColumnDefaultValue.php 875 2007-12-19 11:10:15Z heltem $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://propel.phpdb.org>.
+ */
+
+/**
+ * A class for holding a column default value.
+ *
+ * @author     Hans Lellelid <hans@xmpl.org>
+ * @version    $Revision: 875 $
+ * @package    propel.engine.database.model
+ */
+class ColumnDefaultValue {
+
+	const TYPE_VALUE = "value";
+	const TYPE_EXPR = "expr";
+
+	/**
+	 * @var        string The default value, as specified in the schema.
+	 */
+	private $value;
+
+	/**
+	 * @var        string The type of value represented by this object (DefaultValue::TYPE_VALUE or DefaultValue::TYPE_EXPR).
+	 */
+	private $type = ColumnDefaultValue::TYPE_VALUE;
+
+	/**
+	 * Creates a new DefaultValue object.
+	 *
+	 * @param      string $value The default value, as specified in the schema.
+	 * @param      string $type The type of default value (DefaultValue::TYPE_VALUE or DefaultValue::TYPE_EXPR)
+	 */
+	public function __construct($value, $type = null)
+	{
+		$this->setValue($value);
+		if ($type !== null) {
+			$this->setType($type);
+		}
+	}
+
+	/**
+	 * @return     string The type of default value (DefaultValue::TYPE_VALUE or DefaultValue::TYPE_EXPR)
+	 */
+	public function getType()
+	{
+		return $this->type;
+	}
+
+	/**
+	 * @param      string $type The type of default value (DefaultValue::TYPE_VALUE or DefaultValue::TYPE_EXPR)
+	 */
+	public function setType($type)
+	{
+		$this->type = $type;
+	}
+
+	/**
+	 * Convenience method to indicate whether the value in this object is an expression (as opposed to simple value).
+	 *
+	 * @return     boolean Whether value this object holds is an expression.
+	 */
+	public function isExpression()
+	{
+		return ($this->type == self::TYPE_EXPR);
+	}
+
+	/**
+	 * @return     string The value, as specified in the schema.
+	 */
+	public function getValue()
+	{
+		return $this->value;
+	}
+
+	/**
+	 * @param      string $value The value, as specified in the schema.
+	 */
+	public function setValue($value)
+	{
+		$this->value = $value;
+	}
+
+
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/database/model/ConstraintNameGenerator.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/database/model/ConstraintNameGenerator.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/database/model/ConstraintNameGenerator.php	(revision 19)
@@ -0,0 +1,84 @@
+<?php
+
+/*
+ *  $Id: ConstraintNameGenerator.php 521 2007-01-05 13:29:36Z heltem $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://propel.phpdb.org>.
+ */
+
+
+/**
+ * A <code>NameGenerator</code> implementation for table-specific
+ * constraints.  Conforms to the maximum column name length for the
+ * type of database in use.
+ *
+ * @author     Hans Lellelid <hans@xmpl.org> (Propel)
+ * @author     Daniel Rall <dlr@finemaltcoding.com> (Torque)
+ * @version    $Revision: 521 $
+ * @package    propel.engine.database.model
+ */
+class ConstraintNameGenerator implements NameGenerator {
+	/**
+	 * Conditional compilation flag.
+	 */
+	const DEBUG = false;
+
+	/**
+	 * First element of <code>inputs</code> should be of type {@link Database}, second
+	 * should be a table name, third is the type identifier (spared if
+	 * trimming is necessary due to database type length constraints),
+	 * and the fourth is a <code>Integer</code> indicating the number
+	 * of this contraint.
+	 *
+	 * @see        NameGenerator
+	 * @throws     EngineException
+	 */
+	public function generateName($inputs)
+	{
+
+		$db = $inputs[0];
+		$name = $inputs[1];
+		$namePostfix = $inputs[2];
+		$constraintNbr = (string) $inputs[3];
+
+		// Calculate maximum RDBMS-specific column character limit.
+		$maxBodyLength = -1;
+		try {
+			$maxColumnNameLength = (int) $db->getPlatform()->getMaxColumnNameLength();
+			$maxBodyLength = ($maxColumnNameLength - strlen($namePostfix)
+					- strlen($constraintNbr) - 2);
+
+			if (self::DEBUG) {
+				print("maxColumnNameLength=" . $maxColumnNameLength
+						. " maxBodyLength=" . $maxBodyLength . "\n");
+			}
+		} catch (EngineException $e) {
+			echo $e;
+			throw $e;
+		}
+
+		// Do any necessary trimming.
+		if ($maxBodyLength !== -1 && strlen($name) > $maxBodyLength) {
+			$name = substr($name, 0, $maxBodyLength);
+		}
+
+		$name .= self::STD_SEPARATOR_CHAR . $namePostfix
+			. self::STD_SEPARATOR_CHAR . $constraintNbr;
+
+		return $name;
+	}
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/database/model/Database.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/database/model/Database.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/database/model/Database.php	(revision 19)
@@ -0,0 +1,518 @@
+<?php
+
+/*
+ *  $Id: Database.php 1020 2008-04-04 10:03:56Z hans $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://propel.phpdb.org>.
+ */
+
+require_once 'propel/engine/database/model/XMLElement.php';
+include_once 'propel/engine/database/model/IDMethod.php';
+include_once 'propel/engine/database/model/NameGenerator.php';
+include_once 'propel/engine/database/model/Table.php';
+
+/**
+ * A class for holding application data structures.
+ *
+ * @author     Hans Lellelid <hans@xmpl.org> (Propel)
+ * @author     Leon Messerschmidt <leon@opticode.co.za> (Torque)
+ * @author     John McNally<jmcnally@collab.net> (Torque)
+ * @author     Martin Poeschl<mpoeschl@marmot.at> (Torque)
+ * @author     Daniel Rall<dlr@collab.net> (Torque)
+ * @author     Byron Foster <byron_foster@yahoo.com> (Torque)
+ * @version    $Revision: 1020 $
+ * @package    propel.engine.database.model
+ */
+class Database extends XMLElement {
+
+	private $platform;
+	private $tableList = array();
+	private $curColumn;
+	private $name;
+	private $pkg;
+	private $baseClass;
+	private $basePeer;
+	private $defaultIdMethod;
+	private $defaultPhpNamingMethod;
+	private $defaultTranslateMethod;
+	private $dbParent;
+	private $tablesByName = array();
+	private $tablesByPhpName = array();
+	private $heavyIndexing;
+
+	private $domainMap = array();
+
+	/**
+	 * Constructs a new Database object.
+	 *
+	 * @param      string $name
+	 */
+	public function __construct($name = null)
+	{
+		$this->name = $name;
+	}
+
+	/**
+	 * Sets up the Database object based on the attributes that were passed to loadFromXML().
+	 * @see        parent::loadFromXML()
+	 */
+	protected function setupObject()
+	{
+		$this->name = $this->getAttribute("name");
+		$this->pkg = $this->getAttribute("package");
+		$this->baseClass = $this->getAttribute("baseClass");
+		$this->basePeer = $this->getAttribute("basePeer");
+		$this->defaultIdMethod = $this->getAttribute("defaultIdMethod", IDMethod::NATIVE);
+		$this->defaultPhpNamingMethod = $this->getAttribute("defaultPhpNamingMethod", NameGenerator::CONV_METHOD_UNDERSCORE);
+		$this->defaultTranslateMethod = $this->getAttribute("defaultTranslateMethod", Validator::TRANSLATE_NONE);
+		$this->heavyIndexing = $this->booleanValue($this->getAttribute("heavyIndexing"));
+	}
+
+	/**
+	 * Returns the Platform implementation for this database.
+	 *
+	 * @return     Platform a Platform implementation
+	 */
+	public function getPlatform()
+	{
+		return $this->platform;
+	}
+
+	/**
+	 * Sets the Platform implementation for this database.
+	 *
+	 * @param      Platform $platform A Platform implementation
+	 */
+	public function setPlatform($platform)
+	{
+		$this->platform = $platform;
+	}
+
+	/**
+	 * Get the name of the Database
+	 */
+	public function getName()
+	{
+		return $this->name;
+	}
+
+	/**
+	 * Set the name of the Database
+	 */
+	public function setName($name)
+	{
+		$this->name = $name;
+	}
+
+	/**
+	 * Get the value of package.
+	 * @return     value of package.
+	 */
+	public function getPackage()
+	{
+		return $this->pkg;
+	}
+
+	/**
+	 * Set the value of package.
+	 * @param      v  Value to assign to package.
+	 */
+	public function setPackage($v)
+	{
+		$this->pkg = $v;
+	}
+
+	/**
+	 * Get the value of baseClass.
+	 * @return     value of baseClass.
+	 */
+	public function getBaseClass()
+	{
+		return $this->baseClass;
+	}
+
+	/**
+	 * Set the value of baseClass.
+	 * @param      v  Value to assign to baseClass.
+	 */
+	public function setBaseClass($v)
+	{
+		$this->baseClass = $v;
+	}
+
+	/**
+	 * Get the value of basePeer.
+	 * @return     value of basePeer.
+	 */
+	public function getBasePeer()
+	{
+		return $this->basePeer;
+	}
+
+	/**
+	 * Set the value of basePeer.
+	 * @param      v Value to assign to basePeer.
+	 */
+	public function setBasePeer($v)
+	{
+		$this->basePeer = $v;
+	}
+
+	/**
+	 * Get the value of defaultIdMethod.
+	 * @return     value of defaultIdMethod.
+	 */
+	public function getDefaultIdMethod()
+	{
+		return $this->defaultIdMethod;
+	}
+
+	/**
+	 * Set the value of defaultIdMethod.
+	 * @param      v Value to assign to defaultIdMethod.
+	 */
+	public function setDefaultIdMethod($v)
+	{
+		$this->defaultIdMethod = $v;
+	}
+
+	/**
+	 * Get the value of defaultPHPNamingMethod which specifies the
+	 * method for converting schema names for table and column to PHP names.
+	 * @return     string The default naming conversion used by this database.
+	 */
+	public function getDefaultPhpNamingMethod()
+	{
+		return $this->defaultPhpNamingMethod;
+	}
+
+	/**
+	 * Set the value of defaultPHPNamingMethod.
+	 * @param      string $v The default naming conversion for this database to use.
+	 */
+	public function setDefaultPhpNamingMethod($v)
+	{
+		$this->defaultPhpNamingMethod = $v;
+	}
+
+	/**
+	 * Get the value of defaultTranslateMethod which specifies the
+	 * method for translate validator error messages.
+	 * @return     string The default translate method.
+	 */
+	public function getDefaultTranslateMethod()
+	{
+		return $this->defaultTranslateMethod;
+	}
+
+	/**
+	 * Set the value of defaultTranslateMethod.
+	 * @param      string $v The default translate method to use.
+	 */
+	public function setDefaultTranslateMethod($v)
+	{
+		$this->defaultTranslateMethod = $v;
+	}
+
+	/**
+	 * Get the value of heavyIndexing.
+	 *
+	 * This is a synonym for getHeavyIndexing().
+	 *
+	 * @return     boolean Value of heavyIndexing.
+	 * @see        getHeavyIndexing()
+	 */
+	public function isHeavyIndexing()
+	{
+		return $this->getHeavyIndexing();
+	}
+
+	/**
+	 * Get the value of heavyIndexing.
+	 *
+	 * @return     boolean Value of heavyIndexing.
+	 */
+	public function getHeavyIndexing()
+	{
+		return $this->heavyIndexing;
+	}
+
+	/**
+	 * Set the value of heavyIndexing.
+	 * @param      boolean $v  Value to assign to heavyIndexing.
+	 */
+	public function setHeavyIndexing($v)
+	{
+		$this->heavyIndexing = (boolean) $v;
+	}
+
+	/**
+	 * Return an array of all tables
+	 */
+	public function getTables()
+	{
+		return $this->tableList;
+	}
+
+	/**
+	 * Return the table with the specified name.
+	 * @param      string $name The name of the table (e.g. 'my_table')
+	 * @return     Table a Table object or null if it doesn't exist
+	 */
+	public function getTable($name)
+	{
+		if (isset($this->tablesByName[$name])) {
+			return $this->tablesByName[$name];
+		}
+		return null; // just to be explicit
+	}
+
+	/**
+	 * Return the table with the specified phpName.
+	 * @param      string $phpName the PHP Name of the table (e.g. 'MyTable')
+	 * @return     Table a Table object or null if it doesn't exist
+	 */
+	public function getTableByPhpName($phpName)
+	{
+		if (isset($this->tablesByPhpName[$phpName])) {
+			return $this->tablesByPhpName[$phpName];
+		}
+		return null; // just to be explicit
+	}
+
+	/**
+	 * An utility method to add a new table from an xml attribute.
+	 */
+	public function addTable($data)
+	{
+		if ($data instanceof Table) {
+			$tbl = $data; // alias
+			$tbl->setDatabase($this);
+			if (isset($this->tablesByName[$tbl->getName()])) {
+				throw new EngineException("Duplicate table declared: " . $tbl->getName());
+			}
+			$this->tableList[] = $tbl;
+			$this->tablesByName[ $tbl->getName() ] = $tbl;
+			$this->tablesByPhpName[ $tbl->getPhpName() ] = $tbl;
+			if ($tbl->getPackage() === null) {
+				$tbl->setPackage($this->getPackage());
+			}
+			return $tbl;
+		} else {
+			$tbl = new Table();
+			$tbl->setDatabase($this);
+			$tbl->loadFromXML($data);
+			return $this->addTable($tbl); // call self w/ different param
+		}
+	}
+
+	/**
+	 * Set the parent of the database
+	 */
+	public function setAppData(AppData $parent)
+	{
+		$this->dbParent = $parent;
+	}
+
+	/**
+	 * Get the parent of the table
+	 */
+	public function getAppData()
+	{
+		return $this->dbParent;
+	}
+
+	/**
+	 * Adds Domain object from <domain> tag.
+	 * @param      mixed XML attributes (array) or Domain object.
+	 */
+	public function addDomain($data) {
+
+		if ($data instanceof Domain) {
+			$domain = $data; // alias
+			$domain->setDatabase($this);
+			$this->domainMap[ $domain->getName() ] = $domain;
+			return $domain;
+		} else {
+			$domain = new Domain();
+			$domain->setDatabase($this);
+			$domain->loadFromXML($data);
+			return $this->addDomain($domain); // call self w/ different param
+		}
+	}
+
+	/**
+	 * Get already configured Domain object by name.
+	 * @return     Domain
+	 */
+	public function getDomain($domainName)
+	{
+		if (isset($this->domainMap[$domainName])) {
+			return $this->domainMap[$domainName];
+		}
+		return null; // just to be explicit
+	}
+
+	public function doFinalInitialization()
+	{
+		$tables = $this->getTables();
+
+		for ($i=0,$size=count($tables); $i < $size; $i++) {
+			$currTable = $tables[$i];
+
+			// check schema integrity
+			// if idMethod="autoincrement", make sure a column is
+			// specified as autoIncrement="true"
+			// FIXME: Handle idMethod="native" via DB adapter.
+			/*
+
+			--- REMOVING THIS BECAUSE IT'S ANNOYING
+
+			if ($currTable->getIdMethod() == IDMethod::NATIVE ) {
+			$columns = $currTable->getColumns();
+			$foundOne = false;
+			for ($j=0, $cLen=count($columns); $j < $cLen && !$foundOne; $j++) {
+			$foundOne = $columns[$j]->isAutoIncrement();
+			}
+
+			if (!$foundOne) {
+			$errorMessage = "Table '" . $currTable->getName()
+			. "' is set to use native id generation, but it does not "
+			. "have a column which declared as the one to "
+			. "auto increment (i.e. autoIncrement=\"true\")";
+
+			throw new BuildException($errorMessage);
+			}
+			}
+			*/
+
+			$currTable->doFinalInitialization();
+
+			// setup reverse fk relations
+			$fks = $currTable->getForeignKeys();
+			for ($j=0, $fksLen=count($fks); $j < $fksLen; $j++) {
+				$currFK = $fks[$j];
+				$foreignTable = $this->getTable($currFK->getForeignTableName());
+				if ($foreignTable === null) {
+					throw new BuildException("ERROR!! Attempt to set foreign"
+					. " key to nonexistent table, "
+					. $currFK->getForeignTableName() . "!");
+				}
+
+				$referrers = $foreignTable->getReferrers();
+				if ($referrers === null || !in_array($currFK, $referrers, true) ) {
+					$foreignTable->addReferrer($currFK);
+				}
+
+				// local column references
+				$localColumnNames = $currFK->getLocalColumns();
+
+				for ($k=0,$lcnLen=count($localColumnNames); $k < $lcnLen; $k++) {
+
+					$local = $currTable->getColumn($localColumnNames[$k]);
+
+					// give notice of a schema inconsistency.
+					// note we do not prevent the npe as there is nothing
+					// that we can do, if it is to occur.
+					if ($local === null) {
+						throw new BuildException("ERROR!! Attempt to define foreign"
+						. " key with nonexistent column, "
+						. $localColumnNames[$k] . ", in table, "
+						. $currTable->getName() . "!");
+					}
+
+					//check for foreign pk's
+					if ($local->isPrimaryKey()) {
+						$currTable->setContainsForeignPK(true);
+					}
+
+				} // for each local col name
+
+				// foreign column references
+				$foreignColumnNames = $currFK->getForeignColumns();
+				for ($k=0,$fcnLen=count($localColumnNames); $k < $fcnLen; $k++) {
+					$foreign = $foreignTable->getColumn($foreignColumnNames[$k]);
+					// if the foreign column does not exist, we may have an
+					// external reference or a misspelling
+					if ($foreign === null) {
+						throw new BuildException("ERROR!! Attempt to set foreign"
+						. " key to nonexistent column, "
+						. $foreignColumnNames[$k] . ", in table, "
+						. $foreignTable->getName() . "!");
+					} else {
+						$foreign->addReferrer($currFK);
+					}
+				} // for each foreign col ref
+			}
+		}
+	}
+
+	/**
+	 * @see        XMLElement::appendXml(DOMNode)
+	 */
+	public function appendXml(DOMNode $node)
+	{
+		$doc = ($node instanceof DOMDocument) ? $node : $node->ownerDocument;
+
+		$dbNode = $node->appendChild($doc->createElement('database'));
+
+		$dbNode->setAttribute('name', $this->name);
+
+		if ($this->pkg) {
+			$dbNode->setAttribute('package', $this->pkg);
+		}
+
+		if ($this->defaultIdMethod) {
+			$dbNode->setAttribute('defaultIdMethod', $this->defaultIdMethod);
+		}
+
+		if ($this->baseClass) {
+			$dbNode->setAttribute('baseClass', $this->baseClass);
+		}
+
+		if ($this->basePeer) {
+			$dbNode->setAttribute('basePeer', $this->basePeer);
+		}
+
+		if ($this->defaultPhpNamingMethod) {
+			$dbNode->setAttribute('defaultPhpNamingMethod', $this->defaultPhpNamingMethod);
+		}
+
+		if ($this->defaultTranslateMethod) {
+			$dbNode->setAttribute('defaultTranslateMethod', $this->defaultTranslateMethod);
+		}
+
+		/*
+
+		FIXME - Before we can add support for domains in the schema, we need
+		to have a method of the Column that indicates whether the column was mapped
+		to a SPECIFIC domain (since Column->getDomain() will always return a Domain object)
+
+		foreach ($this->domainMap as $domain) {
+		$domain->appendXml($dbNode);
+		}
+		*/
+		foreach ($this->vendorInfos as $vi) {
+			$vi->appendXml($dbNode);
+		}
+
+		foreach ($this->tableList as $table) {
+			$table->appendXml($dbNode);
+		}
+
+	}
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/database/model/Domain.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/database/model/Domain.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/database/model/Domain.php	(revision 19)
@@ -0,0 +1,396 @@
+<?php
+/*
+ *  $Id: Domain.php 989 2008-03-11 14:29:30Z heltem $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://propel.phpdb.org>.
+ */
+
+require_once 'propel/engine/database/model/XMLElement.php';
+
+/**
+ * A class for holding data about a domain used in the schema.
+ *
+ * @author     Hans Lellelid <hans@xmpl.org> (Propel)
+ * @author     Martin Poeschl <mpoeschl@marmot.at> (Torque)
+ * @version    $Revision: 989 $
+ * @package    propel.engine.database.model
+ */
+class Domain extends XMLElement {
+
+	/**
+	 * @var        string The name of this domain
+	 */
+	private $name;
+
+	/**
+	 * @var        string Description for this domain.
+	 */
+	private $description;
+
+	/**
+	 * @var        int Size
+	 */
+	private $size;
+
+	/**
+	 * @var        int Scale
+	 */
+	private $scale;
+
+	/**
+	 * @var        int Propel type from schema
+	 */
+	private $propelType;
+
+	/**
+	 * @var        string The SQL type to use for this column
+	 */
+	private $sqlType;
+
+	/**
+	 * @var        ColumnDefaultValue A default value
+	 */
+	private $defaultValue;
+
+	/**
+	 * @var        Database
+	 */
+	private $database;
+
+	/**
+	 * Creates a new Domain object.
+	 * If this domain needs a name, it must be specified manually.
+	 *
+	 * @param      string $type Propel type.
+	 * @param      string $sqlType SQL type.
+	 * @param      string $size
+	 * @param      string $scale
+	 */
+	public function __construct($type = null, $sqlType = null, $size = null, $scale = null)
+	{
+		$this->propelType = $type;
+		$this->sqlType = ($sqlType !== null) ? $sqlType : $type;
+		$this->size = $size;
+		$this->scale = $scale;
+	}
+
+	/**
+	 * Copy the values from current object into passed-in Domain.
+	 * @param      Domain $domain Domain to copy values into.
+	 */
+	public function copy(Domain $domain)
+	{
+		$this->defaultValue = $domain->getDefaultValue();
+		$this->description = $domain->getDescription();
+		$this->name = $domain->getName();
+		$this->scale = $domain->getScale();
+		$this->size = $domain->getSize();
+		$this->sqlType = $domain->getSqlType();
+		$this->propelType = $domain->getType();
+	}
+
+	/**
+	 * Sets up the Domain object based on the attributes that were passed to loadFromXML().
+	 * @see        parent::loadFromXML()
+	 */
+	protected function setupObject()
+	{
+		$schemaType = strtoupper($this->getAttribute("type"));
+		$this->copy($this->getDatabase()->getPlatform()->getDomainForType($schemaType));
+
+		//Name
+		$this->name = $this->getAttribute("name");
+
+		// Default value
+		$defval = $this->getAttribute("defaultValue", $this->getAttribute("default"));
+		if ($defval !== null) {
+			$this->setDefaultValue(new ColumnDefaultValue($defval, ColumnDefaultValue::TYPE_VALUE));
+		} elseif ($this->getAttribute("defaultExpr") !== null) {
+			$this->setDefaultValue(new ColumnDefaultValue($this->getAttribute("defaultExpr"), ColumnDefaultValue::TYPE_EXPR));
+		}
+
+		$this->size = $this->getAttribute("size");
+		$this->scale = $this->getAttribute("scale");
+		$this->description = $this->getAttribute("description");
+	}
+
+	/**
+	 * Sets the owning database object (if this domain is being setup via XML).
+	 * @param      Database $database
+	 */
+	public function setDatabase(Database $database)
+	{
+		$this->database = $database;
+	}
+
+	/**
+	 * Gets the owning database object (if this domain was setup via XML).
+	 * @return     Database
+	 */
+	public function getDatabase()
+	{
+		return $this->database;
+	}
+
+	/**
+	 * @return     string Returns the description.
+	 */
+	public function getDescription()
+	{
+		return $this->description;
+	}
+
+	/**
+	 * @param      string $description The description to set.
+	 */
+	public function setDescription($description)
+	{
+		$this->description = $description;
+	}
+
+	/**
+	 * @return     string Returns the name.
+	 */
+	public function getName()
+	{
+		return $this->name;
+	}
+
+	/**
+	 * @param      string $name The name to set.
+	 */
+	public function setName($name)
+	{
+		$this->name = $name;
+	}
+
+	/**
+	 * @return     string Returns the scale.
+	 */
+	public function getScale()
+	{
+		return $this->scale;
+	}
+
+	/**
+	 * @param      string $scale The scale to set.
+	 */
+	public function setScale($scale)
+	{
+		$this->scale = $scale;
+	}
+
+	/**
+	 * Replaces the size if the new value is not null.
+	 *
+	 * @param      string $value The size to set.
+	 */
+	public function replaceScale($value)
+	{
+		if ($value !== null) {
+			$this->scale = $value;
+		}
+	}
+
+	/**
+	 * @return     int Returns the size.
+	 */
+	public function getSize()
+	{
+		return $this->size;
+	}
+
+	/**
+	 * @param      int $size The size to set.
+	 */
+	public function setSize($size)
+	{
+		$this->size = $size;
+	}
+
+	/**
+	 * Replaces the size if the new value is not null.
+	 *
+	 * @param      int $value The size to set.
+	 */
+	public function replaceSize($value)
+	{
+		if ($value !== null) {
+			$this->size = $value;
+		}
+	}
+
+	/**
+	 * @return     string Returns the propelType.
+	 */
+	public function getType()
+	{
+		return $this->propelType;
+	}
+
+	/**
+	 * @param      string $propelType The PropelTypes type to set.
+	 */
+	public function setType($propelType)
+	{
+		$this->propelType = $propelType;
+	}
+
+	/**
+	 * Replaces the type if the new value is not null.
+	 *
+	 * @param      string $value The tyep to set.
+	 */
+	public function replaceType($value)
+	{
+		if ($value !== null) {
+			$this->propelType = $value;
+		}
+	}
+
+	/**
+	 * Gets the default value object.
+	 * @return     ColumnDefaultValue The default value object for this domain.
+	 */
+	public function getDefaultValue()
+	{
+		return $this->defaultValue;
+	}
+
+	/**
+	 * Gets the default value, type-casted for use in PHP OM.
+	 * @return     mixed
+	 * @see        getDefaultValue()
+	 */
+	public function getPhpDefaultValue()
+	{
+		if ($this->defaultValue === null) {
+			return null;
+		} else {
+			if ($this->defaultValue->isExpression()) {
+				throw new EngineException("Cannot get PHP version of default value for default value EXPRESSION.");
+			}
+			if ($this->propelType === PropelTypes::BOOLEAN) {
+				return $this->booleanValue($this->defaultValue->getValue());
+			} else {
+				return $this->defaultValue->getValue();
+			}
+		}
+	}
+
+	/**
+	 * @param      ColumnDefaultValue $value The column default value to set.
+	 */
+	public function setDefaultValue(ColumnDefaultValue $value)
+	{
+		$this->defaultValue = $value;
+	}
+
+	/**
+	 * Replaces the default value if the new value is not null.
+	 *
+	 * @param      ColumnDefaultValue $value The defualt value object
+	 */
+	public function replaceDefaultValue(ColumnDefaultValue $value = null)
+	{
+		if ($value !== null) {
+			$this->defaultValue = $value;
+		}
+	}
+
+	/**
+	 * @return     string Returns the sqlType.
+	 */
+	public function getSqlType()
+	{
+		return $this->sqlType;
+	}
+
+	/**
+	 * @param      string $sqlType The sqlType to set.
+	 */
+	public function setSqlType($sqlType)
+	{
+		$this->sqlType = $sqlType;
+	}
+
+	/**
+	 * Replaces the SQL type if the new value is not null.
+	 * @param      string $sqlType The native SQL type to use for this domain.
+	 */
+	public function replaceSqlType($sqlType)
+	{
+		if ($sqlType !== null) {
+			$this->sqlType = $sqlType;
+		}
+	}
+
+	/**
+	 * Return the size and scale in brackets for use in an sql schema.
+	 *
+	 * @return     string Size and scale or an empty String if there are no values
+	 *         available.
+	 */
+	public function printSize()
+	{
+		if ($this->size !== null && $this->scale !== null)  {
+			return '(' . $this->size . ',' . $this->scale . ')';
+		} elseif ($this->size !== null) {
+			return '(' . $this->size . ')';
+		} else {
+			return "";
+		}
+	}
+
+	/**
+	 * @see        XMLElement::appendXml(DOMNode)
+	 */
+	public function appendXml(DOMNode $node)
+	{
+		$doc = ($node instanceof DOMDocument) ? $node : $node->ownerDocument;
+
+		$domainNode = $node->appendChild($doc->createElement('domain'));
+		$domainNode->setAttribute('type', $this->getType());
+		$domainNode->setAttribute('name', $this->getName());
+
+		if ($this->sqlType !== $this->getType()) {
+			$domainNode->setAttribute('sqlType', $this->sqlType);
+		}
+
+		$def = $this->getDefaultValue();
+		if ($def) {
+			if ($def->isExpression()) {
+				$domainNode->setAttribute('defaultExpr', $def->getValue());
+			} else {
+				$domainNode->setAttribute('defaultValue', $def->getValue());
+			}
+		}
+
+		if ($this->size) {
+			$domainNode->setAttribute('size', $this->size);
+		}
+
+		if ($this->scale) {
+			$domainNode->setAttribute('scale', $this->scale);
+		}
+
+		if ($this->description) {
+			$domainNode->setAttribute('description', $this->description);
+		}
+	}
+
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/database/model/ForeignKey.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/database/model/ForeignKey.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/database/model/ForeignKey.php	(revision 19)
@@ -0,0 +1,439 @@
+<?php
+/*
+ *  $Id: ForeignKey.php 989 2008-03-11 14:29:30Z heltem $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://propel.phpdb.org>.
+ */
+
+require_once 'propel/engine/database/model/XMLElement.php';
+
+/**
+ * A Class for information about foreign keys of a table.
+ *
+ * @author     Hans Lellelid <hans@xmpl.org>
+ * @author     Fedor <fedor.karpelevitch@home.com>
+ * @author     Daniel Rall <dlr@finemaltcoding.com>
+ * @version    $Revision: 989 $
+ * @package    propel.engine.database.model
+ */
+class ForeignKey extends XMLElement {
+
+	private $foreignTableName;
+	private $name;
+	private $phpName;
+	private $refPhpName;
+	private $onUpdate;
+	private $onDelete;
+	private $parentTable;
+	private $localColumns = array();
+	private $foreignColumns = array();
+
+	// the uppercase equivalent of the onDelete/onUpdate values in the dtd
+	const NONE     = "";            // No "ON [ DELETE | UPDATE]" behaviour specified.
+	const NOACTION  = "NO ACTION";
+	const CASCADE  = "CASCADE";
+	const RESTRICT = "RESTRICT";
+	const SETDEFAULT  = "SET DEFAULT";
+	const SETNULL  = "SET NULL";
+
+	/**
+	 * Constructs a new ForeignKey object.
+	 *
+	 * @param      string $name
+	 */
+	public function __construct($name=null)
+	{
+		$this->name = $name;
+	}
+
+	/**
+	 * Sets up the ForeignKey object based on the attributes that were passed to loadFromXML().
+	 * @see        parent::loadFromXML()
+	 */
+	protected function setupObject()
+	{
+		$this->foreignTableName = $this->getAttribute("foreignTable");
+		$this->name = $this->getAttribute("name");
+		$this->phpName = $this->getAttribute("phpName");
+		$this->refPhpName = $this->getAttribute("refPhpName");
+		$this->onUpdate = $this->normalizeFKey($this->getAttribute("onUpdate"));
+		$this->onDelete = $this->normalizeFKey($this->getAttribute("onDelete"));
+	}
+
+	/**
+	 * normalizes the input of onDelete, onUpdate attributes
+	 */
+	private function normalizeFKey($attrib)
+	{
+		if ($attrib === null  || strtoupper($attrib) == "NONE") {
+			$attrib = self::NONE;
+		}
+		$attrib = strtoupper($attrib);
+		if ($attrib == "SETNULL") {
+			$attrib =  self::SETNULL;
+		}
+		return $attrib;
+	}
+
+	/**
+	 * returns whether or not the onUpdate attribute is set
+	 */
+	public function hasOnUpdate()
+	{
+		return ($this->onUpdate !== self::NONE);
+	}
+
+	/**
+	 * returns whether or not the onDelete attribute is set
+	 */
+	public function hasOnDelete()
+	{
+		return ($this->onDelete !== self::NONE);
+	}
+
+	/**
+	 * returns the onUpdate attribute
+	 * @return     string
+	 */
+	public function getOnUpdate()
+	{
+		return $this->onUpdate;
+	}
+
+	/**
+	 * Returns the onDelete attribute
+	 * @return     string
+	 */
+	public function getOnDelete()
+	{
+		return $this->onDelete;
+	}
+
+	/**
+	 * sets the onDelete attribute
+	 */
+	public function setOnDelete($value)
+	{
+		$this->onDelete = $this->normalizeFKey($value);
+	}
+
+	/**
+	 * sets the onUpdate attribute
+	 */
+	public function setOnUpdate($value)
+	{
+		$this->onUpdate = $this->normalizeFKey($value);
+	}
+
+	/**
+	 * Returns the name attribute.
+	 */
+	public function getName()
+	{
+		return $this->name;
+	}
+
+	/**
+	 * Sets the name attribute.
+	 */
+	public function setName($name)
+	{
+		$this->name = $name;
+	}
+
+	/**
+	 * Gets the phpName for this foreign key (if any).
+	 * @return     string
+	 */
+	public function getPhpName()
+	{
+		return $this->phpName;
+	}
+
+	/**
+	 * Sets a phpName to use for this foreign key.
+	 * @param      string $name
+	 */
+	public function setPhpName($name)
+	{
+		$this->phpName = $name;
+	}
+
+	/**
+	 * Gets the refPhpName for this foreign key (if any).
+	 * @return     string
+	 */
+	public function getRefPhpName()
+	{
+		return $this->refPhpName;
+	}
+
+	/**
+	 * Sets a refPhpName to use for this foreign key.
+	 * @param      string $name
+	 */
+	public function setRefPhpName($name)
+	{
+		$this->refPhpName = $name;
+	}
+
+	/**
+	 * Get the foreignTableName of the FK
+	 */
+	public function getForeignTableName()
+	{
+		return $this->foreignTableName;
+	}
+
+	/**
+	 * Set the foreignTableName of the FK
+	 */
+	public function setForeignTableName($tableName)
+	{
+		$this->foreignTableName = $tableName;
+	}
+
+	/**
+	 * Gets the resolved foreign Table model object.
+	 * @return     Table
+	 */
+	public function getForeignTable()
+	{
+		return $this->getTable()->getDatabase()->getTable($this->getForeignTableName());
+	}
+
+	/**
+	 * Set the parent Table of the foreign key
+	 */
+	public function setTable(Table $parent)
+	{
+		$this->parentTable = $parent;
+	}
+
+	/**
+	 * Get the parent Table of the foreign key
+	 */
+	public function getTable()
+	{
+		return $this->parentTable;
+	}
+
+	/**
+	 * Returns the Name of the table the foreign key is in
+	 */
+	public function getTableName()
+	{
+		return $this->parentTable->getName();
+	}
+
+	/**
+	 * Adds a new reference entry to the foreign key.
+	 */
+	public function addReference($p1, $p2 = null)
+	{
+		if (is_array($p1)) {
+			$this->addReference(@$p1["local"], @$p1["foreign"]);
+		} else {
+			if ($p1 instanceof Column) {
+				$p1 = $p1->getName();
+			}
+			if ($p2 instanceof Column) {
+				$p2 = $p2->getName();
+			}
+			$this->localColumns[] = $p1;
+			$this->foreignColumns[] = $p2;
+		}
+	}
+
+	/**
+	 * Return a comma delimited string of local column names
+	 * @deprecated because Column::makeList() is deprecated; use the array-returning getLocalColumns() and DDLBuilder->getColumnList() instead instead.
+	 */
+	public function getLocalColumnNames()
+	{
+		return Column::makeList($this->getLocalColumns(), $this->getTable()->getDatabase()->getPlatform());
+	}
+
+	/**
+	 * Return a comma delimited string of foreign column names
+	 * @deprecated because Column::makeList() is deprecated; use the array-returning getForeignColumns() and DDLBuilder->getColumnList() instead instead.
+	 */
+	public function getForeignColumnNames()
+	{
+		return Column::makeList($this->getForeignColumns(), $this->getTable()->getDatabase()->getPlatform());
+	}
+
+	/**
+	 * Return an array of local column names.
+	 * @return     array string[]
+	 */
+	public function getLocalColumns()
+	{
+		return $this->localColumns;
+	}
+
+	/**
+	 * Utility method to get local column to foreign column
+	 * mapping for this foreign key.
+	 */
+	public function getLocalForeignMapping()
+	{
+		$h = array();
+		for ($i=0, $size=count($this->localColumns); $i < $size; $i++) {
+			$h[$this->localColumns[$i]] = $this->foreignColumns[$i];
+		}
+		return $h;
+	}
+
+	/**
+	 * Get the foreign column mapped to specified local column.
+	 * @return     string Column name.
+	 */
+	public function getMappedForeignColumn($local)
+	{
+		$m = $this->getLocalForeignMapping();
+		if (isset($m[$local])) {
+			return $m[$local];
+		}
+		return null;
+	}
+
+	/**
+	 * Get the local column mapped to specified foreign column.
+	 * @return     string Column name.
+	 */
+	public function getMappedLocalColumn($foreign)
+	{
+		$m = $this->getForeignLocalMapping();
+		if (isset($m[$foreign])) {
+			return $m[$foreign];
+		}
+		return null;
+	}
+
+	/**
+	 * Return an array of foreign column objects.
+	 * @return     array Column[]
+	 */
+	public function getForeignColumns()
+	{
+		return $this->foreignColumns;
+	}
+
+	/**
+	 * Utility method to get local column to foreign column
+	 * mapping for this foreign key.
+	 */
+	public function getForeignLocalMapping()
+	{
+		$h = array();
+		for ($i=0, $size=count($this->localColumns); $i < $size; $i++) {
+			$h[ $this->foreignColumns[$i] ] = $this->localColumns[$i];
+		}
+		return $h;
+	}
+
+	/**
+	 * Whether this foreign key is also the primary key of the local table.
+	 *
+	 * @return     boolean
+	 */
+	public function isLocalPrimaryKey()
+	{
+		$localCols = $this->getLocalColumns();
+
+		$localPKColumnObjs = $this->getTable()->getPrimaryKey();
+
+		$localPKCols = array();
+		foreach ($localPKColumnObjs as $lPKCol) {
+			$localPKCols[] = $lPKCol->getName();
+		}
+		//
+		//		print "Local key columns: \n";
+		//		print_r($localCols);
+		//
+		//		print "Local table primary key columns: \n";
+		//		print_r($localPKCols);
+
+		return (!array_diff($localPKCols, $localCols));
+	}
+
+	/**
+	 * Whether this foreign key is matched by an invertes foreign key (on foreign table).
+	 *
+	 * This is to prevent duplicate columns being generated for a 1:1 relationship that is represented
+	 * by foreign keys on both tables.  I don't know if that's good practice ... but hell, why not
+	 * support it.
+	 *
+	 * @param      ForeignKey $fk
+	 * @return     boolean
+	 * @link       http://propel.phpdb.org/trac/ticket/549
+	 */
+	public function isMatchedByInverseFK()
+	{
+		$foreignTable = $this->getForeignTable();
+		$map = $this->getForeignLocalMapping();
+
+		foreach ($foreignTable->getForeignKeys() as $refFK) {
+			$fkMap = $refFK->getLocalForeignMapping();
+			if ($map == $fkMap) { // compares keys and values, but doesn't care about order
+				return true;
+			}
+		}
+
+		return false;
+	}
+
+	/**
+	 * @see        XMLElement::appendXml(DOMNode)
+	 */
+	public function appendXml(DOMNode $node)
+	{
+		$doc = ($node instanceof DOMDocument) ? $node : $node->ownerDocument;
+
+		$fkNode = $node->appendChild($doc->createElement('foreign-key'));
+
+		$fkNode->setAttribute('foreignTable', $this->getForeignTableName());
+		$fkNode->setAttribute('name', $this->getName());
+
+		if ($this->getPhpName()) {
+			$fkNode->setAttribute('phpName', $this->getPhpName());
+		}
+
+		if ($this->getRefPhpName()) {
+			$fkNode->setAttribute('refPhpName', $this->getRefPhpName());
+		}
+
+		if ($this->getOnDelete()) {
+			$fkNode->setAttribute('onDelete', $this->getOnDelete());
+		}
+
+		if ($this->getOnUpdate()) {
+			$fkNode->setAttribute('onUpdate', $this->getOnUpdate());
+		}
+
+		for ($i=0, $size=count($this->localColumns); $i < $size; $i++) {
+			$refNode = $fkNode->appendChild($doc->createElement('reference'));
+			$refNode->setAttribute('local', $this->localColumns[$i]);
+			$refNode->setAttribute('foreign', $this->foreignColumns[$i]);
+		}
+
+		foreach ($this->vendorInfos as $vi) {
+			$vi->appendXml($fkNode);
+		}
+	}
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/database/model/IDMethod.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/database/model/IDMethod.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/database/model/IDMethod.php	(revision 19)
@@ -0,0 +1,46 @@
+<?php
+
+/*
+ *  $Id: IDMethod.php 521 2007-01-05 13:29:36Z heltem $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://propel.phpdb.org>.
+ */
+
+/**
+ * Interface for various ID retrieval method types
+ * (i.e. auto-increment, sequence, ID broker, etc.).
+ *
+ * @author     Hans Lellelid <hans@xmpl.org> (Propel)
+ * @author     Daniel Rall <dlr@collab.net> (Torque)
+ * @version    $Revision: 521 $
+ * @package    propel.engine.database.model
+ */
+interface IDMethod {
+
+	/**
+	 * Key generation via database-specific ID method
+	 * (i.e. auto-increment for MySQL, sequence for Oracle, etc.).
+	 */
+	const NATIVE = "native";
+
+	/**
+	 * No RDBMS key generation (keys may be generated by the
+	 * application).
+	 */
+	const NO_ID_METHOD = "none";
+
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/database/model/IdMethodParameter.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/database/model/IdMethodParameter.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/database/model/IdMethodParameter.php	(revision 19)
@@ -0,0 +1,119 @@
+<?php
+
+/*
+ *  $Id: IdMethodParameter.php 989 2008-03-11 14:29:30Z heltem $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://propel.phpdb.org>.
+ */
+
+require_once 'propel/engine/database/model/XMLElement.php';
+
+/**
+ * Information related to an ID method.
+ *
+ * @author     Hans Lellelid <hans@xmpl.org> (Propel)
+ * @author     John McNally <jmcnally@collab.net> (Torque)
+ * @author     Daniel Rall <dlr@collab.net> (Torque)
+ * @version    $Revision: 989 $
+ * @package    propel.engine.database.model
+ */
+class IdMethodParameter extends XMLElement {
+
+	private $name;
+	private $value;
+	private $parentTable;
+
+   /**
+	 * Sets up the IdMethodParameter object based on the attributes that were passed to loadFromXML().
+	 * @see        parent::loadFromXML()
+	 */
+	protected function setupObject()
+	{
+		$this->name = $this->getAttribute("name");
+		$this->value = $this->getAttribute("value");
+	}
+
+	/**
+	 * Get the parameter name
+	 */
+	public function getName()
+	{
+		return $this->name;
+	}
+
+	/**
+	 * Set the parameter name
+	 */
+	public function setName($name)
+	{
+		$this->name = $name;
+	}
+
+	/**
+	 * Get the parameter value
+	 */
+	public function getValue()
+	{
+		return $this->value;
+	}
+
+	/**
+	 * Set the parameter value
+	 */
+	public function setValue($value)
+	{
+		$this->value = $value;
+	}
+
+	/**
+	 * Set the parent Table of the id method
+	 */
+	public function setTable(Table $parent)
+	{
+		$this->parentTable = $parent;
+	}
+
+	/**
+	 * Get the parent Table of the id method
+	 */
+	public function getTable()
+	{
+		return $this->parentTable;
+	}
+
+	/**
+	 * Returns the Name of the table the id method is in
+	 */
+	public function getTableName()
+	{
+		return $this->parentTable->getName();
+	}
+
+	/**
+	 * @see        XMLElement::appendXml(DOMNode)
+	 */
+	public function appendXml(DOMNode $node)
+	{
+		$doc = ($node instanceof DOMDocument) ? $node : $node->ownerDocument;
+
+		$paramNode = $node->appendChild($doc->createElement('id-method-parameter'));
+		if ($this->getName()) {
+			$paramNode->setAttribute('name', $this->getName());
+		}
+		$paramNode->setAttribute('value', $this->getValue());
+	}
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/database/model/Index.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/database/model/Index.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/database/model/Index.php	(revision 19)
@@ -0,0 +1,286 @@
+<?php
+
+/*
+ *  $Id: Index.php 1027 2008-04-09 10:37:52Z hans $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://propel.phpdb.org>.
+ */
+
+require_once 'propel/engine/database/model/XMLElement.php';
+include_once 'propel/engine/EngineException.php';
+
+/**
+ * Information about indices of a table.
+ *
+ * @author     Jason van Zyl <vanzyl@apache.org>
+ * @author     Daniel Rall <dlr@finemaltcoding.com>
+ * @version    $Revision: 1027 $
+ * @package    propel.engine.database.model
+ */
+class Index extends XMLElement {
+
+	/** enables debug output */
+	const DEBUG = false;
+
+	private $indexName;
+	private $parentTable;
+
+	/** @var        array string[] */
+	private $indexColumns;
+
+	/** @var        array  */
+	private $indexColumnSizes = array();
+
+	/**
+	 * Creates a new Index instance.
+	 *
+	 * @param      string $name
+	 */
+	public function __construct($name=null)
+	{
+		$this->indexName = $name;
+	}
+
+	private function createName()
+	{
+		$table = $this->getTable();
+		$inputs = array();
+		$inputs[] = $table->getDatabase();
+		$inputs[] = $table->getName();
+		if ($this->isUnique()) {
+			$inputs[] = "U";
+		} else {
+			$inputs[] = "I";
+		}
+		// ASSUMPTION: This Index not yet added to the list.
+		if ($this->isUnique()) {
+			$inputs[] = count($table->getUnices()) + 1;
+		} else {
+			$inputs[] = count($table->getIndices()) + 1;
+		}
+
+		$this->indexName = NameFactory::generateName(
+		NameFactory::CONSTRAINT_GENERATOR, $inputs);
+	}
+
+	/**
+	 * Sets up the Index object based on the attributes that were passed to loadFromXML().
+	 * @see        parent::loadFromXML()
+	 */
+	protected function setupObject()
+	{
+		$this->indexName = $this->getAttribute("name");
+	}
+
+	/**
+	 * @see        #isUnique()
+	 * @deprecated Use isUnique() instead.
+	 */
+	public function getIsUnique()
+	{
+		return $this->isUnique();
+	}
+
+	/**
+	 * Returns the uniqueness of this index.
+	 */
+	public function isUnique()
+	{
+		return false;
+	}
+
+	/**
+	 * @see        #getName()
+	 * @deprecated Use getName() instead.
+	 */
+	public function getIndexName()
+	{
+		return $this->getName();
+	}
+
+	/**
+	 * Gets the name of this index.
+	 */
+	public function getName()
+	{
+		if ($this->indexName === null) {
+			try {
+				// generate an index name if we don't have a supplied one
+				$this->createName();
+			} catch (EngineException $e) {
+				// still no name
+			}
+		}
+		return substr($this->indexName, 0, $this->getTable()->getDatabase()->getPlatform()->getMaxColumnNameLength());
+	}
+
+	/**
+	 * @see        #setName(String name)
+	 * @deprecated Use setName(String name) instead.
+	 */
+	public function setIndexName($name)
+	{
+		$this->setName($name);
+	}
+
+	/**
+	 * Set the name of this index.
+	 */
+	public function setName($name)
+	{
+		$this->indexName = $name;
+	}
+
+	/**
+	 * Set the parent Table of the index
+	 */
+	public function setTable(Table $parent)
+	{
+		$this->parentTable = $parent;
+	}
+
+	/**
+	 * Get the parent Table of the index
+	 */
+	public function getTable()
+	{
+		return $this->parentTable;
+	}
+
+	/**
+	 * Returns the Name of the table the index is in
+	 */
+	public function getTableName()
+	{
+		return $this->parentTable->getName();
+	}
+
+	/**
+	 * Adds a new column to an index.
+	 * @param      mixed $data Column or attributes from XML.
+	 */
+	public function addColumn($data)
+	{
+		if ($data instanceof Column) {
+			$column = $data;
+			$this->indexColumns[] = $column->getName();
+			if ($column->getSize()) {
+				$this->indexColumnSizes[$column->getName()] = $column->getSize();
+			}
+		} else {
+			$attrib = $data;
+			$name = $attrib["name"];
+			$this->indexColumns[] = $name;
+			if (isset($attrib["size"])) {
+				$this->indexColumnSizes[$name] = $attrib["size"];
+			}
+		}
+	}
+
+	/**
+	 * Sets array of columns to use for index.
+	 *
+	 * @param      array $indexColumns Column[]
+	 */
+	public function setColumns(array $indexColumns)
+	{
+		$this->indexColumns = array();
+		$this->indexColumnSizes = array();
+		foreach ($indexColumns as $col) {
+			$this->addColumn($col);
+		}
+	}
+
+	/**
+	 * Whether there is a size for the specified column.
+	 * @param      string $name
+	 * @return     boolean
+	 */
+	public function hasColumnSize($name)
+	{
+		return isset($this->indexColumnSizes[$name]);
+	}
+
+	/**
+	 * Returns the size for the specified column, if given.
+	 * @param      string $name
+	 * @return     numeric The size or NULL
+	 */
+	public function getColumnSize($name)
+	{
+		if (isset($this->indexColumnSizes[$name])) {
+			return $this->indexColumnSizes[$name];
+		}
+		return null; // just to be explicit
+	}
+
+	/**
+	 * @see        #getColumnList()
+	 * @deprecated Use getColumnList() instead (which is not deprecated too!)
+	 */
+	public function getIndexColumnList()
+	{
+		return $this->getColumnList();
+	}
+
+	/**
+	 * Return a comma delimited string of the columns which compose this index.
+	 * @deprecated because Column::makeList() is deprecated; use the array-returning getColumns() and DDLBuilder->getColumnList() instead instead.
+	 */
+	public function getColumnList()
+	{
+		return Column::makeList($this->getColumns(), $this->getTable()->getDatabase()->getPlatform());
+	}
+
+	/**
+	 * @see        #getColumns()
+	 * @deprecated Use getColumns() instead.
+	 */
+	public function getIndexColumns()
+	{
+		return $this->getColumns();
+	}
+
+	/**
+	 * Return the list of local columns. You should not edit this list.
+	 * @return     array string[]
+	 */
+	public function getColumns()
+	{
+		return $this->indexColumns;
+	}
+
+	/**
+	 * @see        XMLElement::appendXml(DOMNode)
+	 */
+	public function appendXml(DOMNode $node)
+	{
+		$doc = ($node instanceof DOMDocument) ? $node : $node->ownerDocument;
+
+		$idxNode = $node->appendChild($doc->createElement('index'));
+		$idxNode->setAttribute('name', $this->getName());
+
+		foreach ($this->indexColumns as $colname) {
+			$idxColNode = $idxNode->appendChild($doc->createElement('index-column'));
+			$idxColNode->setAttribute('name', $colname);
+		}
+
+		foreach ($this->vendorInfos as $vi) {
+			$vi->appendXml($idxNode);
+		}
+	}
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/database/model/Inheritance.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/database/model/Inheritance.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/database/model/Inheritance.php	(revision 19)
@@ -0,0 +1,158 @@
+<?php
+
+/*
+ *  $Id: Inheritance.php 989 2008-03-11 14:29:30Z heltem $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://propel.phpdb.org>.
+ */
+
+require_once 'propel/engine/database/model/XMLElement.php';
+
+/**
+ * A Class for information regarding possible objects representing a table
+ *
+ * @author     Hans Lellelid <hans@xmpl.org> (Propel)
+ * @author     John McNally <jmcnally@collab.net> (Torque)
+ * @version    $Revision: 989 $
+ * @package    propel.engine.database.model
+ */
+class Inheritance extends XMLElement {
+
+	private $key;
+	private $className;
+	private $pkg;
+	private $ancestor;
+	private $parent;
+
+	/**
+	 * Sets up the Inheritance object based on the attributes that were passed to loadFromXML().
+	 * @see        parent::loadFromXML()
+	 */
+	protected function setupObject()
+	{
+		$this->key = $this->getAttribute("key");
+		$this->className = $this->getAttribute("class");
+		$this->pkg = $this->getAttribute("package");
+		$this->ancestor = $this->getAttribute("extends");
+	}
+
+	/**
+	 * Get the value of key.
+	 * @return     value of key.
+	 */
+	public function getKey()
+	{
+		return $this->key;
+	}
+
+	/**
+	 * Set the value of key.
+	 * @param      v  Value to assign to key.
+	 */
+	public function setKey($v)
+	{
+		$this->key = $v;
+	}
+
+	/**
+	 * Get the value of parent.
+	 * @return     value of parent.
+	 */
+	public function getColumn()
+	{
+		return $this->parent;
+	}
+
+	/**
+	 * Set the value of parent.
+	 * @param      v  Value to assign to parent.
+	 */
+	public function setColumn(Column  $v)
+	{
+		$this->parent = $v;
+	}
+
+	/**
+	 * Get the value of className.
+	 * @return     value of className.
+	 */
+	public function getClassName()
+	{
+		return $this->className;
+	}
+
+	/**
+	 * Set the value of className.
+	 * @param      v  Value to assign to className.
+	 */
+	public function setClassName($v)
+	{
+		$this->className = $v;
+	}
+
+	/**
+	 * Get the value of package.
+	 * @return     value of package.
+	 */
+	public function getPackage()
+	{
+		return $this->pkg;
+	}
+
+	/**
+	 * Set the value of package.
+	 * @param      v  Value to assign to package.
+	 */
+	public function setPackage($v)
+	{
+		$this->pkg = $v;
+	}
+
+	/**
+	 * Get the value of ancestor.
+	 * @return     value of ancestor.
+	 */
+	public function getAncestor()
+	{
+		return $this->ancestor;
+	}
+
+	/**
+	 * Set the value of ancestor.
+	 * @param      v  Value to assign to ancestor.
+	 */
+	public function setAncestor($v)
+	{
+		$this->ancestor = $v;
+	}
+
+	/**
+	 * @see        XMLElement::appendXml(DOMNode)
+	 */
+	public function appendXml(DOMNode $node)
+	{
+		$doc = ($node instanceof DOMDocument) ? $node : $node->ownerDocument;
+
+		$inherNode = $node->appendChild($doc->createElement('inheritance'));
+		$inherNode->setAttribute('key', $this->key);
+		$inherNode->setAttribute('class', $this->className);
+
+		if ($this->ancestor !== null) {
+			$inherNode->setAttribute('extends', $this->ancestor);
+		}
+	}
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/database/model/NameFactory.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/database/model/NameFactory.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/database/model/NameFactory.php	(revision 19)
@@ -0,0 +1,88 @@
+<?php
+
+/*
+ *  $Id: NameFactory.php 964 2008-02-10 20:42:38Z hans $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://propel.phpdb.org>.
+ */
+
+include_once 'propel/engine/EngineException.php';
+include_once 'propel/engine/database/model/NameGenerator.php';
+include_once 'propel/engine/database/model/PhpNameGenerator.php';
+include_once 'propel/engine/database/model/ConstraintNameGenerator.php';
+
+/**
+ * A name generation factory.
+ *
+ * @author     Hans Lellelid <hans@xmpl.org> (Propel)
+ * @author     Daniel Rall <dlr@finemaltcoding.com> (Torque)
+ * @version    $Revision: 964 $
+ * @package    propel.engine.database.model
+ */
+class NameFactory {
+
+	/**
+	 * The class name of the PHP name generator.
+	 */
+	const PHP_GENERATOR = 'PhpNameGenerator';
+
+	/**
+	 * The fully qualified class name of the constraint name generator.
+	 */
+	const CONSTRAINT_GENERATOR = 'ConstraintNameGenerator';
+
+	/**
+	 * The single instance of this class.
+	 */
+	private static $instance;
+
+	/**
+	 * The cache of <code>NameGenerator</code> algorithms in use for
+	 * name generation, keyed by fully qualified class name.
+	 */
+	private static $algorithms = array();
+
+	/**
+	 * Factory method which retrieves an instance of the named generator.
+	 *
+	 * @param      name The fully qualified class name of the name
+	 * generation algorithm to retrieve.
+	 */
+	protected static function getAlgorithm($name)
+	{
+		if (!isset(self::$algorithms[$name])) {
+			self::$algorithms[$name] = new $name();
+		}
+		return self::$algorithms[$name];
+	}
+
+	/**
+	 * Given a list of <code>String</code> objects, implements an
+	 * algorithm which produces a name.
+	 *
+	 * @param      string $algorithmName The fully qualified class name of the {@link NameGenerator}
+	 *             implementation to use to generate names.
+	 * @param      array $inputs Inputs used to generate a name.
+	 * @return     The generated name.
+	 * @throws     EngineException
+	 */
+	public static function generateName($algorithmName, $inputs)
+	{
+		$algorithm = self::getAlgorithm($algorithmName);
+		return $algorithm->generateName($inputs);
+	}
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/database/model/NameGenerator.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/database/model/NameGenerator.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/database/model/NameGenerator.php	(revision 19)
@@ -0,0 +1,72 @@
+<?php
+
+/*
+ *  $Id: NameGenerator.php 521 2007-01-05 13:29:36Z heltem $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://propel.phpdb.org>.
+ */
+
+/**
+ * The generic interface to a name generation algorithm.
+ *
+ * @author     Hans Lellelid <hans@xmpl.org> (Propel)
+ * @author     Daniel Rall <dlr@finemaltcoding.com> (Torque)
+ * @author     Byron Foster <byron_foster@yahoo.com> (Torque)
+ * @version    $Revision: 521 $
+ * @package    propel.engine.database.model
+ */
+interface NameGenerator {
+	/**
+	 * The character used by most implementations as the separator
+	 * between name elements.
+	 */
+	const STD_SEPARATOR_CHAR = '_';
+
+	/**
+	 * Traditional method for converting schema table and column names
+	 * to PHP names.  The <code>CONV_METHOD_XXX</code> constants
+	 * define how names for columns and tables in the database schema
+	 * will be converted to PHP source names.
+	 *
+	 * @see        PhpNameGenerator::underscoreMethod()
+	 */
+	const CONV_METHOD_UNDERSCORE = "underscore";
+
+	/**
+	 * Similar to {@link #CONV_METHOD_UNDERSCORE} except nothing is
+	 * converted to lowercase.
+	 *
+	 * @see        PhpNameGenerator::phpnameMethod()
+	 */
+	const CONV_METHOD_PHPNAME = "phpname";
+
+	/**
+	 * Specifies no modification when converting from a schema column
+	 * or table name to a PHP name.
+	 */
+	const CONV_METHOD_NOCHANGE = "nochange";
+
+	/**
+	 * Given a list of <code>String</code> objects, implements an
+	 * algorithm which produces a name.
+	 *
+	 * @param      inputs Inputs used to generate a name.
+	 * @return     The generated name.
+	 * @throws     EngineException
+	 */
+	public function generateName($inputs);
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/database/model/PhpNameGenerator.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/database/model/PhpNameGenerator.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/database/model/PhpNameGenerator.php	(revision 19)
@@ -0,0 +1,144 @@
+<?php
+/*
+ *  $Id: PhpNameGenerator.php 718 2007-10-26 01:31:34Z heltem $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://propel.phpdb.org>.
+ */
+
+include_once 'propel/engine/database/model/NameGenerator.php';
+
+/**
+ * A <code>NameGenerator</code> implementation for PHP-esque names.
+ *
+ * @author     Hans Lellelid <hans@xmpl.org> (Propel)
+ * @author     Daniel Rall <dlr@finemaltcoding.com> (Torque)
+ * @author     Byron Foster <byron_foster@yahoo.com> (Torque)
+ * @author     Bernd Goldschmidt <bgoldschmidt@rapidsoft.de>
+ * @version    $Revision: 718 $
+ * @package    propel.engine.database.model
+ */
+class PhpNameGenerator implements NameGenerator {
+
+	/**
+	 * <code>inputs</code> should consist of two (three) elements, the
+	 * original name of the database element and the method for
+	 * generating the name.
+	 * The optional third element may contain a prefix that will be
+	 * stript from name prior to generate the resulting name.
+	 * There are currently three methods:
+	 * <code>CONV_METHOD_NOCHANGE</code> - xml names are converted
+	 * directly to php names without modification.
+	 * <code>CONV_METHOD_UNDERSCORE</code> will capitalize the first
+	 * letter, remove underscores, and capitalize each letter before
+	 * an underscore.  All other letters are lowercased. "phpname"
+	 * works the same as the <code>CONV_METHOD_PHPNAME</code> method
+	 * but will not lowercase any characters.
+	 *
+	 * @param      inputs list expected to contain two (optional: three) parameters,
+	 * element 0 contains name to convert, element 1 contains method for conversion,
+	 * optional element 2 contains prefix to be striped from name
+	 * @return     The generated name.
+	 * @see        NameGenerator
+	 */
+	public function generateName($inputs)
+	{
+		$schemaName = $inputs[0];
+		$method = $inputs[1];
+
+		if (count($inputs)>2) {
+			$prefix = $inputs[2];
+			if ($prefix != '' && substr($schemaName, 0, strlen($prefix)) == $prefix) {
+				$schemaName = substr($schemaName, strlen($prefix));
+			}
+		}
+
+		$phpName = null;
+
+		if ($method == self::CONV_METHOD_UNDERSCORE) {
+			$phpName = $this->underscoreMethod($schemaName);
+		} elseif ($method == self::CONV_METHOD_PHPNAME) {
+			$phpName = $this->phpnameMethod($schemaName);
+		} else if ($method == self::CONV_METHOD_NOCHANGE) {
+			$phpName = $this->nochangeMethod($schemaName);
+		} else {
+			// if for some reason nothing is defined then we default
+			// to the traditional method.
+			$phpName = $this->underscoreMethod($schemaName);
+		}
+
+		return $phpName;
+	}
+
+	/**
+	 * Converts a database schema name to php object name.  Removes
+	 * <code>STD_SEPARATOR_CHAR</code>, capitilizes first letter of
+	 * name and each letter after the <code>STD_SEPERATOR</code>,
+	 * converts the rest of the letters to lowercase.
+	 *
+	 * my_CLASS_name -> MyClassName
+	 *
+	 * @param      string $schemaName name to be converted.
+	 * @return     string Converted name.
+	 * @see        NameGenerator
+	 * @see        #underscoreMethod()
+	 */
+	protected function underscoreMethod($schemaName)
+	{
+		$name = "";
+		$tok = strtok($schemaName, self::STD_SEPARATOR_CHAR);
+		while ($tok) {
+			$name .= ucfirst(strtolower($tok));
+			$tok = strtok(self::STD_SEPARATOR_CHAR);
+		}
+		return $name;
+	}
+
+	/**
+	 * Converts a database schema name to php object name.  Operates
+	 * same as underscoreMethod but does not convert anything to
+	 * lowercase.
+	 *
+	 * my_CLASS_name -> MyCLASSName
+	 *
+	 * @param      string $schemaName name to be converted.
+	 * @return     string Converted name.
+	 * @see        NameGenerator
+	 * @see        #underscoreMethod(String)
+	 */
+	protected function phpnameMethod($schemaName)
+	{
+		$name = "";
+		$tok = strtok($schemaName, self::STD_SEPARATOR_CHAR);
+		while ($tok) {
+			$name .= ucfirst($tok);
+			$tok = strtok(self::STD_SEPARATOR_CHAR);
+		}
+		return $name;
+	}
+
+	/**
+	 * Converts a database schema name to PHP object name.  In this
+	 * case no conversion is made.
+	 *
+	 * @param      string $name name to be converted.
+	 * @return     string The <code>name</code> parameter, unchanged.
+	 */
+	protected function nochangeMethod($name)
+	{
+		return $name;
+	}
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/database/model/PropelTypes.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/database/model/PropelTypes.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/database/model/PropelTypes.php	(revision 19)
@@ -0,0 +1,331 @@
+<?php
+/*
+ *  $Id: PropelTypes.php 989 2008-03-11 14:29:30Z heltem $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://propel.phpdb.org>.
+ */
+
+/**
+ * A class that maps PropelTypes to PHP native types, PDO types (and Creole types).
+ *
+ * @author     Hans Lellelid <hans@xmpl.org> (Propel)
+ * @version    $Revision: 989 $
+ * @package    propel.engine.database.model
+ */
+class PropelTypes {
+
+	const CHAR = "CHAR";
+	const VARCHAR = "VARCHAR";
+	const LONGVARCHAR = "LONGVARCHAR";
+	const CLOB = "CLOB";
+	const NUMERIC = "NUMERIC";
+	const DECIMAL = "DECIMAL";
+	const TINYINT = "TINYINT";
+	const SMALLINT = "SMALLINT";
+	const INTEGER = "INTEGER";
+	const BIGINT = "BIGINT";
+	const REAL = "REAL";
+	const FLOAT = "FLOAT";
+	const DOUBLE = "DOUBLE";
+	const BINARY = "BINARY";
+	const VARBINARY = "VARBINARY";
+	const LONGVARBINARY = "LONGVARBINARY";
+	const BLOB = "BLOB";
+	const DATE = "DATE";
+	const TIME = "TIME";
+	const TIMESTAMP = "TIMESTAMP";
+
+	const BU_DATE = "BU_DATE";
+	const BU_TIMESTAMP = "BU_TIMESTAMP";
+
+	const BOOLEAN = "BOOLEAN";
+
+	private static $TEXT_TYPES = array (
+						self::CHAR, self::VARCHAR, self::LONGVARCHAR, self::CLOB, self::DATE, self::TIME, self::TIMESTAMP, self::BU_DATE, self::BU_TIMESTAMP
+					);
+
+	private static $LOB_TYPES = array (
+						self::VARBINARY, self::LONGVARBINARY, self::BLOB
+					);
+
+	private static $TEMPORAL_TYPES = array (
+						self::DATE, self::TIME, self::TIMESTAMP, self::BU_DATE, self::BU_TIMESTAMP
+					);
+
+	private static $NUMERIC_TYPES = array (
+						self::SMALLINT, self::TINYINT, self::INTEGER, self::BIGINT, self::FLOAT, self::DOUBLE, self::NUMERIC, self::DECIMAL, self::REAL
+					);
+
+	const CHAR_NATIVE_TYPE = "string";
+	const VARCHAR_NATIVE_TYPE = "string";
+	const LONGVARCHAR_NATIVE_TYPE = "string";
+	const CLOB_NATIVE_TYPE = "string"; // Clob
+	const NUMERIC_NATIVE_TYPE = "string";
+	const DECIMAL_NATIVE_TYPE = "string";
+	const BOOLEAN_NATIVE_TYPE = "boolean";
+	const TINYINT_NATIVE_TYPE = "int";
+	const SMALLINT_NATIVE_TYPE = "int";
+	const INTEGER_NATIVE_TYPE = "int";
+	const BIGINT_NATIVE_TYPE = "string";
+	const REAL_NATIVE_TYPE = "double";
+	const FLOAT_NATIVE_TYPE = "double";
+	const DOUBLE_NATIVE_TYPE = "double";
+	const BINARY_NATIVE_TYPE = "string";
+	const VARBINARY_NATIVE_TYPE = "string";
+	const LONGVARBINARY_NATIVE_TYPE = "string";
+	const BLOB_NATIVE_TYPE = "resource";
+	const BU_DATE_NATIVE_TYPE = "string";
+	const DATE_NATIVE_TYPE = "string";
+	const TIME_NATIVE_TYPE = "string";
+	const TIMESTAMP_NATIVE_TYPE = "string";
+	const BU_TIMESTAMP_NATIVE_TYPE = "string";
+
+	/**
+	 * Mapping between Propel types and PHP native types.
+	 *
+	 * @var        array
+	 */
+	private static $propelToPHPNativeMap = array(
+			self::CHAR => self::CHAR_NATIVE_TYPE,
+			self::VARCHAR => self::VARCHAR_NATIVE_TYPE,
+			self::LONGVARCHAR => self::LONGVARCHAR_NATIVE_TYPE,
+			self::CLOB => self::CLOB_NATIVE_TYPE,
+			self::NUMERIC => self::NUMERIC_NATIVE_TYPE,
+			self::DECIMAL => self::DECIMAL_NATIVE_TYPE,
+			self::TINYINT => self::TINYINT_NATIVE_TYPE,
+			self::SMALLINT => self::SMALLINT_NATIVE_TYPE,
+			self::INTEGER => self::INTEGER_NATIVE_TYPE,
+			self::BIGINT => self::BIGINT_NATIVE_TYPE,
+			self::REAL => self::REAL_NATIVE_TYPE,
+			self::FLOAT => self::FLOAT_NATIVE_TYPE,
+			self::DOUBLE => self::DOUBLE_NATIVE_TYPE,
+			self::BINARY => self::BINARY_NATIVE_TYPE,
+			self::VARBINARY => self::VARBINARY_NATIVE_TYPE,
+			self::LONGVARBINARY => self::LONGVARBINARY_NATIVE_TYPE,
+			self::BLOB => self::BLOB_NATIVE_TYPE,
+			self::DATE => self::DATE_NATIVE_TYPE,
+			self::BU_DATE => self::BU_DATE_NATIVE_TYPE,
+			self::TIME => self::TIME_NATIVE_TYPE,
+			self::TIMESTAMP => self::TIMESTAMP_NATIVE_TYPE,
+			self::BU_TIMESTAMP => self::BU_TIMESTAMP_NATIVE_TYPE,
+			self::BOOLEAN => self::BOOLEAN_NATIVE_TYPE,
+	);
+
+	/**
+	 * Mapping between Propel types and Creole types (for rev-eng task)
+	 *
+	 * @var        array
+	 */
+	private static $propelTypeToCreoleTypeMap = array(
+
+			self::CHAR => self::CHAR,
+			self::VARCHAR => self::VARCHAR,
+			self::LONGVARCHAR => self::LONGVARCHAR,
+			self::CLOB => self::CLOB,
+			self::NUMERIC => self::NUMERIC,
+			self::DECIMAL => self::DECIMAL,
+			self::TINYINT => self::TINYINT,
+			self::SMALLINT => self::SMALLINT,
+			self::INTEGER => self::INTEGER,
+			self::BIGINT => self::BIGINT,
+			self::REAL => self::REAL,
+			self::FLOAT => self::FLOAT,
+			self::DOUBLE => self::DOUBLE,
+			self::BINARY => self::BINARY,
+			self::VARBINARY => self::VARBINARY,
+			self::LONGVARBINARY => self::LONGVARBINARY,
+			self::BLOB => self::BLOB,
+			self::DATE => self::DATE,
+			self::TIME => self::TIME,
+			self::TIMESTAMP => self::TIMESTAMP,
+			self::BOOLEAN => self::BOOLEAN,
+
+			// These are pre-epoch dates, which we need to map to String type
+			// since they cannot be properly handled using strtotime() -- or even numeric
+			// timestamps on Windows.
+			self::BU_DATE => self::VARCHAR,
+			self::BU_TIMESTAMP => self::VARCHAR,
+
+	);
+
+	/**
+	 * Mapping between Propel types and PDO type contants (for prepared statement setting).
+	 *
+	 * @var        array
+	 */
+	private static $propelTypeToPDOTypeMap = array(
+			self::CHAR => PDO::PARAM_STR,
+			self::VARCHAR => PDO::PARAM_STR,
+			self::LONGVARCHAR => PDO::PARAM_STR,
+			self::CLOB => PDO::PARAM_STR,
+			self::NUMERIC => PDO::PARAM_INT,
+			self::DECIMAL => PDO::PARAM_STR,
+			self::TINYINT => PDO::PARAM_INT,
+			self::SMALLINT => PDO::PARAM_INT,
+			self::INTEGER => PDO::PARAM_INT,
+			self::BIGINT => PDO::PARAM_INT,
+			self::REAL => PDO::PARAM_STR,
+			self::FLOAT => PDO::PARAM_STR,
+			self::DOUBLE => PDO::PARAM_STR,
+			self::BINARY => PDO::PARAM_STR,
+			self::VARBINARY => PDO::PARAM_LOB,
+			self::LONGVARBINARY => PDO::PARAM_LOB,
+			self::BLOB => PDO::PARAM_LOB,
+			self::DATE => PDO::PARAM_STR,
+			self::TIME => PDO::PARAM_STR,
+			self::TIMESTAMP => PDO::PARAM_STR,
+			self::BOOLEAN => PDO::PARAM_BOOL,
+
+			// These are pre-epoch dates, which we need to map to String type
+			// since they cannot be properly handled using strtotime() -- or even numeric
+			// timestamps on Windows.
+			self::BU_DATE => PDO::PARAM_STR,
+			self::BU_TIMESTAMP => PDO::PARAM_STR,
+	);
+
+	/**
+	 * Return native PHP type which corresponds to the
+	 * Creole type provided. Use in the base object class generation.
+	 *
+	 * @param      $propelType The Propel type name.
+	 * @return     string Name of the native PHP type
+	 */
+	public static function getPhpNative($propelType)
+	{
+		return self::$propelToPHPNativeMap[$propelType];
+	}
+
+	/**
+	 * Returns the correct Creole type _name_ for propel added types
+	 *
+	 * @param      $type the propel added type.
+	 * @return     string Name of the the correct Creole type (e.g. "VARCHAR").
+	 */
+	public static function getCreoleType($type)
+	{
+		return  self::$propelTypeToCreoleTypeMap[$type];
+	}
+
+	/**
+	 * Resturns the PDO type (PDO::PARAM_* constant) value.
+	 * @return     int
+	 */
+	public static function getPDOType($type)
+	{
+		return self::$propelTypeToPDOTypeMap[$type];
+	}
+
+	/**
+	 * Returns Propel type constant corresponding to Creole type code.
+	 * Used but Propel Creole task.
+	 *
+	 * @param      int $sqlType The Creole SQL type constant.
+	 * @return     string The Propel type to use or NULL if none found.
+	 */
+	public static function getPropelType($sqlType)
+	{
+		if (isset(self::$creoleToPropelTypeMap[$sqlType])) {
+			return self::$creoleToPropelTypeMap[$sqlType];
+		}
+	}
+
+	/**
+	 * Get array of Propel types.
+	 *
+	 * @return     array string[]
+	 */
+	public static function getPropelTypes()
+	{
+		return array_keys(self::$propelTypeToCreoleTypeMap);
+	}
+
+	/**
+	 * Whether passed type is a temporal (date/time/timestamp) type.
+	 *
+	 * @param      string $type Propel type
+	 * @return     boolean
+	 */
+	public static function isTemporalType($type)
+	{
+		return in_array($type, self::$TEMPORAL_TYPES);
+	}
+
+	/**
+	 * Returns true if values for the type need to be quoted.
+	 *
+	 * @param      string $type The Propel type to check.
+	 * @return     boolean True if values for the type need to be quoted.
+	 */
+	public static function isTextType($type)
+	{
+		return in_array($type, self::$TEXT_TYPES);
+	}
+
+	/**
+	 * Returns true if values for the type are numeric.
+	 *
+	 * @param      string $type The Propel type to check.
+	 * @return     boolean True if values for the type need to be quoted.
+	 */
+	public static function isNumericType($type)
+	{
+		return in_array($type, self::$NUMERIC_TYPES);
+	}
+
+	/**
+	 * Returns true if type is a LOB type (i.e. would be handled by Blob/Clob class).
+	 * @param      string $type Propel type to check.
+	 * @return     boolean
+	 */
+	public static function isLobType($type)
+	{
+		return in_array($type, self::$LOB_TYPES);
+	}
+
+	/**
+	 * Convenience method to indicate whether a passed-in PHP type is a primitive.
+	 *
+	 * @param      string $phpType The PHP type to check
+	 * @return     boolean Whether the PHP type is a primitive (string, int, boolean, float)
+	 */
+	public static function isPhpPrimitiveType($phpType)
+	{
+		return in_array($phpType, array("boolean", "int", "double", "float", "string"));
+	}
+
+	/**
+	 * Convenience method to indicate whether a passed-in PHP type is a numeric primitive.
+	 *
+	 * @param      string $phpType The PHP type to check
+	 * @return     boolean Whether the PHP type is a primitive (string, int, boolean, float)
+	 */
+	public static function isPhpPrimitiveNumericType($phpType)
+	{
+		return in_array($phpType, array("boolean", "int", "double", "float"));
+	}
+
+	/**
+	 * Convenience method to indicate whether a passed-in PHP type is an object.
+	 *
+	 * @param      string $phpType The PHP type to check
+	 * @return     boolean Whether the PHP type is a primitive (string, int, boolean, float)
+	 */
+	public static function isPhpObjectType($phpType)
+	{
+		return (!self::isPhpPrimitiveType($phpType) && !in_array($phpType, array("resource", "array")));
+	}
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/database/model/Rule.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/database/model/Rule.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/database/model/Rule.php	(revision 19)
@@ -0,0 +1,204 @@
+<?php
+/*
+ *  $Id: Rule.php 989 2008-03-11 14:29:30Z heltem $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://propel.phpdb.org>.
+ */
+
+require_once 'propel/engine/database/model/XMLElement.php';
+
+/**
+ * Data about a validation rule used in an application.
+ *
+ * @author     Michael Aichler <aichler@mediacluster.de> (Propel)
+ * @author     John McNally <jmcnally@collab.net> (Intake)
+ * @version    $Revision: 989 $
+ * @package    propel.engine.database.model
+ */
+class Rule extends XMLElement {
+
+	private $name;
+	private $value;
+	private $message;
+	private $validator;
+	private $classname;
+
+	/**
+	 * Sets up the Rule object based on the attributes that were passed to loadFromXML().
+	 * @see        parent::loadFromXML()
+	 */
+	protected function setupObject()
+	{
+		$this->name = $this->getAttribute("name");
+		$this->value = $this->getAttribute("value");
+		$this->classname = $this->getAttribute("class");
+
+		/*
+		* Set some default values if they are not specified.
+		* This is escpecially useful for maxLength; the size
+		* is already known by the column and this way it is
+		* not necessary to manage the same size two times.
+		*
+		* Currently there is only one such supported default:
+		*   - maxLength value = column max length
+		*   (this default cannot be easily set at runtime w/o changing
+		*   design of class system in undesired ways)
+		*/
+		if ($this->value === null) {
+			switch($this->name) {
+				case 'maxLength':
+					$this->value = $this->validator->getColumn()->getSize();
+					break;
+			}
+		}
+
+		$this->message = $this->getAttribute("message");
+	}
+
+	/**
+	 * Sets the owning validator for this rule.
+	 * @param      Validator $validator
+	 * @see        Validator::addRule()
+	 */
+	public function setValidator(Validator $validator)
+	{
+		$this->validator = $validator;
+	}
+
+	/**
+	 * Gets the owning validator for this rule.
+	 * @return     Validator
+	 */
+	public function getValidator()
+	{
+		return $this->validator;
+	}
+
+	/**
+	 * Sets the dot-path name of class to use for rule.
+	 * If no class is specified in XML, then a classname will
+	 * be built based on the 'name' attrib.
+	 * @param      string $classname dot-path classname (e.g. myapp.propel.MyValidator)
+	 */
+	public function setClass($classname)
+	{
+		$this->classname = $classname;
+	}
+
+	/**
+	 * Gets the dot-path name of class to use for rule.
+	 * If no class was specified, this method will build a default classname
+	 * based on the 'name' attribute.  E.g. 'maxLength' -> 'propel.validator.MaxLengthValidator'
+	 * @return     string dot-path classname (e.g. myapp.propel.MyValidator)
+	 */
+	public function getClass()
+	{
+		if ($this->classname === null && $this->name !== null) {
+			return "propel.validator." . ucfirst($this->name) . "Validator";
+		}
+		return $this->classname;
+	}
+
+	/**
+	 * Sets the name of the validator for this rule.
+	 * This name is used to build the classname if none was specified.
+	 * @param      string $name Validator name for this rule (e.g. "maxLength", "required").
+	 * @see        getClass()
+	 */
+	public function setName($name)
+	{
+		$this->name = $name;
+	}
+
+	/**
+	 * Gets the name of the validator for this rule.
+	 * @return     string Validator name for this rule (e.g. "maxLength", "required").
+	 */
+	public function getName()
+	{
+		return $this->name;
+	}
+
+	/**
+	 * Sets the value parameter for this validator rule.
+	 * Note: not all validators need a value parameter (e.g. 'required' validator
+	 * does not).
+	 * @param      string $value
+	 */
+	public function setValue($value)
+	{
+		$this->value = $value;
+	}
+
+	/**
+	 * Gets the value parameter for this validator rule.
+	 * @return     string
+	 */
+	public function getValue()
+	{
+		return $this->value;
+	}
+
+	/**
+	 * Sets the message that will be displayed to the user if validation fails.
+	 * This message may be a Gettext msgid (if translation="gettext") or some other
+	 * id for an alternative not-yet-supported translation system.  It may also
+	 * be a simple, single-language string.
+	 * @param      string $message
+	 * @see        setTranslation()
+	 */
+	public function setMessage($message)
+	{
+		$this->message = $message;
+	}
+
+	/**
+	 * Gets the message that will be displayed to the user if validation fails.
+	 * This message may be a Gettext msgid (if translation="gettext") or some other
+	 * id for an alternative not-yet-supported translation system.  It may also
+	 * be a simple, single-language string.
+	 * @return     string
+	 * @see        setTranslation()
+	 */
+	public function getMessage()
+	{
+		$message = str_replace('${value}', $this->getValue(), $this->message);
+		return $message;
+	}
+
+	/**
+	 * @see        XMLElement::appendXml(DOMNode)
+	 */
+	public function appendXml(DOMNode $node)
+	{
+		$doc = ($node instanceof DOMDocument) ? $node : $node->ownerDocument;
+
+		$ruleNode = $node->appendChild($doc->createElement('rule'));
+		$ruleNode->setAttribute('name', $this->getName());
+
+		if ($this->getValue() !== null) {
+			$ruleNode->setAttribute('value', $this->getValue());
+		}
+
+		if ($this->classname !== null) {
+			$ruleNode->setAttribute('class', $this->getClass());
+		}
+
+		$ruleNode->setAttribute('message', $this->getMessage());
+	}
+
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/database/model/Table.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/database/model/Table.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/database/model/Table.php	(revision 19)
@@ -0,0 +1,1373 @@
+<?php
+
+/*
+ *  $Id: Table.php 1043 2008-05-08 13:27:19Z ron $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://propel.phpdb.org>.
+ */
+
+require_once 'propel/engine/database/model/XMLElement.php';
+include_once 'propel/engine/EngineException.php';
+include_once 'propel/engine/database/model/IDMethod.php';
+include_once 'propel/engine/database/model/NameFactory.php';
+include_once 'propel/engine/database/model/Column.php';
+include_once 'propel/engine/database/model/Unique.php';
+include_once 'propel/engine/database/model/ForeignKey.php';
+include_once 'propel/engine/database/model/IdMethodParameter.php';
+include_once 'propel/engine/database/model/Validator.php';
+
+/**
+ * Data about a table used in an application.
+ *
+ * @author     Hans Lellelid <hans@xmpl.org> (Propel)
+ * @author     Leon Messerschmidt <leon@opticode.co.za> (Torque)
+ * @author     Jason van Zyl <jvanzyl@apache.org> (Torque)
+ * @author     Martin Poeschl <mpoeschl@marmot.at> (Torque)
+ * @author     John McNally <jmcnally@collab.net> (Torque)
+ * @author     Daniel Rall <dlr@collab.net> (Torque)
+ * @author     Byron Foster <byron_foster@yahoo.com> (Torque)
+ * @version    $Revision: 1043 $
+ * @package    propel.engine.database.model
+ */
+class Table extends XMLElement implements IDMethod {
+
+	/**
+	 * Enables some debug printing.
+	 */
+	const DEBUG = false;
+
+	/**
+	 * Columns for this table.
+	 *
+	 * @var        array Column[]
+	 */
+	private $columnList = array();
+
+	/**
+	 * Validators for this table.
+	 *
+	 * @var        array Validator[]
+	 */
+	private $validatorList = array();
+
+	/**
+	 * Foreign keys for this table.
+	 *
+	 * @var        array ForeignKey[]
+	 */
+	private $foreignKeys = array();
+
+	/**
+	 * Indexes for this table.
+	 *
+	 * @var        array Index[]
+	 */
+	private $indices = array();
+
+	/**
+	 * Unique indexes for this table.
+	 *
+	 * @var        array Unique[]
+	 */
+	private $unices = array();
+
+	/**
+	 * Any parameters for the ID method (currently supports changing sequence name).
+	 *
+	 * @var        array
+	 */
+	private $idMethodParameters = array();
+
+	/**
+	 * Table name.
+	 *
+	 * @var        string
+	 */
+	private $name;
+
+	/**
+	 * Table description.
+	 *
+	 * @var        string
+	 */
+	private $description;
+
+	/**
+	 * phpName for the table.
+	 *
+	 * @var        string
+	 */
+	private $phpName;
+
+	/**
+	 * ID method for the table (e.g. IDMethod::NATIVE, IDMethod::NONE).
+	 *
+	 * @var        string
+	 */
+	private $idMethod;
+
+	/**
+	 * Wether an INSERT with set PK is allowed on tables with IDMethod::NATIVE
+	 *
+	 * @var        boolean
+	 */
+	private $allowPkInsert;
+
+	/**
+	 * Strategry to use for converting column name to phpName.
+	 *
+	 * @var        string
+	 */
+	private $phpNamingMethod;
+
+	/**
+	 * The Database that this table belongs to.
+	 *
+	 * @var        Database
+	 */
+	private $database;
+
+	/**
+	 * Foreign Keys that refer to this table.
+	 *
+	 * @var        array ForeignKey[]
+	 */
+	private $referrers = array();
+
+	/**
+	 * Names of foreign tables.
+	 *
+	 * @var        array string[]
+	 */
+	private $foreignTableNames;
+
+	/**
+	 * Whether this table contains a foreign primary key.
+	 *
+	 * @var        boolean
+	 */
+	private $containsForeignPK;
+
+	/**
+	 * The inheritance column for this table (if any).
+	 *
+	 * @var        Column
+	 */
+	private $inheritanceColumn;
+
+	/**
+	 * Whether to skip generation of SQL for this table.
+	 *
+	 * @var        boolean
+	 */
+	private $skipSql;
+
+	/**
+	 * Whether this table is "read-only".
+	 *
+	 * @var        boolean
+	 */
+	private $readOnly;
+
+	/**
+	 * Whether this table should result in abstract OM classes.
+	 *
+	 * @var        boolean
+	 */
+	private $abstractValue;
+
+	/**
+	 * Whether this table is an alias for another table.
+	 *
+	 * @var        string
+	 */
+	private $alias;
+
+	/**
+	 * The interface that the generated "object" class should implement.
+	 *
+	 * @var        string
+	 */
+	private $enterface;
+
+	/**
+	 * The package for the generated OM.
+	 *
+	 * @var        string
+	 */
+	private $pkg;
+
+	/**
+	 * The base class to extend for the generated "object" class.
+	 *
+	 * @var        string
+	 */
+	private $baseClass;
+
+	/**
+	 * The base peer class to extend for generated "peer" class.
+	 *
+	 * @var        string
+	 */
+	private $basePeer;
+
+	/**
+	 * Map of columns by name.
+	 *
+	 * @var        array
+	 */
+	private $columnsByName = array();
+
+	/**
+	 * Map of columns by phpName.
+	 *
+	 * @var        array
+	 */
+	private $columnsByPhpName = array();
+
+	/**
+	 * Whether this table needs to use transactions in Postgres.
+	 *
+	 * @var        string
+	 * @deprecated
+	 */
+	private $needsTransactionInPostgres;
+
+	/**
+	 * Whether to perform additional indexing on this table.
+	 *
+	 * @var        boolean
+	 */
+	private $heavyIndexing;
+
+	/**
+	 * Whether this table is for reference only.
+	 *
+	 * @var        boolean
+	 */
+	private $forReferenceOnly;
+
+	/**
+	 * The tree mode (nested set, etc.) implemented by this table.
+	 *
+	 * @var        string
+	 */
+	private $treeMode;
+
+	/**
+	 * Whether to reload the rows in this table after insert.
+	 *
+	 * @var        boolean
+	 */
+	private $reloadOnInsert;
+
+	/**
+	 * Whether to reload the rows in this table after update.
+	 *
+	 * @var        boolean
+	 */
+	private $reloadOnUpdate;
+
+	/**
+	 * Constructs a table object with a name
+	 *
+	 * @param      string $name table name
+	 */
+	public function __construct($name = null)
+	{
+		$this->name = $name;
+	}
+
+	/**
+	 * Sets up the Rule object based on the attributes that were passed to loadFromXML().
+	 * @see        parent::loadFromXML()
+	 */
+	public function setupObject()
+	{
+		$this->name = $this->getAttribute("name");
+		$this->phpName = $this->getAttribute("phpName");
+		$this->idMethod = $this->getAttribute("idMethod", $this->getDatabase()->getDefaultIdMethod());
+		$this->allowPkInsert = $this->booleanValue($this->getAttribute("allowPkInsert"));
+
+		// retrieves the method for converting from specified name to a PHP name.
+		$this->phpNamingMethod = $this->getAttribute("phpNamingMethod", $this->getDatabase()->getDefaultPhpNamingMethod());
+
+		$this->skipSql = $this->booleanValue($this->getAttribute("skipSql"));
+		$this->readOnly = $this->booleanValue($this->getAttribute("readOnly"));
+
+		$this->pkg = $this->getAttribute("package");
+		$this->abstractValue = $this->booleanValue($this->getAttribute("abstract"));
+		$this->baseClass = $this->getAttribute("baseClass");
+		$this->basePeer = $this->getAttribute("basePeer");
+		$this->alias = $this->getAttribute("alias");
+
+		$this->heavyIndexing = ( $this->booleanValue($this->getAttribute("heavyIndexing"))
+		|| ("false" !== $this->getAttribute("heavyIndexing")
+		&& $this->getDatabase()->isHeavyIndexing() ) );
+		$this->description = $this->getAttribute("description");
+		$this->enterface = $this->getAttribute("interface"); // sic ('interface' is reserved word)
+		$this->treeMode = $this->getAttribute("treeMode");
+
+		$this->reloadOnInsert = $this->booleanValue($this->getAttribute("reloadOnInsert"));
+		$this->reloadOnUpdate = $this->booleanValue($this->getAttribute("reloadOnUpdate"));
+	}
+
+	/**
+	 * <p>A hook for the SAX XML parser to call when this table has
+	 * been fully loaded from the XML, and all nested elements have
+	 * been processed.</p>
+	 *
+	 * <p>Performs heavy indexing and naming of elements which weren't
+	 * provided with a name.</p>
+	 */
+	public function doFinalInitialization()
+	{
+		// Heavy indexing must wait until after all columns composing
+		// a table's primary key have been parsed.
+		if ($this->heavyIndexing) {
+			$this->doHeavyIndexing();
+		}
+
+		// If there is no PK, then throw an error.  Propel 1.3 requires primary keys.
+		$pk = $this->getPrimaryKey();
+		if (empty($pk)) {
+			throw new EngineException("Table '".$this->getName()."' does not have a primary key defined.  Propel requires all tables to have a primary key.");
+		}
+
+		// Name any indices which are missing a name using the
+		// appropriate algorithm.
+		$this->doNaming();
+
+		// if idMethod is "native" and in fact there are no autoIncrement
+		// columns in the table, then change it to "none"
+		$anyAutoInc = false;
+		$hasPK = false;
+		foreach ($this->getColumns() as $col) {
+			if ($col->isAutoIncrement()) {
+				$anyAutoInc = true;
+			}
+			if ($col->isPrimaryKey()) {
+				$hasPK = true;
+			}
+		}
+		if ($this->getIdMethod() === IDMethod::NATIVE && !$anyAutoInc) {
+			$this->setIdMethod(IDMethod::NO_ID_METHOD);
+		}
+		if (!$hasPK) {
+			throw new EngineException("Table '" . $this->getName() . "' does not define a primary key column!");
+		}
+	}
+
+	/**
+	 * <p>Adds extra indices for multi-part primary key columns.</p>
+	 *
+	 * <p>For databases like MySQL, values in a where clause much
+	 * match key part order from the left to right.  So, in the key
+	 * definition <code>PRIMARY KEY (FOO_ID, BAR_ID)</code>,
+	 * <code>FOO_ID</code> <i>must</i> be the first element used in
+	 * the <code>where</code> clause of the SQL query used against
+	 * this table for the primary key index to be used.  This feature
+	 * could cause problems under MySQL with heavily indexed tables,
+	 * as MySQL currently only supports 16 indices per table (i.e. it
+	 * might cause too many indices to be created).</p>
+	 *
+	 * <p>See <a href="http://www.mysql.com/doc/E/X/EXPLAIN.html">the
+	 * manual</a> for a better description of why heavy indexing is
+	 * useful for quickly searchable database tables.</p>
+	 */
+	private function doHeavyIndexing()
+	{
+		if (self::DEBUG) {
+			print("doHeavyIndex() called on table " . $this->name."\n");
+		}
+
+		$pk = $this->getPrimaryKey();
+		$size = count($pk);
+
+		// We start at an offset of 1 because the entire column
+		// list is generally implicitly indexed by the fact that
+		// it's a primary key.
+		for ($i=1; $i < $size; $i++) {
+			$idx = new Index();
+			$idx->setColumns(array_slice($pk, $i, $size));
+			$this->addIndex($idx);
+		}
+	}
+
+	/**
+	 * Names composing objects which haven't yet been named.  This
+	 * currently consists of foreign-key and index entities.
+	 */
+	private function doNaming() {
+
+		// Assure names are unique across all databases.
+		try {
+			for ($i=0, $size = count($this->foreignKeys); $i < $size; $i++) {
+				$fk = $this->foreignKeys[$i];
+				$name = $fk->getName();
+				if (empty($name)) {
+					$name = $this->acquireConstraintName("FK", $i + 1);
+					$fk->setName($name);
+				}
+			}
+
+			for ($i = 0, $size = count($this->indices); $i < $size; $i++) {
+				$index = $this->indices[$i];
+				$name = $index->getName();
+				if (empty($name)) {
+					$name = $this->acquireConstraintName("I", $i + 1);
+					$index->setName($name);
+				}
+			}
+
+			for ($i = 0, $size = count($this->unices); $i < $size; $i++) {
+				$index = $this->unices[$i];
+				$name = $index->getName();
+				if (empty($name)) {
+					$name = $this->acquireConstraintName("U", $i + 1);
+					$index->setName($name);
+				}
+			}
+
+			// NOTE: Most RDBMSes can apparently name unique column
+			// constraints/indices themselves (using MySQL and Oracle
+			// as test cases), so we'll assume that we needn't add an
+			// entry to the system name list for these.
+		} catch (EngineException $nameAlreadyInUse) {
+			print $nameAlreadyInUse->getMessage() . "\n";
+			print $nameAlreadyInUse->getTraceAsString();
+		}
+	}
+
+	/**
+	 * Macro to a constraint name.
+	 *
+	 * @param      nameType constraint type
+	 * @param      nbr unique number for this constraint type
+	 * @return     unique name for constraint
+	 * @throws     EngineException
+	 */
+	private function acquireConstraintName($nameType, $nbr)
+	{
+		$inputs = array();
+		$inputs[] = $this->getDatabase();
+		$inputs[] = $this->getName();
+		$inputs[] = $nameType;
+		$inputs[] = $nbr;
+		return NameFactory::generateName(NameFactory::CONSTRAINT_GENERATOR, $inputs);
+	}
+
+	/**
+	 * Gets the value of base class for classes produced from this table.
+	 *
+	 * @return     The base class for classes produced from this table.
+	 */
+	public function getBaseClass()
+	{
+		if ($this->isAlias() && $this->baseClass === null) {
+			return $this->alias;
+		} elseif ($this->baseClass === null) {
+			return $this->getDatabase()->getBaseClass();
+		} else {
+			return $this->baseClass;
+		}
+	}
+
+	/**
+	 * Set the value of baseClass.
+	 * @param      v  Value to assign to baseClass.
+	 */
+	public function setBaseClass($v)
+	{
+		$this->baseClass = $v;
+	}
+
+	/**
+	 * Get the value of basePeer.
+	 * @return     value of basePeer.
+	 */
+	public function getBasePeer()
+	{
+		if ($this->isAlias() && $this->basePeer === null) {
+			return $this->alias . "Peer";
+		} elseif ($this->basePeer === null) {
+			return $this->getDatabase()->getBasePeer();
+		} else {
+			return $this->basePeer;
+		}
+	}
+
+	/**
+	 * Set the value of basePeer.
+	 * @param      v  Value to assign to basePeer.
+	 */
+	public function setBasePeer($v)
+	{
+		$this->basePeer = $v;
+	}
+
+	/**
+	 * A utility function to create a new column from attrib and add it to this
+	 * table.
+	 *
+	 * @param      $coldata xml attributes or Column class for the column to add
+	 * @return     the added column
+	 */
+	public function addColumn($data)
+	{
+		if ($data instanceof Column) {
+			$col = $data;
+			$col->setTable($this);
+			if ($col->isInheritance()) {
+				$this->inheritanceColumn = $col;
+			}
+			$this->columnList[] = $col;
+			$this->columnsByName[$col->getName()] = $col;
+			$this->columnsByPhpName[$col->getPhpName()] = $col;
+			$col->setPosition(count($this->columnList));
+			$this->needsTransactionInPostgres |= $col->requiresTransactionInPostgres();
+			return $col;
+		} else {
+			$col = new Column();
+			$col->setTable($this);
+			$col->loadFromXML($data);
+			return $this->addColumn($col); // call self w/ different param
+		}
+	}
+
+	/**
+	 * Add a validator to this table.
+	 *
+	 * Supports two signatures:
+	 * - addValidator(Validator $validator)
+	 * - addValidator(array $attribs)
+	 *
+	 * @param      mixed $data Validator object or XML attribs (array) from <validator /> element.
+	 * @return     Validator The added Validator.
+	 * @throws     EngineException
+	 */
+	public function addValidator($data)
+	{
+		if ($data instanceof Validator) {
+			$validator = $data;
+			$col = $this->getColumn($validator->getColumnName());
+			if ($col == null) {
+				throw new EngineException("Failed adding validator to table '" . $this->getName() .
+				"': column '" . $validator->getColumnName() . "' does not exist !");
+			}
+			$validator->setColumn($col);
+			$validator->setTable($this);
+			$this->validatorList[] = $validator;
+			return $validator;
+		} else {
+			$validator = new Validator();
+			$validator->setTable($this);
+			$validator->loadFromXML($data);
+			return $this->addValidator($validator);
+		}
+	}
+
+	/**
+	 * A utility function to create a new foreign key
+	 * from attrib and add it to this table.
+	 */
+	public function addForeignKey($fkdata)
+	{
+		if ($fkdata instanceof ForeignKey) {
+			$fk = $fkdata;
+			$fk->setTable($this);
+			$this->foreignKeys[] = $fk;
+
+			if ($this->foreignTableNames === null) {
+				$this->foreignTableNames = array();
+			}
+			if (!in_array($fk->getForeignTableName(), $this->foreignTableNames)) {
+				$this->foreignTableNames[] = $fk->getForeignTableName();
+			}
+			return $fk;
+		} else {
+			$fk = new ForeignKey();
+			$fk->loadFromXML($fkdata);
+			return $this->addForeignKey($fk);
+		}
+	}
+
+	/**
+	 * Gets the column that subclasses of the class representing this
+	 * table can be produced from.
+	 * @return     Column
+	 */
+	public function getChildrenColumn()
+	{
+		return $this->inheritanceColumn;
+	}
+
+	/**
+	 * Get the subclasses that can be created from this table.
+	 * @return     array string[] Class names
+	 */
+	public function getChildrenNames()
+	{
+		if ($this->inheritanceColumn === null
+		|| !$this->inheritanceColumn->isEnumeratedClasses()) {
+			return null;
+		}
+		$children = $this->inheritanceColumn->getChildren();
+		$names = array();
+		for ($i = 0, $size=count($children); $i < $size; $i++) {
+			$names[] = get_class($children[$i]);
+		}
+		return $names;
+	}
+
+	/**
+	 * Adds the foreign key from another table that refers to this table.
+	 */
+	public function addReferrer(ForeignKey $fk)
+	{
+		if ($this->referrers === null) {
+			$this->referrers = array();
+		}
+		$this->referrers[] = $fk;
+	}
+
+	/**
+	 * Get list of references to this table.
+	 */
+	public function getReferrers()
+	{
+		return $this->referrers;
+	}
+
+	/**
+	 * Set whether this table contains a foreign PK
+	 */
+	public function setContainsForeignPK($b)
+	{
+		$this->containsForeignPK = (boolean) $b;
+	}
+
+	/**
+	 * Determine if this table contains a foreign PK
+	 */
+	public function getContainsForeignPK()
+	{
+		return $this->containsForeignPK;
+	}
+
+	/**
+	 * A list of tables referenced by foreign keys in this table
+	 */
+	public function getForeignTableNames()
+	{
+		if ($this->foreignTableNames === null) {
+			$this->foreignTableNames = array();
+		}
+		return $this->foreignTableNames;
+	}
+
+	/**
+	 * Return true if the column requires a transaction in Postgres
+	 */
+	public function requiresTransactionInPostgres()
+	{
+		return $this->needsTransactionInPostgres;
+	}
+
+	/**
+	 * A utility function to create a new id method parameter
+	 * from attrib or object and add it to this table.
+	 */
+	public function addIdMethodParameter($impdata)
+	{
+		if ($impdata instanceof IdMethodParameter) {
+			$imp = $impdata;
+			$imp->setTable($this);
+			if ($this->idMethodParameters === null) {
+				$this->idMethodParameters = array();
+			}
+			$this->idMethodParameters[] = $imp;
+			return $imp;
+		} else {
+			$imp = new IdMethodParameter();
+			$imp->loadFromXML($impdata);
+			return $this->addIdMethodParameter($imp); // call self w/ diff param
+		}
+	}
+
+	/**
+	 * Adds a new index to the index list and set the
+	 * parent table of the column to the current table
+	 */
+	public function addIndex($idxdata)
+	{
+		if ($idxdata instanceof Index) {
+			$index = $idxdata;
+			$index->setTable($this);
+			$index->getName(); // we call this method so that the name is created now if it doesn't already exist.
+			$this->indices[] = $index;
+			return $index;
+		} else {
+			$index = new Index($this);
+			$index->loadFromXML($idxdata);
+			return $this->addIndex($index);
+		}
+	}
+
+	/**
+	 * Adds a new Unique to the Unique list and set the
+	 * parent table of the column to the current table
+	 */
+	public function addUnique($unqdata)
+	{
+		if ($unqdata instanceof Unique) {
+			$unique = $unqdata;
+			$unique->setTable($this);
+			$unique->getName(); // we call this method so that the name is created now if it doesn't already exist.
+			$this->unices[] = $unique;
+			return $unique;
+		} else {
+			$unique = new Unique($this);
+			$unique->loadFromXML($unqdata);
+			return $this->addUnique($unique);
+		}
+	}
+
+	/**
+	 * Get the name of the Table
+	 */
+	public function getName()
+	{
+		return $this->name;
+	}
+
+	/**
+	 * Set the name of the Table
+	 */
+	public function setName($newName)
+	{
+		$this->name = $newName;
+	}
+
+	/**
+	 * Get the description for the Table
+	 */
+	public function getDescription()
+	{
+		return $this->description;
+	}
+
+	/**
+	 * Set the description for the Table
+	 *
+	 * @param      newDescription description for the Table
+	 */
+	public function setDescription($newDescription)
+	{
+		$this->description = $newDescription;
+	}
+
+	/**
+	 * Get name to use in PHP sources
+	 * @return     string
+	 */
+	public function getPhpName()
+	{
+		if ($this->phpName === null) {
+			$inputs = array();
+			$inputs[] = $this->name;
+			$inputs[] = $this->phpNamingMethod;
+			try {
+				$this->phpName = NameFactory::generateName(NameFactory::PHP_GENERATOR, $inputs);
+			} catch (EngineException $e) {
+				print $e->getMessage() . "\n";
+				print $e->getTraceAsString();
+			}
+		}
+		return $this->phpName;
+	}
+
+	/**
+	 * Set name to use in PHP sources
+	 * @param      string $phpName
+	 */
+	public function setPhpName($phpName)
+	{
+		$this->phpName = $phpName;
+	}
+
+	/**
+	 * Get the method for generating pk's
+	 * [HL] changing behavior so that Database default
+	 *        method is returned if no method has been specified
+	 *        for the table.
+	 * @return     string
+	 */
+	public function getIdMethod()
+	{
+		if ($this->idMethod === null) {
+			return IDMethod::NO_ID_METHOD;
+		} else {
+			return $this->idMethod;
+		}
+	}
+
+	/**
+	 * Whether we allow to insert primary keys on tables with
+	 * idMethod=native
+	 *
+	 * @return     boolean
+	 */
+	public function isAllowPkInsert()
+	{
+		return $this->allowPkInsert;
+	}
+
+
+	/**
+	 * Set the method for generating pk's
+	 */
+	public function setIdMethod($idMethod)
+	{
+		$this->idMethod = $idMethod;
+	}
+
+	/**
+	 * Skip generating sql for this table (in the event it should
+	 * not be created from scratch).
+	 * @return     boolean Value of skipSql.
+	 */
+	public function isSkipSql()
+	{
+		return ($this->skipSql || $this->isAlias() || $this->isForReferenceOnly());
+	}
+
+	/**
+	 * Is table read-only, in which case only accessors (and relationship setters)
+	 * will be created.
+	 * @return     boolan Value of readOnly.
+	 */
+	public function isReadOnly()
+	{
+		return $this->readOnly;
+	}
+
+	/**
+	 * Set whether this table should have its creation sql generated.
+	 * @param      boolean $v Value to assign to skipSql.
+	 */
+	public function setSkipSql($v)
+	{
+		$this->skipSql = $v;
+	}
+
+	/**
+	 * Whether to force object to reload on INSERT.
+	 * @return     boolean
+	 */
+	public function isReloadOnInsert()
+	{
+		return $this->reloadOnInsert;
+	}
+
+	/**
+	 * Whether to force object to reload on UPDATE.
+	 * @return     boolean
+	 */
+	public function isReloadOnUpdate()
+	{
+		return $this->reloadOnUpdate;
+	}
+
+	/**
+	 * PhpName of om object this entry references.
+	 * @return     value of external.
+	 */
+	public function getAlias()
+	{
+		return $this->alias;
+	}
+
+	/**
+	 * Is this table specified in the schema or is there just
+	 * a foreign key reference to it.
+	 * @return     value of external.
+	 */
+	public function isAlias()
+	{
+		return ($this->alias !== null);
+	}
+
+	/**
+	 * Set whether this table specified in the schema or is there just
+	 * a foreign key reference to it.
+	 * @param      v  Value to assign to alias.
+	 */
+	public function setAlias($v)
+	{
+		$this->alias = $v;
+	}
+
+
+	/**
+	 * Interface which objects for this table will implement
+	 * @return     value of interface.
+	 */
+	public function getInterface()
+	{
+		return $this->enterface;
+	}
+
+	/**
+	 * Interface which objects for this table will implement
+	 * @param      v  Value to assign to interface.
+	 */
+	public function setInterface($v)
+	{
+		$this->enterface = $v;
+	}
+
+	/**
+	 * When a table is abstract, it marks the business object class that is
+	 * generated as being abstract. If you have a table called "FOO", then the
+	 * Foo BO will be <code>public abstract class Foo</code>
+	 * This helps support class hierarchies
+	 *
+	 * @return     value of abstractValue.
+	 */
+	public function isAbstract()
+	{
+		return $this->abstractValue;
+	}
+
+	/**
+	 * When a table is abstract, it marks the business object
+	 * class that is generated as being abstract. If you have a
+	 * table called "FOO", then the Foo BO will be
+	 * <code>public abstract class Foo</code>
+	 * This helps support class hierarchies
+	 *
+	 * @param      v  Value to assign to abstractValue.
+	 */
+	public function setAbstract($v)
+	{
+		$this->abstractValue = (boolean) $v;
+	}
+
+	/**
+	 * Get the value of package.
+	 * @return     value of package.
+	 */
+	public function getPackage()
+	{
+		return $this->pkg;
+	}
+
+	/**
+	 * Set the value of package.
+	 * @param      v  Value to assign to package.
+	 */
+	public function setPackage($v)
+	{
+		$this->pkg = $v;
+	}
+
+	/**
+	 * Returns an Array containing all the columns in the table
+	 * @return     array Column[]
+	 */
+	public function getColumns()
+	{
+		return $this->columnList;
+	}
+
+	/**
+	 * Utility method to get the number of columns in this table
+	 */
+	public function getNumColumns()
+	{
+		return count($this->columnList);
+	}
+
+	/**
+	 * Utility method to get the number of columns in this table
+	 */
+	public function getNumLazyLoadColumns()
+	{
+		$count = 0;
+		foreach ($this->columnList as $col) {
+			if ($col->isLazyLoad()) {
+				$count++;
+			}
+		}
+		return $count;
+	}
+
+	/**
+	 * Returns an Array containing all the validators in the table
+	 * @return     array Validator[]
+	 */
+	public function getValidators()
+	{
+		return $this->validatorList;
+	}
+
+	/**
+	 * Returns an Array containing all the FKs in the table.
+	 * @return     array ForeignKey[]
+	 */
+	public function getForeignKeys()
+	{
+		return $this->foreignKeys;
+	}
+
+	/**
+	 * Returns a Collection of parameters relevant for the chosen
+	 * id generation method.
+	 */
+	public function getIdMethodParameters()
+	{
+		return $this->idMethodParameters;
+	}
+
+	/**
+	 * Returns an Array containing all the FKs in the table
+	 * @return     array Index[]
+	 */
+	public function getIndices()
+	{
+		return $this->indices;
+	}
+
+	/**
+	 * Returns an Array containing all the UKs in the table
+	 * @return     array Unique[]
+	 */
+	public function getUnices()
+	{
+		return $this->unices;
+	}
+
+	/**
+	 * Returns a specified column.
+	 * @return     Column Return a Column object or null if it does not exist.
+	 */
+	public function getColumn($name)
+	{
+		return @$this->columnsByName[$name];
+	}
+
+	/**
+	 * Returns a specified column.
+	 * @return     Column Return a Column object or null if it does not exist.
+	 */
+	public function getColumnByPhpName($phpName)
+	{
+		return @$this->columnsByPhpName[$phpName];
+	}
+
+	/**
+	 * Get all the foreign keys from this table to the specufued tabke.
+	 * @return     array ForeignKey[]
+	 */
+	public function getForeignKeysReferencingTable($tablename)
+	{
+		$matches = array();
+		$keys = $this->getForeignKeys();
+		foreach ($keys as $fk) {
+			if ($fk->getForeignTableName() === $tablename) {
+				$matches[] = $fk;
+			}
+		}
+		return $matches;
+	}
+
+	/**
+	 * Return the foreign keys that includes col in it's list of local columns.
+	 * Eg. Foreign key (a,b,c) refrences tbl(x,y,z) will be returned of col is either a,b or c.
+	 * @param      string $col
+	 * @return     array ForeignKey[] or null if there is no FK for specified column.
+	 */
+	public function getColumnForeignKeys($colname)
+	{
+		$matches = array();
+		foreach ($this->foreignKeys as $fk) {
+			if (in_array($colname, $fk->getLocalColumns())) {
+				$matches[] = $fk;
+			}
+		}
+		return $matches;
+	}
+
+	/**
+	 * Returns true if the table contains a specified column
+	 * @param      mixed $col Column or column name.
+	 */
+	public function containsColumn($col)
+	{
+		if ($col instanceof Column) {
+			return in_array($col, $this->columnList);
+		} else {
+			return ($this->getColumn($col) !== null);
+		}
+	}
+
+	/**
+	 * Set the database that contains this table.
+	 *
+	 * @param      Database $db
+	 */
+	public function setDatabase(Database $db)
+	{
+		$this->database = $db;
+	}
+
+	/**
+	 * Get the database that contains this table.
+	 *
+	 * @return     Database
+	 */
+	public function getDatabase()
+	{
+		return $this->database;
+	}
+
+	/**
+	 * Flag to determine if code/sql gets created for this table.
+	 * Table will be skipped, if return true.
+	 * @return     boolean
+	 */
+	public function isForReferenceOnly()
+	{
+		return $this->forReferenceOnly;
+	}
+
+	/**
+	 * Flag to determine if code/sql gets created for this table.
+	 * Table will be skipped, if set to true.
+	 * @param      boolean $v
+	 */
+	public function setForReferenceOnly($v)
+	{
+		$this->forReferenceOnly = (boolean) $v;
+	}
+
+	/**
+	 * Flag to determine if tree node class should be generated for this table.
+	 * @return     valur of treeMode
+	 */
+	public function treeMode()
+	{
+		return $this->treeMode;
+	}
+
+	/**
+	 * Flag to determine if tree node class should be generated for this table.
+	 * @param      v  Value to assign to treeMode.
+	 */
+	public function setTreeMode($v)
+	{
+		$this->treeMode = $v;
+	}
+
+	/**
+	 * Appends XML nodes to passed-in DOMNode.
+	 *
+	 * @param      DOMNode $node
+	 */
+	public function appendXml(DOMNode $node)
+	{
+		$doc = ($node instanceof DOMDocument) ? $node : $node->ownerDocument;
+
+		$tableNode = $node->appendChild($doc->createElement('table'));
+		$tableNode->setAttribute('name', $this->getName());
+
+		if ($this->phpName !== null) {
+			$tableNode->setAttribute('phpName', $this->phpName);
+		}
+
+		if ($this->idMethod !== null) {
+			$tableNode->setAttribute('idMethod', $this->idMethod);
+		}
+
+		if ($this->skipSql !== null) {
+			$tableNode->setAttribute('idMethod', var_export($this->skipSql, true));
+		}
+
+		if ($this->readOnly !== null) {
+			$tableNode->setAttribute('readOnly', var_export($this->readOnly, true));
+		}
+
+		if ($this->treeMode !== null) {
+			$tableNode->setAttribute('treeMode', $this->treeMode);
+		}
+
+		if ($this->reloadOnInsert !== null) {
+			$tableNode->setAttribute('reloadOnInsert', var_export($this->reloadOnInsert, true));
+		}
+
+		if ($this->reloadOnUpdate !== null) {
+			$tableNode->setAttribute('reloadOnUpdate', var_export($this->reloadOnUpdate, true));
+		}
+
+		if ($this->forReferenceOnly !== null) {
+			$tableNode->setAttribute('forReferenceOnly', var_export($this->forReferenceOnly, true));
+		}
+
+		if ($this->abstractValue !== null) {
+			$tableNode->setAttribute('abstract', var_export($this->abstractValue, true));
+		}
+
+		if ($this->enterface !== null) {
+			$tableNode->setAttribute('interface', $this->enterface);
+		}
+
+		if ($this->description !== null) {
+			$tableNode->setAttribute('description', $this->description);
+		}
+
+		if ($this->baseClass !== null) {
+			$tableNode->setAttribute('baseClass', $this->baseClass);
+		}
+
+		if ($this->basePeer !== null) {
+			$tableNode->setAttribute('basePeer', $this->basePeer);
+		}
+
+		foreach ($this->columnList as $col) {
+			$col->appendXml($tableNode);
+		}
+
+		foreach ($this->validatorList as $validator) {
+			$validator->appendXml($tableNode);
+		}
+
+		foreach ($this->foreignKeys as $fk) {
+			$fk->appendXml($tableNode);
+		}
+
+		foreach ($this->idMethodParameters as $param) {
+			$param->appendXml($tableNode);
+		}
+
+		foreach ($this->indices as $index) {
+			$index->appendXml($tableNode);
+		}
+
+		foreach ($this->unices as $unique) {
+			$unique->appendXml($tableNode);
+		}
+
+		foreach ($this->vendorInfos as $vi) {
+			$vi->appendXml($tableNode);
+		}
+
+	}
+
+	/**
+	 * Returns the collection of Columns which make up the single primary
+	 * key for this table.
+	 *
+	 * @return     array Column[] A list of the primary key parts.
+	 */
+	public function getPrimaryKey()
+	{
+		$pk = array();
+		for ($i=0,$_i=count($this->columnList); $i < $_i; $i++) {
+			$col = $this->columnList[$i];
+			if ($col->isPrimaryKey()) {
+				$pk[] = $col;
+			}
+		}
+		return $pk;
+	}
+
+	/**
+	 * Determine whether this table has a primary key.
+	 *
+	 * @return     boolean Whether this table has any primary key parts.
+	 */
+	public function hasPrimaryKey()
+	{
+		return (count($this->getPrimaryKey()) > 0);
+	}
+
+	/**
+	 * Determine whether this table has any auto-increment primary key(s).
+	 *
+	 * @return     boolean Whether this table has a non-"none" id method and has a primary key column that is auto-increment.
+	 */
+	public function hasAutoIncrementPrimaryKey()
+	{
+		if ($this->getIdMethod() != IDMethod::NO_ID_METHOD) {
+			$pks =$this->getPrimaryKey();
+			foreach ($pks as $pk) {
+				if ($pk->isAutoIncrement()) {
+					return true;
+				}
+			}
+		}
+		return false;
+	}
+
+	/**
+	 * Gets the auto increment PK
+	 *
+	 * @return    Column if any auto increment PK column
+	 */
+	public function getAutoIncrementPrimaryKey()
+	{
+		if ($this->getIdMethod() != IDMethod::NO_ID_METHOD) {
+			$pks =$this->getPrimaryKey();
+			foreach ($pks as $pk) {
+				if ($pk->isAutoIncrement()) {
+					return $pk;
+				}
+			}
+		}
+		return null;
+	}
+
+	/**
+	 * Returns all parts of the primary key, separated by commas.
+	 *
+	 * @return     A CSV list of primary key parts.
+	 * @deprecated Use the DDLBuilder->getColumnList() with the #getPrimaryKey() method.
+	 */
+	public function printPrimaryKey()
+	{
+		return $this->printList($this->columnList);
+	}
+
+	/**
+	 * Returns the elements of the list, separated by commas.
+	 * @param      array $list
+	 * @return     A CSV list.
+	 * @deprecated Use the DDLBuilder->getColumnList() with the #getPrimaryKey() method.
+	 */
+	private function printList($list){
+		$result = "";
+		$comma = 0;
+		for ($i=0,$_i=count($list); $i < $_i; $i++) {
+			$col = $list[$i];
+			if ($col->isPrimaryKey()) {
+				$result .= ($comma++ ? ',' : '') . $this->getDatabase()->getPlatform()->quoteIdentifier($col->getName());
+			}
+		}
+		return $result;
+	}
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/database/model/Unique.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/database/model/Unique.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/database/model/Unique.php	(revision 19)
@@ -0,0 +1,68 @@
+<?php
+/*
+ *  $Id: Unique.php 989 2008-03-11 14:29:30Z heltem $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://propel.phpdb.org>.
+ */
+
+include_once 'propel/engine/database/model/Index.php';
+
+/**
+ * Information about unique columns of a table.  This class assumes
+ * that in the underlying RDBMS, unique constraints and unique indices
+ * are roughly equivalent.  For example, adding a unique constraint to
+ * a column also creates an index on that column (this is known to be
+ * true for MySQL and Oracle).
+ *
+ * @author     Hans Lellelid <hans@xmpl.org> (Propel)
+ * @author     Jason van Zyl <jvanzyl@apache.org> (Torque)
+ * @author     Daniel Rall <dlr@collab.net> (Torque)
+ * @version    $Revision: 989 $
+ * @package    propel.engine.database.model
+ */
+class Unique extends Index {
+
+	/**
+	 * Returns <code>true</code>.
+	 */
+	public function isUnique()
+	{
+		return true;
+	}
+
+	/**
+	 * @see        XMLElement::appendXml(DOMNode)
+	 */
+	public function appendXml(DOMNode $node)
+	{
+		$doc = ($node instanceof DOMDocument) ? $node : $node->ownerDocument;
+
+		$uniqueNode = $node->appendChild($doc->createElement('unique'));
+		$uniqueNode->setAttribute('name', $this->getName());
+		$columns = $this->getColumns();
+		foreach ($this->getColumns() as $colname) {
+			$uniqueColNode = $uniqueNode->appendChild($doc->createElement('unique-column'));
+			$uniqueColNode->setAttribute('name', $colname);
+		}
+
+		foreach ($this->vendorInfos as $vi) {
+			$vi->appendXml($uniqueNode);
+		}
+	}
+
+
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/database/model/Validator.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/database/model/Validator.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/database/model/Validator.php	(revision 19)
@@ -0,0 +1,194 @@
+<?php
+/*
+ *  $Id: Validator.php 989 2008-03-11 14:29:30Z heltem $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://propel.phpdb.org>.
+ */
+
+require_once 'propel/engine/database/model/XMLElement.php';
+include_once 'propel/engine/EngineException.php';
+include_once 'propel/engine/database/model/PropelTypes.php';
+include_once 'propel/engine/database/model/Rule.php';
+
+/**
+ * Validator.
+ *
+ * @author     Michael Aichler <aichler@mediacluster.de> (Propel)
+ * @version    $Revision: 989 $
+ * @package    propel.engine.database.model
+ */
+class Validator extends XMLElement {
+
+	const TRANSLATE_NONE = "none";
+	const TRANSLATE_GETTEXT = "gettext";
+
+	/**
+	 * The column this validator applies to.
+	 *
+	 * @var        Column
+	 */
+	private $column;
+
+	/**
+	 * The rules for the validation.
+	 *
+	 * @var        array Rule[]
+	 */
+	private $ruleList = array();
+
+	/**
+	 * The translation mode.
+	 *
+	 * @var        string
+	 */
+	private $translate;
+
+	/**
+	 * Parent table.
+	 *
+	 * @var        Table
+	 */
+	private $table;
+
+	/**
+	 * Sets up the Validator object based on the attributes that were passed to loadFromXML().
+	 * @see        parent::loadFromXML()
+	 */
+	protected function setupObject()
+	{
+		$this->column = $this->getTable()->getColumn($this->getAttribute("column"));
+		$this->translate = $this->getAttribute("translate", $this->getTable()->getDatabase()->getDefaultTranslateMethod());;
+	}
+
+	/**
+	 * Add a Rule to this validator.
+	 * Supports two signatures:
+	 * - addRule(Rule $rule)
+	 * - addRule(array $attribs)
+	 * @param      mixed $data Rule object or XML attribs (array) from <rule/> element.
+	 * @return     Rule The added Rule.
+	 */
+	public function addRule($data)
+	{
+		if ($data instanceof Rule) {
+			$rule = $data; // alias
+			$rule->setValidator($this);
+			$this->ruleList[] = $rule;
+			return $rule;
+		}
+		else {
+			$rule = new Rule();
+			$rule->setValidator($this);
+			$rule->loadFromXML($data);
+			return $this->addRule($rule); // call self w/ different param
+		}
+	}
+
+	/**
+	 * Gets an array of all added rules for this validator.
+	 * @return     array Rule[]
+	 */
+	public function getRules()
+	{
+		return $this->ruleList;
+	}
+
+	/**
+	 * Gets the name of the column that this Validator applies to.
+	 * @return     string
+	 */
+	public function getColumnName()
+	{
+		return $this->column->getName();
+	}
+
+	/**
+	 * Sets the Column object that this validator applies to.
+	 * @param      Column $column
+	 * @see        Table::addValidator()
+	 */
+	public function setColumn(Column $column)
+	{
+		$this->column = $column;
+	}
+
+	/**
+	 * Gets the Column object that this validator applies to.
+	 * @return     Column
+	 */
+	public function getColumn()
+	{
+		return $this->column;
+	}
+
+	/**
+	 * Set the owning Table.
+	 * @param      Table $table
+	 */
+	public function setTable(Table $table)
+	{
+		$this->table = $table;
+	}
+
+	/**
+	 * Get the owning Table.
+	 * @return     Table
+	 */
+	public function getTable()
+	{
+		return $this->table;
+	}
+
+	/**
+	 * Set the translation mode to use for the message.
+	 * Currently only "gettext" and "none" are supported.  The default is "none".
+	 * @param      string $method Translation method ("gettext", "none").
+	 */
+	public function setTranslate($method)
+	{
+		$this->translate = $method;
+	}
+
+	/**
+	 * Get the translation mode to use for the message.
+	 * Currently only "gettext" and "none" are supported.  The default is "none".
+	 * @return     string Translation method ("gettext", "none").
+	 */
+	public function getTranslate()
+	{
+		return $this->translate;
+	}
+
+	/**
+	 * @see        XMLElement::appendXml(DOMNode)
+	 */
+	public function appendXml(DOMNode $node)
+	{
+		$doc = ($node instanceof DOMDocument) ? $node : $node->ownerDocument;
+
+		$valNode = $node->appendChild($doc->createElement('validator'));
+		$valNode->setAttribute('column', $this->getColumnName());
+
+		if ($this->translate !== null) {
+			$valNode->setAttribute('translate', $this->translate);
+		}
+
+		foreach ($this->ruleList as $rule) {
+			$rule->appendXml($valNode);
+		}
+	}
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/database/model/VendorInfo.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/database/model/VendorInfo.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/database/model/VendorInfo.php	(revision 19)
@@ -0,0 +1,182 @@
+<?php
+/*
+ *  $Id: VendorInfo.php 989 2008-03-11 14:29:30Z heltem $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://propel.phpdb.org>.
+ */
+
+require_once 'propel/engine/database/model/XMLElement.php';
+include_once 'propel/engine/EngineException.php';
+
+/**
+ * Object to hold vendor-specific info.
+ *
+ * @author     Hans Lellelid <hans@xmpl.org>
+ * @version    $Revision: 989 $
+ * @package    propel.engine.database.model
+ */
+class VendorInfo extends XMLElement {
+
+	/**
+	 * The vendor RDBMS type.
+	 *
+	 * @var        string
+	 */
+	private $type;
+
+	/**
+	 * Vendor parameters.
+	 *
+	 * @var        array
+	 */
+	private $parameters = array();
+
+	/**
+	 * Creates a new VendorInfo instance.
+	 *
+	 * @param      string $type RDBMS type (optional)
+	 */
+	public function __construct($type = null)
+	{
+		$this->type = $type;
+	}
+
+	/**
+	 * Sets up this object based on the attributes that were passed to loadFromXML().
+	 * @see        parent::loadFromXML()
+	 */
+	protected function setupObject()
+	{
+		$this->type = $this->getAttribute("type");
+	}
+
+	/**
+	 * Set RDBMS type for this vendor-specific info.
+	 *
+	 * @param      string $v
+	 */
+	public function setType($v)
+	{
+		$this->type = $v;
+	}
+
+	/**
+	 * Get RDBMS type for this vendor-specific info.
+	 *
+	 * @return     string
+	 */
+	public function getType()
+	{
+		return $this->type;
+	}
+
+	/**
+	 * Adds a new vendor parameter to this object.
+	 * @param      array $attrib Attributes from XML.
+	 */
+	public function addParameter($attrib)
+	{
+		$name = $attrib["name"];
+		$this->parameters[$name] = $attrib["value"];
+	}
+
+	/**
+	 * Sets parameter value.
+	 *
+	 * @param      string $name
+	 * @param      mixed $value The value for the parameter.
+	 */
+	public function setParameter($name, $value)
+	{
+		$this->parameters[$name] = $value;
+	}
+
+	/**
+	 * Gets parameter value.
+	 *
+	 * @param      string $name
+	 * @return     mixed Paramter value.
+	 */
+	public function getParameter($name)
+	{
+		if (isset($this->parameters[$name])) {
+			return $this->parameters[$name];
+		}
+		return null; // just to be explicit
+	}
+
+	/**
+	 * Whether parameter exists.
+	 *
+	 * @param      string $name
+	 */
+	public function hasParameter($name)
+	{
+		return isset($this->parameters[$name]);
+	}
+
+	/**
+	 * Sets assoc array of parameters for venfor specific info.
+	 *
+	 * @param      array $params Paramter data.
+	 */
+	public function setParameters(array $params = array())
+	{
+		$this->parameters = $params;
+	}
+
+	/**
+	 * Gets assoc array of parameters for venfor specific info.
+	 *
+	 * @return     array
+	 */
+	public function getParameters()
+	{
+		return $this->parameters;
+	}
+
+	/**
+	 * Gets a new merged VendorInfo object.
+	 * @param      VendorInfo $info
+	 * @return     VendorInfo new object with merged parameters
+	 */
+	public function getMergedVendorInfo(VendorInfo $merge)
+	{
+		$newParams = array_merge($this->getParameters(), $merge->getParameters());
+		$newInfo = new VendorInfo($this->getType());
+		$newInfo->setParameters($newParams);
+		return $newInfo;
+	}
+
+	/**
+	 * @see        XMLElement::appendXml(DOMNode)
+	 */
+	public function appendXml(DOMNode $node)
+	{
+		$doc = ($node instanceof DOMDocument) ? $node : $node->ownerDocument;
+
+		$vendorNode = $node->appendChild($doc->createElement("vendor"));
+		$vendorNode->setAttribute("type", $this->getType());
+
+		foreach ($this->parameters as $key => $value) {
+			$parameterNode = $doc->createElement("parameter");
+			$parameterNode->setAttribute("name", $key);
+			$parameterNode->setAttribute("value", $value);
+			$vendorNode->appendChild($parameterNode);
+		}
+	}
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/database/model/XMLElement.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/database/model/XMLElement.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/database/model/XMLElement.php	(revision 19)
@@ -0,0 +1,158 @@
+<?php
+/*
+ *  $Id: XMLElement.php 989 2008-03-11 14:29:30Z heltem $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://propel.phpdb.org>.
+ */
+
+include_once 'propel/engine/database/model/VendorInfo.php';
+
+/**
+ * An abstract class for elements represented by XML tags (e.g. Column, Table).
+ *
+ * @author     Hans Lellelid <hans@xmpl.org>
+ * @version    $Revision: 989 $
+ * @package    propel.engine.database.model
+ */
+abstract class XMLElement {
+
+	/**
+	 * The name => value attributes from XML.
+	 *
+	 * @var        array
+	 */
+	protected $attributes = array();
+
+	/**
+	 * Any associated vendor-specific information objects.
+	 *
+	 * @var        array VendorInfo[]
+	 */
+	protected $vendorInfos = array();
+
+	/**
+	 * Replaces the old loadFromXML() so that we can use loadFromXML() to load the attribs into the class.
+	 */
+	abstract protected function setupObject();
+
+	/**
+	 * This is the entry point method for loading data from XML.
+	 * It calls a setupObject() method that must be implemented by the child class.
+	 * @param      array $attributes The attributes for the XML tag.
+	 */
+	public function loadFromXML($attributes)
+	{
+		$this->attributes = array_change_key_case($attributes, CASE_LOWER);
+		$this->setupObject();
+	}
+
+	/**
+	 * Returns the assoc array of attributes.
+	 * All attribute names (keys) are lowercase.
+	 * @return     array
+	 */
+	public function getAttributes()
+	{
+		return $this->attributes;
+	}
+
+	/**
+	 * Gets a particular attribute by [case-insensitive] name.
+	 * If attribute is not set then the $defaultValue is returned.
+	 * @param      string $name The [case-insensitive] name of the attribute to lookup.
+	 * @param      mixed $defaultValue The default value to use in case the attribute is not set.
+	 * @return     mixed The value of the attribute or $defaultValue if not set.
+	 */
+	public function getAttribute($name, $defaultValue = null)
+	{
+		$name = strtolower($name);
+		if (isset($this->attributes[$name])) {
+			return $this->attributes[$name];
+		} else {
+			return $defaultValue;
+		}
+	}
+
+	/**
+	 * Converts value specified in XML to a boolean value.
+	 * This is to support the default value when used w/ a boolean column.
+	 * @return     value
+	 */
+	protected function booleanValue($val)
+	{
+		if (is_numeric($val)) {
+			return (bool) $val;
+		} else {
+			return (in_array(strtolower($val), array('true', 't', 'y', 'yes'), true) ? true : false);
+		}
+	}
+
+	/**
+	 * Appends DOM elements to represent this object in XML.
+	 * @param      DOMNode $node
+	 */
+	abstract public function appendXml(DOMNode $node);
+
+	/**
+	 * Sets an associated VendorInfo object.
+	 *
+	 * @param      mixed $data VendorInfo object or XML attrib data (array)
+	 * @return     VendorInfo
+	 */
+	public function addVendorInfo($data)
+	{
+		if ($data instanceof VendorInfo) {
+			$vi = $data;
+			$this->vendorInfos[$vi->getType()] = $vi;
+			return $vi;
+		} else {
+			$vi = new VendorInfo();
+			$vi->loadFromXML($data);
+			return $this->addVendorInfo($vi); // call self w/ different param
+		}
+	}
+
+	/**
+	 * Gets the any associated VendorInfo object.
+	 * @return     VendorInfo
+	 */
+	public function getVendorInfoForType($type)
+	{
+		if (isset($this->vendorInfos[$type])) {
+			return $this->vendorInfos[$type];
+		} else {
+			// return an empty object
+			return new VendorInfo();
+		}
+	}
+
+	/**
+	 * String representation of the current object.
+	 *
+	 * This is an xml representation with the XML declaration removed.
+	 *
+	 * @see        appendXml()
+	 */
+	public function toString()
+	{
+		$doc = new DOMDocument('1.0');
+		$doc->formatOutput = true;
+		$this->appendXml($doc);
+		$xmlstr = $doc->saveXML();
+		return trim(preg_replace('/<\?xml.*?\?>/', '', $xmlstr));
+	}
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/database/reverse/BaseSchemaParser.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/database/reverse/BaseSchemaParser.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/database/reverse/BaseSchemaParser.php	(revision 19)
@@ -0,0 +1,198 @@
+<?php
+/*
+ *  $Id: BaseSchemaParser.php 989 2008-03-11 14:29:30Z heltem $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://propel.phpdb.org>.
+ */
+
+require_once 'propel/engine/database/reverse/SchemaParser.php';
+
+/**
+ * Base class for reverse engineering a database schema.
+ *
+ * @author     Hans Lellelid <hans@xmpl.org>
+ * @version    $Revision: 989 $
+ * @package    propel.engine.database.reverse
+ */
+abstract class BaseSchemaParser implements SchemaParser {
+
+	/**
+	 * The database connection.
+	 * @var        PDO
+	 */
+	protected $dbh;
+
+	/**
+	 * Stack of warnings.
+	 *
+	 * @var        array string[]
+	 */
+	protected $warnings = array();
+
+	/**
+	 * GeneratorConfig object holding build properties.
+	 *
+	 * @var        GeneratorConfig
+	 */
+	private $generatorConfig;
+
+	/**
+	 * Map native DB types to Propel types.
+	 * (Override in subclasses.)
+	 * @var        array
+	 */
+	protected $nativeToPropelTypeMap;
+
+	/**
+	 * Map to hold reverse type mapping (initialized on-demand).
+	 *
+	 * @var        array
+	 */
+	protected $reverseTypeMap;
+
+	/**
+	 * @param      PDO $dbh Optional database connection
+	 */
+	public function __construct(PDO $dbh = null)
+	{
+		if ($dbh) $this->setConnection($dbh);
+	}
+
+	/**
+	 * Sets the database connection.
+	 *
+	 * @param      PDO $dbh
+	 */
+	public function setConnection(PDO $dbh)
+	{
+		$this->dbh = $dbh;
+	}
+
+	/**
+	 * Gets the database connection.
+	 * @return     PDO
+	 */
+	public function getConnection()
+	{
+		return $this->dbh;
+	}
+
+	/**
+	 * Pushes a message onto the stack of warnings.
+	 *
+	 * @param      string $msg The warning message.
+	 */
+	protected function warn($msg)
+	{
+		$this->warnings[] = $msg;
+	}
+
+	/**
+	 * Gets array of warning messages.
+	 *
+	 * @return     array string[]
+	 */
+	public function getWarnings()
+	{
+		return $this->warnings;
+	}
+
+	/**
+	 * Sets the GeneratorConfig to use in the parsing.
+	 *
+	 * @param      GeneratorConfig $config
+	 */
+	public function setGeneratorConfig(GeneratorConfig $config)
+	{
+		$this->generatorConfig = $config;
+	}
+
+	/**
+	 * Gets the GeneratorConfig option.
+	 *
+	 * @return     GeneratorConfig
+	 */
+	public function getGeneratorConfig()
+	{
+		return $this->generatorConfig;
+	}
+
+	/**
+	 * Gets a specific propel (renamed) property from the build.
+	 *
+	 * @param      string $name
+	 * @return     mixed
+	 */
+	public function getBuildProperty($name)
+	{
+		if ($this->generatorConfig !== null) {
+			return $this->generatorConfig->getBuildProperty($name);
+		}
+		return null;
+	}
+
+	/**
+	 * Gets a type mapping from native type to Propel type.
+	 *
+	 * @return     array The mapped Propel type.
+	 */
+	abstract protected function getTypeMapping();
+
+	/**
+	 * Gets a mapped Propel type for specified native type.
+	 *
+	 * @param      string $nativeType
+	 * @return     string The mapped Propel type.
+	 */
+	protected function getMappedPropelType($nativeType)
+	{
+		if ($this->nativeToPropelTypeMap === null) {
+			$this->nativeToPropelTypeMap = $this->getTypeMapping();
+		}
+		if (isset($this->nativeToPropelTypeMap[$nativeType])) {
+			return $this->nativeToPropelTypeMap[$nativeType];
+		}
+		return null;
+	}
+
+	/**
+	 * Give a best guess at the native type.
+	 *
+	 * @param      string $propelType
+	 * @return     string The native SQL type that best matches the specified Propel type.
+	 */
+	protected function getMappedNativeType($propelType)
+	{
+		if ($this->reverseTypeMap === null) {
+			$this->reverseTypeMap = array_flip($this->getTypeMapping());
+		}
+		return isset($this->reverseTypeMap[$propelType]) ? $this->reverseTypeMap[$propelType] : null;
+	}
+
+	/**
+	 * Gets a new VendorInfo object for this platform with specified params.
+	 *
+	 * @param      array $params
+	 */
+	protected function getNewVendorInfoObject(array $params)
+	{
+		$type = $this->getGeneratorConfig()->getConfiguredPlatform()->getDatabaseType();
+		$vi = new VendorInfo($type);
+		$vi->setParameters($params);
+		return $vi;
+	}
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/database/reverse/SchemaParser.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/database/reverse/SchemaParser.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/database/reverse/SchemaParser.php	(revision 19)
@@ -0,0 +1,71 @@
+<?php
+/*
+ *  $Id: SchemaParser.php 989 2008-03-11 14:29:30Z heltem $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://propel.phpdb.org>.
+ */
+
+/**
+ * Interface for reverse engineering schema parsers.
+ *
+ * @author     Hans Lellelid <hans@xmpl.org>
+ * @version    $Revision: 989 $
+ * @package    propel.engine.database.reverse
+ */
+interface SchemaParser {
+
+	/**
+	 * Gets the database connection.
+	 * @return     PDO
+	 */
+	public function getConnection();
+
+	/**
+	 * Sets the database connection.
+	 *
+	 * @param      PDO $dbh
+	 */
+	public function setConnection(PDO $dbh);
+
+	/**
+	 * Sets the GeneratorConfig to use in the parsing.
+	 *
+	 * @param      GeneratorConfig $config
+	 */
+	public function setGeneratorConfig(GeneratorConfig $config);
+
+	/**
+	 * Gets a specific propel (renamed) property from the build.
+	 *
+	 * @param      string $name
+	 * @return     mixed
+	 */
+	public function getBuildProperty($name);
+
+	/**
+	 * Gets array of warning messages.
+	 * @return     array string[]
+	 */
+	public function getWarnings();
+
+	/**
+	 * Parse the schema and populate passed-in Database model object.
+	 *
+	 * @param      Database $database
+	 */
+	public function parse(Database $database);
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/database/reverse/mssql/MssqlSchemaParser.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/database/reverse/mssql/MssqlSchemaParser.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/database/reverse/mssql/MssqlSchemaParser.php	(revision 19)
@@ -0,0 +1,248 @@
+<?php
+/*
+ *  $Id: MssqlSchemaParser.php 989 2008-03-11 14:29:30Z heltem $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://propel.phpdb.org>.
+ */
+
+require_once 'propel/engine/database/reverse/BaseSchemaParser.php';
+
+/**
+ * Microsoft SQL Server database schema parser.
+ *
+ * @author     Hans Lellelid <hans@xmpl.org>
+ * @version    $Revision: 989 $
+ * @package    propel.engine.database.reverse.mssql
+ */
+class MssqlSchemaParser extends BaseSchemaParser {
+
+	/**
+	 * Map MSSQL native types to Propel types.
+	 * @var        array
+	 */
+	private static $mssqlTypeMap = array(
+		"binary" => CreoleTypes::BINARY,
+		"bit" => PropelTypes::BOOLEAN,
+		"char" => PropelTypes::CHAR,
+		"datetime" => PropelTypes::TIMESTAMP,
+		"decimal() identity"  => PropelTypes::DECIMAL,
+		"decimal"  => PropelTypes::DECIMAL,
+		"image" => PropelTypes::LONGVARBINARY,
+		"int" => PropelTypes::INTEGER,
+		"int identity" => PropelTypes::INTEGER,
+		"integer" => PropelTypes::INTEGER,
+		"money" => PropelTypes::DECIMAL,
+		"nchar" => PropelTypes::CHAR,
+		"ntext" => PropelTypes::LONGVARCHAR,
+		"numeric() identity" => PropelTypes::NUMERIC,
+		"numeric" => PropelTypes::NUMERIC,
+		"nvarchar" => PropelTypes::VARCHAR,
+		"real" => PropelTypes::REAL,
+		"float" => PropelTypes::FLOAT,
+		"smalldatetime" => PropelTypes::TIMESTAMP,
+		"smallint" => PropelTypes::SMALLINT,
+		"smallint identity" => PropelTypes::SMALLINT,
+		"smallmoney" => PropelTypes::DECIMAL,
+		"sysname" => PropelTypes::VARCHAR,
+		"text" => PropelTypes::LONGVARCHAR,
+		"timestamp" => PropelTypes::BINARY,
+		"tinyint identity" => PropelTypes::TINYINT,
+		"tinyint" => PropelTypes::TINYINT,
+		"uniqueidentifier" => PropelTypes::CHAR,
+		"varbinary" => PropelTypes::VARBINARY,
+		"varchar" => PropelTypes::VARCHAR,
+		"uniqueidentifier" => PropelTypes::CHAR,
+	// SQL Server 2000 only
+		"bigint identity" => PropelTypes::BIGINT,
+		"bigint" => PropelTypes::BIGINT,
+		"sql_variant" => PropelTypes::VARCHAR,
+	);
+
+	/**
+	 * Gets a type mapping from native types to Propel types
+	 *
+	 * @return     array
+	 */
+	protected function getTypeMapping()
+	{
+		return self::$mssqlTypeMap;
+	}
+
+	/**
+	 *
+	 */
+	public function parse(Database $database)
+	{
+		$stmt = $this->dbh->query("SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_TYPE = 'BASE TABLE' AND TABLE_NAME <> 'dtproperties'");
+
+		// First load the tables (important that this happen before filling out details of tables)
+		$tables = array();
+		while ($row = $stmt->fetch(PDO::FETCH_NUM)) {
+			$name = $row[0];
+			$table = new Table($name);
+			$database->addTable($table);
+			$tables[] = $table;
+		}
+
+		// Now populate only columns.
+		foreach ($tables as $table) {
+			$this->addColumns($table);
+		}
+
+		// Now add indexes and constraints.
+		foreach ($tables as $table) {
+			$this->addForeignKeys($table);
+			$this->addIndexes($table);
+			$this->addPrimaryKey($table);
+		}
+
+	}
+
+
+	/**
+	 * Adds Columns to the specified table.
+	 *
+	 * @param      Table $table The Table model class to add columns to.
+	 */
+	protected function addColumns(Table $table)
+	{
+		$stmt = $this->dbh->query("sp_columns '" . $table->getName() . "'");
+
+		while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
+
+			$name = $row['COLUMN_NAME'];
+			$type = $row['TYPE_NAME'];
+			$size = $row['LENGTH'];
+			$is_nullable = $row['NULLABLE'];
+			$default = $row['COLUMN_DEF'];
+			$precision = $row['PRECISION'];
+			$scale = $row['SCALE'];
+			$autoincrement = false;
+			if (strtolower($type) == "int identity") {
+				$autoincrement = true;
+			}
+
+			$propelType = $this->getMappedPropelType($type);
+			if (!$propelType) {
+				$propelType = Column::DEFAULT_TYPE;
+				$this->warn("Column [" . $table->getName() . "." . $name. "] has a column type (".$type.") that Propel does not support.");
+			}
+
+			$column = new Column($name);
+			$column->setTable($table);
+			$column->setDomainForType($propelType);
+			// We may want to provide an option to include this:
+			// $column->getDomain()->replaceSqlType($type);
+			$column->getDomain()->replaceSize($size);
+			$column->getDomain()->replaceScale($scale);
+			if ($default !== null) {
+				$column->getDomain()->setDefaultValue(new ColumnDefaultValue($default, ColumnDefaultValue::TYPE_VALUE));
+			}
+			$column->setAutoIncrement($autoincrement);
+			$column->setNotNull(!$is_nullable);
+
+			$table->addColumn($column);
+		}
+
+
+	} // addColumn()
+
+	/**
+	 * Load foreign keys for this table.
+	 */
+	protected function addForeignKeys(Table $table)
+	{
+		$database = $table->getDatabase();
+
+		$stmt = $this->dbh->query("SELECT ccu1.TABLE_NAME, ccu1.COLUMN_NAME, ccu2.TABLE_NAME AS FK_TABLE_NAME, ccu2.COLUMN_NAME AS FK_COLUMN_NAME
+									FROM INFORMATION_SCHEMA.CONSTRAINT_COLUMN_USAGE ccu1 INNER JOIN
+								      INFORMATION_SCHEMA.TABLE_CONSTRAINTS tc1 ON tc1.CONSTRAINT_NAME = ccu1.CONSTRAINT_NAME AND
+								      CONSTRAINT_TYPE = 'Foreign Key' INNER JOIN
+								      INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS rc1 ON rc1.CONSTRAINT_NAME = tc1.CONSTRAINT_NAME INNER JOIN
+								      INFORMATION_SCHEMA.CONSTRAINT_COLUMN_USAGE ccu2 ON ccu2.CONSTRAINT_NAME = rc1.UNIQUE_CONSTRAINT_NAME
+									WHERE (ccu1.table_name = '".$table->getName()."')");
+
+		$row = $stmt->fetch(PDO::FETCH_NUM);
+
+		$foreignKeys = array(); // local store to avoid duplicates
+		while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
+
+			$lcol = $row['COLUMN_NAME'];
+			$ftbl = $row['FK_TABLE_NAME'];
+			$fcol = $row['FK_COLUMN_NAME'];
+
+
+			$foreignTable = $database->getTable($ftbl);
+			$foreignColumn = $foreignTable->getColumn($fcol);
+			$localColumn   = $table->getColumn($lcol);
+
+			if (!isset($foreignKeys[$name])) {
+				$fk = new ForeignKey($name);
+				$fk->setForeignTableName($foreignTable->getName());
+				//$fk->setOnDelete($fkactions['ON DELETE']);
+				//$fk->setOnUpdate($fkactions['ON UPDATE']);
+				$table->addForeignKey($fk);
+				$foreignKeys[$name] = $fk;
+			}
+			$foreignKeys[$name]->addReference($localColumn, $foreignColumn);
+		}
+
+	}
+
+	/**
+	 * Load indexes for this table
+	 */
+	protected function addIndexes(Table $table)
+	{
+		$stmt = $this->dbh->query("sp_indexes_rowset " . $table->getName());
+
+		$indexes = array();
+		while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
+			$colName = $row["COLUMN_NAME"];
+			$name = $row['INDEX_NAME'];
+
+			// FIXME -- Add UNIQUE support
+			if (!isset($indexes[$name])) {
+				$indexes[$name] = new Index($name);
+				$table->addIndex($indexes[$name]);
+			}
+
+			$indexes[$name]->addColumn($table->getColumn($colName));
+		}
+	}
+
+	/**
+	 * Loads the primary key for this table.
+	 */
+	protected function addPrimaryKey(Table $table)
+	{
+		$stmt = $this->dbh->query("SELECT COLUMN_NAME
+						FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS
+								INNER JOIN INFORMATION_SCHEMA.CONSTRAINT_COLUMN_USAGE ON
+					  INFORMATION_SCHEMA.TABLE_CONSTRAINTS.CONSTRAINT_NAME = INFORMATION_SCHEMA.CONSTRAINT_COLUMN_USAGE.constraint_name
+						WHERE     (INFORMATION_SCHEMA.TABLE_CONSTRAINTS.CONSTRAINT_TYPE = 'PRIMARY KEY') AND
+					  (INFORMATION_SCHEMA.TABLE_CONSTRAINTS.TABLE_NAME = '".$table->getName()."')");
+
+		// Loop through the returned results, grouping the same key_name together
+		// adding each column for that key.
+		while ($row = $stmt->fetch(PDO::FETCH_NUM)) {
+			$name = $row[0];
+			$table->getColumn($name)->setPrimaryKey(true);
+		}
+	}
+
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/database/reverse/mysql/MysqlSchemaParser.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/database/reverse/mysql/MysqlSchemaParser.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/database/reverse/mysql/MysqlSchemaParser.php	(revision 19)
@@ -0,0 +1,337 @@
+<?php
+/*
+ *  $Id: MysqlSchemaParser.php 1010 2008-03-19 23:08:08Z hans $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://propel.phpdb.org>.
+ */
+
+require_once 'propel/engine/database/reverse/BaseSchemaParser.php';
+
+/**
+ * Mysql database schema parser.
+ *
+ * @author     Hans Lellelid <hans@xmpl.org>
+ * @version    $Revision: 1010 $
+ * @package    propel.engine.database.reverse.mysql
+ */
+class MysqlSchemaParser extends BaseSchemaParser {
+
+	/**
+	 * @var        boolean
+	 */
+	private $addVendorInfo = false;
+
+	/**
+	 * Map MySQL native types to Propel types.
+	 * @var        array
+	 */
+	private static $mysqlTypeMap = array(
+		'tinyint' => PropelTypes::TINYINT,
+		'smallint' => PropelTypes::SMALLINT,
+		'mediumint' => PropelTypes::SMALLINT,
+		'int' => PropelTypes::INTEGER,
+		'integer' => PropelTypes::INTEGER,
+		'bigint' => PropelTypes::BIGINT,
+		'int24' => PropelTypes::BIGINT,
+		'real' => PropelTypes::REAL,
+		'float' => PropelTypes::FLOAT,
+		'decimal' => PropelTypes::DECIMAL,
+		'numeric' => PropelTypes::NUMERIC,
+		'double' => PropelTypes::DOUBLE,
+		'char' => PropelTypes::CHAR,
+		'varchar' => PropelTypes::VARCHAR,
+		'date' => PropelTypes::DATE,
+		'time' => PropelTypes::TIME,
+		'year' => PropelTypes::INTEGER,
+		'datetime' => PropelTypes::TIMESTAMP,
+		'timestamp' => PropelTypes::TIMESTAMP,
+		'tinyblob' => PropelTypes::BINARY,
+		'blob' => PropelTypes::BLOB,
+		'mediumblob' => PropelTypes::BLOB,
+		'longblob' => PropelTypes::BLOB,
+		'longtext' => PropelTypes::CLOB,
+		'tinytext' => PropelTypes::VARCHAR,
+		'mediumtext' => PropelTypes::LONGVARCHAR,
+		'text' => PropelTypes::LONGVARCHAR,
+		'enum' => PropelTypes::CHAR,
+		'set' => PropelTypes::CHAR,
+	);
+
+	/**
+	 * Gets a type mapping from native types to Propel types
+	 *
+	 * @return     array
+	 */
+	protected function getTypeMapping()
+	{
+		return self::$mysqlTypeMap;
+	}
+
+	/**
+	 *
+	 */
+	public function parse(Database $database)
+	{
+		$this->addVendorInfo = $this->getGeneratorConfig()->getBuildProperty('addVendorInfo');
+
+		$stmt = $this->dbh->query("SHOW TABLES");
+
+		// First load the tables (important that this happen before filling out details of tables)
+		$tables = array();
+		while ($row = $stmt->fetch(PDO::FETCH_NUM)) {
+			$name = $row[0];
+			$table = new Table($name);
+			$database->addTable($table);
+			$tables[] = $table;
+		}
+
+		// Now populate only columns.
+		foreach ($tables as $table) {
+			$this->addColumns($table);
+		}
+
+		// Now add indexes and constraints.
+		foreach ($tables as $table) {
+			$this->addForeignKeys($table);
+			$this->addIndexes($table);
+			$this->addPrimaryKey($table);
+			if ($this->addVendorInfo) {
+				$this->addTableVendorInfo($table);
+			}
+		}
+	}
+
+
+	/**
+	 * Adds Columns to the specified table.
+	 *
+	 * @param      Table $table The Table model class to add columns to.
+	 */
+	protected function addColumns(Table $table)
+	{
+		$stmt = $this->dbh->query("SHOW COLUMNS FROM `" . $table->getName() . "`");
+
+		while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
+
+			$name = $row['Field'];
+			$is_nullable = ($row['Null'] == 'YES');
+			$autoincrement = (strpos($row['Extra'], 'auto_increment') !== false);
+			$size = null;
+			$precision = null;
+			$scale = null;
+
+			if (preg_match('/^(\w+)[\(]?([\d,]*)[\)]?( |$)/', $row['Type'], $matches)) {
+				//            colname[1]   size/precision[2]
+				$nativeType = $matches[1];
+				if ($matches[2]) {
+					if ( ($cpos = strpos($matches[2], ',')) !== false) {
+						$size = (int) substr($matches[2], 0, $cpos);
+						$precision = $size;
+						$scale = (int) substr($matches[2], $cpos + 1);
+					} else {
+						$size = (int) $matches[2];
+					}
+				}
+			} elseif (preg_match('/^(\w+)\(/', $row['Type'], $matches)) {
+				$nativeType = $matches[1];
+			} else {
+				$nativeType = $row['Type'];
+			}
+
+			//BLOBs can't have any default values in MySQL
+			$default = preg_match('~blob|text~', $nativeType) ? null : $row['Default'];
+
+			$propelType = $this->getMappedPropelType($nativeType);
+			if (!$propelType) {
+				$propelType = Column::DEFAULT_TYPE;
+				$this->warn("Column [" . $table->getName() . "." . $name. "] has a column type (".$nativeType.") that Propel does not support.");
+			}
+
+			$column = new Column($name);
+			$column->setTable($table);
+			$column->setDomainForType($propelType);
+			// We may want to provide an option to include this:
+			// $column->getDomain()->replaceSqlType($type);
+			$column->getDomain()->replaceSize($size);
+			$column->getDomain()->replaceScale($scale);
+			if ($default !== null) {
+				$column->getDomain()->setDefaultValue(new ColumnDefaultValue($default, ColumnDefaultValue::TYPE_VALUE));
+			}
+			$column->setAutoIncrement($autoincrement);
+			$column->setNotNull(!$is_nullable);
+
+			if ($this->addVendorInfo) {
+				$vi = $this->getNewVendorInfoObject($row);
+				$column->addVendorInfo($vi);
+			}
+
+			$table->addColumn($column);
+		}
+
+
+	} // addColumn()
+
+	/**
+	 * Load foreign keys for this table.
+	 */
+	protected function addForeignKeys(Table $table)
+	{
+		$database = $table->getDatabase();
+
+		$stmt = $this->dbh->query("SHOW CREATE TABLE `" . $table->getName(). "`");
+		$row = $stmt->fetch(PDO::FETCH_NUM);
+
+		$foreignKeys = array(); // local store to avoid duplicates
+
+		// Get the information on all the foreign keys
+		$regEx = '/CONSTRAINT `([^`]+)` FOREIGN KEY \((.+)\) REFERENCES `([^`]*)` \((.+)\)(.*)/';
+		if (preg_match_all($regEx,$row[1],$matches)) {
+			$tmpArray = array_keys($matches[0]);
+			foreach ($tmpArray as $curKey) {
+				$name = $matches[1][$curKey];
+				$rawlcol = $matches[2][$curKey];
+				$ftbl = $matches[3][$curKey];
+				$rawfcol = $matches[4][$curKey];
+				$fkey = $matches[5][$curKey];
+				
+				$lcols = array();
+				foreach(preg_split('/`, `/', $rawlcol) as $piece) {
+					$lcols[] = trim($piece, '` ');
+				}
+				
+				$fcols = array();
+				foreach(preg_split('/`, `/', $rawfcol) as $piece) {
+					$fcols[] = trim($piece, '` ');
+				}
+				
+				//typical for mysql is RESTRICT
+				$fkactions = array(
+					'ON DELETE'	=> ForeignKey::RESTRICT,
+					'ON UPDATE'	=> ForeignKey::RESTRICT,
+				);
+
+				if ($fkey) {
+					//split foreign key information -> search for ON DELETE and afterwords for ON UPDATE action
+					foreach (array_keys($fkactions) as $fkaction) {
+						$result = NULL;
+						preg_match('/' . $fkaction . ' (' . ForeignKey::CASCADE . '|' . ForeignKey::SETNULL . ')/', $fkey, $result);
+						if ($result && is_array($result) && isset($result[1])) {
+							$fkactions[$fkaction] = $result[1];
+						}
+					}
+				}
+				
+				$localColumns = array();
+				$foreignColumns = array();
+				
+				$foreignTable = $database->getTable($ftbl);
+				
+				foreach($fcols as $fcol) {
+					$foreignColumns[] = $foreignTable->getColumn($fcol);
+				}
+				foreach($lcols as $lcol) {
+					$localColumns[] = $table->getColumn($lcol);
+				}
+
+				if (!isset($foreignKeys[$name])) {
+					$fk = new ForeignKey($name);
+					$fk->setForeignTableName($foreignTable->getName());
+					$fk->setOnDelete($fkactions['ON DELETE']);
+					$fk->setOnUpdate($fkactions['ON UPDATE']);
+					$table->addForeignKey($fk);
+					$foreignKeys[$name] = $fk;
+				}
+				
+				for($i=0; $i < count($localColumns); $i++) {
+					$foreignKeys[$name]->addReference($localColumns[$i], $foreignColumns[$i]);
+				}
+				
+			}
+
+		}
+
+	}
+
+	/**
+	 * Load indexes for this table
+	 */
+	protected function addIndexes(Table $table)
+	{
+		$stmt = $this->dbh->query("SHOW INDEX FROM `" . $table->getName() . "`");
+
+		// Loop through the returned results, grouping the same key_name together
+		// adding each column for that key.
+
+		$indexes = array();
+		while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
+			$colName = $row["Column_name"];
+			$name = $row["Key_name"];
+
+			if ($name == "PRIMARY") {
+				continue;
+			}
+
+			if (!isset($indexes[$name])) {
+				$isUnique = ($row["Non_unique"] == 0);
+				if ($isUnique) {
+					$indexes[$name] = new Unique($name);
+				} else {
+					$indexes[$name] = new Index($name);
+				}
+				if ($this->addVendorInfo) {
+					$vi = $this->getNewVendorInfoObject($row);
+					$indexes[$name]->addVendorInfo($vi);
+				}
+				$table->addIndex($indexes[$name]);
+			}
+
+			$indexes[$name]->addColumn($table->getColumn($colName));
+		}
+	}
+
+	/**
+	 * Loads the primary key for this table.
+	 */
+	protected function addPrimaryKey(Table $table)
+	{
+		$stmt = $this->dbh->query("SHOW KEYS FROM `" . $table->getName() . "`");
+
+		// Loop through the returned results, grouping the same key_name together
+		// adding each column for that key.
+		while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
+			// Skip any non-primary keys.
+			if ($row['Key_name'] !== 'PRIMARY') {
+				continue;
+			}
+			$name = $row["Column_name"];
+			$table->getColumn($name)->setPrimaryKey(true);
+		}
+	}
+
+	/**
+	 * Adds vendor-specific info for table.
+	 *
+	 * @param      Table $table
+	 */
+	protected function addTableVendorInfo(Table $table)
+	{
+		$stmt = $this->dbh->query("SHOW TABLE STATUS LIKE '" . $table->getName() . "'");
+		$row = $stmt->fetch(PDO::FETCH_ASSOC);
+		$vi = $this->getNewVendorInfoObject($row);
+		$table->addVendorInfo($vi);
+	}
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/database/reverse/pgsql/PgsqlSchemaParser.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/database/reverse/pgsql/PgsqlSchemaParser.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/database/reverse/pgsql/PgsqlSchemaParser.php	(revision 19)
@@ -0,0 +1,543 @@
+<?php
+/*
+ *  $Id: PgsqlSchemaParser.php 1051 2008-05-28 09:27:01Z hans $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://propel.phpdb.org>.
+ */
+
+require_once 'propel/engine/database/reverse/BaseSchemaParser.php';
+
+/**
+ * Postgresql database schema parser.
+ *
+ * @author     Hans Lellelid <hans@xmpl.org>
+ * @version    $Revision: 1051 $
+ * @package    propel.engine.database.reverse.pgsql
+ */
+class PgsqlSchemaParser extends BaseSchemaParser {
+
+	/**
+	 * Map PostgreSQL native types to Propel types.
+	 * @var        array
+	 */
+	 /** Map MySQL native types to Creole (JDBC) types. */
+	private static $pgsqlTypeMap = array(
+				'bool' => PropelTypes::BOOLEAN,
+				'boolean' => PropelTypes::BOOLEAN,
+				'tinyint' => PropelTypes::TINYINT,
+				'smallint' => PropelTypes::SMALLINT,
+				'mediumint' => PropelTypes::SMALLINT,
+				'int' => PropelTypes::INTEGER,
+				'int4' => PropelTypes::INTEGER,
+				'integer' => PropelTypes::INTEGER,
+				'int8' => PropelTypes::BIGINT,
+				'bigint' => PropelTypes::BIGINT,
+				'int24' => PropelTypes::BIGINT,
+				'real' => PropelTypes::REAL,
+				'float' => PropelTypes::FLOAT,
+				'decimal' => PropelTypes::DECIMAL,
+				'numeric' => PropelTypes::NUMERIC,
+				'double' => PropelTypes::DOUBLE,
+				'char' => PropelTypes::CHAR,
+				'varchar' => PropelTypes::VARCHAR,
+				'date' => PropelTypes::DATE,
+				'time' => PropelTypes::TIME,
+				'timetz' => PropelTypes::TIME,
+				//'year' => PropelTypes::YEAR,  PropelTypes::YEAR does not exist... does this need to be mapped to a different propel type?
+				'datetime' => PropelTypes::TIMESTAMP,
+				'timestamp' => PropelTypes::TIMESTAMP,
+				'timestamptz' => PropelTypes::TIMESTAMP,
+				'bytea' => PropelTypes::BLOB,
+				'text' => PropelTypes::LONGVARCHAR,
+	);
+
+	/**
+	 * Gets a type mapping from native types to Propel types
+	 *
+	 * @return     array
+	 */
+	protected function getTypeMapping()
+	{
+		return self::$pgsqlTypeMap;
+	}
+
+	/**
+	 *
+	 */
+	public function parse(Database $database)
+	{
+		$stmt = $this->dbh->query("SELECT version() as ver");
+		$nativeVersion = $stmt->fetchColumn();
+
+		if (!$nativeVersion) {
+			throw new EngineException("Failed to get database version");
+		}
+
+		$arrVersion = sscanf ($nativeVersion, '%*s %d.%d');
+		$version = sprintf ("%d.%d", $arrVersion[0], $arrVersion[1]);
+
+		// Clean up
+		$stmt = null;
+
+		$stmt = $this->dbh->query("SELECT c.oid,
+								    case when n.nspname='public' then c.relname else n.nspname||'.'||c.relname end as relname
+								    FROM pg_class c join pg_namespace n on (c.relnamespace=n.oid)
+								    WHERE c.relkind = 'r'
+								      AND n.nspname NOT IN ('information_schema','pg_catalog')
+								      AND n.nspname NOT LIKE 'pg_temp%'
+								      AND n.nspname NOT LIKE 'pg_toast%'
+								    ORDER BY relname");
+
+		$tableWraps = array();
+
+		// First load the tables (important that this happen before filling out details of tables)
+		while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
+			$name = $row['relname'];
+			$oid = $row['oid'];
+			$table = new Table($name);
+			$database->addTable($table);
+
+			// Create a wrapper to hold these tables and their associated OID
+			$wrap = new stdClass;
+			$wrap->table = $table;
+			$wrap->oid = $oid;
+			$tableWraps[] = $wrap;
+		}
+
+		// Now populate only columns.
+		foreach ($tableWraps as $wrap) {
+			$this->addColumns($wrap->table, $wrap->oid, $version);
+		}
+
+		// Now add indexes and constraints.
+		foreach ($tableWraps as $wrap) {
+			$this->addForeignKeys($wrap->table, $wrap->oid, $version);
+			$this->addIndexes($wrap->table, $wrap->oid, $version);
+			$this->addPrimaryKey($wrap->table, $wrap->oid, $version);
+		}
+
+		// TODO - Handle Sequences ...
+
+	}
+
+
+	 /**
+	 * Adds Columns to the specified table.
+	 *
+	 * @param      Table $table The Table model class to add columns to.
+	 * @param      int $oid The table OID
+	 * @param      string $version The database version.
+	 */
+	protected function addColumns(Table $table, $oid, $version)
+	{
+
+		// Get the columns, types, etc.
+		// Based on code from pgAdmin3 (http://www.pgadmin.org/)
+		$stmt = $this->dbh->prepare("SELECT
+								        att.attname,
+								        att.atttypmod,
+								        att.atthasdef,
+								        att.attnotnull,
+								        def.adsrc,
+								        CASE WHEN att.attndims > 0 THEN 1 ELSE 0 END AS isarray,
+								        CASE
+								            WHEN ty.typname = 'bpchar'
+								                THEN 'char'
+								            WHEN ty.typname = '_bpchar'
+								                THEN '_char'
+								            ELSE
+								                ty.typname
+								        END AS typname,
+								        ty.typtype
+								    FROM pg_attribute att
+								        JOIN pg_type ty ON ty.oid=att.atttypid
+								        LEFT OUTER JOIN pg_attrdef def ON adrelid=att.attrelid AND adnum=att.attnum
+								    WHERE att.attrelid = ? AND att.attnum > 0
+								        AND att.attisdropped IS FALSE
+								    ORDER BY att.attnum");
+
+		$stmt->bindValue(1, $oid, PDO::PARAM_INT);
+		$stmt->execute();
+
+		while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
+
+			$size = null;
+			$precision = null;
+			$scale = null;
+
+			// Check to ensure that this column isn't an array data type
+			if (((int) $row['isarray']) === 1) {
+				throw new EngineException (sprintf ("Array datatypes are not currently supported [%s.%s]", $this->name, $row['attname']));
+			} // if (((int) $row['isarray']) === 1)
+
+			$name = $row['attname'];
+
+			// If they type is a domain, Process it
+			if (strtolower ($row['typtype']) == 'd') {
+				$arrDomain = $this->processDomain ($row['typname']);
+				$type = $arrDomain['type'];
+				$size = $arrDomain['length'];
+				$precision = $size;
+				$scale = $arrDomain['scale'];
+				$boolHasDefault = (strlen (trim ($row['atthasdef'])) > 0) ? $row['atthasdef'] : $arrDomain['hasdefault'];
+				$default = (strlen (trim ($row['adsrc'])) > 0) ? $row['adsrc'] : $arrDomain['default'];
+				$is_nullable = (strlen (trim ($row['attnotnull'])) > 0) ? $row['attnotnull'] : $arrDomain['notnull'];
+				$is_nullable = (($is_nullable == 't') ? false : true);
+			} else {
+				$type = $row['typname'];
+				$arrLengthPrecision = $this->processLengthScale ($row['atttypmod'], $type);
+				$size = $arrLengthPrecision['length'];
+				$precision = $size;
+				$scale = $arrLengthPrecision['scale'];
+				$boolHasDefault = $row['atthasdef'];
+				$default = $row['adsrc'];
+				$is_nullable = (($row['attnotnull'] == 't') ? false : true);
+			} // else (strtolower ($row['typtype']) == 'd')
+
+			$autoincrement = null;
+
+			// if column has a default
+			if (($boolHasDefault == 't') && (strlen (trim ($default)) > 0)) {
+				if (!preg_match('/^nextval\(/', $default)) {
+					$strDefault= preg_replace ('/::[\W\D]*/', '', $default);
+					$default = str_replace ("'", '', $strDefault);
+				} else {
+					$autoincrement = true;
+					$default = null;
+				}
+			} else {
+				$default = null;
+			}
+
+			$propelType = $this->getMappedPropelType($type);
+			if (!$propelType) {
+				$propelType = Column::DEFAULT_TYPE;
+				$this->warn("Column [" . $table->getName() . "." . $name. "] has a column type (".$type.") that Propel does not support.");
+			}
+
+			$column = new Column($name);
+			$column->setTable($table);
+			$column->setDomainForType($propelType);
+			// We may want to provide an option to include this:
+			// $column->getDomain()->replaceSqlType($type);
+			$column->getDomain()->replaceSize($size);
+			$column->getDomain()->replaceScale($scale);
+			if ($default !== null) {
+				$column->getDomain()->setDefaultValue(new ColumnDefaultValue($default, ColumnDefaultValue::TYPE_VALUE));
+			}
+			$column->setAutoIncrement($autoincrement);
+			$column->setNotNull(!$is_nullable);
+
+			$table->addColumn($column);
+		}
+
+
+	} // addColumn()
+
+	private function processLengthScale($intTypmod, $strName)
+	{
+		// Define the return array
+		$arrRetVal = array ('length'=>null, 'scale'=>null);
+
+		// Some datatypes don't have a Typmod
+		if ($intTypmod == -1)
+		{
+			return $arrRetVal;
+		} // if ($intTypmod == -1)
+
+		// Numeric Datatype?
+		if ($strName == $this->getMappedNativeType(PropelTypes::NUMERIC)) {
+			$intLen = ($intTypmod - 4) >> 16;
+			$intPrec = ($intTypmod - 4) & 0xffff;
+			$intLen = sprintf ("%ld", $intLen);
+			if ($intPrec)
+			{
+				$intPrec = sprintf ("%ld", $intPrec);
+			} // if ($intPrec)
+			$arrRetVal['length'] = $intLen;
+			$arrRetVal['scale'] = $intPrec;
+		} // if ($strName == $this->getMappedNativeType(PropelTypes::NUMERIC))
+		elseif ($strName == $this->getMappedNativeType(PropelTypes::TIME) || $strName == 'timetz'
+			|| $strName == $this->getMappedNativeType(PropelTypes::TIMESTAMP) || $strName == 'timestamptz'
+			|| $strName == 'interval' || $strName == 'bit')
+		{
+			$arrRetVal['length'] = sprintf ("%ld", $intTypmod);
+		} // elseif (TIME, TIMESTAMP, INTERVAL, BIT)
+		else
+		{
+			$arrRetVal['length'] = sprintf ("%ld", ($intTypmod - 4));
+		} // else
+		return $arrRetVal;
+	} // private function processLengthScale ($intTypmod, $strName)
+
+	private function processDomain($strDomain)
+	{
+		if (strlen(trim ($strDomain)) < 1) {
+			throw new EngineException ("Invalid domain name [" . $strDomain . "]");
+		}
+
+		$stmt = $this->dbh->prepare("SELECT
+								        d.typname as domname,
+								        b.typname as basetype,
+								        d.typlen,
+								        d.typtypmod,
+								        d.typnotnull,
+								        d.typdefault
+								    FROM pg_type d
+								        INNER JOIN pg_type b ON b.oid = CASE WHEN d.typndims > 0 then d.typelem ELSE d.typbasetype END
+								    WHERE
+								        d.typtype = 'd'
+								        AND d.typname = ?
+								    ORDER BY d.typname");
+		$stmt->bindValue(1, $strDomain);
+		$stmt->execute();
+
+		$row = $stmt->fetch(PDO::FETCH_ASSOC);
+		if (!$row) {
+			throw new EngineException ("Domain [" . $strDomain . "] not found.");
+		}
+
+		$arrDomain = array ();
+		$arrDomain['type'] = $row['basetype'];
+		$arrLengthPrecision = $this->processLengthScale($row['typtypmod'], $row['basetype']);
+		$arrDomain['length'] = $arrLengthPrecision['length'];
+		$arrDomain['scale'] = $arrLengthPrecision['scale'];
+		$arrDomain['notnull'] = $row['typnotnull'];
+		$arrDomain['default'] = $row['typdefault'];
+		$arrDomain['hasdefault'] = (strlen (trim ($row['typdefault'])) > 0) ? 't' : 'f';
+
+		$stmt = null; // cleanup
+		return $arrDomain;
+	} // private function processDomain($strDomain)
+
+	/**
+	 * Load foreign keys for this table.
+	 */
+	protected function addForeignKeys(Table $table, $oid, $version)
+	{
+		$database = $table->getDatabase();
+		$stmt = $this->dbh->prepare("SELECT
+								          conname,
+								          confupdtype,
+								          confdeltype,
+								          cl.relname as fktab,
+								          a2.attname as fkcol,
+								          cr.relname as reftab,
+								          a1.attname as refcol
+								    FROM pg_constraint ct
+								         JOIN pg_class cl ON cl.oid=conrelid
+								         JOIN pg_class cr ON cr.oid=confrelid
+								         LEFT JOIN pg_catalog.pg_attribute a1 ON a1.attrelid = ct.confrelid
+								         LEFT JOIN pg_catalog.pg_attribute a2 ON a2.attrelid = ct.conrelid
+								    WHERE
+								         contype='f'
+								         AND conrelid = ?
+								         AND a2.attnum = ct.conkey[1]
+								         AND a1.attnum = ct.confkey[1]
+								    ORDER BY conname");
+		$stmt->bindValue(1, $oid);
+		$stmt->execute();
+
+		$foreignKeys = array(); // local store to avoid duplicates
+
+		while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
+
+			$name = $row['conname'];
+			$local_table = $row['fktab'];
+			$local_column = $row['fkcol'];
+			$foreign_table = $row['reftab'];
+			$foreign_column = $row['refcol'];
+
+			// On Update
+			switch ($row['confupdtype']) {
+			  case 'c':
+				$onupdate = ForeignKey::CASCADE; break;
+			  case 'd':
+				$onupdate = ForeignKey::SETDEFAULT; break;
+			  case 'n':
+				$onupdate = ForeignKey::SETNULL; break;
+			  case 'r':
+				$onupdate = ForeignKey::RESTRICT; break;
+			  default:
+			  case 'a':
+				//NOACTION is the postgresql default
+				$onupdate = ForeignKey::NONE; break;
+			}
+			// On Delete
+			switch ($row['confdeltype']) {
+			  case 'c':
+				$ondelete = ForeignKey::CASCADE; break;
+			  case 'd':
+				$ondelete = ForeignKey::SETDEFAULT; break;
+			  case 'n':
+				$ondelete = ForeignKey::SETNULL; break;
+			  case 'r':
+				$ondelete = ForeignKey::RESTRICT; break;
+			  default:
+			  case 'a':
+				//NOACTION is the postgresql default
+				$ondelete = ForeignKey::NONE; break;
+			}
+
+			$foreignTable = $database->getTable($foreign_table);
+			$foreignColumn = $foreignTable->getColumn($foreign_column);
+
+			$localTable   = $database->getTable($local_table);
+			$localColumn   = $localTable->getColumn($local_column);
+
+			if (!isset($foreignKeys[$name])) {
+				$fk = new ForeignKey($name);
+				$fk->setForeignTableName($foreignTable->getName());
+				$fk->setOnDelete($ondelete);
+				$fk->setOnUpdate($onupdate);
+				$table->addForeignKey($fk);
+				$foreignKeys[$name] = $fk;
+			}
+
+			$foreignKeys[$name]->addReference($localColumn, $foreignColumn);
+		}
+	}
+
+	/**
+	 * Load indexes for this table
+	 */
+	protected function addIndexes(Table $table, $oid, $version)
+	{
+		$stmt = $this->dbh->prepare("SELECT
+										DISTINCT ON(cls.relname)
+										cls.relname as idxname,
+								        indkey,
+								        indisunique
+								    FROM pg_index idx
+								         JOIN pg_class cls ON cls.oid=indexrelid
+								    WHERE indrelid = ? AND NOT indisprimary
+								    ORDER BY cls.relname");
+
+		$stmt->bindValue(1, $oid);
+		$stmt->execute();
+
+		$stmt2 = $this->dbh->prepare("SELECT a.attname
+										FROM pg_catalog.pg_class c JOIN pg_catalog.pg_attribute a ON a.attrelid = c.oid
+										WHERE c.oid = ? AND a.attnum = ? AND NOT a.attisdropped
+										ORDER BY a.attnum");
+
+		$indexes = array();
+
+		while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
+			$name = $row["idxname"];
+			$unique = ($row["indisunique"] == 't') ? true : false;
+			if (!isset($indexes[$name])) {
+				if ($unique) {
+					$indexes[$name] = new Unique($name);
+				} else {
+					$indexes[$name] = new Index($name);
+				}
+				$table->addIndex($indexes[$name]);
+			}
+
+			$arrColumns = explode (' ', $row['indkey']);
+			foreach ($arrColumns as $intColNum)
+			{
+			   	$stmt2->bindValue(1, $oid);
+			   	$stmt2->bindValue(2, $intColNum);
+			   	$stmt2->execute();
+
+				$row2 = $stmt2->fetch(PDO::FETCH_ASSOC);
+
+				$indexes[$name]->addColumn($table->getColumn($row2['attname']));
+
+			} // foreach ($arrColumns as $intColNum)
+
+		}
+
+	}
+
+	/**
+	 * Loads the primary key for this table.
+	 */
+	protected function addPrimaryKey(Table $table, $oid, $version)
+	{
+
+		$stmt = $this->dbh->prepare("SELECT
+										DISTINCT ON(cls.relname)
+										cls.relname as idxname,
+										indkey,
+										indisunique
+									FROM pg_index idx
+										JOIN pg_class cls ON cls.oid=indexrelid
+									WHERE indrelid = ? AND indisprimary
+									ORDER BY cls.relname");
+		$stmt->bindValue(1, $oid);
+		$stmt->execute();
+
+		// Loop through the returned results, grouping the same key_name together
+		// adding each column for that key.
+
+		while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
+			$arrColumns = explode (' ', $row['indkey']);
+			foreach ($arrColumns as $intColNum) {
+				$stmt2 = $this->dbh->prepare("SELECT a.attname
+												FROM pg_catalog.pg_class c JOIN pg_catalog.pg_attribute a ON a.attrelid = c.oid
+												WHERE c.oid = ? AND a.attnum = ? AND NOT a.attisdropped
+												ORDER BY a.attnum");
+				$stmt2->bindValue(1, $oid);
+				$stmt2->bindValue(2, $intColNum);
+				$stmt2->execute();
+
+				$row2 = $stmt2->fetch(PDO::FETCH_ASSOC);
+				$table->getColumn($row2['attname'])->setPrimaryKey(true);
+
+			} // foreach ($arrColumns as $intColNum)
+		}
+
+	}
+
+	/**
+	 * Adds the sequences for this database.
+	 *
+	 * @return     void
+	 * @throws     SQLException
+	 */
+	protected function addSequences(Database $database)
+	{
+		/*
+		-- WE DON'T HAVE ANY USE FOR THESE YET IN REVERSE ENGINEERING ...
+		$this->sequences = array();
+		$result = pg_query($this->conn->getResource(), "SELECT c.oid,
+								                        case when n.nspname='public' then c.relname else n.nspname||'.'||c.relname end as relname
+								                        FROM pg_class c join pg_namespace n on (c.relnamespace=n.oid)
+								                        WHERE c.relkind = 'S'
+								                          AND n.nspname NOT IN ('information_schema','pg_catalog')
+								                          AND n.nspname NOT LIKE 'pg_temp%'
+								                          AND n.nspname NOT LIKE 'pg_toast%'
+								                        ORDER BY relname");
+
+		if (!$result) {
+			throw new SQLException("Could not list sequences", pg_last_error($this->dblink));
+		}
+
+		while ($row = pg_fetch_assoc($result)) {
+			// FIXME -- decide what info we need for sequences & then create a SequenceInfo object (if needed)
+			$obj = new stdClass;
+			$obj->name = $row['relname'];
+			$obj->oid = $row['oid'];
+			$this->sequences[strtoupper($row['relname'])] = $obj;
+		}
+		*/
+	}
+
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/database/reverse/sqlite/SqliteSchemaParser.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/database/reverse/sqlite/SqliteSchemaParser.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/database/reverse/sqlite/SqliteSchemaParser.php	(revision 19)
@@ -0,0 +1,203 @@
+<?php
+/*
+ *  $Id: SqliteSchemaParser.php 989 2008-03-11 14:29:30Z heltem $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://propel.phpdb.org>.
+ */
+
+require_once 'propel/engine/database/reverse/BaseSchemaParser.php';
+
+/**
+ * SQLite database schema parser.
+ *
+ * @author     Hans Lellelid <hans@xmpl.org>
+ * @version    $Revision: 989 $
+ * @package    propel.engine.database.reverse.mysql
+ */
+class SqliteSchemaParser extends BaseSchemaParser {
+
+	/**
+	 * Map Sqlite native types to Propel types.
+	 *
+	 * There really aren't any SQLite native types, so we're just
+	 * using the MySQL ones here.
+	 *
+	 * @var        array
+	 */
+	private static $sqliteTypeMap = array(
+		'tinyint' => PropelTypes::TINYINT,
+		'smallint' => PropelTypes::SMALLINT,
+		'mediumint' => PropelTypes::SMALLINT,
+		'int' => PropelTypes::INTEGER,
+		'integer' => PropelTypes::INTEGER,
+		'bigint' => PropelTypes::BIGINT,
+		'int24' => PropelTypes::BIGINT,
+		'real' => PropelTypes::REAL,
+		'float' => PropelTypes::FLOAT,
+		'decimal' => PropelTypes::DECIMAL,
+		'numeric' => PropelTypes::NUMERIC,
+		'double' => PropelTypes::DOUBLE,
+		'char' => PropelTypes::CHAR,
+		'varchar' => PropelTypes::VARCHAR,
+		'date' => PropelTypes::DATE,
+		'time' => PropelTypes::TIME,
+		'year' => PropelTypes::INTEGER,
+		'datetime' => PropelTypes::TIMESTAMP,
+		'timestamp' => PropelTypes::TIMESTAMP,
+		'tinyblob' => PropelTypes::BINARY,
+		'blob' => PropelTypes::BLOB,
+		'mediumblob' => PropelTypes::BLOB,
+		'longblob' => PropelTypes::BLOB,
+		'longtext' => PropelTypes::CLOB,
+		'tinytext' => PropelTypes::VARCHAR,
+		'mediumtext' => PropelTypes::LONGVARCHAR,
+		'text' => PropelTypes::LONGVARCHAR,
+		'enum' => PropelTypes::CHAR,
+		'set' => PropelTypes::CHAR,
+	);
+
+	/**
+	 * Gets a type mapping from native types to Propel types
+	 *
+	 * @return     array
+	 */
+	protected function getTypeMapping()
+	{
+		return self::$sqliteTypeMap;
+	}
+
+	/**
+	 *
+	 */
+	public function parse(Database $database)
+	{
+		$stmt = $this->dbh->query("SELECT name FROM sqlite_master WHERE type='table' UNION ALL SELECT name FROM sqlite_temp_master WHERE type='table' ORDER BY name;");
+
+		// First load the tables (important that this happen before filling out details of tables)
+		$tables = array();
+		while ($row = $stmt->fetch(PDO::FETCH_NUM)) {
+			$name = $row[0];
+			$table = new Table($name);
+			$database->addTable($table);
+			$tables[] = $table;
+		}
+
+		// Now populate only columns.
+		foreach ($tables as $table) {
+			$this->addColumns($table);
+		}
+
+		// Now add indexes and constraints.
+		foreach ($tables as $table) {
+			$this->addIndexes($table);
+		}
+
+	}
+
+
+	/**
+	 * Adds Columns to the specified table.
+	 *
+	 * @param      Table $table The Table model class to add columns to.
+	 * @param      int $oid The table OID
+	 * @param      string $version The database version.
+	 */
+	protected function addColumns(Table $table)
+	{
+		$stmt = $this->dbh->query("PRAGMA table_info('" . $table->getName() . "')");
+
+		while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
+
+			$name = $row['name'];
+
+			$fulltype = $row['type'];
+			$size = null;
+			$precision = null;
+			$scale = null;
+
+			if (preg_match('/^([^\(]+)\(\s*(\d+)\s*,\s*(\d+)\s*\)$/', $fulltype, $matches)) {
+				$type = $matches[1];
+				$precision = $matches[2];
+				$scale = $matches[3]; // aka precision
+			} elseif (preg_match('/^([^\(]+)\(\s*(\d+)\s*\)$/', $fulltype, $matches)) {
+				$type = $matches[1];
+				$size = $matches[2];
+			} else {
+				$type = $fulltype;
+			}
+			// If column is primary key and of type INTEGER, it is auto increment
+			// See: http://sqlite.org/faq.html#q1
+			$autoincrement = ($row['pk'] == 1 && strtolower($type) == 'integer');
+			$not_null = $row['notnull'];
+			$default = $row['dflt_value'];
+
+
+			$propelType = $this->getMappedPropelType($type);
+			if (!$propelType) {
+				$propelType = Column::DEFAULT_TYPE;
+				$this->warn("Column [" . $table->getName() . "." . $name. "] has a column type (".$type.") that Propel does not support.");
+			}
+
+			$column = new Column($name);
+			$column->setTable($table);
+			$column->setDomainForType($propelType);
+			// We may want to provide an option to include this:
+			// $column->getDomain()->replaceSqlType($type);
+			$column->getDomain()->replaceSize($size);
+			$column->getDomain()->replaceScale($scale);
+			if ($default !== null) {
+				$column->getDomain()->setDefaultValue(new ColumnDefaultValue($default, ColumnDefaultValue::TYPE_VALUE));
+			}
+			$column->setAutoIncrement($autoincrement);
+			$column->setNotNull($not_null);
+
+
+			if (($row['pk'] == 1) || (strtolower($type) == 'integer')) {
+				$column->setPrimaryKey(true);
+			}
+
+			$table->addColumn($column);
+
+		}
+
+
+	} // addColumn()
+
+	/**
+	 * Load indexes for this table
+	 */
+	protected function addIndexes(Table $table)
+	{
+		$stmt = $this->dbh->query("PRAGMA index_list('" . $table->getName() . "')");
+
+		while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
+
+			$name = $row['name'];
+			$index = new Index($name);
+
+			$stmt2 = $this->dbh->query("PRAGMA index_info('".$name."')");
+			while ($row2 = $stmt2->fetch(PDO::FETCH_ASSOC)) {
+				$colname = $row2['name'];
+				$index->addColumn($table->getColumn($colname));
+			}
+
+			$table->addIndex($index);
+
+		}
+	}
+
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/database/transform/XmlToAppData.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/database/transform/XmlToAppData.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/database/transform/XmlToAppData.php	(revision 19)
@@ -0,0 +1,390 @@
+<?php
+
+/*
+ *  $Id: XmlToAppData.php 989 2008-03-11 14:29:30Z heltem $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://propel.phpdb.org>.
+ */
+
+include_once 'propel/engine/database/model/AppData.php';
+
+// Phing dependencies
+require_once 'phing/parser/AbstractHandler.php';
+include_once 'phing/system/io/FileReader.php';
+
+/**
+ * A class that is used to parse an input xml schema file and creates an AppData
+ * PHP object.
+ *
+ * @author     Hans Lellelid <hans@xmpl.org> (Propel)
+ * @author     Leon Messerschmidt <leon@opticode.co.za> (Torque)
+ * @author     Jason van Zyl <jvanzyl@apache.org> (Torque)
+ * @author     Martin Poeschl <mpoeschl@marmot.at> (Torque)
+ * @author     Daniel Rall <dlr@collab.net> (Torque)
+ * @version    $Revision: 989 $
+ * @package    propel.engine.database.transform
+ */
+class XmlToAppData extends AbstractHandler {
+
+	/** enables debug output */
+	const DEBUG = false;
+
+	private $app;
+	private $platform;
+	private $currDB;
+	private $currTable;
+	private $currColumn;
+	private $currFK;
+	private $currIndex;
+	private $currUnique;
+	private $currValidator;
+	private $currVendorObject;
+
+	private $isForReferenceOnly;
+	private $currentPackage;
+	private $currentXmlFile;
+	private $defaultPackage;
+
+	private $encoding;
+
+	/** two-dimensional array,
+		first dimension is for schemas(key is the path to the schema file),
+		second is for tags within the schema */
+	private $schemasTagsStack = array();
+
+	public $parser;
+
+	/**
+	 * Creates a new instance for the specified database type.
+	 *
+	 * @param      Platform $platform The type of database for the application.
+	 * @param      string $defaultPackage the default PHP package used for the om
+	 * @param      string $encoding The database encoding.
+	 */
+	public function __construct(Platform $platform, $defaultPackage, $encoding = 'iso-8859-1')
+	{
+		$this->app = new AppData($platform);
+		$this->platform = $platform;
+		$this->defaultPackage = $defaultPackage;
+		$this->firstPass = true;
+		$this->encoding = $encoding;
+	}
+
+	/**
+	 * Parses a XML input file and returns a newly created and
+	 * populated AppData structure.
+	 *
+	 * @param      string $xmlFile The input file to parse.
+	 * @return     AppData populated by <code>xmlFile</code>.
+	 */
+	public function parseFile($xmlFile)
+	{
+		// we don't want infinite recursion
+		if ($this->isAlreadyParsed($xmlFile)) {
+			return;
+		}
+
+		$domDocument = new DomDocument('1.0', 'UTF-8');
+		$domDocument->load($xmlFile);
+
+		// store current schema file path
+		$this->schemasTagsStack[$xmlFile] = array();
+
+		$this->currentXmlFile = $xmlFile;
+
+		try {
+			$fr = new FileReader($xmlFile);
+		} catch (Exception $e) {
+			$f = new PhingFile($xmlFile);
+			throw new Exception("XML File not found: " . $f->getAbsolutePath());
+		}
+
+		$br = new BufferedReader($fr);
+
+		$this->parser = new ExpatParser($br);
+		$this->parser->parserSetOption(XML_OPTION_CASE_FOLDING, 0);
+		$this->parser->setHandler($this);
+
+		try {
+			$this->parser->parse();
+		} catch (Exception $e) {
+			$br->close();
+			throw $e;
+		}
+		$br->close();
+
+		array_pop($this->schemasTagsStack);
+
+		return $this->app;
+	}
+
+	/**
+	 * Handles opening elements of the xml file.
+	 *
+	 * @param      string $uri
+	 * @param      string $localName The local name (without prefix), or the empty string if
+	 *		 Namespace processing is not being performed.
+	 * @param      string $rawName The qualified name (with prefix), or the empty string if
+	 *		 qualified names are not available.
+	 * @param      string $attributes The specified or defaulted attributes
+	 */
+	public function startElement($name, $attributes) {
+
+		try {
+
+	  $parentTag = $this->peekCurrentSchemaTag();
+
+	  if ($parentTag === false) {
+
+				switch($name) {
+					case "database":
+						if ($this->isExternalSchema()) {
+							$this->currentPackage = @$attributes["package"];
+							if ($this->currentPackage === null) {
+								$this->currentPackage = $this->defaultPackage;
+							}
+						} else {
+							$this->currDB = $this->app->addDatabase($attributes);
+						}
+					break;
+
+					default:
+						$this->_throwInvalidTagException($name);
+				}
+
+			} elseif  ($parentTag == "database") {
+
+				switch($name) {
+
+					case "external-schema":
+						$xmlFile = @$attributes["filename"];
+
+						//"referenceOnly" attribute is valid in the main schema XML file only,
+						//and it's ingnored in the nested external-schemas
+						if (!$this->isExternalSchema()) {
+							$isForRefOnly = @$attributes["referenceOnly"];
+							$this->isForReferenceOnly = ($isForRefOnly !== null ? (strtolower($isForRefOnly) === "true") : true); // defaults to TRUE
+						}
+
+						if ($xmlFile{0} != '/') {
+							$f = new PhingFile($this->currentXmlFile);
+							$xf = new PhingFile($f->getParent(), $xmlFile);
+							$xmlFile = $xf->getPath();
+						}
+
+						$this->parseFile($xmlFile);
+					break;
+
+		  case "domain":
+					  $this->currDB->addDomain($attributes);
+				  break;
+
+					case "table":
+						$this->currTable = $this->currDB->addTable($attributes);
+						if ($this->isExternalSchema()) {
+							$this->currTable->setForReferenceOnly($this->isForReferenceOnly);
+							$this->currTable->setPackage($this->currentPackage);
+						}
+					break;
+
+					case "vendor":
+						$this->currVendorObject = $this->currDB->addVendorInfo($attributes);
+					break;
+
+					default:
+						$this->_throwInvalidTagException($name);
+				}
+
+			} elseif  ($parentTag == "table") {
+
+				switch($name) {
+					case "column":
+						$this->currColumn = $this->currTable->addColumn($attributes);
+					break;
+
+					case "foreign-key":
+						$this->currFK = $this->currTable->addForeignKey($attributes);
+					break;
+
+					case "index":
+						$this->currIndex = $this->currTable->addIndex($attributes);
+					break;
+
+					case "unique":
+						$this->currUnique = $this->currTable->addUnique($attributes);
+					break;
+
+					case "vendor":
+						$this->currVendorObject = $this->currTable->addVendorInfo($attributes);
+					break;
+
+		  			case "validator":
+					  $this->currValidator = $this->currTable->addValidator($attributes);
+		  			break;
+
+		  			case "id-method-parameter":
+						$this->currTable->addIdMethodParameter($attributes);
+					break;
+
+					default:
+						$this->_throwInvalidTagException($name);
+				}
+
+			} elseif  ($parentTag == "column") {
+
+				switch($name) {
+					case "inheritance":
+						$this->currColumn->addInheritance($attributes);
+					break;
+
+					case "vendor":
+						$this->currVendorObject = $this->currColumn->addVendorInfo($attributes);
+					break;
+
+					default:
+						$this->_throwInvalidTagException($name);
+				}
+
+			} elseif ($parentTag == "foreign-key") {
+
+				switch($name) {
+					case "reference":
+						$this->currFK->addReference($attributes);
+					break;
+
+					case "vendor":
+						$this->currVendorObject = $this->currUnique->addVendorInfo($attributes);
+					break;
+
+					default:
+						$this->_throwInvalidTagException($name);
+				}
+
+			} elseif  ($parentTag == "index") {
+
+				switch($name) {
+					case "index-column":
+						$this->currIndex->addColumn($attributes);
+					break;
+
+					case "vendor":
+						$this->currVendorObject = $this->currIndex->addVendorInfo($attributes);
+					break;
+
+					default:
+						$this->_throwInvalidTagException($name);
+				}
+
+			} elseif ($parentTag == "unique") {
+
+				switch($name) {
+					case "unique-column":
+						$this->currUnique->addColumn($attributes);
+					break;
+
+					case "vendor":
+						$this->currVendorObject = $this->currUnique->addVendorInfo($attributes);
+					break;
+
+					default:
+						$this->_throwInvalidTagException($name);
+				}
+			} elseif ($parentTag == "validator") {
+				switch($name) {
+					case "rule":
+						$this->currValidator->addRule($attributes);
+					break;
+					default:
+						$this->_throwInvalidTagException($name);
+				}
+			} elseif ($parentTag == "vendor") {
+
+				switch($name) {
+					case "parameter":
+						$this->currVendorObject->addParameter($attributes);
+					break;
+					default:
+						$this->_throwInvalidTagException($name);
+				}
+
+			} else {
+				// it must be an invalid tag
+				$this->_throwInvalidTagException($name);
+			}
+
+			$this->pushCurrentSchemaTag($name);
+
+		} catch (BuildException $e) {
+			throw $e;
+		} catch (Exception $e) {
+			echo $e;
+			echo "\n";
+			throw $e;
+		}
+	}
+
+	function _throwInvalidTagException($tag_name)
+	{
+		throw new BuildException("Unexpected tag <" . $tag_name . ">", $this->parser->getLocation());
+	}
+
+	/**
+	 * Handles closing elements of the xml file.
+	 *
+	 * @param      uri
+	 * @param      localName The local name (without prefix), or the empty string if
+	 *		 Namespace processing is not being performed.
+	 * @param      rawName The qualified name (with prefix), or the empty string if
+	 *		 qualified names are not available.
+	 */
+	public function endElement($name)
+	{
+		if (self::DEBUG) {
+			print("endElement(" . $name . ") called\n");
+		}
+
+		$this->popCurrentSchemaTag();
+	}
+
+	protected function peekCurrentSchemaTag()
+	{
+				$keys = array_keys($this->schemasTagsStack);
+		return end($this->schemasTagsStack[end($keys)]);
+	}
+
+	protected function popCurrentSchemaTag()
+	{
+				$keys = array_keys($this->schemasTagsStack);
+		array_pop($this->schemasTagsStack[end($keys)]);
+	}
+
+	protected function pushCurrentSchemaTag($tag)
+	{
+				$keys = array_keys($this->schemasTagsStack);
+		$this->schemasTagsStack[end($keys)][] = $tag;
+	}
+
+	protected function isExternalSchema()
+	{
+		return (sizeof($this->schemasTagsStack) > 1);
+	}
+
+	protected function isAlreadyParsed($filePath)
+	{
+		return isset($this->schemasTagsStack[$filePath]);
+	}
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/platform/DefaultPlatform.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/platform/DefaultPlatform.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/platform/DefaultPlatform.php	(revision 19)
@@ -0,0 +1,301 @@
+<?php
+/*
+ *  $Id: DefaultPlatform.php 989 2008-03-11 14:29:30Z heltem $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://propel.phpdb.org>.
+ */
+
+require_once 'propel/engine/platform/Platform.php';
+include_once 'propel/engine/database/model/Domain.php';
+include_once 'propel/engine/database/model/PropelTypes.php';
+
+/**
+ * Default implementation for the Platform interface.
+ *
+ * @author     Martin Poeschl <mpoeschl@marmot.at> (Torque)
+ * @version    $Revision: 989 $
+ * @package    propel.engine.platform
+ */
+class DefaultPlatform implements Platform {
+
+	/**
+	 * Mapping from Propel types to Domain objects.
+	 *
+	 * @var        array
+	 */
+	private $schemaDomainMap;
+
+	/**
+	 * GeneratorConfig object holding build properties.
+	 *
+	 * @var        GeneratorConfig
+	 */
+	private $generatorConfig;
+
+	/**
+	 * @var        PDO Database connection.
+	 */
+	private $con;
+
+	/**
+	 * Default constructor.
+	 * @param      PDO $con Optional database connection to use in this platform.
+	 */
+	public function __construct(PDO $con = null)
+	{
+		if ($con) $this->setConnection($con);
+		$this->initialize();
+	}
+
+	/**
+	 * Set the database connection to use for this Platform class.
+	 * @param      PDO $con Database connection to use in this platform.
+	 */
+	public function setConnection(PDO $con = null)
+	{
+		$this->con = $con;
+	}
+
+	/**
+	 * Sets the GeneratorConfig to use in the parsing.
+	 *
+	 * @param      GeneratorConfig $config
+	 */
+	public function setGeneratorConfig(GeneratorConfig $config)
+	{
+		$this->generatorConfig = $config;
+	}
+
+	/**
+	 * Gets the GeneratorConfig option.
+	 *
+	 * @return     GeneratorConfig
+	 */
+	public function getGeneratorConfig()
+	{
+		return $this->generatorConfig;
+	}
+
+	/**
+	 * Gets a specific propel (renamed) property from the build.
+	 *
+	 * @param      string $name
+	 * @return     mixed
+	 */
+	protected function getBuildProperty($name)
+	{
+		if ($this->generatorConfig !== null) {
+			return $this->generatorConfig->getBuildProperty($name);
+		}
+		return null;
+	}
+
+	/**
+	 * Returns the database connection to use for this Platform class.
+	 * @return     PDO The database connection or NULL if none has been set.
+	 */
+	public function getConnection()
+	{
+		return $this->con;
+	}
+
+	/**
+	 * Initialize the type -> Domain mapping.
+	 */
+	protected function initialize()
+	{
+		$this->schemaDomainMap = array();
+		foreach (PropelTypes::getPropelTypes() as $type) {
+			$this->schemaDomainMap[$type] = new Domain($type);
+		}
+		// BU_* no longer needed, so map these to the DATE/TIMESTAMP domains
+		$this->schemaDomainMap[PropelTypes::BU_DATE] = new Domain(PropelTypes::DATE);
+		$this->schemaDomainMap[PropelTypes::BU_TIMESTAMP] = new Domain(PropelTypes::TIMESTAMP);
+
+		// Boolean is a bit special, since typically it must be mapped to INT type.
+		$this->schemaDomainMap[PropelTypes::BOOLEAN] = new Domain(PropelTypes::BOOLEAN, "INTEGER");
+	}
+
+	/**
+	 * Adds a mapping entry for specified Domain.
+	 * @param      Domain $domain
+	 */
+	protected function setSchemaDomainMapping(Domain $domain)
+	{
+		$this->schemaDomainMap[$domain->getType()] = $domain;
+	}
+
+	/**
+	 * Returns the short name of the database type that this platform represents.
+	 * For example MysqlPlatform->getDatabaseType() returns 'mysql'.
+	 * @return     string
+	 */
+	public function getDatabaseType()
+	{
+		$clazz = get_class($this);
+		$pos = strpos($clazz, 'Platform');
+		return strtolower(substr($clazz,0,$pos));
+	}
+
+	/**
+	 * @see        Platform::getMaxColumnNameLength()
+	 */
+	public function getMaxColumnNameLength()
+	{
+		return 64;
+	}
+
+	/**
+	 * @see        Platform::getNativeIdMethod()
+	 */
+	public function getNativeIdMethod()
+	{
+		return Platform::IDENTITY;
+	}
+
+	/**
+	 * @see        Platform::getDomainForType()
+	 */
+	public function getDomainForType($propelType)
+	{
+		if (!isset($this->schemaDomainMap[$propelType])) {
+			throw new EngineException("Cannot map unknown Propel type " . var_export($propelType, true) . " to native database type.");
+		}
+		return $this->schemaDomainMap[$propelType];
+	}
+
+	/**
+	 * @return     string Returns the SQL fragment to use if null values are disallowed.
+	 * @see        Platform::getNullString(boolean)
+	 */
+	public function getNullString($notNull)
+	{
+		return ($notNull ? "NOT NULL" : "");
+	}
+
+	/**
+	 * @see        Platform::getAutoIncrement()
+	 */
+	public function getAutoIncrement()
+	{
+		return "IDENTITY";
+	}
+
+	/**
+	 * @see        Platform::hasScale(String)
+	 */
+	public function hasScale($sqlType)
+	{
+		return true;
+	}
+
+	/**
+	 * @see        Platform::hasSize(String)
+	 */
+	public function hasSize($sqlType)
+	{
+		return true;
+	}
+
+	/**
+	 * @see        Platform::quote()
+	 */
+	public function quote($text)
+	{
+		if ($this->getConnection()) {
+			return $this->getConnection()->quote($text);
+		} else {
+			return "'" . $this->disconnectedEscapeText($text) . "'";
+		}
+	}
+
+	/**
+	 * Method to escape text when no connection has been set.
+	 *
+	 * The subclasses can implement this using string replacement functions
+	 * or native DB methods.
+	 *
+	 * @param      string $text Text that needs to be escaped.
+	 * @return     string
+	 */
+	protected function disconnectedEscapeText($text)
+	{
+		return str_replace("'", "''", $text);
+	}
+
+	/**
+	 * @see        Platform::quoteIdentifier()
+	 */
+	public function quoteIdentifier($text)
+	{
+		return '"' . $text . '"';
+	}
+
+	/**
+	 * @see        Platform::supportsNativeDeleteTrigger()
+	 */
+	public function supportsNativeDeleteTrigger()
+	{
+		return false;
+	}
+
+	/**
+	 * Whether the underlying PDO driver for this platform returns BLOB columns as streams (instead of strings).
+	 * @return     boolean
+	 */
+	public function hasStreamBlobImpl()
+	{
+		return false;
+	}
+
+	/**
+	 * @see        Platform::getBooleanString()
+	 */
+	public function getBooleanString($b)
+	{
+		$b = ($b === true || strtolower($b) === 'true' || $b === 1 || $b === '1' || strtolower($b) === 'y' || strtolower($b) === 'yes');
+		return ($b ? '1' : '0');
+	}
+
+	/**
+	 * Gets the preferred timestamp formatter for setting date/time values.
+	 * @return     string
+	 */
+	public function getTimestampFormatter()
+	{
+		return DateTime::ISO8601;
+	}
+
+	/**
+	 * Gets the preferred time formatter for setting date/time values.
+	 * @return     string
+	 */
+	public function getTimeFormatter()
+	{
+		return 'H:i:s';
+	}
+
+	/**
+	 * Gets the preferred date formatter for setting date/time values.
+	 * @return     string
+	 */
+	public function getDateFormatter()
+	{
+		return 'Y-m-d';
+	}
+
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/platform/MssqlPlatform.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/platform/MssqlPlatform.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/platform/MssqlPlatform.php	(revision 19)
@@ -0,0 +1,99 @@
+<?php
+/*
+ *  $Id: MssqlPlatform.php 521 2007-01-05 13:29:36Z heltem $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://propel.phpdb.org>.
+ */
+
+require_once 'propel/engine/platform/DefaultPlatform.php';
+include_once 'propel/engine/database/model/Domain.php';
+
+/**
+ * MS SQL Platform implementation.
+ *
+ * @author     Hans Lellelid <hans@xmpl.org> (Propel)
+ * @author     Martin Poeschl <mpoeschl@marmot.at> (Torque)
+ * @version    $Revision: 521 $
+ * @package    propel.engine.platform
+ */
+class MssqlPlatform extends DefaultPlatform {
+
+	/**
+	 * Initializes db specific domain mapping.
+	 */
+	protected function initialize()
+	{
+		parent::initialize();
+		$this->setSchemaDomainMapping(new Domain(PropelTypes::INTEGER, "INT"));
+		$this->setSchemaDomainMapping(new Domain(PropelTypes::BOOLEAN, "INT"));
+		$this->setSchemaDomainMapping(new Domain(PropelTypes::DOUBLE, "FLOAT"));
+		$this->setSchemaDomainMapping(new Domain(PropelTypes::LONGVARCHAR, "TEXT"));
+		$this->setSchemaDomainMapping(new Domain(PropelTypes::CLOB, "TEXT"));
+		$this->setSchemaDomainMapping(new Domain(PropelTypes::DATE, "DATETIME"));
+		$this->setSchemaDomainMapping(new Domain(PropelTypes::BU_DATE, "DATETIME"));
+		$this->setSchemaDomainMapping(new Domain(PropelTypes::TIME, "DATETIME"));
+		$this->setSchemaDomainMapping(new Domain(PropelTypes::TIMESTAMP, "DATETIME"));
+		$this->setSchemaDomainMapping(new Domain(PropelTypes::BU_TIMESTAMP, "DATETIME"));
+		$this->setSchemaDomainMapping(new Domain(PropelTypes::BINARY, "BINARY(7132)"));
+		$this->setSchemaDomainMapping(new Domain(PropelTypes::VARBINARY, "IMAGE"));
+		$this->setSchemaDomainMapping(new Domain(PropelTypes::LONGVARBINARY, "IMAGE"));
+		$this->setSchemaDomainMapping(new Domain(PropelTypes::BLOB, "IMAGE"));
+	}
+
+	/**
+	 * @see        Platform#getMaxColumnNameLength()
+	 */
+	public function getMaxColumnNameLength()
+	{
+		return 128;
+	}
+
+	/**
+	 * @return     Explicitly returns <code>NULL</code> if null values are
+	 * allowed (as recomended by Microsoft).
+	 * @see        Platform#getNullString(boolean)
+	 */
+	public function getNullString($notNull)
+	{
+		return ($notNull ? "NOT NULL" : "NULL");
+	}
+
+	/**
+	 * @see        Platform::supportsNativeDeleteTrigger()
+	 */
+	public function supportsNativeDeleteTrigger()
+	{
+		return true;
+	}
+
+	/**
+	 * @see        Platform::hasSize(String)
+	 */
+	public function hasSize($sqlType)
+	{
+		return !("INT" == $sqlType || "TEXT" == $sqlType);
+	}
+
+	/**
+	 * @see        Platform::quoteIdentifier()
+	 */
+	public function quoteIdentifier($text)
+	{
+		return '[' . $text . ']';
+	}
+
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/platform/MysqlPlatform.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/platform/MysqlPlatform.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/platform/MysqlPlatform.php	(revision 19)
@@ -0,0 +1,120 @@
+<?php
+/*
+ *  $Id: MysqlPlatform.php 949 2008-01-30 22:41:59Z hans $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://propel.phpdb.org>.
+ */
+
+require_once 'propel/engine/platform/DefaultPlatform.php';
+
+/**
+ * MySql Platform implementation.
+ *
+ * @author     Hans Lellelid <hans@xmpl.org> (Propel)
+ * @author     Martin Poeschl <mpoeschl@marmot.at> (Torque)
+ * @version    $Revision: 949 $
+ * @package    propel.engine.platform
+ */
+class MysqlPlatform extends DefaultPlatform {
+
+	/**
+	 * Initializes db specific domain mapping.
+	 */
+	protected function initialize()
+	{
+		parent::initialize();
+		$this->setSchemaDomainMapping(new Domain(PropelTypes::BOOLEAN, "TINYINT"));
+		$this->setSchemaDomainMapping(new Domain(PropelTypes::NUMERIC, "DECIMAL"));
+		$this->setSchemaDomainMapping(new Domain(PropelTypes::LONGVARCHAR, "TEXT"));
+		$this->setSchemaDomainMapping(new Domain(PropelTypes::BINARY, "BLOB"));
+		$this->setSchemaDomainMapping(new Domain(PropelTypes::VARBINARY, "MEDIUMBLOB"));
+		$this->setSchemaDomainMapping(new Domain(PropelTypes::LONGVARBINARY, "LONGBLOB"));
+		$this->setSchemaDomainMapping(new Domain(PropelTypes::BLOB, "LONGBLOB"));
+		$this->setSchemaDomainMapping(new Domain(PropelTypes::CLOB, "LONGTEXT"));
+		$this->setSchemaDomainMapping(new Domain(PropelTypes::TIMESTAMP, "DATETIME"));
+	}
+
+	/**
+	 * @see        Platform#getAutoIncrement()
+	 */
+	public function getAutoIncrement()
+	{
+		return "AUTO_INCREMENT";
+	}
+
+	/**
+	 * @see        Platform#getMaxColumnNameLength()
+	 */
+	public function getMaxColumnNameLength()
+	{
+		return 64;
+	}
+
+	/**
+	 * @see        Platform::supportsNativeDeleteTrigger()
+	 */
+	public function supportsNativeDeleteTrigger()
+	{
+		$usingInnoDB = false;
+		if (class_exists('DataModelBuilder', false))
+		{
+			$usingInnoDB = strtolower($this->getBuildProperty('mysqlTableType')) == 'innodb';
+		}
+		return $usingInnoDB || false;
+	}
+
+	/**
+	 * @see        Platform#hasSize(String)
+	 */
+	public function hasSize($sqlType)
+	{
+		return !("MEDIUMTEXT" == $sqlType || "LONGTEXT" == $sqlType
+				|| "BLOB" == $sqlType || "MEDIUMBLOB" == $sqlType
+				|| "LONGBLOB" == $sqlType);
+	}
+
+	/**
+	 * Escape the string for RDBMS.
+	 * @param      string $text
+	 * @return     string
+	 */
+	public function disconnectedEscapeText($text)
+	{
+		if (function_exists('mysql_escape_string')) {
+			return mysql_escape_string($text);
+		} else {
+			return addslashes($text);
+		}
+	}
+
+	/**
+	 * @see        Platform::quoteIdentifier()
+	 */
+	public function quoteIdentifier($text)
+	{
+		return '`' . $text . '`';
+	}
+
+	/**
+	 * Gets the preferred timestamp formatter for setting date/time values.
+	 * @return     string
+	 */
+	public function getTimestampFormatter()
+	{
+		return 'Y-m-d H:i:s';
+	}
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/platform/OraclePlatform.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/platform/OraclePlatform.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/platform/OraclePlatform.php	(revision 19)
@@ -0,0 +1,98 @@
+<?php
+/*
+ *  $Id: OraclePlatform.php 656 2007-06-20 15:25:53Z hans $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://propel.phpdb.org>.
+ */
+
+require_once 'propel/engine/platform/DefaultPlatform.php';
+
+/**
+ * Oracle Platform implementation.
+ *
+ * @author     Hans Lellelid <hans@xmpl.org> (Propel)
+ * @author     Martin Poeschl <mpoeschl@marmot.at> (Torque)
+ * @version    $Revision: 656 $
+ * @package    propel.engine.platform
+ */
+class OraclePlatform extends DefaultPlatform {
+
+	/**
+	 * Initializes db specific domain mapping.
+	 */
+	protected function initialize()
+	{
+		parent::initialize();
+		$this->setSchemaDomainMapping(new Domain(PropelTypes::BOOLEAN, "NUMBER", "1", "0"));
+		$this->setSchemaDomainMapping(new Domain(PropelTypes::TINYINT, "NUMBER", "3", "0"));
+		$this->setSchemaDomainMapping(new Domain(PropelTypes::SMALLINT, "NUMBER", "5", "0"));
+		$this->setSchemaDomainMapping(new Domain(PropelTypes::INTEGER, "NUMBER"));
+		$this->setSchemaDomainMapping(new Domain(PropelTypes::BIGINT, "NUMBER", "20", "0"));
+		$this->setSchemaDomainMapping(new Domain(PropelTypes::REAL, "NUMBER"));
+		$this->setSchemaDomainMapping(new Domain(PropelTypes::DOUBLE, "FLOAT"));
+		$this->setSchemaDomainMapping(new Domain(PropelTypes::DECIMAL, "NUMBER"));
+		$this->setSchemaDomainMapping(new Domain(PropelTypes::NUMERIC, "NUMBER"));
+		$this->setSchemaDomainMapping(new Domain(PropelTypes::VARCHAR, "VARCHAR2"));
+		$this->setSchemaDomainMapping(new Domain(PropelTypes::LONGVARCHAR, "VARCHAR2", "2000"));
+		$this->setSchemaDomainMapping(new Domain(PropelTypes::TIME, "DATE"));
+		$this->setSchemaDomainMapping(new Domain(PropelTypes::TIMESTAMP, "DATE"));
+		$this->setSchemaDomainMapping(new Domain(PropelTypes::BINARY, "LONG RAW"));
+		$this->setSchemaDomainMapping(new Domain(PropelTypes::VARBINARY, "BLOB"));
+		$this->setSchemaDomainMapping(new Domain(PropelTypes::LONGVARBINARY, "LONG RAW"));
+	}
+
+	/**
+	 * @see        Platform#getMaxColumnNameLength()
+	 */
+	public function getMaxColumnNameLength()
+	{
+		return 30;
+	}
+
+	/**
+	 * @see        Platform#getNativeIdMethod()
+	 */
+	public function getNativeIdMethod()
+	{
+		return Platform::SEQUENCE;
+	}
+
+	/**
+	 * @see        Platform#getAutoIncrement()
+	 */
+	public function getAutoIncrement()
+	{
+		return "";
+	}
+
+	/**
+	 * @see        Platform::supportsNativeDeleteTrigger()
+	 */
+	public function supportsNativeDeleteTrigger()
+	{
+		return true;
+	}
+
+	/**
+	 * Whether the underlying PDO driver for this platform returns BLOB columns as streams (instead of strings).
+	 * @return     boolean
+	 */
+	public function hasStreamBlobImpl()
+	{
+		return true;
+	}
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/platform/PgsqlPlatform.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/platform/PgsqlPlatform.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/platform/PgsqlPlatform.php	(revision 19)
@@ -0,0 +1,128 @@
+<?php
+/*
+ *  $Id: PgsqlPlatform.php 844 2007-12-02 17:57:36Z hans $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://propel.phpdb.org>.
+ */
+
+require_once 'propel/engine/platform/DefaultPlatform.php';
+
+/**
+ * Postgresql Platform implementation.
+ *
+ * @author     Hans Lellelid <hans@xmpl.org> (Propel)
+ * @author     Martin Poeschl <mpoeschl@marmot.at> (Torque)
+ * @version    $Revision: 844 $
+ * @package    propel.engine.platform
+ */
+class PgsqlPlatform extends DefaultPlatform {
+
+	/**
+	 * Initializes db specific domain mapping.
+	 */
+	protected function initialize()
+	{
+		parent::initialize();
+		$this->setSchemaDomainMapping(new Domain(PropelTypes::BOOLEAN, "BOOLEAN"));
+		$this->setSchemaDomainMapping(new Domain(PropelTypes::TINYINT, "INT2"));
+		$this->setSchemaDomainMapping(new Domain(PropelTypes::SMALLINT, "INT2"));
+		$this->setSchemaDomainMapping(new Domain(PropelTypes::BIGINT, "INT8"));
+		$this->setSchemaDomainMapping(new Domain(PropelTypes::REAL, "FLOAT"));
+		$this->setSchemaDomainMapping(new Domain(PropelTypes::DOUBLE, "DOUBLE PRECISION"));
+		$this->setSchemaDomainMapping(new Domain(PropelTypes::LONGVARCHAR, "TEXT"));
+		$this->setSchemaDomainMapping(new Domain(PropelTypes::BINARY, "BYTEA"));
+		$this->setSchemaDomainMapping(new Domain(PropelTypes::VARBINARY, "BYTEA"));
+		$this->setSchemaDomainMapping(new Domain(PropelTypes::LONGVARBINARY, "BYTEA"));
+		$this->setSchemaDomainMapping(new Domain(PropelTypes::BLOB, "BYTEA"));
+		$this->setSchemaDomainMapping(new Domain(PropelTypes::CLOB, "TEXT"));
+	}
+
+	/**
+	 * @see        Platform#getNativeIdMethod()
+	 */
+	public function getNativeIdMethod()
+	{
+		return Platform::SERIAL;
+	}
+
+	/**
+	 * @see        Platform#getAutoIncrement()
+	 */
+	public function getAutoIncrement()
+	{
+		return "";
+	}
+
+	/**
+	 * @see        Platform#getMaxColumnNameLength()
+	 */
+	public function getMaxColumnNameLength()
+	{
+		return 32;
+	}
+
+	/**
+	 * Escape the string for RDBMS.
+	 * @param      string $text
+	 * @return     string
+	 */
+	public function disconnectedEscapeText($text)
+	{
+		if (function_exists('pg_escape_string')) {
+			return pg_escape_string($text);
+		} else {
+			return parent::disconnectedEscapeText($text);
+		}
+	}
+
+	/**
+	 * @see        Platform::getBooleanString()
+	 */
+	public function getBooleanString($b)
+	{
+		// parent method does the checking for allowes tring
+		// representations & returns integer
+		$b = parent::getBooleanString($b);
+		return ($b ? "'t'" : "'f'");
+	}
+
+	/**
+	 * @see        Platform::supportsNativeDeleteTrigger()
+	 */
+	public function supportsNativeDeleteTrigger()
+	{
+		return true;
+	}
+
+	/**
+	 * @see        Platform::hasSize(String)
+	 * TODO collect info for all platforms
+	 */
+	public function hasSize($sqlType)
+	{
+		return !("BYTEA" == $sqlType || "TEXT" == $sqlType);
+	}
+
+	/**
+	 * Whether the underlying PDO driver for this platform returns BLOB columns as streams (instead of strings).
+	 * @return     boolean
+	 */
+	public function hasStreamBlobImpl()
+	{
+		return true;
+	}
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/platform/Platform.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/platform/Platform.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/platform/Platform.php	(revision 19)
@@ -0,0 +1,186 @@
+<?php
+/*
+ *  $Id: Platform.php 989 2008-03-11 14:29:30Z heltem $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://propel.phpdb.org>.
+ */
+
+/**
+ * Interface for RDBMS platform specific behaviour.
+ *
+ * @author     Hans Lellelid <hans@xmpl.org> (Propel)
+ * @author     Martin Poeschl <mpoeschl@marmot.at> (Torque)
+ * @version    $Revision: 989 $
+ * @package    propel.engine.platform
+ */
+interface Platform {
+
+	/**
+	 * Constant for auto-increment id method.
+	 */
+	const IDENTITY = "identity";
+
+	/**
+	 * Constant for sequence id method.
+	 */
+	const SEQUENCE = "sequence";
+
+	/**
+	 * Constant for serial id method (postgresql).
+	 */
+	const SERIAL = "serial";
+
+	/**
+	 * Sets a database connection to use (for quoting, etc.).
+	 * @param      PDO $con The database connection to use in this Platform class.
+	 */
+	public function setConnection(PDO $con = null);
+
+	/**
+	 * Returns the database connection to use for this Platform class.
+	 * @return     PDO The database connection or NULL if none has been set.
+	 */
+	public function getConnection();
+
+	/**
+	 * Sets the GeneratorConfig which contains any generator build properties.
+	 *
+	 * @param      GeneratorConfig $config
+	 */
+	public function setGeneratorConfig(GeneratorConfig $config);
+
+	/**
+	 * Gets the GeneratorConfig object.
+	 *
+	 * @return     GeneratorConfig
+	 */
+	public function getGeneratorConfig();
+
+	/**
+	 * Returns the short name of the database type that this platform represents.
+	 * For example MysqlPlatform->getDatabaseType() returns 'mysql'.
+	 * @return     string
+	 */
+	public function getDatabaseType();
+
+	/**
+	 * Returns the native IdMethod (sequence|identity)
+	 *
+	 * @return     string The native IdMethod (Platform:IDENTITY, Platform::SEQUENCE).
+	 */
+	public function getNativeIdMethod();
+
+	/**
+	 * Returns the max column length supported by the db.
+	 *
+	 * @return     int The max column length
+	 */
+	public function getMaxColumnNameLength();
+
+	/**
+	 * Returns the db specific domain for a jdbcType.
+	 *
+	 * @param      string $creoleType the creole type name.
+	 * @return     Domain The db specific domain.
+	 */
+	public function getDomainForType($creoleType);
+
+	/**
+	 * @return     string The RDBMS-specific SQL fragment for <code>NULL</code>
+	 * or <code>NOT NULL</code>.
+	 */
+	public function getNullString($notNull);
+
+	/**
+	 * @return     The RDBMS-specific SQL fragment for autoincrement.
+	 */
+	public function getAutoIncrement();
+
+	/**
+	 * Returns if the RDBMS-specific SQL type has a size attribute.
+	 *
+	 * @param      string $sqlType the SQL type
+	 * @return     boolean True if the type has a size attribute
+	 */
+	public function hasSize($sqlType);
+
+	/**
+	 * Returns if the RDBMS-specific SQL type has a scale attribute.
+	 *
+	 * @param      string $sqlType the SQL type
+	 * @return     boolean True if the type has a scale attribute
+	 */
+	public function hasScale($sqlType);
+
+	/**
+	 * Quote and escape needed characters in the string for unerlying RDBMS.
+	 * @param      string $text
+	 * @return     string
+	 */
+	public function quote($text);
+
+	/**
+	 * Quotes identifiers used in database SQL.
+	 * @param      string $text
+	 * @return     string Quoted identifier.
+	 */
+	public function quoteIdentifier($text);
+
+	/**
+	 * Whether RDBMS supports native ON DELETE triggers (e.g. ON DELETE CASCADE).
+	 * @return     boolean
+	 */
+	public function supportsNativeDeleteTrigger();
+
+	/**
+	 * Returns the boolean value for the RDBMS.
+	 *
+	 * This value should match the boolean value that is set
+	 * when using Creole's PreparedStatement::setBoolean().
+	 *
+	 * This function is used to set default column values when building
+	 * SQL.
+	 *
+	 * @param      mixed $tf A boolean or string representation of boolean ('y', 'true').
+	 * @return     mixed
+	 */
+	public function getBooleanString($tf);
+
+	/**
+	 * Whether the underlying PDO driver for this platform returns BLOB columns as streams (instead of strings).
+	 * @return     boolean
+	 */
+	public function hasStreamBlobImpl();
+
+	/**
+	 * Gets the preferred timestamp formatter for setting date/time values.
+	 * @return     string
+	 */
+	public function getTimestampFormatter();
+
+	/**
+	 * Gets the preferred date formatter for setting time values.
+	 * @return     string
+	 */
+	public function getDateFormatter();
+
+	/**
+	 * Gets the preferred time formatter for setting time values.
+	 * @return     string
+	 */
+	public function getTimeFormatter();
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/platform/SqlitePlatform.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/platform/SqlitePlatform.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/engine/platform/SqlitePlatform.php	(revision 19)
@@ -0,0 +1,97 @@
+<?php
+/*
+ *  $Id: SqlitePlatform.php 578 2007-02-21 19:09:59Z hans $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://propel.phpdb.org>.
+ */
+
+require_once 'propel/engine/platform/DefaultPlatform.php';
+
+/**
+ * SQLite Platform implementation.
+ *
+ * @author     Hans Lellelid <hans@xmpl.org>
+ * @version    $Revision: 578 $
+ * @package    propel.engine.platform
+ */
+class SqlitePlatform extends DefaultPlatform {
+
+	/**
+	 * Initializes db specific domain mapping.
+	 */
+	protected function initialize()
+	{
+		parent::initialize();
+		$this->setSchemaDomainMapping(new Domain(PropelTypes::NUMERIC, "DECIMAL"));
+		$this->setSchemaDomainMapping(new Domain(PropelTypes::LONGVARCHAR, "MEDIUMTEXT"));
+		$this->setSchemaDomainMapping(new Domain(PropelTypes::DATE, "DATETIME"));
+		$this->setSchemaDomainMapping(new Domain(PropelTypes::BINARY, "BLOB"));
+		$this->setSchemaDomainMapping(new Domain(PropelTypes::VARBINARY, "MEDIUMBLOB"));
+		$this->setSchemaDomainMapping(new Domain(PropelTypes::LONGVARBINARY, "LONGBLOB"));
+		$this->setSchemaDomainMapping(new Domain(PropelTypes::BLOB, "LONGBLOB"));
+		$this->setSchemaDomainMapping(new Domain(PropelTypes::CLOB, "LONGTEXT"));
+	}
+
+	/**
+	 * @see        Platform#getAutoIncrement()
+	 * @link       http://www.sqlite.org/autoinc.html
+	 */
+	public function getAutoIncrement()
+	{
+
+		return "PRIMARY KEY";
+	}
+
+	/**
+	 * @see        Platform#getMaxColumnNameLength()
+	 */
+	public function getMaxColumnNameLength()
+	{
+		return 1024;
+	}
+
+	/**
+	 * @see        Platform#hasSize(String)
+	 */
+	public function hasSize($sqlType) {
+		return !("MEDIUMTEXT" == $sqlType || "LONGTEXT" == $sqlType
+				|| "BLOB" == $sqlType || "MEDIUMBLOB" == $sqlType
+				|| "LONGBLOB" == $sqlType);
+	}
+
+	/**
+	 * Escape the string for RDBMS.
+	 * @param      string $text
+	 * @return     string
+	 */
+	public function disconnectedEscapeText($text)
+	{
+		if (function_exists('sqlite_escape_string')) {
+			return sqlite_escape_string($text);
+		} else {
+			return parent::disconnectedEscapeText($text);
+		}
+	}
+
+	/**
+	 * @see        Platform::quoteIdentifier()
+	 */
+	public function quoteIdentifier($text)
+	{
+		return '[' . $text . ']';
+	}
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/phing/AbstractPropelDataModelTask.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/phing/AbstractPropelDataModelTask.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/phing/AbstractPropelDataModelTask.php	(revision 19)
@@ -0,0 +1,610 @@
+<?php
+
+/*
+ *  $Id: AbstractPropelDataModelTask.php 1032 2008-04-29 15:22:43Z ron $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://propel.phpdb.org>.
+ */
+
+//include_once 'phing/tasks/ext/CapsuleTask.php';
+require_once 'phing/Task.php';
+include_once 'propel/engine/GeneratorConfig.php';
+include_once 'propel/engine/database/model/AppData.php';
+include_once 'propel/engine/database/model/Database.php';
+include_once 'propel/engine/database/transform/XmlToAppData.php';
+
+/**
+ * An abstract base Propel task to perform work related to the XML schema file.
+ *
+ * The subclasses invoke templates to do the actual writing of the resulting files.
+ *
+ * @author     Hans Lellelid <hans@xmpl.org> (Propel)
+ * @author     Jason van Zyl <jvanzyl@zenplex.com> (Torque)
+ * @author     Daniel Rall <dlr@finemaltcoding.com> (Torque)
+ * @package    propel.phing
+ */
+abstract class AbstractPropelDataModelTask extends Task {
+
+	/**
+	 * Fileset of XML schemas which represent our data models.
+	 * @var        array Fileset[]
+	 */
+	protected $schemaFilesets = array();
+
+	/**
+	 * Data models that we collect. One from each XML schema file.
+	 */
+	protected $dataModels = array();
+
+	/**
+	 * Have datamodels been initialized?
+	 * @var        boolean
+	 */
+	private $dataModelsLoaded = false;
+
+	/**
+	 * Map of data model name to database name.
+	 * Should probably stick to the convention
+	 * of them being the same but I know right now
+	 * in a lot of cases they won't be.
+	 */
+	protected $dataModelDbMap;
+
+	/**
+	 * Hashtable containing the names of all the databases
+	 * in our collection of schemas.
+	 */
+	protected $databaseNames; // doesn't seem to be used anywhere
+
+	/**
+	 * The target database(s) we are generating SQL
+	 * for. Right now we can only deal with a single
+	 * target, but we will support multiple targets
+	 * soon.
+	 */
+	protected $targetDatabase;
+
+	/**
+	 * DB encoding to use for XmlToAppData object
+	 */
+	protected $dbEncoding = 'iso-8859-1';
+
+	/**
+	 * Target PHP package to place the generated files in.
+	 */
+	protected $targetPackage;
+
+	/**
+	 * @var        Mapper
+	 */
+	protected $mapperElement;
+
+	/**
+	 * Destination directory for results of template scripts.
+	 * @var        PhingFile
+	 */
+	protected $outputDirectory;
+
+	/**
+	 * Whether to package the datamodels or not
+	 * @var        PhingFile
+	 */
+	protected $packageObjectModel;
+
+	/**
+	 * Whether to perform validation (XSD) on the schema.xml file(s).
+	 * @var        boolean
+	 */
+	protected $validate;
+
+	/**
+	 * The XSD schema file to use for validation.
+	 * @var        PhingFile
+	 */
+	protected $xsdFile;
+
+	/**
+	 * XSL file to use to normalize (or otherwise transform) schema before validation.
+	 * @var        PhingFile
+	 */
+	protected $xslFile;
+
+	/**
+	 * Optional database connection url.
+	 * @var        string
+	 */
+	private $url = null;
+
+	/**
+	 * Optional database connection user name.
+	 * @var        string
+	 */
+	private $userId = null;
+
+	/**
+	 * Optional database connection password.
+	 * @var        string
+	 */
+	private $password = null;
+
+	/**
+	 * PDO Connection.
+	 * @var        PDO
+	 */
+	private $conn = false;
+
+	/**
+	 * An initialized GeneratorConfig object containing the converted Phing props.
+	 *
+	 * @var        GeneratorConfig
+	 */
+	private $generatorConfig;
+
+	/**
+	 * Return the data models that have been
+	 * processed.
+	 *
+	 * @return     List data models
+	 */
+	public function getDataModels()
+	{
+		if (!$this->dataModelsLoaded) $this->loadDataModels();
+		return $this->dataModels;
+	}
+
+	/**
+	 * Return the data model to database name map.
+	 *
+	 * @return     Hashtable data model name to database name map.
+	 */
+	public function getDataModelDbMap()
+	{
+		if (!$this->dataModelsLoaded) $this->loadDataModels();
+		return $this->dataModelDbMap;
+	}
+
+	/**
+	 * Adds a set of xml schema files (nested fileset attribute).
+	 *
+	 * @param      set a Set of xml schema files
+	 */
+	public function addSchemaFileset(Fileset $set)
+	{
+		$this->schemaFilesets[] = $set;
+	}
+
+	/**
+	 * Get the current target database.
+	 *
+	 * @return     String target database(s)
+	 */
+	public function getTargetDatabase()
+	{
+		return $this->targetDatabase;
+	}
+
+	/**
+	 * Set the current target database. (e.g. mysql, oracle, ..)
+	 *
+	 * @param      v target database(s)
+	 */
+	public function setTargetDatabase($v)
+	{
+		$this->targetDatabase = $v;
+	}
+
+	/**
+	 * Get the current target package.
+	 *
+	 * @return     string target PHP package.
+	 */
+	public function getTargetPackage()
+	{
+		return $this->targetPackage;
+	}
+
+	/**
+	 * Set the current target package. This is where generated PHP classes will
+	 * live.
+	 *
+	 * @param      string $v target PHP package.
+	 */
+	public function setTargetPackage($v)
+	{
+		$this->targetPackage = $v;
+	}
+
+	/**
+	 * Set the packageObjectModel switch on/off
+	 *
+	 * @param      string $v The build.property packageObjectModel
+	 */
+	public function setPackageObjectModel($v)
+	{
+		$this->packageObjectModel = ($v === '1' ? true : false);
+	}
+
+	/**
+	 * Set whether to perform validation on the datamodel schema.xml file(s).
+	 * @param      boolean $v
+	 */
+	public function setValidate($v)
+	{
+		$this->validate = $v;
+	}
+
+	/**
+	 * Set the XSD schema to use for validation of any datamodel schema.xml file(s).
+	 * @param      $v PhingFile
+	 */
+	public function setXsd(PhingFile $v)
+	{
+		$this->xsdFile = $v;
+	}
+
+	/**
+	 * Set the normalization XSLT to use to transform datamodel schema.xml file(s) before validation and parsing.
+	 * @param      $v PhingFile
+	 */
+	public function setXsl(PhingFile $v)
+	{
+		$this->xslFile = $v;
+	}
+
+	/**
+	 * [REQUIRED] Set the output directory. It will be
+	 * created if it doesn't exist.
+	 * @param      PhingFile $outputDirectory
+	 * @return     void
+	 * @throws     Exception
+	 */
+	public function setOutputDirectory(PhingFile $outputDirectory) {
+		try {
+			if (!$outputDirectory->exists()) {
+				$this->log("Output directory does not exist, creating: " . $outputDirectory->getPath(),Project::MSG_VERBOSE);
+				if (!$outputDirectory->mkdirs()) {
+					throw new IOException("Unable to create Ouptut directory: " . $outputDirectory->getAbsolutePath());
+				}
+			}
+			$this->outputDirectory = $outputDirectory->getCanonicalPath();
+		} catch (IOException $ioe) {
+			throw new BuildException($ioe);
+		}
+	}
+
+	/**
+	 * Set the current target database encoding.
+	 *
+	 * @param      v target database encoding
+	 */
+	public function setDbEncoding($v)
+	{
+		$this->dbEncoding = $v;
+	}
+
+	/**
+	 * Set the DB connection url.
+	 *
+	 * @param      string $url connection url
+	 */
+	public function setUrl($url)
+	{
+		$this->url = $url;
+	}
+
+	/**
+	 * Set the user name for the DB connection.
+	 *
+	 * @param      string $userId database user
+	 */
+	public function setUserid($userId)
+	{
+		$this->userId = $userId;
+	}
+
+	/**
+	 * Set the password for the DB connection.
+	 *
+	 * @param      string $password database password
+	 */
+	public function setPassword($password)
+	{
+		$this->password = $password;
+	}
+
+	/**
+	 * Get the output directory.
+	 * @return     string
+	 */
+	public function getOutputDirectory() {
+		return $this->outputDirectory;
+	}
+
+	/**
+	 * Nested creator, creates one Mapper for this task.
+	 *
+	 * @return     Mapper  The created Mapper type object.
+	 * @throws     BuildException
+	 */
+	public function createMapper() {
+		if ($this->mapperElement !== null) {
+			throw new BuildException("Cannot define more than one mapper.", $this->location);
+		}
+		$this->mapperElement = new Mapper($this->project);
+		return $this->mapperElement;
+	}
+
+	/**
+	 * Maps the passed in name to a new filename & returns resolved File object.
+	 * @param      string $from
+	 * @return     PhingFile Resolved File object.
+	 * @throws     BuilException    - if no Mapper element se
+	 *                          - if unable to map new filename.
+	 */
+	protected function getMappedFile($from)
+	{
+		if (!$this->mapperElement) {
+			throw new BuildException("This task requires you to use a <mapper/> element to describe how filename changes should be handled.");
+		}
+
+		$mapper = $this->mapperElement->getImplementation();
+		$mapped = $mapper->main($from);
+		if (!$mapped) {
+			throw new BuildException("Cannot create new filename based on: " . $from);
+		}
+		// Mappers always return arrays since it's possible for some mappers to map to multiple names.
+		$outFilename = array_shift($mapped);
+		$outFile = new PhingFile($this->getOutputDirectory(), $outFilename);
+		return $outFile;
+	}
+
+	/**
+	 * Gets the PDO connection, if URL specified.
+	 * @return     PDO Connection to use (for quoting, Platform class, etc.) or NULL if no connection params were specified.
+	 */
+	public function getConnection()
+	{
+		if ($this->conn === false) {
+			$this->conn = null;
+			if ($this->url) {
+				$buf = "Using database settings:\n"
+					. " URL: " . $this->url . "\n"
+					. ($this->userId ? " user: " . $this->userId . "\n" : "")
+				. ($this->password ? " password: " . $this->password . "\n" : "");
+
+				$this->log($buf, Project::MSG_VERBOSE);
+
+				// Set user + password to null if they are empty strings
+				if (!$this->userId) { $this->userId = null; }
+				if (!$this->password) { $this->password = null; }
+				try {
+					$this->conn = new PDO($this->url, $this->userId, $this->password);
+					$this->conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
+				} catch (PDOException $x) {
+					$this->log("Unable to create a PDO connection: " . $x->getMessage(), Project::MSG_WARN);
+				}
+			}
+		}
+		return $this->conn;
+	}
+
+	/**
+	 * Gets all matching XML schema files and loads them into data models for class.
+	 * @return     void
+	 */
+	protected function loadDataModels()
+	{
+		$ads = array();
+
+		// Get all matched files from schemaFilesets
+		foreach ($this->schemaFilesets as $fs) {
+			$ds = $fs->getDirectoryScanner($this->project);
+			$srcDir = $fs->getDir($this->project);
+
+			$dataModelFiles = $ds->getIncludedFiles();
+
+			$platform = $this->getGeneratorConfig()->getConfiguredPlatform();
+
+			// Make a transaction for each file
+			foreach ($dataModelFiles as $dmFilename) {
+
+				$this->log("Processing: ".$dmFilename);
+				$xmlFile = new PhingFile($srcDir, $dmFilename);
+
+				$dom = new DomDocument('1.0', 'UTF-8');
+				$dom->load($xmlFile->getAbsolutePath());
+
+				// normalize (or transform) the XML document using XSLT
+				if ($this->xslFile) {
+					$this->log("Transforming " . $xmlFile->getPath() . " using stylesheet " . $this->xslFile->getPath(), Project::MSG_VERBOSE);
+					if (!class_exists('XSLTProcessor')) {
+						$this->log("Could not perform XLST transformation.  Make sure PHP has been compiled/configured to support XSLT.", Project::MSG_ERR);
+					} else {
+						// modify schema to include any external schema's (and remove the external-schema nodes)
+						$this->includeExternalSchemas($dom, $srcDir);
+						// normalize the document using normalizer stylesheet
+
+						$xsl = new XsltProcessor();
+						$xsl->importStyleSheet(DomDocument::load($this->xslFile->getAbsolutePath()));
+						$transformed = $xsl->transformToDoc($dom);
+						$newXmlFilename = substr($xmlFile->getName(), 0, strrpos($xmlFile->getName(), '.')) . '-transformed.xml';
+
+						// now overwrite previous vars to point to newly transformed file
+						$xmlFile = new PhingFile($srcDir, $newXmlFilename);
+						$transformed->save($xmlFile->getAbsolutePath());
+						$this->log("\t- Using new (post-transformation) XML file: " . $xmlFile->getPath(), Project::MSG_VERBOSE);
+
+						$dom = new DomDocument('1.0', 'UTF-8');
+						$dom->load($xmlFile->getAbsolutePath());
+					}
+				}
+
+				// validate the XML document using XSD schema
+				if ($this->validate && $this->xsdFile) {
+					$this->log("Validating XML doc (".$xmlFile->getPath().") using schema file " . $this->xsdFile->getPath(), Project::MSG_VERBOSE);
+					if (!$dom->schemaValidate($this->xsdFile->getAbsolutePath())) {
+						throw new BuildException("XML schema file (".$xmlFile->getPath().") does not validate.  See warnings above for reasons validation failed (make sure error_reporting is set to show E_WARNING if you don't see any).");		throw new EngineException("XML schema does not validate (using schema file $xsdFile).  See warnings above for reasons validation failed (make sure error_reporting is set to show E_WARNING if you don't see any).", $this->getLocation());
+					}
+				}
+
+				$xmlParser = new XmlToAppData($platform, $this->getTargetPackage(), $this->dbEncoding);
+				$ad = $xmlParser->parseFile($xmlFile->getAbsolutePath());
+				$ad->setName($dmFilename); // <-- Important: use the original name, not the -transformed name.
+				$ads[] = $ad;
+			}
+		}
+
+		if (empty($ads)) {
+			throw new BuildException("No schema files were found (matching your schema fileset definition).");
+		}
+
+		if (!$this->packageObjectModel) {
+
+			$this->dataModels = $ads;
+			$this->databaseNames = array(); // doesn't seem to be used anywhere
+			$this->dataModelDbMap = array();
+
+			// Different datamodels may state the same database
+			// names, we just want the unique names of databases.
+			foreach ($this->dataModels as $dm) {
+				$database = $dm->getDatabase();
+				$this->dataModelDbMap[$dm->getName()] = $database->getName();
+				$this->databaseNames[$database->getName()] = $database->getName(); // making list of *unique* dbnames.
+			}
+		} else {
+
+			$this->joinDatamodels($ads);
+			$this->dataModels[0]->getDatabases(); // calls doFinalInitialization()
+		}
+
+		$this->dataModelsLoaded = true;
+	}
+
+	/**
+	 * Replaces all external-schema nodes with the content of xml schema that node refers to
+	 *
+	 * Recurses to include any external schema referenced from in an included xml (and deeper)
+	 * Note: this function very much assumes at least a reasonable XML schema, maybe it'll proof
+	 * users don't have those and adding some more informative exceptions would be better
+	 *
+	 * @param      DomDocument $dom
+	 * @param      string $srcDir
+	 * @return     void (objects, DomDocument, are references by default in PHP 5, so returning it is useless)
+	 **/
+	protected function includeExternalSchemas(DomDocument $dom, $srcDir) {
+		$databaseNode = $dom->getElementsByTagName("database")->item(0);
+		$externalSchemaNodes = $dom->getElementsByTagName("external-schema");
+		while ($externalSchema = $externalSchemaNodes->item(0)) {
+			$include = $externalSchema->getAttribute("filename");
+			$externalSchema->parentNode->removeChild($externalSchema);
+			if (strpos($srcDir->getPath(), "/") === 0) {
+				$externalSchemaFile = new PhingFile($include);
+			} else {
+				$externalSchemaFile = new PhingFile($srcDir, $include);
+			}
+			$externalSchemaDom = new DomDocument('1.0', 'UTF-8');
+			$externalSchemaDom->load($externalSchemaFile->getAbsolutePath());
+			$this->includeExternalSchemas($externalSchemaDom, $srcDir);
+			foreach ($externalSchemaDom->getElementsByTagName("table") as $tableNode) { // see xsd, datatase may only have table or external-schema, the latter was just deleted so this should cover everything
+				$databaseNode->appendChild($dom->importNode($tableNode, true));
+			}
+		}
+	}
+	/**
+	 * Joins the datamodels collected from schema.xml files into one big datamodel
+	 *
+	 * This applies only when the the packageObjectModel option is set. We need to
+	 * join the datamodels in this case to allow for foreign keys that point to
+	 * tables in different packages.
+	 *
+	 * @param      array $ads The datamodels to join
+	 */
+	protected function joinDatamodels($ads) {
+
+		foreach ($ads as $ad) {
+			$db = $ad->getDatabase(null, false);
+			$this->dataModelDbMap[$ad->getName()] = $db->getName();
+		}
+
+		foreach ($ads as $addAd) {
+
+			$ad = &$this->dataModels[0];
+			if (!isset($ad)) {
+				$addAd->setName('JoinedDataModel');
+				$ad = $addAd;
+				continue;
+			}
+			foreach ($addAd->getDatabases(false) as $addDb) {
+				$addDbName = $addDb->getName();
+				if (!$package = $addDb->getPackage()) {
+					throw new BuildException('No package found for database "' . $addDbName . '" in ' . $addAd->getName() . '. The propel.packageObjectModel property requires the package attribute to be set for each database.');
+				}
+				$db = $ad->getDatabase($addDbName, false);
+				if (!$db) {
+					$ad->addDatabase($addDb);
+					continue;
+				}
+				foreach ($addDb->getTables() as $addTable) {
+					$table = $db->getTable($addTable->getName());
+					if ($table) {
+						throw new BuildException('Duplicate table found: ' . $addDbName . '.');
+					}
+					$db->addTable($addTable);
+				}
+			}
+		}
+	}
+
+	/**
+	 * Gets the GeneratorConfig object for this task or creates it on-demand.
+	 * @return     GeneratorConfig
+	 */
+	protected function getGeneratorConfig()
+	{
+		if ($this->generatorConfig === null) {
+			$this->generatorConfig = new GeneratorConfig();
+			$this->generatorConfig->setBuildProperties($this->getProject()->getProperties());
+		}
+		return $this->generatorConfig;
+	}
+
+	/**
+	 * Checks this class against Basic requrements of any propel datamodel task.
+	 *
+	 * @throws     BuildException 	- if schema fileset was not defined
+	 * 							- if no output directory was specified
+	 */
+	protected function validate()
+	{
+		if (empty($this->schemaFilesets)) {
+			throw new BuildException("You must specify a fileset of XML schemas.", $this->getLocation());
+		}
+
+		// Make sure the output directory is set.
+		if ($this->outputDirectory === null) {
+			throw new BuildException("The output directory needs to be defined!", $this->getLocation());
+		}
+
+		if ($this->validate) {
+			if (!$this->xsdFile) {
+				throw new BuildException("'validate' set to TRUE, but no XSD specified (use 'xsd' attribute).", $this->getLocation());
+			}
+		}
+
+	}
+
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/phing/PropelConvertConfTask.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/phing/PropelConvertConfTask.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/phing/PropelConvertConfTask.php	(revision 19)
@@ -0,0 +1,314 @@
+<?php
+
+/*
+ *  $Id: PropelConvertConfTask.php 1053 2008-05-28 09:45:48Z hans $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://propel.phpdb.org>.
+ */
+
+require_once 'phing/Task.php';
+require_once 'propel/phing/PropelDataModelTemplateTask.php';
+require_once 'propel/engine/builder/om/OMBuilder.php';
+include_once 'propel/engine/builder/om/ClassTools.php';
+
+/**
+ * This Task converts the XML runtime configuration file into a PHP array for faster performance.
+ *
+ * @author     Hans Lellelid <hans@xmpl.org>
+ * @package    propel.phing
+ */
+class PropelConvertConfTask extends AbstractPropelDataModelTask {
+
+	/**
+	 * @var        PhingFile The XML runtime configuration file to be converted.
+	 */
+	private $xmlConfFile;
+
+	/**
+	 * @var        string This is the file where the converted conf array dump will be placed.
+	 */
+	private $outputFile;
+
+	/**
+	 * @var        string This is the file where the classmap manifest converted conf array dump will be placed.
+	 */
+	private $outputClassmapFile;
+
+	/**
+	 * [REQUIRED] Set the input XML runtime conf file.
+	 * @param      PhingFile $v The XML runtime configuration file to be converted.
+	 */
+	public function setXmlConfFile(PhingFile $v)
+	{
+		$this->xmlConfFile = $v;
+	}
+
+	/**
+	 * [REQUIRED] Set the output filename for the converted runtime conf.
+	 * The directory is specified using AbstractPropelDataModelTask#setOutputDirectory().
+	 * @param      string $outputFile
+	 * @see        AbstractPropelDataModelTask#setOutputDirectory()
+	 */
+	public function setOutputFile($outputFile)
+	{
+		// this is a string, not a file
+		$this->outputFile = $outputFile;
+	}
+
+	/**
+	 * [REQUIRED] Set the output filename for the autoload classmap.
+	 * The directory is specified using AbstractPropelDataModelTask#setOutputDirectory().
+	 * @param      string $outputFile
+	 * @see        AbstractPropelDataModelTask#setOutputDirectory()
+	 */
+	public function setOutputClassmapFile($outputFile)
+	{
+		// this is a string, not a file
+		$this->outputClassmapFile = $outputFile;
+	}
+
+	/**
+	 * The main method does the work of the task.
+	 */
+	public function main()
+	{
+		// Check to make sure the input and output files were specified and that the input file exists.
+
+		if (!$this->xmlConfFile || !$this->xmlConfFile->exists()) {
+			throw new BuildException("No valid xmlConfFile specified.", $this->getLocation());
+		}
+
+		if (!$this->outputFile) {
+			throw new BuildException("No outputFile specified.", $this->getLocation());
+		}
+
+		if (!$this->outputClassmapFile) {
+			// We'll create a default one for BC
+			$this->outputClassmapFile = 'classmap-' . $this->outputFile;
+		}
+
+		// Create a PHP array from the XML file
+
+		$xmlDom = new DOMDocument();
+		$xmlDom->load($this->xmlConfFile->getAbsolutePath());
+		$xml = simplexml_load_string($xmlDom->saveXML());
+
+		$phpconf = self::simpleXmlToArray($xml);
+		$phpconfClassmap = array();
+
+		// $this->log(var_export($phpconf,true));
+
+		// Create a map of all PHP classes and their filepaths for this data model
+
+		$generatorConfig = $this->getGeneratorConfig();
+
+		foreach ($this->getDataModels() as $dataModel) {
+
+			foreach ($dataModel->getDatabases() as $database) {
+
+				$classMap = array();
+
+				// $this->log("Processing class mappings in database: " . $database->getName());
+
+				//print the tables
+				foreach ($database->getTables() as $table) {
+
+					if (!$table->isForReferenceOnly()) {
+
+						// $this->log("\t+ " . $table->getName());
+
+						// Classes that I'm assuming do not need to be mapped (because they will be required by subclasses):
+						//	- base peer and object classes
+						//	- interfaces
+						//	- base node peer and object classes
+
+						// -----------------------------------------------------------------------------------------
+						// Add Peer & Object stub classes and MapBuilder classes
+						// -----------------------------------------------------------------------------------------
+						// (this code is based on PropelOMTask)
+
+						foreach (array('mapbuilder', 'peerstub', 'objectstub') as $target) {
+							$builder = $generatorConfig->getConfiguredBuilder($table, $target);
+							$this->log("Adding class mapping: " . $builder->getClassname() . ' => ' . $builder->getClassFilePath());
+							$classMap[$builder->getClassname()] = $builder->getClassFilePath();
+						}
+
+						if ($table->getChildrenColumn()) {
+							$col = $table->getChildrenColumn();
+							if ($col->isEnumeratedClasses()) {
+								foreach ($col->getChildren() as $child) {
+									$builder = $generatorConfig->getConfiguredBuilder($table, 'objectmultiextend');
+									$builder->setChild($child);
+									$this->log("Adding class mapping: " . $builder->getClassname() . ' => ' . $builder->getClassFilePath());
+									$classMap[$builder->getClassname()] = $builder->getClassFilePath();
+								}
+							}
+						}
+
+						$baseClass = $table->getBaseClass();
+						if ( $baseClass !== null ) {
+							$className = ClassTools::classname($baseClass);
+							if (!isset($classMap[$className])) {
+								$classPath = ClassTools::getFilePath($baseClass);
+								$this->log('Adding class mapping: ' . $className . ' => ' . $classPath);
+								$classMap[$className] = $classPath;
+							}
+						}
+
+						$basePeer = $table->getBasePeer();
+						if ( $basePeer !== null ) {
+							$className = ClassTools::classname($basePeer);
+							if (!isset($classMap[$className])) {
+								$classPath = ClassTools::getFilePath($basePeer);
+								$this->log('Adding class mapping: ' . $className . ' => ' . $classPath);
+								$classMap[$className] = $classPath;
+							}
+						}
+						
+						// -----------------------------------------------------------------------------------------
+						// Create tree Node classes
+						// -----------------------------------------------------------------------------------------
+
+						if ('MaterializedPath' == $table->treeMode()) {
+							foreach (array('nodepeerstub', 'nodestub') as $target) {
+								$builder = $generatorConfig->getConfiguredBuilder($table, $target);
+								$this->log("Adding class mapping: " . $builder->getClassname() . ' => ' . $builder->getClassFilePath());
+								$classMap[$builder->getClassname()] = $builder->getClassFilePath();
+							}
+						} // if Table->treeMode() == 'MaterializedPath'
+
+					} // if (!$table->isReferenceOnly())
+				}
+
+				$phpconfClassmap['propel']['datasources'][$database->getName()]['classes'] = $classMap;
+			}
+		}
+
+		//		$phpconf['propel']['classes'] = $classMap;
+
+		$phpconf['propel']['generator_version'] = $this->getGeneratorConfig()->getBuildProperty('version');
+
+		// Write resulting PHP data to output file:
+
+		$outfile = new PhingFile($this->outputDirectory, $this->outputFile);
+
+		$output = '<' . '?' . "php\n";
+		$output .= "// This file generated by Propel " . $phpconf['propel']['generator_version'] . " convert-props target".($this->getGeneratorConfig()->getBuildProperty('addTimestamp') ? " on " . strftime("%c") : '') . "\n";
+		$output .= "// from XML runtime conf file " . $this->xmlConfFile->getPath() . "\n";
+		$output .= "return array_merge_recursive(";
+		$output .= var_export($phpconf, true);
+		$output .= ", include(dirname(__FILE__) . DIRECTORY_SEPARATOR . '".$this->outputClassmapFile."'));";
+
+		$this->log("Creating PHP runtime conf file: " . $outfile->getPath());
+		if (!file_put_contents($outfile->getAbsolutePath(), $output)) {
+			throw new BuildException("Error creating output file: " . $outfile->getAbsolutePath(), $this->getLocation());
+		}
+
+		$outfile = new PhingFile($this->outputDirectory, $this->outputClassmapFile);
+		$output = '<' . '?' . "php\n";
+		$output .= "// This file generated by Propel " . $phpconf['propel']['generator_version'] . " convert-props target".($this->getGeneratorConfig()->getBuildProperty('addTimestamp') ? " on " . strftime("%c") : '') . "\n";
+		$output .= "return ";
+		$output .= var_export($phpconfClassmap, true);
+		$output .= ";";
+		$this->log("Creating PHP classmap runtime file: " . $outfile->getPath());
+		if (!file_put_contents($outfile->getAbsolutePath(), $output)) {
+			throw new BuildException("Error creating output file: " . $outfile->getAbsolutePath(), $this->getLocation());
+		}
+
+
+	} // main()
+
+	/**
+	 * Recursive function that converts an SimpleXML object into an array.
+	 * @author     Christophe VG (based on code form php.net manual comment)
+	 * @param      object SimpleXML object.
+	 * @return     array Array representation of SimpleXML object.
+	 */
+	private static function simpleXmlToArray($xml)
+	{
+		$ar = array();
+
+		foreach ( $xml->children() as $k => $v ) {
+
+			// recurse the child
+			$child = self::simpleXmlToArray( $v );
+
+			//print "Recursed down and found: " . var_export($child, true) . "\n";
+
+			// if it's not an array, then it was empty, thus a value/string
+			if ( count($child) == 0 ) {
+				$child = self::getConvertedXmlValue($v);
+
+			}
+
+			// add the childs attributes as if they where children
+			foreach ( $v->attributes() as $ak => $av ) {
+
+				// if the child is not an array, transform it into one
+				if ( !is_array( $child ) ) {
+					$child = array( "value" => $child );
+				}
+
+				if ($ak == 'id') {
+					// special exception: if there is a key named 'id'
+					// then we will name the current key after that id
+					$k = self::getConvertedXmlValue($av);
+				} else {
+					// otherwise, just add the attribute like a child element
+					$child[$ak] = self::getConvertedXmlValue($av);
+				}
+			}
+
+			// if the $k is already in our children list, we need to transform
+			// it into an array, else we add it as a value
+			if ( !in_array( $k, array_keys($ar) ) ) {
+				$ar[$k] = $child;
+			} else {
+				// (This only applies to nested nodes that do not have an @id attribute)
+
+				// if the $ar[$k] element is not already an array, then we need to make it one.
+				// this is a bit of a hack, but here we check to also make sure that if it is an
+				// array, that it has numeric keys.  this distinguishes it from simply having other
+				// nested element data.
+
+				if ( !is_array($ar[$k]) || !isset($ar[$k][0]) ) { $ar[$k] = array($ar[$k]); }
+				$ar[$k][] = $child;
+			}
+
+		}
+
+		return $ar;
+	}
+
+	/**
+	 * Process XML value, handling boolean, if appropriate.
+	 * @param      object The simplexml value object.
+	 * @return     mixed
+	 */
+	private static function getConvertedXmlValue($value)
+	{
+		$value = (string) $value; // convert from simplexml to string
+		// handle booleans specially
+		$lwr = strtolower($value);
+		if ($lwr === "false") {
+			$value = false;
+		} elseif ($lwr === "true") {
+			$value = true;
+		}
+		return $value;
+	}
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/phing/PropelCreoleTransformTask.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/phing/PropelCreoleTransformTask.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/phing/PropelCreoleTransformTask.php	(revision 19)
@@ -0,0 +1,829 @@
+<?php
+
+/*
+ *  $Id: PropelCreoleTransformTask.php 989 2008-03-11 14:29:30Z heltem $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://propel.phpdb.org>.
+ */
+
+require_once 'phing/Task.php';
+include_once 'propel/engine/database/model/PropelTypes.php';
+
+/**
+ * This class generates an XML schema of an existing database from
+ * Creole metadata.
+ *
+ * @author     Hans Lellelid <hans@xmpl.org> (Propel)
+ * @author     Jason van Zyl <jvanzyl@periapt.com> (Torque)
+ * @author     Fedor Karpelevitch <fedor.karpelevitch@barra.com> (Torque)
+ * @version    $Revision: 989 $
+ * @package    propel.phing
+ */
+class PropelCreoleTransformTask extends Task {
+
+	/** Name of XML database schema produced. */
+	protected $xmlSchema;
+
+	/** Creole URL. */
+	protected $dbUrl;
+
+	/** Creole driver. */
+	protected $dbDriver;
+
+	/** Creole user name. */
+	protected $dbUser;
+
+	/** Creole password. */
+	protected $dbPassword;
+
+	/** DB encoding to use */
+	protected $dbEncoding = 'iso-8859-1';
+
+	/** DB schema to use. */
+	protected $dbSchema;
+
+	/** parsed DB DSN */
+	protected $dsn;
+
+	/** DOM document produced. */
+	protected $doc;
+
+	/** The document root element. */
+	protected $databaseNode;
+
+	/** Hashtable of columns that have primary keys. */
+	protected $primaryKeys;
+
+	/** Hashtable to track what table a column belongs to. */
+	// doesn't seem to be used
+	// protected $columnTableMap;
+
+	/** whether to use same name for phpName or not */
+	protected $samePhpName;
+
+	/** whether to add vendor info or not */
+	protected $addVendorInfo;
+
+	/**
+	 * Bitfield to switch on/off which validators will be created.
+	 *
+	 * @var        int
+	 */
+	protected $validatorBits;
+
+	/**
+	 * Collect validatorInfos to create validators.
+	 *
+	 * @var        int
+	 */
+	protected $validatorInfos;
+
+	/**
+	 * Zero bit for no validators
+	 */
+	const VALIDATORS_NONE = 0;
+
+	/**
+	 * Bit for maxLength validator
+	 */
+	const VALIDATORS_MAXLENGTH = 1;
+
+	/**
+	 * Bit for maxValue validator
+	 */
+	const VALIDATORS_MAXVALUE = 2;
+
+	/**
+	 * Bit for type validator
+	 */
+	const VALIDATORS_TYPE = 4;
+
+	/**
+	 * Bit for required validator
+	 */
+	const VALIDATORS_REQUIRED = 8;
+
+	/**
+	 * Bit for unique validator
+	 */
+	const VALIDATORS_UNIQUE = 16;
+
+	/**
+	 * Bit for all validators
+	 */
+	const VALIDATORS_ALL = 255;
+
+	/**
+	 * Maps validator type tokens to bits
+	 *
+	 * The tokens are used in the propel.addValidators property to define
+	 * which validators are to be added
+	 *
+	 * @static
+	 * @var        array
+	 */
+	static protected $validatorBitMap = array (
+		'none' => PropelCreoleTransformTask::VALIDATORS_NONE,
+		'maxlength' => PropelCreoleTransformTask::VALIDATORS_MAXLENGTH,
+		'maxvalue' => PropelCreoleTransformTask::VALIDATORS_MAXVALUE,
+		'type' => PropelCreoleTransformTask::VALIDATORS_TYPE,
+		'required' => PropelCreoleTransformTask::VALIDATORS_REQUIRED,
+		'unique' => PropelCreoleTransformTask::VALIDATORS_UNIQUE,
+		'all' => PropelCreoleTransformTask::VALIDATORS_ALL,
+	);
+
+	/**
+	 * Defines messages that are added to validators
+	 *
+	 * @static
+	 * @var        array
+	 */
+	static protected $validatorMessages = array (
+		'maxlength' => array (
+			'msg' => 'The field %s must be not longer than %s characters.',
+			'var' => array('colName', 'value')
+	),
+		'maxvalue' => array (
+			'msg' => 'The field %s must be not greater than %s.',
+			'var' => array('colName', 'value')
+	),
+		'type' => array (
+			'msg' => 'The field %s is not a valid value.',
+			'var' => array('colName')
+	),
+		'required' => array (
+			'msg' => 'The field %s is required.',
+			'var' => array('colName')
+	),
+		'unique' => array (
+			'msg' => 'This %s already exists in table %s.',
+			'var' => array('colName', 'tableName')
+	),
+	);
+
+	public function getDbSchema()
+	{
+		return $this->dbSchema;
+	}
+
+	public function setDbSchema($dbSchema)
+	{
+		$this->dbSchema = $dbSchema;
+	}
+
+	public function setDbUrl($v)
+	{
+		$this->dbUrl = $v;
+	}
+
+	public function setDbDriver($v)
+	{
+		$this->dbDriver = $v;
+	}
+
+	public function setDbUser($v)
+	{
+		$this->dbUser = $v;
+	}
+
+	public function setDbPassword($v)
+	{
+		$this->dbPassword = $v;
+	}
+
+	public function setDbEncoding($v)
+	{
+		$this->dbEncoding = $v;
+	}
+
+	public function setOutputFile($v)
+	{
+		$this->xmlSchema = $v;
+	}
+
+	public function setSamePhpName($v)
+	{
+		$this->samePhpName = $v;
+	}
+
+	public function setAddVendorInfo($v)
+	{
+		$this->addVendorInfo = (boolean) $v;
+	}
+
+	/**
+	 * Sets set validator bitfield from a comma-separated list of "validator bit" names.
+	 *
+	 * @param      string $v The comma-separated list of which validators to add.
+	 * @return     void
+	 */
+	public function setAddValidators($v)
+	{
+		$validKeys = array_keys(self::$validatorBitMap);
+
+		// lowercase input
+		$v = strtolower($v);
+
+		$bits = self::VALIDATORS_NONE;
+
+		$exprs = explode(',', $v);
+		foreach ($exprs as $expr) {
+			$expr = trim($expr);
+			if (!isset(self::$validatorBitMap[$expr])) {
+				throw new BuildException("Unable to interpret validator in expression ('$v'): " . $expr);
+			}
+			$bits |= self::$validatorBitMap[$expr];
+		}
+
+		$this->validatorBits = $bits;
+	}
+
+	public function isSamePhpName()
+	{
+		return $this->samePhpName;
+	}
+
+	/**
+	 * Default constructor.
+	 * @return     void
+	 * @throws     BuildException
+	 */
+	public function main()
+	{
+		include_once 'creole/Creole.php';
+		if (!class_exists('Creole')) {
+			throw new BuildException( get_class($this) . " task depends on Creole classes being on include_path. (i.e. include of 'creole/Creole.php' failed.)", $this->getLocation());
+		}
+
+		$this->log("Propel - CreoleToXMLSchema starting");
+		$this->log("Your DB settings are:");
+		$this->log("driver : " . ($this->dbDriver ? $this->dbDriver : "(default)"));
+		$this->log("URL : " . $this->dbUrl);
+
+		//(not yet supported) $this->log("schema : " . $this->dbSchema);
+		//DocumentTypeImpl docType = new DocumentTypeImpl(null, "database", null,
+		//	   "http://jakarta.apache.org/turbine/dtd/database.dtd");
+
+		$this->doc = new DOMDocument('1.0', 'utf-8');
+		$this->doc->formatOutput = true; // pretty printing
+
+		$this->doc->appendChild($this->doc->createComment("Autogenerated by CreoleToXMLSchema!"));
+
+		try {
+			$this->generateXML();
+			$this->log("Writing XML to file: " . $this->xmlSchema);
+			$outFile = new PhingFile($this->xmlSchema);
+			$out = new FileWriter($outFile);
+			$xmlstr = $this->doc->saveXML();
+			$out->write($xmlstr);
+			$out->close();
+		} catch (Exception $e) {
+			$this->log("There was an error building XML from metadata: " . $e->getMessage(), Project::MSG_ERR);
+		}
+		$this->log("Propel - CreoleToXMLSchema finished");
+	}
+
+	/**
+	 * Generates an XML database schema from Creole metadata.
+	 *
+	 * @return     void
+	 * @throws     Exception a generic exception.
+	 */
+	public function generateXML()
+	{
+		// Establish db connection
+		$con = $this->getConnection();
+
+		// Get the database Metadata.
+		$dbInfo = $con->getDatabaseInfo();
+
+		// create and add the database node
+		$databaseNode = $this->createDatabaseNode($dbInfo);
+		$this->doc->appendChild($databaseNode);
+	}
+
+	/**
+	 * Establishes a Creole database connection
+	 *
+	 * @return     object The connection
+	 */
+	protected function getConnection() {
+
+		// Attemtp to connect to a database.
+		$this->dsn = Creole::parseDSN($this->dbUrl);
+		if ($this->dbUser) {
+			$this->dsn["username"] = $this->dbUser;
+		}
+		if ($this->dbPassword) {
+			$this->dsn["password"] = $this->dbPassword;
+		}
+		if ($this->dbDriver) {
+			Creole::registerDriver($this->dsn['phptype'], $this->dbDriver);
+		}
+		$con = Creole::getConnection($this->dsn);
+		$this->log("DB connection established");
+
+		return $con;
+	}
+
+	/**
+	 * Creates a database node
+	 *
+	 * @param      object $dbInfo The dbInfo for this db
+	 * @return     object The database node instance
+	 */
+	protected function createDatabaseNode($dbInfo) {
+
+		$this->log("Processing database");
+
+		$node = $this->doc->createElement("database");
+		$node->setAttribute("name", $dbInfo->getName());
+
+		if ($vendorNode = $this->createVendorInfoNode($dbInfo->getVendorSpecificInfo())) {
+			$node->appendChild($vendorNode);
+		}
+
+		// create and add table nodes
+		foreach ($dbInfo->getTables() as $table) {
+			$tableNode = $this->createTableNode($table);
+			$node->appendChild($tableNode);
+		}
+
+		return $node;
+	}
+
+	/**
+	 * Creates a table node
+	 *
+	 * @param      object $table The table
+	 * @return     object The table node instance
+	 */
+	protected function createTableNode($table) {
+
+		$this->log("Processing table: " . $table->toString());
+
+		$node = $this->doc->createElement("table");
+		$node->setAttribute("name", $table->getName());
+		if ($this->isSamePhpName()) {
+			$node->setAttribute("phpName", $table->getName());
+		}
+		if ($vendorNode = $this->createVendorInfoNode($table->getVendorSpecificInfo())) {
+			$node->appendChild($vendorNode);
+		}
+
+		// Create and add column nodes, register column validators
+		$columns = $table->getColumns();
+		foreach ($columns as $column) {
+			$columnNode = $this->createColumnNode($column);
+			$node->appendChild($columnNode);
+			$this->registerValidatorsForColumn($column);
+			if ($column->isAutoIncrement()) {
+				$idMethod = 'native';
+			}
+		}
+		if (isset($idMethod)) {
+			$node->setAttribute("idMethod", $idMethod);
+		}
+
+		// Create and add foreign key nodes.
+		$foreignKeys = $table->getForeignKeys();
+		foreach ($foreignKeys as $foreignKey) {
+			$foreignKeyNode = $this->createForeignKeyNode($foreignKey);
+			$node->appendChild($foreignKeyNode);
+		}
+
+		// Create and add index nodes.
+		$indices =  $table->getIndices();
+		foreach ($indices as $index) {
+			$indexNode = $this->createIndexNode($index);
+			$node->appendChild($indexNode);
+		}
+
+		// add an id-method-parameter if we have a sequence that matches table_colname_seq
+		//
+		//
+		$pkey = $table->getPrimaryKey();
+		if ($pkey) {
+			$cols = $pkey->getColumns();
+			if (count($cols) === 1) {
+				$col = array_shift($cols);
+				if ($col->isAutoIncrement()) {
+					$seq_name = $table->getName().'_'.$col->getName().'_seq';
+					if ($table->getDatabase()->isSequence($seq_name)) {
+						$idMethodParameterNode = $this->doc->createElement("id-method-parameter");
+						$idMethodParameterNode->setAttribute("value", $seq_name);
+						$node->appendChild($idMethodParameterNode);
+					}
+				}
+			}
+		}
+
+
+		// Create and add validator and rule nodes.
+		$nodes = array();
+		$tableName = $table->getName();
+		if (isset($this->validatorInfos[$tableName])) {
+			foreach ($this->validatorInfos[$tableName] as $colName => $rules) {
+				$column = $table->getColumn($colName);
+				$colName = $column->getName();
+				foreach ($rules as $rule) {
+					if (!isset($nodes[$colName])) {
+						$nodes[$colName] = $this->createValidator($column, $rule['type']);
+						$node->appendChild($nodes[$colName]);
+					}
+					$ruleNode = $this->createRuleNode($column, $rule);
+					$nodes[$colName]->appendChild($ruleNode);
+				}
+			}
+		}
+
+		return $node;
+	}
+
+	/**
+	 * Returns the Propel type for given Creole type.
+	 *
+	 * This used to be part of the PropelTypes class when Creole was an integral
+	 * part of the Propel build process.  As of Propel 1.3, though, this method
+	 * is only needed in this reverse-engineering code.
+	 *
+	 * @param      int $creoleType Creole type (e.g. CreoleTypes::CHAR)
+	 * @return     string Equivalent Propel type (e.g. PropelTypes::CHAR)
+	 */
+	protected static function getMappedPropelType($creoleType)
+	{
+		static $creoleToPropelTypeMap;
+		if ($creoleToPropelTypeMap === null) {
+			$creoleToPropelTypeMap = array();
+			$creoleToPropelTypeMap[CreoleTypes::CHAR] = PropelTypes::CHAR;
+			$creoleToPropelTypeMap[CreoleTypes::VARCHAR] = PropelTypes::VARCHAR;
+			$creoleToPropelTypeMap[CreoleTypes::LONGVARCHAR] = PropelTypes::LONGVARCHAR;
+			$creoleToPropelTypeMap[CreoleTypes::CLOB] = PropelTypes::CLOB;
+			$creoleToPropelTypeMap[CreoleTypes::NUMERIC] = PropelTypes::NUMERIC;
+			$creoleToPropelTypeMap[CreoleTypes::DECIMAL] = PropelTypes::DECIMAL;
+			$creoleToPropelTypeMap[CreoleTypes::TINYINT] = PropelTypes::TINYINT;
+			$creoleToPropelTypeMap[CreoleTypes::SMALLINT] = PropelTypes::SMALLINT;
+			$creoleToPropelTypeMap[CreoleTypes::INTEGER] = PropelTypes::INTEGER;
+			$creoleToPropelTypeMap[CreoleTypes::BIGINT] = PropelTypes::BIGINT;
+			$creoleToPropelTypeMap[CreoleTypes::REAL] = PropelTypes::REAL;
+			$creoleToPropelTypeMap[CreoleTypes::FLOAT] = PropelTypes::FLOAT;
+			$creoleToPropelTypeMap[CreoleTypes::DOUBLE] = PropelTypes::DOUBLE;
+			$creoleToPropelTypeMap[CreoleTypes::BINARY] = PropelTypes::BINARY;
+			$creoleToPropelTypeMap[CreoleTypes::VARBINARY] = PropelTypes::VARBINARY;
+			$creoleToPropelTypeMap[CreoleTypes::LONGVARBINARY] = PropelTypes::LONGVARBINARY;
+			$creoleToPropelTypeMap[CreoleTypes::BLOB] = PropelTypes::BLOB;
+			$creoleToPropelTypeMap[CreoleTypes::DATE] = PropelTypes::DATE;
+			$creoleToPropelTypeMap[CreoleTypes::TIME] = PropelTypes::TIME;
+			$creoleToPropelTypeMap[CreoleTypes::TIMESTAMP] = PropelTypes::TIMESTAMP;
+			$creoleToPropelTypeMap[CreoleTypes::BOOLEAN] = PropelTypes::BOOLEAN;
+			$creoleToPropelTypeMap[CreoleTypes::YEAR] = PropelTypes::INTEGER;
+		}
+
+		if (isset($creoleToPropelTypeMap[$creoleType])) {
+			return $creoleToPropelTypeMap[$creoleType];
+		}
+	}
+
+	/**
+	 * Creates an column node
+	 *
+	 * @param      object $column The Creole column
+	 * @return     object The column node instance
+	 */
+	protected function createColumnNode($column) {
+
+		$node = $this->doc->createElement("column");
+
+		$table = $column->getTable();
+		$colName = $column->getName();
+		$colType = $column->getType();
+		$colSize = $column->getSize();
+		$colScale = $column->getScale();
+
+		if ($colType === CreoleTypes::OTHER) {
+			$this->log("Column [" . $table->getName() . "." . $colName . "] has a column type (".$column->getNativeType().") that Propel does not support.", Project::MSG_WARN);
+		}
+
+		$node->setAttribute("name", $colName);
+
+		if ($this->isSamePhpName()) {
+			$node->setAttribute("phpName", $colName);
+		}
+
+		$node->setAttribute("type", self::getMappedPropelType($colType));
+
+		if ($colSize > 0 && (
+		$colType == CreoleTypes::CHAR
+		|| $colType == CreoleTypes::VARCHAR
+		|| $colType == CreoleTypes::LONGVARCHAR
+		|| $colType == CreoleTypes::DECIMAL
+		|| $colType == CreoleTypes::FLOAT
+		|| $colType == CreoleTypes::NUMERIC)) {
+			$node->setAttribute("size", (string) $colSize);
+		}
+
+		if ($colScale > 0 && (
+		$colType == CreoleTypes::DECIMAL
+		|| $colType == CreoleTypes::FLOAT
+		|| $colType == CreoleTypes::NUMERIC)) {
+			$node->setAttribute("scale", (string) $colScale);
+		}
+
+		if (!$column->isNullable()) {
+			$node->setAttribute("required", "true");
+		}
+
+		if ($column->isAutoIncrement()) {
+			$node->setAttribute("autoIncrement", "true");
+		}
+
+		if (in_array($colName, $this->getTablePkCols($table))) {
+			$node->setAttribute("primaryKey", "true");
+		}
+
+		if (($defValue = $column->getDefaultValue()) !== null) {
+			$node->setAttribute("default", iconv($this->dbEncoding, 'utf-8', $defValue));
+		}
+
+		if ($vendorNode = $this->createVendorInfoNode($column->getVendorSpecificInfo())) {
+			$node->appendChild($vendorNode);
+		}
+
+		return $node;
+	}
+
+	/**
+	 * Returns the primary key columns for a table
+	 *
+	 * @param      object $table The table
+	 * @return     array The primary keys
+	 */
+	protected function getTablePkCols($table) {
+
+		static $columns = array();
+
+		$tableName = $table->getName();
+		if (!isset($columns[$tableName])) {
+			$columns[$tableName] = array();
+			$primaryKey = $table->getPrimaryKey();
+			if ($primaryKey) {
+				foreach ($primaryKey->getColumns() as $colObject) {
+					$columns[$tableName][] = $colObject->getName();
+				}
+			}
+		}
+		return $columns[$tableName];
+	}
+
+	/**
+	 * Creates an foreign key node
+	 *
+	 * @param      object $foreignKey The foreign key
+	 * @return     object The foreign key node instance
+	 */
+	protected function createForeignKeyNode($foreignKey) {
+
+		$node = $this->doc->createElement("foreign-key");
+		if ($vendorNode = $this->createVendorInfoNode($foreignKey->getVendorSpecificInfo())) {
+			$node->appendChild($vendorNode);
+		}
+
+		$refs = $foreignKey->getReferences();
+		// all references must be to same table, so we can grab table from the first, foreign column
+		$node->setAttribute("foreignTable", $refs[0][1]->getTable()->getName());
+		$node->setAttribute("onDelete", $refs[0][2]);
+		$node->setAttribute("onUpdate", $refs[0][3]);
+		for ($m = 0, $size = count($refs); $m < $size; $m++) {
+			$refNode = $this->doc->createElement("reference");
+			$refData = $refs[$m];
+			$refNode->setAttribute("local", $refData[0]->getName());
+			$refNode->setAttribute("foreign", $refData[1]->getName());
+			$node->appendChild($refNode);
+		}
+
+		return $node;
+	}
+
+	/**
+	 * Creates an index node
+	 *
+	 * @param      object $index The index
+	 * @return     object The index node instance
+	 */
+	protected function createIndexNode($index) {
+
+		$indexType = $index->isUnique() ?  'unique' : 'index';
+
+		$node = $this->doc->createElement($indexType);
+		$node->setAttribute("name", $index->getName());
+
+		$columns = $index->getColumns();
+		foreach ($columns as $column) {
+			$tableName = $column->getTable()->getName();
+			$colName = $column->getName();
+			$columnNode = $this->doc->createElement("{$indexType}-column");
+			$columnNode->setAttribute("name", $colName);
+			$node->appendChild($columnNode);
+			if ($indexType == 'unique' && $this->isValidatorRequired('unique')) {
+				$this->validatorInfos[$tableName][$colName][] = array('type' => 'unique');
+			}
+		}
+
+		if ($vendorNode = $this->createVendorInfoNode($index->getVendorSpecificInfo())) {
+			$node->appendChild($vendorNode);
+		}
+
+		return $node;
+	}
+
+	/**
+	 * Checks whether to add validators of specified type or not
+	 *
+	 * @param      int $type The validator type constant.
+	 * @return     boolean
+	 */
+	protected function isValidatorRequired($type) {
+		return (($this->validatorBits & $type) === $type);
+	}
+
+	/**
+	 * Registers column type specific validators if necessary
+	 *
+	 * We'll first collect the validators/rule infos and add them later on to
+	 * have them appended to the table tag as a block.
+	 *
+	 * CreoleTypes are:
+	 *
+	 * 		BOOLEAN
+	 * 		BIGINT, SMALLINT, TINYINT, INTEGER
+	 * 		FLOAT, DOUBLE, NUMERIC, DECIMAL, REAL
+	 * 		BIGINT, SMALLINT, TINYINT, INTEGER
+	 * 		TEXT
+	 * 		BLOB, CLOB, BINARY, VARBINARY, LONGVARBINARY
+	 * 		DATE, YEAR, TIME
+	 * 		TIMESTAMP
+	 *
+	 * We will add the following type specific validators:
+	 *
+	 *      for notNull columns: required validator
+	 *      for unique indexes: unique validator
+	 * 		for varchar types: maxLength validators (CHAR, VARCHAR, LONGVARCHAR)
+	 * 		for numeric types: maxValue validators (BIGINT, SMALLINT, TINYINT, INTEGER, FLOAT, DOUBLE, NUMERIC, DECIMAL, REAL)
+	 * 		for integer and timestamp types: notMatch validator with [^\d]+ (BIGINT, SMALLINT, TINYINT, INTEGER, TIMESTAMP)
+	 * 		for float types: notMatch validator with [^\d\.]+ (FLOAT, DOUBLE, NUMERIC, DECIMAL, REAL)
+	 *
+	 * @param      object $column The Creole column
+	 * @return     void
+	 * @todo       find out how to evaluate the appropriate size and adjust maxValue rule values appropriate
+	 * @todo       find out if float type column values must always notMatch('[^\d\.]+'), i.e. digits and point for any db vendor, language etc.
+	 */
+	protected function registerValidatorsForColumn($column) {
+
+		$table = $column->getTable();
+		$tableName = $table->getName();
+
+		$colName = $column->getName();
+		$colType = $column->getType();
+		$colSize = $column->getSize();
+
+		if ($this->isValidatorRequired(self::VALIDATORS_REQUIRED)) {
+			$ruleInfo = array('type' => 'required');
+			$this->validatorInfos[$tableName][$colName][] = $ruleInfo;
+		}
+		$isPrimarykeyCol = in_array($colName, $this->getTablePkCols($table));
+		if ($this->isValidatorRequired(self::VALIDATORS_UNIQUE) && $isPrimarykeyCol) {
+			$ruleInfo = array('type' => 'unique');
+			$this->validatorInfos[$tableName][$colName][] = $ruleInfo;
+		}
+		if ($this->isValidatorRequired(self::VALIDATORS_MAXLENGTH) &&
+		$colSize > 0 && in_array($colType, array(
+		CreoleTypes::CHAR,
+		CreoleTypes::VARCHAR,
+		CreoleTypes::LONGVARCHAR))) {
+			$ruleInfo = array('type' => 'maxLength', 'value' => $colSize);
+			$this->validatorInfos[$tableName][$colName][] = $ruleInfo;
+		}
+		if ($this->isValidatorRequired(self::VALIDATORS_MAXVALUE) &&
+		$colSize > 0 && in_array($colType, array(
+		CreoleTypes::SMALLINT,
+		CreoleTypes::TINYINT,
+		CreoleTypes::INTEGER,
+		CreoleTypes::BIGINT,
+		CreoleTypes::FLOAT,
+		CreoleTypes::DOUBLE,
+		CreoleTypes::NUMERIC,
+		CreoleTypes::DECIMAL,
+		CreoleTypes::REAL))) {
+
+			// TODO: how to evaluate the appropriate size??
+			$this->log("WARNING: maxValue validator added for column $colName. You will have to adjust the size value manually.", Project::MSG_WARN);
+			$ruleInfo = array('type' => 'maxValue', 'value' => $colSize);
+			$this->validatorInfos[$tableName][$colName][] = $ruleInfo;
+		}
+		if ($this->isValidatorRequired(self::VALIDATORS_TYPE) &&
+		$colSize > 0 && in_array($colType, array(
+		CreoleTypes::SMALLINT,
+		CreoleTypes::TINYINT,
+		CreoleTypes::INTEGER,
+		CreoleTypes::TIMESTAMP))) {
+			$ruleInfo = array('type' => 'type', 'value' => '[^\d]+');
+			$this->validatorInfos[$tableName][$colName][] = $ruleInfo;
+		}
+		if ($this->isValidatorRequired(self::VALIDATORS_TYPE) &&
+		$colSize > 0 && in_array($colType, array(
+		CreoleTypes::FLOAT,
+		CreoleTypes::DOUBLE,
+		CreoleTypes::NUMERIC,
+		CreoleTypes::DECIMAL,
+		CreoleTypes::REAL))) {
+			// TODO: is this always true??
+			$ruleInfo = array('type' => 'type', 'value' => '[^\d\.]+');
+			$this->validatorInfos[$tableName][$colName][] = $ruleInfo;
+		}
+	}
+
+	/**
+	 * Creates a validator node
+	 *
+	 * @param      object  $column    The Creole column
+	 * @param      integer $type      The validator type
+	 * @return     object The validator node instance
+	 */
+	protected function createValidator($column, $type) {
+
+		$node = $this->doc->createElement('validator');
+		$node->setAttribute('column', $column->getName());
+
+		return $node;
+	}
+
+	/**
+	 * Creates a rule node
+	 *
+	 * @param      object  $column The Creole column
+	 * @param      array   $rule   The rule info
+	 * @return     object The rule node instance
+	 */
+	protected function createRuleNode($column, $rule) {
+
+		extract($rule);
+
+		// create message
+		$colName = $column->getName();
+		$tableName = $column->getTable()->getName();
+		$msg = self::$validatorMessages[strtolower($type)];
+		$tmp = compact($msg['var']);
+		array_unshift($tmp, $msg['msg']);
+		$msg = call_user_func_array('sprintf', $tmp);
+
+		// add node
+		$node = $this->doc->createElement('rule');
+		$node->setAttribute('name', $type == 'type' ? 'notMatch' : $type);
+		$node->setAttribute('message', $msg);
+
+		return $node;
+	}
+
+	/**
+	 * Creates a vendor info node
+	 *
+	 * returns false if no vendor info can or has to be added
+	 *
+	 * @param      array   $vendorInfo The validator info
+	 * @return     object|boolean The vendor info instance or false
+	 */
+	protected function createVendorInfoNode($vendorInfo)
+	{
+		if (!$vendorInfo OR !$this->addVendorInfo) {
+			return false;
+		}
+
+		$vendorNode = $this->doc->createElement("vendor");
+		$vendorNode->setAttribute("type", $this->dsn["phptype"]);
+
+		foreach ($vendorInfo as $key => $value) {
+			$parameterNode = $this->doc->createElement("parameter");
+			$value = iconv($this->dbEncoding, "utf-8", $value);
+			$parameterNode->setAttribute("name", $key);
+			$parameterNode->setAttribute("value", $value);
+			$vendorNode->appendChild($parameterNode);
+		}
+
+		return $vendorNode;
+	}
+
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/phing/PropelDataDTDTask.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/phing/PropelDataDTDTask.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/phing/PropelDataDTDTask.php	(revision 19)
@@ -0,0 +1,80 @@
+<?php
+
+/*
+ *  $Id: PropelDataDTDTask.php 521 2007-01-05 13:29:36Z heltem $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://propel.phpdb.org>.
+ */
+
+require_once 'propel/phing/PropelDataModelTemplateTask.php';
+include_once 'propel/engine/builder/om/ClassTools.php';
+
+/**
+ * This Task creates the OM classes based on the XML schema file.
+ *
+ * @author     Hans Lellelid <hans@xmpl.org>
+ * @package    propel.phing
+ */
+class PropelDataDTDTask extends PropelDataModelTemplateTask {
+
+
+	public function main() {
+
+		// check to make sure task received all correct params
+		$this->validate();
+
+		if (!$this->mapperElement) {
+			throw new BuildException("You must use a <mapper/> element to describe how names should be transformed.");
+		}
+
+		$basepath = $this->getOutputDirectory();
+
+		// Get new Capsule context
+		$generator = $this->createContext();
+		$generator->put("basepath", $basepath); // make available to other templates
+
+		// we need some values that were loaded into the template context
+		$basePrefix = $generator->get('basePrefix');
+		$project = $generator->get('project');
+
+		foreach ($this->getDataModels() as $dataModel) {
+
+			$this->log("Processing Datamodel : " . $dataModel->getName());
+
+			foreach ($dataModel->getDatabases() as $database) {
+
+				$outFile = $this->getMappedFile($dataModel->getName());
+
+				$generator->put("tables", $database->getTables());
+				$generator->parse("data/dtd/dataset.tpl", $outFile->getAbsolutePath());
+
+				$this->log("Generating DTD for database: " . $database->getName());
+				$this->log("Creating DTD file: " . $outFile->getPath());
+
+				foreach ($database->getTables() as $tbl) {
+					$this->log("\t + " . $tbl->getName());
+					$generator->put("table", $tbl);
+					$generator->parse("data/dtd/table.tpl", $outFile->getAbsolutePath(), true);
+				}
+
+			} // foreach database
+
+		} // foreach dataModel
+
+
+	} // main()
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/phing/PropelDataDumpTask.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/phing/PropelDataDumpTask.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/phing/PropelDataDumpTask.php	(revision 19)
@@ -0,0 +1,365 @@
+<?php
+
+/*
+ *  $Id: PropelDataDumpTask.php 989 2008-03-11 14:29:30Z heltem $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://propel.phpdb.org>.
+ */
+
+/**
+ * Dumps the contenst of selected databases to XML data dump file.
+ *
+ * The generated XML files can have corresponding DTD files generated using the
+ * PropelDataDTDTask.  The results of the data dump can be converted to SQL using
+ * the PropelDataSQLTask class.
+ *
+ * The database may be specified (via 'databaseName' attribute) if you only want to dump
+ * the contents of one database.  Otherwise it is assumed that all databases described
+ * by datamodel schema file(s) will be dumped.
+ *
+ * @author     Hans Lellelid <hans@xmpl.org> (Propel)
+ * @author     Fedor Karpelevitch <fedor.karpelevitch@home.com> (Torque)
+ * @author     Jason van Zyl <jvanzyl@zenplex.com> (Torque)
+ * @author     Daniel Rall <dlr@finemaltcoding.com> (Torque)
+ * @version    $Revision: 989 $
+ * @package    propel.phing
+ */
+class PropelDataDumpTask extends AbstractPropelDataModelTask {
+
+	/**
+	 * Database name.
+	 * The database name may be optionally specified in the XML if you only want
+	 * to dump the contents of one database.
+	 */
+	private $databaseName;
+
+	/**
+	 * Database URL used for Creole connection.
+	 * This is a PEAR-compatible (loosely) DSN URL.
+	 */
+	private $databaseUrl;
+
+	/**
+	 * Database driver used for Creole connection.
+	 * This should normally be left blank so that default (Creole built-in) driver for database type is used.
+	 */
+	private $databaseDriver;
+
+	/**
+	 * Database user used for Creole connection.
+	 * @deprecated Put username in databaseUrl.
+	 */
+	private $databaseUser;
+
+	/**
+	 * Database password used for Creole connection.
+	 * @deprecated Put password in databaseUrl.
+	 */
+	private $databasePassword;
+
+	/**
+	 * Properties file that maps a data XML file to a particular database.
+	 * @var        PhingFile
+	 */
+	private $datadbmap;
+
+	/**
+	 * The database connection used to retrieve the data to dump.
+	 * Needs to be public so that the TableInfo class can access it.
+	 */
+	public $conn;
+
+	/**
+	 * The statement used to acquire the data to dump.
+	 */
+	private $stmt;
+
+	/**
+	 * Set the file that maps between data XML files and databases.
+	 *
+	 * @param      PhingFile $sqldbmap the db map
+	 * @return     void
+	 */
+	public function setDataDbMap(PhingFile $datadbmap)
+	{
+		$this->datadbmap = $datadbmap;
+	}
+
+	/**
+	 * Get the file that maps between data XML files and databases.
+	 *
+	 * @return     PhingFile $datadbmap.
+	 */
+	public function getDataDbMap()
+	{
+		return $this->datadbmap;
+	}
+
+	/**
+	 * Get the database name to dump
+	 *
+	 * @return     The DatabaseName value
+	 */
+	public function getDatabaseName()
+	{
+		return $this->databaseName;
+	}
+
+	/**
+	 * Set the database name
+	 *
+	 * @param      v The new DatabaseName value
+	 */
+	public function setDatabaseName($v)
+	{
+		$this->databaseName = $v;
+	}
+
+	/**
+	 * Get the database url
+	 *
+	 * @return     The DatabaseUrl value
+	 */
+	public function getDatabaseUrl()
+	{
+		return $this->databaseUrl;
+	}
+
+	/**
+	 * Set the database url
+	 *
+	 * @param      string $v The PEAR-compatible database DSN URL.
+	 */
+	public function setDatabaseUrl($v)
+	{
+		$this->databaseUrl = $v;
+	}
+
+	/**
+	 * Get the database user
+	 *
+	 * @return     string database user
+	 * @deprecated
+	 */
+	public function getDatabaseUser()
+	{
+		return $this->databaseUser;
+	}
+
+	/**
+	 * Set the database user
+	 *
+	 * @param      string $v The new DatabaseUser value
+	 * @deprecated Specify user in DSN URL.
+	 */
+	public function setDatabaseUser($v)
+	{
+		$this->databaseUser = $v;
+	}
+
+	/**
+	 * Get the database password
+	 *
+	 * @return     string database password
+	 */
+	public function getDatabasePassword()
+	{
+		return $this->databasePassword;
+	}
+
+	/**
+	 * Set the database password
+	 *
+	 * @param      string $v The new DatabasePassword value
+	 * @deprecated Specify database password in DSN URL.
+	 */
+	public function setDatabasePassword($v)
+	{
+		$this->databasePassword = $v;
+	}
+
+	/**
+	 * Get the database driver name
+	 *
+	 * @return     string database driver name
+	 */
+	public function getDatabaseDriver()
+	{
+		return $this->databaseDriver;
+	}
+
+	/**
+	 * Set the database driver name
+	 *
+	 * @param      string $v The new DatabaseDriver value
+	 */
+	public function setDatabaseDriver($v)
+	{
+		$this->databaseDriver = $v;
+	}
+
+	/**
+	 * Create the data XML -> database map.
+	 *
+	 * This is necessary because there is currently no other method of knowing which
+	 * data XML files correspond to which database.  This map allows us to convert multiple
+	 * data XML files into SQL.
+	 *
+	 * @throws     IOException - if unable to store properties
+	 */
+	private function createDataDbMap()
+	{
+		if ($this->getDataDbMap() === null) {
+			return;
+		}
+
+		// Produce the sql -> database map
+		$datadbmap = new Properties();
+
+		// Check to see if the sqldbmap has already been created.
+		if ($this->getDataDbMap()->exists()) {
+			$datadbmap->load($this->getDataDbMap());
+		}
+
+		foreach ($this->getDataModels() as $dataModel) {            // there is really one 1 db per datamodel
+			foreach ($dataModel->getDatabases() as $database) {
+
+				// if database name is specified, then we only want to dump that one db.
+				if (empty($this->databaseName) || ($this->databaseName && $database->getName() == $this->databaseName)) {
+					$outFile = $this->getMappedFile($dataModel->getName());
+					$datadbmap->setProperty($outFile->getName(), $database->getName());
+				}
+			}
+		}
+
+		try {
+			$datadbmap->store($this->getDataDbMap(), "Data XML file -> Database map");
+		} catch (IOException $e) {
+			throw new IOException("Unable to store properties: ". $e->getMessage());
+		}
+	}
+
+	/**
+	 * Iterates through each datamodel/database, dumps the contents of all tables and creates a DOM XML doc.
+	 *
+	 * @return     void
+	 * @throws     BuildException
+	 */
+	public function main()
+	{
+		$this->validate();
+
+		$buf = "Database settings:\n"
+			. " driver: " . ($this->databaseDriver ? $this->databaseDriver : "(default)" ). "\n"
+			. " URL: " . $this->databaseUrl . "\n"
+			. ($this->databaseUser ? " user: " . $this->databaseUser . "\n" : "")
+			. ($this->databasePassword ? " password: " . $this->databasePassword . "\n" : "");
+
+		$this->log($buf, Project::MSG_VERBOSE);
+
+		// 1) First create the Data XML -> database name map.
+		$this->createDataDbMap();
+
+		// 2) Now go create the XML files from teh database(s)
+		foreach ($this->getDataModels() as $dataModel) {            // there is really one 1 db per datamodel
+			foreach ($dataModel->getDatabases() as $database) {
+
+				// if database name is specified, then we only want to dump that one db.
+				if (empty($this->databaseName) || ($this->databaseName && $database->getName() == $this->databaseName)) {
+
+					$outFile = $this->getMappedFile($dataModel->getName());
+
+					$this->log("Dumping data to XML for database: " . $database->getName());
+					$this->log("Writing to XML file: " . $outFile->getName());
+
+					try {
+
+						$url = str_replace("@DB@", $database->getName(), $this->databaseUrl);
+
+						if ($url !== $this->databaseUrl) {
+							$this->log("New (resolved) URL: " . $url, Project::MSG_VERBOSE);
+						}
+
+						if (empty($url)) {
+							throw new BuildException("Unable to connect to database; no PDO connection URL specified.", $this->getLocation());
+						}
+
+						$this->conn = new PDO($url, $this->databaseUser, $this->databasePassword);
+						$this->conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
+
+						$doc = $this->createXMLDoc($database);
+						$doc->save($outFile->getAbsolutePath());
+
+					} catch (SQLException $se) {
+						$this->log("SQLException while connecting to DB: ". $se->getMessage(), Project::MSG_ERR);
+						throw new BuildException($se);
+					}
+				} // if databaseName && database->getName == databaseName
+			} // foreach database
+		} // foreach datamodel
+	}
+
+	/**
+	 * Gets PDOStatement of query to fetch all data from a table.
+	 * @param      string $tableName
+	 * @param      Platform $platform
+	 * @return     PDOStatement
+	 */
+	private function getTableDataStmt($tableName, Platform $platform)
+	{
+		return $this->conn->query("SELECT * FROM " . $platform->quoteIdentifier( $tableName ) );
+	}
+
+	/**
+	 * Creates a DOM document containing data for specified database.
+	 * @param      Database $database
+	 * @return     DOMDocument
+	 */
+	private function createXMLDoc(Database $database)
+	{
+		$doc = new DOMDocument('1.0', 'utf-8');
+		$doc->formatOutput = true; // pretty printing
+		$doc->appendChild($doc->createComment("Created by data/dump/Control.tpl template."));
+
+		$dsNode = $doc->createElement("dataset");
+		$dsNode->setAttribute("name", "all");
+		$doc->appendChild($dsNode);
+
+		$platform = $this->getGeneratorConfig()->getConfiguredPlatform($this->conn);
+
+		$this->log("Building DOM tree containing data from tables:");
+
+		foreach ($database->getTables() as $tbl) {
+			$this->log("\t+ " . $tbl->getName());
+			$stmt = $this->getTableDataStmt($tbl->getName(), $platform);
+			while ($row = $stmt->fetch()) {
+				$rowNode = $doc->createElement($tbl->getPhpName());
+				foreach ($tbl->getColumns() as $col) {
+					$cval = $row[$col->getName()];
+					if ($cval !== null) {
+						$rowNode->setAttribute($col->getPhpName(), iconv($this->dbEncoding, 'utf-8', $cval));
+					}
+				}
+				$dsNode->appendChild($rowNode);
+				unset($rowNode);
+			}
+			unset($stmt);
+		}
+
+		return $doc;
+	}
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/phing/PropelDataModelTemplateTask.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/phing/PropelDataModelTemplateTask.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/phing/PropelDataModelTemplateTask.php	(revision 19)
@@ -0,0 +1,228 @@
+<?php
+
+/*
+ *  $Id: PropelDataModelTemplateTask.php 952 2008-02-05 22:59:20Z hans $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://propel.phpdb.org>.
+ */
+
+require_once 'propel/phing/AbstractPropelDataModelTask.php';
+include_once 'propel/engine/database/model/AppData.php';
+include_once 'propel/engine/database/model/Database.php';
+include_once 'propel/engine/database/transform/XmlToAppData.php';
+
+/**
+ * A generic class that simply loads the data model and parses a control template.
+ *
+ * This class exists largely for compatibility with early Propel where this was
+ * a CapsuleTask subclass.  This class also makes it easy to quickly add some custom
+ * datamodel-based transformations (by allowing you to put the logic in the templates).
+ *
+ * @author     Hans Lellelid <hans@xmpl.org>
+ * @package    propel.phing
+ * @version    $Revision: 952 $
+ */
+class PropelDataModelTemplateTask extends AbstractPropelDataModelTask {
+
+	/**
+	 * This is the file where the generated text
+	 * will be placed.
+	 * @var        string
+	 */
+	protected $outputFile;
+
+	/**
+	 * Path where Capsule looks for templates.
+	 * @var        PhingFile
+	 */
+	protected $templatePath;
+
+	/**
+	 * This is the control template that governs the output.
+	 * It may or may not invoke the services of worker
+	 * templates.
+	 * @var        string
+	 */
+	protected $controlTemplate;
+
+	/**
+	 * [REQUIRED] Set the output file for the
+	 * generation process.
+	 * @param      string $outputFile (TODO: change this to File)
+	 * @return     void
+	 */
+	public function setOutputFile($outputFile) {
+		$this->outputFile = $outputFile;
+	}
+
+	/**
+	 * Get the output file for the
+	 * generation process.
+	 * @return     string
+	 */
+	public function getOutputFile() {
+		return $this->outputFile;
+	}
+
+	/**
+	 * [REQUIRED] Set the control template for the
+	 * generating process.
+	 * @param      string $controlTemplate
+	 * @return     void
+	 */
+	public function setControlTemplate ($controlTemplate) {
+		$this->controlTemplate = $controlTemplate;
+	}
+
+	/**
+	 * Get the control template for the
+	 * generating process.
+	 * @return     string
+	 */
+	public function getControlTemplate() {
+		return $this->controlTemplate;
+	}
+
+	/**
+	 * [REQUIRED] Set the path where Capsule will look
+	 * for templates using the file template
+	 * loader.
+	 * @return     void
+	 * @throws     Exception
+	 */
+	public function setTemplatePath($templatePath) {
+		$resolvedPath = "";
+		$tok = strtok($templatePath, ",");
+		while ( $tok ) {
+			// resolve relative path from basedir and leave
+			// absolute path untouched.
+			$fullPath = $this->project->resolveFile($tok);
+			$cpath = $fullPath->getCanonicalPath();
+			if ($cpath === false) {
+				$this->log("Template directory does not exist: " . $fullPath->getAbsolutePath());
+			} else {
+				$resolvedPath .= $cpath;
+			}
+			$tok = strtok(",");
+			if ( $tok ) {
+				$resolvedPath .= ",";
+			}
+		}
+		$this->templatePath = $resolvedPath;
+	 }
+
+	/**
+	 * Get the path where Velocity will look
+	 * for templates using the file template
+	 * loader.
+	 * @return     string
+	 */
+	public function getTemplatePath() {
+		return $this->templatePath;
+	}
+
+	/**
+	 * Creates a new Capsule context with some basic properties set.
+	 * (Capsule is a simple PHP encapsulation system -- aka a php "template" class.)
+	 * @return     Capsule
+	 */
+	protected function createContext() {
+
+		$context = new Capsule();
+
+		// Make sure the output directory exists, if it doesn't
+		// then create it.
+		$outputDir = new PhingFile($this->outputDirectory);
+		if (!$outputDir->exists()) {
+			$this->log("Output directory does not exist, creating: " . $outputDir->getAbsolutePath());
+			$outputDir->mkdirs();
+		}
+
+		// Place our set of data models into the context along
+		// with the names of the databases as a convenience for now.
+		$context->put("targetDatabase", $this->getTargetDatabase());
+		$context->put("targetPackage", $this->getTargetPackage());
+		$context->put("now", strftime("%c"));
+
+		$this->log("Target database type: " . $this->getTargetDatabase());
+		$this->log("Target package: " . $this->getTargetPackage());
+		$this->log("Using template path: " . $this->templatePath);
+		$this->log("Output directory: " . $this->getOutputDirectory());
+
+		$context->setTemplatePath($this->templatePath);
+		$context->setOutputDirectory($this->outputDirectory);
+
+		$this->populateContextProperties($context);
+
+		return $context;
+	}
+
+	/**
+	 * Adds the propel build properties to the passed Capsule context.
+	 *
+	 * @param      Capsule $context
+	 * @see        GeneratorConfig::getBuildProperties()
+	 */
+	public function populateContextProperties(Capsule $context)
+	{
+		foreach ($this->getGeneratorConfig()->getBuildProperties() as $key => $propValue) {
+			$this->log('Adding property ${' . $key . '} to context', Project::MSG_DEBUG);
+			$context->put($key, $propValue);
+		}
+	}
+
+	/**
+	 * Performs validation for single-file mode.
+	 * @throws     BuildException - if there are any validation errors
+	 */
+	protected function singleFileValidate()
+	{
+		parent::validate();
+
+		// Make sure the control template is set.
+		if ($this->controlTemplate === null) {
+			throw new BuildException("The control template needs to be defined!");
+		}
+		// Make sure there is an output file.
+		if ($this->outputFile === null) {
+			throw new BuildException("The output file needs to be defined!");
+		}
+
+	}
+
+	/**
+	 * Creates Capsule context and parses control template.
+	 * @return     void
+	 */
+	public function main()
+	{
+		$this->singleFileValidate();
+		$context = $this->createContext();
+
+		$context->put("dataModels", $this->getDataModels());
+
+		$path = $this->outputDirectory . DIRECTORY_SEPARATOR . $this->outputFile;
+		$this->log("Generating to file " . $path);
+
+		try {
+			$this->log("Parsing control template: " . $this->controlTemplate);
+			$context->parse($this->controlTemplate, $path);
+		} catch (Exception $ioe) {
+			throw new BuildException("Cannot write parsed template: ". $ioe->getMessage());
+		}
+	}
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/phing/PropelDataSQLTask.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/phing/PropelDataSQLTask.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/phing/PropelDataSQLTask.php	(revision 19)
@@ -0,0 +1,204 @@
+<?php
+
+/*
+ *  $Id: PropelDataSQLTask.php 989 2008-03-11 14:29:30Z heltem $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://propel.phpdb.org>.
+ */
+
+include_once 'propel/engine/database/model/AppData.php';
+include_once 'propel/engine/database/model/Database.php';
+include_once 'propel/engine/database/transform/XmlToAppData.php';
+include_once 'propel/engine/builder/util/transform/XmlToDataSQL.php';
+
+/**
+ * Task that transforms XML datadump files into files containing SQL INSERT statements.
+ *
+ * @author     Hans Lellelid <hans@xmpl.org> (Propel)
+ * @author     Jason van Zyl  <jvanzyl@periapt.com> (Torque)
+ * @author     John McNally  <jmcnally@collab.net> (Torque)
+ * @author     Fedor Karpelevitch  <fedor.karpelevitch@home.com> (Torque)
+ * @version    $Revision: 989 $
+ * @package    propel.phing
+ */
+class PropelDataSQLTask extends AbstractPropelDataModelTask {
+
+	/**
+	 * Properties file that maps an SQL file to a particular database.
+	 * @var        PhingFile
+	 */
+	private $sqldbmap;
+
+	/**
+	 * Properties file that maps a data XML file to a particular database.
+	 * @var        PhingFile
+	 */
+	private $datadbmap;
+
+	/**
+	 * The base directory in which to find data XML files.
+	 * @var        PhingFile
+	 */
+	private $srcDir;
+
+	/**
+	 * Set the file that maps between SQL files and databases.
+	 *
+	 * @param      PhingFile $sqldbmap the sql -> db map.
+	 * @return     void
+	 */
+	public function setSqlDbMap(PhingFile $sqldbmap)
+	{
+		$this->sqldbmap = $sqldbmap;
+	}
+
+	/**
+	 * Get the file that maps between SQL files and databases.
+	 *
+	 * @return     PhingFile sqldbmap.
+	 */
+	public function getSqlDbMap()
+	{
+		return $this->sqldbmap;
+	}
+
+	/**
+	 * Set the file that maps between data XML files and databases.
+	 *
+	 * @param      PhingFile $sqldbmap the db map
+	 * @return     void
+	 */
+	public function setDataDbMap(PhingFile $datadbmap)
+	{
+		$this->datadbmap = $datadbmap;
+	}
+
+	/**
+	 * Get the file that maps between data XML files and databases.
+	 *
+	 * @return     PhingFile $datadbmap.
+	 */
+	public function getDataDbMap()
+	{
+		return $this->datadbmap;
+	}
+
+	/**
+	 * Set the src directory for the data xml files listed in the datadbmap file.
+	 * @param      PhingFile $srcDir data xml source directory
+	 */
+	public function setSrcDir(PhingFile $srcDir)
+	{
+		$this->srcDir = $srcDir;
+	}
+
+	/**
+	 * Get the src directory for the data xml files listed in the datadbmap file.
+	 *
+	 * @return     PhingFile data xml source directory
+	 */
+	public function getSrcDir()
+	{
+		return $this->srcDir;
+	}
+
+	/**
+	 * Search through all data models looking for matching database.
+	 * @return     Database or NULL if none found.
+	 */
+	private function getDatabase($name)
+	{
+		foreach ($this->getDataModels() as $dm) {
+			foreach ($dm->getDatabases() as $db) {
+				if ($db->getName() == $name) {
+					return $db;
+				}
+			}
+		}
+	}
+
+	/**
+	 * Main method parses the XML files and creates SQL files.
+	 *
+	 * @return     void
+	 * @throws     Exception If there is an error parsing the data xml.
+	 */
+	public function main()
+	{
+		$this->validate();
+
+		$targetDatabase = $this->getTargetDatabase();
+
+		$platform = $this->getGeneratorConfig()->getConfiguredPlatform();
+
+		// Load the Data XML -> DB Name properties
+		$map = new Properties();
+		try {
+			$map->load($this->getDataDbMap());
+		} catch (IOException $ioe) {
+			throw new BuildException("Cannot open and process the datadbmap!", $ioe);
+		}
+
+		// Parse each file in the data -> db map
+		foreach ($map->keys() as $dataXMLFilename) {
+
+			$dataXMLFile = new PhingFile($this->srcDir, $dataXMLFilename);
+
+			// if file exists then proceed
+			if ($dataXMLFile->exists()) {
+
+				$dbname = $map->get($dataXMLFilename);
+
+				$db = $this->getDatabase($dbname);
+
+				if (!$db) {
+					throw new BuildException("Cannot find instantiated Database for name '$dbname' from datadbmap file.");
+				}
+
+				$db->setPlatform($platform);
+
+				$outFile = $this->getMappedFile($dataXMLFilename);
+				$sqlWriter = new FileWriter($outFile);
+
+				$this->log("Creating SQL from XML data dump file: " . $dataXMLFile->getAbsolutePath());
+
+				try {
+					$dataXmlParser = new XmlToDataSQL($db, $this->getGeneratorConfig(), $this->dbEncoding);
+					$dataXmlParser->transform($dataXMLFile, $sqlWriter);
+				} catch (Exception $e) {
+					throw new BuildException("Exception parsing data XML: " . $e->getMessage(), $x);
+				}
+
+				// Place the generated SQL file(s)
+				$p = new Properties();
+				if ($this->getSqlDbMap()->exists()) {
+					$p->load($this->getSqlDbMap());
+				}
+
+				$p->setProperty($outFile->getName(), $db->getName());
+				$p->store($this->getSqlDbMap(), "Sqlfile -> Database map");
+
+			} else {
+				$this->log("File '" . $dataXMLFile->getAbsolutePath()
+						. "' in datadbmap does not exist, so skipping it.", Project::MSG_WARN);
+			}
+
+		} // foreach data xml file
+
+	} // main()
+
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/phing/PropelGraphvizTask.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/phing/PropelGraphvizTask.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/phing/PropelGraphvizTask.php	(revision 19)
@@ -0,0 +1,181 @@
+<?php
+
+/*
+ *  $Id: PropelGraphvizTask.php 989 2008-03-11 14:29:30Z heltem $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://propel.phpdb.org>.
+ */
+
+require_once 'propel/phing/AbstractPropelDataModelTask.php';
+include_once 'propel/engine/database/model/AppData.php';
+
+/**
+ * A task to generate Graphviz dot files from Propel datamodel.
+ *
+ * @author     Mark Kimsal
+ * @version    $Revision: 989 $
+ * @package    propel.phing
+ */
+class PropelGraphvizTask extends AbstractPropelDataModelTask {
+
+	/**
+	 * The properties file that maps an SQL file to a particular database.
+	 * @var        PhingFile
+	 */
+	private $sqldbmap;
+
+	/**
+	 * Name of the database.
+	 */
+	private $database;
+
+	/**
+	 * Name of the output directory.
+	 */
+	private $outDir;
+
+
+	/**
+	 * Set the sqldbmap.
+	 * @param      PhingFile $sqldbmap The db map.
+	 */
+	public function setOutputDirectory(PhingFile $out)
+	{
+		if (!$out->exists()) {
+			$out->mkdirs();
+		}
+		$this->outDir = $out;
+	}
+
+
+	/**
+	 * Set the sqldbmap.
+	 * @param      PhingFile $sqldbmap The db map.
+	 */
+	public function setSqlDbMap(PhingFile $sqldbmap)
+	{
+		$this->sqldbmap = $sqldbmap;
+	}
+
+	/**
+	 * Get the sqldbmap.
+	 * @return     PhingFile $sqldbmap.
+	 */
+	public function getSqlDbMap()
+	{
+		return $this->sqldbmap;
+	}
+
+	/**
+	 * Set the database name.
+	 * @param      string $database
+	 */
+	public function setDatabase($database)
+	{
+		$this->database = $database;
+	}
+
+	/**
+	 * Get the database name.
+	 * @return     string
+	 */
+	public function getDatabase()
+	{
+		return $this->database;
+	}
+
+
+	public function main()
+	{
+
+		$count = 0;
+
+		$dotSyntax = '';
+
+		// file we are going to create
+
+		$dbMaps = $this->getDataModelDbMap();
+
+		foreach ($this->getDataModels() as $dataModel) {
+
+			$dotSyntax .= "digraph G {\n";
+			foreach ($dataModel->getDatabases() as $database) {
+
+				$this->log("db: " . $database->getName());
+
+				//print the tables
+				foreach ($database->getTables() as $tbl) {
+
+					$this->log("\t+ " . $tbl->getName());
+
+					++$count;
+					$dotSyntax .= 'node'.$tbl->getName().' [label="{<table>'.$tbl->getName().'|<cols>';
+
+					foreach ($tbl->getColumns() as $col) {
+						$dotSyntax .= $col->getName() . ' (' . $col->getType()  . ')';
+						if (count($col->getForeignKeys()) > 0) {
+							$dotSyntax .= ' [FK]';
+						} elseif ($col->isPrimaryKey()) {
+							$dotSyntax .= ' [PK]';
+						}
+						$dotSyntax .= '\l';
+					}
+					$dotSyntax .= '}", shape=record];';
+					$dotSyntax .= "\n";
+				}
+
+				//print the relations
+
+				$count = 0;
+				$dotSyntax .= "\n";
+				foreach ($database->getTables() as $tbl) {
+					++$count;
+
+					foreach ($tbl->getColumns() as $col) {
+						$fk = $col->getForeignKeys();
+						if ( count($fk) == 0 or $fk === null ) continue;
+						if ( count($fk) > 1 ) throw( new Exception("not sure what to do here...") );
+						$fk = $fk[0];   // try first one
+						$dotSyntax .= 'node'.$tbl->getName() .':cols -> node'.$fk->getForeignTableName() . ':table [label="' . $col->getName() . '=' . implode(',', $fk->getForeignColumns()) . ' "];';
+						$dotSyntax .= "\n";
+					}
+				}
+
+
+
+			} // foreach database
+			$dotSyntax .= "}\n";
+
+			$this->writeDot($dotSyntax,$this->outDir,$database->getName());
+
+		$dotSyntax = '';
+
+		} //foreach datamodels
+
+	} // main()
+
+
+	/**
+	 * probably insecure
+	 */
+	function writeDot($dotSyntax, PhingFile $outputDir, $baseFilename) {
+		$file = new PhingFile($outputDir, $baseFilename . '.schema.dot');
+		$this->log("Writing dot file to " . $file->getAbsolutePath());
+		file_put_contents($file->getAbsolutePath(), $dotSyntax);
+	}
+
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/phing/PropelOMTask.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/phing/PropelOMTask.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/phing/PropelOMTask.php	(revision 19)
@@ -0,0 +1,212 @@
+<?php
+
+/*
+ *  $Id: PropelOMTask.php 989 2008-03-11 14:29:30Z heltem $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://propel.phpdb.org>.
+ */
+
+require_once 'propel/phing/AbstractPropelDataModelTask.php';
+include_once 'propel/engine/builder/om/ClassTools.php';
+require_once 'propel/engine/builder/om/OMBuilder.php';
+
+/**
+ * This Task creates the OM classes based on the XML schema file.
+ *
+ * @author     Hans Lellelid <hans@xmpl.org>
+ * @package    propel.phing
+ */
+class PropelOMTask extends AbstractPropelDataModelTask {
+
+	/**
+	 * The platform (php4, php5, etc.) for which the om is being built.
+	 * @var        string
+	 */
+	private $targetPlatform;
+
+	/**
+	 * Sets the platform (php4, php5, etc.) for which the om is being built.
+	 * @param      string $v
+	 */
+	public function setTargetPlatform($v) {
+		$this->targetPlatform = $v;
+	}
+
+	/**
+	 * Gets the platform (php4, php5, etc.) for which the om is being built.
+	 * @return     string
+	 */
+	public function getTargetPlatform() {
+		return $this->targetPlatform;
+	}
+
+	/**
+	 * Utility method to create directory for package if it doesn't already exist.
+	 * @param      string $path The [relative] package path.
+	 * @throws     BuildException - if there is an error creating directories
+	 */
+	protected function ensureDirExists($path)
+	{
+		$f = new PhingFile($this->getOutputDirectory(), $path);
+		if (!$f->exists()) {
+			if (!$f->mkdirs()) {
+				throw new BuildException("Error creating directories: ". $f->getPath());
+			}
+		}
+	}
+
+	/**
+	 * Uses a builder class to create the output class.
+	 * This method assumes that the DataModelBuilder class has been initialized with the build properties.
+	 * @param      OMBuilder $builder
+	 * @param      boolean $overwrite Whether to overwrite existing files with te new ones (default is YES).
+	 * @todo       -cPropelOMTask Consider refactoring build() method into AbstractPropelDataModelTask (would need to be more generic).
+	 */
+	protected function build(OMBuilder $builder, $overwrite = true)
+	{
+
+		$path = $builder->getClassFilePath();
+		$this->ensureDirExists(dirname($path));
+
+		$_f = new PhingFile($this->getOutputDirectory(), $path);
+		if ($overwrite || !$_f->exists()) {
+			$this->log("\t\t-> " . $builder->getClassname() . " [builder: " . get_class($builder) . "]");
+			$script = $builder->build();
+			file_put_contents($_f->getAbsolutePath(), $script);
+			foreach ($builder->getWarnings() as $warning) {
+				$this->log($warning, Project::MSG_WARN);
+			}
+		} else {
+			$this->log("\t\t-> (exists) " . $builder->getClassname());
+		}
+
+	}
+
+	/**
+	 * Main method builds all the targets for a typical propel project.
+	 */
+	public function main()
+	{
+		// check to make sure task received all correct params
+		$this->validate();
+
+		$generatorConfig = $this->getGeneratorConfig();
+
+		foreach ($this->getDataModels() as $dataModel) {
+			$this->log("Processing Datamodel : " . $dataModel->getName());
+
+			foreach ($dataModel->getDatabases() as $database) {
+
+				$this->log("  - processing database : " . $database->getName());
+
+				foreach ($database->getTables() as $table) {
+
+					if (!$table->isForReferenceOnly()) {
+
+						$this->log("\t+ " . $table->getName());
+
+						// -----------------------------------------------------------------------------------------
+						// Create Peer, Object, and MapBuilder classes
+						// -----------------------------------------------------------------------------------------
+
+						// these files are always created / overwrite any existing files
+						foreach (array('peer', 'object', 'mapbuilder') as $target) {
+							$builder = $generatorConfig->getConfiguredBuilder($table, $target);
+							$this->build($builder);
+						}
+
+						// -----------------------------------------------------------------------------------------
+						// Create [empty] stub Peer and Object classes if they don't exist
+						// -----------------------------------------------------------------------------------------
+
+						// these classes are only generated if they don't already exist
+						foreach (array('peerstub', 'objectstub') as $target) {
+							$builder = $generatorConfig->getConfiguredBuilder($table, $target);
+							$this->build($builder, $overwrite=false);
+						}
+
+						// -----------------------------------------------------------------------------------------
+						// Create [empty] stub child Object classes if they don't exist
+						// -----------------------------------------------------------------------------------------
+
+						// If table has enumerated children (uses inheritance) then create the empty child stub classes if they don't already exist.
+						if ($table->getChildrenColumn()) {
+							$col = $table->getChildrenColumn();
+							if ($col->isEnumeratedClasses()) {
+								foreach ($col->getChildren() as $child) {
+									$builder = $generatorConfig->getConfiguredBuilder($table, 'objectmultiextend');
+									$builder->setChild($child);
+									$this->build($builder, $overwrite=false);
+								} // foreach
+							} // if col->is enumerated
+						} // if tbl->getChildrenCol
+
+
+						// -----------------------------------------------------------------------------------------
+						// Create [empty] Interface if it doesn't exist
+						// -----------------------------------------------------------------------------------------
+
+						// Create [empty] interface if it does not already exist
+						if ($table->getInterface()) {
+							$builder = $generatorConfig->getConfiguredBuilder($table, 'interface');
+							$this->build($builder, $overwrite=false);
+						}
+
+						// -----------------------------------------------------------------------------------------
+						// Create tree Node classes
+						// -----------------------------------------------------------------------------------------
+
+						if ($table->treeMode()) {
+							switch($table->treeMode()) {
+								case 'NestedSet':
+									foreach (array('nestedsetpeer', 'nestedset') as $target) {
+										$builder = $generatorConfig->getConfiguredBuilder($table, $target);
+										$this->build($builder);
+									}
+								break;
+
+								case 'MaterializedPath':
+									foreach (array('nodepeer', 'node') as $target) {
+										$builder = $generatorConfig->getConfiguredBuilder($table, $target);
+										$this->build($builder);
+									}
+
+									foreach (array('nodepeerstub', 'nodestub') as $target) {
+										$builder = $generatorConfig->getConfiguredBuilder($table, $target);
+										$this->build($builder, $overwrite=false);
+									}
+								break;
+
+								case 'AdjacencyList':
+									// No implementation for this yet.
+								default:
+								break;
+							}
+
+						} // if Table->treeMode()
+
+
+					} // if !$table->isForReferenceOnly()
+
+				} // foreach table
+
+			} // foreach database
+
+		} // foreach dataModel
+
+	} // main()
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/phing/PropelSQLExec.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/phing/PropelSQLExec.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/phing/PropelSQLExec.php	(revision 19)
@@ -0,0 +1,711 @@
+<?php
+
+/*
+ *  $Id: PropelSQLExec.php 1059 2008-06-04 03:22:13Z hans $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://propel.phpdb.org>.
+ */
+
+require_once 'phing/Task.php';
+
+/**
+ * Executes all SQL files referenced in the sqldbmap file against their mapped databases.
+ *
+ * This task uses an SQL -> Database map in the form of a properties
+ * file to insert each SQL file listed into its designated database.
+ *
+ * @author     Hans Lellelid <hans@xmpl.org>
+ * @author     Dominik del Bondio
+ * @author     Jeff Martin <jeff@custommonkey.org> (Torque)
+ * @author     Michael McCallum <gholam@xtra.co.nz> (Torque)
+ * @author     Tim Stephenson <tim.stephenson@sybase.com> (Torque)
+ * @author     Jason van Zyl <jvanzyl@apache.org> (Torque)
+ * @author     Martin Poeschl <mpoeschl@marmot.at> (Torque)
+ * @version    $Revision: 1059 $
+ * @package    propel.phing
+ */
+class PropelSQLExec extends Task {
+
+	private $goodSql = 0;
+	private $totalSql = 0;
+
+	const DELIM_ROW = "row";
+	const DELIM_NORMAL = "normal";
+
+	/**
+	 * The delimiter type indicating whether the delimiter will
+	 * only be recognized on a line by itself
+	 */
+	private $delimiterType = "normal"; // can't use constant just defined
+
+	//private static $delimiterTypes = array(DELIM_NORMAL, DELIM_ROW);
+	//private static $errorActions = array("continue", "stop", "abort");
+
+	/** PDO Database connection */
+	private $conn = null;
+
+	/** Autocommit flag. Default value is false */
+	private $autocommit = false;
+
+	/** DB url. */
+	private $url = null;
+
+	/** User name. */
+	private $userId = null;
+
+	/** Password */
+	private $password = null;
+
+	/** SQL input command */
+	private $sqlCommand = "";
+
+	/** SQL transactions to perform */
+	private $transactions = array();
+
+	/** SQL Statement delimiter */
+	private $delimiter = ";";
+
+	/** Print SQL results. */
+	private $print = false;
+
+	/** Print header columns. */
+	private $showheaders = true;
+
+	/** Results Output file. */
+	private $output = null;
+
+	/** RDBMS Product needed for this SQL. */
+	private $rdbms = null;
+
+	/** RDBMS Version needed for this SQL. */
+	private $version = null;
+
+	/** Action to perform if an error is found */
+	private $onError = "abort";
+
+	/** Encoding to use when reading SQL statements from a file */
+	private $encoding = null;
+
+	/** Src directory for the files listed in the sqldbmap. */
+	private $srcDir;
+
+	/** Properties file that maps an individual SQL file to a database. */
+	private $sqldbmap;
+
+	/**
+	 * Set the sqldbmap properties file.
+	 *
+	 * @param      sqldbmap filename for the sqldbmap
+	 */
+	public function setSqlDbMap($sqldbmap)
+	{
+		$this->sqldbmap = $this->project->resolveFile($sqldbmap);
+	}
+
+	/**
+	 * Get the sqldbmap properties file.
+	 *
+	 * @return     filename for the sqldbmap
+	 */
+	public function getSqlDbMap()
+	{
+		return $this->sqldbmap;
+	}
+
+	/**
+	 * Set the src directory for the sql files listed in the sqldbmap file.
+	 *
+	 * @param      PhingFile $srcDir sql source directory
+	 */
+	public function setSrcDir(PhingFile $srcDir)
+	{
+		$this->srcDir = $srcDir;
+	}
+
+	/**
+	 * Get the src directory for the sql files listed in the sqldbmap file.
+	 *
+	 * @return     PhingFile SQL Source directory
+	 */
+	public function getSrcDir()
+	{
+		return $this->srcDir;
+	}
+
+	/**
+	 * Set the sql command to execute
+	 *
+	 * @param      sql sql command to execute
+	 */
+	public function addText($sql)
+	{
+		$this->sqlCommand .= $sql;
+	}
+
+	/**
+	 * Set the DB connection url.
+	 *
+	 * @param      string $url connection url
+	 */
+	public function setUrl($url)
+	{
+		$this->url = $url;
+	}
+
+	/**
+	 * Set the user name for the DB connection.
+	 *
+	 * @param      string $userId database user
+	 * @deprecated Specify userid in the DSN URL.
+	 */
+	public function setUserid($userId)
+	{
+		$this->userId = $userId;
+	}
+
+	/**
+	 * Set the password for the DB connection.
+	 *
+	 * @param      string $password database password
+	 * @deprecated Specify password in the DSN URL.
+	 */
+	public function setPassword($password)
+	{
+		$this->password = $password;
+	}
+
+	/**
+	 * Set the autocommit flag for the DB connection.
+	 *
+	 * @param      boolean $autocommit the autocommit flag
+	 */
+	public function setAutoCommit($autocommit)
+	{
+		$this->autocommit = (boolean) $autocommit;
+	}
+
+	/**
+	 * Set the statement delimiter.
+	 *
+	 * <p>For example, set this to "go" and delimitertype to "ROW" for
+	 * Sybase ASE or MS SQL Server.</p>
+	 *
+	 * @param      string $delimiter
+	 */
+	public function setDelimiter($delimiter)
+	{
+		$this->delimiter = $delimiter;
+	}
+
+	/**
+	 * Set the Delimiter type for this sql task. The delimiter type takes two
+	 * values - normal and row. Normal means that any occurence of the delimiter
+	 * terminate the SQL command whereas with row, only a line containing just
+	 * the delimiter is recognized as the end of the command.
+	 *
+	 * @param      string $delimiterType
+	 */
+	public function setDelimiterType($delimiterType)
+	{
+		$this->delimiterType = $delimiterType;
+	}
+
+	/**
+	 * Set the print flag.
+	 *
+	 * @param      boolean $print
+	 */
+	public function setPrint($print)
+	{
+		$this->print = (boolean) $print;
+	}
+
+	/**
+	 * Set the showheaders flag.
+	 *
+	 * @param      boolean $showheaders
+	 */
+	public function setShowheaders($showheaders)
+	{
+		$this->showheaders = (boolean) $showheaders;
+	}
+
+	/**
+	 * Set the output file.
+	 *
+	 * @param      PhingFile $output
+	 */
+	public function setOutput(PhingFile $output)
+	{
+		$this->output = $output;
+	}
+
+	/**
+	 * Set the action to perform onerror
+	 *
+	 * @param      string $action
+	 */
+	public function setOnerror($action)
+	{
+		$this->onError = $action;
+	}
+
+	/**
+	 * Load the sql file and then execute it
+	 *
+	 * @throws     BuildException
+	 */
+	public function main()
+	{
+		$this->sqlCommand = trim($this->sqlCommand);
+
+		if ($this->sqldbmap === null || $this->getSqlDbMap()->exists() === false) {
+			throw new BuildException("You haven't provided an sqldbmap, or "
+					. "the one you specified doesn't exist: " . $this->sqldbmap->getPath());
+		}
+
+		if ($this->url === null) {
+			throw new BuildException("DSN url attribute must be set!");
+		}
+
+		$map = new Properties();
+
+		try {
+			$map->load($this->getSqlDbMap());
+		} catch (IOException $ioe) {
+			throw new BuildException("Cannot open and process the sqldbmap!");
+		}
+
+		$databases = array();
+
+		foreach ($map->keys() as $sqlfile) {
+
+			$database = $map->getProperty($sqlfile);
+
+			// Q: already there?
+			if (!isset($databases[$database])) {
+			// A: No.
+				$databases[$database] = array();
+			}
+
+			// We want to make sure that the base schemas
+			// are inserted first.
+			if (strpos($sqlfile, "schema.sql") !== false) {
+				// add to the beginning of the array
+				array_unshift($databases[$database], $sqlfile);
+			} else {
+				array_push($databases[$database], $sqlfile);
+			}
+		}
+
+		foreach ($databases as $db => $files) {
+			$transactions = array();
+
+			foreach ($files as $fileName) {
+
+				$file = new PhingFile($this->srcDir, $fileName);
+
+				if ($file->exists()) {
+					$this->log("Executing statements in file: " . $file->__toString());
+					$transaction = new PropelSQLExecTransaction($this);
+					$transaction->setSrc($file);
+					$transactions[] = $transaction;
+				} else {
+					$this->log("File '" . $file->__toString()
+							. "' in sqldbmap does not exist, so skipping it.");
+				}
+			}
+			$this->insertDatabaseSqlFiles($this->url, $db, $transactions);
+		}
+	}
+
+	/**
+	 * Take the base url, the target database and insert a set of SQL
+	 * files into the target database.
+	 *
+	 * @param      string $url
+	 * @param      string $database
+	 * @param      array $transactions
+	 */
+	private function insertDatabaseSqlFiles($url, $database, $transactions)
+	{
+		$url = str_replace("@DB@", $database, $url);
+		$this->log("Our new url -> " . $url);
+
+		try {
+
+			$buf = "Database settings:" . PHP_EOL
+			. " URL: " . $url . PHP_EOL
+			. ($this->userId ? " user: " . $this->userId . PHP_EOL : "")
+			. ($this->password ? " password: " . $this->password . PHP_EOL : "");
+
+			$this->log($buf, Project::MSG_VERBOSE);
+
+			// Set user + password to null if they are empty strings
+			if (!$this->userId) { $this->userId = null; }
+
+			if (!$this->password) { $this->password = null; }
+
+			$this->conn = new PDO($url, $this->userId, $this->password);
+			$this->conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
+
+			// $this->conn->setAutoCommit($this->autocommit);
+			// $this->statement = $this->conn->createStatement();
+
+			$out = null;
+
+			try {
+				if ($this->output !== null) {
+					$this->log("Opening PrintStream to output file " . $this->output->__toString(), Project::MSG_VERBOSE);
+					$out = new FileWriter($this->output);
+				}
+
+				// Process all transactions
+				for ($i=0,$size=count($transactions); $i < $size; $i++) {
+					$transactions[$i]->runTransaction($out);
+					if (!$this->autocommit) {
+						$this->log("Commiting transaction", Project::MSG_VERBOSE);
+						$this->conn->commit();
+					}
+				}
+			} catch (Exception $e) {
+				if ($out) $out->close();
+			}
+
+		} catch (IOException $e) {
+
+			if (!$this->autocommit && $this->conn !== null && $this->onError == "abort") {
+				try {
+					$this->conn->rollBack();
+				} catch (PDOException $ex) {
+					// do nothing.
+					System::println("Rollback failed.");
+				}
+			}
+			if ($this->statement) $this->statement = null; // close
+			throw new BuildException($e);
+		} catch (PDOException $e) {
+			if (!$this->autocommit && $this->conn !== null && $this->onError == "abort") {
+				try {
+					$this->conn->rollBack();
+				} catch (PDOException $ex) {
+					// do nothing.
+					System::println("Rollback failed");
+				}
+			}
+			if ($this->statement) $this->statement = null; // close
+			throw new BuildException($e);
+		}
+
+		   $this->statement = null; // close
+
+		$this->log($this->goodSql . " of " . $this->totalSql
+				. " SQL statements executed successfully");
+	}
+
+	/**
+	 * Read the statements from the .sql file and execute them.
+	 * Lines starting with '//', '--' or 'REM ' are ignored.
+	 *
+	 * Developer note:  must be public in order to be called from
+	 * sudo-"inner" class PropelSQLExecTransaction.
+	 *
+	 * @param      Reader $reader
+	 * @param      $out Optional output stream.
+	 * @throws     PDOException
+	 * @throws     IOException
+	 */
+	public function runStatements(Reader $reader, $out = null)
+	{
+		$sql = "";
+		$line = "";
+		$sqlBacklog = "";
+		$hasQuery = false;
+
+		$in = new BufferedReader($reader);
+
+		$parser['pointer'] = 0;
+		$parser['isInString'] = false;
+		$parser['stringQuotes'] = "";
+		$parser['backslashCount'] = 0;
+		$parser['parsedString'] = "";
+
+		$sqlParts = array();
+
+		while (($line = $in->readLine()) !== null) {
+
+			$line = trim($line);
+			$line = ProjectConfigurator::replaceProperties($this->project, $line,
+			$this->project->getProperties());
+
+			if (StringHelper::startsWith("//", $line)
+				|| StringHelper::startsWith("--", $line)
+		 		|| StringHelper::startsWith("#", $line)) {
+				continue;
+			}
+
+			if (strlen($line) > 4 && strtoupper(substr($line,0, 4)) == "REM ") {
+				continue;
+			}
+
+			if ($sqlBacklog !== "") {
+				$sql = $sqlBacklog;
+				$sqlBacklog = "";
+			}
+
+			$sql .= " " . $line . PHP_EOL;
+
+			// SQL defines "--" as a comment to EOL
+			// and in Oracle it may contain a hint
+			// so we cannot just remove it, instead we must end it
+			if (strpos($line, "--") !== false) {
+				$sql .= PHP_EOL;
+			}
+
+			// DELIM_ROW doesn't need this (as far as i can tell)
+			if ($this->delimiterType == self::DELIM_NORMAL) {
+
+				// old regex, being replaced due to segfaults:
+				// See: http://propel.phpdb.org/trac/ticket/294
+				//$reg = "#((?:\"(?:\\\\.|[^\"])*\"?)+|'(?:\\\\.|[^'])*'?|" . preg_quote($this->delimiter) . ")#";
+				//$sqlParts = preg_split($reg, $sql, 0, PREG_SPLIT_DELIM_CAPTURE);
+
+				$i = $parser['pointer'];
+				$c = strlen($sql);
+				while ($i < $c) {
+
+					$char = $sql[$i];
+
+					switch($char) {
+						case "\\":
+							$parser['backslashCount']++;
+							$this->log("c$i: found ".$parser['backslashCount']." backslash(es)", Project::MSG_VERBOSE);
+							break;
+						case "'":
+						case "\"":
+							if ($parser['isInString'] && $parser['stringQuotes'] == $char) {
+								if (($parser['backslashCount'] & 1) == 0) {
+									#$this->log("$i: out of string", Project::MSG_VERBOSE);
+									$parser['isInString'] = false;
+								} else {
+									$this->log("c$i: rejected quoted delimiter", Project::MSG_VERBOSE);
+								}
+
+							} elseif (!$parser['isInString']) {
+								$parser['stringQuotes']	= $char;
+								$parser['isInString'] = true;
+								#$this->log("$i: into string with $parser['stringQuotes']", Project::MSG_VERBOSE);
+							}
+							break;
+					}
+
+					if ($char == $this->delimiter && !$parser['isInString']) {
+						$this->log("c$i: valid end of command found!", Project::MSG_VERBOSE);
+						$sqlParts[] = $parser['parsedString'];
+						$sqlParts[] = $this->delimiter;
+						break;
+					}
+					$parser['parsedString'] .= $char;
+					if ($char !== "\\") {
+						if ($parser['backslashCount']) $this->log("$i: backslash reset", Project::MSG_VERBOSE);
+						$parser['backslashCount'] = 0;
+					}
+					$i++;
+					$parser['pointer']++;
+				}
+
+				$sqlBacklog = "";
+				foreach ($sqlParts as $sqlPart) {
+					// we always want to append, even if it's a delim (which will be stripped off later)
+					$sqlBacklog .= $sqlPart;
+
+					// we found a single (not enclosed by ' or ") delimiter, so we can use all stuff before the delim as the actual query
+					if ($sqlPart === $this->delimiter) {
+						$sql = $sqlBacklog;
+						$sqlBacklog = "";
+						$hasQuery = true;
+					}
+				}
+			}
+
+			if ($hasQuery || ($this->delimiterType == self::DELIM_ROW && $line == $this->delimiter)) {
+				// this assumes there is always a delimter on the end of the SQL statement.
+				$sql = StringHelper::substring($sql, 0, strlen($sql) - 1 - strlen($this->delimiter));
+				$this->log("SQL: " . $sql, Project::MSG_VERBOSE);
+				$this->execSQL($sql, $out);
+				$sql = "";
+				$hasQuery = false;
+
+				$parser['pointer'] = 0;
+				$parser['isInString'] = false;
+				$parser['stringQuotes'] = "";
+				$parser['backslashCount'] = 0;
+				$parser['parsedString'] = "";
+				$sqlParts = array();
+			}
+		}
+
+		// Catch any statements not followed by ;
+		if ($sql !== "") {
+			$this->execSQL($sql, $out);
+		}
+	}
+
+	/**
+	 * Exec the sql statement.
+	 *
+	 * @param      sql
+	 * @param      out
+	 * @throws     PDOException
+	 */
+	protected function execSQL($sql, $out = null)
+	{
+		// Check and ignore empty statements
+		if (trim($sql) == "") {
+			return;
+		}
+
+		try {
+			$this->totalSql++;
+
+			if (!$this->autocommit) $this->conn->beginTransaction();
+
+			$stmt = $this->conn->prepare($sql);
+			$stmt->execute();
+			$this->log($stmt->rowCount() . " rows affected", Project::MSG_VERBOSE);
+
+			if (!$this->autocommit) $this->conn->commit();
+
+			$this->goodSql++;
+		} catch (PDOException $e) {
+			$this->log("Failed to execute: " . $sql, Project::MSG_ERR);
+			if ($this->onError != "continue") {
+				throw $e;
+			}
+			$this->log($e->getMessage(), Project::MSG_ERR);
+		}
+	}
+
+	/**
+	 * print any results in the statement.
+	 *
+	 * @param      out
+	 * @throws     PDOException
+	 */
+	protected function printResults($out = null)
+	{
+		$rs = null;
+
+		do {
+			$rs = $this->statement->getResultSet();
+
+			if ($rs !== null) {
+
+				$this->log("Processing new result set.", Project::MSG_VERBOSE);
+
+				$line = "";
+
+				$colsprinted = false;
+
+				while ($rs->next()) {
+
+					if (!$colsprinted && $this->showheaders) {
+						$first = true;
+						foreach ($this->fields as $fieldName => $ignore) {
+							if ($first) $first = false; else $line .= ",";
+							$line .= $fieldName;
+						}
+					} // if show headers
+
+					$first = true;
+					foreach ($rs->fields as $columnValue) {
+
+						if ($columnValue != null) {
+							$columnValue = trim($columnValue);
+						}
+
+						if ($first) {
+							$first = false;
+						} else {
+							$line .= ",";
+						}
+						$line .= $columnValue;
+					}
+
+					if ($out !== null) {
+						$out->write($line);
+						$out->newLine();
+					}
+
+					System::println($line);
+					$line = "";
+				} // while rs->next()
+			}
+		} while ($this->statement->getMoreResults());
+		System::println();
+		if ($out !== null) $out->newLine();
+	}
+
+}
+
+/**
+ * "Inner" class that contains the definition of a new transaction element.
+ * Transactions allow several files or blocks of statements
+ * to be executed using the same Creole connection and commit
+ * operation in between.
+ * @package    propel.phing
+ */
+class PropelSQLExecTransaction {
+
+	private $tSrcFile = null;
+	private $tSqlCommand = "";
+	private $parent;
+
+	function __construct($parent)
+	{
+		// Parent is required so that we can log things ...
+		$this->parent = $parent;
+	}
+
+	public function setSrc(PhingFile $src)
+	{
+		$this->tSrcFile = $src;
+	}
+
+	public function addText($sql)
+	{
+		$this->tSqlCommand .= $sql;
+	}
+
+	/**
+	 * @throws     IOException, PDOException
+	 */
+	public function runTransaction($out = null)
+	{
+		if (!empty($this->tSqlCommand)) {
+			$this->parent->log("Executing commands", Project::MSG_INFO);
+			$this->parent->runStatements($this->tSqlCommand, $out);
+		}
+
+		if ($this->tSrcFile !== null) {
+			$this->parent->log("Executing file: " . $this->tSrcFile->getAbsolutePath(), Project::MSG_INFO);
+			$reader = new FileReader($this->tSrcFile);
+			$this->parent->runStatements($reader, $out);
+			$reader->close();
+		}
+	}
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/phing/PropelSQLTask.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/phing/PropelSQLTask.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/phing/PropelSQLTask.php	(revision 19)
@@ -0,0 +1,261 @@
+<?php
+
+/*
+ *  $Id: PropelSQLTask.php 989 2008-03-11 14:29:30Z heltem $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://propel.phpdb.org>.
+ */
+
+include_once 'propel/engine/database/model/AppData.php';
+
+/**
+ * The task for building SQL DDL based on the XML datamodel.
+ *
+ * This class uses the new DDLBuilder classes instead of the Capsule PHP templates.
+ *
+ * @author     Hans Lellelid <hans@xmpl.org>
+ * @package    propel.phing
+ */
+class PropelSQLTask extends AbstractPropelDataModelTask {
+
+	/**
+	 * The properties file that maps an SQL file to a particular database.
+	 * @var        PhingFile
+	 */
+	private $sqldbmap;
+
+	/**
+	 * Name of the database.
+	 */
+	private $database;
+
+	/**
+	 * Set the sqldbmap.
+	 * @param      PhingFile $sqldbmap The db map.
+	 */
+	public function setSqlDbMap(PhingFile $sqldbmap)
+	{
+		$this->sqldbmap = $sqldbmap;
+	}
+
+	/**
+	 * Get the sqldbmap.
+	 * @return     PhingFile $sqldbmap.
+	 */
+	public function getSqlDbMap()
+	{
+		return $this->sqldbmap;
+	}
+
+	/**
+	 * Set the database name.
+	 * @param      string $database
+	 */
+	public function setDatabase($database)
+	{
+		$this->database = $database;
+	}
+
+	/**
+	 * Get the database name.
+	 * @return     string
+	 */
+	public function getDatabase()
+	{
+		return $this->database;
+	}
+
+	/**
+	 * Create the sql -> database map.
+	 *
+	 * @throws     IOException - if unable to store properties
+	 */
+	protected function createSqlDbMap()
+	{
+		if ($this->getSqlDbMap() === null) {
+			return;
+		}
+
+		// Produce the sql -> database map
+		$sqldbmap = new Properties();
+
+		// Check to see if the sqldbmap has already been created.
+		if ($this->getSqlDbMap()->exists()) {
+			$sqldbmap->load($this->getSqlDbMap());
+		}
+
+		if ($this->packageObjectModel) {
+			// in this case we'll get the sql file name from the package attribute
+			$dataModels = $this->packageDataModels();
+			foreach ($dataModels as $package => $dataModel) {
+				foreach ($dataModel->getDatabases() as $database) {
+					$name = ($package ? $package . '.' : '') . 'schema.xml';
+					$sqlFile = $this->getMappedFile($name);
+					$sqldbmap->setProperty($sqlFile->getName(), $database->getName());
+				}
+			}
+		} else {
+			// the traditional way is to map the schema.xml filenames
+			$dmMap = $this->getDataModelDbMap();
+			foreach (array_keys($dmMap) as $dataModelName) {
+				$sqlFile = $this->getMappedFile($dataModelName);
+				if ($this->getDatabase() === null) {
+					$databaseName = $dmMap[$dataModelName];
+				} else {
+					$databaseName = $this->getDatabase();
+				}
+				$sqldbmap->setProperty($sqlFile->getName(), $databaseName);
+			}
+		}
+
+		try {
+			$sqldbmap->store($this->getSqlDbMap(), "Sqlfile -> Database map");
+		} catch (IOException $e) {
+			throw new IOException("Unable to store properties: ". $e->getMessage());
+		}
+	}
+
+	public function main() {
+
+		$this->validate();
+
+		if (!$this->mapperElement) {
+			throw new BuildException("You must use a <mapper/> element to describe how names should be transformed.");
+		}
+
+		if ($this->packageObjectModel) {
+			$dataModels = $this->packageDataModels();
+		} else {
+			$dataModels = $this->getDataModels();
+		}
+
+		// 1) first create a map of filenames to databases; this is used by other tasks like
+		// the SQLExec task.
+		$this->createSqlDbMap();
+
+		// 2) Now actually create the DDL based on the datamodel(s) from XML schema file.
+		$targetDatabase = $this->getTargetDatabase();
+
+		$generatorConfig = $this->getGeneratorConfig();
+
+		$builderClazz = $generatorConfig->getBuilderClassname('ddl');
+
+		foreach ($dataModels as $package => $dataModel) {
+
+			foreach ($dataModel->getDatabases() as $database) {
+
+				// Clear any start/end DLL
+				call_user_func(array($builderClazz, 'reset'));
+
+				// file we are going to create
+				if (!$this->packageObjectModel) {
+					$name = $dataModel->getName();
+				} else {
+					$name = ($package ? $package . '.' : '') . 'schema.xml';
+				}
+
+				$outFile = $this->getMappedFile($name);
+
+				$this->log("Writing to SQL file: " . $outFile->getPath());
+
+				// First add any "header" SQL
+				$ddl = call_user_func(array($builderClazz, 'getDatabaseStartDDL'));
+
+				foreach ($database->getTables() as $table) {
+
+					if (!$table->isSkipSql()) {
+						$builder = $generatorConfig->getConfiguredBuilder($table, 'ddl');
+						$this->log("\t+ " . $table->getName() . " [builder: " . get_class($builder) . "]");
+						$ddl .= $builder->build();
+						foreach ($builder->getWarnings() as $warning) {
+							$this->log($warning, Project::MSG_WARN);
+						}
+					} else {
+						$this->log("\t + (skipping) " . $table->getName());
+					}
+
+				} // foreach database->getTables()
+
+				// Finally check to see if there is any "footer" SQL
+				$ddl .= call_user_func(array($builderClazz, 'getDatabaseEndDDL'));
+
+				#var_dump($outFile->getAbsolutePath());
+				// Now we're done.  Write the file!
+				file_put_contents($outFile->getAbsolutePath(), $ddl);
+
+			} // foreach database
+		} //foreach datamodels
+
+	} // main()
+
+	/**
+	 * Packages the datamodels to one datamodel per package
+	 *
+	 * This applies only when the the packageObjectModel option is set. We need to
+	 * re-package the datamodels to allow the database package attribute to control
+	 * which tables go into which SQL file.
+	 *
+	 * @return     array The packaged datamodels
+	 */
+	protected function packageDataModels() {
+
+		static $packagedDataModels;
+
+		if (is_null($packagedDataModels)) {
+
+			$dataModels = $this->getDataModels();
+			$dataModel = array_shift($dataModels);
+			$packagedDataModels = array();
+
+			$platform = $this->getGeneratorConfig()->getConfiguredPlatform();
+
+			foreach ($dataModel->getDatabases() as $db) {
+				foreach ($db->getTables() as $table) {
+					$package = $table->getPackage();
+					if (!isset($packagedDataModels[$package])) {
+						$dbClone = $this->cloneDatabase($db);
+						$dbClone->setPackage($package);
+						$ad = new AppData($platform);
+						$ad->setName($dataModel->getName());
+						$ad->addDatabase($dbClone);
+						$packagedDataModels[$package] = $ad;
+					}
+					$packagedDataModels[$package]->getDatabase($db->getName())->addTable($table);
+				}
+			}
+		}
+
+		return $packagedDataModels;
+	}
+
+	protected function cloneDatabase($db) {
+
+		$attributes = array (
+			'name' => $db->getName(),
+			'baseClass' => $db->getBaseClass(),
+			'basePeer' => $db->getBasePeer(),
+			'defaultIdMethod' => $db->getDefaultIdMethod(),
+			'defaultPhpNamingMethod' => $db->getDefaultPhpNamingMethod(),
+			'defaultTranslateMethod' => $db->getDefaultTranslateMethod(),
+			'heavyIndexing' => $db->getHeavyIndexing(),
+		);
+
+		$clone = new Database();
+		$clone->loadFromXML($attributes);
+		return $clone;
+	}
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/phing/PropelSchemaReverseTask.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/phing/PropelSchemaReverseTask.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/classes/propel/phing/PropelSchemaReverseTask.php	(revision 19)
@@ -0,0 +1,556 @@
+<?php
+
+/*
+ *  $Id: PropelSchemaReverseTask.php 945 2008-01-30 02:14:46Z hans $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://propel.phpdb.org>.
+ */
+
+require_once 'phing/tasks/ext/pdo/PDOTask.php';
+include_once 'propel/engine/GeneratorConfig.php';
+include_once 'propel/engine/database/model/PropelTypes.php';
+
+/**
+ * This class generates an XML schema of an existing database from
+ * the database metadata.
+ *
+ * @author     Hans Lellelid <hans@xmpl.org>
+ * @version    $Revision: 945 $
+ * @package    propel.phing
+ */
+class PropelSchemaReverseTask extends PDOTask {
+
+	/**
+	 * Zero bit for no validators
+	 */
+	const VALIDATORS_NONE = 0;
+
+	/**
+	 * Bit for maxLength validator
+	 */
+	const VALIDATORS_MAXLENGTH = 1;
+
+	/**
+	 * Bit for maxValue validator
+	 */
+	const VALIDATORS_MAXVALUE = 2;
+
+	/**
+	 * Bit for type validator
+	 */
+	const VALIDATORS_TYPE = 4;
+
+	/**
+	 * Bit for required validator
+	 */
+	const VALIDATORS_REQUIRED = 8;
+
+	/**
+	 * Bit for unique validator
+	 */
+	const VALIDATORS_UNIQUE = 16;
+
+	/**
+	 * Bit for all validators
+	 */
+	const VALIDATORS_ALL = 255;
+
+	/**
+	 * File to contain XML database schema.
+	 * @var        PhingFIle
+	 */
+	protected $xmlSchema;
+
+	/**
+	 * DB encoding to use
+	 * @var        string
+	 */
+	protected $dbEncoding = 'iso-8859-1';
+
+	/**
+	 * DB schema to use.
+	 * @var        string
+	 */
+	protected $dbSchema;
+
+	/**
+	 * The datasource name (used for <database name=""> in schema.xml)
+	 *
+	 * @var        string
+	 */
+	protected $databaseName;
+
+	/**
+	 * DOM document produced.
+	 * @var        DOMDocument
+	 */
+	protected $doc;
+
+	/**
+	 * The document root element.
+	 * @var        DOMElement
+	 */
+	protected $databaseNode;
+
+	/**
+	 * Hashtable of columns that have primary keys.
+	 * @var        array
+	 */
+	protected $primaryKeys;
+
+	/**
+	 * Whether to use same name for phpName or not.
+	 * @var        boolean
+	 */
+	protected $samePhpName;
+
+	/**
+	 * whether to add vendor info or not
+	 * @var        boolean
+	 */
+	protected $addVendorInfo;
+
+	/**
+	 * Bitfield to switch on/off which validators will be created.
+	 *
+	 * @var        int
+	 */
+	protected $validatorBits = PropelSchemaReverseTask::VALIDATORS_NONE;
+
+	/**
+	 * Collect validatorInfos to create validators.
+	 *
+	 * @var        int
+	 */
+	protected $validatorInfos;
+
+	/**
+	 * An initialized GeneratorConfig object containing the converted Phing props.
+	 *
+	 * @var        GeneratorConfig
+	 */
+	private $generatorConfig;
+
+	/**
+	 * Maps validator type tokens to bits
+	 *
+	 * The tokens are used in the propel.addValidators property to define
+	 * which validators are to be added
+	 *
+	 * @var        array
+	 */
+	static protected $validatorBitMap = array (
+		'none' => PropelSchemaReverseTask::VALIDATORS_NONE,
+		'maxlength' => PropelSchemaReverseTask::VALIDATORS_MAXLENGTH,
+		'maxvalue' => PropelSchemaReverseTask::VALIDATORS_MAXVALUE,
+		'type' => PropelSchemaReverseTask::VALIDATORS_TYPE,
+		'required' => PropelSchemaReverseTask::VALIDATORS_REQUIRED,
+		'unique' => PropelSchemaReverseTask::VALIDATORS_UNIQUE,
+		'all' => PropelSchemaReverseTask::VALIDATORS_ALL,
+	);
+
+	/**
+	 * Defines messages that are added to validators
+	 *
+	 * @var        array
+	 */
+	static protected $validatorMessages = array (
+		'maxlength' => array (
+			'msg' => 'The field %s must be not longer than %s characters.',
+			'var' => array('colName', 'value')
+	),
+		'maxvalue' => array (
+			'msg' => 'The field %s must be not greater than %s.',
+			'var' => array('colName', 'value')
+	),
+		'type' => array (
+			'msg' => 'The column %s must be an %s value.',
+			'var' => array('colName', 'value')
+	),
+		'required' => array (
+			'msg' => 'The field %s is required.',
+			'var' => array('colName')
+	),
+		'unique' => array (
+			'msg' => 'This %s already exists in table %s.',
+			'var' => array('colName', 'tableName')
+	),
+	);
+
+	/**
+	 * Gets the (optional) schema name to use.
+	 *
+	 * @return     string
+	 */
+	public function getDbSchema()
+	{
+		return $this->dbSchema;
+	}
+
+	/**
+	 * Sets the name of a database schema to use (optional).
+	 *
+	 * @param      string $dbSchema
+	 */
+	public function setDbSchema($dbSchema)
+	{
+		$this->dbSchema = $dbSchema;
+	}
+
+	/**
+	 * Gets the database encoding.
+	 *
+	 * @return     string
+	 */
+	public function getDbEncoding($v)
+	{
+		return $this->dbEncoding;
+	}
+
+	/**
+	 * Sets the database encoding.
+	 *
+	 * @param      string $v
+	 */
+	public function setDbEncoding($v)
+	{
+		$this->dbEncoding = $v;
+	}
+
+	/**
+	 * Gets the datasource name.
+	 *
+	 * @return     string
+	 */
+	public function getDatabaseName()
+	{
+		return $this->databaseName;
+	}
+
+	/**
+	 * Sets the datasource name.
+	 *
+	 * This will be used as the <database name=""> value in the generated schema.xml
+	 *
+	 * @param      string $v
+	 */
+	public function setDatabaseName($v)
+	{
+		$this->databaseName = $v;
+	}
+
+	/**
+	 * Sets the output name for the XML file.
+	 *
+	 * @param      PhingFile $v
+	 */
+	public function setOutputFile(PhingFile $v)
+	{
+		$this->xmlSchema = $v;
+	}
+
+	/**
+	 * Set whether to use the column name as phpName without any translation.
+	 *
+	 * @param      boolean $v
+	 */
+	public function setSamePhpName($v)
+	{
+		$this->samePhpName = $v;
+	}
+
+	/**
+	 * Set whether to add vendor info to the schema.
+	 *
+	 * @param      boolean $v
+	 */
+	public function setAddVendorInfo($v)
+	{
+		$this->addVendorInfo = (boolean) $v;
+	}
+
+	/**
+	 * Sets set validator bitfield from a comma-separated list of "validator bit" names.
+	 *
+	 * @param      string $v The comma-separated list of which validators to add.
+	 * @return     void
+	 */
+	public function setAddValidators($v)
+	{
+		$validKeys = array_keys(self::$validatorBitMap);
+
+		// lowercase input
+		$v = strtolower($v);
+
+		$bits = self::VALIDATORS_NONE;
+
+		$exprs = explode(',', $v);
+		foreach ($exprs as $expr) {
+			$expr = trim($expr);
+			if(!empty($expr)) {
+  			if (!isset(self::$validatorBitMap[$expr])) {
+  				throw new BuildException("Unable to interpret validator in expression ('$v'): " . $expr);
+  			}
+  			$bits |= self::$validatorBitMap[$expr];
+			}
+		}
+
+		$this->validatorBits = $bits;
+	}
+
+	/**
+	 * Checks whether to add validators of specified type or not
+	 *
+	 * @param      int $type The validator type constant.
+	 * @return     boolean
+	 */
+	protected function isValidatorRequired($type)
+	{
+		return (($this->validatorBits & $type) === $type);
+	}
+
+	/**
+	 * Whether to use the column name as phpName without any translation.
+	 *
+	 * @return     boolean
+	 */
+	public function isSamePhpName()
+	{
+		return $this->samePhpName;
+	}
+
+	/**
+	 * @throws     BuildException
+	 */
+	public function main()
+	{
+		if (!$this->getDatabaseName()) {
+			throw new BuildException("databaseName attribute is required for schema reverse engineering", $this->getLocation());
+		}
+
+		//(not yet supported) $this->log("schema : " . $this->dbSchema);
+		//DocumentTypeImpl docType = new DocumentTypeImpl(null, "database", null,
+		//	   "http://jakarta.apache.org/turbine/dtd/database.dtd");
+
+		$this->doc = new DOMDocument('1.0', 'utf-8');
+		$this->doc->formatOutput = true; // pretty printing
+
+		$this->doc->appendChild($this->doc->createComment("Autogenerated by ".get_class($this)." class."));
+
+		try {
+
+			$database = $this->buildModel();
+
+			if ($this->validatorBits !== self::VALIDATORS_NONE) {
+				$this->addValidators($database);
+			}
+
+			$database->appendXml($this->doc);
+
+			$this->log("Writing XML to file: " . $this->xmlSchema->getPath());
+			$out = new FileWriter($this->xmlSchema);
+			$xmlstr = $this->doc->saveXML();
+			$out->write($xmlstr);
+			$out->close();
+
+		} catch (Exception $e) {
+			$this->log("There was an error building XML from metadata: " . $e->getMessage(), Project::MSG_ERR);
+		}
+
+		$this->log("Schema reverse engineering finished");
+	}
+
+	/**
+	 * Gets the GeneratorConfig object for this task or creates it on-demand.
+	 * @return     GeneratorConfig
+	 */
+	protected function getGeneratorConfig()
+	{
+		if ($this->generatorConfig === null) {
+			$this->generatorConfig = new GeneratorConfig();
+			$this->generatorConfig->setBuildProperties($this->getProject()->getProperties());
+		}
+		return $this->generatorConfig;
+	}
+
+	/**
+	 * Builds the model classes from the database schema.
+	 * @return     Database The built-out Database (with all tables, etc.)
+	 */
+	protected function buildModel()
+	{
+		$config = $this->getGeneratorConfig();
+		$con = $this->getConnection();
+
+		$database = new Database($this->getDatabaseName());
+		$database->setPlatform($config->getConfiguredPlatform($con));
+
+		// Some defaults ...
+		$database->setDefaultIdMethod(IDMethod::NATIVE);
+
+		$parser = $config->getConfiguredSchemaParser($con);
+
+		$parser->parse($database);
+
+		return $database;
+	}
+
+	/**
+	 * Adds any requested validators to the data model.
+	 *
+	 * We will add the following type specific validators:
+	 *
+	 *      for notNull columns: required validator
+	 *      for unique indexes: unique validator
+	 * 		for varchar types: maxLength validators (CHAR, VARCHAR, LONGVARCHAR)
+	 * 		for numeric types: maxValue validators (BIGINT, SMALLINT, TINYINT, INTEGER, FLOAT, DOUBLE, NUMERIC, DECIMAL, REAL)
+	 * 		for integer and timestamp types: notMatch validator with [^\d]+ (BIGINT, SMALLINT, TINYINT, INTEGER, TIMESTAMP)
+	 * 		for float types: notMatch validator with [^\d\.]+ (FLOAT, DOUBLE, NUMERIC, DECIMAL, REAL)
+	 *
+	 * @param      Database $database The Database model.
+	 * @return     void
+	 * @todo       find out how to evaluate the appropriate size and adjust maxValue rule values appropriate
+	 * @todo       find out if float type column values must always notMatch('[^\d\.]+'), i.e. digits and point for any db vendor, language etc.
+	 */
+	protected function addValidators(Database $database)
+	{
+
+		$platform = $this->getGeneratorConfig()->getConfiguredPlatform();
+
+		foreach ($database->getTables() as $table) {
+
+			$set = new PropelSchemaReverse_ValidatorSet();
+
+			foreach ($table->getColumns() as $col) {
+
+				if ($col->isNotNull() && $this->isValidatorRequired(self::VALIDATORS_REQUIRED)) {
+					$validator = $set->getValidator($col);
+					$validator->addRule($this->getValidatorRule($col, 'required'));
+				}
+
+				if (in_array($col->getType(), array(PropelTypes::CHAR, PropelTypes::VARCHAR, PropelTypes::LONGVARCHAR))
+						&& $col->getSize() && $this->isValidatorRequired(self::VALIDATORS_MAXLENGTH)) {
+					$validator = $set->getValidator($col);
+					$validator->addRule($this->getValidatorRule($col, 'maxLength', $col->getSize()));
+				}
+
+				if ($col->isNumericType() && $this->isValidatorRequired(self::VALIDATORS_MAXVALUE)) {
+					$this->log("WARNING: maxValue validator added for column ".$col->getName().". You will have to adjust the size value manually.", Project::MSG_WARN);
+					$validator = $set->getValidator($col);
+					$validator->addRule($this->getValidatorRule($col, 'maxSize', 'REPLACEME'));
+				}
+
+				if ($col->isPhpPrimitiveType() && $this->isValidatorRequired(self::VALIDATORS_TYPE)) {
+					$validator = $set->getValidator($col);
+					$validator->addRule($this->getValidatorRule($col, 'type', $col->getPhpType()));
+				}
+
+			}
+
+			foreach ($table->getUnices() as $unique) {
+				$colnames = $unique->getColumns();
+				if (count($colnames) == 1) { // currently 'unique' validator only works w/ single columns.
+					$col = $table->getColumn($colnames[0]);
+					$validator = $set->getValidator($col);
+					$validator->addRule($this->getValidatorRule($col, 'unique'));
+				}
+			}
+
+			foreach ($set->getValidators() as $validator) {
+				$table->addValidator($validator);
+			}
+
+		} // foreach table
+
+	}
+
+	/**
+	 * Gets validator rule for specified type (string).
+	 *
+	 * @param      Column $column The column that is being validated.
+	 * @param      string $type The type (string) for validator (e.g. 'required').
+	 * @param      mixed $value The value for the validator (if applicable)
+	 */
+	protected function getValidatorRule(Column $column, $type, $value = null)
+	{
+		$rule = new Rule();
+		$rule->setName($type);
+		if ($value !== null) {
+			$rule->setValue($value);
+		}
+		$rule->setMessage($this->getRuleMessage($column, $type, $value));
+		return $rule;
+	}
+
+	/**
+	 * Gets the message for a specified rule.
+	 *
+	 * @param      Column $column
+	 * @param      string $type
+	 * @param      mixed $value
+	 */
+	protected function getRuleMessage(Column $column, $type, $value)
+	{
+		// create message
+		$colName = $column->getName();
+		$tableName = $column->getTable()->getName();
+		$msg = self::$validatorMessages[strtolower($type)];
+		$tmp = compact($msg['var']);
+		array_unshift($tmp, $msg['msg']);
+		$msg = call_user_func_array('sprintf', $tmp);
+		return $msg;
+	}
+
+}
+
+/**
+ * A helper class to store validator sets indexed by column.
+ * @package    propel.phing
+ */
+class PropelSchemaReverse_ValidatorSet {
+
+	/**
+	 * Map of column names to validators.
+	 *
+	 * @var        array Validator[]
+	 */
+	private $validators = array();
+
+	/**
+	 * Gets a single validator for specified column name.
+	 * @param      Column $column
+	 * @return     Validator
+	 */
+	public function getValidator(Column $column)
+	{
+		$key = $column->getName();
+		if (!isset($this->validators[$key])) {
+			$this->validators[$key] = new Validator();
+			$this->validators[$key]->setColumn($column);
+		}
+		return $this->validators[$key];
+	}
+
+	/**
+	 * Gets all validators.
+	 * @return     array Validator[]
+	 */
+	public function getValidators()
+	{
+		return $this->validators;
+	}
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/default.properties
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/default.properties	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/default.properties	(revision 19)
@@ -0,0 +1,250 @@
+# -------------------------------------------------------------------
+#
+#  D E F A U L T   P R O P E R T I E S
+#
+# -------------------------------------------------------------------
+# This file sets default properties.  You can override any of these
+# by specifying your new value in the build.properties file for your
+# project or a top-level build.properties file. Either way, you
+# should not need to edit this file.
+# -------------------------------------------------------------------
+
+
+# -------------------------------------------------------------------
+#
+#  B A S I C   P R O P E R T I E S
+#
+# -------------------------------------------------------------------
+
+propel.version = 1.3.0
+
+propel.home = .
+
+propel.project =
+propel.database =
+propel.targetPackage = ${propel.project}
+propel.runOnlyOnSchemaChange = false
+
+# Default behavior settings
+#
+propel.targetPlatform = php5
+propel.packageObjectModel = false
+propel.schema.validate = true
+propel.useDateTimeClass = true
+propel.dateTimeClass = DateTime
+
+# controls what type of joins will be used in the doSelectJoin*() peer methods, 
+# if set to true, LEFT JOINS will be used, INNER JOINS otherwise
+# see ticket #491, #588
+propel.useLeftJoinsInDoJoinMethods = true
+
+# -------------------------------------------------------------------
+#
+#  D A T A B A S E   S E T T I N G S
+#
+# -------------------------------------------------------------------
+
+propel.database.url =
+propel.database.buildUrl = ${propel.database.url}
+propel.database.createUrl = ${propel.database.buildUrl}
+
+propel.database.driver =
+
+propel.database.schema =
+propel.database.encoding =
+propel.database.manualCreation = false
+
+# if these arent blank then when we try to connect with insert-sql to a database
+# that doesnt require them and it isnt in the build.properties it sends
+# the ${blah} for the username and password
+propel.database.user =
+propel.database.password =
+
+# Creole database settings for reverse engineering applications
+# -------------------------------------------------------------
+
+# by default leave the databaseDriver blank, so that bundled driver is used by Creole
+propel.database.creole.driver =
+propel.database.creole.url =
+
+# -------------------------------------------------------------------
+#
+#  C R E O L E  TO  X M L  S E T T I N G S
+#
+# -------------------------------------------------------------------
+
+propel.samePhpName = false
+propel.addVendorInfo = false
+propel.addValidators = none
+
+# -------------------------------------------------------------------
+#
+#  T E M P L A T E   V A R I A B L E S
+#
+# -------------------------------------------------------------------
+
+propel.addGenericAccessors = false
+propel.addGenericMutators = false
+propel.addSaveMethod = true
+propel.addTimeStamp = false
+propel.basePrefix = Base
+propel.saveException = PropelException
+propel.emulateForeignKeyConstraints = false
+
+# Identifier quoting is only implemented at the DDL layer at this point.
+# Since this may result in undesired behavior (especially in Postgres),
+# it can be disabled by setting this property to true in your build.properties file.
+propel.disableIdentifierQuoting = false
+
+# These are the default formats that will be used when fetching values
+# from temporal columns in Propel.  You can always specify these when
+# calling the methods directly, but for methods like getByName()
+# it is nice to change the defaults.
+
+propel.defaultTimeStampFormat = Y-m-d H:i:s
+propel.defaultTimeFormat = %X
+propel.defaultDateFormat = %x
+
+propel.omtar.src.base = false
+propel.omtar.src.extension = false
+propel.omtar.bin.base = false
+propel.omtar.bin.extension = false
+propel.omtar.deleteFiles = false
+
+
+# -------------------------------------------------------------------
+#
+#  C O N T R O L   T E M P L A T E S
+#
+# -------------------------------------------------------------------
+#
+# This is a deprecated idea, that will almost certainly be completely
+# removed in Propel 1.2 and/or 2.0.
+#
+
+propel.template.conf = ${propel.home}/templates/conf/Control.tpl
+propel.template.sql = ${propel.home}/templates/sql/base/Control.tpl
+propel.template.sqlDbInit = ${propel.home}/templates/sql/db-init/Control.tpl
+
+
+# -------------------------------------------------------------------
+#
+#  D I R E C T O R I E S
+#
+# -------------------------------------------------------------------
+
+propel.project.dir = ${propel.home}/projects/${propel.project}
+
+propel.output.dir = ${propel.project.dir}/build
+propel.schema.dir = ${propel.project.dir}
+propel.templatePath = ${propel.home}/templates
+propel.conf.dir = ${propel.project.dir}
+
+propel.doc.dir = ${propel.output.dir}/doc
+propel.php.dir = ${propel.output.dir}/classes
+propel.phpconf.dir = ${propel.output.dir}/conf
+propel.phpdoc.dir = ${propel.output.dir}/phpdoc
+propel.sql.dir = ${propel.output.dir}/sql
+propel.graph.dir = ${propel.output.dir}/graph
+propel.omtar.dir = ${propel.output.dir}
+
+
+# -------------------------------------------------------------------
+#
+#  D E F A U L T   F I L E   N A M ES
+#
+# -------------------------------------------------------------------
+
+# propel.sqlfile
+
+propel.runtime.conf.file = runtime-conf.xml
+propel.runtime.phpconf.file = ${propel.project}-conf.php
+propel.runtime.phpconf-classmap.file = ${propel.project}-classmap.php
+propel.default.schema.basename = schema
+
+# Can't use because of inconsistencies in where the files
+# are named (some from build-propel.xml, but some from within templates)
+# propel.default.data.basename = ${propel.project}-data
+
+propel.schema.xsd.file = ${propel.home}/resources/xsd/database.xsd
+propel.schema.xsl.file = ${propel.home}/resources/xsl/database.xsl
+
+# -------------------------------------------------------------------
+#
+#  I N C L U D E   A N D   E X C L U D E   S E T T I N G S
+#
+# -------------------------------------------------------------------
+
+propel.schema.sql.includes = *schema.xml
+propel.schema.sql.excludes =
+propel.schema.doc.includes = *schema.xml
+propel.schema.doc.excludes =
+propel.schema.create-db.includes = *schema.xml
+propel.schema.create-db.excludes =
+propel.schema.init-sql.includes = *schema.xml
+propel.schema.init-sql.excludes = id-table-schema.xml
+propel.schema.om.includes = *schema.xml
+propel.schema.om.excludes = id-table-schema.xml
+propel.schema.datadtd.includes = *schema.xml
+propel.schema.datadtd.excludes = id-table-schema.xml
+
+# -------------------------------------------------------------------
+#
+#  M A P P E R   S E T T I N G S
+#
+# -------------------------------------------------------------------
+
+# (note: data xml files are selected based on datadbmap file)
+propel.datasql.mapper.from = *.xml
+propel.datasql.mapper.to = *.sql
+
+propel.datadump.mapper.from = *schema.xml
+propel.datadump.mapper.to = *data.xml
+
+propel.datadtd.mapper.from = *.xml
+propel.datadtd.mapper.to = *.dtd
+
+propel.sql.mapper.from = *.xml
+propel.sql.mapper.to = *.sql
+
+
+# -------------------------------------------------------------------
+#
+#  B U I L D E R    S E T T I N G S
+#
+# -------------------------------------------------------------------
+
+# Object Model builders
+propel.builder.peer.class = propel.engine.builder.om.php5.PHP5PeerBuilder
+propel.builder.object.class = propel.engine.builder.om.php5.PHP5ObjectBuilder
+propel.builder.objectstub.class = propel.engine.builder.om.php5.PHP5ExtensionObjectBuilder
+propel.builder.peerstub.class = propel.engine.builder.om.php5.PHP5ExtensionPeerBuilder
+
+propel.builder.objectmultiextend.class = propel.engine.builder.om.php5.PHP5MultiExtendObjectBuilder
+
+propel.builder.mapbuilder.class = propel.engine.builder.om.php5.PHP5MapBuilderBuilder
+
+propel.builder.interface.class = propel.engine.builder.om.php5.PHP5InterfaceBuilder
+
+propel.builder.node.class = propel.engine.builder.om.php5.PHP5NodeBuilder
+propel.builder.nodepeer.class = propel.engine.builder.om.php5.PHP5NodePeerBuilder
+propel.builder.nodestub.class = propel.engine.builder.om.php5.PHP5ExtensionNodeBuilder
+propel.builder.nodepeerstub.class = propel.engine.builder.om.php5.PHP5ExtensionNodePeerBuilder
+
+propel.builder.nestedset.class = propel.engine.builder.om.php5.PHP5NestedSetBuilder
+propel.builder.nestedsetpeer.class = propel.engine.builder.om.php5.PHP5NestedSetPeerBuilder
+
+propel.builder.pluralizer.class = propel.engine.builder.util.DefaultEnglishPluralizer
+
+# SQL builders
+
+propel.builder.ddl.class = propel.engine.builder.sql.${propel.database}.${propel.database}DDLBuilder
+propel.builder.datasql.class = propel.engine.builder.sql.${propel.database}.${propel.database}DataSQLBuilder
+
+# Platform classes
+
+propel.platform.class = propel.engine.platform.${propel.database}Platform
+
+# Schema Parser (reverse-engineering) classes
+
+propel.reverse.parser.class = propel.engine.database.reverse.${propel.database}.${propel.database}SchemaParser
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/pear/BuildPropelGenPEARPackageTask.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/pear/BuildPropelGenPEARPackageTask.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/pear/BuildPropelGenPEARPackageTask.php	(revision 19)
@@ -0,0 +1,272 @@
+<?php
+/*
+ *  $Id: BuildPropelGenPEARPackageTask.php 1752 2010-05-09 12:36:59Z francois $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://phing.info>.
+ */
+
+require_once 'phing/tasks/system/MatchingTask.php';
+include_once 'phing/types/FileSet.php';
+include_once 'phing/tasks/ext/pearpackage/Fileset.php';
+
+/**
+ *
+ * @author     Hans Lellelid <hans@xmpl.org>
+ * @package    phing.tasks.ext
+ * @version    $Revision: 1752 $
+ */
+class BuildPropelGenPEARPackageTask extends MatchingTask {
+
+	/** Base directory for reading files. */
+	private $dir;
+
+	private $version;
+	private $state = 'stable';
+	private $notes;
+
+	private $filesets = array();
+
+	/** Package file */
+	private $packageFile;
+
+	public function init() {
+		include_once 'PEAR/PackageFileManager2.php';
+		if (!class_exists('PEAR_PackageFileManager2')) {
+			throw new BuildException("You must have installed PEAR_PackageFileManager2 (PEAR_PackageFileManager >= 1.6.0) in order to create a PEAR package.xml file.");
+		}
+	}
+
+	private function setOptions($pkg){
+
+		$options['baseinstalldir'] = 'propel';
+		$options['packagedirectory'] = $this->dir->getAbsolutePath();
+
+		if (empty($this->filesets)) {
+			throw new BuildException("You must use a <fileset> tag to specify the files to include in the package.xml");
+		}
+
+		$options['filelistgenerator'] = 'Fileset';
+
+		// Some PHING-specific options needed by our Fileset reader
+		$options['phing_project'] = $this->getProject();
+		$options['phing_filesets'] = $this->filesets;
+
+		if ($this->packageFile !== null) {
+			// create one w/ full path
+			$f = new PhingFile($this->packageFile->getAbsolutePath());
+			$options['packagefile'] = $f->getName();
+			// must end in trailing slash
+			$options['outputdirectory'] = $f->getParent() . DIRECTORY_SEPARATOR;
+			$this->log("Creating package file: " . $f->getPath(), Project::MSG_INFO);
+		} else {
+			$this->log("Creating [default] package.xml file in base directory.", Project::MSG_INFO);
+		}
+
+		// add install exceptions
+		$options['installexceptions'] = array(	'pear/pear-propel-gen' => '/',
+												'pear/pear-propel-gen.bat' => '/',
+												'pear/pear-build.xml' => '/',
+												'pear/build.properties' => '/',
+												);
+
+		$options['dir_roles'] = array(	'projects' => 'data',
+										'test' => 'test',
+										'templates' => 'data',
+										'resources' => 'data');
+
+		$options['exceptions'] = array(	'pear/pear-propel-gen.bat' => 'script',
+										'pear/pear-propel-gen' => 'script',
+										'pear/pear-build.xml' => 'data',
+										'build.xml' => 'data',
+										'build-propel.xml' => 'data',
+									);
+
+		$pkg->setOptions($options);
+
+	}
+
+	/**
+	 * Main entry point.
+	 * @return     void
+	 */
+	public function main() {
+
+		if ($this->dir === null) {
+			throw new BuildException("You must specify the \"dir\" attribute for PEAR package task.");
+		}
+
+		if ($this->version === null) {
+			throw new BuildException("You must specify the \"version\" attribute for PEAR package task.");
+		}
+
+		$package = new PEAR_PackageFileManager2();
+
+		$this->setOptions($package);
+
+		// the hard-coded stuff
+		$package->setPackage('propel_generator');
+		$package->setSummary('Generator component of the Propel PHP object persistence layer');
+		$package->setDescription('Propel is an object persistence layer for PHP5 based on Apache Torque. This package provides the generator engine that builds PHP classes and SQL DDL based on an XML representation of your data model.');
+		$package->setChannel('pear.propelorm.org');
+		$package->setPackageType('php');
+
+		$package->setReleaseVersion($this->version);
+		$package->setAPIVersion($this->version);
+
+		$package->setReleaseStability($this->state);
+		$package->setAPIStability($this->state);
+
+		$package->setNotes($this->notes);
+
+		$package->setLicense('LGPL', 'http://www.gnu.org/licenses/lgpl.html');
+
+		// Add package maintainers
+		$package->addMaintainer('lead', 'hans', 'Hans Lellelid', 'hans@xmpl.org');
+		$package->addMaintainer('lead', 'david', 'David Zuelke', 'dz@bitxtender.com');
+
+
+
+		// (wow ... this is a poor design ...)
+		//
+		// note that the order of the method calls below is creating
+		// sub-"release" sections which have specific rules.  This replaces
+		// the platformexceptions system in the older version of PEAR's package.xml
+		//
+		// Programmatically, I feel the need to re-iterate that this API for PEAR_PackageFileManager
+		// seems really wrong.  Sub-sections should be encapsulated in objects instead of having
+		// a "flat" API that does not represent the structure being created....
+
+
+		// creating a sub-section for 'windows'
+			$package->addRelease();
+			$package->setOSInstallCondition('windows');
+			$package->addInstallAs('pear/pear-propel-gen.bat', 'propel-gen.bat');
+			$package->addIgnoreToRelease('pear/pear-propel-gen');
+
+		// creating a sub-section for non-windows
+			$package->addRelease();
+			$package->addInstallAs('pear/pear-propel-gen', 'propel-gen');
+			$package->addIgnoreToRelease('pear/pear-propel-gen.bat');
+
+
+		// "core" dependencies
+		$package->setPhpDep('5.2.0');
+		$package->setPearinstallerDep('1.4.0');
+
+		// "package" dependencies
+		$package->addPackageDepWithChannel( 'required', 'phing', 'pear.phing.info', '2.3.0');
+		$package->addPackageDepWithChannel( 'optional', 'creole', 'pear.propelorm.org', '1.1.0');
+
+		$package->addExtensionDep('required', 'pdo');
+		$package->addExtensionDep('required', 'xml');
+		$package->addExtensionDep('required', 'xsl');
+
+		// now add the replacements ....
+		$package->addReplacement('Phing.php', 'pear-config', '@DATA-DIR@', 'data_dir');
+		$package->addReplacement('pear/pear-propel-gen.bat', 'pear-config', '@PHP-BIN@', 'php_bin');
+		$package->addReplacement('pear/pear-propel-gen.bat', 'pear-config', '@BIN-DIR@', 'bin_dir');
+		$package->addReplacement('pear/pear-propel-gen.bat', 'pear-config', '@PEAR-DIR@', 'php_dir');
+		$package->addReplacement('pear/pear-propel-gen.bat', 'pear-config', '@DATA-DIR@', 'data_dir');
+
+		$package->addReplacement('pear/pear-propel-gen', 'pear-config', '@PHP-BIN@', 'php_bin');
+		$package->addReplacement('pear/pear-propel-gen', 'pear-config', '@BIN-DIR@', 'bin_dir');
+		$package->addReplacement('pear/pear-propel-gen', 'pear-config', '@PEAR-DIR@', 'php_dir');
+		$package->addReplacement('pear/pear-propel-gen', 'pear-config', '@DATA-DIR@', 'data_dir');
+
+		$package->addReplacement('pear/pear-build.xml', 'pear-config', '@PHP-BIN@', 'php_bin');
+		$package->addReplacement('pear/pear-build.xml', 'pear-config', '@BIN-DIR@', 'bin_dir');
+		$package->addReplacement('pear/pear-build.xml', 'pear-config', '@PEAR-DIR@', 'php_dir');
+		$package->addReplacement('pear/pear-build.xml', 'pear-config', '@DATA-DIR@', 'data_dir');
+
+
+		// now we run this weird generateContents() method that apparently
+		// is necessary before we can add replacements ... ?
+		$package->generateContents();
+
+		$e = $package->writePackageFile();
+
+		if (PEAR::isError($e)) {
+			throw new BuildException("Unable to write package file.", new Exception($e->getMessage()));
+		}
+
+	}
+
+	/**
+	 * Used by the PEAR_PackageFileManager_PhingFileSet lister.
+	 * @return     array FileSet[]
+	 */
+	public function getFileSets() {
+		return $this->filesets;
+	}
+
+	// -------------------------------
+	// Set properties from XML
+	// -------------------------------
+
+	/**
+	 * Nested creator, creates a FileSet for this task
+	 *
+	 * @return     FileSet The created fileset object
+	 */
+	function createFileSet() {
+		$num = array_push($this->filesets, new FileSet());
+		return $this->filesets[$num-1];
+	}
+
+	/**
+	 * Set the version we are building.
+	 * @param      string $v
+	 * @return     void
+	 */
+	public function setVersion($v){
+		$this->version = $v;
+	}
+
+	/**
+	 * Set the state we are building.
+	 * @param      string $v
+	 * @return     void
+	 */
+	public function setState($v) {
+		$this->state = $v;
+	}
+
+	/**
+	 * Sets release notes field.
+	 * @param      string $v
+	 * @return     void
+	 */
+	public function setNotes($v) {
+		$this->notes = $v;
+	}
+	/**
+	 * Sets "dir" property from XML.
+	 * @param      PhingFile $f
+	 * @return     void
+	 */
+	public function setDir(PhingFile $f) {
+		$this->dir = $f;
+	}
+
+	/**
+	 * Sets the file to use for generated package.xml
+	 */
+	public function setDestFile(PhingFile $f) {
+		$this->packageFile = $f;
+	}
+
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/pear/build-pear-package.xml
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/pear/build-pear-package.xml	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/pear/build-pear-package.xml	(revision 19)
@@ -0,0 +1,146 @@
+<?xml version="1.0"?>
+
+<!--
+	This build file creates a minimal package of propel-generator files,
+	builds a package.xml for installation using PEAR and creates the necessary TGZ file.
+
+	It's pretty easy to build the PEAR package:
+
+	$> cd /path/to/propel-generator
+	$> phing -Dversion=1.0.0RC1 -f pear\build-pear-package.xml
+
+-->
+
+<project name="propel_generator" basedir="." default="main">
+
+	<property name="propelgen.home" value=".."/>
+	<property name="build.base.dir" value="build"/>
+	<property name="pkgname" value="${phing.project.name}-${version}"/>
+	<property name="build.src.dir" value="${build.base.dir}/${pkgname}"/>
+
+	<!-- some default properties -->
+	<property name="notes"><![CDATA[This is a beta release for the 1.3 branch of the Propel Generator.
+See: http://propel.phpdb.org/trac/query?status=closed&milestone=1.3&resolution=fixed&order=priority for CHANGELOG.
+	]]></property>
+	<property name="state" value="stable"/>
+
+	<taskdef
+    name="pear-package"
+    classname="BuildPropelGenPEARPackageTask" classpath="."/>
+
+	<fileset dir="${propelgen.home}/classes/propel" id="classes">
+		<include name="**"/>
+	</fileset>
+
+	<fileset dir="${propelgen.home}" id="data">
+		<!--<include name="build.xml"/>-->
+		<include name="build-propel.xml"/>
+		<include name="projects/bookstore/*"/>
+		<include name="projects/treetest/*"/>
+		<include name="pear/pear-build.xml"/>
+		<include name="pear/pear-propel*"/>
+		<include name="pear/build.properties"/>
+		<include name="default.properties"/>
+		<include name="templates/**"/>
+		<include name="resources/**"/>
+	</fileset>
+
+	<!--
+		==============================================
+		Main entry point
+		==============================================
+	-->
+	<target name="main" if="version" depends="versioncheck">
+		<phingcall target="build"/>
+		<phingcall target="pear-package"/>
+		<phingcall target="tar"/>
+	</target>
+
+	<!--
+	 ===================================================================
+	 Target: checks if language was given, otherwise fail
+	 ===================================================================
+	-->
+	<target name="versioncheck" unless="version">
+		<echo message="====================================================="/>
+		<echo message="Version not specified. You must enter a version. In"/>
+		<echo message="the future you can add this to build.properties or"/>
+		<echo message="enter it on the command line: "/>
+		<echo message=" "/>
+		<echo message="-Dversion=1.0.0"/>
+		<echo message="====================================================="/>
+		<input propertyname="version" promptChar=":">Propel version for package</input>
+
+		<property name="pkgname" value="${phing.project.name}-${version}" override="true"/>
+		<property name="build.src.dir" value="${build.base.dir}/${pkgname}" override="true"/>
+
+	</target>
+
+	<!--
+		==============================================
+		Copy the desired files into the build/ dir
+		making sure to put them in the directory
+		structure that will be needed for PEAR install
+		==============================================
+	-->
+	<target name="build">
+		<echo>-----------------------------</echo>
+		<echo>| Creating directory layout |</echo>
+		<echo>-----------------------------</echo>
+
+		<delete dir="${build.base.dir}"/>
+		<mkdir dir="${build.base.dir}"/>
+
+		<copy todir="${build.src.dir}">
+			<fileset refid="classes"/>
+			<fileset refid="data"/>
+		</copy>
+
+		<!-- some files need to be manually moved here to save headache when
+		doing the pear package.xml creation -->
+		<move file="${build.src.dir}/pear/build.properties" todir="${build.src.dir}"/>
+		<move file="${build.src.dir}/pear/pear-build.xml" todir="${build.src.dir}"/>
+
+		<chmod file="${build.src.dir}/pear/pear-propel-gen" mode="755"/>
+
+	</target>
+
+	<!--
+		==============================================
+		Create a PEAR package.xml which will guide the
+		installation.
+		==============================================
+	-->
+	<target name="pear-package">
+
+		<echo>-----------------------------</echo>
+		<echo>| Creating PEAR package.xml |</echo>
+		<echo>-----------------------------</echo>
+		<echo></echo>
+
+		<pear-package dir="${build.src.dir}" destFile="${build.base.dir}/package.xml" version="${version}" state="${state}" notes="${notes}">
+
+			<fileset dir="${build.src.dir}">
+				<include name="**"/>
+			</fileset>
+
+		</pear-package>
+
+	</target>
+
+	<!--
+		==============================================
+		Create a tar.gz of the files, which will be
+		installed by pear package manager.
+		==============================================
+	-->
+	<target name="tar">
+		<echo>-----------------------------</echo>
+		<echo>| Creating tar.gz package   |</echo>
+		<echo>-----------------------------</echo>
+		<property name="tarfile" value="${build.base.dir}/${pkgname}.tgz"/>
+		<delete	file="${tarfile}"/>
+		<tar destFile="${tarfile}" basedir="${build.base.dir}" />
+	</target>
+
+</project>
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/pear/build.properties
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/pear/build.properties	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/pear/build.properties	(revision 19)
@@ -0,0 +1,5 @@
+# In this file you can define any properties taht you want to affect
+# all projects built using the propel-gen script on this system
+#
+# See http://propel.phpdb.org/trac/wiki/Users/Documentation/BuildProperties for a
+# list of available properties.
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/pear/pear-build.xml
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/pear/pear-build.xml	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/pear/pear-build.xml	(revision 19)
@@ -0,0 +1,125 @@
+<!--
+    Use this file to faciliate easy per-project building using 
+	PEAR-installed Propel-generator.
+
+	This Phing script is invoked via the shell script propel-gen (.bat
+	for Windows).  Normally you should not need to edit this script or
+	be aware of it in any way.
+	
+    Normal use:
+    $> propel-gen /path/to/my/project
+    
+    Specific target: 
+    $> propel-gen insert-sql /path/to/my/project 
+
+-->
+<project name="propel-project-builder" default="main" basedir=".">
+
+<!-- set a default target if none provided -->
+<property name="target" value="main"/>
+
+<resolvepath propertyName="propel.project.dir" file="${project.dir}" dir="${application.startdir}"/>
+
+<target name="projdircheckExists">
+  <condition property="projDirExists">
+  	<and>
+		<not>
+			<equals arg1="${propel.project.dir}" arg2="" trim="true"/>
+		</not>
+		<available file="${propel.project.dir}/build.properties"/>
+	</and>
+  </condition>
+</target>
+
+<target name="projdircheck" depends="projdircheckExists" unless="projDirExists">
+	<echo message="====================================================="/>
+	<echo message="Project directory not specified or invalid. You must "/>
+	<echo message="specify the path to your project directory and your "/>
+	<echo message="project directory must contain your build.properties "/>
+	<echo message="and schema.xml files.                                "/>
+	<echo message=" "/>
+	<echo message="Usage: "/>
+	<echo message=" "/>
+	<echo message="$&gt; propel-gen /path/to/projectdir [target]"/>
+	<echo message=" "/>
+	<echo message="====================================================="/>	
+	<fail message="No project directory specified."/>
+</target>
+
+<target name="configure" depends="projdircheck">
+	<if>
+		<isset property="additional.properties"/>
+		<then>
+			<echo>Processing additional properties file: ${additional.properties}</echo>
+			<resolvepath propertyName="additional.properties.resolved" file="${additional.properties}" dir="${application.startdir}"/>
+			<property file="${additional.properties.resolved}"/>
+		</then>
+	</if>
+	<echo msg="Loading project-specific props from ${project.dir}/build.properties"/>
+	<property file="${propel.project.dir}/build.properties"/>
+</target>
+
+<target name="main" depends="configure" 
+  description="The main target. Includes project-specific build.properties and calls the build-propel.xml script">	
+
+ <!--<property file="${project.dir}/build.properties"/>-->
+ <phing phingfile="build-propel.xml" target="${target}"/>
+ 
+</target>
+
+
+<!-- 
+ Convenience mappings to build-propel.xml main targets 
+ 
+ This makes it possible to use this buildfile w/o needing to specify
+ target as a property, e.g.:
+ 
+ $> phing -Dproject=bookstore insert-sql
+ 
+ The main reason for this is just consistency w/ old build-propel.xml file
+ (primarily for documentation & user confusion avoidance reasons).  There are relatively
+ few & infrequently changing main targets of build-propel.xml, so it's a non-
+ issue as far as maintenance is concerned.
+-->
+
+<target name="convert-conf" depends="configure">
+	<phing phingfile="build-propel.xml" target="convert-conf"/>
+</target>
+
+<target name="create-db" depends="configure">
+	<phing phingfile="build-propel.xml" target="create-db"/>
+</target>
+
+<target name="creole" depends="configure">
+	<phing phingfile="build-propel.xml" target="creole"/>
+</target>
+
+<target name="reverse" depends="configure">
+	<phing phingfile="build-propel.xml" target="reverse"/>
+</target>
+
+<target name="datadtd" depends="configure">
+	<phing phingfile="build-propel.xml" target="datadtd"/>
+</target>
+
+<target name="datadump" depends="configure">
+	<phing phingfile="build-propel.xml" target="datadump"/>
+</target>
+
+<target name="datasql" depends="configure">
+	<phing phingfile="build-propel.xml" target="datasql"/>
+</target>
+
+<target name="insert-sql" depends="configure">
+	<phing phingfile="build-propel.xml" target="insert-sql"/>
+</target>
+
+<target name="om" depends="configure">
+	<phing phingfile="build-propel.xml" target="om"/>
+</target>
+
+<target name="sql" depends="configure">
+	<phing phingfile="build-propel.xml" target="sql"/>
+</target>
+
+</project>
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/pear/pear-propel-gen
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/pear/pear-propel-gen	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/pear/pear-propel-gen	(revision 19)
@@ -0,0 +1,21 @@
+#!/bin/sh
+
+# ------------------------------------------------------------------------
+# The phing build script for Unix based systems
+# $Id: pear-propel-gen,v 1.2 2004/10/17 13:24:09 hlellelid Exp $
+# ------------------------------------------------------------------------
+
+# Change this to reflect your environment if the default value doesn't work
+export PHING_COMMAND="phing"
+
+# -------------------------------------------------------------------------
+# Do not change anything below this line unless you know what you're doing.
+# -------------------------------------------------------------------------
+
+# (currently this is not reached)
+if (test -z "$PHING_COMMAND") ; then
+	echo "WARNING: PHP_COMMAND environment not set. (Assuming phing on PATH)"
+	export PHING_COMMAND=php
+fi
+
+$PHING_COMMAND -f @DATA-DIR@/propel_generator/pear-build.xml -Dproject.dir=$*
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/pear/pear-propel-gen.bat
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/pear/pear-propel-gen.bat	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/pear/pear-propel-gen.bat	(revision 19)
@@ -0,0 +1,24 @@
+@ECHO OFF
+
+:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+:: The propel-gen build script for Windows based systems
+:: $Id: pear-propel-gen.bat,v 1.2 2004/10/17 13:24:09 hlellelid Exp $
+:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+
+::----------------------------------------------------------------------------------
+:: Please set following to the "phing" script.  By default this is expected to be
+:: on your path.  (You don't need to modify this file if that is the case.)
+  
+  SET phingScript=phing
+
+::---------------------------------------------------------------------------------
+::---------------------------------------------------------------------------------
+:: Do not modify below this line!! (Unless you know what your doing :)
+::---------------------------------------------------------------------------------
+::---------------------------------------------------------------------------------
+
+"%phingScript%" -f @DATA-DIR@\propel_generator\pear-build.xml -Dproject.dir=%*
+GOTO :EOF
+
+:PAUSE_END
+PAUSE
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/projects/bookstore-packaged/author.schema.xml
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/projects/bookstore-packaged/author.schema.xml	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/projects/bookstore-packaged/author.schema.xml	(revision 19)
@@ -0,0 +1,59 @@
+<?xml version="1.0" encoding="ISO-8859-1" standalone="no"?>
+<!DOCTYPE database SYSTEM "../dtd/database.dtd">
+
+<database package="core.author" name="bookstore" defaultIdMethod="native">
+
+  <table name="author" description="Author Table">
+    <column
+      name="id"
+      required="true"
+      primaryKey="true"
+	  autoIncrement="true"
+      type="INTEGER"
+      description="Author Id"/>
+    <column
+      name="first_name"
+      required="true"
+      type="VARCHAR"
+      size="128"
+      description="First Name"/>
+    <column
+      name="last_name"
+      required="true"
+      type="VARCHAR"
+      size="128"
+      description="Last Name"/>
+    <column
+      name="email"
+      type="VARCHAR"
+      size="128"
+      description="E-Mail Address"/>
+    <column
+      name="age"
+      type="INTEGER"
+      description="The authors age"/>
+	<validator column="last_name" translate="none">
+		<rule
+			name="required"
+			message="The last name field is required."/>
+	</validator>
+	<validator column="email" translate="none">
+		<rule
+			name="match"
+			value="/^([a-zA-Z0-9])+([\.a-zA-Z0-9_-])*@([a-zA-Z0-9])+(\.[a-zA-Z0-9_-]+)+$/"
+			message="Please enter a valid email address."/>
+	</validator>
+	<validator column="age" translate="none">
+      <rule
+         name="minValue"
+         value="0"
+         message="Please enter a positive number." />
+      <rule
+         name="maxValue"
+         value="100"
+         message="Impressive age! Just kidding, hm?" />
+	</validator>
+
+  </table>
+
+</database>
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/projects/bookstore-packaged/book.schema.xml
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/projects/bookstore-packaged/book.schema.xml	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/projects/bookstore-packaged/book.schema.xml	(revision 19)
@@ -0,0 +1,68 @@
+<?xml version="1.0" encoding="ISO-8859-1" standalone="no"?>
+<!DOCTYPE database SYSTEM "../dtd/database.dtd">
+
+<database package="core.book" name="bookstore" defaultIdMethod="native">
+
+  <table name="book" description="Book Table">
+    <column
+      name="id"
+      required="true"
+      primaryKey="true"
+	  autoIncrement="true"
+      type="INTEGER"
+      description="Book Id"/>
+    <column
+      name="title"
+      required="true"
+      type="VARCHAR"
+      size="255"
+      description="Book Title"/>
+    <column
+      name="isbn"
+      required="true"
+      type="VARCHAR"
+      size="24"
+      phpName="ISBN"
+      description="ISBN Number"/>
+    <column
+      name="publisher_id"
+      required="false"
+      type="INTEGER"
+      description="Foreign Key Publisher"/>
+    <column
+      name="author_id"
+      required="false"
+      type="INTEGER"
+      description="Foreign Key Author"/>
+    <foreign-key foreignTable="publisher" onDelete="SETNULL">
+      <reference
+        local="publisher_id"
+        foreign="id"/>
+    </foreign-key>
+    <foreign-key foreignTable="author" onDelete="SETNULL">
+      <reference
+        local="author_id"
+        foreign="id"/>
+    </foreign-key>
+    <validator column="title" translate="none">
+      <rule
+        name="unique"
+        message="Book title already in database." />
+      <rule
+        name="minLength"
+        value="10"
+        message="Book title must be more than ${value} characters long."/>
+      <rule
+        name="maxLength"
+        value="255"
+        message="Book title must not be longer than ${value} characters."/>
+    </validator>
+    <validator column="isbn" translate="none">
+      <rule
+         name="notMatch"
+         value="/[^\d-]+/"
+         message="The ISBN contains invalid characters." />
+    </validator>
+  </table>
+
+</database>
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/projects/bookstore-packaged/book_club_list.schema.xml
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/projects/bookstore-packaged/book_club_list.schema.xml	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/projects/bookstore-packaged/book_club_list.schema.xml	(revision 19)
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="ISO-8859-1" standalone="no"?>
+<!DOCTYPE database SYSTEM "../dtd/database.dtd">
+
+<database package="addon.club" name="bookstore" defaultIdMethod="native">
+
+  <!-- this table exists to test the many-to-many -->
+  <table name="book_club_list" description="Reading list for a book club.">
+	<column
+	  name="id"
+	  required="true"
+	  primaryKey="true"
+	  autoIncrement="true"
+	  type="INTEGER"
+	  description="Unique ID for a school reading list."/>
+	<column
+	  name="group_leader"
+	  required="true"
+	  type="VARCHAR"
+	  size="100"
+	  description="The name of the teacher in charge of summer reading."/>
+	<column
+	  name="theme"
+	  required="false"
+	  type="VARCHAR"
+	  size="50"
+	  description="The theme, if applicable, for the reading list."/>
+  </table>
+
+  <table name="book_x_list" phpName="BookListRel" description="Cross-reference table for many-to-many relationship between book rows and book_club_list rows.">
+	<column
+	  name="book_id"
+	  primaryKey="true"
+	  type="INTEGER"
+	  description="Fkey to book.id"/>
+	<column
+	  name="book_club_list_id"
+	  primaryKey="true"
+	  type="INTEGER"
+	  description="Fkey to book_club_list.id"/>
+	<foreign-key foreignTable="book" onDelete="CASCADE">
+	  <reference local="book_id" foreign="id"/>
+	</foreign-key>
+	<foreign-key foreignTable="book_club_list" onDelete="CASCADE">
+	  <reference local="book_club_list_id" foreign="id"/>
+	</foreign-key>
+  </table>
+
+</database>
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/projects/bookstore-packaged/build.properties
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/projects/bookstore-packaged/build.properties	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/projects/bookstore-packaged/build.properties	(revision 19)
@@ -0,0 +1,19 @@
+# $Id: build.properties 505 2007-01-01 19:45:13Z heltem $
+# 
+# This is a project-specific build.properties file.  The properties
+# in this file override anything set in Propel's top-level build.properties
+# file when *this* project is being built.
+#
+# See top-level build.properties-sample for explanation of configuration 
+# options.
+#
+# Because this file is included before the top-level build.properties file, 
+# you cannot refer to any properties set therein.
+
+propel.project = bookstore-packaged
+propel.database = sqlite
+propel.database.url = sqlite://localhost/./test/@DB@.db
+# propel.database.createUrl = (doesn't aply for SQLite, since db is auto-created)
+
+propel.targetPackage = bookstore-packaged
+propel.packageObjectModel = true
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/projects/bookstore-packaged/log.schema.xml
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/projects/bookstore-packaged/log.schema.xml	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/projects/bookstore-packaged/log.schema.xml	(revision 19)
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="ISO-8859-1" standalone="no"?>
+<!DOCTYPE database SYSTEM "../dtd/database.dtd">
+
+<database package="util.log" name="bookstore-log" defaultIdMethod="native">
+
+  <table name="log" phpName="BookstoreLog" description="Used to test multiple databases support">
+    <column
+      name="id"
+      required="true"
+      primaryKey="true"
+	  autoIncrement="true"
+      type="INTEGER"
+      description="Id"/>
+	<column
+      name="time"
+      required="true"
+      type="TIMESTAMP"
+      description="Log time"/>
+	<column
+      name="ident"
+      required="true"
+      type="CHAR"
+      size="24"
+      description="Log priority"/>
+	<column
+      name="priority"
+      required="true"
+      type="INTEGER"
+      description="Log priority"/>
+    <column
+      name="message"
+      required="true"
+      type="LONGVARCHAR"
+      description="Log message"/>
+  </table>
+
+</database>
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/projects/bookstore-packaged/media.schema.xml
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/projects/bookstore-packaged/media.schema.xml	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/projects/bookstore-packaged/media.schema.xml	(revision 19)
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="ISO-8859-1" standalone="no"?>
+<!DOCTYPE database SYSTEM "../dtd/database.dtd">
+
+<database package="core.book" name="bookstore" defaultIdMethod="native">
+
+  <!-- This table exists to explore/test the handling of BLOB/CLOB objects. -->
+  <table name="media">
+   <column
+      name="id"
+      required="true"
+      primaryKey="true"
+	  autoIncrement="true"
+      type="INTEGER"
+      description="Media Id"/>
+    <column
+      name="cover_image"
+      type="BLOB"
+      lazyLoad="true"
+      description="The image of the book cover."/>
+	<column
+      name="excerpt"
+      type="CLOB"
+      lazyLoad="true"
+      description="An excerpt from the book."/>
+	<column
+	  name="book_id"
+	  required="true"
+	  type="INTEGER"
+	  description="Book ID for this media collection."/>
+	<foreign-key foreignTable="book" onDelete="CASCADE">
+      <reference
+        local="book_id"
+        foreign="id"/>
+    </foreign-key>
+  </table>
+
+</database>
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/projects/bookstore-packaged/publisher.schema.xml
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/projects/bookstore-packaged/publisher.schema.xml	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/projects/bookstore-packaged/publisher.schema.xml	(revision 19)
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="ISO-8859-1" standalone="no"?>
+<!DOCTYPE database SYSTEM "../dtd/database.dtd">
+
+<database package="core.publisher" name="bookstore" defaultIdMethod="native">
+
+  <table name="publisher" description="Publisher Table">
+    <column
+      name="id"
+      required="true"
+      primaryKey="true"
+	  autoIncrement="true"
+      type="INTEGER"
+      description="Publisher Id"/>
+    <column
+      name="name"
+      required="true"
+      type="VARCHAR"
+      size="128"
+	  default="Penguin"
+      description="Publisher Name"/>
+  </table>
+
+</database>
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/projects/bookstore-packaged/review.schema.xml
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/projects/bookstore-packaged/review.schema.xml	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/projects/bookstore-packaged/review.schema.xml	(revision 19)
@@ -0,0 +1,59 @@
+<?xml version="1.0" encoding="ISO-8859-1" standalone="no"?>
+<!DOCTYPE database SYSTEM "../dtd/database.dtd">
+
+<database package="core.review" name="bookstore" defaultIdMethod="native">
+
+  <table name="review" description="Book Review">
+    <column
+      name="id"
+      required="true"
+      primaryKey="true"
+	  autoIncrement="true"
+      type="INTEGER"
+      description="Author Id"/>
+    <column
+      name="reviewed_by"
+      required="true"
+      type="VARCHAR"
+      size="128"
+      description="Reviewer Name"/>
+	<column
+      name="review_date"
+      required="true"
+      type="DATE"
+	  default="01/01/2001"
+      description="Date of Review"/>
+	<column
+      name="recommended"
+      required="true"
+      type="BOOLEAN"
+      description="Does reviewer recommend book?"/>
+	<column
+      name="status"
+      type="VARCHAR"
+      size="8"
+      description="The status of this review."/>
+	<column
+	  name="book_id"
+	  required="true"
+	  type="INTEGER"
+	  description="Book ID for this review"/>
+	<foreign-key foreignTable="book" onDelete="CASCADE">
+      <reference
+        local="book_id"
+        foreign="id"/>
+    </foreign-key>
+	<validator column="reviewed_by" translate="none">
+		<rule
+			name="required"
+			message="The reviewed by field is required."/>
+	</validator>
+   <validator column="status" translate="none">
+      <rule
+         name="validValues"
+         value="new|reviewed|archived"
+         message="Invalid status. (new, reviewed, archived)" />
+	</validator>
+  </table>
+
+</database>
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/projects/bookstore-packaged/runtime-conf.xml
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/projects/bookstore-packaged/runtime-conf.xml	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/projects/bookstore-packaged/runtime-conf.xml	(revision 19)
@@ -0,0 +1,66 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<!-- This new XML configuration format is the default format for properties
+	files.  You can also used the old INI-based .properties format, but
+	support for this will be removed in next major Propel version. -->
+
+<config>
+	<!--
+	#
+	#  L O G G I N G
+	#
+	# We use PEAR-compatible Log for all Propel logging and we embed the
+	# log conf properties within our application configuration.
+	#
+	#   type    - the type of log (default 'file')
+	#   name    - the name of log or path to file. (default './propel.log')
+	#   ident   - the text used to identify the log messages
+	#   level   - the log level
+	#                   PEAR_LOG_EMERG    0
+	#                   PEAR_LOG_ALERT    1
+	#                   PEAR_LOG_CRIT     2
+	#                   PEAR_LOG_ERR      3
+	#                   PEAR_LOG_WARNING  4
+	#                   PEAR_LOG_NOTICE   5
+	#                   PEAR_LOG_INFO     6
+	#                   PEAR_LOG_DEBUG    7  <== DEFAULT
+	-->
+	<log>
+		<ident>propel-bookstore-packaged</ident>
+		<level>7</level>
+	</log>
+	<!--
+	#
+	#  P R O P E L  P R O P E R T I E S
+	#
+	# Note that you can configure multiple datasources; for example if your
+	# project uses several databases.
+	-->
+	<propel>
+		<datasources default="bookstore-packaged">
+			<datasource id="bookstore">
+				<!-- the Propel adapter (usually same as phptype of connection DSN) -->
+				<adapter>sqlite</adapter>
+				<!-- Connection DSN.  See PEAR DSN format for other supported parameters. -->
+				<connection>
+					<phptype>sqlite</phptype>
+					<hostspec>localhost</hostspec>
+					<database>./bookstore.db</database>
+					<username></username>
+					<password></password>
+				</connection>
+			</datasource>
+			<datasource id="bookstore-log">
+				<!-- the Propel adapter (usually same as phptype of connection DSN) -->
+				<adapter>sqlite</adapter>
+				<!-- Connection DSN.  See PEAR DSN format for other supported parameters. -->
+				<connection>
+					<phptype>sqlite</phptype>
+					<hostspec>localhost</hostspec>
+					<database>./bookstore-log.db</database>
+					<username></username>
+					<password></password>
+				</connection>
+			</datasource>
+		</datasources>
+	</propel>
+</config>
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/projects/bookstore/build.properties
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/projects/bookstore/build.properties	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/projects/bookstore/build.properties	(revision 19)
@@ -0,0 +1,38 @@
+# $Id: build.properties 1015 2008-03-22 13:39:51Z heltem $
+# 
+# This is a project-specific build.properties file.  The properties
+# in this file override anything set in Propel's top-level build.properties
+# file when *this* project is being built.
+#
+# See top-level build.properties-sample for explanation of configuration
+# options.
+#
+# Because this file is included before the top-level build.properties file,
+# you cannot refer to any properties set therein.
+
+propel.project = bookstore
+propel.database = mysql 
+propel.database.url = mysql:dbname=test
+propel.mysqlTableType = InnoDB
+propel.disableIdentifierQuoting=true
+
+# For MySQL or Oracle, you also need to specify username & password 
+#propel.database.user = [db username]
+#propel.database.password = [db password]
+
+# Note that if you do not wish to specify the database (e.g. if you
+# are using multiple databses) you can use the @DB@ token which
+# will be replaced with a database at runtime.
+# E.g.: propel.database.url = sqlite://localhost/./test/@DB@.db
+# This will work for the datadump and the insert-sql tasks.
+
+# propel.database.createUrl = (doesn't apply for SQLite, since db is auto-created)
+
+propel.targetPackage = bookstore
+
+# The unit tests need to test this stuff
+propel.addGenericAccessors = true
+propel.addGenericMutators = true
+
+# Use the new PHP 5.2 DateTime class
+propel.useDateTimeClass = true
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/projects/bookstore/cms-schema.xml
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/projects/bookstore/cms-schema.xml	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/projects/bookstore/cms-schema.xml	(revision 19)
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<database name="bookstore-cms" defaultPhpNamingMethod="nochange" package="cms">
+
+	<table name="Page" idMethod="native" treeMode="NestedSet">
+		<column name="Id" type="INTEGER" required="true" autoIncrement="true" primaryKey="true"/>
+		<column name="LeftChild" type="INTEGER" required="true" nestedSetLeftKey="true"/>
+		<column name="RightChild" type="INTEGER" required="true" nestedSetRightKey="true"/>
+		<column name="ScopeId" type="INTEGER" required="true" default="0" treeScopeKey="true"/>
+		<column name="Title" type="VARCHAR" size="255" />
+	</table>
+
+	<table name="Category" idMethod="native" treeMode="NestedSet">
+		<column name="Id" type="INTEGER" required="true" autoIncrement="true" primaryKey="true"/>
+		<column name="LeftChild" type="INTEGER" required="true" nestedSetLeftKey="true"/>
+		<column name="RightChild" type="INTEGER" required="true" nestedSetRightKey="true"/>
+		<column name="Title" type="VARCHAR" size="255" />
+	</table>
+
+</database>
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/projects/bookstore/runtime-conf.xml
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/projects/bookstore/runtime-conf.xml	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/projects/bookstore/runtime-conf.xml	(revision 19)
@@ -0,0 +1,103 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<config>
+	<!--
+	#
+	#  L O G G I N G
+	#
+	# We use PEAR-compatible Log for all Propel logging and we embed the
+	# log conf properties within our application configuration.
+	#
+	#   type    - the type of log (default 'file')
+	#   name    - the name of log or path to file. (default './propel.log')
+	#   ident   - the text used to identify the log messages
+	#   level   - the log level
+	#                   PEAR_LOG_EMERG    0
+	#                   PEAR_LOG_ALERT    1
+	#                   PEAR_LOG_CRIT     2
+	#                   PEAR_LOG_ERR      3
+	#                   PEAR_LOG_WARNING  4
+	#                   PEAR_LOG_NOTICE   5
+	#                   PEAR_LOG_INFO     6
+	#                   PEAR_LOG_DEBUG    7
+	#
+	# Note that if you omit the <log> config section, Propel will not attempt to
+	# configure a logger, and you will need to specify one manually using
+	# Propel::setLogger() if you want Propel to log debug or error messages.
+	-->
+	<log>
+		<ident>propel-bookstore</ident>
+		<name>propel.log</name>
+		<level>7</level>
+	</log>
+	<!--
+	#
+	#  P R O P E L  P R O P E R T I E S
+	#
+	# Note that you can configure multiple datasources; for example if your
+	# project uses several databases.
+	-->
+	<propel>
+		<datasources default="bookstore">
+			<datasource id="bookstore">
+			
+				<!-- the Propel adapter to use for this connection -->
+				<adapter>mysql</adapter>
+				<!-- Connection parameters. See PDO documentation for DSN format and available option constants. -->
+				<connection>
+					<classname>DebugPDO</classname>
+					<dsn>mysql:dbname=test</dsn>
+					<!--
+					For MySQL and Oracle you must specify username + password separate from DSN:
+					<user>bookstore</user>
+					<password></password>
+					-->
+					<options>
+						<option id="ATTR_PERSISTENT">false</option>
+					</options>
+					
+					<attributes>
+						<!--
+							For MySQL, you should also turn on prepared statement emulation, 
+								as prepared statements support is buggy in mysql driver
+						-->
+						<option id="ATTR_EMULATE_PREPARES">true</option>
+					</attributes>
+					
+					<settings>
+						<!--  Set the character set for client connection -->
+						<setting id="charset">utf8</setting>
+						<!-- you can also execute arbitrary queries after the connection is created
+						<setting id="queries">
+							<query>SELECT * FROM foo</query>
+							<query>INSERT INTO BAR ('hey', 'there')</query>
+						</setting>
+						-->
+					</settings>
+				</connection>
+			</datasource>
+			
+			<datasource id="bookstore-cms">
+				<adapter>mysql</adapter>
+				<connection>
+					<classname>DebugPDO</classname>
+					<dsn>mysql:dbname=test</dsn>
+					<!--
+					For MySQL and Oracle you must specify username + password separate from DSN:
+					<user>bookstore</user>
+					<password></password>
+					-->
+					<options>
+						<option id="ATTR_PERSISTENT">false</option>
+					</options>
+					<attributes>
+						<option id="ATTR_EMULATE_PREPARES">true</option>
+					</attributes>
+					<settings>
+						<setting id="charset">utf8</setting>
+					</settings>
+				</connection>
+			</datasource>
+
+		</datasources>
+	</propel>
+</config>
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/projects/bookstore/schema.xml
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/projects/bookstore/schema.xml	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/projects/bookstore/schema.xml	(revision 19)
@@ -0,0 +1,318 @@
+<?xml version="1.0" encoding="ISO-8859-1" standalone="no"?>
+<database name="bookstore" defaultIdMethod="native">
+
+	<table name="book" description="Book Table">
+		<column name="id" required="true" primaryKey="true"
+			autoIncrement="true" type="INTEGER" description="Book Id" />
+		<column name="title" type="VARCHAR" required="true"
+			description="Book Title" />
+		<column name="isbn" required="true" type="VARCHAR" size="24"
+			phpName="ISBN" description="ISBN Number" />
+		<column name="price" required="false" type="FLOAT"
+			description="Price of the book." />
+		<column name="publisher_id" required="false" type="INTEGER"
+			description="Foreign Key Publisher" />
+		<column name="author_id" required="false" type="INTEGER"
+			description="Foreign Key Author" />
+		<foreign-key foreignTable="publisher" onDelete="SETNULL">
+			<reference local="publisher_id" foreign="id" />
+		</foreign-key>
+		<foreign-key foreignTable="author" onDelete="SETNULL">
+			<reference local="author_id" foreign="id" />
+		</foreign-key>
+		<validator column="title" translate="none">
+			<rule name="unique"
+				message="Book title already in database." />
+			<rule name="minLength" value="10"
+				message="Book title must be more than ${value} characters long." />
+			<rule name="maxLength" value="255"
+				message="Book title must not be longer than ${value} characters." />
+		</validator>
+		<validator column="isbn" translate="none">
+			<rule name="class" class="bookstore.validator.ISBNValidator" message="ISBN does not validate!"/>
+		</validator>
+	</table>
+
+	<table name="publisher" description="Publisher Table">
+		<column name="id" required="true" primaryKey="true"
+			autoIncrement="true" type="INTEGER" description="Publisher Id" />
+		<column name="name" required="true" type="VARCHAR" size="128"
+			default="Penguin" description="Publisher Name" />
+	</table>
+
+	<table name="author" description="Author Table">
+		<column name="id" required="true" primaryKey="true"
+			autoIncrement="true" type="INTEGER" description="Author Id" />
+		<column name="first_name" required="true" type="VARCHAR"
+			size="128" description="First Name" />
+		<column name="last_name" required="true" type="VARCHAR"
+			size="128" description="Last Name" />
+		<column name="email" type="VARCHAR" size="128"
+			description="E-Mail Address" />
+		<column name="age" type="INTEGER" description="The authors age" />
+		<validator column="last_name" translate="none">
+			<rule name="required"
+				message="The last name field is required." />
+		</validator>
+		<validator column="email" translate="none">
+			<rule name="match"
+				value="/^([a-zA-Z0-9])+([\.a-zA-Z0-9_-])*@([a-zA-Z0-9])+(\.[a-zA-Z0-9_-]+)+$/"
+				message="Please enter a valid email address." />
+		</validator>
+		<validator column="age" translate="none">
+			<rule name="minValue" value="0"
+				message="Please enter a positive number." />
+			<rule name="maxValue" value="100"
+				message="Impressive age! Just kidding, hm?" />
+		</validator>
+	</table>
+
+	<table name="review" description="Book Review">
+		<column name="id" required="true" primaryKey="true"
+			autoIncrement="true" type="INTEGER" description="Author Id" />
+		<column name="reviewed_by" required="true" type="VARCHAR"
+			size="128" description="Reviewer Name" />
+		<column name="review_date" required="true" type="DATE"
+			default="2001-01-01" description="Date of Review" />
+		<column name="recommended" required="true" type="BOOLEAN"
+			description="Does reviewer recommend book?" />
+		<column name="status" type="VARCHAR" size="8"
+			description="The status of this review." />
+		<column name="book_id" required="true" type="INTEGER"
+			description="Book ID for this review" />
+		<foreign-key foreignTable="book" onDelete="CASCADE">
+			<reference local="book_id" foreign="id" />
+		</foreign-key>
+		<validator column="reviewed_by" translate="none">
+			<rule name="required"
+				message="The reviewed by field is required." />
+		</validator>
+		<validator column="status" translate="none">
+			<rule name="validValues" value="new|reviewed|archived"
+				message="Invalid status. (new, reviewed, archived)" />
+		</validator>
+	</table>
+
+	<!-- This table exists to explore/test the handling of BLOB/CLOB objects. -->
+	<table name="media">
+		<column name="id" required="true" primaryKey="true"
+			autoIncrement="true" type="INTEGER" description="Media Id" />
+		<column name="cover_image" type="BLOB" lazyLoad="true"
+			description="The image of the book cover." />
+		<column name="excerpt" type="CLOB" lazyLoad="true"
+			description="An excerpt from the book." />
+		<column name="book_id" required="true" type="INTEGER"
+			description="Book ID for this media collection." />
+		<foreign-key foreignTable="book" onDelete="CASCADE">
+			<reference local="book_id" foreign="id" />
+		</foreign-key>
+	</table>
+
+	<!-- this table exists to test the many-to-many -->
+	<table name="book_club_list"
+		description="Reading list for a book club.">
+		<column name="id" required="true" primaryKey="true"
+			autoIncrement="true" type="INTEGER"
+			description="Unique ID for a school reading list." />
+		<column name="group_leader" required="true" type="VARCHAR"
+			size="100"
+			description="The name of the teacher in charge of summer reading." />
+		<column name="theme" required="false" type="VARCHAR" size="50"
+			description="The theme, if applicable, for the reading list." />
+	</table>
+
+	<table name="book_x_list" phpName="BookListRel"
+		description="Cross-reference table for many-to-many relationship between book rows and book_club_list rows.">
+		<column name="book_id" primaryKey="true" type="INTEGER"
+			description="Fkey to book.id" />
+		<column name="book_club_list_id" primaryKey="true"
+			type="INTEGER" description="Fkey to book_club_list.id" />
+		<foreign-key foreignTable="book" onDelete="CASCADE">
+			<reference local="book_id" foreign="id" />
+		</foreign-key>
+		<foreign-key foreignTable="book_club_list" onDelete="CASCADE">
+			<reference local="book_club_list_id" foreign="id" />
+		</foreign-key>
+	</table>
+
+	<!-- test self-referencing foreign keys and inheritance-->
+	<table name="bookstore_employee"
+		description="Hierarchical table to represent employees of a bookstore.">
+		<column name="id" type="INTEGER" primaryKey="true"
+			autoIncrement="true" description="Employee ID number" />
+		<column name="class_key" type="INTEGER" required="true"
+			default="0" inheritance="single">
+			<inheritance key="0" class="BookstoreEmployee" />
+			<inheritance key="1" class="BookstoreManager"
+				extends="BookstoreEmployee" />
+			<inheritance key="2" class="BookstoreCashier"
+				extends="BookstoreEmployee" />
+		</column>
+		<column name="name" type="VARCHAR" size="32"
+			description="Employee name" />
+		<column name="job_title" type="VARCHAR" size="32"
+			description="Employee job title" />
+		<column name="supervisor_id" type="INTEGER"
+			description="Fkey to supervisor." />
+		<column name="photo" type="BLOB" lazyLoad="true" />
+		<foreign-key foreignTable="bookstore_employee"
+			phpName="Supervisor" refPhpName="Subordinate" onDelete="SETNULL">
+			<reference local="supervisor_id" foreign="id" />
+		</foreign-key>
+	</table>
+
+	<!-- Test one-to-one (1:1) relationship, default values -->
+	<table name="bookstore_employee_account" reloadOnInsert="true"
+		reloadOnUpdate="true"
+		description="A table that represents a bookstore employees login credentials.">
+		<column name="employee_id" type="INTEGER" primaryKey="true"
+			description="Primary key for the account ..." />
+		<column name="login" type="VARCHAR" size="32" />
+		<column name="password" type="VARCHAR" size="100"
+			default="'@''34&quot;" />
+		<column name="enabled" type="BOOLEAN" default="true" />
+		<column name="created" type="TIMESTAMP"
+			defaultExpr="CURRENT_TIMESTAMP" />
+		<column name="role_id" type="INTEGER" required="false" />
+		<column name="authenticator" type="VARCHAR" size="32"
+			defaultExpr="'Password'" />
+		<foreign-key foreignTable="bookstore_employee"
+			onDelete="cascade">
+			<reference local="employee_id" foreign="id" />
+		</foreign-key>
+		<foreign-key foreignTable="acct_access_role"
+			onDelete="setnull">
+			<reference local="role_id" foreign="id" />
+		</foreign-key>
+		<unique>
+			<unique-column name="login" />
+		</unique>
+	</table>
+
+	<table name="acct_access_role">
+		<column name="id" type="INTEGER" primaryKey="true"
+			autoIncrement="true" description="Role ID number" />
+		<column name="name" type="VARCHAR" size="25" required="true" />
+	</table>
+
+	<!--  book_reader, book_opinion, and reader_favorite test some foreign key issues  
+		(see: http://propel.phpdb.org/trac/ticket/228) -->
+	<table name="book_reader">
+		<column name="id" type="INTEGER" primaryKey="true"
+			autoIncrement="true" description="Book reader ID number" />
+		<column name="name" type="VARCHAR" size="50" />
+	</table>
+
+	<table name="book_opinion">
+		<column name="book_id" type="INTEGER" primaryKey="true" />
+		<column name="reader_id" type="INTEGER" primaryKey="true" />
+		<column name="rating" type="DECIMAL" />
+		<column name="recommend_to_friend" type="BOOLEAN" />
+		<foreign-key foreignTable="book" onDelete="cascade">
+			<reference local="book_id" foreign="id" />
+		</foreign-key>
+		<foreign-key foreignTable="book_reader" onDelete="cascade">
+			<reference local="reader_id" foreign="id" />
+		</foreign-key>
+	</table>
+
+	<table name="reader_favorite"><!--  this is just for the sake of testing multiple foreign keys for a single column -->
+		<column name="book_id" type="INTEGER" primaryKey="true" />
+		<column name="reader_id" type="INTEGER" primaryKey="true" />
+		<foreign-key foreignTable="book" onDelete="cascade">
+			<reference local="book_id" foreign="id" />
+		</foreign-key>
+		<foreign-key foreignTable="book_reader" onDelete="cascade">
+			<reference local="reader_id" foreign="id" />
+		</foreign-key>
+		
+		<foreign-key foreignTable="book_opinion" onDelete="cascade">
+			<reference local="book_id" foreign="book_id"/>
+			<reference local="reader_id" foreign="reader_id"/>
+		</foreign-key>
+		
+	</table>
+
+	<!--  Test some custom php column types. -->
+	<table name="bookstore">
+		<column name="id" type="INTEGER" primaryKey="true"
+			autoIncrement="true" description="Book store ID number" />
+		<column name="store_name" type="VARCHAR" size="50"
+			required="true" />
+		<column name="location" type="VARCHAR" size="100" />
+		<column name="population_served" type="BIGINT" />
+		<column name="total_books" type="INTEGER" />
+		<column name="store_open_time" type="TIME" />
+		<column name="website" type="VARCHAR" size="255"/>
+		<validator column="website">
+			<rule name="match" value="/^((ht|f)tp(s?)\:\/\/[a-zA-Z0-9\-\._]+(\.[a-zA-Z0-9\-\._]+){2,}(\/?)([a-zA-Z0-9\-\.\?\,'\/\\\+&amp;amp;%\$#_]*)?$|$)/" message="wrong url"/>
+		</validator>
+	</table>
+
+	<!--  test default values on foreign keys, default expr w/ reloadOnUpdate="true" -->
+	<table name="bookstore_sale" reloadOnUpdate="true">
+		<column name="id" type="INTEGER" primaryKey="true"
+			autoIncrement="true" />
+		<column name="bookstore_id" type="INTEGER" required="false"
+			default="1" />
+		<column name="publisher_id" type="INTEGER" required="false" />
+		<column name="sale_name" type="VARCHAR" size="100"
+			required="false" />
+		<column name="discount" type="TINYINT"
+			description="Discount percentage" defaultExpr="10" />
+		<foreign-key foreignTable="bookstore" onDelete="cascade">
+			<reference local="bookstore_id" foreign="id" />
+		</foreign-key>
+		<foreign-key foreignTable="publisher" onDelete="SETNULL">
+			<reference local="publisher_id" foreign="id" />
+		</foreign-key>
+	</table>
+
+	<table name="customer" allowPkInsert="true">
+		<column name="id" type="INTEGER" primaryKey="true"
+			autoIncrement="true" />
+		<column name="name" type="VARCHAR" size="255" />
+		<column name="join_date" type="DATE" />
+	</table>
+
+	<table name="contest">
+		<column name="id" type="INTEGER" primaryKey="true"
+			autoIncrement="true" />
+		<column name="name" type="VARCHAR" size="100" />
+	</table>
+
+	<table name="bookstore_contest">
+		<column name="bookstore_id" type="INTEGER" primaryKey="true" />
+		<column name="contest_id" type="INTEGER" primaryKey="true" />
+		<column name="prize_book_id" type="INTEGER" />
+		<foreign-key foreignTable="bookstore" onDelete="CASCADE">
+			<reference local="bookstore_id" foreign="id" />
+		</foreign-key>
+		<foreign-key foreignTable="contest" onDelete="CASCADE">
+			<reference local="contest_id" foreign="id" />
+		</foreign-key>
+		<foreign-key foreignTable="book" onDelete="SETNULL">
+			<reference local="prize_book_id" foreign="id" />
+		</foreign-key>
+	</table>
+
+	<table name="bookstore_contest_entry" reloadOnInsert="true">
+		<column name="bookstore_id" type="INTEGER" primaryKey="true" />
+		<column name="contest_id" type="INTEGER" primaryKey="true" />
+		<column name="customer_id" type="INTEGER" primaryKey="true" />
+		<column name="entry_date" type="TIMESTAMP"
+			defaultExpr="CURRENT_TIMESTAMP" />
+		<foreign-key foreignTable="bookstore" onDelete="CASCADE">
+			<reference local="bookstore_id" foreign="id" />
+		</foreign-key>
+		<foreign-key foreignTable="customer" onDelete="CASCADE">
+			<reference local="customer_id" foreign="id" />
+		</foreign-key>
+		<foreign-key foreignTable="bookstore_contest"
+			onDelete="CASCADE">
+			<reference local="bookstore_id" foreign="bookstore_id" />
+			<reference local="contest_id" foreign="contest_id" />
+		</foreign-key>
+	</table>
+
+</database>
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/projects/nestedset/build.properties
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/projects/nestedset/build.properties	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/projects/nestedset/build.properties	(revision 19)
@@ -0,0 +1,40 @@
+# $Id: build.properties 738 2007-11-03 15:24:55Z heltem $
+# 
+# This is a project-specific build.properties file.  The properties
+# in this file override anything set in Propel's top-level build.properties
+# file when *this* project is being built.
+#
+# See top-level build.properties-sample for explanation of configuration
+# options.
+#
+# Because this file is included before the top-level build.properties file,
+# you cannot refer to any properties set therein.
+
+propel.project = nestedset
+propel.database = sqlite
+propel.database.url = sqlite://localhost/./test/nestedset.db
+# For MySQL or Oracle, you also need to specify username & password 
+# propel.database.user = [db username]
+# propel.database.password = [db password]
+
+# Note that if you do not wish to specify the database (e.g. if you
+# are using multiple databses) you can use the @DB@ token which
+# will be replaced with a database at runtime.
+# E.g.: propel.database.url = sqlite://localhost/./test/@DB@.db
+# This will work for the datadump and the insert-sql tasks.
+
+# propel.database.createUrl = (doesn't aply for SQLite, since db is auto-created)
+
+propel.targetPackage = nestedset
+
+# The unit tests need to test this stuff
+propel.addGenericAccessors = true
+propel.addGenericMutators = true
+
+propel.home = .
+propel.output.dir = ${propel.home}/projects/${propel.project}/build
+propel.schema.dir = ${propel.home}/projects/${propel.project}
+propel.conf.dir = ${propel.home}/projects/${propel.project}
+
+# Use the new PHP 5.2 DateTime class
+propel.useDateTimeClass = true
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/projects/nestedset/nestedset-schema.xml
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/projects/nestedset/nestedset-schema.xml	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/projects/nestedset/nestedset-schema.xml	(revision 19)
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="ISO-8859-1" standalone="no"?>
+<database name="treetest" defaultIdMethod="native">
+	<table name="test" treeMode="NestedSet" description="Test">
+		<column
+			name="id"
+			required="true"
+			primaryKey="true"
+			autoIncrement="true"
+			type="INTEGER"
+			description="Node Id"/>
+		<column
+			name="left"
+			required="true"
+			nestedSetLeftKey="true"
+			type="INTEGER"
+			description="Node Left Key"/>
+		<column
+			name="right"
+			required="true"
+			nestedSetRightKey="true"
+			type="INTEGER"
+			description="Node Right Key"/>
+		<column
+			name="label"
+			required="true"
+			type="VARCHAR"
+			size="10"
+			description="Label"/>
+		<unique name="pk">
+			<unique-column name="label"/>
+		</unique>
+		<index name="left">
+			<index-column name="left"/>
+		</index>
+		<index name="right">
+			<index-column name="right"/>
+		</index>
+	</table>
+</database>
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/projects/nestedset/runtime-conf.xml
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/projects/nestedset/runtime-conf.xml	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/projects/nestedset/runtime-conf.xml	(revision 19)
@@ -0,0 +1,54 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<!-- This new XML configuration format is the default format for properties 
+	files.  You can also used the old INI-based .properties format, but 
+	support for this will be removed in next major Propel version. -->
+		
+<config>
+	<!--
+	#
+	#  L O G G I N G
+	#
+	# We use PEAR-compatible Log for all Propel logging and we embed the 
+	# log conf properties within our application configuration.
+	#
+	#   type    - the type of log (default 'file')
+	#   name    - the name of log or path to file. (default './propel.log')
+	#   ident   - the text used to identify the log messages
+	#   level   - the log level
+	#                   PEAR_LOG_EMERG    0
+	#                   PEAR_LOG_ALERT    1
+	#                   PEAR_LOG_CRIT     2
+	#                   PEAR_LOG_ERR      3
+	#                   PEAR_LOG_WARNING  4
+	#                   PEAR_LOG_NOTICE   5
+	#                   PEAR_LOG_INFO     6
+	#                   PEAR_LOG_DEBUG    7  <== DEFAULT
+	-->
+	<log>
+		<ident>propel-nestedset</ident>
+		<level>7</level>
+	</log>
+	<!--
+	#
+	#  P R O P E L  P R O P E R T I E S
+	#
+	# Note that you can configure multiple datasources; for example if your
+	# project uses several databases.
+	-->
+	<propel>
+		<datasources default="nestedset">
+			<datasource id="nestedset">
+				<!-- the Propel adapter (usually same as phptype of connection DSN) -->
+				<adapter>sqlite</adapter>				
+				<!-- Connection DSN.  See PEAR DSN format for other supported parameters. -->
+				<connection>
+					<phptype>sqlite</phptype>
+					<hostspec>localhost</hostspec>
+					<database>./test/nestedset.db</database>
+					<username></username>
+					<password></password>
+				</connection>				
+			</datasource>			
+		</datasources>	
+	</propel>
+</config>
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/projects/treetest/build.properties
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/projects/treetest/build.properties	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/projects/treetest/build.properties	(revision 19)
@@ -0,0 +1,29 @@
+# $Id: build.properties 505 2007-01-01 19:45:13Z heltem $
+# 
+# This is a project-specific build.properties file.  The properties
+# in this file override anything set in Propel's top-level build.properties
+# file when *this* project is being built.
+#
+# See top-level build.properties-sample for explanation of configuration 
+# options.
+#
+# Because this file is included before the top-level build.properties file, 
+# you cannot refer to any properties set therein.
+
+propel.targetPackage = treetest
+propel.project = treetest
+
+propel.database = sqlite
+propel.database.url = sqlite://localhost/./test/treetest.db
+
+#propel.database = mysql
+#propel.database.url = mysql://localhost/test
+
+#propel.database = codebase
+#propel.database.url = odbc://localhost/Driver=CodeBaseOdbcStand;DBQ=test;?adapter=CodeBase
+
+propel.home = .
+propel.output.dir = ${propel.home}/projects/${propel.project}/build
+propel.schema.dir = ${propel.home}/projects/${propel.project}
+propel.conf.dir = ${propel.home}/projects/${propel.project}
+
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/projects/treetest/runtime-conf.xml
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/projects/treetest/runtime-conf.xml	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/projects/treetest/runtime-conf.xml	(revision 19)
@@ -0,0 +1,54 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<!-- This new XML configuration format is the default format for properties 
+	files.  You can also used the old INI-based .properties format, but 
+	support for this will be removed in next major Propel version. -->
+		
+<config>
+	<!--
+	#
+	#  L O G G I N G
+	#
+	# We use PEAR-compatible Log for all Propel logging and we embed the 
+	# log conf properties within our application configuration.
+	#
+	#   type    - the type of log (default 'file')
+	#   name    - the name of log or path to file. (default './propel.log')
+	#   ident   - the text used to identify the log messages
+	#   level   - the log level
+	#                   PEAR_LOG_EMERG    0
+	#                   PEAR_LOG_ALERT    1
+	#                   PEAR_LOG_CRIT     2
+	#                   PEAR_LOG_ERR      3
+	#                   PEAR_LOG_WARNING  4
+	#                   PEAR_LOG_NOTICE   5
+	#                   PEAR_LOG_INFO     6
+	#                   PEAR_LOG_DEBUG    7  <== DEFAULT
+	-->
+	<log>
+		<ident>propel-treetest</ident>
+		<level>7</level>
+	</log>
+	<!--
+	#
+	#  P R O P E L  P R O P E R T I E S
+	#
+	# Note that you can configure multiple datasources; for example if your
+	# project uses several databases.
+	-->
+	<propel>
+		<datasources default="treetest">		
+			<datasource id="treetest">
+				<!-- the Propel adapter (usually same as phptype of connection DSN) -->
+				<adapter>sqlite</adapter>				
+				<!-- Connection DSN.  See PEAR DSN format for other supported parameters. -->
+				<connection>
+					<phptype>sqlite</phptype>
+					<hostspec>localhost</hostspec>
+					<database>./test/treetest.db</database>
+					<username></username>
+					<password></password>
+				</connection>				
+			</datasource>			
+		</datasources>	
+	</propel>
+</config>
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/projects/treetest/treetest-schema.xml
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/projects/treetest/treetest-schema.xml	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/projects/treetest/treetest-schema.xml	(revision 19)
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="ISO-8859-1" standalone="no"?>
+<database name="treetest" defaultIdMethod="none">
+
+  <table name="test" treeMode="MaterializedPath" description="Test">
+    <column
+      name="npath"
+      required="true"
+      nodeKey="true"
+      nodeKeySep="."
+      primaryKey="true"
+      type="VARCHAR"
+      size="80"
+      description="Node Path"/>
+    <column
+      name="label"
+      required="true"
+      type="VARCHAR"
+      size="10"
+      description="Label"/>
+    <unique name="pk">
+      <unique-column name="label"/>
+    </unique>
+    <unique name="ck">
+      <unique-column name="npath"/>
+    </unique>
+  </table>
+
+</database>
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/resources/dtd/database.dtd
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/resources/dtd/database.dtd	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/resources/dtd/database.dtd	(revision 19)
@@ -0,0 +1,170 @@
+<!--
+    Propel XML database schema DTD
+    $Id: database.dtd,v 1.7 2005/03/30 11:38:18 hlellelid Exp $
+
+    This is based very closely on the schema DTD for Torque, but
+    some differences do exist.
+-->
+
+<!--
+
+defaultPhpNamingMethod determines how a table or column name,
+from the name attribute in the xml database file, is converted to a
+PHP class or method name.
+
+     nochange   - indicates not change is performed.
+     underscore - Underscores are removed, First letter is
+              capitalized, first letter after an underscore
+              is capitalized, the rest of the letters are
+              converted to lowercase.
+     phpname   - same as underscore, but no letters are converted
+              to lowercase.
+-->
+
+<!ELEMENT database (external-schema*, table+)>
+<!ATTLIST database
+  name CDATA #IMPLIED
+  defaultIdMethod (native|none) "none"
+  defaultTranslateMethode CDATA #IMPLIED
+  package CDATA #IMPLIED
+  baseClass CDATA #IMPLIED
+  basePeer CDATA #IMPLIED
+  defaultPhpNamingMethod (nochange|underscore|phpname) "underscore"
+  heavyIndexing (true|false) "false"
+>
+
+<!ELEMENT external-schema EMPTY>
+<!ATTLIST external-schema
+  filename CDATA #REQUIRED
+>
+
+<!--
+     note: the interface="true", requires that useManagers=true in the
+     properties file.
+-->
+<!ELEMENT table (column+,(foreign-key|index|unique|id-method-parameter|validator|vendor)*)>
+<!ATTLIST table
+  name CDATA #REQUIRED
+  phpName CDATA #IMPLIED
+  idMethod (native|autoincrement|sequence|none|null) "null"
+  skipSql (true|false) "false"
+  readOnly (true|false) "false"
+  abstract (true|false) "false"
+  treeMode (MaterializedPath|NestedSet|AdjacencyList) "AdjacencyList"
+  package CDATA #IMPLIED
+  baseClass CDATA #IMPLIED
+  basePeer CDATA #IMPLIED
+  alias CDATA #IMPLIED
+  interface CDATA #IMPLIED
+  phpNamingMethod (nochange|underscore|phpname) #IMPLIED
+  heavyIndexing (true|false) #IMPLIED
+  description CDATA #IMPLIED
+>
+
+<!ELEMENT id-method-parameter EMPTY>
+<!ATTLIST id-method-parameter
+  name CDATA "default"
+  value CDATA #REQUIRED
+>
+
+<!ELEMENT column ((inheritance|vendor)*)>
+<!ATTLIST column
+  name CDATA #REQUIRED
+  phpName CDATA #IMPLIED
+  peerName CDATA #IMPLIED
+  primaryKey (true|false) "false"
+  required (true|false) "false"
+  type
+    (
+          BIT  | TINYINT | SMALLINT    | INTEGER    | BIGINT    | FLOAT
+        | REAL | NUMERIC | DECIMAL     | CHAR       | VARCHAR   | LONGVARCHAR
+        | DATE | TIME    | TIMESTAMP   | BINARY     | VARBINARY | LONGVARBINARY
+        | NULL | OTHER   | PHP_OBJECT  | DISTINCT   | STRUCT    | ARRAY
+        | BLOB | CLOB    | REF         | BOOLEANINT | BOOLEANCHAR
+        | DOUBLE | BOOLEAN
+    ) "VARCHAR"
+  phpType CDATA #IMPLIED
+  sqlType CDATA #IMPLIED
+  size CDATA #IMPLIED
+  scale CDATA #IMPLIED
+  default CDATA #IMPLIED
+  defaultValue CDATA #IMPLIED
+  defaultExpr CDATA #IMPLIED
+  autoIncrement (true|false) "false"
+  inheritance (single|false) "false"
+  inputValidator CDATA #IMPLIED
+  phpNamingMethod (nochange|underscore|phpname) #IMPLIED
+  description CDATA #IMPLIED
+  lazyLoad (true|false) "false"
+>
+
+<!ELEMENT inheritance EMPTY>
+<!ATTLIST inheritance
+  key CDATA #REQUIRED
+  class CDATA #REQUIRED
+  package CDATA #IMPLIED
+  extends CDATA #IMPLIED
+>
+
+<!ELEMENT foreign-key (reference+, vendor*)>
+<!ATTLIST foreign-key
+  foreignTable CDATA #REQUIRED
+  name CDATA #IMPLIED
+  phpName CDATA #IMPLIED
+  refPhpName CDATA #IMPLIED
+  onUpdate (CASCADE|cascade|SETNULL|setnull|RESTRICT|restrict|NONE|none) "none"
+  onDelete (CASCADE|cascade|SETNULL|setnull|RESTRICT|restrict|NONE|none) "none"
+>
+
+<!ELEMENT reference EMPTY>
+<!ATTLIST reference
+  local CDATA #REQUIRED
+  foreign CDATA #REQUIRED
+>
+
+<!ELEMENT index (index-column+)>
+<!ATTLIST index
+  name CDATA #IMPLIED
+>
+
+<!ELEMENT index-column (vendor*)>
+<!ATTLIST index-column
+  name CDATA #REQUIRED
+  size CDATA #IMPLIED
+>
+
+<!ELEMENT unique (unique-column+)>
+<!ATTLIST unique
+  name CDATA #IMPLIED
+>
+
+<!ELEMENT unique-column (vendor*)>
+<!ATTLIST unique-column
+  name CDATA #REQUIRED
+>
+
+<!ELEMENT validator (rule+)>
+<!ATTLIST validator
+  column CDATA #REQUIRED
+  translate CDATA #IMPLIED
+>
+
+<!ELEMENT rule EMPTY>
+<!ATTLIST rule
+  name (mask|maxLength|maxValue|minLength|minValue|required|unique|validValues|class) #REQUIRED
+  class CDATA #IMPLIED
+  value CDATA #IMPLIED
+  size ID #IMPLIED
+  message CDATA #IMPLIED
+>
+
+<!ELEMENT vendor (parameter+)>
+<!ATTLIST vendor
+  type CDATA #REQUIRED
+>
+
+<!ELEMENT parameter EMPTY>
+<!ATTLIST parameter
+  name CDATA #REQUIRED
+  value CDATA #REQUIRED
+>
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/resources/xsd/custom_datatypes.xsd
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/resources/xsd/custom_datatypes.xsd	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/resources/xsd/custom_datatypes.xsd	(revision 19)
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="ISO-8859-1" ?>
+<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
+
+	<xs:simpleType name='custom_datatypes'>
+		<xs:restriction base='xs:string'>
+		</xs:restriction>
+	</xs:simpleType>
+</xs:schema>
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/resources/xsd/database.xsd
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/resources/xsd/database.xsd	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/resources/xsd/database.xsd	(revision 19)
@@ -0,0 +1,387 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
+	<!-- XML Schema for the Propel schema file
+		  This is just the first draft derived from the existing DTD
+		  and some additional restrictions have been included
+
+		  Comments are a quite rare, I guess most things are pretty
+		  readable. An additional xml schema: custom_datatypes.xsd is
+		  also included. For now this file is unused, but that will
+		  change; don't worry.
+
+		  Ron -->
+
+	<xs:include schemaLocation="custom_datatypes.xsd"/>
+
+	<xs:element name="database" type="database"/>
+	<xs:element name="vendor" type="vendor"/>
+
+	<xs:simpleType name="file">
+		<xs:restriction base="xs:string">
+			<!-- Match any relative or absolute path and file containing letters, numbers and _ -->
+			<xs:pattern value="((\.{1,2}|[\w_]*)/)*([\w_]*\.?)+"/>
+		</xs:restriction>
+	</xs:simpleType>
+
+	<xs:simpleType name="default_datatypes">
+		<xs:restriction base="xs:string">
+			<xs:enumeration value="BIT"/>
+			<xs:enumeration value="TINYINT"/>
+			<xs:enumeration value="SMALLINT"/>
+			<xs:enumeration value="INTEGER"/>
+			<xs:enumeration value="BIGINT"/>
+			<xs:enumeration value="FLOAT"/>
+			<xs:enumeration value="REAL"/>
+			<xs:enumeration value="NUMERIC"/>
+			<xs:enumeration value="DECIMAL"/>
+			<xs:enumeration value="CHAR"/>
+			<xs:enumeration value="VARCHAR"/>
+			<xs:enumeration value="LONGVARCHAR"/>
+			<xs:enumeration value="DATE"/>
+			<xs:enumeration value="TIME"/>
+			<xs:enumeration value="TIMESTAMP"/>
+			<xs:enumeration value="BINARY"/>
+			<xs:enumeration value="VARBINARY"/>
+			<xs:enumeration value="LONGVARBINARY"/>
+			<xs:enumeration value="NULL"/>
+			<xs:enumeration value="OTHER"/>
+			<xs:enumeration value="PHP_OBJECT"/>
+			<xs:enumeration value="DISTINCT"/>
+			<xs:enumeration value="STRUCT"/>
+			<xs:enumeration value="ARRAY"/>
+			<xs:enumeration value="BLOB"/>
+			<xs:enumeration value="CLOB"/>
+			<xs:enumeration value="REF"/>
+			<xs:enumeration value="BOOLEANINT"/>
+			<xs:enumeration value="BOOLEANCHAR"/>
+			<xs:enumeration value="DOUBLE"/>
+			<xs:enumeration value="BOOLEAN"/>
+		</xs:restriction>
+	</xs:simpleType>
+
+	<xs:simpleType name="datatype">
+		<xs:union memberTypes="default_datatypes custom_datatypes"/>
+	</xs:simpleType>
+
+	<xs:simpleType name="dbidmethod">
+		<xs:restriction base="xs:string">
+			<xs:enumeration value="native"/>
+			<xs:enumeration value="none"/>
+		</xs:restriction>
+	</xs:simpleType>
+
+	<xs:simpleType name="tbidmethod">
+		<xs:restriction base="xs:string">
+			<xs:enumeration value="autoincrement"/>
+			<xs:enumeration value="sequence"/>
+			<xs:enumeration value="null"/>
+		</xs:restriction>
+	</xs:simpleType>
+
+	<xs:simpleType name="idmethod">
+		<xs:union memberTypes="dbidmethod tbidmethod"/>
+	</xs:simpleType>
+
+	<xs:simpleType name="phpnamingmethod">
+		<xs:restriction base="xs:string">
+			<xs:enumeration value="nochange"/>
+			<xs:enumeration value="underscore"/>
+			<xs:enumeration value="phpname"/>
+		</xs:restriction>
+	</xs:simpleType>
+
+	<xs:simpleType name="delete">
+		<xs:restriction base="xs:string">
+			<xs:enumeration value="cascade"/>
+			<xs:enumeration value="set null"/>
+			<xs:enumeration value="setnull"/>
+			<xs:enumeration value="restrict"/>
+			<xs:enumeration value="none"/>
+			<xs:enumeration value=""/>
+		</xs:restriction>
+	</xs:simpleType>
+
+	<xs:simpleType name="update">
+		<xs:restriction base="xs:string">
+			<xs:enumeration value="cascade"/>
+			<xs:enumeration value="setnull"/>
+			<xs:enumeration value="set null"/>
+			<xs:enumeration value="restrict"/>
+			<xs:enumeration value="none"/>
+			<xs:enumeration value=""/>
+		</xs:restriction>
+	</xs:simpleType>
+
+	<xs:simpleType name="rulename">
+		<xs:restriction base="xs:string">
+			<xs:enumeration value="mask"/>
+			<xs:enumeration value="maxLength"/>
+			<xs:enumeration value="maxValue"/>
+			<xs:enumeration value="minLength"/>
+			<xs:enumeration value="minValue"/>
+			<xs:enumeration value="required"/>
+			<xs:enumeration value="unique"/>
+			<xs:enumeration value="validValues"/>
+			<xs:enumeration value="notMatch"/>
+			<xs:enumeration value="match"/>
+			<xs:enumeration value="class"/>
+		</xs:restriction>
+	</xs:simpleType>
+
+	<xs:simpleType name="inh_option">
+		<xs:restriction base="xs:string">
+			<xs:enumeration value="single"/>
+			<xs:enumeration value="false"/>
+		</xs:restriction>
+	</xs:simpleType>
+	
+	<xs:simpleType name="sql_type">
+		<xs:restriction base="xs:string">
+			<xs:pattern value="[\w_\[\]]+"/>
+		</xs:restriction>
+	</xs:simpleType>
+	
+	<xs:simpleType name="php_type">
+		<xs:restriction base="xs:string">
+			<xs:pattern value="[\w_]+"/>
+		</xs:restriction>
+	</xs:simpleType>
+
+	<xs:simpleType name="treemode">
+		<xs:restriction base="xs:string">
+			<xs:enumeration value="AdjacencyList"/>
+			<xs:enumeration value="MaterializedPath"/>
+			<xs:enumeration value="NestedSet"/>
+		</xs:restriction>
+	</xs:simpleType>
+
+	<!-- Visibility for column accessor and mutator methods -->
+	<xs:simpleType name="visibility">
+		<xs:restriction base="xs:string">
+			<xs:enumeration value="public"/>
+			<xs:enumeration value="protected"/>
+			<xs:enumeration value="private"/>
+		</xs:restriction>
+	</xs:simpleType>
+
+	<!-- Restrict column name to letters (upper- and lowercase), numbers and the _ -->
+	<xs:simpleType name="column_name">
+		<xs:restriction base="xs:string">
+			<xs:pattern value="[\w_]+"/>
+		</xs:restriction>
+	</xs:simpleType>
+
+	<!-- Restrict php name to letters (upper- and lowercase), numbers and the _ -->
+	<xs:simpleType name="php_name">
+		<xs:restriction base="xs:string">
+			<xs:pattern value="[\w_]+"/>
+		</xs:restriction>
+	</xs:simpleType>
+
+	<!-- Restrict php class name to letters (upper- and lowercase), numbers and the _. Dot seperated -->
+	<xs:simpleType name="php_class">
+		<xs:restriction base="xs:string">
+			<xs:pattern value="([\w_]+.?)+"/>
+		</xs:restriction>
+	</xs:simpleType>
+
+	<!-- Restrict table name to letters (upper- and lowercase), numbers and the _ -->
+	<xs:simpleType name="table_name">
+		<xs:restriction base="xs:string">
+			<xs:pattern value="[\w_]+"/>
+		</xs:restriction>
+	</xs:simpleType>
+
+	<!-- Restrict index name to letters (upper- and lowercase), numbers and the _ -->
+	<xs:simpleType name="index_name">
+		<xs:restriction base="xs:string">
+			<xs:pattern value="[\w_]+"/>
+		</xs:restriction>
+	</xs:simpleType>
+
+	<!-- Restrict foreign column name to letters (upper- and lowercase), numbers and the _ -->
+	<xs:simpleType name="foreign_name">
+		<xs:restriction base="xs:string">
+			<xs:pattern value="[\w_]+"/>
+		</xs:restriction>
+	</xs:simpleType>
+
+	<xs:complexType name="parameter">
+		<xs:attribute name="name" type="xs:string" use="required"/>
+		<xs:attribute name="value" type="xs:string" use="required"/>
+	</xs:complexType>
+
+	<xs:complexType name="validator">
+		<xs:sequence>
+			<xs:element name="rule" type="rule" maxOccurs="unbounded"/>
+		</xs:sequence>
+		<xs:attribute name="column" type="column_name" use="required"/>
+		<xs:attribute name="translate" type="xs:string" use="optional"/>
+	</xs:complexType>
+
+	<xs:complexType name="vendor">
+		<xs:sequence>
+			<xs:element name="parameter" type="parameter" maxOccurs="unbounded"/>
+		</xs:sequence>
+		<xs:attribute name="type" use="required"/>
+	</xs:complexType>
+
+	<xs:complexType name="rule">
+		<xs:attribute name="name" type="rulename" use="required"/>
+		<xs:attribute name="value" type="xs:string" use="optional"/>
+		<xs:attribute name="size" type="xs:positiveInteger" use="optional"/>
+		<xs:attribute name="message" type="xs:string" use="optional"/>
+		<xs:attribute name="class" type="xs:string" use="optional"/>
+	</xs:complexType>
+
+	<xs:complexType name="id-method-parameter">
+		<xs:attribute name="name" type="xs:string" use="optional"/>
+		<xs:attribute name="value" type="xs:string" use="required"/>
+	</xs:complexType>
+
+	<xs:complexType name="index">
+		<xs:choice maxOccurs="unbounded">
+			<xs:element name="index-column" type="index-column" minOccurs="1" maxOccurs="unbounded"/>
+			<xs:element ref="vendor" minOccurs="0" maxOccurs="unbounded"/>
+		</xs:choice>
+		<xs:attribute name="name" type="index_name" use="optional"/>
+	</xs:complexType>
+
+	<xs:complexType name="unique">
+		<xs:choice maxOccurs="unbounded">
+			<xs:element name="unique-column" type="unique-column" minOccurs="1" maxOccurs="unbounded"/>
+			<xs:element ref="vendor" minOccurs="0" maxOccurs="unbounded"/>
+		</xs:choice>
+		<xs:attribute name="name" type="index_name" use="optional"/>
+	</xs:complexType>
+
+	<xs:complexType name="index-column">
+		<xs:sequence>
+			<xs:element ref="vendor" minOccurs="0" maxOccurs="unbounded"/>
+		</xs:sequence>
+		<xs:attribute name="name" type="column_name" use="required"/>
+		<xs:attribute name="size" type="xs:positiveInteger" use="optional"/>
+	</xs:complexType>
+
+	<xs:complexType name="unique-column">
+		<xs:sequence>
+			<xs:element ref="vendor" minOccurs="0" maxOccurs="unbounded"/>
+		</xs:sequence>
+		<xs:attribute name="name" type="column_name" use="required"/>
+		<xs:attribute name="size" type="xs:positiveInteger" use="optional"/>
+	</xs:complexType>
+
+	<xs:complexType name="inheritance">
+		<xs:attribute name="key" type="xs:string" use="required"/>
+		<xs:attribute name="class" type="xs:string" use="required"/>
+		<xs:attribute name="package" type="xs:string" use="optional"/>
+		<xs:attribute name="extends" type="xs:string" use="optional"/>
+	</xs:complexType>
+
+	<xs:complexType name="reference">
+		<xs:attribute name="local" type="column_name" use="required"/>
+		<xs:attribute name="foreign" type="column_name" use="required"/>
+	</xs:complexType>
+
+	<xs:complexType name="column">
+		<xs:choice maxOccurs="unbounded">
+			<xs:element name="inheritance" type="inheritance" minOccurs="0" maxOccurs="unbounded"/>
+			<xs:element ref="vendor" minOccurs="0" maxOccurs="unbounded"/>
+		</xs:choice>
+		<xs:attribute name="name" type="column_name" use="required"/>
+		<xs:attribute name="phpName" type="php_name" use="optional"/>
+		<xs:attribute name="peerName" type="php_class" use="optional"/>
+		<xs:attribute name="prefix" type="column_name" use="optional"/>
+		<xs:attribute name="accessorVisibility" type="visibility" use="optional"/>
+		<xs:attribute name="mutatorVisibility" type="visibility" use="optional"/>
+		<xs:attribute name="primaryKey" type="xs:boolean" default="false"/>
+		<xs:attribute name="required" type="xs:boolean" default="false"/>
+		<xs:attribute name="type" type="datatype" default="VARCHAR"/>
+		<xs:attribute name="sqlType" type="sql_type" use="optional"/>
+		<xs:attribute name="phpType" type="php_type" use="optional"/>
+		<xs:attribute name="size" type="xs:nonNegativeInteger" use="optional"/>
+		<xs:attribute name="scale" type="xs:nonNegativeInteger" use="optional"/>
+		<xs:attribute name="default" type="xs:string" use="optional"/>
+		<xs:attribute name="defaultValue" type="xs:string" use="optional"/>
+		<xs:attribute name="defaultExpr" type="xs:string" use="optional"/>
+		<xs:attribute name="autoIncrement" type="xs:boolean" default="false"/>
+		<xs:attribute name="inheritance" type="inh_option" default="false"/>
+		<xs:attribute name="inputValidator" type="xs:string" use="optional"/>
+		<xs:attribute name="phpNamingMethod" type="phpnamingmethod" use="optional"/>
+		<xs:attribute name="description" type="xs:string" use="optional"/>
+		<xs:attribute name="lazyLoad" type="xs:boolean" default="false"/>
+		<xs:attribute name="nodeKeySep" type="xs:string" use="optional"/>
+		<xs:attribute name="nodeKey" type="xs:string" use="optional"/>
+		<xs:attribute name="nestedSetLeftKey" type="xs:boolean" default="false"/>
+		<xs:attribute name="nestedSetRightKey" type="xs:boolean" default="false"/>
+		<xs:attribute name="treeScopeKey" type="xs:boolean" default="false"/>
+		<xs:attribute name="require" type="xs:string" use="optional"/>
+	</xs:complexType>
+
+	<xs:complexType name="foreign-key">
+		<xs:choice maxOccurs="unbounded">
+			<xs:element name="reference" type="reference" minOccurs="1" maxOccurs="unbounded"/>
+			<xs:element ref="vendor" minOccurs="0" maxOccurs="unbounded"/>
+		</xs:choice>
+		<xs:attribute name="foreignTable" type="table_name" use="required"/>
+		<xs:attribute name="name" type="foreign_name" use="optional"/>
+		<xs:attribute name="phpName" type="php_name" use="optional"/>
+		<xs:attribute name="refPhpName" type="php_name" use="optional"/>
+		<xs:attribute name="onDelete" type="delete" default="none"/>
+		<xs:attribute name="onUpdate" type="update" default="none"/>
+	</xs:complexType>
+
+	<xs:complexType name="external-schema">
+		<xs:attribute name="filename" type="file" use="required"/>
+	</xs:complexType>
+
+	<xs:complexType name="table">
+		<xs:choice maxOccurs="unbounded">
+			<xs:element name="column" type="column" maxOccurs="unbounded"/>
+			<xs:element name="foreign-key" type="foreign-key" minOccurs="0" maxOccurs="unbounded"/>
+			<xs:element name="index" type="index" minOccurs="0" maxOccurs="unbounded"/>
+			<xs:element name="unique" type="unique" minOccurs="0" maxOccurs="unbounded"/>
+			<xs:element name="id-method-parameter" type="id-method-parameter" minOccurs="0" maxOccurs="unbounded"/>
+			<xs:element name="validator" type="validator" minOccurs="0" maxOccurs="unbounded"/>
+			<xs:element ref="vendor" minOccurs="0" maxOccurs="unbounded"/>
+		</xs:choice>
+		<xs:attribute name="name" type="table_name" use="required"/>
+		<xs:attribute name="phpName" type="php_class" use="optional"/>
+		<xs:attribute name="columnPrefix" type="column_name" use="optional"/>
+		<xs:attribute name="defaultAccessorVisibility" type="visibility" use="optional"/>
+		<xs:attribute name="defaultMutatorVisibility" type="visibility" use="optional"/>
+		<xs:attribute name="idMethod" type="idmethod" use='optional'/>
+		<xs:attribute name="allowPkInsert" type="xs:boolean" default="false" use="optional"/>
+		<xs:attribute name="skipSql" type="xs:boolean" default="false"/>
+		<xs:attribute name="readOnly" type="xs:boolean" default="false"/>
+		<xs:attribute name="abstract" type="xs:boolean" default="false"/>
+		<xs:attribute name="baseClass" type="php_class" use="optional"/>
+		<xs:attribute name="basePeer" type="php_class" use="optional"/>
+		<xs:attribute name="alias" type="table_name" use="optional"/>
+		<xs:attribute name="package" type="xs:string" use="optional"/>
+		<xs:attribute name="interface" type="xs:string" use="optional"/>
+		<xs:attribute name="phpNamingMethod" type="phpnamingmethod" use='optional'/>
+		<xs:attribute name="heavyIndexing" type="xs:boolean" use="optional"/>
+		<xs:attribute name="description" type="xs:string"/>
+		<xs:attribute name="treeMode" type="treemode" use="optional"/>
+		<xs:attribute name="reloadOnInsert" type="xs:boolean" default="false"/>
+		<xs:attribute name="reloadOnUpdate" type="xs:boolean" default="false"/>
+	</xs:complexType>
+
+	<xs:complexType name="database">
+		<xs:choice maxOccurs="unbounded">
+			<xs:element name="external-schema" type="external-schema" minOccurs="0" maxOccurs="unbounded"/>
+			<xs:element name="table" type="table" minOccurs="1" maxOccurs="unbounded"/>
+		</xs:choice>
+		<xs:attribute name="name" type="xs:string" use="optional"/>
+		<xs:attribute name="defaultIdMethod" type="dbidmethod" default="none"/>
+		<xs:attribute name="defaultTranslateMethod" type="xs:string" use="optional"/>
+		<xs:attribute name="defaultAccessorVisibility" type="visibility" use="optional"/>
+		<xs:attribute name="defaultMutatorVisibility" type="visibility" use="optional"/>
+		<xs:attribute name="package" type="php_class" use="optional"/>
+		<xs:attribute name="baseClass" type="php_class" use="optional"/>
+		<xs:attribute name="basePeer" type="php_class" use="optional"/>
+		<xs:attribute name="defaultPhpNamingMethod" type="phpnamingmethod" default="underscore"/>
+		<xs:attribute name="heavyIndexing" type="xs:boolean" default="false"/>
+	</xs:complexType>
+</xs:schema>
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/resources/xsl/database.xsl
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/resources/xsl/database.xsl	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/resources/xsl/database.xsl	(revision 19)
@@ -0,0 +1,279 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!DOCTYPE xsl:stylesheet [<!ENTITY nbsp "&#160;">]>
+
+<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
+	<!--
+	XSL Stylesheet to normalize a database schema
+	-->
+
+	<!--
+	Output indented UTF 8 XML 
+	-->
+	<xsl:output method="xml" indent="yes" encoding="UTF-8" />
+
+	<!--
+	Matches root database node, the only allowed root node
+
+	Starts the normalization process
+	-->
+	<xsl:template match='/database'>
+		<database>
+			<xsl:if test='not(boolean(@defaultIdMethod))'>
+				<xsl:attribute name='defaultIdMethod'>native</xsl:attribute>
+			</xsl:if>
+			<xsl:if test='not(boolean(@defaultPhpNamingMethod))'>
+				<xsl:attribute name='defaultPhpNamingMethod'>underscore</xsl:attribute>
+			</xsl:if>
+			<xsl:if test='not(boolean(@heavyIndexing))'>
+				<xsl:attribute name='heavyIndexing'>false</xsl:attribute>
+			</xsl:if>
+			<xsl:apply-templates select='@*'/>
+			<xsl:apply-templates select='external-schema'/>
+			<xsl:apply-templates select='table'/>
+		</database>
+	</xsl:template>
+
+	<!--
+	Normalizes any defaultPhpNamingMethod attribute by making it lowercase
+	-->	
+	<xsl:template match='@defaultPhPNamingMethod'>
+		<xsl:attribute name='defaultPhPNamingMethod'><xsl:value-of select='translate(., "ABCDEFGHIJKLMNOPQRSTUVWXYZ", "abcdefghijklmnopqrstuvwxyz")'/></xsl:attribute>
+	</xsl:template>
+
+	<!--
+	Normalizes any onDelete attribute by making it lowercase, or none if it is empty (makes onDelete='' act the same as onDelete='none')
+	-->	
+	<xsl:template match='@onDelete' name='onDelete'>
+		<xsl:choose>
+			<xsl:when test='.=""'>
+				<xsl:attribute name='onDelete'>none</xsl:attribute>
+			</xsl:when>
+			<xsl:otherwise>
+				<xsl:attribute name='onDelete'><xsl:value-of select='translate(., "ABCDEFGHIJKLMNOPQRSTUVWXYZ", "abcdefghijklmnopqrstuvwxyz")'/></xsl:attribute>
+			</xsl:otherwise>
+		</xsl:choose>
+	</xsl:template>
+
+	<!--
+	Handle OnDelete the same as onDelete
+	-->
+	<xsl:template match='@OnDelete'>
+		<xsl:call-template name='onDelete'/>
+	</xsl:template>
+
+	<!--
+	Normalizes any onUpdate attribute by making it lowercase, or none if it is empty (similar to onDelete)
+	-->	
+	<xsl:template match='@onUpdate' name='onUpdate'>
+		<xsl:choose>
+			<xsl:when test='.=""'>
+				<xsl:attribute name='onUpdate'>none</xsl:attribute>
+			</xsl:when>
+			<xsl:otherwise>
+				<xsl:attribute name='onUpdate'><xsl:value-of select='translate(., "ABCDEFGHIJKLMNOPQRSTUVWXYZ", "abcdefghijklmnopqrstuvwxyz")'/></xsl:attribute>
+			</xsl:otherwise>
+		</xsl:choose>
+	</xsl:template>
+
+	<!--
+	Handle OnUpdate the same as onUpdate
+	-->
+	<xsl:template match='@OnUpdate'>
+		<xsl:call-template name='onUpdate'/>
+	</xsl:template>
+
+	<!--
+	Tranlate IdMethod attribute to idMethod attribute
+	-->
+	<xsl:template match='@IdMethod'>
+		<xsl:attribute name='idMethod'><xsl:value-of select='.'/></xsl:attribute>
+	</xsl:template>
+
+	<!--
+	Just copy any attribute
+	-->
+	<xsl:template match='@*' priority='-1'>
+		<xsl:copy-of select='.'/>
+	</xsl:template>
+
+	<!--
+	Normalize a table, add some attribute with default values if ommitted and normalize all attribute and childnodes
+	-->
+	<xsl:template match='table'>
+		<table>
+			<xsl:if test='not(boolean(@skipSql))'>
+				<xsl:attribute name='skipSql'>false</xsl:attribute>
+			</xsl:if>
+			<xsl:if test='not(boolean(@abstract))'>
+				<xsl:attribute name='abstract'>false</xsl:attribute>
+			</xsl:if>
+			<xsl:apply-templates select='@*'/>
+			<xsl:apply-templates select='column'/>
+			<xsl:apply-templates select='foreign-key'/>
+			<xsl:apply-templates select='index'/>
+			<xsl:apply-templates select='unique'/>
+			<xsl:apply-templates select='id-method-parameter'/>
+			<xsl:apply-templates select='validator'/>
+			<xsl:apply-templates select='vendor'/>
+		</table>
+	</xsl:template>
+
+	<!--
+	Normalize a foreign-key, add some attribute with default values if ommitted and normalize all attribute and childnodes
+	-->
+	<xsl:template match='foreign-key'>
+		<foreign-key>
+			<xsl:if test='not(boolean(@onDelete)) and not(boolean(@OnDelete))'>
+				<xsl:attribute name='onDelete'>none</xsl:attribute>
+			</xsl:if>
+			<xsl:if test='not(boolean(@onUpdate)) and not(boolean(@OnUpdate))'>
+				<xsl:attribute name='onUpdate'>none</xsl:attribute>
+			</xsl:if>
+			<xsl:apply-templates select='@*'/>
+			<xsl:apply-templates select='reference'/>
+			<xsl:apply-templates select='vendor'/>
+		</foreign-key>
+	</xsl:template>
+
+	<!--
+	Just copy the index node with attributes and add the index-column
+	-->
+	<xsl:template match='index'>
+		<index>
+			<xsl:apply-templates select='@*'/>
+			<xsl:apply-templates select='index-column'/>
+		</index>
+	</xsl:template>
+
+	<!--
+	Just copy the unique node with attributes and add the unique-column
+	-->
+	<xsl:template match='unique'>
+		<unique>
+			<xsl:apply-templates select='@*'/>
+			<xsl:apply-templates select='unique-column'/>
+		</unique>
+	</xsl:template>
+
+	<!--
+	Just copy the unique-column node with attributes and add the vendor node
+	-->
+	<xsl:template match='unique-column'>
+		<unique-column>
+			<xsl:apply-templates select='@*'/>
+			<xsl:apply-templates select='vendor'/>
+		</unique-column>
+	</xsl:template>
+
+	<!--
+	Just copy the index-column node with attributes and add the vendor node
+	-->
+	<xsl:template match='index-column'>
+		<index-column>
+			<xsl:apply-templates select='@*'/>
+			<xsl:apply-templates select='vendor'/>
+		</index-column>
+	</xsl:template>
+
+	<!--
+	Add default name to id-method-parameter (if none) and copy its attributes
+	-->
+	<xsl:template match='id-method-parameter'>
+		<id-method-parameter>
+			<xsl:if test='not(boolean(@name))'>
+				<xsl:attribute name='name'>default</xsl:attribute>
+			</xsl:if>
+			<xsl:apply-templates select='@*'/>
+		</id-method-parameter>
+	</xsl:template>
+
+	<!--
+	Just copy the validator node with attributes and add the rule node
+	-->
+	<xsl:template match='validator'>
+		<validator>
+			<xsl:apply-templates select='@*'/>
+			<xsl:apply-templates select='rule'/>
+		</validator>
+	</xsl:template>
+
+	<!--
+	Adds a default name to the rule (if none given) and copy the attributes
+	-->
+	<xsl:template match='rule'>
+		<rule>
+			<xsl:if test='not(boolean(@name))'>
+				<xsl:attribute name='name'>class</xsl:attribute>
+			</xsl:if>
+			<xsl:apply-templates select='@*'/>
+		</rule>
+	</xsl:template>
+
+	<!--
+	Strip all childnodes (if any) from a parameter node
+	-->
+	<xsl:template match='parameter'>
+		<parameter>
+			<xsl:apply-templates select='@*'/>
+		</parameter>
+	</xsl:template>
+
+	<!--
+	Just copy the vendor node with attributes and add the parameter node
+	-->
+	<xsl:template match='vendor'>
+		<vendor>
+			<xsl:apply-templates select='@*'/>
+			<xsl:apply-templates select='parameter'/>
+		</vendor>
+	</xsl:template>
+
+	<!--
+	Strip all childnodes from an inheritance node
+	-->
+	<xsl:template match='inheritance'>
+		<inheritance>
+			<xsl:apply-templates select='@*'/>
+		</inheritance>
+	</xsl:template>
+
+	<!--
+	Normalize a column node, add default values for missing attributes and copy the content
+	-->
+	<xsl:template match='column'>
+		<column>
+			<xsl:if test='not(boolean(@primaryKey))'>
+				<xsl:attribute name='primaryKey'>false</xsl:attribute>
+			</xsl:if>
+			<xsl:if test='not(boolean(@required))'>
+				<xsl:attribute name='required'>false</xsl:attribute>
+			</xsl:if>
+			<xsl:if test='not(boolean(@type))'>
+				<xsl:attribute name='type'>VARCHAR</xsl:attribute>
+			</xsl:if>
+			<xsl:if test='not(boolean(@autoIncrement))'>
+				<xsl:attribute name='autoIncrement'>false</xsl:attribute>
+			</xsl:if>
+			<xsl:if test='not(boolean(@lazyLoad))'>
+				<xsl:attribute name='lazyLoad'>false</xsl:attribute>
+			</xsl:if>
+			<xsl:if test='@type = "VARCHAR" and not(boolean(@sqlType)) and not(boolean(@size))'>
+				<xsl:attribute name='size'>255</xsl:attribute>
+			</xsl:if>
+			<xsl:apply-templates select='@*'/>
+			<xsl:apply-templates select='inheritance'/>
+			<xsl:apply-templates select='vendor'/>
+		</column>
+	</xsl:template>
+
+	<!--
+	Strip all childnodes from an reference node
+	-->
+	<xsl:template match='reference'>
+		<reference>
+			<xsl:apply-templates select='@*'/>
+		</reference>
+	</xsl:template>
+
+</xsl:stylesheet>
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/test/README
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/test/README	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/test/README	(revision 19)
@@ -0,0 +1,32 @@
+This directory contains scripts and unit test classes for testing a Propel
+generator AND runtime environments.  In particular, the bookstore-test.php 
+script is a good way to test whether everything is *basically* working.  You 
+can run the bookstore test by performing a few simple tasks.
+
+(Assumes a vanilla install of Propel)
+
+(1) Use the default top-level build.properties file (copy/rename 
+build.properties-sample to build.properties).  Built the SQL + OM using the
+default bookstore build.properties and runtime-conf.xml:
+
+$> cd /path/to/propel-generator
+$> phing -f build-propel.xml
+   ....
+   
+(2) Execute the insert-sql target to initialize the sqlite database using the 
+SQL files that were built in previous step:
+
+$> phing -f build-propel.xml insert-sql
+ 
+(3) From the top-level directory (it's important where you are) run the 
+bookstore-test.php script like this:
+
+$> php -qC test/bookstore-test.php
+
+That's it.  You should see a bunch of test descriptions and a return status.  
+If you get an error about not being able to find a table, make sure that the 
+insert-sql step (2) completed successfully, and also that you are using the 
+default proeprty files which should be set to use a sqlite database.
+
+Take a look at the bookstore-test.php script to see some examples of how to 
+use generated Propel objects.
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/test/bookstore-packaged-test.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/test/bookstore-packaged-test.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/test/bookstore-packaged-test.php	(revision 19)
@@ -0,0 +1,803 @@
+<?php
+
+/**
+ * Simple test script for Propel drivers.
+ *
+ * This script will no do in-depth testing, but is designed to test whether drivers
+ * are correctly performing basic operations -- SELECT, UPDATE, DELETE, limit support,
+ * prepared query emulation, etc.
+ *
+ * IMPORTANT:
+ *
+ * Use this script with a clean version of the [example] bookstore database.  If records
+ * already exist, an error will be displayed.
+ *
+ * TODO:
+ * A more advanced driver test system should be developed that could test capabilities
+ * of driver-specific things like callable statements (stored procedures), etc.  Perhaps break
+ * functionality into class & provide ability to subclass.
+ *
+ * @author     Hans Lellelid <hans@xmpl.org>
+ * @version    $Revision: 563 $
+ */
+
+// Setup configuration.  It is expected that the bookstore-conf.php file exists in ../build/conf
+//
+
+error_reporting(E_ALL);
+
+$conf_path = realpath(dirname(__FILE__) . '/../projects/bookstore-packaged/build/conf/bookstore-packaged-conf.php');
+if (!file_exists($conf_path)) {
+	print "Make sure that you specify properties in conf/bookstore-packaged.properties and "
+	."build propel before running this script.";
+	exit;
+}
+
+// Add PHP_CLASSPATH, if set
+if (getenv("PHP_CLASSPATH")) {
+	set_include_path(getenv("PHP_CLASSPATH") . PATH_SEPARATOR . get_include_path());
+}
+
+ // Add build/classes/ and classes/ to path
+set_include_path(
+	realpath(dirname(__FILE__) . '/../projects/bookstore-packaged/build/classes') . PATH_SEPARATOR .
+	dirname(__FILE__) . '/../../runtime/classes' . PATH_SEPARATOR .
+	get_include_path()
+);
+
+
+ // Require classes.
+ require_once 'propel/Propel.php';
+ require_once 'author/Author.php';
+ require_once 'publisher/Publisher.php';
+ require_once 'book/Book.php';
+ require_once 'review/Review.php';
+ include_once 'media/Media.php';
+ include_once 'log/BookstoreLog.php';
+ include_once 'book_club_list/BookClubList.php';
+ include_once 'book_club_list/BookListRel.php';
+
+ include_once 'Benchmark/Timer.php';
+
+ $timer = new Benchmark_Timer;
+
+ $timer->start();
+
+ // Some utility functions
+ function boolTest($cond) {
+	 if ($cond) {
+		 return "[OK]\n";
+	 } else {
+		return "[FAILED]\n";
+	}
+ }
+
+ try {
+	// Initialize Propel
+	 Propel::init($conf_path);
+ } catch (Exception $e) {
+	 die("Error initializing propel: ". $e->__toString());
+ }
+
+function check_tables_empty() {
+	try {
+
+		print "\nChecking to see that tables are empty\n";
+		print "-------------------------------------\n\n";
+
+		print "Ensuring that there are no records in [author] table: ";
+		$res = AuthorPeer::doSelect(new Criteria());
+		print boolTest(empty($res));
+
+		print "Ensuring that there are no records in [publisher] table: ";
+		$res2 = PublisherPeer::doSelect(new Criteria());
+		print boolTest(empty($res2));
+
+		print "Ensuring that there are no records in [book] table: ";
+		$res3 = AuthorPeer::doSelect(new Criteria());
+		print boolTest(empty($res3));
+
+		print "Ensuring that there are no records in [review] table: ";
+		$res4 = ReviewPeer::doSelect(new Criteria());
+		print boolTest(empty($res4));
+
+		print "Ensuring that there are no records in [media] table: ";
+		$res5 = MediaPeer::doSelect(new Criteria());
+		print boolTest(empty($res5));
+
+		print "Ensuring that there are no records in [book_club_list] table: ";
+		$res6 = BookClubListPeer::doSelect(new Criteria());
+		print boolTest(empty($res6));
+
+		print "Ensuring that there are no records in [book_x_list] table: ";
+		$res7 = BookListRelPeer::doSelect(new Criteria());
+		print boolTest(empty($res7));
+
+		return (empty($res) && empty($res2) && empty($res3) && empty($res4) && empty($res5));
+
+	} catch (Exception $e) {
+		die("Error ensuring tables were empty: " . $e->__toString());
+	}
+}
+
+// Check to see if records already exist in any of the three tables.  If so, display an error
+// and exit.
+
+if (!check_tables_empty()) {
+	die("Tables must be empty to perform these tests.");
+}
+
+// Add publisher records
+// ---------------------
+
+try {
+	print "\nAdding some new publishers to the list\n";
+	print "--------------------------------------\n\n";
+
+	$scholastic = new Publisher();
+	$scholastic->setName("Scholastic");
+	// do not save, will do later to test cascade
+	print "Added publisher \"Scholastic\" [not saved yet].\n";
+
+	$morrow = new Publisher();
+	$morrow->setName("William Morrow");
+	$morrow->save();
+	$morrow_id = $morrow->getId();
+	print "Added publisher \"William Morrow\" [id = $morrow_id].\n";
+
+	$penguin = new Publisher();
+	$penguin->setName("Penguin");
+	$penguin->save();
+	$penguin_id = $penguin->getId();
+	print "Added publisher \"Penguin\" [id = $penguin_id].\n";
+
+	$vintage = new Publisher();
+	$vintage->setName("Vintage");
+	$vintage->save();
+	$vintage_id = $vintage->getId();
+	print "Added publisher \"Vintage\" [id = $vintage_id].\n";
+
+} catch (Exception $e) {
+	die("Error adding publisher: " . $e->__toString());
+}
+
+// Add author records
+// ------------------
+
+try {
+	print "\nAdding some new authors to the list\n";
+	print "--------------------------------------\n\n";
+
+	$rowling = new Author();
+	$rowling->setFirstName("J.K.");
+	$rowling->setLastName("Rowling");
+	// no save()
+	print "Added author \"J.K. Rowling\" [not saved yet].\n";
+
+	$stephenson = new Author();
+	$stephenson->setFirstName("Neal");
+	$stephenson->setLastName("Stephenson");
+	$stephenson->save();
+	$stephenson_id = $stephenson->getId();
+	print "Added author \"Neal Stephenson\" [id = $stephenson_id].\n";
+
+	$byron = new Author();
+	$byron->setFirstName("George");
+	$byron->setLastName("Byron");
+	$byron->save();
+	$byron_id = $byron->getId();
+	print "Added author \"George Byron\" [id = $byron_id].\n";
+
+
+	$grass = new Author();
+	$grass->setFirstName("Gunter");
+	$grass->setLastName("Grass");
+	$grass->save();
+	$grass_id = $grass->getId();
+	print "Added author \"Gunter Grass\" [id = $grass_id].\n";
+
+} catch (Exception $e) {
+	die("Error adding author: " . $e->__toString());
+}
+
+// Add book records
+// ----------------
+
+try {
+
+	print "\nAdding some new books to the list\n";
+	print "-------------------------------------\n\n";
+
+	$phoenix = new Book();
+	$phoenix->setTitle("Harry Potter and the Order of the Phoenix");
+	$phoenix->setISBN("043935806X");
+
+	print "Trying cascading save (Harry Potter): ";
+	$phoenix->setAuthor($rowling);
+	$phoenix->setPublisher($scholastic);
+	$phoenix->save();
+	$phoenix_id = $phoenix->getId();
+	print boolTest(true);
+	print "Added book \"Harry Potter and the Order of the Phoenix\" [id = $phoenix_id].\n";
+
+	$qs = new Book();
+	$qs->setISBN("0380977427");
+	$qs->setTitle("Quicksilver");
+	$qs->setAuthor($stephenson);
+	$qs->setPublisher($morrow);
+	$qs->save();
+	$qs_id = $qs->getId();
+	print "Added book \"Quicksilver\" [id = $qs_id].\n";
+
+	$dj = new Book();
+	$dj->setISBN("0140422161");
+	$dj->setTitle("Don Juan");
+	$dj->setAuthor($byron);
+	$dj->setPublisher($penguin);
+	$dj->save();
+	$dj_id = $qs->getId();
+	print "Added book \"Don Juan\" [id = $dj_id].\n";
+
+	$td = new Book();
+	$td->setISBN("067972575X");
+	$td->setTitle("The Tin Drum");
+	$td->setAuthor($grass);
+	$td->setPublisher($vintage);
+	$td->save();
+	$td_id = $td->getId();
+	print "Added book \"The Tin Drum\" [id = $dj_id].\n";
+
+} catch (Exception $e) {
+	die("Error saving book: " . $e->__toString());
+}
+
+// Add review records
+// ------------------
+
+try {
+
+	print "\nAdding some book reviews to the list\n";
+	print "------------------------------------\n\n";
+
+	$r1 = new Review();
+	$r1->setBook($phoenix);
+	$r1->setReviewedBy("Washington Post");
+	$r1->setRecommended(true);
+	$r1->setReviewDate(time());
+	$r1->save();
+	$r1_id = $r1->getId();
+	print "Added Washington Post book review  [id = $r1_id].\n";
+
+	$r2 = new Review();
+	$r2->setBook($phoenix);
+	$r2->setReviewedBy("New York Times");
+	$r2->setRecommended(false);
+	$r2->setReviewDate(time());
+	$r2->save();
+	$r2_id = $r2->getId();
+	print "Added New York Times book review  [id = $r2_id].\n";
+
+} catch (Exception $e) {
+	die("Error saving book review: " . $e->__toString());
+}
+
+// Perform a "complex" search
+// --------------------------
+
+try {
+
+	print "\nDoing complex search on books\n";
+	print "-----------------------------\n\n";
+
+	$crit = new Criteria();
+	$crit->add(BookPeer::TITLE, 'Harry%', Criteria::LIKE);
+
+	print "Looking for \"Harry%\": ";
+	$results = BookPeer::doSelect($crit);
+	print boolTest(count($results) === 1);
+
+
+	$crit2 = new Criteria();
+	$crit2->add(BookPeer::ISBN, array("0380977427", "0140422161"), Criteria::IN);
+	$results = BookPeer::doSelect($crit2);
+	print "Looking for ISBN IN (\"0380977427\", \"0140422161\"): ";
+	print boolTest(count($results) === 2);
+
+} catch (Exception $e) {
+	die("Error while performing complex query: " . $e->__toString());
+}
+
+
+// Perform a "limit" search
+// ------------------------
+
+try {
+
+	print "\nDoing LIMITed search on books\n";
+	print "-----------------------------\n\n";
+
+	$crit = new Criteria();
+	$crit->setLimit(2);
+	$crit->setOffset(1);
+	$crit->addAscendingOrderByColumn(BookPeer::TITLE);
+
+	print "Checking to make sure correct number returned: ";
+	$results = BookPeer::doSelect($crit);
+	print boolTest(count($results) === 2);
+
+	print "Checking to make sure correct books returned: ";
+	// we ordered on book title, so we expect to get
+	print boolTest( $results[0]->getTitle() == "Harry Potter and the Order of the Phoenix" && $results[1]->getTitle() == "Quicksilver"  );
+
+
+} catch (Exception $e) {
+	die("Error while performing LIMIT query: " . $e->__toString());
+}
+
+
+
+// Perform a lookup & update!
+// --------------------------
+
+try {
+
+	print "\nUpdating just-created book title\n";
+	print "--------------------------------\n\n";
+
+	print "First finding book by PK (=$qs_id) .... ";
+
+	try {
+		$qs_lookup = BookPeer::retrieveByPk($qs_id);
+	} catch (Exception $e) {
+		print "ERROR!\n";
+		die("Error retrieving by pk: " . $e->__toString());
+	}
+
+	if ($qs_lookup) {
+		print "FOUND!\n";
+	} else {
+		print "NOT FOUND :(\n";
+		die("Couldn't find just-created book: book_id = $qs_id");
+	}
+
+	try {
+		$new_title = "Quicksilver (".crc32(uniqid(rand())).")";
+		print "Attempting to update found object (".$qs_lookup->getTitle()." -> ".$new_title."): ";
+		$qs_lookup->setTitle($new_title);
+		$qs_lookup->save();
+		print boolTest(true);
+	} catch (Exception $e) {
+		die("Error saving (updating) book: " . $e->__toString());
+	}
+
+	print "Making sure object was correctly updated: ";
+	$qs_lookup2 = BookPeer::retrieveByPk($qs_id);
+	print boolTest($qs_lookup2->getTitle() == $new_title);
+
+} catch (Exception $e) {
+	die("Error updating book: " . $e->__toString());
+}
+
+
+// Test some basic DATE / TIME stuff
+// ---------------------------------
+
+try {
+	print "\nTesting the DATE/TIME columns\n";
+	print "-----------------------------\n\n";
+
+	// that's the control timestamp.
+	$control = strtotime('2004-02-29 00:00:00');
+
+	// should be two in the db
+	$r = ReviewPeer::doSelectOne(new Criteria());
+	$r_id = $r->getId();
+	$r->setReviewDate($control);
+	$r->save();
+
+	$r2 = ReviewPeer::retrieveByPk($r_id);
+
+	print "Checking ability to fetch native unix timestamp: ";
+	print boolTest($r2->getReviewDate(null) === $control);
+
+	print "Checking ability to use date() formatter: ";
+	print boolTest($r2->getReviewDate('n-j-Y') === '2-29-2004');
+
+	print "[FYI] Here's the strftime() formatter for current locale: " . $r2->getReviewDate('%x') . "\n";
+
+} catch (Exception $e) {
+	die("Error test date/time: "  . $e->__toString());
+}
+
+// Handle BLOB/CLOB Columns
+// ------------------------
+
+try {
+	print "\nTesting the BLOB/CLOB columns\n";
+	print "-------------------------------\n\n";
+
+	$blob_path = dirname(__FILE__) . '/etc/lob/tin_drum.gif';
+	$blob2_path = dirname(__FILE__) . '/etc/lob/propel.gif';
+	$clob_path = dirname(__FILE__) . '/etc/lob/tin_drum.txt';
+
+	$m1 = new Media();
+	$m1->setBook($phoenix);
+	$m1->setCoverImage(file_get_contents($blob_path));
+	$m1->setExcerpt(file_get_contents($clob_path));
+	$m1->save();
+	$m1_id = $m1->getId();
+	print "Added Media collection [id = $m1_id].\n";
+
+	print "Looking for just-created mediat by PK (=$m1_id) .... ";
+
+	try {
+		$m1_lookup = MediaPeer::retrieveByPk($m1_id);
+	} catch (Exception $e) {
+		print "ERROR!\n";
+		die("Error retrieving media by pk: " . $e->__toString());
+	}
+
+	if ($m1_lookup) {
+		print "FOUND!\n";
+	} else {
+		print "NOT FOUND :(\n";
+		die("Couldn't find just-created media item: media_id = $m1_id");
+	}
+
+	print "Making sure BLOB was correctly updated: ";
+	print boolTest( $m1_lookup->getCoverImage()->getContents() === file_get_contents($blob_path));
+	print "Making sure CLOB was correctly updated: ";
+	print boolTest((string) $m1_lookup->getExcerpt()->getContents() === file_get_contents($clob_path));
+
+
+	// now update the BLOB column and save it & check the results
+
+	$b = $m1_lookup->getCoverImage();
+	$b->setContents(file_get_contents($blob2_path));
+	$m1_lookup->setCoverImage($b);
+	$m1_lookup->save();
+
+	try {
+		$m2_lookup = MediaPeer::retrieveByPk($m1_id);
+	} catch (Exception $e) {
+		print "ERROR!\n";
+		die("Error retrieving media by pk: " . $e->__toString());
+	}
+
+	print "Making sure BLOB was correctly overwritten: ";
+	print boolTest($m2_lookup->getCoverImage()->getContents() === file_get_contents($blob2_path));
+
+} catch (Exception $e) {
+	die("Error doing blob/clob updates: " . $e->__toString());
+}
+
+// Test Validators
+// ---------------
+
+try {
+
+	print "\nTesting the column validators\n";
+	print "-----------------------------\n\n";
+
+	$bk1 = new Book();
+	$bk1->setTitle("12345"); // min length is 10
+	$ret = $bk1->validate();
+
+	print "Making sure validation failed: ";
+	print boolTest($ret !== true);
+
+	print "Making sure 1 validation message was returned: ";
+	print boolTest(count($ret) === 1);
+
+	print "Making sure expected validation message was returned: ";
+	$el = array_shift($ret);
+	print boolTest(stripos($el->getMessage(), "must be more than") !== false);
+
+	print "\n(Unique validator)\n";
+
+	$bk2 = new Book();
+	$bk2->setTitle("Don Juan");
+	$ret = $bk2->validate();
+
+	print "Making sure validation failed: ";
+	print boolTest($ret !== true);
+
+	print "Making sure 1 validation message was returned: ";
+	print boolTest(count($ret) === 1);
+
+	print "Making sure expected validation message was returned: ";
+	$el = array_shift($ret);
+	print boolTest(stripos($el->getMessage(), "Book title already in database.") !== false);
+
+	print "\n(Now trying some more complex validation.)\n";
+	$auth1 = new Author();
+	$auth1->setFirstName("Hans");
+	// last name required; will fail
+
+	$bk1->setAuthor($auth1);
+
+	$rev1 = new Review();
+	$rev1->setReviewDate("08/09/2001");
+	 // will fail: reviewed_by column required
+
+	$bk1->addReview($rev1);
+
+	$ret2 = $bk1->validate();
+
+	print "Making sure 6 validation messages were returned: ";
+	print boolTest(count($ret2) === 6);
+
+	print "Making sure correct columns failed: ";
+	print boolTest(array_keys($ret2) === array(
+		AuthorPeer::LAST_NAME,
+		AuthorPeer::EMAIL,
+		AuthorPeer::AGE,
+		BookPeer::TITLE,
+		ReviewPeer::REVIEWED_BY,
+		ReviewPeer::STATUS
+	));
+
+
+	$bk2 = new Book();
+	$bk2->setTitle("12345678901"); // passes
+
+	$auth2 = new Author();
+	$auth2->setLastName("Blah"); //passes
+	$auth2->setEmail("some@body.com"); //passes
+	$auth2->setAge(50); //passes
+	$bk2->setAuthor($auth2);
+
+	$rev2 = new Review();
+	$rev2->setReviewedBy("Me!"); // passes
+	$rev2->setStatus("new"); // passes
+	$bk2->addReview($rev2);
+
+	$ret3 = $bk2->validate();
+
+	print "Making sure complex validation can pass: ";
+	print boolTest($ret3 === true);
+
+} catch (Exception $e) {
+	die("Error doing validation tests: " . $e->__toString());
+}
+
+
+// Test doCount()
+//
+try {
+
+	print "\nTesting doCount() functionality\n";
+	print "-------------------------------\n\n";
+
+	$c = new Criteria();
+	$records = BookPeer::doSelect($c);
+	$count = BookPeer::doCount($c);
+
+	print "Making sure correct number of results: ";
+	print boolTest(count($records) === $count);
+
+} catch (Exception $e) {
+	die("Error deleting book: " . $e->__toString());
+}
+
+// Test many-to-many relationships
+// ---------------
+
+try {
+
+	print "\nTesting many-to-many relationships\n";
+	print "-----------------------------\n\n";
+
+	// init book club list 1 with 2 books
+
+	$blc1 = new BookClubList();
+	$blc1->setGroupLeader("Crazyleggs");
+	$blc1->setTheme("Happiness");
+
+	$brel1 = new BookListRel();
+	$brel1->setBook($phoenix);
+
+	$brel2 = new BookListRel();
+	$brel2->setBook($dj);
+
+	$blc1->addBookListRel($brel1);
+	$blc1->addBookListRel($brel2);
+
+	$blc1->save();
+
+	print "Making sure BookClubList 1 was saved: ";
+ 	print boolTest(!is_null($blc1->getId()));
+
+	// init book club list 2 with 1 book
+
+	$blc2 = new BookClubList();
+	$blc2->setGroupLeader("John Foo");
+	$blc2->setTheme("Default");
+
+	$brel3 = new BookListRel();
+	$brel3->setBook($phoenix);
+
+	$blc2->addBookListRel($brel3);
+
+	$blc2->save();
+
+	print "Making sure BookClubList 2 was saved: ";
+ 	print boolTest(!is_null($blc2->getId()));
+
+	// re-fetch books and lists from db to be sure that nothing is cached
+
+	$crit = new Criteria();
+	$crit->add(BookPeer::ID, $phoenix->getId());
+	$phoenix = BookPeer::doSelectOne($crit);
+	print "Making sure book 'phoenix' has been re-fetched from db: ";
+ 	print boolTest(!empty($phoenix));
+
+	$crit = new Criteria();
+	$crit->add(BookClubListPeer::ID, $blc1->getId());
+	$blc1 = BookClubListPeer::doSelectOne($crit);
+	print "Making sure BookClubList 1 has been re-fetched from db: ";
+ 	print boolTest(!empty($blc1));
+
+	$crit = new Criteria();
+	$crit->add(BookClubListPeer::ID, $blc2->getId());
+	$blc2 = BookClubListPeer::doSelectOne($crit);
+	print "Making sure BookClubList 2 has been re-fetched from db: ";
+ 	print boolTest(!empty($blc2));
+
+	$relCount = $phoenix->countBookListRels();
+	print "Making sure book 'phoenix' has 2 BookListRels: ";
+ 	print boolTest($relCount == 2);
+
+	$relCount = $blc1->countBookListRels();
+	print "Making sure BookClubList 1 has 2 BookListRels: ";
+ 	print boolTest($relCount == 2);
+
+	$relCount = $blc2->countBookListRels();
+	print "Making sure BookClubList 2 has 1 BookListRel: ";
+ 	print boolTest($relCount == 1);
+
+
+} catch (Exception $e) {
+	die("Error doing many-to-many relationships tests: " . $e->__toString());
+}
+
+// Test multiple databases
+// ---------------
+
+try {
+
+	print "\nTesting multiple databases\n";
+	print "-----------------------------\n\n";
+
+	$line = new BookstoreLog();
+	$line->setIdent('bookstore-packaged-test');
+	$line->setTime(time());
+	$line->setMessage('We are testing to write something to the log database ...');
+	$line->setPriority('debug');
+	$line->save();
+
+	$line_id = $line->getId();
+	print "Making sure BookstoreLog was saved: ";
+	print boolTest(!empty($line_id));
+
+} catch (Exception $e) {
+	die("Error doing multiple databases tests: " . $e->__toString());
+}
+
+// Cleanup (tests DELETE)
+// ----------------------
+
+try {
+
+	print "\nRemoving books that were just created\n";
+	print "-------------------------------------\n\n";
+
+	print "First finding book by PK (=$phoenix_id) .... ";
+	try {
+		$hp = BookPeer::retrieveByPk($phoenix_id);
+	} catch (Exception $e) {
+		print "ERROR!\n";
+		die("Error retrieving by pk: " . $e->__toString());
+	}
+
+	if ($hp) {
+		print "FOUND!\n";
+	} else {
+		print "NOT FOUND :(\n";
+		die("Couldn't find just-created book: book_id = $phoenix_id");
+	}
+
+	print "Attempting to delete [multi-table] by found pk: ";
+	$c = new Criteria();
+	$c->add(BookPeer::ID, $hp->getId());
+	// The only way for cascading to work currently
+	// is to specify the author_id and publisher_id (i.e. the fkeys
+	// have to be in the criteria).
+	$c->add(AuthorPeer::ID, $hp->getId());
+	$c->add(PublisherPeer::ID, $hp->getId());
+	$c->setSingleRecord(true);
+	BookPeer::doDelete($c);
+	print boolTest(true);
+
+	print "Checking to make sure correct records were removed.\n";
+	print "\tFrom author table: ";
+	$res = AuthorPeer::doSelect(new Criteria());
+	print boolTest(count($res) === 3);
+	print "\tFrom publisher table: ";
+	$res2 = PublisherPeer::doSelect(new Criteria());
+	print boolTest(count($res2) === 3);
+	print "\tFrom book table: ";
+	$res3 = BookPeer::doSelect(new Criteria());
+	print boolTest(count($res3) === 3);
+
+	print "Attempting to delete books by complex criteria: ";
+	$c = new Criteria();
+	$cn = $c->getNewCriterion(BookPeer::ISBN, "043935806X");
+	$cn->addOr($c->getNewCriterion(BookPeer::ISBN, "0380977427"));
+	$cn->addOr($c->getNewCriterion(BookPeer::ISBN, "0140422161"));
+	$c->add($cn);
+	BookPeer::doDelete($c);
+	print boolTest(true);
+
+	print "Attempting to delete book [id = $td_id]: ";
+	$td->delete();
+	print boolTest(true);
+
+	print "Attempting to delete author [id = $stephenson_id]: ";
+	AuthorPeer::doDelete($stephenson_id);
+	print boolTest(true);
+
+	print "Attempting to delete author [id = $byron_id]: ";
+	AuthorPeer::doDelete($byron_id);
+	print boolTest(true);
+
+	print "Attempting to delete author [id = $grass_id]: ";
+	$grass->delete();
+	print boolTest(true);
+
+	print "Attempting to delete publisher [id = $morrow_id]: ";
+	PublisherPeer::doDelete($morrow_id);
+	print boolTest(true);
+
+	print "Attempting to delete publisher [id = $penguin_id]: ";
+	PublisherPeer::doDelete($penguin_id);
+	print boolTest(true);
+
+	print "Attempting to delete publisher [id = $vintage_id]: ";
+	$vintage->delete();
+	print boolTest(true);
+
+	// These have to be deleted manually also since we have onDelete
+	// set to SETNULL in the foreign keys in book. Is this correct?
+	print "Attempting to delete author [lastname = 'Rowling']: ";
+	$rowling->delete();
+	print boolTest(true);
+
+	print "Attempting to delete publisher [lastname = 'Scholastic']: ";
+	$scholastic->delete();
+	print boolTest(true);
+
+	print "Attempting to delete BookClubList 1: ";
+	$blc1->delete();
+	print boolTest(true);
+
+	print "Attempting to delete BookClubList 2: ";
+	$blc2->delete();
+	print boolTest(true);
+
+} catch (Exception $e) {
+	die("Error deleting book: " . $e->__toString());
+}
+
+
+// Check again to make sure that tables are empty
+// ----------------------------------------------
+
+check_tables_empty();
+
+
+
+
+
+$timer->stop();
+print $timer->display();
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/test/bookstore-test.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/test/bookstore-test.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/test/bookstore-test.php	(revision 19)
@@ -0,0 +1,773 @@
+<?php
+
+/**
+ * Simple test script for Propel drivers.
+ *
+ * This script will no do in-depth testing, but is designed to test whether drivers
+ * are correctly performing basic operations -- SELECT, UPDATE, DELETE, limit support,
+ * prepared query emulation, etc.
+ *
+ * IMPORTANT:
+ *
+ * Use this script with a clean version of the [example] bookstore database.  If records
+ * already exist, an error will be displayed.
+ *
+ * TODO:
+ * A more advanced driver test system should be developed that could test capabilities
+ * of driver-specific things like callable statements (stored procedures), etc.  Perhaps break
+ * functionality into class & provide ability to subclass.
+ *
+ * @author     Hans Lellelid <hans@xmpl.org>
+ * @version    $Revision: 563 $
+ */
+
+// Setup configuration.  It is expected that the bookstore-conf.php file exists in ../build/conf
+//
+
+error_reporting(E_ALL);
+
+$conf_path = realpath(dirname(__FILE__) . '/../projects/bookstore/build/conf/bookstore-conf.php');
+if (!file_exists($conf_path)) {
+	print "Make sure that you specify properties in conf/bookstore.properties and "
+	."build propel before running this script.\n";
+	exit;
+}
+
+// Add PHP_CLASSPATH, if set
+if (getenv("PHP_CLASSPATH")) {
+	set_include_path(getenv("PHP_CLASSPATH") . PATH_SEPARATOR . get_include_path());
+}
+
+ // Add build/classes/ and classes/ to path
+set_include_path(
+	realpath(dirname(__FILE__) . '/../projects/bookstore/build/classes') . PATH_SEPARATOR .
+	dirname(__FILE__) . '/../../runtime/classes' . PATH_SEPARATOR .
+	get_include_path()
+);
+
+
+ // Require classes.
+ require 'propel/Propel.php';
+
+ include_once 'Benchmark/Timer.php';
+
+ $timer = new Benchmark_Timer;
+
+ $timer->start();
+
+ // Some utility functions
+ function boolTest($cond) {
+	 if ($cond) {
+		 return "[OK]\n";
+	 } else {
+		return "[FAILED]\n";
+	}
+ }
+
+ try {
+	// Initialize Propel
+	 Propel::init($conf_path);
+ } catch (Exception $e) {
+	 die("Error initializing propel: ". $e->__toString());
+ }
+
+function check_tables_empty() {
+	try {
+
+		print "\nChecking to see that tables are empty\n";
+		print "-------------------------------------\n\n";
+
+		print "Ensuring that there are no records in [author] table: ";
+		$res = AuthorPeer::doSelect(new Criteria());
+		print boolTest(empty($res));
+
+		print "Ensuring that there are no records in [publisher] table: ";
+		$res2 = PublisherPeer::doSelect(new Criteria());
+		print boolTest(empty($res2));
+
+		print "Ensuring that there are no records in [book] table: ";
+		$res3 = AuthorPeer::doSelect(new Criteria());
+		print boolTest(empty($res3));
+
+		print "Ensuring that there are no records in [review] table: ";
+		$res4 = ReviewPeer::doSelect(new Criteria());
+		print boolTest(empty($res4));
+
+		print "Ensuring that there are no records in [media] table: ";
+		$res5 = MediaPeer::doSelect(new Criteria());
+		print boolTest(empty($res5));
+
+		print "Ensuring that there are no records in [book_club_list] table: ";
+		$res6 = BookClubListPeer::doSelect(new Criteria());
+		print boolTest(empty($res6));
+
+		print "Ensuring that there are no records in [book_x_list] table: ";
+		$res7 = BookListRelPeer::doSelect(new Criteria());
+		print boolTest(empty($res7));
+
+		return (empty($res) && empty($res2) && empty($res3) && empty($res4) && empty($res5));
+
+	} catch (Exception $e) {
+		die("Error ensuring tables were empty: " . $e->__toString());
+	}
+}
+
+// Check to see if records already exist in any of the three tables.  If so, display an error
+// and exit.
+
+if (!check_tables_empty()) {
+	die("Tables must be empty to perform these tests.");
+}
+
+// Add publisher records
+// ---------------------
+
+try {
+	print "\nAdding some new publishers to the list\n";
+	print "--------------------------------------\n\n";
+
+	$scholastic = new Publisher();
+	$scholastic->setName("Scholastic");
+	// do not save, will do later to test cascade
+	print "Added publisher \"Scholastic\" [not saved yet].\n";
+
+	$morrow = new Publisher();
+	$morrow->setName("William Morrow");
+	$morrow->save();
+	$morrow_id = $morrow->getId();
+	print "Added publisher \"William Morrow\" [id = $morrow_id].\n";
+
+	$penguin = new Publisher();
+	$penguin->setName("Penguin");
+	$penguin->save();
+	$penguin_id = $penguin->getId();
+	print "Added publisher \"Penguin\" [id = $penguin_id].\n";
+
+	$vintage = new Publisher();
+	$vintage->setName("Vintage");
+	$vintage->save();
+	$vintage_id = $vintage->getId();
+	print "Added publisher \"Vintage\" [id = $vintage_id].\n";
+
+} catch (Exception $e) {
+	die("Error adding publisher: " . $e->__toString());
+}
+
+// Add author records
+// ------------------
+
+try {
+	print "\nAdding some new authors to the list\n";
+	print "--------------------------------------\n\n";
+
+	$rowling = new Author();
+	$rowling->setFirstName("J.K.");
+	$rowling->setLastName("Rowling");
+	// no save()
+	print "Added author \"J.K. Rowling\" [not saved yet].\n";
+
+	$stephenson = new Author();
+	$stephenson->setFirstName("Neal");
+	$stephenson->setLastName("Stephenson");
+	$stephenson->save();
+	$stephenson_id = $stephenson->getId();
+	print "Added author \"Neal Stephenson\" [id = $stephenson_id].\n";
+
+	$byron = new Author();
+	$byron->setFirstName("George");
+	$byron->setLastName("Byron");
+	$byron->save();
+	$byron_id = $byron->getId();
+	print "Added author \"George Byron\" [id = $byron_id].\n";
+
+
+	$grass = new Author();
+	$grass->setFirstName("Gunter");
+	$grass->setLastName("Grass");
+	$grass->save();
+	$grass_id = $grass->getId();
+	print "Added author \"Gunter Grass\" [id = $grass_id].\n";
+
+} catch (Exception $e) {
+	die("Error adding author: " . $e->__toString());
+}
+
+// Add book records
+// ----------------
+
+try {
+
+	print "\nAdding some new books to the list\n";
+	print "-------------------------------------\n\n";
+
+	$phoenix = new Book();
+	$phoenix->setTitle("Harry Potter and the Order of the Phoenix");
+	$phoenix->setISBN("043935806X");
+
+
+
+	print "Trying cascading save (Harry Potter): ";
+	$phoenix->setAuthor($rowling);
+	$phoenix->setPublisher($scholastic);
+	$phoenix->save();
+	$phoenix_id = $phoenix->getId();
+	print boolTest(true);
+	print "Added book \"Harry Potter and the Order of the Phoenix\" [id = $phoenix_id].\n";
+
+	$qs = new Book();
+	$qs->setISBN("0380977427");
+	$qs->setTitle("Quicksilver");
+	$qs->setAuthor($stephenson);
+	$qs->setPublisher($morrow);
+	$qs->save();
+	$qs_id = $qs->getId();
+	print "Added book \"Quicksilver\" [id = $qs_id].\n";
+
+	$dj = new Book();
+	$dj->setISBN("0140422161");
+	$dj->setTitle("Don Juan");
+	$dj->setAuthor($byron);
+	$dj->setPublisher($penguin);
+	$dj->save();
+	$dj_id = $qs->getId();
+	print "Added book \"Don Juan\" [id = $dj_id].\n";
+
+	$td = new Book();
+	$td->setISBN("067972575X");
+	$td->setTitle("The Tin Drum");
+	$td->setAuthor($grass);
+	$td->setPublisher($vintage);
+	$td->save();
+	$td_id = $td->getId();
+	print "Added book \"The Tin Drum\" [id = $dj_id].\n";
+
+} catch (Exception $e) {
+	die("Error saving book: " . $e->__toString());
+}
+
+// Add review records
+// ------------------
+
+try {
+
+	print "\nAdding some book reviews to the list\n";
+	print "------------------------------------\n\n";
+
+	$r1 = new Review();
+	$r1->setBook($phoenix);
+	$r1->setReviewedBy("Washington Post");
+	$r1->setRecommended(true);
+	$r1->setReviewDate(time());
+	$r1->save();
+	$r1_id = $r1->getId();
+	print "Added Washington Post book review  [id = $r1_id].\n";
+
+	$r2 = new Review();
+	$r2->setBook($phoenix);
+	$r2->setReviewedBy("New York Times");
+	$r2->setRecommended(false);
+	$r2->setReviewDate(time());
+	$r2->save();
+	$r2_id = $r2->getId();
+	print "Added New York Times book review  [id = $r2_id].\n";
+
+} catch (Exception $e) {
+	die("Error saving book review: " . $e->__toString());
+}
+
+// Perform a "complex" search
+// --------------------------
+
+try {
+
+	print "\nDoing complex search on books\n";
+	print "-----------------------------\n\n";
+
+	$crit = new Criteria();
+	$crit->add(BookPeer::TITLE, 'Harry%', Criteria::LIKE);
+
+	print "Looking for \"Harry%\": ";
+	$results = BookPeer::doSelect($crit);
+	print boolTest(count($results) === 1);
+
+
+	$crit2 = new Criteria();
+	$crit2->add(BookPeer::ISBN, array("0380977427", "0140422161"), Criteria::IN);
+	$results = BookPeer::doSelect($crit2);
+	print "Looking for ISBN IN (\"0380977427\", \"0140422161\"): ";
+	print boolTest(count($results) === 2);
+
+} catch (Exception $e) {
+	die("Error while performing complex query: " . $e->__toString());
+}
+
+
+// Perform a "limit" search
+// ------------------------
+
+try {
+
+	print "\nDoing LIMITed search on books\n";
+	print "-----------------------------\n\n";
+
+	$crit = new Criteria();
+	$crit->setLimit(2);
+	$crit->setOffset(1);
+	$crit->addAscendingOrderByColumn(BookPeer::TITLE);
+
+	print "Checking to make sure correct number returned: ";
+	$results = BookPeer::doSelect($crit);
+	print boolTest(count($results) === 2);
+
+	print "Checking to make sure correct books returned: ";
+	// we ordered on book title, so we expect to get
+	print boolTest( $results[0]->getTitle() == "Harry Potter and the Order of the Phoenix" && $results[1]->getTitle() == "Quicksilver"  );
+
+
+} catch (Exception $e) {
+	die("Error while performing LIMIT query: " . $e->__toString());
+}
+
+
+
+// Perform a lookup & update!
+// --------------------------
+
+try {
+
+	print "\nUpdating just-created book title\n";
+	print "--------------------------------\n\n";
+
+	print "First finding book by PK (=$qs_id) .... ";
+
+	try {
+		$qs_lookup = BookPeer::retrieveByPk($qs_id);
+	} catch (Exception $e) {
+		print "ERROR!\n";
+		die("Error retrieving by pk: " . $e->__toString());
+	}
+
+	if ($qs_lookup) {
+		print "FOUND!\n";
+	} else {
+		print "NOT FOUND :(\n";
+		die("Couldn't find just-created book: book_id = $qs_id");
+	}
+
+	try {
+		$new_title = "Quicksilver (".crc32(uniqid(rand())).")";
+		print "Attempting to update found object (".$qs_lookup->getTitle()." -> ".$new_title."): ";
+		$qs_lookup->setTitle($new_title);
+		$qs_lookup->save();
+		print boolTest(true);
+	} catch (Exception $e) {
+		die("Error saving (updating) book: " . $e->__toString());
+	}
+
+	print "Making sure object was correctly updated: ";
+	$qs_lookup2 = BookPeer::retrieveByPk($qs_id);
+	print boolTest($qs_lookup2->getTitle() == $new_title);
+
+} catch (Exception $e) {
+	die("Error updating book: " . $e->__toString());
+}
+
+
+// Test some basic DATE / TIME stuff
+// ---------------------------------
+
+try {
+	print "\nTesting the DATE/TIME columns\n";
+	print "-----------------------------\n\n";
+
+	// that's the control timestamp.
+	$control = strtotime('2004-02-29 00:00:00');
+
+	// should be two in the db
+	$r = ReviewPeer::doSelectOne(new Criteria());
+	$r_id = $r->getId();
+	$r->setReviewDate($control);
+	$r->save();
+
+	$r2 = ReviewPeer::retrieveByPk($r_id);
+
+	print "Checking ability to fetch native unix timestamp: ";
+	print boolTest($r2->getReviewDate(null) === $control);
+
+	print "Checking ability to use date() formatter: ";
+	print boolTest($r2->getReviewDate('n-j-Y') === '2-29-2004');
+
+	print "[FYI] Here's the strftime() formatter for current locale: " . $r2->getReviewDate('%x') . "\n";
+
+} catch (Exception $e) {
+	die("Error test date/time: "  . $e->__toString());
+}
+
+// Handle BLOB/CLOB Columns
+// ------------------------
+
+try {
+	print "\nTesting the BLOB/CLOB columns\n";
+	print "-------------------------------\n\n";
+
+	$blob_path = dirname(__FILE__) . '/etc/lob/tin_drum.gif';
+	$blob2_path = dirname(__FILE__) . '/etc/lob/propel.gif';
+	$clob_path = dirname(__FILE__) . '/etc/lob/tin_drum.txt';
+
+	$m1 = new Media();
+	$m1->setBook($phoenix);
+	$m1->setCoverImage(file_get_contents($blob_path));
+	$m1->setExcerpt(file_get_contents($clob_path));
+	$m1->save();
+	$m1_id = $m1->getId();
+	print "Added Media collection [id = $m1_id].\n";
+
+	print "Looking for just-created mediat by PK (=$m1_id) .... ";
+
+	try {
+		$m1_lookup = MediaPeer::retrieveByPk($m1_id);
+	} catch (Exception $e) {
+		print "ERROR!\n";
+		die("Error retrieving media by pk: " . $e->__toString());
+	}
+
+	if ($m1_lookup) {
+		print "FOUND!\n";
+	} else {
+		print "NOT FOUND :(\n";
+		die("Couldn't find just-created media item: media_id = $m1_id");
+	}
+
+	print "Making sure BLOB was correctly updated: ";
+	print boolTest( $m1_lookup->getCoverImage() === file_get_contents($blob_path));
+	print "Making sure CLOB was correctly updated: ";
+	print boolTest((string) $m1_lookup->getExcerpt() === file_get_contents($clob_path));
+
+
+	// now update the BLOB column and save it & check the results
+
+	$m1_lookup->setCoverImage(file_get_contents($blob2_path));
+	$m1_lookup->save();
+
+	try {
+		$m2_lookup = MediaPeer::retrieveByPk($m1_id);
+	} catch (Exception $e) {
+		print "ERROR!\n";
+		die("Error retrieving media by pk: " . $e->__toString());
+	}
+
+	print "Making sure BLOB was correctly overwritten: ";
+	print boolTest($m2_lookup->getCoverImage() === file_get_contents($blob2_path));
+
+} catch (Exception $e) {
+	die("Error doing blob/clob updates: " . $e->__toString());
+}
+
+// Test Validators
+// ---------------
+
+try {
+
+	print "\nTesting the column validators\n";
+	print "-----------------------------\n\n";
+
+	$bk1 = new Book();
+	$bk1->setTitle("12345"); // min length is 10
+	$ret = $bk1->validate();
+
+	print "Making sure validation failed: ";
+	print boolTest($ret !== true);
+
+	$failures = $bk1->getValidationFailures();
+
+	print "Making sure 1 validation message was returned: ";
+	print boolTest(count($failures) === 1);
+
+	print "Making sure expected validation message was returned: ";
+	$el = array_shift($failures);
+	print boolTest(stripos($el->getMessage(), "must be more than") !== false);
+
+	print "\n(Unique validator)\n";
+
+	$bk2 = new Book();
+	$bk2->setTitle("Don Juan");
+	$ret = $bk2->validate();
+
+	print "Making sure validation failed: ";
+	print boolTest($ret !== true);
+
+	$failures = $bk2->getValidationFailures();
+	print "Making sure 1 validation message was returned: ";
+	print boolTest(count($failures) === 1);
+
+	print "Making sure expected validation message was returned: ";
+	$el = array_shift($failures);
+	print boolTest(stripos($el->getMessage(), "Book title already in database.") !== false);
+
+	print "\n(Now trying some more complex validation.)\n";
+	$auth1 = new Author();
+	$auth1->setFirstName("Hans");
+	// last name required; will fail
+
+	$bk1->setAuthor($auth1);
+
+	$rev1 = new Review();
+	$rev1->setReviewDate("08/09/2001");
+	 // will fail: reviewed_by column required
+
+	$bk1->addReview($rev1);
+
+	$ret2 = $bk1->validate();
+
+	$failures2 = $bk1->getValidationFailures();
+
+	print "Making sure 6 validation messages were returned: ";
+	print boolTest(count($failures2) === 3);
+
+	print "Making sure correct columns failed: ";
+	print boolTest(array_keys($failures2) === array(
+		AuthorPeer::LAST_NAME,
+		BookPeer::TITLE,
+		ReviewPeer::REVIEWED_BY,
+	));
+
+
+	$bk2 = new Book();
+	$bk2->setTitle("12345678901"); // passes
+
+	$auth2 = new Author();
+	$auth2->setLastName("Blah"); //passes
+	$auth2->setEmail("some@body.com"); //passes
+	$auth2->setAge(50); //passes
+	$bk2->setAuthor($auth2);
+
+	$rev2 = new Review();
+	$rev2->setReviewedBy("Me!"); // passes
+	$rev2->setStatus("new"); // passes
+	$bk2->addReview($rev2);
+
+	$ret3 = $bk2->validate();
+
+	print "Making sure complex validation can pass: ";
+	print boolTest($ret3 === true);
+
+} catch (Exception $e) {
+	die("Error doing validation tests: " . $e->__toString());
+}
+
+// Test doCount()
+//
+try {
+
+	print "\nTesting doCount() functionality\n";
+	print "-------------------------------\n\n";
+
+	$c = new Criteria();
+	$records = BookPeer::doSelect($c);
+	$count = BookPeer::doCount($c);
+
+	print "Making sure correct number of results: ";
+	print boolTest(count($records) === $count);
+
+} catch (Exception $e) {
+	die("Error deleting book: " . $e->__toString());
+}
+
+// Test many-to-many relationships
+// ---------------
+
+try {
+
+	print "\nTesting many-to-many relationships\n";
+	print "-----------------------------\n\n";
+
+	// init book club list 1 with 2 books
+
+	$blc1 = new BookClubList();
+	$blc1->setGroupLeader("Crazyleggs");
+	$blc1->setTheme("Happiness");
+
+	$brel1 = new BookListRel();
+	$brel1->setBook($phoenix);
+
+	$brel2 = new BookListRel();
+	$brel2->setBook($dj);
+
+	$blc1->addBookListRel($brel1);
+	$blc1->addBookListRel($brel2);
+
+	$blc1->save();
+
+	print "Making sure BookClubList 1 was saved: ";
+ 	print boolTest(!is_null($blc1->getId()));
+
+	// init book club list 2 with 1 book
+
+	$blc2 = new BookClubList();
+	$blc2->setGroupLeader("John Foo");
+	$blc2->setTheme("Default");
+
+	$brel3 = new BookListRel();
+	$brel3->setBook($phoenix);
+
+	$blc2->addBookListRel($brel3);
+
+	$blc2->save();
+
+	print "Making sure BookClubList 2 was saved: ";
+ 	print boolTest(!is_null($blc2->getId()));
+
+	// re-fetch books and lists from db to be sure that nothing is cached
+
+	$crit = new Criteria();
+	$crit->add(BookPeer::ID, $phoenix->getId());
+	$phoenix = BookPeer::doSelectOne($crit);
+	print "Making sure book 'phoenix' has been re-fetched from db: ";
+ 	print boolTest(!empty($phoenix));
+
+	$crit = new Criteria();
+	$crit->add(BookClubListPeer::ID, $blc1->getId());
+	$blc1 = BookClubListPeer::doSelectOne($crit);
+	print "Making sure BookClubList 1 has been re-fetched from db: ";
+ 	print boolTest(!empty($blc1));
+
+	$crit = new Criteria();
+	$crit->add(BookClubListPeer::ID, $blc2->getId());
+	$blc2 = BookClubListPeer::doSelectOne($crit);
+	print "Making sure BookClubList 2 has been re-fetched from db: ";
+ 	print boolTest(!empty($blc2));
+
+	$relCount = $phoenix->countBookListRels();
+	print "Making sure book 'phoenix' has 2 BookListRels: ";
+ 	print boolTest($relCount == 2);
+
+	$relCount = $blc1->countBookListRels();
+	print "Making sure BookClubList 1 has 2 BookListRels: ";
+ 	print boolTest($relCount == 2);
+
+	$relCount = $blc2->countBookListRels();
+	print "Making sure BookClubList 2 has 1 BookListRel: ";
+ 	print boolTest($relCount == 1);
+
+
+} catch (Exception $e) {
+	die("Error doing many-to-many relationships tests: " . $e->__toString());
+}
+
+// Cleanup (tests DELETE)
+// ----------------------
+
+try {
+
+	print "\nRemoving books that were just created\n";
+	print "-------------------------------------\n\n";
+
+	print "First finding book by PK (=$phoenix_id) .... ";
+	try {
+		$hp = BookPeer::retrieveByPk($phoenix_id);
+	} catch (Exception $e) {
+		print "ERROR!\n";
+		die("Error retrieving by pk: " . $e->__toString());
+	}
+
+	if ($hp) {
+		print "FOUND!\n";
+	} else {
+		print "NOT FOUND :(\n";
+		die("Couldn't find just-created book: book_id = $phoenix_id");
+	}
+
+	print "Attempting to delete [multi-table] by found pk: ";
+	$c = new Criteria();
+	$c->add(BookPeer::ID, $hp->getId());
+	// The only way for cascading to work currently
+	// is to specify the author_id and publisher_id (i.e. the fkeys
+	// have to be in the criteria).
+	$c->add(AuthorPeer::ID, $hp->getId());
+	$c->add(PublisherPeer::ID, $hp->getId());
+	$c->setSingleRecord(true);
+	BookPeer::doDelete($c);
+	print boolTest(true);
+
+	print "Checking to make sure correct records were removed.\n";
+	print "\tFrom author table: ";
+	$res = AuthorPeer::doSelect(new Criteria());
+	print boolTest(count($res) === 3);
+	print "\tFrom publisher table: ";
+	$res2 = PublisherPeer::doSelect(new Criteria());
+	print boolTest(count($res2) === 3);
+	print "\tFrom book table: ";
+	$res3 = BookPeer::doSelect(new Criteria());
+	print boolTest(count($res3) === 3);
+
+	print "Attempting to delete books by complex criteria: ";
+	$c = new Criteria();
+	$cn = $c->getNewCriterion(BookPeer::ISBN, "043935806X");
+	$cn->addOr($c->getNewCriterion(BookPeer::ISBN, "0380977427"));
+	$cn->addOr($c->getNewCriterion(BookPeer::ISBN, "0140422161"));
+	$c->add($cn);
+	BookPeer::doDelete($c);
+	print boolTest(true);
+
+	print "Attempting to delete book [id = $td_id]: ";
+	$td->delete();
+	print boolTest(true);
+
+	print "Attempting to delete author [id = $stephenson_id]: ";
+	AuthorPeer::doDelete($stephenson_id);
+	print boolTest(true);
+
+	print "Attempting to delete author [id = $byron_id]: ";
+	AuthorPeer::doDelete($byron_id);
+	print boolTest(true);
+
+	print "Attempting to delete author [id = $grass_id]: ";
+	$grass->delete();
+	print boolTest(true);
+
+	print "Attempting to delete publisher [id = $morrow_id]: ";
+	PublisherPeer::doDelete($morrow_id);
+	print boolTest(true);
+
+	print "Attempting to delete publisher [id = $penguin_id]: ";
+	PublisherPeer::doDelete($penguin_id);
+	print boolTest(true);
+
+	print "Attempting to delete publisher [id = $vintage_id]: ";
+	$vintage->delete();
+	print boolTest(true);
+
+	// These have to be deleted manually also since we have onDelete
+	// set to SETNULL in the foreign keys in book. Is this correct?
+	print "Attempting to delete author [lastname = 'Rowling']: ";
+	$rowling->delete();
+	print boolTest(true);
+
+	print "Attempting to delete publisher [lastname = 'Scholastic']: ";
+	$scholastic->delete();
+	print boolTest(true);
+
+	print "Attempting to delete BookClubList 1: ";
+	$blc1->delete();
+	print boolTest(true);
+
+	print "Attempting to delete BookClubList 2: ";
+	$blc2->delete();
+	print boolTest(true);
+
+} catch (Exception $e) {
+	die("Error deleting book: " . $e->__toString());
+}
+
+
+// Check again to make sure that tables are empty
+// ----------------------------------------------
+
+check_tables_empty();
+
+
+
+
+
+$timer->stop();
+print $timer->display();
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/test/classes/bookstore/BookstoreDataPopulator.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/test/classes/bookstore/BookstoreDataPopulator.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/test/classes/bookstore/BookstoreDataPopulator.php	(revision 19)
@@ -0,0 +1,218 @@
+<?php
+/*
+ *  $Id: BookstoreDataPopulator.php 887 2007-12-19 22:33:34Z heltem $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://propel.phpdb.org>.
+ */
+
+define('_LOB_SAMPLE_FILE_PATH', dirname(__FILE__) . '/../../etc/lob');
+
+/**
+ * Populates data needed by the bookstore unit tests.
+ *
+ * This classes uses the actual Propel objects to do the population rather than
+ * inserting directly into the database.  This will have a performance hit, but will
+ * benefit from increased flexibility (as does anything using Propel).
+ *
+ * @author     Hans Lellelid <hans@xmpl.org>
+ */
+class BookstoreDataPopulator {
+
+	public static function populate()
+	{
+		// Add publisher records
+		// ---------------------
+
+		$scholastic = new Publisher();
+		$scholastic->setName("Scholastic");
+		// do not save, will do later to test cascade
+
+		$morrow = new Publisher();
+		$morrow->setName("William Morrow");
+		$morrow->save();
+		$morrow_id = $morrow->getId();
+
+		$penguin = new Publisher();
+		$penguin->setName("Penguin");
+		$penguin->save();
+		$penguin_id = $penguin->getId();
+
+		$vintage = new Publisher();
+		$vintage->setName("Vintage");
+		$vintage->save();
+		$vintage_id = $vintage->getId();
+
+		$rowling = new Author();
+		$rowling->setFirstName("J.K.");
+		$rowling->setLastName("Rowling");
+		// no save()
+
+		$stephenson = new Author();
+		$stephenson->setFirstName("Neal");
+		$stephenson->setLastName("Stephenson");
+		$stephenson->save();
+		$stephenson_id = $stephenson->getId();
+
+		$byron = new Author();
+		$byron->setFirstName("George");
+		$byron->setLastName("Byron");
+		$byron->save();
+		$byron_id = $byron->getId();
+
+		$grass = new Author();
+		$grass->setFirstName("Gunter");
+		$grass->setLastName("Grass");
+		$grass->save();
+		$grass_id = $grass->getId();
+
+		$phoenix = new Book();
+		$phoenix->setTitle("Harry Potter and the Order of the Phoenix");
+		$phoenix->setISBN("043935806X");
+		$phoenix->setAuthor($rowling);
+		$phoenix->setPublisher($scholastic);
+		$phoenix->setPrice(10.99);
+		$phoenix->save();
+		$phoenix_id = $phoenix->getId();
+
+		$qs = new Book();
+		$qs->setISBN("0380977427");
+		$qs->setTitle("Quicksilver");
+		$qs->setPrice(11.99);
+		$qs->setAuthor($stephenson);
+		$qs->setPublisher($morrow);
+		$qs->save();
+		$qs_id = $qs->getId();
+
+		$dj = new Book();
+		$dj->setISBN("0140422161");
+		$dj->setTitle("Don Juan");
+		$dj->setPrice(12.99);
+		$dj->setAuthor($byron);
+		$dj->setPublisher($penguin);
+		$dj->save();
+		$dj_id = $dj->getId();
+
+		$td = new Book();
+		$td->setISBN("067972575X");
+		$td->setTitle("The Tin Drum");
+		$td->setPrice(13.99);
+		$td->setAuthor($grass);
+		$td->setPublisher($vintage);
+		$td->save();
+		$td_id = $td->getId();
+
+		$r1 = new Review();
+		$r1->setBook($phoenix);
+		$r1->setReviewedBy("Washington Post");
+		$r1->setRecommended(true);
+		$r1->setReviewDate(time());
+		$r1->save();
+		$r1_id = $r1->getId();
+
+		$r2 = new Review();
+		$r2->setBook($phoenix);
+		$r2->setReviewedBy("New York Times");
+		$r2->setRecommended(false);
+		$r2->setReviewDate(time());
+		$r2->save();
+		$r2_id = $r2->getId();
+
+		$blob_path = _LOB_SAMPLE_FILE_PATH . '/tin_drum.gif';
+		$clob_path =  _LOB_SAMPLE_FILE_PATH . '/tin_drum.txt';
+
+		$m1 = new Media();
+		$m1->setBook($td);
+		$m1->setCoverImage(file_get_contents($blob_path));
+		$m1->setExcerpt(file_get_contents($clob_path));
+		$m1->save();
+
+		// Add book list records
+		// ---------------------
+		// (this is for many-to-many tests)
+
+		$blc1 = new BookClubList();
+		$blc1->setGroupLeader("Crazyleggs");
+		$blc1->setTheme("Happiness");
+
+		$brel1 = new BookListRel();
+		$brel1->setBook($phoenix);
+
+		$brel2 = new BookListRel();
+		$brel2->setBook($dj);
+
+		$blc1->addBookListRel($brel1);
+		$blc1->addBookListRel($brel2);
+
+		$bemp1 = new BookstoreEmployee();
+		$bemp1->setName("John");
+		$bemp1->setJobTitle("Manager");
+
+		$bemp2 = new BookstoreEmployee();
+		$bemp2->setName("Pieter");
+		$bemp2->setJobTitle("Clerk");
+		$bemp2->setSupervisor($bemp1);
+		$bemp2->save();
+
+		$role = new AcctAccessRole();
+		$role->setName("Admin");
+
+		$bempacct = new BookstoreEmployeeAccount();
+		$bempacct->setBookstoreEmployee($bemp1);
+		$bempacct->setAcctAccessRole($role);
+		$bempacct->setLogin("john");
+		$bempacct->setPassword("johnp4ss");
+		$bempacct->save();
+
+		// Add bookstores
+
+		$store = new Bookstore();
+		$store->setStoreName("Amazon");
+		$store->setPopulationServed(5000000000); // world population
+		$store->setTotalBooks(300);
+		$store->save();
+
+		$store = new Bookstore();
+		$store->setStoreName("Local Store");
+		$store->setPopulationServed(20);
+		$store->setTotalBooks(500000);
+		$store->save();
+	}
+
+	public static function depopulate()
+	{
+		AcctAccessRolePeer::doDeleteAll();
+		AuthorPeer::doDeleteAll();
+		BookstorePeer::doDeleteAll();
+		BookstoreContestPeer::doDeleteAll();
+		BookstoreContestEntryPeer::doDeleteAll();
+		BookstoreEmployeePeer::doDeleteAll();
+		BookstoreEmployeeAccountPeer::doDeleteAll();
+		BookstoreSalePeer::doDeleteAll();
+		BookClubListPeer::doDeleteAll();
+		BookOpinionPeer::doDeleteAll();
+		BookReaderPeer::doDeleteAll();
+		BookListRelPeer::doDeleteAll();
+		BookPeer::doDeleteAll();
+		ContestPeer::doDeleteAll();
+		CustomerPeer::doDeleteAll();
+		MediaPeer::doDeleteAll();
+		PublisherPeer::doDeleteAll();
+		ReaderFavoritePeer::doDeleteAll();
+		ReviewPeer::doDeleteAll();
+	}
+
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/test/classes/bookstore/BookstoreTestBase.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/test/classes/bookstore/BookstoreTestBase.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/test/classes/bookstore/BookstoreTestBase.php	(revision 19)
@@ -0,0 +1,84 @@
+<?php
+/*
+ *  $Id: BookstoreTestBase.php 818 2007-11-19 01:13:05Z hans $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://propel.phpdb.org>.
+ */
+
+require_once 'PHPUnit/Framework/TestCase.php';
+include_once 'bookstore/BookstoreDataPopulator.php';
+
+/**
+ * Base class contains some methods shared by subclass test cases.
+ */
+abstract class BookstoreTestBase extends PHPUnit_Framework_TestCase {
+
+	/**
+	 * This is run before each unit test; it populates the database.
+	 */
+	protected function setUp()
+	{
+		parent::setUp();
+		BookstoreDataPopulator::depopulate();
+		BookstoreDataPopulator::populate();
+	}
+
+	/**
+	 * This is run after each unit test.  It empties the database.
+	 */
+	protected function tearDown()
+	{
+
+		BookstoreDataPopulator::depopulate();
+
+		$this->assertEquals(0, count(BookPeer::doSelect(new Criteria())), "Expect book table to be empty.");
+		$this->assertEquals(0, count(AuthorPeer::doSelect(new Criteria())), "Expect author table to be empty.");
+		$this->assertEquals(0, count(PublisherPeer::doSelect(new Criteria())), "Expect publisher table to be empty.");
+		$this->assertEquals(0, count(ReviewPeer::doSelect(new Criteria())), "Expect review table to be empty.");
+		$this->assertEquals(0, count(MediaPeer::doSelect(new Criteria())), "Expect media table to be empty.");
+		$this->assertEquals(0, count(BookstoreEmployeePeer::doSelect(new Criteria())), "Expect bookstore_employee table to be empty.");
+		$this->assertEquals(0, count(BookstoreEmployeeAccountPeer::doSelect(new Criteria())), "Expect bookstore_employee_account table to be empty.");
+		$this->assertEquals(0, count(BookstoreSalePeer::doSelect(new Criteria())), "Expect bookstore_sale table to be empty.");
+
+		BookPeer::clearInstancePool();
+		$this->assertEquals(0, count(BookPeer::$instances), "Expected 0 Book instances after clearInstancePool()");
+
+		AuthorPeer::clearInstancePool();
+		$this->assertEquals(0, count(AuthorPeer::$instances), "Expected 0 Author instances after clearInstancePool()");
+
+		PublisherPeer::clearInstancePool();
+		$this->assertEquals(0, count(PublisherPeer::$instances), "Expected 0 Publisher instances after clearInstancePool()");
+
+		ReviewPeer::clearInstancePool();
+		$this->assertEquals(0, count(ReviewPeer::$instances), "Expected 0 Review instances after clearInstancePool()");
+
+		MediaPeer::clearInstancePool();
+		$this->assertEquals(0, count(MediaPeer::$instances), "Expected 0 Media instances after clearInstancePool()");
+
+		BookstoreEmployeePeer::clearInstancePool();
+		$this->assertEquals(0, count(BookstoreEmployeePeer::$instances), "Expected 0 BookstoreEmployee instances after clearInstancePool()");
+
+		BookstoreEmployeeAccountPeer::clearInstancePool();
+		$this->assertEquals(0, count(BookstoreEmployeeAccountPeer::$instances), "Expected 0 BookstoreEmployeeAccount instances after clearInstancePool()");
+
+		BookstoreSalePeer::clearInstancePool();
+		$this->assertEquals(0, count(BookstoreSalePeer::$instances), "Expected 0 BookstoreSale instances after clearInstancePool()");
+
+		parent::tearDown();
+	}
+
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/test/classes/bookstore/validator/ISBNValidator.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/test/classes/bookstore/validator/ISBNValidator.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/test/classes/bookstore/validator/ISBNValidator.php	(revision 19)
@@ -0,0 +1,40 @@
+<?php
+/*
+ *  $Id: MatchValidator.php 521 2007-01-05 13:29:36Z heltem $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://propel.phpdb.org>.
+ */
+
+/**
+ * A custom validator for ISBN.
+ *
+ * @author     Hans Lellelid <hans@xmpl.org>
+ * @version    $Revision$
+ * @package    propel.validator
+ */
+class ISBNValidator implements BasicValidator
+{
+	const NOT_ISBN_REGEXP = '/[^0-9A-Z]/';
+
+	/**
+	 * Whether the passed string matches regular expression.
+	 */
+	public function isValid (ValidatorMap $map, $str)
+	{
+		return !(preg_match(self::NOT_ISBN_REGEXP, $str));
+	}
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/test/classes/cms/CmsDataPopulator.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/test/classes/cms/CmsDataPopulator.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/test/classes/cms/CmsDataPopulator.php	(revision 19)
@@ -0,0 +1,137 @@
+<?php
+/*
+ *  $Id: CmsDataPopulator.php 876 2007-12-19 13:16:31Z heltem $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://propel.phpdb.org>.
+ */
+
+/**
+ * Populates data needed by the bookstore-cms unit tests.
+ *
+ * @author     Hans Lellelid <hans@xmpl.org>
+ */
+class CmsDataPopulator {
+
+	public static function populate()
+	{
+		$dbh = Propel::getConnection(PagePeer::DATABASE_NAME);
+		$dbh->exec("INSERT INTO Page (ScopeId, LeftChild, RightChild, Title) VALUES (1, 1,194,'home')");
+		$dbh->exec("INSERT INTO Page (ScopeId, LeftChild, RightChild, Title) VALUES (1, 2,5,'school')");
+		$dbh->exec("INSERT INTO Page (ScopeId, LeftChild, RightChild, Title) VALUES (1, 6,43,'education')");
+		$dbh->exec("INSERT INTO Page (ScopeId, LeftChild, RightChild, Title) VALUES (1, 44,45,'simulator')");
+		$dbh->exec("INSERT INTO Page (ScopeId, LeftChild, RightChild, Title) VALUES (1, 46,47,'ac')");
+		$dbh->exec("INSERT INTO Page (ScopeId, LeftChild, RightChild, Title) VALUES (1, 3,4,'history')");
+		$dbh->exec("INSERT INTO Page (ScopeId, LeftChild, RightChild, Title) VALUES (1, 7,14,'master-mariner')");
+		$dbh->exec("INSERT INTO Page (ScopeId, LeftChild, RightChild, Title) VALUES (1, 8,9,'education')");
+		$dbh->exec("INSERT INTO Page (ScopeId, LeftChild, RightChild, Title) VALUES (1, 48,85,'courses')");
+		$dbh->exec("INSERT INTO Page (ScopeId, LeftChild, RightChild, Title) VALUES (1, 98,101,'contact')");
+		$dbh->exec("INSERT INTO Page (ScopeId, LeftChild, RightChild, Title) VALUES (1, 10,11,'entrance')");
+		$dbh->exec("INSERT INTO Page (ScopeId, LeftChild, RightChild, Title) VALUES (1, 104,191,'intra')");
+		$dbh->exec("INSERT INTO Page (ScopeId, LeftChild, RightChild, Title) VALUES (1, 102,103,'services')");
+		$dbh->exec("INSERT INTO Page (ScopeId, LeftChild, RightChild, Title) VALUES (1, 12,13,'competency')");
+		$dbh->exec("INSERT INTO Page (ScopeId, LeftChild, RightChild, Title) VALUES (1, 15,22,'watchkeeping-officer')");
+		$dbh->exec("INSERT INTO Page (ScopeId, LeftChild, RightChild, Title) VALUES (1, 16,17,'education')");
+		$dbh->exec("INSERT INTO Page (ScopeId, LeftChild, RightChild, Title) VALUES (1, 18,19,'entrance')");
+		$dbh->exec("INSERT INTO Page (ScopeId, LeftChild, RightChild, Title) VALUES (1, 20,21,'competency')");
+		$dbh->exec("INSERT INTO Page (ScopeId, LeftChild, RightChild, Title) VALUES (1, 31,38,'watchkeeping-engineer')");
+		$dbh->exec("INSERT INTO Page (ScopeId, LeftChild, RightChild, Title) VALUES (1, 32,33,'education')");
+		$dbh->exec("INSERT INTO Page (ScopeId, LeftChild, RightChild, Title) VALUES (1, 34,35,'entrance')");
+		$dbh->exec("INSERT INTO Page (ScopeId, LeftChild, RightChild, Title) VALUES (1, 36,37,'competency')");
+		$dbh->exec("INSERT INTO Page (ScopeId, LeftChild, RightChild, Title) VALUES (1, 39,40,'practice')");
+		$dbh->exec("INSERT INTO Page (ScopeId, LeftChild, RightChild, Title) VALUES (1, 86,97,'news')");
+		$dbh->exec("INSERT INTO Page (ScopeId, LeftChild, RightChild, Title) VALUES (1, 95,96,'2007-02')");
+		$dbh->exec("INSERT INTO Page (ScopeId, LeftChild, RightChild, Title) VALUES (1, 99,100,'personnel')");
+		$dbh->exec("INSERT INTO Page (ScopeId, LeftChild, RightChild, Title) VALUES (1, 87,88,'2007-06')");
+		$dbh->exec("INSERT INTO Page (ScopeId, LeftChild, RightChild, Title) VALUES (1, 49,50,'nautical')");
+		$dbh->exec("INSERT INTO Page (ScopeId, LeftChild, RightChild, Title) VALUES (1, 51,52,'radiotechnical')");
+		$dbh->exec("INSERT INTO Page (ScopeId, LeftChild, RightChild, Title) VALUES (1, 53,54,'resourcemgmt')");
+		$dbh->exec("INSERT INTO Page (ScopeId, LeftChild, RightChild, Title) VALUES (1, 57,58,'safety')");
+		$dbh->exec("INSERT INTO Page (ScopeId, LeftChild, RightChild, Title) VALUES (1, 59,60,'firstaid')");
+		$dbh->exec("INSERT INTO Page (ScopeId, LeftChild, RightChild, Title) VALUES (1, 61,62,'sar')");
+		$dbh->exec("INSERT INTO Page (ScopeId, LeftChild, RightChild, Title) VALUES (1, 67,84,'upcoming')");
+		$dbh->exec("INSERT INTO Page (ScopeId, LeftChild, RightChild, Title) VALUES (1, 65,66,'languages')");
+		$dbh->exec("INSERT INTO Page (ScopeId, LeftChild, RightChild, Title) VALUES (1, 55,56,'cargomgmt')");
+		$dbh->exec("INSERT INTO Page (ScopeId, LeftChild, RightChild, Title) VALUES (1, 119,120,'timetable')");
+		$dbh->exec("INSERT INTO Page (ScopeId, LeftChild, RightChild, Title) VALUES (1, 63,64,'boaters')");
+		$dbh->exec("INSERT INTO Page (ScopeId, LeftChild, RightChild, Title) VALUES (1, 105,118,'bulletinboard')");
+		$dbh->exec("INSERT INTO Page (ScopeId, LeftChild, RightChild, Title) VALUES (1, 106,107,'sdf')");
+		$dbh->exec("INSERT INTO Page (ScopeId, LeftChild, RightChild, Title) VALUES (1, 41,42,'fristaende')");
+		$dbh->exec("INSERT INTO Page (ScopeId, LeftChild, RightChild, Title) VALUES (1, 23,30,'ingenj')");
+		$dbh->exec("INSERT INTO Page (ScopeId, LeftChild, RightChild, Title) VALUES (1, 24,25,'utbildn')");
+		$dbh->exec("INSERT INTO Page (ScopeId, LeftChild, RightChild, Title) VALUES (1, 26,27,'ansokn')");
+		$dbh->exec("INSERT INTO Page (ScopeId, LeftChild, RightChild, Title) VALUES (1, 93,94,'utexaminerade')");
+		$dbh->exec("INSERT INTO Page (ScopeId, LeftChild, RightChild, Title) VALUES (1, 89,92,'Massan')");
+		$dbh->exec("INSERT INTO Page (ScopeId, LeftChild, RightChild, Title) VALUES (1, 192,193,'lankar')");
+		$dbh->exec("INSERT INTO Page (ScopeId, LeftChild, RightChild, Title) VALUES (1, 68,69,'FRB')");
+		$dbh->exec("INSERT INTO Page (ScopeId, LeftChild, RightChild, Title) VALUES (1, 70,71,'pelastautumis')");
+		$dbh->exec("INSERT INTO Page (ScopeId, LeftChild, RightChild, Title) VALUES (1, 72,73,'CCM')");
+		$dbh->exec("INSERT INTO Page (ScopeId, LeftChild, RightChild, Title) VALUES (1, 74,75,'sjukvard')");
+		$dbh->exec("INSERT INTO Page (ScopeId, LeftChild, RightChild, Title) VALUES (1, 121,188,'Veckoscheman')");
+		$dbh->exec("INSERT INTO Page (ScopeId, LeftChild, RightChild, Title) VALUES (1, 134,135,'VS3VSVsjukv')");
+		$dbh->exec("INSERT INTO Page (ScopeId, LeftChild, RightChild, Title) VALUES (1, 122,123,'sjoarb')");
+		$dbh->exec("INSERT INTO Page (ScopeId, LeftChild, RightChild, Title) VALUES (1, 130,131,'fysik1')");
+		$dbh->exec("INSERT INTO Page (ScopeId, LeftChild, RightChild, Title) VALUES (1, 140,141,'kemi')");
+		$dbh->exec("INSERT INTO Page (ScopeId, LeftChild, RightChild, Title) VALUES (1, 76,77,'inr')");
+		$dbh->exec("INSERT INTO Page (ScopeId, LeftChild, RightChild, Title) VALUES (1, 78,79,'forare')");
+		$dbh->exec("INSERT INTO Page (ScopeId, LeftChild, RightChild, Title) VALUES (1, 144,145,'AlexandraYH2')");
+		$dbh->exec("INSERT INTO Page (ScopeId, LeftChild, RightChild, Title) VALUES (1, 132,133,'AlexandraVS2')");
+		$dbh->exec("INSERT INTO Page (ScopeId, LeftChild, RightChild, Title) VALUES (1, 80,81,'Maskin')");
+		$dbh->exec("INSERT INTO Page (ScopeId, LeftChild, RightChild, Title) VALUES (1, 126,127,'forstahjalp')");
+		$dbh->exec("INSERT INTO Page (ScopeId, LeftChild, RightChild, Title) VALUES (1, 136,137,'Juridik')");
+		$dbh->exec("INSERT INTO Page (ScopeId, LeftChild, RightChild, Title) VALUES (1, 142,143,'mate')");
+		$dbh->exec("INSERT INTO Page (ScopeId, LeftChild, RightChild, Title) VALUES (1, 82,83,'basic')");
+		$dbh->exec("INSERT INTO Page (ScopeId, LeftChild, RightChild, Title) VALUES (1, 124,125,'mask')");
+		$dbh->exec("INSERT INTO Page (ScopeId, LeftChild, RightChild, Title) VALUES (1, 108,109,'magnus')");
+		$dbh->exec("INSERT INTO Page (ScopeId, LeftChild, RightChild, Title) VALUES (1, 138,139,'sjosakerhet')");
+		$dbh->exec("INSERT INTO Page (ScopeId, LeftChild, RightChild, Title) VALUES (1, 28,29,'pate')");
+		$dbh->exec("INSERT INTO Page (ScopeId, LeftChild, RightChild, Title) VALUES (1, 148,149,'eng')");
+		$dbh->exec("INSERT INTO Page (ScopeId, LeftChild, RightChild, Title) VALUES (1, 146,147,'forstahjalpYH1')");
+		$dbh->exec("INSERT INTO Page (ScopeId, LeftChild, RightChild, Title) VALUES (1, 110,111,'kortoverlevnadskurs')");
+		$dbh->exec("INSERT INTO Page (ScopeId, LeftChild, RightChild, Title) VALUES (1, 158,159,'kortoverlevnadskurs')");
+		$dbh->exec("INSERT INTO Page (ScopeId, LeftChild, RightChild, Title) VALUES (1, 128,129,'metall')");
+		$dbh->exec("INSERT INTO Page (ScopeId, LeftChild, RightChild, Title) VALUES (1, 152,153,'fysik')");
+		$dbh->exec("INSERT INTO Page (ScopeId, LeftChild, RightChild, Title) VALUES (1, 156,157,'fardplan')");
+		$dbh->exec("INSERT INTO Page (ScopeId, LeftChild, RightChild, Title) VALUES (1, 154,155,'astro')");
+		$dbh->exec("INSERT INTO Page (ScopeId, LeftChild, RightChild, Title) VALUES (1, 90,91,'utstallare')");
+		$dbh->exec("INSERT INTO Page (ScopeId, LeftChild, RightChild, Title) VALUES (1, 150,151,'eng')");
+		$dbh->exec("INSERT INTO Page (ScopeId, LeftChild, RightChild, Title) VALUES (1, 160,161,'ent')");
+		$dbh->exec("INSERT INTO Page (ScopeId, LeftChild, RightChild, Title) VALUES (1, 162,163,'juridik')");
+		$dbh->exec("INSERT INTO Page (ScopeId, LeftChild, RightChild, Title) VALUES (1, 168,169,'svenska')");
+		$dbh->exec("INSERT INTO Page (ScopeId, LeftChild, RightChild, Title) VALUES (1, 164,165,'matemat')");
+		$dbh->exec("INSERT INTO Page (ScopeId, LeftChild, RightChild, Title) VALUES (1, 166,167,'operativa')");
+		$dbh->exec("INSERT INTO Page (ScopeId, LeftChild, RightChild, Title) VALUES (1, 170,171,'plan')");
+		$dbh->exec("INSERT INTO Page (ScopeId, LeftChild, RightChild, Title) VALUES (1, 172,173,'src')");
+		$dbh->exec("INSERT INTO Page (ScopeId, LeftChild, RightChild, Title) VALUES (1, 112,113,'sjukv')");
+		$dbh->exec("INSERT INTO Page (ScopeId, LeftChild, RightChild, Title) VALUES (1, 174,175,'matemati')");
+		$dbh->exec("INSERT INTO Page (ScopeId, LeftChild, RightChild, Title) VALUES (1, 176,177,'fysiikka')");
+		$dbh->exec("INSERT INTO Page (ScopeId, LeftChild, RightChild, Title) VALUES (1, 114,115,'hantv')");
+		$dbh->exec("INSERT INTO Page (ScopeId, LeftChild, RightChild, Title) VALUES (1, 116,117,'CCM')");
+		$dbh->exec("INSERT INTO Page (ScopeId, LeftChild, RightChild, Title) VALUES (1, 178,179,'haveri')");
+		$dbh->exec("INSERT INTO Page (ScopeId, LeftChild, RightChild, Title) VALUES (1, 180,181,'FRB')");
+		$dbh->exec("INSERT INTO Page (ScopeId, LeftChild, RightChild, Title) VALUES (1, 182,183,'kemia')");
+		$dbh->exec("INSERT INTO Page (ScopeId, LeftChild, RightChild, Title) VALUES (1, 184,185,'vaktrutiner')");
+		$dbh->exec("INSERT INTO Page (ScopeId, LeftChild, RightChild, Title) VALUES (1, 189,190,'laroplan')");
+		$dbh->exec("INSERT INTO Page (ScopeId, LeftChild, RightChild, Title) VALUES (1, 186,187,'SSOkurs')");
+	}
+
+	public static function depopulate()
+	{
+		$dbh = Propel::getConnection(PagePeer::DATABASE_NAME);
+		$dbh->exec("DELETE FROM Page");
+	}
+
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/test/classes/cms/CmsTestBase.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/test/classes/cms/CmsTestBase.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/test/classes/cms/CmsTestBase.php	(revision 19)
@@ -0,0 +1,50 @@
+<?php
+/*
+ *  $Id: CmsTestBase.php 875 2007-12-19 11:10:15Z heltem $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://propel.phpdb.org>.
+ */
+
+require_once 'PHPUnit/Framework/TestCase.php';
+include_once 'cms/CmsDataPopulator.php';
+
+/**
+ * Base class contains some methods shared by subclass test cases.
+ */
+abstract class CmsTestBase extends PHPUnit_Framework_TestCase {
+
+	/**
+	 * This is run before each unit test; it populates the database.
+	 */
+	protected function setUp()
+	{
+		parent::setUp();
+		CmsDataPopulator::depopulate();
+		CmsDataPopulator::populate();
+	}
+
+	/**
+	 * This is run after each unit test.  It empties the database.
+	 */
+	protected function tearDown()
+	{
+
+		CmsDataPopulator::depopulate();
+		parent::tearDown();
+	}
+
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/test/classes/propel/BaseTestCase.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/test/classes/propel/BaseTestCase.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/test/classes/propel/BaseTestCase.php	(revision 19)
@@ -0,0 +1,22 @@
+<?php
+
+require_once 'propel/Propel.php';
+require_once 'PHPUnit/Framework/TestCase.php';
+
+/**
+ * Base functionality to be extended by all Propel test cases.  Test
+ * case implementations are used to automate unit testing via PHPUnit.
+ *
+ * @author     Hans Lellelid <hans@xmpl.org> (Propel)
+ * @author     Daniel Rall <dlr@finemaltcoding.com> (Torque)
+ * @author     Christopher Elkins <celkins@scardini.com> (Torque)
+ * @version    $Revision: 752 $
+ */
+abstract class BaseTestCase extends PHPUnit_Framework_TestCase {
+
+	/**
+	 * Conditional compilation flag.
+	 */
+	const DEBUG = false;
+
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/test/classes/propel/CharacterEncodingTest.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/test/classes/propel/CharacterEncodingTest.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/test/classes/propel/CharacterEncodingTest.php	(revision 19)
@@ -0,0 +1,118 @@
+<?php
+/*
+ *  $Id: GeneratedPeerTest.php 842 2007-12-02 16:28:20Z heltem $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://propel.phpdb.org>.
+ */
+
+require_once 'bookstore/BookstoreTestBase.php';
+
+/**
+ * Tests the character encoding support of the adapter.
+ *
+ * This test assumes that the created database supports UTF-8.  For this to work,
+ * this file also has to be UTF-8.
+ *
+ * The database is relaoded before every test and flushed after every test.  This
+ * means that you can always rely on the contents of the databases being the same
+ * for each test method in this class.  See the BookstoreDataPopulator::populate()
+ * method for the exact contents of the database.
+ *
+ * @see        BookstoreDataPopulator
+ * @author     Hans Lellelid <hans@xmpl.org>
+ */
+class CharacterEncodingTest extends BookstoreTestBase {
+
+	/**
+	 * Database adapter.
+	 * @var        DBAdapter
+	 */
+	private $adapter;
+
+	public function setUp()
+	{
+		parent::setUp();
+		if (!extension_loaded('iconv')) {
+			throw new Exception("Character-encoding tests require iconv extension to be loaded.");
+		}
+	}
+
+	public function testUtf8()
+	{
+		$db = Propel::getDB(BookPeer::DATABASE_NAME);
+
+		$title = "Ð¡ÐŒÐµÑÑÑ ÐœÐ° Ð±ÑÑÐŽÐµÑÑÐ°ÑÑ. ÐÐ»Ð°ÐŽÐµÐœÐµÑ Ðž ÑÐµÑÑ";
+		//        1234567890123456789012345678901234567
+		//                 1         2         3
+
+		$a = new Author();
+		$a->setFirstName("Ð.");
+		$a->setLastName("ÐÐÐ£ÐÐÐ");
+
+		$p = new Publisher();
+		$p->setName("ÐÐµÑÐµÐºÑÐžÐ² ÑÐŸÑÑÐžÐ¹ÑÐºÐžÐ¹, ÐŸÑÑÑÐŸÑÑÐ¶ÐµÑÐœÐ°Ñ Ð¿ÑÐŸÐ·Ð°");
+
+		$b = new Book();
+		$b->setTitle($title);
+		$b->setISBN("B-59246");
+		$b->setAuthor($a);
+		$b->setPublisher($p);
+		$b->save();
+
+		$b->reload();
+
+		$this->assertEquals(37, iconv_strlen($b->getTitle(), 'utf-8'), "Expected 37 characters (not bytes) in title.");
+		$this->assertTrue(strlen($b->getTitle()) > iconv_strlen($b->getTitle(), 'utf-8'), "Expected more bytes than characters in title.");
+
+	}
+
+	public function testInvalidCharset()
+	{
+		$db = Propel::getDB(BookPeer::DATABASE_NAME);
+		if ($db instanceof DBSQLite) {
+			$this->markTestSkipped();
+		}
+
+		$a = new Author();
+		$a->setFirstName("Ð.");
+		$a->setLastName("ÐÐÐ£ÐÐÐ");
+		$a->save();
+
+		$authorNameWindows1251 = iconv("utf-8", "windows-1251", $a->getLastName());
+		$a->setLastName($authorNameWindows1251);
+
+		// Different databases seem to handle invalid data differently (no surprise, I guess...)
+		if ($db instanceof DBPostgres) {
+			try {
+				$a->save();
+				$this->fail("Expected an exception when saving non-UTF8 data to database.");
+			} catch (Exception $x) {
+				print $x;
+			}
+
+		} else {
+
+			// No exception is thrown by MySQL ... (others need to be tested still)
+			$a->save();
+			$a->reload();
+
+			$this->assertEquals("",$a->getLastName(), "Expected last_name to be empty (after inserting invalid charset data)");
+		}
+
+	}
+
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/test/classes/propel/FieldnameRelatedTest.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/test/classes/propel/FieldnameRelatedTest.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/test/classes/propel/FieldnameRelatedTest.php	(revision 19)
@@ -0,0 +1,398 @@
+<?php
+/*
+ *  $Id: FieldnameRelatedTest.php 752 2007-11-03 17:19:19Z hans $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://propel.phpdb.org>.
+ */
+
+require_once 'PHPUnit/Framework/TestCase.php';
+require_once 'bookstore/BookstoreTestBase.php';
+
+/**
+ * Tests some of the methods of generated Object classes. These are:
+ *
+ * - Base[Object]Peer::getFieldNames()
+ * - Base[Object]Peer::translateFieldName()
+ * - BasePeer::getFieldNames()
+ * - BasePeer::translateFieldName()
+ * - Base[Object]::getByName()
+ * - Base[Object]::setByName()
+ * - Base[Object]::fromArray()
+ * - Base[Object]::toArray()
+ *
+ * I've pulled these tests from the GeneratedObjectTest because the don't
+ * need the BookstoreTestBase's setUp and tearDown (database de/population)
+ * behaviour. The tests will run faster this way.
+ *
+ * @author     Sven Fuchs <svenfuchs@artweb-design.de>
+ */
+class FieldnameRelatedTest extends PHPUnit_Framework_TestCase {
+
+	/**
+	 * Tests if fieldname type constants are defined
+	 */
+	public function testFieldNameTypeConstants () {
+
+		$result = defined('BasePeer::TYPE_PHPNAME');
+		$this->assertTrue($result);
+	}
+
+	/**
+	 * Tests the Base[Object]Peer::getFieldNames() method
+	 */
+	public function testGetFieldNames () {
+
+		$types = array(
+			BasePeer::TYPE_PHPNAME,
+			BasePeer::TYPE_COLNAME,
+			BasePeer::TYPE_FIELDNAME,
+			BasePeer::TYPE_NUM
+		);
+		$expecteds = array (
+			BasePeer::TYPE_PHPNAME => array(
+				0 => 'Id',
+				1 => 'Title',
+				2 => 'ISBN',
+				3 => 'Price',
+				4 => 'PublisherId',
+				5 => 'AuthorId'
+			),
+			BasePeer::TYPE_STUDLYPHPNAME => array(
+				0 => 'id',
+				1 => 'title',
+				2 => 'iSBN',
+				3 => 'price',
+				4 => 'publisherId',
+				5 => 'authorId'
+			),
+			BasePeer::TYPE_COLNAME => array(
+				0 => 'book.ID',
+				1 => 'book.TITLE',
+				2 => 'book.ISBN',
+				3 => 'book.PRICE',
+				4 => 'book.PUBLISHER_ID',
+				5 => 'book.AUTHOR_ID'
+			),
+			BasePeer::TYPE_FIELDNAME => array(
+				0 => 'id',
+				1 => 'title',
+				2 => 'isbn',
+				3 => 'price',
+				4 => 'publisher_id',
+				5 => 'author_id'
+			),
+			BasePeer::TYPE_NUM => array(
+				0 => 0,
+				1 => 1,
+				2 => 2,
+				3 => 3,
+				4 => 4,
+				5 => 5
+			)
+		);
+
+		foreach ($types as $type) {
+			$results[$type] = BookPeer::getFieldnames($type);
+			$this->assertEquals(
+				$expecteds[$type],
+				$results[$type],
+				'expected was: ' . print_r($expecteds[$type], 1) .
+				'but getFieldnames() returned ' . print_r($results[$type], 1)
+			);
+		}
+	}
+
+	/**
+	 * Tests the Base[Object]Peer::translateFieldName() method
+	 */
+	public function testTranslateFieldName () {
+
+		$types = array(
+			BasePeer::TYPE_PHPNAME,
+			BasePeer::TYPE_STUDLYPHPNAME,
+			BasePeer::TYPE_COLNAME,
+			BasePeer::TYPE_FIELDNAME,
+			BasePeer::TYPE_NUM
+		);
+		$expecteds = array (
+			BasePeer::TYPE_PHPNAME => 'AuthorId',
+			BasePeer::TYPE_STUDLYPHPNAME => 'authorId',
+			BasePeer::TYPE_COLNAME => 'book.AUTHOR_ID',
+			BasePeer::TYPE_FIELDNAME => 'author_id',
+			BasePeer::TYPE_NUM => 5,
+		);
+		foreach ($types as $fromType) {
+			foreach ($types as $toType) {
+				$name = $expecteds[$fromType];
+				$expected = $expecteds[$toType];
+				$result = BookPeer::translateFieldName($name, $fromType, $toType);
+				$this->assertEquals($expected, $result);
+			}
+		}
+	}
+
+	/**
+	 * Tests the BasePeer::getFieldNames() method
+	 */
+	public function testGetFieldNamesStatic () {
+
+		$types = array(
+			BasePeer::TYPE_PHPNAME,
+			BasePeer::TYPE_STUDLYPHPNAME,
+			BasePeer::TYPE_COLNAME,
+			BasePeer::TYPE_FIELDNAME,
+			BasePeer::TYPE_NUM
+		);
+		$expecteds = array (
+			BasePeer::TYPE_PHPNAME => array(
+				0 => 'Id',
+				1 => 'Title',
+				2 => 'ISBN',
+				3 => 'Price',
+				4 => 'PublisherId',
+				5 => 'AuthorId'
+			),
+			BasePeer::TYPE_STUDLYPHPNAME => array(
+				0 => 'id',
+				1 => 'title',
+				2 => 'iSBN',
+				3 => 'price',
+				4 => 'publisherId',
+				5 => 'authorId'
+			),
+			BasePeer::TYPE_COLNAME => array(
+				0 => 'book.ID',
+				1 => 'book.TITLE',
+				2 => 'book.ISBN',
+				3 => 'book.PRICE',
+				4 => 'book.PUBLISHER_ID',
+				5 => 'book.AUTHOR_ID'
+			),
+			BasePeer::TYPE_FIELDNAME => array(
+				0 => 'id',
+				1 => 'title',
+				2 => 'isbn',
+				3 => 'price',
+				4 => 'publisher_id',
+				5 => 'author_id'
+			),
+			BasePeer::TYPE_NUM => array(
+				0 => 0,
+				1 => 1,
+				2 => 2,
+				3 => 3,
+				4 => 4,
+				5 => 5
+			)
+		);
+
+		foreach ($types as $type) {
+			$results[$type] = BasePeer::getFieldnames('Book', $type);
+			$this->assertEquals(
+				$expecteds[$type],
+				$results[$type],
+				'expected was: ' . print_r($expecteds[$type], 1) .
+				'but getFieldnames() returned ' . print_r($results[$type], 1)
+			);
+		}
+	}
+
+	/**
+	 * Tests the BasePeer::translateFieldName() method
+	 */
+	public function testTranslateFieldNameStatic () {
+
+		$types = array(
+			BasePeer::TYPE_PHPNAME,
+			BasePeer::TYPE_STUDLYPHPNAME,
+			BasePeer::TYPE_COLNAME,
+			BasePeer::TYPE_FIELDNAME,
+			BasePeer::TYPE_NUM
+		);
+		$expecteds = array (
+			BasePeer::TYPE_PHPNAME => 'AuthorId',
+			BasePeer::TYPE_STUDLYPHPNAME => 'authorId',
+			BasePeer::TYPE_COLNAME => 'book.AUTHOR_ID',
+			BasePeer::TYPE_FIELDNAME => 'author_id',
+			BasePeer::TYPE_NUM => 5,
+		);
+		foreach ($types as $fromType) {
+			foreach ($types as $toType) {
+				$name = $expecteds[$fromType];
+				$expected = $expecteds[$toType];
+				$result = BasePeer::translateFieldName('Book', $name, $fromType, $toType);
+				$this->assertEquals($expected, $result);
+			}
+		}
+	}
+
+	/**
+	 * Tests the Base[Object]::getByName() method
+	 */
+	public function testGetByName() {
+
+		$types = array(
+			BasePeer::TYPE_PHPNAME => 'Title',
+			BasePeer::TYPE_STUDLYPHPNAME => 'title',
+			BasePeer::TYPE_COLNAME => 'book.TITLE',
+			BasePeer::TYPE_FIELDNAME => 'title',
+			BasePeer::TYPE_NUM => 1
+		);
+
+		$book = new Book();
+		$book->setTitle('Harry Potter and the Order of the Phoenix');
+
+		$expected = 'Harry Potter and the Order of the Phoenix';
+		foreach ($types as $type => $name) {
+			$result = $book->getByName($name, $type);
+			$this->assertEquals($expected, $result);
+		}
+	}
+
+	/**
+	 * Tests the Base[Object]::setByName() method
+	 */
+	public function testSetByName() {
+
+		$book = new Book();
+		$types = array(
+			BasePeer::TYPE_PHPNAME => 'Title',
+			BasePeer::TYPE_STUDLYPHPNAME => 'title',
+			BasePeer::TYPE_COLNAME => 'book.TITLE',
+			BasePeer::TYPE_FIELDNAME => 'title',
+			BasePeer::TYPE_NUM => 1
+		);
+
+		$title = 'Harry Potter and the Order of the Phoenix';
+		foreach ($types as $type => $name) {
+			$book->setByName($name, $title, $type);
+			$result = $book->getTitle();
+			$this->assertEquals($title, $result);
+		}
+	}
+
+	/**
+	 * Tests the Base[Object]::fromArray() method
+	 *
+	 * this also tests populateFromArray() because that's an alias
+	 */
+	public function testFromArray(){
+
+		$types = array(
+			BasePeer::TYPE_PHPNAME,
+			BasePeer::TYPE_STUDLYPHPNAME,
+			BasePeer::TYPE_COLNAME,
+			BasePeer::TYPE_FIELDNAME,
+			BasePeer::TYPE_NUM
+		);
+		$expecteds = array (
+			BasePeer::TYPE_PHPNAME => array (
+				'Title' => 'Harry Potter and the Order of the Phoenix',
+				'ISBN' => '043935806X'
+			),
+			BasePeer::TYPE_STUDLYPHPNAME => array (
+				'title' => 'Harry Potter and the Order of the Phoenix',
+				'iSBN' => '043935806X'
+			),
+			BasePeer::TYPE_COLNAME => array (
+				'book.TITLE' => 'Harry Potter and the Order of the Phoenix',
+				'book.ISBN' => '043935806X'
+			),
+			BasePeer::TYPE_FIELDNAME => array (
+				'title' => 'Harry Potter and the Order of the Phoenix',
+				'isbn' => '043935806X'
+			),
+			BasePeer::TYPE_NUM => array (
+				'1' => 'Harry Potter and the Order of the Phoenix',
+				'2' => '043935806X'
+			)
+		);
+
+		$book = new Book();
+
+		foreach ($types as $type) {
+			$expected = $expecteds[$type];
+			$book->fromArray($expected, $type);
+			$result = array();
+			foreach (array_keys($expected) as $key) {
+				$result[$key] = $book->getByName($key, $type);
+			}
+			$this->assertEquals(
+				$expected,
+				$result,
+				'expected was: ' . print_r($expected, 1) .
+				'but fromArray() returned ' . print_r($result, 1)
+			);
+		}
+	}
+
+	/**
+	 * Tests the Base[Object]::toArray() method
+	 */
+	public function testToArray(){
+
+		$types = array(
+			BasePeer::TYPE_PHPNAME,
+			BasePeer::TYPE_STUDLYPHPNAME,
+			BasePeer::TYPE_COLNAME,
+			BasePeer::TYPE_FIELDNAME,
+			BasePeer::TYPE_NUM
+		);
+
+		$book = new Book();
+		$book->fromArray(array (
+			'Title' => 'Harry Potter and the Order of the Phoenix',
+			'ISBN' => '043935806X'
+		));
+
+		$expecteds = array (
+			BasePeer::TYPE_PHPNAME => array (
+				'Title' => 'Harry Potter and the Order of the Phoenix',
+				'ISBN' => '043935806X'
+			),
+			BasePeer::TYPE_STUDLYPHPNAME => array (
+				'title' => 'Harry Potter and the Order of the Phoenix',
+				'iSBN' => '043935806X'
+			),
+			BasePeer::TYPE_COLNAME => array (
+				'book.TITLE' => 'Harry Potter and the Order of the Phoenix',
+				'book.ISBN' => '043935806X'
+			),
+			BasePeer::TYPE_FIELDNAME => array (
+				'title' => 'Harry Potter and the Order of the Phoenix',
+				'isbn' => '043935806X'
+			),
+			BasePeer::TYPE_NUM => array (
+				'1' => 'Harry Potter and the Order of the Phoenix',
+				'2' => '043935806X'
+			)
+		);
+
+		foreach ($types as $type) {
+			$expected = $expecteds[$type];
+			$result = $book->toArray($type);
+			// remove ID since its autoincremented at each test iteration
+			$result = array_slice($result, 1, 2, true);
+			$this->assertEquals(
+				$expected,
+				$result,
+				'expected was: ' . print_r($expected, 1) .
+				'but toArray() returned ' . print_r($result, 1)
+			);
+		}
+	}
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/test/classes/propel/GeneratedNestedSetObjectTest.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/test/classes/propel/GeneratedNestedSetObjectTest.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/test/classes/propel/GeneratedNestedSetObjectTest.php	(revision 19)
@@ -0,0 +1,157 @@
+<?php
+/*
+ *  $Id: GeneratedNestedSetObjectTest.php 894 2007-12-27 14:39:01Z heltem $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://propel.phpdb.org>.
+ */
+
+require_once 'cms/CmsTestBase.php';
+
+/**
+ * Tests the generated nested-set Object classes.
+ *
+ * This test uses generated Bookstore-Cms classes to test the behavior of various
+ * object operations.  The _idea_ here is to test every possible generated method
+ * from Object.tpl; if necessary, bookstore will be expanded to accommodate this.
+ *
+ * The database is relaoded before every test and flushed after every test.  This
+ * means that you can always rely on the contents of the databases being the same
+ * for each test method in this class.  See the CmsDataPopulator::populate()
+ * method for the exact contents of the database.
+ *
+ * @see        CmsDataPopulator
+ */
+class GeneratedNestedSetObjectTest extends CmsTestBase {
+
+	/**
+	 * Test xxxNestedSet::isRoot() as true
+	 */
+	public function testObjectIsRootTrue()
+	{
+		$pp = PagePeer::retrieveRoot(1);
+		$this->assertTrue($pp->isRoot(), 'Node must be root');
+	}
+
+	/**
+	 * Test xxxNestedSet::isRoot() as false
+	 */
+	public function testObjectIsRootFalse()
+	{
+		$c = new Criteria(PagePeer::DATABASE_NAME);
+		$c->add(PagePeer::TITLE, 'school', Criteria::EQUAL);
+
+		$school = PagePeer::doSelectOne($c);
+		$this->assertFalse($school->isRoot(), 'Node must not be root');
+	}
+
+	/**
+	 * Test xxxNestedSet::retrieveParent() as true.
+	 */
+	public function testObjectRetrieveParentTrue()
+	{
+		$c = new Criteria(PagePeer::DATABASE_NAME);
+		$c->add(PagePeer::TITLE, 'school', Criteria::EQUAL);
+
+		$school = PagePeer::doSelectOne($c);
+		$this->assertNotNull($school->retrieveParent(), 'Parent node must exist');
+	}
+
+	/**
+	 * Test xxxNestedSet::retrieveParent() as false.
+	 */
+	public function testObjectRetrieveParentFalse()
+	{
+		$c = new Criteria(PagePeer::DATABASE_NAME);
+		$c->add(PagePeer::TITLE, 'home', Criteria::EQUAL);
+
+		$home = PagePeer::doSelectOne($c);
+		$this->assertNull($home->retrieveParent(), 'Parent node must not exist and retrieved not be null');
+	}
+
+	/**
+	 * Test xxxNestedSet::hasParent() as true.
+	 */
+	public function testObjectHasParentTrue()
+	{
+		$c = new Criteria();
+		$c->add(PagePeer::TITLE, 'school', Criteria::EQUAL);
+
+		$school = PagePeer::doSelectOne($c);
+		$this->assertTrue($school->hasParent(), 'Node must have parent node');
+	}
+
+	/**
+	 * Test xxxNestedSet::hasParent() as false
+	 */
+	public function testObjectHasParentFalse()
+	{
+		$c = new Criteria();
+		$c->add(PagePeer::TITLE, 'home', Criteria::EQUAL);
+
+		$home = PagePeer::doSelectOne($c);
+		$this->assertFalse($home->hasParent(), 'Root node must not have parent');
+	}
+
+	/**
+	 * Test xxxNestedSet::isLeaf() as true.
+	 */
+	public function testObjectIsLeafTrue()
+	{
+		$c = new Criteria();
+		$c->add(PagePeer::TITLE, 'simulator', Criteria::EQUAL);
+
+		$simulator = PagePeer::doSelectOne($c);
+		$this->assertTrue($simulator->isLeaf($simulator), 'Node must be a leaf');
+	}
+
+	/**
+	 * Test xxxNestedSet::isLeaf() as false
+	 */
+	public function testObjectIsLeafFalse()
+	{
+		$c = new Criteria();
+		$c->add(PagePeer::TITLE, 'contact', Criteria::EQUAL);
+
+		$contact = PagePeer::doSelectOne($c);
+		$this->assertFalse($contact->isLeaf($contact), 'Node must not be a leaf');
+	}
+
+	/**
+	 * Test xxxNestedSet::makeRoot()
+	 */
+	public function testObjectMakeRoot()
+	{
+		$page = new Page();
+		$page->makeRoot();
+		$this->assertEquals(1, $page->getLeftValue(), 'Node left value must equal 1');
+		$this->assertEquals(2, $page->getRightValue(), 'Node right value must equal 2');
+	}
+
+	/**
+	 * Test xxxNestedSet::makeRoot() exception
+	 * @expectedException PropelException
+	 */
+	public function testObjectMakeRootException()
+	{
+		$c = new Criteria();
+		$c->add(PagePeer::TITLE, 'home', Criteria::EQUAL);
+
+		$home = PagePeer::doSelectOne($c);
+		$home->makeRoot();
+	}
+
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/test/classes/propel/GeneratedNestedSetPeerTest.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/test/classes/propel/GeneratedNestedSetPeerTest.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/test/classes/propel/GeneratedNestedSetPeerTest.php	(revision 19)
@@ -0,0 +1,198 @@
+<?php
+/*
+ *  $Id: GeneratedNestedSetPeerTest.php 989 2008-03-11 14:29:30Z heltem $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://propel.phpdb.org>.
+ */
+
+require_once 'cms/CmsTestBase.php';
+
+/**
+ * Tests the generated nested-set Object classes.
+ *
+ * This test uses generated Bookstore-Cms classes to test the behavior of various
+ * object operations.  The _idea_ here is to test every possible generated method
+ * from Object.tpl; if necessary, bookstore will be expanded to accommodate this.
+ *
+ * The database is relaoded before every test and flushed after every test.  This
+ * means that you can always rely on the contents of the databases being the same
+ * for each test method in this class.  See the CmsDataPopulator::populate()
+ * method for the exact contents of the database.
+ *
+ * @see        CmsDataPopulator
+ */
+class GeneratedNestedSetPeerTest extends CmsTestBase {
+
+	/**
+	 * Test retrieveRoot() as true
+	 */
+	public function testRetrieveRootExist()
+	{
+		$pp = PagePeer::retrieveRoot(1);
+		$this->assertNotNull($pp, 'Node must exist and not be null');
+		$this->assertEquals(1, $pp->getLeftValue(), 'Node left value must be equal to 1');
+	}
+
+	/**
+	 * Test retrieveRoot() as false
+	 */
+	public function testRetrieveRootNotExist()
+	{
+		$pp = PagePeer::retrieveRoot(2);
+		$this->assertNull($pp, 'Root with such scopeId must not exist');
+	}
+
+	/**
+	 * Test xxxNestedSetPeer::isRoot() as true
+	 */
+	public function testPeerIsRootTrue()
+	{
+		$pp = PagePeer::retrieveRoot(1);
+		$this->assertTrue(PagePeer::isRoot($pp), 'Node must be root');
+	}
+
+	/**
+	 * Test xxxNestedSetPeer::isRoot() as false
+	 */
+	public function testPeerIsRootFalse()
+	{
+		$c = new Criteria(PagePeer::DATABASE_NAME);
+		$c->add(PagePeer::TITLE, 'school', Criteria::EQUAL);
+
+		$school = PagePeer::doSelectOne($c);
+		$this->assertFalse(PagePeer::isRoot($school), 'Node must not be root');
+	}
+
+	/**
+	 * Test xxxNestedSetPeer::retrieveParent() as true.
+	 */
+	public function testPeerRetrieveParentTrue()
+	{
+		$c = new Criteria(PagePeer::DATABASE_NAME);
+		$c->add(PagePeer::TITLE, 'school', Criteria::EQUAL);
+
+		$school = PagePeer::doSelectOne($c);
+		$this->assertNotNull(PagePeer::retrieveParent($school), 'Parent node must exist');
+	}
+
+	/**
+	 * Test xxxNestedSetPeer::retrieveParent() as false.
+	 */
+	public function testPeerRetrieveParentFalse()
+	{
+		$c = new Criteria(PagePeer::DATABASE_NAME);
+		$c->add(PagePeer::TITLE, 'home', Criteria::EQUAL);
+
+		$home = PagePeer::doSelectOne($c);
+		$this->assertNull(PagePeer::retrieveParent($home), 'Parent node must not exist and retrieved not be null');
+	}
+
+	/**
+	 * Test xxxNestedSetPeer::hasParent() as true.
+	 */
+	public function testPeerHasParentTrue()
+	{
+		$c = new Criteria();
+		$c->add(PagePeer::TITLE, 'school', Criteria::EQUAL);
+
+		$school = PagePeer::doSelectOne($c);
+		$this->assertTrue(PagePeer::hasParent($school), 'Node must have parent node');
+	}
+
+	/**
+	 * Test xxxNestedSetPeer::hasParent() as false
+	 */
+	public function testPeerHasParentFalse()
+	{
+		$c = new Criteria();
+		$c->add(PagePeer::TITLE, 'home', Criteria::EQUAL);
+
+		$home = PagePeer::doSelectOne($c);
+		$this->assertFalse(PagePeer::hasParent($home), 'Root node must not have parent');
+	}
+
+	/**
+	 * Test xxxNestedSetPeer::isValid() as true.
+	 */
+	public function testPeerIsValidTrue()
+	{
+		$c = new Criteria();
+		$c->add(PagePeer::TITLE, 'school', Criteria::EQUAL);
+
+		$school = PagePeer::doSelectOne($c);
+		$this->assertTrue(PagePeer::isValid($school), 'Node must be valid');
+	}
+
+	/**
+	 * Test xxxNestedSetPeer::isValid() as false
+	 */
+	public function testPeerIsValidFalse()
+	{
+		$page = new Page();
+		$this->assertFalse(PagePeer::isValid($page), 'Node left and right values must be invalid');
+		$this->assertFalse(PagePeer::isValid(null), 'Null must be invalid');
+	}
+
+	/**
+	 * Test xxxNestedSetPeer::isLeaf() as true.
+	 */
+	public function testPeerIsLeafTrue()
+	{
+		$c = new Criteria();
+		$c->add(PagePeer::TITLE, 'simulator', Criteria::EQUAL);
+
+		$simulator = PagePeer::doSelectOne($c);
+		$this->assertTrue(PagePeer::isLeaf($simulator), 'Node must be a leaf');
+	}
+
+	/**
+	 * Test xxxNestedSetPeer::isLeaf() as false
+	 */
+	public function testPeerIsLeafFalse()
+	{
+		$c = new Criteria();
+		$c->add(PagePeer::TITLE, 'contact', Criteria::EQUAL);
+
+		$contact = PagePeer::doSelectOne($c);
+		$this->assertFalse(PagePeer::isLeaf($contact), 'Node must not be a leaf');
+	}
+
+	/**
+	 * Test xxxNestedSetPeer::createRoot()
+	 */
+	public function testPeerCreateRoot()
+	{
+		$page = new Page();
+		PagePeer::createRoot($page);
+		$this->assertEquals(1, $page->getLeftValue(), 'Node left value must equal 1');
+		$this->assertEquals(2, $page->getRightValue(), 'Node right value must equal 2');
+	}
+
+	/**
+	 * Test xxxNestedSetPeer::createRoot() exception
+	 * @expectedException PropelException
+	 */
+	public function testPeerCreateRootException()
+	{
+		$c = new Criteria();
+		$c->add(PagePeer::TITLE, 'home', Criteria::EQUAL);
+
+		$home = PagePeer::doSelectOne($c);
+		PagePeer::createRoot($home);
+	}
+
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/test/classes/propel/GeneratedNestedSetTest.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/test/classes/propel/GeneratedNestedSetTest.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/test/classes/propel/GeneratedNestedSetTest.php	(revision 19)
@@ -0,0 +1,130 @@
+<?php
+/*
+ *  $Id: GeneratedNestedSetTest.php 989 2008-03-11 14:29:30Z heltem $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://propel.phpdb.org>.
+ */
+
+require_once 'cms/CmsTestBase.php';
+
+/**
+ * Tests the generated nested-set Object classes.
+ *
+ * This test uses generated Bookstore-Cms classes to test the behavior of various
+ * object operations.  The _idea_ here is to test every possible generated method
+ * from Object.tpl; if necessary, bookstore will be expanded to accommodate this.
+ *
+ * The database is relaoded before every test and flushed after every test.  This
+ * means that you can always rely on the contents of the databases being the same
+ * for each test method in this class.  See the CmsDataPopulator::populate()
+ * method for the exact contents of the database.
+ *
+ * @see        CmsDataPopulator
+ */
+class GeneratedNestedSetTest extends CmsTestBase {
+
+	/**
+	 * A convenience method to dump the page rows.
+	 */
+	private function showPageItems()
+	{
+		$tree = PagePeer::retrieveTree();
+		$iterator = new RecursiveIteratorIterator($tree, RecursiveIteratorIterator::SELF_FIRST);
+
+		foreach ($iterator as $item) { /* @var        $item Page */
+			echo str_repeat('- ', $iterator->getDepth())
+			, $item->getId() , ': '
+			, $item->getTitle()
+			, ' [', $item->getLeftValue(), ':', $item->getRightValue() , ']'
+			. "\n";
+		}
+	}
+
+	/**
+	 * Adds a new Page row with specified parent Id.
+	 *
+	 * @param      int $parentId
+	 */
+	protected function addNewChildPage($parentId)
+	{
+		$db = Propel::getConnection(PagePeer::DATABASE_NAME);
+
+		//$db->beginTransaction();
+
+		$parent = PagePeer::retrieveByPK($parentId);
+		$page = new Page();
+		$page->setTitle('new page '.time());
+		$page->insertAsLastChildOf($parent);
+		$page->save();
+
+		//$db->commit();
+	}
+
+	/**
+	 * Asserts that the Page table tree integrity is intact.
+	 */
+	protected function assertPageTreeIntegrity()
+	{
+		$db = Propel::getConnection(PagePeer::DATABASE_NAME);
+
+		$values = array();
+		$log = '';
+
+		foreach ($db->query('SELECT Id, LeftChild, RightChild, Title FROM Page', PDO::FETCH_NUM) as $row) {
+
+			list($id, $leftChild, $rightChild, $title) = $row;
+
+			if (!in_array($leftChild, $values)) {
+				$values[] = (int) $leftChild;
+			} else {
+				$this->fail('Duplicate LeftChild value '.$leftChild);
+			}
+
+			if (!in_array($rightChild, $values)) {
+				$values[] = (int) $rightChild;
+			} else {
+				$this->fail('Duplicate RightChild value '.$rightChild);
+			}
+
+			$log .= "[$id($leftChild:$rightChild)]";
+		}
+
+		sort($values);
+
+		if ($values[count($values)-1] != count($values)) {
+			$message = sprintf("Tree integrity NOT ok (%s)\n", $log);
+			$message .= sprintf('Integrity error: value count: %d, high value: %d', count($values), $values[count($values)-1]);
+			$this->fail($message);
+		}
+
+	}
+
+	/**
+	 * Tests adding a node to the Page tree.
+	 */
+	public function testAdd()
+	{
+		$db = Propel::getConnection(PagePeer::DATABASE_NAME);
+
+		// I'm not sure if the specific ID matters, but this should match original
+		// code.  The ID will change with subsequent runs (e.g. the first time it will be 11)
+		$startId = $db->query('SELECT MIN(Id) FROM Page')->fetchColumn();
+		$this->addNewChildPage($startId + 10);
+		$this->assertPageTreeIntegrity();
+	}
+
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/test/classes/propel/GeneratedObjectLobTest.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/test/classes/propel/GeneratedObjectLobTest.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/test/classes/propel/GeneratedObjectLobTest.php	(revision 19)
@@ -0,0 +1,268 @@
+<?php
+/*
+ *  $Id: GeneratedObjectTest.php 928 2008-01-18 12:21:27Z hans $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://propel.phpdb.org>.
+ */
+
+require_once 'bookstore/BookstoreTestBase.php';
+
+/**
+ * Tests the generated Object classes and LOB behavior.
+ *
+ * This test uses generated Bookstore classes to test the behavior of various
+ * object operations.  The _idea_ here is to test every possible generated method
+ * from Object.tpl; if necessary, bookstore will be expanded to accommodate this.
+ *
+ * The database is relaoded before every test and flushed after every test.  This
+ * means that you can always rely on the contents of the databases being the same
+ * for each test method in this class.  See the BookstoreDataPopulator::populate()
+ * method for the exact contents of the database.
+ *
+ * @see        BookstoreDataPopulator
+ * @author     Hans Lellelid <hans@xmpl.org>
+ */
+class GeneratedObjectLobTest extends BookstoreTestBase {
+
+	/**
+	 * Array of filenames pointing to blob/clob files indexed by the basename.
+	 *
+	 * @var        array string[]
+	 */
+	protected $sampleLobFiles = array();
+
+	protected function setUp()
+	{
+		parent::setUp();
+		$this->sampleLobFiles['tin_drum.gif'] = TESTS_BASE_DIR . '/etc/lob/tin_drum.gif';
+		$this->sampleLobFiles['tin_drum.txt'] = TESTS_BASE_DIR . '/etc/lob/tin_drum.txt';
+		$this->sampleLobFiles['propel.gif'] = TESTS_BASE_DIR . '/etc/lob/propel.gif';
+	}
+
+	/**
+	 * Gets a LOB filename.
+	 *
+	 * @param      string $basename Basename of LOB filename to return (if left blank, will choose random file).
+	 * @return     string
+	 * @throws     Exception - if specified basename doesn't correspond to a registered LOB filename
+	 */
+	protected function getLobFile($basename = null)
+	{
+		if ($basename === null) {
+			$basename = array_rand($this->sampleLobFiles);
+		}
+
+		if (isset($this->sampleLobFiles[$basename])) {
+			return $this->sampleLobFiles[$basename];
+		} else {
+			throw new Exception("Invalid base LOB filename: $basename");
+		}
+	}
+
+	/**
+	 * Test the LOB results returned in a resultset.
+	 */
+	public function testLobResults()
+	{
+
+		$blob_path = $this->getLobFile('tin_drum.gif');
+		$clob_path = $this->getLobFile('tin_drum.txt');
+
+		$book = BookPeer::doSelectOne(new Criteria());
+
+		$m1 = new Media();
+		$m1->setBook($book);
+		$m1->setCoverImage(file_get_contents($blob_path));
+		$m1->setExcerpt(file_get_contents($clob_path));
+		$m1->save();
+		$m1_id = $m1->getId();
+
+		$m1->reload();
+
+		$img = $m1->getCoverImage();
+		$txt = $m1->getExcerpt();
+
+		$this->assertType('resource', $img, "Expected results of BLOB method to be a resource.");
+		$this->assertType('string', $txt, "Expected results of CLOB method to be a string.");
+
+		$stat = fstat($img);
+		$size = $stat['size'];
+
+		$this->assertEquals(filesize($blob_path), $size, "Expected filesize to match stat(blobrsc)");
+		$this->assertEquals(filesize($clob_path), strlen($txt), "Expected filesize to match clob strlen");
+	}
+
+	/**
+	 * Test to make sure that file pointer is not when it is fetched
+	 * from the object.
+	 *
+	 * This is actually a test for correct behavior and does not completely fix
+	 * the associated ticket (which was resolved wontfix).
+	 *
+	 * This does test the rewind-after-save functionality, however.
+	 *
+	 * @link       http://propel.phpdb.org/trac/ticket/531
+	 */
+	public function testLobRepeatRead()
+	{
+		$blob_path = $this->getLobFile('tin_drum.gif');
+		$clob_path = $this->getLobFile('tin_drum.txt');
+
+		$book = BookPeer::doSelectOne(new Criteria());
+
+		$m1 = new Media();
+		$m1->setBook($book);
+		$m1->setCoverImage(file_get_contents($blob_path));
+		$m1->setExcerpt(file_get_contents($clob_path));
+		$m1->save();
+
+		$img = $m1->getCoverImage();
+
+		// 1) Assert that this resource has been rewound.
+
+		$this->assertEquals(0, ftell($img), "Expected position of cursor in file pointer to be 0");
+
+		// 1) Assert that we've got a valid stream to start with
+
+		$this->assertType('resource', $img, "Expected results of BLOB method to be a resource.");
+
+		// read first 100 bytes
+		$firstBytes = fread($img, 100);
+
+		$img2 = $m1->getCoverImage();
+		$this->assertSame($img, $img2, "Assert that the two resources are the same.");
+
+		// read next 100 bytes
+		$nextBytes = fread($img, 100);
+
+		$this->assertNotEquals(bin2hex($firstBytes), bin2hex($nextBytes), "Expected the first 100 and next 100 bytes to not be identical.");
+	}
+
+	/**
+	 * Tests the setting of LOB (BLOB and CLOB) values.
+	 */
+	public function testLobSetting()
+	{
+		$blob_path = $this->getLobFile('tin_drum.gif');
+		$blob2_path = $this->getLobFile('propel.gif');
+
+		$clob_path = $this->getLobFile('tin_drum.txt');
+		$book = BookPeer::doSelectOne(new Criteria());
+
+		$m1 = new Media();
+		$m1->setBook($book);
+		$m1->setCoverImage(file_get_contents($blob_path));
+		$m1->setExcerpt(file_get_contents($clob_path));
+		$m1->save();
+		$m1_id = $m1->getId();
+
+		// 1) Assert that we've got a valid stream to start with
+		$img = $m1->getCoverImage();
+		$this->assertType('resource', $img, "Expected results of BLOB method to be a resource.");
+
+		// 2) Test setting a BLOB column with file contents
+		$m1->setCoverImage(file_get_contents($blob2_path));
+		$this->assertType('resource', $m1->getCoverImage(), "Expected to get a resource back after setting BLOB with file contents.");
+
+		// commit those changes & reload
+		$m1->save();
+
+		// 3) Verify that we've got a valid resource after reload
+		$m1->reload();
+		$this->assertType('resource', $m1->getCoverImage(), "Expected to get a resource back after setting reloading object.");
+
+		// 4) Test isModified() behavior
+		$fp = fopen("php://temp", "r+");
+		fwrite($fp, file_get_contents($blob2_path));
+
+		$m1->setCoverImage($fp);
+		$this->assertTrue($m1->isModified(), "Expected Media object to be modified, despite fact that stream is to same data");
+
+		// 5) Test external modification of the stream (and re-setting it into the object)
+		$stream = $m1->getCoverImage();
+		fwrite($stream, file_get_contents($blob_path)); // change the contents of the stream
+
+		$m1->setCoverImage($stream);
+
+		$this->assertTrue($m1->isModified(), "Expected Media object to be modified when stream contents changed.");
+		$this->assertNotEquals(file_get_contents($blob2_path), stream_get_contents($m1->getCoverImage()));
+
+		$m1->save();
+
+		// 6) Assert that when we call the setter with a stream, that the file in db gets updated.
+
+		$m1->reload(); // start with a fresh copy from db
+
+		// Ensure that object is set up correctly
+		$this->assertNotEquals(file_get_contents($blob_path), stream_get_contents($m1->getCoverImage()), "The object is not correctly set up to verify the stream-setting test.");
+
+		$fp = fopen($blob_path, "r");
+		$m1->setCoverImage($fp);
+		$m1->save();
+		$m1->reload(); // refresh from db
+
+		// Assert that we've updated the db
+		$this->assertEquals(file_get_contents($blob_path), stream_get_contents($m1->getCoverImage()), "Expected the updated BLOB value after setting with a stream.");
+
+		// 7) Assert that 'w' mode works
+
+	}
+
+	public function testLobSetting_WriteMode()
+	{
+		$blob_path = $this->getLobFile('tin_drum.gif');
+		$blob2_path = $this->getLobFile('propel.gif');
+
+		$clob_path = $this->getLobFile('tin_drum.txt');
+		$book = BookPeer::doSelectOne(new Criteria());
+
+		$m1 = new Media();
+		$m1->setBook($book);
+		$m1->setCoverImage(file_get_contents($blob_path));
+		$m1->setExcerpt(file_get_contents($clob_path));
+		$m1->save();
+
+		MediaPeer::clearInstancePool();
+
+		// make sure we have the latest from the db:
+		$m2 = MediaPeer::retrieveByPK($m1->getId());
+
+		// now attempt to assign a temporary stream, opened in 'w' mode, to the db
+
+		$stream = fopen("php://memory", 'w');
+		fwrite($stream, file_get_contents($blob2_path));
+		$m2->setCoverImage($stream);
+		$m2->save();
+		fclose($stream);
+
+		$m2->reload();
+		$this->assertEquals(file_get_contents($blob2_path), stream_get_contents($m2->getCoverImage()), "Expected contents to match when setting stream w/ 'w' mode");
+
+		$stream2 = fopen("php://memory", 'w+');
+		fwrite($stream2, file_get_contents($blob_path));
+		rewind($stream2);
+		$this->assertEquals(file_get_contents($blob_path), stream_get_contents($stream2), "Expecting setup to be correct");
+
+		$m2->setCoverImage($stream2);
+		$m2->save();
+		$m2->reload();
+
+		$this->assertEquals(file_get_contents($blob_path), stream_get_contents($m2->getCoverImage()), "Expected contents to match when setting stream w/ 'w+' mode");
+
+	}
+
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/test/classes/propel/GeneratedObjectRelTest.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/test/classes/propel/GeneratedObjectRelTest.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/test/classes/propel/GeneratedObjectRelTest.php	(revision 19)
@@ -0,0 +1,233 @@
+<?php
+/*
+ *  $Id: GeneratedObjectRelTest.php 989 2008-03-11 14:29:30Z heltem $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://propel.phpdb.org>.
+ */
+
+require_once 'bookstore/BookstoreTestBase.php';
+
+/**
+ * Tests relationships between generated Object classes.
+ *
+ * This test uses generated Bookstore classes to test the behavior of various
+ * object operations.  The _idea_ here is to test every possible generated method
+ * from Object.tpl; if necessary, bookstore will be expanded to accommodate this.
+ *
+ * The database is relaoded before every test and flushed after every test.  This
+ * means that you can always rely on the contents of the databases being the same
+ * for each test method in this class.  See the BookstoreDataPopulator::populate()
+ * method for the exact contents of the database.
+ *
+ * @see        BookstoreDataPopulator
+ * @author     Hans Lellelid <hans@xmpl.org>
+ */
+class GeneratedObjectRelTest extends BookstoreTestBase {
+
+	/**
+	 * Tests one side of a bi-directional setting of many-to-many relationships.
+	 */
+	public function testManyToMany_Dir1()
+	{
+		$list = new BookClubList();
+		$list->setGroupLeader('Archimedes Q. Porter');
+		// No save ...
+
+		$book = new Book();
+		$book->setTitle( "Jungle Expedition Handbook" );
+		$book->setISBN('TEST');
+		// No save ...
+
+		$this->assertEquals(0, count($list->getBookListRels()) );
+		$this->assertEquals(0, count($book->getBookListRels()) );
+		$this->assertEquals(0, count(BookListRelPeer::doSelect(new Criteria())) );
+
+		$xref = new BookListRel();
+		$xref->setBook($book);
+		$list->addBookListRel($xref);
+
+		$this->assertEquals(1, count($list->getBookListRels()));
+		$this->assertEquals(1, count($book->getBookListRels()) );
+		$this->assertEquals(0, count(BookListRelPeer::doSelect(new Criteria())) );
+
+		$list->save();
+
+		$this->assertEquals(1, count($list->getBookListRels()) );
+		$this->assertEquals(1, count($book->getBookListRels()) );
+		$this->assertEquals(1, count(BookListRelPeer::doSelect(new Criteria())) );
+
+	}
+
+	/**
+	 * Tests reverse setting of one of many-to-many relationship, with all saves cascaded.
+	 */
+	public function testManyToMany_Dir2_Unsaved()
+	{
+		$list = new BookClubList();
+		$list->setGroupLeader('Archimedes Q. Porter');
+		// No save ...
+
+		$book = new Book();
+		$book->setTitle( "Jungle Expedition Handbook" );
+		$book->setISBN('TEST');
+		// No save (yet) ...
+
+		$this->assertEquals(0, count($list->getBookListRels()) );
+		$this->assertEquals(0, count($book->getBookListRels()) );
+		$this->assertEquals(0, count(BookListRelPeer::doSelect(new Criteria())) );
+
+		$xref = new BookListRel();
+		$xref->setBookClubList($list);
+		$book->addBookListRel($xref);
+
+		$this->assertEquals(1, count($list->getBookListRels()) );
+		$this->assertEquals(1, count($book->getBookListRels()) );
+		$this->assertEquals(0, count(BookListRelPeer::doSelect(new Criteria())) );
+		$book->save();
+
+		$this->assertEquals(1, count($list->getBookListRels()) );
+		$this->assertEquals(1, count($book->getBookListRels()) );
+		$this->assertEquals(1, count(BookListRelPeer::doSelect(new Criteria())) );
+
+	}
+
+	/**
+	 * Tests reverse setting of relationships, saving one of the objects first.
+	 * @link       http://propel.phpdb.org/trac/ticket/508
+	 */
+	public function testManyToMany_Dir2_Saved()
+	{
+		$list = new BookClubList();
+		$list->setGroupLeader('Archimedes Q. Porter');
+		$list->save();
+
+		$book = new Book();
+		$book->setTitle( "Jungle Expedition Handbook" );
+		$book->setISBN('TEST');
+		// No save (yet) ...
+
+		$this->assertEquals(0, count($list->getBookListRels()) );
+		$this->assertEquals(0, count($book->getBookListRels()) );
+		$this->assertEquals(0, count(BookListRelPeer::doSelect(new Criteria())) );
+
+		// Now set the relationship from the opposite direction.
+
+		$xref = new BookListRel();
+		$xref->setBookClubList($list);
+		$book->addBookListRel($xref);
+
+		$this->assertEquals(1, count($list->getBookListRels()) );
+		$this->assertEquals(1, count($book->getBookListRels()) );
+		$this->assertEquals(0, count(BookListRelPeer::doSelect(new Criteria())) );
+		$book->save();
+
+		$this->assertEquals(1, count($list->getBookListRels()) );
+		$this->assertEquals(1, count($book->getBookListRels()) );
+		$this->assertEquals(1, count(BookListRelPeer::doSelect(new Criteria())) );
+
+	}
+
+	/**
+	 * Test behavior of columns that are implicated in multiple foreign keys.
+	 * @link       http://propel.phpdb.org/trac/ticket/228
+	 */
+	public function testMultiFkImplication()
+	{
+		// Create a new bookstore, contest, bookstore_contest, and bookstore_contest_entry
+		$b = new Bookstore();
+		$b->setStoreName("Foo!");
+		$b->save();
+
+		$c = new Contest();
+		$c->setName("Bookathon Contest");
+		$c->save();
+
+		$bc = new BookstoreContest();
+		$bc->setBookstore($b);
+		$bc->setContest($c);
+		$bc->save();
+
+		$c = new Customer();
+		$c->setName("Happy Customer");
+		$c->save();
+
+		$bce = new BookstoreContestEntry();
+		$bce->setBookstore($b);
+		$bce->setBookstoreContest($bc);
+		$bce->setCustomer($c);
+		$bce->save();
+
+		$bce->setBookstoreId(null);
+
+		$this->assertNull($bce->getBookstoreContest());
+		$this->assertNull($bce->getBookstore());
+	}
+
+	/**
+	 * Test the clearing of related object collection.
+	 * @link       http://propel.phpdb.org/trac/ticket/529
+	 */
+	public function testClearRefFk()
+	{
+		$book = new Book();
+		$book->setISBN("Foo-bar-baz");
+		$book->setTitle("The book title");
+
+		// No save ...
+
+		$r = new Review();
+		$r->setReviewedBy('Me');
+		$r->setReviewDate(new DateTime("now"));
+
+		$book->addReview($r);
+
+		// No save (yet) ...
+
+		$this->assertEquals(1, count($book->getReviews()) );
+		$book->clearReviews();
+		$this->assertEquals(0, count($book->getReviews()));
+	}
+
+	/**
+	 * This tests to see whether modified objects are being silently overwritten by calls to fk accessor methods.
+	 * @link       http://propel.phpdb.org/trac/ticket/509#comment:5
+	 */
+	public function testModifiedObjectOverwrite()
+	{
+		$author = new Author();
+		$author->setFirstName("John");
+		$author->setLastName("Public");
+
+		$books = $author->getBooks(); // empty, of course
+		$this->assertEquals(array(), $books, "Expected empty array.");
+
+		$book = new Book();
+		$book->setTitle("A sample book");
+		$book->setISBN("INITIAL ISBN");
+
+		$author->addBook($book);
+
+		$author->save();
+
+		$book->setISBN("MODIFIED ISBN");
+
+		$books = $author->getBooks();
+		$this->assertEquals(1, count($books), "Expected 1 book.");
+		$this->assertSame($book, $books[0], "Expected the same object to be returned by fk accessor.");
+		$this->assertEquals("MODIFIED ISBN", $books[0]->getISBN(), "Expected the modified value NOT to have been overwritten.");
+	}
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/test/classes/propel/GeneratedObjectTest.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/test/classes/propel/GeneratedObjectTest.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/test/classes/propel/GeneratedObjectTest.php	(revision 19)
@@ -0,0 +1,1022 @@
+<?php
+/*
+ *  $Id: GeneratedObjectTest.php 1043 2008-05-08 13:27:19Z ron $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://propel.phpdb.org>.
+ */
+
+require_once 'bookstore/BookstoreTestBase.php';
+
+/**
+ * Tests the generated Object classes.
+ *
+ * This test uses generated Bookstore classes to test the behavior of various
+ * object operations.  The _idea_ here is to test every possible generated method
+ * from Object.tpl; if necessary, bookstore will be expanded to accommodate this.
+ *
+ * The database is relaoded before every test and flushed after every test.  This
+ * means that you can always rely on the contents of the databases being the same
+ * for each test method in this class.  See the BookstoreDataPopulator::populate()
+ * method for the exact contents of the database.
+ *
+ * @see        BookstoreDataPopulator
+ * @author     Hans Lellelid <hans@xmpl.org>
+ */
+class GeneratedObjectTest extends BookstoreTestBase {
+
+	/**
+	 * Test saving an object after setting default values for it.
+	 */
+	public function testSaveWithDefaultValues()
+	{
+		// From the schema.xml, I am relying on the following:
+		//  - that 'Penguin' is the default Name for a Publisher
+		//  - that 2001-01-01 is the default ReviewDate for a Review
+
+		// 1) check regular values (VARCHAR)
+		$pub = new Publisher();
+		$pub->setName('Penguin');
+		$pub->save();
+		$this->assertTrue($pub->getId() !== null, "Expect Publisher to have been saved when default value set.");
+
+		// 2) check date/time values
+		$review = new Review();
+		// note that this is different from how it's represented in schema, but should resolve to same unix timestamp
+		$review->setReviewDate('2001-01-01');
+		$this->assertTrue($review->isModified(), "Expect Review to have been marked 'modified' after default date/time value set.");
+
+	}
+
+	/**
+	 * Test default return values.
+	 */
+	public function testDefaultValues()
+	{
+		$r = new Review();
+		$this->assertEquals('2001-01-01', $r->getReviewDate('Y-m-d'));
+
+		$this->assertFalse($r->isModified(), "expected isModified() to be false");
+
+		$acct = new BookstoreEmployeeAccount();
+		$this->assertEquals(true, $acct->getEnabled());
+		$this->assertFalse($acct->isModified());
+
+		$acct->setLogin("testuser");
+		$acct->setPassword("testpass");
+		$this->assertTrue($acct->isModified());
+	}
+
+	/**
+	 * Tests the use of default expressions and the reloadOnInsert and reloadOnUpdate attributes.
+	 *
+	 * @link       http://propel.phpdb.org/trac/ticket/378
+	 * @link       http://propel.phpdb.org/trac/ticket/555
+	 */
+	public function testDefaultExpresions()
+	{
+		if (Propel::getDb(BookstoreEmployeePeer::DATABASE_NAME) instanceof DBSqlite) {
+			$this->markTestSkipped("Cannot test default expressions with SQLite");
+		}
+
+		$b = new Bookstore();
+		$b->setStoreName("Foo!");
+		$b->save();
+
+		$employee = new BookstoreEmployee();
+		$employee->setName("Johnny Walker");
+
+		$acct = new BookstoreEmployeeAccount();
+		$acct->setBookstoreEmployee($employee);
+		$acct->setLogin("test-login");
+
+		$this->assertNull($acct->getCreated(), "Expected created column to be NULL.");
+		$this->assertNull($acct->getAuthenticator(), "Expected authenticator column to be NULL.");
+
+		$acct->save();
+
+		$acct = BookstoreEmployeeAccountPeer::retrieveByPK($acct->getEmployeeId());
+
+		$this->assertNotNull($acct->getAuthenticator(), "Expected a valid (non-NULL) authenticator column after save.");
+		$this->assertEquals('Password', $acct->getAuthenticator(), "Expected authenticator='Password' after save.");
+		$this->assertNotNull($acct->getCreated(), "Expected a valid date after retrieving saved object.");
+
+		$now = new DateTime("now");
+		$this->assertEquals($now->format("Y-m-d"), $acct->getCreated("Y-m-d"));
+
+		$acct->setCreated($now);
+		$this->assertEquals($now->format("Y-m-d"), $acct->getCreated("Y-m-d"));
+
+		// Unfortunately we can't really test the conjunction of reloadOnInsert and reloadOnUpdate when using just
+		// default values. (At least not in a cross-db way.)
+	}
+
+	/**
+	 * Tests the use of default expressions and the reloadOnInsert attribute.
+	 *
+	 * @link       http://propel.phpdb.org/trac/ticket/378
+	 * @link       http://propel.phpdb.org/trac/ticket/555
+	 */
+	public function testDefaultExpresions_ReloadOnInsert()
+	{
+		if (Propel::getDb(BookstoreEmployeePeer::DATABASE_NAME) instanceof DBSqlite) {
+			$this->markTestSkipped("Cannot test default date expressions with SQLite");
+		}
+
+		// Create a new bookstore, contest, bookstore_contest, and bookstore_contest_entry
+
+		$b = new Bookstore();
+		$b->setStoreName("Barnes & Noble");
+		$b->save();
+
+		$c = new Contest();
+		$c->setName("Bookathon Contest");
+		$c->save();
+
+		$bc = new BookstoreContest();
+		$bc->setBookstore($b);
+		$bc->setContest($c);
+		$bc->save();
+
+		$c = new Customer();
+		$c->setName("Happy Customer");
+		$c->save();
+
+		$bce = new BookstoreContestEntry();
+		$bce->setBookstore($b);
+		$bce->setBookstoreContest($bc);
+		$bce->setCustomer($c);
+		$bce->save();
+
+		$this->assertNotNull($bce->getEntryDate(), "Expected a non-null entry_date after save.");
+	}
+
+	/**
+	 * Tests the overriding reloadOnInsert at runtime.
+	 *
+	 * @link       http://propel.phpdb.org/trac/ticket/378
+	 * @link       http://propel.phpdb.org/trac/ticket/555
+	 */
+	public function testDefaultExpresions_ReloadOnInsert_Override()
+	{
+		if (Propel::getDb(BookstoreEmployeePeer::DATABASE_NAME) instanceof DBSqlite) {
+			$this->markTestSkipped("Cannot test default date expressions with SQLite");
+		}
+
+		// Create a new bookstore, contest, bookstore_contest, and bookstore_contest_entry
+		$b = new Bookstore();
+		$b->setStoreName("Barnes & Noble");
+		$b->save();
+
+		$c = new Contest();
+		$c->setName("Bookathon Contest");
+		$c->save();
+
+		$bc = new BookstoreContest();
+		$bc->setBookstore($b);
+		$bc->setContest($c);
+		$bc->save();
+
+		$c = new Customer();
+		$c->setName("Happy Customer");
+		$c->save();
+
+		$bce = new BookstoreContestEntry();
+		$bce->setBookstore($b);
+		$bce->setBookstoreContest($bc);
+		$bce->setCustomer($c);
+		$bce->save(null, $skipReload=true);
+
+		$this->assertNull($bce->getEntryDate(), "Expected a NULL entry_date after save.");
+	}
+
+	/**
+	 * Tests the use of default expressions and the reloadOnUpdate attribute.
+	 *
+	 * @link       http://propel.phpdb.org/trac/ticket/555
+	 */
+	public function testDefaultExpresions_ReloadOnUpdate()
+	{
+		$b = new Bookstore();
+		$b->setStoreName("Foo!");
+		$b->save();
+
+		$sale = new BookstoreSale();
+		$sale->setBookstore(BookstorePeer::doSelectOne(new Criteria()));
+		$sale->setSaleName("Spring Sale");
+		$sale->save();
+
+		// Expect that default values are set, but not default expressions
+		$this->assertNull($sale->getDiscount(), "Expected discount to be NULL.");
+
+		$sale->setSaleName("Winter Clearance");
+		$sale->save();
+		// Since reloadOnUpdate = true, we expect the discount to be set now.
+
+		$this->assertNotNull($sale->getDiscount(), "Expected discount to be non-NULL after save.");
+	}
+
+	/**
+	 * Tests the overriding reloadOnUpdate at runtime.
+	 *
+	 * @link       http://propel.phpdb.org/trac/ticket/378
+	 * @link       http://propel.phpdb.org/trac/ticket/555
+	 */
+	public function testDefaultExpresions_ReloadOnUpdate_Override()
+	{
+		$b = new Bookstore();
+		$b->setStoreName("Foo!");
+		$b->save();
+
+		$sale = new BookstoreSale();
+		$sale->setBookstore(BookstorePeer::doSelectOne(new Criteria()));
+		$sale->setSaleName("Spring Sale");
+		$sale->save();
+
+		// Expect that default values are set, but not default expressions
+		$this->assertNull($sale->getDiscount(), "Expected discount to be NULL.");
+
+		$sale->setSaleName("Winter Clearance");
+		$sale->save(null, $skipReload=true);
+
+		// Since reloadOnUpdate = true, we expect the discount to be set now.
+
+		$this->assertNull($sale->getDiscount(), "Expected NULL value for discount after save.");
+	}
+
+	/**
+	 * Test the behavior of date/time/values.
+	 * This requires that the model was built with propel.useDateTimeClass=true.
+	 */
+	public function testTemporalValues_PreEpoch()
+	{
+		$r = new Review();
+
+		$preEpochDate = new DateTime('1602-02-02');
+
+		$r->setReviewDate($preEpochDate);
+
+		$this->assertEquals('1602-02-02', $r->getReviewDate(null)->format("Y-m-d"));
+
+		$r->setReviewDate('1702-02-02');
+
+		$this->assertTrue($r->isModified());
+
+		$this->assertEquals('1702-02-02', $r->getReviewDate(null)->format("Y-m-d"));
+
+		// Now test for setting null
+		$r->setReviewDate(null);
+		$this->assertNull($r->getReviewDate());
+
+	}
+
+	/**
+	 * Test setting invalid date/time.
+	 */
+	public function testSetTemporalValue_Invalid()
+	{
+		$this->markTestSkipped();
+		// FIXME - Figure out why this doesn't work (causes a PHP ERROR instead of throwing Exception) in
+		// the Phing+PHPUnit context
+		$r = new Review();
+		try {
+			$r->setReviewDate("Invalid Date");
+			$this->fail("Expected PropelException when setting date column w/ invalid date");
+		} catch (PropelException $x) {
+			print "Caught expected PropelException: " . $x->__toString();
+		}
+	}
+
+	/**
+	 * Test setting TIMESTAMP columns w/ unix int timestamp.
+	 */
+	public function testTemporalValues_Unix()
+	{
+		$store = new Bookstore();
+		$store->setStoreName("test");
+		$store->setStoreOpenTime(strtotime('12:55'));
+		$store->save();
+		$this->assertEquals('12:55', $store->getStoreOpenTime(null)->format('H:i'));
+
+		$acct = new BookstoreEmployeeAccount();
+		$acct->setCreated(time());
+		$this->assertEquals(date('Y-m-d H:i'), $acct->getCreated('Y-m-d H:i'));
+
+		$review = new Review();
+		$review->setReviewDate(time());
+		$this->assertEquals(date('Y-m-d'), $review->getReviewDate('Y-m-d'));
+	}
+
+	/**
+	 * Test setting empty temporal values.
+	 * @link       http://propel.phpdb.org/trac/ticket/586
+	 */
+	public function testTemporalValues_Empty()
+	{
+		$review = new Review();
+		$review->setReviewDate('');
+		$this->assertNull($review->getReviewDate());
+	}
+
+	/**
+	 * Test setting TIME columns.
+	 */
+	public function testTemporalValues_TimeSetting()
+	{
+		$store = new Bookstore();
+		$store->setStoreName("test");
+		$store->setStoreOpenTime("12:55");
+		$store->save();
+
+		$store = new Bookstore();
+		$store->setStoreName("test2");
+		$store->setStoreOpenTime(new DateTime("12:55"));
+		$store->save();
+	}
+
+	/**
+	 * Test setting TIME columns.
+	 */
+	public function testTemporalValues_DateSetting()
+	{
+		$r = new Review();
+		$r->setBook(BookPeer::doSelectOne(new Criteria()));
+		$r->setReviewDate(new DateTime('1999-12-20'));
+		$r->setReviewedBy("Hans");
+		$r->setRecommended(false);
+		$r->save();
+	}
+
+	/**
+	 * Testing creating & saving new object & instance pool.
+	 */
+	public function testObjectInstances_New()
+	{
+		$emp = new BookstoreEmployee();
+		$emp->setName(md5(microtime()));
+		$emp->save();
+		$id = $emp->getId();
+
+		$retrieved = BookstoreEmployeePeer::retrieveByPK($id);
+		$this->assertSame($emp, $retrieved, "Expected same object (from instance pool)");
+	}
+
+	/**
+	 *
+	 */
+	public function testObjectInstances_Fkeys()
+	{
+		// Establish a relationship between one employee and account
+		// and then change the employee_id and ensure that the account
+		// is not pulling the old employee.
+
+		$pub1 = new Publisher();
+		$pub1->setName('Publisher 1');
+		$pub1->save();
+
+		$pub2 = new Publisher();
+		$pub2->setName('Publisher 2');
+		$pub2->save();
+
+		$book = new Book();
+		$book->setTitle("Book Title");
+		$book->setISBN("1234");
+		$book->setPublisher($pub1);
+		$book->save();
+
+		$this->assertSame($pub1, $book->getPublisher());
+
+		// now change values behind the scenes
+		$con = Propel::getConnection(BookstoreEmployeeAccountPeer::DATABASE_NAME);
+		$con->exec("UPDATE " . BookPeer::TABLE_NAME . " SET "
+		. " publisher_id = " . $pub2->getId()
+		. " WHERE id = " . $book->getId());
+
+
+		$book2 = BookPeer::retrieveByPK($book->getId());
+		$this->assertSame($book, $book2, "Expected same book object instance");
+
+		$this->assertEquals($pub1->getId(), $book->getPublisherId(), "Expected book to have OLD publisher id before reload()");
+
+		$book->reload();
+
+		$this->assertEquals($pub2->getId(), $book->getPublisherId(), "Expected book to have new publisher id");
+		$this->assertSame($pub2, $book->getPublisher(), "Expected book to have new publisher object associated.");
+
+		// Now let's set it back, just to be double sure ...
+
+		$con->exec("UPDATE " . BookPeer::TABLE_NAME . " SET "
+		. " publisher_id = " . $pub1->getId()
+		. " WHERE id = " . $book->getId());
+
+		$book->reload();
+
+		$this->assertEquals($pub1->getId(), $book->getPublisherId(), "Expected book to have old publisher id (again).");
+		$this->assertSame($pub1, $book->getPublisher(), "Expected book to have old publisher object associated (again).");
+
+	}
+
+	/**
+	 * Test the effect of typecast on primary key values and instance pool retrieval.
+	 */
+	public function testObjectInstancePoolTypecasting()
+	{
+		$reader = new BookReader();
+		$reader->setName("Tester");
+		$reader->save();
+		$readerId = $reader->getId();
+
+		$book = new Book();
+		$book->setTitle("BookTest");
+		$book->setISBN("TEST");
+		$book->save();
+		$bookId = $book->getId();
+
+		$opinion = new BookOpinion();
+		$opinion->setBookId((string)$bookId);
+		$opinion->setReaderId((string)$readerId);
+		$opinion->setRating("BAD!");
+		$opinion->setRecommendToFriend(false);
+		$opinion->save();
+
+
+		$opinion2 = BookOpinionPeer::retrieveByPK($bookId, $readerId);
+
+		$this->assertSame($opinion, $opinion2, "Expected same object to be retrieved from differently type-casted primary key values.");
+
+	}
+
+	/**
+	 * Test the reload() method.
+	 */
+	public function testReload()
+	{
+		$a = AuthorPeer::doSelectOne(new Criteria());
+
+		$origName = $a->getFirstName();
+
+		$a->setFirstName(md5(time()));
+
+		$this->assertNotEquals($origName, $a->getFirstName());
+		$this->assertTrue($a->isModified());
+
+		$a->reload();
+
+		$this->assertEquals($origName, $a->getFirstName());
+		$this->assertFalse($a->isModified());
+
+	}
+
+	/**
+	 * Test reload(deep=true) method.
+	 */
+	public function testReloadDeep()
+	{
+		// arbitrary book
+		$b = BookPeer::doSelectOne(new Criteria());
+
+		// arbitrary, different author
+		$c = new Criteria();
+		$c->add(AuthorPeer::ID, $b->getAuthorId(), Criteria::NOT_EQUAL);
+		$a = AuthorPeer::doSelectOne($c);
+
+		$origAuthor = $b->getAuthor();
+
+		$b->setAuthor($a);
+
+		$this->assertNotEquals($origAuthor, $b->getAuthor(), "Expected just-set object to be different from obj from DB");
+		$this->assertTrue($b->isModified());
+
+		$b->reload($deep=true);
+
+		$this->assertEquals($origAuthor, $b->getAuthor(), "Expected object in DB to be restored");
+		$this->assertFalse($a->isModified());
+	}
+
+	/**
+	 * Test saving an object and getting correct number of affected rows from save().
+	 * This includes tests of cascading saves to fk-related objects.
+	 */
+	public function testSaveReturnValues()
+	{
+
+		$author = new Author();
+		$author->setFirstName("Mark");
+		$author->setLastName("Kurlansky");
+		// do not save
+
+		$pub = new Publisher();
+		$pub->setName("Penguin Books");
+		// do not save
+
+		$book = new Book();
+		$book->setTitle("Salt: A World History");
+		$book->setISBN("0142001619");
+		$book->setAuthor($author);
+		$book->setPublisher($pub);
+
+		$affected = $book->save();
+		$this->assertEquals(3, $affected, "Expected 3 affected rows when saving book + publisher + author.");
+
+		// change nothing ...
+		$affected = $book->save();
+		$this->assertEquals(0, $affected, "Expected 0 affected rows when saving already-saved book.");
+
+		// modify the book (UPDATE)
+		$book->setTitle("Salt A World History");
+		$affected = $book->save();
+		$this->assertEquals(1, $affected, "Expected 1 affected row when saving modified book.");
+
+		// modify the related author
+		$author->setLastName("Kurlanski");
+		$affected = $book->save();
+		$this->assertEquals(1, $affected, "Expected 1 affected row when saving book with updated author.");
+
+		// modify both the related author and the book
+		$author->setLastName("Kurlansky");
+		$book->setTitle("Salt: A World History");
+		$affected = $book->save();
+		$this->assertEquals(2, $affected, "Expected 2 affected rows when saving updated book with updated author.");
+
+	}
+
+	/**
+	 * Test deleting an object using the delete() method.
+	 */
+	public function testDelete() {
+
+		// 1) grab an arbitrary object
+		$book = BookPeer::doSelectOne(new Criteria());
+		$bookId = $book->getId();
+
+		// 2) delete it
+		$book->delete();
+
+		// 3) make sure it can't be save()d now that it's deleted
+		try {
+			$book->setTitle("Will Fail");
+			$book->save();
+			$this->fail("Expect an exception to be thrown when attempting to save() a deleted object.");
+		} catch (PropelException $e) {}
+
+		// 4) make sure that it doesn't exist in db
+		$book = BookPeer::retrieveByPK($bookId);
+		$this->assertNull($book, "Expect NULL from retrieveByPK on deleted Book.");
+
+	}
+
+	/**
+	 *
+	 */
+	public function testNoColsModified()
+	{
+		$e1 = new BookstoreEmployee();
+		$e1->setName('Employee 1');
+
+		$e2 = new BookstoreEmployee();
+		$e2->setName('Employee 2');
+
+		$super = new BookstoreEmployee();
+		// we don't know who the supervisor is yet
+		$super->addSubordinate($e1);
+		$super->addSubordinate($e2);
+
+		$affected = $super->save();
+
+	}
+
+	/**
+	 * Tests new one-to-one functionality.
+	 */
+	public function testOneToOne()
+	{
+		$emp = BookstoreEmployeePeer::doSelectOne(new Criteria());
+
+		$acct = new BookstoreEmployeeAccount();
+		$acct->setBookstoreEmployee($emp);
+		$acct->setLogin("testuser");
+		$acct->setPassword("testpass");
+
+		$this->assertSame($emp->getBookstoreEmployeeAccount(), $acct, "Expected same object instance.");
+	}
+
+	/**
+	 * Test the type sensitivity of the resturning columns.
+	 *
+	 */
+	public function testTypeSensitive()
+	{
+		$book = BookPeer::doSelectOne(new Criteria());
+
+		$r = new Review();
+		$r->setReviewedBy("testTypeSensitive Tester");
+		$r->setReviewDate(time());
+		$r->setBook($book);
+		$r->setRecommended(true);
+		$r->save();
+
+		$id = $r->getId();
+		unset($r);
+
+		// clear the instance cache to force reload from database.
+		ReviewPeer::clearInstancePool();
+		BookPeer::clearInstancePool();
+
+		// reload and verify that the types are the same
+		$r2 = ReviewPeer::retrieveByPK($id);
+
+		$this->assertType('integer', $r2->getId(), "Expected getId() to return an integer.");
+		$this->assertType('string', $r2->getReviewedBy(), "Expected getReviewedBy() to return a string.");
+		$this->assertType('boolean', $r2->getRecommended(), "Expected getRecommended() to return a boolean.");
+		$this->assertType('Book', $r2->getBook(), "Expected getBook() to return a Book.");
+		$this->assertType('float', $r2->getBook()->getPrice(), "Expected Book->getPrice() to return a float.");
+		$this->assertType('DateTime', $r2->getReviewDate(null), "Expected Book->getReviewDate() to return a DateTime.");
+
+	}
+
+	/**
+	 * This is a test for expected exceptions when saving UNIQUE.
+	 * See http://propel.phpdb.org/trac/ticket/2
+	 */
+	public function testSaveUnique()
+	{
+		$emp = new BookstoreEmployee();
+		$emp->setName(md5(microtime()));
+
+		$acct = new BookstoreEmployeeAccount();
+		$acct->setBookstoreEmployee($emp);
+		$acct->setLogin("foo");
+		$acct->setPassword("bar");
+		$acct->save();
+
+		// now attempt to create a new acct
+		$acct2 = $acct->copy();
+
+		try {
+			$acct2->save();
+			$this->fail("Expected PropelException in first attempt to save object with duplicate value for UNIQUE constraint.");
+		} catch (Exception $x) {
+			try {
+				// attempt to save it again
+				$acct3 = $acct->copy();
+				$acct3->save();
+				$this->fail("Expected PropelException in second attempt to save object with duplicate value for UNIQUE constraint.");
+			} catch (Exception $x) {
+				// this is expected.
+			}
+			// now let's double check that it can succeed if we're not violating the constraint.
+			$acct3->setLogin("foo2");
+			$acct3->save();
+		}
+	}
+
+	/**
+	 * Test for correct reporting of isModified().
+	 */
+	public function testIsModified()
+	{
+		// 1) Basic test
+
+		$a = new Author();
+		$a->setFirstName("John");
+		$a->setLastName("Doe");
+		$a->setAge(25);
+
+		$this->assertTrue($a->isModified(), "Expected Author to be modified after setting values.");
+
+		$a->save();
+
+		$this->assertFalse($a->isModified(), "Expected Author to be unmodified after saving set values.");
+
+		// 2) Test behavior with setting vars of different types
+
+		// checking setting int col to string val
+		$a->setAge('25');
+		$this->assertFalse($a->isModified(), "Expected Author to be unmodified after setting int column to string-cast of same value.");
+
+		$a->setFirstName("John2");
+		$this->assertTrue($a->isModified(), "Expected Author to be modified after changing string column value.");
+
+		// checking setting string col to int val
+		$a->setFirstName("1");
+		$a->save();
+		$this->assertFalse($a->isModified(), "Expected Author to be unmodified after saving set values.");
+
+		$a->setFirstName(1);
+		$this->assertFalse($a->isModified(), "Expected Author to be unmodified after setting string column to int-cast of same value.");
+
+		// 3) Test for appropriate behavior of NULL
+
+		// checking "" -> NULL
+		$a->setFirstName("");
+		$a->save();
+		$this->assertFalse($a->isModified(), "Expected Author to be unmodified after saving set values.");
+
+		$a->setFirstName(null);
+		$this->assertTrue($a->isModified(), "Expected Author to be modified after changing empty string column value to NULL.");
+
+		$a->setFirstName("John");
+		$a->setAge(0);
+		$a->save();
+		$this->assertFalse($a->isModified(), "Expected Author to be unmodified after saving set values.");
+
+		$a->setAge(null);
+		$this->assertTrue($a->isModified(), "Expected Author to be modified after changing 0-value int column to NULL.");
+
+		$a->save();
+		$this->assertFalse($a->isModified(), "Expected Author to be unmodified after saving set values.");
+
+		$a->setAge(0);
+		$this->assertTrue($a->isModified(), "Expected Author to be modified after changing NULL-value int column to 0.");
+
+	}
+
+	/**
+	 * Test the BaseObject#equals().
+	 */
+	public function testEquals()
+	{
+		$b = BookPeer::doSelectOne(new Criteria());
+		$c = new Book();
+		$c->setId($b->getId());
+		$this->assertTrue($b->equals($c), "Expected Book objects to be equal()");
+
+		$a = new Author();
+		$a->setId($b->getId());
+		$this->assertFalse($b->equals($a), "Expected Book and Author with same primary key NOT to match.");
+	}
+
+	/**
+	 * Test checking for non-default values.
+	 * @see        http://propel.phpdb.org/trac/ticket/331
+	 */
+	public function testHasOnlyDefaultValues()
+	{
+		$emp = new BookstoreEmployee();
+		$emp->setName(md5(microtime()));
+
+		$acct2 = new BookstoreEmployeeAccount();
+
+		$acct = new BookstoreEmployeeAccount();
+		$acct->setBookstoreEmployee($emp);
+		$acct->setLogin("foo");
+		$acct->setPassword("bar");
+		$acct->save();
+
+		$this->assertFalse($acct->isModified(), "Expected BookstoreEmployeeAccount NOT to be modified after save().");
+
+		$acct->setEnabled(true);
+		$acct->setPassword($acct2->getPassword());
+
+		$this->assertTrue($acct->isModified(), "Expected BookstoreEmployeeAccount to be modified after setting default values.");
+
+		$this->assertTrue($acct->hasOnlyDefaultValues(), "Expected BookstoreEmployeeAccount to not have only default values.");
+
+		$acct->setPassword("bar");
+		$this->assertFalse($acct->hasOnlyDefaultValues(), "Expected BookstoreEmployeeAccount to have at one non-default value after setting one value to non-default.");
+
+		// Test a default date/time value
+		$r = new Review();
+		$r->setReviewDate(new DateTime("now"));
+		$this->assertFalse($r->hasOnlyDefaultValues());
+	}
+
+	public function testDefaultFkColVal()
+	{
+		$sale = new BookstoreSale();
+		$this->assertEquals(1, $sale->getBookstoreId(), "Expected BookstoreSale object to have a default bookstore_id of 1.");
+
+		$bookstore = BookstorePeer::doSelectOne(new Criteria());
+
+		$sale->setBookstore($bookstore);
+		$this->assertEquals($bookstore->getId(), $sale->getBookstoreId(), "Expected FK id to have changed when assigned a valid FK.");
+
+		$sale->setBookstore(null);
+		$this->assertEquals(1, $sale->getBookstoreId(), "Expected BookstoreSale object to have reset to default ID.");
+
+		$sale->setPublisher(null);
+		$this->assertEquals(null, $sale->getPublisherId(), "Expected BookstoreSale object to have reset to NULL publisher ID.");
+	}
+
+	public function testCountRefFk()
+	{
+		$book = new Book();
+		$book->setTitle("Test Book");
+		$book->setISBN("TT-EE-SS-TT");
+
+		$num = 5;
+
+		for ($i=2; $i < $num + 2; $i++) {
+			$r = new Review();
+			$r->setReviewedBy('Hans ' . $num);
+			$dt = new DateTime("now");
+			$dt->modify("-".$i." weeks");
+			$r->setReviewDate($dt);
+			$r->setRecommended(($i % 2) == 0);
+			$book->addReview($r);
+		}
+
+		$this->assertEquals($num, $book->countReviews(), "Expected countReviews to return $num");
+		$this->assertEquals($num, count($book->getReviews()), "Expected getReviews to return $num reviews");
+
+		$book->save();
+
+		BookPeer::clearInstancePool();
+		ReviewPeer::clearInstancePool();
+
+		$book = BookPeer::retrieveByPK($book->getId());
+		$this->assertEquals($num, $book->countReviews(), "Expected countReviews() to return $num (after save)");
+		$this->assertEquals($num, count($book->getReviews()), "Expected getReviews() to return $num (after save)");
+
+		// Now set different criteria and expect different results
+		$c = new Criteria();
+		$c->add(ReviewPeer::RECOMMENDED, false);
+		$this->assertEquals(floor($num/2), $book->countReviews($c), "Expected " . floor($num/2) . " results from countReviews(recomm=false)");
+
+		// Change Criteria, run again -- expect different.
+		$c = new Criteria();
+		$c->add(ReviewPeer::RECOMMENDED, true);
+		$this->assertEquals(ceil($num/2), count($book->getReviews($c)), "Expected " . ceil($num/2) . " results from getReviews(recomm=true)");
+
+		$this->assertEquals($num, $book->countReviews(), "Expected countReviews to return $num with new empty Criteria");
+	}
+
+	/**
+	 * Test copyInto method.
+	 */
+	public function testCopyInto_Deep()
+	{
+		// Test a "normal" object
+		$c = new Criteria();
+		$c->add(BookPeer::TITLE, 'Harry%', Criteria::LIKE);
+
+		$book = BookPeer::doSelectOne($c);
+		$reviews = $book->getReviews();
+
+		$b2 = $book->copy(true);
+		$this->assertType('Book', $b2);
+		$this->assertNull($b2->getId());
+
+		$r2 = $b2->getReviews();
+
+		$this->assertEquals(count($reviews), count($r2));
+
+		// Test a one-to-one object
+		$emp = BookstoreEmployeePeer::doSelectOne(new Criteria());
+		$e2 = $emp->copy(true);
+
+		$this->assertType('BookstoreEmployee', $e2);
+		$this->assertNull($e2->getId());
+
+		$this->assertEquals($emp->getBookstoreEmployeeAccount()->getLogin(), $e2->getBookstoreEmployeeAccount()->getLogin());
+	}
+	
+	/**
+	 * Test copying when an object has composite primary key.
+	 * @link http://propel.phpdb.org/trac/ticket/618
+	 */
+	public function testCopy_CompositePK()
+	{
+		$br = new BookReader();
+		$br->setName("TestReader");
+		$br->save();
+		$br->copy();
+		
+		$b = new Book();
+		$b->setTitle("TestBook");
+		$b->setISBN("XX-XX-XX-XX");
+		$b->save();
+		
+		$op = new BookOpinion();
+		$op->setBookReader($br);
+		$op->setBook($b);
+		$op->setRating(10);
+		$op->setRecommendToFriend(true);
+		$op->save();
+		
+		
+		$br2 = $br->copy(true);
+		
+		$this->assertNull($br2->getId());
+		
+		$opinions = $br2->getBookOpinions();
+		$this->assertEquals(1, count($opinions), "Expected to have a related BookOpinion after copy()");
+		
+		// We DO expect the reader_id to be null
+		$this->assertNull($opinions[0]->getReaderId());
+		// but we DO NOT expect the book_id to be null 
+		$this->assertEquals($op->getBookId(), $opinions[0]->getBookId());
+	}
+
+	/**
+	 * Test the toArray() method with new lazyLoad param.
+	 * @link       http://propel.phpdb.org/trac/ticket/527
+	 */
+	public function testToArrayLazyLoad()
+	{
+		$c = new Criteria();
+		$c->add(MediaPeer::COVER_IMAGE, null, Criteria::NOT_EQUAL);
+		$c->add(MediaPeer::EXCERPT, null, Criteria::NOT_EQUAL);
+
+		$m = MediaPeer::doSelectOne($c);
+		if ($m === null) {
+			$this->fail("Test requires at least one media row w/ cover_image and excerpt NOT NULL");
+		}
+
+		$arr1 = $m->toArray(BasePeer::TYPE_COLNAME);
+		$this->assertNotNull($arr1[MediaPeer::COVER_IMAGE]);
+		$this->assertType('resource', $arr1[MediaPeer::COVER_IMAGE]);
+
+		$arr2 = $m->toArray(BasePeer::TYPE_COLNAME, false);
+		$this->assertNull($arr2[MediaPeer::COVER_IMAGE]);
+		$this->assertNull($arr2[MediaPeer::EXCERPT]);
+
+		$diffKeys = array_keys(array_diff($arr1, $arr2));
+
+		$expectedDiff = array(MediaPeer::COVER_IMAGE, MediaPeer::EXCERPT);
+
+		$this->assertEquals($expectedDiff, $diffKeys);
+	}
+
+	/**
+	 * Test regexp validator for ticket:542
+	 * @link       http://propel.phpdb.org/trac/ticket/542
+	 */
+	public function testRegexValidator()
+	{
+		$b = new Bookstore();
+		$b->setWebsite("http://this.is.valid.com/foo.bar");
+		$res = $b->validate();
+		$this->assertTrue($res, "Expected URL to validate");
+	}
+
+	/**
+	 * Test that setting the auto-increment primary key will result in exception.
+	 */
+	public function testSettingAutoIncrementPK()
+	{
+		$b = new Bookstore();
+		$b->setId(1);
+		$b->setStoreName("Test");
+		try {
+			$b->save();
+			$this->fail("Expected setting auto-increment primary key to result in Exception");
+		} catch (Exception $x) {
+			$this->assertType('PropelException', $x);
+		}
+
+		// ... but we should silently ignore NULL values, since these are really
+		// the same as "not set" in PHP world.
+		$b = new Bookstore();
+		$b->setId(null);
+		$b->setStoreName("Test2");
+		try {
+			$b->save();
+		} catch (Exception $x) {
+			$this->fail("Expected no exception when setting auto-increment primary key to NULL");
+		}
+		// success ...
+	}
+	
+	/**
+	 * Checks wether we are allowed to specify the primary key on a 
+	 * table with allowPkInsert=true set
+         *
+	 * saves the object, gets it from data-source again and then compares
+	 * them for equality (thus the instance pool is also checked) 
+	 */
+	public function testAllowPkInsertOnIdMethodNativeTable()
+	{
+		$cu = new Customer;
+		$cu->setPrimaryKey(100000);
+		
+		$cu->save();
+		
+		$cu2 = CustomerPeer::retrieveByPk(100000);
+				
+		$this->assertSame($cu, $cu2);
+	}
+	/**
+	 * Checks if it is allowed to save new, empty objects with a auto increment column
+	 */
+	public function testAllowEmptyWithAutoIncrement()
+	{
+		$bookreader = new BookReader();
+		$bookreader->save();
+				
+		$this->assertFalse($bookreader->isNew() );
+	}
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/test/classes/propel/GeneratedPeerTest.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/test/classes/propel/GeneratedPeerTest.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/test/classes/propel/GeneratedPeerTest.php	(revision 19)
@@ -0,0 +1,852 @@
+<?php
+/*
+ *  $Id: GeneratedPeerTest.php 1049 2008-05-23 00:47:40Z hans $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://propel.phpdb.org>.
+ */
+
+require_once 'bookstore/BookstoreTestBase.php';
+
+/**
+ * Tests the generated Peer classes.
+ *
+ * This test uses generated Bookstore classes to test the behavior of various
+ * peer operations.
+ *
+ * The database is relaoded before every test and flushed after every test.  This
+ * means that you can always rely on the contents of the databases being the same
+ * for each test method in this class.  See the BookstoreDataPopulator::populate()
+ * method for the exact contents of the database.
+ *
+ * @see        BookstoreDataPopulator
+ * @author     Hans Lellelid <hans@xmpl.org>
+ */
+class GeneratedPeerTest extends BookstoreTestBase {
+
+	/**
+	 * Test ability to delete multiple rows via single Criteria object.
+	 */
+	public function testDoDelete_MultiTable() {
+
+		$selc = new Criteria();
+		$selc->add(BookPeer::TITLE, "Harry Potter and the Order of the Phoenix");
+		$hp = BookPeer::doSelectOne($selc);
+
+		// print "Attempting to delete [multi-table] by found pk: ";
+		$c = new Criteria();
+		$c->add(BookPeer::ID, $hp->getId());
+		// The only way for multi-delete to work currently
+		// is to specify the author_id and publisher_id (i.e. the fkeys
+		// have to be in the criteria).
+		$c->add(AuthorPeer::ID, $hp->getAuthorId());
+		$c->add(PublisherPeer::ID, $hp->getPublisherId());
+		$c->setSingleRecord(true);
+		BookPeer::doDelete($c);
+
+		//print_r(AuthorPeer::doSelect(new Criteria()));
+
+		// check to make sure the right # of records was removed
+		$this->assertEquals(3, count(AuthorPeer::doSelect(new Criteria())), "Expected 3 authors after deleting.");
+		$this->assertEquals(3, count(PublisherPeer::doSelect(new Criteria())), "Expected 3 publishers after deleting.");
+		$this->assertEquals(3, count(BookPeer::doSelect(new Criteria())), "Expected 3 books after deleting.");
+	}
+
+	/**
+	 * Test using a complex criteria to delete multiple rows from a single table.
+	 */
+	public function testDoDelete_ComplexCriteria() {
+
+		//print "Attempting to delete books by complex criteria: ";
+		$c = new Criteria();
+		$cn = $c->getNewCriterion(BookPeer::ISBN, "043935806X");
+		$cn->addOr($c->getNewCriterion(BookPeer::ISBN, "0380977427"));
+		$cn->addOr($c->getNewCriterion(BookPeer::ISBN, "0140422161"));
+		$c->add($cn);
+		BookPeer::doDelete($c);
+
+		// now there should only be one book left; "The Tin Drum"
+
+		$books = BookPeer::doSelect(new Criteria());
+
+		$this->assertEquals(1, count($books), "Expected 1 book remaining after deleting.");
+		$this->assertEquals("The Tin Drum", $books[0]->getTitle(), "Expect the only remaining book to be 'The Tin Drum'");
+	}
+
+	/**
+	 * Test that cascading deletes are happening correctly (whether emulated or native).
+	 */
+	public function testDoDelete_Cascade_Simple()
+	{
+
+		// The 'media' table will cascade from book deletes
+
+		// 1) Assert the row exists right now
+
+		$medias = MediaPeer::doSelect(new Criteria());
+		$this->assertTrue(count($medias) > 0, "Expected to find at least one row in 'media' table.");
+		$media = $medias[0];
+		$mediaId = $media->getId();
+
+		// 2) Delete the owning book
+
+		$owningBookId = $media->getBookId();
+		BookPeer::doDelete($owningBookId);
+
+		// 3) Assert that the media row is now also gone
+
+		$obj = MediaPeer::retrieveByPK($mediaId);
+		$this->assertNull($obj, "Expect NULL when retrieving on no matching Media.");
+
+	}
+
+	/**
+	 * Test that cascading deletes are happening correctly for composite pk.
+	 * @link       http://propel.phpdb.org/trac/ticket/544
+	 */
+	public function testDoDelete_Cascade_CompositePK()
+	{
+
+		$origBceCount = BookstoreContestEntryPeer::doCount(new Criteria());
+
+		$cust1 = new Customer();
+		$cust1->setName("Cust1");
+		$cust1->save();
+
+		$cust2 = new Customer();
+		$cust2->setName("Cust2");
+		$cust2->save();
+
+		$c1 = new Contest();
+		$c1->setName("Contest1");
+		$c1->save();
+
+		$c2 = new Contest();
+		$c2->setName("Contest2");
+		$c2->save();
+
+		$store1 = new Bookstore();
+		$store1->setStoreName("Store1");
+		$store1->save();
+
+		$bc1 = new BookstoreContest();
+		$bc1->setBookstore($store1);
+		$bc1->setContest($c1);
+		$bc1->save();
+
+		$bc2 = new BookstoreContest();
+		$bc2->setBookstore($store1);
+		$bc2->setContest($c2);
+		$bc2->save();
+
+		$bce1 = new BookstoreContestEntry();
+		$bce1->setEntryDate("now");
+		$bce1->setCustomer($cust1);
+		$bce1->setBookstoreContest($bc1);
+		$bce1->save();
+
+		$bce2 = new BookstoreContestEntry();
+		$bce2->setEntryDate("now");
+		$bce2->setCustomer($cust1);
+		$bce2->setBookstoreContest($bc2);
+		$bce2->save();
+
+		// Now, if we remove $bc1, we expect *only* bce1 to be no longer valid.
+
+		BookstoreContestPeer::doDelete($bc1);
+
+		$newCount = BookstoreContestEntryPeer::doCount(new Criteria());
+
+		$this->assertEquals($origBceCount + 1, $newCount, "Expected new number of rows in BCE to be orig + 1");
+
+		$bcetest = BookstoreContestEntryPeer::retrieveByPK($store1->getId(), $c1->getId(), $cust1->getId());
+		$this->assertNull($bcetest, "Expected BCE for store1 to be cascade deleted.");
+
+		$bcetest2 = BookstoreContestEntryPeer::retrieveByPK($store1->getId(), $c2->getId(), $cust1->getId());
+		$this->assertNotNull($bcetest2, "Expected BCE for store2 to NOT be cascade deleted.");
+
+	}
+
+	/**
+	 * Test that onDelete="SETNULL" is happening correctly (whether emulated or native).
+	 */
+	public function testDoDelete_SetNull() {
+
+		// The 'author_id' column in 'book' table will be set to null when author is deleted.
+
+		// 1) Get an arbitrary book
+		$c = new Criteria();
+		$book = BookPeer::doSelectOne($c);
+		$bookId = $book->getId();
+		$authorId = $book->getAuthorId();
+		unset($book);
+
+		// 2) Delete the author for that book
+		AuthorPeer::doDelete($authorId);
+
+		// 3) Assert that the book.author_id column is now NULL
+
+		$book = BookPeer::retrieveByPK($bookId);
+		$this->assertNull($book->getAuthorId(), "Expect the book.author_id to be NULL after the author was removed.");
+
+	}
+
+	/**
+	 * Test deleting a row by passing in the primary key to the doDelete() method.
+	 */
+	public function testDoDelete_ByPK() {
+
+		// 1) get an arbitrary book
+		$book = BookPeer::doSelectOne(new Criteria());
+		$bookId = $book->getId();
+
+		// 2) now delete that book
+		BookPeer::doDelete($bookId);
+
+		// 3) now make sure it's gone
+		$obj = BookPeer::retrieveByPK($bookId);
+		$this->assertNull($obj, "Expect NULL when retrieving on no matching Book.");
+
+	}
+
+	/**
+	 * Test deleting a row by passing the generated object to doDelete().
+	 */
+	public function testDoDelete_ByObj() {
+
+		// 1) get an arbitrary book
+		$book = BookPeer::doSelectOne(new Criteria());
+		$bookId = $book->getId();
+
+		// 2) now delete that book
+		BookPeer::doDelete($book);
+
+		// 3) now make sure it's gone
+		$obj = BookPeer::retrieveByPK($bookId);
+		$this->assertNull($obj, "Expect NULL when retrieving on no matching Book.");
+
+	}
+
+
+	/**
+	 * Test the doDeleteAll() method for single table.
+	 */
+	public function testDoDeleteAll() {
+
+		BookPeer::doDeleteAll();
+		$this->assertEquals(0, count(BookPeer::doSelect(new Criteria())), "Expect all book rows to have been deleted.");
+	}
+
+	/**
+	 * Test the doDeleteAll() method when onDelete="CASCADE".
+	 */
+	public function testDoDeleteAll_Cascade() {
+
+		BookPeer::doDeleteAll();
+		$this->assertEquals(0, count(MediaPeer::doSelect(new Criteria())), "Expect all media rows to have been cascade deleted.");
+		$this->assertEquals(0, count(ReviewPeer::doSelect(new Criteria())), "Expect all review rows to have been cascade deleted.");
+	}
+
+	/**
+	 * Test the doDeleteAll() method when onDelete="SETNULL".
+	 */
+	public function testDoDeleteAll_SetNull() {
+
+		$c = new Criteria();
+		$c->add(BookPeer::AUTHOR_ID, null, Criteria::NOT_EQUAL);
+
+		// 1) make sure there are some books with valid authors
+		$this->assertTrue(count(BookPeer::doSelect($c)) > 0, "Expect some book.author_id columns that are not NULL.");
+
+		// 2) delete all the authors
+		AuthorPeer::doDeleteAll();
+
+		// 3) now verify that the book.author_id columns are all nul
+		$this->assertEquals(0, count(BookPeer::doSelect($c)), "Expect all book.author_id columns to be NULL.");
+	}
+
+	/**
+	 * Test the doInsert() method when passed a Criteria object.
+	 */
+	public function testDoInsert_Criteria() {
+
+		$name = "A Sample Publisher - " . time();
+
+		$values = new Criteria();
+		$values->add(PublisherPeer::NAME, $name);
+		PublisherPeer::doInsert($values);
+
+		$c = new Criteria();
+		$c->add(PublisherPeer::NAME, $name);
+
+		$matches = PublisherPeer::doSelect($c);
+		$this->assertEquals(1, count($matches), "Expect there to be exactly 1 publisher just-inserted.");
+		$this->assertTrue( 1 != $matches[0]->getId(), "Expected to have different ID than one put in values Criteria.");
+
+	}
+
+	/**
+	 * Test the doInsert() method when passed a generated object.
+	 */
+	public function testDoInsert_Obj() {
+
+		$name = "A Sample Publisher - " . time();
+
+		$values = new Publisher();
+		$values->setName($name);
+		PublisherPeer::doInsert($values);
+
+		$c = new Criteria();
+		$c->add(PublisherPeer::NAME, $name);
+
+		$matches = PublisherPeer::doSelect($c);
+		$this->assertEquals(1, count($matches), "Expect there to be exactly 1 publisher just-inserted.");
+		$this->assertTrue( 1 != $matches[0]->getId(), "Expected to have different ID than one put in values Criteria.");
+
+	}
+
+	/**
+	 * Tests performing doSelect() and doSelectJoin() using LIMITs.
+	 */
+	public function testDoSelect_Limit() {
+
+		// 1) get the total number of items in a particular table
+		$count = BookPeer::doCount(new Criteria());
+
+		$this->assertTrue($count > 1, "Need more than 1 record in books table to perform this test.");
+
+		$limitcount = $count - 1;
+
+		$lc = new Criteria();
+		$lc->setLimit($limitcount);
+
+		$results = BookPeer::doSelect($lc);
+
+		$this->assertEquals($limitcount, count($results), "Expected $limitcount results from BookPeer::doSelect()");
+
+		// re-create it just to avoid side-effects
+		$lc2 = new Criteria();
+		$lc2->setLimit($limitcount);
+		$results2 = BookPeer::doSelectJoinAuthor($lc2);
+
+		$this->assertEquals($limitcount, count($results2), "Expected $limitcount results from BookPeer::doSelectJoinAuthor()");
+
+	}
+
+	/**
+	 * Test the basic functionality of the doSelectJoin*() methods.
+	 */
+	public function testDoSelectJoin()
+	{
+
+		BookPeer::clearInstancePool();
+
+		$c = new Criteria();
+
+		$books = BookPeer::doSelect($c);
+		$obj = $books[0];
+		$size = strlen(serialize($obj));
+
+		BookPeer::clearInstancePool();
+
+		$joinBooks = BookPeer::doSelectJoinAuthor($c);
+		$obj2 = $joinBooks[0];
+		$joinSize = strlen(serialize($obj2));
+
+		$this->assertEquals(count($books), count($joinBooks), "Expected to find same number of rows in doSelectJoin*() call as doSelect() call.");
+
+		$this->assertTrue($joinSize > $size, "Expected a serialized join object to be larger than a non-join object.");
+	}
+
+	/**
+	 * Test the doSelectJoin*() methods when the related object is NULL.
+	 */
+	public function testDoSelectJoin_NullFk()
+	{
+		$b1 = new Book();
+		$b1->setTitle("Test NULLFK 1");
+		$b1->setISBN("NULLFK-1");
+		$b1->save();
+
+		$b2 = new Book();
+		$b2->setTitle("Test NULLFK 2");
+		$b2->setISBN("NULLFK-2");
+		$b2->setAuthor(new Author());
+		$b2->getAuthor()->setFirstName("Hans")->setLastName("L");
+		$b2->save();
+
+		BookPeer::clearInstancePool();
+		AuthorPeer::clearInstancePool();
+
+		$c = new Criteria();
+		$c->add(BookPeer::ISBN, 'NULLFK-%', Criteria::LIKE);
+		$c->addAscendingOrderByColumn(BookPeer::ISBN);
+
+		$matches = BookPeer::doSelectJoinAuthor($c);
+		$this->assertEquals(2, count($matches), "Expected 2 matches back from new books; got back " . count($matches));
+
+		$this->assertNull($matches[0]->getAuthor(), "Expected first book author to be null");
+		$this->assertType('Author', $matches[1]->getAuthor(), "Expected valid Author object for second book.");
+	}
+
+	public function testObjectInstances()
+	{
+
+		$sample = BookPeer::doSelectOne(new Criteria());
+		$samplePk = $sample->getPrimaryKey();
+
+		// 1) make sure consecutive calls to retrieveByPK() return the same object.
+
+		$b1 = BookPeer::retrieveByPK($samplePk);
+		$b2 = BookPeer::retrieveByPK($samplePk);
+
+		$sampleval = md5(microtime());
+
+		$this->assertTrue($b1 === $b2, "Expected object instances to match for calls with same retrieveByPK() method signature.");
+
+		// 2) make sure that calls to doSelect also return references to the same objects.
+		$allbooks = BookPeer::doSelect(new Criteria());
+		foreach ($allbooks as $testb) {
+			if ($testb->getPrimaryKey() == $b1->getPrimaryKey()) {
+				$this->assertTrue($testb === $b1, "Expected same object instance from doSelect() as from retrieveByPK()");
+			}
+		}
+
+		// 3) test fetching related objects
+		$book = BookPeer::retrieveByPK($samplePk);
+
+		$bookauthor = $book->getAuthor();
+
+		$author = AuthorPeer::retrieveByPK($bookauthor->getId());
+
+		$this->assertTrue($bookauthor === $author, "Expected same object instance when calling fk object accessor as retrieveByPK()");
+
+		// 4) test a doSelectJoin()
+		$morebooks = BookPeer::doSelectJoinAuthor(new Criteria());
+		for ($i=0,$j=0; $j < count($morebooks); $i++, $j++) {
+			$testb1 = $allbooks[$i];
+			$testb2 = $allbooks[$j];
+			$this->assertTrue($testb1 === $testb2, "Expected the same objects from consecutive doSelect() calls.");
+			// we could probably also test this by just verifying that $book & $testb are the same
+			if ($testb1->getPrimaryKey() === $book) {
+				$this->assertTrue($book->getAuthor() === $testb1->getAuthor(), "Expected same author object in calls to pkey-matching books.");
+			}
+		}
+
+
+		// 5) test creating a new object, saving it, and then retrieving that object (should all be same instance)
+		$b = new BookstoreEmployee();
+		$b->setName("Testing");
+		$b->setJobTitle("Testing");
+		$b->save();
+
+		$empId = $b->getId();
+
+		$this->assertSame($b, BookstoreEmployeePeer::retrieveByPK($empId), "Expected newly saved object to be same instance as pooled.");
+
+	}
+
+	/**
+	 * Test inheritance features.
+	 */
+	public function testInheritance()
+	{
+		$manager = new BookstoreManager();
+		$manager->setName("Manager 1");
+		$manager->setJobTitle("Warehouse Manager");
+		$manager->save();
+		$managerId = $manager->getId();
+
+		$employee = new BookstoreEmployee();
+		$employee->setName("Employee 1");
+		$employee->setJobTitle("Janitor");
+		$employee->setSupervisorId($managerId);
+		$employee->save();
+		$empId = $employee->getId();
+
+		$cashier = new BookstoreCashier();
+		$cashier->setName("Cashier 1");
+		$cashier->setJobTitle("Cashier");
+		$cashier->save();
+		$cashierId = $cashier->getId();
+
+		// 1) test the pooled instances'
+		$c = new Criteria();
+		$c->add(BookstoreEmployeePeer::ID, array($managerId, $empId, $cashierId), Criteria::IN);
+		$c->addAscendingOrderByColumn(BookstoreEmployeePeer::ID);
+
+		$objects = BookstoreEmployeePeer::doSelect($c);
+
+		$this->assertEquals(3, count($objects), "Expected 3 objects to be returned.");
+
+		list($o1, $o2, $o3) = $objects;
+
+		$this->assertSame($o1, $manager);
+		$this->assertSame($o2, $employee);
+		$this->assertSame($o3, $cashier);
+
+		// 2) test a forced reload from database
+		BookstoreEmployeePeer::clearInstancePool();
+
+		list($o1,$o2,$o3) = BookstoreEmployeePeer::doSelect($c);
+
+		$this->assertTrue($o1 instanceof BookstoreManager, "Expected BookstoreManager object, got " . get_class($o1));
+		$this->assertTrue($o2 instanceof BookstoreEmployee, "Expected BookstoreEmployee object, got " . get_class($o2));
+		$this->assertTrue($o3 instanceof BookstoreCashier, "Expected BookstoreCashier object, got " . get_class($o3));
+
+	}
+
+	/**
+	 * Tests the return type of doCount*() methods.
+	 */
+	public function testDoCountType()
+	{
+		$c = new Criteria();
+		$this->assertType('integer', BookPeer::doCount($c), "Expected doCount() to return an integer.");
+		$this->assertType('integer', BookPeer::doCountJoinAll($c), "Expected doCountJoinAll() to return an integer.");
+		$this->assertType('integer', BookPeer::doCountJoinAuthor($c), "Expected doCountJoinAuthor() to return an integer.");
+	}
+
+	/**
+	 * Tests the doCount() method with limit/offset.
+	 */
+	public function testDoCountLimitOffset()
+	{
+		BookPeer::doDeleteAll();
+
+		for ($i=0; $i < 25; $i++) {
+			$b = new Book();
+			$b->setTitle("Book $i");
+			$b->setISBN("ISBN $i");
+			$b->save();
+		}
+
+		$c = new Criteria();
+		$totalCount = BookPeer::doCount($c);
+
+		$this->assertEquals(25, $totalCount);
+
+		$c2 = new Criteria();
+		$c2->setLimit(10);
+		$this->assertEquals(10, BookPeer::doCount($c2));
+
+		$c3 = new Criteria();
+		$c3->setOffset(10);
+		$this->assertEquals(15, BookPeer::doCount($c3));
+
+		$c4 = new Criteria();
+		$c4->setOffset(5);
+		$c4->setLimit(5);
+		$this->assertEquals(5, BookPeer::doCount($c4));
+
+		$c5 = new Criteria();
+		$c5->setOffset(20);
+		$c5->setLimit(10);
+		$this->assertEquals(5, BookPeer::doCount($c5));
+	}
+
+	/**
+	 * Test doCountJoin*() methods.
+	 */
+	public function testDoCountJoin()
+	{
+		BookPeer::doDeleteAll();
+
+		for ($i=0; $i < 25; $i++) {
+			$b = new Book();
+			$b->setTitle("Book $i");
+			$b->setISBN("ISBN $i");
+			$b->save();
+		}
+
+		$c = new Criteria();
+		$totalCount = BookPeer::doCount($c);
+
+		$this->assertEquals($totalCount, BookPeer::doCountJoinAuthor($c));
+		$this->assertEquals($totalCount, BookPeer::doCountJoinPublisher($c));
+	}
+
+	/**
+	 * Test passing null values to removeInstanceFromPool().
+	 */
+	public function testRemoveInstanceFromPool_Null()
+	{
+		// if it throws an exception, then it's broken.
+		try {
+			BookPeer::removeInstanceFromPool(null);
+		} catch (Exception $x) {
+			$this->fail("Expected to get no exception when removing an instance from the pool.");
+		}
+	}
+
+	/**
+	 * @see        testDoDeleteCompositePK()
+	 */
+	private function createBookWithId($id)
+	{
+		$con = Propel::getConnection(BookPeer::DATABASE_NAME);
+		$b = BookPeer::retrieveByPK($id);
+		if (!$b) {
+			$b = new Book();
+			$b->setTitle("Book$id")->setISBN("BookISBN$id")->save();
+			$b1Id = $b->getId();
+			$sql = "UPDATE " . BookPeer::TABLE_NAME . " SET id = ? WHERE id = ?";
+			$stmt = $con->prepare($sql);
+			$stmt->bindValue(1, $id);
+			$stmt->bindValue(2, $b1Id);
+			$stmt->execute();
+		}
+	}
+
+	/**
+	 * @see        testDoDeleteCompositePK()
+	 */
+	private function createReaderWithId($id)
+	{
+		$con = Propel::getConnection(BookReaderPeer::DATABASE_NAME);
+		$r = BookReaderPeer::retrieveByPK($id);
+		if (!$r) {
+			$r = new BookReader();
+			$r->setName('Reader'.$id)->save();
+			$r1Id = $r->getId();
+			$sql = "UPDATE " . BookReaderPeer::TABLE_NAME . " SET id = ? WHERE id = ?";
+			$stmt = $con->prepare($sql);
+			$stmt->bindValue(1, $id);
+			$stmt->bindValue(2, $r1Id);
+			$stmt->execute();
+		}
+	}
+
+	/**
+	 * @link       http://propel.phpdb.org/trac/ticket/519
+	 */
+	public function testDoDeleteCompositePK()
+	{
+		$con = Propel::getConnection(BookPeer::DATABASE_NAME);
+
+		ReaderFavoritePeer::doDeleteAll();
+		// Create book and reader with ID 1
+		// Create book and reader with ID 2
+
+		$this->createBookWithId(1);
+		$this->createBookWithId(2);
+		$this->createReaderWithId(1);
+		$this->createReaderWithId(2);
+
+		for ($i=1; $i <= 2; $i++) {
+			for ($j=1; $j <= 2; $j++) {
+				$bo = new BookOpinion();
+				$bo->setBookId($i);
+				$bo->setReaderId($j);
+				$bo->save();
+				
+				$rf = new ReaderFavorite();
+				$rf->setBookId($i);
+				$rf->setReaderId($j);
+				$rf->save();
+			}
+		}
+
+		$this->assertEquals(4, ReaderFavoritePeer::doCount(new Criteria()));
+
+		// Now delete 2 of those rows
+		ReaderFavoritePeer::doDelete(array(array(1,1), array(2,2)));
+
+		$this->assertEquals(2, ReaderFavoritePeer::doCount(new Criteria()));
+
+		$this->assertNotNull(ReaderFavoritePeer::retrieveByPK(2,1));
+		$this->assertNotNull(ReaderFavoritePeer::retrieveByPK(1,2));
+		$this->assertNull(ReaderFavoritePeer::retrieveByPK(1,1));
+		$this->assertNull(ReaderFavoritePeer::retrieveByPK(2,2));
+	}
+
+
+	/**
+	 * Test hydration of joined rows that contain lazy load columns.
+	 * @link       http://propel.phpdb.org/trac/ticket/464
+	 */
+	public function testHydrationJoinLazyLoad()
+	{
+		BookstoreEmployeeAccountPeer::doDeleteAll();
+		BookstoreEmployeePeer::doDeleteAll();
+		AcctAccessRolePeer::doDeleteAll();
+
+		$bemp2 = new BookstoreEmployee();
+		$bemp2->setName("Pieter");
+		$bemp2->setJobTitle("Clerk");
+		$bemp2->save();
+
+		$role = new AcctAccessRole();
+		$role->setName("Admin");
+
+		$bempacct = new BookstoreEmployeeAccount();
+		$bempacct->setBookstoreEmployee($bemp2);
+		$bempacct->setAcctAccessRole($role);
+		$bempacct->setLogin("john");
+		$bempacct->setPassword("johnp4ss");
+		$bempacct->save();
+
+		$c = new Criteria();
+		$results = BookstoreEmployeeAccountPeer::doSelectJoinAll($c);
+		$o = $results[0];
+
+		$this->assertEquals('Admin', $o->getAcctAccessRole()->getName());
+	}
+
+	/**
+	 * Testing foreign keys with multiple referrer columns.
+	 * @link       http://propel.phpdb.org/trac/ticket/606
+	 */
+	public function testMultiColFk()
+	{
+		$con = Propel::getConnection(BookPeer::DATABASE_NAME);
+
+		ReaderFavoritePeer::doDeleteAll();
+		
+		$b1 = new Book();
+		$b1->setTitle("Book1");
+		$b1->setISBN("ISBN-1");
+		$b1->save();
+		
+		$r1 = new BookReader();
+		$r1-> setName("Me");
+		$r1->save();
+		
+		$bo1 = new BookOpinion();
+		$bo1->setBookId($b1->getId());
+		$bo1->setReaderId($r1->getId());
+		$bo1->setRating(9);
+		$bo1->setRecommendToFriend(true);
+		$bo1->save();
+		
+		$rf1 = new ReaderFavorite();
+		$rf1->setReaderId($r1->getId());
+		$rf1->setBookId($b1->getId());
+		$rf1->save();
+		
+		$c = new Criteria(ReaderFavoritePeer::DATABASE_NAME);
+		$c->add(ReaderFavoritePeer::BOOK_ID, $b1->getId());
+		$c->add(ReaderFavoritePeer::READER_ID, $r1->getId());
+		
+		// This will produce an error!
+		$results = ReaderFavoritePeer::doSelectJoinBookOpinion($c);
+		$this->assertEquals(1, count($results), "Expected 1 result");
+	}
+	/**
+	 * Testing foreign keys with multiple referrer columns.
+	 * @link       http://propel.phpdb.org/trac/ticket/606
+	 */
+	public function testMultiColJoin()
+	{
+		BookstoreContestPeer::doDeleteAll();
+		BookstoreContestEntryPeer::doDeleteAll();
+		
+		$bs = new Bookstore();
+		$bs->setStoreName("Test1");
+		$bs->setPopulationServed(5);
+		$bs->save();
+		$bs1Id = $bs->getId();
+		
+		$bs2 = new Bookstore();
+		$bs2->setStoreName("Test2");
+		$bs2->setPopulationServed(5);
+		$bs2->save();
+		$bs2Id = $bs2->getId();
+		
+		$ct1 = new Contest();
+		$ct1->setName("Contest1!");
+		$ct1->save();
+		$ct1Id = $ct1->getId();
+		
+		$ct2 = new Contest();
+		$ct2->setName("Contest2!");
+		$ct2->save();
+		$ct2Id = $ct2->getId();
+		
+		$cmr = new Customer();
+		$cmr->setName("Customer1");
+		$cmr->save();
+		$cmr1Id = $cmr->getId();
+
+		$cmr2 = new Customer();
+		$cmr2->setName("Customer2");
+		$cmr2->save();
+		$cmr2Id = $cmr2->getId();
+		
+		$contest = new BookstoreContest();
+		$contest->setBookstoreId($bs1Id);
+		$contest->setContestId($ct1Id);
+		$contest->save();
+		
+		$contest = new BookstoreContest();
+		$contest->setBookstoreId($bs2Id);
+		$contest->setContestId($ct1Id);
+		$contest->save();
+	
+		$entry = new BookstoreContestEntry();
+		$entry->setBookstoreId($bs1Id);
+		$entry->setContestId($ct1Id);
+		$entry->setCustomerId($cmr1Id);
+		$entry->save();
+		
+		$entry = new BookstoreContestEntry();
+		$entry->setBookstoreId($bs1Id);
+		$entry->setContestId($ct1Id);
+		$entry->setCustomerId($cmr2Id);
+		$entry->save();
+		
+		// Note: this test isn't really working very well.  We setup fkeys that
+		// require that the BookstoreContest rows exist and then try to violate
+		// the rules ... :-/  This may work in some lenient databases, but an error
+		// is expected here. 
+		
+		/*
+		 * Commented out for now ... though without it, this test may not really be testing anything
+		$entry = new BookstoreContestEntry();
+		$entry->setBookstoreId($bs1Id);
+		$entry->setContestId($ct2Id);
+		$entry->setCustomerId($cmr2Id);
+		$entry->save();
+		*/
+		
+	
+		$c = new Criteria();
+		$c->addJoin(array(BookstoreContestEntryPeer::BOOKSTORE_ID, BookstoreContestEntryPeer::CONTEST_ID), array(BookstoreContestPeer::BOOKSTORE_ID, BookstoreContestPeer::CONTEST_ID) );
+
+		$results = BookstoreContestEntryPeer::doSelect($c);
+		$this->assertEquals(2, count($results) );
+		foreach ($results as $result) {
+			$this->assertEquals($bs1Id, $result->getBookstoreId() );
+			$this->assertEquals($ct1Id, $result->getContestId() );
+		}
+	}
+	
+	
+	/**
+	 * Test doCountJoin*() methods with ORDER BY columns in Criteria.
+	 * @link http://propel.phpdb.org/trac/ticket/627
+	 */
+	public function testDoCountJoinWithOrderBy()
+	{
+		$c = new Criteria(BookPeer::DATABASE_NAME);
+		$c->addAscendingOrderByColumn(BookPeer::ID);
+		
+		// None of these should not throw an exception!
+		BookPeer::doCountJoinAll($c); 
+		BookPeer::doCountJoinAllExceptAuthor($c);
+		BookPeer::doCountJoinAuthor($c);
+	}
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/test/classes/propel/Ticket520Test.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/test/classes/propel/Ticket520Test.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/test/classes/propel/Ticket520Test.php	(revision 19)
@@ -0,0 +1,250 @@
+<?php
+require_once 'bookstore/BookstoreTestBase.php';
+
+/* It's only fair to admit that these tests were carefully crafted
+after studying the current implementation to make it look as bad as
+possible. I am really sorry. :-( */
+
+class Ticket520Test extends BookstoreTestBase {
+
+	public function testNewObjectsAvailableWhenSaveNotCalled() {
+		$a = new Author();
+		$a->setFirstName("Douglas");
+		$a->setLastName("Adams");
+
+		$b1 = new Book();
+		$b1->setTitle("The Hitchhikers Guide To The Galaxy");
+		$a->addBook($b1);
+
+		$b2 = new Book();
+		$b2->setTitle("The Restaurant At The End Of The Universe");
+		$a->addBook($b2);
+
+		/* As of revision 851, this passes as new objects (here: the Author)
+		always contain all added FK-related objects (here: the Books) in
+		their internal $colBooks collection. */
+		$books = $a->getBooks();
+		$this->assertContains($b1, $books);
+		$this->assertContains($b2, $books);
+	}
+
+	public function testNewObjectsWithCriteria() {
+
+		$a = new Author();
+		$a->setFirstName("Douglas");
+		$a->setLastName("Adams");
+
+		$b1 = new Book();
+		$b1->setTitle("The Hitchhikers Guide To The Galaxy");
+		$a->addBook($b1);
+
+		$b2 = new Book();
+		$b2->setTitle("The Restaurant At The End Of The Universe");
+		$a->addBook($b2);
+
+		$c = new Criteria();
+		$c->add(BookPeer::TITLE, "%Hitchhiker%", Criteria::LIKE);
+
+		/* As of revision 851, this fails because new objects like the Author
+		always contain added objects in their internal collection but are unable
+		to apply any Criteria. */
+
+		$guides = $a->getBooks($c);
+		$this->assertEquals(1, count($guides));
+		foreach ($guides as $book) {
+			$this->assertEquals($b1, $book);
+		}
+	}
+
+	public function testSavedObjectsWithCriteria() {
+		$a = new Author();
+		$a->setFirstName("Douglas");
+		$a->setLastName("Adams");
+
+		$b1 = new Book();
+		$b1->setTitle("The Hitchhikers Guide To The Galaxy");
+		$a->addBook($b1);
+
+		$b2 = new Book();
+		$b2->setTitle("The Restaurant At The End Of The Universe");
+		$a->addBook($b2);
+
+		$c = new Criteria();
+		$c->add(BookPeer::TITLE, "%Hitchhiker%", Criteria::LIKE);
+
+		/* This is the same as testNewObjectsWithCriteria EXCEPT we're now going
+		to save(). Now the $author and related objects are no longer new
+		and thus the criteria will be applied in the database.
+
+		Apart from that the fix is for sure not trivial, observable behaviour
+		of the $author should not depend on having called save() or not... */
+
+		$booksBeforeSave = $a->getBooks($c);
+		$a->save();
+		$booksAfterSave = $a->getBooks($c);
+
+		// As of revision 851, this passes...
+		$this->assertEquals(1, count($booksAfterSave));
+		foreach ($booksAfterSave as $book) {
+			$this->assertEquals($b1, $book);
+		}
+
+		/* ... but this would fail. Commented out because it's covered
+		by testNewObjectsWithCriteria(). */
+		//$this->assertEquals($booksBeforeSave, $booksAfterSave);
+	}
+
+	public function testAddNewObjectAfterSave() {
+		/* This is like testNewObjectsAvailableWhenSaveNotCalled(),
+		but this time we save the author before adding the book. */
+
+		$a = new Author();
+		$a->setFirstName("Douglas");
+		$a->setLastName("Adams");
+
+		$a->save();
+
+		$b1 = new Book();
+		$b1->setTitle("The Hitchhikers Guide To The Galaxy");
+		$a->addBook($b1);
+
+		/* As of revision 851, although testNewObjectsAvailableWhenSaveNotCalled()
+		worked, this will fail. Because the author has been saved this time,
+		it will only check the database and not see the new (unsaved) book. */
+		$books = $a->getBooks();
+		$this->assertEquals(1, count($books));
+		$this->assertContains($b1, $books);
+
+		/* Now this is the initial ticket 520: If we have a saved author,
+		add a new book but happen to call getBooks() before we call save() again,
+		the book is lost. As of revision 851, this will fail: */
+		$a->save();
+		$this->assertFalse($b1->isNew());
+
+	}
+
+	public function testAddNewObjectAfterSaveWithPoisonedCache() {
+		/* This is like testAddNewObjectAfterSave(),
+		but this time we "poison" the author's $colBooks cache
+		before adding the book by calling getBooks(). */
+
+		$a = new Author();
+		$a->setFirstName("Douglas");
+		$a->setLastName("Adams");
+
+		$a->save();
+		$a->getBooks();
+
+		$b1 = new Book();
+		$b1->setTitle("The Hitchhikers Guide To The Galaxy");
+		$a->addBook($b1);
+
+		/* As of revision 851, this passes. This is because the following
+		call will not look at the database because the same (nil) criteria
+		is used as in the call to getBooks() above. The book has been added to
+		the cache inside the Author object that now is returned. */
+		$books = $a->getBooks();
+		$this->assertEquals(1, count($books));
+		$this->assertContains($b1, $books);
+	}
+
+	public function testCachePoisoning() {
+		/* Like testAddNewObjectAfterSaveWithPoisonedCache, emphasizing
+		cache poisoning. */
+
+		$a = new Author();
+		$a->setFirstName("Douglas");
+		$a->setLastName("Adams");
+
+		$a->save();
+
+		$c = new Criteria();
+		$c->add(BookPeer::TITLE, "%Restaurant%", Criteria::LIKE);
+
+		$this->assertEquals(0, count($a->getBooks($c)));
+
+		$b1 = new Book();
+		$b1->setTitle("The Hitchhikers Guide To The Galaxy");
+		$a->addBook($b1);
+
+		/* Like testAddNewObjectAfterSaveWithPoisonedCache, but this time
+		with a real criteria. As of revision 851, this fails because
+		the $b1 is returned although it should not (does not match the
+		criteria). This is the first comment on the 520 ticket. */
+		$this->assertEquals(0, count($a->getBooks($c)));
+
+		/* If we called $a->getBooks() now, $b1 would be lost although
+		it should be in the result. Already covered by
+		testAddNewObjectAfterSave().
+
+		Instead, this time we call save() again, saving the book. However,
+		although everything is in the DB, the cache is still wrong like
+		in the assertion before. */
+		$a->save();
+		$this->assertFalse($b1->isNew());
+		$this->assertEquals(0, count($a->getBooks($c)));
+	}
+
+	public function testDeletedBookDisappears() {
+		$a = new Author();
+		$a->setFirstName("Douglas");
+		$a->setLastName("Adams");
+
+		$b1 = new Book();
+		$b1->setTitle("The Hitchhikers Guide To The Galaxy");
+		$a->addBook($b1);
+
+		$b2 = new Book();
+		$b2->setTitle("The Restaurant At The End Of The Universe");
+		$a->addBook($b2);
+
+		/* As you cannot write $a->remove($b2), you have to delete $b2
+		directly. */
+
+		/* All objects unsaved. As of revision 851, this circumvents the
+		$colBooks cache. Anyway, fails because getBooks() never checks if
+		a colBooks entry has been deleted. */
+		$this->assertEquals(2, count($a->getBooks()));
+		$b2->delete();
+		$this->assertEquals(1, count($a->getBooks()));
+
+		/* Even if we had saved everything before and the delete() had
+		actually updated the DB, the $b2 would still be a "zombie" in
+		$a's $colBooks field. */
+	}
+
+	public function testNewObjectsGetLostOnJoin() {
+		/* While testNewObjectsAvailableWhenSaveNotCalled passed as of
+		revision 851, in this case we call getBooksJoinPublisher() instead
+		of just getBooks(). get...Join...() does not contain the check whether
+		the current object is new, it will always consult the DB and lose the
+		new objects entirely. Thus the test fails. (At least for Propel 1.2 ?!?) */
+
+		$a = new Author();
+		$a->setFirstName("Douglas");
+		$a->setLastName("Adams");
+
+		$p = new Publisher();
+		$p->setName('Pan Books Ltd.');
+
+		$b1 = new Book();
+		$b1->setTitle("The Hitchhikers Guide To The Galaxy");
+		$b1->setPublisher($p); // uh... did not check that :^)
+		$a->addBook($b1);
+
+		$b2 = new Book();
+		$b2->setTitle("The Restaurant At The End Of The Universe");
+		$b2->setPublisher($p);
+		$a->addBook($b2);
+
+		$books = $a->getBooksJoinPublisher();
+		$this->assertEquals(2, count($books));
+		$this->assertContains($b1, $books);
+		$this->assertContains($b2, $books);
+
+		$a->save();
+		$this->assertFalse($b1->isNew());
+		$this->assertFalse($b2->isNew());
+	}
+
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/test/classes/propel/engine/database/model/ColumnTest.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/test/classes/propel/engine/database/model/ColumnTest.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/test/classes/propel/engine/database/model/ColumnTest.php	(revision 19)
@@ -0,0 +1,62 @@
+<?php
+
+/*
+ *  $Id: ColumnTest.php 759 2007-11-04 01:22:29Z heltem $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://propel.phpdb.org>.
+ */
+
+require_once 'PHPUnit/Framework/TestCase.php';
+require_once 'propel/engine/database/model/Column.php';
+include_once 'propel/engine/platform/MysqlPlatform.php';
+
+/**
+ * Tests for package handling.
+ *
+ * @author     <a href="mailto:mpoeschl@marmot.at>Martin Poeschl</a>
+ * @version    $Revision: 759 $
+ */
+class ColumnTest extends PHPUnit_Framework_TestCase {
+
+	/**
+	 * Tests static Column::makeList() method.
+	 * @deprecated - Column::makeList() is deprecated and set to be removed in 1.3
+	 */
+	public function testMakeList()
+	{
+		$expected = "`Column0`, `Column1`, `Column2`, `Column3`, `Column4`";
+		$objArray = array();
+		for ($i=0; $i<5; $i++) {
+			$c = new Column();
+			$c->setName("Column" . $i);
+			$objArray[] = $c;
+		}
+
+		$list = Column::makeList($objArray, new MySQLPlatform());
+		$this->assertEquals($expected, $list, sprintf("Expected '%s' match, got '%s' ", var_export($expected, true), var_export($list,true)));
+
+		$strArray = array();
+		for ($i=0; $i<5; $i++) {
+			$strArray[] = "Column" . $i;
+		}
+
+		$list = Column::makeList($strArray, new MySQLPlatform());
+		$this->assertEquals($expected, $list, sprintf("Expected '%s' match, got '%s' ", var_export($expected, true), var_export($list,true)));
+
+	}
+
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/test/classes/propel/engine/database/model/NameFactoryTest.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/test/classes/propel/engine/database/model/NameFactoryTest.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/test/classes/propel/engine/database/model/NameFactoryTest.php	(revision 19)
@@ -0,0 +1,162 @@
+<?php
+
+/*
+ *  $Id: NameFactoryTest.php 521 2007-01-05 13:29:36Z heltem $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://propel.phpdb.org>.
+ */
+
+require_once 'classes/propel/BaseTestCase.php';
+include_once 'propel/engine/database/model/NameFactory.php';
+include_once 'propel/engine/platform/MysqlPlatform.php';
+include_once 'propel/engine/database/model/AppData.php';
+
+/**
+ * <p>Unit tests for class <code>NameFactory</code> and known
+ * <code>NameGenerator</code> implementations.</p>
+ *
+ * <p>To add more tests, add entries to the <code>ALGORITHMS</code>,
+ * <code>INPUTS</code>, and <code>OUTPUTS</code> arrays, and code to
+ * the <code>makeInputs()</code> method.</p>
+ *
+ * <p>This test assumes that it's being run using the MySQL database
+ * adapter, <code>DBMM</code>.  MySQL has a column length limit of 64
+ * characters.</p>
+ *
+ * @author     <a href="mailto:dlr@collab.net">Daniel Rall</a>
+ * @version    $Id: NameFactoryTest.php 521 2007-01-05 13:29:36Z heltem $
+ */
+class NameFactoryTest extends BaseTestCase {
+
+	/** The database to mimic in generating the SQL. */
+	const DATABASE_TYPE = "mysql";
+
+	/**
+	 * The list of known name generation algorithms, specified as the
+	 * fully qualified class names to <code>NameGenerator</code>
+	 * implementations.
+	 */
+	private static $ALGORITHMS = array(NameFactory::CONSTRAINT_GENERATOR, NameFactory::PHP_GENERATOR);
+
+	/**
+	 * Two dimensional arrays of inputs for each algorithm.
+	 */
+	private static $INPUTS = array();
+
+
+	/**
+	 * Given the known inputs, the expected name outputs.
+	 */
+	private static $OUTPUTS = array();
+
+	/**
+	 * Used as an input.
+	 */
+	private $database;
+
+	/**
+	 * Creates a new instance.
+	 *
+	 */
+	public function __construct() {
+
+		self::$INPUTS = array(
+				array( array(self::makeString(61), "I", 1),
+						array(self::makeString(61), "I", 2),
+						array(self::makeString(65), "I", 3),
+						array(self::makeString(4), "FK", 1),
+						array(self::makeString(5), "FK", 2)
+					),
+				array(
+						array("MY_USER", NameGenerator::CONV_METHOD_UNDERSCORE),
+						array("MY_USER", NameGenerator::CONV_METHOD_PHPNAME),
+						array("MY_USER", NameGenerator::CONV_METHOD_NOCHANGE)
+					)
+				);
+
+
+		self::$OUTPUTS = array(
+						array(
+							self::makeString(60) . "_I_1",
+							self::makeString(60) . "_I_2",
+							self::makeString(60) . "_I_3",
+							self::makeString(4) . "_FK_1",
+							self::makeString(5) . "_FK_2"),
+						array("MyUser", "MYUSER", "MY_USER")
+					);
+
+	}
+
+	/**
+	 * Creates a string of the specified length consisting entirely of
+	 * the character <code>A</code>.  Useful for simulating table
+	 * names, etc.
+	 *
+	 * @param      int $len the number of characters to include in the string
+	 * @return     a string of length <code>len</code> with every character an 'A'
+	 */
+	private static function makeString($len) {
+		$buf = "";
+		for ($i = 0; $i < $len; $i++) {
+			$buf .= 'A';
+		}
+		return $buf;
+	}
+
+	/** Sets up the Propel model. */
+	public function setUp()
+	{
+		$appData = new AppData(new MysqlPlatform());
+		$this->database = new Database();
+		$appData->addDatabase($this->database);
+	}
+
+	/**
+	 * @throws     Exception on fail
+	 */
+	public function testNames() {
+		for ($algoIndex = 0; $algoIndex < count(self::$ALGORITHMS); $algoIndex++) {
+			$algo = self::$ALGORITHMS[$algoIndex];
+			$algoInputs = self::$INPUTS[$algoIndex];
+			for ($i = 0; $i < count($algoInputs); $i++) {
+				$inputs = $this->makeInputs($algo, $algoInputs[$i]);
+				$generated = NameFactory::generateName($algo, $inputs);
+				$expected = self::$OUTPUTS[$algoIndex][$i];
+				$this->assertEquals($expected, $generated, 0, "Algorithm " . $algo . " failed to generate an unique name");
+			}
+		}
+	}
+
+	/**
+	 * Creates the list of arguments to pass to the specified type of
+	 * <code>NameGenerator</code> implementation.
+	 *
+	 * @param      algo The class name of the <code>NameGenerator</code> to
+	 * create an argument list for.
+	 * @param      inputs The (possibly partial) list inputs from which to
+	 * generate the final list.
+	 * @return     the list of arguments to pass to the <code>NameGenerator</code>
+	 */
+	private function makeInputs($algo, $inputs)
+	{
+		if (NameFactory::CONSTRAINT_GENERATOR == $algo) {
+			array_unshift($inputs, $this->database);
+		}
+		return $inputs;
+	}
+
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/test/classes/propel/engine/database/model/TableTest.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/test/classes/propel/engine/database/model/TableTest.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/test/classes/propel/engine/database/model/TableTest.php	(revision 19)
@@ -0,0 +1,63 @@
+<?php
+
+/*
+ *  $Id: TableTest.php 759 2007-11-04 01:22:29Z heltem $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://propel.phpdb.org>.
+ */
+
+require_once 'PHPUnit/Framework/TestCase.php';
+include_once 'propel/engine/database/transform/XmlToAppData.php';
+include_once 'propel/engine/platform/MysqlPlatform.php';
+
+/**
+ * Tests for package handling.
+ *
+ * @author     <a href="mailto:mpoeschl@marmot.at>Martin Poeschl</a>
+ * @version    $Revision: 759 $
+ */
+class TableTest extends PHPUnit_Framework_TestCase {
+
+	private $xmlToAppData;
+	private $appData;
+
+	/**
+	 * test if the tables get the package name from the properties file
+	 *
+	 */
+	public function testIdMethodHandling() {
+		$this->xmlToAppData = new XmlToAppData(new MysqlPlatform(), "defaultpackage", null);
+
+		//$this->appData = $this->xmlToAppData->parseFile(dirname(__FILE__) . "/tabletest-schema.xml");
+		$this->appData = $this->xmlToAppData->parseFile("etc/schema/tabletest-schema.xml");
+
+		$db = $this->appData->getDatabase("iddb");
+		$expected = IDMethod::NATIVE;
+		$result = $db->getDefaultIdMethod();
+		$this->assertEquals($expected, $result);
+
+		$table2 = $db->getTable("table_native");
+		$expected = IDMethod::NATIVE;
+		$result = $table2->getIdMethod();
+		$this->assertEquals($expected, $result);
+
+		$table = $db->getTable("table_none");
+		$expected = IDMethod::NO_ID_METHOD;
+		$result = $table->getIdMethod();
+		$this->assertEquals($expected, $result);
+	}
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/test/classes/propel/engine/platform/DefaultPlatformTest.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/test/classes/propel/engine/platform/DefaultPlatformTest.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/test/classes/propel/engine/platform/DefaultPlatformTest.php	(revision 19)
@@ -0,0 +1,34 @@
+<?php
+
+require_once 'propel/engine/platform/PlatformTestBase.php';
+
+class DefaultPlatformTest extends PlatformTestBase {
+
+
+	protected function setUp()
+	{
+		parent::setUp();
+	}
+
+	public function tearDown()
+	{
+		 parent::tearDown();
+	}
+
+	public function testQuote()
+	{
+		$p = $this->getPlatform();
+
+		$unquoted = "Nice";
+		$quoted = $p->quote($unquoted);
+
+		$this->assertEquals("'$unquoted'", $quoted);
+
+
+		$unquoted = "Naughty ' string";
+		$quoted = $p->quote($unquoted);
+		$expected = "'Naughty '' string'";
+		$this->assertEquals($expected, $quoted);
+	}
+
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/test/classes/propel/engine/platform/PlatformTestBase.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/test/classes/propel/engine/platform/PlatformTestBase.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/test/classes/propel/engine/platform/PlatformTestBase.php	(revision 19)
@@ -0,0 +1,43 @@
+<?php
+
+require_once 'PHPUnit/Framework/TestCase.php';
+
+class PlatformTestBase extends PHPUnit_Framework_TestCase {
+
+	/**
+	 * Platform object.
+	 *
+	 * @var        Platform
+	 */
+	protected $platform;
+
+	/**
+	 *
+	 */
+	protected function setUp()
+	{
+		parent::setUp();
+
+		$clazz = preg_replace('/Test$/', '', get_class($this));
+		include_once 'propel/engine/platform/' . $clazz . '.php';
+		$this->platform = new $clazz();
+	}
+
+	/**
+	 *
+	 */
+	protected function tearDown()
+	{
+		parent::tearDown();
+	}
+
+	/**
+	 *
+	 * @return     Platform
+	 */
+	protected function getPlatform()
+	{
+		return $this->platform;
+	}
+
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/test/classes/propel/engine/platform/SqlitePlatformTest.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/test/classes/propel/engine/platform/SqlitePlatformTest.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/test/classes/propel/engine/platform/SqlitePlatformTest.php	(revision 19)
@@ -0,0 +1,36 @@
+<?php
+
+require_once 'propel/engine/platform/DefaultPlatformTest.php';
+
+class SqlitePlatformTest extends DefaultPlatformTest {
+
+	/**
+	 * @var        PDO The PDO connection to SQLite DB.
+	 */
+	private $pdo;
+
+	protected function setUp()
+	{
+		parent::setUp();
+		$this->pdo = new PDO("sqlite::memory:");
+
+	}
+
+	public function tearDown()
+	{
+		 parent::tearDown();
+	}
+
+	public function testQuoteConnected()
+	{
+		$p = $this->getPlatform();
+		$p->setConnection($this->pdo);
+
+		$unquoted = "Naughty ' string";
+		$quoted = $p->quote($unquoted);
+
+		$expected = "'Naughty '' string'";
+		$this->assertEquals($expected, $quoted);
+	}
+
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/test/classes/propel/util/BasePeerTest.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/test/classes/propel/util/BasePeerTest.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/test/classes/propel/util/BasePeerTest.php	(revision 19)
@@ -0,0 +1,111 @@
+<?php
+/*
+ *  $Id: BasePeerTest.php 989 2008-03-11 14:29:30Z heltem $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://propel.phpdb.org>.
+ */
+
+require_once 'bookstore/BookstoreTestBase.php';
+
+/**
+ * Tests the BasePeer classes.
+ *
+ * @see        BookstoreDataPopulator
+ * @author     Hans Lellelid <hans@xmpl.org>
+ */
+class BasePeerTest extends BookstoreTestBase {
+
+	protected function setUp()
+	{
+		parent::setUp();
+	}
+
+	protected function tearDown()
+	{
+		parent::tearDown();
+	}
+
+	/**
+	 * @link       http://propel.phpdb.org/trac/ticket/425
+	 */
+	public function testMultipleFunctionInCriteria()
+	{
+		$db = Propel::getDB(BookPeer::DATABASE_NAME);
+		try {
+			$c = new Criteria();
+			$c->setDistinct();
+			if ($db instanceof DBPostgres) {
+				$c->addSelectColumn("substring(".BookPeer::TITLE." from position('Potter' in ".BookPeer::TITLE.")) AS col");
+			} else {
+				$this->markTestSkipped();
+			}
+			$stmt = BookPeer::doSelectStmt( $c );
+		} catch (PropelException $x) {
+			$this->fail("Paring of nested functions failed: " . $x->getMessage());
+		}
+	}
+
+	/**
+	 *
+	 */
+	public function testBigIntIgnoreCaseOrderBy()
+	{
+		// Some sample data
+		$b = new Bookstore();
+		$b->setStoreName("SortTest1")->setPopulationServed(2000)->save();
+
+		$b = new Bookstore();
+		$b->setStoreName("SortTest2")->setPopulationServed(201)->save();
+
+		$b = new Bookstore();
+		$b->setStoreName("SortTest3")->setPopulationServed(302)->save();
+
+		$b = new Bookstore();
+		$b->setStoreName("SortTest4")->setPopulationServed(10000000)->save();
+
+		$c = new Criteria();
+		$c->setIgnoreCase(true);
+		$c->add(BookstorePeer::STORE_NAME, 'SortTest%', Criteria::LIKE);
+		$c->addAscendingOrderByColumn(BookstorePeer::POPULATION_SERVED);
+
+		$rows = BookstorePeer::doSelect($c);
+		$this->assertEquals('SortTest2', $rows[0]->getStoreName());
+		$this->assertEquals('SortTest3', $rows[1]->getStoreName());
+		$this->assertEquals('SortTest1', $rows[2]->getStoreName());
+		$this->assertEquals('SortTest4', $rows[3]->getStoreName());
+	}
+
+	/**
+	 *
+	 */
+	public function testMixedJoinOrder()
+	{
+		$this->markTestIncomplete();
+		$c = new Criteria(BookPeer::DATABASE_NAME);
+		$c->addSelectColumn(BookPeer::ID);
+		$c->addSelectColumn(BookPeer::TITLE);
+
+		$c->addJoin(BookPeer::PUBLISHER_ID, PublisherPeer::ID, Criteria::LEFT_JOIN);
+		$c->addJoin(BookPeer::AUTHOR_ID, AuthorPeer::ID);
+
+		$params = array();
+		$sql = BasePeer::createSelectSql($c, $params);
+
+		$expectedSql = "SELECT book.ID, book.TITLE FROM book LEFT JOIN publisher ON (book.PUBLISHER_ID=publisher.ID), author WHERE book.AUTHOR_ID=author.ID";
+		// print $sql . "\n";
+	}
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/test/classes/propel/util/CriteriaTest.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/test/classes/propel/util/CriteriaTest.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/test/classes/propel/util/CriteriaTest.php	(revision 19)
@@ -0,0 +1,638 @@
+<?php
+
+require_once 'classes/propel/BaseTestCase.php';
+include_once 'propel/util/Criteria.php';
+include_once 'propel/util/BasePeer.php';
+
+/**
+ * Test class for Criteria.
+ *
+ * @author     <a href="mailto:celkins@scardini.com">Christopher Elkins</a>
+ * @author     <a href="mailto:sam@neurogrid.com">Sam Joseph</a>
+ * @version    $Id: CriteriaTest.php 1057 2008-06-02 23:27:29Z hans $
+ */
+class CriteriaTest extends BaseTestCase {
+
+	/**
+	 * The criteria to use in the test.
+	 * @var        Criteria
+	 */
+	private $c;
+
+	/**
+	 * DB adapter saved for later.
+	 *
+	 * @var        DBAdapter
+	 */
+	private $savedAdapter;
+
+	protected function setUp()
+	{
+		parent::setUp();
+		$this->c = new Criteria();
+		$this->savedAdapter = Propel::getDB(null);
+		Propel::setDB(null, new DBSQLite());
+	}
+
+	protected function tearDown()
+	{
+		Propel::setDB(null, $this->savedAdapter);
+		parent::tearDown();
+	}
+
+	/**
+	 * Test basic adding of strings.
+	 */
+	public function testAddString() {
+
+		$table = "myTable";
+		$column = "myColumn";
+		$value = "myValue";
+
+		// Add the string
+		$this->c->add($table . '.' . $column, $value);
+
+		// Verify that the key exists
+		$this->assertTrue($this->c->containsKey($table . '.' . $column));
+
+		// Verify that what we get out is what we put in
+		$this->assertTrue($this->c->getValue($table . '.' . $column) === $value);
+	}
+
+	/**
+	 * test various properties of Criterion and nested criterion
+	 */
+	public function testNestedCriterion()
+	{
+		$table2 = "myTable2";
+		$column2 = "myColumn2";
+		$value2 = "myValue2";
+		$key2 = "$table2.$column2";
+
+		$table3 = "myTable3";
+		$column3 = "myColumn3";
+		$value3 = "myValue3";
+		$key3 = "$table3.$column3";
+
+		$table4 = "myTable4";
+		$column4 = "myColumn4";
+		$value4 = "myValue4";
+		$key4 = "$table4.$column4";
+
+		$table5 = "myTable5";
+		$column5 = "myColumn5";
+		$value5 = "myValue5";
+		$key5 = "$table5.$column5";
+
+		$crit2 = $this->c->getNewCriterion($key2, $value2, Criteria::EQUAL);
+		$crit3 = $this->c->getNewCriterion($key3, $value3, Criteria::EQUAL);
+		$crit4 = $this->c->getNewCriterion($key4, $value4, Criteria::EQUAL);
+		$crit5 = $this->c->getNewCriterion($key5, $value5, Criteria::EQUAL);
+
+		$crit2->addAnd($crit3)->addOr($crit4->addAnd($crit5));
+		$expect =
+			"((myTable2.myColumn2=:p1 "
+				. "AND myTable3.myColumn3=:p2) "
+			. "OR (myTable4.myColumn4=:p3 "
+				. "AND myTable5.myColumn5=:p4))";
+
+		$sb = "";
+		$params = array();
+		$crit2->appendPsTo($sb, $params);
+
+		$expect_params = array(
+								    array('table' => 'myTable2', 'column' => 'myColumn2', 'value' => 'myValue2'),
+								    array('table' => 'myTable3', 'column' => 'myColumn3', 'value' => 'myValue3'),
+								    array('table' => 'myTable4', 'column' => 'myColumn4', 'value' => 'myValue4'),
+								    array('table' => 'myTable5', 'column' => 'myColumn5', 'value' => 'myValue5'),
+								);
+
+		$this->assertEquals($expect, $sb);
+		$this->assertEquals($expect_params, $params);
+
+		$crit6 = $this->c->getNewCriterion($key2, $value2, Criteria::EQUAL);
+		$crit7 = $this->c->getNewCriterion($key3, $value3, Criteria::EQUAL);
+		$crit8 = $this->c->getNewCriterion($key4, $value4, Criteria::EQUAL);
+		$crit9 = $this->c->getNewCriterion($key5, $value5, Criteria::EQUAL);
+
+		$crit6->addAnd($crit7)->addOr($crit8)->addAnd($crit9);
+		$expect =
+			"(((myTable2.myColumn2=:p1 "
+					. "AND myTable3.myColumn3=:p2) "
+				. "OR myTable4.myColumn4=:p3) "
+					. "AND myTable5.myColumn5=:p4)";
+
+		$sb = "";
+		$params = array();
+		$crit6->appendPsTo($sb, $params);
+
+		$expect_params = array(
+								    array('table' => 'myTable2', 'column' => 'myColumn2', 'value' => 'myValue2'),
+								    array('table' => 'myTable3', 'column' => 'myColumn3', 'value' => 'myValue3'),
+								    array('table' => 'myTable4', 'column' => 'myColumn4', 'value' => 'myValue4'),
+								    array('table' => 'myTable5', 'column' => 'myColumn5', 'value' => 'myValue5'),
+								);
+
+		$this->assertEquals($expect, $sb);
+		$this->assertEquals($expect_params, $params);
+
+		// should make sure we have tests for all possibilities
+
+		$crita = $crit2->getAttachedCriterion();
+
+		$this->assertEquals($crit2, $crita[0]);
+		$this->assertEquals($crit3, $crita[1]);
+		$this->assertEquals($crit4, $crita[2]);
+		$this->assertEquals($crit5, $crita[3]);
+
+		$tables = $crit2->getAllTables();
+
+		$this->assertEquals($crit2->getTable(), $tables[0]);
+		$this->assertEquals($crit3->getTable(), $tables[1]);
+		$this->assertEquals($crit4->getTable(), $tables[2]);
+		$this->assertEquals($crit5->getTable(), $tables[3]);
+
+		// simple confirmations that equality operations work
+		$this->assertTrue($crit2->hashCode() === $crit2->hashCode());
+	}
+
+	/**
+	 * Tests &lt;= and =&gt;.
+	 */
+	public function testBetweenCriterion()
+	{
+		$cn1 = $this->c->getNewCriterion(
+				"INVOICE.COST",
+				1000,
+				Criteria::GREATER_EQUAL);
+
+		$cn2 = $this->c->getNewCriterion(
+				"INVOICE.COST",
+				5000,
+				Criteria::LESS_EQUAL);
+		$this->c->add($cn1->addAnd($cn2));
+		$expect =
+			"SELECT  FROM INVOICE WHERE "
+			. "(INVOICE.COST>=:p1 AND INVOICE.COST<=:p2)";
+
+		$expect_params = array( array('table' => 'INVOICE', 'column' => 'COST', 'value' => 1000),
+								array('table' => 'INVOICE', 'column' => 'COST', 'value' => 5000),
+							   );
+
+		try {
+			$params = array();
+			$result = BasePeer::createSelectSql($this->c, $params);
+		} catch (PropelException $e) {
+			$this->fail("PropelException thrown in BasePeer.createSelectSql(): ".$e->getMessage());
+		}
+
+		$this->assertEquals($expect, $result);
+		$this->assertEquals($expect_params, $params);
+	}
+
+	/**
+	 * Verify that AND and OR criterion are nested correctly.
+	 */
+	public function testPrecedence()
+	{
+		$cn1 = $this->c->getNewCriterion("INVOICE.COST", "1000", Criteria::GREATER_EQUAL);
+		$cn2 = $this->c->getNewCriterion("INVOICE.COST", "2000", Criteria::LESS_EQUAL);
+		$cn3 = $this->c->getNewCriterion("INVOICE.COST", "8000", Criteria::GREATER_EQUAL);
+		$cn4 = $this->c->getNewCriterion("INVOICE.COST", "9000", Criteria::LESS_EQUAL);
+		$this->c->add($cn1->addAnd($cn2));
+		$this->c->addOr($cn3->addAnd($cn4));
+
+		$expect =
+			"SELECT  FROM INVOICE WHERE "
+			. "((INVOICE.COST>=:p1 AND INVOICE.COST<=:p2) "
+			. "OR (INVOICE.COST>=:p3 AND INVOICE.COST<=:p4))";
+
+		$expect_params = array( array('table' => 'INVOICE', 'column' => 'COST', 'value' => '1000'),
+								array('table' => 'INVOICE', 'column' => 'COST', 'value' => '2000'),
+								array('table' => 'INVOICE', 'column' => 'COST', 'value' => '8000'),
+								array('table' => 'INVOICE', 'column' => 'COST', 'value' => '9000'),
+							   );
+
+		try {
+			$params=array();
+			$result = BasePeer::createSelectSql($this->c, $params);
+		} catch (PropelException $e) {
+			$this->fail("PropelException thrown in BasePeer::createSelectSql()");
+		}
+
+		$this->assertEquals($expect, $result);
+		$this->assertEquals($expect_params, $params);
+	}
+
+	/**
+	 * Test Criterion.setIgnoreCase().
+	 * As the output is db specific the test just prints the result to
+	 * System.out
+	 */
+	public function testCriterionIgnoreCase()
+	{
+		$adapters = array(new DBMySQL(), new DBPostgres());
+		$expectedIgnore = array("UPPER(TABLE.COLUMN) LIKE UPPER(:p1)", "TABLE.COLUMN ILIKE :p1");
+
+		$i =0;
+		foreach ($adapters as $adapter) {
+
+			Propel::setDB(null, $adapter);
+			$myCriteria = new Criteria();
+
+			$myCriterion = $myCriteria->getNewCriterion(
+					"TABLE.COLUMN", "FoObAr", Criteria::LIKE);
+			$sb = "";
+			$params=array();
+			$myCriterion->appendPsTo($sb, $params);
+			$expected = "TABLE.COLUMN LIKE :p1";
+
+			$this->assertEquals($expected, $sb);
+
+			$ignoreCriterion = $myCriterion->setIgnoreCase(true);
+
+			$sb = "";
+			$params=array();
+			$ignoreCriterion->appendPsTo($sb, $params);
+			// $expected = "UPPER(TABLE.COLUMN) LIKE UPPER(?)";
+			$this->assertEquals($expectedIgnore[$i], $sb);
+			$i++;
+		}
+	}
+
+	/**
+	 * Test that true is evaluated correctly.
+	 */
+	public function testBoolean()
+	{
+		$this->c = new Criteria();
+		$this->c->add("TABLE.COLUMN", true);
+
+		$expect = "SELECT  FROM TABLE WHERE TABLE.COLUMN=:p1";
+		$expect_params = array( array('table' => 'TABLE', 'column' => 'COLUMN', 'value' => true),
+							   );
+		try {
+			$params = array();
+			$result = BasePeer::createSelectSql($this->c, $params);
+		} catch (PropelException $e) {
+			$this->fail("PropelException thrown in BasePeer.createSelectSql(): ". $e->getMessage());
+		}
+
+		$this->assertEquals($expect, $result, "Boolean test failed.");
+		$this->assertEquals($expect_params, $params);
+
+	}
+
+	public function testCurrentDate()
+	{
+		$this->c = new Criteria();
+		$this->c->add("TABLE.TIME_COLUMN", Criteria::CURRENT_TIME);
+		$this->c->add("TABLE.DATE_COLUMN", Criteria::CURRENT_DATE);
+
+		$expect = "SELECT  FROM TABLE WHERE TABLE.TIME_COLUMN=CURRENT_TIME AND TABLE.DATE_COLUMN=CURRENT_DATE";
+
+		$result = null;
+		try {
+			$result = BasePeer::createSelectSql($this->c, $params=array());
+		} catch (PropelException $e) {
+			print $e->getTraceAsString();
+			$this->fail("PropelException thrown in BasePeer.createSelectSql(): ". $e->getMessage());
+		}
+
+		$this->assertEquals($expect, $result, "Current date test failed!");
+
+	}
+
+	public function testCountAster()
+	{
+		$this->c = new Criteria();
+		$this->c->addSelectColumn("COUNT(*)");
+		$this->c->add("TABLE.TIME_COLUMN", Criteria::CURRENT_TIME);
+		$this->c->add("TABLE.DATE_COLUMN", Criteria::CURRENT_DATE);
+
+		$expect = "SELECT COUNT(*) FROM TABLE WHERE TABLE.TIME_COLUMN=CURRENT_TIME AND TABLE.DATE_COLUMN=CURRENT_DATE";
+
+		$result = null;
+		try {
+			$result = BasePeer::createSelectSql($this->c, $params=array());
+		} catch (PropelException $e) {
+			print $e->getTraceAsString();
+			$this->fail("PropelException thrown in BasePeer.createSelectSql(): ". $e->getMessage());
+		}
+
+		$this->assertEquals($expect, $result);
+
+	}
+
+	public function testIn()
+	{
+		$c = new Criteria();
+		$c->addSelectColumn("*");
+		$c->add("TABLE.SOME_COLUMN", array(), Criteria::IN);
+		$c->add("TABLE.OTHER_COLUMN", array(1, 2, 3), Criteria::IN);
+
+		$expect = "SELECT * FROM TABLE WHERE 1<>1 AND TABLE.OTHER_COLUMN IN (:p1,:p2,:p3)";
+		try {
+			$result = BasePeer::createSelectSql($c, $params=array());
+		} catch (PropelException $e) {
+			print $e->getTraceAsString();
+			$this->fail("PropelException thrown in BasePeer.createSelectSql(): ". $e->getMessage());
+		}
+		$this->assertEquals($expect, $result);
+
+
+		// ----------------------------------------------------------------------------------
+		// now do a nested logic test, just for sanity (not that this should be any surprise)
+
+		$c = new Criteria();
+		$c->addSelectColumn("*");
+		$myCriterion = $c->getNewCriterion("TABLE.COLUMN", array(), Criteria::IN);
+		$myCriterion->addOr($c->getNewCriterion("TABLE.COLUMN2", array(1,2), Criteria::IN));
+		$c->add($myCriterion);
+
+		$expect = "SELECT * FROM TABLE WHERE (1<>1 OR TABLE.COLUMN2 IN (:p1,:p2))";
+		try {
+			$result = BasePeer::createSelectSql($c, $params=array());
+		} catch (PropelException $e) {
+			print $e->getTraceAsString();
+			$this->fail("PropelException thrown in BasePeer.createSelectSql(): ". $e->getMessage());
+		}
+		$this->assertEquals($expect, $result);
+
+	}
+
+	public function testJoinObject ()
+	{
+		$j = new Join('TABLE_A.COL_1', 'TABLE_B.COL_2');
+		$this->assertEquals(null, $j->getJoinType());
+		$this->assertEquals('TABLE_A.COL_1', $j->getLeftColumn());
+		$this->assertEquals('TABLE_A', $j->getLeftTableName());
+		$this->assertEquals('COL_1', $j->getLeftColumnName());
+		$this->assertEquals('TABLE_B.COL_2', $j->getRightColumn());
+		$this->assertEquals('TABLE_B', $j->getRightTableName());
+		$this->assertEquals('COL_2', $j->getRightColumnName());
+
+		$j = new Join('TABLE_A.COL_1', 'TABLE_B.COL_1', Criteria::LEFT_JOIN);
+		$this->assertEquals('LEFT JOIN', $j->getJoinType());
+		$this->assertEquals('TABLE_A.COL_1', $j->getLeftColumn());
+		$this->assertEquals('TABLE_B.COL_1', $j->getRightColumn());
+
+		$j = new Join('TABLE_A.COL_1', 'TABLE_B.COL_1', Criteria::RIGHT_JOIN);
+		$this->assertEquals('RIGHT JOIN', $j->getJoinType());
+		$this->assertEquals('TABLE_A.COL_1', $j->getLeftColumn());
+		$this->assertEquals('TABLE_B.COL_1', $j->getRightColumn());
+
+		$j = new Join('TABLE_A.COL_1', 'TABLE_B.COL_1', Criteria::INNER_JOIN);
+		$this->assertEquals('INNER JOIN', $j->getJoinType());
+		$this->assertEquals('TABLE_A.COL_1', $j->getLeftColumn());
+		$this->assertEquals('TABLE_B.COL_1', $j->getRightColumn());
+
+		$j = new Join(array('TABLE_A.COL_1', 'TABLE_A.COL_2'), array('TABLE_B.COL_1', 'TABLE_B.COL_2'), Criteria::INNER_JOIN);
+		$this->assertEquals('TABLE_A.COL_1', $j->getLeftColumn(0));
+		$this->assertEquals('TABLE_A.COL_2', $j->getLeftColumn(1));
+		$this->assertEquals('TABLE_B.COL_1', $j->getRightColumn(0));
+		$this->assertEquals('TABLE_B.COL_2', $j->getRightColumn(1));
+	}
+
+	public function testAddingJoin ()
+	{
+		$c = new Criteria();
+		$c->addSelectColumn("*");
+		$c->addJoin('TABLE_A.COL_1', 'TABLE_B.COL_1'); // straight join
+
+		$expect = "SELECT * FROM TABLE_A, TABLE_B WHERE TABLE_A.COL_1=TABLE_B.COL_1";
+		try {
+			$result = BasePeer::createSelectSql($c, $params=array());
+		} catch (PropelException $e) {
+			print $e->getTraceAsString();
+			$this->fail("PropelException thrown in BasePeer.createSelectSql(): ". $e->getMessage());
+		}
+		$this->assertEquals($expect, $result);
+	}
+
+	public function testAddingMultipleJoins ()
+	{
+		$c = new Criteria();
+		$c->addSelectColumn("*");
+		$c->addJoin('TABLE_A.COL_1', 'TABLE_B.COL_1');
+		$c->addJoin('TABLE_B.COL_X', 'TABLE_D.COL_X');
+
+		$expect = 'SELECT * FROM TABLE_A, TABLE_B, TABLE_D '
+				 .'WHERE TABLE_A.COL_1=TABLE_B.COL_1 AND TABLE_B.COL_X=TABLE_D.COL_X';
+		try {
+			$result = BasePeer::createSelectSql($c, $params=array());
+		} catch (PropelException $e) {
+			print $e->getTraceAsString();
+			$this->fail("PropelException thrown in BasePeer.createSelectSql(): ". $e->getMessage());
+		}
+		$this->assertEquals($expect, $result);
+	}
+
+	public function testAddingLeftJoin ()
+	{
+		$c = new Criteria();
+		$c->addSelectColumn("TABLE_A.*");
+		$c->addSelectColumn("TABLE_B.*");
+		$c->addJoin('TABLE_A.COL_1', 'TABLE_B.COL_2', Criteria::LEFT_JOIN);
+
+		$expect = "SELECT TABLE_A.*, TABLE_B.* FROM TABLE_A LEFT JOIN TABLE_B ON (TABLE_A.COL_1=TABLE_B.COL_2)";
+		try {
+			$result = BasePeer::createSelectSql($c, $params=array());
+		} catch (PropelException $e) {
+			print $e->getTraceAsString();
+			$this->fail("PropelException thrown in BasePeer.createSelectSql(): ". $e->getMessage());
+		}
+		$this->assertEquals($expect, $result);
+	}
+
+	public function testAddingMultipleLeftJoins ()
+	{
+		// Fails.. Suspect answer in the chunk starting at BasePeer:605
+		$c = new Criteria();
+		$c->addSelectColumn('*');
+		$c->addJoin('TABLE_A.COL_1', 'TABLE_B.COL_1', Criteria::LEFT_JOIN);
+		$c->addJoin('TABLE_A.COL_2', 'TABLE_C.COL_2', Criteria::LEFT_JOIN);
+
+		$expect = 'SELECT * FROM TABLE_A '
+				 .'LEFT JOIN TABLE_B ON (TABLE_A.COL_1=TABLE_B.COL_1) '
+						 .'LEFT JOIN TABLE_C ON (TABLE_A.COL_2=TABLE_C.COL_2)';
+		try {
+			$result = BasePeer::createSelectSql($c, $params=array());
+		} catch (PropelException $e) {
+			print $e->getTraceAsString();
+			$this->fail("PropelException thrown in BasePeer.createSelectSql(): ". $e->getMessage());
+		}
+		$this->assertEquals($expect, $result);
+	}
+
+	public function testAddingRightJoin ()
+	{
+		$c = new Criteria();
+		$c->addSelectColumn("*");
+		$c->addJoin('TABLE_A.COL_1', 'TABLE_B.COL_2', Criteria::RIGHT_JOIN);
+
+		$expect = "SELECT * FROM TABLE_A RIGHT JOIN TABLE_B ON (TABLE_A.COL_1=TABLE_B.COL_2)";
+		try {
+			$result = BasePeer::createSelectSql($c, $params=array());
+		} catch (PropelException $e) {
+			print $e->getTraceAsString();
+			$this->fail("PropelException thrown in BasePeer.createSelectSql(): ". $e->getMessage());
+		}
+		$this->assertEquals($expect, $result);
+	}
+
+	public function testAddingMultipleRightJoins ()
+	{
+		// Fails.. Suspect answer in the chunk starting at BasePeer:605
+		$c = new Criteria();
+		$c->addSelectColumn('*');
+		$c->addJoin('TABLE_A.COL_1', 'TABLE_B.COL_1', Criteria::RIGHT_JOIN);
+		$c->addJoin('TABLE_A.COL_2', 'TABLE_C.COL_2', Criteria::RIGHT_JOIN);
+
+		$expect = 'SELECT * FROM TABLE_A '
+				 .'RIGHT JOIN TABLE_B ON (TABLE_A.COL_1=TABLE_B.COL_1) '
+						 .'RIGHT JOIN TABLE_C ON (TABLE_A.COL_2=TABLE_C.COL_2)';
+		try {
+			$result = BasePeer::createSelectSql($c, $params=array());
+		} catch (PropelException $e) {
+			print $e->getTraceAsString();
+			$this->fail("PropelException thrown in BasePeer.createSelectSql(): ". $e->getMessage());
+		}
+		$this->assertEquals($expect, $result);
+	}
+
+	public function testAddingInnerJoin ()
+	{
+		$c = new Criteria();
+		$c->addSelectColumn("*");
+		$c->addJoin('TABLE_A.COL_1', 'TABLE_B.COL_1', Criteria::INNER_JOIN);
+
+		$expect = "SELECT * FROM TABLE_A INNER JOIN TABLE_B ON (TABLE_A.COL_1=TABLE_B.COL_1)";
+		try {
+			$result = BasePeer::createSelectSql($c, $params=array());
+		} catch (PropelException $e) {
+			print $e->getTraceAsString();
+			$this->fail("PropelException thrown in BasePeer.createSelectSql(): ". $e->getMessage());
+		}
+		$this->assertEquals($expect, $result);
+	}
+
+	public function testAddingMultipleInnerJoin ()
+	{
+		$c = new Criteria();
+		$c->addSelectColumn("*");
+		$c->addJoin('TABLE_A.COL_1', 'TABLE_B.COL_1', Criteria::INNER_JOIN);
+		$c->addJoin('TABLE_B.COL_1', 'TABLE_C.COL_1', Criteria::INNER_JOIN);
+
+		$expect = 'SELECT * FROM TABLE_A '
+				 .'INNER JOIN TABLE_B ON (TABLE_A.COL_1=TABLE_B.COL_1) '
+						 .'INNER JOIN TABLE_C ON (TABLE_B.COL_1=TABLE_C.COL_1)';
+		try {
+			$result = BasePeer::createSelectSql($c, $params=array());
+		} catch (PropelException $e) {
+			print $e->getTraceAsString();
+			$this->fail("PropelException thrown in BasePeer.createSelectSql(): ". $e->getMessage());
+		}
+		$this->assertEquals($expect, $result);
+	}
+
+	/**
+	 * @link       http://propel.phpdb.org/trac/ticket/451
+	 */
+	public function testMultipleMixedJoinOrders()
+	{
+		$c = new Criteria();
+		$c->clearSelectColumns()->
+			addJoin("TABLE_A.FOO_ID", "TABLE_B.ID", Criteria::LEFT_JOIN)->
+			addJoin("TABLE_A.BAR_ID", "TABLE_C.ID")->
+			addSelectColumn("TABLE_A.ID");
+
+		# These are no longer different, see http://propel.phpdb.org/trac/ticket/283#comment:8
+		#$db = Propel::getDB();
+		#
+		#if ($db instanceof DBMySQL) {
+		#	$expect = 'SELECT TABLE_A.ID FROM (TABLE_A CROSS JOIN TABLE_C)'
+		#			.' LEFT JOIN TABLE_B ON (TABLE_A.FOO_ID=TABLE_B.ID) WHERE TABLE_A.BAR_ID=TABLE_C.ID';
+		#} else {
+			$expect = 'SELECT TABLE_A.ID FROM TABLE_A CROSS JOIN TABLE_C'
+					.' LEFT JOIN TABLE_B ON (TABLE_A.FOO_ID=TABLE_B.ID) WHERE TABLE_A.BAR_ID=TABLE_C.ID';
+		#}
+
+		$result = BasePeer::createSelectSql($c, $params=array());
+
+		#print "Actual:   " . $result . "\n---\n";
+		#print "Expected: " . $expect . "\n";
+
+		$this->assertEquals($expect, $result);
+	}
+
+	/**
+	 * Test the Criteria::CUSTOM behavior.
+	 */
+	public function testCustomOperator()
+	{
+		$c = new Criteria();
+		$c->addSelectColumn('A.COL');
+		$c->add('A.COL', 'date_part(\'YYYY\', A.COL) = \'2007\'', Criteria::CUSTOM);
+
+		$expected = "SELECT A.COL FROM A WHERE date_part('YYYY', A.COL) = '2007'";
+
+		$result = BasePeer::createSelectSql($c, $params=array());
+		$this->assertEquals($expected, $result);
+	}
+	
+	/**
+	 * Tests adding duplicate joins.
+	 * @link       http://propel.phpdb.org/trac/ticket/613
+	 */
+	public function testAddJoin_Duplicate()
+	{
+		$c = new Criteria();
+		
+		$c->addJoin("tbl.COL1", "tbl.COL2", Criteria::LEFT_JOIN);
+		$c->addJoin("tbl.COL1", "tbl.COL2", Criteria::LEFT_JOIN);
+		$this->assertEquals(1, count($c->getJoins()), "Expected not to have duplciate LJOIN added.");
+		
+		$c->addJoin("tbl.COL1", "tbl.COL2", Criteria::RIGHT_JOIN);
+		$c->addJoin("tbl.COL1", "tbl.COL2", Criteria::RIGHT_JOIN);
+		$this->assertEquals(2, count($c->getJoins()), "Expected 1 new right join to be added.");
+		
+		$c->addJoin("tbl.COL1", "tbl.COL2");
+		$c->addJoin("tbl.COL1", "tbl.COL2");
+		$this->assertEquals(3, count($c->getJoins()), "Expected 1 new implicit join to be added.");
+		
+		$c->addJoin("tbl.COL3", "tbl.COL4");
+		$this->assertEquals(4, count($c->getJoins()), "Expected new col join to be added.");
+		
+	}
+	
+	/**
+	 * @link       http://propel.phpdb.org/trac/ticket/634
+	 */
+	public function testHasSelectClause()
+	{
+		$c = new Criteria();
+		$c->addSelectColumn("foo");
+		
+		$this->assertTrue($c->hasSelectClause());
+		
+		$c = new Criteria();
+		$c->addAsColumn("foo", "bar");
+		
+		$this->assertTrue($c->hasSelectClause());
+	}
+	
+	/**
+	 * Tests including aliases in criterion objects.
+	 * @link       http://propel.phpdb.org/trac/ticket/636
+	 */
+	public function testAliasInCriterion()
+	{
+		$c = new Criteria(); 
+		$c->addAsColumn("column_alias", "tbl.COL1");
+		$crit = $c->getNewCriterion("column_alias", "FOO");
+		$this->assertNull($crit->getTable());
+		$this->assertEquals("column_alias", $crit->getColumn());
+		$c->addHaving($crit); // produces invalid SQL referring to '.olumn_alias'
+	}
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/test/classes/propel/util/PropelDateTimeTest.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/test/classes/propel/util/PropelDateTimeTest.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/test/classes/propel/util/PropelDateTimeTest.php	(revision 19)
@@ -0,0 +1,150 @@
+<?php
+/*
+ *  $Id: PropelDateTimeTest.php 784 2007-11-08 10:15:50Z heltem $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://propel.phpdb.org>.
+ */
+
+require_once 'classes/propel/BaseTestCase.php';
+require_once 'propel/util/PropelDateTime.php';
+
+/**
+ * Test for DateTime subclass to support serialization.
+ *
+ * @author     Alan Pinstein
+ * @author     Soenke Ruempler
+ * @package    propel.util
+ */
+class PropelDateTimeTest extends BaseTestCase
+{
+
+	/**
+	 * Assert that two dates are identical (equal and have same time zone).
+	 */
+	protected function assertDatesIdentical(DateTime $dt1, DateTime $dt2, $msg = "Expected DateTime1 IDENTICAL to DateTime2: %s")
+	{
+		$this->assertEquals($dt1->format('Y-m-d H:i:s'), $dt1->format('Y-m-d H:i:s'), sprintf($msg, "Dates w/ no timezone resolution were not the same."));
+		$this->assertEquals($dt1->getTimeZone()->getName(), $dt2->getTimeZone()->getName(), sprintf($msg, "timezones were not the same."));
+
+
+		// We do this last, because a PHP bug will make this true while the dates
+		// may not truly be equal.
+		// See: http://bugs.php.net/bug.php?id=40743
+		$this->assertTrue($dt1 == $dt2, sprintf($msg, "dates did not pass equality check (==)."));
+	}
+
+	/**
+	 * Assert that two dates are equal.
+	 */
+	protected function assertDatesEqual(DateTime $dt1, DateTime $dt2, $msg = "Expected DateTime1 == DateTime2: %s")
+	{
+		if ($dt1 != $dt2) {
+			if ($dt1->getTimeZone()->getName() != $dt2->getTimeZone()->getName()) {
+				$this->fail(sprintf($msg, "Timezones were not the same."));
+			} else {
+				$this->fail(sprintf($msg, "Timezones were the same, but date values were different."));
+			}
+		}
+	}
+
+	/**
+	 * Assert that two dates are not equal.
+	 */
+	protected function assertDatesNotEqual(DateTime $dt1, DateTime $dt2, $msg = "Expected DateTime1 != DateTime2: %s")
+	{
+		$this->assertTrue($dt1 != $dt2, $msg);
+	}
+
+	/**
+	 * Ensure that our constructor matches DateTime constructor signature.
+	 */
+	public function testConstruct()
+	{
+
+		// Because of a PHP bug ()
+		// we cannot use a timestamp format that includes a timezone.  It gets weird. :)
+		$now = date('Y-m-d H:i:s');
+
+		$dt = new DateTime($now);
+		$pdt = new PropelDateTime($now);
+		$this->assertDatesEqual($dt, $pdt, "Expected DateTime == PropelDateTime: %s");
+
+		$dt = new DateTime($now, new DateTimeZone('UTC'));
+		$pdt = new PropelDateTime($now, new DateTimeZone('America/New_York'));
+		$this->assertDatesNotEqual($dt, $pdt, "Expected DateTime != PropelDateTime: %s");
+
+	}
+
+	/**
+	 * Tests the ability to serialize() a PropelDateTime object.
+	 */
+	public function testSerialize_NoTZ()
+	{
+		$now = date('Y-m-d H:i:s');
+		$dt = new DateTime($now);
+		$pdt = new PropelDateTime($now);
+
+		$this->assertDatesIdentical($dt, $pdt);
+
+		// We expect these to be the same -- there's no time zone info
+		$ser = serialize($pdt);
+		unset($pdt);
+
+		$pdt = unserialize($ser);
+		$this->assertDatesIdentical($dt, $pdt);
+	}
+
+	/**
+	 * Tests the ability to serialize() a PropelDateTime object.
+	 */
+	public function testSerialize_SameTZ()
+	{
+		$now = date('Y-m-d H:i:s');
+		$dt = new DateTime($now, new DateTimeZone('America/New_York'));
+		$pdt = new PropelDateTime($now, new DateTimeZone('America/New_York'));
+
+		$this->assertDatesIdentical($dt, $pdt);
+
+		// We expect these to be the same -- there's no time zone info
+		$ser = serialize($pdt);
+		unset($pdt);
+
+		$pdt = unserialize($ser);
+		$this->assertDatesIdentical($dt, $pdt);
+	}
+
+	/**
+	 * Tests the ability to serialize() a PropelDateTime object.
+	 */
+	public function testSerialize_DiffTZ()
+	{
+		$now = date('Y-m-d H:i:s');
+		$dt = new DateTime($now, new DateTimeZone('UTC'));
+		$pdt = new PropelDateTime($now, new DateTimeZone('America/New_York'));
+
+		$this->assertDatesNotEqual($dt, $pdt);
+
+		// We expect these to be the same -- there's no time zone info
+		$ser = serialize($pdt);
+		unset($pdt);
+
+		$pdt = unserialize($ser);
+		$this->assertDatesNotEqual($dt, $pdt);
+	}
+
+
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/test/classes/propel/util/PropelPDOTest.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/test/classes/propel/util/PropelPDOTest.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/test/classes/propel/util/PropelPDOTest.php	(revision 19)
@@ -0,0 +1,44 @@
+<?php
+/*
+ *  $Id: PropelDateTimeTest.php 784 2007-11-08 10:15:50Z heltem $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://propel.phpdb.org>.
+ */
+
+require_once 'bookstore/BookstoreTestBase.php';
+require_once 'propel/util/PropelPDO.php';
+
+/**
+ * Test for PropelPDO subclass.
+ *
+ * @package    propel.util
+ */
+class PropelPDOTest extends BookstoreTestBase
+{
+
+	public function testSetAttribute()
+	{
+		$con = Propel::getConnection(BookPeer::DATABASE_NAME);
+		$this->assertFalse($con->getAttribute(PropelPDO::PROPEL_ATTR_CACHE_PREPARES));
+		$con->setAttribute(PropelPDO::PROPEL_ATTR_CACHE_PREPARES, true);
+		$this->assertTrue($con->getAttribute(PropelPDO::PROPEL_ATTR_CACHE_PREPARES));
+
+		$con->setAttribute(PDO::ATTR_CASE, PDO::CASE_LOWER);
+		$this->assertEquals(PDO::CASE_LOWER, $con->getAttribute(PDO::ATTR_CASE));
+	}
+
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/test/classes/propel/validator/ValidatorTest.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/test/classes/propel/validator/ValidatorTest.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/test/classes/propel/validator/ValidatorTest.php	(revision 19)
@@ -0,0 +1,230 @@
+<?php
+/*
+ * $Id: ValidatorTest.php 989 2008-03-11 14:29:30Z heltem $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://propel.phpdb.org>.
+ */
+
+require_once 'bookstore/BookstoreTestBase.php';
+
+/**
+ * Tests the validator classes.
+ *
+ * This test uses generated Bookstore classes to test the behavior of various
+ * validator operations.
+ *
+ * The database is relaoded before every test and flushed after every test.	This
+ * means that you can always rely on the contents of the databases being the same
+ * for each test method in this class.	See the BookstoreDataPopulator::populate()
+ * method for the exact contents of the database.
+ *
+ * @see        BookstoreDataPopulator
+ * @author     Michael Aichler <aichler@mediacluster.de>
+ */
+class ValidatorTest extends BookstoreTestBase
+{
+
+	/**
+	 * Test minLength validator.
+	 * This also tests the ${value} substitution.
+	 */
+	public function testDoValidate_MinLength()
+	{
+		$book = new Book();
+		$book->setTitle("12345"); // min length is 10
+
+		$res = $book->validate();
+		$this->assertFalse($res, "Expected validation to fail.");
+
+		$failures = $book->getValidationFailures();
+		$this->assertSingleValidation($failures, "Book title must be more than 10 characters long.");
+	}
+
+	/**
+	 * Test unique validator.
+	 */
+	public function testDoValidate_Unique()
+	{
+		$book = new Book();
+		$book->setTitle("Don Juan");
+
+		$ret = $book->validate();
+		$failures = $book->getValidationFailures();
+		$this->assertSingleValidation($failures, "Book title already in database.");
+	}
+
+	/**
+	 * Test recursive validaton.
+	 */
+	public function testDoValidate_Complex()
+	{
+		$book = new Book();
+		$book->setTitle("12345"); // min length is 10
+
+		$author = new Author();
+		$author->setFirstName("Hans"); // last name required, valid email format, age > 0
+
+		$review = new Review();
+		$review->setReviewDate("08/09/2001"); // reviewed_by column required, invalid status (new, reviewed, archived)
+
+		$book->setAuthor($author);
+		$book->addReview($review);
+
+		$res = $book->validate();
+
+		$this->assertFalse($res, "Expected validation to fail.");
+
+		$failures = $book->getValidationFailures();
+
+		/* Make sure 3 validation messages were returned; NOT 6, because the others were NULL */
+		$this->assertEquals(3, count($failures), "");
+
+		/* Make sure correct columns failed */
+		$expectedCols = array(
+		AuthorPeer::LAST_NAME,
+		BookPeer::TITLE,
+		ReviewPeer::REVIEWED_BY
+		);
+		$returnedCols = array_keys($failures);
+
+		/* implode for readability */
+		$this->assertEquals(implode(',', $expectedCols), implode(',', $returnedCols));
+	}
+
+	/**
+	 * Test recursive validaton with specified columns.
+	 */
+	public function testDoValidate_ComplexSpecifiedCols()
+	{
+		$book = new Book();
+		$book->setTitle("12345"); // min length is 10
+
+		$author = new Author();
+		$author->setFirstName("Hans"); // last name required, valid email format, age > 0
+
+		$review = new Review();
+		$review->setReviewDate("08/09/2001"); // reviewed_by column required, invalid status (new, reviewed, archived)
+
+		$book->setAuthor($author);
+		$book->addReview($review);
+
+		$cols = array(AuthorPeer::LAST_NAME, ReviewPeer::REVIEWED_BY);
+
+		$res = $book->validate($cols);
+
+		$this->assertFalse($res, "Expected validation to fail.");
+
+		$failures = $book->getValidationFailures();
+
+		/* Make sure 3 validation messages were returned; NOT 6, because the others were NULL */
+		$this->assertEquals(2, count($failures), "");
+
+		/* Make sure correct columns failed */
+		$expectedCols = array(
+		AuthorPeer::LAST_NAME,
+		ReviewPeer::REVIEWED_BY
+		);
+
+		$returnedCols = array_keys($failures);
+
+		/* implode for readability */
+		$this->assertEquals(implode(',', $expectedCols), implode(',', $returnedCols));
+	}
+
+	/**
+	 * Test the fact that validators should not complain NULL values for non-required columns.
+	 */
+	public function testDoValidate_Nulls()
+	{
+		$author = new Author();
+		$author->setFirstName("Malcolm"); // last name required, valid email format, age > 0
+		$author->setLastName("X");
+
+		$author->setEmail(null); // just to be explicit, of course these are the defaults anyway
+		$author->setAge(null);
+
+		$res = $author->validate();
+
+
+		$this->assertTrue($res, "Expected validation to pass with NULL columns");
+
+		$author->setEmail('malcolm@'); // fail
+		$res = $author->validate();
+
+		$this->assertFalse($res, "Expected validation to fail.");
+
+		$failures = $author->getValidationFailures();
+		$this->assertEquals(1, count($failures), "Expected 1 column to fail validation.");
+		$this->assertEquals(array(AuthorPeer::EMAIL), array_keys($failures), "Expected EMAIL to fail validation.");
+
+	}
+
+	public function testDoValidate_BasicValidatorObj()
+	{
+		$author = new Author();
+		$author->setFirstName("Malcolm"); // last name required, valid email format, age > 0
+		$author->setLastName("X");
+		$author->setEmail('malcolm@'); // fail
+
+		$res = $author->validate();
+
+		$this->assertFalse($res, "Expected validation to fail.");
+
+		$failures = $author->getValidationFailures();
+
+		$this->assertEquals(1, count($failures), "Expected 1 column to fail validation.");
+		$this->assertEquals(array(AuthorPeer::EMAIL), array_keys($failures), "Expected EMAIL to fail validation.");
+
+		$validator = $failures[AuthorPeer::EMAIL]->getValidator();
+		$this->assertTrue($validator instanceof MatchValidator, "Expected validator that failed to be MatchValidator");
+
+	}
+
+	public function testDoValidate_CustomValidator()
+	{
+		$book = new Book();
+		$book->setTitle("testDoValidate_CustomValidator"); // (valid)
+		$book->setISBN("Foo.Bar.Baz"); // (invalid)
+
+		$res = $book->validate();
+
+		$this->assertFalse($res, "Expected validation to fail.");
+
+		$failures = $book->getValidationFailures();
+
+		$this->assertEquals(1, count($failures), "Expected 1 column to fail validation.");
+		$this->assertEquals(array(BookPeer::ISBN), array_keys($failures), "Expected EMAIL to fail validation.");
+
+		$validator = $failures[BookPeer::ISBN]->getValidator();
+		$this->assertType('ISBNValidator', $validator, "Expected validator that failed to be ISBNValidator");
+	}
+
+	protected function assertSingleValidation($ret, $expectedMsg)
+	{
+		/* Make sure validation failed */
+		$this->assertTrue($ret !== true, "Expected validation to fail !");
+
+		/* Make sure 1 validation message was returned */
+		$count = count($ret);
+		$this->assertTrue($count === 1, "Expected that exactly one validation failed ($count) !");
+
+		/* Make sure expected validation message was returned */
+		$el = array_shift($ret);
+		$this->assertEquals($el->getMessage(), $expectedMsg, "Got unexpected validation failed message: " . $el->getMessage());
+	}
+
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/test/etc/lob/tin_drum.txt
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/test/etc/lob/tin_drum.txt	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/test/etc/lob/tin_drum.txt	(revision 19)
@@ -0,0 +1,76 @@
+Granted: I am an inmate of a mental hospital; my keeper is watching me, he never lets me out of his sight; there's a peephole in the door, and my keeper's eye is the shade of brown that can never see through a blue-eyed type like me.
+
+So you see, my keeper can't be an enemy. I've come to be very fond of him; when he stops looking at me from behind the door and comes into the room, I tell him incidents from my life, so he can get to know me in spite of the peephole between us. He seems to treasure my stories, because every time I tell him some fairy tale, he shows his gratitude by bringing out his latest knot construction. I wouldn't swear that he's an artist. But I am certain that an exhibition of his creations would be well received by the press and attract a few purchasers. He picks up common pieces of string in the patients' rooms after visiting hours, disentangles them, and works them up into elaborate contorted spooks; then he dips them in plaster, lets them harden, and mounts them on knitting needles that he fastens to little wooden pedestals.
+
+He often plays with the idea of coloring his works. l advise him against it, taking my white enamel bed as an example and bidding him try to imagine how this most perfect of all beds would look if painted in many colors. He raises his hands in horror, tries to give his rather expressionless face an expression of extreme disgust, and abandons his polychrome projects.
+
+So you see, my white-enameled, metal hospital bed has become a norm and standard. To me it is still more: my bed is a goal attained at last, it is my consolation and might become my faith if the management allowed me to make a few changes: I should like, for instance, to have the bars built up higher, to prevent anyone from coming too close to me.
+
+
+Once a week a visiting day breaks in on the stillness that I plait between the white metal bars. This is the time for the people who want to save me, whom it amuses to love me, who try to esteem and respect themselves, to get to know themselves, through me. How blind, how nervous and ill-bred they are! They scratch the white enamel of my bedstead with their fingernail scissors, they scribble obscene little men on it with their ballpoint pens and blue pencils. No sooner has my lawyer blasted the room with his hello than he slaps his nylon hat down over the lower left-hand bedpost--an act of violence that shatters my peace of mind for the duration of his visit, and lawyers find a good deal to talk about.
+
+After my visitors have deposited their gifts beneath the water color of the anemones, on the little white table covered with oilcloth, after they have submitted their current projects for my salvation, and convinced me, whom they are working indefatigably to save, of the high quality of their charity, they recover their relish in their own existence, and leave me. Then my keeper comes in to air the room and collect the strings from the gift packages. Often after airing he finds time to sit by my bed for a while, disentangling his strings, and spreading silence until I call the silence Bruno and Bruno silence.
+
+Bruno Munsterberg--this time I mean my keeper, I've stopped playing with words--has bought me five hundred sheets of writing paper.
+
+Should this supply prove insufficient, Bruno, who is unmarried and childless and hails from the Sauerland, will go to the little stationery store that also sells toys, and get me some more of the unlined space I need for the recording of my memories--I only hope they are accurate. I could never have asked such a service of my visitors, the lawyer for instance, or Klepp. The solicitous affection prescribed in my case would surely have deterred my friends from bringing me anything so dangerous as blank paper and making it available to this mind of mine which persists in excreting syllables.
+
+"Oh, Bruno," I said, "would you buy me a ream of virgin paper?" And Bruno, looking up at the ceiling and pointing his index finger in the same direction by way of inviting a comparison, replied: "You mean white paper, Herr Oskar?"
+
+I stuck to "virgin" and asked Bruno to say just that in the store. When he came back late in the afternoon with the package, he gave the impression of a Bruno shaken by thought. Several times he looked fixedly up at the ceiling from which he derived all his inspiration. And a little later he spoke: "That was the right word you told me. I asked for virgin paper and the salesgirl blushed like mad before getting it."
+
+Fearing an interminable conversation about salesgirls in stationery stores, I regretted having spoken of virgin paper and said nothing, waiting for Bruno to leave the room. Only then did I open the package with the five hundred sheets of writing paper.
+
+For a time I weighed the hard, flexible ream in my hands; then I counted out ten sheets and stowed the rest in my bedside table. I found my fountain pen in the drawer beside the photograph album: it's full, ink is no problem, how shall I begin?
+
+You can begin a story in the middle and create confusion by striking out boldly, backward and forward. You can be modern, put aside all mention of time and distance and, when the whole thing is done, proclaim, or let someone else proclaim, that you have finally, at the last moment, solved the space-time problem. Or you can declare at the very start that it's impossible to write a novel nowadays, but then, behind your own back so to speak, give birth to a whopper, a novel to end all novels. I have also been told that it makes a good impression, an impression of modesty so to speak, if you begin by saying that a novel can't have a hero any more because there are no more individualists, because individuality is a thing of the past, because man--each man and all men together--is alone in his loneliness and no one is entitled to individual loneliness, and all men lumped together make up a "lonely mass" without names and without heroes. All this may be true. But as far as I and Bruno my keeper are concerned, I beg leave to say that we are both heroes, very different heroes, he on his side of the peephole, and I on my side; and even, when he opens the door, the two of us, with all our friendship and loneliness, are still far from being a nameless, heroless mass.
+
+I shall begin far away from me; for no one ought to tell the story of his life who hasn't the patience to say a word or two about at least half of his grandparents before plunging into his own existence. And so to you personally, dear reader, who are no doubt leading a muddled kind of life outside this institution, to you my friends and weekly visitors who suspect nothing of my paper supply, I introduce Oskar's maternal grandmother.
+
+Late one October afternoon my grandmother Anna Bronski was sitting in her skirts at the edge of a potato field. In the morning you might have seen how expert my grandmother was at making the limp potato plants into neat piles; at noon she had eaten a chunk of bread smeared with lard and syrup; then she had dug over the field a last time, and now she sat in her skirts between two nearly full baskets. The soles of her boots rose up at right angles to the ground, converging slightly at the toes, and in front of them smoldered a fire of potato plants, flaring up asthmatically from time to time, sending a queasy film of smoke out over the scarcely inclined crust of the earth. The year was 1899; she was sitting in the heart of Kashubia, not far from Bissau but still closer to the brickworks between Ramkau and Viereck, in front of her the Brenntau highway at a point between Dirschau and Karthaus, behind her the black forest of Goldkrug; there she sat, pushing potatoes about beneath the hot ashes with the charred tip of a hazel branch.
+
+If I have made a special point of my grandmother's skirt, leaving no doubt, I hope, that she was sitting in her skirts; if indeed I have gone so far as to call the whole chapter "The Wide Skirt," it is because I know how much I owe to this article of apparel. My grandmother had on not just one skirt, but four, one over the other. It should not be supposed that she wore one skirt and three petticoats; no, she wore four skirts; one supported the next, and she wore the lot of them in accordance with a definite system, that is, the order of the skirts was changed from day to day. The one that was on top yesterday was today in second place; the second became the third. The one that was third yesterday was next to her skin today. The one that was closest to her yesterday clearly disclosed its pattern today, or rather its lack of pattern: all my grandmother Anna Bronski's skirts favored the same potato color. It must have been becoming to her.
+
+Aside from the color, my grandmother's skirts were distinguished by a lavish expanse of material. They puffed and billowed when the wind came, crackled as it passed, and sagged when it was gone, and all four of them flew out ahead of her when she had the wind in her stern. When she sat down, she gathered her skirts about her.
+
+In addition to the four skirts, billowing, sagging, hanging down in folds, or standing stiff and empty beside her bed, my grandmother possessed a fifth. It differed in no way from the other four potato-coloured garments. And actually the fifth skirt was not always fifth. Like its brothers-for skirts are masculine by nature-it was subject to change, it was worn like the other four, and like them when its time had come, took its turn in the wash trough every fifth Friday, then Saturday on the line by the kitchen window, and when dry on the ironing board.
+
+When, after one of these Saturdays spent in housecleaning, baking, washing and ironing, after milking and feeding the cow, my grandmother immersed herself from top to toe in the tub, when after leaving a little of herself in the soapsuds and letting the water in the tub sink back to its normal level, she sat down on the edge of the bed swathed in a great flowery towel, the four worn skirts and the freshly washed skirt lay spread out before her on the floor. She pondered, propping the lower lid of her right eye with her right index finger, and since she consulted no one, not even her brother Vincent, she quickly made up her mind. She stood up and with her bare toes pushed aside the skirt whose potato color had lost the most bloom. The freshly laundered one took its place.
+
+On Sunday morning she went to church in Ramkau and inaugurated the new order of skirts in honor of ]esus, about whom she had very set ideas. Where did my grandmother wear the laundered skirt? She was not only a cleanly woman, but also a rather vain one; she wore the best piece where it could be seen in the sunlight when the weather was good.
+
+But now it was a Monday afternoon and my grandmother was sitting by the potato fire. Today her Sunday skirt was one layer closer to her person, while the one that had basked in the warmth of her skin on Sunday swathed her hips in Monday gloom. Whistling with no particular tune in mind, she coaxed the first cooked potato out of the ashes with her hazel branch and pushed it away from the smoldering mound to cool in the breeze. Then she spitted the charred and crusty tuber on a pointed stick and held it close to her mouth; she had stopped whistling and instead pursed her cracked, wind-parched lips to blow the earth and ashes off the potato skin.
+
+In blowing, my grandmother closed her eyes. When she thought she had blown enough, she opened first one eye, then the other, bit into the potato with her widely spaced but otherwise perfect front teeth, removed half the potato, cradled the other half, mealy, steaming, and still too hot to chew, in her open mouth, and, snifflng at the smoke and the October air, gazed wide-eyed across the field toward the nearby horizon, sectioned by telegraph poles and the upper third of the brickworks chimney.
+
+Something was moving between the telegraph poles. My grandmother closed her mouth. Something was jumping about. Three men were darting between the poles, three men made for the chimney, then round in front, then one doubled back. Short and wide he seemed, he took a fresh start and made it across the brickyard, the other two, sort of long and thin, just behind him. They were out of the brickyard, back between the telegraph poles, but Short and Wide twisted and turned and seemed to be in more of a hurry than Long and Thin, who had to double back to the chimney, because he was already rolling over it when they two hands' breadths away, were still taking a start, and suddenly they were gone as though they had given up, and the little one disappeared too, behind the horizon, in the middle of his jump from the chimney.
+
+Out of sight they remained, it was intermission, they were changing their costumes, or making bricks and getting paid for it.
+
+Taking advantage of the intermission, my grandmother tried to spit another potato, but missed it. Because the one who seemed to be short and wide, who hadn't changed his clothes after all climbed up over the horizon as if it were a fence and he had left his pursuers behind it, in among the bricks or on the road to Brenntau. But he was still in a hurry; trying to go faster than the telegraph poles, he took long slow leaps across the field; the mud flew from his boots as he leapt over the soggy ground, but leap as he might, he seemed to be crawling. Sometimes he seemed to stick in the ground and then to stick in mid-air, short and wide time enough to wipe his face before his foot came down again in the freshly plowed field, which bordered the five acres of potatoes and narrowed into a sunken lane.
+
+He made it to the lane; short and wide, he had barely disappeared into the lane, when the two others, long and thin, who had probably been searching the brickyard in the meantime, climbed over the horizon and came plodding through the mud, so long and thin, but not really skinny, that my grandmother missed her potato again; because it's not every day that you see this kind of thing, three full-grown men, though they hadn't grown in exactly the same directions, hopping around telegraph poles, nearly breaking the chimney off the brickworks, and then at intervals, first short and wide, then long and thin, but all with the same difficulty, picking up more and more mud on the soles of their boots, leaping through the field that Vincent had plowed two days before, and disappearing down the sunken lane.
+
+Then all three of them were gone and my grandmother ventured to spit another potato, which by this time was almost cold. She hastily blew the earth and ashes off the skin, popped the whole potato straight into her mouth. They must be from the brickworks, she thought if she thought anything, and she was still chewing with a circular motion when one of them jumped out of the lane, wild eyes over a black mustache, reached the fire in two jumps, stood before, behind, and beside the fire all at once, cursing, scared, not knowing which way to go, unable to turn back, for behind him Long and Thin were running down the lane. He hit his knees, the eyes in his head were like to pop out, and sweat poured from his forehead. Panting, his whole face atremble, he ventured to crawl closer, toward the soles of my grandmother's boots, peering up at her like a squat little animal. Heaving a great sigh, which made her stop chewing on her potato, my grandmother let her feet tilt over, stopped thinking about bricks and brickmakers, and lifted high her skirt, no, all four skirts, high enough so that Short and Wide, who was not from the brickworks, could crawl underneath. Gone was his black mustache; he didn't look like an animal any more, he was neither from Ramkau nor from Viereck, at any rate he had vanished with his fright, he had ceased to be wide or short but he took up room just the same, he forgot to pant or tremble and he had stopped hitting his knees; all was as still as on the first day of Creation or the last; a bit of wind hummed in the potato fire, the telegraph poles counted themselves in silence, the chimney of the brickworks stood at attention, and my grandmother smoothed down her uppermost skirt neatly and sensibly over the second one; she scarcely felt him under her fourth skirt, and her third skirt wasn't even aware that there was anything new and unusual next to her skin. Yes, unusual it was, but the top was nicely smoothed out and the second and third layers didn't know a thing; and so she scraped two or three potatoes out of the ashes, took four raw ones from the basket beneath her right elbow, pushed the raw spuds one after another into the hot ashes, covered them over with more ashes, and poked the fire till the smoke rose in clouds--what else could she have done?
+
+My grandmother's skirts had barely settled down; the sticky smudge of the potato fire, which had lost its direction with all the poking and thrashing about, had barely had time to adjust itself to the wind and resume its low yellow course across the field to southwestward, when Long and Thin popped out of the lane, hot in pursuit of Short and Wide, who by now had set up housekeeping beneath my grandmother's skirts; they were indeed long and thin and they wore the uniform of the rural constabulary.
+
+They nearly ran past my grandmother. One of them even jumped over the fire. But suddenly they remembered they had heels and used them to brake with, about-faced, stood booted and uniformed in the smudge, coughed, pulled their uniforms out of the smudge, taking some of it along with them, and, still coughing, turned to my grandmother, asked her if she had seen Koljaiczek, 'cause she must have seen him 'cause she was sitting here by the lane and that was the way he had come.
+
+My grandmother hadn't seen any Koljaiczek because she didn't know any Koljaiczek. Was he from the brickworks, she asked, 'cause the only ones she knew were the ones from the brickworks. But according to the uniforms, this Koljaiczek had nothing to do with bricks, but was short and stocky. My grandmother remembered she had seen somebody like that running and pointed her stick with the steaming potato on the end toward Bissau, which, to judge by the potato, must have been between the sixth and seventh telegraph poles if you counted westward from the chimney. But whether this fellow that was running was a Koljaiczek, my grandmother couldn't say; she'd been having enough trouble with this fire,: she explained, it was burning poorly, how could she worry her head about all the people that ran by or stood in the smoke, and anyway she never worried her head about people she didn't know, she only knew the people in Bissau, Ramkau, Viereck, and the brickworks--and that was plenty for her.
+
+After saying all this, my grandmother heaved a gentle sigh, but lt was enough of a sigh to make the uniforms ask what there was to sigh about. She nodded toward the fire, meaning to say that she had sighed because the fire was doing poorly and maybe a little on account of the people standing in the smoke; then she bit off half her potato with her widely spaced incisors, and gave her undivided attention to the business of chewing, while her eyeballs rolled heavenward.
+
+My grandmother's absent gaze told the uniforms nothing; unable to make up their minds whether to look for Bissau behind the telegraph poles, they poked their bayonets into all the piles of potato tops that hadn't been set on fire. Responding to a sudden inspiration, they upset the two baskets under my grandmother's elbows almost simultaneously and were quite bewildered when nothing but potatoes came rolling out, and no Koljaiczek. Full of suspicion, they crept round the stack of potatoes, as though Koljaiczek had somehow got into it, thrust in their bayonets as though deliberately taking aim, and were disappointed to hear no cry. Their suspicions were aroused by every bush, however abject, by every mousehole, by a colony of molehills, and most of all by my grandmother, who sat there as if rooted to the spot, sighing, rolling her eyes so that the whites showed, listing the Kashubian names of all the saints--all of which seemed to have been brought on by the poor performance of the fire and the overturning of her potato baskets.
+
+The uniforms stayed on for a good half-hour. They took up positions at varying distances from the fire, they took an azimuth on the chimney, contemplated an offensive against Bissau but postponed it, and held out their purple hands over the fire until my grandmother, though without interrupting her sighs, gave each of them a charred potato. But in the midst of chewing, the uniforms remembered their uniforms, dashed a little way out into the field along the furze bordering the lane, and scared up a hare which, however, turned out not to be Koljaiczek. Returning to the fire, they recovered the mealy, steaming spuds and then, wearied and rather mellowed by their battles, decided to pick up the raw potatoes and put them back into the baskets which they had overturned in line of duty.
+
+Only when evening began to squeeze a fine slanting rain and an inky twilight from the October sky did they briefly and without enthusiasm attack a dark boulder at the other end of the field, but once this enemy had been disposed of they decided to let well enough alone. After flexing their legs for another moment or two and holding out their hands in blessing over the rather dampened fire, they coughed a last cough and dropped a last tear in the green and yellow smudge, and plodded off coughing and weeping in the direction of Bissau. If Koljaiczek wasn't here, he must be in Bissau. Rural constables never envisage more than two possibilities.
+
+The smoke of the slowly dying fire enveloped my grandmother like a spacious fifth skirt, so that she too with her four skirts, her sighs, and her holy names, was under a skirt. Only when the uniforms had become staggering dots, vanishing in the dusk between the telegraph poles, did my grandmother arise, slowly and painfully as though she had struck root and now, drawing earth and fibers along with her, were tearing herself out of the ground.
+
+Suddenly Koljaiczek found himself short, wide, and coverless in the rain, and he was cold. Quickly he buttoned his pants, which fear and a boundless need for shelter had bidden him open during his stay beneath the skirts. Hurriedly he manipulated the buttons, fearing to let his piston cool too quickly, for there was a threat of dire chills in the autumn air.
+
+My grandmother found four more hot potatoes under the ashes. She gave Koljaiczek three of them and took one for herself; before biting into it she asked if he was from the brickworks, though she knew perfectly well that Koljaiczek came from somewhere else and had no connection with bricks. Without waiting for an answer, she lifted the lighter basket to his back, took the heavier one for herself, and still had a hand free for her rake and hoe. Then with her basket, her potatoes, her rake, and her hoe, she set off, like a sail billowing in the breeze, in the direction of Bissau Quarry.
+
+That wasn't the same as Bissau itself. It lay more in the direction of Ramkau. Passing to the right of the brickworks, they headed for the black forest with Goldkrug in it and Brenntau behind it. But in a hollow, before you come to the forest, lay Bissau Quarry. Thither Joseph Koljaiczek, unable to tear himself away from her skirts, followed my grandmother.
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/test/etc/schema/tabletest-schema.xml
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/test/etc/schema/tabletest-schema.xml	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/test/etc/schema/tabletest-schema.xml	(revision 19)
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="ISO-8859-1" standalone="no"?>
+<!DOCTYPE database SYSTEM "http://db.apache.org/torque/dtd/database_3_1.dtd">
+
+<database name="iddb" defaultIdMethod="native">
+
+  <table name="table_native">
+  	<!--
+  		Added the autoIncrement attribute to get run-tests.php running.
+  		Without autoIncrement=true the idMethod will get reset to
+  		IDMethod::NO_ID_METHOD in Table::doFinalInitialization() and
+  		the test (expecting IDMethod::NATIVE) will fail.
+  		Hope this makes sense.
+  	-->
+    <column name="table_a_id" required="true" autoIncrement="true" primaryKey="true" type="INTEGER" />
+    <column name="col_a" type="CHAR" size="5" />
+  </table>
+
+  <table name="table_none" idMethod="none">
+    <column name="table_a_id" required="true" primaryKey="true" type="INTEGER" />
+    <column name="col_a" type="CHAR" size="5" />
+  </table>
+
+
+</database>
+
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/test/etc/xsl/coverage-frames.xsl
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/test/etc/xsl/coverage-frames.xsl	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/test/etc/xsl/coverage-frames.xsl	(revision 19)
@@ -0,0 +1,636 @@
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"
+    xmlns:exsl="http://exslt.org/common"
+    xmlns:date="http://exslt.org/dates-and-times"
+    extension-element-prefixes="exsl date">
+<xsl:output method="html" indent="yes"/>
+<xsl:decimal-format decimal-separator="." grouping-separator="," />
+<!--
+    Copyright  2001-2004 The Apache Software Foundation
+   
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+   
+         http://www.apache.org/licenses/LICENSE-2.0
+   
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+   
+-->
+
+<!--
+
+ Sample stylesheet to be used with Xdebug/Phing code coverage output.
+ Based on JProbe stylesheets from Apache Ant.
+
+ It creates a set of HTML files a la javadoc where you can browse easily
+ through all packages and classes.
+
+ @author Michiel Rook <a href="mailto:michiel@trendserver.nl"/>
+ @author Stephane Bailliez <a href="mailto:sbailliez@apache.org"/>
+
+-->
+
+<!-- default output directory is current directory -->
+<xsl:param name="output.dir" select="'.'"/>
+
+<!-- ======================================================================
+    Root element
+    ======================================================================= -->
+<xsl:template match="/snapshot">
+    <!-- create the index.html -->
+    <exsl:document href="efile://{$output.dir}/index.html">
+        <xsl:call-template name="index.html"/>
+    </exsl:document>
+
+    <!-- create the stylesheet.css -->
+    <exsl:document href="efile://{$output.dir}/stylesheet.css">
+        <xsl:call-template name="stylesheet.css"/>
+    </exsl:document>
+
+    <!-- create the overview-packages.html at the root -->
+    <exsl:document href="efile://{$output.dir}/overview-summary.html">
+        <xsl:apply-templates select="." mode="overview.packages"/>
+    </exsl:document>
+
+    <!-- create the all-packages.html at the root -->
+    <exsl:document href="efile://{$output.dir}/overview-frame.html">
+        <xsl:apply-templates select="." mode="all.packages"/>
+    </exsl:document>
+
+    <!-- create the all-classes.html at the root -->
+    <exsl:document href="efile://{$output.dir}/allclasses-frame.html">
+        <xsl:apply-templates select="." mode="all.classes"/>
+    </exsl:document>
+
+    <!-- process all packages -->
+    <xsl:apply-templates select="./package" mode="write"/>
+</xsl:template>
+
+<!-- =======================================================================
+    Frameset definition. Entry point for the report.
+    3 frames: packageListFrame, classListFrame, classFrame
+    ======================================================================= -->
+<xsl:template name="index.html">
+<html>
+    <head><title>Coverage Results.</title></head>
+    <frameset cols="20%,80%">
+        <frameset rows="30%,70%">
+            <frame src="overview-frame.html" name="packageListFrame"/>
+            <frame src="allclasses-frame.html" name="classListFrame"/>
+        </frameset>
+        <frame src="overview-summary.html" name="classFrame"/>
+    </frameset>
+    <noframes>
+        <h2>Frame Alert</h2>
+        <p>
+        This document is designed to be viewed using the frames feature. If you see this message, you are using a non-frame-capable web client.
+        </p>
+    </noframes>
+</html>
+</xsl:template>
+
+<!-- =======================================================================
+    Stylesheet CSS used
+    ======================================================================= -->
+<!-- this is the stylesheet css to use for nearly everything -->
+<xsl:template name="stylesheet.css">
+    .bannercell {
+      border: 0px;
+      padding: 0px;
+    }
+    body {
+      margin-left: 10;
+      margin-right: 10;
+      background-color:#FFFFFF;
+      font-family: verdana,arial,sanserif;
+      color:#000000;
+    }
+    a {
+      color: #003399;
+    }
+    a:hover {
+      color: #888888;
+    }
+    .a td {
+      background: #efefef;
+    }
+    .b td {
+      background: #fff;
+    }
+    th, td {
+      text-align: left;
+      vertical-align: top;
+    }
+    th {
+      font-weight:bold;
+      background: #ccc;
+      color: black;
+    }
+    table, th, td {
+      font-size: 12px;
+      border: none
+    }
+    table.log tr td, tr th {
+    }
+    h2 {
+      font-weight:bold;
+      font-size: 12px;
+      margin-bottom: 5;
+    }
+    h3 {
+      font-size:100%;
+      font-weight: 12px;
+       background: #DFDFDF
+      color: white;
+      text-decoration: none;
+      padding: 5px;
+      margin-right: 2px;
+      margin-left: 2px;
+      margin-bottom: 0;
+    }
+    .small {
+       font-size: 9px;
+    }
+TD.empty {
+    FONT-SIZE: 2px; BACKGROUND: #c0c0c0; BORDER:#9c9c9c 1px solid;
+    color: #c0c0c0;
+}
+TD.fullcover {
+    FONT-SIZE: 2px; BACKGROUND: #00df00; BORDER:#9c9c9c 1px solid;
+    color: #00df00;
+}
+TD.covered {
+    FONT-SIZE: 2px; BACKGROUND: #00df00; BORDER-LEFT:#9c9c9c 1px solid;BORDER-TOP:#9c9c9c 1px solid;BORDER-BOTTOM:#9c9c9c 1px solid;
+    color: #00df00;
+}
+TD.uncovered {
+    FONT-SIZE: 2px; BACKGROUND: #df0000; BORDER:#9c9c9c 1px solid;
+    color: #df0000;
+}
+PRE.srcLine {
+  BACKGROUND: #ffffff; MARGIN-TOP: 0px; MARGIN-BOTTOM: 0px; 
+}
+td.lineCount, td.coverageCount {
+      BACKGROUND: #F0F0F0; PADDING-RIGHT: 3px;
+      text-align: right;
+}
+td.lineCountHighlight {
+      background: #C8C8F0; PADDING-RIGHT: 3px;
+      text-align: right;
+}
+td.coverageCountHighlight {
+      background: #F0C8C8; PADDING-RIGHT: 3px;
+      text-align: right;
+}
+span.srcLineHighlight {
+      background: #F0C8C8;
+}
+span.srcLine {
+      background: #C8C8F0;
+}
+TD.srcLineClassStart {
+   WIDTH: 100%; BORDER-TOP:#dcdcdc 1px solid; FONT-WEIGHT: bold;    
+}
+.srcLine , .srcLine ol, .srcLine ol li {margin: 0;}
+.srcLine .de1, .srcLine .de2 {font-family: 'Courier New', Courier, monospace; font-weight: normal;}
+.srcLine .imp {font-weight: bold; color: red;}
+.srcLine .kw1 {color: #b1b100;}
+.srcLine .kw2 {color: #000000; font-weight: bold;}
+.srcLine .kw3 {color: #000066;}
+.srcLine .co1 {color: #808080; font-style: italic;}
+.srcLine .co2 {color: #808080; font-style: italic;}
+.srcLine .coMULTI {color: #808080; font-style: italic;}
+.srcLine .es0 {color: #000099; font-weight: bold;}
+.srcLine .br0 {color: #66cc66;}
+.srcLine .st0 {color: #ff0000;}
+.srcLine .nu0 {color: #cc66cc;}
+.srcLine .me1 {color: #006600;}
+.srcLine .me2 {color: #006600;}
+.srcLine .re0 {color: #0000ff;}
+</xsl:template>
+
+<!-- =======================================================================
+    List of all classes in all packages
+    This will be the first page in the classListFrame
+    ======================================================================= -->
+<xsl:template match="snapshot" mode="all.classes">
+    <html>
+        <head>
+            <xsl:call-template name="create.stylesheet.link"/>
+        </head>
+        <body>
+            <h2>All Classes</h2>
+            <table width="100%">
+                <xsl:for-each select="package/class">
+                    <xsl:sort select="@name"/>
+                    <xsl:variable name="package.name" select="(ancestor::package)[last()]/@name"/>
+                    <xsl:variable name="link">
+                        <xsl:if test="not($package.name='')">
+                            <xsl:value-of select="translate($package.name,'.','/')"/><xsl:text>/</xsl:text>
+                        </xsl:if><xsl:value-of select="@name"/><xsl:text>.html</xsl:text>
+                    </xsl:variable>
+                    <tr>
+                        <td nowrap="nowrap">
+                            <a target="classFrame" href="{$link}"><xsl:value-of select="@name"/></a>
+                            <xsl:choose>
+								<xsl:when test="@methodcount=0">
+									<i> (-)</i>
+								</xsl:when>
+								<xsl:otherwise>
+									<i> (<xsl:value-of select="format-number(@methodscovered div @methodcount, '0.0%')"/>)</i>
+								</xsl:otherwise>
+							</xsl:choose>
+                        </td>
+                    </tr>
+                </xsl:for-each>
+            </table>
+        </body>
+    </html>
+</xsl:template>
+
+<!-- list of all packages -->
+<xsl:template match="snapshot" mode="all.packages">
+    <html>
+        <head>
+            <xsl:call-template name="create.stylesheet.link"/>
+        </head>
+        <body>
+            <h2><a href="overview-summary.html" target="classFrame">Overview</a></h2>
+            <h2>All Packages</h2>
+            <table width="100%">
+                <xsl:for-each select="package">
+                    <xsl:sort select="@name" order="ascending"/>
+                    <tr>
+                        <td nowrap="nowrap">
+                            <a href="{translate(@name,'.','/')}/package-summary.html" target="classFrame">
+                                <xsl:value-of select="@name"/>
+                            </a>
+                        </td>
+                    </tr>
+                </xsl:for-each>
+            </table>
+        </body>
+    </html>
+</xsl:template>
+
+<!-- overview of statistics in packages -->
+<xsl:template match="snapshot" mode="overview.packages">
+    <html>
+        <head>
+            <xsl:call-template name="create.stylesheet.link"/>
+        </head>
+        <body onload="open('allclasses-frame.html','classListFrame')">
+        <xsl:call-template name="pageHeader"/>
+        <table class="log" cellpadding="5" cellspacing="0" width="100%">
+            <tr class="a">
+                <td class="small">Packages: <xsl:value-of select="count(package)"/></td>
+                <td class="small">Classes: <xsl:value-of select="count(package/class)"/></td>
+                <td class="small">Methods: <xsl:value-of select="@methodcount"/></td>
+                <td class="small">LOC: <xsl:value-of select="count(package/class/sourcefile/sourceline)"/></td>
+            </tr>
+        </table>        
+        <br/>
+
+        <table class="log" cellpadding="5" cellspacing="0" width="100%">
+            <tr>
+                <th width="100%" nowrap="nowrap"></th>
+                <th width="350" colspan="2" nowrap="nowrap">Methods covered</th>
+            </tr>
+            <tr class="a">
+        <td>Total coverage</td>
+                <xsl:call-template name="stats.formatted"/>
+            </tr>
+            <tr>
+                <td colspan="3"><br/></td>
+            </tr>
+            <tr>
+                <th width="100%">Packages</th>
+                <th width="350" colspan="2" nowrap="nowrap">Methods covered</th>
+            </tr>
+            <!-- display packages and sort them via their coverage rate -->
+            <xsl:for-each select="package">
+                <xsl:sort data-type="number" select="@methodscovered div @methodcount"/>
+                <tr>
+                  <xsl:call-template name="alternate-row"/>
+                    <td><a href="{translate(@name,'.','/')}/package-summary.html"><xsl:value-of select="@name"/></a></td>
+                    <xsl:call-template name="stats.formatted"/>
+                </tr>
+            </xsl:for-each>
+        </table>
+        <xsl:call-template name="pageFooter"/>
+        </body>
+        </html>
+</xsl:template>
+
+<!--
+ detailed info for a package. It will output the list of classes
+, the summary page, and the info for each class
+-->
+<xsl:template match="package" mode="write">
+    <xsl:variable name="package.dir">
+        <xsl:if test="not(@name = '')"><xsl:value-of select="translate(@name,'.','/')"/></xsl:if>
+        <xsl:if test="@name = ''">.</xsl:if>
+    </xsl:variable>
+
+    <!-- create a classes-list.html in the package directory -->
+    <exsl:document href="efile://{$output.dir}/{$package.dir}/package-frame.html">
+        <xsl:apply-templates select="." mode="classes.list"/>
+    </exsl:document>
+
+    <!-- create a package-summary.html in the package directory -->
+    <exsl:document href="efile://{$output.dir}/{$package.dir}/package-summary.html">
+        <xsl:apply-templates select="." mode="package.summary"/>
+    </exsl:document>
+
+    <!-- for each class, creates a @name.html -->
+    <xsl:for-each select="class">
+        <exsl:document href="efile://{$output.dir}/{$package.dir}/{@name}.html">
+            <xsl:apply-templates select="." mode="class.details"/>
+        </exsl:document>
+    </xsl:for-each>
+</xsl:template>
+
+<!-- list of classes in a package -->
+<xsl:template match="package" mode="classes.list">
+    <html>
+        <HEAD>
+            <xsl:call-template name="create.stylesheet.link">
+                <xsl:with-param name="package.name" select="@name"/>
+            </xsl:call-template>
+        </HEAD>
+        <BODY>
+            <table width="100%">
+                <tr>
+                    <td nowrap="nowrap">
+                        <H2><a href="package-summary.html" target="classFrame"><xsl:value-of select="@name"/></a></H2>
+                    </td>
+                </tr>
+            </table>
+
+            <H2>Classes</H2>
+            <TABLE WIDTH="100%">
+                <xsl:for-each select="class">
+                    <xsl:sort select="@name"/>
+                    <tr>
+                        <td nowrap="nowrap">
+                            <a href="{@name}.html" target="classFrame"><xsl:value-of select="@name"/></a>
+                            <xsl:choose>
+								<xsl:when test="@methodcount=0">
+									<i> (-)</i>
+								</xsl:when>
+								<xsl:otherwise>
+                            		<i>(<xsl:value-of select="format-number(@methodscovered div @methodcount, '0.0%')"/>)</i>
+                            	</xsl:otherwise>
+                            </xsl:choose>
+                        </td>
+                    </tr>
+                </xsl:for-each>
+            </TABLE>
+        </BODY>
+    </html>
+</xsl:template>
+
+<!-- summary of a package -->
+<xsl:template match="package" mode="package.summary">
+    <HTML>
+        <HEAD>
+            <xsl:call-template name="create.stylesheet.link">
+                <xsl:with-param name="package.name" select="@name"/>
+            </xsl:call-template>
+        </HEAD>
+        <!-- when loading this package, it will open the classes into the frame -->
+        <BODY onload="open('package-frame.html','classListFrame')">
+            <xsl:call-template name="pageHeader"/>
+            <table class="log" cellpadding="5" cellspacing="0" width="100%">
+                <tr class="a">
+                    <td class="small">Classes: <xsl:value-of select="count(class)"/></td>
+                    <td class="small">Methods: <xsl:value-of select="@methodcount"/></td>
+                    <td class="small">LOC: <xsl:value-of select="count(class/sourcefile/sourceline)"/></td>
+                </tr>
+            </table>        
+            <br/>
+
+            <table class="log" cellpadding="5" cellspacing="0" width="100%">
+                <tr>
+                    <th width="100%">Package</th>
+                    <th width="350" colspan="2" nowrap="nowrap">Methods covered</th>
+                </tr>
+                <xsl:apply-templates select="." mode="stats"/>
+
+                <xsl:if test="count(class) &gt; 0">
+                    <tr>
+                        <td colspan="3"><br/></td>
+                    </tr>
+                    <tr>
+                        <th width="100%">Classes</th>
+                        <th width="350" colspan="2" nowrap="nowrap">Methods covered</th>
+                    </tr>
+                    <xsl:apply-templates select="class" mode="stats">
+                        <xsl:sort data-type="number" select="@methodscovered div @methodcount"/>
+                    </xsl:apply-templates>
+                </xsl:if>
+            </table>
+            <xsl:call-template name="pageFooter"/>
+        </BODY>
+    </HTML>
+</xsl:template>
+
+<!-- details of a class -->
+<xsl:template match="class" mode="class.details">
+    <xsl:variable name="package.name" select="(ancestor::package)[last()]/@name"/>
+    <HTML>
+        <HEAD>
+            <xsl:call-template name="create.stylesheet.link">
+                <xsl:with-param name="package.name" select="$package.name"/>
+            </xsl:call-template>
+        </HEAD>
+        <BODY>
+            <xsl:call-template name="pageHeader"/>
+            <table class="log" cellpadding="5" cellspacing="0" width="100%">
+                <tr class="a">
+                    <td class="small">Methods: <xsl:value-of select="@methodcount"/></td>
+                    <td class="small">LOC: <xsl:value-of select="count(sourcefile/sourceline)"/></td>
+                </tr>
+            </table>        
+            <br/>
+
+            <!-- class summary -->
+            <table class="log" cellpadding="5" cellspacing="0" width="100%">
+                <tr>
+                    <th width="100%">Source file</th>
+                    <th width="250" colspan="2" nowrap="nowrap">Methods covered</th>
+                </tr>
+                <tr>
+                    <xsl:call-template name="alternate-row"/>
+                    <td><xsl:value-of select="sourcefile/@name"/></td>
+                    <xsl:call-template name="stats.formatted"/>
+                </tr>
+            </table>
+            <table cellspacing="0" cellpadding="0" width="100%">
+                <xsl:apply-templates select="sourcefile/sourceline"/>
+            </table>
+            <br/>
+            <xsl:call-template name="pageFooter"/>
+        </BODY>
+    </HTML>
+
+</xsl:template>
+
+<!-- Page Header -->
+<xsl:template name="pageHeader">
+  <!-- jakarta logo -->
+  <table border="0" cellpadding="0" cellspacing="0" width="100%">
+  <tr>
+    <td class="bannercell" rowspan="2">
+      <a href="http://phing.info/">
+      <img src="http://phing.info/images/phing.gif" alt="http://phing.info/" align="left" border="0"/>
+      </a>
+    </td>
+        <td style="text-align:right"><h2>Source Code Coverage</h2></td>
+        </tr>
+        <tr>
+        <td style="text-align:right">Designed for use with <a href='http://pear.php.net/package/PHPUnit2'>PHPUnit2</a>, <a href='http://www.xdebug.org/'>Xdebug</a> and <a href='http://phing.info/'>Phing</a>.</td>
+        </tr>
+  </table>
+    <hr size="1"/>
+</xsl:template>
+
+<!-- Page Footer -->
+<xsl:template name="pageFooter">
+    <table width="100%">
+      <tr><td><hr noshade="yes" size="1"/></td></tr>
+      <tr><td class="small">Report generated at <xsl:value-of select="date:date-time()"/></td></tr>
+    </table>
+</xsl:template>
+
+<xsl:template match="package" mode="stats">
+    <tr>
+      <xsl:call-template name="alternate-row"/>
+        <td><xsl:value-of select="@name"/></td>
+        <xsl:call-template name="stats.formatted"/>
+    </tr>
+</xsl:template>
+
+<xsl:template match="class" mode="stats">
+    <tr>
+      <xsl:call-template name="alternate-row"/>
+        <td><a href="{@name}.html" target="classFrame"><xsl:value-of select="@name"/></a></td>
+        <xsl:call-template name="stats.formatted"/>
+    </tr>
+</xsl:template>
+
+<xsl:template name="stats.formatted">
+    <xsl:choose>
+        <xsl:when test="@methodcount=0">
+            <td>-</td>
+            <td>
+            <table cellspacing="0" cellpadding="0" border="0" width="100%" style="display: inline">
+                <tr>
+                    <td class="empty" width="200" height="12">&#160;</td>
+                </tr>
+            </table>
+            </td>
+        </xsl:when>
+        <xsl:otherwise>
+            <td>
+            <xsl:value-of select="format-number(@methodscovered div @methodcount,'0.0%')"/>
+            </td>
+            <td>
+            <xsl:variable name="leftwidth"><xsl:value-of select="format-number((@methodscovered * 200) div @methodcount,'0')"/></xsl:variable>
+            <xsl:variable name="rightwidth"><xsl:value-of select="format-number(200 - (@methodscovered * 200) div @methodcount,'0')"/></xsl:variable>
+            <table cellspacing="0" cellpadding="0" border="0" width="100%" style="display: inline">
+                <tr>
+                    <xsl:choose>
+                        <xsl:when test="$leftwidth=200">
+                            <td class="fullcover" width="200" height="12">&#160;</td>
+                        </xsl:when>
+                        <xsl:otherwise>
+                            <xsl:if test="not($leftwidth=0)">
+                                <td class="covered" width="{$leftwidth}" height="12">&#160;</td>
+                            </xsl:if>
+                            <xsl:if test="not($rightwidth=0)">
+                                <td class="uncovered" width="{$rightwidth}" height="12">&#160;</td>
+                            </xsl:if>
+                        </xsl:otherwise>
+                    </xsl:choose>
+                </tr>
+            </table>
+            </td>
+        </xsl:otherwise>
+    </xsl:choose>
+</xsl:template>
+
+<xsl:template match="sourceline">
+    <tr>
+        <xsl:if test="@coveredcount>0">
+            <td class="lineCountHighlight"><xsl:value-of select="position()"/></td>
+            <td class="lineCountHighlight"><xsl:value-of select="@coveredcount"/></td>
+        </xsl:if>
+        <xsl:if test="@coveredcount&lt;0">
+            <td class="lineCountHighlight"><xsl:value-of select="position()"/></td>
+            <td class="coverageCountHighlight">0</td>
+        </xsl:if>
+        <xsl:if test="@coveredcount=0">
+            <td class="lineCount"><xsl:value-of select="position()"/></td>
+            <td class="coverageCount"></td>
+        </xsl:if>
+        <td>
+        	<xsl:if test="@startclass=1">        	
+            	<xsl:attribute name="class">srcLineClassStart</xsl:attribute>
+            </xsl:if>
+            <xsl:if test="@coveredcount>0">
+                <span class="srcLine">
+                <pre class="srcLine"><xsl:value-of select="." disable-output-escaping="yes"/></pre>
+                </span>
+            </xsl:if>
+            <xsl:if test="@coveredcount&lt;0">
+                <span class="srcLineHighlight">
+                <pre class="srcLine"><xsl:value-of select="." disable-output-escaping="yes"/></pre>
+                </span>
+            </xsl:if>
+            <xsl:if test="@coveredcount=0">
+                <pre class="srcLine"><xsl:value-of select="." disable-output-escaping="yes"/></pre>
+            </xsl:if>
+        </td>
+    </tr>
+</xsl:template>
+
+<!--
+    transform string like a.b.c to ../../../
+    @param path the path to transform into a descending directory path
+-->
+<xsl:template name="path">
+    <xsl:param name="path"/>
+    <xsl:if test="contains($path,'.')">
+        <xsl:text>../</xsl:text>
+        <xsl:call-template name="path">
+            <xsl:with-param name="path"><xsl:value-of select="substring-after($path,'.')"/></xsl:with-param>
+        </xsl:call-template>
+    </xsl:if>
+    <xsl:if test="not(contains($path,'.')) and not($path = '')">
+        <xsl:text>../</xsl:text>
+    </xsl:if>
+</xsl:template>
+
+
+<!-- create the link to the stylesheet based on the package name -->
+<xsl:template name="create.stylesheet.link">
+    <xsl:param name="package.name"/>
+    <LINK REL ="stylesheet" TYPE="text/css" TITLE="Style"><xsl:attribute name="href"><xsl:if test="not($package.name = 'unnamed package')"><xsl:call-template name="path"><xsl:with-param name="path" select="$package.name"/></xsl:call-template></xsl:if>stylesheet.css</xsl:attribute></LINK>
+</xsl:template>
+
+<!-- alternated row style -->
+<xsl:template name="alternate-row">
+<xsl:attribute name="class">
+  <xsl:if test="position() mod 2 = 1">a</xsl:if>
+  <xsl:if test="position() mod 2 = 0">b</xsl:if>
+</xsl:attribute>
+</xsl:template>
+
+</xsl:stylesheet>
+
+
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/test/etc/xsl/log.xsl
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/test/etc/xsl/log.xsl	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/test/etc/xsl/log.xsl	(revision 19)
@@ -0,0 +1,216 @@
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
+<xsl:output method="html" indent="yes" encoding="US-ASCII"/>
+<!--
+    Copyright  2000-2004 The Apache Software Foundation
+   
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+   
+         http://www.apache.org/licenses/LICENSE-2.0
+   
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+   
+-->
+ 
+<!--
+
+  The purpose have this XSL is to provide a nice way to look at the output
+  from the Ant XmlLogger (ie: ant -listener org.apache.tools.ant.XmlLogger )
+  
+  @author <a href="mailto:michiel@trendserver.nl>Michiel Rook</a>
+  @author <a href="mailto:sbailliez@apache.org">Stephane Bailliez</a>
+  
+-->
+<xsl:decimal-format decimal-separator="." grouping-separator="," />
+
+<xsl:template match="/">
+<html>
+  <head>
+    <title>Phing Build Log</title>
+    <style type="text/css">
+    .bannercell {
+      border: 0px;
+      padding: 0px;
+    }
+    body {
+      margin: 0;
+      font:normal 100% arial,helvetica,sanserif;
+      background-color:#FFFFFF;
+      color:#000000;
+    }
+    table.status {
+      font:bold 80% arial,helvetica,sanserif;
+      background-color:#525D76;
+      color:#ffffff;
+    }
+    table.log tr td, tr th {
+      font-size: 80%;
+    }
+    .error {
+      color:red;
+    }
+    .warn {
+      color:brown;
+    }
+    .info {
+      color:gray;
+    }
+    .debug{
+      color:gray;
+    }
+    .failed {
+      font-size:80%;
+      background-color: red;
+      color:#FFFFFF;
+      font-weight: bold
+    }
+    .complete {
+      font-size:80%;
+      background-color: #525D76;
+      color:#FFFFFF;
+      font-weight: bold
+    }
+    .a td { 
+      background: #efefef;
+    }
+    .b td { 
+      background: #fff;
+    }
+    th, td {
+      text-align: left;
+      vertical-align: top;
+    }
+    th {
+      background: #ccc;
+      color: black;
+    }
+    table, th, td {
+      border: none
+    }
+    h3 {
+      font:bold 80% arial,helvetica,sanserif;
+      background: #525D76;
+      color: white;
+      text-decoration: none;
+      padding: 5px;
+      margin-right: 2px;
+      margin-left: 2px;
+      margin-bottom: 0;
+    }
+    a {
+      color: #003399;
+    }
+    a:hover {
+      color: #888888;
+    }
+    </style>
+  </head>
+  <body>
+    <!-- jakarta logo -->
+    <table border="0" cellpadding="0" cellspacing="0" width="100%">
+    <tr>
+      <td valign="top" class="bannercell">
+        <a href="http://phing.info/">
+        <img src="http://phing.info/images/phing.gif" alt="http://phing.info/" align="left" border="0"/>
+        </a>
+      </td>
+      <td style="text-align:right;vertical-align:bottom">
+        <a href="http://phing.info/">Phing</a>
+      </td>
+    </tr>
+    </table>
+      
+    <table border="0" width="100%">
+    <tr><td><hr noshade="yes" size="1"/></td></tr>
+    </table>
+
+    <xsl:apply-templates select="build"/>
+
+    <!-- FOOTER -->
+    <table width="100%">
+      <tr><td><hr noshade="yes" size="1"/></td></tr>
+      <tr><td>
+      <div align="center"><font color="#525D76" size="-1"><em>
+      <a href="http://phing.info/">Phing</a>
+      </em></font></div>
+      </td></tr>
+    </table>
+  </body>
+</html>
+</xsl:template>
+
+<xsl:template match="build">
+  <!-- build status -->
+  <table width="100%">
+    <xsl:attribute name="class">
+      <xsl:if test="@error">failed</xsl:if>
+      <xsl:if test="not(@error)">complete</xsl:if>
+    </xsl:attribute>
+    <tr>
+      <xsl:if test="@error">
+        <td nowrap="yes">Build Failed</td> 
+      </xsl:if>
+      <xsl:if test="not(@error)">
+        <td nowrap="yes">Build Complete</td>
+      </xsl:if>
+        <td style="text-align:right" nowrap="yes">Total Time: <xsl:value-of select="@time"/></td>
+    </tr>
+    <tr>
+      <td colspan="2">
+        <xsl:if test="@error">
+          <tt><xsl:value-of select="@error"/></tt><br/>
+          <i style="font-size:80%">See the <a href="#stacktrace" alt="Click for details">stacktrace</a>.</i>
+        </xsl:if>
+      </td>
+    </tr>
+  </table>
+  <table border="1" cellspacing="2" cellpadding="3" width="100%" style="font-size:80%">
+    <tr class="a"><td width="1">phing.file</td><td><xsl:value-of select="substring-after(//message[contains(text(),'phing.file')], '->')"/></td></tr>
+    <tr class="b"><td width="1">phing.version</td><td><xsl:value-of select="substring-after(//message[contains(text(),'phing.version')], '->')"/></td></tr>
+  </table>
+  <!-- build information -->
+  <h3>Build events</h3>
+  <table class="log" border="1" cellspacing="2" cellpadding="3" width="100%">
+  <tr>
+    <th nowrap="yes" align="left" width="1%">target</th>
+    <th nowrap="yes" align="left" width="1%">task</th>
+    <th nowrap="yes" align="left">message</th>
+  </tr>
+  <xsl:apply-templates select=".//message[@priority != 'debug']"/>
+  </table>
+  <p>
+  <!-- stacktrace -->
+  <xsl:if test="stacktrace">
+  <a name="stacktrace"/>
+  <h3>Error details</h3>
+  <table width="100%">
+    <tr><td>
+      <pre><xsl:value-of select="stacktrace"/></pre>
+    </td></tr>
+  </table>
+  </xsl:if>
+  </p>
+</xsl:template>
+
+<!-- report every message but those with debug priority -->
+<xsl:template match="message[@priority!='debug']">
+  <tr valign="top">
+    <!-- alternated row style -->
+    <xsl:attribute name="class">
+      <xsl:if test="position() mod 2 = 1">a</xsl:if>
+      <xsl:if test="position() mod 2 = 0">b</xsl:if>
+    </xsl:attribute>
+    <td nowrap="yes" width="1%"><xsl:value-of select="../../@name"/></td>
+    <td nowrap="yes" style="text-align:right" width="1%">[ <xsl:value-of select="../@name"/> ]</td>
+    <td class="{@priority}" nowrap="yes">
+            <xsl:value-of select="text()"/>
+    </td>
+  </tr>
+</xsl:template>
+
+</xsl:stylesheet>
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/test/etc/xsl/phpunit2-noframes.xsl
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/test/etc/xsl/phpunit2-noframes.xsl	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/test/etc/xsl/phpunit2-noframes.xsl	(revision 19)
@@ -0,0 +1,438 @@
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"
+    xmlns:exsl="http://exslt.org/common"
+    xmlns:str="http://exslt.org/strings"
+    xmlns:date="http://exslt.org/dates-and-times"
+    extension-element-prefixes="exsl str date">
+<xsl:include href="str.replace.function.xsl"/>
+<xsl:output method="html" indent="yes" encoding="US-ASCII"
+  doctype-public="-//W3C//DTD HTML 4.01 Transitional//EN" />
+<xsl:decimal-format decimal-separator="." grouping-separator="," />
+<!--
+   Copyright 2001-2004 The Apache Software Foundation
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+ -->
+ 
+<!--
+ 
+ Sample stylesheet to be used with Phing/PHPUnit2 output.
+ Based on JUnit stylesheets from Apache Ant.
+ 
+ It creates a non-framed report that can be useful to send via
+ e-mail or such.
+ 
+ @author Michiel Rook <a href="mailto:michiel@trendserver.nl"/>
+ @author Stephane Bailliez <a href="mailto:sbailliez@apache.org"/>
+ @author Erik Hatcher <a href="mailto:ehatcher@apache.org"/>
+ 
+-->
+<xsl:template match="testsuites">
+    <html>
+        <head>
+            <title>Unit Test Results</title>
+    <style type="text/css">
+    body {
+        font-family: verdana,arial,helvetica;
+        color:#000000;
+        font-size: 12px;
+    }
+    table tr td, table tr th {
+        font-family: verdana,arial,helvetica;
+        font-size: 12px;
+    }
+    table.details tr th{
+        font-family: verdana,arial,helvetica;
+        font-weight: bold;
+        text-align:left;
+        background:#a6caf0;
+    }
+    table.details tr td{
+        background:#eeeee0;
+    }
+
+    p {
+        line-height:1.5em;
+        margin-top:0.5em; margin-bottom:1.0em;
+        font-size: 12px;
+    }
+    h1 {
+        margin: 0px 0px 5px;
+        font-family: verdana,arial,helvetica;
+    }
+    h2 {
+        margin-top: 1em; margin-bottom: 0.5em;
+        font-family: verdana,arial,helvetica;
+    }
+    h3 {
+        margin-bottom: 0.5em;
+        font-family: verdana,arial,helvetica;
+    }
+    h4 {
+        margin-bottom: 0.5em;
+        font-family: verdana,arial,helvetica;
+    }
+    h5 {
+        margin-bottom: 0.5em;
+        font-family: verdana,arial,helvetica;
+    }
+    h6 {
+        margin-bottom: 0.5em;
+        font-family: verdana,arial,helvetica;
+    }
+    .Error {
+        font-weight:bold; color:red;
+    }
+    .Failure {
+        font-weight:bold; color:purple;
+    }
+    .small {
+       font-size: 9px;
+    }
+    a {
+      color: #003399;
+    }
+    a:hover {
+      color: #888888;
+    }
+    </style>
+        </head>
+        <body>
+            <a name="top"></a>
+            <xsl:call-template name="pageHeader"/>  
+            
+            <!-- Summary part -->
+            <xsl:call-template name="summary"/>
+            <hr size="1" width="95%" align="left"/>
+            
+            <!-- Package List part -->
+            <xsl:call-template name="packagelist"/>
+            <hr size="1" width="95%" align="left"/>
+            
+            <!-- For each package create its part -->
+            <xsl:call-template name="packages"/>
+            <hr size="1" width="95%" align="left"/>
+            
+            <!-- For each class create the  part -->
+            <xsl:call-template name="classes"/>
+            
+            <xsl:call-template name="pageFooter"/>  
+        </body>
+    </html>
+</xsl:template>
+    
+    
+    
+    <!-- ================================================================== -->
+    <!-- Write a list of all packages with an hyperlink to the anchor of    -->
+    <!-- of the package name.                                               -->
+    <!-- ================================================================== -->
+    <xsl:template name="packagelist">   
+        <h2>Packages</h2>
+        Note: package statistics are not computed recursively, they only sum up all of its testsuites numbers.
+        <table class="details" border="0" cellpadding="5" cellspacing="2" width="95%">
+            <xsl:call-template name="testsuite.test.header"/>
+            <!-- list all packages recursively -->
+            <xsl:for-each select="./testsuite[not(./@package = preceding-sibling::testsuite/@package)]">
+                <xsl:sort select="@package"/>
+                <xsl:variable name="testsuites-in-package" select="/testsuites/testsuite[./@package = current()/@package]"/>
+                <xsl:variable name="testCount" select="sum($testsuites-in-package/@tests)"/>
+                <xsl:variable name="errorCount" select="sum($testsuites-in-package/@errors)"/>
+                <xsl:variable name="failureCount" select="sum($testsuites-in-package/@failures)"/>
+                <xsl:variable name="timeCount" select="sum($testsuites-in-package/@time)"/>
+                
+                <!-- write a summary for the package -->
+                <tr valign="top">
+                    <!-- set a nice color depending if there is an error/failure -->
+                    <xsl:attribute name="class">
+                        <xsl:choose>
+                            <xsl:when test="$failureCount &gt; 0">Failure</xsl:when>
+                            <xsl:when test="$errorCount &gt; 0">Error</xsl:when>
+                        </xsl:choose>
+                    </xsl:attribute>
+                    <td><a href="#{@package}"><xsl:value-of select="@package"/></a></td>
+                    <td><xsl:value-of select="$testCount"/></td>
+                    <td><xsl:value-of select="$errorCount"/></td>
+                    <td><xsl:value-of select="$failureCount"/></td>
+                    <td>
+                    <xsl:call-template name="display-time">
+                        <xsl:with-param name="value" select="$timeCount"/>
+                    </xsl:call-template>
+                    </td>
+                </tr>
+            </xsl:for-each>
+        </table>        
+    </xsl:template>
+    
+    
+    <!-- ================================================================== -->
+    <!-- Write a package level report                                       -->
+    <!-- It creates a table with values from the document:                  -->
+    <!-- Name | Tests | Errors | Failures | Time                            -->
+    <!-- ================================================================== -->
+    <xsl:template name="packages">
+        <!-- create an anchor to this package name -->
+        <xsl:for-each select="/testsuites/testsuite[not(./@package = preceding-sibling::testsuite/@package)]">
+            <xsl:sort select="@package"/>
+                <a name="{@package}"></a>
+                <h3>Package <xsl:value-of select="@package"/></h3>
+                
+                <table class="details" border="0" cellpadding="5" cellspacing="2" width="95%">
+                    <xsl:call-template name="testsuite.test.header"/>
+            
+                    <!-- match the testsuites of this package -->
+                    <xsl:apply-templates select="/testsuites/testsuite[./@package = current()/@package]" mode="print.test"/>
+                </table>
+                <a href="#top">Back to top</a>
+                <p/>
+                <p/>
+        </xsl:for-each>
+    </xsl:template>
+    
+    <xsl:template name="classes">
+        <xsl:for-each select="testsuite">
+            <xsl:sort select="@name"/>
+            <!-- create an anchor to this class name -->
+            <a name="{@name}"></a>
+            <h3>TestCase <xsl:value-of select="@name"/></h3>
+            
+            <table class="details" border="0" cellpadding="5" cellspacing="2" width="95%">
+              <xsl:call-template name="testcase.test.header"/>
+              <!--
+              test can even not be started at all (failure to load the class)
+              so report the error directly
+              -->
+                <xsl:if test="./error">
+                    <tr class="Error">
+                        <td colspan="4"><xsl:apply-templates select="./error"/></td>
+                    </tr>
+                </xsl:if>
+                <xsl:apply-templates select="./testcase" mode="print.test"/>
+            </table>
+            <p/>
+            
+            <a href="#top">Back to top</a>
+        </xsl:for-each>
+    </xsl:template>
+    
+    <xsl:template name="summary">
+        <h2>Summary</h2>
+        <xsl:variable name="testCount" select="sum(testsuite/@tests)"/>
+        <xsl:variable name="errorCount" select="sum(testsuite/@errors)"/>
+        <xsl:variable name="failureCount" select="sum(testsuite/@failures)"/>
+        <xsl:variable name="timeCount" select="sum(testsuite/@time)"/>
+        <xsl:variable name="successRate" select="($testCount - $failureCount - $errorCount) div $testCount"/>
+        <table class="details" border="0" cellpadding="5" cellspacing="2" width="95%">
+        <tr valign="top">
+            <th>Tests</th>
+            <th>Failures</th>
+            <th>Errors</th>
+            <th>Success rate</th>
+            <th>Time</th>
+        </tr>
+        <tr valign="top">
+            <xsl:attribute name="class">
+                <xsl:choose>
+                    <xsl:when test="$failureCount &gt; 0">Failure</xsl:when>
+                    <xsl:when test="$errorCount &gt; 0">Error</xsl:when>
+                </xsl:choose>
+            </xsl:attribute>
+            <td><xsl:value-of select="$testCount"/></td>
+            <td><xsl:value-of select="$failureCount"/></td>
+            <td><xsl:value-of select="$errorCount"/></td>
+            <td>
+                <xsl:call-template name="display-percent">
+                    <xsl:with-param name="value" select="$successRate"/>
+                </xsl:call-template>
+            </td>
+            <td>
+                <xsl:call-template name="display-time">
+                    <xsl:with-param name="value" select="$timeCount"/>
+                </xsl:call-template>
+            </td>
+
+        </tr>
+        </table>
+        <table border="0" width="95%">
+        <tr>
+        <td style="text-align: justify;">
+        Note: <i>failures</i> are anticipated and checked for with assertions while <i>errors</i> are unanticipated.
+        </td>
+        </tr>
+        </table>
+    </xsl:template>
+      
+<!-- Page HEADER -->
+<xsl:template name="pageHeader">
+    <h1>Unit Test Results</h1>
+    <table width="100%">
+    <tr>
+        <td align="left"></td>
+        <td align="right">Designed for use with <a href='http://pear.php.net/package/PHPUnit2'>PHPUnit2</a> and <a href='http://phing.info/'>Phing</a>.</td>
+    </tr>
+    </table>
+    <hr size="1"/>
+</xsl:template>
+
+<!-- Page Footer -->
+<xsl:template name="pageFooter">
+    <table width="100%">
+      <tr><td><hr noshade="yes" size="1"/></td></tr>
+      <tr><td class="small">Report generated at <xsl:value-of select="date:date-time()"/></td></tr>
+    </table>
+</xsl:template>
+
+<xsl:template match="testsuite" mode="header">
+    <tr valign="top">
+        <th width="80%">Name</th>
+        <th>Tests</th>
+        <th>Errors</th>
+        <th>Failures</th>
+        <th nowrap="nowrap">Time(s)</th>
+    </tr>
+</xsl:template>
+
+<!-- class header -->
+<xsl:template name="testsuite.test.header">
+    <tr valign="top">
+        <th width="80%">Name</th>
+        <th>Tests</th>
+        <th>Errors</th>
+        <th>Failures</th>
+        <th nowrap="nowrap">Time(s)</th>
+    </tr>
+</xsl:template>
+
+<!-- method header -->
+<xsl:template name="testcase.test.header">
+    <tr valign="top">
+        <th>Name</th>
+        <th>Status</th>
+        <th width="80%">Type</th>
+        <th nowrap="nowrap">Time(s)</th>
+    </tr>
+</xsl:template>
+
+
+<!-- class information -->
+<xsl:template match="testsuite" mode="print.test">
+    <tr valign="top">
+        <!-- set a nice color depending if there is an error/failure -->
+        <xsl:attribute name="class">
+            <xsl:choose>
+                <xsl:when test="@failures[.&gt; 0]">Failure</xsl:when>
+                <xsl:when test="@errors[.&gt; 0]">Error</xsl:when>
+            </xsl:choose>
+        </xsl:attribute>
+    
+        <!-- print testsuite information -->
+        <td><a href="#{@name}"><xsl:value-of select="@name"/></a></td>
+        <td><xsl:value-of select="@tests"/></td>
+        <td><xsl:value-of select="@errors"/></td>
+        <td><xsl:value-of select="@failures"/></td>
+        <td>
+            <xsl:call-template name="display-time">
+                <xsl:with-param name="value" select="@time"/>
+            </xsl:call-template>
+        </td>
+    </tr>
+</xsl:template>
+
+<xsl:template match="testcase" mode="print.test">
+    <tr valign="top">
+        <xsl:attribute name="class">
+            <xsl:choose>
+                <xsl:when test="failure | error">Error</xsl:when>
+            </xsl:choose>
+        </xsl:attribute>
+        <td><xsl:value-of select="@name"/></td>
+        <xsl:choose>
+            <xsl:when test="failure">
+                <td>Failure</td>
+                <td><xsl:apply-templates select="failure"/></td>
+            </xsl:when>
+            <xsl:when test="error">
+                <td>Error</td>
+                <td><xsl:apply-templates select="error"/></td>
+            </xsl:when>
+            <xsl:otherwise>
+                <td>Success</td>
+                <td></td>
+            </xsl:otherwise>
+        </xsl:choose>
+        <td>
+            <xsl:call-template name="display-time">
+                <xsl:with-param name="value" select="@time"/>
+            </xsl:call-template>
+        </td>
+    </tr>
+</xsl:template>
+
+
+<xsl:template match="failure">
+    <xsl:call-template name="display-failures"/>
+</xsl:template>
+
+<xsl:template match="error">
+    <xsl:call-template name="display-failures"/>
+</xsl:template>
+
+<!-- Style for the error and failure in the tescase template -->
+<xsl:template name="display-failures">
+    <xsl:choose>
+        <xsl:when test="not(@message)">N/A</xsl:when>
+        <xsl:otherwise>
+            <xsl:value-of select="@message"/>
+        </xsl:otherwise>
+    </xsl:choose>
+    <!-- display the stacktrace -->
+    <code>
+        <br/><br/>
+		<xsl:value-of select="."/>
+        <xsl:call-template name="br-replace">
+            <xsl:with-param name="word" select="."/>
+        </xsl:call-template>
+    </code>
+    <!-- the later is better but might be problematic for non-21" monitors... -->
+    <!--pre><xsl:value-of select="."/></pre-->
+</xsl:template>
+
+<xsl:template name="JS-escape">
+    <xsl:param name="string"/>
+    <xsl:param name="tmp1" select="str:replace(string($string),'\','\\')"/>
+    <xsl:param name="tmp2" select="str:replace(string($tmp1),&quot;'&quot;,&quot;\&apos;&quot;)"/>
+    <xsl:value-of select="$tmp2"/>
+</xsl:template>
+
+
+<!--
+    template that will convert a carriage return into a br tag
+    @param word the text from which to convert CR to BR tag
+-->
+<xsl:template name="br-replace">
+    <xsl:param name="word"/>
+    <xsl:param name="br"><br/></xsl:param>
+    <xsl:value-of select='str:replace(string($word),"&#xA;",$br)'/>
+</xsl:template>
+
+<xsl:template name="display-time">
+    <xsl:param name="value"/>
+    <xsl:value-of select="format-number($value,'0.000')"/>
+</xsl:template>
+
+<xsl:template name="display-percent">
+    <xsl:param name="value"/>
+    <xsl:value-of select="format-number($value,'0.00%')"/>
+</xsl:template>
+
+</xsl:stylesheet>
+
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/test/etc/xsl/str.replace.function.xsl
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/test/etc/xsl/str.replace.function.xsl	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/test/etc/xsl/str.replace.function.xsl	(revision 19)
@@ -0,0 +1,105 @@
+<?xml version="1.0"?>
+<xsl:stylesheet version="1.0"
+                xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+                xmlns:str="http://exslt.org/strings"
+                xmlns:func="http://exslt.org/functions"
+                xmlns:exsl="http://exslt.org/common"
+                extension-element-prefixes="str exsl func">
+
+<func:function name="str:replace">
+	<xsl:param name="string" select="''" />
+   <xsl:param name="search" select="/.." />
+   <xsl:param name="replace" select="/.." />
+   <xsl:choose>
+      <xsl:when test="not($string)">
+        <func:result select="/.." />
+      </xsl:when>
+      <xsl:when test="function-available('exsl:node-set')">
+         <!-- this converts the search and replace arguments to node sets
+              if they are one of the other XPath types -->
+         <xsl:variable name="search-nodes-rtf">
+           <xsl:copy-of select="$search" />
+         </xsl:variable>
+         <xsl:variable name="replace-nodes-rtf">
+           <xsl:copy-of select="$replace" />
+         </xsl:variable>
+         <xsl:variable name="replacements-rtf">
+            <xsl:for-each select="exsl:node-set($search-nodes-rtf)/node()">
+               <xsl:variable name="pos" select="position()" />
+               <replace search="{.}">
+                  <xsl:copy-of select="exsl:node-set($replace-nodes-rtf)/node()[$pos]" />
+               </replace>
+            </xsl:for-each>
+         </xsl:variable>
+         <xsl:variable name="sorted-replacements-rtf">
+            <xsl:for-each select="exsl:node-set($replacements-rtf)/replace">
+               <xsl:sort select="string-length(@search)" data-type="number" order="descending" />
+               <xsl:copy-of select="." />
+            </xsl:for-each>
+         </xsl:variable>
+         <xsl:variable name="result">
+           <xsl:choose>
+              <xsl:when test="not($search)">
+                <xsl:value-of select="$string" />
+              </xsl:when>
+             <xsl:otherwise>
+               <xsl:call-template name="str:_replace">
+                  <xsl:with-param name="string" select="$string" />
+                  <xsl:with-param name="replacements" select="exsl:node-set($sorted-replacements-rtf)/replace" />
+               </xsl:call-template>
+             </xsl:otherwise>
+           </xsl:choose>
+         </xsl:variable>
+         <func:result select="exsl:node-set($result)/node()" />
+      </xsl:when>
+      <xsl:otherwise>
+         <xsl:message terminate="yes">
+            ERROR: function implementation of str:replace() relies on exsl:node-set().
+         </xsl:message>
+      </xsl:otherwise>
+   </xsl:choose>
+</func:function>
+
+<xsl:template name="str:_replace">
+  <xsl:param name="string" select="''" />
+  <xsl:param name="replacements" select="/.." />
+  <xsl:choose>
+    <xsl:when test="not($string)" />
+    <xsl:when test="not($replacements)">
+      <xsl:value-of select="$string" />
+    </xsl:when>
+    <xsl:otherwise>
+      <xsl:variable name="replacement" select="$replacements[1]" />
+      <xsl:variable name="search" select="$replacement/@search" />
+      <xsl:choose>
+        <xsl:when test="not(string($search))">
+          <xsl:value-of select="substring($string, 1, 1)" />
+          <xsl:copy-of select="$replacement/node()" />
+          <xsl:call-template name="str:_replace">
+            <xsl:with-param name="string" select="substring($string, 2)" />
+            <xsl:with-param name="replacements" select="$replacements" />
+          </xsl:call-template>
+        </xsl:when>
+        <xsl:when test="contains($string, $search)">
+          <xsl:call-template name="str:_replace">
+            <xsl:with-param name="string" select="substring-before($string, $search)" />
+            <xsl:with-param name="replacements" select="$replacements[position() > 1]" />
+          </xsl:call-template>      
+          <xsl:copy-of select="$replacement/node()" />
+          <xsl:call-template name="str:_replace">
+            <xsl:with-param name="string" select="substring-after($string, $search)" />
+            <xsl:with-param name="replacements" select="$replacements" />
+          </xsl:call-template>
+        </xsl:when>
+        <xsl:otherwise>
+          <xsl:call-template name="str:_replace">
+            <xsl:with-param name="string" select="$string" />
+            <xsl:with-param name="replacements" select="$replacements[position() > 1]" />
+          </xsl:call-template>
+        </xsl:otherwise>
+      </xsl:choose>
+    </xsl:otherwise>
+  </xsl:choose>
+</xsl:template>
+
+</xsl:stylesheet>
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/test/test.xml
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/test/test.xml	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/test/test.xml	(revision 19)
@@ -0,0 +1,92 @@
+<?xml version="1.0"?>
+
+<project name="Propel Tests" default="phpunit" basedir=".">
+
+	<!--
+		=========================================================================================
+		Global Properties
+		~~~~~~~~~~~~~~~~~
+		
+		=========================================================================================					
+	-->
+	<property name="tests.dir" value="./tests" />
+	<property name="tests.phpunit.dir" value="." />
+	<property name="tests.reports.dir" value="${tests.phpunit.dir}/reports" />
+	<property name="tests.tools.dir" value="${tests.phpunit.dir}/tools" />
+
+	<property file="./test.properties" />
+
+	<path id="test-tools">
+		<pathelement dir="${tests.tools.dir}" />
+	</path>
+
+	<taskdef name="define" classname="phing.DefineTask" classpathRef="test-tools" />
+
+	<!--
+		=========================================================================================
+		PHPUnit Targets
+		~~~~~~~~~~~~~~~~
+		
+		=========================================================================================					
+	-->
+
+	<property name="test.class" value="${test}" />
+
+	<resolvepath propertyName="tests.dir.resolved" file="${tests.phpunit.dir}" />
+	<resolvepath propertyName="tests.classes.dir.resolved" file="${tests.phpunit.dir}/classes" />
+	<resolvepath propertyName="propel-generator.classes.dir.resolved" file="../classes" />
+	<resolvepath propertyName="propel-runtime.classes.dir.resolved" file="../../runtime/classes" />
+	<resolvepath propertyName="bookstore.classes.dir.resolved" file="../projects/bookstore/build/classes" />
+	<resolvepath propertyName="bookstore.conf.dir.resolved" file="../projects/bookstore/build/conf" />
+
+	<path id="incthis">
+		<pathelement dir="${tests.dir.resolved}" />
+		<pathelement dir="${tests.classes.dir.resolved}" />
+		<pathelement dir="${propel-generator.classes.dir.resolved}" />
+		<pathelement dir="${propel-runtime.classes.dir.resolved}" />
+		<pathelement dir="${bookstore.classes.dir.resolved}" />
+		<pathelement dir="${bookstore.conf.dir.resolved}" />
+	</path>
+
+	<target name="configure">
+		<echo>-------------------------------------------------</echo>
+		<echo> +++++ Running Propel unit tests</echo>
+		<echo>-------------------------------------------------</echo>
+		<define name="TESTS_BASE_DIR" value="${tests.dir.resolved}" />
+		<adhoc>
+			<![CDATA[
+			require_once 'propel/Propel.php';
+			Propel::init('bookstore-conf.php');	
+		]]>
+		</adhoc>
+
+		<fileset dir="${tests.classes.dir.resolved}" id="relevant-tests">
+			<include name="**/*${test.class}Test.php" />
+		</fileset>
+	</target>
+
+	<includepath classpathRef="incthis" />
+
+	<target name="reports" depends="configure">
+
+		<phpunit2 haltonerror="false" haltonfailure="false" printsummary="true">
+			<formatter type="xml" usefile="true" todir="${tests.reports.dir}" outfile="test-results.xml" />
+			<formatter type="plain" usefile="false" />
+			<batchtest>
+				<fileset refid="relevant-tests" />
+			</batchtest>
+		</phpunit2>
+		<phpunit2report format="noframes" todir="${tests.reports.dir}" infile="${tests.reports.dir}/test-results.xml" styledir="${tests.phpunit.dir}/etc/xsl" />
+	</target>
+
+	<!-- run the insert-sql target of the build.xml unless we are doing this for one specific test -->
+	<target name="initialize" unless="test">
+		<!--
+		<phing phingFile="build.xml" target="insert-sql"/>
+		-->
+		<property name="test.class" value="" override="true" />
+	</target>
+
+	<target name="phpunit" depends="initialize,reports" description="Executes the PHPUnit test suite" />
+
+</project>
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/test/tools/phing/DefineTask.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/test/tools/phing/DefineTask.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/test/tools/phing/DefineTask.php	(revision 19)
@@ -0,0 +1,50 @@
+<?php
+
+require_once 'phing/Task.php';
+
+/**
+ * Defines a constant using PHP define() method.
+ *
+ * This is handy if you want to initialize a constant to a value that is available only as build properties.
+ */
+class DefineTask extends Task {
+
+	/**
+	 * @var        string
+	 */
+	private $name;
+
+	/**
+	 * @var        string
+	 */
+	private $value;
+
+	/**
+	 * Sets the name for the constant.
+	 * @param      string $v
+	 */
+	public function setName($v) {
+		$this->name = $v;
+	}
+
+	/**
+	 * Sets the value for the constant.
+	 * @param      string $v
+	 */
+	public function setValue($v) {
+		$this->value = $v;
+	}
+
+	public function main() {
+		if (!isset($this->name) || !isset($this->value)) {
+			throw new BuildException("Both name and value params are required.", $this->getLocation());
+		}
+		$const = strtoupper($this->name);
+		if (defined($const)) {
+			 $this->log("The constant $const has already been defined!", Project::MSG_ERR);
+		} else {
+			define($const, $this->value);
+			$this->log("Defined $const with value " . var_export($this->value, true), Project::MSG_INFO);
+		}
+	}
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/test/tree-test.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/test/tree-test.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel-generator/test/tree-test.php	(revision 19)
@@ -0,0 +1,418 @@
+<?php
+
+if (!isset($argc)) echo "<pre>";
+
+error_reporting(E_ALL);
+
+$conf_path = realpath(dirname(__FILE__) . '/../projects/treetest/build/conf/treetest-conf.php');
+if (!file_exists($conf_path)) {
+	echo "Make sure that you specify properties in conf/treetest.properties and "
+	."build propel before running this script.";
+	exit;
+}
+
+// Add PHP_CLASSPATH, if set
+if (getenv("PHP_CLASSPATH")) {
+	set_include_path(getenv("PHP_CLASSPATH") . PATH_SEPARATOR . get_include_path());
+}
+
+ // Add build/classes/ and classes/ to path
+set_include_path(
+	realpath(dirname(__FILE__) . '/../projects/treetest/build/classes') . PATH_SEPARATOR .
+	dirname(__FILE__) . '/../../runtime/classes' . PATH_SEPARATOR .
+	get_include_path()
+);
+
+
+// Require classes.
+require_once 'propel/Propel.php';
+require_once 'treetest/TestNodePeer.php';
+
+function dumpTree($node, $querydb = false, $con = null)
+{
+	$opts = array('querydb' => $querydb,
+				  'con' => $con);
+
+	$node->setIteratorOptions('pre', $opts);
+
+	$indent = 0;
+	$lastLevel = $node->getNodeLevel();
+
+	foreach ($node as $n)
+	{
+		$nodeLevel = $n->getNodeLevel();
+		$indent += $nodeLevel - $lastLevel;
+		echo str_repeat('  ',  $indent);
+		echo $n->getNodePath() . " -> " . $n->getLabel();
+		echo "\n";
+		$lastLevel = $nodeLevel;
+	}
+}
+
+try {
+	// Initialize Propel
+	 Propel::init($conf_path);
+} catch (Exception $e) {
+	die("Error initializing propel: ". $e->__toString());
+}
+
+try {
+
+	$nodeKeySep = TestNodePeer::NPATH_SEP;
+
+	echo "\nCreating initial tree:\n";
+	echo "-------------------------------------\n";
+
+	$a = new Test();
+	$a->setLabel("a");
+	$a = TestNodePeer::createNewRootNode($a);
+	echo "Created 'a' as new root\n";
+
+	$b = new TestNode();
+	$b->setLabel('b');
+	$a->addChildNode($b);
+	echo "Added 'b' as first child of 'a'\n";
+
+	$c = new TestNode();
+	$c->setLabel('c');
+	$a->addChildNode($c);
+	echo "Added 'c' as second child of 'a'\n";
+
+	$f = new TestNode();
+	$f->setLabel('f');
+	$b->addChildNode($f);
+	echo "Added 'f' as first child of 'b'\n";
+
+	$d = new TestNode();
+	$d->setLabel('d');
+	$b->addChildNode($d, $f);
+	echo "Added 'd' as first child of 'b' before 'f' (insert before first child test - f is now second child)\n";
+
+	$e = new TestNode();
+	$e->setLabel('e');
+	$b->addChildNode($e, $f);
+	echo "Added 'e' as second child of 'b' before 'f' (insert before last child test - f is now third child)\n";
+
+	$g = new TestNode();
+	$g->setLabel('g');
+	$c->addChildNode($g);
+	echo "Added 'g' as first child of 'c'\n";
+
+	$h = new TestNode();
+	$h->setLabel('h');
+	$c->addChildNode($h);
+	echo "Added 'h' as second child of 'c'\n";
+
+	$i = new TestNode();
+	$i->setLabel('i');
+	$d->addChildNode($i);
+	echo "Added 'i' as first child of 'd'\n";
+
+	$j = new TestNode();
+	$j->setLabel('j');
+	$f->addChildNode($j);
+	echo "Added 'j' as first child of 'f'\n";
+
+	$k = new TestNode();
+	$k->setLabel('k');
+	$j->addChildNode($k);
+	echo "Added 'k' as first child of 'j'\n";
+
+	$l = new TestNode();
+	$l->setLabel('l');
+	$j->addChildNode($l);
+	echo "Added 'l' as second child of 'j'\n";
+
+	dumpTree($a);
+
+
+	echo "\n\nDeleting 'd' node sub-tree:\n";
+	echo "-------------------------------------\n";
+
+	$d->delete();
+
+	dumpTree($a);
+
+
+	echo "\n\nMove node tests:\n";
+	echo "-------------------------------------\n";
+
+	echo "Move 'j' sub-tree to 'b' before 'e' (move tree/insert before first child test):\n";
+	$b->addChildNode($j, $e);
+	dumpTree($a);
+
+	echo "\nMove 'j' sub-tree to 'c' (move tree after last child test):\n";
+	$c->addChildNode($j);
+	dumpTree($a);
+
+	echo "\nMove 'j' sub-tree to 'g' (move tree to first child test):\n";
+	$g->addChildNode($j);
+	dumpTree($a);
+
+
+	echo "\n\nCreating new (in-memory) sub-tree:\n";
+	echo "-------------------------------------\n";
+
+	$m = new TestNode();
+	$m->setLabel('m');
+	echo "Created 'm' as root of new sub-tree\n";
+
+	$n = new TestNode();
+	$n->setLabel('n');
+	$m->addChildNode($n);
+	echo "Added 'n' as first child of 'm'\n";
+
+	$o = new TestNode();
+	$o->setLabel('o');
+	$m->addChildNode($o);
+	echo "Added 'o' as second child of 'm'\n";
+
+	$r = new TestNode();
+	$r->setLabel('r');
+	$n->addChildNode($r);
+	echo "Added 'r' as first child of 'n'\n";
+
+	$p = new TestNode();
+	$p->setLabel('p');
+	$n->addChildNode($p, $r);
+	echo "Added 'p' as first child of 'n' before 'r' (insert before first child test - r is now second child)\n";
+
+	$q = new TestNode();
+	$q->setLabel('q');
+	$n->addChildNode($q, $r);
+	echo "Added 'q' as second child of 'n' before 'r' (insert before last child test - r is now third child)\n";
+
+	$s = new TestNode();
+	$s->setLabel('s');
+	$o->addChildNode($s);
+	echo "Added 's' as first child of 'o'\n";
+
+	$t = new TestNode();
+	$t->setLabel('t');
+	$o->addChildNode($t);
+	echo "Added 't' as second child of 'o'\n";
+
+	$u = new TestNode();
+	$u->setLabel('u');
+	$p->addChildNode($u);
+	echo "Added 'u' as first child of 'p'\n";
+
+	$v = new TestNode();
+	$v->setLabel('v');
+	$r->addChildNode($v);
+	echo "Added 'v' as first child of 'r'\n";
+
+	$w = new TestNode();
+	$w->setLabel('w');
+	$v->addChildNode($w);
+	echo "Added 'w' as first child of 'v'\n";
+
+	$x = new TestNode();
+	$x->setLabel('x');
+	$v->addChildNode($x);
+	echo "Added 'x' as second child of 'v'\n";
+
+	dumpTree($m);
+
+
+	echo "\n\nDeleting in-memory 'p' node sub-tree:\n";
+	echo "-------------------------------------\n";
+
+	$p->delete();
+
+	dumpTree($m);
+
+
+	echo "\n\nMove in-memory node tests:\n";
+	echo "-------------------------------------\n";
+
+	echo "Move 'v' sub-tree to 'n' before 'q' (move tree/insert before first child test):\n";
+	$n->addChildNode($v, $q);
+	dumpTree($m);
+
+	echo "\nMove 'v' sub-tree to 'o' (move tree after last child test):\n";
+	$o->addChildNode($v);
+	dumpTree($m);
+
+	echo "\nMove 'v' sub-tree to 's' (move tree to first child test):\n";
+	$s->addChildNode($v);
+	dumpTree($m);
+
+
+	echo "\n\nAdd in-memory 'm' sub-tree to 'a':\n";
+	echo "-------------------------------------\n";
+
+	$a->addChildNode($m);
+
+	dumpTree($a);
+
+
+	echo "\n\nInsert new root node 'z' and retrieve descendants on demand (via querydb param in iterator):\n";
+	echo "-------------------------------------\n";
+	$z = new Test();
+	$z->setLabel("z");
+	$z = TestNodePeer::insertNewRootNode($z);
+
+	dumpTree($z, true);
+
+} catch (Exception $e) {
+	die("Error creating initial tree: " . $e->__toString());
+}
+
+try {
+
+	echo "\n\nTest retrieveRootNode() (without descendants)\n";
+	echo "-------------------------------------\n";
+	$root = TestNodePeer::retrieveRootNode(false);
+	dumpTree($root);
+
+
+	echo "\n\nTest retrieveRootNode() (with descendants)\n";
+	echo "-------------------------------------\n";
+	$root = TestNodePeer::retrieveRootNode(true);
+	dumpTree($root);
+
+	$m_addr = array(1,1,3);
+
+	echo "\n\nTest retrieveNodeByNP() for 'm' (without descendants)\n";
+	echo "-------------------------------------\n";
+	$node = TestNodePeer::retrieveNodeByNP(implode($nodeKeySep, $m_addr), false, false);
+	dumpTree($node);
+
+
+	echo "\n\nTest retrieveNodeByNP() for 'm' (with descendants)\n";
+	echo "-------------------------------------\n";
+	$node = TestNodePeer::retrieveNodeByNP(implode($nodeKeySep, $m_addr), false, true);
+	dumpTree($node);
+
+
+	echo "\n\nTest getAncestors() for 'x' in one query:\n";
+	echo "-------------------------------------\n";
+
+	$criteria = new Criteria();
+	$criteria->add(TestPeer::LABEL, 'x', Criteria::EQUAL);
+
+	$nodes = TestNodePeer::retrieveNodes($criteria, true, false);
+	$ancestors = $nodes[0]->getAncestors(false);
+
+	foreach ($ancestors as $ancestor)
+		echo $ancestor->getNodePath() . " -> " . $ancestor->getLabel() . "\n";
+
+
+	echo "\n\nTest retrieveNodeByNP() for 'o' (with ancestors and descendants in one query):\n";
+	echo "-------------------------------------\n";
+
+	$o_addr = array(1,1,3,2);
+
+	$node = TestNodePeer::retrieveNodeByNP(implode($nodeKeySep, $o_addr), true, true);
+
+	echo "ancestors:\n";
+	foreach ($node->getAncestors(false) as $ancestor)
+		echo $ancestor->getNodePath() . " -> " . $ancestor->getLabel() . "\n";
+
+	echo "\ndescendants:\n";
+	dumpTree($node);
+
+
+	echo "\n\nTest retrieveNodes() between 'b' and 'g' (without descendants)\n";
+	echo "-------------------------------------\n";
+
+	$criteria = new Criteria();
+	$criteria->add(TestPeer::LABEL, 'b', Criteria::GREATER_EQUAL);
+	$criteria->addAnd(TestPeer::LABEL, 'g', Criteria::LESS_EQUAL);
+	$criteria->addAscendingOrderByColumn(TestPeer::LABEL);
+
+	$nodes = TestNodePeer::retrieveNodes($criteria, false, false);
+
+	foreach ($nodes as $node)
+		echo $node->getNodePath() . " -> " . $node->getLabel() . "\n";
+
+
+	echo "\n\nTest retrieveNodes() between 'b' and 'g' (with descendants)\n";
+	echo "-------------------------------------\n";
+
+	$criteria = new Criteria();
+	$criteria->add(TestPeer::LABEL, 'b', Criteria::GREATER_EQUAL);
+	$criteria->addAnd(TestPeer::LABEL, 'g', Criteria::LESS_EQUAL);
+	$criteria->addAscendingOrderByColumn(TestPeer::LABEL);
+
+	$nodes = TestNodePeer::retrieveNodes($criteria, false, true);
+
+	foreach ($nodes as $node)
+	{
+		dumpTree($node);
+		echo "\n";
+	}
+
+
+} catch (Exception $e) {
+	die("Error retrieving nodes: " . $e->__toString());
+}
+
+try {
+
+	echo "\nCreating new tree:\n";
+	echo "-------------------------------------\n";
+
+	$a = new Test();
+	$a->setLabel("a");
+	$a = TestNodePeer::createNewRootNode($a);
+	echo "Created 'a' as new root\n";
+
+	echo "\nAdding 10 child nodes:\n";
+	echo "-------------------------------------\n";
+
+	$b = new TestNode();
+	$b->setLabel('b');
+	$a->addChildNode($b);
+
+	$c = new TestNode();
+	$c->setLabel('c');
+	$a->addChildNode($c);
+
+	$d = new TestNode();
+	$d->setLabel('d');
+	$a->addChildNode($d);
+
+	$e = new TestNode();
+	$e->setLabel('e');
+	$a->addChildNode($e);
+
+	$f = new TestNode();
+	$f->setLabel('f');
+	$a->addChildNode($f);
+
+	$g = new TestNode();
+	$g->setLabel('g');
+	$a->addChildNode($g);
+
+	$h = new TestNode();
+	$h->setLabel('h');
+	$a->addChildNode($h);
+
+	$i = new TestNode();
+	$i->setLabel('i');
+	$a->addChildNode($i);
+
+	$j = new TestNode();
+	$j->setLabel('j');
+	$a->addChildNode($j);
+
+	$k = new TestNode();
+	$k->setLabel('k');
+	$a->addChildNode($k);
+
+	echo "\ndescendants:\n";
+	dumpTree($a);
+
+	echo "\nRetrieving last node:\n";
+	echo "-------------------------------------\n";
+
+	$last = $a->getLastChildNode(true);
+	echo "Last child node is '" . $last->getLabel() . "' (" . $last->getNodePath() . ")\n";
+
+} catch (Exception $e) {
+	die("Error creating tree with > 10 nodes: " . $e->__toString());
+}
+
+if (!isset($argc)) echo "</pre>";
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel/Propel.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel/Propel.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel/Propel.php	(revision 19)
@@ -0,0 +1,832 @@
+<?php
+/*
+ *  $Id: Propel.php 989 2008-03-11 14:29:30Z heltem $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://propel.phpdb.org>.
+ */
+
+require 'propel/PropelException.php';
+require 'propel/adapter/DBAdapter.php';
+require 'propel/util/PropelPDO.php';
+
+/**
+ * Propel's main resource pool and initialization & configuration class.
+ *
+ * This static class is used to handle Propel initialization and to maintain all of the
+ * open database connections and instantiated database maps.
+ *
+ * @author     Hans Lellelid <hans@xmpl.rg> (Propel)
+ * @author     Daniel Rall <dlr@finemaltcoding.com> (Torque)
+ * @author     MagnÃºs ÃÃ³r Torfason <magnus@handtolvur.is> (Torque)
+ * @author     Jason van Zyl <jvanzyl@apache.org> (Torque)
+ * @author     Rafal Krzewski <Rafal.Krzewski@e-point.pl> (Torque)
+ * @author     Martin Poeschl <mpoeschl@marmot.at> (Torque)
+ * @author     Henning P. Schmiedehausen <hps@intermeta.de> (Torque)
+ * @author     Kurt Schrader <kschrader@karmalab.org> (Torque)
+ * @version    $Revision: 989 $
+ * @package    propel
+ */
+class Propel
+{
+	/**
+	 * A constant for <code>default</code>.
+	 */
+	const DEFAULT_NAME = "default";
+
+	/**
+	 * A constant defining 'System is unusuable' logging level
+	 */
+	const LOG_EMERG = 0;
+
+	/**
+	 * A constant defining 'Immediate action required' logging level
+	 */
+	const LOG_ALERT = 1;
+
+	/**
+	 * A constant defining 'Critical conditions' logging level
+	 */
+	const LOG_CRIT = 2;
+
+	/**
+	 * A constant defining 'Error conditions' logging level
+	 */
+	const LOG_ERR = 3;
+
+	/**
+	 * A constant defining 'Warning conditions' logging level
+	 */
+	const LOG_WARNING = 4;
+
+	/**
+	 * A constant defining 'Normal but significant' logging level
+	 */
+	const LOG_NOTICE = 5;
+
+	/**
+	 * A constant defining 'Informational' logging level
+	 */
+	const LOG_INFO = 6;
+
+	/**
+	 * A constant defining 'Debug-level messages' logging level
+	 */
+	const LOG_DEBUG = 7;
+
+	/**
+	 * The Propel version.
+	 */
+	const VERSION = '1.3.0-dev';
+
+	/**
+	 * The class name for a PDO object.
+	 */
+	const CLASS_PDO = 'PDO';
+
+	/**
+	 * The class name for a PropelPDO object.
+	 */
+	const CLASS_PROPEL_PDO = 'PropelPDO';
+
+	/**
+	 * The class name for a DebugPDO object.
+	 */
+	const CLASS_DEBUG_PDO = 'DebugPDO';
+
+	/**
+	 * Constant used to request a READ connection (applies to replication).
+	 */
+	const CONNECTION_READ = 'read';
+
+	/**
+	 * Constant used to request a WRITE connection (applies to replication).
+	 */
+	const CONNECTION_WRITE = 'write';
+
+	/**
+	 * @var        string The db name that is specified as the default in the property file
+	 */
+	private static $defaultDBName;
+
+	/**
+	 * @var        array The global cache of database maps
+	 */
+	private static $dbMaps = array();
+
+	/**
+	 * @var        array The cache of DB adapter keys
+	 */
+	private static $adapterMap = array();
+
+	/**
+	 * @var        array Cache of established connections (to eliminate overhead).
+	 */
+	private static $connectionMap = array();
+
+	/**
+	 * @var        array Propel-specific configuration.
+	 */
+	private static $configuration;
+
+	/**
+	 * @var        bool flag to set to true once this class has been initialized
+	 */
+	private static $isInit = false;
+
+	/**
+	 * @var        Log optional logger
+	 */
+	private static $logger = null;
+
+	/**
+	 * @var        string The name of the database mapper class
+	 */
+	private static $databaseMapClass = 'DatabaseMap';
+
+	/**
+	 * @var        bool Whether the object instance pooling is enabled
+	 */
+	private static $instancePoolingEnabled = true;
+
+	/**
+	 * @var        bool For replication, whether to force the use of master connection.
+	 */
+	private static $forceMasterConnection = false;
+
+	/**
+	 * @var        array A map of class names and their file paths for autoloading
+	 */
+	private static $autoloadMap = array(
+		'PropelException' => 'propel/PropelException.php',
+
+		'DBAdapter' => 'propel/adapter/DBAdapter.php',
+		'DBMSSQL' => 'propel/adapter/DBMSSQL.php',
+		'DBMySQL' => 'propel/adapter/DBMySQL.php',
+		'DBMySQLi' => 'propel/adapter/DBMySQLi.php',
+		'DBNone' => 'propel/adapter/DBNone.php',
+		'DBOracle' => 'propel/adapter/DBOracle.php',
+		'DBPostgres' => 'propel/adapter/DBPostgres.php',
+		'DBSQLite' => 'propel/adapter/DBSQLite.php',
+		'DBSybase' => 'propel/adapter/DBSybase.php',
+
+		'BasicLogger' => 'propel/logger/BasicLogger.php',
+		'MojaviLogAdapter' => 'propel/logger/MojaviLogAdapter.php',
+
+		'ColumnMap' => 'propel/map/ColumnMap.php',
+		'DatabaseMap' => 'propel/map/DatabaseMap.php',
+		'MapBuilder' => 'propel/map/MapBuilder.php',
+		'TableMap' => 'propel/map/TableMap.php',
+		'ValidatorMap' => 'propel/map/ValidatorMap.php',
+
+		'BaseObject' => 'propel/om/BaseObject.php',
+		'NodeObject' => 'propel/om/NodeObject.php',
+		'Persistent' => 'propel/om/Persistent.php',
+		'PreOrderNodeIterator' => 'propel/om/PreOrderNodeIterator.php',
+		'NestedSetPreOrderNodeIterator' => 'propel/om/NestedSetPreOrderNodeIterator.php',
+		'NestedSetRecursiveIterator' => 'propel/om/NestedSetRecursiveIterator.php',
+
+		'BasePeer' => 'propel/util/BasePeer.php',
+		'NodePeer' => 'propel/util/NodePeer.php',
+		'Criteria' => 'propel/util/Criteria.php',
+		'PeerInfo' => 'propel/util/PeerInfo.php',
+		'PropelColumnTypes' => 'propel/util/PropelColumnTypes.php',
+		'PropelPDO' => 'propel/util/PropelPDO.php',
+		'PropelPager' => 'propel/util/PropelPager.php',
+		'PropelDateTime' => 'propel/util/PropelDateTime.php',
+		'DebugPDO' => 'propel/util/DebugPDO.php',
+		'DebugPDOStatement' => 'propel/util/DebugPDOStatement.php',
+
+		'BasicValidator' => 'propel/validator/BasicValidator.php',
+		'MatchValidator' => 'propel/validator/MatchValidator.php',
+		'MaxLengthValidator' => 'propel/validator/MaxLengthValidator.php',
+		'MaxValueValidator' => 'propel/validator/MaxValueValidator.php',
+		'MinLengthValidator' => 'propel/validator/MinLengthValidator.php',
+		'MinValueValidator' => 'propel/validator/MinValueValidator.php',
+		'NotMatchValidator' => 'propel/validator/NotMatchValidator.php',
+		'RequiredValidator' => 'propel/validator/RequiredValidator.php',
+		'UniqueValidator' => 'propel/validator/UniqueValidator.php',
+		'ValidValuesValidator' => 'propel/validator/ValidValuesValidator.php',
+		'ValidationFailed' => 'propel/validator/ValidationFailed.php',
+	);
+
+	/**
+	 * Initializes Propel
+	 *
+	 * @throws     PropelException Any exceptions caught during processing will be
+	 *                             rethrown wrapped into a PropelException.
+	 */
+	public static function initialize()
+	{
+		if (self::$configuration === null) {
+			throw new PropelException("Propel cannot be initialized without "
+			. "a valid configuration. Please check the log files "
+			. "for further details.");
+		}
+
+		self::configureLogging();
+
+		// Support having the configuration stored within a 'propel' sub-section or at the top-level
+		if (isset(self::$configuration['propel']) && is_array(self::$configuration['propel'])) {
+			self::$configuration = self::$configuration['propel'];
+		}
+
+		// reset the connection map (this should enable runtime changes of connection params)
+		self::$connectionMap = array();
+
+		foreach (self::$configuration['datasources'] as $key => $datasource) {
+			if ($key != 'default' && isset($datasource['classes'])) {
+				// merge the classes to the autoload map
+				self::$autoloadMap = array_merge($datasource['classes'], self::$autoloadMap);
+			}
+		}
+
+		self::$isInit = true;
+	}
+
+	/**
+	 * Configure Propel using an INI or PHP (array) config file.
+	 *
+	 * @param      string Path (absolute or relative to include_path) to config file.
+	 *
+	 * @throws     PropelException If configuration file cannot be opened.
+	 *                             (E_WARNING probably will also be raised by PHP)
+	 */
+	public static function configure($configFile)
+	{
+		self::$configuration = include($configFile);
+		if (self::$configuration === false) {
+			throw new PropelException("Unable to open configuration file: " . var_export($configFile, true));
+		}
+	}
+
+	/**
+	 * Configure the logging system, if config is specified in the runtime configuration.
+	 */
+	protected static function configureLogging()
+	{
+		if (self::$logger === null) {
+			if (isset(self::$configuration['log']) && is_array(self::$configuration['log']) && count(self::$configuration['log'])) {
+				include_once 'Log.php'; // PEAR Log class
+				$c = self::$configuration['log'];
+				$type = isset($c['type']) ? $c['type'] : 'file';
+				$name = isset($c['name']) ? $c['name'] : './propel.log';
+				$ident = isset($c['ident']) ? $c['ident'] : 'propel';
+				$conf = isset($c['conf']) ? $c['conf'] : array();
+				$level = isset($c['level']) ? $c['level'] : PEAR_LOG_DEBUG;
+				self::$logger = Log::singleton($type, $name, $ident, $conf, $level);
+			} // if isset()
+		}
+	}
+
+	/**
+	 * Initialization of Propel with an INI or PHP (array) configuration file.
+	 *
+	 * @param      string $c The Propel configuration file path.
+	 *
+	 * @throws     PropelException Any exceptions caught during processing will be
+	 *                             rethrown wrapped into a PropelException.
+	 */
+	public static function init($c)
+	{
+		self::configure($c);
+		self::initialize();
+	}
+
+	/**
+	 * Determine whether Propel has already been initialized.
+	 *
+	 * @return     bool True if Propel is already initialized.
+	 */
+	public static function isInit()
+	{
+		return self::$isInit;
+	}
+
+	/**
+	 * Sets the configuration for Propel and all dependencies.
+	 *
+	 * @param      array The Configuration
+	 */
+	public static function setConfiguration($c)
+	{
+		self::$configuration = $c;
+	}
+
+	/**
+	 * Get the configuration for this component.
+	 *
+	 * @return     array The Configuration
+	 */
+	public static function getConfiguration()
+	{
+		return self::$configuration;
+	}
+
+	/**
+	 * Override the configured logger.
+	 *
+	 * This is primarily for things like unit tests / debugging where
+	 * you want to change the logger without altering the configuration file.
+	 *
+	 * You can use any logger class that implements the propel.logger.BasicLogger
+	 * interface.  This interface is based on PEAR::Log, so you can also simply pass
+	 * a PEAR::Log object to this method.
+	 *
+	 * @param      object The new logger to use. ([PEAR] Log or BasicLogger)
+	 */
+	public static function setLogger($logger)
+	{
+		self::$logger = $logger;
+	}
+
+	/**
+	 * Returns true if a logger, for example PEAR::Log, has been configured,
+	 * otherwise false.
+	 *
+	 * @return     bool True if Propel uses logging
+	 */
+	public static function hasLogger()
+	{
+		return (self::$logger !== null);
+	}
+
+	/**
+	 * Get the configured logger.
+	 *
+	 * @return     object Configured log class ([PEAR] Log or BasicLogger).
+	 */
+	public static function logger()
+	{
+		return self::$logger;
+	}
+
+	/**
+	 * Logs a message
+	 * If a logger has been configured, the logger will be used, otherwrise the
+	 * logging message will be discarded without any further action
+	 *
+	 * @param      string The message that will be logged.
+	 * @param      string The logging level.
+	 *
+	 * @return     bool True if the message was logged successfully or no logger was used.
+	 */
+	public static function log($message, $level = self::LOG_DEBUG)
+	{
+		if (self::hasLogger()) {
+			$logger = self::logger();
+			switch ($level) {
+				case self::LOG_EMERG:
+					return $logger->log($message, $level);
+				case self::LOG_ALERT:
+					return $logger->alert($message);
+				case self::LOG_CRIT:
+					return $logger->crit($message);
+				case self::LOG_ERR:
+					return $logger->err($message);
+				case self::LOG_WARNING:
+					return $logger->warning($message);
+				case self::LOG_NOTICE:
+					return $logger->notice($message);
+				case self::LOG_INFO:
+					return $logger->info($message);
+				default:
+					return $logger->debug($message);
+			}
+		}
+		return true;
+	}
+
+	/**
+	 * Returns the database map information. Name relates to the name
+	 * of the connection pool to associate with the map.
+	 *
+	 * The database maps are "registered" by the generated map builder classes.
+	 *
+	 * @param      string The name of the database corresponding to the DatabaseMap to retrieve.
+	 *
+	 * @return     DatabaseMap The named <code>DatabaseMap</code>.
+	 *
+	 * @throws     PropelException - if database map is null or propel was not initialized properly.
+	 */
+	public static function getDatabaseMap($name = null)
+	{
+		if ($name === null) {
+			$name = self::getDefaultDB();
+			if ($name === null) {
+				throw new PropelException("DatabaseMap name was null!");
+			}
+		}
+
+		if (!isset(self::$dbMaps[$name])) {
+			$clazz = self::$databaseMapClass;
+			self::$dbMaps[$name] = new $clazz($name);
+		}
+
+		return self::$dbMaps[$name];
+	}
+
+	/**
+	 * Sets the database map object to use for specified datasource.
+	 *
+	 * @param      string $name The datasource name.
+	 * @param      DatabaseMap $map The database map object to use for specified datasource.
+	 */
+	public static function setDatabaseMap($name, DatabaseMap $map)
+	{
+		if ($name === null) {
+			$name = self::getDefaultDB();
+		}
+		self::$dbMaps[$name] = $map;
+	}
+
+	/**
+	 * For replication, set whether to always force the use of a master connection.
+	 *
+	 * @param      boolean $bit True or False
+	 */
+	public static function setForceMasterConnection($bit)
+	{
+		self::$forceMasterConnection = (bool) $bit;
+	}
+
+	/**
+	 * For replication, whether to always force the use of a master connection.
+	 *
+	 * @return     boolean
+	 */
+	public static function getForceMasterConnection()
+	{
+		return self::$forceMasterConnection;
+	}
+
+	/**
+	 * Sets a Connection for specified datasource name.
+	 *
+	 * @param      string $name The datasource name for the connection being set.
+	 * @param      PropelPDO $con The PDO connection.
+	 * @param      string $mode Whether this is a READ or WRITE connection (Propel::CONNECTION_READ, Propel::CONNECTION_WRITE)
+	 */
+	public static function setConnection($name, PropelPDO $con, $mode = Propel::CONNECTION_WRITE)
+	{
+		if ($name === null) {
+			$name = self::getDefaultDB();
+		}
+		if ($mode == Propel::CONNECTION_READ) {
+			self::$connectionMap[$name]['slave'] = $con;
+		} else {
+			self::$connectionMap[$name]['master'] = $con;
+		}
+	}
+
+	/**
+	 * Gets an already-opened PDO connection or opens a new one for passed-in db name.
+	 *
+	 * @param      string $name The datasource name that is used to look up the DSN from the runtime configuation file.
+	 * @param      string $mode The connection mode (this applies to replication systems).
+	 *
+	 * @return     PDO A database connection
+	 *
+	 * @throws     PropelException - if connection cannot be configured or initialized.
+	 */
+	public static function getConnection($name = null, $mode = Propel::CONNECTION_WRITE)
+	{
+		if ($name === null) {
+			$name = self::getDefaultDB();
+		}
+
+		// IF a WRITE-mode connection was requested
+		// or Propel is configured to always use the master connection
+		// or the slave for this connection has already been set to FALSE (indicating no slave)
+		// THEN return the master connection.
+		if ($mode != Propel::CONNECTION_READ || self::$forceMasterConnection || (isset(self::$connectionMap[$name]['slave']) && self::$connectionMap[$name]['slave'] === false)) {
+			if (!isset(self::$connectionMap[$name]['master'])) {
+				// load connection parameter for master connection
+				$conparams = isset(self::$configuration['datasources'][$name]['connection']) ? self::$configuration['datasources'][$name]['connection'] : null;
+				if (empty($conparams)) {
+					throw new PropelException('No connection information in your runtime configuration file for datasource ['.$name.']');
+				}
+				// initialize master connection
+				$con = Propel::initConnection($conparams, $name);
+				self::$connectionMap[$name]['master'] = $con;
+			}
+
+			return self::$connectionMap[$name]['master'];
+
+		} else {
+
+			if (!isset(self::$connectionMap[$name]['slave'])) {
+
+				// we've already ensured that the configuration exists, in previous if-statement
+				$slaveconfigs = isset(self::$configuration['datasources'][$name]['slaves']) ? self::$configuration['datasources'][$name]['slaves'] : null;
+
+				if (empty($slaveconfigs)) { // no slaves configured for this datasource
+					self::$connectionMap[$name]['slave'] = false;
+					return self::getConnection($name, Propel::CONNECTION_WRITE); // Recurse to get the WRITE connection
+				} else { // Initialize a new slave
+					if (isset($slaveconfigs['connection']['dsn'])) { // only one slave connection configured
+						$conparams = $slaveconfigs['connection'];
+					} else {
+						$randkey = array_rand($slaveconfigs['connection']);
+						$conparams = $slaveconfigs['connection'][$randkey];
+						if (empty($conparams)) {
+							throw new PropelException('No connection information in your runtime configuration file for SLAVE ['.$randkey.'] to datasource ['.$name.']');
+						}
+					}
+
+					// initialize master connection
+					$con = Propel::initConnection($conparams, $name);
+					self::$connectionMap[$name]['slave'] = $con;
+				}
+
+			} // if datasource slave not set
+
+			return self::$connectionMap[$name]['slave'];
+
+		} // if mode == CONNECTION_WRITE
+
+	} // getConnection()
+
+	/**
+	 * Opens a new PDO connection for passed-in db name.
+	 *
+	 * @param      array $conparams Connection paramters.
+	 * @param      string $name Datasource name.
+	 * @param      string $defaultClass The PDO subclass to instantiate if there is no explicit classname
+	 * 									specified in the connection params (default is Propel::CLASS_PROPEL_PDO)
+	 *
+	 * @return     PDO A database connection of the given class (PDO, PropelPDO, SlavePDO or user-defined)
+	 *
+	 * @throws     PropelException - if lower-level exception caught when trying to connect.
+	 */
+	public static function initConnection($conparams, $name, $defaultClass = Propel::CLASS_PROPEL_PDO)
+	{
+
+		$dsn = $conparams['dsn'];
+		if ($dsn === null) {
+			throw new PropelException('No dsn specified in your connection parameters for datasource ['.$name.']');
+		}
+
+		if (isset($conparams['classname']) && !empty($conparams['classname'])) {
+			$classname = $conparams['classname'];
+			if (!class_exists($classname)) {
+				throw new PropelException('Unable to load specified PDO subclass: ' . $classname);
+			}
+		} else {
+			$classname = $defaultClass;
+		}
+
+		$user = isset($conparams['user']) ? $conparams['user'] : null;
+		$password = isset($conparams['password']) ? $conparams['password'] : null;
+
+		// load any driver options from the config file
+		// driver options are those PDO settings that have to be passed during the connection construction
+		$driver_options = array();
+		if ( isset($conparams['options']) && is_array($conparams['options']) ) {
+			try {
+				self::processDriverOptions( $conparams['options'], $driver_options );
+			} catch (PropelException $e) {
+				throw new PropelException('Error processing driver options for datasource ['.$name.']', $e);
+			}
+		}
+
+		try {
+			$con = new $classname($dsn, $user, $password, $driver_options);
+			$con->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
+		} catch (PDOException $e) {
+			throw new PropelException("Unable to open PDO connection", $e);
+		}
+
+		// load any connection options from the config file
+		// connection attributes are those PDO flags that have to be set on the initialized connection
+		if (isset($conparams['attributes']) && is_array($conparams['attributes'])) {
+			$attributes = array();
+			try {
+				self::processDriverOptions( $conparams['attributes'], $attributes );
+			} catch (PropelException $e) {
+				throw new PropelException('Error processing connection attributes for datasource ['.$name.']', $e);
+			}
+			foreach ($attributes as $key => $value) {
+				$con->setAttribute($key, $value);
+			}
+		}
+
+		// initialize the connection using the settings provided in the config file. this could be a "SET NAMES <charset>" query for MySQL, for instance
+		$adapter = self::getDB($name);
+		$adapter->initConnection($con, isset($conparams['settings']) && is_array($conparams['settings']) ? $conparams['settings'] : array());
+
+		return $con;
+	}
+
+	/**
+	 * Internal function to handle driver options or conneciton attributes in PDO.
+	 *
+	 * Process the INI file flags to be passed to each connection.
+	 *
+	 * @param      array Where to find the list of constant flags and their new setting.
+	 * @param      array Put the data into here
+	 *
+	 * @throws     PropelException If invalid options were specified.
+	 */
+	private static function processDriverOptions($source, &$write_to)
+	{
+		foreach ($source as $option => $optiondata) {
+			if (is_string($option) && strpos($option, '::') !== false) {
+				$key = $option;
+			} elseif (is_string($option)) {
+				$key = 'PropelPDO::' . $option;
+			}
+			if (!defined($key)) {
+				throw new PropelException("Invalid PDO option/attribute name specified: ".$key);
+			}
+			$key = constant($key);
+
+			$value = $optiondata['value'];
+			if (is_string($value) && strpos($value, '::') !== false) {
+				if (!defined($value)) {
+					throw new PropelException("Invalid PDO option/attribute value specified: ".$value);
+				}
+				$value = constant($value);
+			}
+
+			$write_to[$key] = $value;
+		}
+	}
+
+	/**
+	 * Returns database adapter for a specific datasource.
+	 *
+	 * @param      string The datasource name.
+	 *
+	 * @return     DBAdapter The corresponding database adapter.
+	 *
+	 * @throws     PropelException If unable to find DBdapter for specified db.
+	 */
+	public static function getDB($name = null)
+	{
+		if ($name === null) {
+			$name = self::getDefaultDB();
+		}
+
+		if (!isset(self::$adapterMap[$name])) {
+			if (!isset(self::$configuration['datasources'][$name]['adapter'])) {
+				throw new PropelException("Unable to find adapter for datasource [" . $name . "].");
+			}
+			$db = DBAdapter::factory(self::$configuration['datasources'][$name]['adapter']);
+			// register the adapter for this name
+			self::$adapterMap[$name] = $db;
+		}
+
+		return self::$adapterMap[$name];
+	}
+
+	/**
+	 * Sets a database adapter for specified datasource.
+	 *
+	 * @param      string $name The datasource name.
+	 * @param      DBAdapter $adapter The DBAdapter implementation to use.
+	 */
+	public static function setDB($name, DBAdapter $adapter)
+	{
+		if ($name === null) {
+			$name = self::getDefaultDB();
+		}
+		self::$adapterMap[$name] = $adapter;
+	}
+
+	/**
+	 * Returns the name of the default database.
+	 *
+	 * @return     string Name of the default DB
+	 */
+	public static function getDefaultDB()
+	{
+		if (self::$defaultDBName === null) {
+			// Determine default database name.
+			self::$defaultDBName = isset(self::$configuration['datasources']['default']) ? self::$configuration['datasources']['default'] : self::DEFAULT_NAME;
+		}
+		return self::$defaultDBName;
+	}
+
+	/**
+	 * Closes any associated resource handles.
+	 *
+	 * This method frees any database connection handles that have been
+	 * opened by the getConnection() method.
+	 */
+	public static function close()
+	{
+		foreach (self::$connectionMap as $idx => $cons) {
+			// Propel::log("Closing connections for " . $idx, Propel::LOG_DEBUG);
+			unset(self::$connectionMap[$idx]);
+		}
+	}
+
+	/**
+	 * Autoload function for loading propel dependencies.
+	 *
+	 * @param      string The class name needing loading.
+	 *
+	 * @return     boolean TRUE if the class was loaded, false otherwise.
+	 */
+	public static function autoload($className)
+	{
+		if (isset(self::$autoloadMap[$className])) {
+			require(self::$autoloadMap[$className]);
+			return true;
+		}
+		return false;
+	}
+
+	/**
+	 * Include once a file specified in DOT notation and reutrn unqualified clasname.
+	 *
+	 * Typically, Propel uses autoload is used to load classes and expects that all classes
+	 * referenced within Propel are included in Propel's autoload map.  This method is only
+	 * called when a specific non-Propel classname was specified -- for example, the
+	 * classname of a validator in the schema.xml.  This method will attempt to include that
+	 * class via autoload and then relative to a location on the include_path.
+	 *
+	 * @param      string $class dot-path to clas (e.g. path.to.my.ClassName).
+	 * @return     string unqualified classname
+	 */
+	public static function importClass($path) {
+
+		// extract classname
+		if (($pos = strrpos($path, '.')) === false) {
+			$class = $path;
+		} else {
+			$class = substr($path, $pos + 1);
+		}
+
+		// check if class exists, using autoloader to attempt to load it.
+		if (class_exists($class, $useAutoload=true)) {
+			return $class;
+		}
+
+		// turn to filesystem path
+		$path = strtr($path, '.', DIRECTORY_SEPARATOR) . '.php';
+
+		// include class
+		$ret = include_once($path);
+		if ($ret === false) {
+			throw new PropelException("Unable to import class: " . $class . " from " . $path);
+		}
+
+		// return qualified name
+		return $class;
+	}
+
+	/**
+	 * Set your own class-name for Database-Mapping. Then
+	 * you can change the whole TableMap-Model, but keep its
+	 * functionality for Criteria.
+	 *
+	 * @param      string The name of the class.
+	 */
+	public static function setDatabaseMapClass($name)
+	{
+		self::$databaseMapClass = $name;
+	}
+
+	/**
+	 * Disable instance pooling.
+	 */
+	public static function disableInstancePooling()
+	{
+		self::$instancePoolingEnabled = false;
+	}
+
+	/**
+	 * Enable instance pooling (enabled by default).
+	 */
+	public static function enableInstancePooling()
+	{
+		self::$instancePoolingEnabled = true;
+	}
+
+	/**
+	 *  the instance pooling behaviour. True by default.
+	 *
+	 * @return     boolean Whether the pooling is enabled or not.
+	 */
+	public static function isInstancePoolingEnabled()
+	{
+		return self::$instancePoolingEnabled;
+	}
+}
+
+spl_autoload_register(array('Propel', 'autoload'));
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel/PropelException.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel/PropelException.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel/PropelException.php	(revision 19)
@@ -0,0 +1,61 @@
+<?php
+/*
+ *  $Id: PropelException.php 521 2007-01-05 13:29:36Z heltem $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://propel.phpdb.org>.
+ */
+
+/**
+ * The base class of all exceptions thrown by Propel.
+ * @author     Hans Lellelid <hans@xmpl.org>
+ * @version    $Revision: 521 $
+ * @package    propel
+ */
+class PropelException extends Exception {
+
+	/** The nested "cause" exception. */
+	protected $cause;
+
+	function __construct($p1, $p2 = null) {
+
+		$cause = null;
+
+		if ($p2 !== null) {
+			$msg = $p1;
+			$cause = $p2;
+		} else {
+			if ($p1 instanceof Exception) {
+				$msg = "";
+				$cause = $p1;
+			} else {
+				$msg = $p1;
+			}
+		}
+
+		parent::__construct($msg);
+
+		if ($cause !== null) {
+			$this->cause = $cause;
+			$this->message .= " [wrapped: " . $cause->getMessage() ."]";
+		}
+	}
+
+	function getCause() {
+		return $this->cause;
+	}
+
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel/adapter/DBAdapter.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel/adapter/DBAdapter.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel/adapter/DBAdapter.php	(revision 19)
@@ -0,0 +1,305 @@
+<?php
+/*
+ *  $Id: DBAdapter.php 1011 2008-03-20 11:36:27Z hans $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://propel.phpdb.org>.
+ */
+
+/**
+ * DBAdapter</code> defines the interface for a Propel database adapter.
+ *
+ * <p>Support for new databases is added by subclassing
+ * <code>DBAdapter</code> and implementing its abstract interface, and by
+ * registering the new database adapter and corresponding Creole
+ * driver in the private adapters map (array) in this class.</p>
+ *
+ * <p>The Propel database adapters exist to present a uniform
+ * interface to database access across all available databases.  Once
+ * the necessary adapters have been written and configured,
+ * transparent swapping of databases is theoretically supported with
+ * <i>zero code change</i> and minimal configuration file
+ * modifications.</p>
+ *
+ * @author     Hans Lellelid <hans@xmpl.org> (Propel)
+ * @author     Jon S. Stevens <jon@latchkey.com> (Torque)
+ * @author     Brett McLaughlin <bmclaugh@algx.net> (Torque)
+ * @author     Daniel Rall <dlr@finemaltcoding.com> (Torque)
+ * @version    $Revision: 1011 $
+ * @package    propel.adapter
+ */
+abstract class DBAdapter {
+
+	const ID_METHOD_NONE = 0;
+	const ID_METHOD_AUTOINCREMENT = 1;
+	const ID_METHOD_SEQUENCE = 2;
+
+	/**
+	 * Creole driver to Propel adapter map.
+	 * @var        array
+	 */
+	private static $adapters = array(
+		'mysql' => 'DBMySQL',
+		'mysqli' => 'DBMySQLi',
+		'mssql' => 'DBMSSQL',
+		'sybase' => 'DBSybase',
+		'oracle' => 'DBOracle',
+		'pgsql' => 'DBPostgres',
+		'sqlite' => 'DBSQLite',
+		'' => 'DBNone',
+	);
+
+	/**
+	 * Creates a new instance of the database adapter associated
+	 * with the specified Creole driver.
+	 *
+	 * @param      string $driver The name of the Propel/Creole driver to
+	 * create a new adapter instance for or a shorter form adapter key.
+	 * @return     DBAdapter An instance of a Propel database adapter.
+	 * @throws     PropelException if the adapter could not be instantiated.
+	 */
+	public static function factory($driver) {
+		$adapterClass = isset(self::$adapters[$driver]) ? self::$adapters[$driver] : null;
+		if ($adapterClass !== null) {
+			$a = new $adapterClass();
+			return $a;
+		} else {
+			throw new PropelException("Unsupported Propel driver: " . $driver . ": Check your configuration file");
+		}
+	}
+
+	/**
+	 * This method is called after a connection was created to run necessary
+	 * post-initialization queries or code.
+	 *
+	 * If a charset was specified, this will be set before any other queries
+	 * are executed.
+	 *
+	 * This base method runs queries specified using the "query" setting.
+	 *
+	 * @param      PDO   A PDO connection instance.
+	 * @param      array An array of settings.
+	 * @see        setCharset()
+	 */
+	public function initConnection(PDO $con, array $settings)
+	{
+		if (isset($settings['charset']['value'])) {
+			$this->setCharset($con, $settings['charset']['value']);
+		}
+		if (isset($settings['queries']) && is_array($settings['queries'])) {
+			foreach ($settings['queries'] as $queries) {
+				foreach ((array)$queries as $query) {
+					$con->exec($query);
+				}
+			}
+		}
+	}
+
+	/**
+	 * Sets the character encoding using SQL standard SET NAMES statement.
+	 *
+	 * This method is invoked from the default initConnection() method and must
+	 * be overridden for an RDMBS which does _not_ support this SQL standard.
+	 *
+	 * @param      PDO   A PDO connection instance.
+	 * @param      string The charset encoding.
+	 * @see        initConnection()
+	 */
+	public function setCharset(PDO $con, $charset)
+	{
+		$con->exec("SET NAMES '" . $charset . "'");
+	}
+
+	/**
+	 * This method is used to ignore case.
+	 *
+	 * @param      string The string to transform to upper case.
+	 * @return     string The upper case string.
+	 */
+	public abstract function toUpperCase($in);
+
+	/**
+	 * Returns the character used to indicate the beginning and end of
+	 * a piece of text used in a SQL statement (generally a single
+	 * quote).
+	 *
+	 * @return     string The text delimeter.
+	 */
+	public function getStringDelimiter()
+	{
+		return '\'';
+	}
+
+	/**
+	 * This method is used to ignore case.
+	 *
+	 * @param      string $in The string whose case to ignore.
+	 * @return     string The string in a case that can be ignored.
+	 */
+	public abstract function ignoreCase($in);
+
+	/**
+	 * This method is used to ignore case in an ORDER BY clause.
+	 * Usually it is the same as ignoreCase, but some databases
+	 * (Interbase for example) does not use the same SQL in ORDER BY
+	 * and other clauses.
+	 *
+	 * @param      string $in The string whose case to ignore.
+	 * @return     string The string in a case that can be ignored.
+	 */
+	public function ignoreCaseInOrderBy($in)
+	{
+		return $this->ignoreCase($in);
+	}
+
+	/**
+	 * Returns SQL which concatenates the second string to the first.
+	 *
+	 * @param      string String to concatenate.
+	 * @param      string String to append.
+	 * @return     string
+	 */
+	public abstract function concatString($s1, $s2);
+
+	/**
+	 * Returns SQL which extracts a substring.
+	 *
+	 * @param      string String to extract from.
+	 * @param      int Offset to start from.
+	 * @param      int Number of characters to extract.
+	 * @return     string
+	 */
+	public abstract function subString($s, $pos, $len);
+
+	/**
+	 * Returns SQL which calculates the length (in chars) of a string.
+	 *
+	 * @param      string String to calculate length of.
+	 * @return     string
+	 */
+	public abstract function strLength($s);
+
+
+	/**
+	 * Quotes database objec identifiers (table names, col names, sequences, etc.).
+	 * @param      string $text The identifier to quote.
+	 * @return     string The quoted identifier.
+	 */
+	public function quoteIdentifier($text)
+	{
+		return '"' . $text . '"';
+	}
+
+	/**
+	 * Quotes a database table which could have space seperating it from an alias, both should be identified seperately
+	 * @param      string $table The table name to quo
+	 * @return     string The quoted table name
+	 **/
+	public function quoteIdentifierTable($table) {
+		return implode(" ", array_map(array($this, "quoteIdentifier"), explode(" ", $table) ) );
+	}
+
+	/**
+	 * Returns the native ID method for this RDBMS.
+	 * @return     int one of DBAdapter:ID_METHOD_SEQUENCE, DBAdapter::ID_METHOD_AUTOINCREMENT.
+	 */
+	protected function getIdMethod()
+	{
+		return DBAdapter::ID_METHOD_AUTOINCREMENT;
+	}
+
+	/**
+	 * Whether this adapter uses an ID generation system that requires getting ID _before_ performing INSERT.
+	 * @return     boolean
+	 */
+	public function isGetIdBeforeInsert()
+	{
+		return ($this->getIdMethod() === DBAdapter::ID_METHOD_SEQUENCE);
+	}
+
+	/**
+	 * Whether this adapter uses an ID generation system that requires getting ID _before_ performing INSERT.
+	 * @return     boolean
+	 */
+	public function isGetIdAfterInsert()
+	{
+		return ($this->getIdMethod() === DBAdapter::ID_METHOD_AUTOINCREMENT);
+	}
+
+	/**
+	 * Gets the generated ID (either last ID for autoincrement or next sequence ID).
+	 * @return     mixed
+	 */
+	public function getId(PDO $con, $name = null)
+	{
+		return $con->lastInsertId($name);
+	}
+
+	/**
+	 * Returns timestamp formatter string for use in date() function.
+	 * @return     string
+	 */
+	public function getTimestampFormatter()
+	{
+		return "Y-m-d H:i:s";
+	}
+
+	/**
+	 * Returns date formatter string for use in date() function.
+	 * @return     string
+	 */
+	public function getDateFormatter()
+	{
+		return "Y-m-d";
+	}
+
+	/**
+	 * Returns time formatter string for use in date() function.
+	 * @return     string
+	 */
+	public function getTimeFormatter()
+	{
+		return "H:i:s";
+	}
+
+	/**
+	 * Should Column-Names get identifiers for inserts or updates.
+	 * By default false is returned -> backwards compability.
+	 *
+	 * it`s a workaround...!!!
+	 *
+	 * @todo       should be abstract
+	 * @return     boolean
+	 * @deprecated
+	 */
+	public function useQuoteIdentifier()
+	{
+		return false;
+	}
+
+	/**
+	 * Modifies the passed-in SQL to add LIMIT and/or OFFSET.
+	 */
+	public abstract function applyLimit(&$sql, $offset, $limit);
+	
+	/**
+	 * Gets the SQL string that this adapter uses for getting a random number.
+	 *
+	 * @param      mixed $seed (optional) seed value for databases that support this
+	 */
+	public abstract function random($seed = null);
+
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel/adapter/DBMSSQL.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel/adapter/DBMSSQL.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel/adapter/DBMSSQL.php	(revision 19)
@@ -0,0 +1,206 @@
+<?php
+
+/*
+*  $Id: DBMSSQL.php 989 2008-03-11 14:29:30Z heltem $
+*
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*
+* This software consists of voluntary contributions made by many individuals
+* and is licensed under the LGPL. For more information please see
+* <http://propel.phpdb.org>.
+*/
+
+/**
+ * This is used to connect to a MSSQL database.
+ *
+ * @author     Hans Lellelid <hans@xmpl.org> (Propel)
+ * @version    $Revision: 989 $
+ * @package    propel.adapter
+ */
+class DBMSSQL extends DBAdapter {
+
+	/**
+	 * This method is used to ignore case.
+	 *
+	 * @param      in The string to transform to upper case.
+	 * @return     The upper case string.
+	 */
+	public function toUpperCase($in)
+	{
+		return "UPPER(" . $in . ")";
+	}
+
+	/**
+	 * This method is used to ignore case.
+	 *
+	 * @param      in The string whose case to ignore.
+	 * @return     The string in a case that can be ignored.
+	 */
+	public function ignoreCase($in)
+	{
+		return "UPPER(" . $in . ")";
+	}
+
+	/**
+	 * Returns SQL which concatenates the second string to the first.
+	 *
+	 * @param      string String to concatenate.
+	 * @param      string String to append.
+	 * @return     string
+	 */
+	public function concatString($s1, $s2)
+	{
+		return "($s1 + $s2)";
+	}
+
+	/**
+	 * Returns SQL which extracts a substring.
+	 *
+	 * @param      string String to extract from.
+	 * @param      int Offset to start from.
+	 * @param      int Number of characters to extract.
+	 * @return     string
+	 */
+	public function subString($s, $pos, $len)
+	{
+		return "SUBSTRING($s, $pos, $len)";
+	}
+
+	/**
+	 * Returns SQL which calculates the length (in chars) of a string.
+	 *
+	 * @param      string String to calculate length of.
+	 * @return     string
+	 */
+	public function strLength($s)
+	{
+		return "LEN($s)";
+	}
+
+	/**
+	 * @see        DBAdapter::quoteIdentifier()
+	 */
+	public function quoteIdentifier($text)
+	{
+		return '[' . $text . ']';
+	}
+
+	/**
+	 * @see        DBAdapter::random()
+	 */
+	public function random($seed = null)
+	{
+		return 'rand('.((int) $seed).')';
+	}
+
+	/**
+	* Simulated Limit/Offset
+	* This rewrites the $sql query to apply the offset and limit.
+	* @see        DBAdapter::applyLimit()
+	* @author     Justin Carlson <justin.carlson@gmail.com>
+	*/
+	public function applyLimit(&$sql, $offset, $limit)
+	{
+		// make sure offset and limit are numeric
+		if (!is_numeric($offset) || !is_numeric($limit)){
+			throw new Exception("DBMSSQL ::applyLimit() expects a number for argument 2 and 3");
+		}
+
+		// obtain the original select statement
+		preg_match('/\A(.*)select(.*)from/si',$sql,$select_segment);
+		if (count($select_segment)>0)
+		{
+			$original_select = $select_segment[0];
+		} else {
+			throw new Exception("DBMSSQL ::applyLimit() could not locate the select statement at the start of the query. ");
+		}
+		$modified_select = substr_replace($original_select, null, stristr($original_select,'select') , 6 );
+
+		// obtain the original order by clause, or create one if there isn't one
+		preg_match('/order by(.*)\Z/si',$sql,$order_segment);
+		if (count($order_segment)>0)
+		{
+			$order_by = $order_segment[0];
+		} else {
+
+			// no order by clause, if there are columns we can attempt to sort by the columns in the select statement
+			$select_items = split(',',$modified_select);
+			if (count($select_items)>0)
+			{
+				$item_number = 0;
+				$order_by = null;
+				while ($order_by === null && $item_number<count($select_items))
+				{
+					if ($select_items[$item_number]!='*' && !strstr($select_items[$item_number],'('))
+					{
+						$order_by = 'order by ' . $select_items[0] . ' asc';
+					}
+					$item_number++;
+				}
+			}
+			if ($order_by === null)
+			{
+				throw new Exception("DBMSSQL ::applyLimit() could not locate the order by statement at the end of your query or any columns at the start of your query. ");
+			} else {
+				$sql.= ' ' . $order_by;
+			}
+
+		}
+
+		// remove the original select statement
+		$sql = str_replace($original_select , null, $sql);
+
+		/* modify the sort order by for paging */
+		$inverted_order = '';
+		$order_columns = split(',',str_ireplace('order by ','',$order_by));
+		$original_order_by = $order_by;
+		$order_by = '';
+		foreach ($order_columns as $column)
+		{
+			// strip "table." from order by columns
+			$column = array_reverse(split("\.",$column));
+			$column = $column[0];
+
+			// commas if we have multiple sort columns
+			if (strlen($inverted_order)>0){
+				$order_by.= ', ';
+				$inverted_order.=', ';
+			}
+
+			// put together order for paging wrapper
+			if (stristr($column,' desc'))
+			{
+				$order_by .= $column;
+				$inverted_order .= str_ireplace(' desc',' asc',$column);
+			} elseif (stristr($column,' asc')) {
+				$order_by .= $column;
+				$inverted_order .= str_ireplace(' asc',' desc',$column);
+			} else {
+				$order_by .= $column;
+				$inverted_order .= $column .' desc';
+			}
+		}
+		$order_by = 'order by ' . $order_by;
+		$inverted_order = 'order by ' . $inverted_order;
+
+		// build the query
+		$offset = ($limit+$offset);
+		$modified_sql = 'select * from (';
+		$modified_sql.= 'select top '.$limit.' * from (';
+		$modified_sql.= 'select top '.$offset.' '.$modified_select.$sql;
+		$modified_sql.= ') deriveda '.$inverted_order.') derivedb '.$order_by;
+		$sql = $modified_sql;
+
+	}
+
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel/adapter/DBMySQL.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel/adapter/DBMySQL.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel/adapter/DBMySQL.php	(revision 19)
@@ -0,0 +1,156 @@
+<?php
+
+/*
+ *  $Id: DBMySQL.php 989 2008-03-11 14:29:30Z heltem $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://propel.phpdb.org>.
+ */
+
+/**
+ * This is used in order to connect to a MySQL database.
+ *
+ * @author     Hans Lellelid <hans@xmpl.org> (Propel)
+ * @author     Jon S. Stevens <jon@clearink.com> (Torque)
+ * @author     Brett McLaughlin <bmclaugh@algx.net> (Torque)
+ * @author     Daniel Rall <dlr@finemaltcoding.com> (Torque)
+ * @version    $Revision: 989 $
+ * @package    propel.adapter
+ */
+class DBMySQL extends DBAdapter {
+
+	/**
+	 * This method is used to ignore case.
+	 *
+	 * @param      in The string to transform to upper case.
+	 * @return     The upper case string.
+	 */
+	public function toUpperCase($in)
+	{
+		return "UPPER(" . $in . ")";
+	}
+
+	/**
+	 * This method is used to ignore case.
+	 *
+	 * @param      in The string whose case to ignore.
+	 * @return     The string in a case that can be ignored.
+	 */
+	public function ignoreCase($in)
+	{
+		return "UPPER(" . $in . ")";
+	}
+
+	/**
+	 * Returns SQL which concatenates the second string to the first.
+	 *
+	 * @param      string String to concatenate.
+	 * @param      string String to append.
+	 * @return     string
+	 */
+	public function concatString($s1, $s2)
+	{
+		return "CONCAT($s1, $s2)";
+	}
+
+	/**
+	 * Returns SQL which extracts a substring.
+	 *
+	 * @param      string String to extract from.
+	 * @param      int Offset to start from.
+	 * @param      int Number of characters to extract.
+	 * @return     string
+	 */
+	public function subString($s, $pos, $len)
+	{
+		return "SUBSTRING($s, $pos, $len)";
+	}
+
+	/**
+	 * Returns SQL which calculates the length (in chars) of a string.
+	 *
+	 * @param      string String to calculate length of.
+	 * @return     string
+	 */
+	public function strLength($s)
+	{
+		return "CHAR_LENGTH($s)";
+	}
+
+
+	/**
+	 * Locks the specified table.
+	 *
+	 * @param      Connection $con The Creole connection to use.
+	 * @param      string $table The name of the table to lock.
+	 * @throws     PDOException No Statement could be created or
+	 * executed.
+	 */
+	public function lockTable(PDO $con, $table)
+	{
+		$con->exec("LOCK TABLE " . $table . " WRITE");
+	}
+
+	/**
+	 * Unlocks the specified table.
+	 *
+	 * @param      PDO $con The PDO connection to use.
+	 * @param      string $table The name of the table to unlock.
+	 * @throws     PDOException No Statement could be created or
+	 * executed.
+	 */
+	public function unlockTable(PDO $con, $table)
+	{
+		$statement = $con->exec("UNLOCK TABLES");
+	}
+
+	/**
+	 * @see        DBAdapter::quoteIdentifier()
+	 */
+	public function quoteIdentifier($text)
+	{
+		return '`' . $text . '`';
+	}
+
+	/**
+	 * @see        DBAdapter::useQuoteIdentifier()
+	 */
+	public function useQuoteIdentifier()
+	{
+		return true;
+	}
+
+	/**
+	 * @see        DBAdapter::applyLimit()
+	 */
+	public function applyLimit(&$sql, $offset, $limit)
+	{
+		if ( $limit > 0 ) {
+			$sql .= " LIMIT " . ($offset > 0 ? $offset . ", " : "") . $limit;
+		} else if ( $offset > 0 ) {
+			$sql .= " LIMIT " . $offset . ", 18446744073709551615";
+		}
+	}
+
+	/**
+	 * @see        DBAdapter::random()
+	 */
+	public function random($seed = null)
+	{
+		return 'rand('.((int) $seed).')';
+	}
+
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel/adapter/DBNone.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel/adapter/DBNone.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel/adapter/DBNone.php	(revision 19)
@@ -0,0 +1,99 @@
+<?php
+
+/*
+ *  $Id: DBNone.php 898 2008-01-02 00:18:44Z hans $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://propel.phpdb.org>.
+ */
+
+/**
+ * This adapter  is used when you do not have a database installed.
+ *
+ * @author     Hans Lellelid <hans@xmpl.org> (Propel)
+ * @author     Jon S. Stevens <jon@clearink.com> (Torque)
+ * @author     Brett McLaughlin <bmclaugh@algx.net> (Torque)
+ * @version    $Revision: 898 $
+ * @package    propel.adapter
+ */
+class DBNone extends DBAdapter {
+
+	/**
+	 * @see        DBAdapter::initConnection()
+	 */
+	public function initConnection(PDO $con, array $settings)
+	{
+	}
+
+	/**
+	 * This method is used to ignore case.
+	 *
+	 * @param      in The string to transform to upper case.
+	 * @return     The upper case string.
+	 */
+	public function toUpperCase($in)
+	{
+		return $in;
+	}
+
+	/**
+	 * This method is used to ignore case.
+	 *
+	 * @param      in The string whose case to ignore.
+	 * @return     The string in a case that can be ignored.
+	 */
+	public function ignoreCase($in)
+	{
+		return $in;
+	}
+
+	/**
+	 * Returns SQL which concatenates the second string to the first.
+	 *
+	 * @param      string String to concatenate.
+	 * @param      string String to append.
+	 * @return     string
+	 */
+	public function concatString($s1, $s2)
+	{
+		return ($s1 . $s2);
+	}
+
+	/**
+	 * Returns SQL which extracts a substring.
+	 *
+	 * @param      string String to extract from.
+	 * @param      int Offset to start from.
+	 * @param      int Number of characters to extract.
+	 * @return     string
+	 */
+	public function subString($s, $pos, $len)
+	{
+		return substr($s, $pos, $len);
+	}
+
+	/**
+	 * Returns SQL which calculates the length (in chars) of a string.
+	 *
+	 * @param      string String to calculate length of.
+	 * @return     string
+	 */
+	public function strLength($s)
+	{
+		return strlen($s);
+	}
+
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel/adapter/DBOracle.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel/adapter/DBOracle.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel/adapter/DBOracle.php	(revision 19)
@@ -0,0 +1,143 @@
+<?php
+
+/*
+ *  $Id: DBOracle.php 718 2007-10-26 01:31:34Z heltem $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://propel.phpdb.org>.
+ */
+
+/**
+ * Oracle adapter.
+ *
+ * @author     David Giffin <david@giffin.org> (Propel)
+ * @author     Hans Lellelid <hans@xmpl.org> (Propel)
+ * @author     Jon S. Stevens <jon@clearink.com> (Torque)
+ * @author     Brett McLaughlin <bmclaugh@algx.net> (Torque)
+ * @author     Bill Schneider <bschneider@vecna.com> (Torque)
+ * @author     Daniel Rall <dlr@finemaltcoding.com> (Torque)
+ * @version    $Revision: 718 $
+ * @package    propel.adapter
+ */
+class DBOracle extends DBAdapter {
+
+	/**
+	 * This method is used to ignore case.
+	 *
+	 * @param      string $in The string to transform to upper case.
+	 * @return     string The upper case string.
+	 */
+	public function toUpperCase($in)
+	{
+		return "UPPER(" . $in . ")";
+	}
+
+	/**
+	 * This method is used to ignore case.
+	 *
+	 * @param      string $in The string whose case to ignore.
+	 * @return     string The string in a case that can be ignored.
+	 */
+	public function ignoreCase($in)
+	{
+		return "UPPER(" . $in . ")";
+	}
+
+	/**
+	 * Returns SQL which concatenates the second string to the first.
+	 *
+	 * @param      string String to concatenate.
+	 * @param      string String to append.
+	 * @return     string
+	 */
+	public function concatString($s1, $s2)
+	{
+		return "CONCAT($s1, $s2)";
+	}
+
+	/**
+	 * Returns SQL which extracts a substring.
+	 *
+	 * @param      string String to extract from.
+	 * @param      int Offset to start from.
+	 * @param      int Number of characters to extract.
+	 * @return     string
+	 */
+	public function subString($s, $pos, $len)
+	{
+		return "SUBSTR($s, $pos, $len)";
+	}
+
+	/**
+	 * Returns SQL which calculates the length (in chars) of a string.
+	 *
+	 * @param      string String to calculate length of.
+	 * @return     string
+	 */
+	public function strLength($s)
+	{
+		return "LENGTH($s)";
+	}
+
+	/**
+	 * @see        DBAdapter::applyLimit()
+	 */
+	public function applyLimit(&$sql, $offset, $limit)
+	{
+		 $sql =
+			'SELECT B.* FROM (  '
+			.  'SELECT A.*, rownum AS PROPEL$ROWNUM FROM (  '
+			. $sql
+			. '  ) A '
+			.  ' ) B WHERE ';
+
+		if ( $offset > 0 ) {
+			$sql				.= ' B.PROPEL$ROWNUM > ' . $offset;
+
+			if ( $limit > 0 )
+			{
+				$sql			.= ' AND B.PROPEL$ROWNUM <= '
+									. ( $offset + $limit );
+			}
+		} else {
+			$sql				.= ' B.PROPEL$ROWNUM <= ' . $limit;
+		}
+	}
+
+	protected function getIdMethod()
+	{
+		return DBAdapter::ID_METHOD_SEQUENCE;
+	}
+
+	public function getId(PDO $con, $name = null)
+	{
+		if ($name === null) {
+			throw new PropelException("Unable to fetch next sequence ID without sequence name.");
+		}
+
+		$stmt = $con->query("SELECT " . $name . ".nextval FROM dual");
+		$row = $stmt->fetch(PDO::FETCH_NUM);
+
+		return $row[0];
+	}
+
+	public function random($seed=NULL)
+	{
+		return 'dbms_random.value';
+	}
+
+
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel/adapter/DBPostgres.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel/adapter/DBPostgres.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel/adapter/DBPostgres.php	(revision 19)
@@ -0,0 +1,152 @@
+<?php
+
+/*
+ *  $Id: DBPostgres.php 1011 2008-03-20 11:36:27Z hans $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://propel.phpdb.org>.
+ */
+
+/**
+ * This is used to connect to PostgresQL databases.
+ *
+ * <a href="http://www.pgsql.org">http://www.pgsql.org</a>
+ *
+ * @author     Hans Lellelid <hans@xmpl.org> (Propel)
+ * @author     Hakan Tandogan <hakan42@gmx.de> (Torque)
+ * @version    $Revision: 1011 $
+ * @package    propel.adapter
+ */
+class DBPostgres extends DBAdapter {
+
+	/**
+	 * This method is used to ignore case.
+	 *
+	 * @param      string $in The string to transform to upper case.
+	 * @return     string The upper case string.
+	 */
+	public function toUpperCase($in)
+	{
+		return "UPPER(" . $in . ")";
+	}
+
+	/**
+	 * This method is used to ignore case.
+	 *
+	 * @param      in The string whose case to ignore.
+	 * @return     The string in a case that can be ignored.
+	 */
+	public function ignoreCase($in)
+	{
+		return "UPPER(" . $in . ")";
+	}
+
+	/**
+	 * Returns SQL which concatenates the second string to the first.
+	 *
+	 * @param      string String to concatenate.
+	 * @param      string String to append.
+	 * @return     string
+	 */
+	public function concatString($s1, $s2)
+	{
+		return "($s1 || $s2)";
+	}
+
+	/**
+	 * Returns SQL which extracts a substring.
+	 *
+	 * @param      string String to extract from.
+	 * @param      int Offset to start from.
+	 * @param      int Number of characters to extract.
+	 * @return     string
+	 */
+	public function subString($s, $pos, $len)
+	{
+		return "substring($s from $pos" . ($len > -1 ? "for $len" : "") . ")";
+	}
+
+	/**
+	 * Returns SQL which calculates the length (in chars) of a string.
+	 *
+	 * @param      string String to calculate length of.
+	 * @return     string
+	 */
+	public function strLength($s)
+	{
+		return "char_length($s)";
+	}
+
+	/**
+	 * @see        DBAdapter::getIdMethod()
+	 */
+	protected function getIdMethod()
+	{
+		return DBAdapter::ID_METHOD_SEQUENCE;
+	}
+
+	/**
+	 * Gets ID for specified sequence name.
+	 */
+	public function getId(PDO $con, $name = null)
+	{
+		if ($name === null) {
+			throw new PropelException("Unable to fetch next sequence ID without sequence name.");
+		}
+		$stmt = $con->query("SELECT nextval(".$con->quote($name).")");
+		$row = $stmt->fetch(PDO::FETCH_NUM);
+		return $row[0];
+	}
+
+	/**
+	 * Returns timestamp formatter string for use in date() function.
+	 * @return     string
+	 */
+	public function getTimestampFormatter()
+	{
+		return "Y-m-d H:i:s O";
+	}
+
+	/**
+	 * Returns timestamp formatter string for use in date() function.
+	 * @return     string
+	 */
+	public function getTimeFormatter()
+	{
+		return "H:i:s O";
+	}
+
+	/**
+	 * @see        DBAdapter::applyLimit()
+	 */
+	public function applyLimit(&$sql, $offset, $limit)
+	{
+		if ( $limit > 0 ) {
+			$sql .= " LIMIT ".$limit;
+		}
+		if ( $offset > 0 ) {
+			$sql .= " OFFSET ".$offset;
+		}
+	}
+	
+	/**
+	 * @see        DBAdapter::random()
+	 */
+	public function random($seed=NULL)
+	{
+		return 'random()';
+	}
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel/adapter/DBSQLite.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel/adapter/DBSQLite.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel/adapter/DBSQLite.php	(revision 19)
@@ -0,0 +1,127 @@
+<?php
+
+/*
+ *  $Id: DBSQLite.php 989 2008-03-11 14:29:30Z heltem $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://propel.phpdb.org>.
+ */
+
+/**
+ * This is used in order to connect to a SQLite database.
+ *
+ * @author     Hans Lellelid <hans@xmpl.org>
+ * @version    $Revision: 989 $
+ * @package    propel.adapter
+ */
+class DBSQLite extends DBAdapter {
+
+	/**
+	 * For SQLite this method has no effect, since SQLite doesn't support specifying a character
+	 * set (or, another way to look at it, it doesn't require a single character set per DB).
+	 *
+	 * @param      PDO   A PDO connection instance.
+	 * @param      string The charset encoding.
+	 * @throws     PropelException If the specified charset doesn't match sqlite_libencoding()
+	 */
+	public function setCharset(PDO $con, $charset)
+	{
+	}
+
+	/**
+	 * This method is used to ignore case.
+	 *
+	 * @param      in The string to transform to upper case.
+	 * @return     The upper case string.
+	 */
+	public function toUpperCase($in)
+	{
+		return 'UPPER(' . $in . ')';
+	}
+
+	/**
+	 * This method is used to ignore case.
+	 *
+	 * @param      in The string whose case to ignore.
+	 * @return     The string in a case that can be ignored.
+	 */
+	public function ignoreCase($in)
+	{
+		return 'UPPER(' . $in . ')';
+	}
+
+	/**
+	 * Returns SQL which concatenates the second string to the first.
+	 *
+	 * @param      string String to concatenate.
+	 * @param      string String to append.
+	 * @return     string
+	 */
+	public function concatString($s1, $s2)
+	{
+		return "($s1 || $s2)";
+	}
+
+	/**
+	 * Returns SQL which extracts a substring.
+	 *
+	 * @param      string String to extract from.
+	 * @param      int Offset to start from.
+	 * @param      int Number of characters to extract.
+	 * @return     string
+	 */
+	public function subString($s, $pos, $len)
+	{
+		return "substr($s, $pos, $len)";
+	}
+
+	/**
+	 * Returns SQL which calculates the length (in chars) of a string.
+	 *
+	 * @param      string String to calculate length of.
+	 * @return     string
+	 */
+	public function strLength($s)
+	{
+		return "length($s)";
+	}
+
+	/**
+	 * @see        DBAdapter::quoteIdentifier()
+	 */
+	public function quoteIdentifier($text)
+	{
+		return '[' . $text . ']';
+	}
+
+	/**
+	 * @see        DBAdapter::applyLimit()
+	 */
+	public function applyLimit(&$sql, $offset, $limit)
+	{
+		if ( $limit > 0 ) {
+			$sql .= " LIMIT " . $limit . ($offset > 0 ? " OFFSET " . $offset : "");
+		} elseif ( $offset > 0 ) {
+			$sql .= " LIMIT -1 OFFSET " . $offset;
+		}
+	}
+
+	public function random($seed=NULL)
+	{
+		return 'random()';
+	}
+
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel/logger/BasicLogger.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel/logger/BasicLogger.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel/logger/BasicLogger.php	(revision 19)
@@ -0,0 +1,103 @@
+<?php
+
+/*
+ *  $Id: BasicLogger.php 521 2007-01-05 13:29:36Z heltem $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://propel.phpdb.org>.
+ */
+
+
+/**
+ * This is a minimalistic interface that any logging class must implement for Propel.
+ *
+ * The API for this interface is based on the PEAR::Log interface.  It provides a simple
+ * API that can be used by Propel independently of Log backend.
+ *
+ * PEAR::Log and perhaps the Log API was developed by Chuck Hagenbuch <chuck@horde.org>
+ * and Jon Parise <jon@php.net>.
+ *
+ * @author     Hans Lellelid <hans@xmpl.org>
+ * @version    $Revision: 521 $
+ * @package    propel.logger
+ */
+interface BasicLogger {
+
+	/**
+	 * A convenience function for logging an alert event.
+	 *
+	 * @param      mixed   $message    String or Exception object containing the message
+	 *                              to log.
+	 */
+	public function alert($message);
+
+	/**
+	 * A convenience function for logging a critical event.
+	 *
+	 * @param      mixed   $message    String or Exception object containing the message
+	 *                              to log.
+	 */
+	public function crit($message);
+
+	/**
+	 * A convenience function for logging an error event.
+	 *
+	 * @param      mixed   $message    String or Exception object containing the message
+	 *                              to log.
+	 */
+	public function err($message);
+
+	/**
+	 * A convenience function for logging a warning event.
+	 *
+	 * @param      mixed   $message    String or Exception object containing the message
+	 *                              to log.
+	 */
+	public function warning($message);
+	/**
+	 * A convenience function for logging an critical event.
+	 *
+	 * @param      mixed   $message    String or Exception object containing the message
+	 *                              to log.
+	 */
+	public function notice($message);
+	/**
+	 * A convenience function for logging an critical event.
+	 *
+	 * @param      mixed   $message    String or Exception object containing the message
+	 *                              to log.
+	 */
+	public function info($message);
+
+	/**
+	 * A convenience function for logging a debug event.
+	 *
+	 * @param      mixed   $message    String or Exception object containing the message
+	 *                              to log.
+	 */
+	public function debug($message);
+
+	/**
+	 * Primary method to handle logging.
+	 *
+	 * @param      mixed   $message    String or Exception object containing the message
+	 *                              to log.
+	 * @param      int     $severity   The numeric severity.  Defaults to null so that no
+	 *                              assumptions are made about the logging backend.
+	 */
+	public function log($message, $severity = null);
+
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel/logger/MojaviLogAdapter.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel/logger/MojaviLogAdapter.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel/logger/MojaviLogAdapter.php	(revision 19)
@@ -0,0 +1,170 @@
+<?php
+/*
+ *  $Id: MojaviLogAdapter.php 521 2007-01-05 13:29:36Z heltem $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://propel.phpdb.org>.
+ */
+
+/**
+ * Mojavi logging adapter for propel
+ *
+ * @author     Brandon Keepers <brandon@opensoul.org>
+ * @version    $Revision: 521 $
+ * @package    propel.logger
+ */
+class MojaviLogAdapter implements BasicLogger {
+
+	/**
+	 * Instance of mojavi logger
+	 */
+	private $logger = null;
+
+	/**
+	 * constructor for setting up Mojavi log adapter
+	 *
+	 * @param      ErrorLog   $logger   instance of Mojavi error log obtained by
+	 *                               calling LogManager::getLogger();
+	 */
+	public function __construct($logger = null)
+	{
+		$this->logger = $logger;
+	}
+
+	/**
+	 * A convenience function for logging an alert event.
+	 *
+	 * @param      mixed   $message    String or Exception object containing the message
+	 *                              to log.
+	 */
+	public function alert($message)
+	{
+		$this->log($message, 'alert');
+	}
+
+	/**
+	 * A convenience function for logging a critical event.
+	 *
+	 * @param      mixed   $message    String or Exception object containing the message
+	 *                              to log.
+	 */
+	public function crit($message)
+	{
+		$this->log($message, 'crit');
+	}
+
+	/**
+	 * A convenience function for logging an error event.
+	 *
+	 * @param      mixed   $message    String or Exception object containing the message
+	 *                              to log.
+	 */
+	public function err($message)
+	{
+		$this->log($message, 'err');
+	}
+
+	/**
+	 * A convenience function for logging a warning event.
+	 *
+	 * @param      mixed   $message    String or Exception object containing the message
+	 *                              to log.
+	 */
+	public function warning($message)
+	{
+		$this->log($message, 'warning');
+	}
+
+
+	/**
+	 * A convenience function for logging an critical event.
+	 *
+	 * @param      mixed   $message    String or Exception object containing the message
+	 *                              to log.
+	 */
+	public function notice($message)
+	{
+		$this->log($message, 'notice');
+	}
+	/**
+	 * A convenience function for logging an critical event.
+	 *
+	 * @param      mixed   $message    String or Exception object containing the message
+	 *                              to log.
+	 */
+	public function info($message)
+	{
+		$this->log($message, 'info');
+	}
+
+	/**
+	 * A convenience function for logging a debug event.
+	 *
+	 * @param      mixed   $message    String or Exception object containing the message
+	 *                              to log.
+	 */
+	public function debug($message)
+	{
+		$this->log($message, 'debug');
+	}
+
+	/**
+	 * Primary method to handle logging.
+	 *
+	 * @param      mixed   $message    String or Exception object containing the message
+	 *                              to log.
+	 * @param      int     $severity   The numeric severity.  Defaults to null so that no
+	 *                              assumptions are made about the logging backend.
+	 */
+	public function log($message, $severity = null)
+	{
+		if (is_null($this->logger))
+			$this->logger = LogManager::getLogger('propel');
+
+		switch($severity)
+		{
+			case 'crit':
+				$method = 'fatal';
+				break;
+			case 'err':
+				$method = 'error';
+				break;
+			case 'alert':
+			case 'warning':
+				$method = 'warning';
+				break;
+			case 'notice':
+			case 'info':
+				$method = 'info';
+				break;
+			case 'debug':
+			default:
+				$method = 'debug';
+		}
+
+		// get a backtrace to pass class, function, file, & line to Mojavi logger
+		$trace = debug_backtrace();
+
+		// call the appropriate Mojavi logger method
+		$this->logger->{$method} (
+			$message,
+			$trace[2]['class'],
+			$trace[2]['function'],
+			$trace[1]['file'],
+			$trace[1]['line']
+			);
+	}
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel/map/ColumnMap.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel/map/ColumnMap.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel/map/ColumnMap.php	(revision 19)
@@ -0,0 +1,417 @@
+<?php
+
+/*
+ *  $Id: ColumnMap.php 784 2007-11-08 10:15:50Z heltem $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://propel.phpdb.org>.
+ */
+
+/**
+ * ColumnMap is used to model a column of a table in a database.
+ *
+ * GENERAL NOTE
+ * ------------
+ * The propel.map classes are abstract building-block classes for modeling
+ * the database at runtime.  These classes are similar (a lite version) to the
+ * propel.engine.database.model classes, which are build-time modeling classes.
+ * These classes in themselves do not do any database metadata lookups, but instead
+ * are used by the MapBuilder classes that were generated for your datamodel. The
+ * MapBuilder that was created for your datamodel build a representation of your
+ * database by creating instances of the DatabaseMap, TableMap, ColumnMap, etc.
+ * classes. See propel/templates/om/php5/MapBuilder.tpl and the classes generated
+ * by that template for your datamodel to further understand how these are put
+ * together.
+ *
+ * @author     Hans Lellelid <hans@xmpl.org> (Propel)
+ * @author     John D. McNally <jmcnally@collab.net> (Torque)
+ * @version    $Revision: 784 $
+ * @package    propel.map
+ */
+class ColumnMap {
+
+	/** @var        string Propel type of the column. */
+	private $type;
+
+	/** Size of the column. */
+	private $size = 0;
+
+	/** Is it a primary key? */
+	private $pk = false;
+
+	/** Is null value allowed ?*/
+	private $notNull = false;
+
+	/** The default value for this column. */
+	private $defaultValue;
+
+	/** Name of the table that this column is related to. */
+	private $relatedTableName = "";
+
+	/** Name of the column that this column is related to. */
+	private $relatedColumnName = "";
+
+	/** The TableMap for this column. */
+	private $table;
+
+	/** The name of the column. */
+	private $columnName;
+
+	/** The php name of the column. */
+	private $phpName;
+
+	/** validators for this column */
+	private $validators = array();
+
+	/**
+	 * Constructor.
+	 *
+	 * @param      string $name The name of the column.
+	 * @param      TableMap containingTable TableMap of the table this column is in.
+	 */
+	public function __construct($name, TableMap $containingTable)
+	{
+		$this->columnName = $name;
+		$this->table = $containingTable;
+	}
+
+	/**
+	 * Gets column name (DEPRECATED).
+	 * @return     string
+	 * @deprecated Use getName() instead.
+	 */
+	public function getColumnName()
+	{
+		return $this->getName();
+	}
+
+	/**
+	 * Get the name of a column.
+	 *
+	 * @return     string A String with the column name.
+	 */
+	public function getName()
+	{
+		return $this->columnName;
+	}
+
+	/**
+	 * Get the name of a column.
+	 *
+	 * @return     string A String with the column name.
+	 */
+	public function getPhpName()
+	{
+		return $this->phpName;
+	}
+
+	/**
+	 * Set the php anme of this column.
+	 *
+	 * @param      string $phpName A string representing the PHP name.
+	 * @return     void
+	 */
+	public function setPhpName($phpName)
+	{
+		$this->phpName = $phpName;
+	}
+
+	/**
+	 * Get the table name + column name.
+	 *
+	 * @return     string A String with the full column name.
+	 */
+	public function getFullyQualifiedName()
+	{
+		return $this->table->getName() . "." . $this->columnName;
+	}
+
+	/**
+	 * Get the table map this column belongs to.
+	 * @return     TableMap
+	 */
+	public function getTable()
+	{
+		return $this->table;
+	}
+
+	/**
+	 * Get the name of the table this column is in.
+	 *
+	 * @return     string A String with the table name.
+	 */
+	public function getTableName()
+	{
+		return $this->table->getName();
+	}
+
+	/**
+	 * Get the Propel type of this column.
+	 *
+	 * @return     string A string representing the Propel type (e.g. PropelColumnTypes::DATE).
+	 */
+	public function getType()
+	{
+		return $this->type;
+	}
+
+	/**
+	 * Set the Propel type of this column.
+	 *
+	 * @param      string $type A string representing the Propel type (e.g. PropelColumnTypes::DATE).
+	 * @return     void
+	 */
+	public function setType($type)
+	{
+		$this->type = $type;
+	}
+
+	/**
+	 * Get the PHP type of this column.
+	 *
+	 * @return     int The PDO::PARMA_* value
+	 */
+	 /*
+	public function getPhpType()
+	{
+		return PropelColumnTypes::getPhpType($this->type);
+	}
+	*/
+	/**
+	 * Get the PDO type of this column.
+	 *
+	 * @return     int The PDO::PARMA_* value
+	 */
+	public function getPdoType()
+	{
+		return PropelColumnTypes::getPdoType($this->type);
+	}
+
+	/**
+	 * Whether this is a BLOB, LONGVARBINARY, or VARBINARY.
+	 * @return     boolean
+	 */
+	public function isLob()
+	{
+		return ($this->type == PropelColumnTypes::BLOB || $this->type == PropelColumnTypes::VARBINARY || $this->type == PropelColumnTypes::LONGVARBINARY);
+	}
+
+	/**
+	 * Whether this is a DATE/TIME/TIMESTAMP column that is post-epoch (1970).
+	 *
+	 * PHP cannot handle pre-epoch timestamps well -- hence the need to differentiate
+	 * between epoch and pre-epoch timestamps.
+	 *
+	 * @return     boolean
+	 * @deprecated Propel supports non-epoch dates
+	 */
+	public function isEpochTemporal()
+	{
+		return ($this->type == PropelColumnTypes::TIMESTAMP || $this->type == PropelColumnTypes::DATE || $this->type == PropelColumnTypes::TIME);
+	}
+
+	/**
+	 * Whether this column is numeric (int, decimal, bigint etc).
+	 * @return     boolean
+	 */
+	public function isNumeric()
+	{
+		return ($this->type == PropelColumnTypes::NUMERIC || $this->type == PropelColumnTypes::DECIMAL || $this->type == PropelColumnTypes::TINYINT || $this->type == PropelColumnTypes::SMALLINT || $this->type == PropelColumnTypes::INTEGER || $this->type == PropelColumnTypes::BIGINT || $this->type == PropelColumnTypes::REAL || $this->type == PropelColumnTypes::FLOAT || $this->type == PropelColumnTypes::DOUBLE);
+	}
+
+	/**
+	 * Whether this is a DATE/TIME/TIMESTAMP column.
+	 *
+	 * @return     boolean
+	 * @since      1.3
+	 */
+	public function isTemporal()
+	{
+		return ($this->type == PropelColumnTypes::TIMESTAMP || $this->type == PropelColumnTypes::DATE || $this->type == PropelColumnTypes::TIME || $this->type == PropelColumnTypes::BU_DATE  || $this->type == PropelColumnTypes::BU_TIMESTAMP);
+	}
+
+	/**
+	 * Whether this column is a text column (varchar, char, longvarchar).
+	 * @return     boolean
+	 */
+	public function isText()
+	{
+		return ($this->type == PropelColumnTypes::VARCHAR || $this->type == PropelColumnTypes::LONGVARCHAR || $this->type == PropelColumnTypes::CHAR);
+	}
+
+	/**
+	 * Set the size of this column.
+	 *
+	 * @param      int $size An int specifying the size.
+	 * @return     void
+	 */
+	public function setSize($size)
+	{
+		$this->size = $size;
+	}
+
+	/**
+	 * Set if this column is a primary key or not.
+	 *
+	 * @param      boolean $pk True if column is a primary key.
+	 * @return     void
+	 */
+	public function setPrimaryKey($pk)
+	{
+		$this->pk = $pk;
+	}
+
+	/**
+	 * Set if this column may be null.
+	 *
+	 * @param      boolean nn True if column may be null.
+	 * @return     void
+	 */
+	public function setNotNull($nn)
+	{
+		$this->notNull = $nn;
+	}
+
+	/**
+	 * Gets the default value for this column.
+	 * @return     mixed String or NULL
+	 */
+	public function getDefaultValue()
+	{
+		return $this->defaultValue;
+	}
+
+	/**
+	 * Set the foreign key for this column.
+	 *
+	 * @param      string tableName The name of the table that is foreign.
+	 * @param      string columnName The name of the column that is foreign.
+	 * @return     void
+	 */
+	public function setForeignKey($tableName, $columnName)
+	{
+		if ($tableName && $columnName) {
+			$this->relatedTableName = $tableName;
+			$this->relatedColumnName = $columnName;
+		} else {
+			$this->relatedTableName = "";
+			$this->relatedColumnName = "";
+		}
+	}
+
+	public function addValidator($validator)
+	{
+	  $this->validators[] = $validator;
+	}
+
+	public function hasValidators()
+	{
+	  return count($this->validators) > 0;
+	}
+
+	public function getValidators()
+	{
+	  return $this->validators;
+	}
+
+	/**
+	 * Get the size of this column.
+	 *
+	 * @return     int An int specifying the size.
+	 */
+	public function getSize()
+	{
+		return $this->size;
+	}
+
+	/**
+	 * Is this column a primary key?
+	 *
+	 * @return     boolean True if column is a primary key.
+	 */
+	public function isPrimaryKey()
+	{
+		return $this->pk;
+	}
+
+	/**
+	 * Is null value allowed ?
+	 *
+	 * @return     boolean True if column may not be null.
+	 */
+	public function isNotNull()
+	{
+		return ($this->notNull || $this->isPrimaryKey());
+	}
+
+	/**
+	 * Is this column a foreign key?
+	 *
+	 * @return     boolean True if column is a foreign key.
+	 */
+	public function isForeignKey()
+	{
+		if ($this->relatedTableName) {
+			return true;
+		} else {
+			return false;
+		}
+	}
+
+	/**
+	 * Get the table.column that this column is related to.
+	 *
+	 * @return     string A String with the full name for the related column.
+	 */
+	public function getRelatedName()
+	{
+		return $this->relatedTableName . "." . $this->relatedColumnName;
+	}
+
+	/**
+	 * Get the table name that this column is related to.
+	 *
+	 * @return     string A String with the name for the related table.
+	 */
+	public function getRelatedTableName()
+	{
+		return $this->relatedTableName;
+	}
+
+	/**
+	 * Get the column name that this column is related to.
+	 *
+	 * @return     string A String with the name for the related column.
+	 */
+	public function getRelatedColumnName()
+	{
+		return $this->relatedColumnName;
+	}
+
+	/**
+	 * Performs DB-specific ignore case, but only if the column type necessitates it.
+	 * @param      string $str The expression we want to apply the ignore case formatting to (e.g. the column name).
+	 * @param      DBAdapter $db
+	 */
+	public function ignoreCase($str, DBAdapter $db)
+	{
+		if ($this->isText()) {
+			return $db->ignoreCase($str);
+		} else {
+			return $str;
+		}
+	}
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel/map/DatabaseMap.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel/map/DatabaseMap.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel/map/DatabaseMap.php	(revision 19)
@@ -0,0 +1,152 @@
+<?php
+
+/*
+ *  $Id: DatabaseMap.php 521 2007-01-05 13:29:36Z heltem $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://propel.phpdb.org>.
+ */
+
+/**
+ * DatabaseMap is used to model a database.
+ *
+ * GENERAL NOTE
+ * ------------
+ * The propel.map classes are abstract building-block classes for modeling
+ * the database at runtime.  These classes are similar (a lite version) to the
+ * propel.engine.database.model classes, which are build-time modeling classes.
+ * These classes in themselves do not do any database metadata lookups, but instead
+ * are used by the MapBuilder classes that were generated for your datamodel. The
+ * MapBuilder that was created for your datamodel build a representation of your
+ * database by creating instances of the DatabaseMap, TableMap, ColumnMap, etc.
+ * classes.
+ *
+ * @author     Hans Lellelid <hans@xmpl.org> (Propel)
+ * @author     John D. McNally <jmcnally@collab.net> (Torque)
+ * @author     Daniel Rall <dlr@collab.net> (Torque)
+ * @version    $Revision: 521 $
+ * @package    propel.map
+ */
+class DatabaseMap {
+
+	/** Name of the database. */
+	private $name;
+
+	/** Name of the tables in the database. */
+	protected $tables = array();
+
+	/**
+	 * The table MapBuilder objects that will initialize tables (on demand).
+	 * @var        array Map of table builders (name => MapBuilder)
+	 */
+	private $tableBuilders = array();
+
+	/**
+	 * Constructor.
+	 *
+	 * @param      string $name Name of the database.
+	 */
+	public function __construct($name)
+	{
+		$this->name = $name;
+	}
+
+	/**
+	 * Does this database contain this specific table?
+	 *
+	 * @param      string $name The String representation of the table.
+	 * @return     boolean True if the database contains the table.
+	 */
+	public function containsTable($name)
+	{
+		if ( strpos($name, '.') > 0) {
+			$name = substr($name, 0, strpos($name, '.'));
+		}
+		// table builders are *always* loaded, whereas the tables aren't necessarily
+		return isset($this->tableBuilders[$name]);
+	}
+
+	/**
+	 * Get the name of this database.
+	 *
+	 * @return     string The name of the database.
+	 */
+	public function getName()
+	{
+		return $this->name;
+	}
+
+	/**
+	 * Get a TableMap for the table by name.
+	 *
+	 * @param      string $name Name of the table.
+	 * @return     TableMap A TableMap
+	 * @throws     PropelException if the table is undefined
+	 */
+	public function getTable($name)
+	{
+		if (!isset($this->tables[$name])) {
+			if (!isset($this->tableBuilders[$name])) {
+				throw new PropelException("Cannot fetch TableMap for undefined table: " . $name . ".  Make sure you have the static MapBuilder registration code after your peer stub class definition.");
+			}
+			$this->tableBuilders[$name]->doBuild();
+		}
+		return $this->tables[$name];
+	}
+
+	/**
+	 * Get a TableMap[] of all of the tables in the database.
+	 *
+	 * @return     array A TableMap[].
+	 */
+	public function getTables()
+	{
+		// if there's a mismatch in the tables and tableBuilders
+		if (count($this->tableBuilders) != count($this->tables)) {
+			$missingTables = array_diff(array_keys($this->tableBuilders), array_keys($this->tables));
+			foreach ($missingTables as $table) {
+				$this->tableBuilders[$table]->doBuild();
+			}
+		}
+		return $this->tables;
+	}
+
+	/**
+	 * Add a new table to the database by name.
+	 *
+	 * This method creates an empty TableMap that must then be populated. This
+	 * is called indirectly on-demand by the getTable() method, when there is
+	 * a table builder (MapBuilder) registered, but no TableMap loaded.
+	 *
+	 * @param      string $tableName The name of the table.
+	 * @return     TableMap The newly created TableMap.
+	 */
+	public function addTable($tableName)
+	{
+		$this->tables[$tableName] = new TableMap($tableName, $this);
+		return $this->tables[$tableName];
+	}
+
+	/**
+	 * Add a new table builder (MapBuilder) to the database by name.
+	 *
+	 * @param      string $tableName The name of the table.
+	 */
+	public function addTableBuilder($tableName, MapBuilder $builder)
+	{
+		$this->tableBuilders[$tableName] = $builder;
+	}
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel/map/MapBuilder.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel/map/MapBuilder.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel/map/MapBuilder.php	(revision 19)
@@ -0,0 +1,75 @@
+<?php
+
+/*
+ *  $Id: MapBuilder.php 521 2007-01-05 13:29:36Z heltem $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://propel.phpdb.org>.
+ */
+
+/**
+ * MapBuilders are classes that construct a model of a database at runtime.
+ *
+ * MapBuilders support a single database, so this class essentially serves as
+ * a wrapper around the DatabaseMap class.  This interface can be used for any
+ * class that needs to construct a runtime database model; by default in Propel
+ * the MapBuilder.tpl generates a class for your datamodel that implements this
+ * interface and re-creates your database using the DatabaseMap, TableMap,
+ * ColumnMap, and ValidatorMap classes.
+ *
+ * GENERAL NOTE
+ * ------------
+ * The propel.map classes are abstract building-block classes for modeling
+ * the database at runtime.  These classes are similar (a lite version) to the
+ * propel.engine.database.model classes, which are build-time modeling classes.
+ * These classes in themselves do not do any database metadata lookups, but instead
+ * are used by the MapBuilder classes that were generated for your datamodel. The
+ * MapBuilder that was created for your datamodel build a representation of your
+ * database by creating instances of the DatabaseMap, TableMap, ColumnMap, etc.
+ * classes. See propel/templates/om/php5/MapBuilder.tpl and the classes generated
+ * by that template for your datamodel to further understand how these are put
+ * together.
+ *
+ * @author     Hans Lellelid <hans@xmpl.org> (Propel)
+ * @author     John D. McNally <jmcnally@collab.net> (Torque)
+ * @author     Hans Lellelid <hans@xmpl.org> (Torque)
+ * @version    $Revision: 521 $
+ * @package    propel.map
+ */
+interface MapBuilder {
+
+	/**
+	 * Build up the database mapping.
+	 * @return     void
+	 * @throws     Exception Couldn't build mapping.
+	 */
+	function doBuild();
+
+	/**
+	 * Tells us if the database mapping is built so that we can avoid
+	 * re-building it repeatedly.
+	 *
+	 * @return     boolean Whether the DatabaseMap is built.
+	 */
+	function isBuilt();
+
+	/**
+	 * Gets the database mapping this map builder built.
+	 *
+	 * @return     DatabaseMap A DatabaseMap.
+	 */
+	function getDatabaseMap();
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel/map/TableMap.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel/map/TableMap.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel/map/TableMap.php	(revision 19)
@@ -0,0 +1,458 @@
+<?php
+/*
+ *  $Id: TableMap.php 1073 2008-08-07 00:32:16Z soenke $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://propel.phpdb.org>.
+ */
+
+/**
+ * TableMap is used to model a table in a database.
+ *
+ * GENERAL NOTE
+ * ------------
+ * The propel.map classes are abstract building-block classes for modeling
+ * the database at runtime.  These classes are similar (a lite version) to the
+ * propel.engine.database.model classes, which are build-time modeling classes.
+ * These classes in themselves do not do any database metadata lookups, but instead
+ * are used by the MapBuilder classes that were generated for your datamodel. The
+ * MapBuilder that was created for your datamodel build a representation of your
+ * database by creating instances of the DatabaseMap, TableMap, ColumnMap, etc.
+ * classes. See propel/templates/om/php5/MapBuilder.tpl and the classes generated
+ * by that template for your datamodel to further understand how these are put
+ * together.
+ *
+ * @author     Hans Lellelid <hans@xmpl.org> (Propel)
+ * @author     John D. McNally <jmcnally@collab.net> (Torque)
+ * @author     Daniel Rall <dlr@finemaltcoding.com> (Torque)
+ * @version    $Revision: 1073 $
+ * @package    propel.map
+ */
+class TableMap {
+
+	/** The columns in the table. */
+	private $columns;
+
+	/** The database this table belongs to. */
+	private $dbMap;
+
+	/** The name of the table. */
+	private $tableName;
+
+	/** The PHP name of the table. */
+	private $phpName;
+
+	/** The prefix on the table name. */
+	private $prefix;
+
+	/** The Classname for this table */
+	private $classname;
+
+	/** Whether to use an id generator for pkey. */
+	private $useIdGenerator;
+
+	/**
+	 * Object to store information that is needed if the
+	 * for generating primary keys.
+	 */
+	private $pkInfo;
+
+	/**
+	 * Construct a new TableMap.
+	 *
+	 * @param      string $tableName The name of the table.
+	 * @param      DatabaseMap $containingDB A DatabaseMap that this table belongs to.
+	 */
+	public function __construct($tableName, DatabaseMap $containingDB)
+	{
+		$this->tableName = $tableName;
+		$this->dbMap = $containingDB;
+		$this->columns = array();
+	}
+
+	/**
+	 * Normalizes the column name, removing table prefix and uppercasing.
+	 * @param      string $name
+	 * @return     string Normalized column name.
+	 */
+	private function normalizeColName($name) {
+		if (false !== ($pos = strpos($name, '.'))) {
+			$name = substr($name, $pos + 1);
+		}
+		$name = strtoupper($name);
+		return $name;
+	}
+
+	/**
+	 * Does this table contain the specified column?
+	 *
+	 * @param      string $name name of the column
+	 * @return     boolean True if the table contains the column.
+	 */
+	public function containsColumn($name)
+	{
+		if (!is_string($name)) {
+			$name = $name->getColumnName();
+		}
+		return isset($this->columns[$this->normalizeColName($name)]);
+	}
+
+	/**
+	 * Get the DatabaseMap containing this TableMap.
+	 *
+	 * @return     DatabaseMap A DatabaseMap.
+	 */
+	public function getDatabaseMap()
+	{
+		return $this->dbMap;
+	}
+
+	/**
+	 * Get the name of the Table.
+	 *
+	 * @return     string A String with the name of the table.
+	 */
+	public function getName()
+	{
+		return $this->tableName;
+	}
+
+	/**
+	 * Get the PHP name of the Table.
+	 *
+	 * @return     string A String with the name of the table.
+	 */
+	public function getPhpName()
+	{
+		return $this->phpName;
+	}
+
+	/**
+	 * Set the PHP name of the Table.
+	 *
+	 * @param      string $phpName The PHP Name for this table
+	 */
+	public function setPhpName($phpName)
+	{
+		$this->phpName = $phpName;
+	}
+
+	/**
+	 * Get table prefix name.
+	 *
+	 * @return     string A String with the prefix.
+	 */
+	public function getPrefix()
+	{
+		return $this->prefix;
+	}
+
+	/**
+	 * Set table prefix name.
+	 *
+	 * @param      string $prefix The prefix for the table name (ie: SCARAB for
+	 * SCARAB_PROJECT).
+	 * @return     void
+	 */
+	public function setPrefix($prefix)
+	{
+		$this->prefix = $prefix;
+	}
+
+	/**
+	 * Get the Classname of the Propel-Classes belonging to this table.
+	 * @return     string
+	 */
+	public function getClassname()
+	{
+		return $this->classname;
+	}
+
+	/**
+	 * Set the Classname of the Table. Could be useful for calling
+	 * Peer and Object methods dynamically.
+	 * @param      string $classname The Classname
+	 */
+	public function setClassname($classname)
+	{
+		$this->classname = $classname;
+	}
+
+	/**
+	 * Whether to use Id generator for primary key.
+	 * @return     boolean
+	 */
+	public function isUseIdGenerator() {
+		return $this->useIdGenerator;
+	}
+
+	/**
+	 * Get the information used to generate a primary key
+	 *
+	 * @return     An Object.
+	 */
+	public function getPrimaryKeyMethodInfo()
+	{
+		return $this->pkInfo;
+	}
+
+	/**
+	 * Returns array of ColumnMap objects that make up the primary key for this table.
+	 * @return     array ColumnMap[]
+	 */
+	public function getPrimaryKeyColumns()
+	{
+		$pk = array();
+		foreach ($this->columns as $col) {
+			if ($col->isPrimaryKey()) {
+				$pk[] = $col;
+			}
+		}
+		return $pk;
+	}
+
+	/**
+	 * Get a ColumnMap[] of the columns in this table.
+	 *
+	 * @return     array A ColumnMap[].
+	 */
+	public function getColumns()
+	{
+		return $this->columns;
+	}
+
+	/**
+	 * Get a ColumnMap for the named table.
+	 *
+	 * @param      string $name A String with the name of the table.
+	 * @return     ColumnMap A ColumnMap.
+	 * @throws     PropelException if the column is undefined
+	 */
+	public function getColumn($name)
+	{
+		$name = $this->normalizeColName($name);
+		if (!isset($this->columns[$name])) {
+			throw new PropelException("Cannot fetch ColumnMap for undefined column: " . $name);
+		}
+		return $this->columns[$name];
+	}
+
+	/**
+	 * Add a primary key column to this Table.
+	 *
+	 * @param      string $columnName A String with the column name.
+	 * @param      string $type A string specifying the Propel type.
+	 * @param      boolean $isNotNull Whether column does not allow NULL values.
+	 * @param      $size An int specifying the size.
+	 * @return     ColumnMap Newly added PrimaryKey column.
+	 */
+	public function addPrimaryKey($columnName, $phpName, $type, $isNotNull = false, $size = null)
+	{
+		return $this->addColumn($columnName, $phpName, $type, $isNotNull, $size, true, null, null);
+	}
+
+	/**
+	 * Add a foreign key column to the table.
+	 *
+	 * @param      string $columnName A String with the column name.
+	 * @param      string $type A string specifying the Propel type.
+	 * @param      string $fkTable A String with the foreign key table name.
+	 * @param      string $fkColumn A String with the foreign key column name.
+	 * @param      boolean $isNotNull Whether column does not allow NULL values.
+	 * @param      int $size An int specifying the size.
+	 * @param      string $defaultValue The default value for this column.
+	 * @return     ColumnMap Newly added ForeignKey column.
+	 */
+	public function addForeignKey($columnName, $phpName, $type, $fkTable, $fkColumn, $isNotNull = false, $size = 0)
+	{
+		return $this->addColumn($columnName, $phpName, $type, $isNotNull, $size, false, $fkTable, $fkColumn);
+	}
+
+	/**
+	 * Add a foreign primary key column to the table.
+	 *
+	 * @param      string $columnName A String with the column name.
+	 * @param      string $type A string specifying the Propel type.
+	 * @param      string $fkTable A String with the foreign key table name.
+	 * @param      string $fkColumn A String with the foreign key column name.
+	 * @param      boolean $isNotNull Whether column does not allow NULL values.
+	 * @param      int $size An int specifying the size.
+	 * @param      string $defaultValue The default value for this column.
+	 * @return     ColumnMap Newly created foreign pkey column.
+	 */
+	public function addForeignPrimaryKey($columnName, $phpName, $type, $fkTable, $fkColumn, $isNotNull = false, $size = 0)
+	{
+		return $this->addColumn($columnName, $phpName, $type, $isNotNull, $size, true, $fkTable, $fkColumn);
+	}
+
+	/**
+	 * Add a pre-created column to this table.  It will replace any
+	 * existing column.
+	 *
+	 * @param      ColumnMap $cmap A ColumnMap.
+	 * @return     ColumnMap The added column map.
+	 */
+	public function addConfiguredColumn($cmap)
+	{
+		$this->columns[ $cmap->getColumnName() ] = $cmap;
+		return $cmap;
+	}
+
+	/**
+	 * Add a column to the table.
+	 *
+	 * @param      string name A String with the column name.
+	 * @param      string $type A string specifying the Propel type.
+	 * @param      boolean $isNotNull Whether column does not allow NULL values.
+	 * @param      int $size An int specifying the size.
+	 * @param      boolean $pk True if column is a primary key.
+	 * @param      string $fkTable A String with the foreign key table name.
+	 * @param      $fkColumn A String with the foreign key column name.
+	 * @param      string $defaultValue The default value for this column.
+	 * @return     ColumnMap The newly created column.
+	 */
+	public function addColumn($name, $phpName, $type, $isNotNull = false, $size = null, $pk = null, $fkTable = null, $fkColumn = null)
+	{
+
+		$col = new ColumnMap($name, $this);
+
+		if ($fkTable && $fkColumn) {
+			if (strpos($fkColumn, '.') > 0 && strpos($fkColumn, $fkTable) !== false) {
+				$fkColumn = substr($fkColumn, strlen($fkTable) + 1);
+			}
+			$col->setForeignKey($fkTable, $fkColumn);
+		}
+
+		$col->setType($type);
+		$col->setPrimaryKey($pk);
+		$col->setSize($size);
+		$col->setPhpName($phpName);
+		$col->setNotNull($isNotNull);
+
+		$this->columns[$name] = $col;
+
+		return $this->columns[$name];
+	}
+
+	/**
+	* Add a validator to a table's column
+	*
+	* @param      string $columnName The name of the validator's column
+	* @param      string $name The rule name of this validator
+	* @param      string $classname The dot-path name of class to use (e.g. myapp.propel.MyValidator)
+	* @param      string $value
+	* @param      string $message The error message which is returned on invalid values
+	* @return     void
+	*/
+	public function addValidator($columnName, $name, $classname, $value, $message)
+	{
+		if (false !== ($pos = strpos($columnName, '.'))) {
+			$columnName = substr($columnName, $pos + 1);
+		}
+
+		$col = $this->getColumn($columnName);
+		if ($col !== null) {
+			$validator = new ValidatorMap($col);
+			$validator->setName($name);
+			$validator->setClass($classname);
+			$validator->setValue($value);
+			$validator->setMessage($message);
+			$col->addValidator($validator);
+		}
+	}
+
+	/**
+	 * Set whether or not to use Id generator for primary key.
+	 * @param      boolean $bit
+	 */
+	public function setUseIdGenerator($bit) {
+		$this->useIdGenerator = $bit;
+	}
+
+	/**
+	 * Sets the pk information needed to generate a key
+	 *
+	 * @param      $pkInfo information needed to generate a key
+	 */
+	public function setPrimaryKeyMethodInfo($pkInfo)
+	{
+		$this->pkInfo = $pkInfo;
+	}
+
+	//---Utility methods for doing intelligent lookup of table names
+
+	/**
+	 * Tell me if i have PREFIX in my string.
+	 *
+	 * @param      data A String.
+	 * @return     boolean True if prefix is contained in data.
+	 */
+	private function hasPrefix($data)
+	{
+		return (substr($data, $this->getPrefix()) !== false);
+	}
+
+	/**
+	 * Removes the PREFIX.
+	 *
+	 * @param      string $data A String.
+	 * @return     string A String with data, but with prefix removed.
+	 */
+	private function removePrefix($data)
+	{
+		return substr($data, strlen($this->getPrefix()));
+	}
+
+
+
+	/**
+	 * Removes the PREFIX, removes the underscores and makes
+	 * first letter caps.
+	 *
+	 * SCARAB_FOO_BAR becomes FooBar.
+	 *
+	 * @param      data A String.
+	 * @return     string A String with data processed.
+	 */
+	public final function removeUnderScores($data)
+	{
+		$tmp = null;
+		$out = "";
+		if ($this->hasPrefix($data)) {
+			$tmp = $this->removePrefix($data);
+		} else {
+			$tmp = $data;
+		}
+
+		$tok = strtok($tmp, "_");
+		while ($tok) {
+			$out .= ucfirst($tok);
+			$tok = strtok("_");
+		}
+		return $out;
+	}
+
+	/**
+	 * Makes the first letter caps and the rest lowercase.
+	 *
+	 * @param      string $data A String.
+	 * @return     string A String with data processed.
+	 */
+	private function firstLetterCaps($data)
+	{
+		return(ucfirst(strtolower($data)));
+	}
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel/map/ValidatorMap.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel/map/ValidatorMap.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel/map/ValidatorMap.php	(revision 19)
@@ -0,0 +1,109 @@
+<?php
+/*
+ *  $Id: ValidatorMap.php 521 2007-01-05 13:29:36Z heltem $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://propel.phpdb.org>.
+ */
+
+/**
+ * ValidatorMap is used to model a column validator.
+ *
+ * GENERAL NOTE
+ * ------------
+ * The propel.map classes are abstract building-block classes for modeling
+ * the database at runtime.  These classes are similar (a lite version) to the
+ * propel.engine.database.model classes, which are build-time modeling classes.
+ * These classes in themselves do not do any database metadata lookups, but instead
+ * are used by the MapBuilder classes that were generated for your datamodel. The
+ * MapBuilder that was created for your datamodel build a representation of your
+ * database by creating instances of the DatabaseMap, TableMap, ColumnMap, etc.
+ * classes. See propel/templates/om/php5/MapBuilder.tpl and the classes generated
+ * by that template for your datamodel to further understand how these are put
+ * together.
+ *
+ * @author     Michael Aichler <aichler@mediacluster.de>
+ * @version    $Revision: 521 $
+ * @package    propel.map
+ */
+class ValidatorMap
+{
+	/** rule name of this validator */
+	private $name;
+	/** the dot-path to class to use for validator */
+	private $classname;
+	/** value to check against */
+	private $value;
+	/** execption message thrown on invalid input */
+	private $message;
+	/** related column */
+	private $column;
+
+	public function __construct($containingColumn)
+	{
+		$this->column = $containingColumn;
+	}
+
+	public function getColumn()
+	{
+		return $this->column;
+	}
+
+	public function getColumnName()
+	{
+		return $this->column->getColumnName();
+	}
+
+	public function setName($name)
+	{
+		$this->name = $name;
+	}
+
+	public function setClass($classname)
+	{
+		$this->classname = $classname;
+	}
+
+	public function setValue($value)
+	{
+		$this->value = $value;
+	}
+
+	public function setMessage($message)
+	{
+		$this->message = $message;
+	}
+
+	public function getName()
+	{
+		return $this->name;
+	}
+
+	public function getClass()
+	{
+		return $this->classname;
+	}
+
+	public function getValue()
+	{
+		return $this->value;
+	}
+
+	public function getMessage()
+	{
+		return $this->message;
+	}
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel/om/BaseObject.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel/om/BaseObject.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel/om/BaseObject.php	(revision 19)
@@ -0,0 +1,202 @@
+<?php
+
+/*
+ *  $Id: BaseObject.php 1066 2008-07-17 07:33:35Z ron $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://propel.phpdb.org>.
+ */
+
+/**
+ * This class contains attributes and methods that are used by all
+ * business objects within the system.
+ *
+ * @author     Hans Lellelid <hans@xmpl.org> (Propel)
+ * @author     Frank Y. Kim <frank.kim@clearink.com> (Torque)
+ * @author     John D. McNally <jmcnally@collab.net> (Torque)
+ * @version    $Revision: 1066 $
+ * @package    propel.om
+ */
+abstract class BaseObject {
+
+	/**
+	 * attribute to determine if this object has previously been saved.
+	 * @var        boolean
+	 */
+	private $_new = true;
+
+	/**
+	 * attribute to determine whether this object has been deleted.
+	 * @var        boolean
+	 */
+	private $_deleted = false;
+
+	/**
+	 * The columns that have been modified in current object.
+	 * Tracking modified columns allows us to only update modified columns.
+	 * @var        array
+	 */
+	protected $modifiedColumns = array();
+
+	/**
+	 * Empty constructor (this allows people with their own BaseObject implementation to use its constructor)
+	 */
+	public function __construct() {
+
+	}
+
+	/**
+	 * Returns whether the object has been modified.
+	 *
+	 * @return     boolean True if the object has been modified.
+	 */
+	public function isModified()
+	{
+		return !empty($this->modifiedColumns);
+	}
+
+	/**
+	 * Has specified column been modified?
+	 *
+	 * @param      string $col
+	 * @return     boolean True if $col has been modified.
+	 */
+	public function isColumnModified($col)
+	{
+		return in_array($col, $this->modifiedColumns);
+	}
+
+	/**
+	 * Get the columns that have been modified in this object.
+	 * @return     array A unique list of the modified column names for this object.
+	 */
+	public function getModifiedColumns()
+	{
+		return array_unique($this->modifiedColumns);
+	}
+
+	/**
+	 * Returns whether the object has ever been saved.  This will
+	 * be false, if the object was retrieved from storage or was created
+	 * and then saved.
+	 *
+	 * @return     true, if the object has never been persisted.
+	 */
+	public function isNew()
+	{
+		return $this->_new;
+	}
+
+	/**
+	 * Setter for the isNew attribute.  This method will be called
+	 * by Propel-generated children and Peers.
+	 *
+	 * @param      boolean $b the state of the object.
+	 */
+	public function setNew($b)
+	{
+		$this->_new = (boolean) $b;
+	}
+
+	/**
+	 * Whether this object has been deleted.
+	 * @return     boolean The deleted state of this object.
+	 */
+	public function isDeleted()
+	{
+		return $this->_deleted;
+	}
+
+	/**
+	 * Specify whether this object has been deleted.
+	 * @param      boolean $b The deleted state of this object.
+	 * @return     void
+	 */
+	public function setDeleted($b)
+	{
+		$this->_deleted = (boolean) $b;
+	}
+
+	/**
+	 * Sets the modified state for the object to be false.
+	 * @param      string $col If supplied, only the specified column is reset.
+	 * @return     void
+	 */
+	public function resetModified($col = null)
+	{
+		if ($col !== null)
+		{
+			while (($offset = array_search($col, $this->modifiedColumns)) !== false)
+				array_splice($this->modifiedColumns, $offset, 1);
+		}
+		else
+		{
+			$this->modifiedColumns = array();
+		}
+	}
+
+	/**
+	 * Compares this with another <code>BaseObject</code> instance.  If
+	 * <code>obj</code> is an instance of <code>BaseObject</code>, delegates to
+	 * <code>equals(BaseObject)</code>.  Otherwise, returns <code>false</code>.
+	 *
+	 * @param      obj The object to compare to.
+	 * @return     Whether equal to the object specified.
+	 */
+	public function equals($obj)
+	{
+		$thisclazz = get_class($this);
+		if (is_object($obj) && $obj instanceof $thisclazz) {
+			if ($this === $obj) {
+				return true;
+			} elseif ($this->getPrimaryKey() === null || $obj->getPrimaryKey() === null)  {
+				return false;
+			} else {
+				return ($this->getPrimaryKey() === $obj->getPrimaryKey());
+			}
+		} else {
+			return false;
+		}
+	}
+
+	/**
+	 * If the primary key is not <code>null</code>, return the hashcode of the
+	 * primary key.  Otherwise calls <code>Object.hashCode()</code>.
+	 *
+	 * @return     int Hashcode
+	 */
+	public function hashCode()
+	{
+		$ok = $this->getPrimaryKey();
+		if ($ok === null) {
+			return crc32(serialize($this));
+		}
+		return crc32(serialize($ok)); // serialize because it could be an array ("ComboKey")
+	}
+
+	/**
+	 * Logs a message using Propel::log().
+	 *
+	 * @param      string $msg
+	 * @param      int $priority One of the Propel::LOG_* logging levels
+	 * @return     boolean
+	 */
+	protected function log($msg, $priority = Propel::LOG_INFO)
+	{
+		return Propel::log(get_class($this) . ': ' . $msg, $priority);
+	}
+
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel/om/NestedSetRecursiveIterator.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel/om/NestedSetRecursiveIterator.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel/om/NestedSetRecursiveIterator.php	(revision 19)
@@ -0,0 +1,88 @@
+<?php
+
+/*
+ *  $Id: NestedSetRecursiveIterator.php 875 2007-12-19 11:10:15Z heltem $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://propel.phpdb.org>.
+ */
+
+/**
+ * Pre-order node iterator for Node objects.
+ *
+ * @author     Heltem <heltem@o2php.com>
+ * @version    $Revision: 875 $
+ * @package    propel.om
+ */
+class NestedSetRecursiveIterator implements RecursiveIterator
+{
+	protected $topNode = null;
+
+	protected $curNode = null;
+
+	public function __construct($node) {
+		$this->topNode = $node;
+		$this->curNode = $node;
+	}
+
+	public function rewind() {
+		$this->curNode = $this->topNode;
+	}
+
+	public function valid() {
+		return ($this->curNode !== null);
+	}
+
+	public function current() {
+		return $this->curNode;
+	}
+
+	public function key() {
+		$key = array();
+		foreach ($this->curNode->getPath() as $node) {
+			$key[] = $node->getPrimaryKey();
+		}
+		return implode('.', $key);
+	}
+
+	public function next() {
+		$nextNode = null;
+
+		if ($this->valid()) {
+			while (null === $nextNode) {
+				if (null === $this->curNode) {
+					break;
+				}
+
+				if ($this->curNode->hasNextSibling()) {
+					$nextNode = $this->curNode->retrieveNextSibling();
+				} else {
+					break;
+				}
+			}
+			$this->curNode = $nextNode;
+		}
+		return $this->curNode;
+	}
+
+	public function hasChildren() {
+		return $this->curNode->hasChildren();
+	}
+
+	public function getChildren() {
+		return new NestedSetRecursiveIterator($this->curNode->retrieveFirstChild());
+	}
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel/om/NodeObject.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel/om/NodeObject.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel/om/NodeObject.php	(revision 19)
@@ -0,0 +1,334 @@
+<?php
+/*
+ *  $Id: NodeObject.php 797 2007-11-09 19:21:21Z heltem $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://propel.phpdb.org>.
+ */
+
+/**
+ * This interface defines methods that must be implemented by all
+ * business objects within the system to handle Node object.
+ *
+ * @author     Heltem <heltem@o2php.com> (Propel)
+ * @version    $Revision: 797 $
+ * @package    propel.om
+ */
+interface NodeObject extends IteratorAggregate {
+	/**
+	 * If object is saved without left/right values, set them as undefined (0)
+	 *
+	 * @param      PropelPDO $con	Connection to use.
+	 * @return     void
+	 * @throws     PropelException
+	 */
+	public function save(PropelPDO $con = null);
+
+	/**
+	 * Delete node and descendants
+	 *
+	 * @param      PropelPDO $con	Connection to use.
+	 * @return     void
+	 * @throws     PropelException
+	 */
+	public function delete(PropelPDO $con = null);
+
+	/**
+	 * Sets node properties to make it a root node.
+	 *
+	 * @return     object The current object (for fluent API support)
+	 * @throws     PropelException
+	 */
+	public function makeRoot();
+
+	/**
+	 * Gets the level if set, otherwise calculates this and returns it
+	 *
+	 * @param      PropelPDO $con	Connection to use.
+	 * @return     int
+	 */
+	public function getLevel(PropelPDO $con = null);
+
+	/**
+	 * Get the path to the node in the tree
+	 *
+	 * @param      PropelPDO $con	Connection to use.
+	 * @return     array
+	 */
+	public function getPath(PropelPDO $con = null);
+
+	/**
+	 * Gets the number of children for the node (direct descendants)
+	 *
+	 * @param      PropelPDO $con	Connection to use.
+	 * @return     int
+	 */
+	public function getNumberOfChildren(PropelPDO $con = null);
+
+	/**
+	 * Gets the total number of desceandants for the node
+	 *
+	 * @param      PropelPDO $con	Connection to use.
+	 * @return     int
+	 */
+	public function getNumberOfDescendants(PropelPDO $con = null);
+
+	/**
+	 * Gets the children for the node
+	 *
+	 * @param      PropelPDO $con	Connection to use.
+	 * @return     array
+	 */
+	public function getChildren(PropelPDO $con = null);
+
+	/**
+	 * Gets the descendants for the node
+	 *
+	 * @param      PropelPDO $con	Connection to use.
+ 	 * @return     array
+	 */
+	public function getDescendants(PropelPDO $con = null);
+
+	/**
+	 * Sets the level of the node in the tree
+	 *
+	 * @param      int $v new value
+	 * @return     object The current object (for fluent API support)
+	 */
+	public function setLevel($level);
+
+	/**
+	 * Sets the children array of the node in the tree
+	 *
+	 * @param      array of Node $children	array of Propel node object
+	 * @return     object The current object (for fluent API support)
+	 */
+	public function setChildren(array $children);
+
+	/**
+	 * Sets the parentNode of the node in the tree
+	 *
+	 * @param      Node $parent Propel node object
+	 * @return     object The current object (for fluent API support)
+	 */
+	public function setParentNode(NodeObject $parent = null);
+
+	/**
+	 * Sets the previous sibling of the node in the tree
+	 *
+	 * @param      Node $node Propel node object
+	 * @return     object The current object (for fluent API support)
+	 */
+	public function setPrevSibling(NodeObject $node = null);
+
+	/**
+	 * Sets the next sibling of the node in the tree
+	 *
+	 * @param      Node $node Propel node object
+	 * @return     object The current object (for fluent API support)
+	 */
+	public function setNextSibling(NodeObject $node = null);
+
+	/**
+	 * Determines if the node is the root node
+	 *
+	 * @return     bool
+	 */
+	public function isRoot();
+
+	/**
+	 * Determines if the node is a leaf node
+	 *
+	 * @return     bool
+	 */
+	public function isLeaf();
+
+	/**
+	 * Tests if object is equal to $node
+	 *
+	 * @param      object $node	Propel object for node to compare to
+	 * @return     bool
+	 */
+	public function isEqualTo(NodeObject $node);
+
+	/**
+	 * Tests if object has an ancestor
+	 *
+	 * @param      PropelPDO $con	Connection to use.
+	 * @return     bool
+	 */
+	public function hasParent(PropelPDO $con = null);
+
+	/**
+	 * Determines if the node has children / descendants
+	 *
+	 * @return     bool
+	 */
+	public function hasChildren();
+
+	/**
+	 * Determines if the node has previous sibling
+	 *
+	 * @param      PropelPDO $con	Connection to use.
+	 * @return     bool
+	 */
+	public function hasPrevSibling(PropelPDO $con = null);
+
+	/**
+	 * Determines if the node has next sibling
+	 *
+	 * @param      PropelPDO $con	Connection to use.
+	 * @return     bool
+	 */
+	public function hasNextSibling(PropelPDO $con = null);
+
+	/**
+	 * Gets ancestor for the given node if it exists
+	 *
+	 * @param      PropelPDO $con	Connection to use.
+	 * @return     mixed 		Propel object if exists else false
+	 */
+	public function retrieveParent(PropelPDO $con = null);
+
+	/**
+	 * Gets first child if it exists
+	 *
+	 * @param      PropelPDO $con	Connection to use.
+	 * @return     mixed 		Propel object if exists else false
+	 */
+	public function retrieveFirstChild(PropelPDO $con = null);
+
+	/**
+	 * Gets last child if it exists
+	 *
+	 * @param      PropelPDO $con	Connection to use.
+	 * @return     mixed 		Propel object if exists else false
+	 */
+	public function retrieveLastChild(PropelPDO $con = null);
+
+	/**
+	 * Gets prev sibling for the given node if it exists
+	 *
+	 * @param      PropelPDO $con	Connection to use.
+	 * @return     mixed 		Propel object if exists else false
+	 */
+	public function retrievePrevSibling(PropelPDO $con = null);
+
+	/**
+	 * Gets next sibling for the given node if it exists
+	 *
+	 * @param      PropelPDO $con	Connection to use.
+	 * @return     mixed 		Propel object if exists else false
+	 */
+	public function retrieveNextSibling(PropelPDO $con = null);
+
+	/**
+	 * Inserts as first child of destination node $parent
+	 *
+	 * @param      object $parent	Propel object for given destination node
+	 * @param      PropelPDO $con	Connection to use.
+	 * @return     object The current object (for fluent API support)
+	 */
+	public function insertAsFirstChildOf(NodeObject $parent, PropelPDO $con = null);
+
+	/**
+	 * Inserts as last child of destination node $parent
+	 *
+	 * @param      object $parent	Propel object for given destination node
+	 * @param      PropelPDO $con	Connection to use.
+	 * @return     object The current object (for fluent API support)
+	 */
+	public function insertAsLastChildOf(NodeObject $parent, PropelPDO $con = null);
+
+	/**
+	 * Inserts node as previous sibling to destination node $dest
+	 *
+	 * @param      object $dest	Propel object for given destination node
+	 * @param      PropelPDO $con	Connection to use.
+	 * @return     object The current object (for fluent API support)
+	 */
+	public function insertAsPrevSiblingOf(NodeObject $dest, PropelPDO $con = null);
+
+	/**
+	 * Inserts node as next sibling to destination node $dest
+	 *
+	 * @param      object $dest	Propel object for given destination node
+	 * @param      PropelPDO $con	Connection to use.
+	 * @return     object The current object (for fluent API support)
+	 */
+	public function insertAsNextSiblingOf(NodeObject $dest, PropelPDO $con = null);
+
+	/**
+	 * Moves node to be first child of $parent
+	 *
+	 * @param      object $parent	Propel object for destination node
+	 * @param      PropelPDO $con Connection to use.
+	 * @return     void
+	 */
+	public function moveToFirstChildOf(NodeObject $parent, PropelPDO $con = null);
+
+	/**
+	 * Moves node to be last child of $parent
+	 *
+	 * @param      object $parent	Propel object for destination node
+	 * @param      PropelPDO $con Connection to use.
+	 * @return     void
+	 */
+	public function moveToLastChildOf(NodeObject $parent, PropelPDO $con = null);
+
+	/**
+	 * Moves node to be prev sibling to $dest
+	 *
+	 * @param      object $dest	Propel object for destination node
+	 * @param      PropelPDO $con Connection to use.
+	 * @return     void
+	 */
+	public function moveToPrevSiblingOf(NodeObject $dest, PropelPDO $con = null);
+
+	/**
+	 * Moves node to be next sibling to $dest
+	 *
+	 * @param      object $dest	Propel object for destination node
+	 * @param      PropelPDO $con Connection to use.
+	 * @return     void
+	 */
+	public function moveToNextSiblingOf(NodeObject $dest, PropelPDO $con = null);
+
+	/**
+	 * Inserts node as parent of given node.
+	 *
+	 * @param      object $node  Propel object for given destination node
+	 * @param      PropelPDO $con	Connection to use.
+	 * @return     void
+	 * @throws     Exception      When trying to insert node as parent of a root node
+	 */
+	public function insertAsParentOf(NodeObject $node, PropelPDO $con = null);
+
+	/**
+	 * Wraps the getter for the scope value
+	 *
+	 * @return     int
+	 */
+	public function getScopeIdValue();
+
+	/**
+	 * Set the value of scope column
+	 *
+	 * @param      int $v new value
+	 * @return     object The current object (for fluent API support)
+	 */
+	public function setScopeIdValue($v);
+} // NodeObject
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel/om/Persistent.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel/om/Persistent.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel/om/Persistent.php	(revision 19)
@@ -0,0 +1,118 @@
+<?php
+/*
+ *  $Id: Persistent.php 713 2007-10-24 07:22:40Z dwhittle $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://propel.phpdb.org>.
+ */
+
+/**
+ * This interface defines methods related to saving an object
+ *
+ * @author     Hans Lellelid <hans@xmpl.org> (Propel)
+ * @author     John D. McNally <jmcnally@collab.net> (Torque)
+ * @author     Fedor K. <fedor@apache.org> (Torque)
+ * @version    $Revision: 713 $
+ * @package    propel.om
+ */
+interface Persistent {
+
+	/**
+	 * getter for the object primaryKey.
+	 *
+	 * @return     ObjectKey the object primaryKey as an Object
+	 */
+	public function getPrimaryKey();
+
+	/**
+	 * Sets the PrimaryKey for the object.
+	 *
+	 * @param      mixed $primaryKey The new PrimaryKey object or string (result of PrimaryKey.toString()).
+	 * @return     void
+	 * @throws     Exception, This method might throw an exceptions
+	 */
+	public function setPrimaryKey($primaryKey);
+
+
+	/**
+	 * Returns whether the object has been modified, since it was
+	 * last retrieved from storage.
+	 *
+	 * @return     boolean True if the object has been modified.
+	 */
+	public function isModified();
+
+	/**
+	 * Has specified column been modified?
+	 *
+	 * @param      string $col
+	 * @return     boolean True if $col has been modified.
+	 */
+	public function isColumnModified($col);
+
+	/**
+	 * Returns whether the object has ever been saved.  This will
+	 * be false, if the object was retrieved from storage or was created
+	 * and then saved.
+	 *
+	 * @return     boolean True, if the object has never been persisted.
+	 */
+	public function isNew();
+
+	/**
+	 * Setter for the isNew attribute.  This method will be called
+	 * by Propel-generated children and Peers.
+	 *
+	 * @param      boolean $b the state of the object.
+	 */
+	public function setNew($b);
+
+	/**
+	 * Resets (to false) the "modified" state for this object.
+	 *
+	 * @return     void
+	 */
+	public function resetModified();
+
+	/**
+	 * Whether this object has been deleted.
+	 * @return     boolean The deleted state of this object.
+	 */
+	public function isDeleted();
+
+	/**
+	 * Specify whether this object has been deleted.
+	 * @param      boolean $b The deleted state of this object.
+	 * @return     void
+	 */
+	public function setDeleted($b);
+
+	/**
+	 * Deletes the object.
+	 * @param      PropelPDO $con
+	 * @return     void
+	 * @throws     Exception
+	 */
+	public function delete(PropelPDO $con = null);
+
+	/**
+	 * Saves the object.
+	 * @param      PropelPDO $con
+	 * @return     void
+	 * @throws     Exception
+	 */
+	public function save(PropelPDO $con = null);
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel/om/PreOrderNodeIterator.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel/om/PreOrderNodeIterator.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel/om/PreOrderNodeIterator.php	(revision 19)
@@ -0,0 +1,90 @@
+<?php
+
+/*
+ *  $Id: PreOrderNodeIterator.php 563 2007-02-01 09:45:55Z heltem $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://propel.phpdb.org>.
+ */
+
+/**
+ * Pre-order node iterator for Node objects.
+ *
+ * @author     Dave Lawson <dlawson@masterytech.com>
+ * @version    $Revision: 563 $
+ * @package    propel.om
+ */
+class PreOrderNodeIterator implements Iterator
+{
+	private $topNode = null;
+
+	private $curNode = null;
+
+	private $querydb = false;
+
+	private $con = null;
+
+	public function __construct($node, $opts) {
+		$this->topNode = $node;
+		$this->curNode = $node;
+
+		if (isset($opts['con']))
+			$this->con = $opts['con'];
+
+		if (isset($opts['querydb']))
+			$this->querydb = $opts['querydb'];
+	}
+
+	public function rewind() {
+		$this->curNode = $this->topNode;
+	}
+
+	public function valid() {
+		return ($this->curNode !== null);
+	}
+
+	public function current() {
+		return $this->curNode;
+	}
+
+	public function key() {
+		return $this->curNode->getNodePath();
+	}
+
+	public function next() {
+
+		if ($this->valid())
+		{
+			$nextNode = $this->curNode->getFirstChildNode($this->querydb, $this->con);
+
+			while ($nextNode === null)
+			{
+				if ($this->curNode === null || $this->curNode->equals($this->topNode))
+					break;
+
+				$nextNode = $this->curNode->getSiblingNode(false, $this->querydb, $this->con);
+
+				if ($nextNode === null)
+					$this->curNode = $this->curNode->getParentNode($this->querydb, $this->con);
+			}
+
+			$this->curNode = $nextNode;
+		}
+
+		return $this->curNode;
+	}
+
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel/util/BasePeer.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel/util/BasePeer.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel/util/BasePeer.php	(revision 19)
@@ -0,0 +1,1070 @@
+<?php
+/*
+ *  $Id: BasePeer.php 1060 2008-06-13 12:52:23Z hans $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://propel.phpdb.org>.
+ */
+
+/**
+ * This is a utility class for all generated Peer classes in the system.
+ *
+ * Peer classes are responsible for isolating all of the database access
+ * for a specific business object.  They execute all of the SQL
+ * against the database.  Over time this class has grown to include
+ * utility methods which ease execution of cross-database queries and
+ * the implementation of concrete Peers.
+ *
+ * @author     Hans Lellelid <hans@xmpl.org> (Propel)
+ * @author     Kaspars Jaudzems <kaspars.jaudzems@inbox.lv> (Propel)
+ * @author     Heltem <heltem@o2php.com> (Propel)
+ * @author     Frank Y. Kim <frank.kim@clearink.com> (Torque)
+ * @author     John D. McNally <jmcnally@collab.net> (Torque)
+ * @author     Brett McLaughlin <bmclaugh@algx.net> (Torque)
+ * @author     Stephen Haberman <stephenh@chase3000.com> (Torque)
+ * @version    $Revision: 1060 $
+ * @package    propel.util
+ */
+class BasePeer
+{
+
+	/** Array (hash) that contains the cached mapBuilders. */
+	private static $mapBuilders = array();
+
+	/** Array (hash) that contains cached validators */
+	private static $validatorMap = array();
+
+	/**
+	 * phpname type
+	 * e.g. 'AuthorId'
+	 */
+	const TYPE_PHPNAME = 'phpName';
+
+	/**
+	 * studlyphpname type
+	 * e.g. 'authorId'
+	 */
+	const TYPE_STUDLYPHPNAME = 'studlyPhpName';
+
+	/**
+	 * column (peer) name type
+	 * e.g. 'book.AUTHOR_ID'
+	 */
+	const TYPE_COLNAME = 'colName';
+
+	/**
+	 * column fieldname type
+	 * e.g. 'author_id'
+	 */
+	const TYPE_FIELDNAME = 'fieldName';
+
+	/**
+	 * num type
+	 * simply the numerical array index, e.g. 4
+	 */
+	const TYPE_NUM = 'num';
+
+	static public function getFieldnames ($classname, $type = self::TYPE_PHPNAME) {
+
+		// TODO we should take care of including the peer class here
+
+		$peerclass = 'Base' . $classname . 'Peer'; // TODO is this always true?
+		$callable = array($peerclass, 'getFieldnames');
+		$args = array($type);
+
+		return call_user_func_array($callable, $args);
+	}
+
+	static public function translateFieldname($classname, $fieldname, $fromType, $toType) {
+
+		// TODO we should take care of including the peer class here
+
+		$peerclass = 'Base' . $classname . 'Peer'; // TODO is this always true?
+		$callable = array($peerclass, 'translateFieldname');
+		$args = array($fieldname, $fromType, $toType);
+
+		return call_user_func_array($callable, $args);
+	}
+
+	/**
+	 * Method to perform deletes based on values and keys in a
+	 * Criteria.
+	 *
+	 * @param      Criteria $criteria The criteria to use.
+	 * @param      PropelPDO $con A PropelPDO connection object.
+	 * @return     int	The number of rows affected by last statement execution.  For most
+	 * 				uses there is only one delete statement executed, so this number
+	 * 				will correspond to the number of rows affected by the call to this
+	 * 				method.  Note that the return value does require that this information
+	 * 				is returned (supported) by the PDO driver.
+	 * @throws     PropelException
+	 */
+	public static function doDelete(Criteria $criteria, PropelPDO $con)
+	{
+		$db = Propel::getDB($criteria->getDbName());
+		$dbMap = Propel::getDatabaseMap($criteria->getDbName());
+
+		// Set up a list of required tables (one DELETE statement will
+		// be executed per table)
+
+		$tables_keys = array();
+		foreach ($criteria as $c) {
+			foreach ($c->getAllTables() as $tableName) {
+				$tableName2 = $criteria->getTableForAlias($tableName);
+				if ($tableName2 !== null) {
+					$tables_keys[$tableName2 . ' ' . $tableName] = true;
+				} else {
+					$tables_keys[$tableName] = true;
+				}
+			}
+		} // foreach criteria->keys()
+
+		$affectedRows = 0; // initialize this in case the next loop has no iterations.
+
+		$tables = array_keys($tables_keys);
+
+		foreach ($tables as $tableName) {
+
+			$whereClause = array();
+			$selectParams = array();
+			foreach ($dbMap->getTable($tableName)->getColumns() as $colMap) {
+				$key = $tableName . '.' . $colMap->getColumnName();
+				if ($criteria->containsKey($key)) {
+					$sb = "";
+					$criteria->getCriterion($key)->appendPsTo($sb, $selectParams);
+					$whereClause[] = $sb;
+				}
+			}
+
+			if (empty($whereClause)) {
+				throw new PropelException("Cowardly refusing to delete from table $tableName with empty WHERE clause.");
+			}
+
+			for ($i=0; $i<2; $i++) {
+  			// Execute the statement.
+  			try {
+  				$sql = "DELETE FROM " . $tableName . " WHERE " .  implode(" AND ", $whereClause);
+  				$stmt = $con->prepare($sql);
+  				self::populateStmtValues($stmt, $selectParams, $dbMap, $db);
+  				$stmt->execute();
+  				$affectedRows = $stmt->rowCount();
+  				break;
+  			} catch (Exception $e) {
+
+  			  if (preg_match('@MySQL server has gone away@', $e->getMessage())) {
+    			  error_log(date('Y-m-d H:i:s').": Mysql delete query failed ($i), requery\n", 3, sfConfig::get('sf_log_dir').'/dblog.txt');
+    	      Propel::close();
+    	      Propel::initialize();
+    	      Propel::initConnection();
+    	      $con = Propel::getConnection($criteria->getDbName(), Propel::CONNECTION_WRITE);
+    	      continue;
+    			}
+
+  				Propel::log($e->getMessage(), Propel::LOG_ERR);
+  				throw new PropelException("Unable to execute DELETE statement.",$e);
+  			}
+			}
+
+		} // for each table
+
+		return $affectedRows;
+	}
+
+	/**
+	 * Method to deletes all contents of specified table.
+	 *
+	 * This method is invoked from generated Peer classes like this:
+	 * <code>
+	 * public static function doDeleteAll($con = null)
+	 * {
+	 *   if ($con === null) $con = Propel::getConnection(self::DATABASE_NAME);
+	 *   BasePeer::doDeleteAll(self::TABLE_NAME, $con);
+	 * }
+	 * </code>
+	 *
+	 * @param      string $tableName The name of the table to empty.
+	 * @param      PropelPDO $con A PropelPDO connection object.
+	 * @return     int	The number of rows affected by the statement.  Note
+	 * 				that the return value does require that this information
+	 * 				is returned (supported) by the Creole db driver.
+	 * @throws     PropelException - wrapping SQLException caught from statement execution.
+	 */
+	public static function doDeleteAll($tableName, PropelPDO $con)
+	{
+		try {
+			$sql = "DELETE FROM " . $tableName;
+			$stmt = $con->prepare($sql);
+			$stmt->execute();
+			return $stmt->rowCount();
+		} catch (Exception $e) {
+			Propel::log($e->getMessage(), Propel::LOG_ERR);
+			throw new PropelException("Unable to perform DELETE ALL operation.", $e);
+		}
+	}
+
+	/**
+	 * Method to perform inserts based on values and keys in a
+	 * Criteria.
+	 * <p>
+	 * If the primary key is auto incremented the data in Criteria
+	 * will be inserted and the auto increment value will be returned.
+	 * <p>
+	 * If the primary key is included in Criteria then that value will
+	 * be used to insert the row.
+	 * <p>
+	 * If no primary key is included in Criteria then we will try to
+	 * figure out the primary key from the database map and insert the
+	 * row with the next available id using util.db.IDBroker.
+	 * <p>
+	 * If no primary key is defined for the table the values will be
+	 * inserted as specified in Criteria and null will be returned.
+	 *
+	 * @param      Criteria $criteria Object containing values to insert.
+	 * @param      PropelPDO $con A PropelPDO connection.
+	 * @return     mixed The primary key for the new row if (and only if!) the primary key
+	 *				is auto-generated.  Otherwise will return <code>null</code>.
+	 * @throws     PropelException
+	 */
+	public static function doInsert(Criteria $criteria, PropelPDO $con) {
+		// the primary key
+		$id = null;
+
+		$db = Propel::getDB($criteria->getDbName());
+
+		// Get the table name and method for determining the primary
+		// key value.
+		$keys = $criteria->keys();
+		if (!empty($keys)) {
+			$tableName = $criteria->getTableName( $keys[0] );
+		} else {
+			throw new PropelException("Database insert attempted without anything specified to insert");
+		}
+
+		$dbMap = Propel::getDatabaseMap($criteria->getDbName());
+		$tableMap = $dbMap->getTable($tableName);
+		$keyInfo = $tableMap->getPrimaryKeyMethodInfo();
+		$useIdGen = $tableMap->isUseIdGenerator();
+		//$keyGen = $con->getIdGenerator();
+
+		$pk = self::getPrimaryKey($criteria);
+
+		// only get a new key value if you need to
+		// the reason is that a primary key might be defined
+		// but you are still going to set its value. for example:
+		// a join table where both keys are primary and you are
+		// setting both columns with your own values
+
+		// pk will be null if there is no primary key defined for the table
+		// we're inserting into.
+		if ($pk !== null && $useIdGen && !$criteria->keyContainsValue($pk->getFullyQualifiedName()) && $db->isGetIdBeforeInsert()) {
+			try {
+				$id = $db->getId($con, $keyInfo);
+			} catch (Exception $e) {
+				throw new PropelException("Unable to get sequence id.", $e);
+			}
+			$criteria->add($pk->getFullyQualifiedName(), $id);
+		}
+
+		for ($i=0; $i<2; $i++) {
+  		try {
+  			$adapter = Propel::getDB($criteria->getDBName());
+
+  			$qualifiedCols = $criteria->keys(); // we need table.column cols when populating values
+  			$columns = array(); // but just 'column' cols for the SQL
+  			foreach ($qualifiedCols as $qualifiedCol) {
+  				$columns[] = substr($qualifiedCol, strrpos($qualifiedCol, '.') + 1);
+  			}
+
+  			// add identifiers
+  			if ($adapter->useQuoteIdentifier()) {
+  				$columns = array_map(array($adapter, 'quoteIdentifier'), $columns);
+  			}
+
+  			$sql = 'INSERT INTO ' . $tableName
+  			. ' (' . implode(',', $columns) . ')'
+  			. ' VALUES (';
+  			// . substr(str_repeat("?,", count($columns)), 0, -1) .
+  			for($p=1, $cnt=count($columns); $p <= $cnt; $p++) {
+  				$sql .= ':p'.$p;
+  				if ($p !== $cnt) $sql .= ',';
+  			}
+  			$sql .= ')';
+
+  			$stmt = $con->prepare($sql);
+  			self::populateStmtValues($stmt, self::buildParams($qualifiedCols, $criteria), $dbMap, $db);
+  			$stmt->execute();
+  			break;
+
+  		} catch (Exception $e) {
+
+      	if (preg_match('@MySQL server has gone away@', $e->getMessage())) {
+  			  error_log(date('Y-m-d H:i:s').": Mysql insert query failed ($i), requery\n", 3, sfConfig::get('sf_log_dir').'/dblog.txt');
+  	      Propel::close();
+  	      Propel::initialize();
+  	      Propel::initConnection();
+  	      $con = Propel::getConnection($criteria->getDbName(), Propel::CONNECTION_WRITE);
+  	      continue;
+  			}
+
+  			Propel::log($e->getMessage(), Propel::LOG_ERR);
+  			throw new PropelException("Unable to execute INSERT statement.", $e);
+  		}
+		}
+
+		// If the primary key column is auto-incremented, get the id now.
+		if ($pk !== null && $useIdGen && $db->isGetIdAfterInsert()) {
+			try {
+				$id = $db->getId($con, $keyInfo);
+			} catch (Exception $e) {
+				throw new PropelException("Unable to get autoincrement id.", $e);
+			}
+		}
+
+		return $id;
+	}
+
+	public static $low_priority = false;
+	/**
+	 * Method used to update rows in the DB.  Rows are selected based
+	 * on selectCriteria and updated using values in updateValues.
+	 * <p>
+	 * Use this method for performing an update of the kind:
+	 * <p>
+	 * WHERE some_column = some value AND could_have_another_column =
+	 * another value AND so on.
+	 *
+	 * @param      $selectCriteria A Criteria object containing values used in where
+	 *		clause.
+	 * @param      $updateValues A Criteria object containing values used in set
+	 *		clause.
+	 * @param      PropelPDO $con The PropelPDO connection object to use.
+	 * @return     int	The number of rows affected by last update statement.  For most
+	 * 				uses there is only one update statement executed, so this number
+	 * 				will correspond to the number of rows affected by the call to this
+	 * 				method.  Note that the return value does require that this information
+	 * 				is returned (supported) by the Creole db driver.
+	 * @throws     PropelException
+	 */
+	public static function doUpdate(Criteria $selectCriteria, Criteria $updateValues, PropelPDO $con) {
+
+		$db = Propel::getDB($selectCriteria->getDbName());
+		$dbMap = Propel::getDatabaseMap($selectCriteria->getDbName());
+
+		// Get list of required tables, containing all columns
+		$tablesColumns = $selectCriteria->getTablesColumns();
+
+		// we also need the columns for the update SQL
+		$updateTablesColumns = $updateValues->getTablesColumns();
+
+		$affectedRows = 0; // initialize this in case the next loop has no iterations.
+
+		foreach ($tablesColumns as $tableName => $columns) {
+
+			$whereClause = array();
+
+			$params = array();
+
+			$stmt = null;
+			for ($i=0; $i<2; $i++) {
+  			try {
+
+          /*if (self::$low_priority)
+	  		    $sql = "UPDATE LOW_PRIORITY " . $tableName . " SET ";
+          else*/
+	  		    $sql = "UPDATE " . $tableName . " SET ";
+  				$p = 1;
+  				foreach ($updateTablesColumns[$tableName] as $col) {
+  					$updateColumnName = substr($col, strrpos($col, '.') + 1);
+  					// add identifiers for the actual database?
+  					if ($db->useQuoteIdentifier()) {
+  						$updateColumnName = $db->quoteIdentifier($updateColumnName);
+  					}
+  					if ($updateValues->getComparison($col) != Criteria::CUSTOM_EQUAL) {
+  						$sql .= $updateColumnName . '=:p'.$p++.', ';
+  					} else {
+  						$param = $updateValues->get($col);
+  						$sql .= $updateColumnName . ' = ';
+  						if (is_array($param)) {
+  							if (isset($param['raw'])) {
+  								$raw = $param['raw'];
+  								$rawcvt = '';
+  								// parse the $params['raw'] for ? chars
+  								for($r=0,$len=strlen($raw); $r < $len; $r++) {
+  									if ($raw{$r} == '?') {
+  										$rawcvt .= ':p'.$p++;
+  									} else {
+  										$rawcvt .= $raw{$r};
+  									}
+  								}
+  								$sql .= $rawcvt . ', ';
+  							} else {
+  								$sql .= ':p'.$p++.', ';
+  							}
+  							if (isset($param['value'])) {
+  								$updateValues->put($col, $param['value']);
+  							}
+  						} else {
+  							$updateValues->remove($col);
+  							$sql .= $param . ', ';
+  						}
+  					}
+  				}
+
+  				$params = self::buildParams($updateTablesColumns[$tableName], $updateValues);
+
+  				foreach ($columns as $colName) {
+  					$sb = "";
+  					$selectCriteria->getCriterion($colName)->appendPsTo($sb, $params);
+  					$whereClause[] = $sb;
+  				}
+
+  				$sql = substr($sql, 0, -2) . " WHERE " .  implode(" AND ", $whereClause);
+
+  				$stmt = $con->prepare($sql);
+
+  				// Replace ':p?' with the actual values
+  				self::populateStmtValues($stmt, $params, $dbMap, $db);
+
+  				$stmt->execute();
+
+  				$affectedRows = $stmt->rowCount();
+
+  				$stmt = null; // close
+  				break;
+
+  			} catch (Exception $e) {
+  				if ($stmt) $stmt = null; // close
+
+  				if (preg_match('@MySQL server has gone away@', $e->getMessage())) {
+    			  error_log(date('Y-m-d H:i:s').": Mysql update query failed ($i), requery\n", 3, sfConfig::get('sf_log_dir').'/dblog.txt');
+  		      Propel::close();
+  		      Propel::initialize();
+  		      Propel::initConnection();
+  		      $con = Propel::getConnection($criteria->getDbName(), Propel::CONNECTION_WRITE);
+  		      continue;
+    			}
+
+  				Propel::log($e->getMessage(), Propel::LOG_ERR);
+  				throw new PropelException("Unable to execute UPDATE statement.", $e);
+  			}
+			} // for
+
+		} // foreach table in the criteria
+
+		return $affectedRows;
+	}
+
+	/**
+	 * Executes query build by createSelectSql() and returns the resultset statement.
+	 *
+	 * @param      Criteria $criteria A Criteria.
+	 * @param      PropelPDO $con A PropelPDO connection to use.
+	 * @return     PDOStatement The resultset.
+	 * @throws     PropelException
+	 * @see        createSelectSql()
+	 */
+	public static function doSelect(Criteria $criteria, PropelPDO $con = null)
+	{
+		$dbMap = Propel::getDatabaseMap($criteria->getDbName());
+		$db = Propel::getDB($criteria->getDbName());
+
+		if ($con === null) {
+		  try {
+			 $con = Propel::getConnection($criteria->getDbName(), Propel::CONNECTION_READ);
+		  } catch (Exception $e) {
+		    if (preg_match('@MySQL server has gone away@', $e->getMessage())) {
+		      error_log(date('Y-m-d H:i:s').": Mysql get connection failed, reconnect\n", 3, sfConfig::get('sf_log_dir').'/dblog.txt');
+		      Propel::close();
+		      Propel::initialize();
+		      Propel::initConnection();
+		      $con = Propel::getConnection($criteria->getDbName(), Propel::CONNECTION_READ);
+		    }
+		  }
+		}
+
+		$stmt = null;
+
+		if ($criteria->isUseTransaction()) $con->beginTransaction();
+
+		for ($i=0; $i<2; $i++) {
+  		try {
+
+  			$params = array();
+  			$sql = self::createSelectSql($criteria, $params);
+
+  			$stmt = $con->prepare($sql);
+
+  			self::populateStmtValues($stmt, $params, $dbMap, $db);
+
+  			$stmt->execute();
+
+  			if ($criteria->isUseTransaction()) $con->commit();
+  			break;
+
+  		} catch (Exception $e) {
+  			if ($stmt) $stmt = null; // close
+  			if ($criteria->isUseTransaction()) $con->rollBack();
+  			if (preg_match('@MySQL server has gone away@', $e->getMessage())) {
+  			  error_log(date('Y-m-d H:i:s').": Mysql select query failed ($i), requery\n", 3, sfConfig::get('sf_log_dir').'/dblog.txt');
+		      Propel::close();
+		      Propel::initialize();
+		      Propel::initConnection();
+		      $con = Propel::getConnection($criteria->getDbName(), Propel::CONNECTION_READ);
+		      if ($criteria->isUseTransaction()) $con->beginTransaction();
+		      continue;
+  			}
+  			Propel::log($e->getMessage(), Propel::LOG_ERR);
+  			throw new PropelException($e);
+  		}
+		}
+
+		return $stmt;
+	}
+
+	/**
+	 * Executes a COUNT query using either a simple SQL rewrite or, for more complex queries, a
+	 * sub-select of the SQL created by createSelectSql() and returns the statement.
+	 *
+	 * @param      Criteria $criteria A Criteria.
+	 * @param      PropelPDO $con A PropelPDO connection to use.
+	 * @return     PDOStatement The resultset statement.
+	 * @throws     PropelException
+	 * @see        createSelectSql()
+	 */
+	public static function doCount(Criteria $criteria, PropelPDO $con = null)
+	{
+		$dbMap = Propel::getDatabaseMap($criteria->getDbName());
+		$db = Propel::getDB($criteria->getDbName());
+
+		if ($con === null) {
+			$con = Propel::getConnection($criteria->getDbName(), Propel::CONNECTION_READ);
+		}
+
+		$stmt = null;
+
+		if ($criteria->isUseTransaction()) $con->beginTransaction();
+
+		$needsComplexCount = ($criteria->getGroupByColumns() || $criteria->getOffset()
+								|| $criteria->getLimit() || $criteria->getHaving() || in_array(Criteria::DISTINCT, $criteria->getSelectModifiers()));
+
+		try {
+
+			$params = array();
+
+			if ($needsComplexCount) {
+				$selectSql = self::createSelectSql($criteria, $params);
+				$sql = 'SELECT COUNT(*) FROM (' . $selectSql . ') AS propelmatch4cnt';
+			} else {
+				// Replace SELECT columns with COUNT(*)
+				$criteria->clearSelectColumns()->addSelectColumn('COUNT(*)');
+				$sql = self::createSelectSql($criteria, $params);
+			}
+
+			$stmt = $con->prepare($sql);
+			self::populateStmtValues($stmt, $params, $dbMap, $db);
+			$stmt->execute();
+
+			if ($criteria->isUseTransaction()) $con->commit();
+
+		} catch (Exception $e) {
+			if ($stmt) $stmt = null; // close
+			if ($criteria->isUseTransaction()) $con->rollBack();
+			Propel::log($e->getMessage(), Propel::LOG_ERR);
+			throw new PropelException($e);
+		}
+
+		return $stmt;
+	}
+
+	/**
+	 * Populates values in a prepared statement.
+	 *
+	 * This method is designed to work with the createSelectSql() method, which creates
+	 * both the SELECT SQL statement and populates a passed-in array of parameter
+	 * values that should be substituted.
+	 *
+	 * <code>
+	 * $params = array();
+	 * $sql = BasePeer::createSelectSql($criteria, $params);
+	 * BasePeer::populateStmtValues($stmt, $params, Propel::getDatabaseMap($critera->getDbName()), Propel::getDB($criteria->getDbName()));
+	 * </code>
+	 *
+	 * @param      PDOStatement $stmt
+	 * @param      array $params array('column' => ..., 'table' => ..., 'value' => ...)
+	 * @param      DatabaseMap $dbMap
+	 * @return     int The number of params replaced.
+	 * @see        createSelectSql()
+	 * @see        doSelect()
+	 */
+	private static function populateStmtValues(PDOStatement $stmt, array $params, DatabaseMap $dbMap, DBAdapter $db)
+	{
+		$i = 1;
+		foreach ($params as $param) {
+			$tableName = $param['table'];
+			$columnName = $param['column'];
+			$value = $param['value'];
+
+			if ($value === null) {
+
+				$stmt->bindValue(':p'.$i++, null, PDO::PARAM_NULL);
+
+			} else {
+
+				$cMap = $dbMap->getTable($tableName)->getColumn($columnName);
+				$type = $cMap->getType();
+				$pdoType = $cMap->getPdoType();
+
+				// FIXME - This is a temporary hack to get around apparent bugs w/ PDO+MYSQL
+				// See http://pecl.php.net/bugs/bug.php?id=9919
+				if ($pdoType == PDO::PARAM_BOOL && $db instanceof DBMySQL) {
+					$value = (int) $value;
+					$pdoType = PDO::PARAM_INT;
+				} elseif (is_numeric($value) && $cMap->isEpochTemporal()) { // it's a timestamp that needs to be formatted
+					if ($type == PropelColumnTypes::TIMESTAMP) {
+						$value = date($db->getTimestampFormatter(), $value);
+					} else if ($type == PropelColumnTypes::DATE) {
+						$value = date($db->getDateFormatter(), $value);
+					} else if ($type == PropelColumnTypes::TIME) {
+						$value = date($db->getTimeFormatter(), $value);
+					}
+				} elseif ($value instanceof DateTime && $cMap->isTemporal()) { // it's a timestamp that needs to be formatted
+					if ($type == PropelColumnTypes::TIMESTAMP || $type == PropelColumnTypes::BU_TIMESTAMP) {
+						$value = $value->format($db->getTimestampFormatter());
+					} else if ($type == PropelColumnTypes::DATE || $type == PropelColumnTypes::BU_DATE) {
+						$value = $value->format($db->getDateFormatter());
+					} else if ($type == PropelColumnTypes::TIME) {
+						$value = $value->format($db->getTimeFormatter());
+					}
+				} elseif (is_resource($value) && $cMap->isLob()) {
+					// we always need to make sure that the stream is rewound, otherwise nothing will
+					// get written to database.
+					rewind($value);
+				}
+
+				$stmt->bindValue(':p'.$i++, $value, $pdoType);
+			}
+		} // foreach
+	}
+
+	/**
+	 * Applies any validators that were defined in the schema to the specified columns.
+	 *
+	 * @param      string $dbName The name of the database
+	 * @param      string $tableName The name of the table
+	 * @param      array $columns Array of column names as key and column values as value.
+	 */
+	public static function doValidate($dbName, $tableName, $columns)
+	{
+		$dbMap = Propel::getDatabaseMap($dbName);
+		$tableMap = $dbMap->getTable($tableName);
+		$failureMap = array(); // map of ValidationFailed objects
+		foreach ($columns as $colName => $colValue) {
+			if ($tableMap->containsColumn($colName)) {
+				$col = $tableMap->getColumn($colName);
+				foreach ($col->getValidators() as $validatorMap) {
+					$validator = BasePeer::getValidator($validatorMap->getClass());
+					if ($validator && ($col->isNotNull() || $colValue !== null) && $validator->isValid($validatorMap, $colValue) === false) {
+						if (!isset($failureMap[$colName])) { // for now we do one ValidationFailed per column, not per rule
+							$failureMap[$colName] = new ValidationFailed($colName, $validatorMap->getMessage(), $validator);
+						}
+					}
+				}
+			}
+		}
+		return (!empty($failureMap) ? $failureMap : true);
+	}
+
+	/**
+	 * Helper method which returns the primary key contained
+	 * in the given Criteria object.
+	 *
+	 * @param      Criteria $criteria A Criteria.
+	 * @return     ColumnMap If the Criteria object contains a primary
+	 *		  key, or null if it doesn't.
+	 * @throws     PropelException
+	 */
+	private static function getPrimaryKey(Criteria $criteria)
+	{
+		// Assume all the keys are for the same table.
+		$keys = $criteria->keys();
+		$key = $keys[0];
+		$table = $criteria->getTableName($key);
+
+		$pk = null;
+
+		if (!empty($table)) {
+
+			$dbMap = Propel::getDatabaseMap($criteria->getDbName());
+
+			if ($dbMap === null) {
+				throw new PropelException("\$dbMap is null");
+			}
+
+			if ($dbMap->getTable($table) === null) {
+				throw new PropelException("\$dbMap->getTable() is null");
+			}
+
+			$columns = $dbMap->getTable($table)->getColumns();
+			foreach (array_keys($columns) as $key) {
+				if ($columns[$key]->isPrimaryKey()) {
+					$pk = $columns[$key];
+					break;
+				}
+			}
+		}
+		return $pk;
+	}
+
+	/**
+	 * Method to create an SQL query based on values in a Criteria.
+	 *
+	 * This method creates only prepared statement SQL (using ? where values
+	 * will go).  The second parameter ($params) stores the values that need
+	 * to be set before the statement is executed.  The reason we do it this way
+	 * is to let the PDO layer handle all escaping & value formatting.
+	 *
+	 * @param      Criteria $criteria Criteria for the SELECT query.
+	 * @param      array &$params Parameters that are to be replaced in prepared statement.
+	 * @return     string
+	 * @throws     PropelException Trouble creating the query string.
+	 */
+	public static function createSelectSql(Criteria $criteria, &$params) {
+
+		$db = Propel::getDB($criteria->getDbName());
+		$dbMap = Propel::getDatabaseMap($criteria->getDbName());
+
+		// redundant definition $selectModifiers = array();
+		$selectClause = array();
+		$fromClause = array();
+		$joinClause = array();
+		$joinTables = array();
+		$whereClause = array();
+		$orderByClause = array();
+		// redundant definition $groupByClause = array();
+
+		$orderBy = $criteria->getOrderByColumns();
+		$groupBy = $criteria->getGroupByColumns();
+		$ignoreCase = $criteria->isIgnoreCase();
+		$select = $criteria->getSelectColumns();
+		$aliases = $criteria->getAsColumns();
+
+		// simple copy
+		$selectModifiers = $criteria->getSelectModifiers();
+
+		// get selected columns
+		foreach ($select as $columnName) {
+
+			// expect every column to be of "table.column" formation
+			// it could be a function:  e.g. MAX(books.price)
+
+			$tableName = null;
+
+			$selectClause[] = $columnName; // the full column name: e.g. MAX(books.price)
+
+			$parenPos = strrpos($columnName, '(');
+			$dotPos = strrpos($columnName, '.', ($parenPos !== false ? $parenPos : 0));
+
+			// [HL] I think we really only want to worry about adding stuff to
+			// the fromClause if this function has a TABLE.COLUMN in it at all.
+			// e.g. COUNT(*) should not need this treatment -- or there needs to
+			// be special treatment for '*'
+			if ($dotPos !== false) {
+
+				if ($parenPos === false) { // table.column
+					$tableName = substr($columnName, 0, $dotPos);
+				} else { // FUNC(table.column)
+					$tableName = substr($columnName, $parenPos + 1, $dotPos - ($parenPos + 1));
+					// functions may contain qualifiers so only take the last
+					// word as the table name.
+					// COUNT(DISTINCT books.price)
+					$lastSpace = strpos($tableName, ' ');
+					if ($lastSpace !== false) { // COUNT(DISTINCT books.price)
+						$tableName = substr($tableName, $lastSpace + 1);
+					}
+				}
+				$tableName2 = $criteria->getTableForAlias($tableName);
+				if ($tableName2 !== null) {
+					$fromClause[] = $tableName2 . ' ' . $tableName;
+				} else {
+					$fromClause[] = $tableName;
+				}
+
+			} // if $dotPost !== null
+		}
+
+		// set the aliases
+		foreach ($aliases as $alias => $col) {
+			$selectClause[] = $col . " AS " . $alias;
+		}
+
+		// set the index hint
+		$indexHint = implode(',',$criteria->getIndexes());
+
+		// add the criteria to WHERE clause
+		// this will also add the table names to the FROM clause if they are not already
+		// invluded via a LEFT JOIN
+		foreach ($criteria->keys() as $key) {
+
+			$criterion = $criteria->getCriterion($key);
+			$someCriteria = $criterion->getAttachedCriterion();
+			$someCriteriaLength = count($someCriteria);
+			$table = null;
+			for ($i=0; $i < $someCriteriaLength; $i++) {
+				$tableName = $someCriteria[$i]->getTable();
+
+				$table = $criteria->getTableForAlias($tableName);
+				if ($table !== null) {
+					$fromClause[] = $table . ' ' . $tableName;
+				} else {
+					$fromClause[] = $tableName;
+					$table = $tableName;
+				}
+
+				$ignoreCase =
+				(($criteria->isIgnoreCase()
+				|| $someCriteria[$i]->isIgnoreCase())
+				&& (strpos($dbMap->getTable($table)->getColumn($someCriteria[$i]->getColumn())->getType(), "VARCHAR") !== false)
+				);
+
+				$someCriteria[$i]->setIgnoreCase($ignoreCase);
+			}
+
+			$criterion->setDB($db);
+
+			$sb = "";
+			$criterion->appendPsTo($sb, $params);
+			$whereClause[] = $sb;
+
+		}
+
+		// handle RIGHT (straight) joins
+		// Loop through the joins,
+		// joins with a null join type will be added to the FROM clause and the condition added to the WHERE clause.
+		// joins of a specified type: the LEFT side will be added to the fromClause and the RIGHT to the joinClause
+		// New Code.
+		foreach ((array) $criteria->getJoins() as $join) { // we'll only loop if there's actually something here
+
+			// The join might have been established using an alias name
+
+			$leftTable = $join->getLeftTableName();
+			$leftTableAlias = '';
+			if ($realTable = $criteria->getTableForAlias($leftTable)) {
+				$leftTableAlias = " $leftTable";
+				$leftTable = $realTable;
+			}
+
+			$rightTable = $join->getRightTableName();
+			$rightTableAlias = '';
+			if ($realTable = $criteria->getTableForAlias($rightTable)) {
+				$rightTableAlias = " $rightTable";
+				$rightTable = $realTable;
+			}
+
+			// determine if casing is relevant.
+			if ($ignoreCase = $criteria->isIgnoreCase()) {
+				$leftColType = $dbMap->getTable($leftTable)->getColumn($join->getLeftColumnName())->getType();
+				$rightColType = $dbMap->getTable($rightTable)->getColumn($join->getRightColumnName())->getType();
+				$ignoreCase = ($leftColType == 'string' || $rightColType == 'string');
+			}
+
+			// build the condition
+			$left = $join->getLeftColumns();
+			$right = $join->getRightColumns();
+			$condition = "";
+			for ($i = 0; $i < count($left); $i++) {
+				if ($ignoreCase) {
+					$condition .= $db->ignoreCase($left[$i]) . '=' . $db->ignoreCase($right[$i]);
+				} else {
+					$condition .= $left[$i] . '=' . $right[$i];
+				}
+				if ($i + 1 < count($left) ) {
+					$condition .= " AND ";
+				}
+			}
+
+			// add 'em to the queues..
+			if ($joinType = $join->getJoinType()) {
+				if (!$fromClause) {
+					$fromClause[] = $leftTable . $leftTableAlias;
+				}
+				$joinTables[] = $rightTable . $rightTableAlias;
+				$joinClause[] = $join->getJoinType() . ' ' . $rightTable . $rightTableAlias . " ON ($condition)";
+			} else {
+				$fromClause[] = $leftTable . $leftTableAlias;
+				$fromClause[] = $rightTable . $rightTableAlias;
+				$whereClause[] = $condition;
+			}
+		}
+
+		// Unique from clause elements
+		$fromClause = array_unique($fromClause);
+
+		// tables should not exist in both the from and join clauses
+		if ($joinTables && $fromClause) {
+			foreach ($fromClause as $fi => $ftable) {
+				if (in_array($ftable, $joinTables)) {
+					unset($fromClause[$fi]);
+				}
+			}
+		}
+
+		// Add the GROUP BY columns
+		$groupByClause = $groupBy;
+
+		$having = $criteria->getHaving();
+		$havingString = null;
+		if ($having !== null) {
+			$sb = "";
+			$having->appendPsTo($sb, $params);
+			$havingString = $sb;
+		}
+
+		if (!empty($orderBy)) {
+
+			foreach ($orderBy as $orderByColumn) {
+
+				// Add function expression as-is.
+
+				if (strpos($orderByColumn, '(') !== false) {
+					$orderByClause[] = $orderByColumn;
+					continue;
+				}
+
+				// Split orderByColumn (i.e. "table.column DESC")
+
+				$dotPos = strrpos($orderByColumn, '.');
+
+				if ($dotPos !== false) {
+					$tableName = substr($orderByColumn, 0, $dotPos);
+					$columnName = substr($orderByColumn, $dotPos+1);
+				}
+				else {
+					$tableName = '';
+					$columnName = $orderByColumn;
+				}
+
+				$spacePos = strpos($columnName, ' ');
+
+				if ($spacePos !== false) {
+					$direction = substr($columnName, $spacePos);
+					$columnName = substr($columnName, 0, $spacePos);
+				}
+				else {
+					$direction = '';
+				}
+
+				$tableAlias = $tableName;
+				if ($aliasTableName = $criteria->getTableForAlias($tableName)) {
+					$tableName = $aliasTableName;
+				}
+
+				$columnAlias = $columnName;
+				if ($asColumnName = $criteria->getColumnForAs($columnName)) {
+					$columnName = $asColumnName;
+				}
+
+				$column = $tableName ? $dbMap->getTable($tableName)->getColumn($columnName) : null;
+
+				if ($criteria->isIgnoreCase() && $column && $column->isText()) {
+					$orderByClause[] = $db->ignoreCaseInOrderBy("$tableAlias.$columnAlias") . $direction;
+					$selectClause[] = $db->ignoreCaseInOrderBy("$tableAlias.$columnAlias");
+				} else {
+					$orderByClause[] = $orderByColumn;
+				}
+			}
+		}
+
+		if (empty($fromClause) && $criteria->getPrimaryTableName()) {
+			$fromClause[] = $criteria->getPrimaryTableName();
+		}
+
+		// from / join tables quoten if it is necessary
+		if ($db->useQuoteIdentifier()) {
+			$fromClause = array_map(array($db, 'quoteIdentifierTable'), $fromClause);
+			$joinClause = $joinClause ? $joinClause : array_map(array($db, 'quoteIdentifierTable'), $joinClause);
+		}
+
+		// build from-clause
+		$from = '';
+		if (!empty($joinClause) && count($fromClause) > 1) {
+			$from .= implode(" CROSS JOIN ", $fromClause);
+		} else {
+			$from .= implode(", ", $fromClause);
+		}
+
+		$from .= $joinClause ? ' ' . implode(' ', $joinClause) : '';
+
+		// Build the SQL from the arrays we compiled
+		$sql =  "SELECT "
+		.($selectModifiers ? implode(" ", $selectModifiers) . " " : "")
+		.implode(", ", $selectClause)
+		." FROM "  . $from
+		.($indexHint ? " USE INDEX (".$indexHint.")" : "")
+		.($whereClause ? " WHERE ".implode(" AND ", $whereClause) : "")
+		.($groupByClause ? " GROUP BY ".implode(",", $groupByClause) : "")
+		.($havingString ? " HAVING ".$havingString : "")
+		.($orderByClause ? " ORDER BY ".implode(",", $orderByClause) : "");
+
+		// APPLY OFFSET & LIMIT to the query.
+		if ($criteria->getLimit() || $criteria->getOffset()) {
+			$db->applyLimit($sql, $criteria->getOffset(), $criteria->getLimit());
+		}
+
+		return $sql;
+
+	}
+
+	/**
+	 * Builds a params array, like the kind populated by Criterion::appendPsTo().
+	 * This is useful for building an array even when it is not using the appendPsTo() method.
+	 * @param      array $columns
+	 * @param      Criteria $values
+	 * @return     array params array('column' => ..., 'table' => ..., 'value' => ...)
+	 */
+	private static function buildParams($columns, Criteria $values) {
+		$params = array();
+		foreach ($columns as $key) {
+			if ($values->containsKey($key)) {
+				$crit = $values->getCriterion($key);
+				$params[] = array('column' => $crit->getColumn(), 'table' => $crit->getTable(), 'value' => $crit->getValue());
+			}
+		}
+		return $params;
+	}
+
+	/**
+	 * This function searches for the given validator $name under propel/validator/$name.php,
+	 * imports and caches it.
+	 *
+	 * @param      string $classname The dot-path name of class (e.g. myapp.propel.MyValidator)
+	 * @return     Validator object or null if not able to instantiate validator class (and error will be logged in this case)
+	 */
+	public static function getValidator($classname)
+	{
+		try {
+			$v = isset(self::$validatorMap[$classname]) ? self::$validatorMap[$classname] : null;
+			if ($v === null) {
+				$cls = Propel::importClass($classname);
+				$v = new $cls();
+				self::$validatorMap[$classname] = $v;
+			}
+			return $v;
+		} catch (Exception $e) {
+			Propel::log("BasePeer::getValidator(): failed trying to instantiate " . $classname . ": ".$e->getMessage(), Propel::LOG_ERR);
+		}
+	}
+
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel/util/Criteria.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel/util/Criteria.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel/util/Criteria.php	(revision 19)
@@ -0,0 +1,1841 @@
+<?php
+/*
+ *  $Id: Criteria.php 1057 2008-06-02 23:27:29Z hans $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://propel.phpdb.org>.
+ */
+
+/**
+ * This is a utility class for holding criteria information for a query.
+ *
+ * BasePeer constructs SQL statements based on the values in this class.
+ *
+ * @author     Hans Lellelid <hans@xmpl.org> (Propel)
+ * @author     Kaspars Jaudzems <kaspars.jaudzems@inbox.lv> (Propel)
+ * @author     Frank Y. Kim <frank.kim@clearink.com> (Torque)
+ * @author     John D. McNally <jmcnally@collab.net> (Torque)
+ * @author     Brett McLaughlin <bmclaugh@algx.net> (Torque)
+ * @author     Eric Dobbs <eric@dobbse.net> (Torque)
+ * @author     Henning P. Schmiedehausen <hps@intermeta.de> (Torque)
+ * @author     Sam Joseph <sam@neurogrid.com> (Torque)
+ * @version    $Revision: 1057 $
+ * @package    propel.util
+ */
+class Criteria implements IteratorAggregate {
+
+	/** Comparison type. */
+	const EQUAL = "=";
+
+	/** Comparison type. */
+	const NOT_EQUAL = "<>";
+
+	/** Comparison type. */
+	const ALT_NOT_EQUAL = "!=";
+
+	/** Comparison type. */
+	const GREATER_THAN = ">";
+
+	/** Comparison type. */
+	const LESS_THAN = "<";
+
+	/** Comparison type. */
+	const GREATER_EQUAL = ">=";
+
+	/** Comparison type. */
+	const LESS_EQUAL = "<=";
+
+	/** Comparison type. */
+	const LIKE = " LIKE ";
+
+	/** Comparison type. */
+	const NOT_LIKE = " NOT LIKE ";
+
+	/** PostgreSQL comparison type */
+	const ILIKE = " ILIKE ";
+
+	/** PostgreSQL comparison type */
+	const NOT_ILIKE = " NOT ILIKE ";
+
+	/** Comparison type. */
+	const CUSTOM = "CUSTOM";
+
+	/** Comparison type for update */
+	const CUSTOM_EQUAL = "CUSTOM_EQUAL";
+
+	/** Comparison type. */
+	const DISTINCT = "DISTINCT ";
+
+	/** Comparison type. */
+	const IN = " IN ";
+
+	/** Comparison type. */
+	const NOT_IN = " NOT IN ";
+
+	/** Comparison type. */
+	const ALL = "ALL ";
+
+	/** Comparison type. */
+	const JOIN = "JOIN";
+
+	/** Binary math operator: AND */
+	const BINARY_AND = "&";
+
+	/** Binary math operator: OR */
+	const BINARY_OR = "|";
+
+	/** "Order by" qualifier - ascending */
+	const ASC = "ASC";
+
+	/** "Order by" qualifier - descending */
+	const DESC = "DESC";
+
+	/** "IS NULL" null comparison */
+	const ISNULL = " IS NULL ";
+
+	/** "IS NOT NULL" null comparison */
+	const ISNOTNULL = " IS NOT NULL ";
+
+	/** "CURRENT_DATE" ANSI SQL function */
+	const CURRENT_DATE = "CURRENT_DATE";
+
+	/** "CURRENT_TIME" ANSI SQL function */
+	const CURRENT_TIME = "CURRENT_TIME";
+
+	/** "CURRENT_TIMESTAMP" ANSI SQL function */
+	const CURRENT_TIMESTAMP = "CURRENT_TIMESTAMP";
+
+	/** "LEFT JOIN" SQL statement */
+	const LEFT_JOIN = "LEFT JOIN";
+
+	/** "RIGHT JOIN" SQL statement */
+	const RIGHT_JOIN = "RIGHT JOIN";
+
+	/** "INNER JOIN" SQL statement */
+	const INNER_JOIN = "INNER JOIN";
+
+	private $ignoreCase = false;
+	private $singleRecord = false;
+	private $selectModifiers = array();
+	private $selectColumns = array();
+	private $orderByColumns = array();
+	private $groupByColumns = array();
+	private $having = null;
+	private $asColumns = array();
+	private $joins = array();
+	private $indexes = array();
+
+	/** The name of the database. */
+	private $dbName;
+
+	/**
+	 * The primary table for this Criteria.
+	 * Useful in cases where there are no select or where
+	 * columns.
+	 * @var        string
+	 */
+	private $primaryTableName;
+
+	/** The name of the database as given in the contructor. */
+	private $originalDbName;
+
+	/**
+	 * To limit the number of rows to return.  <code>0</code> means return all
+	 * rows.
+	 */
+	private $limit = 0;
+
+	/** To start the results at a row other than the first one. */
+	private $offset = 0;
+
+	// flag to note that the criteria involves a blob.
+	private $blobFlag = null;
+
+	private $aliases = array();
+
+	private $useTransaction = false;
+
+	/**
+	 * Primary storage of criteria data.
+	 * @var        array
+	 */
+	private $map = array();
+
+	/**
+	 * Creates a new instance with the default capacity which corresponds to
+	 * the specified database.
+	 *
+	 * @param      dbName The dabase name.
+	 */
+	public function __construct($dbName = null)
+	{
+		$this->setDbName($dbName);
+		$this->originalDbName = $dbName;
+	}
+
+	/**
+	 * Implementing SPL IteratorAggregate interface.  This allows
+	 * you to foreach () over a Criteria object.
+	 */
+	public function getIterator()
+	{
+		return new CriterionIterator($this);
+	}
+
+	/**
+	 * Get the criteria map.
+	 * @return     array
+	 */
+	public function getMap()
+	{
+		return $this->map;
+	}
+
+	/**
+	 * Brings this criteria back to its initial state, so that it
+	 * can be reused as if it was new. Except if the criteria has grown in
+	 * capacity, it is left at the current capacity.
+	 * @return     void
+	 */
+	public function clear()
+	{
+		$this->map = array();
+		$this->ignoreCase = false;
+		$this->singleRecord = false;
+		$this->selectModifiers = array();
+		$this->selectColumns = array();
+		$this->orderByColumns = array();
+		$this->groupByColumns = array();
+		$this->having = null;
+		$this->asColumns = array();
+		$this->joins = array();
+		$this->indexes = array();
+		$this->dbName = $this->originalDbName;
+		$this->offset = 0;
+		$this->limit = -1;
+		$this->blobFlag = null;
+		$this->aliases = array();
+		$this->useTransaction = false;
+	}
+
+	/**
+	 * Add an AS clause to the select columns. Usage:
+	 *
+	 * <code>
+	 * Criteria myCrit = new Criteria();
+	 * myCrit->addAsColumn("alias", "ALIAS(".MyPeer::ID.")");
+	 * </code>
+	 *
+	 * @param      string $name Wanted Name of the column (alias).
+	 * @param      string $clause SQL clause to select from the table
+	 *
+	 * If the name already exists, it is replaced by the new clause.
+	 *
+	 * @return     Criteria A modified Criteria object.
+	 */
+	public function addAsColumn($name, $clause)
+	{
+		$this->asColumns[$name] = $clause;
+		return $this;
+	}
+
+	/**
+	 * Get the column aliases.
+	 *
+	 * @return     array An assoc array which map the column alias names
+	 * to the alias clauses.
+	 */
+	public function getAsColumns()
+	{
+		return $this->asColumns;
+	}
+
+		/**
+	 * Returns the column name associated with an alias (AS-column).
+	 *
+	 * @param      string $alias
+	 * @return     string $string
+	 */
+	public function getColumnForAs($as)
+	{
+		if (isset($this->asColumns[$as])) {
+			return $this->asColumns[$as];
+		}
+	}
+
+	/**
+	 * Allows one to specify an alias for a table that can
+	 * be used in various parts of the SQL.
+	 *
+	 * @param      string $alias
+	 * @param      string $table
+	 * @return     void
+	 */
+	public function addAlias($alias, $table)
+	{
+		$this->aliases[$alias] = $table;
+	}
+
+	/**
+	 * Returns the table name associated with an alias.
+	 *
+	 * @param      string $alias
+	 * @return     string $string
+	 */
+	public function getTableForAlias($alias)
+	{
+		if (isset($this->aliases[$alias])) {
+			return $this->aliases[$alias];
+		}
+	}
+
+	/**
+	 * Get the keys for the criteria map.
+	 * @return     array
+	 */
+	public function keys()
+	{
+		return array_keys($this->map);
+	}
+
+	/**
+	 * Does this Criteria object contain the specified key?
+	 *
+	 * @param      string $column [table.]column
+	 * @return     boolean True if this Criteria object contain the specified key.
+	 */
+	public function containsKey($column)
+	{
+		// must use array_key_exists() because the key could
+		// exist but have a NULL value (that'd be valid).
+		return array_key_exists($column, $this->map);
+	}
+
+	/**
+	 * Does this Criteria object contain the specified key and does it have a value set for the key 
+	 *
+	 * @param      string $column [table.]column
+	 * @return     boolean True if this Criteria object contain the specified key and a value for that key
+	 */
+	public function keyContainsValue($column)
+	{
+		// must use array_key_exists() because the key could
+		// exist but have a NULL value (that'd be valid).
+		return (array_key_exists($column, $this->map) && ($this->map[$column]->getValue() !== null) );
+	}
+
+	/**
+	 * Will force the sql represented by this criteria to be executed within
+	 * a transaction.  This is here primarily to support the oid type in
+	 * postgresql.  Though it can be used to require any single sql statement
+	 * to use a transaction.
+	 * @return     void
+	 */
+	public function setUseTransaction($v)
+	{
+		$this->useTransaction = (boolean) $v;
+	}
+
+	/**
+	 * Whether the sql command specified by this criteria must be wrapped
+	 * in a transaction.
+	 *
+	 * @return     boolean
+	 */
+	public function isUseTransaction()
+	{
+		return $this->useTransaction;
+	}
+
+	/**
+	 * Method to return criteria related to columns in a table.
+	 *
+	 * @param      string $column Column name.
+	 * @return     Criterion A Criterion or null if $column is invalid.
+	 */
+	public function getCriterion($column)
+	{
+		if ( isset ( $this->map[$column] ) ) {
+			return $this->map[$column];
+		}
+		return null;
+	}
+
+	/**
+	 * Method to return criterion that is not added automatically
+	 * to this Criteria.  This can be used to chain the
+	 * Criterions to form a more complex where clause.
+	 *
+	 * @param      string $column Full name of column (for example TABLE.COLUMN).
+	 * @param      mixed $value
+	 * @param      string $comparison
+	 * @return     Criterion
+	 */
+	public function getNewCriterion($column, $value, $comparison = null)
+	{
+		return new Criterion($this, $column, $value, $comparison);
+	}
+
+	/**
+	 * Method to return a String table name.
+	 *
+	 * @param      string $name Name of the key.
+	 * @return     string The value of the object at key.
+	 */
+	public function getColumnName($name)
+	{
+		if (isset($this->map[$name])) {
+			return $this->map[$name]->getColumn();
+		}
+		return null;
+	}
+
+	/**
+	 * Shortcut method to get an array of columns indexed by table.
+	 * @return     array array(table => array(table.column1, table.column2))
+	 */
+	public function getTablesColumns()
+	{
+		$tables = array();
+		foreach ( array_keys ( $this->map ) as $key) {
+			$t = substr ( $key, 0, strrpos ( $key, '.' ) );
+			if ( ! isset ( $tables[$t] ) ) {
+				$tables[$t] = array( $key );
+			} else {
+				$tables[$t][] = $key;
+			}
+		}
+		return $tables;
+	}
+
+	/**
+	 * Method to return a comparison String.
+	 *
+	 * @param      string $key String name of the key.
+	 * @return     string A String with the value of the object at key.
+	 */
+	public function getComparison($key)
+	{
+		if ( isset ( $this->map[$key] ) ) {
+			return $this->map[$key]->getComparison();
+		}
+		return null;
+	}
+
+	/**
+	 * Get the Database(Map) name.
+	 *
+	 * @return     string A String with the Database(Map) name.
+	 */
+	public function getDbName()
+	{
+		return $this->dbName;
+	}
+
+	/**
+	 * Set the DatabaseMap name.  If <code>null</code> is supplied, uses value
+	 * provided by <code>Propel::getDefaultDB()</code>.
+	 *
+	 * @param      string $dbName The Database (Map) name.
+	 * @return     void
+	 */
+	public function setDbName($dbName = null)
+	{
+		$this->dbName = ($dbName === null ? Propel::getDefaultDB() : $dbName);
+	}
+
+	/**
+	 * Get the primary table for this Criteria.
+	 *
+	 * This is useful for cases where a Criteria may not contain
+	 * any SELECT columns or WHERE columns.  This must be explicitly
+	 * set, of course, in order to be useful.
+	 *
+	 * @return     string
+	 */
+	public function getPrimaryTableName()
+	{
+		return $this->primaryTableName;
+	}
+
+	/**
+	 * Sets the primary table for this Criteria.
+	 *
+	 * This is useful for cases where a Criteria may not contain
+	 * any SELECT columns or WHERE columns.  This must be explicitly
+	 * set, of course, in order to be useful.
+	 *
+	 * @param      string $v
+	 */
+	public function setPrimaryTableName($tableName)
+	{
+		$this->primaryTableName = $tableName;
+	}
+
+	/**
+	 * Method to return a String table name.
+	 *
+	 * @param      string $name The name of the key.
+	 * @return     string The value of table for criterion at key.
+	 */
+	public function getTableName($name)
+	{
+		if (isset($this->map[$name])) {
+			return $this->map[$name]->getTable();
+		}
+		return null;
+	}
+
+	/**
+	 * Method to return the value that was added to Criteria.
+	 *
+	 * @param      string $name A String with the name of the key.
+	 * @return     mixed The value of object at key.
+	 */
+	public function getValue($name)
+	{
+		if (isset($this->map[$name])) {
+			return $this->map[$name]->getValue();
+		}
+		return null;
+	}
+
+	/**
+	 * An alias to getValue() -- exposing a Hashtable-like interface.
+	 *
+	 * @param      string $key An Object.
+	 * @return     mixed The value within the Criterion (not the Criterion object).
+	 */
+	public function get($key)
+	{
+		return $this->getValue($key);
+	}
+
+	/**
+	 * Overrides Hashtable put, so that this object is returned
+	 * instead of the value previously in the Criteria object.
+	 * The reason is so that it more closely matches the behavior
+	 * of the add() methods. If you want to get the previous value
+	 * then you should first Criteria.get() it yourself. Note, if
+	 * you attempt to pass in an Object that is not a String, it will
+	 * throw a NPE. The reason for this is that none of the add()
+	 * methods support adding anything other than a String as a key.
+	 *
+	 * @param      string $key
+	 * @param      mixed $value
+	 * @return     Instance of self.
+	 */
+	public function put($key, $value)
+	{
+		return $this->add($key, $value);
+	}
+
+	/**
+	 * Copies all of the mappings from the specified Map to this Criteria
+	 * These mappings will replace any mappings that this Criteria had for any
+	 * of the keys currently in the specified Map.
+	 *
+	 * if the map was another Criteria, its attributes are copied to this
+	 * Criteria, overwriting previous settings.
+	 *
+	 * @param      mixed $t Mappings to be stored in this map.
+	 */
+	public function putAll($t)
+	{
+
+		if (is_array($t)) {
+
+			foreach ($t as $key=>$value) {
+
+				if ($value instanceof Criterion) {
+
+					$this->map[$key] = $value;
+
+				} else {
+
+					$this->put($key, $value);
+
+				}
+
+			}
+
+		} elseif ($t instanceof Criteria) {
+
+			$this->joins = $t->joins;
+
+		}
+
+	}
+
+
+	/**
+	 * This method adds a new criterion to the list of criterias.
+	 * If a criterion for the requested column already exists, it is
+	 * replaced. If is used as follow:
+	 *
+	 * <p>
+	 * <code>
+	 * $crit = new Criteria();
+	 * $crit->add(&quot;column&quot;,
+	 *                                      &quot;value&quot;
+	 *                                      &quot;Criteria::GREATER_THAN&quot;);
+	 * </code>
+	 *
+	 * Any comparison can be used.
+	 *
+	 * The name of the table must be used implicitly in the column name,
+	 * so the Column name must be something like 'TABLE.id'. If you
+	 * don't like this, you can use the add(table, column, value) method.
+	 *
+	 * @param      string $critOrColumn The column to run the comparison on, or Criterion object.
+	 * @param      mixed $value
+	 * @param      string $comparison A String.
+	 *
+	 * @return     A modified Criteria object.
+	 */
+	public function add($p1, $value = null, $comparison = null)
+	{
+		if ($p1 instanceof Criterion) {
+			$this->map[$p1->getTable() . '.' . $p1->getColumn()] = $p1;
+		} else {
+			$this->map[$p1] = new Criterion($this, $p1, $value, $comparison);
+		}
+		return $this;
+	}
+
+	/**
+	 * This is the way that you should add a straight (inner) join of two tables.  For
+	 * example:
+	 *
+	 * <p>
+	 * AND PROJECT.PROJECT_ID=FOO.PROJECT_ID
+	 * <p>
+	 *
+	 * left = PROJECT.PROJECT_ID
+	 * right = FOO.PROJECT_ID
+	 *
+	 * @param      string $left A String with the left side of the join.
+	 * @param      string $right A String with the right side of the join.
+		 * @param      string $operator A String with the join operator e.g. LEFT JOIN, ...
+	 * @return     Criteria A modified Criteria object.
+	 */
+	public function addJoin($left, $right, $operator = null)
+	{
+		$j = new Join($left, $right, $operator);
+		if (!in_array($j, $this->joins)) { // compare equality, NOT identity
+			$this->joins[] = $j;
+		}
+		return $this;
+	}
+
+	/**
+	 * Get the array of Joins.
+	 * @return     array Join[]
+	 */
+	public function getJoins()
+	{
+		return $this->joins;
+	}
+
+	/**
+	 * Add index for Index Hint of SQL statement
+	 * @return     A modified Criteria object.
+	 */
+	public function addIndex($indexName)
+	{
+		if (!in_array($indexName, $this->indexes)) {
+			$this->indexes[] = $indexName;
+		}
+		return $this;
+	}
+
+	/**
+	 * Get the array of Indexes.
+	 * @return     array Indexes[]
+	 */
+	public function getIndexes()
+	{
+		return $this->indexes;
+	}
+
+	/**
+	 * Adds "ALL" modifier to the SQL statement.
+	 * @return     Criteria Modified Criteria object (for fluent API)
+	 */
+	public function setAll()
+	{
+		$this->selectModifiers[] = self::ALL;
+		return $this;
+	}
+
+	/**
+	 * Adds "DISTINCT" modifier to the SQL statement.
+	 * @return     Criteria Modified Criteria object (for fluent API)
+	 */
+	public function setDistinct()
+	{
+		$this->selectModifiers[] = self::DISTINCT;
+		return $this;
+	}
+
+	/**
+	 * Sets ignore case.
+	 *
+	 * @param      boolean $b True if case should be ignored.
+	 * @return     Criteria Modified Criteria object (for fluent API)
+	 */
+	public function setIgnoreCase($b)
+	{
+		$this->ignoreCase = (boolean) $b;
+		return $this;
+	}
+
+	/**
+	 * Is ignore case on or off?
+	 *
+	 * @return     boolean True if case is ignored.
+	 */
+	public function isIgnoreCase()
+	{
+		return $this->ignoreCase;
+	}
+
+	/**
+	 * Set single record?  Set this to <code>true</code> if you expect the query
+	 * to result in only a single result record (the default behaviour is to
+	 * throw a PropelException if multiple records are returned when the query
+	 * is executed).  This should be used in situations where returning multiple
+	 * rows would indicate an error of some sort.  If your query might return
+	 * multiple records but you are only interested in the first one then you
+	 * should be using setLimit(1).
+	 *
+	 * @param      boolean $b Set to TRUE if you expect the query to select just one record.
+	 * @return     Criteria Modified Criteria object (for fluent API)
+	 */
+	public function setSingleRecord($b)
+	{
+		$this->singleRecord = (boolean) $b;
+		return $this;
+	}
+
+	/**
+	 * Is single record?
+	 *
+	 * @return     boolean True if a single record is being returned.
+	 */
+	public function isSingleRecord()
+	{
+		return $this->singleRecord;
+	}
+
+	/**
+	 * Set limit.
+	 *
+	 * @param      limit An int with the value for limit.
+	 * @return     Criteria Modified Criteria object (for fluent API)
+	 */
+	public function setLimit($limit)
+	{
+		// TODO: do we enforce int here? 32bit issue if we do
+		$this->limit = $limit;
+		return $this;
+	}
+
+	/**
+	 * Get limit.
+	 *
+	 * @return     int An int with the value for limit.
+	 */
+	public function getLimit()
+	{
+		return $this->limit;
+	}
+
+	/**
+	 * Set offset.
+	 *
+	 * @param      int $offset An int with the value for offset.  (Note this values is
+	 * 							cast to a 32bit integer and may result in truncatation)
+	 * @return     Criteria Modified Criteria object (for fluent API)
+	 */
+	public function setOffset($offset)
+	{
+		$this->offset = (int) $offset;
+		return $this;
+	}
+
+	/**
+	 * Get offset.
+	 *
+	 * @return     An int with the value for offset.
+	 */
+	public function getOffset()
+	{
+		return $this->offset;
+	}
+
+	/**
+	 * Add select column.
+	 *
+	 * @param      string $name Name of the select column.
+	 * @return     Criteria Modified Criteria object (for fluent API)
+	 */
+	public function addSelectColumn($name)
+	{
+		$this->selectColumns[] = $name;
+		return $this;
+	}
+	
+	/**
+	 * Whether this Criteria has any select columns.
+	 * 
+	 * This will include columns added with addAsColumn() method.
+	 *
+	 * @return     boolean
+	 * @see        addAsColumn()
+	 * @see        addSelectColumn()
+	 */
+	public function hasSelectClause()
+	{
+		return (!empty($this->selectColumns) || !empty($this->asColumns));
+	}
+	
+	/**
+	 * Get select columns.
+	 *
+	 * @return     array An array with the name of the select
+	 * columns.
+	 */
+	public function getSelectColumns()
+	{
+		return $this->selectColumns;
+	}
+
+	/**
+	 * Clears current select columns.
+	 *
+	 * @return     Criteria Modified Criteria object (for fluent API)
+	 */
+	public function clearSelectColumns() {
+		$this->selectColumns = $this->asColumns = array();
+		return $this;
+	}
+
+	/**
+	 * Get select modifiers.
+	 *
+	 * @return     An array with the select modifiers.
+	 */
+	public function getSelectModifiers()
+	{
+		return $this->selectModifiers;
+	}
+
+	/**
+	 * Add group by column name.
+	 *
+	 * @param      string $groupBy The name of the column to group by.
+	 * @return     A modified Criteria object.
+	 */
+	public function addGroupByColumn($groupBy)
+	{
+		$this->groupByColumns[] = $groupBy;
+		return $this;
+	}
+
+	/**
+	 * Add order by column name, explicitly specifying ascending.
+	 *
+	 * @param      name The name of the column to order by.
+	 * @return     A modified Criteria object.
+	 */
+	public function addAscendingOrderByColumn($name)
+	{
+		$this->orderByColumns[] = $name . ' ' . self::ASC;
+		return $this;
+	}
+
+	/**
+	 * Add order by column name, explicitly specifying descending.
+	 *
+	 * @param      string $name The name of the column to order by.
+	 * @return     Criteria Modified Criteria object (for fluent API)
+	 */
+	public function addDescendingOrderByColumn($name)
+	{
+		$this->orderByColumns[] = $name . ' ' . self::DESC;
+		return $this;
+	}
+
+	/**
+	 * Get order by columns.
+	 *
+	 * @return     array An array with the name of the order columns.
+	 */
+	public function getOrderByColumns()
+	{
+		return $this->orderByColumns;
+	}
+
+	/**
+	 * Clear the order-by columns.
+	 *
+	 * @return     Criteria Modified Criteria object (for fluent API)
+	 */
+	public function clearOrderByColumns()
+	{
+		$this->orderByColumns = array();
+		return $this;
+	}
+
+	/**
+	 * Clear the group-by columns.
+	 *
+	 * @return     Criteria
+	 */
+	public function clearGroupByColumns()
+	{
+		$this->groupByColumns = array();
+		return $this;
+	}
+
+	/**
+	 * Get group by columns.
+	 *
+	 * @return     array
+	 */
+	public function getGroupByColumns()
+	{
+		return $this->groupByColumns;
+	}
+
+	/**
+	 * Get Having Criterion.
+	 *
+	 * @return     Criterion A Criterion object that is the having clause.
+	 */
+	public function getHaving()
+	{
+		return $this->having;
+	}
+
+	/**
+	 * Remove an object from the criteria.
+	 *
+	 * @param      string $key A string with the key to be removed.
+	 * @return     mixed The removed value.
+	 */
+	public function remove($key)
+	{
+		if ( isset ( $this->map[$key] ) ) {
+			$removed = $this->map[$key];
+			unset ( $this->map[$key] );
+			if ( $removed instanceof Criterion ) {
+				return $removed->getValue();
+			}
+			return $removed;
+		}
+	}
+
+	/**
+	 * Build a string representation of the Criteria.
+	 *
+	 * @return     string A String with the representation of the Criteria.
+	 */
+	public function toString()
+	{
+
+		$sb = "Criteria:";
+		try {
+
+			$params = array();
+			$sb .= "\nSQL (may not be complete): "
+			  . BasePeer::createSelectSql($this, $params);
+
+			$sb .= "\nParams: ";
+			$paramstr = array();
+			foreach ($params as $param) {
+				$paramstr[] = $param['table'] . '.' . $param['column'] . ' => ' . var_export($param['value'], true);
+			}
+			$sb .= implode(", ", $paramstr);
+
+		} catch (Exception $exc) {
+			$sb .= "(Error: " . $exc->getMessage() . ")";
+		}
+
+		return $sb;
+	}
+
+	/**
+	 * Returns the size (count) of this criteria.
+	 * @return     int
+	 */
+	public function size()
+	{
+		return count($this->map);
+	}
+
+	/**
+	 * This method checks another Criteria to see if they contain
+	 * the same attributes and hashtable entries.
+	 * @return     boolean
+	 */
+	public function equals($crit)
+	{
+		$isEquiv = false;
+		if ($crit === null || !($crit instanceof Criteria)) {
+			$isEquiv = false;
+		} elseif ($this === $crit) {
+			$isEquiv = true;
+		} elseif ($this->size() === $crit->size()) {
+
+			// Important: nested criterion objects are checked
+
+			$criteria = $crit; // alias
+			if ($this->offset === $criteria->getOffset()
+				&& $this->limit === $criteria->getLimit()
+				&& $this->ignoreCase === $criteria->isIgnoreCase()
+				&& $this->singleRecord === $criteria->isSingleRecord()
+				&& $this->dbName === $criteria->getDbName()
+				&& $this->selectModifiers === $criteria->getSelectModifiers()
+				&& $this->selectColumns === $criteria->getSelectColumns()
+				&& $this->orderByColumns === $criteria->getOrderByColumns()
+			   )
+			{
+				$isEquiv = true;
+				foreach ($criteria->keys() as $key) {
+					if ($this->containsKey($key)) {
+						$a = $this->getCriterion($key);
+						$b = $criteria->getCriterion($key);
+						if (!$a->equals($b)) {
+							$isEquiv = false;
+							break;
+						}
+					} else {
+						$isEquiv = false;
+						break;
+					}
+				}
+			}
+		}
+		return $isEquiv;
+	}
+
+	/**
+	 * This method adds a prepared Criterion object to the Criteria as a having clause.
+	 * You can get a new, empty Criterion object with the
+	 * getNewCriterion() method.
+	 *
+	 * <p>
+	 * <code>
+	 * $crit = new Criteria();
+	 * $c = $crit->getNewCriterion(BasePeer::ID, 5, Criteria::LESS_THAN);
+	 * $crit->addHaving($c);
+	 * </code>
+	 *
+	 * @param      having A Criterion object
+	 *
+	 * @return     A modified Criteria object.
+	 */
+	public function addHaving(Criterion $having)
+	{
+		$this->having = $having;
+		return $this;
+	}
+
+	/**
+	 * This method adds a new criterion to the list of criterias.
+	 * If a criterion for the requested column already exists, it is
+	 * "AND"ed to the existing criterion.
+	  *
+	 * addAnd(column, value, comparison)
+	 * <code>
+	 * $crit = $orig_crit->addAnd(&quot;column&quot;,
+	 *                                      &quot;value&quot;
+	 *                                      &quot;Criterion::GREATER_THAN&quot;);
+	 * </code>
+	 *
+	 * addAnd(column, value)
+	 * <code>
+	 * $crit = $orig_crit->addAnd(&quot;column&quot;, &quot;value&quot;);
+	 * </code>
+	 *
+	 * addAnd(Criterion)
+	 * <code>
+	 * $crit = new Criteria();
+	 * $c = $crit->getNewCriterion(BasePeer::ID, 5, Criteria::LESS_THAN);
+	 * $crit->addAnd($c);
+	 * </code>
+	 *
+	 * Any comparison can be used, of course.
+	 *
+	 *
+	 * @return     Criteria A modified Criteria object.
+	 */
+	public function addAnd($p1, $p2 = null, $p3 = null)
+	{
+		if ($p3 !== null) {
+			// addAnd(column, value, comparison)
+			$oc = $this->getCriterion($p1);
+			$nc = new Criterion($this, $p1, $p2, $p3);
+			if ( $oc === null) {
+				$this->map[$p1] = $nc;
+			} else {
+				$oc->addAnd($nc);
+			}
+		} elseif ($p2 !== null) {
+			// addAnd(column, value)
+			$this->addAnd($p1, $p2, self::EQUAL);
+		} elseif ($p1 instanceof Criterion) {
+			// addAnd(Criterion)
+			$oc = $this->getCriterion($p1->getTable() . '.' . $p1->getColumn());
+			if ($oc === null) {
+				$this->add($p1);
+			} else {
+				$oc->addAnd($p1);
+			}
+		} elseif ($p2 === null && $p3 === null) {
+			// client has not specified $p3 (comparison)
+			// which means Criteria::EQUAL but has also specified $p2 == null
+			// which is a valid combination we should handle by creating "IS NULL"
+			$this->addAnd($p1, $p2, self::EQUAL);
+		}
+		return $this;
+	}
+
+	/**
+	 * This method adds a new criterion to the list of criterias.
+	 * If a criterion for the requested column already exists, it is
+	 * "OR"ed to the existing criterion.
+	 *
+	 * Any comparison can be used.
+	 *
+	 * Supports a number of different signatures:
+	 *
+	 * addOr(column, value, comparison)
+	 * <code>
+	 * $crit = $orig_crit->addOr(&quot;column&quot;,
+	 *                                      &quot;value&quot;
+	 *                                      &quot;Criterion::GREATER_THAN&quot;);
+	 * </code>
+	 *
+	 * addOr(column, value)
+	 * <code>
+	 * $crit = $orig_crit->addOr(&quot;column&quot;, &quot;value&quot;);
+	 * </code>
+	 *
+	 * addOr(Criterion)
+	 *
+	 * @return     Criteria A modified Criteria object.
+	 */
+	public function addOr($p1, $p2 = null, $p3 = null)
+	{
+		if ($p3 !== null) {
+			// addOr(column, value, comparison)
+			$nc = new Criterion($this, $p1, $p2, $p3);
+			$oc = $this->getCriterion($p1);
+			if ($oc === null) {
+				$this->map[$p1] = $nc;
+			} else {
+				$oc->addOr($nc);
+			}
+		} elseif ($p2 !== null) {
+			// addOr(column, value)
+			$this->addOr($p1, $p2, self::EQUAL);
+		} elseif ($p1 instanceof Criterion) {
+			// addOr(Criterion)
+			$oc = $this->getCriterion($p1->getTable() . '.' . $p1->getColumn());
+			if ($oc === null) {
+				$this->add($p1);
+			} else {
+				$oc->addOr($p1);
+			}
+		} elseif ($p2 === null && $p3 === null) {
+			// client has not specified $p3 (comparison)
+			// which means Criteria::EQUAL but has also specified $p2 == null
+			// which is a valid combination we should handle by creating "IS NULL"
+			$this->addOr($p1, $p2, self::EQUAL);
+		}
+
+		return $this;
+	}
+}
+
+// --------------------------------------------------------------------
+// Criterion Iterator class -- allows foreach ($criteria as $criterion)
+// --------------------------------------------------------------------
+
+/**
+ * Class that implements SPL Iterator interface.  This allows foreach () to
+ * be used w/ Criteria objects.  Probably there is no performance advantage
+ * to doing it this way, but it makes sense -- and simpler code.
+ *
+ * @author     Hans Lellelid <hans@xmpl.org>
+ * @package    propel.util
+ */
+class CriterionIterator implements Iterator {
+
+	private $idx = 0;
+	private $criteria;
+	private $criteriaKeys;
+	private $criteriaSize;
+
+	public function __construct(Criteria $criteria) {
+		$this->criteria = $criteria;
+		$this->criteriaKeys = $criteria->keys();
+		$this->criteriaSize = count($this->criteriaKeys);
+	}
+
+	public function rewind() {
+		$this->idx = 0;
+	}
+
+	public function valid() {
+		return $this->idx < $this->criteriaSize;
+	}
+
+	public function key() {
+		return $this->criteriaKeys[$this->idx];
+	}
+
+	public function current() {
+		return $this->criteria->getCriterion($this->criteriaKeys[$this->idx]);
+	}
+
+	public function next() {
+		$this->idx++;
+	}
+
+}
+
+// --------------------------------------------------------------------
+// Criterion "inner" class
+// --------------------------------------------------------------------
+
+/**
+ * This is an "inner" class that describes an object in the criteria.
+ *
+ * In Torque this is an inner class of the Criteria class.
+ *
+ * @author     Hans Lellelid <hans@xmpl.org> (Propel)
+ * @package    propel.util
+ */
+class Criterion  {
+
+	const UND = " AND ";
+	const ODER = " OR ";
+
+	/** Value of the CO. */
+	private $value;
+
+	/** Comparison value.
+	 * @var        SqlEnum
+	 */
+	private $comparison;
+
+	/** Table name. */
+	private $table;
+
+	/** Real table name */
+	private $realtable;
+
+	/** Column name. */
+	private $column;
+
+	/** flag to ignore case in comparision */
+	private $ignoreStringCase = false;
+
+	/**
+	 * The DBAdaptor which might be used to get db specific
+	 * variations of sql.
+	 */
+	private $db;
+
+	/**
+	 * other connected criteria and their conjunctions.
+	 */
+	private $clauses = array();
+	private $conjunctions = array();
+
+	/** "Parent" Criteria class */
+	private $parent;
+
+	/**
+	 * Create a new instance.
+	 *
+	 * @param      Criteria $parent The outer class (this is an "inner" class).
+	 * @param      string $column TABLE.COLUMN format.
+	 * @param      mixed $value
+	 * @param      string $comparison
+	 */
+	public function __construct(Criteria $outer, $column, $value, $comparison = null)
+	{
+		$this->value = $value;
+		$dotPos = strrpos($column,'.');
+		if ($dotPos === false) {
+			// no dot => aliased column
+			$this->table = null;
+			$this->column = $column;
+		} else {
+			$this->table = substr($column, 0, $dotPos); 
+			$this->column = substr($column, $dotPos+1, strlen($column));
+		}
+		$this->comparison = ($comparison === null ? Criteria::EQUAL : $comparison);
+		$this->init($outer);
+	}
+
+	/**
+	* Init some properties with the help of outer class
+	* @param      Criteria $criteria The outer class
+	*/
+	public function init(Criteria $criteria)
+	{
+		//init $this->db
+		try {
+			$db = Propel::getDB($criteria->getDbName());
+			$this->setDB($db);
+		} catch (Exception $e) {
+			// we are only doing this to allow easier debugging, so
+			// no need to throw up the exception, just make note of it.
+			Propel::log("Could not get a DBAdapter, sql may be wrong", Propel::LOG_ERR);
+		}
+
+		//init $this->realtable
+		$realtable = $criteria->getTableForAlias($this->table);
+		if (! strlen ( $realtable ) ) {
+			$realtable = $this->table;
+		}
+		$this->realtable = $realtable;
+
+	}
+
+	/**
+	 * Get the column name.
+	 *
+	 * @return     string A String with the column name.
+	 */
+	public function getColumn()
+	{
+		return $this->column;
+	}
+
+	/**
+	 * Set the table name.
+	 *
+	 * @param      name A String with the table name.
+	 * @return     void
+	 */
+	public function setTable($name)
+	{
+		$this->table = $name;
+	}
+
+	/**
+	 * Get the table name.
+	 *
+	 * @return     string A String with the table name.
+	 */
+	public function getTable()
+	{
+		return $this->table;
+	}
+
+	/**
+	 * Get the comparison.
+	 *
+	 * @return     string A String with the comparison.
+	 */
+	public function getComparison()
+	{
+		return $this->comparison;
+	}
+
+	/**
+	 * Get the value.
+	 *
+	 * @return     mixed An Object with the value.
+	 */
+	public function getValue()
+	{
+		return $this->value;
+	}
+
+	/**
+	 * Get the value of db.
+	 * The DBAdapter which might be used to get db specific
+	 * variations of sql.
+	 * @return     DBAdapter value of db.
+	 */
+	public function getDB()
+	{
+		return $this->db;
+	}
+
+	/**
+	 * Set the value of db.
+	 * The DBAdapter might be used to get db specific variations of sql.
+	 * @param      DBAdapter $v Value to assign to db.
+	 * @return     void
+	 */
+	public function setDB(DBAdapter $v)
+	{
+		$this->db = $v;
+		foreach ( $this->clauses as $clause ) {
+			$clause->setDB($v);
+		}
+	}
+
+	/**
+	 * Sets ignore case.
+	 *
+	 * @param      boolean $b True if case should be ignored.
+	 * @return     Criterion A modified Criterion object.
+	 */
+	public function setIgnoreCase($b)
+	{
+		$this->ignoreStringCase = (boolean) $b;
+		return $this;
+	}
+
+	/**
+	 * Is ignore case on or off?
+	 *
+	 * @return     boolean True if case is ignored.
+	 */
+	 public function isIgnoreCase()
+	 {
+		 return $this->ignoreStringCase;
+	 }
+
+	/**
+	 * Get the list of clauses in this Criterion.
+	 * @return     array
+	 */
+	private function getClauses()
+	{
+		return $this->clauses;
+	}
+
+	/**
+	 * Get the list of conjunctions in this Criterion
+	 * @return     array
+	 */
+	public function getConjunctions()
+	{
+		return $this->conjunctions;
+	}
+
+	/**
+	 * Append an AND Criterion onto this Criterion's list.
+	 */
+	public function addAnd(Criterion $criterion)
+	{
+		$this->clauses[] = $criterion;
+		$this->conjunctions[] = self::UND;
+		return $this;
+	}
+
+	/**
+	 * Append an OR Criterion onto this Criterion's list.
+	 * @return     Criterion
+	 */
+	public function addOr(Criterion $criterion)
+	{
+		$this->clauses[] = $criterion;
+		$this->conjunctions[] = self::ODER;
+		return $this;
+	}
+
+	/**
+	 * Appends a Prepared Statement representation of the Criterion
+	 * onto the buffer.
+	 *
+	 * @param      string &$sb The string that will receive the Prepared Statement
+	 * @param      array $params A list to which Prepared Statement parameters
+	 * will be appended
+	 * @return     void
+	 * @throws     PropelException - if the expression builder cannot figure out how to turn a specified
+	 *                           expression into proper SQL.
+	 */
+	public function appendPsTo(&$sb, array &$params)
+	{
+		if ($this->column === null) {
+			return;
+		}
+
+		$db = $this->getDb();
+		$sb .= str_repeat ( '(', count($this->clauses) );
+
+		if (Criteria::CUSTOM === $this->comparison) {
+			if ($this->value !== "") {
+				$sb .= (string) $this->value;
+			}
+		} else {
+
+			if  ($this->table === null) {
+				$field = $this->column;
+			} else {
+				$field = $this->table . '.' . $this->column;
+			}
+
+			// Check to see if table is an alias & store real name, if so
+			// (real table name is needed for the returned $params array)
+			$realtable = $this->realtable;
+
+			// There are several different types of expressions that need individual handling:
+			// IN/NOT IN, LIKE/NOT LIKE, and traditional expressions.
+
+			// OPTION 1:  table.column IN (?, ?) or table.column NOT IN (?, ?)
+			if ($this->comparison === Criteria::IN || $this->comparison === Criteria::NOT_IN) {
+				
+				$_bindParams = array(); // the param names used in query building
+				$_idxstart = count($params);
+				$valuesLength = 0;
+				foreach ( (array) $this->value as $value ) {
+					$valuesLength++; // increment this first to correct for wanting bind params to start with :p1
+					$params[] = array('table' => $realtable, 'column' => $this->column, 'value' => $value);
+					$_bindParams[] = ':p'.($_idxstart + $valuesLength);
+				}
+				if ( $valuesLength !== 0 ) {
+					$sb .= $field . $this->comparison . '(' . implode(',', $_bindParams) . ')';
+				} else {
+					$sb .= ($this->comparison === Criteria::IN) ? "1<>1" : "1=1";
+				}
+				unset ( $value, $valuesLength );
+
+			// OPTION 2:  table.column LIKE ? or table.column NOT LIKE ?  (or ILIKE for Postgres)
+			} elseif ($this->comparison === Criteria::LIKE || $this->comparison === Criteria::NOT_LIKE
+				|| $this->comparison === Criteria::ILIKE || $this->comparison === Criteria::NOT_ILIKE) {
+				// Handle LIKE, NOT LIKE (and related ILIKE, NOT ILIKE for Postgres)
+
+				// If selection is case insensitive use ILIKE for PostgreSQL or SQL
+				// UPPER() function on column name for other databases.
+				if ($this->ignoreStringCase) {
+					if ($db instanceof DBPostgres) {
+						if ($this->comparison === Criteria::LIKE) {
+							$this->comparison = Criteria::ILIKE;
+						} elseif ($this->comparison === Criteria::NOT_LIKE) {
+							$this->comparison = Criteria::NOT_ILIKE;
+						}
+					} else {
+						$field = $db->ignoreCase($field);
+					}
+				}
+				
+				$params[] = array('table' => $realtable, 'column' => $this->column, 'value' => $this->value);
+				
+				$sb .= $field . $this->comparison;
+
+				// If selection is case insensitive use SQL UPPER() function
+				// on criteria or, if Postgres we are using ILIKE, so not necessary.
+				if ($this->ignoreStringCase && !($db instanceof DBPostgres)) {
+					$sb .= $db->ignoreCase(':p'.count($params));
+				} else {
+					$sb .= ':p'.count($params);
+				}
+				
+			// OPTION 3:  table.column = ? or table.column >= ? etc. (traditional expressions, the default)
+			} else {
+
+				// NULL VALUES need special treatment because the SQL syntax is different
+				// i.e. table.column IS NULL rather than table.column = null
+				if ($this->value !== null) {
+
+					// ANSI SQL functions get inserted right into SQL (not escaped, etc.)
+					if ($this->value === Criteria::CURRENT_DATE || $this->value === Criteria::CURRENT_TIME || $this->value === Criteria::CURRENT_TIMESTAMP) {
+						$sb .= $field . $this->comparison . $this->value;
+					} else {
+						
+						$params[] = array('table' => $realtable, 'column' => $this->column, 'value' => $this->value);
+						
+						// default case, it is a normal col = value expression; value
+						// will be replaced w/ '?' and will be inserted later using PDO bindValue()
+						if ($this->ignoreStringCase) {
+							$sb .= $db->ignoreCase($field) . $this->comparison . $db->ignoreCase(':p'.count($params));
+						} else {
+							$sb .= $field . $this->comparison . ':p'.count($params);
+						}
+						
+					}
+				} else {
+
+					// value is null, which means it was either not specified or specifically
+					// set to null.
+					if ($this->comparison === Criteria::EQUAL || $this->comparison === Criteria::ISNULL) {
+						$sb .= $field . Criteria::ISNULL;
+					} elseif ($this->comparison === Criteria::NOT_EQUAL || $this->comparison === Criteria::ISNOTNULL) {
+						$sb .= $field . Criteria::ISNOTNULL;
+					} else {
+						// for now throw an exception, because not sure how to interpret this
+						throw new PropelException("Could not build SQL for expression: $field " . $this->comparison . " NULL");
+					}
+
+				}
+
+			}
+		}
+
+		foreach ( $this->clauses as $key=>$clause ) {
+			$sb .= $this->conjunctions[$key];
+			$clause->appendPsTo($sb, $params);
+			$sb .= ')';
+		}
+	}
+
+	/**
+	 * This method checks another Criteria to see if they contain
+	 * the same attributes and hashtable entries.
+	 * @return     boolean
+	 */
+	public function equals($obj)
+	{
+		// TODO: optimize me with early outs
+		if ($this === $obj) {
+			return true;
+		}
+
+		if (($obj === null) || !($obj instanceof Criterion)) {
+			return false;
+		}
+
+		$crit = $obj;
+
+		$isEquiv = ( ( ($this->table === null && $crit->getTable() === null)
+			|| ( $this->table !== null && $this->table === $crit->getTable() )
+						  )
+			&& $this->column === $crit->getColumn()
+			&& $this->comparison === $crit->getComparison());
+
+		// check chained criterion
+
+		$clausesLength = count($this->clauses);
+		$isEquiv &= (count($crit->getClauses()) == $clausesLength);
+		$critConjunctions = $crit->getConjunctions();
+		$critClauses = $crit->getClauses();
+		for ($i=0; $i < $clausesLength && $isEquiv; $i++) {
+			$isEquiv &= ($this->conjunctions[$i] === $critConjunctions[$i]);
+			$isEquiv &= ($this->clauses[$i] === $critClauses[$i]);
+		}
+
+		if ($isEquiv) {
+			$isEquiv &= $this->value === $crit->getValue();
+		}
+
+		return $isEquiv;
+	}
+
+	/**
+	 * Returns a hash code value for the object.
+	 */
+	public function hashCode()
+	{
+		$h = crc32(serialize($this->value)) ^ crc32($this->comparison);
+
+		if ($this->table !== null) {
+			$h ^= crc32($this->table);
+		}
+
+		if ($this->column !== null) {
+			$h ^= crc32($this->column);
+		}
+
+		foreach ( $this->clauses as $clause ) {
+			// TODO: i KNOW there is a php incompatibility with the following line
+			// but i dont remember what it is, someone care to look it up and
+			// replace it if it doesnt bother us?
+			// $clause->appendPsTo($sb='',$params=array());
+			$sb = '';
+			$params = array();
+			$clause->appendPsTo($sb,$params);
+			$h ^= crc32(serialize(array($sb,$params)));
+			unset ( $sb, $params );
+		}
+
+		return $h;
+	}
+
+	/**
+	 * Get all tables from nested criterion objects
+	 * @return     array
+	 */
+	public function getAllTables()
+	{
+		$tables = array();
+		$this->addCriterionTable($this, $tables);
+		return $tables;
+	}
+
+	/**
+	 * method supporting recursion through all criterions to give
+	 * us a string array of tables from each criterion
+	 * @return     void
+	 */
+	private function addCriterionTable(Criterion $c, array &$s)
+	{
+		$s[] = $c->getTable();
+		foreach ( $c->getClauses() as $clause ) {
+			$this->addCriterionTable($clause, $s);
+		}
+	}
+
+	/**
+	 * get an array of all criterion attached to this
+	 * recursing through all sub criterion
+	 * @return     array Criterion[]
+	 */
+	public function getAttachedCriterion()
+	{
+		$crits = array();
+		$this->traverseCriterion($this, $crits);
+		return $crits;
+	}
+
+	/**
+	 * method supporting recursion through all criterions to give
+	 * us an array of them
+	 * @param      Criterion $c
+	 * @param      array &$a
+	 * @return     void
+	 */
+	private function traverseCriterion(Criterion $c, array &$a)
+	{
+		$a[] = $c;
+		foreach ( $c->getClauses() as $clause ) {
+			$this->traverseCriterion($clause, $a);
+		}
+	}
+}
+
+/**
+* Data object to describe a join between two tables, for example
+* <pre>
+* table_a LEFT JOIN table_b ON table_a.id = table_b.a_id
+* </pre>
+*/
+class Join
+{
+	/** the left column of the join condition */
+	private $leftColumn = null;
+
+	/** the right column of the join condition */
+	private $rightColumn = null;
+
+	/** the type of the join (LEFT JOIN, ...), or null */
+	private $joinType = null;
+
+	/**
+	 * Constructor
+	 * @param      leftColumn the left column of the join condition;
+	 *        might contain an alias name
+	 * @param      rightColumn the right column of the join condition
+	 *        might contain an alias name
+	 * @param      joinType the type of the join. Valid join types are
+	 *        null (adding the join condition to the where clause),
+	 *        Criteria::LEFT_JOIN(), Criteria::RIGHT_JOIN(), and Criteria::INNER_JOIN()
+	 */
+	public function __construct($leftColumn, $rightColumn, $joinType = null)
+	{
+		if (!is_array($leftColumn) ) {
+			$leftColumn = array($leftColumn);
+		}
+		if (!is_array($rightColumn) ) {
+			$rightColumn = array($rightColumn);
+		}
+		if (count($leftColumn) != count($rightColumn) ) {
+			throw new PropelException("Unable to create join because the left column count isn't equal to the right column count");
+		}
+		$this->leftColumn = $leftColumn;
+		$this->rightColumn = $rightColumn;
+		$this->joinType = $joinType;
+	}
+
+	/**
+	 * @return     the type of the join, i.e. Criteria::LEFT_JOIN(), ...,
+	 *         or null for adding the join condition to the where Clause
+	 */
+	public function getJoinType()
+	{
+		return $this->joinType;
+	}
+
+	/**
+	 * @return     the left column of the join condition
+	 */
+	public function getLeftColumn($index = 0)
+	{
+		return $this->leftColumn[$index];
+	}
+	
+	/**
+	 * @return     all right columns of the join condition
+	 */
+	public function getLeftColumns() {
+		return $this->leftColumn;
+	}
+
+
+	public function getLeftColumnName($index = 0)
+	{
+		return substr($this->leftColumn[$index], strrpos($this->leftColumn[$index], '.') + 1);
+	}
+
+	public function getLeftTableName($index = 0)
+	{
+		return substr($this->leftColumn[$index], 0, strrpos($this->leftColumn[$index], '.'));
+	}
+
+	/**
+	 * @return     the right column of the join condition
+	 */
+	public function getRightColumn($index = 0)
+	{
+		return $this->rightColumn[$index];
+	}
+	
+	/**
+	 * @return     all right columns of the join condition
+	 */
+	public function getRightColumns() {
+		return $this->rightColumn;
+	}
+
+	public function getRightColumnName($index = 0)
+	{
+		return substr($this->rightColumn[$index], strrpos($this->rightColumn[$index], '.') + 1);
+	}
+
+	public function getRightTableName($index = 0)
+	{
+		return substr($this->rightColumn[$index], 0, strrpos($this->rightColumn[$index], '.'));
+	}
+
+	/**
+	 * returns a String representation of the class,
+	 * mainly for debugging purposes
+	 * @return     a String representation of the class
+	 */
+	public function toString()
+	{
+		$result = "";
+		if ($this->joinType !== null)
+		{
+			$result .= $this->joinType . " : ";
+		}
+		$result .= $this->leftColumn . "=" . $this->rightColumn . " (ignoreCase not considered)";
+
+		return $result;
+	}
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel/util/DebugPDO.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel/util/DebugPDO.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel/util/DebugPDO.php	(revision 19)
@@ -0,0 +1,220 @@
+<?php
+/*
+ *  $Id: DebugPDO.php 1052 2008-05-28 09:43:01Z hans $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://propel.phpdb.org>.
+ */
+
+/**
+ * PDO connection subclass that provides some basic support for query counting and logging.
+ *
+ * This class is ONLY intended for development use.  This class is also a work in-progress
+ * and, as such, it should be expected that this class' API may change.  We will be looking
+ * at ways to refactor this class to provide a more pluggable system for hooking in more query
+ * informatics.  In the meantime, this class should illustrate how you can
+ *
+ * @author     Cameron Brunner <cameron.brunner@gmail.com>
+ * @author     Hans Lellelid <hans@xmpl.org>
+ * @author     Christian Abegg <abegg.ch@gmail.com>
+ * @since      2006-09-22
+ * @package    propel.util
+ */
+class DebugPDO extends PropelPDO {
+
+	/**
+	 * Count of queries performed
+	 * @var        int
+	 */
+	protected $queryCount = 0;
+
+	/**
+	 * The statement class to use.
+	 *
+	 * @var        string
+	 */
+	protected $statementClass = 'DebugPDOStatement';
+
+	/**
+	 * Configured BasicLogger (or compatible) logger.
+	 *
+	 * @var        BasicLogger
+	 */
+	protected $logger;
+
+	/**
+	 * The log level to use for logging.
+	 *
+	 * @var        int
+	 */
+	private $logLevel = Propel::LOG_DEBUG;
+
+	/**
+	 * Construct a new DebugPDO connection.
+	 *
+	 * This method is overridden in order to specify a custom PDOStatement class.
+	 *
+	 * @param      string $dsn Connection DSN
+	 * @param      string $username (optional
+	 * @param      string $password
+	 * @param      array $driver_options
+	 * @throws     PDOException - if there is an error during connection initialization
+	 */
+	public function __construct($dsn, $username = null, $password = null, $driver_options = array())
+	{
+		parent::__construct($dsn, $username, $password, $driver_options);
+		$this->configureStatementClass($suppress=true);
+	}
+
+	/**
+	 * Configures the PDOStatement class for this connection.
+	 * @param      boolean $suppressError Whether to suppress an exception if the statement class cannot be set.
+	 * @throws     PropelException if the statement class cannot be set (and $suppressError is false)
+	 */
+	protected function configureStatementClass($suppressError = false)
+	{
+		// extending PDOStatement is not supported with persistent connections
+		if (!$this->getAttribute(PDO::ATTR_PERSISTENT)) {
+			$this->setAttribute(PDO::ATTR_STATEMENT_CLASS, array($this->getStatementClass(), array($this)));
+		} elseif (!$suppressError) {
+			throw new PropelException('Extending PDOStatement is not supported with persistent connections.');
+		}
+	}
+
+	/**
+	 * Sets the custom classname to use for PDOStatement.
+	 *
+	 * It is assumed that the specified classname has been loaded (or can be loaded
+	 * on-demand with autoload).
+	 *
+	 * @param      string $classname
+	 */
+	public function setStatementClass($classname)
+	{
+		$this->statementClass = $classname;
+		$this->configureStatementClass();
+	}
+
+	/**
+	 * Gets the custom classname to use for PDOStatement.
+	 * @return     string
+	 */
+	public function getStatementClass()
+	{
+		return $this->statementClass;
+	}
+
+	/**
+	 * Gets the query count
+	 * @return     int
+	 * @throws     PropelException - if persistent connection is used (since unable to override PDOStatement in that case).
+	 */
+	public function getQueryCount()
+	{
+		// extending PDOStatement is not supported with persistent connections
+		if ($this->getAttribute(PDO::ATTR_PERSISTENT)) {
+			throw new PropelException('Extending PDOStatement is not supported with persistent connections. ' .
+																'Count would be inaccurate, because we cannot count the PDOStatment::execute() calls. ' .
+																'Either don\'t use persistent connections or don\'t call PropelPDO::getQueryCount()');
+		}
+		return $this->queryCount;
+	}
+
+	/**
+	 * increments the query count
+	 * @return     int
+	 */
+	public function incrementQueryCount()
+	{
+		$this->queryCount++;
+	}
+
+	/**
+	 * Overrides PDO::prepare() to add logging.
+	 * .
+	 * @param      string $sql
+	 * @param      array
+	 * @return     PDOStatement
+	 */
+	public function prepare($sql, $driver_options = array())
+	{
+		$this->log('prepare: ' . $sql);
+		return parent::prepare($sql, $driver_options);
+	}
+
+	/**
+	 * overridden for query counting
+	 * @return     int
+	 */
+	public function exec($sql)
+	{
+		$this->log('exec: ' . $sql);
+		$this->incrementQueryCount();
+		return parent::exec($sql);
+	}
+
+	/**
+	 * Overridden for query counting and logging.
+	 * @return     int
+	 */
+	public function query()
+	{
+		$args = func_get_args();
+		$this->log('query: ' . $args[0]);
+		$this->incrementQueryCount();
+		return call_user_func_array(array($this, 'parent::query'), $args);
+	}
+
+	/**
+	 * Sets the logging level to use for logging SQL statements.
+	 *
+	 * @param      int $level
+	 */
+	public function setLogLevel($level)
+	{
+		$this->logLevel = $level;
+	}
+
+	/**
+	 * Sets a logger to use.
+	 * @param      BasicLogger $logger A Logger with an API compatible with BasicLogger (or PEAR Log).
+	 */
+	public function setLogger($logger)
+	{
+		$this->logger = $logger;
+	}
+
+	/**
+	 * Logs the SQL using the Propel::log() method or registered logger class.
+	 *
+	 * @param      string $msg Message to log.
+	 * @param      int $level (optional) Log level to use; will use setLogLevel() specified level by default. 
+	 * @see        setLogger()
+	 * @see
+	 */
+	public function log($msg, $level = null)
+	{
+		if ($level === null) {
+			$level = $this->logLevel; 
+		}
+		if ($this->logger) {
+			$this->logger->log($msg, $level);
+		} else {
+			Propel::log($msg, $level);
+		}
+	}
+
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel/util/DebugPDOStatement.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel/util/DebugPDOStatement.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel/util/DebugPDOStatement.php	(revision 19)
@@ -0,0 +1,82 @@
+<?php
+/*
+ *  $Id: DebugPDOStatement.php 989 2008-03-11 14:29:30Z heltem $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://propel.phpdb.org>.
+ */
+
+/**
+ * PDOStatement that provides some enhanced functionality needed by Propel.
+ *
+ * Simply adds the ability to count the number of queries executed and log the queries.
+ *
+ * @author     Oliver Schonrock <oliver@realtsp.com>
+ * @since      2007-07-12
+ * @package    propel.util
+ */
+class DebugPDOStatement extends PDOStatement {
+
+	/**
+	 * the pdo connection from which we were created
+	 * @var        DebugPDO
+	 */
+	protected $pdo;
+
+	protected $typeMap = array(	PDO::PARAM_BOOL => "PDO::PARAM_BOOL",
+								PDO::PARAM_INT => "PDO::PARAM_INT",
+								PDO::PARAM_STR => "PDO::PARAM_STR",
+								PDO::PARAM_LOB => "PDO::PARAM_LOB",
+								PDO::PARAM_NULL => "PDO::PARAM_NULL",
+								);
+
+	/**
+	 * Construct a new statement class with reference to main DebugPDO object.
+	 */
+	protected function __construct(DebugPDO $pdo)
+	{
+		$this->pdo = $pdo;
+	}
+
+	/**
+	 * Overridden for query counting.
+	 * @return     int
+	 */
+	public function execute($input_parameters = null)
+	{
+		$this->pdo->incrementQueryCount();
+		return parent::execute($input_parameters);
+	}
+
+	/**
+	 * Binds value to PDOStatement.
+	 *
+	 * @param      int $pos
+	 * @param      mixed $value
+	 * @param      int $type
+	 * @return     boolean
+	 */
+	public function bindValue($pos, $value, $type = null)
+	{
+		$typestr = isset($this->typeMap[$type]) ? $this->typeMap[$type] : '(default)';
+		if ($type == PDO::PARAM_LOB) {
+			$this->pdo->log("Binding [LOB value] at position ".$pos." w/ PDO  type " . $typestr);
+		} else {
+			$this->pdo->log("Binding " . var_export($value, true) . " at position $pos w/ PDO type " . $typestr);
+		}
+		return parent::bindValue($pos, $value, $type);
+	}
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel/util/NodePeer.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel/util/NodePeer.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel/util/NodePeer.php	(revision 19)
@@ -0,0 +1,379 @@
+<?php
+/*
+ *  $Id: NodePeer.php 797 2007-11-09 19:21:21Z heltem $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://propel.phpdb.org>.
+ */
+
+/**
+ * This is a utility interface for all generated NodePeer classes in the system.
+ *
+ * @author     Heltem <heltem@o2php.com> (Propel)
+ * @version    $Revision: 797 $
+ * @package    propel.util
+ */
+interface NodePeer {
+	/**
+	 * Creates the supplied node as the root node.
+	 *
+	 * @param      object $node	Propel object for model
+	 * @return     object		Inserted propel object for model
+	 */
+	public static function createRoot(NodeObject $node);
+
+	/**
+	 * Returns the root node for a given scope id
+	 *
+	 * @param      int $scopeId		Scope id to determine which root node to return
+	 * @param      PropelPDO $con	Connection to use.
+	 * @return     object			Propel object for root node
+	 */
+	public static function retrieveRoot($scopeId = 1, PropelPDO $con = null);
+
+	/**
+	 * Inserts $child as first child of destination node $parent
+	 *
+	 * @param      object $child	Propel object for child node
+	 * @param      object $parent	Propel object for parent node
+	 * @param      PropelPDO $con	Connection to use.
+	 * @return     void
+	 */
+	public static function insertAsFirstChildOf(NodeObject $child, NodeObject $parent, PropelPDO $con = null);
+
+	/**
+	 * Inserts $child as last child of destination node $parent
+	 *
+	 * @param      object $child	Propel object for child node
+	 * @param      object $parent	Propel object for parent node
+	 * @param      PropelPDO $con	Connection to use.
+	 * @return     void
+	 */
+	public static function insertAsLastChildOf(NodeObject $child, NodeObject $parent, PropelPDO $con = null);
+
+	/**
+	 * Inserts $sibling as previous sibling to destination node $node
+	 *
+	 * @param      object $node		Propel object for destination node
+	 * @param      object $sibling	Propel object for source node
+	 * @param      PropelPDO $con	Connection to use.
+	 * @return     void
+	 */
+	public static function insertAsPrevSiblingOf(NodeObject $node, NodeObject $sibling, PropelPDO $con = null);
+
+	/**
+	 * Inserts $sibling as next sibling to destination node $node
+	 *
+	 * @param      object $node		Propel object for destination node
+	 * @param      object $sibling	Propel object for source node
+	 * @param      PropelPDO $con	Connection to use.
+	 * @return     void
+	 */
+	public static function insertAsNextSiblingOf(NodeObject $node, NodeObject $sibling, PropelPDO $con = null);
+
+	/**
+	 * Inserts $parent as parent of given $node.
+	 *
+	 * @param      object $parent  	Propel object for given parent node
+	 * @param      object $node  	Propel object for given destination node
+	 * @param      PropelPDO $con	Connection to use.
+	 * @return     void
+	 * @throws     Exception      When trying to insert node as parent of a root node
+	 */
+	public static function insertAsParentOf(NodeObject $parent, NodeObject $node, PropelPDO $con = null);
+
+	/**
+	 * Inserts $node as root node
+	 *
+	 * @param      object $node	Propel object as root node
+	 * @param      PropelPDO $con	Connection to use.
+	 * @return     void
+	 */
+	public static function insertRoot(NodeObject $node, PropelPDO $con = null);
+
+	/**
+	 * Delete root node
+	 *
+	 * @param      int $scopeId		Scope id to determine which root node to delete
+	 * @param      PropelPDO $con	Connection to use.
+	 * @return     boolean		Deletion status
+	 */
+	public static function deleteRoot($scopeId = 1, PropelPDO $con = null);
+
+	/**
+	 * Delete $dest node
+	 *
+	 * @param      object $dest	Propel object node to delete
+	 * @param      PropelPDO $con	Connection to use.
+	 * @return     boolean		Deletion status
+	 */
+	public static function deleteNode(NodeObject $dest, PropelPDO $con = null);
+
+	/**
+	 * Moves $child to be first child of $parent
+	 *
+	 * @param      object $parent	Propel object for parent node
+	 * @param      object $child	Propel object for child node
+	 * @param      PropelPDO $con	Connection to use.
+	 * @return     void
+	 */
+	public static function moveToFirstChildOf(NodeObject $parent, NodeObject $child, PropelPDO $con = null);
+
+	/**
+	 * Moves $node to be last child of $dest
+	 *
+	 * @param      object $dest	Propel object for destination node
+	 * @param      object $node	Propel object for source node
+	 * @param      PropelPDO $con	Connection to use.
+	 * @return     void
+	 */
+	public static function moveToLastChildOf(NodeObject $dest, NodeObject $node, PropelPDO $con = null);
+
+	/**
+	 * Moves $node to be prev sibling to $dest
+	 *
+	 * @param      object $dest	Propel object for destination node
+	 * @param      object $node	Propel object for source node
+	 * @param      PropelPDO $con	Connection to use.
+	 * @return     void
+	 */
+	public static function moveToPrevSiblingOf(NodeObject $dest, NodeObject $node, PropelPDO $con = null);
+
+	/**
+	 * Moves $node to be next sibling to $dest
+	 *
+	 * @param      object $dest	Propel object for destination node
+	 * @param      object $node	Propel object for source node
+	 * @param      PropelPDO $con	Connection to use.
+	 * @return     void
+	 */
+	public static function moveToNextSiblingOf(NodeObject $dest, NodeObject $node, PropelPDO $con = null);
+
+	/**
+	 * Gets first child for the given node if it exists
+	 *
+	 * @param      object $node	Propel object for src node
+	 * @param      PropelPDO $con	Connection to use.
+	 * @return     mixed 		Propel object if exists else false
+	 */
+	public static function retrieveFirstChild(NodeObject $node, PropelPDO $con = null);
+
+	/**
+	 * Gets last child for the given node if it exists
+	 *
+	 * @param      object $node	Propel object for src node
+	 * @param      PropelPDO $con	Connection to use.
+	 * @return     mixed 		Propel object if exists else false
+	 */
+	public static function retrieveLastChild(NodeObject $node, PropelPDO $con = null);
+
+	/**
+	 * Gets prev sibling for the given node if it exists
+	 *
+	 * @param      object $node	Propel object for src node
+	 * @param      PropelPDO $con	Connection to use.
+	 * @return     mixed 		Propel object if exists else false
+	 */
+	public static function retrievePrevSibling(NodeObject $node, PropelPDO $con = null);
+
+	/**
+	 * Gets next sibling for the given node if it exists
+	 *
+	 * @param      object $node	Propel object for src node
+	 * @param      PropelPDO $con	Connection to use.
+	 * @return     mixed 		Propel object if exists else false
+	 */
+	public static function retrieveNextSibling(NodeObject $node, PropelPDO $con = null);
+
+	/**
+	 * Retrieves the entire tree from root
+	 *
+	 * @param      int $scopeId		Scope id to determine which scope tree to return
+	 * @param      PropelPDO $con	Connection to use.
+	 */
+	public static function retrieveTree($scopeId = 1, PropelPDO $con = null);
+
+	/**
+	 * Retrieves the entire tree from parent $node
+	 *
+	 * @param      PropelPDO $con	Connection to use.
+	 */
+	public static function retrieveBranch(NodeObject $node, PropelPDO $con = null);
+
+	/**
+	 * Gets direct children for the node
+	 *
+	 * @param      object $node	Propel object for parent node
+	 * @param      PropelPDO $con	Connection to use.
+	 */
+	public static function retrieveChildren(NodeObject $node, PropelPDO $con = null);
+
+	/**
+	 * Gets all descendants for the node
+	 *
+	 * @param      object $node	Propel object for parent node
+	 * @param      PropelPDO $con	Connection to use.
+	 */
+	public static function retrieveDescendants(NodeObject $node, PropelPDO $con = null);
+
+	/**
+	 * Gets all siblings for the node
+	 *
+	 * @param      object $node	Propel object for src node
+	 * @param      PropelPDO $con	Connection to use.
+	 */
+	public static function retrieveSiblings(NodeObject $node, PropelPDO $con = null);
+
+	/**
+	 * Gets ancestor for the given node if it exists
+	 *
+	 * @param      object $node	Propel object for src node
+	 * @param      PropelPDO $con	Connection to use.
+	 * @return     mixed 		Propel object if exists else false
+	 */
+	public static function retrieveParent(NodeObject $node, PropelPDO $con = null);
+
+	/**
+	 * Gets level for the given node
+	 *
+	 * @param      object $node	Propel object for src node
+	 * @param      PropelPDO $con	Connection to use.
+	 * @return     int			Level for the given node
+	 */
+	public static function getLevel(NodeObject $node, PropelPDO $con = null);
+
+	/**
+	 * Gets number of direct children for given node
+	 *
+	 * @param      object $node	Propel object for src node
+	 * @param      PropelPDO $con	Connection to use.
+	 * @return     int			Level for the given node
+	 */
+	public static function getNumberOfChildren(NodeObject $node, PropelPDO $con = null);
+
+	/**
+	 * Gets number of descendants for given node
+	 *
+	 * @param      object $node	Propel object for src node
+	 * @param      PropelPDO $con	Connection to use.
+	 * @return     int			Level for the given node
+	 */
+	public static function getNumberOfDescendants(NodeObject $node, PropelPDO $con = null);
+
+ 	/**
+	 * Returns path to a specific node as an array, useful to create breadcrumbs
+	 *
+	 * @param      object $node	Propel object of node to create path to
+	 * @param      PropelPDO $con	Connection to use.
+	 * @return     array		Array in order of heirarchy
+	 */
+	public static function getPath(NodeObject $node, PropelPDO $con = null);
+
+	/**
+	 * Tests if node is valid
+	 *
+	 * @param      object $node	Propel object for src node
+	 * @return     bool
+	 */
+	public static function isValid(NodeObject $node = null);
+
+	/**
+	 * Tests if node is a root
+	 *
+	 * @param      object $node	Propel object for src node
+	 * @return     bool
+	 */
+	public static function isRoot(NodeObject $node);
+
+	/**
+	 * Tests if node is a leaf
+	 *
+	 * @param      object $node	Propel object for src node
+	 * @return     bool
+	 */
+	public static function isLeaf(NodeObject $node);
+
+	/**
+	 * Tests if $child is a child of $parent
+	 *
+	 * @param      object $child	Propel object for node
+	 * @param      object $parent	Propel object for node
+	 * @return     bool
+	 */
+	public static function isChildOf(NodeObject $child, NodeObject $parent);
+
+	/**
+	 * Tests if $node1 is equal to $node2
+	 *
+	 * @param      object $node1	Propel object for node
+	 * @param      object $node2	Propel object for node
+	 * @return     bool
+	 */
+	public static function isEqualTo(NodeObject $node1, NodeObject $node2);
+
+	/**
+	 * Tests if $node has an ancestor
+	 *
+	 * @param      object $node	Propel object for node
+	 * @param      PropelPDO $con		Connection to use.
+	 * @return     bool
+	 */
+	public static function hasParent(NodeObject $node, PropelPDO $con = null);
+
+	/**
+	 * Tests if $node has prev sibling
+	 *
+	 * @param      object $node	Propel object for node
+	 * @param      PropelPDO $con	Connection to use.
+	 * @return     bool
+	 */
+	public static function hasPrevSibling(NodeObject $node, PropelPDO $con = null);
+
+	/**
+	 * Tests if $node has next sibling
+	 *
+	 * @param      object $node	Propel object for node
+	 * @param      PropelPDO $con	Connection to use.
+	 * @return     bool
+	 */
+	public static function hasNextSibling(NodeObject $node, PropelPDO $con = null);
+
+	/**
+	 * Tests if $node has children
+	 *
+	 * @param      object $node	Propel object for node
+	 * @return     bool
+	 */
+	public static function hasChildren(NodeObject $node);
+
+	/**
+	 * Deletes $node and all of its descendants
+	 *
+	 * @param      object $node	Propel object for source node
+	 * @param      PropelPDO $con	Connection to use.
+	 */
+	public static function deleteDescendants(NodeObject $node, PropelPDO $con = null);
+
+	/**
+	 * Returns a node given its primary key or the node itself
+	 *
+	 * @param      int/object $node	Primary key/instance of required node
+	 * @param      PropelPDO $con	Connection to use.
+	 * @return     object		Propel object for model
+	 */
+	public static function getNode($node, PropelPDO $con = null);
+
+} // NodePeer
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel/util/PropelColumnTypes.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel/util/PropelColumnTypes.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel/util/PropelColumnTypes.php	(revision 19)
@@ -0,0 +1,136 @@
+<?php
+/*
+ *  $Id: PropelColumnTypes.php 783 2007-11-08 09:46:20Z heltem $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://propel.phpdb.org>.
+ */
+
+/**
+ * Enumeration of Propel types.
+ *
+ * THIS CLASS MUST BE KEPT UP-TO-DATE WITH THE MORE EXTENSIVE GENERATOR VERSION OF THIS CLASS.
+ *
+ * @author     Hans Lellelid <hans@xmpl.org> (Propel)
+ * @version    $Revision: 783 $
+ * @package    propel.util
+ */
+class PropelColumnTypes {
+
+	const CHAR = "CHAR";
+	const VARCHAR = "VARCHAR";
+	const LONGVARCHAR = "LONGVARCHAR";
+	const CLOB = "CLOB";
+	const NUMERIC = "NUMERIC";
+	const DECIMAL = "DECIMAL";
+	const TINYINT = "TINYINT";
+	const SMALLINT = "SMALLINT";
+	const INTEGER = "INTEGER";
+	const BIGINT = "BIGINT";
+	const REAL = "REAL";
+	const FLOAT = "FLOAT";
+	const DOUBLE = "DOUBLE";
+	const BINARY = "BINARY";
+	const VARBINARY = "VARBINARY";
+	const LONGVARBINARY = "LONGVARBINARY";
+	const BLOB = "BLOB";
+	const DATE = "DATE";
+	const TIME = "TIME";
+	const TIMESTAMP = "TIMESTAMP";
+
+	const BU_DATE = "BU_DATE";
+	const BU_TIMESTAMP = "BU_TIMESTAMP";
+
+	const BOOLEAN = "BOOLEAN";
+
+	/*
+	private static $propelToPhpMap = array(
+		self::CHAR 			=> "string",
+		self::VARCHAR 		=> "string",
+		self::LONGVARCHAR 	=> "string",
+		self::CLOB 			=> "string",
+		self::NUMERIC 		=> "PARAM_STR",
+		self::DECIMAL 		=> "PARAM_STR",
+		self::TINYINT 		=> "PARAM_INT",
+		self::SMALLINT 		=> "PARAM_INT",
+		self::INTEGER 		=> "PARAM_INT",
+		self::BIGINT 		=> "PARAM_STR",
+		self::REAL 			=> "PARAM_STR",
+		self::FLOAT 		=> "PARAM_STR",
+		self::DOUBLE 		=> "PARAM_STR",
+		self::BINARY 		=> "PARAM_STR",
+		self::VARBINARY 	=> "PARAM_STR",
+		self::LONGVARBINARY => "PARAM_STR",
+		self::BLOB 			=> "PARAM_LOB",
+		self::DATE 			=> "PARAM_STR",
+		self::TIME 			=> "PARAM_STR",
+		self::TIMESTAMP 	=> "PARAM_STR",
+		self::BU_DATE 		=> "PARAM_STR",
+		self::BU_TIMESTAMP 	=> "PARAM_STR",
+		self::BOOLEAN 		=> "PARAM_BOOL",
+	);
+	*/
+
+	private static $propelToPdoMap = array(
+		self::CHAR 			=> PDO::PARAM_STR,
+		self::VARCHAR 		=> PDO::PARAM_STR,
+		self::LONGVARCHAR 	=> PDO::PARAM_STR,
+		self::CLOB 			=> PDO::PARAM_LOB,
+		self::NUMERIC 		=> PDO::PARAM_STR,
+		self::DECIMAL 		=> PDO::PARAM_STR,
+		self::TINYINT 		=> PDO::PARAM_INT,
+		self::SMALLINT 		=> PDO::PARAM_INT,
+		self::INTEGER 		=> PDO::PARAM_INT,
+		self::BIGINT 		=> PDO::PARAM_STR,
+		self::REAL 			=> PDO::PARAM_STR,
+		self::FLOAT 		=> PDO::PARAM_STR,
+		self::DOUBLE 		=> PDO::PARAM_STR,
+		self::BINARY 		=> PDO::PARAM_STR,
+		self::VARBINARY 	=> PDO::PARAM_STR,
+		self::LONGVARBINARY => PDO::PARAM_STR,
+		self::BLOB 			=> PDO::PARAM_LOB,
+		self::DATE 			=> PDO::PARAM_STR,
+		self::TIME 			=> PDO::PARAM_STR,
+		self::TIMESTAMP 	=> PDO::PARAM_STR,
+		self::BU_DATE 		=> PDO::PARAM_STR,
+		self::BU_TIMESTAMP 	=> PDO::PARAM_STR,
+		self::BOOLEAN 		=> PDO::PARAM_BOOL,
+	);
+
+	/**
+	 * Return native PHP type which corresponds to the Propel type provided.
+	 *
+	 * @param      $propelType The Propel type.
+	 * @return     string Name of the native PHP type
+	 */
+	 /*
+	public static function getPhpType($propelType)
+	{
+		return self::$propelToPhpMap[$propelType];
+	}
+	*/
+
+	/**
+	 * Resturns the PDO type (PDO::PARAM_* constant) value for the Propel type provided.
+	 * @param      string $propelType
+	 * @return     int
+	 */
+	public static function getPdoType($propelType)
+	{
+		return self::$propelToPdoMap[$propelType];
+	}
+
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel/util/PropelDateTime.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel/util/PropelDateTime.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel/util/PropelDateTime.php	(revision 19)
@@ -0,0 +1,87 @@
+<?php
+/*
+ *  $Id: PropelDateTime.php 784 2007-11-08 10:15:50Z heltem $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://propel.phpdb.org>.
+ */
+
+/**
+ * DateTime subclass which supports serialization.
+ *
+ * Currently Propel is not using this for storing date/time objects
+ * within model objeects; however, we are keeping it in the repository
+ * because it is useful if you want to store a DateTime object in a session.
+ *
+ * @author     Alan Pinstein
+ * @author     Soenke Ruempler
+ * @author     Hans Lellelid
+ * @package    propel.util
+ */
+class PropelDateTime extends DateTime
+{
+
+	/**
+	 * A string representation of the date, for serialization.
+	 * @var        string
+	 */
+	private $dateString;
+
+	/**
+	 * A string representation of the time zone, for serialization.
+	 * @var        string
+	 */
+	private $tzString;
+
+	/**
+	 * Convenience method to enable a more fluent API.
+	 * @param      string $date Date/time value.
+	 * @param      DateTimeZone $tz (optional) timezone
+	 */
+	public static function newInstance($date, DateTimeZone $tz = null)
+	{
+		if ($tz) {
+			return new DateTime($date, $tz);
+		} else {
+			return new DateTime($date);
+		}
+	}
+
+	/**
+	 * PHP "magic" function called when object is serialized.
+	 * Sets an internal property with the date string and returns properties
+	 * of class that should be serialized.
+	 * @return     array string[]
+	 */
+	function __sleep()
+	{
+		// We need to use a string without a time zone, due to
+		// PHP bug: http://bugs.php.net/bug.php?id=40743
+		$this->dateString = $this->format('Y-m-d H:i:s');
+		$this->tzString = $this->getTimeZone()->getName();
+		return array('dateString', 'tzString');
+	}
+
+	/**
+	 * PHP "magic" function called when object is restored from serialized state.
+	 * Calls DateTime constructor with previously stored string value of date.
+	 */
+	function __wakeup()
+	{
+		parent::__construct($this->dateString, new DateTimeZone($this->tzString));
+	}
+
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel/util/PropelPDO.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel/util/PropelPDO.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel/util/PropelPDO.php	(revision 19)
@@ -0,0 +1,233 @@
+<?php
+/*
+ *  $Id: PropelPDO.php 1067 2008-08-06 07:37:21Z ron $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://propel.phpdb.org>.
+ */
+
+
+/**
+ * PDO connection subclass that provides the basic fixes to PDO that are required by Propel.
+ *
+ * This class was designed to work around the limitation in PDO where attempting to begin
+ * a transaction when one has already been begun will trigger a PDOException.  Propel
+ * relies on the ability to create nested transactions, even if the underlying layer
+ * simply ignores these (because it doesn't support nested transactions).
+ *
+ * The changes that this class makes to the underlying API include the addition of the
+ * getNestedTransactionDepth() and isInTransaction() and the fact that beginTransaction()
+ * will no longer throw a PDOException (or trigger an error) if a transaction is already
+ * in-progress.
+ *
+ * @author     Cameron Brunner <cameron.brunner@gmail.com>
+ * @author     Hans Lellelid <hans@xmpl.org>
+ * @author     Christian Abegg <abegg.ch@gmail.com>
+ * @since      2006-09-22
+ * @package    propel.util
+ */
+class PropelPDO extends PDO {
+
+	/**
+	 * Attribute to use to set whether to cache prepared statements.
+	 */
+	const PROPEL_ATTR_CACHE_PREPARES = -1;
+
+	/**
+	 * The current transaction depth.
+	 * @var        int
+	 */
+	protected $nestedTransactionCount = 0;
+
+	/**
+	 * Cache of prepared statements (PDOStatement) keyed by md5 of SQL.
+	 *
+	 * @var        array [md5(sql) => PDOStatement]
+	 */
+	protected $preparedStatements = array();
+
+	/**
+	 * Whether to cache prepared statements.
+	 *
+	 * @var        boolean
+	 */
+	protected $cachePreparedStatements = false;
+
+	/**
+	 * Gets the current transaction depth.
+	 * @return     int
+	 */
+	public function getNestedTransactionCount()
+	{
+		return $this->nestedTransactionCount;
+	}
+
+	/**
+	 * Set the current transaction depth.
+	 * @param      int $v The new depth.
+	 */
+	protected function setNestedTransactionCount($v)
+	{
+		$this->nestedTransactionCount = $v;
+	}
+
+	/**
+	 * Decrements the current transaction depth by one.
+	 */
+	protected function decrementNestedTransactionCount()
+	{
+		$this->nestedTransactionCount--;
+	}
+
+	/**
+	 * Increments the current transaction depth by one.
+	 */
+	protected function incrementNestedTransactionCount()
+	{
+		$this->nestedTransactionCount++;
+	}
+
+	/**
+	 * Is this PDO connection currently in-transaction?
+	 * This is equivalent to asking whether the current nested transaction count
+	 * is greater than 0.
+	 * @return     boolean
+	 */
+	public function isInTransaction()
+	{
+		return ($this->getNestedTransactionCount() > 0);
+	}
+
+	/**
+	 * Overrides PDO::beginTransaction() to prevent errors due to already-in-progress transaction.
+	 */
+	public function beginTransaction()
+	{
+		$return = true;
+		$opcount = $this->getNestedTransactionCount();
+		if ( $opcount === 0 ) {
+			$return = parent::beginTransaction();
+		}
+		$this->incrementNestedTransactionCount();
+		return $return;
+	}
+
+	/**
+	 * Overrides PDO::commit() to only commit the transaction if we are in the outermost
+	 * transaction nesting level.
+	 */
+	public function commit()
+	{
+		$return = true;
+		$opcount = $this->getNestedTransactionCount();
+		if ($opcount > 0) {
+			if ($opcount === 1) {
+				$return = parent::commit();
+			}
+			$this->decrementNestedTransactionCount();
+		}
+		return $return;
+	}
+
+	/**
+	 * Overrides PDO::rollBack() to only rollback the transaction if we are in the outermost
+	 * transaction nesting level.
+	 */
+	public function rollBack()
+	{
+		$return = true;
+		$opcount = $this->getNestedTransactionCount();
+		if ($opcount > 0) {
+			if ($opcount === 1) {
+				$return = parent::rollBack();
+			}
+			$this->decrementNestedTransactionCount();
+		}
+		return $return;
+	}
+
+	/**
+	 * Sets a connection attribute.
+	 *
+	 * This is overridden here to provide support for setting Propel-specific attributes
+	 * too.
+	 *
+	 * @param      int $attribute The attribute to set (e.g. PropelPDO::PROPEL_ATTR_CACHE_PREPARES).
+	 * @param      mixed $value The attribute value.
+	 */
+	public function setAttribute($attribute, $value)
+	{
+		switch($attribute) {
+			case self::PROPEL_ATTR_CACHE_PREPARES:
+				$this->cachePreparedStatements = $value;
+				break;
+			default:
+				parent::setAttribute($attribute, $value);
+		}
+	}
+
+	/**
+	 * Gets a connection attribute.
+	 *
+	 * This is overridden here to provide support for setting Propel-specific attributes
+	 * too.
+	 *
+	 * @param      int $attribute The attribute to get (e.g. PropelPDO::PROPEL_ATTR_CACHE_PREPARES).
+	 */
+	public function getAttribute($attribute)
+	{
+		switch($attribute) {
+			case self::PROPEL_ATTR_CACHE_PREPARES:
+				return $this->cachePreparedStatements;
+				break;
+			default:
+				return parent::getAttribute($attribute);
+		}
+	}
+
+	/**
+	 * Overrides PDO::prepare() to add query caching support if the
+	 * PropelPDO::PROPEL_ATTR_CACHE_PREPARES was set to true.
+	 * .
+	 * @param      string $sql
+	 * @param      array
+	 * @return     PDOStatement
+	 */
+	public function prepare($sql, $driver_options = array())
+	{
+		if ($this->cachePreparedStatements) {
+			$key = $sql;
+			if (!isset($this->preparedStatements[$key])) {
+				$stmt = parent::prepare($sql, $driver_options);
+				$this->preparedStatements[$key] = $stmt;
+				return $stmt;
+			} else {
+				return $this->preparedStatements[$key];
+			}
+		} else {
+			return parent::prepare($sql, $driver_options);
+		}
+	}
+
+	/**
+	 * Clears any stored prepared statements for this connection.
+	 */
+	public function clearStatementCache()
+	{
+		$this->preparedStatements = array();
+	}
+
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel/util/PropelPager.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel/util/PropelPager.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel/util/PropelPager.php	(revision 19)
@@ -0,0 +1,559 @@
+<?php
+/*
+ *  $Id: PropelPager.php 563 2007-02-01 09:45:55Z heltem $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://propel.phpdb.org>.
+ */
+
+/**
+ *  PropelPager
+ *
+ *  Example Usage:
+ *
+ *  require_once 'propel/util/PropelPager.php';
+ *  require_once 'PEACH/Propel/Poem/poemPeer.php';
+ *
+ *  $c = new Criteria();
+ *  $c->addDescendingOrderByColumn(poemPeer::SID);
+ *
+ *  // with join
+ *  $pager = new PropelPager($c, 'poemPeer', 'doSelectJoinPoemUsers', 1, 50);
+ *
+ *  // without Join
+ *
+ *  $pager = new PropelPager($c, 'poemPeer', 'doSelect', 1, 50);
+ *
+ * Some template:
+ *
+ * <p>
+ * Total Pages: <?=$pager->getTotalPages()?>  Total Records: <?=$pager->getTotalRecordCount()?>
+ * </p>
+ * <table>
+ * <tr>
+ * <td>
+ * <?if ($link = $pager->getFirstPage):?>
+ * <a href="somescript?page=<?=$link?>"><?=$link?></a>|
+ * <?endif?>
+ * </td>
+ * <td>
+ * <?if ($link = $pager->getPrev()):?>
+ * <a href="somescript?page=<?=$link?>">Previous</a>|
+ * <?endif?>
+ * </td>
+ * <td>
+ * <?foreach ($pager->getPrevLinks() as $link):?>
+ * <a href="somescript?page=<?=$link?>"><?=$link?></a>|
+ * <?endforeach?>
+ * </td>
+ * <td><?=$pager->getPage()?></td>
+ * <td>
+ * <?foreach ($pager->getNextLinks() as $link):?>
+ * | <a href="somescript?page=<?=$link?>"><?=$link?></a>
+ * <?endforeach?>
+ * </td>
+ * <td>
+ * <?if ($link = $pager->getNext()):?>
+ * <a href="somescript?page=<?=$link?>">Last</a>|
+ * <?endif?>
+ * </td>
+ * <td>
+ * <?if ($link = $pager->getLastPage()):?>
+ * <a href="somescript?page=<?=$link?>"><?=$link?></a>|
+ * <?endif?>
+ * </td>
+ * </tr>
+ * </table>
+ * <table id="latestPoems">
+ * <tr>
+ * <th>Title</th>
+ * <th>Auteur</th>
+ * <th>Date</th>
+ * <th>comments</th>
+ * </tr>
+ * <?foreach ($pager->getResult() as $poem):?>
+ * <tr>
+ * <td><?=$poem->getTitle()?></td>
+ * <td><?=$poem->getPoemUsers()->getUname()?></td>
+ * <td><?=$poem->getTime()?></td>
+ * <td><?=$poem->getComments()?></td>
+ * </tr>
+ * <?endforeach?>
+ * </table>
+ *
+ *
+ * @author     Rob Halff <info@rhalff.com>
+ * @version    $Revision: 563 $
+ * @copyright  Copyright (c) 2004 Rob Halff: LGPL - See LICENCE
+ * @package    propel.util
+ */
+class PropelPager {
+
+	private $recordCount;
+	private $pages;
+	private $peerClass;
+	private $peerSelectMethod;
+	private $peerCountMethod;
+	private $criteria;
+	private $countCriteria;
+	private $page;
+	private $rs = null;
+
+	/** @var        int Start row (offset) */
+	protected $start = 0;
+
+	/** @var        int Max rows to return (0 means all) */
+	protected $max = 0;
+
+	/**
+	 * Create a new Propel Pager.
+	 * @param      Criteria $c
+	 * @param      string $peerClass The name of the static Peer class.
+	 * @param      string $peerSelectMethod The name of the static method for selecting content from the Peer class.
+	 * @param      int $page The current page (1-based).
+	 * @param      int $rowsPerPage The number of rows that should be displayed per page.
+	 */
+	public function __construct($c = null, $peerClass = null, $peerSelectMethod = null, $page = 1, $rowsPerPage = 25)
+	{
+		if (!isset($c)) {
+			$c = new Criteria();
+		}
+		$this->setCriteria($c);
+		$this->setPeerClass($peerClass);
+		$this->setPeerSelectMethod($peerSelectMethod);
+		$this->guessPeerCountMethod();
+		$this->setPage($page);
+		$this->setRowsPerPage($rowsPerPage);
+	}
+
+	/**
+	 * Set the criteria for this pager.
+	 * @param      Criteria $c
+	 * @return     void
+	 */
+	public function setCriteria(Criteria $c)
+	{
+		$this->criteria = $c;
+	}
+
+	/**
+	 * Return the Criteria object for this pager.
+	 * @return     Criteria
+	 */
+	public function getCriteria()
+	{
+		return $this->criteria;
+	}
+
+	/**
+	 * Set the Peer Classname
+	 *
+	 * @param      string $class
+	 * @return     void
+	 */
+	public function setPeerClass($class)
+	{
+		$this->peerClass = $class;
+	}
+
+	/**
+	 * Return the Peer Classname.
+	 * @return     string
+	 */
+	public function getPeerClass()
+	{
+		return $this->peerClass;
+	}
+
+	/**
+	 * Set the Peer select method.
+	 * This exists for legacy support, please use setPeerSelectMethod().
+	 * @param      string $method The name of the static method to call on the Peer class.
+	 * @return     void
+	 * @see        setPeerSelectMethod()
+	 * @deprecated
+	 */
+	public function setPeerMethod($method)
+	{
+		$this->setPeerSelectMethod($method);
+	}
+
+	/**
+	 * Return the Peer select method.
+	 * This exists for legacy support, please use getPeerSelectMethod().
+	 * @return     string
+	 * @see        getPeerSelectMethod()
+	 * @deprecated
+	 */
+	public function getPeerMethod()
+	{
+		return $this->getPeerSelectMethod();
+	}
+
+	/**
+	 * Set the Peer select method.
+	 *
+	 * @param      string $method The name of the static method to call on the Peer class.
+	 * @return     void
+	 */
+	public function setPeerSelectMethod($method)
+	{
+		$this->peerSelectMethod = $method;
+	}
+
+	/**
+	 * Return the Peer select method.
+	 * @return     string
+	 */
+	public function getPeerSelectMethod()
+	{
+		return $this->peerSelectMethod;
+	}
+
+	/**
+	 * Sets the Count method.
+	 * This is set based on the Peer method, for example if Peer method is doSelectJoin*() then the
+	 * count method will be doCountJoin*().
+	 * @param      string $method The name of the static method to call on the Peer class.
+	 */
+	public function setPeerCountMethod($method)
+	{
+		$this->peerCountMethod = $method;
+	}
+
+	/**
+	 * Return the Peer count method.
+	 */
+	public function getPeerCountMethod()
+	{
+		return $this->peerCountMethod;
+	}
+
+	/**
+	 * Guesses the Peer count method based on the select method.
+	 */
+	private function guessPeerCountMethod()
+	{
+		$selectMethod = $this->getPeerSelectMethod();
+		if ($selectMethod == 'doSelect') {
+			$countMethod = 'doCount';
+		} elseif ( ($pos = stripos($selectMethod, 'doSelectJoin')) === 0) {
+			$countMethod = 'doCount' . substr($selectMethod, strlen('doSelect'));
+		} else {
+			// we will fall back to doCount() if we don't understand the join
+			// method; however, it probably won't be accurate.  Maybe triggering an error would
+			// be appropriate ...
+			$countMethod = 'doCount';
+		}
+		$this->setPeerCountMethod($countMethod);
+	}
+
+	/**
+	 * Get the paged resultset
+	 *
+	 * @return     mixed $rs
+	 */
+	public function getResult()
+	{
+		if (!isset($this->rs)) {
+			$this->doRs();
+		}
+
+		return $this->rs;
+	}
+
+	/**
+	 * Get the paged resultset
+	 *
+	 * Main method which creates a paged result set based on the criteria
+	 * and the requested peer select method.
+	 *
+	 */
+	private function doRs()
+	{
+		$this->rs = array();
+		$this->criteria->setOffset($this->start);
+		$this->criteria->setLimit($this->max);
+		$start = $this->start;
+		$total = $this->getTotalRecordCount();
+		$order = $this->criteria->getOrderByColumns();
+		if ($start < 0 || $start >= $total) return;
+		if (count($order)==1 && $total > 240 && $start > $total/2) {
+		  $c = clone $this->criteria;
+		  $start = $total - $start - $this->max;
+		  if ($start >= 0) $c->setOffset($start);
+		  else {
+		    $c->setOffset(0);
+		    $c->setLimit($start + $this->max);
+		  }
+		  $c->clearOrderByColumns();
+		  $params = explode(" ", $order[0]);
+		  if ($params[1] == Criteria::DESC) $c->addAscendingOrderByColumn($params[0]);
+		  else $c->addDescendingOrderByColumn($params[0]);
+		  $rs = call_user_func(array($this->getPeerClass(), $this->getPeerSelectMethod()), $c);
+		  while (!empty($rs)) array_push($this->rs, array_pop($rs));
+		}
+		else
+		$this->rs = call_user_func(array($this->getPeerClass(), $this->getPeerSelectMethod()), $this->criteria);
+	}
+
+	/**
+	 * Get the first page
+	 *
+	 * For now I can only think of returning 1 always.
+	 * It should probably return 0 if there are no pages
+	 *
+	 * @return     int 1
+	 */
+	public function getFirstPage()
+	{
+		return '1';
+	}
+
+	/**
+	 * Convenience method to indicate whether current page is the first page.
+	 *
+	 * @return     boolean
+	 */
+	public function atFirstPage()
+	{
+		return $this->getPage() == $this->getFirstPage();
+	}
+
+	/**
+	 * Get last page
+	 *
+	 * @return     int $lastPage
+	 */
+	public function getLastPage()
+	{
+		$totalPages = $this->getTotalPages();
+		if ($totalPages == 0) {
+			return 1;
+		} else {
+			return $totalPages;
+		}
+	}
+
+	/**
+	 * Convenience method to indicate whether current page is the last page.
+	 *
+	 * @return     boolean
+	 */
+	public function atLastPage()
+	{
+		return $this->getPage() == $this->getLastPage();
+	}
+
+	/**
+	 * get total pages
+	 *
+	 * @return     int $this->pages
+	 */
+	public function getTotalPages() {
+		if (!isset($this->pages)) {
+			$recordCount = $this->getTotalRecordCount();
+			if ($this->max > 0) {
+					$this->pages = ceil($recordCount/$this->max);
+			} else {
+					$this->pages = 0;
+			}
+		}
+		return $this->pages;
+	}
+
+	/**
+	 * get an array of previous id's
+	 *
+	 * @param      int $range
+	 * @return     array $links
+	 */
+	public function getPrevLinks($range = 5)
+	{
+		$total = $this->getTotalPages();
+		$start = $this->getPage() - 1;
+		$end = $this->getPage() - $range;
+		$first =  $this->getFirstPage();
+		$links = array();
+		for ($i=$start; $i>$end; $i--) {
+			if ($i < $first) {
+					break;
+			}
+			$links[] = $i;
+		}
+
+		return array_reverse($links);
+	}
+
+	/**
+	 * get an array of next id's
+	 *
+	 * @param      int $range
+	 * @return     array $links
+	 */
+	public function getNextLinks($range = 5)
+	{
+		$total = $this->getTotalPages();
+		$start = $this->getPage() + 1;
+		$end = $this->getPage() + $range;
+		$last =  $this->getLastPage();
+		$links = array();
+		for ($i=$start; $i<$end; $i++) {
+			if ($i > $last) {
+					break;
+			}
+			$links[] = $i;
+		}
+
+		return $links;
+	}
+
+	/**
+	 * Returns whether last page is complete
+	 *
+	 * @return     bool Last page complete or not
+	 */
+	public function isLastPageComplete()
+	{
+		return !($this->getTotalRecordCount() % $this->max);
+	}
+
+	/**
+	 * get previous id
+	 *
+	 * @return     mixed $prev
+	 */
+	public function getPrev() {
+		if ($this->getPage() != $this->getFirstPage()) {
+				$prev = $this->getPage() - 1;
+		} else {
+				$prev = false;
+		}
+		return $prev;
+	}
+
+	/**
+	 * get next id
+	 *
+	 * @return     mixed $next
+	 */
+	public function getNext() {
+		if ($this->getPage() != $this->getLastPage()) {
+				$next = $this->getPage() + 1;
+		} else {
+				$next = false;
+		}
+		return $next;
+	}
+
+	/**
+	 * Set the current page number (First page is 1).
+	 * @param      int $page
+	 * @return     void
+	 */
+	public function setPage($page)
+	{
+		$this->page = $page;
+		// (re-)calculate start rec
+		$this->calculateStart();
+	}
+
+	/**
+	 * Get current page.
+	 * @return     int
+	 */
+	public function getPage()
+	{
+		return $this->page;
+	}
+
+	/**
+	 * Set the number of rows per page.
+	 * @param      int $r
+	 */
+	public function setRowsPerPage($r)
+	{
+		$this->max = $r;
+		// (re-)calculate start rec
+		$this->calculateStart();
+	}
+
+	/**
+	 * Get number of rows per page.
+	 * @return     int
+	 */
+	public function getRowsPerPage()
+	{
+		return $this->max;
+	}
+
+	/**
+	 * Calculate startrow / max rows based on current page and rows-per-page.
+	 * @return     void
+	 */
+	private function calculateStart()
+	{
+		$this->start = ( ($this->page - 1) * $this->max );
+	}
+
+	/**
+	 * Gets the total number of (un-LIMITed) records.
+	 *
+	 * This method will perform a query that executes un-LIMITed query.
+	 *
+	 * @return     int Total number of records - disregarding page, maxrows, etc.
+	 */
+	public function getTotalRecordCount()
+	{
+				if (empty($this->recordCount)) {
+						$this->countCriteria = clone $this->criteria;
+						$this->countCriteria->setLimit(0);
+						$this->countCriteria->setOffset(0);
+
+						$this->recordCount = call_user_func(
+								        array(
+								                $this->getPeerClass(),
+												$this->getPeerCountMethod()
+								             ),
+								        $this->countCriteria
+								        );
+
+				}
+
+				return $this->recordCount;
+
+	}
+
+	/**
+	 * Sets the start row or offset.
+	 * @param      int $v
+	 */
+	public function setStart($v)
+	{
+		$this->start = $v;
+	}
+
+	/**
+	 * Sets max rows (limit).
+	 * @param      int $v
+	 * @return     void
+	 */
+	public function setMax($v)
+	{
+		$this->max = $v;
+	}
+
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel/validator/BasicValidator.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel/validator/BasicValidator.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel/validator/BasicValidator.php	(revision 19)
@@ -0,0 +1,46 @@
+<?php
+/*
+ *  $Id: BasicValidator.php 521 2007-01-05 13:29:36Z heltem $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://propel.phpdb.org>.
+ */
+
+/**
+ * Basic Validator interface.
+ *
+ * BasicValidator objects perform validation without any knowledge of column/table
+ * context.  They are simply given an input and some value and asked whether the input
+ * is valid.
+ *
+ * @author     Michael Aichler <aichler@mediacluster.de>
+ * @version    $Revision: 521 $
+ * @package    propel.validator
+ */
+interface BasicValidator
+{
+
+	/**
+	 * Determine whether a value meets the criteria specified
+	 *
+	 * @param      ValidatorMap $map A column map object for the column to be validated.
+	 * @param      string $str a <code>String</code> to be tested
+	 *
+	 * @return     mixed TRUE if valid, error message otherwise
+	 */
+	public function isValid(ValidatorMap $map, $str);
+
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel/validator/MatchValidator.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel/validator/MatchValidator.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel/validator/MatchValidator.php	(revision 19)
@@ -0,0 +1,79 @@
+<?php
+/*
+ *  $Id: MatchValidator.php 521 2007-01-05 13:29:36Z heltem $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://propel.phpdb.org>.
+ */
+
+/**
+ * A validator for regular expressions.
+ *
+ * This validator will return true, when the passed value *matches* the
+ * regular expression.
+ *
+ * ## This class replaces the former class MaskValidator ##
+ *
+ * If you do want to test if the value does *not* match an expression,
+ * you can use the MatchValidator class instead.
+ *
+ * Below is an example usage for your Propel xml schema file.
+ *
+ * <code>
+ *   <column name="email" type="VARCHAR" size="128" required="true" />
+ *   <validator column="username">
+ *     <!-- allow strings that match the email adress pattern -->
+ *     <rule
+ *       name="match"
+ *       value="/^([a-zA-Z0-9])+([\.a-zA-Z0-9_-])*@([a-zA-Z0-9])+(\.[a-zA-Z0-9_-]+)+$/"
+ *       message="Please enter a valid email address." />
+ *   </validator>
+ * </code>
+ *
+ * @author     Michael Aichler <aichler@mediacluster.de>
+ * @author     Hans Lellelid <hans@xmpl.org>
+ * @version    $Revision: 521 $
+ * @package    propel.validator
+ */
+class MatchValidator implements BasicValidator
+{
+	/**
+	 * Prepares the regular expression entered in the XML
+	 * for use with preg_match().
+	 * @param      string $exp
+	 * @return     string Prepared regular expession.
+	 */
+	private function prepareRegexp($exp)
+	{
+		// remove surrounding '/' marks so that they don't get escaped in next step
+		if ($exp{0} !== '/' || $exp{strlen($exp)-1} !== '/' ) {
+			$exp = '/' . $exp . '/';
+		}
+
+		// if they did not escape / chars; we do that for them
+		$exp = preg_replace('/([^\\\])\/([^$])/', '$1\/$2', $exp);
+
+		return $exp;
+	}
+
+	/**
+	 * Whether the passed string matches regular expression.
+	 */
+	public function isValid (ValidatorMap $map, $str)
+	{
+		return (preg_match($this->prepareRegexp($map->getValue()), $str) != 0);
+	}
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel/validator/MaxLengthValidator.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel/validator/MaxLengthValidator.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel/validator/MaxLengthValidator.php	(revision 19)
@@ -0,0 +1,50 @@
+<?php
+/*
+ *  $Id: MaxLengthValidator.php 521 2007-01-05 13:29:36Z heltem $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://propel.phpdb.org>.
+ */
+
+/**
+ * A validator for maximum string length.
+ *
+ * Below is an example usage for your Propel xml schema file.
+ *
+ * Note that if you have specified the size attribute in the column tag
+ * you do not have to specify it as value in the validator rule again as
+ * this is done automatically.
+ *
+ * <code>
+ *   <column name="username" type="VARCHAR" size="25" required="true" />
+ *
+ *   <validator column="username">
+ *     <rule name="maxLength" message="Passwort must be at least ${value} characters !" />
+ *   </validator>
+ * </code>
+ *
+ * @author     Michael Aichler <aichler@mediacluster.de>
+ * @version    $Revision: 521 $
+ * @package    propel.validator
+ */
+class MaxLengthValidator implements BasicValidator
+{
+
+  public function isValid (ValidatorMap $map, $str)
+  {
+	return strlen($str) <= intval($map->getValue());
+  }
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel/validator/MaxValueValidator.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel/validator/MaxValueValidator.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel/validator/MaxValueValidator.php	(revision 19)
@@ -0,0 +1,54 @@
+<?php
+/*
+ *  $Id: MaxValueValidator.php 521 2007-01-05 13:29:36Z heltem $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://propel.phpdb.org>.
+ */
+
+/**
+ * A validator for maximum values.
+ *
+ * Below is an example usage for your Propel xml schema file.
+ *
+ * <code>
+ *   <column name="articles" type="INTEGER" required="true" />
+ *
+ *   <validator column="articles">
+ *     <rule name="minValue" value="1"  message="Minimum value for selected articles is ${value} !" />
+ *     <rule name="maxValue" value="10"  message="Maximum value for selected articles is ${value} !" />
+ *   </validator>
+ * </code>
+ *
+ * @author     Michael Aichler <aichler@mediacluster.de>
+ * @version    $Revision: 521 $
+ * @package    propel.validator
+ */
+class MaxValueValidator implements BasicValidator
+{
+
+	/**
+	 * @see        BasicValidator::isValid()
+	 */
+	public function isValid (ValidatorMap $map, $value)
+	{
+		if (is_null($value) == false && is_numeric($value) == true) {
+			return intval($value) <= intval($map->getValue());
+		}
+
+		return false;
+	}
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel/validator/MinLengthValidator.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel/validator/MinLengthValidator.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel/validator/MinLengthValidator.php	(revision 19)
@@ -0,0 +1,47 @@
+<?php
+/*
+ *  $Id: MinLengthValidator.php 521 2007-01-05 13:29:36Z heltem $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://propel.phpdb.org>.
+ */
+
+/**
+ * A validator for minimum string length.
+ *
+ * <code>
+ *   <column name="password" type="VARCHAR" size="34" required="true" />
+ *
+ *   <validator column="password">
+ *     <rule name="minLength" value="5" message="Passwort must be at least ${value} characters !" />
+ *   </validator>
+ * </code>
+ *
+ * @author     Michael Aichler <aichler@mediacluster.de>
+ * @version    $Revision: 521 $
+ * @package    propel.validator
+ */
+class MinLengthValidator implements BasicValidator
+{
+
+	/**
+	 * @see        BasicValidator::isValid()
+	 */
+	public function isValid (ValidatorMap $map, $str)
+	{
+		return strlen($str) >= intval($map->getValue());
+	}
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel/validator/MinValueValidator.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel/validator/MinValueValidator.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel/validator/MinValueValidator.php	(revision 19)
@@ -0,0 +1,54 @@
+<?php
+/*
+ *  $Id: MinValueValidator.php 521 2007-01-05 13:29:36Z heltem $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://propel.phpdb.org>.
+ */
+
+/**
+ * A validator for minimum values.
+ *
+ * Below is an example usage for your Propel xml schema file.
+ *
+ * <code>
+ *   <column name="articles" type="INTEGER" required="true" />
+ *
+ *   <validator column="articles">
+ *     <rule name="minValue" value="1"  message="Minimum value for selected articles is ${value} !" />
+ *     <rule name="maxValue" value="10"  message="Maximum value for selected articles is ${value} !" />
+ *   </validator>
+ * </code>
+ *
+ * @author     Michael Aichler <aichler@mediacluster.de>
+ * @version    $Revision: 521 $
+ * @package    propel.validator
+ */
+class MinValueValidator implements BasicValidator
+{
+
+	/**
+	 * @see        BasicValidator::isValid()
+	 */
+	public function isValid (ValidatorMap $map, $value)
+	{
+	  if (is_null($value) == false && is_numeric($value)) {
+		  return intval($value) >= intval($map->getValue());
+	  }
+
+	  return false;
+	}
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel/validator/NotMatchValidator.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel/validator/NotMatchValidator.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel/validator/NotMatchValidator.php	(revision 19)
@@ -0,0 +1,77 @@
+<?php
+/*
+ *  $Id: NotMatchValidator.php 521 2007-01-05 13:29:36Z heltem $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://propel.phpdb.org>.
+ */
+
+/**
+ * A validator for regular expressions.
+ *
+ * This validator will return true, when the passed value does *not* match
+ * the regular expression.
+ *
+ * If you do want to test if the value *matches* an expression, you can use
+ * the MatchValidator class instead.
+ *
+ * Below is an example usage for your Propel xml schema file.
+ *
+ * <code>
+ *   <column name="ISBN" type="VARCHAR" size="20" required="true" />
+ *   <validator column="username">
+ *     <!-- disallow everything that's not a digit or minus -->
+ *     <rule
+ *       name="notMatch"
+ *       value="/[^\d-]+/"
+ *       message="Please enter a valid email adress." />
+ *   </validator>
+ * </code>
+ *
+ * @author     Michael Aichler <aichler@mediacluster.de>
+ * @author     Hans Lellelid <hans@xmpl.org>
+ * @version    $Revision: 521 $
+ * @package    propel.validator
+ */
+class NotMatchValidator implements BasicValidator
+{
+	/**
+	 * Prepares the regular expression entered in the XML
+	 * for use with preg_match().
+	 * @param      string $exp
+	 * @return     string Prepared regular expession.
+	 */
+	private function prepareRegexp($exp)
+	{
+		// remove surrounding '/' marks so that they don't get escaped in next step
+		if ($exp{0} !== '/' || $exp{strlen($exp)-1} !== '/' ) {
+			$exp = '/' . $exp . '/';
+		}
+
+		// if they did not escape / chars; we do that for them
+		$exp = preg_replace('/([^\\\])\/([^$])/', '$1\/$2', $exp);
+
+		return $exp;
+	}
+
+	/**
+	 * Whether the passed string matches regular expression.
+	 */
+	public function isValid (ValidatorMap $map, $str)
+	{
+		return (preg_match($this->prepareRegexp($map->getValue()), $str) == 0);
+	}
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel/validator/RequiredValidator.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel/validator/RequiredValidator.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel/validator/RequiredValidator.php	(revision 19)
@@ -0,0 +1,49 @@
+<?php
+/*
+ *  $Id: RequiredValidator.php 521 2007-01-05 13:29:36Z heltem $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://propel.phpdb.org>.
+ */
+
+/**
+ * A validator for required fields.
+ *
+ * Below is an example usage for your Propel xml schema file.
+ *
+ * <code>
+ *   <column name="username" type="VARCHAR" size="25" required="true" />
+ *
+ *   <validator column="username">
+ *     <rule name="required" message="Username is required." />
+ *   </validator>
+ * </code>
+ *
+ * @author     Michael Aichler <aichler@mediacluster.de>
+ * @version    $Revision: 521 $
+ * @package    propel.validator
+ */
+class RequiredValidator implements BasicValidator
+{
+
+	/**
+	 * @see        BasicValidator::isValid()
+	 */
+	public function isValid (ValidatorMap $map, $str)
+	{
+		return ($str !== null && $str !== "");
+	}
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel/validator/TypeValidator.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel/validator/TypeValidator.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel/validator/TypeValidator.php	(revision 19)
@@ -0,0 +1,44 @@
+<?php
+/*
+ *  $Id: TypeValidator.php 964 2008-02-10 20:42:38Z hans $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://propel.phpdb.org>.
+ */
+
+/**
+ * A validator for validating the (PHP) type of the value submitted.
+ *
+ * <code>
+ *   <column name="some_int" type="INTEGER" required="true"/>
+ *
+ *   <validator column="some_int">
+ *     <rule name="type" value="integer" message="Please specify an integer value for some_int column." />
+ *   </validator>
+ * </code>
+ *
+ * @author     Hans Lellelid <hans@xmpl.org>
+ * @version    $Revision: 964 $
+ * @package    propel.validator
+ */
+class TypeValidator implements BasicValidator
+{
+
+	public function isValid(ValidatorMap $map, $value)
+	{
+		return (gettype($value) == $map->getValue());
+	}
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel/validator/UniqueValidator.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel/validator/UniqueValidator.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel/validator/UniqueValidator.php	(revision 19)
@@ -0,0 +1,61 @@
+<?php
+/*
+ *  $Id: UniqueValidator.php 989 2008-03-11 14:29:30Z heltem $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://propel.phpdb.org>.
+ */
+
+/**
+ * A validator for unique column names.
+ *
+ * <code>
+ *   <column name="username" type="VARCHAR" size="25" required="true" />
+ *
+ *   <validator column="username">
+ *     <rule name="unique" message="Username already exists !" />
+ *   </validator>
+ * </code>
+ *
+ * @author     Michael Aichler <aichler@mediacluster.de>
+ * @version    $Revision: 989 $
+ * @package    propel.validator
+ */
+class UniqueValidator implements BasicValidator
+{
+
+	/**
+	 * @see        BasicValidator::isValid()
+	 */
+	public function isValid (ValidatorMap $map, $str)
+	{
+		$column = $map->getColumn();
+
+		$c = new Criteria();
+		$c->add($column->getFullyQualifiedName(), $str, Criteria::EQUAL);
+
+		$isValid = false;
+
+		$table = $column->getTable()->getPhpName();
+
+		$clazz = $table . 'Peer';
+		$count = call_user_func(array($clazz, 'doCount'), $c);
+
+		$isValid = ($count === 0);
+
+		return $isValid;
+	}
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel/validator/ValidValuesValidator.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel/validator/ValidValuesValidator.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel/validator/ValidValuesValidator.php	(revision 19)
@@ -0,0 +1,44 @@
+<?php
+/*
+ *  $Id: ValidValuesValidator.php 964 2008-02-10 20:42:38Z hans $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://propel.phpdb.org>.
+ */
+
+/**
+ * A validator for valid values (e.g. for enum fields)
+ *
+ * <code>
+ *   <column name="address_type" type="VARCHAR" required="true" default="delivery" />
+ *
+ *   <validator column="address_type">
+ *     <rule name="validValues" value="account|delivery" message="Please select a valid address type." />
+ *   </validator>
+ * </code>
+ *
+ * @author     Michael Aichler <aichler@mediacluster.de>
+ * @version    $Revision: 964 $
+ * @package    propel.validator
+ */
+class ValidValuesValidator implements BasicValidator
+{
+
+	public function isValid (ValidatorMap $map, $str)
+	{
+		return in_array($str, preg_split("/[|,]/", $map->getValue()));
+	}
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel/validator/ValidationFailed.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel/validator/ValidationFailed.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/lib/vendor/propel/validator/ValidationFailed.php	(revision 19)
@@ -0,0 +1,126 @@
+<?php
+/*
+ *  $Id: ValidationFailed.php 521 2007-01-05 13:29:36Z heltem $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information please see
+ * <http://propel.phpdb.org>.
+ */
+
+
+/**
+ * Simple class that serves as a container for any information about a failed validation.
+ *
+ * Currently this class stores the qualified column name (e.g. tablename.COLUMN_NAME) and
+ * the message that should be displayed to the user.
+ *
+ * An array of these objects will be returned by BasePeer::doValidate() if validation
+ * failed.
+ *
+ * @author     Hans Lellelid <hans@xmpl.org>
+ * @version    $Revision: 521 $
+ * @package    propel.validator
+ * @see        BasePeer::doValidate()
+ */
+class ValidationFailed {
+
+	/** Column name in tablename.COLUMN_NAME format */
+	private $colname;
+
+	/** Message to display to user. */
+	private $message;
+
+	/** Validator object that caused this to fail. */
+	private $validator;
+
+	/**
+	 * Construct a new ValidationFailed object.
+	 * @param      string $colname Column name.
+	 * @param      string $message Message to display to user.
+	 * @param      object $validator The Validator that caused this column to fail.
+	 */
+	public function __construct($colname, $message, $validator = null)
+	{
+		$this->colname = $colname;
+		$this->message = $message;
+		$this->validator = $validator;
+	}
+
+	/**
+	 * Set the column name.
+	 * @param      string $v
+	 */
+	public function setColumn($v)
+	{
+		$this->colname = $v;
+	}
+
+	/**
+	 * Gets the column name.
+	 * @return     string Qualified column name (tablename.COLUMN_NAME)
+	 */
+	public function getColumn()
+	{
+		return $this->colname;
+	}
+
+	/**
+	 * Set the message for the validation failure.
+	 * @param      string $v
+	 */
+	public function setMessage($v)
+	{
+		$this->message = $v;
+	}
+
+	/**
+	 * Gets the message for the validation failure.
+	 * @return     string
+	 */
+	public function getMessage()
+	{
+		return $this->message;
+	}
+
+	/**
+	 * Set the validator object that caused this to fail.
+	 * @param      object $v
+	 */
+	public function setValidator($v)
+	{
+		$this->validator = $v;
+	}
+
+	/**
+	 * Gets the validator object that caused this to fail.
+	 * @return     object
+	 */
+	public function getValidator()
+	{
+		return $this->validator;
+	}
+
+	/**
+	 * "magic" method to get string represenation of object.
+	 * Maybe someday PHP5 will support the invoking this method automatically
+	 * on (string) cast.  Until then it's pretty useless.
+	 * @return     string
+	 */
+	public function __toString()
+	{
+		return $this->getMessage();
+	}
+
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/package.xml
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/package.xml	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/package.xml	(revision 19)
@@ -0,0 +1,1048 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<package packagerversion="1.6.1" version="2.0" xmlns="http://pear.php.net/dtd/package-2.0" xmlns:tasks="http://pear.php.net/dtd/tasks-1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://pear.php.net/dtd/tasks-1.0
+    http://pear.php.net/dtd/tasks-1.0.xsd
+    http://pear.php.net/dtd/package-2.0
+    http://pear.php.net/dtd/package-2.0.xsd">
+ <name>sfPropel13Plugin</name>
+ <channel>pear.symfony-project.com</channel>
+ <summary>Propel 1.3 (beta) functionality in symfony 1.0</summary>
+ <description>sfPropel13Plugin instroduces Propel 1.3 (beta) functionality into symfony 1.0. It *should* work without modifying
+any core libraries, thus offering greater stability (despite being beta, it&apos;s now using PDO instead of Creole), and
+immensely improved performance.</description>
+ <lead>
+  <name>Joshua May</name>
+  <user>notjosh</user>
+  <email>josh@notjosh.com</email>
+  <active>yes</active>
+ </lead>
+ <date>2008-05-28</date>
+ <time>23:16:01</time>
+ <version>
+  <release>0.6.0</release>
+  <api>0.6.0</api>
+ </version>
+ <stability>
+  <release>beta</release>
+  <api>beta</api>
+ </stability>
+ <license uri="http://www.symfony-project.com/license">MIT License</license>
+ <notes>--</notes>
+ <contents>
+  <dir baseinstalldir="/" name="/">
+   <dir name="config">
+    <file name="config.php" role="php" />
+   </dir> <!-- /config -->
+   <dir name="data">
+    <dir name="generator">
+     <dir name="sfPropelAdmin">
+      <dir name="default">
+       <dir name="skeleton">
+        <dir name="actions">
+         <file name="actions.class.php" role="php" />
+        </dir> <!-- /data/generator/sfPropelAdmin/default/skeleton/actions -->
+        <dir name="config">
+         <file name="generator.yml" role="data" />
+        </dir> <!-- /data/generator/sfPropelAdmin/default/skeleton/config -->
+       </dir> <!-- /data/generator/sfPropelAdmin/default/skeleton -->
+       <dir name="template">
+        <dir name="actions">
+         <file name="actions.class.php" role="php" />
+        </dir> <!-- /data/generator/sfPropelAdmin/default/template/actions -->
+        <dir name="templates">
+         <file name="editSuccess.php" role="php" />
+         <file name="listSuccess.php" role="php" />
+         <file name="_edit_actions.php" role="php" />
+         <file name="_edit_footer.php" role="php" />
+         <file name="_edit_form.php" role="php" />
+         <file name="_edit_header.php" role="php" />
+         <file name="_edit_messages.php" role="php" />
+         <file name="_filters.php" role="php" />
+         <file name="_list.php" role="php" />
+         <file name="_list_actions.php" role="php" />
+         <file name="_list_batch_actions.php" role="php" />
+         <file name="_list_footer.php" role="php" />
+         <file name="_list_header.php" role="php" />
+         <file name="_list_messages.php" role="php" />
+         <file name="_list_td_actions.php" role="php" />
+         <file name="_list_td_batch_actions.php" role="php" />
+         <file name="_list_td_stacked.php" role="php" />
+         <file name="_list_td_tabular.php" role="php" />
+         <file name="_list_th_stacked.php" role="php" />
+         <file name="_list_th_tabular.php" role="php" />
+        </dir> <!-- /data/generator/sfPropelAdmin/default/template/templates -->
+       </dir> <!-- /data/generator/sfPropelAdmin/default/template -->
+      </dir> <!-- /data/generator/sfPropelAdmin/default -->
+     </dir> <!-- /data/generator/sfPropelAdmin -->
+     <dir name="sfPropelCrud">
+      <dir name="default">
+       <dir name="skeleton">
+        <dir name="actions">
+         <file name="actions.class.php" role="php" />
+        </dir> <!-- /data/generator/sfPropelCrud/default/skeleton/actions -->
+        <dir name="config">
+         <file name="generator.yml" role="data" />
+        </dir> <!-- /data/generator/sfPropelCrud/default/skeleton/config -->
+       </dir> <!-- /data/generator/sfPropelCrud/default/skeleton -->
+       <dir name="template">
+        <dir name="actions">
+         <file name="actions.class.php" role="php" />
+        </dir> <!-- /data/generator/sfPropelCrud/default/template/actions -->
+        <dir name="templates">
+         <file name="editSuccess.php" role="php" />
+         <file name="listSuccess.php" role="php" />
+         <file name="showSuccess.php" role="php" />
+        </dir> <!-- /data/generator/sfPropelCrud/default/template/templates -->
+       </dir> <!-- /data/generator/sfPropelCrud/default/template -->
+      </dir> <!-- /data/generator/sfPropelCrud/default -->
+     </dir> <!-- /data/generator/sfPropelCrud -->
+    </dir> <!-- /data/generator -->
+    <dir name="tasks">
+     <file name="sfPakePropel13.php" role="php" />
+     <file name="sfPakePropel13AdminGenerator.php" role="php" />
+     <file name="sfPakePropel13CrudGenerator.php" role="php" />
+    </dir> <!-- /data/tasks -->
+   </dir> <!-- /data -->
+   <dir name="lib">
+    <dir name="propel">
+     <dir name="builder">
+      <file name="SfObjectBuilder.php" role="php" />
+      <file name="SfPeerBuilder.php" role="php" />
+     </dir> <!-- /lib/propel/builder -->
+     <dir name="database">
+      <file name="sfPropel13Database.class.php" role="php" />
+     </dir> <!-- /lib/propel/database -->
+     <dir name="generator">
+      <file name="sfPropel13AdminGenerator.class.php" role="php" />
+      <file name="sfPropel13CrudGenerator.class.php" role="php" />
+     </dir> <!-- /lib/propel/generator -->
+     <file name="sfPropel13Autoload.php" role="php" />
+     <file name="sfPropel13Data.class.php" role="php" />
+     <file name="sfPropel13LogWrapper.class.php" role="php" />
+    </dir> <!-- /lib/propel -->
+    <dir name="vendor">
+     <dir name="phing">
+      <dir name="bin">
+       <file name="pear-phing" role="data" />
+       <file name="pear-phing.bat" role="data" />
+       <file name="phing" role="data" />
+       <file name="phing.bat" role="data" />
+       <file name="phing.php" role="php" />
+      </dir> <!-- /lib/vendor/phing/bin -->
+      <dir name="classes">
+       <dir name="phing">
+        <dir name="filters">
+         <dir name="util">
+          <file name="ChainReaderHelper.php" role="php" />
+          <file name="IniFileTokenReader.php" role="php" />
+         </dir> <!-- /lib/vendor/phing/classes/phing/filters/util -->
+         <file name="BaseFilterReader.php" role="php" />
+         <file name="BaseParamFilterReader.php" role="php" />
+         <file name="ChainableReader.php" role="php" />
+         <file name="ExpandProperties.php" role="php" />
+         <file name="HeadFilter.php" role="php" />
+         <file name="LineContains.php" role="php" />
+         <file name="LineContainsRegexp.php" role="php" />
+         <file name="PrefixLines.php" role="php" />
+         <file name="ReplaceRegexp.php" role="php" />
+         <file name="ReplaceTokens.php" role="php" />
+         <file name="StripLineBreaks.php" role="php" />
+         <file name="StripLineComments.php" role="php" />
+         <file name="StripPhpComments.php" role="php" />
+         <file name="StripWhitespace.php" role="php" />
+         <file name="TabToSpaces.php" role="php" />
+         <file name="TailFilter.php" role="php" />
+         <file name="TidyFilter.php" role="php" />
+         <file name="TranslateGettext.php" role="php" />
+         <file name="XincludeFilter.php" role="php" />
+         <file name="XsltFilter.php" role="php" />
+        </dir> <!-- /lib/vendor/phing/classes/phing/filters -->
+        <dir name="input">
+         <file name="DefaultInputHandler.php" role="php" />
+         <file name="InputHandler.php" role="php" />
+         <file name="InputRequest.php" role="php" />
+         <file name="MultipleChoiceInputRequest.php" role="php" />
+         <file name="PropertyFileInputHandler.php" role="php" />
+         <file name="YesNoInputRequest.php" role="php" />
+        </dir> <!-- /lib/vendor/phing/classes/phing/input -->
+        <dir name="lib">
+         <file name="Capsule.php" role="php" />
+         <file name="Zip.php" role="php" />
+        </dir> <!-- /lib/vendor/phing/classes/phing/lib -->
+        <dir name="listener">
+         <file name="AnsiColorLogger.php" role="php" />
+         <file name="DefaultLogger.php" role="php" />
+         <file name="defaults.properties" role="data" />
+         <file name="NoBannerLogger.php" role="php" />
+         <file name="PearLogListener.php" role="php" />
+         <file name="StreamRequiredBuildLogger.php" role="php" />
+         <file name="XmlLogger.php" role="php" />
+        </dir> <!-- /lib/vendor/phing/classes/phing/listener -->
+        <dir name="mappers">
+         <file name="FileNameMapper.php" role="php" />
+         <file name="FlattenMapper.php" role="php" />
+         <file name="GlobMapper.php" role="php" />
+         <file name="IdentityMapper.php" role="php" />
+         <file name="MergeMapper.php" role="php" />
+         <file name="RegexpMapper.php" role="php" />
+        </dir> <!-- /lib/vendor/phing/classes/phing/mappers -->
+        <dir name="parser">
+         <file name="AbstractHandler.php" role="php" />
+         <file name="AbstractSAXParser.php" role="php" />
+         <file name="DataTypeHandler.php" role="php" />
+         <file name="ExpatParseException.php" role="php" />
+         <file name="ExpatParser.php" role="php" />
+         <file name="Location.php" role="php" />
+         <file name="NestedElementHandler.php" role="php" />
+         <file name="ProjectConfigurator.php" role="php" />
+         <file name="ProjectHandler.php" role="php" />
+         <file name="RootHandler.php" role="php" />
+         <file name="TargetHandler.php" role="php" />
+         <file name="TaskHandler.php" role="php" />
+        </dir> <!-- /lib/vendor/phing/classes/phing/parser -->
+        <dir name="system">
+         <dir name="io">
+          <file name="BufferedReader.php" role="php" />
+          <file name="BufferedWriter.php" role="php" />
+          <file name="ConsoleReader.php" role="php" />
+          <file name="FileInputStream.php" role="php" />
+          <file name="FileOutputStream.php" role="php" />
+          <file name="FileReader.php" role="php" />
+          <file name="FileSystem.php" role="php" />
+          <file name="FileWriter.php" role="php" />
+          <file name="FilterReader.php" role="php" />
+          <file name="InputStream.php" role="php" />
+          <file name="InputStreamReader.php" role="php" />
+          <file name="IOException.php" role="php" />
+          <file name="OutputStream.php" role="php" />
+          <file name="OutputStreamWriter.php" role="php" />
+          <file name="PhingFile.php" role="php" />
+          <file name="Reader.php" role="php" />
+          <file name="StringReader.php" role="php" />
+          <file name="UnixFileSystem.php" role="php" />
+          <file name="Win32FileSystem.php" role="php" />
+          <file name="WinNTFileSystem.php" role="php" />
+          <file name="Writer.php" role="php" />
+         </dir> <!-- /lib/vendor/phing/classes/phing/system/io -->
+         <dir name="lang">
+          <file name="Character.php" role="php" />
+          <file name="EventObject.php" role="php" />
+          <file name="FileNotFoundException.php" role="php" />
+          <file name="NullPointerException.php" role="php" />
+          <file name="SecurityException.php" role="php" />
+         </dir> <!-- /lib/vendor/phing/classes/phing/system/lang -->
+         <dir name="util">
+          <file name="Message.php" role="php" />
+          <file name="Properties.php" role="php" />
+          <file name="Register.php" role="php" />
+          <file name="Timer.php" role="php" />
+         </dir> <!-- /lib/vendor/phing/classes/phing/system/util -->
+        </dir> <!-- /lib/vendor/phing/classes/phing/system -->
+        <dir name="tasks">
+         <dir name="ext">
+          <dir name="coverage">
+           <file name="CoverageMerger.php" role="php" />
+           <file name="CoverageMergerTask.php" role="php" />
+           <file name="CoverageReportTask.php" role="php" />
+           <file name="CoverageReportTransformer.php" role="php" />
+           <file name="CoverageSetupTask.php" role="php" />
+          </dir> <!-- /lib/vendor/phing/classes/phing/tasks/ext/coverage -->
+          <dir name="creole">
+           <file name="CreoleSQLExecTask.php" role="php" />
+           <file name="CreoleTask.php" role="php" />
+          </dir> <!-- /lib/vendor/phing/classes/phing/tasks/ext/creole -->
+          <dir name="dbdeploy">
+           <file name="DbDeployTask.php" role="php" />
+           <file name="DbmsSyntax.php" role="php" />
+           <file name="DbmsSyntaxFactory.php" role="php" />
+           <file name="DbmsSyntaxMsSql.php" role="php" />
+           <file name="DbmsSyntaxMysql.php" role="php" />
+           <file name="DbmsSyntaxSQLite.php" role="php" />
+          </dir> <!-- /lib/vendor/phing/classes/phing/tasks/ext/dbdeploy -->
+          <dir name="ioncube">
+           <file name="IoncubeComment.php" role="php" />
+           <file name="IoncubeEncoderTask.php" role="php" />
+           <file name="IoncubeLicenseTask.php" role="php" />
+          </dir> <!-- /lib/vendor/phing/classes/phing/tasks/ext/ioncube -->
+          <dir name="pdo">
+           <file name="PDOResultFormatter.php" role="php" />
+           <file name="PDOSQLExecFormatterElement.php" role="php" />
+           <file name="PDOSQLExecTask.php" role="php" />
+           <file name="PDOTask.php" role="php" />
+           <file name="PlainPDOResultFormatter.php" role="php" />
+           <file name="XMLPDOResultFormatter.php" role="php" />
+          </dir> <!-- /lib/vendor/phing/classes/phing/tasks/ext/pdo -->
+          <dir name="pearpackage">
+           <file name="Fileset.php" role="php" />
+          </dir> <!-- /lib/vendor/phing/classes/phing/tasks/ext/pearpackage -->
+          <dir name="phpdoc">
+           <file name="PhingPhpDocumentorSetup.php" role="php" />
+           <file name="PhpDocumentorExternalTask.php" role="php" />
+           <file name="PhpDocumentorTask.php" role="php" />
+          </dir> <!-- /lib/vendor/phing/classes/phing/tasks/ext/phpdoc -->
+          <dir name="phpunit">
+           <dir name="phpunit2">
+            <file name="PHPUnit2ResultFormatter.php" role="php" />
+            <file name="PlainPHPUnit2ResultFormatter.php" role="php" />
+            <file name="SummaryPHPUnit2ResultFormatter.php" role="php" />
+            <file name="XMLPHPUnit2ResultFormatter.php" role="php" />
+           </dir> <!-- /lib/vendor/phing/classes/phing/tasks/ext/phpunit/phpunit2 -->
+           <dir name="phpunit3">
+            <file name="PHPUnit3ResultFormatter.php" role="php" />
+            <file name="PlainPHPUnit3ResultFormatter.php" role="php" />
+            <file name="SummaryPHPUnit3ResultFormatter.php" role="php" />
+            <file name="XMLPHPUnit3ResultFormatter.php" role="php" />
+           </dir> <!-- /lib/vendor/phing/classes/phing/tasks/ext/phpunit/phpunit3 -->
+           <file name="BatchTest.php" role="php" />
+           <file name="FormatterElement.php" role="php" />
+           <file name="PHPUnitReportTask.php" role="php" />
+           <file name="PHPUnitTask.php" role="php" />
+           <file name="PHPUnitTestRunner.php" role="php" />
+           <file name="PHPUnitUtil.php" role="php" />
+          </dir> <!-- /lib/vendor/phing/classes/phing/tasks/ext/phpunit -->
+          <dir name="simpletest">
+           <file name="SimpleTestCountResultFormatter.php" role="php" />
+           <file name="SimpleTestFormatterElement.php" role="php" />
+           <file name="SimpleTestPlainResultFormatter.php" role="php" />
+           <file name="SimpleTestResultFormatter.php" role="php" />
+           <file name="SimpleTestSummaryResultFormatter.php" role="php" />
+           <file name="SimpleTestTask.php" role="php" />
+          </dir> <!-- /lib/vendor/phing/classes/phing/tasks/ext/simpletest -->
+          <dir name="svn">
+           <file name="SvnBaseTask.php" role="php" />
+           <file name="SvnCheckoutTask.php" role="php" />
+           <file name="SvnExportTask.php" role="php" />
+           <file name="SvnLastRevisionTask.php" role="php" />
+           <file name="SvnUpdateTask.php" role="php" />
+          </dir> <!-- /lib/vendor/phing/classes/phing/tasks/ext/svn -->
+          <file name="CapsuleTask.php" role="php" />
+          <file name="ExtractBaseTask.php" role="php" />
+          <file name="FtpDeployTask.php" role="php" />
+          <file name="JslLintTask.php" role="php" />
+          <file name="MailTask.php" role="php" />
+          <file name="ManifestTask.php" role="php" />
+          <file name="PackageAsPathTask.php" role="php" />
+          <file name="PearPackage2Task.php" role="php" />
+          <file name="PearPackageTask.php" role="php" />
+          <file name="PhpCodeSnifferTask.php" role="php" />
+          <file name="PhpLintTask.php" role="php" />
+          <file name="ScpSendTask.php" role="php" />
+          <file name="SmartyTask.php" role="php" />
+          <file name="TarTask.php" role="php" />
+          <file name="UntarTask.php" role="php" />
+          <file name="UnzipTask.php" role="php" />
+          <file name="XmlLintTask.php" role="php" />
+          <file name="ZendCodeAnalyzerTask.php" role="php" />
+          <file name="ZipTask.php" role="php" />
+         </dir> <!-- /lib/vendor/phing/classes/phing/tasks/ext -->
+         <dir name="system">
+          <dir name="condition">
+           <file name="AndCondition.php" role="php" />
+           <file name="Condition.php" role="php" />
+           <file name="ConditionBase.php" role="php" />
+           <file name="ContainsCondition.php" role="php" />
+           <file name="EqualsCondition.php" role="php" />
+           <file name="IsFalseCondition.php" role="php" />
+           <file name="IsSetCondition.php" role="php" />
+           <file name="IsTrueCondition.php" role="php" />
+           <file name="NotCondition.php" role="php" />
+           <file name="OrCondition.php" role="php" />
+           <file name="OsCondition.php" role="php" />
+           <file name="ReferenceExistsCondition.php" role="php" />
+          </dir> <!-- /lib/vendor/phing/classes/phing/tasks/system/condition -->
+          <file name="AdhocTask.php" role="php" />
+          <file name="AdhocTaskdefTask.php" role="php" />
+          <file name="AdhocTypedefTask.php" role="php" />
+          <file name="AppendTask.php" role="php" />
+          <file name="AvailableTask.php" role="php" />
+          <file name="ChmodTask.php" role="php" />
+          <file name="ChownTask.php" role="php" />
+          <file name="ConditionTask.php" role="php" />
+          <file name="CopyTask.php" role="php" />
+          <file name="CvsPassTask.php" role="php" />
+          <file name="CvsTask.php" role="php" />
+          <file name="DeleteTask.php" role="php" />
+          <file name="EchoTask.php" role="php" />
+          <file name="ExecTask.php" role="php" />
+          <file name="ExitTask.php" role="php" />
+          <file name="ForeachTask.php" role="php" />
+          <file name="IfTask.php" role="php" />
+          <file name="IncludePathTask.php" role="php" />
+          <file name="InputTask.php" role="php" />
+          <file name="MatchingTask.php" role="php" />
+          <file name="MkdirTask.php" role="php" />
+          <file name="MoveTask.php" role="php" />
+          <file name="PhingCallTask.php" role="php" />
+          <file name="PhingTask.php" role="php" />
+          <file name="PhpEvalTask.php" role="php" />
+          <file name="PropertyPromptTask.php" role="php" />
+          <file name="PropertyTask.php" role="php" />
+          <file name="ReflexiveTask.php" role="php" />
+          <file name="ResolvePathTask.php" role="php" />
+          <file name="SequentialTask.php" role="php" />
+          <file name="TaskdefTask.php" role="php" />
+          <file name="TouchTask.php" role="php" />
+          <file name="TstampTask.php" role="php" />
+          <file name="TypedefTask.php" role="php" />
+          <file name="UpToDateTask.php" role="php" />
+          <file name="WarnTask.php" role="php" />
+          <file name="XsltTask.php" role="php" />
+         </dir> <!-- /lib/vendor/phing/classes/phing/tasks/system -->
+         <file name="defaults.properties" role="data" />
+        </dir> <!-- /lib/vendor/phing/classes/phing/tasks -->
+        <dir name="types">
+         <dir name="selectors">
+          <file name="AndSelector.php" role="php" />
+          <file name="BaseExtendSelector.php" role="php" />
+          <file name="BaseSelector.php" role="php" />
+          <file name="BaseSelectorContainer.php" role="php" />
+          <file name="ContainsRegexpSelector.php" role="php" />
+          <file name="ContainsSelector.php" role="php" />
+          <file name="DateSelector.php" role="php" />
+          <file name="DependSelector.php" role="php" />
+          <file name="DepthSelector.php" role="php" />
+          <file name="ExtendFileSelector.php" role="php" />
+          <file name="ExtendSelector.php" role="php" />
+          <file name="FilenameSelector.php" role="php" />
+          <file name="FileSelector.php" role="php" />
+          <file name="MajoritySelector.php" role="php" />
+          <file name="NoneSelector.php" role="php" />
+          <file name="NotSelector.php" role="php" />
+          <file name="OrSelector.php" role="php" />
+          <file name="PresentSelector.php" role="php" />
+          <file name="SelectorContainer.php" role="php" />
+          <file name="SelectorScanner.php" role="php" />
+          <file name="SelectorUtils.php" role="php" />
+          <file name="SelectSelector.php" role="php" />
+          <file name="SizeSelector.php" role="php" />
+          <file name="TypeSelector.php" role="php" />
+         </dir> <!-- /lib/vendor/phing/classes/phing/types/selectors -->
+         <file name="AbstractFileSet.php" role="php" />
+         <file name="Commandline.php" role="php" />
+         <file name="DataType.php" role="php" />
+         <file name="defaults.properties" role="data" />
+         <file name="Description.php" role="php" />
+         <file name="DirSet.php" role="php" />
+         <file name="FileList.php" role="php" />
+         <file name="FileSet.php" role="php" />
+         <file name="FilterChain.php" role="php" />
+         <file name="Mapper.php" role="php" />
+         <file name="Parameter.php" role="php" />
+         <file name="Parameterizable.php" role="php" />
+         <file name="Path.php" role="php" />
+         <file name="PatternSet.php" role="php" />
+         <file name="PhingFilterReader.php" role="php" />
+         <file name="Reference.php" role="php" />
+         <file name="RegularExpression.php" role="php" />
+         <file name="TokenReader.php" role="php" />
+         <file name="TokenSource.php" role="php" />
+        </dir> <!-- /lib/vendor/phing/classes/phing/types -->
+        <dir name="util">
+         <dir name="regexp">
+          <file name="PregEngine.php" role="php" />
+          <file name="Regexp.php" role="php" />
+          <file name="RegexpEngine.php" role="php" />
+         </dir> <!-- /lib/vendor/phing/classes/phing/util/regexp -->
+         <file name="DirectoryScanner.php" role="php" />
+         <file name="ExtendedFileStream.php" role="php" />
+         <file name="FileUtils.php" role="php" />
+         <file name="LogWriter.php" role="php" />
+         <file name="PathTokenizer.php" role="php" />
+         <file name="SourceFileScanner.php" role="php" />
+         <file name="StringHelper.php" role="php" />
+        </dir> <!-- /lib/vendor/phing/classes/phing/util -->
+        <file name="BuildEvent.php" role="php" />
+        <file name="BuildException.php" role="php" />
+        <file name="BuildListener.php" role="php" />
+        <file name="BuildLogger.php" role="php" />
+        <file name="ConfigurationException.php" role="php" />
+        <file name="IntrospectionHelper.php" role="php" />
+        <file name="Phing.php" role="php" />
+        <file name="Project.php" role="php" />
+        <file name="ProjectComponent.php" role="php" />
+        <file name="RuntimeConfigurable.php" role="php" />
+        <file name="Target.php" role="php" />
+        <file name="Task.php" role="php" />
+        <file name="TaskAdapter.php" role="php" />
+        <file name="TaskContainer.php" role="php" />
+        <file name="UnknownElement.php" role="php" />
+       </dir> <!-- /lib/vendor/phing/classes/phing -->
+      </dir> <!-- /lib/vendor/phing/classes -->
+      <dir name="docs">
+       <dir name="docsystem">
+        <dir name="html">
+         <file name="FrameToCBottom.html" role="doc" />
+         <file name="FrameToCTop.html" role="doc" />
+         <file name="StandardToCBottom.html" role="doc" />
+         <file name="StandardToCTop.html" role="doc" />
+        </dir> <!-- /lib/vendor/phing/docs/docsystem/html -->
+        <dir name="xsl">
+         <file name="Chapters.xsl" role="data" />
+         <file name="Toc.xsl" role="data" />
+        </dir> <!-- /lib/vendor/phing/docs/docsystem/xsl -->
+       </dir> <!-- /lib/vendor/phing/docs/docsystem -->
+       <dir name="example">
+        <dir name="src">
+         <file name="HelloWorld.php" role="php" />
+         <file name="HelloWorldTest.php" role="php" />
+        </dir> <!-- /lib/vendor/phing/docs/example/src -->
+        <file name="build.xml" role="data" />
+       </dir> <!-- /lib/vendor/phing/docs/example -->
+       <dir name="phing_guide">
+        <dir name="book">
+         <dir name="chapters">
+          <dir name="appendixes">
+           <file name="AppendixA-FactSheet.html" role="doc" />
+           <file name="AppendixB-CoreTasks.html" role="doc" />
+           <file name="AppendixC-OptionalTasks.html" role="doc" />
+           <file name="AppendixD-CoreTypes.html" role="doc" />
+           <file name="AppendixD2-CoreFilters.html" role="doc" />
+           <file name="AppendixD3-CoreMappers.html" role="doc" />
+           <file name="AppendixD4-CoreSelectors.html" role="doc" />
+           <file name="AppendixE-ProjectComponents.html" role="doc" />
+           <file name="AppendixF-FileFormats.html" role="doc" />
+          </dir> <!-- /lib/vendor/phing/docs/phing_guide/book/chapters/appendixes -->
+          <file name="AboutThisBook.html" role="doc" />
+          <file name="BasicConcepts.html" role="doc" />
+          <file name="Bibliography.html" role="doc" />
+          <file name="ExtendingPhing.html" role="doc" />
+          <file name="GettingStarted.html" role="doc" />
+          <file name="Introduction.html" role="doc" />
+          <file name="ProjectComponents.html" role="doc" />
+          <file name="Setup.html" role="doc" />
+         </dir> <!-- /lib/vendor/phing/docs/phing_guide/book/chapters -->
+         <dir name="css">
+          <file name="Documentation.css" role="data" />
+          <file name="FrameToc.css" role="data" />
+         </dir> <!-- /lib/vendor/phing/docs/phing_guide/book/css -->
+         <dir name="frame">
+          <file name="DocFrame.html" role="doc" />
+          <file name="NavTop.html" role="doc" />
+          <file name="TitlePage.html" role="doc" />
+         </dir> <!-- /lib/vendor/phing/docs/phing_guide/book/frame -->
+         <dir name="images">
+          <file name="ExtendingTree.gif" role="data" />
+          <file name="logo-pdfsm.png" role="data" />
+          <file name="logo.png" role="data" />
+          <file name="README.txt" role="data" />
+         </dir> <!-- /lib/vendor/phing/docs/phing_guide/book/images -->
+         <dir name="js">
+          <file name="BookNav.js" role="data" />
+          <file name="Chapters.js" role="data" />
+         </dir> <!-- /lib/vendor/phing/docs/phing_guide/book/js -->
+         <dir name="toc">
+          <file name="FrameToC.html" role="doc" />
+          <file name="ToC.html" role="doc" />
+         </dir> <!-- /lib/vendor/phing/docs/phing_guide/book/toc -->
+         <file name="index.html" role="doc" />
+         <file name="PhingGuide.book" role="data" />
+        </dir> <!-- /lib/vendor/phing/docs/phing_guide/book -->
+        <dir name="export">
+         <file name="PhingGuide_en.pdf" role="data" />
+        </dir> <!-- /lib/vendor/phing/docs/phing_guide/export -->
+        <dir name="langs">
+         <dir name="de">
+          <file name="README.txt" role="data" />
+         </dir> <!-- /lib/vendor/phing/docs/phing_guide/langs/de -->
+         <dir name="fr">
+          <file name="README.txt" role="data" />
+         </dir> <!-- /lib/vendor/phing/docs/phing_guide/langs/fr -->
+         <dir name="pt_BR">
+          <file name="README.txt" role="data" />
+         </dir> <!-- /lib/vendor/phing/docs/phing_guide/langs/pt_BR -->
+        </dir> <!-- /lib/vendor/phing/docs/phing_guide/langs -->
+        <file name="build.xml" role="data" />
+       </dir> <!-- /lib/vendor/phing/docs/phing_guide -->
+      </dir> <!-- /lib/vendor/phing/docs -->
+      <dir name="etc">
+       <file name="coverage-frames.xsl" role="data" />
+       <file name="log.xsl" role="data" />
+       <file name="phpunit2-frames.xsl" role="data" />
+       <file name="phpunit2-noframes.xsl" role="data" />
+       <file name="str.replace.function.xsl" role="data" />
+       <file name="VERSION.TXT" role="data" />
+      </dir> <!-- /lib/vendor/phing/etc -->
+      <dir name="pear">
+       <file name="build.xml" role="data" />
+       <file name="BuildPhingPEARPackageTask.php" role="php" />
+      </dir> <!-- /lib/vendor/phing/pear -->
+      <dir name="test">
+       <dir name="classes">
+        <dir name="example">
+         <dir name="tasks">
+          <file name="TaskdefTestSimpleTask.php" role="php" />
+         </dir> <!-- /lib/vendor/phing/test/classes/example/tasks -->
+         <dir name="types">
+          <file name="TypedefTestType.php" role="php" />
+         </dir> <!-- /lib/vendor/phing/test/classes/example/types -->
+        </dir> <!-- /lib/vendor/phing/test/classes/example -->
+        <dir name="phing">
+         <dir name="filters">
+          <file name="LineContainsTest.php" role="php" />
+         </dir> <!-- /lib/vendor/phing/test/classes/phing/filters -->
+         <dir name="system">
+          <file name="FileOutputStreamTest.php" role="php" />
+         </dir> <!-- /lib/vendor/phing/test/classes/phing/system -->
+         <dir name="tasks">
+          <dir name="condition">
+           <file name="ContainsConditionTest.php" role="php" />
+           <file name="EqualsConditionTest.php" role="php" />
+          </dir> <!-- /lib/vendor/phing/test/classes/phing/tasks/condition -->
+          <file name="PropertyTaskTest.php" role="php" />
+          <file name="TypedefTaskTest.php" role="php" />
+         </dir> <!-- /lib/vendor/phing/test/classes/phing/tasks -->
+         <dir name="types">
+          <file name="AbstractFileSetTest.php" role="php" />
+          <file name="CommandlineTest.php" role="php" />
+          <file name="FileSetTest.php" role="php" />
+          <file name="MapperTest.php" role="php" />
+         </dir> <!-- /lib/vendor/phing/test/classes/phing/types -->
+         <file name="BuildFileTest.php" role="php" />
+         <file name="IntrospectionHelperTest.php" role="php" />
+        </dir> <!-- /lib/vendor/phing/test/classes/phing -->
+       </dir> <!-- /lib/vendor/phing/test/classes -->
+       <dir name="etc">
+        <dir name="filters">
+         <dir name="expected">
+          <file name="linecontains.test" role="data" />
+         </dir> <!-- /lib/vendor/phing/test/etc/filters/expected -->
+         <dir name="gettext">
+          <dir name="fr_FR">
+           <dir name="LC_MESSAGES">
+            <file name="messages.mo" role="data" />
+           </dir> <!-- /lib/vendor/phing/test/etc/filters/gettext/fr_FR/LC_MESSAGES -->
+          </dir> <!-- /lib/vendor/phing/test/etc/filters/gettext/fr_FR -->
+          <file name="fr_FR.po" role="data" />
+          <file name="sample.php" role="php" />
+         </dir> <!-- /lib/vendor/phing/test/etc/filters/gettext -->
+         <dir name="input">
+          <file name="linecontains.test" role="data" />
+         </dir> <!-- /lib/vendor/phing/test/etc/filters/input -->
+         <file name="gettext.xml" role="data" />
+         <file name="linecontains.xml" role="data" />
+        </dir> <!-- /lib/vendor/phing/test/etc/filters -->
+        <dir name="resources">
+         <file name="sample.txt" role="data" />
+        </dir> <!-- /lib/vendor/phing/test/etc/resources -->
+        <dir name="tasks">
+         <file name="adhoc.xml" role="data" />
+         <file name="cvs.xml" role="data" />
+         <file name="InputTask.xml" role="data" />
+         <file name="pearpackage.xml" role="data" />
+         <file name="property.xml" role="data" />
+         <file name="property1.properties" role="data" />
+         <file name="property2.properties" role="data" />
+         <file name="property3.properties" role="data" />
+         <file name="propertyprompt.xml" role="data" />
+         <file name="sql.xml" role="data" />
+         <file name="typedef.xml" role="data" />
+        </dir> <!-- /lib/vendor/phing/test/etc/tasks -->
+        <dir name="tokensources">
+         <file name="build.xml" role="data" />
+         <file name="test.txt" role="data" />
+         <file name="tokens.ini" role="data" />
+        </dir> <!-- /lib/vendor/phing/test/etc/tokensources -->
+        <dir name="types">
+         <dir name="fileset">
+          <dir name="a">
+           <dir name="aa">
+            <file name="aaa.php" role="php" />
+           </dir> <!-- /lib/vendor/phing/test/etc/types/fileset/a/aa -->
+           <file name="aa.php" role="php" />
+          </dir> <!-- /lib/vendor/phing/test/etc/types/fileset/a -->
+          <file name="a.php" role="php" />
+          <file name="b.phps" role="data" />
+          <file name="c.xml" role="data" />
+          <file name="d.xsl" role="data" />
+          <file name="e.txt" role="data" />
+          <file name="f.php" role="php" />
+         </dir> <!-- /lib/vendor/phing/test/etc/types/fileset -->
+         <file name="fileset.xml" role="data" />
+         <file name="mapper.xml" role="data" />
+        </dir> <!-- /lib/vendor/phing/test/etc/types -->
+        <dir name="xsl">
+         <file name="coverage-frames.xsl" role="data" />
+         <file name="log.xsl" role="data" />
+         <file name="phpunit2-noframes.xsl" role="data" />
+         <file name="str.replace.function.xsl" role="data" />
+        </dir> <!-- /lib/vendor/phing/test/etc/xsl -->
+        <file name="taskcontainer.xml" role="data" />
+       </dir> <!-- /lib/vendor/phing/test/etc -->
+       <file name="build.xml" role="data" />
+       <file name="run-tests.php" role="php" />
+      </dir> <!-- /lib/vendor/phing/test -->
+      <file name="CHANGELOG" role="data" />
+      <file name="CREDITS" role="data" />
+      <file name="LICENSE" role="data" />
+      <file name="README" role="data" />
+     </dir> <!-- /lib/vendor/phing -->
+     <dir name="propel">
+      <dir name="adapter">
+       <file name="DBAdapter.php" role="php" />
+       <file name="DBMSSQL.php" role="php" />
+       <file name="DBMySQL.php" role="php" />
+       <file name="DBNone.php" role="php" />
+       <file name="DBOracle.php" role="php" />
+       <file name="DBPostgres.php" role="php" />
+       <file name="DBSQLite.php" role="php" />
+      </dir> <!-- /lib/vendor/propel/adapter -->
+      <dir name="logger">
+       <file name="BasicLogger.php" role="php" />
+       <file name="MojaviLogAdapter.php" role="php" />
+      </dir> <!-- /lib/vendor/propel/logger -->
+      <dir name="map">
+       <file name="ColumnMap.php" role="php" />
+       <file name="DatabaseMap.php" role="php" />
+       <file name="MapBuilder.php" role="php" />
+       <file name="TableMap.php" role="php" />
+       <file name="ValidatorMap.php" role="php" />
+      </dir> <!-- /lib/vendor/propel/map -->
+      <dir name="om">
+       <file name="BaseObject.php" role="php" />
+       <file name="NestedSetRecursiveIterator.php" role="php" />
+       <file name="NodeObject.php" role="php" />
+       <file name="Persistent.php" role="php" />
+       <file name="PreOrderNodeIterator.php" role="php" />
+      </dir> <!-- /lib/vendor/propel/om -->
+      <dir name="util">
+       <file name="BasePeer.php" role="php" />
+       <file name="Criteria.php" role="php" />
+       <file name="DebugPDO.php" role="php" />
+       <file name="DebugPDOStatement.php" role="php" />
+       <file name="NodePeer.php" role="php" />
+       <file name="PropelColumnTypes.php" role="php" />
+       <file name="PropelDateTime.php" role="php" />
+       <file name="PropelPager.php" role="php" />
+       <file name="PropelPDO.php" role="php" />
+      </dir> <!-- /lib/vendor/propel/util -->
+      <dir name="validator">
+       <file name="BasicValidator.php" role="php" />
+       <file name="MatchValidator.php" role="php" />
+       <file name="MaxLengthValidator.php" role="php" />
+       <file name="MaxValueValidator.php" role="php" />
+       <file name="MinLengthValidator.php" role="php" />
+       <file name="MinValueValidator.php" role="php" />
+       <file name="NotMatchValidator.php" role="php" />
+       <file name="RequiredValidator.php" role="php" />
+       <file name="TypeValidator.php" role="php" />
+       <file name="UniqueValidator.php" role="php" />
+       <file name="ValidationFailed.php" role="php" />
+       <file name="ValidValuesValidator.php" role="php" />
+      </dir> <!-- /lib/vendor/propel/validator -->
+      <file name="Propel.php" role="php" />
+      <file name="PropelException.php" role="php" />
+     </dir> <!-- /lib/vendor/propel -->
+     <dir name="propel-generator">
+      <dir name="bin">
+       <file name="propel-gen" role="data" />
+       <file name="propel-gen.bat" role="data" />
+      </dir> <!-- /lib/vendor/propel-generator/bin -->
+      <dir name="classes">
+       <dir name="propel">
+        <dir name="engine">
+         <dir name="builder">
+          <dir name="om">
+           <dir name="php5">
+            <file name="PHP5ExtensionNodeBuilder.php" role="php" />
+            <file name="PHP5ExtensionNodePeerBuilder.php" role="php" />
+            <file name="PHP5ExtensionObjectBuilder.php" role="php" />
+            <file name="PHP5ExtensionPeerBuilder.php" role="php" />
+            <file name="PHP5InterfaceBuilder.php" role="php" />
+            <file name="PHP5MapBuilderBuilder.php" role="php" />
+            <file name="PHP5MultiExtendObjectBuilder.php" role="php" />
+            <file name="PHP5NestedSetBuilder.php" role="php" />
+            <file name="PHP5NestedSetPeerBuilder.php" role="php" />
+            <file name="PHP5NodeBuilder.php" role="php" />
+            <file name="PHP5NodePeerBuilder.php" role="php" />
+            <file name="PHP5ObjectBuilder.php" role="php" />
+            <file name="PHP5PeerBuilder.php" role="php" />
+           </dir> <!-- /lib/vendor/propel-generator/classes/propel/engine/builder/om/php5 -->
+           <file name="ClassTools.php" role="php" />
+           <file name="ObjectBuilder.php" role="php" />
+           <file name="OMBuilder.php" role="php" />
+           <file name="PeerBuilder.php" role="php" />
+          </dir> <!-- /lib/vendor/propel-generator/classes/propel/engine/builder/om -->
+          <dir name="sql">
+           <dir name="mssql">
+            <file name="MssqlDataSQLBuilder.php" role="php" />
+            <file name="MssqlDDLBuilder.php" role="php" />
+           </dir> <!-- /lib/vendor/propel-generator/classes/propel/engine/builder/sql/mssql -->
+           <dir name="mysql">
+            <file name="MysqlDataSQLBuilder.php" role="php" />
+            <file name="MysqlDDLBuilder.php" role="php" />
+           </dir> <!-- /lib/vendor/propel-generator/classes/propel/engine/builder/sql/mysql -->
+           <dir name="oracle">
+            <file name="OracleDataSQLBuilder.php" role="php" />
+            <file name="OracleDDLBuilder.php" role="php" />
+           </dir> <!-- /lib/vendor/propel-generator/classes/propel/engine/builder/sql/oracle -->
+           <dir name="pgsql">
+            <file name="PgsqlDataSQLBuilder.php" role="php" />
+            <file name="PgsqlDDLBuilder.php" role="php" />
+           </dir> <!-- /lib/vendor/propel-generator/classes/propel/engine/builder/sql/pgsql -->
+           <dir name="sqlite">
+            <file name="SqliteDataSQLBuilder.php" role="php" />
+            <file name="SqliteDDLBuilder.php" role="php" />
+           </dir> <!-- /lib/vendor/propel-generator/classes/propel/engine/builder/sql/sqlite -->
+           <file name="DataSQLBuilder.php" role="php" />
+           <file name="DDLBuilder.php" role="php" />
+          </dir> <!-- /lib/vendor/propel-generator/classes/propel/engine/builder/sql -->
+          <dir name="util">
+           <dir name="transform">
+            <file name="XmlToDataSQL.php" role="php" />
+           </dir> <!-- /lib/vendor/propel-generator/classes/propel/engine/builder/util/transform -->
+           <file name="DefaultEnglishPluralizer.php" role="php" />
+           <file name="Pluralizer.php" role="php" />
+          </dir> <!-- /lib/vendor/propel-generator/classes/propel/engine/builder/util -->
+          <file name="DataModelBuilder.php" role="php" />
+         </dir> <!-- /lib/vendor/propel-generator/classes/propel/engine/builder -->
+         <dir name="database">
+          <dir name="model">
+           <file name="AppData.php" role="php" />
+           <file name="Column.php" role="php" />
+           <file name="ColumnDefaultValue.php" role="php" />
+           <file name="ConstraintNameGenerator.php" role="php" />
+           <file name="Database.php" role="php" />
+           <file name="Domain.php" role="php" />
+           <file name="ForeignKey.php" role="php" />
+           <file name="IDMethod.php" role="php" />
+           <file name="IdMethodParameter.php" role="php" />
+           <file name="Index.php" role="php" />
+           <file name="Inheritance.php" role="php" />
+           <file name="NameFactory.php" role="php" />
+           <file name="NameGenerator.php" role="php" />
+           <file name="PhpNameGenerator.php" role="php" />
+           <file name="PropelTypes.php" role="php" />
+           <file name="Rule.php" role="php" />
+           <file name="Table.php" role="php" />
+           <file name="Unique.php" role="php" />
+           <file name="Validator.php" role="php" />
+           <file name="VendorInfo.php" role="php" />
+           <file name="XMLElement.php" role="php" />
+          </dir> <!-- /lib/vendor/propel-generator/classes/propel/engine/database/model -->
+          <dir name="reverse">
+           <dir name="mssql">
+            <file name="MssqlSchemaParser.php" role="php" />
+           </dir> <!-- /lib/vendor/propel-generator/classes/propel/engine/database/reverse/mssql -->
+           <dir name="mysql">
+            <file name="MysqlSchemaParser.php" role="php" />
+           </dir> <!-- /lib/vendor/propel-generator/classes/propel/engine/database/reverse/mysql -->
+           <dir name="pgsql">
+            <file name="PgsqlSchemaParser.php" role="php" />
+           </dir> <!-- /lib/vendor/propel-generator/classes/propel/engine/database/reverse/pgsql -->
+           <dir name="sqlite">
+            <file name="SqliteSchemaParser.php" role="php" />
+           </dir> <!-- /lib/vendor/propel-generator/classes/propel/engine/database/reverse/sqlite -->
+           <file name="BaseSchemaParser.php" role="php" />
+           <file name="SchemaParser.php" role="php" />
+          </dir> <!-- /lib/vendor/propel-generator/classes/propel/engine/database/reverse -->
+          <dir name="transform">
+           <file name="XmlToAppData.php" role="php" />
+          </dir> <!-- /lib/vendor/propel-generator/classes/propel/engine/database/transform -->
+         </dir> <!-- /lib/vendor/propel-generator/classes/propel/engine/database -->
+         <dir name="platform">
+          <file name="DefaultPlatform.php" role="php" />
+          <file name="MssqlPlatform.php" role="php" />
+          <file name="MysqlPlatform.php" role="php" />
+          <file name="OraclePlatform.php" role="php" />
+          <file name="PgsqlPlatform.php" role="php" />
+          <file name="Platform.php" role="php" />
+          <file name="SqlitePlatform.php" role="php" />
+         </dir> <!-- /lib/vendor/propel-generator/classes/propel/engine/platform -->
+         <file name="EngineException.php" role="php" />
+         <file name="GeneratorConfig.php" role="php" />
+        </dir> <!-- /lib/vendor/propel-generator/classes/propel/engine -->
+        <dir name="phing">
+         <file name="AbstractPropelDataModelTask.php" role="php" />
+         <file name="PropelConvertConfTask.php" role="php" />
+         <file name="PropelCreoleTransformTask.php" role="php" />
+         <file name="PropelDataDTDTask.php" role="php" />
+         <file name="PropelDataDumpTask.php" role="php" />
+         <file name="PropelDataModelTemplateTask.php" role="php" />
+         <file name="PropelDataSQLTask.php" role="php" />
+         <file name="PropelGraphvizTask.php" role="php" />
+         <file name="PropelOMTask.php" role="php" />
+         <file name="PropelSchemaReverseTask.php" role="php" />
+         <file name="PropelSQLExec.php" role="php" />
+         <file name="PropelSQLTask.php" role="php" />
+        </dir> <!-- /lib/vendor/propel-generator/classes/propel/phing -->
+       </dir> <!-- /lib/vendor/propel-generator/classes/propel -->
+      </dir> <!-- /lib/vendor/propel-generator/classes -->
+      <dir name="pear">
+       <file name="build-pear-package.xml" role="data" />
+       <file name="build.properties" role="data" />
+       <file name="BuildPropelGenPEARPackageTask.php" role="php" />
+       <file name="pear-build.xml" role="data" />
+       <file name="pear-propel-gen" role="data" />
+       <file name="pear-propel-gen.bat" role="data" />
+      </dir> <!-- /lib/vendor/propel-generator/pear -->
+      <dir name="projects">
+       <dir name="bookstore">
+        <file name="build.properties" role="data" />
+        <file name="cms-schema.xml" role="data" />
+        <file name="runtime-conf.xml" role="data" />
+        <file name="schema.xml" role="data" />
+       </dir> <!-- /lib/vendor/propel-generator/projects/bookstore -->
+       <dir name="bookstore-packaged">
+        <file name="author.schema.xml" role="data" />
+        <file name="book.schema.xml" role="data" />
+        <file name="book_club_list.schema.xml" role="data" />
+        <file name="build.properties" role="data" />
+        <file name="log.schema.xml" role="data" />
+        <file name="media.schema.xml" role="data" />
+        <file name="publisher.schema.xml" role="data" />
+        <file name="review.schema.xml" role="data" />
+        <file name="runtime-conf.xml" role="data" />
+       </dir> <!-- /lib/vendor/propel-generator/projects/bookstore-packaged -->
+       <dir name="nestedset">
+        <file name="build.properties" role="data" />
+        <file name="nestedset-schema.xml" role="data" />
+        <file name="runtime-conf.xml" role="data" />
+       </dir> <!-- /lib/vendor/propel-generator/projects/nestedset -->
+       <dir name="treetest">
+        <file name="build.properties" role="data" />
+        <file name="runtime-conf.xml" role="data" />
+        <file name="treetest-schema.xml" role="data" />
+       </dir> <!-- /lib/vendor/propel-generator/projects/treetest -->
+      </dir> <!-- /lib/vendor/propel-generator/projects -->
+      <dir name="resources">
+       <dir name="dtd">
+        <file name="database.dtd" role="data" />
+       </dir> <!-- /lib/vendor/propel-generator/resources/dtd -->
+       <dir name="xsd">
+        <file name="custom_datatypes.xsd" role="data" />
+        <file name="database.xsd" role="data" />
+       </dir> <!-- /lib/vendor/propel-generator/resources/xsd -->
+       <dir name="xsl">
+        <file name="database.xsl" role="data" />
+       </dir> <!-- /lib/vendor/propel-generator/resources/xsl -->
+      </dir> <!-- /lib/vendor/propel-generator/resources -->
+      <dir name="test">
+       <dir name="classes">
+        <dir name="bookstore">
+         <dir name="validator">
+          <file name="ISBNValidator.php" role="php" />
+         </dir> <!-- /lib/vendor/propel-generator/test/classes/bookstore/validator -->
+         <file name="BookstoreDataPopulator.php" role="php" />
+         <file name="BookstoreTestBase.php" role="php" />
+        </dir> <!-- /lib/vendor/propel-generator/test/classes/bookstore -->
+        <dir name="cms">
+         <file name="CmsDataPopulator.php" role="php" />
+         <file name="CmsTestBase.php" role="php" />
+        </dir> <!-- /lib/vendor/propel-generator/test/classes/cms -->
+        <dir name="propel">
+         <dir name="engine">
+          <dir name="database">
+           <dir name="model">
+            <file name="ColumnTest.php" role="php" />
+            <file name="NameFactoryTest.php" role="php" />
+            <file name="TableTest.php" role="php" />
+           </dir> <!-- /lib/vendor/propel-generator/test/classes/propel/engine/database/model -->
+          </dir> <!-- /lib/vendor/propel-generator/test/classes/propel/engine/database -->
+          <dir name="platform">
+           <file name="DefaultPlatformTest.php" role="php" />
+           <file name="PlatformTestBase.php" role="php" />
+           <file name="SqlitePlatformTest.php" role="php" />
+          </dir> <!-- /lib/vendor/propel-generator/test/classes/propel/engine/platform -->
+         </dir> <!-- /lib/vendor/propel-generator/test/classes/propel/engine -->
+         <dir name="util">
+          <file name="BasePeerTest.php" role="php" />
+          <file name="CriteriaTest.php" role="php" />
+          <file name="PropelDateTimeTest.php" role="php" />
+          <file name="PropelPDOTest.php" role="php" />
+         </dir> <!-- /lib/vendor/propel-generator/test/classes/propel/util -->
+         <dir name="validator">
+          <file name="ValidatorTest.php" role="php" />
+         </dir> <!-- /lib/vendor/propel-generator/test/classes/propel/validator -->
+         <file name="BaseTestCase.php" role="php" />
+         <file name="CharacterEncodingTest.php" role="php" />
+         <file name="FieldnameRelatedTest.php" role="php" />
+         <file name="GeneratedNestedSetObjectTest.php" role="php" />
+         <file name="GeneratedNestedSetPeerTest.php" role="php" />
+         <file name="GeneratedNestedSetTest.php" role="php" />
+         <file name="GeneratedObjectLobTest.php" role="php" />
+         <file name="GeneratedObjectRelTest.php" role="php" />
+         <file name="GeneratedObjectTest.php" role="php" />
+         <file name="GeneratedPeerTest.php" role="php" />
+         <file name="Ticket520Test.php" role="php" />
+        </dir> <!-- /lib/vendor/propel-generator/test/classes/propel -->
+       </dir> <!-- /lib/vendor/propel-generator/test/classes -->
+       <dir name="etc">
+        <dir name="lob">
+         <file name="propel.gif" role="data" />
+         <file name="tin_drum.gif" role="data" />
+         <file name="tin_drum.txt" role="data" />
+        </dir> <!-- /lib/vendor/propel-generator/test/etc/lob -->
+        <dir name="schema">
+         <file name="tabletest-schema.xml" role="data" />
+        </dir> <!-- /lib/vendor/propel-generator/test/etc/schema -->
+        <dir name="xsl">
+         <file name="coverage-frames.xsl" role="data" />
+         <file name="log.xsl" role="data" />
+         <file name="phpunit2-noframes.xsl" role="data" />
+         <file name="str.replace.function.xsl" role="data" />
+        </dir> <!-- /lib/vendor/propel-generator/test/etc/xsl -->
+       </dir> <!-- /lib/vendor/propel-generator/test/etc -->
+       <dir name="tools">
+        <dir name="phing">
+         <file name="DefineTask.php" role="php" />
+        </dir> <!-- /lib/vendor/propel-generator/test/tools/phing -->
+       </dir> <!-- /lib/vendor/propel-generator/test/tools -->
+       <file name="bookstore-packaged-test.php" role="php" />
+       <file name="bookstore-test.php" role="php" />
+       <file name="README" role="data" />
+       <file name="test.xml" role="data" />
+       <file name="tree-test.php" role="php" />
+      </dir> <!-- /lib/vendor/propel-generator/test -->
+      <file name="build-propel.xml" role="data" />
+      <file name="build.properties-sample" role="data" />
+      <file name="build.xml" role="data" />
+      <file name="build.xml-local" role="data" />
+      <file name="default.properties" role="data" />
+     </dir> <!-- /lib/vendor/propel-generator -->
+    </dir> <!-- /lib/vendor -->
+   </dir> <!-- /lib -->
+   <dir name="test">
+    <dir name="other">
+     <dir name="fixtures">
+      <file name="schema.yml" role="data" />
+     </dir> <!-- /test/other/fixtures -->
+     <file name="tasksTest.php" role="php" />
+    </dir> <!-- /test/other -->
+   </dir> <!-- /test -->
+   <file name="LICENSE" role="data" />
+   <file name="README" role="data" />
+  </dir> <!-- / -->
+ </contents>
+ <dependencies>
+  <required>
+   <php>
+    <min>5.2.0</min>
+   </php>
+   <pearinstaller>
+    <min>1.4.1</min>
+   </pearinstaller>
+   <package>
+    <name>symfony</name>
+    <channel>pear.symfony-project.com</channel>
+    <min>1.0.0</min>
+    <max>1.1.0</max>
+    <exclude>1.1.0</exclude>
+   </package>
+  </required>
+ </dependencies>
+ <phprelease />
+ <changelog>
+  <release>
+   <version>
+    <release>0.6.0</release>
+    <api>0.6.0</api>
+   </version>
+   <stability>
+    <release>beta</release>
+    <api>beta</api>
+   </stability>
+   <date>2008-05-28</date>
+   <license uri="http://www.symfony-project.com/license">MIT License</license>
+   <notes>--</notes>
+  </release>
+ </changelog>
+</package>
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/test/other/fixtures/schema.yml
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/test/other/fixtures/schema.yml	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/test/other/fixtures/schema.yml	(revision 19)
@@ -0,0 +1,11 @@
+propel:
+  article:
+    id:
+    title: varchar(255)
+    body:  longvarchar
+    category_id:
+    created_at:
+
+  category:
+    id:
+    name: varchar(255)
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/test/other/tasksTest.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/test/other/tasksTest.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/plugins/sfPropel13Plugin/test/other/tasksTest.php	(revision 19)
@@ -0,0 +1,134 @@
+<?php
+
+$_lib_dir = '/home/joshua/devel/svn/symfony/1.0/lib';
+$_data_dir = '/home/joshua/devel/svn/symfony/1.0/data';
+
+require_once($_lib_dir.'/vendor/lime/lime.php');
+require_once($_lib_dir.'/util/sfFinder.class.php');
+require_once($_lib_dir.'/util/sfToolkit.class.php');
+
+define('DS', DIRECTORY_SEPARATOR);
+
+class symfony_cmd
+{
+  public $php_cli = null;
+  public $data_dir = null;
+  public $tmp_dir = null;
+  public $t = null;
+  public $current_dir = null;
+
+  public function initialize($t, $data_dir)
+  {
+    $this->t = $t;
+    $this->data_dir = $data_dir;
+
+    $this->tmp_dir = sfToolkit::getTmpDir().DIRECTORY_SEPARATOR.'symfony_cmd';
+
+    if (is_dir($this->tmp_dir))
+    {
+      $this->clearTmpDir();
+      rmdir($this->tmp_dir);
+    }
+
+    mkdir($this->tmp_dir, 0777);
+
+    $this->current_dir = getcwd();
+    chdir($this->tmp_dir);
+
+    $this->php_cli = sfToolkit::getPhpCli();
+  }
+
+  public function shutdown()
+  {
+    $this->clearTmpDir();
+    rmdir($this->tmp_dir);
+    chdir($this->current_dir);
+  }
+
+  protected function clearTmpDir()
+  {
+    sfToolkit::clearDirectory($this->tmp_dir);
+  }
+
+  public function execute_command($cmd, $test = true)
+  {
+    ob_start();
+    passthru(sprintf('%s -d html_errors=off -d open_basedir= -q "%s" %s 2>&1', $this->php_cli, $this->data_dir . '/bin/symfony', $cmd), $return);
+    $content = ob_get_clean();
+    if ($test)
+    {
+      $this->t->cmp_ok($return, '<=', 0, sprintf('"symfony %s" returns ok', $cmd));
+    }
+
+    return $content;
+  }
+}
+
+function copyr($source_dir, $dest_dir)
+{
+  $files = sfFinder::type('file')->name('*')->ignore_version_control()->in($source_dir);
+
+  // copy source files
+  foreach ($files as $file)
+  {
+    $dest = str_replace($source_dir, $dest_dir, $file);
+
+    if (!file_exists(dirname($dest)))
+    {
+      mkdir(dirname($dest), 0777, true);
+    }
+    
+    copy($file, $dest);
+  }
+}
+
+function rewrite_config($config_path)
+{
+  $config = file_get_contents($config_path);
+
+  $config = str_replace(
+    array(
+      'addon.propel.builder.SfPeerBuilder',
+      'addon.propel.builder.SfObjectBuilder',
+    ),
+    array(
+      'plugins.sfPropel13Plugin.lib.propel.builder.SfPeerBuilder',
+      'plugins.sfPropel13Plugin.lib.propel.builder.SfObjectBuilder',
+    ),
+    $config
+  );
+
+  file_put_contents($config_path, $config);
+}
+
+$t = new lime_test(10, new lime_output_color());
+$c = new symfony_cmd();
+$c->initialize($t, $_data_dir);
+
+// setup project
+$content = $c->execute_command('init-project myproject', false);
+$content = $c->execute_command('init-app frontend', false);
+
+// sfPakePropel
+copy(dirname(__FILE__).'/fixtures/schema.yml', $c->tmp_dir.DS.'config'.DS.'schema.yml');
+copyr(realpath(dirname(__FILE__) . '/../../'), $c->tmp_dir.DS.'plugins'.DS.'sfPropel13Plugin');
+rewrite_config($c->tmp_dir.DS.'config'.DS.'propel.ini');
+
+$content = $c->execute_command('propel-13-build-sql');
+$t->ok(file_exists($c->tmp_dir.DS.'data'.DS.'sql'.DS.'lib.model.schema.sql'), '"propel-build-sql" creates a "schema.sql" file under "data/sql" directory');
+
+$content = $c->execute_command('propel-13-build-model');
+$t->ok(file_exists($c->tmp_dir.DS.'lib'.DS.'model'.DS.'Article.php'), '"propel-build-model" creates model classes under "lib/model" directory');
+
+// sfPakePropelCrudGenerator
+$content = $c->execute_command('propel-13-init-crud frontend articleInitCrud Article');
+$t->ok(file_exists($c->tmp_dir.DS.'apps'.DS.'frontend'.DS.'modules'.DS.'articleInitCrud'.DS.'config'.DS.'generator.yml'), '"propel-init-crud" initializes a CRUD module');
+
+$content = $c->execute_command('propel-13-generate-crud frontend articleGenCrud Article');
+$t->ok(is_dir($c->tmp_dir.DS.'apps'.DS.'frontend'.DS.'modules'.DS.'articleGenCrud'), '"propel-generate-crud" generates a CRUD module');
+
+// sfPakePropelAdminGenerator
+$content = $c->execute_command('propel-13-init-admin frontend articleInitAdmin Article');
+$t->ok(file_exists($c->tmp_dir.DS.'apps'.DS.'frontend'.DS.'modules'.DS.'articleInitAdmin'.DS.'config'.DS.'generator.yml'), '"propel-init-admin" initializes an admin generator module');
+
+$c->shutdown();
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/symfony
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/symfony	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/symfony	(revision 19)
@@ -0,0 +1,14 @@
+#!/usr/bin/env php
+<?php
+
+/*
+ * This file is part of the symfony package.
+ * (c) 2004-2006 Fabien Potencier <fabien.potencier@symfony-project.com>
+ * 
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+chdir(dirname(__FILE__));
+include('config/config.php');
+include($sf_symfony_data_dir.'/bin/symfony.php');
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/test/bootstrap/functional.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/test/bootstrap/functional.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/test/bootstrap/functional.php	(revision 19)
@@ -0,0 +1,29 @@
+<?php
+
+/*
+ * This file is part of the symfony package.
+ * (c) 2004-2006 Fabien Potencier <fabien.potencier@symfony-project.com>
+ * 
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+// guess current application
+if (!isset($app))
+{
+  $traces = debug_backtrace();
+  $caller = $traces[0];
+  $app = array_pop(explode(DIRECTORY_SEPARATOR, dirname($caller['file'])));
+}
+
+// define symfony constant
+define('SF_ROOT_DIR',    realpath(dirname(__FILE__).'/../..'));
+define('SF_APP',         $app);
+define('SF_ENVIRONMENT', 'test');
+define('SF_DEBUG',       true);
+
+// initialize symfony
+require_once(SF_ROOT_DIR.DIRECTORY_SEPARATOR.'apps'.DIRECTORY_SEPARATOR.SF_APP.DIRECTORY_SEPARATOR.'config'.DIRECTORY_SEPARATOR.'config.php');
+
+// remove all cache
+sfToolkit::clearDirectory(sfConfig::get('sf_cache_dir'));
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/test/bootstrap/unit.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/test/bootstrap/unit.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/test/bootstrap/unit.php	(revision 19)
@@ -0,0 +1,17 @@
+<?php
+
+/*
+ * This file is part of the symfony package.
+ * (c) 2004-2006 Fabien Potencier <fabien.potencier@symfony-project.com>
+ * 
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+$_test_dir = realpath(dirname(__FILE__).'/..');
+define('SF_ROOT_DIR', realpath($_test_dir.'/..'));
+
+// symfony directories
+include(SF_ROOT_DIR.DIRECTORY_SEPARATOR.'config'.DIRECTORY_SEPARATOR.'config.php');
+
+require_once($sf_symfony_lib_dir.'/vendor/lime/lime.php');
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/test/functional/platform/spaceActionsTest.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/test/functional/platform/spaceActionsTest.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/test/functional/platform/spaceActionsTest.php	(revision 19)
@@ -0,0 +1,15 @@
+<?php
+
+include(dirname(__FILE__).'/../../bootstrap/functional.php');
+
+// create a new test browser
+$browser = new sfTestBrowser();
+$browser->initialize();
+
+$browser->
+  get('/space/index')->
+  isStatusCode(200)->
+  isRequestParameter('module', 'space')->
+  isRequestParameter('action', 'index')->
+  checkResponseElement('body', '!/This is a temporary page/')
+;
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/test/functional/platform/userActionsTest.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/test/functional/platform/userActionsTest.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/test/functional/platform/userActionsTest.php	(revision 19)
@@ -0,0 +1,15 @@
+<?php
+
+include(dirname(__FILE__).'/../../bootstrap/functional.php');
+
+// create a new test browser
+$browser = new sfTestBrowser();
+$browser->initialize();
+
+$browser->
+  get('/user/index')->
+  isStatusCode(200)->
+  isRequestParameter('module', 'user')->
+  isRequestParameter('action', 'index')->
+  checkResponseElement('body', '!/This is a temporary page/')
+;
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/web/.htaccess
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/web/.htaccess	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/web/.htaccess	(revision 19)
@@ -0,0 +1,26 @@
+Options +FollowSymLinks +ExecCGI
+
+<IfModule mod_rewrite.c>
+  RewriteEngine On
+
+  # uncomment the following line, if you are having trouble
+  # getting no_script_name to work
+  #RewriteBase /
+
+  # we skip all files with .something
+  # comment the following 3 lines to allow periods in routes
+  RewriteCond %{REQUEST_URI} \..+$
+  RewriteCond %{REQUEST_URI} !\.html$
+  RewriteRule .* - [L]
+
+  # we check if the .html version is here (caching)
+  RewriteRule ^$ index.html [QSA]
+  RewriteRule ^([^.]+)$ $1.html [QSA]
+  RewriteCond %{REQUEST_FILENAME} !-f
+
+  # no, so we redirect to our front web controller
+  RewriteRule ^(.*)$ index.php [QSA,L]
+</IfModule>
+
+# big crash from our front web controller
+ErrorDocument 500 "<h2>Application error</h2>symfony application failed to start properly"
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/web/css/main.css
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/web/css/main.css	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/web/css/main.css	(revision 19)
@@ -0,0 +1,27 @@
+ul,ol,li,h1,h2,h3,h4,h5,h6,pre,form,body,html,p,blockquote,fieldset,input
+{ margin: 0; padding: 0; }
+a img,:link img,:visited img { border: none; }
+
+a
+{
+  text-decoration: none;
+}
+
+a:hover
+{
+  text-decoration: underline;
+}
+
+body, td
+{
+  margin: 0;
+  padding: 0;
+  font-family: Arial, Verdana, sans-serif;
+  font-size: 11px;
+  background-color: #fff;
+}
+
+body
+{
+  padding: 20px;
+}
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/web/index.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/web/index.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/web/index.php	(revision 19)
@@ -0,0 +1,10 @@
+<?php
+
+define('SF_ROOT_DIR',    realpath(dirname(__FILE__).'/..'));
+define('SF_APP',         'platform');
+define('SF_ENVIRONMENT', 'prod');
+define('SF_DEBUG',       false);
+
+require_once(SF_ROOT_DIR.DIRECTORY_SEPARATOR.'apps'.DIRECTORY_SEPARATOR.SF_APP.DIRECTORY_SEPARATOR.'config'.DIRECTORY_SEPARATOR.'config.php');
+
+sfContext::getInstance()->getController()->dispatch();
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/web/info.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/web/info.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/web/info.php	(revision 19)
@@ -0,0 +1,2 @@
+<?php
+phpinfo();
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/web/platform_dev.php
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/web/platform_dev.php	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/web/platform_dev.php	(revision 19)
@@ -0,0 +1,10 @@
+<?php
+
+define('SF_ROOT_DIR',    realpath(dirname(__FILE__).'/..'));
+define('SF_APP',         'platform');
+define('SF_ENVIRONMENT', 'dev');
+define('SF_DEBUG',       true);
+
+require_once(SF_ROOT_DIR.DIRECTORY_SEPARATOR.'apps'.DIRECTORY_SEPARATOR.SF_APP.DIRECTORY_SEPARATOR.'config'.DIRECTORY_SEPARATOR.'config.php');
+
+sfContext::getInstance()->getController()->dispatch();
Index: pro-bachkim-filespace/sourcecode/api.violet.vn/web/robots.txt
===================================================================
--- pro-bachkim-filespace/sourcecode/api.violet.vn/web/robots.txt	(revision 19)
+++ pro-bachkim-filespace/sourcecode/api.violet.vn/web/robots.txt	(revision 19)
@@ -0,0 +1,2 @@
+#User-agent: *
+#Disallow:
Index: pro-bachkim-filespace/sourcecode/assets/js/jquery/jquery.confirm.min.js
===================================================================
--- pro-bachkim-filespace/sourcecode/assets/js/jquery/jquery.confirm.min.js	(revision 19)
+++ pro-bachkim-filespace/sourcecode/assets/js/jquery/jquery.confirm.min.js	(revision 19)
@@ -0,0 +1,14 @@
+/*!
+ * jquery.confirm
+ *
+ * @version 2.3.1
+ *
+ * @author My C-Labs
+ * @author Matthieu Napoli <matthieu@mnapoli.fr>
+ * @author Russel Vela
+ * @author Marcus Schwarz <msspamfang@gmx.de>
+ *
+ * @license MIT
+ * @url http://myclabs.github.io/jquery.confirm/
+ */
+(function($){$.fn.confirm=function(options){if(typeof options==="undefined"){options={}}this.click(function(e){e.preventDefault();var newOptions=$.extend({button:$(this)},options);$.confirm(newOptions,e)});return this};$.confirm=function(options,e){if($(".confirmation-modal").length>0)return;var dataOptions={};if(options.button){var dataOptionsMapping={title:"title",text:"text","confirm-button":"confirmButton","cancel-button":"cancelButton","confirm-button-class":"confirmButtonClass"};$.each(dataOptionsMapping,function(attributeName,optionName){var value=options.button.data(attributeName);if(value){dataOptions[optionName]=value}})}var settings=$.extend({},$.confirm.options,{confirm:function(){var url=e&&("string"===typeof e&&e||e.currentTarget&&e.currentTarget.attributes["href"].value);if(url){if(options.post){var form=$('<form method="post" class="hide" action="'+url+'"></form>');$("body").append(form);form.submit()}else{window.location=url}}},cancel:function(o){},button:null},dataOptions,options);var modalHeader="";if(settings.title!==""){modalHeader="<div class=modal-header>"+'<button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>'+'<h4 class="modal-title">'+settings.title+"</h4>"+"</div>"}var modalHTML='<div class="confirmation-modal modal fade" tabindex="-1" role="dialog">'+'<div class="modal-dialog">'+'<div class="modal-content">'+modalHeader+'<div class="modal-body">'+settings.text+"</div>"+'<div class="modal-footer">'+'<button class="confirm btn '+settings.confirmButtonClass+'" type="button" data-dismiss="modal">'+settings.confirmButton+"</button>"+'<button class="cancel btn btn-default" type="button" data-dismiss="modal">'+settings.cancelButton+"</div>"+"</div>"+"</div>"+"</div>"+"</div>";var modal=$(modalHTML);modal.on("shown.bs.modal",function(){modal.find(".btn-primary:first").focus()});modal.on("hidden.bs.modal",function(){modal.remove()});modal.find(".confirm").click(function(){settings.confirm(settings.button)});modal.find(".cancel").click(function(){settings.cancel(settings.button)});$("body").append(modal);modal.modal("show")};$.confirm.options={text:"Are you sure?",title:"",confirmButton:"Yes",cancelButton:"Cancel",post:false,confirmButtonClass:"btn-primary"}})(jQuery);
