<?xml version="1.0" encoding="UTF-8"?>
<commit>
  <added type="array">
    <added>
      <filename>actionpack/lib/action_view/template_file.rb</filename>
    </added>
    <added>
      <filename>actionpack/lib/action_view/view_load_paths.rb</filename>
    </added>
    <added>
      <filename>actionpack/test/template/template_file_test.rb</filename>
    </added>
  </added>
  <modified type="array">
    <modified>
      <diff>@@ -426,8 +426,7 @@ module ActionMailer #:nodoc:
       end
 
       def template_root=(root)
-        write_inheritable_attribute(:template_root, root)
-        ActionView::TemplateFinder.process_view_paths(root)
+        write_inheritable_attribute(:template_root, ActionView::ViewLoadPaths.new(Array(root)))
       end
     end
 
@@ -547,7 +546,7 @@ module ActionMailer #:nodoc:
       end
 
       def initialize_template_class(assigns)
-        ActionView::Base.new([template_root], assigns, self)
+        ActionView::Base.new(template_root, assigns, self)
       end
 
       def sort_parts(parts, order = [])</diff>
      <filename>actionmailer/lib/action_mailer/base.rb</filename>
    </modified>
    <modified>
      <diff>@@ -942,13 +942,13 @@ end # uses_mocha
 class InheritableTemplateRootTest &lt; Test::Unit::TestCase
   def test_attr
     expected = &quot;#{File.dirname(__FILE__)}/fixtures/path.with.dots&quot;
-    assert_equal expected, FunkyPathMailer.template_root
+    assert_equal [expected], FunkyPathMailer.template_root.map(&amp;:to_s)
 
     sub = Class.new(FunkyPathMailer)
     sub.template_root = 'test/path'
 
-    assert_equal 'test/path', sub.template_root
-    assert_equal expected, FunkyPathMailer.template_root
+    assert_equal ['test/path'], sub.template_root.map(&amp;:to_s)
+    assert_equal [expected], FunkyPathMailer.template_root.map(&amp;:to_s)
   end
 end
 </diff>
      <filename>actionmailer/test/mail_service_test.rb</filename>
    </modified>
    <modified>
      <diff>@@ -1,5 +1,7 @@
 *Edge*
 
+* Replaced TemplateFinder abstraction with ViewLoadPaths [Josh Peek]
+
 * Added block-call style to link_to [Sam Stephenson/DHH]. Example:
 
     &lt;% link_to(@profile) do %&gt;</diff>
      <filename>actionpack/CHANGELOG</filename>
    </modified>
    <modified>
      <diff>@@ -421,8 +421,7 @@ module ActionController #:nodoc:
       end
 
       def view_paths=(value)
-        @view_paths = value
-        ActionView::TemplateFinder.process_view_paths(value)
+        @view_paths = ActionView::ViewLoadPaths.new(Array(value)) if value
       end
 
       # Adds a view_path to the front of the view_paths array.
@@ -434,8 +433,7 @@ module ActionController #:nodoc:
       #
       def prepend_view_path(path)
         @view_paths = superclass.view_paths.dup if @view_paths.nil?
-        view_paths.unshift(*path)
-        ActionView::TemplateFinder.process_view_paths(path)
+        @view_paths.unshift(*path)
       end
 
       # Adds a view_path to the end of the view_paths array.
@@ -447,8 +445,7 @@ module ActionController #:nodoc:
       #
       def append_view_path(path)
         @view_paths = superclass.view_paths.dup if @view_paths.nil?
-        view_paths.push(*path)
-        ActionView::TemplateFinder.process_view_paths(path)
+        @view_paths.push(*path)
       end
 
       # Replace sensitive parameter data from the request log.
@@ -640,11 +637,11 @@ module ActionController #:nodoc:
 
       # View load paths for controller.
       def view_paths
-        @template.finder.view_paths
+        @template.view_paths
       end
 
       def view_paths=(value)
-        @template.finder.view_paths = value  # Mutex needed
+        @template.view_paths = ViewLoadPaths.new(value)
       end
 
       # Adds a view_path to the front of the view_paths array.
@@ -654,7 +651,7 @@ module ActionController #:nodoc:
       #   self.prepend_view_path([&quot;views/default&quot;, &quot;views/custom&quot;])
       #
       def prepend_view_path(path)
-        @template.finder.prepend_view_path(path)  # Mutex needed
+        @template.view_paths.unshift(*path)
       end
 
       # Adds a view_path to the end of the view_paths array.
@@ -664,7 +661,7 @@ module ActionController #:nodoc:
       #   self.append_view_path([&quot;views/default&quot;, &quot;views/custom&quot;])
       #
       def append_view_path(path)
-        @template.finder.append_view_path(path)  # Mutex needed
+        @template.view_paths.push(*path)
       end
 
     protected
