// Path: src/main/java/org/deri/cqels/data/Mapping.java
// public interface Mapping extends Map<Var, Long>{
// 	
// 
// 	public long get(Var var); 
// 	
// 	public void from(OpRouter router);
// 	
// 	public OpRouter from();
// 	
// 	public ExecContext getCtx();
// 	
// 	public Iterator<Var> vars();
// 	
// 	public void addParent(Mapping parent);
// 	
// 	public boolean hasParent();
// 	
// 	public boolean isCompatible(Mapping mapping);
// }
// 
// Path: src/main/java/org/deri/cqels/data/ProjectMapping.java
// public class ProjectMapping extends MappingBase {
// 	Mapping mapping;
// 	List<Var> vars;
// 	public ProjectMapping(ExecContext context, Mapping mapping, List<Var> vars) {
// 		super(context);
// 		this.mapping = mapping;
// 		this.vars = vars;
// 		//TODO check if mapping contains all variable in vars
// 	}
// 	
// 	@Override
// 	public long get(Var var) {
// 		if(vars.contains(var)) {
// 			return mapping.get(var);
// 		}
// 		return -1;
// 	}
// 	
// 	@Override
// 	public Iterator<Var> vars() {
// 		return vars.iterator();
// 	}
// 	
// 	@Override
// 	public boolean containsKey(Object key) {
// 		for(Var _var:vars)
// 			if(_var.equals(key)) return true;
// 		return false;
// 	}
// 	
// 	@Override
// 	public boolean containsValue(Object value) {
// 		//TODO don't allow data access
// 		return false;
// 	}
// 	
// 	@Override
// 	public boolean isCompatible(Mapping mapping) {
// 		for(Var var:vars)
// 			if(mapping.get(var)!=(this.mapping.get(var))) return false;
// 		return true;
// 	}
// 	
// 	@Override
// 	public boolean isEmpty() {
// 		
// 		return vars==null||vars.isEmpty();
// 	}
// 	
// 	@Override
// 	public int size() {
// 		// TODO Auto-generated method stub
// 		return vars!=null?vars.size():0;
// 	}
// }
// 
// Path: src/main/java/org/deri/cqels/engine/iterator/MappingIterOnQueryIter.java
// public class MappingIterOnQueryIter extends MappingIter {
// 	QueryIterator queryItr;
// 	public MappingIterOnQueryIter(ExecContext context, QueryIterator queryItr) {
// 		super(context);
// 		this.queryItr = queryItr;
// 	}
// 
// 	@Override
// 	protected void closeIterator() {
// 		queryItr.close();
// 	}
// 
// 	@Override
// 	protected boolean hasNextMapping() {
// 		// TODO Auto-generated method stub
// 		return queryItr.hasNext();
// 	}
// 
// 	@Override
// 	protected Mapping moveToNextMapping() {
// 		if(!queryItr.hasNext()) {
// 			return null;
// 		}
// 		return new Binding2Mapping(context, queryItr.next()) ;
// 	}
// 
// 	@Override
// 	protected void requestCancel() {
// 		queryItr.cancel();	
// 	}
// }
// 
// Path: src/main/java/org/deri/cqels/engine/iterator/MappingIterator.java
// public interface MappingIterator extends Closeable, Iterator<Mapping> {
// 
//     /**
//      * Get next binding
//      */
//     public Mapping nextMapping();
// 
//     /**
//      * Cancels the query as soon as is possible for the given iterator
//      */
//     public void cancel();
// }


import java.util.List;
import org.deri.cqels.data.Mapping;
import org.deri.cqels.data.ProjectMapping;
import org.deri.cqels.engine.iterator.MappingIterOnQueryIter;
import org.deri.cqels.engine.iterator.MappingIterator;
import org.deri.cqels.engine.iterator.QueryIterOnMappingIter;
import com.hp.hpl.jena.sparql.algebra.op.OpGroup;
import com.hp.hpl.jena.sparql.core.VarExprList;
import com.hp.hpl.jena.sparql.engine.iterator.QueryIterGroup;
import com.hp.hpl.jena.sparql.expr.ExprAggregator;
package org.deri.cqels.engine;


/**
 * This class implements the router with group-by operator
 *
 * @author Danh Le Phuoc
 * @author Chan Le Van
 * @organization DERI Galway, NUIG, Ireland www.deri.ie
 * @email danh.lephuoc@deri.org
 * @email chan.levan@deri.org
 * @see OpRouter1
 */
public class GroupRouter extends OpRouter1 {

    private final VarExprList groupVars;
    private final List<ExprAggregator> aggregators;

    public GroupRouter(ExecContext context, OpGroup op, OpRouter sub) {
        super(context, op, sub);
        this.groupVars = ((OpGroup) op).getGroupVars();
        this.aggregators = ((OpGroup) op).getAggregators();
    }

