@@ -0,0 +1,2786 @@
+package com.redhat.ceylon.compiler.java.language;%0A%0Aimport java.lang.invoke.MethodHandle;%0Aimport java.lang.invoke.MethodHandles;%0Aimport java.lang.invoke.MethodType;%0A%0Aimport ceylon.language.Iterable;%0Aimport ceylon.language.Iterator;%0Aimport ceylon.language.finished_;%0A%0Aimport com.redhat.ceylon.compiler.java.metadata.Ignore;%0Aimport com.redhat.ceylon.compiler.java.runtime.model.TypeDescriptor;%0A%0Apublic abstract class LazyIterable%3CElement, Absent%3E extends AbstractIterable%3CElement, Absent%3E%7B%0A    private static final MethodType methodType = MethodType.methodType(Object.class);%0A    private final TypeDescriptor $reifiedElement;%0A    private final int $numMethods;%0A    private final boolean $spread;%0A%0A    public LazyIterable(%0A            @Ignore TypeDescriptor $reifiedElement, %0A            @Ignore TypeDescriptor $reifiedAbsent, %0A            int $numMethods, %0A            boolean $spread) %7B%0A        super($reifiedElement, $reifiedAbsent);%0A        this.$reifiedElement = $reifiedElement;%0A        this.$numMethods = $numMethods;%0A        this.$spread = $spread;%0A    %7D%0A    // We need the (anonymous) subclass to obtain the lookup for us%0A    protected abstract MethodHandles.Lookup lookup(); %0A    %0A    @Override%0A    public Iterator%3C? extends Element%3E iterator() %7B%0A        return new AbstractIterator($reifiedElement)%7B%0A            %0A            int index = 0;%0A            Iterator%3C? extends Element%3E rest = null;%0A            final MethodHandles.Lookup lookup = lookup();%0A            Class%3C? extends LazyIterable%3E subclass = LazyIterable.this.getClass();%0A            %0A            @Override%0A            public Object next() %7B%0A                if (rest != null) %7B%0A                    return rest.next();%0A                %7D %0A                if (index %3E= $numMethods) %7B%0A                    return finished_.get_();%0A                %7D%0A                java.lang.String methodName = %22$%22+index;%0A                index++;%0A                Object result;%0A                try %7B%0A                    MethodHandle handle = lookup.findSpecial(subclass, methodName, methodType, subclass);%0A                    // by delegating to the (anonymous) subclass %60this%60 will %0A                    // have the subclasses type and it can use invokeExact(), where%0A                    // this class could not (because we can't cast or even name the type of this)%0A                    result = invoke(handle);%0A                %7D catch (Throwable e) %7B%0A                    throw new RuntimeException(e);%0A                %7D%0A                if ($spread && index == $numMethods) %7B%0A                    rest = ((Iterable)result).iterator();%0A                    result = rest.next();%0A                %7D%0A                return result;%0A            %7D%0A        %7D;%0A    %7D%0A    %0A    protected abstract Object invoke(MethodHandle handle) throws Throwable;%0A%7D%0A

Add a LazyIterable to the runtime in support of #1524