Index: wp-includes/class-simplepie.php
===================================================================
--- wp-includes/class-simplepie.php	(revision 15821)
+++ wp-includes/class-simplepie.php	(working copy)
@@ -9105,60 +9105,6 @@
 		return $iri->get_iri();
 	}
 
-	function remove_dot_segments($input)
-	{
-		$output = '';
-		while (strpos($input, './') !== false || strpos($input, '/.') !== false || $input === '.' || $input === '..')
-		{
-			// A: If the input buffer begins with a prefix of "../" or "./", then remove that prefix from the input buffer; otherwise,
-			if (strpos($input, '../') === 0)
-			{
-				$input = substr($input, 3);
-			}
-			elseif (strpos($input, './') === 0)
-			{
-				$input = substr($input, 2);
-			}
-			// B: if the input buffer begins with a prefix of "/./" or "/.", where "." is a complete path segment, then replace that prefix with "/" in the input buffer; otherwise,
-			elseif (strpos($input, '/./') === 0)
-			{
-				$input = substr_replace($input, '/', 0, 3);
-			}
-			elseif ($input === '/.')
-			{
-				$input = '/';
-			}
-			// C: if the input buffer begins with a prefix of "/../" or "/..", where ".." is a complete path segment, then replace that prefix with "/" in the input buffer and remove the last segment and its preceding "/" (if any) from the output buffer; otherwise,
-			elseif (strpos($input, '/../') === 0)
-			{
-				$input = substr_replace($input, '/', 0, 4);
-				$output = substr_replace($output, '', strrpos($output, '/'));
-			}
-			elseif ($input === '/..')
-			{
-				$input = '/';
-				$output = substr_replace($output, '', strrpos($output, '/'));
-			}
-			// D: if the input buffer consists only of "." or "..", then remove that from the input buffer; otherwise,
-			elseif ($input === '.' || $input === '..')
-			{
-				$input = '';
-			}
-			// E: move the first path segment in the input buffer to the end of the output buffer, including the initial "/" character (if any) and any subsequent characters up to, but not including, the next "/" character or the end of the input buffer
-			elseif (($pos = strpos($input, '/', 1)) !== false)
-			{
-				$output .= substr($input, 0, $pos);
-				$input = substr_replace($input, '', 0, $pos);
-			}
-			else
-			{
-				$output .= $input;
-				$input = '';
-			}
-		}
-		return $output . $input;
-	}
-
 	function get_element($realname, $string)
 	{
 		$return = array();
@@ -11768,67 +11714,6 @@
 	}
 
 	/**
-	 * Remove dot segments from a path
-	 *
-	 * @access private
-	 * @param string $input
-	 * @return string
-	 */
-	function remove_dot_segments($input)
-	{
-		$output = '';
-		while (strpos($input, './') !== false || strpos($input, '/.') !== false || $input === '.' || $input === '..')
-		{
-			// A: If the input buffer begins with a prefix of "../" or "./", then remove that prefix from the input buffer; otherwise,
-			if (strpos($input, '../') === 0)
-			{
-				$input = substr($input, 3);
-			}
-			elseif (strpos($input, './') === 0)
-			{
-				$input = substr($input, 2);
-			}
-			// B: if the input buffer begins with a prefix of "/./" or "/.", where "." is a complete path segment, then replace that prefix with "/" in the input buffer; otherwise,
-			elseif (strpos($input, '/./') === 0)
-			{
-				$input = substr_replace($input, '/', 0, 3);
-			}
-			elseif ($input === '/.')
-			{
-				$input = '/';
-			}
-			// C: if the input buffer begins with a prefix of "/../" or "/..", where ".." is a complete path segment, then replace that prefix with "/" in the input buffer and remove the last segment and its preceding "/" (if any) from the output buffer; otherwise,
-			elseif (strpos($input, '/../') === 0)
-			{
-				$input = substr_replace($input, '/', 0, 4);
-				$output = substr_replace($output, '', strrpos($output, '/'));
-			}
-			elseif ($input === '/..')
-			{
-				$input = '/';
-				$output = substr_replace($output, '', strrpos($output, '/'));
-			}
-			// D: if the input buffer consists only of "." or "..", then remove that from the input buffer; otherwise,
-			elseif ($input === '.' || $input === '..')
-			{
-				$input = '';
-			}
-			// E: move the first path segment in the input buffer to the end of the output buffer, including the initial "/" character (if any) and any subsequent characters up to, but not including, the next "/" character or the end of the input buffer
-			elseif (($pos = strpos($input, '/', 1)) !== false)
-			{
-				$output .= substr($input, 0, $pos);
-				$input = substr_replace($input, '', 0, $pos);
-			}
-			else
-			{
-				$output .= $input;
-				$input = '';
-			}
-		}
-		return $output . $input;
-	}
-
-	/**
 	 * Replace invalid character with percent encoding
 	 *
 	 * @access private
@@ -12106,9 +11991,9 @@
 		else
 		{
 			$this->path = $this->replace_invalid_with_pct_encoding($path, 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~!$&\'()*+,;=@/');
-			if ($this->scheme !== null)
+			if ($this->scheme !== null && function_exists( 'remove_dot_segments' ))
 			{
-				$this->path = $this->remove_dot_segments($this->path);
+				$this->path = remove_dot_segments($this->path);
 			}
 			$this->valid[__FUNCTION__] = true;
 			return true;
Index: wp-includes/formatting.php
===================================================================
--- wp-includes/formatting.php	(revision 15821)
+++ wp-includes/formatting.php	(working copy)
@@ -716,6 +716,67 @@
 }
 
 /**
+ * Remove dot segments from a path
+ *
+ * @access private
+ * @param string $input
+ * @return string
+ */
+function remove_dot_segments($input)
+{
+	$output = '';
+	while (strpos($input, './') !== false || strpos($input, '/.') !== false || $input === '.' || $input === '..')
+	{
+		// A: If the input buffer begins with a prefix of "../" or "./", then remove that prefix from the input buffer; otherwise,
+		if (strpos($input, '../') === 0)
+		{
+			$input = substr($input, 3);
+		}
+		elseif (strpos($input, './') === 0)
+		{
+			$input = substr($input, 2);
+		}
+		// B: if the input buffer begins with a prefix of "/./" or "/.", where "." is a complete path segment, then replace that prefix with "/" in the input buffer; otherwise,
+		elseif (strpos($input, '/./') === 0)
+		{
+			$input = substr_replace($input, '/', 0, 3);
+		}
+		elseif ($input === '/.')
+		{
+			$input = '/';
+		}
+		// C: if the input buffer begins with a prefix of "/../" or "/..", where ".." is a complete path segment, then replace that prefix with "/" in the input buffer and remove the last segment and its preceding "/" (if any) from the output buffer; otherwise,
+		elseif (strpos($input, '/../') === 0)
+		{
+			$input = substr_replace($input, '/', 0, 4);
+			$output = substr_replace($output, '', strrpos($output, '/'));
+		}
+		elseif ($input === '/..')
+		{
+			$input = '/';
+			$output = substr_replace($output, '', strrpos($output, '/'));
+		}
+		// D: if the input buffer consists only of "." or "..", then remove that from the input buffer; otherwise,
+		elseif ($input === '.' || $input === '..')
+		{
+			$input = '';
+		}
+		// E: move the first path segment in the input buffer to the end of the output buffer, including the initial "/" character (if any) and any subsequent characters up to, but not including, the next "/" character or the end of the input buffer
+		elseif (($pos = strpos($input, '/', 1)) !== false)
+		{
+			$output .= substr($input, 0, $pos);
+			$input = substr_replace($input, '', 0, $pos);
+		}
+		else
+		{
+			$output .= $input;
+			$input = '';
+		}
+	}
+	return $output . $input;
+}
+
+/**
  * Sanitize username stripping out unsafe characters.
  *
  * If $strict is true, only alphanumeric characters (as well as _, space, ., -,
Index: wp-includes/general-template.php
===================================================================
--- wp-includes/general-template.php	(revision 15821)
+++ wp-includes/general-template.php	(working copy)
@@ -116,16 +116,34 @@
  * @param string $slug The slug name for the generic template.
  * @param string $name The name of the specialised template.
  */
