Index: queryalgebra/evaluation/src/main/java/org/openrdf/query/algebra/evaluation/iterator/MultiProjectionIterator.java
===================================================================
--- queryalgebra/evaluation/src/main/java/org/openrdf/query/algebra/evaluation/iterator/MultiProjectionIterator.java	(revision 9800)
+++ queryalgebra/evaluation/src/main/java/org/openrdf/query/algebra/evaluation/iterator/MultiProjectionIterator.java	(working copy)
@@ -1,21 +1,29 @@
 /*
- * Copyright Aduna (http://www.aduna-software.com/) (c) 1997-2008.
+ * Copyright Aduna (http://www.aduna-software.com/) (c) 1997-2009.
  *
  * Licensed under the Aduna BSD-style license.
  */
 package org.openrdf.query.algebra.evaluation.iterator;
 
+import static org.openrdf.query.algebra.evaluation.iterator.ProjectionIterator.project;
+
+import java.util.HashSet;
 import java.util.List;
+import java.util.Set;
 
 import info.aduna.iteration.CloseableIteration;
-import info.aduna.iteration.CloseableIterationBase;
+import info.aduna.iteration.LookAheadIteration;
 
 import org.openrdf.query.BindingSet;
 import org.openrdf.query.QueryEvaluationException;
 import org.openrdf.query.algebra.MultiProjection;
 import org.openrdf.query.algebra.ProjectionElemList;
 
-public class MultiProjectionIterator extends CloseableIterationBase<BindingSet, QueryEvaluationException> {
+/**
+ * @author Arjohn Kampman
+ * @author James Leigh
+ */
+public class MultiProjectionIterator extends LookAheadIteration<BindingSet, QueryEvaluationException> {
 
 	/*-----------*
 	 * Constants *
@@ -35,6 +43,10 @@
 
 	private volatile int nextProjectionIdx;
 
+	private Set<BindingSet> projected;
+
+	private Set<BindingSet> projecting = new HashSet<BindingSet>();
+
 	/*--------------*
 	 * Constructors *
 	 *--------------*/
@@ -55,32 +67,30 @@
 	 * Methods *
 	 *---------*/
 
-	public boolean hasNext()
+	protected BindingSet getNextElement()
 		throws QueryEvaluationException
 	{
-		return nextProjectionIdx < projections.size() || iter.hasNext();
-	}
-
-	public BindingSet next()
-		throws QueryEvaluationException
-	{
 		int idx = nextProjectionIdx;
 
 		if (idx >= projections.size()) {
+			if (!iter.hasNext())
+				return null;
 			currentBindings = iter.next();
 			idx = nextProjectionIdx = 0;
+			projected = projecting;
+			projecting = new HashSet<BindingSet>(projecting.size() * 2);
 		}
 
 		ProjectionElemList nextProjection = projections.get(idx);
 		nextProjectionIdx++;
 
-		return ProjectionIterator.project(nextProjection, currentBindings, parentBindings);
+		BindingSet project = project(nextProjection, currentBindings, parentBindings);
+		projecting.add(project);
+		if (projected != null && projected.contains(project))
+			return next();
+		return project;
 	}
 
-	public void remove() {
-		throw new UnsupportedOperationException();
-	}
-
 	@Override
 	protected void handleClose()
 		throws QueryEvaluationException
@@ -88,5 +98,7 @@
 		super.handleClose();
 		iter.close();
 		nextProjectionIdx = projections.size();
+		projected = null;
+		projecting.clear();
 	}
 }

