public Object parseXMLObject(XMLObject xo) throws XMLParseException {
          /*
          boolean conditionOnRoot = xo.getAttribute(CONDITION, false);

          FullyConjugateMultivariateTraitLikelihood traitModel = (FullyConjugateMultivariateTraitLikelihood)
                  xo.getChild(FullyConjugateMultivariateTraitLikelihood.class);
          */

          TreeTraitNormalDistributionModel treeTraitModel =
              (TreeTraitNormalDistributionModel)
                  xo.getChild(TreeTraitNormalDistributionModel.class);

          MultivariateDistributionLikelihood likelihood =
              new MultivariateDistributionLikelihood(
                  //  new TreeTraitNormalDistributionModel(traitModel, conditionOnRoot)
                  treeTraitModel);

          XMLObject cxo = xo.getChild(DATA);
          for (int j = 0; j < cxo.getChildCount(); j++) {
            if (cxo.getChild(j) instanceof Parameter) {
              likelihood.addData((Parameter) cxo.getChild(j));
            } else {
              throw new XMLParseException(
                  "illegal element in " + xo.getName() + " element " + cxo.getName());
            }
          }
          return likelihood;
        }
        public Object parseXMLObject(XMLObject xo) throws XMLParseException {

          XMLObject cxo = xo.getChild(COUNTS);
          Parameter counts = (Parameter) cxo.getChild(Parameter.class);

          DirichletDistribution dirichlet = new DirichletDistribution(counts.getParameterValues());

          MultivariateDistributionLikelihood likelihood =
              new MultivariateDistributionLikelihood(dirichlet);

          cxo = xo.getChild(DATA);
          for (int j = 0; j < cxo.getChildCount(); j++) {
            if (cxo.getChild(j) instanceof Parameter) {
              likelihood.addData((Parameter) cxo.getChild(j));
            } else {
              throw new XMLParseException(
                  "illegal element in " + xo.getName() + " element " + cxo.getName());
            }
          }

          return likelihood;
        }
        public Object parseXMLObject(XMLObject xo) throws XMLParseException {

          MultivariateDistributionLikelihood likelihood;

          if (xo.hasAttribute(NON_INFORMATIVE) && xo.getBooleanAttribute(NON_INFORMATIVE)) {
            // Make non-informative settings
            XMLObject cxo = xo.getChild(DATA);
            int dim = ((MatrixParameter) cxo.getChild(0)).getColumnDimension();
            likelihood = new MultivariateDistributionLikelihood(new WishartDistribution(dim));
          } else {
            if (!xo.hasAttribute(DF) || !xo.hasChildNamed(SCALE_MATRIX)) {
              throw new XMLParseException("Must specify both a df and scaleMatrix");
            }

            double df = xo.getDoubleAttribute(DF);

            XMLObject cxo = xo.getChild(SCALE_MATRIX);
            MatrixParameter scaleMatrix = (MatrixParameter) cxo.getChild(MatrixParameter.class);

            likelihood =
                new MultivariateDistributionLikelihood(
                    new WishartDistribution(df, scaleMatrix.getParameterAsMatrix()));
          }

          XMLObject cxo = xo.getChild(DATA);
          for (int j = 0; j < cxo.getChildCount(); j++) {
            if (cxo.getChild(j) instanceof MatrixParameter) {
              likelihood.addData((MatrixParameter) cxo.getChild(j));
            } else {
              throw new XMLParseException(
                  "illegal element in " + xo.getName() + " element " + cxo.getName());
            }
          }

          return likelihood;
        }
        public Object parseXMLObject(XMLObject xo) throws XMLParseException {

          int df = xo.getIntegerAttribute(DF);

          XMLObject cxo = xo.getChild(SCALE_MATRIX);
          MatrixParameter scaleMatrix = (MatrixParameter) cxo.getChild(MatrixParameter.class);
          InverseWishartDistribution invWishart =
              new InverseWishartDistribution(df, scaleMatrix.getParameterAsMatrix());

          MultivariateDistributionLikelihood likelihood =
              new MultivariateDistributionLikelihood(invWishart);

          cxo = xo.getChild(DATA);
          for (int j = 0; j < cxo.getChildCount(); j++) {
            if (cxo.getChild(j) instanceof MatrixParameter) {
              likelihood.addData((MatrixParameter) cxo.getChild(j));
            } else {
              throw new XMLParseException(
                  "illegal element in " + xo.getName() + " element " + cxo.getName());
            }
          }

          return likelihood;
        }
        public Object parseXMLObject(XMLObject xo) throws XMLParseException {

          double[] shape;
          double[] scale;

          if (xo.hasChildNamed(MVGAMMA_SHAPE)) {

            XMLObject cxo = xo.getChild(MVGAMMA_SHAPE);
            shape = ((Parameter) cxo.getChild(Parameter.class)).getParameterValues();

            cxo = xo.getChild(MVGAMMA_SCALE);
            scale = ((Parameter) cxo.getChild(Parameter.class)).getParameterValues();

            if (shape.length != scale.length)
              throw new XMLParseException(
                  "Shape and scale have wrong dimensions in " + xo.getName() + " element");

          } else {

            XMLObject cxo = xo.getChild(MVN_MEAN);
            double[] mean = ((Parameter) cxo.getChild(Parameter.class)).getParameterValues();

            cxo = xo.getChild(MVN_CV);
            double[] cv = ((Parameter) cxo.getChild(Parameter.class)).getParameterValues();

            if (mean.length != cv.length)
              throw new XMLParseException(
                  "Mean and CV have wrong dimensions in " + xo.getName() + " element");

            final int dim = mean.length;
            shape = new double[dim];
            scale = new double[dim];

            for (int i = 0; i < dim; i++) {
              double c2 = cv[i] * cv[i];
              shape[i] = 1.0 / c2;
              scale[i] = c2 * mean[i];
            }
          }

          MultivariateDistributionLikelihood likelihood =
              new MultivariateDistributionLikelihood(
                  new MultivariateGammaDistribution(shape, scale));
          XMLObject cxo = xo.getChild(DATA);
          for (int j = 0; j < cxo.getChildCount(); j++) {
            if (cxo.getChild(j) instanceof Parameter) {
              Parameter data = (Parameter) cxo.getChild(j);
              likelihood.addData(data);
              if (data.getDimension() != shape.length)
                throw new XMLParseException(
                    "dim("
                        + data.getStatisticName()
                        + ") != "
                        + shape.length
                        + " in "
                        + xo.getName()
                        + "element");
            } else {
              throw new XMLParseException("illegal element in " + xo.getName() + " element");
            }
          }
          return likelihood;
        }
        public Object parseXMLObject(XMLObject xo) throws XMLParseException {

          XMLObject cxo = xo.getChild(MVN_MEAN);
          Parameter mean = (Parameter) cxo.getChild(Parameter.class);

          cxo = xo.getChild(MVN_PRECISION);
          MatrixParameter precision = (MatrixParameter) cxo.getChild(MatrixParameter.class);

          if (mean.getDimension() != precision.getRowDimension()
              || mean.getDimension() != precision.getColumnDimension())
            throw new XMLParseException(
                "Mean and precision have wrong dimensions in " + xo.getName() + " element");

          Transform[] transforms = parseListOfTransforms(xo, mean.getDimension());

          MultivariateDistributionLikelihood likelihood =
              new MultivariateDistributionLikelihood(
                  new MultivariateNormalDistribution(
                      mean.getParameterValues(), precision.getParameterAsMatrix()),
                  transforms);
          cxo = xo.getChild(DATA);
          if (cxo != null) {
            for (int j = 0; j < cxo.getChildCount(); j++) {
              if (cxo.getChild(j) instanceof Parameter) {
                Parameter data = (Parameter) cxo.getChild(j);
                if (data instanceof MatrixParameter) {
                  MatrixParameter matrix = (MatrixParameter) data;
                  if (matrix.getParameter(0).getDimension() != mean.getDimension())
                    throw new XMLParseException(
                        "dim("
                            + data.getStatisticName()
                            + ") = "
                            + matrix.getParameter(0).getDimension()
                            + " is not equal to dim("
                            + mean.getStatisticName()
                            + ") = "
                            + mean.getDimension()
                            + " in "
                            + xo.getName()
                            + "element");

                  for (int i = 0; i < matrix.getParameterCount(); i++) {
                    likelihood.addData(matrix.getParameter(i));
                  }
                } else {
                  if (data.getDimension() != mean.getDimension())
                    throw new XMLParseException(
                        "dim("
                            + data.getStatisticName()
                            + ") = "
                            + data.getDimension()
                            + " is not equal to dim("
                            + mean.getStatisticName()
                            + ") = "
                            + mean.getDimension()
                            + " in "
                            + xo.getName()
                            + "element");
                  likelihood.addData(data);
                }
              } else {
                throw new XMLParseException("illegal element in " + xo.getName() + " element");
              }
            }
          }

          return likelihood;
        }
        public Object parseXMLObject(XMLObject xo) throws XMLParseException {

          XMLObject cxo = xo.getChild(DistributionLikelihoodParser.DISTRIBUTION);
          ParametricMultivariateDistributionModel distribution =
              (ParametricMultivariateDistributionModel)
                  cxo.getChild(ParametricMultivariateDistributionModel.class);

          // Parse transforms here
          int maxDim = distribution.getMean().length;
          Transform[] transforms = parseListOfTransforms(xo, maxDim);

          MultivariateDistributionLikelihood likelihood =
              new MultivariateDistributionLikelihood(xo.getId(), distribution, transforms);

          boolean dataAsMatrix = xo.getAttribute(DATA_AS_MATRIX, false);

          cxo = xo.getChild(DATA);
          if (cxo != null) {
            for (int j = 0; j < cxo.getChildCount(); j++) {
              if (cxo.getChild(j) instanceof Parameter) {
                Parameter data = (Parameter) cxo.getChild(j);
                if (data instanceof MatrixParameter) {
                  MatrixParameter matrix = (MatrixParameter) data;
                  if (dataAsMatrix) {
                    likelihood.addData(matrix);
                  } else {
                    if (matrix.getParameter(0).getDimension() != distribution.getMean().length)
                      throw new XMLParseException(
                          "dim("
                              + data.getStatisticName()
                              + ") = "
                              + matrix.getParameter(0).getDimension()
                              + " is not equal to dim("
                              + distribution.getType()
                              + ") = "
                              + distribution.getMean().length
                              + " in "
                              + xo.getName()
                              + "element");

                    for (int i = 0; i < matrix.getParameterCount(); i++) {
                      likelihood.addData(matrix.getParameter(i));
                    }
                  }
                } else {
                  if (data.getDimension() != distribution.getMean().length)
                    throw new XMLParseException(
                        "dim("
                            + data.getStatisticName()
                            + ") = "
                            + data.getDimension()
                            + " is not equal to dim("
                            + distribution.getType()
                            + ") = "
                            + distribution.getMean().length
                            + " in "
                            + xo.getName()
                            + "element");
                  likelihood.addData(data);
                }
              } else {
                throw new XMLParseException("illegal element in " + xo.getName() + " element");
              }
            }
          }

          return likelihood;
        }