public static SearchResult bfsSearch(final boolean useGraphSearch){
    	PriorityQueue<BFSSearchNode> fringe = new PriorityQueue<BFSSearchNode>();
    	SearchResult searchResult = new SearchResult();
    	fringe.add(new BFSSearchNode(startState, null, null, 0)); // add root node
     	searchResult.numNodesEnqueued++;
    	
    	while(!fringe.isEmpty()){
    		BFSSearchNode node = fringe.poll();
    		searchResult.numNodesDequeued++;
    		if(useGraphSearch)
    			node.getState().isClosed = true;
    		
      		if(node.getState().id == goalState.id){	// a goal node!
    			searchResult.solutionWasFound = true;
       			searchResult.solutionDistance = node.getTotalDistance();
       			searchResult.solutionPath = new Stack<Long>();
    			while(node != null){ // push path onto stack in reverse
    				searchResult.solutionPath.push(node.getState().id);
    				node = node.getParent();
    			}
    			break;
     		}
      		// add the neighbors to the fringe
      		ArrayList<BFSSearchNode> neighbors = node.getNeighbors();
      		if(null != neighbors){
      			if(!useGraphSearch){
      				fringe.addAll(neighbors);
      				searchResult.numNodesEnqueued += (long) neighbors.size();
      			}else{
      				for(BFSSearchNode n : neighbors){
      					if(!n.getState().isClosed && !fringe.contains(n)){
      						fringe.add(n);
      						searchResult.numNodesEnqueued++;
      					}
      				}
      			}	
      		}
     	} // end while
    	return searchResult;
    }