diff --git a/class2.php b/class2.php
index 694d1ab9d..4fb2e7921 100644
--- a/class2.php
+++ b/class2.php
@@ -9,9 +9,9 @@
 * General purpose file
 *
 * $Source: /cvs_backup/e107_0.8/class2.php,v $
-* $Revision: 1.152 $
-* $Date: 2009-10-30 20:58:52 $
-* $Author: marj_nl_fr $
+* $Revision: 1.153 $
+* $Date: 2009-10-31 17:57:15 $
+* $Author: secretr $
 *
 */
 //
@@ -2101,8 +2101,21 @@ function plugInstalled($plugname)
 }
 
 /**
- * Magic autoload
- * TODO - move to spl_autoload[_*] some day (PHP5 > 5.1.2)
+ * Magic class autoload.
+ * We are raising plugin structure standard here - plugin auto-loading works ONLY if 
+ * classes live inside 'includes' folder.
+ * Example: plugin_myplug_admin_ui -> 
+ * <code>
+ * <?php
+ * // __autoload() will look in e_PLUGIN.'myplug/includes/admin/ui.php for this class
+ * // e_admin_ui is core handler, so it'll be autoloaded as well
+ * class plugin_myplug_admin_ui extends e_admin_ui
+ * {
+ * 
+ * }
+ * </code>
+ * TODO - use spl_autoload[_*] for core autoloading some day (PHP5 > 5.1.2)
+ * 
  * @param string $className
  * @return void
  */
@@ -2117,9 +2130,10 @@ function __autoload($className)
 	
 	switch($tmp[0])
 	{
-		case 'plugin':
-		case 'eplug_':
+		case 'plugin': 
 			array_shift($tmp);
+			// folder 'includes' is not part of the class name
+			$tmp[0] = $tmp[0].'/includes'; 
 			$filename = e_PLUGIN.implode('/', $tmp).'.php';
 			//TODO add debug screen Auto-loaded classes - ['plugin: '.$filename.' - '.$className];
 		break;
@@ -2132,6 +2146,7 @@ function __autoload($className)
 	
 	if($filename)
 	{
+		// auto load doesn't REQUIRE files, because this will break things like call_user_func()
 		include($filename);
 	}
 } 
diff --git a/e107_admin/header.php b/e107_admin/header.php
index 2de750e25..9162e79ef 100644
--- a/e107_admin/header.php
+++ b/e107_admin/header.php
@@ -9,9 +9,9 @@
  * Admin Header
  *
  * $Source: /cvs_backup/e107_0.8/e107_admin/header.php,v $
- * $Revision: 1.49 $
- * $Date: 2009-10-29 02:29:33 $
- * $Author: marj_nl_fr $
+ * $Revision: 1.50 $
+ * $Date: 2009-10-31 17:57:15 $
+ * $Author: secretr $
 */
 
 if (!defined('e107_INIT'))
@@ -327,13 +327,22 @@ if (vartrue($pref['e_meta_list']))
 	}
 }
 
-//XXX - do we still need it?
+//XXX - do we still need it? Now we have better way of doing this - admin tools (see below)
 if (function_exists('headerjs'))
 {
 	echo headerjs();
 }
 
-// [JSManager] Load JS Includes - Zone 4 - After e_meta, headerjs
+// Admin UI - send header content if any - headerjs() replacement
+$tmp = e107::getAdminUI();
+if($tmp)
+{
+	// Note: normally you shouldn't send JS content here, former is (much better) handled by JS manager (both files and inline)
+	echo $tmp->getHeader();
+}
+unset($tmp);
+
+// [JSManager] Load JS Includes - Zone 4 - After e_meta, headerjs, before Admin UI headers
 e107::getJs()->renderJs('header', 4);
 e107::getJs()->renderJs('header_inline', 4);
 
diff --git a/e107_files/shortcode/batch/admin_shortcodes_class.php b/e107_files/shortcode/batch/admin_shortcodes_class.php
index cb70f7f35..905c54d59 100644
--- a/e107_files/shortcode/batch/admin_shortcodes_class.php
+++ b/e107_files/shortcode/batch/admin_shortcodes_class.php
@@ -1,7 +1,7 @@
 <?php
 /*
 * Copyright e107 Inc e107.org, Licensed under GNU GPL (http://www.gnu.org/licenses/gpl.txt)
-* $Id: admin_shortcodes_class.php,v 1.27 2009-10-22 23:43:21 e107coders Exp $
+* $Id: admin_shortcodes_class.php,v 1.28 2009-10-31 17:57:15 secretr Exp $
 *
 * Admin shortcode batch - class
 */
@@ -439,46 +439,61 @@ class admin_shortcodes
 
 	function sc_admin_menu($parm)
 	{
-		if (ADMIN)
+		if (!ADMIN)
+		{
+			return '';
+		}
+		global $ns, $pref;
+		
+		// SecretR: NEW v0.8
+		$tmp = e107::getAdminUI();
+		if($tmp)
 		{
-			global $ns, $pref;
-
 			ob_start();
-			//Show upper_right menu if the function exists
-			$tmp = explode('.',e_PAGE);
-            $adminmenu_parms = "";
-
-			$adminmenu_func = $tmp[0].'_adminmenu';
-			if(function_exists($adminmenu_func))
-			{
-				if (!$parm)
-				{
-					call_user_func($adminmenu_func,$adminmenu_parms);   // ? not sure why there's an adminmenu_parms;
-				}
-				else
-				{
-					ob_end_clean();
-					return 'pre';
-				}
-			}
-			$plugindir = (str_replace('/','',str_replace('..', '', e_PLUGIN)).'/');
-			$plugpath = e_PLUGIN.str_replace(basename(e_SELF), '', str_replace($plugindir, '', strstr(e_SELF,$plugindir))).'admin_menu.php';
-			if(file_exists($plugpath))
-			{
-				if (!$parm)
-				{
-					@require_once($plugpath);
-				}
-				else
-				{
-					ob_end_clean();
-					return 'pre';
-				}
-			}
+			// FIXME - renderMenu(), respectively e_admin_menu() should return, not output content!
+			$tmp->renderMenu();
 			$ret = ob_get_contents();
 			ob_end_clean();
 			return $ret;
 		}
+		unset($tmp);
+
+		// Obsolete
+		ob_start();
+		//Show upper_right menu if the function exists
+		$tmp = explode('.',e_PAGE);
+        $adminmenu_parms = "";
+
+		$adminmenu_func = $tmp[0].'_adminmenu';
+		if(function_exists($adminmenu_func))
+		{
+			if (!$parm)
+			{
+				call_user_func($adminmenu_func,$adminmenu_parms);   // ? not sure why there's an adminmenu_parms;
+			}
+			else
+			{
+				ob_end_clean();
+				return 'pre';
+			}
+		}
+		$plugindir = (str_replace('/','',str_replace('..', '', e_PLUGIN)).'/');
+		$plugpath = e_PLUGIN.str_replace(basename(e_SELF), '', str_replace($plugindir, '', strstr(e_SELF,$plugindir))).'admin_menu.php';
+		if(file_exists($plugpath))
+		{
+			if (!$parm)
+			{
+				@require_once($plugpath);
+			}
+			else
+			{
+				ob_end_clean();
+				return 'pre';
+			}
+		}
+		$ret = ob_get_contents();
+		ob_end_clean();
+		return $ret;
 	}
 
 	function sc_admin_msg($parm)
