Index: wp-includes/theme.php
===================================================================
--- wp-includes/theme.php	(revision 19969)
+++ wp-includes/theme.php	(working copy)
@@ -178,68 +178,96 @@
  * @since 1.5.0
  *
  * @param string $theme_file Theme file path.
+ * @param bool $markup Optional. If the returned data should have HTML markup applied. Defaults to true.
+ * @param bool $translate Optional. If the returned data should be translated. Defaults to false.
+ * 	Note this is unlike the $translate parameter for get_plugin_data(), which defaults to true.
  * @return array Theme data.
  */
-function get_theme_data( $theme_file ) {
+function get_theme_data( $theme_file, $markup = true, $translate = false ) {
 	$default_headers = array(
 		'Name' => 'Theme Name',
 		'URI' => 'Theme URI',
 		'Description' => 'Description',
 		'Author' => 'Author',
 		'AuthorURI' => 'Author URI',
+		'TextDomain' => 'Text Domain',
+		'DomainPath' => 'Domain Path',
 		'Version' => 'Version',
 		'Template' => 'Template',
 		'Status' => 'Status',
 		'Tags' => 'Tags'
 		);
 
-	$themes_allowed_tags = array(
-		'a' => array(
-			'href' => array(),'title' => array()
-			),
-		'abbr' => array(
-			'title' => array()
-			),
-		'acronym' => array(
-			'title' => array()
-			),
-		'code' => array(),
-		'em' => array(),
-		'strong' => array()
-	);
-
 	$theme_data = get_file_data( $theme_file, $default_headers, 'theme' );
 
-	$theme_data['Name'] = $theme_data['Title'] = wp_kses( $theme_data['Name'], $themes_allowed_tags );
+	$theme_data = _get_theme_data_markup_translate( $theme_file, $theme_data, $markup, $translate );
 
-	$theme_data['URI'] = esc_url( $theme_data['URI'] );
+	return $theme_data;
+}
 
-	$theme_data['Description'] = wptexturize( wp_kses( $theme_data['Description'], $themes_allowed_tags ) );
+/**
+ * Sanitizes theme data, optionally adds markup, optionally translates.
+ *
+ * @since 3.4.0
+ * @access private
+ * @see get_theme_data()
+ */
+function _get_theme_data_markup_translate( $theme_file, $theme_data, $markup = true, $translate = true ) {
 
-	$theme_data['AuthorURI'] = esc_url( $theme_data['AuthorURI'] );
+	// Translate fields
+	if ( $translate && $textdomain = $theme_data['TextDomain'] ) {
+		if ( $theme_data['DomainPath'] )
+			load_theme_textdomain( $textdomain, dirname( $theme_file ) . $theme_data['DomainPath'] );
+		else
+			load_theme_textdomain( $textdomain, dirname( $theme_file ) );
 
-	$theme_data['Template'] = wp_kses( $theme_data['Template'], $themes_allowed_tags );
+		foreach ( array( 'Name', 'URI', 'Description', 'Author', 'AuthorURI', 'Version' ) as $field )
+			$theme_data[ $field ] = translate( $theme_data[ $field ], $textdomain );
+	}
 
-	$theme_data['Version'] = wp_kses( $theme_data['Version'], $themes_allowed_tags );
+	$allowed_tags = $allowed_tags_in_links = array(
+		'abbr'    => array( 'title' => array() ),
+		'acronym' => array( 'title' => array() ),
+		'code'    => array(),
+		'em'      => array(),
+		'strong'  => array(),
+	);
+	$allowed_tags['a'] = array( 'href' => array(), 'title' => array() );
 
-	if ( $theme_data['Status'] == '' )
+	// Sanitized all displayed data.
+
+	// Author and Name are marked up inside <a> tags. Don't allow these.
+	$theme_data['Author']      = wp_kses( $theme_data['Author'], $allowed_tags_in_links );
+	$theme_data['AuthorName']  = $theme_data['Author'];
+
+	$theme_data['Name']        = wp_kses( $theme_data['Name'],   $allowed_tags_in_links );
+	$theme_data['Title']       = $theme_data['Name'];
+
+	$theme_data['Description'] = wp_kses( $theme_data['Description'], $allowed_tags );
+	$theme_data['Version']     = wp_kses( $theme_data['Version'],     $allowed_tags );
+	$theme_data['Template']    = wp_kses( $theme_data['Template'],    $allowed_tags );
+	$theme_data['Status']      = wp_kses( $theme_data['Status'],      $allowed_tags );
+
+	if ( ! $theme_data['Status'] )
 		$theme_data['Status'] = 'publish';
+
+	$theme_data['URI']         = esc_url( $theme_data['URI'] );
+	$theme_data['AuthorURI']   = esc_url( $theme_data['AuthorURI'] );
+
+	if ( $theme_data['Tags'] )
+		$theme_data['Tags'] = array_map( 'trim', explode( ',', strip_tags( $theme_data['Tags'] ) ) );
 	else
-		$theme_data['Status'] = wp_kses( $theme_data['Status'], $themes_allowed_tags );
-
-	if ( $theme_data['Tags'] == '' )
 		$theme_data['Tags'] = array();
-	else
-		$theme_data['Tags'] = array_map( 'trim', explode( ',', wp_kses( $theme_data['Tags'], array() ) ) );
 
-	if ( $theme_data['Author'] == '' ) {
-		$theme_data['Author'] = $theme_data['AuthorName'] = __('Anonymous');
-	} else {
-		$theme_data['AuthorName'] = wp_kses( $theme_data['Author'], $themes_allowed_tags );
-		if ( empty( $theme_data['AuthorURI'] ) ) {
-			$theme_data['Author'] = $theme_data['AuthorName'];
+	// Apply markup
+	if ( $markup ) {
+		$theme_data['Description'] = wptexturize( $theme_data['Description'] );
+
+		if ( $theme_data['Author'] ) {
+			if ( $theme_data['AuthorURI'] )
+				$theme_data['Author'] = sprintf( '<a href="%1$s" title="%2$s">%3$s</a>', $theme_data['AuthorURI'], esc_attr__( 'Visit author homepage' ), $theme_data['Author'] );
 		} else {
-			$theme_data['Author'] = sprintf( '<a href="%1$s" title="%2$s">%3$s</a>', $theme_data['AuthorURI'], esc_attr__( 'Visit author homepage' ), $theme_data['AuthorName'] );
+			$theme_data['Author'] = $theme_data['AuthorName'] = __( 'Anonymous' );
 		}
 	}
 
@@ -287,7 +315,7 @@
 
 		$name        = $theme_data['Name'];
 		$title       = $theme_data['Title'];
-		$description = wptexturize($theme_data['Description']);
+		$description = $theme_data['Description'];
 		$version     = $theme_data['Version'];
 		$author      = $theme_data['Author'];
 		$template    = $theme_data['Template'];
@@ -437,6 +465,8 @@
 			'Tags' => $theme_data['Tags'],
 			'Theme Root' => $theme_root,
 			'Theme Root URI' => str_replace( WP_CONTENT_DIR, content_url(), $theme_root ),
+			'TextDomain' => $theme_data['TextDomain'],
+			'DomainPath' => $theme_data['DomainPath'],
 		);
 	}
 
Index: wp-content/themes/twentyten/style.css
===================================================================
--- wp-content/themes/twentyten/style.css	(revision 19962)
+++ wp-content/themes/twentyten/style.css	(working copy)
@@ -7,6 +7,8 @@
 License: GNU General Public License
 License URI: license.txt
 Tags: black, blue, white, two-columns, fixed-width, custom-header, custom-background, threaded-comments, sticky-post, translation-ready, microformats, rtl-language-support, editor-style, custom-menu
+Text Domain: twentyten
+Domain Path: /languages
 */
 
 
Index: wp-admin/includes/plugin.php
===================================================================
--- wp-admin/includes/plugin.php	(revision 19965)
+++ wp-admin/includes/plugin.php	(working copy)
@@ -65,8 +65,9 @@
  * @since 1.5.0
  *
  * @param string $plugin_file Path to the plugin file
- * @param bool $markup If the returned data should have HTML markup applied
- * @param bool $translate If the returned data should be translated
+ * @param bool $markup Optional. If the returned data should have HTML markup applied. Defaults to true.
+ * @param bool $translate Optional. If the returned data should be translated. Defaults to true.
+ * 	Note this is unlike the $translate parameter for get_theme_data(), which defaults to false.
  * @return array See above for description.
  */
 function get_plugin_data( $plugin_file, $markup = true, $translate = true ) {
@@ -88,30 +89,32 @@
 	$plugin_data = get_file_data( $plugin_file, $default_headers, 'plugin' );
 
 	// Site Wide Only is the old header for Network
-	if ( empty( $plugin_data['Network'] ) && ! empty( $plugin_data['_sitewide'] ) ) {
+	if ( ! $plugin_data['Network'] && $plugin_data['_sitewide'] ) {
 		_deprecated_argument( __FUNCTION__, '3.0', sprintf( __( 'The <code>%1$s</code> plugin header is deprecated. Use <code>%2$s</code> instead.' ), 'Site Wide Only: true', 'Network: true' ) );
 		$plugin_data['Network'] = $plugin_data['_sitewide'];
 	}
 	$plugin_data['Network'] = ( 'true' == strtolower( $plugin_data['Network'] ) );
 	unset( $plugin_data['_sitewide'] );
 
-	//For backward compatibility by default Title is the same as Name.
-	$plugin_data['Title'] = $plugin_data['Name'];
+	// Sanitize, maybe markup, maybe translate
+	$plugin_data = _get_plugin_data_markup_translate( $plugin_file, $plugin_data, $markup, $translate );
 
-	if ( $markup || $translate )
-		$plugin_data = _get_plugin_data_markup_translate( $plugin_file, $plugin_data, $markup, $translate );
-	else
-		$plugin_data['AuthorName'] = $plugin_data['Author'];
-
 	return $plugin_data;
 }
 
-function _get_plugin_data_markup_translate($plugin_file, $plugin_data, $markup = true, $translate = true) {
+/**
+ * Sanitizes plugin data, optionally adds markup, optionally translates.
+ *
+ * @since 2.7.0
+ * @access private
+ * @see get_plugin_data()
+ */
+function _get_plugin_data_markup_translate( $plugin_file, $plugin_data, $markup = true, $translate = true ) {
 
-	//Translate fields
+	// Translate fields
 	if ( $translate ) {
 		if ( $textdomain = $plugin_data['TextDomain'] ) {
-			if ( ! empty( $plugin_data['DomainPath'] ) )
+			if ( $plugin_data['DomainPath'] )
 				load_plugin_textdomain( $textdomain, false, dirname( $plugin_file ) . $plugin_data['DomainPath'] );
 			else
 				load_plugin_textdomain( $textdomain, false, dirname( $plugin_file ) );
@@ -124,38 +127,44 @@
 		}
 	}
 
-	$plugins_allowedtags = array(
-		'a'       => array( 'href' => array(), 'title' => array() ),
+	$allowed_tags = $allowed_tags_in_links = array(
 		'abbr'    => array( 'title' => array() ),
 		'acronym' => array( 'title' => array() ),
 		'code'    => array(),
 		'em'      => array(),
 		'strong'  => array(),
 	);
+	$allowed_tags['a'] = array( 'href' => array(), 'title' => array() );
 
-	$plugin_data['AuthorName'] = $plugin_data['Author'] = wp_kses( $plugin_data['Author'], $plugins_allowedtags );
+	// Sanitized all displayed data.
 
-	//Apply Markup
+	// Author and Name are marked up inside <a> tags. Don't allow these.
+	$plugin_data['Author']      = wp_kses( $plugin_data['Author'], $allowed_tags_in_links );
+	$plugin_data['AuthorName']  = $plugin_data['Author'];
+
+	$plugin_data['Name']        = wp_kses( $plugin_data['Name'],   $allowed_tags_in_links );
+	$plugin_data['Title']       = $plugin_data['Name'];
+
+	$plugin_data['Description'] = wp_kses( $plugin_data['Description'], $allowed_tags );
+	$plugin_data['Version']     = wp_kses( $plugin_data['Version'],     $allowed_tags );
+
+	$plugin_data['PluginURI']   = esc_url( $plugin_data['PluginURI'] );
+	$plugin_data['AuthorURI']   = esc_url( $plugin_data['AuthorURI'] );
+
+	// Apply markup
 	if ( $markup ) {
-		if ( ! empty($plugin_data['PluginURI']) && ! empty($plugin_data['Name']) )
+		if ( $plugin_data['PluginURI'] && $plugin_data['Name'] )
 			$plugin_data['Title'] = '<a href="' . $plugin_data['PluginURI'] . '" title="' . esc_attr__( 'Visit plugin homepage' ) . '">' . $plugin_data['Name'] . '</a>';
-		else
-			$plugin_data['Title'] = $plugin_data['Name'];
 
-		if ( ! empty($plugin_data['AuthorURI']) && ! empty($plugin_data['Author']) )
+		if ( $plugin_data['AuthorURI'] && $plugin_data['Author'] )
 			$plugin_data['Author'] = '<a href="' . $plugin_data['AuthorURI'] . '" title="' . esc_attr__( 'Visit author homepage' ) . '">' . $plugin_data['Author'] . '</a>';
 
 		$plugin_data['Description'] = wptexturize( $plugin_data['Description'] );
-		if ( ! empty($plugin_data['Author']) )
-			$plugin_data['Description'] .= ' <cite>' . sprintf( __('By %s'), $plugin_data['Author'] ) . '.</cite>';
+
+		if ( $plugin_data['Author'] )
+			$plugin_data['Description'] .= ' <cite>' . sprintf( __('By %s.'), $plugin_data['Author'] ) . '</cite>';
 	}
 
-	// Sanitize all displayed data. Author and AuthorName sanitized above.
-	$plugin_data['Title']       = wp_kses( $plugin_data['Title'],       $plugins_allowedtags );
-	$plugin_data['Version']     = wp_kses( $plugin_data['Version'],     $plugins_allowedtags );
-	$plugin_data['Description'] = wp_kses( $plugin_data['Description'], $plugins_allowedtags );
-	$plugin_data['Name']        = wp_kses( $plugin_data['Name'],        $plugins_allowedtags );
-
 	return $plugin_data;
 }
 
Index: wp-admin/includes/file.php
===================================================================
--- wp-admin/includes/file.php	(revision 19962)
+++ wp-admin/includes/file.php	(working copy)
@@ -61,8 +61,24 @@
 	}
 	elseif ( file_exists( $file ) && is_file( $file ) ) {
 		$template_data = implode( '', file( $file ) );
-		if ( preg_match( '|Template Name:(.*)$|mi', $template_data, $name ))
-			return sprintf( __( '%s Page Template' ), _cleanup_header_comment($name[1]) );
+		if ( preg_match( '|Template Name:(.*)$|mi', $template_data, $name ) ) {
+			$themes = get_themes();
+			$theme = get_current_theme();
+			if ( in_array( $file, $themes[ $theme ]['Template Files'] ) ) {
+				$textdomain = $themes[ $theme ]['TextDomain'];
+			} else {
+				foreach ( $themes as $theme ) {
+					if ( ! in_array( $file, $theme['Template Files'] ) )
+						continue;
+					$textdomain = $theme['TextDomain'];
+					break;
+				}
+			}
+			$page_template = _cleanup_header_comment( $name[1] );
+			if ( $textdomain )
+				$page_template = translate( $page_template, $textdomain );
+			return sprintf( __( '%s Page Template' ), $page_template );
+		}
 	}
 
 	return basename( $file );
Index: wp-admin/includes/theme.php
===================================================================
--- wp-admin/includes/theme.php	(revision 19962)
+++ wp-admin/includes/theme.php	(working copy)
@@ -177,6 +177,7 @@
 	$themes = get_themes();
 	$theme = get_current_theme();
 	$templates = $themes[$theme]['Template Files'];
+	$textdomain = $themes[$theme]['TextDomain'];
 	$page_templates = array();
 
 	if ( is_array( $templates ) ) {
@@ -194,13 +195,16 @@
 
 			$template_data = implode( '', file( $template ));
 
-			$name = '';
 			if ( preg_match( '|Template Name:(.*)$|mi', $template_data, $name ) )
-				$name = _cleanup_header_comment($name[1]);
+				$name = trim( _cleanup_header_comment( $name[1] ) );
+			else
+				continue;
 
-			if ( !empty( $name ) ) {
-				$page_templates[trim( $name )] = $basename;
-			}
+			if ( $textdomain )
+				$name = translate( $name, $textdomain );
+
+			if ( $name )
+				$page_templates[ $name ] = $basename;
 		}
 	}
 
Index: wp-admin/includes/class-wp-plugins-list-table.php
===================================================================
--- wp-admin/includes/class-wp-plugins-list-table.php	(revision 19962)
+++ wp-admin/includes/class-wp-plugins-list-table.php	(working copy)
@@ -345,7 +345,7 @@
 				$description = '<p><strong>' . $dropins[ $plugin_file ][0] . ' <span class="attention">' . __('Inactive:') . '</span></strong> ' . sprintf( __( 'Requires <code>%s</code> in <code>wp-config.php</code>.' ), "define('" . $dropins[ $plugin_file ][1] . "', true);" ) . '</p>';
 			}
 			if ( $plugin_data['Description'] )
-				$description .= '<p>' . $plugin_data['Description'] . '</p>';
+				$description .= '<p>' . wptexturize( $plugin_data['Description'] ) . '</p>';
 		} else {
 			$is_active_for_network = is_plugin_active_for_network($plugin_file);
 			if ( $screen->is_network )
@@ -389,7 +389,7 @@
 		$checkbox_id =  "checkbox_" . md5($plugin_data['Name']);
 		$checkbox = in_array( $status, array( 'mustuse', 'dropins' ) ) ? '' : "<input type='checkbox' name='checked[]' value='" . esc_attr( $plugin_file ) . "' id='" . $checkbox_id . "' /><label class='screen-reader-text' for='" . $checkbox_id . "' >" . __('Select') . " " . $plugin_data['Name'] . "</label>";
 		if ( 'dropins' != $context ) {
-			$description = '<p>' . ( $plugin_data['Description'] ? $plugin_data['Description'] : '&nbsp;' ) . '</p>';
+			$description = '<p>' . ( $plugin_data['Description'] ? wptexturize( $plugin_data['Description'] ) : '&nbsp;' ) . '</p>';
 			$plugin_name = $plugin_data['Name'];
 		}
 
Index: wp-admin/theme-editor.php
===================================================================
--- wp-admin/theme-editor.php	(revision 19962)
+++ wp-admin/theme-editor.php	(working copy)
@@ -44,7 +44,7 @@
 
 wp_reset_vars(array('action', 'redirect', 'profile', 'error', 'warning', 'a', 'file', 'theme', 'dir'));
 
-$themes = get_themes();
+$themes = get_themes(); // TODO I can haz translated data?
 
 if (empty($theme)) {
 	$theme = get_current_theme();
