diff --git a/setup/inc/class.setup_cmd.inc.php b/setup/inc/class.setup_cmd.inc.php
index 461ff40678..7459199c78 100644
--- a/setup/inc/class.setup_cmd.inc.php
+++ b/setup/inc/class.setup_cmd.inc.php
@@ -7,7 +7,7 @@
  * @package setup
  * @copyright (c) 2007 by Ralf Becker <RalfBecker-AT-outdoor-training.de>
  * @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License
- * @version $Id: class.admin_cmd_check_acl.inc.php 24709 2007-11-27 03:20:28Z ralfbecker $ 
+ * @version $Id$ 
  */
 
 /**
@@ -73,17 +73,6 @@ abstract class setup_cmd extends admin_cmd
 		return $secret;
 	}
 	
-	/**
-	 * Restore our db connection
-	 *
-	 */
-	static protected function restore_db()
-	{
-		$GLOBALS['egw']->db->disconnect();
-		$GLOBALS['egw']->db->connect();
-		
-	}
-	
 	/**
 	 * Saving the object to the database, reimplemented to not do it in setup context
 	 *
@@ -98,4 +87,252 @@ abstract class setup_cmd extends admin_cmd
 		}
 		return true;
 	}
+	
+	/**
+	 * Reference to the setup object, after calling check_setup_auth method
+	 *
+	 * @var setup
+	 */
+	static protected $egw_setup;
+
+	/**
+	 * Create the setup enviroment (for running within setup or eGW)
+	 */
+	static protected function _setup_enviroment($domain=null)
+	{
+		if (!is_object($GLOBALS['egw_setup']))
+		{
+			$GLOBALS['egw_setup'] = new setup(true,true);
+		}
+		self::$egw_setup = $GLOBALS['egw_setup'];
+		self::$egw_setup->ConfigDomain = $domain;
+
+		if (isset($GLOBALS['egw_info']['server']['header_admin_user']) && !isset($GLOBALS['egw_domain']))
+		{
+			// we run inside eGW, not setup --> read egw_domain array from the header via the showheader cmd
+			$cmd = new setup_cmd_showheader(null);	// null = only header, no db stuff, no hashes
+			$header = $cmd->run();
+			$GLOBALS['egw_domain'] = $header['egw_domain'];
+		}
+		if (is_object($GLOBALS['egw']->db) && $domain)
+		{
+			$GLOBALS['egw']->db->disconnect();
+			$GLOBALS['egw']->db->connect(
+				$GLOBALS['egw_domain'][$domain]['db_name'],
+				$GLOBALS['egw_domain'][$domain]['db_host'],
+				$GLOBALS['egw_domain'][$domain]['db_port'],
+				$GLOBALS['egw_domain'][$domain]['db_user'],
+				$GLOBALS['egw_domain'][$domain]['db_pass'],
+				$GLOBALS['egw_domain'][$domain]['db_type']
+			);
+		}
+	}
+
+	/**
+	 * Restore eGW's db connection
+	 *
+	 */
+	static function restore_db()
+	{
+		if (is_object($GLOBALS['egw']->db))
+		{
+			$GLOBALS['egw']->db->disconnect();
+			$GLOBALS['egw']->db->connect(
+				$GLOBALS['egw_info']['server']['db_name'],
+				$GLOBALS['egw_info']['server']['db_host'],
+				$GLOBALS['egw_info']['server']['db_port'],
+				$GLOBALS['egw_info']['server']['db_user'],
+				$GLOBALS['egw_info']['server']['db_pass'],
+				$GLOBALS['egw_info']['server']['db_type']
+			);
+		}
+	}
+	
+	/**
+	 * Creates a setup like enviroment and checks for the header user/pw or config_user/pw if domain given
+	 *
+	 * @param string $user
+	 * @param string $pw
+	 * @param string $domain=null if given we also check agains config user/pw
+	 * @throws egw_exception_no_permission(lang('Access denied: wrong username or password for manage-header !!!'),21);
+	 * @throws egw_exception_no_permission(lang("Access denied: wrong username or password to configure the domain '%1(%2)' !!!",$domain,$GLOBALS['egw_domain'][$domain]['db_type']),40);
+	 */
+	static function check_setup_auth($user,$pw,$domain=null)
+	{
+		self::_setup_enviroment($domain);
+
+		// check the authentication if a header_admin_password is set, if not we dont have a header yet and no authentication
+		if ($GLOBALS['egw_info']['server']['header_admin_password'])	// if that's not given we dont have a header yet
+		{
+			if (!self::$egw_setup->check_auth($user,$pw,$GLOBALS['egw_info']['server']['header_admin_user'],
+					$GLOBALS['egw_info']['server']['header_admin_password']) &&
+				(is_null($domain) || !isset($GLOBALS['egw_domain'][$domain]) || // if valid domain given check it's config user/pw
+					!self::$egw_setup->check_auth($user,$pw,$GLOBALS['egw_domain'][$domain]['config_user'],
+						$GLOBALS['egw_domain'][$domain]['config_passwd'])))
+			{
+				if (is_null($domain))
+				{
+					throw new egw_exception_no_permission(lang('Access denied: wrong username or password for manage-header !!!'),21);
+				}
+				else
+				{
+					throw new egw_exception_no_permission(lang("Access denied: wrong username or password to configure the domain '%1(%2)' !!!",$domain,$GLOBALS['egw_domain'][$domain]['db_type']),40);
+				}
+			}
+		}
+/*		if ($domain)
+		{
+			self::$egw_setup->ConfigDomain = $domain;
+		}*/
+	}
+
+	/**
+	 * Check if eGW is installed, which versions and if an update is needed
+	 * 
+	 * @param string $domain='' domain to check, default '' = all
+	 * @param int/array $stop=0 stop checks before given exit-code(s), default 0 = all checks
+	 * @param boolean $verbose=false echo messages as they happen, instead returning them
+	 * @return array with translated messages
+	 */
+	function check_installed($domain='',$stop=0,$verbose=false)
+	{
+		self::_setup_enviroment($domain);
+
+		global $setup_info;
+		static $header_checks=true;	// output the header checks only once
+		
+		$messages = array();
+		
+		if ($stop && !is_array($stop)) $stop = array($stop);
+	
+		$versions =& $GLOBALS['egw_info']['server']['versions'];
+	
+		if (!$versions['phpgwapi'])
+		{
+			if (!include('../phpgwapi/setup/setup.inc.php'))
+			{
+				throw new egw_exception_wrong_userinput(lang("eGroupWare sources in '%1' are not complete, file '%2' missing !!!",realpath('..'),'phpgwapi/setup/setup.inc.php'),99);	// should not happen ;-)
+			}
+			$versions['phpgwapi'] = $setup_info['phpgwapi']['version'];
+			unset($setup_info);
+		}
+		if ($header_checks)
+		{
+			$messages[] = self::_echo_message($verbose,lang('eGroupWare API version %1 found.',$versions['phpgwapi']));
+		}
+		$header_stage = self::$egw_setup->detection->check_header();
+		if ($stop && in_array($header_stage,$stop)) return true;
+		
+		switch ($header_stage)
+		{
+			case 1: throw new egw_exception_wrong_userinput(lang('eGroupWare configuration file (header.inc.php) does NOT exist.')."\n".lang('Use --create-header to create the configuration file (--usage gives more options).'),1);
+				
+			case 2: throw new egw_exception_wrong_userinput(lang('eGroupWare configuration file (header.inc.php) version %1 exists%2',$versions['header'],'.')."\n".lang('No header admin password set! Use --edit-header <password>[,<user>] to set one (--usage gives more options).'),2);
+	
+			case 3: throw new egw_exception_wrong_userinput(lang('eGroupWare configuration file (header.inc.php) version %1 exists%2',$versions['header'],'.')."\n".lang('No eGroupWare domains / database instances exist! Use --edit-header --domain to add one (--usage gives more options).'),3);
+	
+			case 4: throw new egw_exception_wrong_userinput(lang('eGroupWare configuration file (header.inc.php) version %1 exists%2',$versions['header'],'.')."\n".lang('It needs upgrading to version %1! Use --update-header <password>[,<user>] to do so (--usage gives more options).',$versions['current_header']),4);
+		}
+		if ($header_checks)
+		{
+			$messages[] = self::_echo_message($verbose,lang('eGroupWare configuration file (header.inc.php) version %1 exists%2',
+				$versions['header'],' '.lang('and is up to date')));
+		}
+		$header_checks = false;	// no further output of the header checks
+	
+		$domains = $GLOBALS['egw_domain'];
+		if ($domain)	// domain to check given
+		{
+			if (!isset($GLOBALS['egw_domain'][$domain])) throw new egw_exception_wrong_userinput(lang("Domain '%1' does NOT exist !!!",$domain));
+			
+			$domains = array($domain => $GLOBALS['egw_domain'][$domain]);
+		}
+		foreach($domains as $domain => $data)
+		{
+			self::$egw_setup->ConfigDomain = $domain;	// set the domain the setup class operates on
+			if (count($GLOBALS['egw_domain']) > 1)
+			{
+				self::_echo_message($verbose);
+				$messages[] = self::_echo_message($verbose,lang('eGroupWare domain/instance %1(%2):',$domain,$data['db_type']));
+			}
+			$setup_info = self::$egw_setup->detection->get_versions();
+			// check if there's already a db-connection and close if, otherwise the db-connection of the previous domain will be used
+			if (is_object(self::$egw_setup->db))
+			{
+				self::$egw_setup->db->disconnect();
+			}
+			self::$egw_setup->loaddb();
+			
+			$db = $data['db_type'].'://'.$data['db_user'].':'.$data['db_pass'].'@'.$data['db_host'].'/'.$data['db_name'];
+	
+			$db_stage =& $GLOBALS['egw_info']['setup']['stage']['db'];
+			if (($db_stage = self::$egw_setup->detection->check_db($setup_info)) != 1)
+			{
+				$setup_info = self::$egw_setup->detection->get_db_versions($setup_info);
+				$db_stage = self::$egw_setup->detection->check_db($setup_info);
+			}
+			if ($stop && in_array(10+$db_stage,$stop))
+			{
+				return $messages;
+			}
+			switch($db_stage)
+			{
+				case 1: throw new egw_exception_wrong_userinput(lang('Your Database is not working!')." $db: ".self::$egw_setup->db->Error,11);
+	
+				case 3: throw new egw_exception_wrong_userinput(lang('Your database is working, but you dont have any applications installed')." ($db). ".lang("Use --install to install eGroupWare."),13);
+	
+				case 4: throw new egw_exception_wrong_userinput(lang('eGroupWare API needs a database (schema) update from version %1 to %2!',$setup_info['phpgwapi']['currentver'],$versions['phpgwapi']).' '.lang('Use --update to do so.'),14);
+				
+				case 10:	// also check apps of updates
+					$apps_to_upgrade = array();
+					$apps_to_install = array();
+					foreach($setup_info as $app => $data)
+					{
+						if ($data['currentver'] && $data['version'] && $data['version'] != $data['currentver'])
+						{
+							$apps_to_upgrade[] = $app;
+						}
+						if (!isset($data['enabled']))
+						{
+							$apps_to_install[] = $app;
+						}
+					}
+					if ($apps_to_install)
+					{
+						self::_echo_message($verbose);
+						$messages[] = self::_echo_message($verbose,lang('The following applications are NOT installed:').' '.implode(', ',$apps_to_install));
+					}
+					if ($apps_to_upgrade)
+					{
+						$db_stage = 4;
+						if ($stop && in_array(10+$db_stage,$stop)) return $messages;
+
+						throw new egw_exception_wrong_userinput(lang('The following applications need to be upgraded:').' '.implode(', ',$apps_to_upgrade).'! '.lang('Use --update to do so.'),14);
+					}
+					break;
+			}
+			$messages[] = self::_echo_message($verbose,lang("database is version %1 and up to date.",$setup_info['phpgwapi']['currentver']));
+	
+			self::$egw_setup->detection->check_config();
+			if ($GLOBALS['egw_info']['setup']['config_errors'] && $stop && !in_array(15,$stop))
+			{
+				throw new egw_exception_wrong_userinput(lang('You need to configure eGroupWare:')."\n- ".@implode("\n- ",$GLOBALS['egw_info']['setup']['config_errors']),15);
+			}
+		}
+		return $messages;
+	}
+
+	/**
+	 * Echo the given message, if $verbose
+	 *
+	 * @param boolean $verbose
+	 * @param string $msg
+	 * @return string $msg
+	 */
+	static function _echo_message($verbose,$msg='')
+	{
+		if ($verbose) echo $msg."\n";
+
+		return $msg;
+	}
 }