@@ -1054,7 +1069,7 @@ class admin_shortcodes
 
 			$text .= adnav_cat(ADLAN_CL_8, '', E_16_CAT_ABOUT, 'docsMenu'); //E_16_NAV_DOCS
 			$text .= "<div id='docsMenu' class='menu' onmouseover=\"menuMouseover(event)\">";
-			if (!$handle=opendir(e_DOCS.e_LANGUAGE."/"))
+			if (!is_readable(e_DOCS.e_LANGUAGE."/")) // warning killed
 			{
 				$handle=opendir(e_DOCS.'English/');
 			}
diff --git a/e107_handlers/admin_handler.php b/e107_handlers/admin_handler.php
index 583fd4986..24cd2dfd6 100644
--- a/e107_handlers/admin_handler.php
+++ b/e107_handlers/admin_handler.php
@@ -390,21 +390,36 @@ class e_admin_request
 	
 	/**
 	 * Build query string from current request array
+	 * NOTE: changing url separator to &amp; ($encode==true) (thus URL XHTML compliance) works in PHP 5.1.2+ environment
+	 * 
 	 * @param string|array $merge_with [optional] override request values
+	 * @param boolean $encode if true &amp; separator will be used, all values will be http encoded, default true
 	 * @return string url encoded query string
 	 */
-	public function buildQueryString($merge_with = array())
+	public function buildQueryString($merge_with = array(), $encode = true)
 	{
 		$ret = $this->getQuery();
 		if(is_string($merge_with))
 		{
 			parse_str($merge_with, $merge_with);
 		}
-		return http_build_query(array_merge($ret, (array) $merge_with));
+		$ret = array_merge($ret, (array) $merge_with);
+		$separator = '&';
+		if($encode)
+		{
+			$separator = '&amp;';
+			$ret = array_map('rawurlencode', $ret);
+			foreach ($ret as $key => $value)
+			{
+				$ret[$key] = rawurlencode($value);
+			}
+		}
+		
+		return http_build_query($ret, 'numeric_', $separator);
 	}
 	
 	/**
-	 * Convert string to camelCase
+	 * Convert string to CamelCase
 	 * 
 	 * @param string $str
 	 * @return string
@@ -894,7 +909,7 @@ class e_admin_dispatcher
 	 * 
 	 * @var array
 	 */
-	protected $controllerList;
+	protected $modes;
 	
 	/**
 	 * Optional (set by child class).
@@ -917,7 +932,7 @@ class e_admin_dispatcher
 	 * @param string|array|e_admin_request $request [optional]
 	 * @param e_admin_response $response
 	 */
-	public function __construct($request = null, $response = null)
+	public function __construct($request = null, $response = null, $auto_observe = true)
 	{
 		if(null === $request || !is_object($request))
 		{
@@ -930,7 +945,14 @@ class e_admin_dispatcher
 		}
 		
 		$this->setRequest($request)->setResponse($response)->init();
-		//$this->_initController();
+		
+		// register itself
+		e107::setRegistry('admin/ui/dispatcher', $this);
+		
+		if($auto_observe)
+		{
+			$this->runObservers(true);
+		}
 		
 	}
 	
@@ -1087,6 +1109,16 @@ class e_admin_dispatcher
 		return $response->send('default', $options);
 	}
 	
+	/**
+	 * Proxy method
+	 * 
+	 * @return string
+	 */
+	public function getHeader()
+	{
+		return $this->getController()->getHeader();
+	}
+	
 	/**
 	 * Get current controller object
 	 * @return e_admin_controller
@@ -1109,10 +1141,10 @@ class e_admin_dispatcher
 	{
 		$request = $this->getRequest();
 		$response = $this->getResponse();
-		if(isset($this->controllerList[$request->getModeName()]) && isset($this->controllerList[$request->getModeName()]['controller']))
+		if(isset($this->modes[$request->getModeName()]) && isset($this->modes[$request->getModeName()]['controller']))
 		{
-			$class_name = $this->controllerList[$request->getModeName()]['controller'];
-			$class_path = vartrue($this->controllerList[$request->getModeName()]['path']);
+			$class_name = $this->modes[$request->getModeName()]['controller'];
+			$class_path = vartrue($this->modes[$request->getModeName()]['path']);
 			
 			if($class_path)
 			{
@@ -1138,10 +1170,10 @@ class e_admin_dispatcher
 				$this->_current_controller->setRequest($request)->init(); 
 			}
 			
-			if(vartrue($this->controllerList[$request->getModeName()]['ui']))
+			if(vartrue($this->modes[$request->getModeName()]['ui']))
 			{
-				$class_name = $this->controllerList[$request->getModeName()]['ui'];
-				$class_path = vartrue($this->controllerList[$request->getModeName()]['uipath']);
+				$class_name = $this->modes[$request->getModeName()]['ui'];
+				$class_path = vartrue($this->modes[$request->getModeName()]['uipath']);
 				if($class_path)
 				{
 					require_once(e107::getParser()->replaceConstants($class_path));
@@ -1151,6 +1183,8 @@ class e_admin_dispatcher
 					$this->_current_controller->setParam('ui', new $class_name($this->_current_controller));
 				}
 			}
+			$this->_current_controller->setParam('modes', $this->modes);
+			
 		}
 		
 		return $this;
@@ -1179,7 +1213,7 @@ class e_admin_dispatcher
 	 * Generic Admin Menu Generator
 	 * @return string
 	 */
-	function renderMenu()
+	function renderMenu($return = true)
 	{
 		$tp = e107::getParser();
 		$var = array();
@@ -1217,7 +1251,7 @@ class e_admin_dispatcher
 			$var[$key]['perm'] = $val['perm'];	*/
 		}
 		$request = $this->getRequest();
-		e_admin_menu($this->menuTitle, $request->getMode().'/'.$request->getAction(), $var);
+		return e_admin_menu($this->menuTitle, $request->getMode().'/'.$request->getAction(), $var);
 	}
 }
 
@@ -1267,7 +1301,8 @@ class e_admin_controller
 	 * Get controller parameter
 	 * Currently used core parameters:
 	 * - enable_triggers: don't use it direct, see {@link setTriggersEnabled()}
-	 * - TODO - more parameters
+	 * - modes - see dispatcher::$modes
+	 * - TODO - more parameters/add missing to this list
 	 * 
 	 * @param string $key [optional] if null - get whole array 
 	 * @param mixed $default [optional]
