Index: branches/5.3.x/composer.json
===================================================================
--- branches/5.3.x/composer.json
+++ branches/5.3.x/composer.json
@@ -1,5 +1,9 @@
 {
 	"name": "In-Portal",
+	"require": {
+		"symfony/console": "~2.6",
+		"stecman/symfony-console-completion": "~0.5"
+	},
 	"require-dev": {
 		"aik099/coding-standard": "dev-in-portal",
 		"nikic/php-parser": "~1.2"
Index: branches/5.3.x/composer.lock
===================================================================
--- branches/5.3.x/composer.lock
+++ branches/5.3.x/composer.lock
@@ -4,8 +4,112 @@
         "Read more about it at http://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
         "This file is @generated automatically"
     ],
-    "hash": "746788fc49ab32d05ca2bd837e9f0a1f",
-    "packages": [],
+    "hash": "0084b5c04f49b47e81eff44c0343b57f",
+    "packages": [
+        {
+            "name": "stecman/symfony-console-completion",
+            "version": "0.5.1",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/stecman/symfony-console-completion.git",
+                "reference": "1a9fc7ab4820cd1aabbdc584c6b25d221e7b6cb5"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/stecman/symfony-console-completion/zipball/1a9fc7ab4820cd1aabbdc584c6b25d221e7b6cb5",
+                "reference": "1a9fc7ab4820cd1aabbdc584c6b25d221e7b6cb5",
+                "shasum": ""
+            },
+            "require": {
+                "php": ">=5.3.2",
+                "symfony/console": "~2.2"
+            },
+            "require-dev": {
+                "phpunit/phpunit": "~4.1"
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "0.5.x-dev"
+                }
+            },
+            "autoload": {
+                "psr-4": {
+                    "Stecman\\Component\\Symfony\\Console\\BashCompletion\\": "src/"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Stephen Holdaway",
+                    "email": "stephen@stecman.co.nz"
+                }
+            ],
+            "description": "Automatic BASH completion for Symfony Console Component based applications.",
+            "time": "2015-05-07 12:21:50"
+        },
+        {
+            "name": "symfony/console",
+            "version": "v2.6.7",
+            "target-dir": "Symfony/Component/Console",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/symfony/Console.git",
+                "reference": "ebc5679854aa24ed7d65062e9e3ab0b18a917272"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/symfony/Console/zipball/ebc5679854aa24ed7d65062e9e3ab0b18a917272",
+                "reference": "ebc5679854aa24ed7d65062e9e3ab0b18a917272",
+                "shasum": ""
+            },
+            "require": {
+                "php": ">=5.3.3"
+            },
+            "require-dev": {
+                "psr/log": "~1.0",
+                "symfony/event-dispatcher": "~2.1",
+                "symfony/phpunit-bridge": "~2.7",
+                "symfony/process": "~2.1"
+            },
+            "suggest": {
+                "psr/log": "For using the console logger",
+                "symfony/event-dispatcher": "",
+                "symfony/process": ""
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "2.6-dev"
+                }
+            },
+            "autoload": {
+                "psr-0": {
+                    "Symfony\\Component\\Console\\": ""
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Fabien Potencier",
+                    "email": "fabien@symfony.com"
+                },
+                {
+                    "name": "Symfony Community",
+                    "homepage": "https://symfony.com/contributors"
+                }
+            ],
+            "description": "Symfony Console Component",
+            "homepage": "https://symfony.com",
+            "time": "2015-05-02 15:18:45"
+        }
+    ],
     "packages-dev": [
         {
             "name": "aik099/coding-standard",
@@ -13,12 +117,12 @@
             "source": {
                 "type": "git",
                 "url": "https://github.com/aik099/CodingStandard.git",
-                "reference": "3680b3926f0e936dc95de82dece9310b97c73e97"
+                "reference": "a47f2b767c99a33f437802b3315179887018e114"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/aik099/CodingStandard/zipball/3680b3926f0e936dc95de82dece9310b97c73e97",
-                "reference": "3680b3926f0e936dc95de82dece9310b97c73e97",
+                "url": "https://api.github.com/repos/aik099/CodingStandard/zipball/a47f2b767c99a33f437802b3315179887018e114",
+                "reference": "a47f2b767c99a33f437802b3315179887018e114",
                 "shasum": ""
             },
             "require-dev": {
@@ -45,20 +149,20 @@
                 "PHP_CodeSniffer",
                 "codesniffer"
             ],
-            "time": "2015-04-10 07:05:51"
+            "time": "2015-05-06 08:54:38"
         },
         {
             "name": "nikic/php-parser",
-            "version": "v1.2.2",
+            "version": "v1.3.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/nikic/PHP-Parser.git",
-                "reference": "08f97eb4efa029e2fafb6d8c98b71731bf0cf621"
+                "reference": "dff239267fd1befa1cd40430c9ed12591aa720ca"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/08f97eb4efa029e2fafb6d8c98b71731bf0cf621",
-                "reference": "08f97eb4efa029e2fafb6d8c98b71731bf0cf621",
+                "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/dff239267fd1befa1cd40430c9ed12591aa720ca",
+                "reference": "dff239267fd1befa1cd40430c9ed12591aa720ca",
                 "shasum": ""
             },
             "require": {
@@ -68,7 +172,7 @@
             "type": "library",
             "extra": {
                 "branch-alias": {
-                    "dev-master": "1.2-dev"
+                    "dev-master": "1.3-dev"
                 }
             },
             "autoload": {
@@ -90,7 +194,7 @@
                 "parser",
                 "php"
             ],
-            "time": "2015-04-03 14:33:59"
+            "time": "2015-05-02 15:40:40"
         }
     ],
     "aliases": [],
