Index: general-template.php
===================================================================
--- general-template.php	(revision 15382)
+++ general-template.php	(working copy)
@@ -19,19 +19,13 @@
  * @since 1.5.0
  * @uses do_action() Calls 'get_header' action.
  *
- * @param string $name The name of the specialised header.
+ * @param mixed $names The names of the specialised header templates (it can be a string, or an array of names to search for in priority order.).
  */
-function get_header( $name = null ) {
-	do_action( 'get_header', $name );
+function get_header( $names = array() ) {
+	do_action( 'get_header', $names );
 
-	$templates = array();
-	if ( isset($name) )
-		$templates[] = "header-{$name}.php";
-
-	$templates[] = "header.php";
-
 	// Backward compat code will be removed in a future release
-	if ('' == locate_template($templates, true))
+	if ('' == get_template_part( 'header', $names, true ) )
 		load_template( WPINC . '/theme-compat/header.php');
 }
 
@@ -48,19 +42,13 @@
  * @since 1.5.0
  * @uses do_action() Calls 'get_footer' action.
  *
- * @param string $name The name of the specialised footer.
+ * @param mixed $names The names of the specialised footer templates (it can be a string, or an array of names to search for in priority order.).
  */
-function get_footer( $name = null ) {
-	do_action( 'get_footer', $name );
+function get_footer( $names = null ) {
+	do_action( 'get_footer', $names );
 
-	$templates = array();
-	if ( isset($name) )
-		$templates[] = "footer-{$name}.php";
-
-	$templates[] = "footer.php";
-
 	// Backward compat code will be removed in a future release
-	if ('' == locate_template($templates, true))
+	if ('' == get_template_part( 'footer', $names, true ) )
 		load_template( WPINC . '/theme-compat/footer.php');
 }
 
@@ -77,19 +65,13 @@
  * @since 1.5.0
  * @uses do_action() Calls 'get_sidebar' action.
  *
- * @param string $name The name of the specialised sidebar.
+ * @param mixed $names The names of the specialised sidebar templates (it can be a string, or an array of names to search for in priority order.). 
  */
-function get_sidebar( $name = null ) {
-	do_action( 'get_sidebar', $name );
+function get_sidebar( $names = array() ) {
+	do_action( 'get_sidebar', $names );
 
-	$templates = array();
-	if ( isset($name) )
-		$templates[] = "sidebar-{$name}.php";
-
-	$templates[] = "sidebar.php";
-
 	// Backward compat code will be removed in a future release
-	if ('' == locate_template($templates, true))
+	if ('' == get_template_part( 'sidebar', $names ) )
 		load_template( WPINC . '/theme-compat/sidebar.php');
 }
 
@@ -111,21 +93,21 @@
  *
  * @uses locate_template()
  * @since 3.0.0
- * @uses do_action() Calls 'get_template_part{$slug}' action.
+ * @uses do_action() Calls 'get_template_part_{$slug}' action.
  *
  * @param string $slug The slug name for the generic template.
- * @param string $name The name of the specialised template.
+ * @param mixed $names The names of the specialised templates (it can be a string, or an array of names to search for in priority order.).
  */
-function get_template_part( $slug, $name = null ) {
-	do_action( "get_template_part_{$slug}", $slug, $name );
-
+function get_template_part( $slug, $names = array(), $require_once = false ) {
+	do_action( "get_template_part_{$slug}", $slug, $names );
+	
 	$templates = array();
-	if ( isset($name) )
+	foreach ( (array)$names as $name ) {
 		$templates[] = "{$slug}-{$name}.php";
-
+	}
 	$templates[] = "{$slug}.php";
 
-	locate_template($templates, true, false);
+	return locate_template($templates, true, $require_once);
 }
 
 /**
Index: theme.php
===================================================================
--- theme.php	(revision 15382)
+++ theme.php	(working copy)
@@ -1044,15 +1044,15 @@
 function locate_template($template_names, $load = false, $require_once = true ) {
 	if ( !is_array($template_names) )
 		return '';
-
+	
 	$located = '';
 	foreach ( $template_names as $template_name ) {
 		if ( !$template_name )
 			continue;
-		if ( file_exists(STYLESHEETPATH . '/' . $template_name)) {
+		if ( template_exists( STYLESHEETPATH, $template_name ) ) {
 			$located = STYLESHEETPATH . '/' . $template_name;
 			break;
-		} else if ( file_exists(TEMPLATEPATH . '/' . $template_name) ) {
+		} else if ( TEMPLATEPATH != STYLESHEETPATH && template_exists( TEMPLATEPATH, $template_name ) ) {
 			$located = TEMPLATEPATH . '/' . $template_name;
 			break;
 		}
@@ -1064,7 +1064,61 @@
 	return $located;
 }
 
+// Cache the parent and child theme's template paths
+add_action( 'init', 'wp_cache_template_paths', 1 );
+function wp_cache_template_paths() {
+	foreach ( array( STYLESHEETPATH, TEMPLATEPATH ) as $dir )
+		wp_cache_templates( $dir );
+	global $wp_templates;
+}
+
 /**
+ * Stores template files in the cache in global $wp_templates;
+ *
+ * @param string $dir Directory location to scan.
+ * @return bool
+ */
+function wp_cache_templates( $dir ) {
+	global $wp_templates;
+	if ( $handle = opendir( $dir ) ) {
+		$wp_templates[$dir] = 'dir';
+		while ( false !== ($file = readdir( $handle )) ) {
+			if ( is_file( $dir.'/'.$file ) && $file != '.' && $file != '..' )
+				$wp_templates[$dir.'/'.$file] = true;
+		}
+		closedir( $handle );
+		return true;
+	}
+	return false;
+}
+
+/**
+ * Checks in the cache if a template file exists locally.
+ *
+ * @param string $dir Directory location (template path).
+ * @param string $file Relative template file location.
+ * @return bool
+ */
+function template_exists( $dir, $file ) {
+	if ( '' == $file || '' == $dir )
+		return false;
+	
+	global $wp_templates;
+	$path = $dir.'/'.$file;
+	
+	if ( isset( $wp_templates[$path] ) )
+		return true;
+
+	//if its a file in a subdirectory, scan that dir
+	if ( false !== strpos( $file, '/' ) || false !== strpos( $file, '\\' ) ) {
+		$dir = dirname( $path );
+		if ( !isset( $wp_templates[$dir] ) )
+			wp_cache_templates( $dir );
+	}
+	return isset( $wp_templates[$path] );
+}
+
+/**
  * Require the template file with WordPress environment.
  *
  * The globals are set up for the template file to ensure that the WordPress