@@ -1225,7 +1222,7 @@ module ActionController #:nodoc:
       end
 
       def template_exists?(template_name = default_template_name)
-        @template.finder.file_exists?(template_name)
+        @template.file_exists?(template_name)
       end
 
       def template_public?(template_name = default_template_name)
@@ -1233,9 +1230,8 @@ module ActionController #:nodoc:
       end
 
       def template_exempt_from_layout?(template_name = default_template_name)
-        extension = @template &amp;&amp; @template.finder.pick_template_extension(template_name)
-        name_with_extension = !template_name.include?('.') &amp;&amp; extension ? &quot;#{template_name}.#{extension}&quot; : template_name
-        @@exempt_from_layout.any? { |ext| name_with_extension =~ ext }
+        template_name = @template.send(:template_file_from_name, template_name) if @template
+        @@exempt_from_layout.any? { |ext| template_name.to_s =~ ext }
       end
 
       def default_template_name(action_name = self.action_name)</diff>
      <filename>actionpack/lib/action_controller/base.rb</filename>
    </modified>
    <modified>
      <diff>@@ -134,7 +134,7 @@ module ActionController
       run_callbacks :prepare_dispatch
 
       Routing::Routes.reload
-      ActionView::TemplateFinder.reload! unless ActionView::Base.cache_template_loading
+      ActionController::Base.view_paths.reload!
     end
 
     # Cleanup the application by clearing out loaded classes so they can</diff>
      <filename>actionpack/lib/action_controller/dispatcher.rb</filename>
    </modified>
    <modified>
      <diff>@@ -304,7 +304,7 @@ module ActionController #:nodoc:
       end
 
       def layout_directory?(layout_name)
