static void find_reachable_operations_recursive(Tags &reachable, NodeOperation *op)
{
	if (reachable.find(op) != reachable.end())
		return;
	reachable.insert(op);
	
	for (int i = 0; i < op->getNumberOfInputSockets(); ++i) {
		NodeOperationInput *input = op->getInputSocket(i);
		if (input->isConnected())
			find_reachable_operations_recursive(reachable, &input->getLink()->getOperation());
	}
	
	/* associated write-buffer operations are executed as well */
	if (op->isReadBufferOperation()) {
		ReadBufferOperation *read_op = (ReadBufferOperation *)op;
		MemoryProxy *memproxy = read_op->getMemoryProxy();
		find_reachable_operations_recursive(reachable, memproxy->getWriteBufferOperation());
	}
}
void NodeOperationBuilder::group_operations()
{
	for (Operations::const_iterator it = m_operations.begin(); it != m_operations.end(); ++it) {
		NodeOperation *op = *it;
		
		if (op->isOutputOperation(m_context->isRendering())) {
			ExecutionGroup *group = make_group(op);
			group->setOutputExecutionGroup(true);
		}
		
		/* add new groups for associated memory proxies where needed */
		if (op->isReadBufferOperation()) {
			ReadBufferOperation *read_op = (ReadBufferOperation *)op;
			MemoryProxy *memproxy = read_op->getMemoryProxy();
			
			if (memproxy->getExecutor() == NULL) {
				ExecutionGroup *group = make_group(memproxy->getWriteBufferOperation());
				memproxy->setExecutor(group);
			}
		}
	}
}