protected RegressionTree buildDepthLimitedTree(Instances instances, int maxDepth) {
		RegressionTree tree = new RegressionTree();
		final int limit = 5;
		// stats[0]: totalWeights
		// stats[1]: sum
		// stats[2]: weightedMean
		// stats[3]: splitEval
		double[] stats = new double[4];
		if (maxDepth <= 0) {
			getStats(instances, stats);
			tree.root = new RegressionTreeLeaf(stats[1]);
			return tree;
		}
		Map<TreeNode, Dataset> datasets = new HashMap<>();
		Map<TreeNode, Integer> depths = new HashMap<>();
		Dataset dataset = null;
		if (this.cache != null) {
			dataset = Dataset.create(this.cache, instances);
		} else {
			dataset = Dataset.get(instances);
		}
		tree.root = createNode(dataset, limit, stats);
		PriorityQueue<Element<TreeNode>> q = new PriorityQueue<>();
		q.add(new Element<TreeNode>(tree.root, stats[2]));
		datasets.put(tree.root, dataset);
		depths.put(tree.root, 0);

		while (!q.isEmpty()) {
			Element<TreeNode> elemt = q.remove();
			TreeNode node = elemt.element;
			Dataset data = datasets.get(node);
			int depth = depths.get(node);
			if (!node.isLeaf()) {
				TreeInteriorNode interiorNode = (TreeInteriorNode) node;
				Dataset left = new Dataset(data.instances);
				Dataset right = new Dataset(data.instances);
				split(data, interiorNode, left, right);

				if (depth >= maxDepth - 1) {
					getStats(left.instances, stats);
					interiorNode.left = new RegressionTreeLeaf(stats[2]);
					getStats(right.instances, stats);
					interiorNode.right = new RegressionTreeLeaf(stats[2]);
				} else {
					interiorNode.left = createNode(left, limit, stats);
					if (!interiorNode.left.isLeaf()) {
						q.add(new Element<TreeNode>(interiorNode.left, stats[3]));
						datasets.put(interiorNode.left, left);
						depths.put(interiorNode.left, depth + 1);
					}
					interiorNode.right = createNode(right, limit, stats);
					if (!interiorNode.right.isLeaf()) {
						q.add(new Element<TreeNode>(interiorNode.right, stats[3]));
						datasets.put(interiorNode.right, right);
						depths.put(interiorNode.right, depth + 1);
					}
				}
			}
		}

		return tree;
	}