public void getKnightTour(mxAnalysisGraph aGraph, int xDim, int yDim, int startVertexValue) throws StructuralException
	{
		if (xDim < 5 || yDim < 5)
		{
			throw new IllegalArgumentException();
		}

		ArrayList<Object> resultPath = new ArrayList<Object>();
		int vertexNum = xDim * yDim;

		mxGraph graph = aGraph.getGraph();
		Object parent = graph.getDefaultParent();
		int vertexCount = 0;

		for (int i = 0; i < vertexNum; i++)
		{
			graph.insertVertex(parent, null, new Integer(vertexCount).toString(), 0, 0, 25, 25);
			vertexCount++;
		}

		// we have the board set up
		Object[] vertices = aGraph.getChildVertices(parent);

		//now we set up the starting conditions
		int currValue = startVertexValue;
		int[] currCoords = new int[2];
		Object oldMove = vertices[startVertexValue];
		currCoords = getVertexGridCoords(xDim, yDim, startVertexValue);
		resultPath.add(oldMove);
		Object nextMove = getNextKnightMove(aGraph, xDim, yDim, currCoords[0], currCoords[1], resultPath);
		mxCostFunction costFunction = aGraph.getGenerator().getCostFunction();
		mxGraphView view = graph.getView();
		
		//the main loop
		while (nextMove != null)
		{
			// connect current with the possible move that has minimum number of its (possible moves)
			graph.insertEdge(parent, null, null, oldMove, nextMove);
			resultPath.add(nextMove);
			// that vertex becomes the current vertex and we repeat until no possible moves
			
			currValue = (int) costFunction.getCost(new mxCellState(view, nextMove, null));
			currCoords = getVertexGridCoords(xDim, yDim, currValue);
			oldMove = nextMove;
			nextMove = getNextKnightMove(aGraph, xDim, yDim, currCoords[0], currCoords[1], resultPath);
		}

		if (resultPath.size() < vertexNum)
		{
			//the mirrored strategy should go here, instead of the exception
			//and the exception would be thrown only if the mirrored fails too
			throw new StructuralException("Could not generate a correct Knight tour with size " + xDim + " x " + yDim + ".");
		}
	};