public Node execute (SearchProblemInterface problem) {
	Node result = null, node, shallowestNode = null;
	resetStatistics();
	openlist.add(initialNode(problem));

	/* Loop until openlist is empty, search is cancelled, or
	 * solution is found. */
	while (true) {
	    node = openlist.poll();
	    if (node == null) {
		result = shallowestNode;
		break; // Open list empty, no solution found.
	    }
	    if (isCancelled) {
		result = null;
		break; // Search cancelled.
	    }
	    updateNofNodesVisited(node);
	    currentDepth = Math.max(currentDepth, node.depth);
	    if (!depthlimit.belowLimit(node)) {
		/* Depth limit reached. */
		nofNodesPruned++;
		if (shallowestNode == null ||
		    node.totalcost < shallowestNode.totalcost) {
		    shallowestNode = node;
		}
	    } else if (problem.isSolution(node.state)) {
		/* Solution found. */
		result = node; 
		break; // Solution found.
	    } else if (closedlist.contains(node.state)) {
		/* State already seen. */
		nofClosedListHits++;
	    } else {
		/* State not yet seen, not a solution, below limit. */
		closedlist.add(node.state);
		List<Node> children = node.expand(problem);
		openlist.addAll(children);
	    }
	}
	openlist.clear();
	closedlist.clear();
	return result;
    }