Index: wp-admin/includes/class-wp-filesystem-base.php
===================================================================
--- wp-admin/includes/class-wp-filesystem-base.php	(revision 10864)
+++ wp-admin/includes/class-wp-filesystem-base.php	(working copy)
@@ -46,8 +46,6 @@
 	 * @return string The location of the remote path.
 	 */
 	function abspath() {
-		if ( defined('FTP_BASE') && strpos($this->method, 'ftp') !== false )
-			return FTP_BASE;
 		$folder = $this->find_folder(ABSPATH);
 		//Perhaps the FTP folder is rooted at the WordPress install, Check for wp-includes folder in root, Could have some false positives, but rare.
 		if ( ! $folder && $this->is_dir('/wp-includes') )
@@ -62,8 +60,6 @@
 	 * @return string The location of the remote path.
 	 */
 	function wp_content_dir() {
-		if ( defined('FTP_CONTENT_DIR') && strpos($this->method, 'ftp') !== false )
-			return FTP_CONTENT_DIR;
 		return $this->find_folder(WP_CONTENT_DIR);
 	}
 	/**
@@ -75,8 +71,6 @@
 	 * @return string The location of the remote path.
 	 */
 	function wp_plugins_dir() {
-		if ( defined('FTP_PLUGIN_DIR') && strpos($this->method, 'ftp') !== false )
-			return FTP_PLUGIN_DIR;
 		return $this->find_folder(WP_PLUGIN_DIR);
 	}
 	/**
@@ -142,13 +136,23 @@
 	 */
 	function find_folder($folder) {
 
-		$folder = preg_replace('|^([a-z]{1}):|i', '', $folder); //Strip out windows driveletter if its there.
+		if ( strpos($this->method, 'ftp') !== false ) {
+			$constant_overrides = array( 'FTP_BASE' => ABSPATH, 'FTP_CONTENT_DIR' => WP_CONTENT_DIR, 'FTP_PLUGIN_DIR' => WP_PLUGIN_DIR );
+			foreach ( $constant_overrides as $constant => $dir )
+				if ( defined($constant) && $folder === $dir )
+					return trailingslashit(constant($constant));
+		} elseif ( 'direct' == $this->method ) {
+			return trailingslashit($folder);
+		}
+
+		$folder = preg_replace('|^([a-z]{1}):|i', '', $the_folder); //Strip out windows driveletter if its there.
 		$folder = str_replace('\\', '/', $folder); //Windows path sanitiation
 
 		if ( isset($this->cache[ $folder ] ) )
 			return $this->cache[ $folder ];
 
 		if ( $this->exists($folder) ) { //Folder exists at that absolute path.
+			$folder = trailingslashit($folder);
 			$this->cache[ $folder ] = $folder;
 			return $folder;
 		}
@@ -189,23 +193,23 @@
 			// If its found, change into it and follow through looking for it.
 			// If it cant find WordPress down that route, it'll continue onto the next folder level, and see if that matches, and so on.
 			// If it reaches the end, and still cant find it, it'll return false for the entire function.
-			if( isset($files[ $key ]) ){
+			if ( isset($files[ $key ]) ){
 				//Lets try that folder:
 				$newdir = trailingslashit(path_join($base, $key));
-				if( $this->verbose )
+				if ( $this->verbose )
 					printf( __('Changing to %s') . '<br/>', $newdir );
-				if( $ret = $this->search_for_folder( $folder, $newdir, $loop) )
+				if ( $ret = $this->search_for_folder( $folder, $newdir, $loop) )
 					return $ret;
 			}
 		}
 
 		//Only check this as a last resort, to prevent locating the incorrect install. All above proceeedures will fail quickly if this is the right branch to take.
-		if(isset( $files[ $last_path ] ) ) {
-			if( $this->verbose )
+		if (isset( $files[ $last_path ] ) ) {
+			if ( $this->verbose )
 				printf( __('Found %s') . '<br/>',  $base . $last_path );
-			return $base . $last_path;
+			return trailingslashit($base . $last_path);
 		}
-		if( $loop )
+		if ( $loop )
 			return false;//Prevent tihs function looping again.
 		//As an extra last resort, Change back to / if the folder wasnt found. This comes into effect when the CWD is /home/user/ but WP is at /var/www/.... mainly dedicated setups.
 		return $this->search_for_folder($folder, '/', true);
Index: wp-admin/includes/class-wp-filesystem-direct.php
===================================================================
--- wp-admin/includes/class-wp-filesystem-direct.php	(revision 10864)
+++ wp-admin/includes/class-wp-filesystem-direct.php	(working copy)
@@ -49,82 +49,82 @@
 		return @chdir($dir);
 	}
 	function chgrp($file, $group, $recursive = false) {
-		if( ! $this->exists($file) )
+		if ( ! $this->exists($file) )
 			return false;
-		if( ! $recursive )
+		if ( ! $recursive )
 			return @chgrp($file, $group);
-		if( ! $this->is_dir($file) )
+		if ( ! $this->is_dir($file) )
 			return @chgrp($file, $group);
 		//Is a directory, and we want recursive
 		$file = trailingslashit($file);
 		$filelist = $this->dirlist($file);
-		foreach($filelist as $filename)
+		foreach ($filelist as $filename)
 			$this->chgrp($file . $filename, $group, $recursive);
 
 		return true;
 	}
 	function chmod($file, $mode = false, $recursive = false) {
-		if( ! $mode )
+		if ( ! $mode )
 			$mode = $this->permission;
-		if( ! $this->exists($file) )
+		if ( ! $this->exists($file) )
 			return false;
-		if( ! $recursive )
+		if ( ! $recursive )
 			return @chmod($file,$mode);
-		if( ! $this->is_dir($file) )
+		if ( ! $this->is_dir($file) )
 			return @chmod($file, $mode);
 		//Is a directory, and we want recursive
 		$file = trailingslashit($file);
 		$filelist = $this->dirlist($file);
-		foreach($filelist as $filename)
+		foreach ($filelist as $filename)
 			$this->chmod($file . $filename, $mode, $recursive);
 
 		return true;
 	}
 	function chown($file, $owner, $recursive = false) {
-		if( ! $this->exists($file) )
+		if ( ! $this->exists($file) )
 			return false;
-		if( ! $recursive )
+		if ( ! $recursive )
 			return @chown($file, $owner);
-		if( ! $this->is_dir($file) )
+		if ( ! $this->is_dir($file) )
 			return @chown($file, $owner);
 		//Is a directory, and we want recursive
 		$filelist = $this->dirlist($file);
-		foreach($filelist as $filename){
+		foreach ($filelist as $filename){
 			$this->chown($file . '/' . $filename, $owner, $recursive);
 		}
 		return true;
 	}
 	function owner($file) {
 		$owneruid = @fileowner($file);
-		if( ! $owneruid )
+		if ( ! $owneruid )
 			return false;
-		if( ! function_exists('posix_getpwuid') )
+		if ( ! function_exists('posix_getpwuid') )
 			return $owneruid;
 		$ownerarray = posix_getpwuid($owneruid);
 		return $ownerarray['name'];
 	}
 	function getchmod($file) {
-		return @fileperms($file);
+		return substr(decoct(@fileperms($file)),3);
 	}
 	function group($file) {
 		$gid = @filegroup($file);
-		if( ! $gid )
+		if ( ! $gid )
 			return false;
-		if( ! function_exists('posix_getgrgid') )
+		if ( ! function_exists('posix_getgrgid') )
 			return $gid;
 		$grouparray = posix_getgrgid($gid);
 		return $grouparray['name'];
 	}
 
 	function copy($source, $destination, $overwrite = false) {
-		if( ! $overwrite && $this->exists($destination) )
+		if ( ! $overwrite && $this->exists($destination) )
 			return false;
 		return copy($source, $destination);
 	}
 
 	function move($source, $destination, $overwrite = false) {
 		//Possible to use rename()?
-		if( $this->copy($source, $destination, $overwrite) && $this->exists($destination) ){
+		if ( $this->copy($source, $destination, $overwrite) && $this->exists($destination) ){
 			$this->delete($source);
 			return true;
 		} else {
@@ -135,9 +135,9 @@
 	function delete($file, $recursive = false) {
 		$file = str_replace('\\', '/', $file); //for win32, occasional problems deleteing files otherwise
 
-		if( $this->is_file($file) )
+		if ( $this->is_file($file) )
 			return @unlink($file);
-		if( ! $recursive && $this->is_dir($file) )
+		if ( ! $recursive && $this->is_dir($file) )
 			return @rmdir($file);
 
 		//At this point its a folder, and we're in recursive mode
@@ -145,13 +145,13 @@
 		$filelist = $this->dirlist($file, true);
 
 		$retval = true;
-		if( is_array($filelist) ) //false if no files, So check first.
-			foreach($filelist as $filename => $fileinfo)
-				if( ! $this->delete($file . $filename, $recursive) )
+		if ( is_array($filelist) ) //false if no files, So check first.
+			foreach ($filelist as $filename => $fileinfo)
+				if ( ! $this->delete($file . $filename, $recursive) )
 					$retval = false;
 
-		if( ! @rmdir($file) )
-			return false;
+		if ( file_exists($file) && ! @rmdir($file) )
+			$retval = false;
 		return $retval;
 	}
 
@@ -187,33 +187,33 @@
 	}
 
 	function touch($file, $time = 0, $atime = 0){
-		if($time == 0)
+		if ($time == 0)
 			$time = time();
-		if($atime == 0)
+		if ($atime == 0)
 			$atime = time();
 		return @touch($file, $time, $atime);
 	}
 
 	function mkdir($path, $chmod = false, $chown = false, $chgrp = false){
-		if( ! $chmod)
+		if ( ! $chmod)
 			$chmod = $this->permission;
 
-		if( ! @mkdir($path, $chmod) )
+		if ( ! @mkdir($path, $chmod) )
 			return false;
-		if( $chown )
+		if ( $chown )
 			$this->chown($path, $chown);
-		if( $chgrp )
+		if ( $chgrp )
 			$this->chgrp($path, $chgrp);
 		return true;
 	}
 
 	function rmdir($path, $recursive = false) {
 		//Currently unused and untested, Use delete() instead.
-		if( ! $recursive )
+		if ( ! $recursive )
 			return @rmdir($path);
 		//recursive:
 		$filelist = $this->dirlist($path);
-		foreach($filelist as $filename => $det) {
+		foreach ($filelist as $filename => $det) {
 			if ( '/' == substr($filename, -1, 1) )
 				$this->rmdir($path . '/' . $filename, $recursive);
 			@rmdir($filename);
@@ -222,13 +222,13 @@
 	}
 
 	function dirlist($path, $incdot = false, $recursive = false) {
-		if( $this->is_file($path) ) {
+		if ( $this->is_file($path) ) {
 			$limitFile = basename($path);
 			$path = dirname($path);
 		} else {
 			$limitFile = false;
 		}
-		if( ! $this->is_dir($path) )
+		if ( ! $this->is_dir($path) )
 			return false;
 
 		$ret = array();
@@ -239,11 +239,11 @@
 			$struc = array();
 			$struc['name'] = $entry;
 
-			if( '.' == $struc['name'] || '..' == $struc['name'] )
+			if ( '.' == $struc['name'] || '..' == $struc['name'] )
 				continue; //Do not care about these folders.
-			if( '.' == $struc['name'][0] && !$incdot)
+			if ( '.' == $struc['name'][0] && !$incdot)
 				continue;
-			if( $limitFile && $struc['name'] != $limitFile)
+			if ( $limitFile && $struc['name'] != $limitFile)
 				continue;
 
 			$struc['perms'] 	= $this->gethchmod($path.'/'.$entry);
@@ -258,7 +258,7 @@
 			$struc['type']		= $this->is_dir($path.'/'.$entry) ? 'd' : 'f';
 
 			if ( 'd' == $struc['type'] ) {
-				if( $recursive )
+				if ( $recursive )
 					$struc['files'] = $this->dirlist($path . '/' . $struc['name'], $incdot, $recursive);
 				else
 					$struc['files'] = array();
Index: wp-admin/includes/class-wp-filesystem-ftpext.php
===================================================================
--- wp-admin/includes/class-wp-filesystem-ftpext.php	(revision 10864)
+++ wp-admin/includes/class-wp-filesystem-ftpext.php	(working copy)
@@ -169,7 +169,7 @@
 	}
 	function getchmod($file) {
 		$dir = $this->dirlist($file);
-		return $dir[$file]['permsn'];
+		return $this->getnumchmodfromh( $dir[basename($file)]['perms'] );
 	}
 	function group($file) {
 		$dir = $this->dirlist($file);
@@ -321,11 +321,12 @@
 	}
 
 	function dirlist($path = '.', $incdot = false, $recursive = false) {
-		if( $this->is_file($path) ) {
-			$limitFile = basename($path);
-			$path = dirname($path) . '/';
+
+		if ( substr($path, -1) !== '/') {
+			$limit = basename($path);
+			$path = trailingslashit(dirname($path));
 		} else {
-			$limitFile = false;
+			$limit = false;
 		}
 
 		$list = @ftp_rawlist($this->link, '-a ' . $path, false);
@@ -339,9 +340,12 @@
 			if ( empty($entry) )
 				continue;
 
-			if ( '.' == $entry["name"] || '..' == $entry["name"] )
+			if ( '.' == $entry['name'] || '..' == $entry['name'] )
 				continue;
 
+			if ( $limit && $entry['name'] != $limit )
+				continue;
+
 			$dirlist[ $entry['name'] ] = $entry;
 		}
 
Index: wp-admin/includes/class-wp-filesystem-ftpsockets.php
===================================================================
--- wp-admin/includes/class-wp-filesystem-ftpsockets.php	(revision 10864)
+++ wp-admin/includes/class-wp-filesystem-ftpsockets.php	(working copy)
@@ -186,7 +186,7 @@
 
 	function getchmod($file) {
 		$dir = $this->dirlist($file);
-		return $dir[$file]['permsn'];
+		return $this->getnumchmodfromh( $dir[basename($file)]['perms'] );
 	}
 
 	function group($file) {
@@ -281,21 +281,25 @@
 	}
 
 	function dirlist($path = '.', $incdot = false, $recursive = false ) {
-		if( $this->is_file($path) ) {
-			$limitFile = basename($path);
-			$path = dirname($path) . '/';
+
+		if ( substr($path, -1) !== '/') {
+			$limit = basename($path);
+			$path = trailingslashit(dirname($path));
 		} else {
-			$limitFile = false;
+			$limit = false;
 		}
 
 		$list = $this->ftp->dirlist($path);
 		if( ! $list )
 			return false;
+
 		if( empty($list) )
 			return array();
 
 		$ret = array();
 		foreach ( $list as $struc ) {
+			if ( $limit && $struc['name'] != $limit )
+				continue;
 
 			if ( 'd' == $struc['type'] ) {
 				$struc['files'] = array();
Index: wp-admin/includes/class-wp-upgrader.php
===================================================================
--- wp-admin/includes/class-wp-upgrader.php	(revision 0)
+++ wp-admin/includes/class-wp-upgrader.php	(revision 0)
@@ -0,0 +1,522 @@
+<?php
+/**
+ * This file is an attempt at an abstracted version of the plugin/theme/core installer/upgrader which can be used interchangably for all uses needed within WordPress.
+ * It is designed to be as flexible as possible, but some logic may seem rather, crazy to say the least.
+ * Yes, this header is designed to be replaced before commiting, Hopefully i'll get some proper documentation in here.
+ *
+ * Oh yeah, this needs testing with FTP, only tested with Direct class.
+ */
+class WP_Upgrader {
+	var $strings = array(); //Set in child classes constructor.
+	
+	function generic_strings() {
+		$this->strings['bad_request'] = __('Invalid Data provided.');
+		$this->strings['fs_unavailable'] = __('Could not access filesystem.');
+		$this->strings['fs_error'] = __('Filesystem error');
+		$this->strings['fs_no_root_dir'] = __('Unable to locate WordPress Root directory.');
+		$this->strings['fs_no_content_dir'] = __('Unable to locate WordPress Content directory (wp-content).');
+		$this->strings['fs_no_plugins_dir'] = __('Unable to locate WordPress Plugin directory.');
+		$this->strings['fs_no_themes_dir'] = __('Unable to locate WordPress Theme directory.');
+		$this->strings['fs_no_folder'] = __('Unable to locate needed folder (%s).');
+
+		$this->strings['download_failed'] = __('Download failed.');
+		$this->strings['installing_package'] = __('Installing the latest version.');
+		$this->strings['folder_exists'] = __('Destination folder already exists.');
+		$this->strings['mkdir_failed'] = __('Could not create directory.');
+		$this->strings['bad_package'] = __('Incompatible Archive');
+	}
+	
+	function feedback($string) {
+		//TODO Front end fixing.
+		$str = $this->strings[$string];
+		 
+		$args = func_get_args();
+		$args = array_splice($args, 1);
+		if ( !empty($args) )
+			$str = vsprintf($str, $args);
+		
+		return apply_filters('update_feedback', $str);
+	}
+
+	function fs_connect( $directories = array() ) {
+		global $wp_filesystem;
+	
+		// Is a filesystem accessor setup?
+		if ( ! $wp_filesystem || ! is_object($wp_filesystem) )
+			WP_Filesystem();
+	
+		if ( ! is_object($wp_filesystem) )
+			return new WP_Error('fs_unavailable', $this->strings['fs_unavailable'] );
+	
+		if ( $wp_filesystem->errors->get_error_code() )
+			return new WP_Error('fs_error', $this->strings['fs_error'], $wp_filesystem->errors);
+
+		foreach ( (array)$directories as $dir ) {
+			if ( ABSPATH == $dir && ! $wp_filesystem->abspath() )
+				return new WP_Error('fs_no_root_dir', $this->strings['fs_no_root_dir']);
+
+			elseif ( WP_CONTENT_DIR == $dir && ! $wp_filesystem->wp_content_dir() )
+				return new WP_Error('fs_no_content_dir', $this->strings['fs_no_content_dir']);
+
+			elseif ( WP_PLUGIN_DIR == $dir && ! $wp_filesystem->wp_plugins_dir() )
+				return new WP_Error('fs_no_plugins_dir', $this->strings['fs_no_plugins_dir']);
+
+			elseif ( WP_CONTENT_DIR . '/themes' == $dir && ! $wp_filesystem->find_folder(WP_CONTENT_DIR . '/themes') )
+				return new WP_Error('fs_no_themes_dir', $this->strings['fs_no_themes_dir']);
+
+			elseif ( ! $wp_filesystem->find_folder($dir) )
+				return new WP_Error('fs_no_folder', sprintf($strings['fs_no_folder'], $dir));
+		}
+	} //end fs_connect();
+
+	function download_package($package) {
+
+		if ( ! preg_match('!^(http|https|ftp)://!i', $package) && file_exists($package) ) //Local file or remote?
+			return $package; //must be a local file..
+		
+		if ( empty($package) )
+			return new WP_Error('no_package', $this->strings['no_package']);
+
+		$this->feedback('downloading_package', $package);
+
+		$download_file = download_url($package); //TODO, move to class?
+	
+		if ( is_wp_error($download_file) )
+			return new WP_Error('download_failed', $this->strings['download_failed'], $download_file->get_error_message());
+		
+		return $download_file;
+	}
+	
+	function unpack_package($package, $delete_package = true) {
+		global $wp_filesystem;
+		
+		$this->feedback('unpack_package');
+
+		//We need a working directory
+		$working_dir = $wp_filesystem->wp_content_dir() . 'upgrade/' . basename($package, '.zip');
+
+		// Clean up working directory
+		if ( $wp_filesystem->is_dir($working_dir) )
+			$wp_filesystem->delete($working_dir, true);
+
+		// Unzip package to working directory
+		$result = unzip_file($package, $working_dir); //TODO: Move to class?
+
+		// Once extracted, delete the package
+		unlink($package);
+
+		if ( is_wp_error($result) ) {
+			$wp_filesystem->delete($working_dir, true);
+			return $result;
+		}
+		
+		return $working_dir;
+	}
+	
+	//TODO: Better variable naming.
+	function install_package($args = array()) {
+		global $wp_filesystem;
+		$defaults = array( 'source' => '', 'destination' => '', //Please always pass these
+						'clear_destination' => false, 'clear_working' => false,
+						'hook_extra' => array());
+
+		$r = wp_parse_args($args, $defaults);
+		extract($r);
+		
+		if ( empty($source) || empty($destination) )
+			return new WP_Error('bad_request', $this->strings['bad_request']);
+		
+		$this->feedback('installing_package');
+
+		$res = apply_filters('upgrader_pre_install', $hook_extra);
+		if ( is_wp_error($res) )
+			return $res;
+
+		//Retain the Original source and destinations
+		$the_source = $source;
+		$local_destination = $destination;
+		
+		$source_files = array_keys( $wp_filesystem->dirlist($the_source) );
+		$remote_destination = $wp_filesystem->find_folder($local_destination);
+
+		//Locate which directory to copy to the new folder, This is based on the actual folder holding the files.
+		if ( count($source_files) > 1 ) //If multiple files, then we want the parent directory as source. //Note, This can be changed via the filter 'upgrader_source_selection'
+			$source = trailingslashit(dirname($source));
+		elseif ( 1 == count($source_files) && $wp_filesystem->is_dir( trailingslashit($source) . $source_files[0]) ) //Only one folder? Then we want its contents.
+			$source = trailingslashit($source) . trailingslashit($source_files[0]);
+		elseif ( count($source_files) == 0 )
+			return new WP_Error('bad_package', $this->strings['bad_package']); //There are no files?
+		//else //Its only a single file, I guess this can just be dumped into the destination folder hopefully.
+		
+		//Hook ability to change the source file location..
+		$source = apply_filters('upgrader_source_selection', $source, $the_source, &$this);
+		if ( is_wp_error($source) )
+			return $source;
+		
+		//Has the source location changed? If so, we need a new source_files list.
+		if ( $source !== $the_source )
+			$source_files = array_keys( $wp_filesystem->dirlist($source) );
+		
+		//Protection against deleting files in any important base directories.
+		if ( in_array( $destination, array(ABSPATH, WP_CONTENT_DIR, WP_PLUGIN_DIR, WP_CONTENT_DIR . '/themes') ) ) {
+			$remote_destination = trailingslashit($remote_destination) . trailingslashit(basename($source));
+			$destination = trailingslashit($destination) . trailingslashit(basename($source));
+		}
+
+		//If we're not clearing the destination folder, and something exists there allready, Bail.
+		if ( ! $clear_destination && $wp_filesystem->exists($remote_destination) ) {
+			$wp_filesystem->delete($working_dir, true);
+			return new WP_Error('folder_exists', $this->strings['folder_exists'], $filelist[0] );
+		} else if ( $clear_destination ) {
+			//We're going to clear the destination if theres something there
+			$this->feedback('remove_old');
+
+			$removed = true;
+			if ( $wp_filesystem->exists($remote_destination) )
+				$removed = $wp_filesystem->delete($remote_destination, true);
+
+			$removed = apply_filters('upgrader_clear_destination', $removed, $local_destination, $remote_destination, $hook_extra);
+
+			if ( is_wp_error($removed) )
+				return $removed;
+			elseif ( ! $removed )
+				return new WP_Error('remove_old_failed', $this->strings['remove_old_failed']);
+		}
+
+		//The folder name of the destination folder. will get put into the destiination folder, ie. WP_PLUGIN_DIR/SOURCE_DIR/
+		$source_folder = basename($source);
+		
+		//Create destination if needed
+		if ( !$wp_filesystem->exists($remote_destination) )
+			if ( !$wp_filesystem->mkdir($remote_destination) )
+				return new WP_Error('mkdir_failed', $this->strings['mkdir_failed'], $remote_destination);
+		
+		// Copy new version of item into place.
+		$result = copy_dir($source, $remote_destination);
+		if ( is_wp_error($result) ) {
+			if ( $clear_working )
+				$wp_filesystem->delete($the_source, true);
+			return $result;
+		}
+		
+		//Clear the Working folder? 
+		if ( $clear_working )
+			$wp_filesystem->delete($the_source, true);
+
+		//Bombard the calling function will all the info which we've just used.
+		return compact('the_source', 'source', 'source_folder', 'source_files', 'destination', 'remote_destination', 'clear_destination', 'delete_source_dir');
+	}
+	
+	function run($options) {
+
+		$defaults = array( 	'package' => '', //Please always pass this.
+							'destination' => '', //And this
+							'clear_destination' => false,
+							'clear_working' => true,
+							'hook_extra' => array() //Pass any extra $hook_extra args here, this will be passed to any hooked filters.
+						);
+
+		$options = wp_parse_args($args, $options);
+		extract($options);
+	
+		//Connect to the Filesystem first.
+		$res = $this->fs_connect( array(WP_CONTENT_DIR, $destination) );
+		if ( is_wp_error($res) )
+			return $res;
+		
+		//Download the package (Note, This just returns the filename of the file if the package is a local file)
+		$download = $this->download_package( $package );
+		if ( is_wp_error($download) )
+			return $download;
+		
+		//Unzip's the file into a temporary directory
+		$working_dir = $this->unpack_package( $download );
+		if ( is_wp_error($working_dir) )
+			return $working_dir;
+
+		//With the given options, this installs it to the destination directory.
+		return $this->install_package( array( 
+											'source' => $working_dir,
+											'destination' => $destination,
+											'clear_destination' => $clear_destination,
+											'clear_working' => $clear_working,
+											'hook_extra' => $hook_extra
+										) );
+	}
+	
+}
+
+class Plugin_Upgrader extends WP_Upgrader {
+
+	function upgrade_strings() {
+		$this->generic_strings();
+		$this->strings['up_to_date'] = __('The plugin is at the latest version.');
+		$this->strings['no_package'] = __('Upgrade package not available.');
+		$this->strings['downloading_package'] = __('Downloading update from %s.');
+		$this->strings['unpack_package'] = __('Unpacking the update.');
+		$this->strings['deactivate_plugin'] = __('Deactivating the plugin.');
+		$this->strings['remove_old'] = __('Removing the old version of the plugin.');
+		$this->strings['remove_old_failed'] = __('Could not remove the old plugin.');
+	}
+
+	function install_strings() {
+		$this->generic_strings();
+		$this->strings['no_package'] = __('Install package not available.');
+		$this->strings['downloading_package'] = __('Downloading install package from %s.');
+		$this->strings['unpack_package'] = __('Unpacking the package.');
+	}
+
+	function install($package) {
+		
+		$this->install_strings();
+
+		$options = array(
+						'package' => $package,
+						'destination' => WP_PLUGIN_DIR,
+						'clear_destination' => false, //Do not overwrite files.
+						'clear_working' => true,
+						'hook_extra' => array()
+						);
+		
+		$result = $this->run($options);
+	
+		// Force refresh of plugin update information
+		delete_transient('update_plugins');
+	
+		if( empty($result['destination_name']) )
+			return false; 
+
+		$plugin = get_plugins('/' . $result['destination_name']); //Ensure to pass with leading slash
+		$pluginfiles = array_keys($plugin); //Assume the requested plugin is the first in the list
+	
+		return $result['destination_name']. '/' . $pluginfiles[0];
+	}
+
+	function upgrade($plugin) {
+		
+		$this->upgrade_strings();
+		
+		$current = get_transient( 'update_plugins' );
+		if ( !isset( $current->response[ $plugin ] ) )
+			return new WP_Error('up_to_date', $this->strings['up_to_date']);
+
+		// Get the URL to the zip file
+		$r = $current->response[ $plugin ];
+		
+		add_filter('upgrader_pre_install', array(&$this, 'deactivate_plugin_before_upgrade'));
+		add_filter('upgrader_clear_destination', array(&$this, 'delete_old_plugin'), 10, 4);
+		//'source_selection' => array(&$this, 'source_selection'), //theres a track ticket to move up the directory for zip's which are made a bit differently, useful for non-.org plugins.
+		
+		$options = array(
+					'package' => $r->package,
+					'destination' => WP_PLUGIN_DIR,
+					'clear_destination' => true,
+					'clear_working' => true,
+					'hook_extra' => array(
+								'plugin' => $plugin
+					)
+				);
+		
+		$result = $this->run($options);
+
+		//Cleanup our hooks, incase something else does a upgrade on this connection.
+		remove_filter('upgrader_pre_install', array(&$this, 'deactivate_plugin_before_upgrade'));
+		remove_filter('upgrader_clear_destination', array(&$this, 'delete_old_plugin'));
+
+		if ( is_wp_error($result) )
+			return $result;
+
+		// Force refresh of plugin update information
+		delete_transient('update_plugins');
+
+		if( empty($result['source_folder']) )
+			return false; 
+
+		$plugin = get_plugins('/' . $result['source_folder']); //Ensure to pass with leading slash
+		$pluginfiles = array_keys($plugin); //Assume the requested plugin is the first in the list
+	
+		return $result['source_folder'] . '/' . $pluginfiles[0];
+	}
+
+	//Hooked to pre_install
+	function deactivate_plugin_before_upgrade($plugin) {
+
+		$plugin = isset($plugin['plugin']) ? $plugin['plugin'] : '';
+		if ( empty($plugin) )
+			return new WP_Error('bad_request', $this->strings['bad_request']);
+
+		if ( is_plugin_active($plugin) ) {
+			$this->feedback('deactivate_plugin');
+			//Deactivate the plugin silently, Prevent deactivation hooks from running.
+			deactivate_plugins($plugin, true);
+		}	
+	}
+
+	//Hooked to upgrade_clear_destination
+	function delete_old_plugin($removed, $local_destination, $remote_destination, $plugin) {
+		global $wp_filesystem;
+	
+		if ( is_wp_error($removed) )
+			return $removed; //Pass errors through.
+	
+		$plugin = isset($plugin['plugin']) ? $plugin['plugin'] : '';
+		if ( empty($plugin) )
+			return new WP_Error('bad_request', $this->strings['bad_request']);
+
+		$plugins_dir = $wp_filesystem->wp_plugins_dir();
+		$this_plugin_dir = trailingslashit( dirname($plugins_dir . $plugin) );
+	
+		// If plugin is in its own directory, recursively delete the directory.
+		if ( strpos($plugin, '/') && $this_plugin_dir != $plugins_dir ) //base check on if plugin includes directory seperator AND that its not the root plugin folder
+			$deleted = $wp_filesystem->delete($this_plugin_dir, true);
+		else
+			$deleted = $wp_filesystem->delete($plugins_dir . $plugin);
+
+		if ( ! $deleted )
+			return new WP_Error('remove_old_failed', $this->strings['remove_old_failed']);
+		
+		return $removed;
+	}
+}
+
+
+class Theme_Upgrader extends WP_Upgrader {
+
+	function upgrade_strings() {
+		$this->generic_strings();
+		$this->strings['up_to_date'] = __('The theme is at the latest version.');
+		$this->strings['no_package'] = __('Upgrade package not available.');
+		$this->strings['downloading_package'] = __('Downloading update from %s.');
+		$this->strings['unpack_package'] = __('Unpacking the update.');
+//		$this->strings['deactivate_plugin'] = __('Deactivating the plugin.'); // => Maintainence mode?
+		$this->strings['remove_old'] = __('Removing the old version of the theme.');
+		$this->strings['remove_old_failed'] = __('Could not remove the old theme.');
+	}
+
+	function install_strings() {
+		$this->generic_strings();
+		$this->strings['no_package'] = __('Install package not available.');
+		$this->strings['downloading_package'] = __('Downloading install package from %s.');
+		$this->strings['unpack_package'] = __('Unpacking the package.');
+	}
+
+	function install($package) {
+		
+		$this->install_strings();
+
+		$options = array(
+						'package' => $package,
+						'destination' => WP_CONTENT_DIR . '/themes',
+						'clear_destination' => false, //Do not overwrite files.
+						'clear_working' => true
+						);
+		
+		$result = $this->run($options);
+	
+		// Force refresh of theme update information
+		delete_transient('update_themes');
+	
+		if( empty($result['destination_name']) )
+			return false; 
+
+		$plugin = get_plugins('/' . $result['destination_name']); //Ensure to pass with leading slash
+		$pluginfiles = array_keys($plugin); //Assume the requested plugin is the first in the list
+	
+		return $folder . '/' . $pluginfiles[0];
+	}
+
+	function upgrade($theme) {
+		
+		$this->upgrade_strings();
+		
+		// Is an update available?
+		$current = get_transient( 'update_themes' );
+		if ( !isset( $current->response[ $theme ] ) )
+			return new WP_Error('up_to_date', $this->strings['up_to_date']);
+		
+		$r = $current->response[ $theme ];
+		
+		$themes = get_themes();
+		foreach ( (array) $themes as $this_theme ) {
+			if ( $this_theme['Stylesheet'] == $theme ) {
+				$theme_directory = preg_replace('!^/themes/!i', '', $this_theme['Stylesheet Dir']);
+				break;
+			}
+		}
+		unset($themes);
+
+		$options = array(
+						'package' => $r['package'],
+						'destination' => WP_CONTENT_DIR . '/themes',
+						'clear_destination' => true,
+						'clear_working' => true,
+						'hook_extra' => array(
+											'theme' => $theme
+											)
+						);
+		
+		$result = $this->run($options);
+
+		if ( is_wp_error($result) )
+			return $result;
+
+		// Force refresh of theme update information
+		delete_transient('update_themes');
+
+		return true;
+	}
+
+}
+
+//Untested.
+class Core_Upgrader extends WP_Upgrader {
+
+	function upgrade_strings() {
+		$this->generic_strings();
+		$this->strings['up_to_date'] = __('WordPress is at the latest version.');
+		$this->strings['no_package'] = __('Upgrade package not available.');
+		$this->strings['downloading_package'] = __('Downloading update from %s.');
+		$this->strings['unpack_package'] = __('Unpacking the update.');
+		$this->strings['copy_failed'] = __('Could not copy files.');
+	}
+
+	function upgrade($current) {
+		global $wp_filesystem;
+		$this->upgrade_strings();
+		
+		@set_time_limit( 300 );
+	
+		if ( !empty($feedback) )
+			add_filter('update_feedback', $feedback);
+	
+		// Is an update available?
+		if ( !isset( $current->response ) || $current->response == 'latest' )
+			return new WP_Error('up_to_date', $this->strings['up_to_date']);
+
+		$res = $this->fs_connect( array(ABSPATH, WP_CONTENT_DIR) );
+		if ( is_wp_error($res) )
+			return $res;
+		
+		$wp_dir = trailingslashit($wp_filesystem->abspath());
+		
+		$download = $this->download_package( $current->package );
+		if ( is_wp_error($download) )
+			return $download;
+		
+		$working_dir = $this->unpack_package( $download );
+		if ( is_wp_error($working_dir) )
+			return $working_dir;
+
+		// Copy update-core.php from the new version into place.
+		if ( !$wp_filesystem->copy($working_dir . '/wordpress/wp-admin/includes/update-core.php', $wp_dir . 'wp-admin/includes/update-core.php', true) ) {
+			$wp_filesystem->delete($working_dir, true);
+			return new WP_Error('copy_failed', $this->strings['copy_failed']);
+		}
+		$wp_filesystem->chmod($wp_dir . 'wp-admin/includes/update-core.php', FS_CHMOD_FILE);
+	
+		require(ABSPATH . 'wp-admin/includes/update-core.php');
+	
+		return update_core($working_dir, $wp_dir);
+	}
+
+}
\ No newline at end of file
Index: wp-admin/includes/plugin-install.php
===================================================================
--- wp-admin/includes/plugin-install.php	(revision 10864)
+++ wp-admin/includes/plugin-install.php	(working copy)
@@ -723,93 +723,12 @@
  * @return mixed.
  */
 function wp_install_plugin($package, $feedback = '') {
-	global $wp_filesystem;
-
 	if ( !empty($feedback) )
-		add_filter('install_feedback', $feedback);
+		add_filter('update_feedback', $feedback);
 
-	// Is a filesystem accessor setup?
-	if ( ! $wp_filesystem || ! is_object($wp_filesystem) )
-		WP_Filesystem();
-
-	if ( ! is_object($wp_filesystem) )
-		return new WP_Error('fs_unavailable', __('Could not access filesystem.'));
-
-	if ( $wp_filesystem->errors->get_error_code() )
-		return new WP_Error('fs_error', __('Filesystem error'), $wp_filesystem->errors);
-
-	//Get the base plugin folder
-	$plugins_dir = $wp_filesystem->wp_plugins_dir();
-	if ( empty($plugins_dir) )
-		return new WP_Error('fs_no_plugins_dir', __('Unable to locate WordPress Plugin directory.'));
-
-	//And the same for the Content directory.
-	$content_dir = $wp_filesystem->wp_content_dir();
-	if( empty($content_dir) )
-		return new WP_Error('fs_no_content_dir', __('Unable to locate WordPress Content directory (wp-content).'));
-
-	$plugins_dir = trailingslashit( $plugins_dir );
-	$content_dir = trailingslashit( $content_dir );
-
-	if ( empty($package) )
-		return new WP_Error('no_package', __('Install package not available.'));
-
-	// Download the package
-	apply_filters('install_feedback', sprintf(__('Downloading plugin package from %s'), $package));
-	$download_file = download_url($package);
-
-	if ( is_wp_error($download_file) )
-		return new WP_Error('download_failed', __('Download failed.'), $download_file->get_error_message());
-
-	$working_dir = $content_dir . 'upgrade/' . basename($package, '.zip');
-
-	// Clean up working directory
-	if ( $wp_filesystem->is_dir($working_dir) )
-		$wp_filesystem->delete($working_dir, true);
-
-	apply_filters('install_feedback', __('Unpacking the plugin package'));
-	// Unzip package to working directory
-	$result = unzip_file($download_file, $working_dir);
-
-	// Once extracted, delete the package
-	@unlink($download_file);
-
-	if ( is_wp_error($result) ) {
-		$wp_filesystem->delete($working_dir, true);
-		return $result;
-	}
-
-	//Get a list of the directories in the working directory before we delete it, We need to know the new folder for the plugin
-	$filelist = array_keys( $wp_filesystem->dirlist($working_dir) );
-
-	if( $wp_filesystem->exists( $plugins_dir . $filelist[0] ) ) {
-		$wp_filesystem->delete($working_dir, true);
-		return new WP_Error('install_folder_exists', __('Folder already exists.'), $filelist[0] );
-	}
-
-	apply_filters('install_feedback', __('Installing the plugin'));
-	// Copy new version of plugin into place.
-	$result = copy_dir($working_dir, $plugins_dir);
-	if ( is_wp_error($result) ) {
-		$wp_filesystem->delete($working_dir, true);
-		return $result;
-	}
-
-	//Get a list of the directories in the working directory before we delete it, We need to know the new folder for the plugin
-	$filelist = array_keys( $wp_filesystem->dirlist($working_dir) );
-
-	// Remove working directory
-	$wp_filesystem->delete($working_dir, true);
-
-	if( empty($filelist) )
-		return false; //We couldnt find any files in the working dir, therefor no plugin installed? Failsafe backup.
-
-	$folder = $filelist[0];
-	$plugin = get_plugins('/' . $folder); //Ensure to pass with leading slash
-	$pluginfiles = array_keys($plugin); //Assume the requested plugin is the first in the list
-
-	//Return the plugin files name.
-	return  $folder . '/' . $pluginfiles[0];
+	include ABSPATH . 'wp-admin/includes/class-wp-upgrader.php';
+	$upgrader = new Plugin_Upgrader();
+	return $upgrader->install($package);
 }
 
 /**
@@ -822,86 +741,12 @@
  * @return mixed.
  */
 function wp_install_plugin_local_package($package, $feedback = '') {
-	global $wp_filesystem;
-
 	if ( !empty($feedback) )
-		add_filter('install_feedback', $feedback);
+		add_filter('update_feedback', $feedback);
 
-	// Is a filesystem accessor setup?
-	if ( ! $wp_filesystem || ! is_object($wp_filesystem) )
-		WP_Filesystem();
-
-	if ( ! is_object($wp_filesystem) )
-		return new WP_Error('fs_unavailable', __('Could not access filesystem.'));
-
-	if ( $wp_filesystem->errors->get_error_code() )
-		return new WP_Error('fs_error', __('Filesystem error'), $wp_filesystem->errors);
-
-	//Get the base plugin folder
-	$plugins_dir = $wp_filesystem->wp_plugins_dir();
-	if ( empty($plugins_dir) )
-		return new WP_Error('fs_no_plugins_dir', __('Unable to locate WordPress Plugin directory.'));
-
-	//And the same for the Content directory.
-	$content_dir = $wp_filesystem->wp_content_dir();
-	if( empty($content_dir) )
-		return new WP_Error('fs_no_content_dir', __('Unable to locate WordPress Content directory (wp-content).'));
-
-	$plugins_dir = trailingslashit( $plugins_dir );
-	$content_dir = trailingslashit( $content_dir );
-
-	if ( empty($package) )
-		return new WP_Error('no_package', __('Install package not available.'));
-
-	$working_dir = $content_dir . 'upgrade/' . basename($package, '.zip');
-
-	// Clean up working directory
-	if ( $wp_filesystem->is_dir($working_dir) )
-		$wp_filesystem->delete($working_dir, true);
-
-	apply_filters('install_feedback', __('Unpacking the plugin package'));
-	// Unzip package to working directory
-	$result = unzip_file($package, $working_dir);
-
-	// Once extracted, delete the package
-	unlink($package);
-
-	if ( is_wp_error($result) ) {
-		$wp_filesystem->delete($working_dir, true);
-		return $result;
-	}
-
-	//Get a list of the directories in the working directory before we delete it, We need to know the new folder for the plugin
-	$filelist = array_keys( $wp_filesystem->dirlist($working_dir) );
-
-	if( $wp_filesystem->exists( $plugins_dir . $filelist[0] ) ) {
-		$wp_filesystem->delete($working_dir, true);
-		return new WP_Error('install_folder_exists', __('Folder already exists.'), $filelist[0] );
-	}
-
-	apply_filters('install_feedback', __('Installing the plugin'));
-	// Copy new version of plugin into place.
-	$result = copy_dir($working_dir, $plugins_dir);
-	if ( is_wp_error($result) ) {
-		$wp_filesystem->delete($working_dir, true);
-		return $result;
-	}
-
-	//Get a list of the directories in the working directory before we delete it, We need to know the new folder for the plugin
-	$filelist = array_keys( $wp_filesystem->dirlist($working_dir) );
-
-	// Remove working directory
-	$wp_filesystem->delete($working_dir, true);
-
-	if( empty($filelist) )
-		return false; //We couldnt find any files in the working dir, therefor no plugin installed? Failsafe backup.
-
-	$folder = $filelist[0];
-	$plugin = get_plugins('/' . $folder); //Ensure to pass with leading slash
-	$pluginfiles = array_keys($plugin); //Assume the requested plugin is the first in the list
-
-	//Return the plugin files name.
-	return  $folder . '/' . $pluginfiles[0];
+	include ABSPATH . 'wp-admin/includes/class-wp-upgrader.php';
+	$upgrader = new Plugin_Upgrader();
+	return $upgrader->install($package);
 }
 
 ?>
Index: wp-admin/includes/update.php
===================================================================
--- wp-admin/includes/update.php	(revision 10864)
+++ wp-admin/includes/update.php	(working copy)
@@ -167,312 +167,35 @@
 add_action( 'after_plugin_row', 'wp_plugin_update_row', 10, 2 );
 
 function wp_update_plugin($plugin, $feedback = '') {
-	global $wp_filesystem;
 
 	if ( !empty($feedback) )
 		add_filter('update_feedback', $feedback);
 
-	// Is an update available?
-	$current = get_transient( 'update_plugins' );
-	if ( !isset( $current->response[ $plugin ] ) )
-		return new WP_Error('up_to_date', __('The plugin is at the latest version.'));
-
-	// Is a filesystem accessor setup?
-	if ( ! $wp_filesystem || ! is_object($wp_filesystem) )
-		WP_Filesystem();
-
-	if ( ! is_object($wp_filesystem) )
-		return new WP_Error('fs_unavailable', __('Could not access filesystem.'));
-
-	if ( $wp_filesystem->errors->get_error_code() )
-		return new WP_Error('fs_error', __('Filesystem error'), $wp_filesystem->errors);
-
-	//Get the base plugin folder
-	$plugins_dir = $wp_filesystem->wp_plugins_dir();
-	if ( empty($plugins_dir) )
-		return new WP_Error('fs_no_plugins_dir', __('Unable to locate WordPress Plugin directory.'));
-
-	//And the same for the Content directory.
-	$content_dir = $wp_filesystem->wp_content_dir();
-	if( empty($content_dir) )
-		return new WP_Error('fs_no_content_dir', __('Unable to locate WordPress Content directory (wp-content).'));
-
-	$plugins_dir = trailingslashit( $plugins_dir );
-	$content_dir = trailingslashit( $content_dir );
-
-	// Get the URL to the zip file
-	$r = $current->response[ $plugin ];
-
-	if ( empty($r->package) )
-		return new WP_Error('no_package', __('Upgrade package not available.'));
-
-	// Download the package
-	$package = $r->package;
-	apply_filters('update_feedback', sprintf(__('Downloading update from %s'), $package));
-	$download_file = download_url($package);
-
-	if ( is_wp_error($download_file) )
-		return new WP_Error('download_failed', __('Download failed.'), $download_file->get_error_message());
-
-	$working_dir = $content_dir . 'upgrade/' . basename($plugin, '.php');
-
-	// Clean up working directory
-	if ( $wp_filesystem->is_dir($working_dir) )
-		$wp_filesystem->delete($working_dir, true);
-
-	apply_filters('update_feedback', __('Unpacking the update'));
-	// Unzip package to working directory
-	$result = unzip_file($download_file, $working_dir);
-
-	// Once extracted, delete the package
-	unlink($download_file);
-
-	if ( is_wp_error($result) ) {
-		$wp_filesystem->delete($working_dir, true);
-		return $result;
-	}
-
-	if ( is_plugin_active($plugin) ) {
-		//Deactivate the plugin silently, Prevent deactivation hooks from running.
-		apply_filters('update_feedback', __('Deactivating the plugin'));
-		deactivate_plugins($plugin, true);
-	}
-
-	// Remove the existing plugin.
-	apply_filters('update_feedback', __('Removing the old version of the plugin'));
-	$this_plugin_dir = trailingslashit( dirname($plugins_dir . $plugin) );
-
-	// If plugin is in its own directory, recursively delete the directory.
-	if ( strpos($plugin, '/') && $this_plugin_dir != $plugins_dir ) //base check on if plugin includes directory seperator AND that its not the root plugin folder
-		$deleted = $wp_filesystem->delete($this_plugin_dir, true);
-	else
-		$deleted = $wp_filesystem->delete($plugins_dir . $plugin);
-
-	if ( ! $deleted ) {
-		$wp_filesystem->delete($working_dir, true);
-		return new WP_Error('delete_failed', __('Could not remove the old plugin'));
-	}
-
-	apply_filters('update_feedback', __('Installing the latest version'));
-	// Copy new version of plugin into place.
-	$result = copy_dir($working_dir, $plugins_dir);
-	if ( is_wp_error($result) ) {
-		$wp_filesystem->delete($working_dir, true);
-		return $result;
-	}
-
-	//Get a list of the directories in the working directory before we delete it, We need to know the new folder for the plugin
-	$filelist = array_keys( $wp_filesystem->dirlist($working_dir) );
-
-	// Remove working directory
-	$wp_filesystem->delete($working_dir, true);
-
-	// Force refresh of plugin update information
-	delete_transient('update_plugins');
-
-	if( empty($filelist) )
-		return false; //We couldnt find any files in the working dir, therefor no plugin installed? Failsafe backup.
-
-	$folder = $filelist[0];
-	$plugin = get_plugins('/' . $folder); //Ensure to pass with leading slash
-	$pluginfiles = array_keys($plugin); //Assume the requested plugin is the first in the list
-
-	return  $folder . '/' . $pluginfiles[0];
+	include ABSPATH . 'wp-admin/includes/class-wp-upgrader.php';
+	$upgrader = new Plugin_Upgrader();
+	return $upgrader->upgrade($plugin);
 }
 
 function wp_update_theme($theme, $feedback = '') {
-	global $wp_filesystem;
-
+	
 	if ( !empty($feedback) )
 		add_filter('update_feedback', $feedback);
 
-	// Is an update available?
-	$current = get_transient( 'update_themes' );
-	if ( !isset( $current->response[ $theme ] ) )
-		return new WP_Error('up_to_date', __('The theme is at the latest version.'));
-
-	$r = $current->response[ $theme ];
-
-	$themes = get_themes();
-	foreach ( (array) $themes as $this_theme ) {
-		if ( $this_theme['Stylesheet'] == $theme ) {
-			$theme_directory = preg_replace('!^/themes/!i', '', $this_theme['Stylesheet Dir']);
-			break;
-		}
-	}
-	unset($themes);
-
-	if ( empty($theme_directory) )
-		return new WP_Error('theme_non_existant', __('Theme does not exist.'));
-
-	// Is a filesystem accessor setup?
-	if ( ! $wp_filesystem || ! is_object($wp_filesystem) )
-		WP_Filesystem();
-
-	if ( ! is_object($wp_filesystem) )
-		return new WP_Error('fs_unavailable', __('Could not access filesystem.'));
-
-	if ( $wp_filesystem->errors->get_error_code() )
-		return new WP_Error('fs_error', __('Filesystem error'), $wp_filesystem->errors);
-
-	//Get the base plugin folder
-	$themes_dir = $wp_filesystem->wp_themes_dir();
-	if ( empty($themes_dir) )
-		return new WP_Error('fs_no_themes_dir', __('Unable to locate WordPress Theme directory.'));
-
-	//And the same for the Content directory.
-	$content_dir = $wp_filesystem->wp_content_dir();
-	if( empty($content_dir) )
-		return new WP_Error('fs_no_content_dir', __('Unable to locate WordPress Content directory (wp-content).'));
-
-	$themes_dir = trailingslashit( $themes_dir );
-	$content_dir = trailingslashit( $content_dir );
-
-	if ( empty($r->package) )
-		return new WP_Error('no_package', __('Upgrade package not available.'));
-
-	// Download the package
-	apply_filters('update_feedback', sprintf(__('Downloading update from %s'), $r['package']));
-	$download_file = download_url($r['package']);
-
-	if ( is_wp_error($download_file) )
-		return new WP_Error('download_failed', __('Download failed.'), $download_file->get_error_message());
-
-	$working_dir = $content_dir . 'upgrade/' . basename($theme_directory);
-
-	// Clean up working directory
-	if ( $wp_filesystem->is_dir($working_dir) )
-		$wp_filesystem->delete($working_dir, true);
-
-	apply_filters('update_feedback', __('Unpacking the update'));
-	// Unzip package to working directory
-	$result = unzip_file($download_file, $working_dir);
-
-	// Once extracted, delete the package
-	unlink($download_file);
-
-	if ( is_wp_error($result) ) {
-		$wp_filesystem->delete($working_dir, true);
-		return $result;
-	}
-
-	//TODO: Is theme currently active? If so, set default theme
-	/*
-	if ( is_plugin_active($plugin) ) {
-		//Deactivate the plugin silently, Prevent deactivation hooks from running.
-		apply_filters('update_feedback', __('Deactivating the plugin'));
-		deactivate_plugins($plugin, true);
-	}*/
-
-	// Remove the existing plugin.
-	apply_filters('update_feedback', __('Removing the old version of the theme'));
-	$deleted = $wp_filesystem->delete($themes_dir . $theme_directory, true);
-
-	if ( ! $deleted ) {
-		$wp_filesystem->delete($working_dir, true);
-		return new WP_Error('delete_failed', __('Could not remove the old plugin'));
-	}
-
-	apply_filters('update_feedback', __('Installing the latest version'));
-	// Copy new version of plugin into place.
-	$result = copy_dir($working_dir, $themes_dir);
-	if ( is_wp_error($result) ) {
-		$wp_filesystem->delete($working_dir, true);
-		return $result;
-	}
-
-	//Get a list of the directories in the working directory before we delete it, We need to know the new folder for the plugin
-	//$filelist = array_keys( $wp_filesystem->dirlist($working_dir) );
-
-	// Remove working directory
-	$wp_filesystem->delete($working_dir, true);
-
-	// Force refresh of plugin update information
-	delete_transient('update_themes');
-
-	/*if( empty($filelist) )
-		return false; //We couldnt find any files in the working dir, therefor no plugin installed? Failsafe backup.
-
-	$folder = $filelist[0];
-	$plugin = get_plugins('/' . $folder); //Ensure to pass with leading slash
-	$pluginfiles = array_keys($plugin); //Assume the requested plugin is the first in the list
-
-	return  $folder . '/' . $pluginfiles[0];*/
+	include ABSPATH . 'wp-admin/includes/class-wp-upgrader.php';
+	$upgrader = new Theme_Upgrader();
+	return $upgrader->upgrade($theme);
 }
 
 
 function wp_update_core($current, $feedback = '') {
-	global $wp_filesystem;
-
-	@set_time_limit( 300 );
-
+	
 	if ( !empty($feedback) )
 		add_filter('update_feedback', $feedback);
 
-	// Is an update available?
-	if ( !isset( $current->response ) || $current->response == 'latest' )
-		return new WP_Error('up_to_date', __('WordPress is at the latest version.'));
+	include ABSPATH . 'wp-admin/includes/class-wp-upgrader.php';
+	$upgrader = new Core_Upgrader();
+	return $upgrader->upgrade($current);
 
-	// Is a filesystem accessor setup?
-	if ( ! $wp_filesystem || ! is_object($wp_filesystem) )
-		WP_Filesystem();
-
-	if ( ! is_object($wp_filesystem) )
-		return new WP_Error('fs_unavailable', __('Could not access filesystem.'));
-
-	if ( $wp_filesystem->errors->get_error_code() )
-		return new WP_Error('fs_error', __('Filesystem error'), $wp_filesystem->errors);
-
-	// Get the base WP folder
-	$wp_dir = $wp_filesystem->abspath();
-	if ( empty($wp_dir) )
-		return new WP_Error('fs_no_wp_dir', __('Unable to locate WordPress directory.'));
-
-	// And the same for the Content directory.
-	$content_dir = $wp_filesystem->wp_content_dir();
-	if( empty($content_dir) )
-		return new WP_Error('fs_no_content_dir', __('Unable to locate WordPress Content directory (wp-content).'));
-
-	$wp_dir = trailingslashit( $wp_dir );
-	$content_dir = trailingslashit( $content_dir );
-
-	// Get the URL to the zip file
-	$package = $current->package;
-
-	// Download the package
-	apply_filters('update_feedback', sprintf(__('Downloading update from %s'), $package));
-	$download_file = download_url($package);
-
-	if ( is_wp_error($download_file) )
-		return new WP_Error('download_failed', __('Download failed.'), $download_file->get_error_message());
-
-	$working_dir = $content_dir . 'upgrade/core';
-	// Clean up working directory
-	if ( $wp_filesystem->is_dir($working_dir) ) {
-		$wp_filesystem->delete($working_dir, true);
-	}
-
-	apply_filters('update_feedback', __('Unpacking the core update'));
-	// Unzip package to working directory
-	$result = unzip_file($download_file, $working_dir);
-	// Once extracted, delete the package
-	unlink($download_file);
-
-	if ( is_wp_error($result) ) {
-		$wp_filesystem->delete($working_dir, true);
-		return $result;
-	}
-
-	// Copy update-core.php from the new version into place.
-	if ( !$wp_filesystem->copy($working_dir . '/wordpress/wp-admin/includes/update-core.php', $wp_dir . 'wp-admin/includes/update-core.php', true) ) {
-		$wp_filesystem->delete($working_dir, true);
-		return new WP_Error('copy_failed', __('Could not copy files'));
-	}
-	$wp_filesystem->chmod($wp_dir . 'wp-admin/includes/update-core.php', FS_CHMOD_FILE);
-
-	require(ABSPATH . 'wp-admin/includes/update-core.php');
-
-	return update_core($working_dir, $wp_dir);
 }
 
 function maintenance_nag() {
Index: wp-includes/update.php
===================================================================
--- wp-includes/update.php	(revision 10864)
+++ wp-includes/update.php	(working copy)
@@ -112,7 +112,7 @@
 
 	$new_option = new stdClass;
 	$new_option->last_checked = time();
-	$timeout = 'load-plugins.php' == current_filter() ? 360 : 43200; //Check for updated every 60 minutes if hitting the themes page, Else, check every 12 hours
+	$timeout = 'load-plugins.php' == current_filter() ? 3600 : 43200; //Check for updated every 60 minutes if hitting the themes page, Else, check every 12 hours
 	$time_not_changed = isset( $current->last_checked ) && $timeout > ( time() - $current->last_checked );
 
 	$plugin_changed = false;
@@ -195,7 +195,7 @@
 
 	$new_option = new stdClass;
 	$new_option->last_checked = time( );
-	$timeout = 'load-themes.php' == current_filter() ? 360 : 43200; //Check for updated every 60 minutes if hitting the themes page, Else, check every 12 hours
+	$timeout = 'load-themes.php' == current_filter() ? 3600 : 43200; //Check for updated every 60 minutes if hitting the themes page, Else, check every 12 hours
 	$time_not_changed = isset( $current_theme->last_checked ) && $timeout > ( time( ) - $current_theme->last_checked );
 
 	if( $time_not_changed )

