Index: wp-admin/css/themes.css
===================================================================
--- wp-admin/css/themes.css	(revision 27988)
+++ wp-admin/css/themes.css	(working copy)
@@ -216,7 +216,8 @@
  * Displays a theme update notice
  * when an update is available.
  */
-.theme-browser .theme .theme-update {
+.theme-browser .theme .theme-update,
+.theme-browser .theme .theme-installed {
 	background: #d54e21;
 	background: rgba(213, 78, 33, 0.95);
 	color: #fff;
@@ -234,7 +235,8 @@
 	overflow: hidden;
 }
 
-.theme-browser .theme .theme-update:before {
+.theme-browser .theme .theme-update:before,
+.theme-browser .theme .theme-installed:before {
 	content: '\f463';
 	display: inline-block;
 	font: normal 20px/1 'dashicons';
@@ -1074,6 +1076,25 @@
   16.2 - Install Themes
 ------------------------------------------------------------------------------*/
 
+/* Already installed theme */
+.theme-browser .theme.is-installed {
+	cursor: default;
+}
+.theme-browser .theme .theme-installed {
+	background: #0074a2;
+}
+.theme-browser .theme .theme-installed:before {
+	content: '\f147';
+}
+.theme-browser .theme.is-installed .theme-actions,
+.theme-browser.rendered .theme.is-installed .more-details {
+	display: none !important;
+}
+.theme-browser.rendered .theme.is-installed:hover .theme-screenshot img,
+.theme-browser.rendered .theme.is-installed:focus .theme-screenshot img {
+	opacity: 1 !important;
+}
+
 .theme-navigation {
 	background: #fff;
 	-webkit-box-shadow: 0 1px 1px 0 rgba(0,0,0,.1);
Index: wp-admin/js/theme.js
===================================================================
--- wp-admin/js/theme.js	(revision 27988)
+++ wp-admin/js/theme.js	(working copy)
@@ -22,7 +22,7 @@
 	// Adds attributes to the default data coming through the .org themes api
 	// Map `id` to `slug` for shared code
 	initialize: function() {
-		var install, preview;
+		var install, installed;
 
 		// Install url for the theme
 		// using the install nonce
@@ -35,18 +35,14 @@
 		// Build the url query
 		install = themes.data.settings.updateURI + '?' + $.param( install );
 
-		// Preview url for the theme
-		preview = {
-			tab: 'theme-information',
-			theme: this.get( 'slug' )
-		};
+		// If theme is already installed, set an attribute.
+		if ( _.indexOf( themes.data.installedThemes, this.get( 'slug' ) ) !== -1 ) {
+			this.set({ installed: true });
+		}
 
-		preview = themes.data.settings.installURI + '?' + $.param( preview );
-
 		// Set the attributes
 		this.set({
-			installURI: install,
-			previewURI: preview,
+			installURI: ( this.get( 'slug' ) ) ? install : false,
 			// slug is for installation, id is for existing.
 			id: this.get( 'slug' ) || this.get( 'id' )
 		});
@@ -391,6 +387,11 @@
 		if ( this.model.get( 'displayAuthor' ) ) {
 			this.$el.addClass( 'display-author' );
 		}
+
+		if ( this.model.get( 'installed' ) ) {
+			this.$el.addClass( 'is-installed' );
+			this.$el.unbind();
+		}
 	},
 
 	// Adds a class to the currently active theme
@@ -451,6 +452,11 @@
 			return this.touchDrag = false;
 		}
 
+		// Allow direct link path to installing a theme.
+		if ( $( event.target ).hasClass( 'button-primary' ) ) {
+			return;
+		}
+
 		// 'enter' and 'space' keys expand the details view when a theme is :focused
 		if ( event.type === 'keydown' && ( event.which !== 13 && event.which !== 32 ) ) {
 			return;
@@ -494,6 +500,7 @@
 
 			// If we have no more themes, bail.
 			if ( _.isUndefined( self.current ) ) {
+				self.options.parent.parent.trigger( 'theme:end' );
 				return self.current = current;
 			}
 
@@ -505,6 +512,7 @@
 			// Render and append.
 			preview.render();
 			$( 'div.wrap' ).append( preview.el );
+			$( '.next-theme' ).focus();
 		})
 		.listenTo( preview, 'theme:previous', function() {
 
@@ -532,6 +540,7 @@
 			// Render and append.
 			preview.render();
 			$( 'div.wrap' ).append( preview.el );
+			$( '.previous-theme' ).focus();
 		});
 	}
 });
