// $Id: lamarcschema.cpp,v 1.38 2018/01/03 21:33:05 mkkuhner Exp $

/*
Copyright 2002-2005 Mary K. Kuhner, Peter Beerli, and Joseph Felsenstein

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

*/

/* Authors: Mary Kuhner, Jon Yamato, and Joseph Felsenstein */


#include "local_build.h"
#include "parsetreeschema.h"
#include "xml_strings.h"

LamarcSchema::LamarcSchema()
{
    const bool required = true;
    const bool optional = false;
    const bool onlyone = true;
    const bool many = false;
    AddTag(xmlstr::XML_TAG_LAMARC);
    AddAttribute(optional,xmlstr::XML_TAG_LAMARC,xmlstr::XML_ATTRTYPE_VERSION);

    AddSubtag(required, onlyone, xmlstr::XML_TAG_LAMARC,xmlstr::XML_TAG_DATA);
    AddSubtag(optional, onlyone, xmlstr::XML_TAG_LAMARC,xmlstr::XML_TAG_FORCES);
    AddSubtag(optional, onlyone, xmlstr::XML_TAG_LAMARC,xmlstr::XML_TAG_CHAINS);
    AddSubtag(optional, onlyone, xmlstr::XML_TAG_LAMARC,xmlstr::XML_TAG_FORMAT);
    AddSubtag(optional, many, xmlstr::XML_TAG_LAMARC,xmlstr::XML_TAG_MODEL);

    AddSubtag(optional, onlyone, xmlstr::XML_TAG_FORCES,xmlstr::XML_TAG_COALESCENCE);

    //LS DEBUG:  is this valid? :
    //AddAttribute(optional ,xmlstr::XML_TAG_COALESCENCE,xmlstr::XML_ATTRTYPE_VALUE);

    AddSubtag(optional, onlyone, xmlstr::XML_TAG_COALESCENCE,xmlstr::XML_TAG_START_VALUES);
    AddSubtag(optional, onlyone, xmlstr::XML_TAG_COALESCENCE,xmlstr::XML_TAG_METHOD);
    AddSubtag(optional, onlyone, xmlstr::XML_TAG_COALESCENCE,xmlstr::XML_TAG_TRUEVALUE);
    AddSubtag(optional, onlyone, xmlstr::XML_TAG_COALESCENCE,xmlstr::XML_TAG_MAX_EVENTS);
    AddSubtag(optional, onlyone, xmlstr::XML_TAG_COALESCENCE,xmlstr::XML_TAG_CONSTRAINTS);
    AddSubtag(optional, many, xmlstr::XML_TAG_COALESCENCE,xmlstr::XML_TAG_GROUP);
    AddSubtag(optional, many, xmlstr::XML_TAG_COALESCENCE,xmlstr::XML_TAG_PRIOR);
    AddSubtag(optional, onlyone, xmlstr::XML_TAG_COALESCENCE,xmlstr::XML_TAG_PROFILES);

    AddSubtag(optional, onlyone, xmlstr::XML_TAG_FORCES,xmlstr::XML_TAG_DISEASE);
    AddAttribute(optional ,xmlstr::XML_TAG_DISEASE,xmlstr::XML_ATTRTYPE_VALUE);
    AddSubtag(optional, onlyone, xmlstr::XML_TAG_DISEASE,xmlstr::XML_TAG_START_VALUES);
    AddSubtag(optional, onlyone, xmlstr::XML_TAG_DISEASE,xmlstr::XML_TAG_METHOD);
    AddSubtag(optional, onlyone, xmlstr::XML_TAG_DISEASE,xmlstr::XML_TAG_MAX_EVENTS);
    AddSubtag(optional, onlyone, xmlstr::XML_TAG_DISEASE,xmlstr::XML_TAG_TRUEVALUE);
    AddSubtag(optional, onlyone, xmlstr::XML_TAG_DISEASE,xmlstr::XML_TAG_CONSTRAINTS);
    AddSubtag(optional, many, xmlstr::XML_TAG_DISEASE,xmlstr::XML_TAG_GROUP);
    AddSubtag(optional, many, xmlstr::XML_TAG_DISEASE,xmlstr::XML_TAG_PRIOR);
    AddSubtag(optional, onlyone, xmlstr::XML_TAG_DISEASE,xmlstr::XML_TAG_PROFILES);
    AddSubtag(optional, onlyone, xmlstr::XML_TAG_DISEASE,xmlstr::XML_TAG_DISEASELOCATION);

    AddSubtag(optional, onlyone, xmlstr::XML_TAG_FORCES,xmlstr::XML_TAG_GROWTH);
    AddAttribute(optional ,xmlstr::XML_TAG_GROWTH,xmlstr::XML_ATTRTYPE_TYPE);
    AddAttribute(optional ,xmlstr::XML_TAG_GROWTH,xmlstr::XML_ATTRTYPE_VALUE);

    AddSubtag(optional, onlyone, xmlstr::XML_TAG_GROWTH,xmlstr::XML_TAG_START_VALUES);
    AddSubtag(optional, onlyone, xmlstr::XML_TAG_GROWTH,xmlstr::XML_TAG_METHOD);
    AddSubtag(optional, onlyone, xmlstr::XML_TAG_GROWTH,xmlstr::XML_TAG_MAX_EVENTS);
    AddSubtag(optional, onlyone, xmlstr::XML_TAG_GROWTH,xmlstr::XML_TAG_TRUEVALUE);
    AddSubtag(optional, onlyone, xmlstr::XML_TAG_GROWTH,xmlstr::XML_TAG_CONSTRAINTS);
    AddSubtag(optional, many, xmlstr::XML_TAG_GROWTH,xmlstr::XML_TAG_GROUP);
    AddSubtag(optional, many, xmlstr::XML_TAG_GROWTH,xmlstr::XML_TAG_PRIOR);
    AddSubtag(optional, onlyone, xmlstr::XML_TAG_GROWTH,xmlstr::XML_TAG_PROFILES);

    AddSubtag(optional, onlyone, xmlstr::XML_TAG_FORCES,xmlstr::XML_TAG_LOGISTICSELECTION);
    AddAttribute(optional ,xmlstr::XML_TAG_LOGISTICSELECTION,xmlstr::XML_ATTRTYPE_VALUE);

    AddSubtag(optional, onlyone, xmlstr::XML_TAG_FORCES,xmlstr::XML_TAG_STOCHASTICSELECTION);
    AddAttribute(optional ,xmlstr::XML_TAG_STOCHASTICSELECTION,xmlstr::XML_ATTRTYPE_VALUE);

    AddSubtag(optional, onlyone, xmlstr::XML_TAG_STOCHASTICSELECTION,xmlstr::XML_TAG_START_VALUES);
    AddSubtag(optional, onlyone, xmlstr::XML_TAG_STOCHASTICSELECTION,xmlstr::XML_TAG_METHOD);
    AddSubtag(optional, onlyone, xmlstr::XML_TAG_STOCHASTICSELECTION,xmlstr::XML_TAG_MAX_EVENTS);
    AddSubtag(optional, onlyone, xmlstr::XML_TAG_STOCHASTICSELECTION,xmlstr::XML_TAG_TRUEVALUE);
    AddSubtag(optional, onlyone, xmlstr::XML_TAG_STOCHASTICSELECTION,xmlstr::XML_TAG_CONSTRAINTS);
    AddSubtag(optional, many, xmlstr::XML_TAG_STOCHASTICSELECTION,xmlstr::XML_TAG_GROUP);
    AddSubtag(optional, many, xmlstr::XML_TAG_STOCHASTICSELECTION,xmlstr::XML_TAG_PRIOR);
    AddSubtag(optional, onlyone, xmlstr::XML_TAG_STOCHASTICSELECTION,xmlstr::XML_TAG_PROFILES);

    AddSubtag(optional, onlyone, xmlstr::XML_TAG_LOGISTICSELECTION,xmlstr::XML_TAG_START_VALUES);
    AddSubtag(optional, onlyone, xmlstr::XML_TAG_LOGISTICSELECTION,xmlstr::XML_TAG_METHOD);
    AddSubtag(optional, onlyone, xmlstr::XML_TAG_LOGISTICSELECTION,xmlstr::XML_TAG_MAX_EVENTS);
    AddSubtag(optional, onlyone, xmlstr::XML_TAG_LOGISTICSELECTION,xmlstr::XML_TAG_TRUEVALUE);
    AddSubtag(optional, onlyone, xmlstr::XML_TAG_LOGISTICSELECTION,xmlstr::XML_TAG_CONSTRAINTS);
    AddSubtag(optional, many, xmlstr::XML_TAG_LOGISTICSELECTION,xmlstr::XML_TAG_GROUP);
    AddSubtag(optional, many, xmlstr::XML_TAG_LOGISTICSELECTION,xmlstr::XML_TAG_PRIOR);
    AddSubtag(optional, onlyone, xmlstr::XML_TAG_LOGISTICSELECTION,xmlstr::XML_TAG_PROFILES);

    AddSubtag(optional, onlyone, xmlstr::XML_TAG_FORCES,xmlstr::XML_TAG_MIGRATION);
    AddAttribute(optional ,xmlstr::XML_TAG_MIGRATION,xmlstr::XML_ATTRTYPE_VALUE);
    AddSubtag(optional, onlyone, xmlstr::XML_TAG_MIGRATION,xmlstr::XML_TAG_START_VALUES);
    AddSubtag(optional, onlyone, xmlstr::XML_TAG_MIGRATION,xmlstr::XML_TAG_METHOD);
    AddSubtag(optional, onlyone, xmlstr::XML_TAG_MIGRATION,xmlstr::XML_TAG_TRUEVALUE);
    AddSubtag(optional, onlyone, xmlstr::XML_TAG_MIGRATION,xmlstr::XML_TAG_MAX_EVENTS);
    AddSubtag(optional, onlyone, xmlstr::XML_TAG_MIGRATION,xmlstr::XML_TAG_CONSTRAINTS);
    AddSubtag(optional, many, xmlstr::XML_TAG_MIGRATION,xmlstr::XML_TAG_GROUP);
    AddSubtag(optional, many, xmlstr::XML_TAG_MIGRATION,xmlstr::XML_TAG_PRIOR);
    AddSubtag(optional, onlyone, xmlstr::XML_TAG_MIGRATION,xmlstr::XML_TAG_PROFILES);

    AddSubtag(optional, onlyone, xmlstr::XML_TAG_FORCES,xmlstr::XML_TAG_DIVMIG);
    AddAttribute(optional ,xmlstr::XML_TAG_DIVMIG,xmlstr::XML_ATTRTYPE_VALUE);
    AddSubtag(optional, onlyone, xmlstr::XML_TAG_DIVMIG,xmlstr::XML_TAG_START_VALUES);
    AddSubtag(optional, onlyone, xmlstr::XML_TAG_DIVMIG,xmlstr::XML_TAG_METHOD);
    AddSubtag(optional, onlyone, xmlstr::XML_TAG_DIVMIG,xmlstr::XML_TAG_TRUEVALUE);
    AddSubtag(optional, onlyone, xmlstr::XML_TAG_DIVMIG,xmlstr::XML_TAG_MAX_EVENTS);
    AddSubtag(optional, onlyone, xmlstr::XML_TAG_DIVMIG,xmlstr::XML_TAG_CONSTRAINTS);
    AddSubtag(optional, many, xmlstr::XML_TAG_DIVMIG,xmlstr::XML_TAG_GROUP);
    AddSubtag(optional, many, xmlstr::XML_TAG_DIVMIG,xmlstr::XML_TAG_PRIOR);
    AddSubtag(optional, onlyone, xmlstr::XML_TAG_DIVMIG,xmlstr::XML_TAG_PROFILES);

    AddSubtag(optional, onlyone, xmlstr::XML_TAG_FORCES,xmlstr::XML_TAG_DIVERGENCE);
    AddAttribute(optional ,xmlstr::XML_TAG_DIVERGENCE,xmlstr::XML_ATTRTYPE_VALUE);
    AddSubtag(optional, onlyone, xmlstr::XML_TAG_DIVERGENCE,xmlstr::XML_TAG_START_VALUES);
    AddSubtag(optional, onlyone, xmlstr::XML_TAG_DIVERGENCE,xmlstr::XML_TAG_METHOD);
    AddSubtag(optional, onlyone, xmlstr::XML_TAG_DIVERGENCE,xmlstr::XML_TAG_TRUEVALUE);
    AddSubtag(optional, onlyone, xmlstr::XML_TAG_DIVERGENCE,xmlstr::XML_TAG_MAX_EVENTS);
    AddSubtag(optional, onlyone, xmlstr::XML_TAG_DIVERGENCE,xmlstr::XML_TAG_CONSTRAINTS);
    AddSubtag(optional, many, xmlstr::XML_TAG_DIVERGENCE,xmlstr::XML_TAG_GROUP);
    AddSubtag(optional, many, xmlstr::XML_TAG_DIVERGENCE,xmlstr::XML_TAG_PRIOR);
    AddSubtag(optional, onlyone, xmlstr::XML_TAG_DIVERGENCE,xmlstr::XML_TAG_PROFILES);
    AddSubtag(optional, onlyone, xmlstr::XML_TAG_DIVERGENCE,xmlstr::XML_TAG_POPTREE);

    AddSubtag(optional, many, xmlstr::XML_TAG_POPTREE,xmlstr::XML_TAG_EPOCH_BOUNDARY);
    AddSubtag(optional, onlyone, xmlstr::XML_TAG_EPOCH_BOUNDARY,xmlstr::XML_TAG_NEWPOP);
    AddSubtag(optional, onlyone, xmlstr::XML_TAG_EPOCH_BOUNDARY,xmlstr::XML_TAG_ANCESTOR);

    AddSubtag(optional, onlyone, xmlstr::XML_TAG_FORCES,xmlstr::XML_TAG_RECOMBINATION);
    AddAttribute(optional ,xmlstr::XML_TAG_RECOMBINATION,xmlstr::XML_ATTRTYPE_VALUE);
    AddSubtag(optional, onlyone, xmlstr::XML_TAG_RECOMBINATION,xmlstr::XML_TAG_START_VALUES);
    AddSubtag(optional, onlyone, xmlstr::XML_TAG_RECOMBINATION,xmlstr::XML_TAG_METHOD);
    AddSubtag(optional, onlyone, xmlstr::XML_TAG_RECOMBINATION,xmlstr::XML_TAG_TRUEVALUE);
    AddSubtag(optional, onlyone, xmlstr::XML_TAG_RECOMBINATION,xmlstr::XML_TAG_MAX_EVENTS);
    AddSubtag(optional, onlyone, xmlstr::XML_TAG_RECOMBINATION,xmlstr::XML_TAG_CONSTRAINTS);
    AddSubtag(optional, many, xmlstr::XML_TAG_RECOMBINATION,xmlstr::XML_TAG_GROUP);
    AddSubtag(optional, many, xmlstr::XML_TAG_RECOMBINATION,xmlstr::XML_TAG_PRIOR);
    AddSubtag(optional, onlyone, xmlstr::XML_TAG_RECOMBINATION,xmlstr::XML_TAG_PROFILES);

    AddSubtag(optional, onlyone, xmlstr::XML_TAG_FORCES,xmlstr::XML_TAG_REGION_GAMMA);
    AddSubtag(optional, onlyone, xmlstr::XML_TAG_REGION_GAMMA,xmlstr::XML_TAG_START_VALUES);
    AddSubtag(optional, onlyone, xmlstr::XML_TAG_REGION_GAMMA,xmlstr::XML_TAG_PROFILES);
    AddSubtag(optional, onlyone, xmlstr::XML_TAG_REGION_GAMMA,xmlstr::XML_TAG_CONSTRAINTS);

    AddAttribute(optional, xmlstr::XML_TAG_GROUP,xmlstr::XML_ATTRTYPE_CONSTRAINT);

    AddAttribute(required, xmlstr::XML_TAG_PRIOR,xmlstr::XML_ATTRTYPE_TYPE);
    AddSubtag(required, onlyone, xmlstr::XML_TAG_PRIOR,xmlstr::XML_TAG_PRIORLOWERBOUND);
    AddSubtag(required, onlyone, xmlstr::XML_TAG_PRIOR,xmlstr::XML_TAG_PRIORUPPERBOUND);
    AddSubtag(optional, onlyone, xmlstr::XML_TAG_PRIOR,xmlstr::XML_TAG_PARAMINDEX);

#ifdef LAMARC_NEW_FEATURE_RELATIVE_SAMPLING
    AddSubtag(optional, onlyone, xmlstr::XML_TAG_PRIOR,xmlstr::XML_TAG_RELATIVE_SAMPLE_RATE);
#endif

    AddSubtag(optional, onlyone, xmlstr::XML_TAG_CHAINS,xmlstr::XML_TAG_REPLICATES);
    AddSubtag(optional, onlyone, xmlstr::XML_TAG_CHAINS,xmlstr::XML_TAG_HEATING);
    AddSubtag(optional, onlyone, xmlstr::XML_TAG_CHAINS,xmlstr::XML_TAG_STRATEGY);
    AddSubtag(optional, onlyone, xmlstr::XML_TAG_CHAINS,xmlstr::XML_TAG_INITIAL);
    AddSubtag(optional, onlyone, xmlstr::XML_TAG_CHAINS,xmlstr::XML_TAG_FINAL);
    AddSubtag(optional, onlyone, xmlstr::XML_TAG_CHAINS,xmlstr::XML_TAG_BAYESIAN_ANALYSIS);
    AddSubtag(optional, onlyone, xmlstr::XML_TAG_HEATING,xmlstr::XML_TAG_HEATING_STRATEGY);
    AddSubtag(optional, onlyone, xmlstr::XML_TAG_HEATING,xmlstr::XML_TAG_TEMPERATURES);
    AddSubtag(optional, onlyone, xmlstr::XML_TAG_HEATING,xmlstr::XML_TAG_SWAP_INTERVAL);
    AddSubtag(optional, onlyone, xmlstr::XML_TAG_STRATEGY,xmlstr::XML_TAG_BAYESIAN);
    AddSubtag(optional, onlyone, xmlstr::XML_TAG_STRATEGY,xmlstr::XML_TAG_RESIMULATING);
    AddSubtag(optional, onlyone, xmlstr::XML_TAG_STRATEGY,xmlstr::XML_TAG_HAPLOTYPING);
    AddSubtag(optional, onlyone, xmlstr::XML_TAG_STRATEGY,xmlstr::XML_TAG_LOCUSARRANGER);
    AddSubtag(optional, onlyone, xmlstr::XML_TAG_STRATEGY,xmlstr::XML_TAG_TREESIZE);
    AddSubtag(optional, onlyone, xmlstr::XML_TAG_STRATEGY,xmlstr::XML_TAG_EPOCHSIZEARRANGER);
    AddSubtag(optional, onlyone, xmlstr::XML_TAG_INITIAL,xmlstr::XML_TAG_NUMBER);
    AddSubtag(optional, onlyone, xmlstr::XML_TAG_INITIAL,xmlstr::XML_TAG_SAMPLES);
    AddSubtag(optional, onlyone, xmlstr::XML_TAG_INITIAL,xmlstr::XML_TAG_DISCARD);
    AddSubtag(optional, onlyone, xmlstr::XML_TAG_INITIAL,xmlstr::XML_TAG_INTERVAL);
    AddSubtag(optional, onlyone, xmlstr::XML_TAG_FINAL, xmlstr::XML_TAG_NUMBER);
    AddSubtag(optional, onlyone, xmlstr::XML_TAG_FINAL, xmlstr::XML_TAG_SAMPLES);
    AddSubtag(optional, onlyone, xmlstr::XML_TAG_FINAL, xmlstr::XML_TAG_DISCARD);
    AddSubtag(optional, onlyone, xmlstr::XML_TAG_FINAL, xmlstr::XML_TAG_INTERVAL);

    AddSubtag(optional, onlyone, xmlstr::XML_TAG_FORMAT, xmlstr::XML_TAG_PROGRESS_REPORTS);
    DeprecatedSubtag(xmlstr::XML_TAG_FORMAT, xmlstr::XML_TAG_ECHO);
    DeprecatedSubtag(xmlstr::XML_TAG_FORMAT, xmlstr::XML_TAG_PARAMETER_FILE);
    DeprecatedSubtag(xmlstr::XML_TAG_FORMAT, xmlstr::XML_TAG_OLD_SUMMARY_FILE);
    AddSubtag(optional, onlyone, xmlstr::XML_TAG_FORMAT, xmlstr::XML_TAG_VERBOSITY);
    AddSubtag(optional, onlyone, xmlstr::XML_TAG_FORMAT, xmlstr::XML_TAG_PLOTTING);
    AddSubtag(optional, onlyone, xmlstr::XML_TAG_FORMAT, xmlstr::XML_TAG_SEED);
    AddSubtag(optional, onlyone, xmlstr::XML_TAG_FORMAT, xmlstr::XML_TAG_SEED_FROM_CLOCK);
    AddSubtag(optional, onlyone, xmlstr::XML_TAG_FORMAT, xmlstr::XML_TAG_RESULTS_FILE);
    AddSubtag(optional, onlyone, xmlstr::XML_TAG_FORMAT, xmlstr::XML_TAG_IN_SUMMARY_FILE);
    AddSubtag(optional, onlyone, xmlstr::XML_TAG_FORMAT, xmlstr::XML_TAG_OUT_SUMMARY_FILE);
    AddSubtag(optional, onlyone, xmlstr::XML_TAG_FORMAT, xmlstr::XML_TAG_OUT_XML_FILE);
    AddSubtag(optional, onlyone, xmlstr::XML_TAG_FORMAT, xmlstr::XML_TAG_REPORT_XML_FILE);

#ifdef LAMARC_QA_TREE_DUMP
    AddSubtag(optional, onlyone, xmlstr::XML_TAG_FORMAT, xmlstr::XML_TAG_ARGFILE_PREFIX);
    AddSubtag(optional, onlyone, xmlstr::XML_TAG_FORMAT, xmlstr::XML_TAG_MANY_ARGFILES);
#endif // LAMARC_QA_TREE_DUMP

    AddSubtag(optional, onlyone, xmlstr::XML_TAG_FORMAT, xmlstr::XML_TAG_CURVEFILE_PREFIX);
    AddSubtag(optional, onlyone, xmlstr::XML_TAG_FORMAT, xmlstr::XML_TAG_NEWICKTREEFILE_PREFIX);
    AddSubtag(optional, onlyone, xmlstr::XML_TAG_FORMAT, xmlstr::XML_TAG_PROFILE_PREFIX);
    AddSubtag(optional, onlyone, xmlstr::XML_TAG_FORMAT, xmlstr::XML_TAG_RECLOCFILE_PREFIX);
    AddSubtag(optional, onlyone, xmlstr::XML_TAG_FORMAT, xmlstr::XML_TAG_TRACEFILE_PREFIX);

#ifdef LAMARC_QA_TREE_DUMP
    AddSubtag(optional, onlyone, xmlstr::XML_TAG_FORMAT, xmlstr::XML_TAG_USE_ARGFILES);
#endif // LAMARC_QA_TREE_DUMP

    AddSubtag(optional, onlyone, xmlstr::XML_TAG_FORMAT, xmlstr::XML_TAG_USE_CURVEFILES);
    AddSubtag(optional, onlyone, xmlstr::XML_TAG_FORMAT, xmlstr::XML_TAG_USE_IN_SUMMARY);
    AddSubtag(optional, onlyone, xmlstr::XML_TAG_FORMAT, xmlstr::XML_TAG_USE_NEWICKTREEFILE);
    AddSubtag(optional, onlyone, xmlstr::XML_TAG_FORMAT, xmlstr::XML_TAG_USE_OUT_SUMMARY);
    AddSubtag(optional, onlyone, xmlstr::XML_TAG_FORMAT, xmlstr::XML_TAG_USE_RECLOCFILE);
    AddSubtag(optional, onlyone, xmlstr::XML_TAG_FORMAT, xmlstr::XML_TAG_USE_TRACEFILE);
    AddSubtag(optional, onlyone, xmlstr::XML_TAG_FORMAT, xmlstr::XML_TAG_CONVERT_OUTPUT);
    AddSubtag(optional, onlyone, xmlstr::XML_TAG_PLOTTING, xmlstr::XML_TAG_PROFILE);
    AddSubtag(optional, onlyone, xmlstr::XML_TAG_PLOTTING, xmlstr::XML_TAG_POSTERIOR);

    AddSubtag(required, many, xmlstr::XML_TAG_DATA,xmlstr::XML_TAG_REGION);

    AddAttribute(optional, xmlstr::XML_TAG_REGION,xmlstr::XML_ATTRTYPE_NAME);
    AddSubtag(optional, many, xmlstr::XML_TAG_REGION,xmlstr::XML_TAG_MODEL);
    AddSubtag(optional, onlyone, xmlstr::XML_TAG_REGION,xmlstr::XML_TAG_SPACING);
    AddSubtag(required, many, xmlstr::XML_TAG_REGION,xmlstr::XML_TAG_POPULATION);
    AddSubtag(optional, onlyone, xmlstr::XML_TAG_REGION,xmlstr::XML_TAG_EFFECTIVE_POPSIZE);

    // Turn on Newick tree and ARG input.
    AddSubtag(optional, onlyone, xmlstr::XML_TAG_REGION,xmlstr::XML_TAG_TREE);
    AddAttribute(required, xmlstr::XML_TAG_TREE,xmlstr::XML_ATTRTYPE_TYPE);
    AddSubtag(optional, many, xmlstr::XML_TAG_TREE,xmlstr::XML_TAG_KEY);
    AddAttribute(required, xmlstr::XML_TAG_KEY,xmlstr::XML_ATTRTYPE_ID);
    AddAttribute(required, xmlstr::XML_TAG_KEY,xmlstr::XML_ATTRTYPE_FOR);
    AddAttribute(required, xmlstr::XML_TAG_KEY,xmlstr::XML_ATTRTYPE_ATTR_NAME);
    AddAttribute(required, xmlstr::XML_TAG_KEY,xmlstr::XML_ATTRTYPE_ATTR_TYPE);
    AddSubtag(optional, onlyone, xmlstr::XML_TAG_TREE,xmlstr::XML_TAG_GRAPH);
    AddAttribute(required, xmlstr::XML_TAG_GRAPH,xmlstr::XML_ATTRTYPE_ID);
    AddAttribute(required, xmlstr::XML_TAG_GRAPH,xmlstr::XML_ATTRTYPE_EDGEDEFAULT);
    AddSubtag(optional, many, xmlstr::XML_TAG_GRAPH,xmlstr::XML_TAG_NODE);
    AddAttribute(required, xmlstr::XML_TAG_NODE,xmlstr::XML_ATTRTYPE_ID);
    AddSubtag(required, many, xmlstr::XML_TAG_NODE,xmlstr::XML_TAG_ARGDATA);
    AddAttribute(required, xmlstr::XML_TAG_ARGDATA,xmlstr::XML_ATTRTYPE_KEY);
    AddSubtag(optional, many, xmlstr::XML_TAG_GRAPH,xmlstr::XML_TAG_EDGE);
    AddAttribute(required, xmlstr::XML_TAG_EDGE,xmlstr::XML_ATTRTYPE_SOURCE);
    AddAttribute(required, xmlstr::XML_TAG_EDGE,xmlstr::XML_ATTRTYPE_TARGET);
    AddSubtag(required, many, xmlstr::XML_TAG_EDGE,xmlstr::XML_TAG_ARGDATA);

    //The 'traits' tag
    AddSubtag(optional, onlyone, xmlstr::XML_TAG_REGION,xmlstr::XML_TAG_TRAITS);
    AddSubtag(required, many, xmlstr::XML_TAG_TRAITS,xmlstr::XML_TAG_TRAIT);
    AddSubtag(required, onlyone, xmlstr::XML_TAG_TRAIT,xmlstr::XML_TAG_NAME);
    AddSubtag(optional, onlyone, xmlstr::XML_TAG_TRAIT,xmlstr::XML_TAG_ANALYSIS);
    AddSubtag(optional, onlyone, xmlstr::XML_TAG_TRAIT,xmlstr::XML_TAG_POSSIBLE_LOCATIONS);
    AddSubtag(required, many, xmlstr::XML_TAG_POSSIBLE_LOCATIONS,xmlstr::XML_TAG_RANGE);
    AddSubtag(required, onlyone, xmlstr::XML_TAG_RANGE,xmlstr::XML_TAG_START);
    AddSubtag(required, onlyone, xmlstr::XML_TAG_RANGE,xmlstr::XML_TAG_END);

    //DeprecatedSubtag(xmlstr::XML_TAG_TRAITS,xmlstr::XML_TAG_POSSIBLE_ALLELES);
    AddSubtag(optional, onlyone, xmlstr::XML_TAG_TRAIT,xmlstr::XML_TAG_PHENOTYPES);
    AddSubtag(optional, onlyone, xmlstr::XML_TAG_TRAIT,xmlstr::XML_TAG_MODEL);
    AddSubtag(required, many, xmlstr::XML_TAG_PHENOTYPES,xmlstr::XML_TAG_GENOTYPE);
    AddSubtag(required, onlyone, xmlstr::XML_TAG_GENOTYPE,xmlstr::XML_TAG_ALLELES);
    AddSubtag(required, many, xmlstr::XML_TAG_GENOTYPE,xmlstr::XML_TAG_PHENOTYPE);
    AddSubtag(required, many, xmlstr::XML_TAG_PHENOTYPE,xmlstr::XML_TAG_PHENOTYPE_NAME);
    AddSubtag(required, many, xmlstr::XML_TAG_PHENOTYPE,xmlstr::XML_TAG_PENETRANCE);

    AddAttribute(optional, xmlstr::XML_TAG_POPULATION,xmlstr::XML_ATTRTYPE_NAME);
    AddSubtag(optional, many, xmlstr::XML_TAG_POPULATION,xmlstr::XML_TAG_INDIVIDUAL);
    AddSubtag(optional, onlyone, xmlstr::XML_TAG_POPULATION,xmlstr::XML_TAG_PANEL);

    AddAttribute(optional, xmlstr::XML_TAG_INDIVIDUAL,xmlstr::XML_ATTRTYPE_NAME);
    AddSubtag(required, many, xmlstr::XML_TAG_INDIVIDUAL,xmlstr::XML_TAG_SAMPLE);

    AddAttribute(optional, xmlstr::XML_TAG_PANEL,xmlstr::XML_ATTRTYPE_NAME);
    AddAttribute(optional, xmlstr::XML_TAG_PANEL,xmlstr::XML_ATTRTYPE_LOCUS_NAME);
    AddSubtag(required, onlyone, xmlstr::XML_TAG_PANEL,xmlstr::XML_TAG_PANELSIZE);

    // LS DEBUG -- fill in hierarchy for genotype resolutions
    AddSubtag(optional, many, xmlstr::XML_TAG_INDIVIDUAL,xmlstr::XML_TAG_GENOTYPE_RESOLUTIONS);
    AddSubtag(required, onlyone, xmlstr::XML_TAG_GENOTYPE_RESOLUTIONS, xmlstr::XML_TAG_TRAIT_NAME);
    AddSubtag(required, many, xmlstr::XML_TAG_GENOTYPE_RESOLUTIONS, xmlstr::XML_TAG_HAPLOTYPES);
    AddSubtag(required, onlyone, xmlstr::XML_TAG_HAPLOTYPES, xmlstr::XML_TAG_ALLELES);
    AddSubtag(optional, onlyone, xmlstr::XML_TAG_HAPLOTYPES, xmlstr::XML_TAG_PENETRANCE);
    AddSubtag(optional, many   , xmlstr::XML_TAG_INDIVIDUAL,xmlstr::XML_TAG_PHASE);
    AddAttribute(optional, xmlstr::XML_TAG_PHASE,xmlstr::XML_ATTRTYPE_TYPE);

    AddAttribute(optional, xmlstr::XML_TAG_SAMPLE,xmlstr::XML_ATTRTYPE_NAME);
    AddSubtag(required, many, xmlstr::XML_TAG_SAMPLE,xmlstr::XML_TAG_DATABLOCK);
    AddSubtag(optional, onlyone, xmlstr::XML_TAG_SAMPLE,xmlstr::XML_TAG_STATUS);
    AddSubtag(optional, many, xmlstr::XML_TAG_STATUS,xmlstr::XML_TAG_DISEASESTATUS);

    AddAttribute(required, xmlstr::XML_TAG_DATABLOCK,xmlstr::XML_ATTRTYPE_TYPE);
    AddAttribute(optional, xmlstr::XML_TAG_DATABLOCK,xmlstr::XML_ATTRTYPE_SOURCE);
    AddAttribute(optional, xmlstr::XML_TAG_DATABLOCK,xmlstr::XML_ATTRTYPE_LOCUS_NAME);

    AddAttribute(required, xmlstr::XML_TAG_MODEL,xmlstr::XML_ATTRTYPE_NAME);
    AddSubtag(optional, onlyone, xmlstr::XML_TAG_MODEL,xmlstr::XML_TAG_AUTOCORRELATION);
    AddSubtag(optional, onlyone, xmlstr::XML_TAG_MODEL,xmlstr::XML_TAG_BASE_FREQS);
    AddSubtag(optional, onlyone, xmlstr::XML_TAG_MODEL,xmlstr::XML_TAG_GTRRATES);
    AddSubtag(optional, onlyone, xmlstr::XML_TAG_MODEL,xmlstr::XML_TAG_CATEGORIES);
    AddSubtag(optional, onlyone, xmlstr::XML_TAG_MODEL,xmlstr::XML_TAG_NORMALIZE);
    AddSubtag(optional, onlyone, xmlstr::XML_TAG_MODEL,xmlstr::XML_TAG_TTRATIO);
    AddSubtag(optional, onlyone, xmlstr::XML_TAG_MODEL,xmlstr::XML_TAG_RELATIVE_MURATE);
    AddSubtag(optional, onlyone, xmlstr::XML_TAG_MODEL,xmlstr::XML_TAG_ALPHA);
    AddSubtag(optional, onlyone, xmlstr::XML_TAG_MODEL,xmlstr::XML_TAG_ISOPT);
    AddSubtag(optional, onlyone, xmlstr::XML_TAG_MODEL,xmlstr::XML_TAG_PER_BASE_ERROR_RATE);
    AddSubtag(optional, onlyone, xmlstr::XML_TAG_CATEGORIES,xmlstr::XML_TAG_NUM_CATEGORIES);
    AddSubtag(optional, onlyone, xmlstr::XML_TAG_CATEGORIES,xmlstr::XML_TAG_RATES);
    AddSubtag(optional, onlyone, xmlstr::XML_TAG_CATEGORIES,xmlstr::XML_TAG_PROBABILITIES);
    AddSubtag(optional, onlyone, xmlstr::XML_TAG_CATEGORIES,xmlstr::XML_TAG_AUTOCORRELATION);

    AddSubtag(required, many, xmlstr::XML_TAG_SPACING,xmlstr::XML_TAG_BLOCK);

    AddAttribute(optional, xmlstr::XML_TAG_BLOCK,xmlstr::XML_ATTRTYPE_NAME);
    DeprecatedSubtag(xmlstr::XML_TAG_BLOCK,xmlstr::XML_TAG_MARKER_WEIGHTS);
    AddSubtag(optional, onlyone, xmlstr::XML_TAG_BLOCK,xmlstr::XML_TAG_MAP_POSITION);
    AddSubtag(optional, onlyone, xmlstr::XML_TAG_BLOCK,xmlstr::XML_TAG_LENGTH);
    AddSubtag(optional, onlyone, xmlstr::XML_TAG_BLOCK,xmlstr::XML_TAG_LOCATIONS);
    AddSubtag(optional, onlyone, xmlstr::XML_TAG_BLOCK,xmlstr::XML_TAG_OFFSET);

}

LamarcSchema::~LamarcSchema()
{
}

//____________________________________________________________________________________
