Index: wp-admin/css/install.dev.css
===================================================================
--- wp-admin/css/install.dev.css	(revision 18619)
+++ wp-admin/css/install.dev.css	(working copy)
@@ -211,6 +211,10 @@
 	margin: 5px 0 15px;
 	background-color: #ffffe0;
 }
+.error {
+	background-color: #ffebe8;
+	border-color: #c00;
+}
 
 
 /* install-rtl */
Index: wp-admin/setup-config.php
===================================================================
--- wp-admin/setup-config.php	(revision 18619)
+++ wp-admin/setup-config.php	(working copy)
@@ -35,38 +35,81 @@
  * the database class while being wp-content/db.php aware.
  * @ignore
  */
-define('ABSPATH', dirname(dirname(__FILE__)).'/');
+define('ABSPATH', dirname(dirname(__FILE__)) . '/');
 define('WPINC', 'wp-includes');
 define('WP_CONTENT_DIR', ABSPATH . 'wp-content');
 define('WP_DEBUG', false);
 /**#@-*/
 
 require_once(ABSPATH . WPINC . '/load.php');
+
 require_once(ABSPATH . WPINC . '/version.php');
 wp_check_php_mysql_versions();
 
 require_once(ABSPATH . WPINC . '/compat.php');
 require_once(ABSPATH . WPINC . '/functions.php');
+require_once(ABSPATH . WPINC . '/plugin.php');
+require_once(ABSPATH . WPINC . '/formatting.php');
 require_once(ABSPATH . WPINC . '/class-wp-error.php');
+require_once(ABSPATH . WPINC . '/kses.php');
 
-if (!file_exists(ABSPATH . 'wp-config-sample.php'))
-	wp_die('Sorry, I need a wp-config-sample.php file to work from. Please re-upload this file from your WordPress installation.');
+wp_start_object_cache();
+wp_set_lang_dir();
 
-$configFile = file(ABSPATH . 'wp-config-sample.php');
+add_filter('wp_die_handler', '_installer_wp_die');
+function _installer_wp_die($handler) {
+	return '_installer_wp_die_handler';
+}
+function _installer_wp_die_handler($error) {
+	display_header();
+	echo '<p>';
+	echo is_wp_error($error) ? $error->get_error_message() : $error;
+	echo '</p>';
+	display_footer();
+	die();
+}
 
+
+/**#@+
+ * A hacky way to set WPLANG to the installs default. 
+ * @TODO This should be set somehow a little bit less hacky, $text_direction also needs to be set.
+ * @ignore
+ */
+if ( is_dir( WP_LANG_DIR ) && preg_match( '!define\(.+WPLANG.+[\'"]([A-z_]+)[\'"]!', file_get_contents( ABSPATH . 'wp-config-sample.php' ), $lang_match ) ) {
+	define('WPLANG', $lang_match[1]);
+}
+/**#@-*/
+
+require_once( ABSPATH . WPINC . '/pomo/mo.php' );
+require_once( ABSPATH . WPINC . '/l10n.php');
+load_default_textdomain();
+
 // Check if wp-config.php has been created
-if (file_exists(ABSPATH . 'wp-config.php'))
-	wp_die("<p>The file 'wp-config.php' already exists. If you need to reset any of the configuration items in this file, please delete it first. You may try <a href='install.php'>installing now</a>.</p>");
+if ( file_exists(ABSPATH . 'wp-config.php' ))
+	wp_die( __("<p>The file 'wp-config.php' already exists. If you need to reset any of the configuration items in this file, please delete it first. You may try <a href='install.php'>installing now</a>.</p>") );
 
 // Check if wp-config.php exists above the root directory but is not part of another install