@@ -882,7 +891,8 @@
 		// Loop through the themes and setup each theme view
 		self.instance.each( function( theme ) {
 			self.theme = new themes.view.Theme({
-				model: theme
+				model: theme,
+				parent: self
 			});
 
 			// Render the views...
@@ -1224,6 +1234,9 @@
 		// Get the themes by sending Ajax POST request to api.wordpress.org/themes
 		// or searching the local cache
 		this.collection.query( request );
+
+		// Set route
+		themes.router.navigate( themes.router.baseUrl( '?search=' + value ), { replace: true } );
 	}, 300 )
 });
 
@@ -1329,7 +1342,7 @@
 	},
 
 	sort: function( sort ) {
-		$( '#theme-search-input' ).val( '' );
+		this.clearSearch();
 
 		$( '.theme-section, .theme-filter' ).removeClass( this.activeClass );
 		$( '[data-sort="' + sort + '"]' ).addClass( this.activeClass );
@@ -1450,6 +1463,9 @@
 			return this.addFilter();
 		}
 
+		this.clearSearch();
+
+		themes.router.navigate( themes.router.baseUrl( '' ) );
 		$( 'body' ).toggleClass( 'more-filters-opened' );
 	},
 
@@ -1474,6 +1490,10 @@
 
 	backToFilters: function() {
 		$( 'body' ).removeClass( 'filters-applied' );
+	},
+
+	clearSearch: function() {
+		$( '#theme-search-input').val( '' );
 	}
 });
 
Index: wp-admin/theme-install.php
===================================================================
--- wp-admin/theme-install.php	(revision 27988)
+++ wp-admin/theme-install.php	(working copy)
@@ -33,6 +33,13 @@
 	'new'      => __( 'Newest Themes' ),
 );
 
+$installed_themes = search_theme_directories();
+foreach ( $installed_themes as $k => $v ) {
+	if ( false !== strpos( $k, '/' ) ) {
+		unset( $installed_themes[ $k ] );
+	}
+}
+
 wp_localize_script( 'theme', '_wpThemeSettings', array(
 	'themes'   => false,
 	'settings' => array(
@@ -51,6 +58,7 @@
 		'back'   => __( 'Back' ),
 		'error'  => ( 'There was a problem trying to load the themes. Please, try again.' ), // @todo improve
 	),
+	'installedThemes' => array_keys( $installed_themes ),
 	'browse' => array(
 		'sections' => $sections,
 	),
@@ -190,13 +198,19 @@
 		<a class="button button-primary" href="{{ data.installURI }}"><?php esc_html_e( 'Install' ); ?></a>
 		<a class="button button-secondary preview install-theme-preview" href="#"><?php esc_html_e( 'Preview' ); ?></a>
 	</div>
+
+	<# if ( data.installed ) { #>
+		<div class="theme-installed"><?php _e( 'Already Installed' ); ?></div>
+	<# } #>
 </script>
 
 <script id="tmpl-theme-preview" type="text/template">
 	<div class="wp-full-overlay-sidebar">
 		<div class="wp-full-overlay-header">
 			<a href="#" class="close-full-overlay button-secondary"><?php _e( 'Close' ); ?></a>
-			<a href="{{ data.installURI }}" class="button button-primary theme-install"><?php _e( 'Install' ); ?></a>
+		<# if ( data.installed ) { #>
+			<a href="#" class="button button-primary theme-install disabled"><?php _e( 'Installed' ); ?></a>
+		<# } #>
 		</div>
 		<div class="wp-full-overlay-sidebar-content">
 			<div class="install-theme-info">