-        @template.finder.find_template_extension_from_handler(File.join('layouts', layout_name))
+        @template.view_paths.find_template_file_for_path(&quot;#{File.join('layouts', layout_name)}.#{@template.template_format}.erb&quot;) ? true : false
       end
   end
 end</diff>
      <filename>actionpack/lib/action_controller/layout.rb</filename>
    </modified>
    <modified>
      <diff>@@ -22,7 +22,8 @@
 #++
 
 require 'action_view/template_handlers'
-require 'action_view/template_finder'
+require 'action_view/template_file'
+require 'action_view/view_load_paths'
 require 'action_view/template'
 require 'action_view/partial_template'
 require 'action_view/inline_template'</diff>
      <filename>actionpack/lib/action_view.rb</filename>
    </modified>
    <modified>
      <diff>@@ -1,17 +1,17 @@
 module ActionView #:nodoc:
   class ActionViewError &lt; StandardError #:nodoc:
   end
-  
+
   class MissingTemplate &lt; ActionViewError #:nodoc:
   end
 
-  # Action View templates can be written in three ways. If the template file has a &lt;tt&gt;.erb&lt;/tt&gt; (or &lt;tt&gt;.rhtml&lt;/tt&gt;) extension then it uses a mixture of ERb 
-  # (included in Ruby) and HTML. If the template file has a &lt;tt&gt;.builder&lt;/tt&gt; (or &lt;tt&gt;.rxml&lt;/tt&gt;) extension then Jim Weirich's Builder::XmlMarkup library is used. 
+  # Action View templates can be written in three ways. If the template file has a &lt;tt&gt;.erb&lt;/tt&gt; (or &lt;tt&gt;.rhtml&lt;/tt&gt;) extension then it uses a mixture of ERb
+  # (included in Ruby) and HTML. If the template file has a &lt;tt&gt;.builder&lt;/tt&gt; (or &lt;tt&gt;.rxml&lt;/tt&gt;) extension then Jim Weirich's Builder::XmlMarkup library is used.
   # If the template file has a &lt;tt&gt;.rjs&lt;/tt&gt; extension then it will use ActionView::Helpers::PrototypeHelper::JavaScriptGenerator.
-  # 
+  #
   # = ERb
-  # 
-  # You trigger ERb by using embeddings such as &lt;% %&gt;, &lt;% -%&gt;, and &lt;%= %&gt;. The &lt;%= %&gt; tag set is used when you want output. Consider the 
+  #
+  # You trigger ERb by using embeddings such as &lt;% %&gt;, &lt;% -%&gt;, and &lt;%= %&gt;. The &lt;%= %&gt; tag set is used when you want output. Consider the
   # following loop for names:
   #
   #   &lt;b&gt;Names of all the people&lt;/b&gt;
@@ -51,7 +51,7 @@ module ActionView #:nodoc:
   #   &lt;title&gt;&lt;%= @page_title %&gt;&lt;/title&gt;
   #
   # == Passing local variables to sub templates
-  # 
+  #
   # You can pass local variables to sub templates by using a hash with the variable names as keys and the objects as values:
   #
   #   &lt;%= render &quot;shared/header&quot;, { :headline =&gt; &quot;Welcome&quot;, :person =&gt; person } %&gt;
@@ -77,8 +77,8 @@ module ActionView #:nodoc:
   #
   # == Builder
   #
-  # Builder templates are a more programmatic alternative to ERb. They are especially useful for generating XML content. An XmlMarkup object 
-  # named +xml+ is automatically made available to templates with a &lt;tt&gt;.builder&lt;/tt&gt; extension. 
+  # Builder templates are a more programmatic alternative to ERb. They are especially useful for generating XML content. An XmlMarkup object
+  # named +xml+ is automatically made available to templates with a &lt;tt&gt;.builder&lt;/tt&gt; extension.
   #
   # Here are some basic examples:
   #
@@ -87,7 +87,7 @@ module ActionView #:nodoc:
   #   xml.a(&quot;A Link&quot;, &quot;href&quot;=&gt;&quot;http://onestepback.org&quot;) # =&gt; &lt;a href=&quot;http://onestepback.org&quot;&gt;A Link&lt;/a&gt;
   #   xml.target(&quot;name&quot;=&gt;&quot;compile&quot;, &quot;option&quot;=&gt;&quot;fast&quot;)   # =&gt; &lt;target option=&quot;fast&quot; name=&quot;compile&quot;\&gt;
   #                                                     # NOTE: order of attributes is not specified.
-  # 
+  #
   # Any method with a block will be treated as an XML markup tag with nested markup in the block. For example, the following:
   #
   #   xml.div {
@@ -111,7 +111,7 @@ module ActionView #:nodoc:
   #       xml.description &quot;Basecamp: Recent items&quot;
   #       xml.language &quot;en-us&quot;
   #       xml.ttl &quot;40&quot;
-  # 
+  #
   #       for item in @recent_items
   #         xml.item do
   #           xml.title(item_title(item))
@@ -119,7 +119,7 @@ module ActionView #:nodoc:
   #           xml.pubDate(item_pubDate(item))
   #           xml.guid(@person.firm.account.url + @recent_items.url(item))
   #           xml.link(@person.firm.account.url + @recent_items.url(item))
-  #       
+  #
   #           xml.tag!(&quot;dc:creator&quot;, item.author_name) if item_has_creator?(item)
   #         end
   #       end
@@ -130,12 +130,12 @@ module ActionView #:nodoc:
   #
   # == JavaScriptGenerator
   #
-  # JavaScriptGenerator templates end in &lt;tt&gt;.rjs&lt;/tt&gt;. Unlike conventional templates which are used to 
-  # render the results of an action, these templates generate instructions on how to modify an already rendered page. This makes it easy to 
-  # modify multiple elements on your page in one declarative Ajax response. Actions with these templates are called in the background with Ajax 
+  # JavaScriptGenerator templates end in &lt;tt&gt;.rjs&lt;/tt&gt;. Unlike conventional templates which are used to
+  # render the results of an action, these templates generate instructions on how to modify an already rendered page. This makes it easy to
+  # modify multiple elements on your page in one declarative Ajax response. Actions with these templates are called in the background with Ajax
   # and make updates to the page where the request originated from.
-  # 
-  # An instance of the JavaScriptGenerator object named +page+ is automatically made available to your template, which is implicitly wrapped in an ActionView::Helpers::PrototypeHelper#update_page block. 
+  #
+  # An instance of the JavaScriptGenerator object named +page+ is automatically made available to your template, which is implicitly wrapped in an ActionView::Helpers::PrototypeHelper#update_page block.
   #
   # When an &lt;tt&gt;.rjs&lt;/tt&gt; action is called with +link_to_remote+, the generated JavaScript is automatically evaluated.  Example:
   #
@@ -145,15 +145,14 @@ module ActionView #:nodoc:
   #
   #   page.replace_html  'sidebar', :partial =&gt; 'sidebar'
   #   page.remove        &quot;person-#{@person.id}&quot;
-  #   page.visual_effect :highlight, 'user-list' 
+  #   page.visual_effect :highlight, 'user-list'
   #
   # This refreshes the sidebar, removes a person element and highlights the user list.
-  # 
+  #
   # See the ActionView::Helpers::PrototypeHelper::GeneratorMethods documentation for more details.
   class Base
     include ERB::Util
 
-    attr_reader   :finder
     attr_accessor :base_path, :assigns, :template_extension, :first_render
     attr_accessor :controller
 
@@ -170,14 +169,14 @@ module ActionView #:nodoc:
     # Specify whether file modification times should be checked to see if a template needs recompilation
     @@cache_template_loading = false
     cattr_accessor :cache_template_loading
-    
+
     def self.cache_template_extensions=(*args)
       ActiveSupport::Deprecation.warn(&quot;config.action_view.cache_template_extensions option has been deprecated and has no affect. &quot; &lt;&lt;
                                        &quot;Please remove it from your config files.&quot;, caller)
     end
 
     # Specify whether RJS responses should be wrapped in a try/catch block
-    # that alert()s the caught exception (and then re-raises it). 
+    # that alert()s the caught exception (and then re-raises it).
     @@debug_rjs = false
     cattr_accessor :debug_rjs
 
@@ -185,7 +184,7 @@ module ActionView #:nodoc:
 
     delegate :request_forgery_protection_token, :template, :params, :session, :cookies, :response, :headers,
              :flash, :logger, :action_name, :controller_name, :to =&gt; :controller
- 
+
     module CompiledTemplates #:nodoc:
       # holds compiled template code
     end
@@ -221,11 +220,17 @@ module ActionView #:nodoc:
       @assigns = assigns_for_first_render
       @assigns_added = nil
       @controller = controller
-      @finder = TemplateFinder.new(self, view_paths)
+      self.view_paths = view_paths
     end
 
-    # Renders the template present at &lt;tt&gt;template_path&lt;/tt&gt;. If &lt;tt&gt;use_full_path&lt;/tt&gt; is set to true, 
-    # it's relative to the view_paths array, otherwise it's absolute. The hash in &lt;tt&gt;local_assigns&lt;/tt&gt; 
+    attr_reader :view_paths
+
+    def view_paths=(paths)
+      @view_paths = ViewLoadPaths.new(Array(paths))
+    end
+
+    # Renders the template present at &lt;tt&gt;template_path&lt;/tt&gt;. If &lt;tt&gt;use_full_path&lt;/tt&gt; is set to true,
+    # it's relative to the view_paths array, otherwise it's absolute. The hash in &lt;tt&gt;local_assigns&lt;/tt&gt;
     # is made available as local variables.
     def render_file(template_path, use_full_path = true, local_assigns = {}) #:nodoc:
       if defined?(ActionMailer) &amp;&amp; defined?(ActionMailer::Base) &amp;&amp; controller.is_a?(ActionMailer::Base) &amp;&amp; !template_path.include?(&quot;/&quot;)
@@ -240,11 +245,11 @@ If you are rendering a subtemplate, you must now use controller-like partial syn
   render :partial =&gt; 'signup' # no mailer_name necessary
         END_ERROR
       end
-      
+
       Template.new(self, template_path, use_full_path, local_assigns).render_template
     end
-    
-    # Renders the template present at &lt;tt&gt;template_path&lt;/tt&gt; (relative to the view_paths array). 
+
+    # Renders the template present at &lt;tt&gt;template_path&lt;/tt&gt; (relative to the view_paths array).
     # The hash in &lt;tt&gt;local_assigns&lt;/tt&gt; is made available as local variables.
     def render(options = {}, local_assigns = {}, &amp;block) #:nodoc:
       if options.is_a?(String)
@@ -257,7 +262,7 @@ If you are rendering a subtemplate, you must now use controller-like partial syn
 
         if partial_layout = options.delete(:layout)
           if block_given?
-            wrap_content_for_layout capture(&amp;block) do 
+            wrap_content_for_layout capture(&amp;block) do
               concat(render(options.merge(:partial =&gt; partial_layout)))
             end
           else
@@ -314,6 +319,10 @@ If you are rendering a subtemplate, you must now use controller-like partial syn
       end
     end
 
+    def file_exists?(template_path)
+      view_paths.template_exists?(template_file_from_name(template_path))
+    end
+
     private
       def wrap_content_for_layout(content)
         original_content_for_layout, @content_for_layout = @content_for_layout, content
@@ -334,11 +343,43 @@ If you are rendering a subtemplate, you must now use controller-like partial syn
       def assign_variables_from_controller
         @assigns.each { |key, value| instance_variable_set(&quot;@#{key}&quot;, value) }
       end
-      
+
       def execute(template)
         send(template.method, template.locals) do |*names|
           instance_variable_get &quot;@content_for_#{names.first || 'layout'}&quot;
-        end        
+        end
+      end
+
+      def template_file_from_name(template_name)
+        template_name = TemplateFile.from_path(template_name)
+        pick_template_extension(template_name) unless template_name.extension
+      end
+
+      # Gets the extension for an existing template with the given template_path.
+      # Returns the format with the extension if that template exists.
+      #
+      #   pick_template_extension('users/show')
+      #   # =&gt; 'html.erb'
+      #
+      #   pick_template_extension('users/legacy')
+      #   # =&gt; &quot;rhtml&quot;
+      #
+      def pick_template_extension(file)
+        if f = self.view_paths.find_template_file_for_path(file.dup_with_extension(template_format)) || file_from_first_render(file)
+          f
+        elsif template_format == :js &amp;&amp; f = self.view_paths.find_template_file_for_path(file.dup_with_extension(:html))
+          @template_format = :html
+          f
+        else
+          nil
+        end
+      end
+
+      # Determine the template extension from the &lt;tt&gt;@first_render&lt;/tt&gt; filename
+      def file_from_first_render(file)
+        if extension = File.basename(@first_render.to_s)[/^[^.]+\.(.+)$/, 1]
+          file.dup_with_extension(extension)
+        end
       end
   end
 end</diff>
      <filename>actionpack/lib/action_view/base.rb</filename>
    </modified>
    <modified>
      <diff>@@ -1,20 +1,17 @@
 module ActionView #:nodoc:
   class InlineTemplate &lt; Template #:nodoc:
-    
     def initialize(view, source, locals = {}, type = nil)
       @view = view
-      @finder = @view.finder
-      
+
       @source = source
       @extension = type
       @locals = locals || {}
-      
+
       @handler = self.class.handler_class_for_extension(@extension).new(@view)
     end
-    
+
     def method_key
       @source
     end
-    
   end
 end</diff>
      <filename>actionpack/lib/action_view/inline_template.rb</filename>
    </modified>
    <modified>
      <diff>@@ -16,7 +16,7 @@ module ActionView #:nodoc:
     end
 
     def render
-      ActionController::Base.benchmark(&quot;Rendered #{@path}&quot;, Logger::DEBUG, false) do
+      ActionController::Base.benchmark(&quot;Rendered #{@path.path_without_format_and_extension}&quot;, Logger::DEBUG, false) do
         @handler.render(self)
       end
     end</diff>
      <filename>actionpack/lib/action_view/partial_template.rb</filename>
    </modified>
    <modified>
      <diff>@@ -3,15 +3,15 @@ module ActionView #:nodoc:
     extend TemplateHandlers
 
     attr_accessor :locals
-    attr_reader :handler, :path, :extension, :filename, :path_without_extension, :method
+    attr_reader :handler, :path, :extension, :filename, :method
 
     def initialize(view, path, use_full_path, locals = {})
       @view = view
-      @finder = @view.finder
+      @paths = view.view_paths
 
-      # Clear the forward slash at the beginning if exists
-      @path = use_full_path ? path.sub(/^\//, '') : path
-      @view.first_render ||= @path
+      @original_path = path
+      @path = TemplateFile.from_path(path, !use_full_path)
+      @view.first_render ||= @path.to_s
       @source = nil # Don't read the source until we know that it is required
       set_extension_and_file_name(use_full_path)
 
@@ -36,6 +36,10 @@ module ActionView #:nodoc:
       @handler.render(self)
     end
 
+    def path_without_extension
+      @path.path_without_extension
+    end
+
     def source
       @source ||= File.read(self.filename)
     end
@@ -45,7 +49,7 @@ module ActionView #:nodoc:
     end
 
     def base_path_for_exception
-      @finder.find_base_path_for(&quot;#{@path_without_extension}.#{@extension}&quot;) || @finder.view_paths.first
+      (@paths.find_load_path_for_path(@path) || @paths.first).to_s
     end
 
     def prepare!
@@ -60,28 +64,30 @@ module ActionView #:nodoc:
 
     private
       def set_extension_and_file_name(use_full_path)
-        @path_without_extension, @extension = @finder.path_and_extension(@path)
+        @extension = @path.extension
+
         if use_full_path
-          if @extension
-            @filename = @finder.pick_template(@path_without_extension, @extension)
-          else
-            @extension = @finder.pick_template_extension(@path).to_s
-            raise_missing_template_exception unless @extension
-
-            @filename = @finder.pick_template(@path, @extension)
-            @extension = @extension.gsub(/^.+\./, '') # strip off any formats
+          unless @extension
+            @path = @view.send(:template_file_from_name, @path)
+            raise_missing_template_exception unless @path
+            @extension = @path.extension
+          end
+
+          if @path = @paths.find_template_file_for_path(path)
+            @filename = @path.full_path
+            @extension = @path.extension
           end
         else
-          @filename = @path
+          @filename = @path.full_path
         end
 
         raise_missing_template_exception if @filename.blank?
       end
 
       def raise_missing_template_exception
-        full_template_path = @path.include?('.') ? @path : &quot;#{@path}.#{@view.template_format}.erb&quot;
-        display_paths = @finder.view_paths.join(':')
-        template_type = (@path =~ /layouts/i) ? 'layout' : 'template'
+        full_template_path = @original_path.include?('.') ? @original_path : &quot;#{@original_path}.#{@view.template_format}.erb&quot;
+        display_paths = @paths.join(':')
+        template_type = (@original_path =~ /layouts/i) ? 'layout' : 'template'
         raise(MissingTemplate, &quot;Missing #{template_type} #{full_template_path} in view path #{display_paths}&quot;)
       end
   end</diff>
      <filename>actionpack/lib/action_view/template.rb</filename>
    </modified>
    <modified>
      <diff>@@ -28,7 +28,6 @@ module ActionView #:nodoc:
     # return the rendered template as a string.
     def register_template_handler(extension, klass)
       @@template_handlers[extension.to_sym] = klass
-      ActionView::TemplateFinder.reload!
     end
 
     def template_handler_extensions</diff>
      <filename>actionpack/lib/action_view/template_handlers.rb</filename>
    </modified>
    <modified>
      <diff>@@ -1,30 +1,30 @@
 require 'abstract_unit'
 
 class ViewLoadPathsTest &lt; Test::Unit::TestCase
-  
   LOAD_PATH_ROOT = File.join(File.dirname(__FILE__), '..', 'fixtures')
 
-  ActionController::Base.view_paths = [ LOAD_PATH_ROOT ]
+  ActionController::Base.view_paths = [LOAD_PATH_ROOT]
 
   class TestController &lt; ActionController::Base
     def self.controller_path() &quot;test&quot; end
     def rescue_action(e) raise end
-    
+
     before_filter :add_view_path, :only =&gt; :hello_world_at_request_time
-    
+
     def hello_world() end
     def hello_world_at_request_time() render(:action =&gt; 'hello_world') end
+
     private
-    def add_view_path
-      prepend_view_path &quot;#{LOAD_PATH_ROOT}/override&quot;
-    end
+      def add_view_path
+        prepend_view_path &quot;#{LOAD_PATH_ROOT}/override&quot;
+      end
   end
-  
+
   class Test::SubController &lt; ActionController::Base
     layout 'test/sub'
     def hello_world; render(:template =&gt; 'test/hello_world'); end
   end
-  
+
   def setup
     TestController.view_paths = nil
 
@@ -41,68 +41,80 @@ class ViewLoadPathsTest &lt; Test::Unit::TestCase
     @last_message = nil
     ActiveSupport::Deprecation.behavior = Proc.new { |message, callback| @last_message = message }
   end
-  
+
   def teardown
     ActiveSupport::Deprecation.behavior = @old_behavior
   end
-  
+
   def test_template_load_path_was_set_correctly
-    assert_equal [ LOAD_PATH_ROOT ], @controller.view_paths
+    assert_equal [ LOAD_PATH_ROOT ], @controller.view_paths.map(&amp;:to_s)
   end
-  
+
   def test_controller_appends_view_path_correctly
     @controller.append_view_path 'foo'
-    assert_equal [LOAD_PATH_ROOT, 'foo'], @controller.view_paths
-    
+    assert_equal [LOAD_PATH_ROOT, 'foo'], @controller.view_paths.map(&amp;:to_s)
+
     @controller.append_view_path(%w(bar baz))
-    assert_equal [LOAD_PATH_ROOT, 'foo', 'bar', 'baz'], @controller.view_paths
+    assert_equal [LOAD_PATH_ROOT, 'foo', 'bar', 'baz'], @controller.view_paths.map(&amp;:to_s)
+
+    @controller.append_view_path(LOAD_PATH_ROOT)
+    assert_equal ['foo', 'bar', 'baz', LOAD_PATH_ROOT], @controller.view_paths.map(&amp;:to_s)
+
+    @controller.append_view_path([LOAD_PATH_ROOT])
+    assert_equal ['foo', 'bar', 'baz', LOAD_PATH_ROOT], @controller.view_paths.map(&amp;:to_s)
   end
-  
+
   def test_controller_prepends_view_path_correctly
     @controller.prepend_view_path 'baz'
-    assert_equal ['baz', LOAD_PATH_ROOT], @controller.view_paths
-    
+    assert_equal ['baz', LOAD_PATH_ROOT], @controller.view_paths.map(&amp;:to_s)
+
     @controller.prepend_view_path(%w(foo bar))
-    assert_equal ['foo', 'bar', 'baz', LOAD_PATH_ROOT], @controller.view_paths
+    assert_equal ['foo', 'bar', 'baz', LOAD_PATH_ROOT], @controller.view_paths.map(&amp;:to_s)
+
+    @controller.prepend_view_path(LOAD_PATH_ROOT)
+    assert_equal [LOAD_PATH_ROOT, 'foo', 'bar', 'baz'], @controller.view_paths.map(&amp;:to_s)
+
+    @controller.prepend_view_path([LOAD_PATH_ROOT])
+    assert_equal [LOAD_PATH_ROOT, 'foo', 'bar', 'baz'], @controller.view_paths.map(&amp;:to_s)
   end
-  
+
   def test_template_appends_view_path_correctly
     @controller.instance_variable_set :@template, ActionView::Base.new(TestController.view_paths, {}, @controller)
     class_view_paths = TestController.view_paths
 
     @controller.append_view_path 'foo'
-    assert_equal [LOAD_PATH_ROOT, 'foo'], @controller.view_paths
-    
+    assert_equal [LOAD_PATH_ROOT, 'foo'], @controller.view_paths.map(&amp;:to_s)
+
     @controller.append_view_path(%w(bar baz))
-    assert_equal [LOAD_PATH_ROOT, 'foo', 'bar', 'baz'], @controller.view_paths
+    assert_equal [LOAD_PATH_ROOT, 'foo', 'bar', 'baz'], @controller.view_paths.map(&amp;:to_s)
     assert_equal class_view_paths, TestController.view_paths
   end
-  
+
   def test_template_prepends_view_path_correctly
     @controller.instance_variable_set :@template, ActionView::Base.new(TestController.view_paths, {}, @controller)
     class_view_paths = TestController.view_paths
-    
+
     @controller.prepend_view_path 'baz'
-    assert_equal ['baz', LOAD_PATH_ROOT], @controller.view_paths
-    
+    assert_equal ['baz', LOAD_PATH_ROOT], @controller.view_paths.map(&amp;:to_s)
+
     @controller.prepend_view_path(%w(foo bar))
-    assert_equal ['foo', 'bar', 'baz', LOAD_PATH_ROOT], @controller.view_paths
+    assert_equal ['foo', 'bar', 'baz', LOAD_PATH_ROOT], @controller.view_paths.map(&amp;:to_s)
     assert_equal class_view_paths, TestController.view_paths
   end
-  
+
   def test_view_paths
     get :hello_world
     assert_response :success
     assert_equal &quot;Hello world!&quot;, @response.body
   end
-  
+
   def test_view_paths_override
     TestController.prepend_view_path &quot;#{LOAD_PATH_ROOT}/override&quot;
     get :hello_world
     assert_response :success
     assert_equal &quot;Hello overridden world!&quot;, @response.body
   end
-  
+
   def test_view_paths_override_for_layouts_in_controllers_with_a_module
     @controller = Test::SubController.new
     Test::SubController.view_paths = [ &quot;#{LOAD_PATH_ROOT}/override&quot;, LOAD_PATH_ROOT, &quot;#{LOAD_PATH_ROOT}/override2&quot; ]
@@ -110,31 +122,44 @@ class ViewLoadPathsTest &lt; Test::Unit::TestCase
     assert_response :success
     assert_equal &quot;layout: Hello overridden world!&quot;, @response.body
   end
-  
+
   def test_view_paths_override_at_request_time
     get :hello_world_at_request_time
     assert_response :success
     assert_equal &quot;Hello overridden world!&quot;, @response.body
   end
-  
+
   def test_inheritance
     original_load_paths = ActionController::Base.view_paths
-    
+
     self.class.class_eval %{
       class A &lt; ActionController::Base; end
       class B &lt; A; end
       class C &lt; ActionController::Base; end
     }
-  
-    A.view_paths = [ 'a/path' ]
-    
-    assert_equal [ 'a/path' ],        A.view_paths
-    assert_equal A.view_paths,   B.view_paths
+
+    A.view_paths = ['a/path']
+
+    assert_equal ['a/path'], A.view_paths.map(&amp;:to_s)
+    assert_equal A.view_paths, B.view_paths
     assert_equal original_load_paths, C.view_paths
-    
+
     C.view_paths = []
     assert_nothing_raised { C.view_paths &lt;&lt; 'c/path' }
-    assert_equal ['c/path'], C.view_paths
+    assert_equal ['c/path'], C.view_paths.map(&amp;:to_s)
+  end
+
+  def test_find_template_file_for_path
+    assert_equal &quot;test/hello_world.erb&quot;, @controller.view_paths.find_template_file_for_path(&quot;test/hello_world.erb&quot;).to_s
+    assert_equal &quot;test/hello.builder&quot;, @controller.view_paths.find_template_file_for_path(&quot;test/hello.builder&quot;).to_s
+    assert_equal nil, @controller.view_paths.find_template_file_for_path(&quot;test/missing.erb&quot;)
+  end
+
+  def test_view_paths_find_template_file_for_path
+    assert_equal &quot;test/formatted_html_erb.html.erb&quot;, @controller.view_paths.find_template_file_for_path(&quot;test/formatted_html_erb.html&quot;).to_s
+    assert_equal &quot;test/formatted_xml_erb.xml.erb&quot;, @controller.view_paths.find_template_file_for_path(&quot;test/formatted_xml_erb.xml&quot;).to_s
+    assert_equal &quot;test/hello_world.erb&quot;, @controller.view_paths.find_template_file_for_path(&quot;test/hello_world.html&quot;).to_s
+    assert_equal &quot;test/hello_world.erb&quot;, @controller.view_paths.find_template_file_for_path(&quot;test/hello_world.xml&quot;).to_s
+    assert_equal nil, @controller.view_paths.find_template_file_for_path(&quot;test/missing.html&quot;)
   end
-  
 end</diff>
      <filename>actionpack/test/controller/view_paths_test.rb</filename>
    </modified>
    <modified>
      <diff>@@ -2,60 +2,57 @@ require 'abstract_unit'
 
 class TemplateObjectTest &lt; Test::Unit::TestCase
   LOAD_PATH_ROOT = File.join(File.dirname(__FILE__), '..', 'fixtures')
-  ActionView::TemplateFinder.process_view_paths(LOAD_PATH_ROOT)
-  
+
   class TemplateTest &lt; Test::Unit::TestCase
     def setup
       @view = ActionView::Base.new(LOAD_PATH_ROOT)
       @path = &quot;test/hello_world.erb&quot;
     end
-    
+
     def test_should_create_valid_template
       template = ActionView::Template.new(@view, @path, true)
-      
+
       assert_kind_of ActionView::TemplateHandlers::ERB, template.handler
-      assert_equal &quot;test/hello_world.erb&quot;, template.path
+      assert_equal &quot;test/hello_world.erb&quot;, template.path.to_s
       assert_nil template.instance_variable_get(:&quot;@source&quot;)
       assert_equal &quot;erb&quot;, template.extension
     end
-    
+
     uses_mocha 'Template preparation tests' do
-      
       def test_should_prepare_template_properly
         template = ActionView::Template.new(@view, @path, true)
         view = template.instance_variable_get(:&quot;@view&quot;)
-        
+
         view.expects(:evaluate_assigns)
         template.handler.expects(:compile_template).with(template)
         view.expects(:method_names).returns({})
-        
+
         template.prepare!
       end
-      
     end
   end
-  
+
   class PartialTemplateTest &lt; Test::Unit::TestCase
     def setup
       @view = ActionView::Base.new(LOAD_PATH_ROOT)
       @path = &quot;test/partial_only&quot;
     end
-    
+
     def test_should_create_valid_partial_template
       template = ActionView::PartialTemplate.new(@view, @path, nil)
-      
-      assert_equal &quot;test/_partial_only&quot;, template.path
+
+      assert_equal &quot;test/_partial_only&quot;, template.path.path_without_format_and_extension
       assert_equal :partial_only, template.variable_name
-      
+
       assert template.locals.has_key?(:object)
       assert template.locals.has_key?(:partial_only)
     end
-    
+
     def test_partial_with_errors
       template = ActionView::PartialTemplate.new(@view, 'test/raise', nil)
       assert_raise(ActionView::TemplateError) { template.render_template }
     end
-    
+
     uses_mocha 'Partial template preparation tests' do
       def test_should_prepare_on_initialization
         ActionView::PartialTemplate.any_instance.expects(:prepare!)
@@ -63,7 +60,7 @@ class TemplateObjectTest &lt; Test::Unit::TestCase
       end
     end
   end
-  
+
   class PartialTemplateFallbackTest &lt; Test::Unit::TestCase
     def setup
       @view = ActionView::Base.new(LOAD_PATH_ROOT)
@@ -72,7 +69,7 @@ class TemplateObjectTest &lt; Test::Unit::TestCase
 
     def test_default
       template = ActionView::PartialTemplate.new(@view, @path, nil)
-      assert_equal 'test/_layout_for_partial', template.path
+      assert_equal 'test/_layout_for_partial', template.path.path_without_format_and_extension
       assert_equal 'erb', template.extension
       assert_equal :html, @view.template_format
     end
@@ -80,7 +77,7 @@ class TemplateObjectTest &lt; Test::Unit::TestCase
     def test_js
       @view.template_format = :js
       template = ActionView::PartialTemplate.new(@view, @path, nil)
-      assert_equal 'test/_layout_for_partial', template.path
+      assert_equal 'test/_layout_for_partial', template.path.path_without_format_and_extension
       assert_equal 'erb', template.extension
       assert_equal :html, @view.template_format
     end</diff>
      <filename>actionpack/test/template/template_object_test.rb</filename>
    </modified>
  </modified>
  <removed type="array">
    <removed>
      <filename>actionpack/lib/action_view/template_finder.rb</filename>
    </removed>
    <removed>
      <filename>actionpack/test/template/template_finder_test.rb</filename>
    </removed>
  </removed>
  <parents type="array">
    <parent>
      <id>6ffe32160e16398d347e6bcd396ad843ba68e52a</id>
    </parent>
  </parents>
  <author>
    <name>Joshua Peek</name>
    <email>josh@joshpeek.com</email>
  </author>
  <url>http://github.com/rails/rails/commit/bec4b69a3b65c3696edad3c880207e8c476b0937</url>
  <id>bec4b69a3b65c3696edad3c880207e8c476b0937</id>
  <committed-date>2008-06-17T19:21:07-07:00</committed-date>
  <authored-date>2008-06-15T19:22:27-07:00</authored-date>
  <message>Replaced TemplateFinder abstraction with ViewLoadPaths</message>
  <tree>ef655dd59b5b46eb38f7f868c7e8c182635abe65</tree>
  <committer>
    <name>Joshua Peek</name>
    <email>josh@joshpeek.com</email>
  </committer>
</commit>
