private void prune(DataSet tune) {
		double originalAccuracy = calcTestAccuracy(tune, classify(tune));
//		System.out.println("Original Accuracy: "+originalAccuracy);
		// Can't really go about pruning if the root isn't internal
		if(root instanceof InternalDecTreeNode) {			
			InternalDecTreeNode nodeToPrune = null, parentNodeToPrune = null;			
			double maxAccuracy = originalAccuracy;
			
			InternalDecTreeNode savedInternalNode = (InternalDecTreeNode) root;
			LeafDecTreeNode prunedLeafNode = new LeafDecTreeNode(savedInternalNode.label, savedInternalNode.parentAttributeValue);
			
			// Test pruning the root node
			root = prunedLeafNode;
			// Calculate the test accuracy with this node pruned
			double accuracy = calcTestAccuracy(tune, classify(tune));
//			System.out.println("Prune Accuracy: "+accuracy);
			if(accuracy >= maxAccuracy) {
				maxAccuracy = accuracy;
				nodeToPrune = (InternalDecTreeNode)savedInternalNode;				
			}			
			
			// Return tree back to original state
			root = savedInternalNode;
			
			// Do a BFS search to determine which node to prune
			Queue<InternalDecTreeNode> queue = new LinkedList<InternalDecTreeNode>();
			queue.add((InternalDecTreeNode)root);
			while(!queue.isEmpty()) {
				InternalDecTreeNode internalNode = queue.remove();
				for (int i = 0; i < internalNode.children.size(); i++) {
					DecTreeNode child = internalNode.children.get(i);
					if(child instanceof InternalDecTreeNode) {
						// Calculate the test accuracy with this node pruned
						savedInternalNode = (InternalDecTreeNode) child;
						prunedLeafNode = new LeafDecTreeNode(savedInternalNode.label, savedInternalNode.parentAttributeValue);
						
						internalNode.removeChild(child);						
						internalNode.addChild(prunedLeafNode);
						
						accuracy = calcTestAccuracy(tune, classify(tune));
//						System.out.println("Prune Accuracy: "+accuracy);
						if(accuracy >= maxAccuracy) {
							maxAccuracy = accuracy;
							nodeToPrune = savedInternalNode;
							parentNodeToPrune = internalNode;
						}
						
						internalNode.removeChild(prunedLeafNode);
						internalNode.returnChild(i, child);
						
						queue.add(savedInternalNode);
					}
				}
			}
			
			// Prune the node if it's better than original accuracy
			if(nodeToPrune != null && maxAccuracy > originalAccuracy) {
				if(parentNodeToPrune != null) {
					parentNodeToPrune.removeChild(nodeToPrune);
					parentNodeToPrune.addChild(new LeafDecTreeNode(nodeToPrune.label, nodeToPrune.parentAttributeValue));

					// Keep pruning until we can't get better accuracy than current
					prune(tune);
				} else {
					root = new LeafDecTreeNode(nodeToPrune.label, nodeToPrune.parentAttributeValue);
				}
			} 
		}
	}