// Path: pmml-xgboost/src/main/java/org/jpmml/xgboost/visitors/TreeModelCompactor.java
// public class TreeModelCompactor extends AbstractTreeModelTransformer {
// 
// 	@Override
// 	public void enterNode(Node node){
// 		Object id = node.getId();
// 		Object score = node.getScore();
// 		Object defaultChild = node.getDefaultChild();
// 
// 		if(id == null){
// 			throw new UnsupportedElementException(node);
// 		} // End if
// 
// 		if(node.hasNodes()){
// 			List<Node> children = node.getNodes();
// 
// 			if(score != null || defaultChild == null || children.size() != 2){
// 				throw new UnsupportedElementException(node);
// 			}
// 
// 			Node firstChild = children.get(0);
// 			Node secondChild = children.get(1);
// 
// 			SimplePredicate firstPredicate = firstChild.requirePredicate(SimplePredicate.class);
// 			SimplePredicate secondPredicate = secondChild.requirePredicate(SimplePredicate.class);
// 
// 			checkFieldReference((HasFieldReference<?>)firstPredicate, secondPredicate);
// 			checkValue((HasValue<?>)firstPredicate, secondPredicate);
// 
// 			if(equalsNode(defaultChild, firstChild)){
// 				children = swapChildren(node);
// 
// 				firstChild = children.get(0);
// 				secondChild = children.get(1);
// 			} else
// 
// 			if(equalsNode(defaultChild, secondChild)){
// 				// Ignored
// 			} else
// 
// 			{
// 				throw new UnsupportedElementException(node);
// 			}
// 
// 			node.setDefaultChild(null);
// 
// 			secondChild.setPredicate(True.INSTANCE);
// 		} else
// 
// 		{
// 			if(score == null || defaultChild != null){
// 				throw new UnsupportedElementException(node);
// 			}
// 		}
// 
// 		node.setId(null);
// 	}
// 
// 	@Override
// 	public void exitNode(Node node){
// 		Predicate predicate = node.requirePredicate();
// 
// 		if(predicate instanceof True){
// 			Node parentNode = getParentNode();
// 
// 			if(parentNode == null){
// 				return;
// 			}
// 
// 			initScore(parentNode, node);
// 			replaceChildWithGrandchildren(parentNode, node);
// 		}
// 	}
// 
// 	@Override
// 	public void enterTreeModel(TreeModel treeModel){
// 		super.enterTreeModel(treeModel);
// 
// 		TreeModel.MissingValueStrategy missingValueStrategy = treeModel.getMissingValueStrategy();
// 		if(missingValueStrategy != TreeModel.MissingValueStrategy.DEFAULT_CHILD){
// 			throw new UnsupportedAttributeException(treeModel, missingValueStrategy);
// 		}
// 
// 		TreeModel.NoTrueChildStrategy noTrueChildStrategy = treeModel.getNoTrueChildStrategy();
// 		if(noTrueChildStrategy != TreeModel.NoTrueChildStrategy.RETURN_NULL_PREDICTION){
// 			throw new UnsupportedAttributeException(treeModel, noTrueChildStrategy);
// 		}
// 
// 		TreeModel.SplitCharacteristic splitCharacteristic = treeModel.getSplitCharacteristic();
// 		if(splitCharacteristic != TreeModel.SplitCharacteristic.BINARY_SPLIT){
// 			throw new UnsupportedAttributeException(treeModel, splitCharacteristic);
// 		}
// 
// 		treeModel
// 			.setMissingValueStrategy(TreeModel.MissingValueStrategy.NONE)
// 			.setNoTrueChildStrategy(TreeModel.NoTrueChildStrategy.RETURN_LAST_PREDICTION)
// 			.setSplitCharacteristic(TreeModel.SplitCharacteristic.MULTI_SPLIT);
// 	}
// 
// 	@Override
// 	public void exitTreeModel(TreeModel treeModel){
// 		super.exitTreeModel(treeModel);
// 	}
// }


