@Override
	protected void exec() {
		//it's possible that both vertices are not visited, but
		//it should not occur. To simplify the code we assume
		//at least one vertex is bound.
		Vertex end;
		Set<Binding> results = null;
		results = te.exec(null);
		//if both vertices are bound
		if(edge.getV1().isBound() && edge.getV2().isBound()) {
			start = edge.getV1();
			end = edge.getV2();
			results = QueryUtil.join(results, start.getBindings());
			results = QueryUtil.join(results, end.getBindings());
			
			results = QueryUtil.join(results, input);
			if(Config.debug) {
				System.out.println(edge+": "+results.size());
			}
			if(results.size() == 0) {
				finished = true;
				//System.out.println("SE shutdown");
				BGPEval.getCurrentExeService().shutdownNow();
			}
			if(start.getNode().isConcrete()) {
				end.setBindings(results);
				synchronized (end) {
					end.notifyAll();
				}
			}else {
				start.setBindings(results);
				synchronized (start) {
					start.notifyAll();
				}
			}
			start.removeEdge(edge);
			end.removeEdge(edge);
			return;
		}
		//only one vertex is bound
		if(edge.getV1().isBound()) {
			start = edge.getV1();
			end = edge.getV2();
		} else {
			start = edge.getV2();
			end = edge.getV1();
		}
		results = QueryUtil.join(results, start.getBindings());
		
		results = QueryUtil.join(results, input);
		if(Config.debug) {
			System.out.println(edge+": "+results.size());
		}
		if(results.size() == 0) {
			finished = true;
			//System.out.println("SE shutdown");
			BGPEval.getCurrentExeService().shutdownNow();
		}
		end.setBindings(results);
		synchronized (end) {
			end.notifyAll();
		}
		start.removeEdge(edge);
		end.removeEdge(edge);
	}