@@ -1674,6 +1709,99 @@ class e_admin_controller
 		return '<div class="center">Requested page was not found!</div>'; // TODO - lan
 	}
 	
+	/**
+	 * Generic redirect handler, it handles almost everything we would need.
+	 * Additionally, it moves currently registered system messages to SESSION message stack
+	 * In almost every case {@link redirectAction()} and {@link redirectMode()} are better solution
+	 * 
+	 * @param string $action defaults to current action 
+	 * @param string $mode defaults to current mode 
+	 * @param string|array $exclude_query comma delimited variable names to be excluded from current query OR TRUE to exclude everything
+	 * @param string|array $merge_query query string (&amp; delimiter) or associative array to be merged with current query
+	 * @param string $path default to e_SELF
+	 * @return void
+	 */
+	public function redirect($action = null, $mode = null, $exclude_query = '', $merge_query = array(), $path = null)
+	{
+		$request = $this->getRequest();
+		
+		//special case - exclude all current
+		if(true === $exclude_query)
+		{
+			$exclude_query = $this->getQuery();
+		}
+		// to array
+		if(is_string($exclude_query))
+		{
+			$exclude_query = array_map('trim', explode(',', $exclude_query));
+		}
+		// to array
+		if(is_string($merge_query))
+		{
+			parse_str($merge_query, $merge_query);
+		}
+		//this should be part of request handler
+		if($exclude_query) 
+		{
+			// Converting array on the fly as of PHP 5.3+/6 - cool, isn't it!
+			// $request->setQuery(array_map(function($value) { return null; }, $exclude_query));
+			foreach ($exclude_query as $var)
+			{
+				$request->setQuery($var, null);
+			}
+		}
+		// Set them in the end
+		if($mode) $request->setMode($mode);
+		if($action) $request->setAction($action);
+		if(!$path) $path = e_SELF;
+		
+		$url = $path.'?'.$request->buildQueryString($merge_query, false);
+		// Transfer all messages to session
+		e107::getMessage()->mergeWithSession();
+		// write session data
+		session_write_close();
+		// do redirect
+		header('Location: '.$url);
+		exit;
+	}
+	
+	/**
+	 * Convenient redirect() proxy method, make life easier when redirecting between actions 
+	 * in same mode.
+	 * 
+	 * @param string $action [optional]
+	 * @param string|array $exclude_query [optional]
+	 * @param string|array $merge_query [optional]
+	 * @return 
+	 */
+	public function redirectAction($action = null, $exclude_query = '', $merge_query = array())
+	{
+		$this->redirect($action, null, $exclude_query, $merge_query);
+	}
+	
+	/**
+	 * Convenient redirect to another mode (doesn't use current Query state)
+	 * If path is empty, it'll be auto-detected from modes (dispatcher) array
+	 * 
+	 * @param string $mode
+	 * @param string $action
+	 * @param string|array $query [optional]
+	 * @param string $path
+	 * @return void
+	 */
+	public function redirectMode($mode, $action, $query = array(), $path = null)
+	{
+		if(!$path && $this->getParam('modes'))
+		{
+			$modes = $this->getParam('modes');
+			if(vartue($modes[$mode]) && vartrue($modes[$mode]['url']))
+			{
+				$path = e107::getParser()->replaceConstants($modes[$mode]['url'], 'abs');
+			}
+		}
+		$this->redirect($action, $mode, true, $query, $path);
+	}
+	
 	/**
 	 * Convert action name to method name
 	 * 
@@ -1727,13 +1855,13 @@ class e_admin_controller
 	}
 }
 
-//FIXME - move everything from e_admin_controller_main except model auto-create related code
+//FIXME - move everything from e_admin_ui except model auto-create related code
 class e_admin_controller_ui extends e_admin_controller
 {
 	
 }
 
-class e_admin_controller_main extends e_admin_controller_ui
+class e_admin_ui extends e_admin_controller_ui
 {
 	protected $fields = array();
 	protected $fieldpref = array();
@@ -1869,6 +1997,14 @@ class e_admin_controller_main extends e_admin_controller_ui
 		$this->getModel()->load($this->getId());
 	}
 	
+	/**
+	 * Generic Create submit trigger
+	 */
+	public function EditCancelTrigger()
+	{
+		$this->redirectAction('list', 'id');
+	}
+	
 	/**
 	 * Generic Edit submit trigger
 	 */
@@ -1895,6 +2031,14 @@ class e_admin_controller_main extends e_admin_controller_ui
 		$this->triggersEnabled(true);
 	}
 	
+	/**
+	 * Generic Create submit trigger
+	 */
+	public function CreateCancelTrigger()
+	{
+		$this->redirectAction('list', 'id');
+	}
+	
 	/**
 	 * Generic Create submit trigger
 	 */
@@ -2069,7 +2213,7 @@ class e_admin_controller_main extends e_admin_controller_ui
 				->setValidationRules($this->validationRules)
 				->setFieldTypes($this->fieldTypes)
 				->setDataFields($this->dataFields)
-				->setParam($this->editQry);
+				->setParam('db_query', $this->editQry);
 		}
 		return $this->_model;
 	}
@@ -2122,16 +2266,16 @@ class e_admin_controller_main extends e_admin_controller_ui
 	}
 }
 
-class e_admin_ui extends e_form
+class e_admin_form_ui extends e_form
 {	
 	/**
-	 * @var e_admin_controller_main
+	 * @var e_admin_ui
 	 */
 	protected $_controller = null;
 	
 	/**
 	 * Constructor
-	 * @param e_admin_controller_main $controller
+	 * @param e_admin_ui $controller
 	 * @param boolean $tabindex [optional] enable form element auto tab-indexing
 	 */
 	function __construct($controller, $tabindex = false)
@@ -2211,6 +2355,7 @@ class e_admin_ui extends e_form
 						$text .= $this->admin_button('etrigger_submit', LAN_CREATE, 'create');	
 						$text .= "<input type='hidden' name='record_id' value='0' />";
 					}
+					$text .= $this->admin_button('etrigger_cancel', LAN_CANCEL, 'cancel');
 					
 		$text .= "
 				</div>
@@ -2502,7 +2647,7 @@ class e_admin_ui extends e_form
 	}
 	
 	/**
-	 * @return e_admin_controller_main
+	 * @return e_admin_ui
 	 */
 	public function getController()
 	{
@@ -2515,13 +2660,13 @@ class e_admin_ui extends e_form
 class e_admin_ui_dummy extends e_form
 {	
 	/**
-	 * @var e_admin_controller_main
+	 * @var e_admin_ui
 	 */
 	protected $_controller = null;
 	
 	/**
 	 * Constructor
-	 * @param e_admin_controller_main $controller
+	 * @param e_admin_ui $controller
 	 * @return 
 	 */
 	function __construct($controller)
@@ -2796,7 +2941,7 @@ class e_admin_ui_dummy extends e_form
 	}
 	
 	/**
-	 * @return e_admin_controller_main
+	 * @return e_admin_ui
 	 */
 	public function getController()
 	{
@@ -2804,3 +2949,16 @@ class e_admin_ui_dummy extends e_form
 	}
 }
 