Index: branches/5.3.x/core/install/cache/class_structure.php
===================================================================
--- branches/5.3.x/core/install/cache/class_structure.php
+++ branches/5.3.x/core/install/cache/class_structure.php
@@ -2,7 +2,7 @@
 // @codingStandardsIgnoreFile
 
 /**
- * This file is automatically @generated. Use 'php tools/build_class_map.php' to rebuild it.
+ * This file is automatically @generated. Please use 'in-portal classmap:rebuild' command to rebuild it.
  */
 return array(
 	'cache_format' => 2,
@@ -82,6 +82,15 @@
 		'ImagesItem' => '/core/units/images/images.php',
 		'InPortalPrerequisites' => '/core/install/prerequisites.php',
 		'InpCustomFieldsHelper' => '/core/units/helpers/custom_fields_helper.php',
+		'Intechnic\\InPortal\\Core\\kernel\\Console\\Command\\AbstractCommand' => '/core/kernel/Console/Command/AbstractCommand.php',
+		'Intechnic\\InPortal\\Core\\kernel\\Console\\Command\\BuildClassMapCommand' => '/core/kernel/Console/Command/BuildClassMapCommand.php',
+		'Intechnic\\InPortal\\Core\\kernel\\Console\\Command\\CompletionCommand' => '/core/kernel/Console/Command/CompletionCommand.php',
+		'Intechnic\\InPortal\\Core\\kernel\\Console\\Command\\IConsoleCommand' => '/core/kernel/Console/Command/IConsoleCommand.php',
+		'Intechnic\\InPortal\\Core\\kernel\\Console\\Command\\ResetCacheCommand' => '/core/kernel/Console/Command/ResetCacheCommand.php',
+		'Intechnic\\InPortal\\Core\\kernel\\Console\\Command\\RunEventCommand' => '/core/kernel/Console/Command/RunEventCommand.php',
+		'Intechnic\\InPortal\\Core\\kernel\\Console\\ConsoleApplication' => '/core/kernel/Console/ConsoleApplication.php',
+		'Intechnic\\InPortal\\Core\\kernel\\Console\\ConsoleCommandProvider' => '/core/kernel/Console/ConsoleCommandProvider.php',
+		'Intechnic\\InPortal\\Core\\kernel\\Console\\IConsoleCommandProvider' => '/core/kernel/Console/IConsoleCommandProvider.php',
 		'Intechnic\\InPortal\\Core\\kernel\\utility\\ClassDiscovery\\ClassDetector' => '/core/kernel/utility/ClassDiscovery/ClassDetector.php',
 		'Intechnic\\InPortal\\Core\\kernel\\utility\\ClassDiscovery\\ClassMapBuilder' => '/core/kernel/utility/ClassDiscovery/ClassMapBuilder.php',
 		'Intechnic\\InPortal\\Core\\kernel\\utility\\ClassDiscovery\\CodeFolderFilterIterator' => '/core/kernel/utility/ClassDiscovery/CodeFolderFilterIterator.php',
@@ -836,6 +845,66 @@
 				0 => 'kHelper',
 			),
 		),
