Index: wp-admin/includes/file.php
===================================================================
--- wp-admin/includes/file.php	(revision 9324)
+++ wp-admin/includes/file.php	(working copy)
@@ -482,6 +482,14 @@
 	if ( 0 == count($archive_files) )
 		return new WP_Error('empty_archive', __('Empty archive'));
 
+	//Prepend another directory level if there are files in the root directory of the zip
+	foreach ( $archive_files as $archive_file ) {
+		if ( false === strpos($archive_file['filename'], '/') ) {
+			$to = trailingslashit($to) . basename($file, '.zip');
+			break;
+		}
+	}
+
 	$path = explode('/', untrailingslashit($to));
 	for ( $i = count($path); $i > 0; $i-- ) { //>0 = first element is empty allways for paths starting with '/'
 		$tmppath = implode('/', array_slice($path, 0, $i) );
@@ -558,6 +566,42 @@
 }
 
 /**
+ * Locates the lowest safe directory in a Plugin folder to copy to the plugins directory.
+ *
+ * @since 2.7.0
+ *
+ * @param string $working_dir the Working directory of the plugin files
+ * @return string The directory from the folder to copy from.
+ */
+function update_pluginfiles_base_dir($working_dir) {
+	$files = list_files($working_dir);
+	//Remove non-php files
+	foreach ( (array)$files as $key => $file ) 
+		if ( ! preg_match('!.php$!i', $file) )
+			unset($files[$key]);
+	//remove non-plugin files
+	foreach ( (array)$files as $key => $file ) {
+		$details = get_plugin_data($file, false, false);
+		if ( empty($details['Name']) )
+			unset($files[$key]);
+	}
+	if ( empty($files) )
+		return false;
+	//Left with paths to files which ARE plugins.
+	$min_num = 100; //assume no zips with deeper paths will come along
+	$min_file = '';
+	foreach ( (array)$files as $key => $file ) {
+		$this_num = substr_count($file, '/');
+		if ( $this_num < $min_num ) {
+			$min_file = $file;
+			$min_num = $this_num;
+		}
+	}
+	unset($min_num);
+	return dirname(dirname($min_file));
+}
+
+/**
  * {@internal Missing Short Description}}
  *
  * @since unknown
Index: wp-admin/includes/plugin-install.php
===================================================================
--- wp-admin/includes/plugin-install.php	(revision 9324)
+++ wp-admin/includes/plugin-install.php	(working copy)
@@ -752,15 +752,19 @@
 	}
 
 	apply_filters('install_feedback', __('Installing the plugin'));
+
+	//find base plugin directory
+	$plugin_working_dir = update_pluginfiles_base_dir($working_dir);
+
 	// Copy new version of plugin into place.
-	$result = copy_dir($working_dir, $plugins_dir);
+	$result = copy_dir($plugin_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) );
+	$filelist = array_keys( $wp_filesystem->dirlist($plugin_working_dir) );
 
 	// Remove working directory
 	$wp_filesystem->delete($working_dir, true);
@@ -847,15 +851,19 @@
 	}
 
 	apply_filters('install_feedback', __('Installing the plugin'));
+
+	//find base plugin directory
+	$plugin_working_dir = update_pluginfiles_base_dir($working_dir);
+	
 	// Copy new version of plugin into place.
-	$result = copy_dir($working_dir, $plugins_dir);
+	$result = copy_dir($plugin_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) );
+	$filelist = array_keys( $wp_filesystem->dirlist($plugin_working_dir) );
 
 	// Remove working directory
 	$wp_filesystem->delete($working_dir, true);
@@ -871,4 +879,4 @@
 	return  $folder . '/' . $pluginfiles[0];
 }
 
-?>
+?>
\ No newline at end of file
Index: wp-admin/includes/update.php
===================================================================
--- wp-admin/includes/update.php	(revision 9324)
+++ wp-admin/includes/update.php	(working copy)
@@ -173,15 +173,19 @@
 	}
 
 	apply_filters('update_feedback', __('Installing the latest version'));
+
+	//find base plugin directory
+	$plugin_working_dir = update_pluginfiles_base_dir($working_dir);
+
 	// Copy new version of plugin into place.
-	$result = copy_dir($working_dir, $plugins_dir);
+	$result = copy_dir($plugin_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) );
+	$filelist = array_keys( $wp_filesystem->dirlist($plugin_working_dir) );
 
 	// Remove working directory
 	$wp_filesystem->delete($working_dir, true);