+/**
+ * TODO:
+ * 1. move abstract peaces of code to the proper classes
+ * 2. remove duplicated code (e_form & e_admin_form_ui), refactoring
+ * 3. make JS Manager handle Styles (.css files and inline CSS)
+ * 4. e_form is missing some methods used in e_admin_form_ui
+ * 5. date convert needs string-to-datestamp auto parsing, strptime() is the solution but needs support for 
+ * 		Windows and PHP < 5.1.0 - build custom strptime() function (php_compatibility_handler.php) on this - 
+ * 		http://sauron.lionel.free.fr/?page=php_lib_strptime (bad license so no copy/paste is allowed!)
+ * 6. $fields[parms] mess - fix it, separate list/edit mode parms somehow
+ * 7. clean up/document all object vars (e_admin_ui, e_admin_dispatcher)
+ * 8. clean up/document all parameters (get/setParm()) in controller and model classes
+ */
\ No newline at end of file
diff --git a/e107_handlers/e107_class.php b/e107_handlers/e107_class.php
index 266903ede..a80636c6c 100644
--- a/e107_handlers/e107_class.php
+++ b/e107_handlers/e107_class.php
@@ -9,8 +9,8 @@
  * e107 Main
  *
  * $Source: /cvs_backup/e107_0.8/e107_handlers/e107_class.php,v $
- * $Revision: 1.61 $
- * $Date: 2009-10-30 17:59:31 $
+ * $Revision: 1.62 $
+ * $Date: 2009-10-31 17:57:15 $
  * $Author: secretr $
 */
 
@@ -93,39 +93,47 @@ class e107
 	 * 'class name' => 'path' pair
 	 * 
 	 * Used to auto-load core handlers 
+	 * TODO - we really need to alphabetically re-order this!
 	 *
 	 * @see getSingleton()
 	 * @see getObject()
 	 * @var array
 	 */
 	protected static $_known_handlers = array (
-		'db'			=> '{e_HANDLER}mysql_class.php',
-		'ecache'		=> '{e_HANDLER}cache_handler.php',
-		'user_class'	=> '{e_HANDLER}userclass_class.php',
-		'e107_event'	=> '{e_HANDLER}event_class.php',
-		'ArrayData'		=> '{e_HANDLER}arraystorage_class.php',
-		'eURL'			=> '{e_HANDLER}e107Url.php',
-		'e_file'		=> '{e_HANDLER}file_class.php',
-		'e_admin_log'	=> '{e_HANDLER}admin_log_class.php',
-		'notify'		=> '{e_HANDLER}notify_class.php',
-		'e_online'		=> '{e_HANDLER}online_class.php',
-		'convert'		=> '{e_HANDLER}date_handler.php',
-		'e_news_item' 	=> '{e_HANDLER}news_class.php',
-		'e_news_tree' 	=> '{e_HANDLER}news_class.php',
-		'news' 			=> '{e_HANDLER}news_class.php',
-		'e_form' 		=> '{e_HANDLER}form_handler.php',
-		'e_upgrade' 	=> '{e_HANDLER}e_upgrade_class.php',
-		'e_jshelper' 	=> '{e_HANDLER}js_helper.php',
-		'e_menu' 		=> '{e_HANDLER}menu_class.php',
-		'e107plugin' 	=> '{e_HANDLER}plugin_class.php',
-		'xmlClass' 		=> '{e_HANDLER}xml_class.php',
-		'e107_traffic'	=> '{e_HANDLER}traffic_class.php',
-		'comment'		=> '{e_HANDLER}comment_class.php',
-		'e_validator'	=> '{e_HANDLER}validator_class.php',
-		'themeHandler'	=> '{e_HANDLER}theme_handler.php',
-		'e_model'		=> '{e_HANDLER}model_class.php',
-		'e_admin_model'	=> '{e_HANDLER}model_class.php',
-		'DHTML_Calendar'=> '{e_HANDLER}calendar/calendar_class.php',
+		'db'						=> '{e_HANDLER}mysql_class.php',
+		'ecache'					=> '{e_HANDLER}cache_handler.php',
+		'user_class'				=> '{e_HANDLER}userclass_class.php',
+		'e107_event'				=> '{e_HANDLER}event_class.php',
+		'ArrayData'					=> '{e_HANDLER}arraystorage_class.php',
+		'eURL'						=> '{e_HANDLER}e107Url.php',
+		'e_file'					=> '{e_HANDLER}file_class.php',
+		'e_admin_log'				=> '{e_HANDLER}admin_log_class.php',
+		'notify'					=> '{e_HANDLER}notify_class.php',
+		'e_online'					=> '{e_HANDLER}online_class.php',
+		'convert'					=> '{e_HANDLER}date_handler.php',
+		'e_news_item' 				=> '{e_HANDLER}news_class.php',
+		'e_news_tree' 				=> '{e_HANDLER}news_class.php',
+		'news' 						=> '{e_HANDLER}news_class.php',
+		'e_form' 					=> '{e_HANDLER}form_handler.php',
+		'e_upgrade' 				=> '{e_HANDLER}e_upgrade_class.php',
+		'e_jshelper' 				=> '{e_HANDLER}js_helper.php',
+		'e_menu' 					=> '{e_HANDLER}menu_class.php',
+		'e107plugin' 				=> '{e_HANDLER}plugin_class.php',
+		'xmlClass' 					=> '{e_HANDLER}xml_class.php',
+		'e107_traffic'				=> '{e_HANDLER}traffic_class.php',
+		'comment'					=> '{e_HANDLER}comment_class.php',
+		'e_validator'				=> '{e_HANDLER}validator_class.php',
+		'themeHandler'				=> '{e_HANDLER}theme_handler.php',
+		'e_model'					=> '{e_HANDLER}model_class.php',
+		'e_admin_model'				=> '{e_HANDLER}model_class.php',
+		'e_admin_dispatcher' 		=> '{e_HANDLER}admin_handler.php',
+		'e_admin_request' 			=> '{e_HANDLER}admin_handler.php',
+		'e_admin_response' 			=> '{e_HANDLER}admin_handler.php',
+		'e_admin_controller' 		=> '{e_HANDLER}admin_handler.php',
+		'e_admin_controller_ui' 	=> '{e_HANDLER}admin_handler.php',
+		'e_admin_ui' 				=> '{e_HANDLER}admin_handler.php',
+		'e_admin_form_ui' 			=> '{e_HANDLER}admin_handler.php',
+		'DHTML_Calendar'			=> '{e_HANDLER}calendar/calendar_class.php',
 	);
 	
 	/**
@@ -837,6 +845,18 @@ class e107
 		return e_jsmanager::getInstance();
 	}
 	
+	/**
+	 * Retrieve admin dispatcher instance.
+	 * It's instance is self registered (for now, this could change in the future) on initialization (__construct())
+	 * 
+	 * @see e_admin_dispatcher
+	 * @return e_admin_dispatcher
+	 */
+	public static function getAdminUI()
+	{
+		return self::getRegistry('admin/ui/dispatcher');
+	}
+	
 	/**
 	 * Get core template. Use this method for templates, which are following the 
 	 * new template standards:
diff --git a/e107_plugins/release/admin_config.php b/e107_plugins/release/admin_config.php
index b6ed6d2af..b3f6f1e88 100644
--- a/e107_plugins/release/admin_config.php
+++ b/e107_plugins/release/admin_config.php
@@ -9,8 +9,8 @@
  * e107 Release Plugin
  *
  * $Source: /cvs_backup/e107_0.8/e107_plugins/release/admin_config.php,v $
- * $Revision: 1.11 $
- * $Date: 2009-10-30 17:59:32 $
+ * $Revision: 1.12 $
+ * $Date: 2009-10-31 17:57:15 $
  * $Author: secretr $
  *
 */