+		'Intechnic\\InPortal\\Core\\kernel\\Console\\Command\\AbstractCommand' => array(
+			'type' => 1,
+			'modifiers' => 1,
+			'extends' => array(
+				0 => 'Symfony\\Component\\Console\\Command\\Command',
+				1 => 'Intechnic\\InPortal\\Core\\kernel\\Console\\Command\\IConsoleCommand',
+			),
+		),
+		'Intechnic\\InPortal\\Core\\kernel\\Console\\Command\\BuildClassMapCommand' => array(
+			'type' => 1,
+			'modifiers' => 0,
+			'extends' => array(
+				0 => 'Intechnic\\InPortal\\Core\\kernel\\Console\\Command\\AbstractCommand',
+				1 => 'Stecman\\Component\\Symfony\\Console\\BashCompletion\\Completion\\CompletionAwareInterface',
+			),
+		),
+		'Intechnic\\InPortal\\Core\\kernel\\Console\\Command\\CompletionCommand' => array(
+			'type' => 1,
+			'modifiers' => 0,
+			'extends' => array(
+				0 => 'Stecman\\Component\\Symfony\\Console\\BashCompletion\\CompletionCommand',
+				1 => 'Intechnic\\InPortal\\Core\\kernel\\Console\\Command\\IConsoleCommand',
+			),
+		),
+		'Intechnic\\InPortal\\Core\\kernel\\Console\\Command\\IConsoleCommand' => array(
+			'type' => 2,
+		),
+		'Intechnic\\InPortal\\Core\\kernel\\Console\\Command\\ResetCacheCommand' => array(
+			'type' => 1,
+			'modifiers' => 0,
+			'extends' => array(
+				0 => 'Intechnic\\InPortal\\Core\\kernel\\Console\\Command\\AbstractCommand',
+			),
+		),
+		'Intechnic\\InPortal\\Core\\kernel\\Console\\Command\\RunEventCommand' => array(
+			'type' => 1,
+			'modifiers' => 0,
+			'extends' => array(
+				0 => 'Intechnic\\InPortal\\Core\\kernel\\Console\\Command\\AbstractCommand',
+				1 => 'Stecman\\Component\\Symfony\\Console\\BashCompletion\\Completion\\CompletionAwareInterface',
+			),
+		),
+		'Intechnic\\InPortal\\Core\\kernel\\Console\\ConsoleApplication' => array(
+			'type' => 1,
+			'modifiers' => 0,
+			'extends' => array(
+				0 => 'Symfony\\Component\\Console\\Application',
+			),
+		),
+		'Intechnic\\InPortal\\Core\\kernel\\Console\\ConsoleCommandProvider' => array(
+			'type' => 1,
+			'modifiers' => 0,
+			'extends' => array(
+				0 => 'kBase',
+				1 => 'Intechnic\\InPortal\\Core\\kernel\\Console\\IConsoleCommandProvider',
+			),
+		),
+		'Intechnic\\InPortal\\Core\\kernel\\Console\\IConsoleCommandProvider' => array(
+			'type' => 2,
+		),
 		'Intechnic\\InPortal\\Core\\kernel\\utility\\ClassDiscovery\\ClassDetector' => array(
 			'type' => 1,
 			'modifiers' => 0,
Index: branches/5.3.x/core/kernel/Console/Command/AbstractCommand.php
===================================================================
--- branches/5.3.x/core/kernel/Console/Command/AbstractCommand.php
+++ branches/5.3.x/core/kernel/Console/Command/AbstractCommand.php
@@ -0,0 +1,79 @@
+<?php
+/**
+* @version	$Id$
+* @package	In-Portal
+* @copyright	Copyright (C) 1997 - 2015 Intechnic. All rights reserved.
+* @license      GNU/GPL
+* In-Portal is Open Source software.
+* This means that this software may have been modified pursuant
+* the GNU General Public License, and as distributed it includes
+* or is derivative of works licensed under the GNU General Public License
+* or other free or open source software licenses.
+* See http://www.in-portal.org/license for copyright notices and details.
+*/
+
+namespace Intechnic\InPortal\Core\kernel\Console\Command;
+
+
+use Intechnic\InPortal\Core\kernel\Console\ConsoleApplication;
+use Symfony\Component\Console\Command\Command as SymfonyCommand;
+use Symfony\Component\Console\Input\InputInterface;
+use Symfony\Component\Console\Output\OutputInterface;
+
+defined('FULL_PATH') or die('restricted access!');
+
+abstract class AbstractCommand extends SymfonyCommand implements IConsoleCommand
+{
+
+	/**
+	 * Reference to global kApplication instance
+	 *
+	 * @var \kApplication.
+	 */
+	protected $Application = null;
+
+	/**
+	 * Connection to database.
+	 *
+	 * @var \IDBConnection
+	 */
+	protected $Conn = null;
+
+	/**
+	 * Sets the application instance for this command.
+	 *
+	 * @param ConsoleApplication $application An Application instance.
+	 *
+	 * @return void
+	 */
+	public function setApplication(ConsoleApplication $application = null)
+	{
+		parent::setApplication($application);
+
+		// For disabled commands $application is not set.
+		if ( isset($application) ) {
+			$this->Application = $application->getKernelApplication();
+			$this->Conn =& $this->Application->GetADODBConnection();
+		}
+	}
+
+	/**
+	 * Perform additional validation of the input.
+	 *
+	 * @param InputInterface  $input  An InputInterface instance.
+	 * @param OutputInterface $output An OutputInterface instance.
+	 *
+	 * @return void
+	 * @throws \RuntimeException When not all required arguments were passed.
+	 */
+	protected function initialize(InputInterface $input, OutputInterface $output)
+	{
+		$arguments = array_filter($input->getArguments());
+
+		// Consider required arguments passed with empty values as an error.
+		if ( count($arguments) < $this->getDefinition()->getArgumentRequiredCount() ) {
+			throw new \RuntimeException('Not enough arguments.');
+		}
+	}
+
+}
Index: branches/5.3.x/core/kernel/Console/Command/BuildClassMapCommand.php
===================================================================
--- branches/5.3.x/core/kernel/Console/Command/BuildClassMapCommand.php
+++ branches/5.3.x/core/kernel/Console/Command/BuildClassMapCommand.php
@@ -0,0 +1,136 @@
+<?php
+/**
+* @version	$Id$
+* @package	In-Portal
+* @copyright	Copyright (C) 1997 - 2015 Intechnic. All rights reserved.
+* @license      GNU/GPL
+* In-Portal is Open Source software.
+* This means that this software may have been modified pursuant
+* the GNU General Public License, and as distributed it includes
+* or is derivative of works licensed under the GNU General Public License
+* or other free or open source software licenses.
+* See http://www.in-portal.org/license for copyright notices and details.
+*/
+
+namespace Intechnic\InPortal\Core\kernel\Console\Command;
+
+
+use Intechnic\InPortal\Core\kernel\utility\ClassDiscovery\ClassMapBuilder;
+use Stecman\Component\Symfony\Console\BashCompletion\Completion\CompletionAwareInterface;
+use Stecman\Component\Symfony\Console\BashCompletion\CompletionContext;
+use Symfony\Component\Console\Input\InputInterface;
+use Symfony\Component\Console\Input\InputOption;
+use Symfony\Component\Console\Output\OutputInterface;
+
+defined('FULL_PATH') or die('restricted access!');
+
+class BuildClassMapCommand extends AbstractCommand implements CompletionAwareInterface
+{
+
+	/**
+	 * Configures the current command.
+	 *
+	 * @return void
+	 */
+	protected function configure()
+	{
+		$this
+			->setName('classmap:rebuild')
+			->setDescription('Rebuilds the class map')
+			->addOption(
+				'module',
+				null,
+				InputOption::VALUE_OPTIONAL | InputOption::VALUE_IS_ARRAY,
+				'Module name to build class map for'
+			);
+	}
+
+	/**
+	 * Executes the current command.
+	 *
+	 * @param InputInterface  $input  An InputInterface instance.
+	 * @param OutputInterface $output An OutputInterface instance.
+	 *
+	 * @return null|integer
+	 */
+	protected function execute(InputInterface $input, OutputInterface $output)
+	{
+		$user_modules = $input->getOption('module');
+
+		if ( $user_modules ) {
+			$modules_filter = array();
+			$valid_modules = $this->getModules();
+
+			foreach ( $user_modules as $module_name ) {
+				if ( !in_array($module_name, $valid_modules) ) {
+					throw new \InvalidArgumentException('Module "' . $module_name . '" not found or installed');
+				}
+
+				$modules_filter[$module_name] = $this->Application->ModuleInfo[$module_name];
+			}
+		}
+		else {
+			$modules_filter = null;
+		}
+
+		$table_rows = array();
+
+		foreach ( ClassMapBuilder::createBuilders($modules_filter) as $class_map_builder ) {
+			$table_rows[] = $class_map_builder->build();
+		}
+
+		// Needed because we aggregate class map from installed modules in unit config cache.
+		$this->Application->HandleEvent(new \kEvent('adm:OnResetParsedData'));
+
+		$table = $this->getHelper('table');
+		$table
+			->setHeaders(array('Path', 'Scanned in', 'Parsed in'))
+			->setRows($table_rows);
+		$table->render($output);
+
+		return 0;
+	}
+
+	/**
+	 * Return possible values for the named option
+	 *
+	 * @param string            $optionName Option name.
+	 * @param CompletionContext $context    Completion context.
+	 *
+	 * @return array
+	 */
+	public function completeOptionValues($optionName, CompletionContext $context)
+	{
+		if ( $optionName === 'module' ) {
+			return $this->getModules();
+		}
+
+		return array();
+	}
+
+	/**
+	 * Returns possible module names.
+	 *
+	 * @return array
+	 */
+	protected function getModules()
+	{
+		$modules = array_keys($this->Application->ModuleInfo);
+
+		return array_diff($modules, array('In-Portal'));
+	}
+
+	/**
+	 * Return possible values for the named argument.
+	 *
+	 * @param string            $argumentName Argument name.
+	 * @param CompletionContext $context      Completion context.
+	 *
+	 * @return array
+	 */
+	public function completeArgumentValues($argumentName, CompletionContext $context)
+	{
+		return array();
+	}
+
+}
Index: branches/5.3.x/core/kernel/Console/Command/CompletionCommand.php
===================================================================
--- branches/5.3.x/core/kernel/Console/Command/CompletionCommand.php
+++ branches/5.3.x/core/kernel/Console/Command/CompletionCommand.php
@@ -0,0 +1,89 @@
+<?php
+/**
+* @version	$Id$
+* @package	In-Portal
+* @copyright	Copyright (C) 1997 - 2015 Intechnic. All rights reserved.
+* @license      GNU/GPL
+* In-Portal is Open Source software.
+* This means that this software may have been modified pursuant
+* the GNU General Public License, and as distributed it includes
+* or is derivative of works licensed under the GNU General Public License
+* or other free or open source software licenses.
+* See http://www.in-portal.org/license for copyright notices and details.
+*/
+
+namespace Intechnic\InPortal\Core\kernel\Console\Command;
+
+
+use Intechnic\InPortal\Core\kernel\Console\ConsoleApplication;
+use Stecman\Component\Symfony\Console\BashCompletion\Completion;
+use Stecman\Component\Symfony\Console\BashCompletion\CompletionCommand as BashCompletionCommand;
+use Stecman\Component\Symfony\Console\BashCompletion\CompletionHandler;
+
+defined('FULL_PATH') or die('restricted access!');
+
+class CompletionCommand extends BashCompletionCommand implements IConsoleCommand
+{
+
+	/**
+	 * Reference to global kApplication instance
+	 *
+	 * @var \kApplication.
+	 */
+	protected $Application = null;
+
+	/**
+	 * Connection to database.
+	 *
+	 * @var \IDBConnection
+	 */
+	protected $Conn = null;
+
+	/**
+	 * Sets the application instance for this command.
+	 *
+	 * @param ConsoleApplication $application An Application instance.
+	 *
+	 * @return void
+	 */
+	public function setApplication(ConsoleApplication $application = null)
+	{
+		parent::setApplication($application);
+
+		// For disabled commands $application is not set.
+		if ( isset($application) ) {
+			$this->Application = $application->getKernelApplication();
+			$this->Conn =& $this->Application->GetADODBConnection();
+		}
+	}
+
+	/**
+	 * Configure the CompletionHandler instance before it is run
+	 *
+	 * @param CompletionHandler $handler Completion handler.
+	 *
+	 * @return void
+	 */
+	protected function configureCompletion(CompletionHandler $handler)
+	{
+		// This can be removed once https://github.com/stecman/symfony-console-completion v0.5.2 will be released.
+		$handler->addHandler(
+			new Completion(
+				'help',
+				'command_name',
+				Completion::TYPE_ARGUMENT,
+				array_keys($this->getApplication()->all())
+			)
+		);
+
+		$handler->addHandler(
+			new Completion(
+				'list',
+				'namespace',
+				Completion::TYPE_ARGUMENT,
+				$this->getApplication()->getNamespaces()
+			)
+		);
+	}
+
+}
Index: branches/5.3.x/core/kernel/Console/Command/IConsoleCommand.php
===================================================================
--- branches/5.3.x/core/kernel/Console/Command/IConsoleCommand.php
+++ branches/5.3.x/core/kernel/Console/Command/IConsoleCommand.php
@@ -0,0 +1,23 @@
+<?php
+/**
+* @version	$Id$
+* @package	In-Portal
+* @copyright	Copyright (C) 1997 - 2015 Intechnic. All rights reserved.
+* @license      GNU/GPL
+* In-Portal is Open Source software.
+* This means that this software may have been modified pursuant
+* the GNU General Public License, and as distributed it includes
+* or is derivative of works licensed under the GNU General Public License
+* or other free or open source software licenses.
+* See http://www.in-portal.org/license for copyright notices and details.
+*/
+
+namespace Intechnic\InPortal\Core\kernel\Console\Command;
+
+
+defined('FULL_PATH') or die('restricted access!');
+
+interface IConsoleCommand
+{
+
+}
Index: branches/5.3.x/core/kernel/Console/Command/ResetCacheCommand.php
===================================================================
--- branches/5.3.x/core/kernel/Console/Command/ResetCacheCommand.php
+++ branches/5.3.x/core/kernel/Console/Command/ResetCacheCommand.php
@@ -0,0 +1,131 @@
+<?php
+/**
+* @version	$Id$
+* @package	In-Portal
+* @copyright	Copyright (C) 1997 - 2015 Intechnic. All rights reserved.
+* @license      GNU/GPL
+* In-Portal is Open Source software.
+* This means that this software may have been modified pursuant
+* the GNU General Public License, and as distributed it includes
+* or is derivative of works licensed under the GNU General Public License
+* or other free or open source software licenses.
+* See http://www.in-portal.org/license for copyright notices and details.
+*/
+
+namespace Intechnic\InPortal\Core\kernel\Console\Command;
+
+
+use Symfony\Component\Console\Input\InputInterface;
+use Symfony\Component\Console\Input\InputOption;
+use Symfony\Component\Console\Output\OutputInterface;
+
+defined('FULL_PATH') or die('restricted access!');
+
+class ResetCacheCommand extends AbstractCommand
+{
+
+	/**
+	 * Determines what options will execute what events.
+	 *
+	 * @var array
+	 */
+	protected $optionMap = array(
+		'unit-data' => array(
+			'short' => 'd',
+			'description' => 'Reset Parsed and Cached System Data',
+			'event' => 'adm:OnResetParsedData',
+		),
+		'unit-files' => array(
+			'short' => 'f',
+			'description' => 'Reset Configs Files Cache and Parsed System Data',
+			'event' => 'adm:OnResetConfigsCache',
+		),
+		'admin-sections' => array(
+			'short' => 's',
+			'description' => 'Reset Admin Console Sections',
+			'event' => 'adm:OnResetSections',
+		),
+		'mod-rewrite' => array(
+			'short' => 'r',
+			'description' => 'Reset ModRewrite Cache',
+			'event' => 'adm:OnResetModRwCache',
+		),
+		'sms-menu' => array(
+			'short' => 'm',
+			'description' => 'Reset SMS Menu Cache',
+			'event' => 'c:OnResetCMSMenuCache',
+		),
+		'templates' => array(
+			'short' => 't',
+			'description' => 'Clear Templates Cache',
+			'event' => 'adm:OnDeleteCompiledTemplates',
+		),
+		'all-keys' => array(
+			'short' => 'k',
+			'description' => 'Reset All Keys',
+			'event' => 'adm:OnResetMemcache',
+		),
+	);
+
+	/**
+	 * Configures the current command.
+	 *
+	 * @return void
+	 */
+	protected function configure()
+	{
+		$this
+			->setName('cache:reset')
+			->setDescription('Resets the cache');
+
+		foreach ( $this->optionMap as $option_name => $option_data ) {
+			$this->addOption(
+				$option_name,
+				$option_data['short'],
+				InputOption::VALUE_NONE,
+				$option_data['description']
+			);
+		}
+	}
+
+	/**
+	 * Executes the current command.
+	 *
+	 * @param InputInterface  $input  An InputInterface instance.
+	 * @param OutputInterface $output An OutputInterface instance.
+	 *
+	 * @return null|integer
+	 */
+	protected function execute(InputInterface $input, OutputInterface $output)
+	{
+		$success_count = 0;
+		$error_count = 0;
+
+		foreach ( $this->optionMap as $option_name => $option_data ) {
+			if ( !$input->getOption($option_name) ) {
+				continue;
+			}
+
+			$success_count++;
+			$output->write('- ' . $option_data['description'] . ' ... ');
+
+			$event = new \kEvent($option_data['event']);
+			$this->Application->HandleEvent($event);
+
+			if ( $event->getRedirectParam('action_completed') ) {
+				$output->writeln('<info>OK</info>');
+			}
+			else {
+				$error_count++;
+				$output->writeln('<error>FAILED</error>');
+			}
+		}
+
+		if ( $success_count === 0 ) {
+			throw new \RuntimeException('Please specify at least one reset option');
+		}
+
+		return $error_count == 0 ? 0 : 64;
+	}
+
+}
Index: branches/5.3.x/core/kernel/Console/Command/RunEventCommand.php
===================================================================
--- branches/5.3.x/core/kernel/Console/Command/RunEventCommand.php
+++ branches/5.3.x/core/kernel/Console/Command/RunEventCommand.php
@@ -0,0 +1,126 @@
+<?php
+/**
+* @version	$Id$
+* @package	In-Portal
+* @copyright	Copyright (C) 1997 - 2015 Intechnic. All rights reserved.
+* @license      GNU/GPL
+* In-Portal is Open Source software.
+* This means that this software may have been modified pursuant
+* the GNU General Public License, and as distributed it includes
+* or is derivative of works licensed under the GNU General Public License
+* or other free or open source software licenses.
+* See http://www.in-portal.org/license for copyright notices and details.
+*/
+
+namespace Intechnic\InPortal\Core\kernel\Console\Command;
+
+
+use Stecman\Component\Symfony\Console\BashCompletion\Completion\CompletionAwareInterface;
+use Stecman\Component\Symfony\Console\BashCompletion\CompletionContext;
+use Symfony\Component\Console\Input\InputArgument;
+use Symfony\Component\Console\Input\InputInterface;
+use Symfony\Component\Console\Output\OutputInterface;
+
+defined('FULL_PATH') or die('restricted access!');
+
+class RunEventCommand extends AbstractCommand implements CompletionAwareInterface
+{
+
+	/**
+	 * Configures the current command.
+	 *
+	 * @return void
+	 */
+	protected function configure()
+	{
+		$this
+			->setName('event:run')
+			->setDescription('Executes an event')
+			->addArgument(
+				'event_name',
+				InputArgument::REQUIRED,
+				'Event name (e.g. "<info>adm:OnDoSomething</info>")'
+			);
+	}
+
+	/**
+	 * Executes the current command.
+	 *
+	 * @param InputInterface  $input  An InputInterface instance.
+	 * @param OutputInterface $output An OutputInterface instance.
+	 *
+	 * @return null|integer
+	 */
+	protected function execute(InputInterface $input, OutputInterface $output)
+	{
+		$event_name = $input->getArgument('event_name');
+
+		$run_event = new \kEvent($event_name);
+		$this->Application->HandleEvent($run_event);
+
+		return $run_event->status == \kEvent::erSUCCESS ? 0 : 64;
+	}
+
+	/**
+	 * Return possible values for the named option
+	 *
+	 * @param string            $optionName Option name.
+	 * @param CompletionContext $context    Completion context.
+	 *
+	 * @return array
+	 */
+	public function completeOptionValues($optionName, CompletionContext $context)
+	{
+		return array();
+	}
+
+	/**
+	 * Return possible values for the named argument.
+	 *
+	 * @param string            $argumentName Argument name.
+	 * @param CompletionContext $context      Completion context.
+	 *
+	 * @return array
+	 */
+	public function completeArgumentValues($argumentName, CompletionContext $context)
+	{
+		if ( $argumentName === 'event_name' ) {
+			$event_name = $context->getCurrentWord();
+
+			// Suggest unit config prefixes.
+			if ( strpos($event_name, ':') === false ) {
+				return $this->Application->UnitConfigReader->getPrefixes(false);
+			}
+
+			try {
+				$event = new \kEvent($event_name);
+			}
+			catch ( \InvalidArgumentException $e ) {
+				// Invalid event name.
+				return array();
+			}
+
+			// Unknown unit.
+			if ( !$this->Application->prefixRegistred($event->Prefix) ) {
+				return array();
+			}
+
+			// Suggest event names.
+			$suggestions = array();
+			$reflection = new \ReflectionClass(
+				$this->Application->makeClass($event->Prefix . '_EventHandler')
+			);
+
+			foreach ( $reflection->getMethods() as $method ) {
+				if ( substr($method->getName(), 0, 2) === 'On' ) {
+					$suggestions[] = $event->Prefix . ':' . $method->getName();
+				}
+			}
+
+			return $suggestions;
+		}
+
+		return array();
+	}
+
+}
Index: branches/5.3.x/core/kernel/Console/ConsoleApplication.php
===================================================================
--- branches/5.3.x/core/kernel/Console/ConsoleApplication.php
+++ branches/5.3.x/core/kernel/Console/ConsoleApplication.php
@@ -0,0 +1,89 @@
+<?php
+/**
+* @version	$Id$
+* @package	In-Portal
+* @copyright	Copyright (C) 1997 - 2015 Intechnic. All rights reserved.
+* @license      GNU/GPL
+* In-Portal is Open Source software.
+* This means that this software may have been modified pursuant
+* the GNU General Public License, and as distributed it includes
+* or is derivative of works licensed under the GNU General Public License
+* or other free or open source software licenses.
+* See http://www.in-portal.org/license for copyright notices and details.
+*/
+
+namespace Intechnic\InPortal\Core\kernel\Console;
+
+
+use Symfony\Component\Console\Application as BaseApplication;
+use Symfony\Component\Console\Command\Command;
+
+defined('FULL_PATH') or die('restricted access!');
+
+class ConsoleApplication extends BaseApplication
+{
+
+	/**
+	 * Reference to global kApplication instance.
+	 *
+	 * @var \kApplication
+	 */
+	protected $Application = null;
+
+	/**
+	 * Connection to database
+	 *
+	 * @var \IDBConnection
+	 */
+	protected $Conn = null;
+
+	/**
+	 * Constructor.
+	 *
+	 * @param string $name    The name of the application.
+	 * @param string $version The version of the application.
+	 */
+	public function __construct($name = 'UNKNOWN', $version = 'UNKNOWN')
+	{
+		$this->Application =& \kApplication::Instance();
+		$this->Conn =& $this->Application->GetADODBConnection();
+
+		parent::__construct(
+			'In-Portal CLI',
+			$this->Application->ModuleInfo['Core']['Version'] . ' (PHP v' . phpversion() . ')'
+		);
+	}
+
+	/**
+	 * Returns Kernel Application instance.
+	 *
+	 * @return \kApplication
+	 */
+	public function getKernelApplication()
+	{
+		return $this->Application;
+	}
+
+	/**
+	 * Gets the default commands that should always be available.
+	 *
+	 * @return Command[] An array of default Command instances
+	 */
+	protected function getDefaultCommands()
+	{
+		$default_commands = parent::getDefaultCommands();
+
+		$command_provider_classes = $this->Application->getSubClasses(
+			'Intechnic\InPortal\Core\kernel\Console\IConsoleCommandProvider'
+		);
+
+		foreach ( $command_provider_classes as $command_provider_class ) {
+			/** @var IConsoleCommandProvider $command_provider */
+			$command_provider = new $command_provider_class();
+			$default_commands = array_merge($default_commands, $command_provider->getConsoleCommands());
+		}
+
+		return $default_commands;
+	}
+
+}
Index: branches/5.3.x/core/kernel/Console/ConsoleCommandProvider.php
===================================================================
--- branches/5.3.x/core/kernel/Console/ConsoleCommandProvider.php
+++ branches/5.3.x/core/kernel/Console/ConsoleCommandProvider.php
@@ -0,0 +1,42 @@
+<?php
+/**
+* @version	$Id$
+* @package	In-Portal
+* @copyright	Copyright (C) 1997 - 2015 Intechnic. All rights reserved.
+* @license      GNU/GPL
+* In-Portal is Open Source software.
+* This means that this software may have been modified pursuant
+* the GNU General Public License, and as distributed it includes
+* or is derivative of works licensed under the GNU General Public License
+* or other free or open source software licenses.
+* See http://www.in-portal.org/license for copyright notices and details.
+*/
+
+namespace Intechnic\InPortal\Core\kernel\Console;
+
+
+defined('FULL_PATH') or die('restricted access!');
+
+class ConsoleCommandProvider extends \kBase implements IConsoleCommandProvider
+{
+
+	/**
+	 * Returns console commands.
+	 *
+	 * @return array
+	 */
+	public function getConsoleCommands()
+	{
+		$commands = array();
+		$command_classes = $this->Application->getSubClasses(
+			'Intechnic\InPortal\Core\kernel\Console\Command\IConsoleCommand'
+		);
+
+		foreach ( $command_classes as $command_class ) {
+			$commands[] = new $command_class();
+		}
+
+		return $commands;
+	}
+
+}
Index: branches/5.3.x/core/kernel/Console/IConsoleCommandProvider.php
===================================================================
--- branches/5.3.x/core/kernel/Console/IConsoleCommandProvider.php
+++ branches/5.3.x/core/kernel/Console/IConsoleCommandProvider.php
@@ -0,0 +1,30 @@
+<?php
+/**
+* @version	$Id$
+* @package	In-Portal
+* @copyright	Copyright (C) 1997 - 2015 Intechnic. All rights reserved.
+* @license      GNU/GPL
+* In-Portal is Open Source software.
+* This means that this software may have been modified pursuant
+* the GNU General Public License, and as distributed it includes
+* or is derivative of works licensed under the GNU General Public License
+* or other free or open source software licenses.
+* See http://www.in-portal.org/license for copyright notices and details.
+*/
+
+namespace Intechnic\InPortal\Core\kernel\Console;
+
+
+defined('FULL_PATH') or die('restricted access!');
+
+interface IConsoleCommandProvider
+{
+
+	/**
+	 * Returns console commands.
+	 *
+	 * @return array
+	 */
+	public function getConsoleCommands();
+
+}
Index: branches/5.3.x/core/kernel/application.php
===================================================================
--- branches/5.3.x/core/kernel/application.php
+++ branches/5.3.x/core/kernel/application.php
@@ -12,6 +12,8 @@
 * See http://www.in-portal.org/license for copyright notices and details.
 */
 
+use Intechnic\InPortal\Core\kernel\Console\ConsoleApplication;
+
 defined('FULL_PATH') or die('restricted access!');
 
 /**
@@ -1053,6 +1055,16 @@
 	}
 
 	/**
+	 * Returns console application.
+	 *
+	 * @return ConsoleApplication
+	 */
+	public function getConsoleApplication()
+	{
+		return $this->makeClass('Intechnic\InPortal\Core\kernel\Console\ConsoleApplication');
+	}
+
+	/**
 	 * Only renders template
 	 *
 	 * @see kDBEventHandler::_errorNotFound()
Index: branches/5.3.x/core/kernel/utility/ClassDiscovery/ClassMapBuilder.php
===================================================================
--- branches/5.3.x/core/kernel/utility/ClassDiscovery/ClassMapBuilder.php
+++ branches/5.3.x/core/kernel/utility/ClassDiscovery/ClassMapBuilder.php
@@ -173,7 +173,7 @@
 	/**
 	 * Builds class map.
 	 *
-	 * @return void
+	 * @return array
 	 * @throws \RuntimeException When PHP parser not found.
 	 */
 	public function build()
@@ -184,16 +184,17 @@
 			throw new \RuntimeException($error_msg);
 		}
 