diff --git a/setup/inc/class.setup_cmd_header.inc.php b/setup/inc/class.setup_cmd_header.inc.php
index dfe03655f9..b2e426ca74 100644
--- a/setup/inc/class.setup_cmd_header.inc.php
+++ b/setup/inc/class.setup_cmd_header.inc.php
@@ -83,42 +83,24 @@ class setup_cmd_header extends setup_cmd
 				throw new egw_exception_wrong_userinput(
 					lang('eGroupWare configuration file header.inc.php already exists, you need to use --edit-header or delete it first!'),20);
 			}
-			
-			// check header-admin-user and -password (only if a password is set!)
-			if ($GLOBALS['egw_info']['server']['header_admin_password'])
+			if ($this->arguments)
 			{
-				if (!is_object($GLOBALS['egw_setup']))
-				{
-					$GLOBALS['egw_setup'] = new setup();				
-				}
-				if ($this->arguments)
-				{
-					list($this->header_admin_password,$this->header_admin_user) = explode(',',$this->arguments[1]);
-				}
-				if (!$GLOBALS['egw_setup']->check_auth($this->header_admin_user,$this->header_admin_password,
-					$GLOBALS['egw_info']['server']['header_admin_user'],
-					$GLOBALS['egw_info']['server']['header_admin_password']))
-				{
-					throw new egw_exception_no_permission(lang('Access denied: wrong username or password for manage-header !!!'),21);
-				}
+				list($this->header_admin_password,$this->header_admin_user) = explode(',',$this->arguments[1]);
 			}