-if (file_exists(ABSPATH . '../wp-config.php') && ! file_exists(ABSPATH . '../wp-settings.php'))
-	wp_die("<p>The file 'wp-config.php' already exists one level above your WordPress installation. If you need to reset any of the configuration items in this file, please delete it first. You may try <a href='install.php'>installing now</a>.</p>");
+if ( file_exists(ABSPATH . '../wp-config.php') && ! file_exists(ABSPATH . '../wp-settings.php') )
+	wp_die( __("<p>The file 'wp-config.php' already exists one level above your WordPress installation. If you need to reset any of the configuration items in this file, please delete it first. You may try <a href='install.php'>installing now</a>.</p>") );
 
-if (isset($_GET['step']))
+// @TODO: Err, This string can't be translated this way, If the config file doesnt exist, we can't set the language. See TODO of setting the default language another way.
+if ( ! file_exists(ABSPATH . 'wp-config-sample.php') )
+	wp_die( __('Sorry, I need a wp-config-sample.php file to work from. Please re-upload this file from your WordPress installation.') );
+
+if ( isset($_GET['step']) )
 	$step = $_GET['step'];
 else
 	$step = 0;
 
+display_header();
+if ( 2 == $step )
+	step_2();
+elseif ( 1 == $step )
+	step_1();
+else
+	step_0();
+display_footer();
+
 /**
  * Display setup wp-config.php file header.
  *
@@ -82,8 +125,8 @@
 <html xmlns="http://www.w3.org/1999/xhtml">
 <head>
 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
-<title>WordPress &rsaquo; Setup Configuration File</title>
-<link rel="stylesheet" href="css/install.css" type="text/css" />
+<title><?php _e('WordPress &rsaquo; Setup Configuration File'); ?></title>
+<link rel="stylesheet" href="css/install.dev.css" type="text/css" />
 
 </head>
 <body>
@@ -91,76 +134,92 @@
 <?php
 }//end function display_header();
 
-switch($step) {
-	case 0:
-		display_header();
+function step_0() {
 ?>
 
-<p>Welcome to WordPress. Before getting started, we need some information on the database. You will need to know the following items before proceeding.</p>
+<p><?php _e('Welcome to WordPress. Before getting started, we need some information on the database. You will need to know the following items before proceeding.'); ?></p>
 <ol>
-	<li>Database name</li>
-	<li>Database username</li>
-	<li>Database password</li>
-	<li>Database host</li>
-	<li>Table prefix (if you want to run more than one WordPress in a single database) </li>
+	<li><?php _e('Database name'); ?></li>
+	<li><?php _e('Database username'); ?></li>
+	<li><?php _e('Database password'); ?></li>
+	<li><?php _e('Database host'); ?></li>
+	<li><?php _e('Table prefix (if you want to run more than one WordPress in a single database)'); ?></li>
 </ol>
-<p><strong>If for any reason this automatic file creation doesn't work, don't worry. All this does is fill in the database information to a configuration file. You may also simply open <code>wp-config-sample.php</code> in a text editor, fill in your information, and save it as <code>wp-config.php</code>. </strong></p>
-<p>In all likelihood, these items were supplied to you by your Web Host. If you do not have this information, then you will need to contact them before you can continue. If you&#8217;re all ready&hellip;</p>
+<p><?php _e("<strong>If for any reason this automatic file creation doesn't work, don't worry. All this does is fill in the database information to a configuration file. You may also simply open <code>wp-config-sample.php</code> in a text editor, fill in your information, and save it as <code>wp-config.php</code>. </strong></p>
+<p>In all likelihood, these items were supplied to you by your Web Host. If you do not have this information, then you will need to contact them before you can continue. If you&#8217;re all ready&hellip;"); ?></p>
 
-<p class="step"><a href="setup-config.php?step=1<?php if ( isset( $_GET['noapi'] ) ) echo '&amp;noapi'; ?>" class="button">Let&#8217;s go!</a></p>
+<p class="step"><a href="setup-config.php?step=1<?php if ( isset( $_GET['noapi'] ) ) echo '&amp;noapi'; ?>" class="button"><?php _e('Let&#8217;s go!'); ?></a></p>
 <?php
-	break;
+}
 
-	case 1:
-		display_header();
+function step_1( $details = array(), $errors = array() ) {
+	if ( empty($details) ) {
+		$details = array(
+					'dbname' => _x('wordpress', 'installer default database'),
+					'uname'  => _x('username', 'installer default username'),
+					'pwd'    => _x('password', 'installer default password'),
+					'dbhost' => _x('localhost', 'installer default host'),
+					'prefix' => _x('wp_', 'installer default table prefix'),
+					);
+	}
+
+	foreach ( $errors as $error ) {
+		echo '<p class="error message">' . $error->get_error_message() . '</p>';
+	}
+
 	?>
 <form method="post" action="setup-config.php?step=2">
-	<p>Below you should enter your database connection details. If you're not sure about these, contact your host. </p>
+	<p><?php _e("Below you should enter your database connection details. If you're not sure about these, contact your host."); ?></p>
 	<table class="form-table">
 		<tr>
-			<th scope="row"><label for="dbname">Database Name</label></th>
-			<td><input name="dbname" id="dbname" type="text" size="25" value="wordpress" /></td>
-			<td>The name of the database you want to run WP in. </td>
+			<th scope="row"><label for="dbname"><?php _e('Database Name'); ?></label></th>
+			<td><input name="dbname" id="dbname" type="text" size="25" value="<?php echo esc_attr($details['dbname']); ?>" /></td>
+			<td><?php _e('The name of the database you want to run WP in.'); ?></td>
 		</tr>
 		<tr>
-			<th scope="row"><label for="uname">User Name</label></th>
-			<td><input name="uname" id="uname" type="text" size="25" value="username" /></td>
-			<td>Your MySQL username</td>
+			<th scope="row"><label for="uname"><?php _e('User Name'); ?></label></th>
+			<td><input name="uname" id="uname" type="text" size="25" value="<?php echo esc_attr($details['uname']); ?>" /></td>
+			<td><?php _e('Your MySQL username'); ?></td>
 		</tr>
 		<tr>
-			<th scope="row"><label for="pwd">Password</label></th>
-			<td><input name="pwd" id="pwd" type="text" size="25" value="password" /></td>
-			<td>...and MySQL password.</td>
+			<th scope="row"><label for="pwd"><?php _e('Password'); ?></label></th>
+			<td><input name="pwd" id="pwd" type="text" size="25" value="<?php echo esc_attr($details['pwd']); ?>" /></td>
+			<td><?php _e('...and MySQL password.'); ?></td>
 		</tr>
 		<tr>
-			<th scope="row"><label for="dbhost">Database Host</label></th>
-			<td><input name="dbhost" id="dbhost" type="text" size="25" value="localhost" /></td>
-			<td>You should be able to get this info from your web host, if <code>localhost</code> does not work.</td>
+			<th scope="row"><label for="dbhost"><?php _e('Database Host'); ?></label></th>
+			<td><input name="dbhost" id="dbhost" type="text" size="25" value="<?php echo esc_attr($details['dbhost']); ?>" /></td>
+			<td><?php _e('You should be able to get this info from your web host, if <code>localhost</code> does not work.'); ?></td>
 		</tr>
 		<tr>
-			<th scope="row"><label for="prefix">Table Prefix</label></th>
-			<td><input name="prefix" id="prefix" type="text" value="wp_" size="25" /></td>
-			<td>If you want to run multiple WordPress installations in a single database, change this.</td>
+			<th scope="row"><label for="prefix"><?php _e('Table Prefix'); ?></label></th>
+			<td><input name="prefix" id="prefix" type="text" value="<?php echo esc_attr($details['prefix']); ?>" size="25" /></td>
+			<td><?php _e('If you want to run multiple WordPress installations in a single database, change this.'); ?></td>
 		</tr>
 	</table>
 	<?php if ( isset( $_GET['noapi'] ) ) { ?><input name="noapi" type="hidden" value="true" /><?php } ?>
-	<p class="step"><input name="submit" type="submit" value="Submit" class="button" /></p>
+	<p class="step"><input name="submit" type="submit" value="<?php esc_attr_e('Submit'); ?>" class="button" /></p>
 </form>
 <?php
-	break;
+}
 
-	case 2:
+function step_2() {
+	global $wpdb;
+
 	$dbname  = trim($_POST['dbname']);
 	$uname   = trim($_POST['uname']);
-	$passwrd = trim($_POST['pwd']);
+	$pwd     = trim($_POST['pwd']);
 	$dbhost  = trim($_POST['dbhost']);
 	$prefix  = trim($_POST['prefix']);
+
+	$errors = array();
+
 	if ( empty($prefix) )
-		$prefix = 'wp_';
+		$errors[] = new WP_Error('empty_prefix', __('"Table Prefix" must not be empty.') );
 
 	// Validate $prefix: it can only contain letters, numbers and underscores
 	if ( preg_match( '|[^a-z0-9_]|i', $prefix ) )
-		wp_die( /*WP_I18N_BAD_PREFIX*/'<strong>ERROR</strong>: "Table Prefix" can only contain numbers, letters, and underscores.'/*/WP_I18N_BAD_PREFIX*/ );
+		$errors[] = new WP_Error('invalid_prefix', __('"Table Prefix" can only contain numbers, letters, and underscores.') );
 
 	// Test the db connection.
 	/**#@+
@@ -168,22 +227,38 @@
 	 */
 	define('DB_NAME', $dbname);
 	define('DB_USER', $uname);