+		$table_output = array();
 		$scan_path = preg_replace('/^' . preg_quote(FULL_PATH, '/') . '/', '...', $this->scanPath, 1);
 
-		echo $this->strPad('path "' . $scan_path . '"', 40);
+		$table_output[] = $scan_path; // The "Path" column.
 
 		$this->load(self::CACHE_FILE_STRUCTURE, true);
 		$this->load(self::CACHE_FILE_HASHES, true);
 
 		$start = microtime(true);
 		$files = $this->scan();
-		echo $this->strPad('scanned in ' . sprintf('%.4f', microtime(true) - $start) . 's', 25);
+		$table_output[] = sprintf('%.4f', microtime(true) - $start) . 's'; // The "Scanned in" column.
 
 		$start = microtime(true);
 
@@ -203,8 +204,7 @@
 			$this->parseFile($file);
 		}
 
-		echo $this->strPad('parsed in ' . sprintf('%.4f', microtime(true) - $start) . 's', 25);
-		echo PHP_EOL;
+		$table_output[] = sprintf('%.4f', microtime(true) - $start) . 's'; // The "Parsed in" column.
 
 		ksort($this->classToFileMap);
 		ksort($this->fileHashes);
@@ -212,19 +212,8 @@
 
 		$this->store(self::CACHE_FILE_STRUCTURE);
 		$this->store(self::CACHE_FILE_HASHES);
