Fixed a bug with the loop context of a for loop if the iterator passed has a volatile `__len__` like the listreverseiterator.  `else` in inline if-expressions is optional now.

--HG--
branch : trunk
diff --git a/jinja2/runtime.py b/jinja2/runtime.py
index 0417f61..d6c5553 100644
--- a/jinja2/runtime.py
+++ b/jinja2/runtime.py
@@ -197,14 +197,19 @@
 class LoopContext(object):
     """A loop context for dynamic iteration."""
 
-    def __init__(self, iterable, enforce_length=False, recurse=None):
-        self._iterable = iterable
-        self._next = iter(iterable).next
-        self._length = None
+    def __init__(self, iterable, recurse=None):
+        self._iterator = iter(iterable)
         self._recurse = recurse
         self.index0 = -1
-        if enforce_length:
-            len(self)
+
+        # try to get the length of the iterable early.  This must be done
+        # here because there are some broken iterators around where there
+        # __len__ is the number of iterations left (i'm looking at your
+        # listreverseiterator!).
+        try:
+            self._length = len(iterable)
+        except (TypeError, AttributeError):
+            self._length = None
 
     def cycle(self, *args):
         """Cycles among the arguments with the current loop index."""
@@ -213,7 +218,7 @@
         return args[self.index0 % len(args)]
 
     first = property(lambda x: x.index0 == 0)
-    last = property(lambda x: x.revindex0 == 0)
+    last = property(lambda x: x.index0 + 1 == x.length)
     index = property(lambda x: x.index0 + 1)
     revindex = property(lambda x: x.length - x.index0)
     revindex0 = property(lambda x: x.length - x.index)
@@ -237,18 +242,13 @@
     @property
     def length(self):
         if self._length is None:
-            try:
-                # first try to get the length from the iterable (if the
-                # iterable is a sequence)
-                length = len(self._iterable)
-            except TypeError:
-                # if that's not possible (ie: iterating over a generator)
-                # we have to convert the iterable into a sequence and
-                # use the length of that.
-                self._iterable = tuple(self._iterable)
-                self._next = iter(self._iterable).next
-                length = len(tuple(self._iterable)) + self.index0 + 1
-            self._length = length
+            # if was not possible to get the length of the iterator when
+            # the loop context was created (ie: iterating over a generator)
+            # we have to convert the iterable into a sequence and use the
+            # length of that.
+            iterable = tuple(self._iterator)
+            self._iterator = iter(iterable)
+            self._length = len(iterable) + self.index0 + 1
         return self._length
 
     def __repr__(self):
@@ -272,7 +272,7 @@
     def next(self):
         ctx = self.context
         ctx.index0 += 1
-        return ctx._next(), ctx
+        return ctx._iterator.next(), ctx
 
 
 class Macro(object):