@@ -18,270 +18,42 @@
 require_once("../../class2.php");
 if (!getperms("P")) { header("location:".e_BASE."index.php"); exit; }
 
-require_once(e_HANDLER.'admin_handler.php');
+/*
+ * After initialization we'll be able to call dispatcher via e107::getAdminUI()
+ * so this is the first we should do on admin page.
+ * Global instance variable is not needed.
+ * NOTE: class is auto-loaded - see class2.php __autoload()
+ */
+/* $dispatcher = */new plugin_release_admin();
 
-class plugin_release_admin_dispatcher extends e_admin_dispatcher
-{
-		/**
-		 * Format: 'MODE' => array('controller' =>'CONTROLLER_CLASS'[, 'path' => 'CONTROLLER SCRIPT PATH', 'ui' => 'UI CLASS NAME child of e_admin_ui', 'uipath' => 'UI SCRIPT PATH']);
-		 * @var array
-		 */
-		protected $controllerList = array(
-			'main'		=> array('controller' => 'plugin_release_admin_controller_main', 'path' => null, 'ui' => 'plugin_release_admin_ui_main', 'uipath' => null)				
-		);	
-		/**
-		 * Format: 'MODE/ACTION' => array('caption' => 'Menu link title'[, 'url' => '{e_PLUGIN}release/admin_config.php', 'perm' => '0']);
-		 * Additionally, any valid e_admin_menu() key-value pair could be added to the above array
-		 * @var array
-		 */
-		protected $adminMenu = array(
-			'main/list'		=> array('caption'=> 'Release List', 'perm'=>'0'),
-			'main/create' 	=> array('caption'=> LAN_CREATE, 'perm'=>'0'),
-			'main/options' 	=> array('caption'=> LAN_OPTIONS, 'perm'=>'0'),
-			'main/custom'	=> array('caption'=> 'Custom Page', 'perm'=>0)		
-		);	
-		
-		/**
-		 * Navigation menu title
-		 * @var string
-		 */
-		protected $menuTitle = 'Release Menu';
-}
-
-class plugin_release_admin_controller_main extends e_admin_controller_main
-{
-		// required
-		protected $pluginTitle = "e107 Release";
-		
-		// required
-		protected $pluginName = 'release';
-		
-		// required - if no custom model is set in init()
-		protected $table = "release";
-		
-		// required - if no custom model is set in init() (primary id)
-		protected $pid = "release_id";
-		
-		// optional 
-		protected $perPage = 20;
-		
-		// default - true
-		protected $batchDelete = true;
-	    
-		//TODO change the release_url type back to URL before release. 
-		// required
-    	protected  $fields = array(
-			'checkboxes'				=> array('title'=> '', 					'type' => null,			'data' => null,			'width'=>'5%', 		'thclass' =>'center', 'forced'=> TRUE,  'class'=>'center', 'toggle' => 'e-multiselect'),
-			'release_id'				=> array('title'=> ID, 					'type' => 'int',		'data' => 'int',		'width'=>'5%',		'thclass' => '',	'forced'=> TRUE, 'primary'=>TRUE/*, 'noedit'=>TRUE*/), //Primary ID is note editable
-            'release_type'	   			=> array('title'=> 'Type', 				'type' => 'method', 	'data' => 'str',		'width'=>'auto',	'thclass' => '', 'batch' => TRUE, 'filter'=>TRUE),
-			'release_folder' 			=> array('title'=> 'Folder', 			'type' => 'text', 		'data' => 'str',		'width' => 'auto',	'thclass' => ''),	
-			'release_name' 				=> array('title'=> 'Name', 				'type' => 'text', 		'data' => 'str',		'width' => 'auto',	'thclass' => ''),
-			'release_version' 			=> array('title'=> 'Version',			'type' => 'text', 		'data' => 'str',		'width' => 'auto',	'thclass' => ''),
-			'release_author' 			=> array('title'=> LAN_AUTHOR,			'type' => 'text', 		'data' => 'str',		'width' => 'auto',	'thclass' => 'left'), 
-         	'release_authorURL' 		=> array('title'=> LAN_AUTHOR_URL, 		'type' => 'url', 		'data' => 'str',		'width' => 'auto',	'thclass' => 'left'), 
-            'release_date' 				=> array('title'=> LAN_DATE, 			'type' => 'datestamp', 	'data' => 'int',		'width' => 'auto',	'thclass' => ''),	 
-			'release_compatibility' 	=> array('title'=> 'compatib',			'type' => 'text', 		'data' => 'str',		'width' => '10%',	'thclass' => 'center' ),	 
-			'release_url' 				=> array('title'=> 'release_url',		'type' => 'url', 		'data' => 'str',		'width' => '20%',	'thclass' => 'center',	'batch' => TRUE, 'filter'=>TRUE, 'parms' => 'truncate=30', 'validate' => true, 'help' => 'Enter release URL here', 'error' => 'please, ener valid URL'),	 
-			'options' 					=> array('title'=> LAN_OPTIONS, 		'type' => null, 		'data' => null,			'width' => '10%',	'thclass' => 'center last', 'class' => 'center last', 'forced'=>TRUE)
-		);
-		
-		//required - default column user prefs 
-		protected $fieldpref = array('checkboxes', 'release_id', 'release_type', 'release_url', 'release_compatibility', 'options');
-		
-		// optional if fields 'data' attribute is set or if custom model is set in init()
-		/*protected $dataFields = array(
-			'release_id' => 'int',
-			'release_type' => 'str',
-			'release_folder' => 'str',
-			'release_name' => 'str',
-			'release_version' => 'str',
-			'release_author' => 'str',
-			'release_authorURL' => 'str',
-			'release_date' => 'int',
-			'release_compatibility' => 'str',
-			'release_url' => 'str',
-		);*/
-		
-		// optional, could be also set directly from $fields array with attributes 'validate' => true|'rule_name', 'rule' => 'condition_name', 'error' => 'Validation Error message'
-		/*protected  $validationRules = array(
-			'release_url' => array('required', '', 'Release URL', 'Help text', 'not valid error message')
-		);*/
-		
-		// optional
-		protected $prefs = array( //TODO add option for core or plugin pref. 
-		
-			'pref_type'	   				=> array('title'=> 'type', 'type'=>'text'),
-			'pref_folder' 				=> array('title'=> 'folder', 'type' => 'boolean'),	
-			'pref_name' 				=> array('title'=> 'name', 'type' => 'text')		
-		);
-		
-		// required if no custom tree model is set in init()
-		protected $listQry = "SELECT * FROM #release"; // without any Order or Limit. 
-		
-		// optional - required only in case of e.g. tables JOIN. This also could be done with custom model (set it in init())
-		protected $editQry = "SELECT * FROM #release WHERE release_id = {ID}";
-		
-		// optional
-		public function init()
-		{
-		}
-}
-
-class plugin_release_admin_ui_main extends e_admin_ui
-{
-	function release_type($curVal,$mode) // not really necessary since we can use 'dropdown' - but just an example of a custom function. 
-	{
-		if($mode == 'list')
-		{
-			return $curVal.' (custom!)';
-		}
-		
-		if($mode == 'batch') // Custom Batch List for release_type
-		{
-			return array('theme'=>"Theme","plugin"=>'Plugin');	
-		}
-		
-		if($mode == 'filter') // Custom Filter List for release_type
-		{
-			return array('theme'=>"Theme","plugin"=>'Plugin');	
-		}
-		
-		$types = array("theme","plugin");
-		$text = "<select class='tbox' name='release_type' >";
-		foreach($types as $val)
-		{
-			$selected = ($curVal == $val) ? "selected='selected'" : "";
-			$text .= "<option value='{$val}' {$selected}>".$val."</option>\n";
-		}
-		$text .= "</select>";
-		return $text;
-	}
-}
-
-$dispatcher = new plugin_release_admin_dispatcher();
-$dispatcher->runObservers(true);
-e107::setRegistry('admin/release_dispatcher', $dispatcher);
+/*
+ * Uncomment the below only if you disable the auto observing above
+ * Example: $dispatcher = new plugin_release_admin(null, null, false);
+ */
+//$dispatcher->runObservers(true);
 
 require_once(e_ADMIN."auth.php");
 