    @Override
// Path: src/main/java/org/deri/cqels/data/Mapping.java
// public interface Mapping extends Map<Var, Long>{
// 	
// 
// 	public long get(Var var); 
// 	
// 	public void from(OpRouter router);
// 	
// 	public OpRouter from();
// 	
// 	public ExecContext getCtx();
// 	
// 	public Iterator<Var> vars();
// 	
// 	public void addParent(Mapping parent);
// 	
// 	public boolean hasParent();
// 	
// 	public boolean isCompatible(Mapping mapping);
// }
// 
// Path: src/main/java/org/deri/cqels/data/ProjectMapping.java
// public class ProjectMapping extends MappingBase {
// 	Mapping mapping;
// 	List<Var> vars;
// 	public ProjectMapping(ExecContext context, Mapping mapping, List<Var> vars) {
// 		super(context);
// 		this.mapping = mapping;
// 		this.vars = vars;
// 		//TODO check if mapping contains all variable in vars
// 	}
// 	
// 	@Override
// 	public long get(Var var) {
// 		if(vars.contains(var)) {
// 			return mapping.get(var);
// 		}
// 		return -1;
// 	}
// 	
// 	@Override
// 	public Iterator<Var> vars() {
// 		return vars.iterator();
// 	}
// 	
// 	@Override
// 	public boolean containsKey(Object key) {
// 		for(Var _var:vars)
// 			if(_var.equals(key)) return true;
// 		return false;
// 	}
// 	
// 	@Override
// 	public boolean containsValue(Object value) {
// 		//TODO don't allow data access
// 		return false;
// 	}
// 	
// 	@Override
// 	public boolean isCompatible(Mapping mapping) {
// 		for(Var var:vars)
// 			if(mapping.get(var)!=(this.mapping.get(var))) return false;
// 		return true;
// 	}
// 	
// 	@Override
// 	public boolean isEmpty() {
// 		
// 		return vars==null||vars.isEmpty();
// 	}
// 	
// 	@Override
// 	public int size() {
// 		// TODO Auto-generated method stub
// 		return vars!=null?vars.size():0;
// 	}
// }
// 
// Path: src/main/java/org/deri/cqels/engine/iterator/MappingIterOnQueryIter.java
// public class MappingIterOnQueryIter extends MappingIter {
// 	QueryIterator queryItr;
// 	public MappingIterOnQueryIter(ExecContext context, QueryIterator queryItr) {
// 		super(context);
// 		this.queryItr = queryItr;
// 	}
// 
// 	@Override
// 	protected void closeIterator() {
// 		queryItr.close();
// 	}
// 
// 	@Override
// 	protected boolean hasNextMapping() {
// 		// TODO Auto-generated method stub
// 		return queryItr.hasNext();
// 	}
// 
// 	@Override
// 	protected Mapping moveToNextMapping() {
// 		if(!queryItr.hasNext()) {
// 			return null;
// 		}
// 		return new Binding2Mapping(context, queryItr.next()) ;
// 	}
// 
// 	@Override
// 	protected void requestCancel() {
// 		queryItr.cancel();	
// 	}
// }
// 
// Path: src/main/java/org/deri/cqels/engine/iterator/MappingIterator.java
// public interface MappingIterator extends Closeable, Iterator<Mapping> {
// 
//     /**
//      * Get next binding
//      */
//     public Mapping nextMapping();
// 
//     /**
//      * Cancels the query as soon as is possible for the given iterator
//      */
//     public void cancel();
// }


// Path: src/main/java/org/deri/cqels/engine/GroupRouter.java
import java.util.List;
import org.deri.cqels.data.Mapping;
import org.deri.cqels.data.ProjectMapping;
import org.deri.cqels.engine.iterator.MappingIterOnQueryIter;
import org.deri.cqels.engine.iterator.MappingIterator;
import org.deri.cqels.engine.iterator.QueryIterOnMappingIter;
import com.hp.hpl.jena.sparql.algebra.op.OpGroup;
import com.hp.hpl.jena.sparql.core.VarExprList;
import com.hp.hpl.jena.sparql.engine.iterator.QueryIterGroup;
import com.hp.hpl.jena.sparql.expr.ExprAggregator;

package org.deri.cqels.engine;


/**
 * This class implements the router with group-by operator
 *
 * @author Danh Le Phuoc
 * @author Chan Le Van
 * @organization DERI Galway, NUIG, Ireland www.deri.ie
 * @email danh.lephuoc@deri.org
 * @email chan.levan@deri.org
 * @see OpRouter1
 */
public class GroupRouter extends OpRouter1 {

    private final VarExprList groupVars;
    private final List<ExprAggregator> aggregators;

    public GroupRouter(ExecContext context, OpGroup op, OpRouter sub) {
        super(context, op, sub);
        this.groupVars = ((OpGroup) op).getGroupVars();
        this.aggregators = ((OpGroup) op).getAggregators();
    }

    @Override
    public void route(Mapping mapping) {