+			$this->check_setup_auth($this->header_admin_user,$this->header_admin_password);	// no domain, we require header access!
+
 			$GLOBALS['egw_info']['server']['server_root'] = EGW_SERVER_ROOT;
 			$GLOBALS['egw_info']['server']['include_root'] = EGW_INCLUDE_ROOT;
-			
-			if (!isset($GLOBALS['egw_domain']))
-			{
-				// we run inside eGW, not setup --> read egw_domain array from the header via the showheader cmd
-				$cmd = new setup_cmd_showheader();
-				$header = $cmd->run();
-				$GLOBALS['egw_domain'] = $header['egw_domain'];
-				unset($cmd); unset($header);
-			}
 		}
 		
 		if ($this->arguments)	// we have command line arguments
 		{
 			$this->_parse_cli_arguments();
 		}
+		elseif ($this->sub_command == 'delete')
+		{
+			self::_delete_domain($this->domain);
+		}
 		else
 		{
 			$this->_parse_properties();
@@ -249,11 +231,7 @@ class setup_cmd_header extends setup_cmd
 			
 			if ($arg == '--delete-domain')
 			{
-				if (!isset($GLOBALS['egw_domain'][$values]))
-				{
-					throw new egw_exception_wrong_userinput(lang("Domain '%1' does NOT exist !!!",$values),92);
-				}
-				unset($GLOBALS['egw_domain'][$values]);
+				$this->_delete_domain($values);
 				continue;
 			}
 			
@@ -275,6 +253,20 @@ class setup_cmd_header extends setup_cmd
 		}
 	}
 	