-e107::getRegistry('admin/release_dispatcher')->runPage();
+/*
+ * Send page content
+ */
+e107::getAdminUI()->runPage();
 
 require_once(e_ADMIN."footer.php");
 
-/*
-class releasePlugin extends e_model_interface
-{
-
-	function __construct()
-	{	
-	
-		$this->pluginTitle = "e107 Release";
-	
-		$this->table = "release";
-	    
-		//TODO change the release_url type back to URL before release. 
-		
-    	$this->fields = array(
-			'checkboxes'				=> array('title'=> '', 					'type' => '',		'width'=>'5%', 		'thclass' =>'center', 'forced'=> TRUE,  'class'=>'center'),
-			'release_id'				=> array('title'=> ID, 					'type' => '',		'width'=>'5%',		'thclass' => '',	'forced'=> TRUE, 'primary'=>TRUE),
-            'release_type'	   			=> array('title'=> 'Type', 				'type' => 'method', 'width'=>'auto',	'thclass' => '', 'batch' => TRUE, 'filter'=>TRUE),
-			'release_folder' 			=> array('title'=> 'Folder', 			'type' => 'text', 	'width' => 'auto',	'thclass' => ''),	
-			'release_name' 				=> array('title'=> 'Name', 				'type' => 'text', 	'width' => 'auto',	'thclass' => ''),
-			'release_version' 			=> array('title'=> 'Version',			'type' => 'text', 	'width' => 'auto',	'thclass' => ''),
-			'release_author' 			=> array('title'=> LAN_AUTHOR,			'type' => 'text', 	'width' => 'auto',	'thclass' => 'left'), 
-         	'release_authorURL' 		=> array('title'=> LAN_AUTHOR.'URL', 	'type' => 'url', 	'width' => 'auto',	'thclass' => 'left'), 
-            'release_date' 				=> array('title'=> LAN_DATE, 			'type' => 'text', 	'width' => 'auto',	'thclass' => ''),	 
-			'release_compatibility' 	=> array('title'=> 'compatib',			'type' => 'text', 	'width' => '10%',	'thclass' => 'center' ),	 
-			'release_url' 				=> array('title'=> 'Userclass',				'type' => 'userclass', 	'width' => '10%',	'thclass' => 'center',	'batch' => TRUE, 'filter'=>TRUE),	 
-			'options' 					=> array('title'=> LAN_OPTIONS, 		'type' => '', 		'width' => '10%',	'thclass' => 'center last', 'class' => 'center last', 'forced'=>TRUE)
-		);
-		
-		$this->prefs = array( //TODO add option for core or plugin pref. 
-		
-			'pref_type'	   				=> array('title'=> 'type', 'type'=>'text'),
-			'pref_folder' 				=> array('title'=> 'folder', 'type' => 'boolean'),	
-			'pref_name' 				=> array('title'=> 'name', 'type' => 'text')		
-		);
-		
-		$this->listQry = "SELECT * FROM #release"; // without any Order or Limit. 
-		$this->editQry = "SELECT * FROM #release WHERE release_id = {ID}";		
-	
-		$this->adminMenu = array(
-			'list'		=> array('caption'=>'Release List', 'perm'=>'0'),
-			'create' 	=> array('caption'=>LAN_CREATE."/".LAN_EDIT, 'perm'=>'0'),
-			'options' 	=> array('caption'=>LAN_OPTIONS, 'perm'=>'0'),
-			'custom'	=> array('caption'=>'Custom Page', 'perm'=>0)				
-		);		
-	}
-	
-	// Custom View/Form-Element method. ie. Naming should match field/key with type=method.
-	
-	
-	function release_type($curVal,$mode) // not really necessary since we can use 'dropdown' - but just an example of a custom function. 
-	{
-		if($mode == 'list')
-		{
-			return $curVal.' (custom!)';
-		}
-		
-		if($mode == 'batch') // Custom Batch List for release_type
-		{
-			return array('theme'=>"Theme","plugin"=>'Plugin');	
-		}
-		
-		if($mode == 'filter') // Custom Filter List for release_type
-		{
-			return array('theme'=>"Theme","plugin"=>'Plugin');	
-		}
-		
-		$types = array("theme","plugin");
-		$text = "<select class='tbox' name='release_type' >";
-		foreach($types as $val)
-		{
-			$selected = ($curVal == $val) ? "selected='selected'" : "";
-			$text .= "<option value='{$val}' {$selected}>".$val."</option>\n";
-		}
-		$text .= "</select>";
-		return $text;
-	}
-	
-	//custom Page = Naming should match $this->adminMenu key + 'Page'. 
-	function customPage()
-	{
-		$ns = e107::getRender();
-		$ns->tablerender("Custom","This is a custom Page");
-	}
-
-}
-*/
-//$rp = new releasePlugin;
-//$rp->init();
-
-
+/* OBSOLETE - see admin_shortcodes::sc_admin_menu()
 function admin_config_adminmenu() //TODO move this into e_model_interface
 {
 	//global $rp;
 	//$rp->show_options();
 	e107::getRegistry('admin/release_dispatcher')->renderMenu();
 }
+*/
 