-function get_template_part( $slug, $name = null ) {
-	do_action( "get_template_part_{$slug}", $slug, $name );
+function get_template_part( $slug, $name = null, $directory = null ) {
+	if ( false !== strpos( $slug, DIRECTORY_SEPARATOR ) ) {
+		$original_slug = $slug;
+		$slug = substr( strrchr( $slug, DIRECTORY_SEPARATOR ), 1 );
+		if ( empty( $directory ) ) {
+			$directory = substr( $original_slug, 0, strrpos( $original_slug, DIRECTORY_SEPARATOR ) );
+		}
+	}
+	$slug = sanitize_file_name( $slug );
 
+	$directory = rtrim( remove_dot_segments( $directory ), DIRECTORY_SEPARATOR );
+
+	do_action( "get_template_part_{$slug}", $slug, $name, $directory );
+
 	$templates = array();
+	if ( ! empty( $directory ) ) {
+		if ( isset($name) )
+			$templates[] = $directory . DIRECTORY_SEPARATOR . "{$slug}-{$name}.php";
+
+		$templates[] = $directory . DIRECTORY_SEPARATOR . "{$slug}.php";
+	}
+
 	if ( isset($name) )
 		$templates[] = "{$slug}-{$name}.php";
 
 	$templates[] = "{$slug}.php";
 
-	locate_template($templates, true, false);
+	locate_template( $templates, true, false );
 }
 
 /**
@@ -654,7 +672,7 @@
 	if ( ! is_post_type_archive() )
 		return;
 
-	
+
 	$post_type_obj = get_post_type_object( get_query_var( 'post_type' ) );
 	$title = apply_filters('post_type_archive_title', $post_type_obj->labels->name );
 
@@ -663,7 +681,7 @@
 	else
 		return $title;
 }
-	
+
 /**
  * Display or retrieve page title for category archive.
  *