-	}
 
-	/**
-	 * Pads text with spaces from right side.
-	 *
-	 * @param string  $text   Text.
-	 * @param integer $length Pad length.
-	 *
-	 * @return string
-	 */
-	protected function strPad($text, $length)
-	{
-		return str_pad($text, $length, ' ', STR_PAD_RIGHT);
+		return $table_output;
 	}
 
 	/**
@@ -385,7 +374,7 @@
 // {$at}codingStandardsIgnoreFile
 
 /**
- * This file is automatically {$at}generated. Use 'php tools/build_class_map.php' to rebuild it.
+ * This file is automatically {$at}generated. Please use 'in-portal classmap:rebuild' command to rebuild it.
  */
 return {$cache};
 
Index: branches/5.3.x/core/kernel/utility/event.php
===================================================================
--- branches/5.3.x/core/kernel/utility/event.php
+++ branches/5.3.x/core/kernel/utility/event.php
@@ -134,39 +134,41 @@
 		 * Parameter $params could be be an an array with following  keys: "prefix", "special" (optional), "name".
 		 * Parameter $params could be a string in format: "prefix:name" or "prefix.special:name".
 		 *
-		 * @param mixed $params
-		 * @param Array $specific_params event specific params (none by default)
-		 * @return kEvent
-		 * @access public
+		 * @param mixed $params          Params.
+		 * @param array $specific_params Event specific params (none by default).
+		 *
+		 * @throws InvalidArgumentException When incorrect event string given.
 		 */
 		public function __construct($params = Array(), $specific_params = null)
 		{
 			parent::__construct();
 
-			if ($params) {
+			if ( $params ) {
 				if ( is_array($params) ) {
 					$prefix = isset($params['prefix']) ? $params['prefix'] : false;
 					$special = isset($params['special']) ? $params['special'] : false;
 
-					if ($prefix) {
+					if ( $prefix ) {
 						$this->Init($prefix, $special);
 					}
 
 					$this->Name = isset($params['name']) ? $params['name'] : '';
 				}
 				elseif ( is_string($params) ) {
-					if (preg_match('/([^.:]*)[.]{0,1}([^:]*):(.*)/', $params, $regs)) {
+					if ( preg_match('/([^.:]*)[.]{0,1}([^:]*):(.*)/', $params, $regs) ) {
 						$prefix = $regs[1];
 						$special = $regs[2];
 
-						if ($prefix) {
+						if ( $prefix ) {
 							$this->Init($prefix, $special);
 						}
 
 						$this->Name = $regs[3];
 					}
 					else {
-						throw new Exception('Invalid event string: "<strong>' . $params . '</strong>". Should be in "prefix[.special]:OnEvent" format');
+						$error_msg = 'Invalid event string: "<strong>' . $params . '</strong>". ';
+						$error_msg .= 'Should be in "prefix[.special]:OnEvent" format';
+						throw new InvalidArgumentException($error_msg);
 					}
 				}
 			}
@@ -445,4 +447,4 @@
 		{
 			return $this->getPrefixSpecial() . ':' . $this->Name;
 		}
-	}
\ No newline at end of file
+	}
Index: branches/5.3.x/core/kernel/utility/factory.php
===================================================================
--- branches/5.3.x/core/kernel/utility/factory.php
+++ branches/5.3.x/core/kernel/utility/factory.php
@@ -347,7 +347,7 @@
 	{
 		if ( !isset($this->realClasses[$pseudo_class]) ) {
 			$error_msg = 'RealClass not defined for "<strong>' . $pseudo_class . '</strong>" pseudo_class.';
-			$error_msg .= ' Please use "<strong>php tools/build_class_map.php</strong>" to discover new classes.';
+			$error_msg .= ' Please use "<strong>in-portal classmap:rebuild</strong>" command to discover new classes.';
 
 			if ( $this->Application->isInstalled() ) {
 				throw new kFactoryException($error_msg);
Index: branches/5.3.x/core/kernel/utility/unit_config_reader.php
===================================================================
--- branches/5.3.x/core/kernel/utility/unit_config_reader.php
+++ branches/5.3.x/core/kernel/utility/unit_config_reader.php
@@ -641,13 +641,19 @@
 	}
 
 	/**
-	 * Returns prefixes of unit configs, that were registered
+	 * Returns prefixes of unit configs, that were registered.
 	 *
-	 * @return Array
+	 * @param boolean $loaded_only Only return prefixes, that were loaded till now.
+	 *
+	 * @return array
 	 */
-	public function getPrefixes()
+	public function getPrefixes($loaded_only = true)
 	{
-		return array_keys($this->configData);
+		if ( $loaded_only ) {
+			return array_keys($this->configData);
+		}
+
+		return array_keys($this->prefixFiles);
 	}
 
 	/**
@@ -721,12 +727,14 @@
 	 * @param string $prefix Unit config prefix.
 	 *
 	 * @return string
-	 * @throws Exception When unit config is not found.
+	 * @throws InvalidArgumentException When unit config is not found.
 	 */
 	public function getPrefixFile($prefix)
 	{
 		if ( !isset($this->prefixFiles[$prefix]) ) {
-			throw new Exception('Configuration file for prefix "<strong>' . $prefix . '</strong>" is unknown');
+			throw new InvalidArgumentException(
+				'Configuration file for prefix "<strong>' . $prefix . '</strong>" is unknown'
+			);
 		}
 
 		return $this->prefixFiles[$prefix];
Index: branches/5.3.x/in-portal
===================================================================
--- branches/5.3.x/in-portal
+++ branches/5.3.x/in-portal
@@ -0,0 +1,40 @@
+#!/usr/bin/env php
+<?php
+/**
+* @version	$Id$
+* @package	In-Portal
+* @copyright	Copyright (C) 1997 - 2015 Intechnic. All rights reserved.
+* @license      GNU/GPL
+* In-Portal is Open Source software.
+* This means that this software may have been modified pursuant
+* the GNU General Public License, and as distributed it includes
+* or is derivative of works licensed under the GNU General Public License
+* or other free or open source software licenses.
+* See http://www.in-portal.org/license for copyright notices and details.
+*/
+
+if ( PHP_SAPI !== 'cli' ) {
+	echo 'This script is intended to be used from command-line only !';
+	exit(64);
+}
+
+$start = microtime(true);
+
+define('CRON', 1);
+define('DBG_SKIP_REPORTING', 1);
+$_SERVER['REQUEST_URI'] = 'CRON';
+$_SERVER['HTTP_USER_AGENT'] = 'gecko';
+
+define('FULL_PATH', realpath(dirname(__FILE__)));
+include_once(FULL_PATH . '/core/kernel/startup.php');
+
+$application =& kApplication::Instance();
+$application->Init();
+
+// Assume user with all privileges, because nobody is doing authentication from CLI.
+$application->StoreVar('user_id', USER_ROOT, true);
+
+$application->getConsoleApplication()->run();
+$application->Done();
+
+$end = microtime(true);
Index: branches/5.3.x/tools/bash_completion.sh
===================================================================
--- branches/5.3.x/tools/bash_completion.sh
+++ branches/5.3.x/tools/bash_completion.sh
@@ -0,0 +1,35 @@
+
+function _in-portal_d41351fc9a70c756_complete {
+
+
+    local CMDLINE_CONTENTS="$COMP_LINE"
+    local CMDLINE_CURSOR_INDEX="$COMP_POINT"
+    local CMDLINE_WORDBREAKS="$COMP_WORDBREAKS";
+
+    export CMDLINE_CONTENTS CMDLINE_CURSOR_INDEX CMDLINE_WORDBREAKS
+
+    local RESULT STATUS;
+
+    # this is custom line
+    RESULT=$(${1} _completion); # complete
+    STATUS=$?;
+
+    local cur;
+    _get_comp_words_by_ref -n : cur;
+
+
+    if [ $STATUS -eq 200 ]; then
+        _filedir;
+        return 0;
+
+    elif [ $STATUS -ne 0 ]; then
+        echo -e "$RESULT";
+        return $?;
+    fi;
+
+    COMPREPLY=(`compgen -W "$RESULT" -- $cur`);
+
+    __ltrim_colon_completions "$cur";
+};
+
+complete -F _in-portal_d41351fc9a70c756_complete in-portal;
Index: branches/5.3.x/tools/build_class_map.php
===================================================================
--- branches/5.3.x/tools/build_class_map.php
+++ branches/5.3.x/tools/build_class_map.php
@@ -1,19 +0,0 @@
-<?php
-
-use Intechnic\InPortal\Core\kernel\utility\ClassDiscovery\ClassMapBuilder;
-
-if ( PHP_SAPI !== 'cli' ) {
-	exit(64);
-}
-
-$_GET['full_init'] = 0; // See INP-1413.
-
-define('FULL_PATH', realpath(dirname(__FILE__) . '/..'));
-require_once (FULL_PATH . '/core/kernel/startup.php');
-
-$application =& kApplication::Instance();
-$application->Init();
-
-foreach ( ClassMapBuilder::createBuilders() as $class_map_builder ) {
-	$class_map_builder->build();
-}
Index: branches/5.3.x/tools/run_event.php
===================================================================
--- branches/5.3.x/tools/run_event.php
+++ branches/5.3.x/tools/run_event.php
@@ -2,7 +2,7 @@
 /**
 * @version   $Id$
 * @package   In-Portal
-* @copyright   Copyright (C) 1997 - 2011 Intechnic. All rights reserved.
+* @copyright   Copyright (C) 1997 - 2015 Intechnic. All rights reserved.
 * @license      GNU/GPL
 * In-Portal is Open Source software.
 * This means that this software may have been modified pursuant
@@ -12,50 +12,22 @@
 * See http://www.in-portal.org/license for copyright notices and details.
 */
 
-exit_code(1, 'This script needs to be enabled manually !');
-
-if ( php_sapi_name() != 'cli' ) {
-	exit_code(2, 'This script is intended to be used from command-line only !');
+if ( PHP_SAPI !== 'cli' ) {
+	echo 'This script is intended to be used from command-line only !';
+	exit(64);
 }
 
-$start = microtime(true);
-
-define('CRON', 1);
-define('ADMIN', 1);
 define('FULL_PATH', realpath(dirname(__FILE__) . '/..'));
-define('DBG_SKIP_REPORTING', 1);
-
-$_SERVER['HTTP_USER_AGENT'] = 'gecko';
-
-// in command line, then 2nd argument is password
-$password = isset($argv) && isset($argv[2]) ? $argv[2] : '';
-
-if ( $password != 'b674006f3edb1d9cd4d838c150b0567d' ) {
-	exit_code(3, 'Bad key');
-}
-
-include_once(FULL_PATH . '/core/kernel/startup.php');
-
-$application =& kApplication::Instance();
-$application->Init();
-
-$application->StoreVar('user_id', USER_ROOT, true);
-
-$run_event = new kEvent($argv[1]); // event name in form "prefix[.special]:event_name"
-$application->HandleEvent($run_event);
-
-$application->Done();
 
+/*
+ * Arguments:
+ * 1 - event name
+ * 2 - password
+ * 3 - ip address for deployment (not handled)
+ */
+
+$exit_code = 0;
+$event_name = isset($argv[1]) ? $argv[1] : '';
+passthru(FULL_PATH . '/in-portal event:run ' . escapeshellarg($event_name), $exit_code);
+exit($exit_code);
 $end = microtime(true);
-
-exit_code($run_event->status == kEvent::erSUCCESS ? 0 : 4);
-
-function exit_code($code, $msg = '')
-{
-	if ( $msg ) {
-		echo $msg . PHP_EOL;
-	}
-
-	exit($code);
-}
-$end = microtime(true);
\ No newline at end of file