-
+/* OBSOLETE - done within header.php
 function headerjs() // needed for the checkboxes - how can we remove the need to duplicate this code?
 {
-	/*require_once (e_HANDLER.'js_helper.php');
-	$ret = "
-		<script type='text/javascript'>
-			if(typeof e107Admin == 'undefined') var e107Admin = {}
-
-			e107Admin.initRules = {
-				'Helper': true,
-				'AdminMenu': false
-			}
-		</script>
-		<script type='text/javascript' src='".e_FILE_ABS."jslib/core/admin.js'></script>
-	";*/
-	return e107::getRegistry('admin/release_dispatcher')->getController()->getHeader();
-
-	//return $ret;
+	return e107::getAdminUI()->getHeader();
 }
+*/
 ?>
\ No newline at end of file
diff --git a/e107_plugins/release/includes/admin.php b/e107_plugins/release/includes/admin.php
new file mode 100644
index 000000000..a95d9b625
--- /dev/null
+++ b/e107_plugins/release/includes/admin.php
@@ -0,0 +1,231 @@
+<?php
+/*
+ * e107 website system
+ *
+ * Copyright (C) 2001-2009 e107 Inc (e107.org)
+ * Released under the terms and conditions of the
+ * GNU General Public License (http://www.gnu.org/licenses/gpl.txt)
+ *
+ * Release Plugin Administration UI
+ *
+ * $Source: /cvs_backup/e107_0.8/e107_plugins/release/includes/admin.php,v $
+ * $Revision: 1.1 $
+ * $Date: 2009-10-31 17:57:15 $
+ * $Author: secretr $
+*/
+
+//require_once(e_HANDLER.'admin_handler.php'); - autoloaded - see class2.php __autoload()
+class plugin_release_admin extends e_admin_dispatcher
+{
+	/**
+	 * Format: 'MODE' => array('controller' =>'CONTROLLER_CLASS'[, 'path' => 'CONTROLLER SCRIPT PATH', 'ui' => 'UI CLASS NAME child of e_admin_ui', 'uipath' => 'UI SCRIPT PATH']);
+	 * @var array
+	 */
+	protected $modes = array(
+		'main'		=> array('controller' => 'plugin_release_admin_ui', 'path' => null, 'ui' => 'plugin_release_admin_form_ui', 'uipath' => null)				
+	);	
+	/**
+	 * Format: 'MODE/ACTION' => array('caption' => 'Menu link title'[, 'url' => '{e_PLUGIN}release/admin_config.php', 'perm' => '0']);
+	 * Additionally, any valid e_admin_menu() key-value pair could be added to the above array
+	 * @var array
+	 */
+	protected $adminMenu = array(
+		'main/list'		=> array('caption'=> 'Release List', 'perm'=>'0'),
+		'main/create' 	=> array('caption'=> LAN_CREATE, 'perm'=>'0'),
+		'main/options' 	=> array('caption'=> LAN_OPTIONS, 'perm'=>'0'),
+		'main/custom'	=> array('caption'=> 'Custom Page', 'perm'=>0)		
+	);	
+	
+	/**
+	 * Navigation menu title
+	 * @var string
+	 */
+	protected $menuTitle = 'Release Menu';
+}
+
+class plugin_release_admin_ui extends e_admin_ui
+{
+		// required
+		protected $pluginTitle = "e107 Release";
+		
+		// required
+		protected $pluginName = 'release';
+		
+		// required - if no custom model is set in init()
+		protected $table = "release";
+		
+		// required - if no custom model is set in init() (primary id)
+		protected $pid = "release_id";
+		
+		// optional 
+		protected $perPage = 20;
+		
+		// default - true
+		protected $batchDelete = true;
+	    
+		//TODO change the release_url type back to URL before release. 
+		// required
+    	protected  $fields = array(
+			'checkboxes'				=> array('title'=> '', 					'type' => null,			'data' => null,			'width'=>'5%', 		'thclass' =>'center', 'forced'=> TRUE,  'class'=>'center', 'toggle' => 'e-multiselect'),
+			'release_id'				=> array('title'=> ID, 					'type' => 'int',		'data' => 'int',		'width'=>'5%',		'thclass' => '',	'forced'=> TRUE, 'primary'=>TRUE/*, 'noedit'=>TRUE*/), //Primary ID is note editable
+            'release_type'	   			=> array('title'=> 'Type', 				'type' => 'method', 	'data' => 'str',		'width'=>'auto',	'thclass' => '', 'batch' => TRUE, 'filter'=>TRUE),
+			'release_folder' 			=> array('title'=> 'Folder', 			'type' => 'text', 		'data' => 'str',		'width' => 'auto',	'thclass' => ''),	
+			'release_name' 				=> array('title'=> 'Name', 				'type' => 'text', 		'data' => 'str',		'width' => 'auto',	'thclass' => ''),
+			'release_version' 			=> array('title'=> 'Version',			'type' => 'text', 		'data' => 'str',		'width' => 'auto',	'thclass' => ''),
+			'release_author' 			=> array('title'=> LAN_AUTHOR,			'type' => 'text', 		'data' => 'str',		'width' => 'auto',	'thclass' => 'left'), 
+         	'release_authorURL' 		=> array('title'=> LAN_AUTHOR_URL, 		'type' => 'url', 		'data' => 'str',		'width' => 'auto',	'thclass' => 'left'), 
+            'release_date' 				=> array('title'=> LAN_DATE, 			'type' => 'datestamp', 	'data' => 'int',		'width' => 'auto',	'thclass' => ''),	 
+			'release_compatibility' 	=> array('title'=> 'compatib',			'type' => 'text', 		'data' => 'str',		'width' => '10%',	'thclass' => 'center' ),	 
+			'release_url' 				=> array('title'=> 'release_url',		'type' => 'url', 		'data' => 'str',		'width' => '20%',	'thclass' => 'center',	'batch' => TRUE, 'filter'=>TRUE, 'parms' => 'truncate=30', 'validate' => true, 'help' => 'Enter release URL here', 'error' => 'please, ener valid URL'),	 
+			'options' 					=> array('title'=> LAN_OPTIONS, 		'type' => null, 		'data' => null,			'width' => '10%',	'thclass' => 'center last', 'class' => 'center last', 'forced'=>TRUE)
+		);
+		
+		//required - default column user prefs 
+		protected $fieldpref = array('checkboxes', 'release_id', 'release_type', 'release_url', 'release_compatibility', 'options');
+		
+		// FORMAT field_name=>type - optional if fields 'data' attribute is set or if custom model is set in init()
+		/*protected $dataFields = array();*/
+		
+		// optional, could be also set directly from $fields array with attributes 'validate' => true|'rule_name', 'rule' => 'condition_name', 'error' => 'Validation Error message'
+		/*protected  $validationRules = array(
+			'release_url' => array('required', '', 'Release URL', 'Help text', 'not valid error message')
+		);*/
+		
+		// optional, if $pluginName == 'core', core prefs will be used, else e107::getPluginConfig($pluginName);
+		protected $prefs = array( 
+			'pref_type'	   				=> array('title'=> 'type', 'type'=>'text'),
+			'pref_folder' 				=> array('title'=> 'folder', 'type' => 'boolean'),	
+			'pref_name' 				=> array('title'=> 'name', 'type' => 'text')		
+		);
+		
+		// required if no custom tree model is set in init()
+		protected $listQry = "SELECT * FROM #release"; // without any Order or Limit. 
+		
+		// optional - required only in case of e.g. tables JOIN. This also could be done with custom model (set it in init())
+		protected $editQry = "SELECT * FROM #release WHERE release_id = {ID}";
+		
+		// optional
+		public function init()
+		{
+		}
+}
+
+class plugin_release_admin_form_ui extends e_admin_form_ui
+{
+	function release_type($curVal,$mode) // not really necessary since we can use 'dropdown' - but just an example of a custom function. 
+	{
+		if($mode == 'list')
+		{
+			return $curVal.' (custom!)';
+		}
+		
+		if($mode == 'batch') // Custom Batch List for release_type
+		{
+			return array('theme'=>"Theme","plugin"=>'Plugin');	
+		}
+		
+		if($mode == 'filter') // Custom Filter List for release_type
+		{
+			return array('theme'=>"Theme","plugin"=>'Plugin');	
+		}
+		
+		$types = array("theme","plugin");
+		$text = "<select class='tbox' name='release_type' >";
+		foreach($types as $val)
+		{
+			$selected = ($curVal == $val) ? "selected='selected'" : "";
+			$text .= "<option value='{$val}' {$selected}>".$val."</option>\n";
+		}
+		$text .= "</select>";
+		return $text;
+	}
+}
+
+/* OBSOLETE - will be removed soon
+class releasePlugin extends e_model_interface
+{
+
+	function __construct()
+	{	
+	
+		$this->pluginTitle = "e107 Release";
+	
+		$this->table = "release";
+	    
+		//TODO change the release_url type back to URL before release. 
+		
+    	$this->fields = array(
+			'checkboxes'				=> array('title'=> '', 					'type' => '',		'width'=>'5%', 		'thclass' =>'center', 'forced'=> TRUE,  'class'=>'center'),
+			'release_id'				=> array('title'=> ID, 					'type' => '',		'width'=>'5%',		'thclass' => '',	'forced'=> TRUE, 'primary'=>TRUE),
+            'release_type'	   			=> array('title'=> 'Type', 				'type' => 'method', 'width'=>'auto',	'thclass' => '', 'batch' => TRUE, 'filter'=>TRUE),
+			'release_folder' 			=> array('title'=> 'Folder', 			'type' => 'text', 	'width' => 'auto',	'thclass' => ''),	
+			'release_name' 				=> array('title'=> 'Name', 				'type' => 'text', 	'width' => 'auto',	'thclass' => ''),
+			'release_version' 			=> array('title'=> 'Version',			'type' => 'text', 	'width' => 'auto',	'thclass' => ''),
+			'release_author' 			=> array('title'=> LAN_AUTHOR,			'type' => 'text', 	'width' => 'auto',	'thclass' => 'left'), 
+         	'release_authorURL' 		=> array('title'=> LAN_AUTHOR.'URL', 	'type' => 'url', 	'width' => 'auto',	'thclass' => 'left'), 
+            'release_date' 				=> array('title'=> LAN_DATE, 			'type' => 'text', 	'width' => 'auto',	'thclass' => ''),	 
+			'release_compatibility' 	=> array('title'=> 'compatib',			'type' => 'text', 	'width' => '10%',	'thclass' => 'center' ),	 
+			'release_url' 				=> array('title'=> 'Userclass',				'type' => 'userclass', 	'width' => '10%',	'thclass' => 'center',	'batch' => TRUE, 'filter'=>TRUE),	 
+			'options' 					=> array('title'=> LAN_OPTIONS, 		'type' => '', 		'width' => '10%',	'thclass' => 'center last', 'class' => 'center last', 'forced'=>TRUE)
+		);
+		
+		$this->prefs = array( //TODO add option for core or plugin pref. 
+		
+			'pref_type'	   				=> array('title'=> 'type', 'type'=>'text'),
+			'pref_folder' 				=> array('title'=> 'folder', 'type' => 'boolean'),	
+			'pref_name' 				=> array('title'=> 'name', 'type' => 'text')		
+		);
+		
+		$this->listQry = "SELECT * FROM #release"; // without any Order or Limit. 
+		$this->editQry = "SELECT * FROM #release WHERE release_id = {ID}";		
+	
+		$this->adminMenu = array(
+			'list'		=> array('caption'=>'Release List', 'perm'=>'0'),
+			'create' 	=> array('caption'=>LAN_CREATE."/".LAN_EDIT, 'perm'=>'0'),
+			'options' 	=> array('caption'=>LAN_OPTIONS, 'perm'=>'0'),
+			'custom'	=> array('caption'=>'Custom Page', 'perm'=>0)				
+		);		
+	}
+	
+	// Custom View/Form-Element method. ie. Naming should match field/key with type=method.
+	
+	
+	function release_type($curVal,$mode) // not really necessary since we can use 'dropdown' - but just an example of a custom function. 
+	{
+		if($mode == 'list')
+		{
+			return $curVal.' (custom!)';
+		}
+		
+		if($mode == 'batch') // Custom Batch List for release_type
+		{
+			return array('theme'=>"Theme","plugin"=>'Plugin');	
+		}
+		
+		if($mode == 'filter') // Custom Filter List for release_type
+		{
+			return array('theme'=>"Theme","plugin"=>'Plugin');	
+		}
+		
+		$types = array("theme","plugin");
+		$text = "<select class='tbox' name='release_type' >";
+		foreach($types as $val)
+		{
+			$selected = ($curVal == $val) ? "selected='selected'" : "";
+			$text .= "<option value='{$val}' {$selected}>".$val."</option>\n";
+		}
+		$text .= "</select>";
+		return $text;
+	}
+	
+	//custom Page = Naming should match $this->adminMenu key + 'Page'. 
+	function customPage()
+	{
+		$ns = e107::getRender();
+		$ns->tablerender("Custom","This is a custom Page");
+	}
+
+}
+*/
+//$rp = new releasePlugin;
+//$rp->init();
\ No newline at end of file