public ParseTree optimise(ParseTree root) {
		//This is the root that will replace the unoptimised root
		ParseTree optimisedTree = new ParseTree();
		
		//Copy the root's data into the optimised tree
		optimisedTree.value = root.value;
		optimisedTree.attribute = root.attribute;
		
		//Optimise all children
		if (root.children != null && root.children.size() > 0)
			for (int i = 0; i < root.children.size(); i++)
				optimisedTree.children.add(optimise(root.children.get(i)));
		
		//Optimise the current node
		optimisedTree = optimiseNode(optimisedTree);
		
		return optimisedTree;
	}