<?xml version="1.0" encoding="UTF-8"?>
<commit>
  <added type="array"/>
  <modified type="array">
    <modified>
      <diff>@@ -90,8 +90,7 @@ module Liquid
           token.respond_to?(:render) ? token.render(context) : token
         rescue Exception =&gt; e          
           context.handle_error(e)
-        end
-          
+        end          
       end      
     end
   end  </diff>
      <filename>lib/liquid/block.rb</filename>
    </modified>
    <modified>
      <diff>@@ -60,6 +60,7 @@ module Liquid
 
     # push new local scope on the stack. use &lt;tt&gt;Context#stack&lt;/tt&gt; instead
     def push
+      raise StackLevelError, &quot;Nesting too deep&quot; if @scopes.length &gt; 100
       @scopes.unshift({})
     end
     </diff>
      <filename>lib/liquid/context.rb</filename>
    </modified>
    <modified>
      <diff>@@ -7,4 +7,5 @@ module Liquid
   class FileSystemError &lt; Error; end
   class StandardError &lt; Error; end
   class SyntaxError &lt; Error; end
+  class StackLevelError &lt; Error; end
 end
\ No newline at end of file</diff>
      <filename>lib/liquid/errors.rb</filename>
    </modified>
    <modified>
      <diff>@@ -64,35 +64,31 @@ module Liquid
       collection = context[@collection_name]
       collection = collection.to_a if collection.is_a?(Range)
     
-      return '' if collection.nil? or collection.empty?
-    
-      range = (0..collection.length)
-    
-      if @attributes['limit'] or @attributes['offset']
-        offset = 0
-        if @attributes['offset'] == 'continue'
-          offset = context.registers[:for][@name] 
-        else          
-          offset = context[@attributes['offset']] || 0
-        end
-        limit  = context[@attributes['limit']]
-
-        range_end = limit ? offset + limit : collection.length
-        range = (offset..range_end-1)
-      
-        # Save the range end in the registers so that future calls to 
-        # offset:continue have something to pick up
-        context.registers[:for][@name] = range_end
+      return '' unless collection.respond_to?(:each) 
+                                                 
+      from = if @attributes['offset'] == 'continue'
+        context.registers[:for][@name].to_i
+      else
+        context[@attributes['offset']].to_i
       end
-            
+        
+      limit = context[@attributes['limit']]
+      to    = limit ? limit.to_i + from : nil  
+          
+                       
+      segment = slice_collection_using_each(collection, from, to)      
+      
+      return '' if segment.empty?
+      
       result = []
-      segment = collection[range]
-      return '' if segment.nil?        
-
-      context.stack do 
-        length = segment.length
+        
+      length = segment.length
       
-        segment.each_with_index do |item, index|
+      # Store our progress through the collection for the continue flag
+      context.registers[:for][@name] = from + segment.length
+              
+      context.stack do 
+        segment.each_with_index do |item, index|     
           context[@variable_name] = item
           context['forloop'] = {
             'name'    =&gt; @name,
@@ -103,15 +99,32 @@ module Liquid
             'rindex0' =&gt; length - index -1,
             'first'   =&gt; (index == 0),
             'last'    =&gt; (index == length - 1) }
-        
+
           result &lt;&lt; render_all(@nodelist, context)
         end
       end
-    
-      # Store position of last element we rendered. This allows us to do 
-    
-      result 
-    end           
+      result     
+    end          
+        
+    def slice_collection_using_each(collection, from, to)       
+      segments = []      
+      index = 0      
+      yielded = 0
+      collection.each do |item|         
+                
+        if to &amp;&amp; to &lt;= index
+          break
+        end
+        
+        if from &lt;= index                               
+          segments &lt;&lt; item
+        end                    
+                
+        index += 1
+      end    
+
+      segments
+    end
   end
 
   Template.register_tag('for', For)</diff>
      <filename>lib/liquid/tags/for.rb</filename>
    </modified>
    <modified>
      <diff>@@ -83,7 +83,7 @@ module Liquid
     #    filters and tags and might be useful to integrate liquid more with its host application  
     #
     def render(*args)
-      return '' if @root.nil?
+      return '' if @root.nil?                          
 
       context = case args.first
       when Liquid::Context
@@ -107,17 +107,17 @@ module Liquid
 
         if options[:filters]
           context.add_filters(options[:filters])
-        end
+        end                         
+        
       when Module
         context.add_filters(args.pop)    
       when Array
         context.add_filters(args.pop)            
       end
-                              
-                              
-      # render the nodelist.
-      # for performance reasons we get a array back here. to_s will make a string out of it
+                                                            
       begin
