<?xml version="1.0" encoding="UTF-8"?>
<commit>
  <added type="array"/>
  <modified type="array">
    <modified>
      <diff>@@ -1,9 +1,25 @@
-== master
+== 2.3.6, released 2008-10-26
 
-* Rename :prev_label to :previous_label for consistency. Old name still
-  functions, but it's deprecated
-* ActiveRecord 2.1: remove :include from count query when tables are not
-  referenced in :conditions
+* Rails 2.2 fix: stop using `extract_attribute_names_from_match` inernal AR method, it no longer exists
+
+== 2.3.5, released 2008-10-07
+
+* update the backported named_scope implementation for Rails versions older than 2.1
+* break out of scope of paginated_each() yielded block when used on named scopes
+* fix paginate(:from)
+
+== 2.3.4, released 2008-09-16
+
+* Removed gem dependency to Active Support (causes trouble with vendored rails).
+* Rails 2.1: fix a failing test and a deprecation warning.
+* Cope with scoped :select when counting.
+
+== 2.3.3, released 2008-08-29
+
+* Ensure that paginate_by_sql doesn't change the original SQL query.
+* RDoc love (now live at http://mislav.caboo.se/static/will_paginate/doc/)
+* Rename :prev_label to :previous_label for consistency. old name still functions but is deprecated
+* ActiveRecord 2.1: Remove :include option from count_all query when it's possible.
 
 == 2.3.2, released 2008-05-16
 </diff>
      <filename>CHANGELOG.rdoc</filename>
    </modified>
    <modified>
      <diff>@@ -87,7 +87,8 @@ contributions or just simply awesome ideas:
 Chris Wanstrath, Dr. Nic Williams, K. Adam Christensen, Mike Garey, Bence
 Golda, Matt Aimonetti, Charles Brian Quinn, Desi McAdam, James Coglan, Matijs
 van Zuijlen, Maria, Brendan Ribera, Todd Willey, Bryan Helmkamp, Jan Berkel,
-Lourens Naud&#233;, Rick Olson, Russell Norris, Piotr Usewicz, Chris Eppstein.
+Lourens Naud&#233;, Rick Olson, Russell Norris, Piotr Usewicz, Chris Eppstein,
+Denis Barushev, Ben Pickles.
 
 
 == Usable pagination in the UI</diff>
      <filename>README.rdoc</filename>
    </modified>
    <modified>
      <diff>@@ -104,7 +104,10 @@ module WillPaginate
         
         begin 
           collection = paginate(options)
-          total += collection.each(&amp;block).size
+          with_exclusive_scope(:find =&gt; {}) do
+            # using exclusive scope so that the block is yielded in scope-free context
+            total += collection.each(&amp;block).size
+          end
           options[:page] += 1
         end until collection.size &lt; collection.per_page
         
@@ -127,7 +130,7 @@ module WillPaginate
       # 
       def paginate_by_sql(sql, options)
         WillPaginate::Collection.create(*wp_parse_options(options)) do |pager|
-          query = sanitize_sql(sql)
+          query = sanitize_sql(sql.dup)
           original_query = query.dup
           # add limit, offset
           add_limit! query, :offset =&gt; pager.offset, :limit =&gt; pager.per_page
@@ -181,7 +184,20 @@ module WillPaginate
       # in the database. It relies on the ActiveRecord +count+ method.
       def wp_count(options, args, finder)
         excludees = [:count, :order, :limit, :offset, :readonly]
-        unless options[:select] and options[:select] =~ /^\s*DISTINCT\b/i
+        excludees &lt;&lt; :from unless ActiveRecord::Calculations::CALCULATIONS_OPTIONS.include?(:from)
+
+        # we may be in a model or an association proxy
+        klass = (@owner and @reflection) ? @reflection.klass : self
+
+        # Use :select from scope if it isn't already present.
+        options[:select] = scope(:find, :select) unless options[:select]
+
+        if options[:select] and options[:select] =~ /^\s*DISTINCT\b/i
+          # Remove quoting and check for table_name.*-like statement.
+          if options[:select].gsub('`', '') =~ /\w+\.\*/
+            options[:select] = &quot;DISTINCT #{klass.table_name}.#{klass.primary_key}&quot;
+          end
+        else
           excludees &lt;&lt; :select # only exclude the select param if it doesn't begin with DISTINCT
         end
 
@@ -191,10 +207,7 @@ module WillPaginate
         # merge the hash found in :count
         # this allows you to specify :select, :order, or anything else just for the count query
         count_options.update options[:count] if options[:count]
-        
-        # we may be in a model or an association proxy
-        klass = (@owner and @reflection) ? @reflection.klass : self
-        
+
         # forget about includes if they are irrelevant (Rails 2.1)
         if count_options[:include] and
             klass.private_methods.include?('references_eager_loaded_tables?') and
@@ -209,9 +222,9 @@ module WillPaginate
                   # scope_out adds a 'with_finder' method which acts like with_scope, if it's present
                   # then execute the count with the scoping provided by the with_finder
                   send(scoper, &amp;counter)
-                elsif match = /^find_(all_by|by)_([_a-zA-Z]\w*)$/.match(finder)
+                elsif finder =~ /^find_(all_by|by)_([_a-zA-Z]\w*)$/
                   # extract conditions from calls like &quot;paginate_by_foo_and_bar&quot;
-                  attribute_names = extract_attribute_names_from_match(match)
+                  attribute_names = $2.split('_and_')
                   conditions = construct_attributes_from_arguments(attribute_names, args)
                   with_scope(:find =&gt; { :conditions =&gt; conditions }, &amp;counter)
                 else</diff>
      <filename>lib/will_paginate/finder.rb</filename>
    </modified>
    <modified>
      <diff>@@ -1,27 +1,22 @@
-## stolen from: http://dev.rubyonrails.org/browser/trunk/activerecord/lib/active_record/named_scope.rb?rev=9084
-
 module WillPaginate
   # This is a feature backported from Rails 2.1 because of its usefullness not only with will_paginate,
   # but in other aspects when managing complex conditions that you want to be reusable.
   module NamedScope
     # All subclasses of ActiveRecord::Base have two named_scopes:
     # * &lt;tt&gt;all&lt;/tt&gt;, which is similar to a &lt;tt&gt;find(:all)&lt;/tt&gt; query, and
-    # * &lt;tt&gt;scoped&lt;/tt&gt;, which allows for the creation of anonymous scopes, on the fly:
-    #
-    #   Shirt.scoped(:conditions =&gt; {:color =&gt; 'red'}).scoped(:include =&gt; :washing_instructions)
+    # * &lt;tt&gt;scoped&lt;/tt&gt;, which allows for the creation of anonymous scopes, on the fly: &lt;tt&gt;Shirt.scoped(:conditions =&gt; {:color =&gt; 'red'}).scoped(:include =&gt; :washing_instructions)&lt;/tt&gt;
     #
     # These anonymous scopes tend to be useful when procedurally generating complex queries, where passing
     # intermediate values (scopes) around as first-class objects is convenient.
     def self.included(base)
       base.class_eval do
         extend ClassMethods
-        named_scope :all
         named_scope :scoped, lambda { |scope| scope }
       end
     end
 
     module ClassMethods
-      def scopes #:nodoc:
+      def scopes
         read_inheritable_attribute(:scopes) || write_inheritable_attribute(:scopes, {})
       end
 
@@ -46,7 +41,7 @@ module WillPaginate
       # Nested finds and calculations also work with these compositions: &lt;tt&gt;Shirt.red.dry_clean_only.count&lt;/tt&gt; returns the number of garments
       # for which these criteria obtain. Similarly with &lt;tt&gt;Shirt.red.dry_clean_only.average(:thread_count)&lt;/tt&gt;.
       #
-      # All scopes are available as class methods on the ActiveRecord descendent upon which the scopes were defined. But they are also available to
+      # All scopes are available as class methods on the ActiveRecord::Base descendent upon which the scopes were defined. But they are also available to
       # &lt;tt&gt;has_many&lt;/tt&gt; associations. If,
       #
       #   class Person &lt; ActiveRecord::Base
@@ -76,7 +71,20 @@ module WillPaginate
       #     end
       #   end
       #
+      #
+      # For testing complex named scopes, you can examine the scoping options using the
+      # &lt;tt&gt;proxy_options&lt;/tt&gt; method on the proxy itself.
+      #
+      #   class Shirt &lt; ActiveRecord::Base
+      #     named_scope :colored, lambda { |color|
+      #       { :conditions =&gt; { :color =&gt; color } }
+      #     }
+      #   end
+      #
+      #   expected_options = { :conditions =&gt; { :colored =&gt; 'red' } }
+      #   assert_equal expected_options, Shirt.colored('red').proxy_options
       def named_scope(name, options = {}, &amp;block)
+        name = name.to_sym
         scopes[name] = lambda do |parent_scope, *args|
           Scope.new(parent_scope, case options
             when Hash
@@ -93,9 +101,15 @@ module WillPaginate
       end
     end
     
-    class Scope #:nodoc:
+    class Scope
       attr_reader :proxy_scope, :proxy_options
-      [].methods.each { |m| delegate m, :to =&gt; :proxy_found unless m =~ /(^__|^nil\?|^send|class|extend|find|count|sum|average|maximum|minimum|paginate)/ }
+
+      [].methods.each do |m|
+        unless m =~ /(^__|^nil\?|^send|^object_id$|class|extend|^find$|count|sum|average|maximum|minimum|paginate|first|last|empty\?|respond_to\?)/
+          delegate m, :to =&gt; :proxy_found
+        end
+      end
+
       delegate :scopes, :with_scope, :to =&gt; :proxy_scope
 
       def initialize(proxy_scope, options, &amp;block)
@@ -108,6 +122,30 @@ module WillPaginate
         load_found; self
       end
 
+      def first(*args)
+        if args.first.kind_of?(Integer) || (@found &amp;&amp; !args.first.kind_of?(Hash))
+          proxy_found.first(*args)
+        else
+          find(:first, *args)
+        end
+      end
+
+      def last(*args)
+        if args.first.kind_of?(Integer) || (@found &amp;&amp; !args.first.kind_of?(Hash))
+          proxy_found.last(*args)
+        else
+          find(:last, *args)
+        end
+      end
+
+      def empty?
+        @found ? @found.empty? : count.zero?
+      end
+
+      def respond_to?(method, include_private = false)
+        super || @proxy_scope.respond_to?(method, include_private)
+      end
+
       protected
       def proxy_found
         @found || load_found</diff>
      <filename>lib/will_paginate/named_scope.rb</filename>
    </modified>
    <modified>
      <diff>@@ -1,5 +1,3 @@
-## based on http://dev.rubyonrails.org/changeset/9084
-
 ActiveRecord::Associations::AssociationProxy.class_eval do
   protected
   def with_scope(*args, &amp;block)</diff>
      <filename>lib/will_paginate/named_scope_patch.rb</filename>
    </modified>
    <modified>
      <diff>@@ -2,7 +2,7 @@ module WillPaginate
   module VERSION
     MAJOR = 2
     MINOR = 3
-    TINY  = 3
+    TINY  = 5
 
     STRING = [MAJOR, MINOR, TINY].join('.')
   end</diff>
      <filename>lib/will_paginate/version.rb</filename>
    </modified>
    <modified>
      <diff>@@ -42,7 +42,7 @@ module WillPaginate
     # 
     # ==== Options
     # Display options:
-    # * &lt;tt&gt;:previous_label&lt;/tt&gt; -- default: &quot;&#171; Previous&quot;
+    # * &lt;tt&gt;:previous_label&lt;/tt&gt; -- default: &quot;&#171; Previous&quot; (this parameter is called &lt;tt&gt;:prev_label&lt;/tt&gt; in versions &lt;b&gt;2.3.2&lt;/b&gt; and older!)
     # * &lt;tt&gt;:next_label&lt;/tt&gt; -- default: &quot;Next &#187;&quot;
     # * &lt;tt&gt;:page_links&lt;/tt&gt; -- when false, only previous/next links are rendered (default: true)
     # * &lt;tt&gt;:inner_window&lt;/tt&gt; -- how many links are shown around the current page (default: 4)</diff>
      <filename>lib/will_paginate/view_helpers.rb</filename>
    </modified>
    <modified>
      <diff>@@ -2,6 +2,9 @@ require 'helper'
 require 'will_paginate/array'
 
 class ArrayPaginationTest &lt; Test::Unit::TestCase
+  
+  def setup ; end
+  
   def test_simple
     collection = ('a'..'e').to_a
     </diff>
      <filename>test/collection_test.rb</filename>
    </modified>
    <modified>
      <diff>@@ -17,6 +17,6 @@ mysql:
 postgres:
   adapter: postgresql
   username: mislav
-  password: mislav
+  password: 
   database: will_paginate_unittest
   min_messages: warning</diff>
      <filename>test/database.yml</filename>
    </modified>
    <modified>
      <diff>@@ -261,6 +261,12 @@ class FinderTest &lt; ActiveRecordTestCase
       assert_equal 1, entries.total_entries, 'only one topic should be found'
     end
   end
+  
+  def test_named_scope_with_include
+    project = projects(:active_record)
+    entries = project.topics.with_replies_starting_with('AR ').paginate(:page =&gt; 1, :per_page =&gt; 1)
+    assert_equal 1, entries.size
+  end
 
   ## misc ##
 
@@ -340,6 +346,12 @@ class FinderTest &lt; ActiveRecordTestCase
       Developer.paginate :select =&gt; 'DISTINCT salary', :page =&gt; 2
     end
 
+    def test_count_with_scoped_select_when_distinct
+      Developer.stubs(:find).returns([])
+      Developer.expects(:count).with(:select =&gt; 'DISTINCT users.id').returns(0)
+      Developer.distinct.paginate :page =&gt; 2
+    end
+
     def test_should_use_scoped_finders_if_present
       # scope-out compatibility
       Topic.expects(:find_best).returns(Array.new(5))
@@ -390,12 +402,20 @@ class FinderTest &lt; ActiveRecordTestCase
 
     def test_paginating_finder_doesnt_mangle_options
       Developer.expects(:find).returns([])
-      options = { :page =&gt; 1 }
-      options.expects(:delete).never
+      options = { :page =&gt; 1, :per_page =&gt; 2, :foo =&gt; 'bar' }
       options_before = options.dup
       
       Developer.paginate(options)
-      assert_equal options, options_before
+      assert_equal options_before, options
+    end
+    
+    def test_paginate_by_sql_doesnt_change_original_query
+      query = 'SQL QUERY'
+      original_query = query.dup
+      Developer.expects(:find_by_sql).returns([])
+      
+      Developer.paginate_by_sql query, :page =&gt; 1
+      assert_equal original_query, query
     end
 
     def test_paginated_each
@@ -413,6 +433,12 @@ class FinderTest &lt; ActiveRecordTestCase
       assert_equal 14, Developer.paginated_each(:page =&gt; '2') { }
     end
 
+    def test_paginated_each_with_named_scope
+      assert_equal 2, Developer.poor.paginated_each(:per_page =&gt; 1) {
+        assert_equal 11, Developer.count
+      }
+    end
+
     # detect ActiveRecord 2.1
     if ActiveRecord::Base.private_methods.include?('references_eager_loaded_tables?')
       def test_removes_irrelevant_includes_in_count
@@ -430,5 +456,21 @@ class FinderTest &lt; ActiveRecordTestCase
           :include =&gt; :projects, :conditions =&gt; 'projects.id &gt; 2'
       end
     end
+    
+    def test_paginate_from
+      result = Developer.paginate(:from =&gt; 'users', :page =&gt; 1, :per_page =&gt; 1)
+      assert_equal 1, result.size
+    end
+    
+    def test_hmt_with_include
+      # ticket #220
+      reply = projects(:active_record).replies.find(:first, :order =&gt; 'replies.id')
+      assert_equal replies(:decisive), reply
+      
+      # ticket #223
+      Project.find(1, :include =&gt; :replies)
+      
+      # I cannot reproduce any of the failures from those reports :(
+    end
   end
 end</diff>
      <filename>test/finder_test.rb</filename>
    </modified>
    <modified>
      <diff>@@ -7,6 +7,7 @@ class Developer &lt; User
     end
   end
 
+  named_scope :distinct, :select =&gt; 'DISTINCT `users`.*'
   named_scope :poor, :conditions =&gt; ['salary &lt;= ?', 80000], :order =&gt; 'salary'
 
   def self.per_page() 10 end</diff>
      <filename>test/fixtures/developer.rb</filename>
    </modified>
    <modified>
      <diff>@@ -3,4 +3,8 @@ class Topic &lt; ActiveRecord::Base
   belongs_to :project
 
   named_scope :mentions_activerecord, :conditions =&gt; ['topics.title LIKE ?', '%ActiveRecord%']
+  
+  named_scope :with_replies_starting_with, lambda { |text|
+    { :conditions =&gt; &quot;replies.content LIKE '#{text}%' &quot;, :include  =&gt; :replies }
+  }
 end</diff>
      <filename>test/fixtures/topic.rb</filename>
    </modified>
    <modified>
      <diff>@@ -16,16 +16,20 @@ class ActiveRecordTestConnector
     unless self.connected || !self.able_to_connect
       setup_connection
       load_schema
-      Dependencies.load_paths.unshift FIXTURES_PATH
+      add_load_path FIXTURES_PATH
       self.connected = true
     end
   rescue Exception =&gt; e  # errors from ActiveRecord setup
-    $stderr.puts &quot;\nSkipping ActiveRecord tests: #{e}&quot;
-    $stderr.puts &quot;Install SQLite3 to run the full test suite for will_paginate.\n\n&quot;
+    $stderr.puts &quot;\nSkipping ActiveRecord tests: #{e}\n\n&quot;
     self.able_to_connect = false
   end
 
   private
+  
+  def self.add_load_path(path)
+    dep = defined?(ActiveSupport::Dependencies) ? ActiveSupport::Dependencies : ::Dependencies
+    dep.load_paths.unshift path
+  end
 
   def self.setup_connection
     db = ENV['DB'].blank?? 'sqlite3' : ENV['DB']</diff>
      <filename>test/lib/activerecord_test_connector.rb</filename>
    </modified>
    <modified>
      <diff>@@ -35,7 +35,7 @@ task :test_full =&gt; %w(test test_mysql test_postgres)
 desc %{Test everything with Rails 2.1.x, 2.0.x &amp; 1.2.x gems}
 task :test_all do
   all = Rake::Task['test_full']
-  versions = %w(2.1.0 2.0.2 1.2.6)
+  versions = %w(2.1.0 2.0.4 1.2.6)
   versions.each do |version|
     ENV['RAILS_VERSION'] = &quot;~&gt; #{version}&quot;
     all.invoke</diff>
      <filename>test/tasks.rake</filename>
    </modified>
    <modified>
      <diff>@@ -1,7 +1,7 @@
 Gem::Specification.new do |s|
   s.name    = 'will_paginate'
-  s.version = '2.3.2'
-  s.date    = '2008-05-16'
+  s.version = '2.3.6'
+  s.date    = '2008-10-26'
   
   s.summary = &quot;Most awesome pagination solution for Rails&quot;
   s.description = &quot;The will_paginate library provides a simple, yet powerful and extensible API for ActiveRecord pagination and rendering of pagination links in ActionView templates.&quot;
@@ -13,9 +13,10 @@ Gem::Specification.new do |s|
   s.has_rdoc = true
   s.rdoc_options = ['--main', 'README.rdoc']
   s.rdoc_options &lt;&lt; '--inline-source' &lt;&lt; '--charset=UTF-8'
-  s.extra_rdoc_files = ['README.rdoc', 'LICENSE', 'CHANGELOG']
+  s.extra_rdoc_files = ['README.rdoc', 'LICENSE', 'CHANGELOG.rdoc']
+  
   s.add_dependency 'activesupport', ['&gt;= 1.4.4']
   
-  s.files = %w(CHANGELOG LICENSE README.rdoc Rakefile examples examples/apple-circle.gif examples/index.haml examples/index.html examples/pagination.css examples/pagination.sass init.rb lib lib/will_paginate lib/will_paginate.rb lib/will_paginate/array.rb lib/will_paginate/collection.rb lib/will_paginate/core_ext.rb lib/will_paginate/finder.rb lib/will_paginate/named_scope.rb lib/will_paginate/named_scope_patch.rb lib/will_paginate/version.rb lib/will_paginate/view_helpers.rb test test/boot.rb test/collection_test.rb test/console test/database.yml test/finder_test.rb test/fixtures test/fixtures/admin.rb test/fixtures/developer.rb test/fixtures/developers_projects.yml test/fixtures/project.rb test/fixtures/projects.yml test/fixtures/replies.yml test/fixtures/reply.rb test/fixtures/schema.rb test/fixtures/topic.rb test/fixtures/topics.yml test/fixtures/user.rb test/fixtures/users.yml test/helper.rb test/lib test/lib/activerecord_test_case.rb test/lib/activerecord_test_connector.rb test/lib/load_fixtures.rb test/lib/view_test_process.rb test/tasks.rake test/view_test.rb)
+  s.files = %w(CHANGELOG.rdoc LICENSE README.rdoc Rakefile examples examples/apple-circle.gif examples/index.haml examples/index.html examples/pagination.css examples/pagination.sass init.rb lib lib/will_paginate lib/will_paginate.rb lib/will_paginate/array.rb lib/will_paginate/collection.rb lib/will_paginate/core_ext.rb lib/will_paginate/finder.rb lib/will_paginate/named_scope.rb lib/will_paginate/named_scope_patch.rb lib/will_paginate/version.rb lib/will_paginate/view_helpers.rb test test/boot.rb test/collection_test.rb test/console test/database.yml test/finder_test.rb test/fixtures test/fixtures/admin.rb test/fixtures/developer.rb test/fixtures/developers_projects.yml test/fixtures/project.rb test/fixtures/projects.yml test/fixtures/replies.yml test/fixtures/reply.rb test/fixtures/schema.rb test/fixtures/topic.rb test/fixtures/topics.yml test/fixtures/user.rb test/fixtures/users.yml test/helper.rb test/lib test/lib/activerecord_test_case.rb test/lib/activerecord_test_connector.rb test/lib/load_fixtures.rb test/lib/view_test_process.rb test/tasks.rake test/view_test.rb)
   s.test_files = %w(test/boot.rb test/collection_test.rb test/console test/database.yml test/finder_test.rb test/fixtures test/fixtures/admin.rb test/fixtures/developer.rb test/fixtures/developers_projects.yml test/fixtures/project.rb test/fixtures/projects.yml test/fixtures/replies.yml test/fixtures/reply.rb test/fixtures/schema.rb test/fixtures/topic.rb test/fixtures/topics.yml test/fixtures/user.rb test/fixtures/users.yml test/helper.rb test/lib test/lib/activerecord_test_case.rb test/lib/activerecord_test_connector.rb test/lib/load_fixtures.rb test/lib/view_test_process.rb test/tasks.rake test/view_test.rb)
 end</diff>
      <filename>will_paginate.gemspec</filename>
    </modified>
  </modified>
  <removed type="array"/>
  <parents type="array">
    <parent>
      <id>9373d5120f1c0404736003f45385a851ebf10f9c</id>
    </parent>
    <parent>
      <id>32f5e93a5298094d10367395fd67d65727fcb1ec</id>
    </parent>
  </parents>
  <author>
    <name>(null)</name>
    <email>(null)</email>
  </author>
  <url>http://github.com/agile/will_paginate/commit/ab6fca53a8a66725899c0fab3e474b9c7e3a173e</url>
  <id>ab6fca53a8a66725899c0fab3e474b9c7e3a173e</id>
  <committed-date>2008-10-27T16:47:45-07:00</committed-date>
  <authored-date>2008-10-27T16:47:45-07:00</authored-date>
  <message>Merge branch 'master' of git://github.com/mislav/will_paginate</message>
  <tree>c6ba7fa5873c5098dc6aa27e8a0df0f5ef91a6bf</tree>
  <committer>
    <name>(null)</name>
    <email>(null)</email>
  </committer>
</commit>