+	/**
+	 * Delete a given domain/instance from the header
+	 *
+	 * @param string $domain
+	 */
+	private static function _delete_domain($domain)
+	{
+		if (!isset($GLOBALS['egw_domain'][$domain]))
+		{
+			throw new egw_exception_wrong_userinput(lang("Domain '%1' does NOT exist !!!",$domain),92);
+		}
+		unset($GLOBALS['egw_domain'][$domain]);
+	}
+
 	/**
 	 * Parses a single value
 	 *
diff --git a/setup/inc/class.setup_cmd_install.inc.php b/setup/inc/class.setup_cmd_install.inc.php
new file mode 100644
index 0000000000..551428ad4a
--- /dev/null
+++ b/setup/inc/class.setup_cmd_install.inc.php
@@ -0,0 +1,96 @@
+<?php
+/**
+ * eGgroupWare setup - install a new instance
+ *
+ * @link http://www.egroupware.org
+ * @author Ralf Becker <RalfBecker-AT-outdoor-training.de>
+ * @package setup
+ * @copyright (c) 2007 by Ralf Becker <RalfBecker-AT-outdoor-training.de>
+ * @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License
+ * @version $Id$ 
+ */
+
+/**
+ * setup command: install a new instance
+ */
+class setup_cmd_install extends setup_cmd 
+{
+	/**
+	 * Constructor
+	 *
+	 * @param string $domain string with domain-name or array with all arguments
+	 * @param string $config_user=null user to config the domain (or header_admin_user)
+	 * @param string $config_passwd=null pw of above user
+	 * @param string $backup=null filename of backup to use instead of new install, default new install
+	 * @param string $charset='utf-8' charset for the install, default utf-8 now
+	 */
+	function __construct($domain,$config_user=null,$config_passwd=null,$backup=null,$charset='utf-8',$verbose=false)
+	{
+		if (!is_array($domain))
+		{
+			$domain = array(
+				'domain'        => $domain,
+				'config_user'   => $config_user,
+				'config_passwd' => $config_passwd,
+				'backup'        => $backup,
+				'charset'       => $charset,
+				'verbose'       => $verbose,
+			);
+		}
+		elseif(!$domain['charset'])
+		{
+			$domain['charset'] = 'utf-8';
+		}
+		//echo __CLASS__.'::__construct()'; _debug_array($domain);
+		admin_cmd::__construct($domain);
+	}
+
+	/**
+	 * test or create database
+	 * 
+	 * @param boolean $check_only=false only run the checks (and throw the exceptions), but not the command itself
+	 * @return string serialized $GLOBALS defined in the header.inc.php
+	 * @throws Exception(lang('Wrong credentials to access the header.inc.php file!'),2);
+	 * @throws Exception('header.inc.php not found!');
+	 */
+	protected function exec($check_only=false)
+	{
+		global $setup_info;
+
+		// instanciate setup object and check authorisation
+		$this->check_setup_auth($this->config_user,$this->config_passwd,$this->domain);
+		
+		$this->check_installed($this->domain,array(13,14,20),$this->verbose);
+		
+		// use uploaded backup, instead installing from scratch
+		if ($this->backup)
+		{
+			$db_backup =& new db_backup();
+	
+			if (!is_resource($f = $db_backup->fopen_backup($this->backup,true)))
+			{
+				throw new egw_exception_wrong_userinput(lang('Restore failed'),31);
+			}
+			//echo lang('Restore started, this might take a few minutes ...')."\n";
+			$db_backup->restore($f,$this->charset);
+			fclose($f);
+
+			return lang('Restore finished');
+		}
+		// regular (new) install
+		if ($GLOBALS['egw_info']['setup']['stage']['db'] != 3)
+		{
+			throw new egw_exception_wrong_userinput(lang('eGroupWare is already installed!'),30);
+		}
+		$setup_info = self::$egw_setup->detection->upgrade_exclude($setup_info);
+
+		// Set the DB's client charset if a system-charset is set
+		self::$egw_setup->system_charset = strtolower($this->charset);
+		self::$egw_setup->db->Link_ID->SetCharSet($this->charset);
+
+		if ($this->verbose) echo lang('Installation started, this might take a few minutes ...')."\n";
+		$setup_info = self::$egw_setup->process->pass($setup_info,'new',false,True);
+		
+		return lang('Installation finished');
+	}
+}
diff --git a/setup/inc/class.setup_cmd_ldap.inc.php b/setup/inc/class.setup_cmd_ldap.inc.php
index cfdc81cef7..c3c7d6598c 100644
--- a/setup/inc/class.setup_cmd_ldap.inc.php
+++ b/setup/inc/class.setup_cmd_ldap.inc.php
@@ -45,7 +45,7 @@ class setup_cmd_ldap extends setup_cmd
 	{
 		if (!is_array($domain))
 		{
-			$data = array(
+			$domain = array(
 				'domain'        => $domain,
 				'ldap_host'     => $ldap_host,
 				'ldap_suffix'   => $ldap_suffix,
diff --git a/setup/inc/class.setup_cmd_showheader.inc.php b/setup/inc/class.setup_cmd_showheader.inc.php
index 47db733d0e..036c244107 100644
--- a/setup/inc/class.setup_cmd_showheader.inc.php
+++ b/setup/inc/class.setup_cmd_showheader.inc.php
@@ -7,7 +7,7 @@
  * @package setup
  * @copyright (c) 2007 by Ralf Becker <RalfBecker-AT-outdoor-training.de>
  * @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License
- * @version $Id: class.admin_cmd_check_acl.inc.php 24709 2007-11-27 03:20:28Z ralfbecker $ 
+ * @version $Id$ 
  */
 
 /**
@@ -21,7 +21,9 @@ class setup_cmd_showheader extends setup_cmd
 	/**
 	 * Constructor
 	 *
-	 * @param boolean $data=true send only the remote_hash, domain and webserver_url and not the complete header
+	 * @param boolean $data=true true: send only the remote_hash, domain and webserver_url, 
+	 *                           false: the complete header vars, plus install_id and webserver_url from the config table,
+	 *                           null:  only the header vars
 	 */
 	function __construct($data=true)
 	{
@@ -72,7 +74,10 @@ class setup_cmd_showheader extends setup_cmd
 		// fetching the install id's stored in the database
 		foreach($GLOBALS['egw_domain'] as $domain => &$data)
 		{
-			$data += $this->_fetch_config($data);
+			if (!is_null($this->hash_only))
+			{
+				$data += $this->_fetch_config($data);
+			}
 			try {
 				// it's saver to only send the remote_hash and not install_id and config_pw
 				$data['remote_hash'] = admin_cmd::remote_hash($data['install_id'],$data['config_passwd']);
@@ -137,12 +142,12 @@ class setup_cmd_showheader extends setup_cmd
 		catch (Exception $e) {
 			$config['error'] = strip_tags($e->getMessage());
 		}
-		// restoring the db connection, seems to be necessary when we run via remote execution
-		$this->restore_db();
-		
 		error_reporting($err_rep);
 		ob_end_clean();
 
+		// restoring the db connection, seems to be necessary when we run via remote execution
+		$this->restore_db();
+		
 		return $config;
 	}
 }
diff --git a/setup/setup-cli.php b/setup/setup-cli.php
index 32014ac080..3f0251b1f6 100755
--- a/setup/setup-cli.php
+++ b/setup/setup-cli.php
@@ -42,6 +42,12 @@ include('inc/functions.inc.php');
 $GLOBALS['egw_setup']->translation->no_translation_marker = '';
 $GLOBALS['egw_setup']->system_charset = $charset;
 
+function cli_exception_handler(Exception $e)
+{
+	fail($e->getCode(),$e->getMessage());
+}
+set_exception_handler('cli_exception_handler');
+
 if ((float) PHP_VERSION < $GLOBALS['egw_setup']->required_php_version)
 {
 	fail(98,lang('You are using PHP version %1. eGroupWare now requires %2 or later, recommended is PHP %3.',PHP_VERSION,$GLOBALS['egw_setup']->required_php_version,$GLOBALS['egw_setup']->recommended_php_version));
@@ -51,7 +57,7 @@ switch($action)
 {
 	case '--version':
 	case '--check':
-		do_check($arguments[0]);
+		setup_cmd::check_installed($arguments[0],0,true);
 		break;
 		
 	case '--create-header':
@@ -423,7 +429,7 @@ function do_lang($arg)
  * We allow the config user/pw of the domain OR the header admin user/pw!
  *
  * @param string $arg [domain(default)],[user(admin)],password
- * @param int $stop see do_check()
+ * @param int $stop see setup_cmd::check_installed
  * @param boolean $set_lang=true set our charset, overwriting the charset of the eGW installation, default true
  * @return array with unprocessed arguments from $arg
  */
@@ -431,29 +437,17 @@ function _check_auth_config($arg,$stop,$set_lang=true)
 {
 	$options = explode(',',$arg);
 	if (!($domain = array_shift($options))) $domain = 'default';
-	if (!($user = array_shift($options))) $user = 'admin';
-	if (!($password = array_shift($options)))
-	{
-		if (!($password = $_SERVER['EGW_CLI_PASSWORD']))
-		{
-			echo lang('Config password').' ';
-			$password = trim(fgets($f = fopen('php://stdin','rb')));
-			fclose($f);
-		}
-	}
-	do_check($domain,$stop);	// check if eGW is installed
+	$user = array_shift($options);
+	$password = array_shift($options);
+	_fetch_user_password($user,$password);
+
+	setup_cmd::check_installed($domain,$stop,true);
 
 	// reset charset for the output to the charset used by the OS
 	if ($set_lang) $GLOBALS['egw_setup']->system_charset = $GLOBALS['charset'];
-	
-	//echo "check_auth('$user','$password','{$GLOBALS['egw_domain'][$domain]['config_user']}','{$GLOBALS['egw_domain'][$domain]['config_passwd']}')\n";
-	if (!$GLOBALS['egw_setup']->check_auth($user,$password,$GLOBALS['egw_domain'][$domain]['config_user'],
-		$GLOBALS['egw_domain'][$domain]['config_passwd']) &&
-		!$GLOBALS['egw_setup']->check_auth($user,$password,$GLOBALS['egw_domain'][$domain]['header_admin_user'],
-		$GLOBALS['egw_domain'][$domain]['header_admin_password']))
-	{
-		fail(40,lang("Access denied: wrong username or password to configure the domain '%1(%2)' !!!",$domain,$GLOBALS['egw_domain'][$domain]['db_type']));
-	}
+
+	setup_cmd::check_setup_auth($user,$password,$domain);
+
 	return $options;
 }
 
@@ -466,166 +460,29 @@ function do_install($args)
 {
 	global $setup_info;
 
-	list($domain,,,$backup,$charset) = explode(',',$args);
-	if (!$domain) $domain = 'default';
+	list($domain,$user,$password,$backup,$charset) = explode(',',$args);
+	_fetch_user_password($user,$password);
 	
-	$options = _check_auth_config($args,array(13,14,20));
-	
-	// use uploaded backup, instead installing from scratch
-	if ($backup)
-	{
-		$db_backup =& CreateObject('phpgwapi.db_backup');
-
-		if (!is_resource($f = $db_backup->fopen_backup($backup,true)))
-		{
-			fail(31,lang('Restore failed'));
-		}
-		echo lang('Restore started, this might take a few minutes ...')."\n";
-		$db_backup->restore($f,$charset);
-		fclose($f);
-		echo lang('Restore finished')."\n";
-	}
-	else
-	{
-		if ($GLOBALS['egw_info']['setup']['stage']['db'] != 3)
-		{
-			fail(30,lang('eGroupWare is already installed!'));
-		}
-		if (!$charset) $charset = $GLOBALS['egw_setup']->translation->langarray['charset'];
-
-		$setup_info = $GLOBALS['egw_setup']->detection->upgrade_exclude($setup_info);
-
-		// Set the DB's client charset if a system-charset is set
-		$GLOBALS['egw_setup']->system_charset = strtolower($charset);
-		$GLOBALS['egw_setup']->db->Link_ID->SetCharSet($charset);
-
-		echo lang('Installation started, this might take a few minutes ...')."\n";
-		$setup_info = $GLOBALS['egw_setup']->process->pass($setup_info,'new',false,True);
-		echo lang('Installation finished')."\n";
-	}	
+	$cmd = new setup_cmd_install($domain,$user,$password,$backup,$charset,true);
+	echo $cmd->run()."\n";
 }
 
 /**
- * Check if eGW is installed, which versions and if an update is needed
- * 
- * @param string $domain='' domain to check, default '' = all
- * @param int/array $stop=0 stop checks before given exit-code(s), default 0 = all checks
+ * Set defaults for user and password or queries the password from the user
+ *
+ * @param string &$user
+ * @param string &$password
  */
-function do_check($domain='',$stop=0)
+function _fetch_user_password(&$user,&$password)
 {
-	global $setup_info;
-	static $header_checks=true;	// output the header checks only once
-	
-	if ($stop && !is_array($stop)) $stop = array($stop);
-
-	$versions =& $GLOBALS['egw_info']['server']['versions'];
-
-	if (!$versions['phpgwapi'])
+	// read password from enviroment or query it from user, if not given
+	if (!$user) $user = 'admin';
+	if (!$password && !($password = $_SERVER['EGW_CLI_PASSWORD']))
 	{
-		if (!include('../phpgwapi/setup/setup.inc.php'))
-		{
-			fail(99,lang("eGroupWare sources in '%1' are not complete, file '%2' missing !!!",realpath('..'),'phpgwapi/setup/setup.inc.php'));	// should not happen ;-)
-		}
-		$versions['phpgwapi'] = $setup_info['phpgwapi']['version'];
-		unset($setup_info);
+		echo lang('Admin password to header manager').' ';
+		$password = trim(fgets($f = fopen('php://stdin','rb')));
+		fclose($f);
 	}
-	if ($header_checks)
-	{
-		echo lang('eGroupWare API version %1 found.',$versions['phpgwapi'])."\n";
-	}
-	$header_stage = $GLOBALS['egw_setup']->detection->check_header();
-	if ($stop && in_array($header_stage,$stop)) return true;
-	
-	switch ($header_stage)
-	{
-		case 1: fail(1,lang('eGroupWare configuration file (header.inc.php) does NOT exist.')."\n".lang('Use --create-header to create the configuration file (--usage gives more options).'));
-			
-		case 2: fail(2,lang('eGroupWare configuration file (header.inc.php) version %1 exists%2',$versions['header'],'.')."\n".lang('No header admin password set! Use --edit-header <password>[,<user>] to set one (--usage gives more options).'));
-
-		case 3: fail(3,lang('eGroupWare configuration file (header.inc.php) version %1 exists%2',$versions['header'],'.')."\n".lang('No eGroupWare domains / database instances exist! Use --edit-header --domain to add one (--usage gives more options).'));
-
-		case 4: fail(4,lang('eGroupWare configuration file (header.inc.php) version %1 exists%2',$versions['header'],'.')."\n".lang('It needs upgrading to version %1! Use --update-header <password>[,<user>] to do so (--usage gives more options).',$versions['current_header']));
-	}
-	if ($header_checks)
-	{
-		echo lang('eGroupWare configuration file (header.inc.php) version %1 exists%2',
-			$versions['header'],' '.lang('and is up to date')).".\n";
-	}
-	$header_checks = false;	// no further output of the header checks
-
-	$domains = $GLOBALS['egw_domain'];
-	if ($domain)	// domain to check given
-	{
-		if (!isset($GLOBALS['egw_domain'][$domain])) fail(92,lang("Domain '%1' does NOT exist !!!",$domain));
-		
-		$domains = array($domain => $GLOBALS['egw_domain'][$domain]);
-	}
-	foreach($domains as $domain => $data)
-	{
-		$GLOBALS['egw_setup']->ConfigDomain = $domain;	// set the domain the setup class operates on
-		if (count($GLOBALS['egw_domain']) > 1) echo "\n".lang('eGroupWare domain/instance %1(%2):',$domain,$data['db_type'])."\n";
-
-		$setup_info = $GLOBALS['egw_setup']->detection->get_versions();
-		// check if there's already a db-connection and close if, otherwise the db-connection of the previous domain will be used
-		if (is_object($GLOBALS['egw_setup']->db))
-		{
-			$GLOBALS['egw_setup']->db->disconnect();
-		}
-		$GLOBALS['egw_setup']->loaddb();
-		
-		$db = $data['db_type'].'://'.$data['db_user'].'@'.$data['db_host'].'/'.$data['db_name'];
-
-		$db_stage =& $GLOBALS['egw_info']['setup']['stage']['db'];
-		if (($db_stage = $GLOBALS['egw_setup']->detection->check_db($setup_info)) != 1)
-		{
-			$setup_info = $GLOBALS['egw_setup']->detection->get_db_versions($setup_info);
-			$db_stage = $GLOBALS['egw_setup']->detection->check_db($setup_info);
-		}
-		if ($stop && in_array(10+$db_stage,$stop)) return true;
-
-		switch($db_stage)
-		{
-			case 1: fail(11,lang('Your Database is not working!')." $db: ".$GLOBALS['egw_setup']->db->Error);
-
-			case 3: fail(13,lang('Your database is working, but you dont have any applications installed')." ($db). ".lang("Use --install to install eGroupWare."));
-
-			case 4: fail(14,lang('eGroupWare API needs a database (schema) update from version %1 to %2!',$setup_info['phpgwapi']['currentver'],$versions['phpgwapi']).' '.lang('Use --update to do so.'));
-			
-			case 10:	// also check apps of updates
-				$apps_to_upgrade = array();
-				$apps_to_install = array();
-				foreach($setup_info as $app => $data)
-				{
-					if ($data['currentver'] && $data['version'] && $data['version'] != $data['currentver'])
-					{
-						$apps_to_upgrade[] = $app;
-					}
-					if (!isset($data['enabled']))
-					{
-						$apps_to_install[] = $app;
-					}
-				}
-				if ($apps_to_install)
-				{
-					echo "\n".lang('The following applications are NOT installed:').' '.implode(', ',$apps_to_install)."\n";
-				}
-				if ($apps_to_upgrade)
-				{
-					$db_stage = 4;
-					if ($stop && in_array(10+$db_stage,$stop)) return true;
-					fail(14,lang('The following applications need to be upgraded:').' '.implode(', ',$apps_to_upgrade).'! '.lang('Use --update to do so.'));
-				}
-				break;
-		}
-		echo lang("database is version %1 and up to date.",$setup_info['phpgwapi']['currentver'])."\n";
-
-		$GLOBALS['egw_setup']->detection->check_config();
-		if ($GLOBALS['egw_info']['setup']['config_errors'] && $stop && !in_array(15,$stop))
-		{
-			fail(15,lang('You need to configure eGroupWare:')."\n- ".@implode("\n- ",$GLOBALS['egw_info']['setup']['config_errors']));
-		}
-	}
-	return false;
 }
 
 /**
@@ -641,15 +498,7 @@ function do_header($create,&$arguments)
 	{
 		// read password from enviroment or query it from user, if not given
 		@list($password,$user) = $options = explode(',',@$arguments[0]);
-		if (!$user) $user = 'admin';
-		if (!$password && !($password = $_SERVER['EGW_CLI_PASSWORD']))
-		{
-			echo lang('Admin password to header manager').' ';
-			$password = trim(fgets($f = fopen('php://stdin','rb')));
-			fclose($f);
-		}
-		$options[0] = $password;
-		$options[1] = $user;
+		_fetch_user_password($options[1],$options[0]);
 		$arguments[0] = implode(',',$options);
 	}
 	array_unshift($arguments,$create ? '--create-header' : '--edit-header');
@@ -665,26 +514,6 @@ function do_header($create,&$arguments)
 	exit(0);
 }
 
-/**
- * Set a value in the given array $arr with (multidimensional) key $index[/$name]
- *
- * @param array &$arr
- * @param string $index multidimensional index written with / as separator, eg. egw_info/server/
- * @param string $name additional index to use if $index end with a slash
- * @param mixed $value value to set
- */
-function _set_value(&$arr,$index,$name,$value)
-{
-	if (substr($index,-1) == '/') $index .= $name;
-	
-	$var =& $arr;
-	foreach(explode('/',$index) as $name)
-	{
-		$var =& $var[$name];
-	}
-	$var = strpos($name,'passw') !== false ? md5($value) : $value;
-}
-
 /**
  * Reads the users language from the enviroment
  *