import java.io.DataInput;
import java.io.EOFException;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import org.dmg.pmml.DataType;
import org.dmg.pmml.PMML;
import org.dmg.pmml.Visitor;
import org.dmg.pmml.mining.MiningModel;
import org.jpmml.converter.BinaryFeature;
import org.jpmml.converter.ContinuousFeature;
import org.jpmml.converter.Feature;
import org.jpmml.converter.Label;
import org.jpmml.converter.MissingValueFeature;
import org.jpmml.converter.Schema;
import org.jpmml.converter.ThresholdFeature;
import org.jpmml.converter.visitors.NaNAsMissingDecorator;
import org.jpmml.converter.visitors.TreeModelPruner;
import org.jpmml.xgboost.visitors.TreeModelCompactor;
		PMML pmml = encoder.encodePMML(miningModel);

		if((Boolean.TRUE).equals(nanAsMissing)){
 			Visitor visitor = new NaNAsMissingDecorator();

 			visitor.applyTo(pmml);
 		}

		return pmml;
	}

	public MiningModel encodeMiningModel(Map<String, ?> options, Schema schema){
		Boolean compact = (Boolean)options.get(HasXGBoostOptions.OPTION_COMPACT);
		Boolean numeric = (Boolean)options.get(HasXGBoostOptions.OPTION_NUMERIC);
		Boolean prune = (Boolean)options.get(HasXGBoostOptions.OPTION_PRUNE);
		Integer ntreeLimit = (Integer)options.get(HasXGBoostOptions.OPTION_NTREE_LIMIT);

		if(numeric == null){
			numeric = Boolean.TRUE;
		}

		MiningModel miningModel = this.gbtree.encodeMiningModel(this.obj, this.base_score, ntreeLimit, numeric, schema)
			.setAlgorithmName("XGBoost (" + this.gbtree.getAlgorithmName() + ")");

		if((Boolean.TRUE).equals(compact)){

			if((Boolean.FALSE).equals(numeric)){
				throw new IllegalArgumentException("Conflicting XGBoost options");
			}

// Path: pmml-xgboost/src/main/java/org/jpmml/xgboost/visitors/TreeModelCompactor.java
// public class TreeModelCompactor extends AbstractTreeModelTransformer {
// 
// 	@Override
// 	public void enterNode(Node node){
// 		Object id = node.getId();
// 		Object score = node.getScore();
// 		Object defaultChild = node.getDefaultChild();
// 
// 		if(id == null){
// 			throw new UnsupportedElementException(node);
// 		} // End if
// 
// 		if(node.hasNodes()){
// 			List<Node> children = node.getNodes();
// 
// 			if(score != null || defaultChild == null || children.size() != 2){
// 				throw new UnsupportedElementException(node);
// 			}
// 
// 			Node firstChild = children.get(0);
// 			Node secondChild = children.get(1);
// 
// 			SimplePredicate firstPredicate = firstChild.requirePredicate(SimplePredicate.class);
// 			SimplePredicate secondPredicate = secondChild.requirePredicate(SimplePredicate.class);
// 
// 			checkFieldReference((HasFieldReference<?>)firstPredicate, secondPredicate);
// 			checkValue((HasValue<?>)firstPredicate, secondPredicate);
// 
// 			if(equalsNode(defaultChild, firstChild)){
// 				children = swapChildren(node);
// 
// 				firstChild = children.get(0);
// 				secondChild = children.get(1);
// 			} else
// 
// 			if(equalsNode(defaultChild, secondChild)){
// 				// Ignored
// 			} else
// 
// 			{
// 				throw new UnsupportedElementException(node);
// 			}
// 
// 			node.setDefaultChild(null);
// 
// 			secondChild.setPredicate(True.INSTANCE);
// 		} else
// 
// 		{
// 			if(score == null || defaultChild != null){
// 				throw new UnsupportedElementException(node);
// 			}
// 		}
// 
// 		node.setId(null);
// 	}
// 
// 	@Override
// 	public void exitNode(Node node){
// 		Predicate predicate = node.requirePredicate();
// 
// 		if(predicate instanceof True){
// 			Node parentNode = getParentNode();
// 
// 			if(parentNode == null){
// 				return;
// 			}
// 
// 			initScore(parentNode, node);
// 			replaceChildWithGrandchildren(parentNode, node);
// 		}
// 	}
// 
// 	@Override
// 	public void enterTreeModel(TreeModel treeModel){
// 		super.enterTreeModel(treeModel);
// 
// 		TreeModel.MissingValueStrategy missingValueStrategy = treeModel.getMissingValueStrategy();
// 		if(missingValueStrategy != TreeModel.MissingValueStrategy.DEFAULT_CHILD){
// 			throw new UnsupportedAttributeException(treeModel, missingValueStrategy);
// 		}
// 
// 		TreeModel.NoTrueChildStrategy noTrueChildStrategy = treeModel.getNoTrueChildStrategy();
// 		if(noTrueChildStrategy != TreeModel.NoTrueChildStrategy.RETURN_NULL_PREDICTION){
// 			throw new UnsupportedAttributeException(treeModel, noTrueChildStrategy);
// 		}
// 
// 		TreeModel.SplitCharacteristic splitCharacteristic = treeModel.getSplitCharacteristic();
// 		if(splitCharacteristic != TreeModel.SplitCharacteristic.BINARY_SPLIT){
// 			throw new UnsupportedAttributeException(treeModel, splitCharacteristic);
// 		}
// 
// 		treeModel
// 			.setMissingValueStrategy(TreeModel.MissingValueStrategy.NONE)
// 			.setNoTrueChildStrategy(TreeModel.NoTrueChildStrategy.RETURN_LAST_PREDICTION)
// 			.setSplitCharacteristic(TreeModel.SplitCharacteristic.MULTI_SPLIT);
// 	}
// 
// 	@Override
// 	public void exitTreeModel(TreeModel treeModel){
// 		super.exitTreeModel(treeModel);
// 	}
// }


// Path: pmml-xgboost/src/main/java/org/jpmml/xgboost/Learner.java
import java.io.DataInput;
import java.io.EOFException;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import org.dmg.pmml.DataType;
import org.dmg.pmml.PMML;
import org.dmg.pmml.Visitor;
import org.dmg.pmml.mining.MiningModel;
import org.jpmml.converter.BinaryFeature;
import org.jpmml.converter.ContinuousFeature;
import org.jpmml.converter.Feature;
import org.jpmml.converter.Label;
import org.jpmml.converter.MissingValueFeature;
import org.jpmml.converter.Schema;
import org.jpmml.converter.ThresholdFeature;
import org.jpmml.converter.visitors.NaNAsMissingDecorator;
import org.jpmml.converter.visitors.TreeModelPruner;
import org.jpmml.xgboost.visitors.TreeModelCompactor;

		PMML pmml = encoder.encodePMML(miningModel);

		if((Boolean.TRUE).equals(nanAsMissing)){
 			Visitor visitor = new NaNAsMissingDecorator();

 			visitor.applyTo(pmml);
 		}

		return pmml;
	}

	public MiningModel encodeMiningModel(Map<String, ?> options, Schema schema){
		Boolean compact = (Boolean)options.get(HasXGBoostOptions.OPTION_COMPACT);
		Boolean numeric = (Boolean)options.get(HasXGBoostOptions.OPTION_NUMERIC);
		Boolean prune = (Boolean)options.get(HasXGBoostOptions.OPTION_PRUNE);
		Integer ntreeLimit = (Integer)options.get(HasXGBoostOptions.OPTION_NTREE_LIMIT);

		if(numeric == null){
			numeric = Boolean.TRUE;
		}

		MiningModel miningModel = this.gbtree.encodeMiningModel(this.obj, this.base_score, ntreeLimit, numeric, schema)
			.setAlgorithmName("XGBoost (" + this.gbtree.getAlgorithmName() + ")");

		if((Boolean.TRUE).equals(compact)){

			if((Boolean.FALSE).equals(numeric)){
				throw new IllegalArgumentException("Conflicting XGBoost options");
			}

			Visitor visitor = new TreeModelCompactor();