+        # render the nodelist.
+        # for performance reasons we get a array back here. join will make a string out of it
         @root.render(context).join
       ensure
         @errors = context.errors</diff>
      <filename>lib/liquid/template.rb</filename>
    </modified>
    <modified>
      <diff>@@ -59,6 +59,16 @@ class ProductDrop &lt; Liquid::Drop
     def callmenot
       &quot;protected&quot;
     end
+end                   
+
+class EnumerableDrop &lt; Liquid::Drop   
+  include Enumerable
+  
+  def each
+    yield 1
+    yield 2
+    yield 3
+  end
 end
 
 
@@ -132,6 +142,10 @@ class DropsTest &lt; Test::Unit::TestCase
   
   def test_access_context_from_drop
     assert_equal '123', Liquid::Template.parse( '{%for a in dummy%}{{ context.loop_pos }}{% endfor %}'  ).render('context' =&gt; ContextDrop.new, 'dummy' =&gt; [1,2,3])            
+  end             
+  
+  def test_enumerable_drop         
+    assert_equal '123', Liquid::Template.parse( '{% for c in collection %}{{c}}{% endfor %}').render('collection' =&gt; EnumerableDrop.new)
   end
   
   </diff>
      <filename>test/drop_test.rb</filename>
    </modified>
    <modified>
      <diff>@@ -57,8 +57,23 @@ class ErrorHandlingTest &lt; Test::Unit::TestCase
       
     end
     
+  end            
+  
+  def test_missing_endtag
+    
+    assert_nothing_raised do
+      
+      template = Liquid::Template.parse(' {% for a in b %} ... ')
+      assert_equal ' Liquid error: Unknown operator =! ', template.render
+      
+      assert_equal 1, template.errors.size
+      assert_equal Liquid::SyntaxError, template.errors.first.class
+      
+    end
+    
   end
   
+  
   def test_unrecognized_operator
     
     assert_nothing_raised do</diff>
      <filename>test/error_handling_test.rb</filename>
    </modified>
    <modified>
      <diff>@@ -96,9 +96,10 @@ class IncludeTagTest &lt; Test::Unit::TestCase
     end                   
     
     Liquid::Template.file_system = infinite_file_system.new
-    
-    assert_match /-{552}Liquid error: stack level too deep$/, 
-      Template.parse(&quot;{% include 'loop' %}&quot;).render                 
+                   
+    assert_raise(Liquid::StackLevelError) do
+      Template.parse(&quot;{% include 'loop' %}&quot;).render!
+    end
     
   end
             </diff>
      <filename>test/include_tag_test.rb</filename>
    </modified>
    <modified>
      <diff>@@ -104,11 +104,14 @@ HERE
     assert_template_result('12','{%for i in array limit:2 %}{{ i }}{%endfor%}',assigns)
     assert_template_result('1234','{%for i in array limit:4 %}{{ i }}{%endfor%}',assigns)
     assert_template_result('3456','{%for i in array limit:4 offset:2 %}{{ i }}{%endfor%}',assigns)
-    assert_template_result('3456','{%for i in array limit: 4 offset: 2 %}{{ i }}{%endfor%}',assigns)    
-    
+    assert_template_result('3456','{%for i in array limit: 4 offset: 2 %}{{ i }}{%endfor%}',assigns)        
+  end
+  
+  def test_dynamic_variable_limiting
+    assigns = {'array' =&gt; [1,2,3,4,5,6,7,8,9,0]}
     assigns['limit'] = 2
     assigns['offset'] = 2
-    assert_template_result('34','{%for i in array limit: limit offset: offset %}{{ i }}{%endfor%}',assigns)    
+    assert_template_result('34','{%for i in array limit: limit offset: offset %}{{ i }}{%endfor%}',assigns)        
   end
   
   def test_nested_for</diff>
      <filename>test/standard_tag_test.rb</filename>
    </modified>
  </modified>
  <removed type="array"/>
  <parents type="array">
    <parent>
      <id>7f58cbf82d9a064c191a1e5ca957f1850bbed5fb</id>
    </parent>
  </parents>
  <author>
    <name>Tobias L&#252;tke</name>
    <email>tobi@jadedpixel.com</email>
  </author>
  <url>http://github.com/tobi/liquid/commit/4c0cfae0b725cd6945fcdd495b0c877b08b8a90b</url>
  <id>4c0cfae0b725cd6945fcdd495b0c877b08b8a90b</id>
  <committed-date>2008-05-08T09:30:48-07:00</committed-date>
  <authored-date>2008-05-08T09:30:48-07:00</authored-date>
  <message>Changed implementation of For in such a way that it only depends on the existence of a each method. This allows drops to simply implement each for enumeration</message>
  <tree>4a48a8f05ce379202b478d7a1a4965bdad9df5f7</tree>
  <committer>
    <name>Tobias L&#252;tke</name>
    <email>tobi@jadedpixel.com</email>
  </committer>
</commit>