-	define('DB_PASSWORD', $passwrd);
+	define('DB_PASSWORD', $pwd);
 	define('DB_HOST', $dbhost);
 	/**#@-*/
 
 	// We'll fail here if the values are no good.
 	require_wp_db();
+
 	if ( ! empty( $wpdb->error ) ) {
-		$back = '<p class="step"><a href="setup-config.php?step=1" onclick="javascript:history.go(-1);return false;" class="button">Try Again</a></p>';
-		wp_die( $wpdb->error->get_error_message() . $back );
+		if ( is_string($wpdb->error) ) {
+			$errors[] = new WP_Error( 'unknown', $wpdb->error );
+		} else if ( 'db_connect_fail' == $wpdb->error->get_error_code() ) {
+			// bad creds
+			$errors[] = new WP_Error( 'credentials', __('An error occured whilst connecting to the Database server listed, Please check the details below are correct.') );
+		} else if ( 'db_select_fail' == $wpdb->error->get_error_code() ) {
+			// database doesn't exist.
+			$errors[] = new WP_Error( 'dbname', __("WordPress couldn't select te specified database, Please ensure it exists and the above user account can access it.") );
+		} else {
+			$errors[] = $wpdb->error;
+		}
 	}
 
+	if ( ! empty($errors) )
+		step_1( compact( 'dbname', 'uname', 'pwd', 'dbhost', 'prefix' ), $errors);
+	else
+		write_config( $dbname, $uname, $pwd, $dbhost, $prefix );
+}
+
+function write_config( $dbname, $uname, $pwd, $dbhost, $prefix ) {
+	global $wpdb;
+
 	// Fetch or generate keys and salts.
 	$no_api = isset( $_POST['noapi'] );
-	require_once( ABSPATH . WPINC . '/plugin.php' );
-	require_once( ABSPATH . WPINC . '/l10n.php' );
-	require_once( ABSPATH . WPINC . '/pomo/translations.php' );
 	if ( ! $no_api ) {
 		require_once( ABSPATH . WPINC . '/class-http.php' );
 		require_once( ABSPATH . WPINC . '/http.php' );
@@ -212,22 +287,28 @@
 	}
 	$key = 0;
 
-	foreach ($configFile as $line_num => $line) {
+	$config_file = file(ABSPATH . 'wp-config-sample.php');
+
+	foreach ( $config_file as $line_num => $line ) {
 		switch (substr($line,0,16)) {
 			case "define('DB_NAME'":
-				$configFile[$line_num] = str_replace("database_name_here", $dbname, $line);
+				$dbname = addcslashes($dbname, "\\'");
+				$config_file[$line_num] = str_replace("'database_name_here'", "'$dbname'", $line);
 				break;
 			case "define('DB_USER'":
-				$configFile[$line_num] = str_replace("'username_here'", "'$uname'", $line);
+				$uname = addcslashes($uname, "\\'");
+				$config_file[$line_num] = str_replace("'username_here'", "'$uname'", $line);
 				break;
 			case "define('DB_PASSW":
-				$configFile[$line_num] = str_replace("'password_here'", "'$passwrd'", $line);
+				$pwd = addcslashes($pwd, "\\'");
+				$config_file[$line_num] = str_replace("'password_here'", "'$pwd'", $line);
 				break;
 			case "define('DB_HOST'":
-				$configFile[$line_num] = str_replace("localhost", $dbhost, $line);
+				$dbhost = addcslashes($dbhost, "\\'");
+				$config_file[$line_num] = str_replace("'localhost'", "'$dbhost'", $line);
 				break;
 			case '$table_prefix  =':
-				$configFile[$line_num] = str_replace('wp_', $prefix, $line);
+				$config_file[$line_num] = str_replace("'wp_'", "'$prefix'", $line);
 				break;
 			case "define('AUTH_KEY":
 			case "define('SECURE_A":
@@ -237,39 +318,36 @@
 			case "define('SECURE_A":
 			case "define('LOGGED_I":
 			case "define('NONCE_SA":
-				$configFile[$line_num] = str_replace('put your unique phrase here', $secret_keys[$key++], $line );
+				$config_file[$line_num] = str_replace( _x('put your unique phrase here', 'MUST MATCH PLACE HOLDER IN SECRET KEYS IN wp-config-sample.php'), $secret_keys[$key++], $line );
 				break;
 		}
 	}
 	if ( ! is_writable(ABSPATH) ) :
-		display_header();
 ?>
-<p>Sorry, but I can't write the <code>wp-config.php</code> file.</p>
-<p>You can create the <code>wp-config.php</code> manually and paste the following text into it.</p>
+<p><?php _e("Sorry, but I can't write the <code>wp-config.php</code> file."); ?></p>
+<p><?php _e('You can create the <code>wp-config.php</code> manually and paste the following text into it.'); ?></p>
 <textarea cols="98" rows="15" class="code"><?php
-		foreach( $configFile as $line ) {
-			echo htmlentities($line, ENT_COMPAT, 'UTF-8');
+		foreach( $config_file as $line ) {
+			echo esc_textarea($line);
 		}
 ?></textarea>
-<p>After you've done that, click "Run the install."</p>
-<p class="step"><a href="install.php" class="button">Run the install</a></p>
+<p><?php _e('After you\'ve done that, click "Run the install."'); ?></p>
+<p class="step"><a href="install.php" class="button"><?php _e('Run the install'); ?></a></p>
 <?php
 	else :
-		$handle = fopen(ABSPATH . 'wp-config.php', 'w');
-		foreach( $configFile as $line ) {
-			fwrite($handle, $line);
-		}
-		fclose($handle);
-		chmod(ABSPATH . 'wp-config.php', 0666);
-		display_header();
+		file_put_contents( ABSPATH . 'wp-config.php', implode('', $config_file) );
+		chmod(ABSPATH . 'wp-config.php', 0644);
 ?>
-<p>All right sparky! You've made it through this part of the installation. WordPress can now communicate with your database. If you are ready, time now to&hellip;</p>
+<p><?php _e("All right sparky! You've made it through this part of the installation. WordPress can now communicate with your database. If you are ready, time now to&hellip;"); ?></p>
 
-<p class="step"><a href="install.php" class="button">Run the install</a></p>
+<p class="step"><a href="install.php" class="button"><?php _e('Run the install'); ?></a></p>
 <?php
 	endif;
-	break;
 }
+
+function display_footer() {
 ?>
 </body>
 </html>
+<?php
+}
