public LinkedList<ASemester> uniformCostSearch()
	{
		LinkedList<ASemester> optimalSemesterList = new LinkedList<ASemester>();

		if ( directoryOfClasses == null ) {
			System.err.println( "Error: directoryOfClasses does not exist");
			System.exit(1);
		}

		// instantiate the root semester, which contains any courses previously
		//  taken, considered as one semester
		ASemester sem = new ASemester(0, -1, 0, 2014, null, null, rootInheritedCourses, 0.0, 0.0);

		// set the root to active
		activeSemester = sem;

		// maintain explored?
		Set<ASemester> explored = new HashSet<ASemester>();

		// add the root to the frontier
		frontier.offer( sem );

		// track current depth
		currentDepth = 0;

		// nodes explored
		int nodeCount = 1;

		// keep track of time
		long startTime = System.nanoTime();
		
		ArrayList<ASemester> childSem = new ArrayList<ASemester>();
		
		while (true)
		{

			// failure condition. optimal not found and nothing to observe
			if (frontier.isEmpty())
			{
				
				optimalSemesterList = null; //returning failure
				System.out.println( "Unable to find a valid schedule.");
		
				break;
			}
							
				
				// we have reached a goal state.  return a linked list of semester
				//  objects for output and user feedback
				if (succeedsGoalTest(activeSemester))
				{
					optimalSemesterList.addFirst(activeSemester);
					
					//backtrack up to the root to get the schedules for each semester
					//along the path from the root to the goal semester

					System.out.println( "Semester Found");
					
					optimalSemesterList = activeSemester.getFinal();
					
					for( int x = 0; x < optimalSemesterList.size(); x++ ) {
						System.out.println( optimalSemesterList.get(x));
					}	
					
					System.out.println( " Nodes explored: "+nodeCount);
					System.out.println( " Time taken: "+(( System.nanoTime() - startTime ) / 1000000000 )+"s");
					
					break;
				}
				
				

				// if we're not at a goal state
				if (activeSemester.getDepth() <= numCourses )		{

					childSem = activeSemester.addChild();
					
					ArrayList<ASemester>temp = new ArrayList<ASemester>();
					
					// add new children to the frontier
					for ( int i=0; i<childSem.size(); i++ ) {
						frontier.offer( childSem.get(i) );						
					}

					nodeCount++;
					activeSemester = frontier.poll();
					
				}
				
				
		}		
		
		
		return optimalSemesterList;
		
		
	}