Source:
<code>private static <TSource, TInner, TResult> Enumerable<TResult> nestedLoopJoinOptimized( final Enumerable<TSource> outer, final Enumerable<TInner> inner, final Predicate2<TSource, TInner> predicate, Function2<TSource, TInner, TResult> resultSelector, final JoinType joinType) { if (joinType == JoinType.RIGHT || joinType == JoinType.FULL) { throw new IllegalArgumentException("JoinType " + joinType + " is unsupported"); } return new AbstractEnumerable<TResult>() { public Enumerator<TResult> enumerator() { return new Enumerator<TResult>() { private Enumerator<TSource> outerEnumerator = outer.enumerator(); private Enumerator<TInner> innerEnumerator = null; private boolean outerMatch = false; private TSource outerValue; private TInner innerValue; private int state = 0; @Override public TResult current() { return resultSelector.apply(outerValue, innerValue); } @Override public boolean moveNext() { while (true) { switch (state) { case 0: if (!outerEnumerator.moveNext()) { return false; } outerValue = outerEnumerator.current(); if (innerEnumerator != null) { <START> innerEnumerator.close(); <END> } innerEnumerator = inner.enumerator(); outerMatch = false; state = 1; continue; case 1: if (innerEnumerator.moveNext()) { innerValue = innerEnumerator.current(); if (predicate.apply(outerValue, innerValue)) { outerMatch = true; switch (joinType) { case ANTI: state = 0; continue; case SEMI: state = 0; default: return true; } } } else { state = 0; innerValue = null; if (!outerMatch && (joinType == JoinType.LEFT || joinType == JoinType.ANTI)) { return true; } } } } } @Override public void reset() { state = 0; outerMatch = false; outerEnumerator.reset(); closeInner(); } @Override public void close() { outerEnumerator.close(); closeInner(); } private void closeInner() { if (innerEnumerator != null) { innerEnumerator.close(); innerEnumerator = null; } } }; } }; }</code><technical_language>close innerEnumerator case 1 ? I in else branch innerEnumerator.moveNext() is false</technical_language>

Target:
private static <TSource, TInner, TResult> Enumerable<TResult> nestedLoopJoinOptimized( final Enumerable<TSource> outer, final Enumerable<TInner> inner, final Predicate2<TSource, TInner> predicate, Function2<TSource, TInner, TResult> resultSelector, final JoinType joinType) { if (joinType == JoinType.RIGHT || joinType == JoinType.FULL) { throw new IllegalArgumentException("JoinType " + joinType + " is unsupported"); } return new AbstractEnumerable<TResult>() { public Enumerator<TResult> enumerator() { return new Enumerator<TResult>() { private Enumerator<TSource> outerEnumerator = outer.enumerator(); private Enumerator<TInner> innerEnumerator = null; private boolean outerMatch = false; private TSource outerValue; private TInner innerValue; private int state = 0; @Override public TResult current() { return resultSelector.apply(outerValue, innerValue); } @Override public boolean moveNext() { while (true) { switch (state) { case 0: if (!outerEnumerator.moveNext()) { return false; } outerValue = outerEnumerator.current(); closeInner(); innerEnumerator = inner.enumerator(); outerMatch = false; state = 1; continue; case 1: if (innerEnumerator.moveNext()) { innerValue = innerEnumerator.current(); if (predicate.apply(outerValue, innerValue)) { outerMatch = true; switch (joinType) { case ANTI: state = 0; continue; case SEMI: state = 0; return true; case INNER: case LEFT: return true; } } } else { state = 0; innerValue = null; if (!outerMatch && (joinType == JoinType.LEFT || joinType == JoinType.ANTI)) { return true; } } } } } @Override public void reset() { state = 0; outerMatch = false; outerEnumerator.reset(); closeInner(); } @Override public void close() { outerEnumerator.close(); closeInner(); } private void closeInner() { if (innerEnumerator != null) { innerEnumerator.close(); innerEnumerator = null; } } }; } }; }