public interface Markups {

    // markups
    final static String SAVOTPARSER = "4.0";
    final static String XML = "XML";
    final static String VOTABLE = "VOTABLE";
    final static String TABLE = "TABLE";
    final static String FIELD = "FIELD";
    final static String FIELDREF = "FIELDref"; /* new since VOTAble 1.1 */

    final static String TABLEDATA = "TABLEDATA";
    final static String DESCRIPTION = "DESCRIPTION";
    final static String DATA = "DATA";
    final static String RESOURCE = "RESOURCE";
    final static String PARAM = "PARAM";
    final static String PARAMREF = "PARAMref"; /* new since VOTAble 1.1 */

    final static String DEFINITIONS = "DEFINITIONS";
    final static String LINK = "LINK";
    final static String GROUP = "GROUP"; /* new since VOTAble 1.1 */

    final static String INFO = "INFO";
    final static String TR = "TR";
    final static String TD = "TD";
    final static String COOSYS = "COOSYS";
    final static String SYSTEM = "SYSTEM";
    final static String OPTION = "OPTION";
    final static String FITS = "FITS";
    final static String STREAM = "STREAM";
    final static String BINARY = "BINARY";
    final static String VALUES = "VALUES";

    // attributes
    final static String ARRAYSIZE = "arraysize";
    final static String DATATYPE = "datatype";
    final static String EPOCH = "epoch";
    final static String EQUINOX = "equinox";
    final static String INCLUSIVE = "inclusive";
    final static String MAX = "max";
    final static String MIN = "min";
    final static String NAME = "name";
    final static String PRECISION = "precision";
    final static String REF = "ref";
    final static String TYPE = "type";
    final static String XTYPE = "xtype"; // since VOTable 1.2
    final static String UTYPE = "utype"; // since VOTable 1.1
    final static String UCD = "ucd";
    final static String UNIT = "unit";
    final static String VALUE = "value";
    final static String WIDTH = "width";
    final static String ID = "id";
    final static String CONTENTROLE = "content-role";
    final static String CONTENTTYPE = "content-type";
    final static String TITLE = "title";
    final static String HREF = "href";
    final static String GREF = "gref"; // deprecated since VOTable 1.1
    final static String ACTION = "action";
    final static String VERSION = "version";
    final static String ENCODING = "encoding";
    final static String EXTNUM = "extnum";
    final static String NULL = "null";
    final static String INVALID = "invalid";
    final static String ACTUATE = "actuate";
    final static String EXPIRES = "expires";
    final static String RIGHTS = "rights";
    final static String NROWS = "nrows"; // since VOTable 1.1
    final static String XMLNS = "xmlns";
    final static String XSI = "xsi";
    final static String XMLNSXSI = XMLNS + ":" + XSI;
    final static String XSI_NOSCHEMA = "noNamespaceSchemaLocation";
    final static String XSI_SCHEMA = "schemaLocation";
    final static String XSINOSCHEMA = XSI + ":" + XSI_NOSCHEMA;
    final static String XSISCHEMA = XSI + ":" + XSI_SCHEMA;
    final static String SYSTEM_ATTRIBUTE = "system";
} public final class SavotStatistics {

    private int iTablesGlobal = 0; // index of TABLE element
    private int iTablesLocal = 0; // index of TABLE element in current RESOURCE
    private int iTRGlobal = 0; // index of TR element
    private int iTRLocal = 0; // index of TR element in current TABLE
    private int iTDGlobal = 0; // index of TD element
    private int iTDLocal = 0; // index of TD element in current TABLE
    private int iResources = 0; // index of RESOURCES element
    private int iGroupsGlobal = 0; // index of GROUP element

    public void iTablesInc() {
        iTablesGlobal++;
        iTablesLocal++;
    }

    public void iTablesGlobalReset() {
        iTablesGlobal = 0;
    }

    public int getITablesGlobal() {
        return iTablesGlobal;
    }

    public void iTablesLocalReset() {
        iTablesLocal = 0;
    }

    public int getITablesLocal() {
        return iTablesLocal;
    }

    public void iTRInc() {
        iTRGlobal++;
        iTRLocal++;
    }

    public void iTRGlobalReset() {
        iTRGlobal = 0;
    }

    public int getITRGlobal() {
        return iTRGlobal;
    }

    public void iTRLocalReset() {
        iTRLocal = 0;
    }

    public int getITRLocal() {
        return iTRLocal;
    }

    public void iTDInc() {
        iTDGlobal++;
        iTDLocal++;
    }

    public void iTDGlobalReset() {
        iTDGlobal = 0;
    }

    public int getITDGlobal() {
        return iTDGlobal;
    }

    public void iTDLocalReset() {
        iTDLocal = 0;
    }

    public int getITDLocal() {
        return iTDLocal;
    }

    public void iResourcesInc() {
        iResources++;
    }

    public void iResourcesReset() {
        iResources = 0;
    }

    public void iResources(final int value) {
        iResources = value;
    }

    public int getIResources() {
        return iResources;
    }

    public void iGroupsGlobalInc() {
        iGroupsGlobal++;
    }

    public void iGroupsGlobalReset() {
        iGroupsGlobal = 0;
    }

    public void iGroupsGlobal(final int value) {
        iGroupsGlobal = value;
    }

    public int getIGroupsGlobal() {
        return iGroupsGlobal;
    }
} public enum VOTableTag {

    UNDEFINED,
    BINARY,
    COOSYS,
    DATA,
    DEFINITIONS,
    DESCRIPTION,
    FIELD,
    FIELDREF,
    FITS,
    GROUP,
    INFO,
    LINK,
    MIN,
    MAX,
    OPTION,
    PARAM,
    PARAMREF,
    RESOURCE,
    STREAM,
    SYSTEM,
    TABLE,
    TABLEDATA,
    TD,
    TR,
    VALUES,
    VOTABLE;

    /**
     * Return the VoTableTag corresponding to the given string (ignore case)
     * 
     * LBO: Note: equalsIgnoreCase() vs() equals as XML is case sensitive and VOTable specification says that clearly
     * 
     * @param name tag name to look up
     * @return VoTableTag or VoTableTag.UNDEFINED if no match
     */
    public static VOTableTag parseTag(final String name) {
        switch (name.charAt(0)) {
            case 'T':
            case 't':
                // note: String comparison using == because our kXml parser or Java Stax Parser provides interned strings using SymbolTable:
                if (Markups.TD == name) {
                    return TD;
                }
                if (Markups.TR == name) {
                    return TR;
                }
                // standard comparison fallback:
                if (Markups.TD.equalsIgnoreCase(name)) {
                    return TD;
                }
                if (Markups.TR.equalsIgnoreCase(name)) {
                    return TR;
                }
                if (Markups.TABLE.equalsIgnoreCase(name)) {
                    return TABLE;
                }
                if (Markups.TABLEDATA.equalsIgnoreCase(name)) {
                    return TABLEDATA;
                }
                break;

            case 'F':
            case 'f':
                if (Markups.FIELD.equalsIgnoreCase(name)) {
                    return FIELD;
                }
                if (Markups.FIELDREF.equalsIgnoreCase(name)) {
                    return FIELDREF;
                }
                if (Markups.FITS.equalsIgnoreCase(name)) {
                    return FITS;
                }
                break;

            case 'G':
            case 'g':
                if (Markups.GROUP.equalsIgnoreCase(name)) {
                    return GROUP;
                }
                break;

            case 'P':
            case 'p':
                if (Markups.PARAM.equalsIgnoreCase(name)) {
                    return PARAM;
                }
                if (Markups.PARAMREF.equalsIgnoreCase(name)) {
                    return PARAMREF;
                }
                break;

            case 'I':
            case 'i':
                if (Markups.INFO.equalsIgnoreCase(name)) {
                    return INFO;
                }
                break;

            case 'D':
            case 'd':
                if (Markups.DESCRIPTION.equalsIgnoreCase(name)) {
                    return DESCRIPTION;
                }
                if (Markups.DATA.equalsIgnoreCase(name)) {
                    return DATA;
                }
                if (Markups.DEFINITIONS.equalsIgnoreCase(name)) {
                    return DEFINITIONS;
                }
                break;

            case 'B':
            case 'b':
                if (Markups.BINARY.equalsIgnoreCase(name)) {
                    return BINARY;
                }
                break;

            case 'C':
            case 'c':
                if (Markups.COOSYS.equalsIgnoreCase(name)) {
                    return COOSYS;
                }
                break;

            case 'L':
            case 'l':
                if (Markups.LINK.equalsIgnoreCase(name)) {
                    return LINK;
                }
                break;

            case 'M':
            case 'm':
                if (Markups.MIN.equalsIgnoreCase(name)) {
                    return MIN;
                }
                if (Markups.MAX.equalsIgnoreCase(name)) {
                    return MAX;
                }
                break;

            case 'O':
            case 'o':
                if (Markups.OPTION.equalsIgnoreCase(name)) {
                    return OPTION;
                }
                break;

            case 'S':
            case 's':
                if (Markups.STREAM.equalsIgnoreCase(name)) {
                    return STREAM;
                }
                if (Markups.SYSTEM.equalsIgnoreCase(name)) {
                    return SYSTEM;
                }
                break;

            case 'R':
            case 'r':
                if (Markups.RESOURCE.equalsIgnoreCase(name)) {
                    return RESOURCE;
                }
                break;

            case 'V':
            case 'v':
                if (Markups.VALUES.equalsIgnoreCase(name)) {
                    return VALUES;
                }
                if (Markups.VOTABLE.equalsIgnoreCase(name)) {
                    return VOTABLE;
                }
                break;

            default:
        }
        return UNDEFINED;
    }
} public final class SavotBinary extends MarkupComment {

    // STREAM element
    private SavotStream stream = null;

    /**
     * Constructor
     */
    public SavotBinary() {
    }

    /**
     * Set the STREAM element
     * 
     * @param stream
     */
    public void setStream(final SavotStream stream) {
        this.stream = stream;
    }

    /**
     * Get the STREAM element
     * 
     * @return SavotStream
     */
    public SavotStream getStream() {
        return stream;
    }
} public final class SavotCoosys extends MarkupComment implements IDSupport {

    // ID attribute
    private String id = null;
    // equinox attribute
    private String equinox = null;
    // epoch attribute
    private String epoch = null;
    // system attribute eq_FK4, eq_FK5, ICRS, ecl_FK4, ecl_FK5, galactic,
    // supergalactic, xy, barycentric, geo_app
    private String system = "eq_FK5"; // default
    // element content
    private String content = null;

    /**
     * Constructor
     */
    public SavotCoosys() {
    }

    /**
     * Set the id attribute
     * 
     * @param id
     */
    @Override
    public void setId(final String id) {
        this.id = id;
    }

    /**
     * Get the id attribute value
     * 
     * @return String
     */
    @Override
    public String getId() {
        return str(id);
    }

    /**
     * Set the equinox attribute
     * 
     * @param equinox
     *            ([JB]?[0-9]+([.][0-9]*)?)
     */
    public void setEquinox(final String equinox) {
        this.equinox = equinox;
    }

    /**
     * Get the equinox attribute value
     * 
     * @return String
     */
    public String getEquinox() {
        return str(equinox);
    }

    /**
     * Set the epoch attribute
     * 
     * @param epoch
     *            ([JB]?[0-9]+([.][0-9]*)?)
     */
    public void setEpoch(final String epoch) {
        this.epoch = epoch;
    }

    /**
     * Get the epoch attribute value
     * 
     * @return String
     */
    public String getEpoch() {
        return str(epoch);
    }

    /**
     * Set the system attribute
     * 
     * @param system
     *            (eq_FK4, eq_FK5, ICRS, ecl_FK4, ecl_FK5, galactic,
     *            supergalactic, xy, barycentric, geo_app)
     */
    public void setSystem(final String system) {
        this.system = system;
    }

    /**
     * Get the system attribute value
     * 
     * @return String
     */
    public String getSystem() {
        return str(system);
    }

    /**
     * Set element content
     * 
     * @param content
     */
    public void setContent(final String content) {
        this.content = content;
    }

    /**
     * Get element content
     * 
     * @return a String
     */
    public String getContent() {
        return str(content);
    }
} public final class SavotData extends MarkupComment {

    // TABLEDATA element
    private SavotTableData tableData = null;
    // BINARY element
    private SavotBinary binary = null;
    // FITS element
    private SavotFits fits = null;

    /**
     * Constructor
     */
    public SavotData() {
    }

    /**
     * Set the TABLEDATA element
     * 
     * @param tableData
     */
    public void setTableData(final SavotTableData tableData) {
        this.tableData = tableData;
    }

    /**
     * Get the TABLEDATA element
     * 
     * @return SavotTableData
     */
    public SavotTableData getTableData() {
        return tableData;
    }

    /**
     * Set the BINARY element
     * 
     * @param binary
     */
    public void setBinary(final SavotBinary binary) {
        this.binary = binary;
    }

    /**
     * Get the BINARY element
     * 
     * @return SavotBinary
     */
    public SavotBinary getBinary() {
        return binary;
    }

    /**
     * Set the FITS element
     * 
     * @param fits
     */
    public void setFits(final SavotFits fits) {
        this.fits = fits;
    }

    /**
     * Get the FITS element
     * 
     * @return SavotFits
     */
    public SavotFits getFits() {
        return fits;
    }
} public final class SavotDefinitions extends MarkupComment {

    // COOSYS elements
    private CoosysSet coosys = null;
    // PARAM elements
    private ParamSet params = null;

    /**
     * Constructor
     */
    public SavotDefinitions() {
    }

    /**
     * Get COOSYS set reference removed in VOTable 1.1
     * 
     * @return a CoosysSet reference
     */
    public CoosysSet getCoosys() {
        if (coosys == null) {
            coosys = new CoosysSet();
        }
        return coosys;
    }

    /**
     * Set COOSYS set reference removed in VOTable 1.1
     * 
     * @param coosys
     */
    public void setCoosys(final CoosysSet coosys) {
        this.coosys = coosys;
    }

    /**
     * Get PARAM set reference removed in VOTable 1.1
     * 
     * @return a ParamSet reference
     */
    public ParamSet getParams() {
        if (params == null) {
            params = new ParamSet();
        }
        return params;
    }

    /**
     * Set PARAM set reference removed in VOTable 1.1
     * 
     * @param params
     */
    public void setParams(final ParamSet params) {
        this.params = params;
    }
} public final class SavotField extends MarkupComment implements IDSupport, NameSupport, RefSupport {

    // ID attribute
    private String id = null;
    // unit attribute
    private String unit = null;
    // datatype attribute
    private String datatype = null;
    // precision attribute
    private String precision = null;
    // width attribute
    private String width = null;
    // xtype attribute @since 1.2
    private String xtype = null;
    // ref attribute
    private String ref = null;
    // name attribute
    private String name = null;
    // ucd attribute
    private String ucd = null;
    // utype attribute
    private String utype = null;
    // arraysize attribute
    private String arraysize = null;
    // type attribute - extension since 1.1
    private String type = null;
    // DESCRIPTION element
    private String description = null;
    // VALUES element
    private SavotValues values = null;
    // LINK elements
    private LinkSet links = null;

    /**
     * Constructor
     */
    public SavotField() {
    }

    /**
     * Set ID attribute
     * 
     * @param id
     */
    @Override
    public void setId(final String id) {
        this.id = id;
    }

    /**
     * Get id attribute
     * 
     * @return String
     */
    @Override
    public String getId() {
        return str(id);
    }

    /**
     * Get unit attribute
     * 
     * @return String
     */
    public String getUnit() {
        return str(unit);
    }

    /**
     * Set unit attribute
     * 
     * @param unit
     */
    public void setUnit(final String unit) {
        this.unit = unit;
    }

    /**
     * Get datatype attribute
     * 
     * @return String
     */
    public String getDataType() {
        return str(datatype);
    }

    /**
     * Set datatype attribute
     * 
     * @param datatype
     *            (boolean, bit, unsignedByte, short, int, long, char,
     *            unicodeChar, float, double, floatComplex, doubleComplex)
     */
    public void setDataType(final String datatype) {
        this.datatype = datatype;
    }

    /**
     * Set name attribute
     * 
     * @param name
     */
    @Override
    public void setName(final String name) {
        this.name = name;
    }

    /**
     * Get name attribute
     * 
     * @return String
     */
    @Override
    public String getName() {
        return str(name);
    }

    /**
     * Set ucd attribute
     * 
     * @param ucd
     *            ([A-Za-z0-9_.,-]*)
     */
    public void setUcd(final String ucd) {
        this.ucd = ucd;
    }

    /**
     * Get ucd attribute
     * 
     * @return String
     */
    public String getUcd() {
        return str(ucd);
    }

    /**
     * Set ref attribute
     * 
     * @param ref
     */
    @Override
    public void setRef(final String ref) {
        this.ref = ref;
    }

    /**
     * Get ref attribute
     * 
     * @return String
     */
    @Override
    public String getRef() {
        return str(ref);
    }

    /**
     * Set precision attribute
     * 
     * @param precision
     *            ([EF]?[1-0][0-9]*)
     */
    public void setPrecision(final String precision) {
        this.precision = precision;
    }

    /**
     * Get precision attribute
     * 
     * @return String
     */
    public String getPrecision() {
        return str(precision);
    }

    /**
     * Set width attribute
     * 
     * @param width
     */
    public void setWidth(final String width) {
        this.width = width;
    }

    /**
     * Get width attribute
     * 
     * @return String
     */
    public String getWidth() {
        return str(width);
    }

    /**
     * Set width attribute
     * 
     * @param width
     */
    public void setWidthValue(final int width) {
        this.width = toStr(width);
    }

    /**
     * Get width attribute
     * 
     * @return String
     */
    public int getWidthValue() {
        return integer(width);
    }

    /**
     * Set xtype attribute
     * 
     * @since VOTable 1.2
     * @param xtype
     */
    public void setXtype(final String xtype) {
        this.xtype = xtype;
    }

    /**
     * Get xtype attribute
     * 
     * @since VOTable 1.2
     * @return String
     */
    public String getXtype() {
        return str(xtype);
    }

    /**
     * Set arraysize attribute
     * 
     * @param arraysize
     */
    public void setArraySize(final String arraysize) {
        this.arraysize = arraysize;
    }

    /**
     * Get arraysize attribute
     * 
     * @return String
     */
    public String getArraySize() {
        return str(arraysize);
    }

    /**
     * Set type attribute
     * 
     * @param type
     *            (hidden, no_query, trigger, location) warning : deprecated in
     *            VOTable 1.1
     */
    public void setType(final String type) {
        this.type = type;
    }

    /**
     * Get type attribute
     * 
     * @return String warning : deprecated in VOTable 1.1
     */
    public String getType() {
        return str(type);
    }

    /**
     * Set utype attribute
     * 
     * @param utype
     */
    public void setUtype(final String utype) {
        this.utype = utype;
    }

    /**
     * Get utype attribute
     * 
     * @return String
     */
    public String getUtype() {
        return str(utype);
    }

    /**
     * Set DESCRIPTION content
     * 
     * @param description
     */
    public void setDescription(final String description) {
        this.description = description;
    }

    /**
     * Get DESCRIPTION content
     * 
     * @return String
     */
    public String getDescription() {
        return str(description);
    }

    /**
     * Set the VALUES element
     * 
     * @param values
     */
    public void setValues(final SavotValues values) {
        this.values = values;
    }

    /**
     * Get the VALUES element
     * 
     * @return SavotValues
     */
    public SavotValues getValues() {
        return values;
    }

    /**
     * Get LINK elements set reference
     * 
     * @return LinkSet
     */
    public LinkSet getLinks() {
        if (links == null) {
            links = new LinkSet();
        }
        return links;
    }

    /**
     * Set LINK elements set reference
     * 
     * @param links
     */
    public void setLinks(final LinkSet links) {
        this.links = links;
    }
} public final class SavotFieldRef extends MarkupComment implements RefSupport {

    // ref attribute
    private String ref = null;
    // ucd attribute - since VOTable 1.2
    private String ucd = null;
    // utype attribute - since VOTable 1.2
    private String utype = null;

    /**
     * Constructor
     */
    public SavotFieldRef() {
    }

    /**
     * Set ref attribute
     * 
     * @param ref
     */
    @Override
    public void setRef(final String ref) {
        this.ref = ref;
    }

    /**
     * Get ref attribute
     * 
     * @return String
     */
    @Override
    public String getRef() {
        return str(ref);
    }

    /**
     * Set ucd attribute
     * 
     * @param ucd
     * @since VOTable 1.2
     */
    public void setUcd(final String ucd) {
        this.ucd = ucd;
    }

    /**
     * Get ucd attribute
     * 
     * @return String
     * @since VOTable 1.2
     */
    public String getUcd() {
        return str(ucd);
    }

    /**
     * Set utype attribute
     * 
     * @param utype
     * @since VOTable 1.2
     */
    public void setUtype(final String utype) {
        this.utype = utype;
    }

    /**
     * Get utype attribute
     * 
     * @return String
     * @since VOTable 1.2
     */
    public String getUtype() {
        return str(utype);
    }
} public final class SavotFits extends MarkupComment {

    // extnum attribute
    private String extnum = null;
    // STREAM element
    private SavotStream stream = null;

    /**
     * Constructor
     */
    public SavotFits() {
    }

    /**
     * Set the extnum
     * 
     * @param extnum
     *            String
     */
    public void setExtnum(final String extnum) {
        this.extnum = extnum;
    }

    /**
     * Get the extnum
     * 
     * @return a String
     */
    public String getExtnum() {
        return str(extnum);
    }

    /**
     * Set the STREAM element
     * 
     * @param stream
     */
    public void setStream(final SavotStream stream) {
        this.stream = stream;
    }

    /**
     * Get the STREAM element
     * 
     * @return SavotStream
     */
    public SavotStream getStream() {
        return stream;
    }
} public final class SavotGroup extends MarkupComment implements IDSupport, NameSupport, RefSupport {

    // ID attribute
    private String id = null;
    // name attribute
    private String name = null;
    // ref attribute
    private String ref = null;
    // ucd attribute
    private String ucd = null;
    // utype attribute
    private String utype = null;
    // description element
    private String description = null;
    // FIELDRef elements
    private FieldRefSet fieldsref = null;
    // PARAM elements
    private ParamSet params = null;
    // PARAMRef elements
    private ParamRefSet paramsref = null;
    // GROUP elements
    private GroupSet groups = null;

    /**
     * Constructor
     */
    public SavotGroup() {
    }

    /**
     * Set ID attribute
     * 
     * @param id
     */
    @Override
    public void setId(final String id) {
        this.id = id;
    }

    /**
     * Get id attribute
     * 
     * @return String
     */
    @Override
    public String getId() {
        return str(id);
    }

    /**
     * Set name attribute
     * 
     * @param name
     */
    @Override
    public void setName(final String name) {
        this.name = name;
    }

    /**
     * Get name attribute
     * 
     * @return String
     */
    @Override
    public String getName() {
        return str(name);
    }

    /**
     * Set ref attribute
     * 
     * @param ref
     */
    @Override
    public void setRef(final String ref) {
        this.ref = ref;
    }

    /**
     * Get ref attribute
     * 
     * @return String
     */
    @Override
    public String getRef() {
        return str(ref);
    }

    /**
     * Set ucd attribute
     * 
     * @param ucd
     *            ([A-Za-z0-9_.,-]*)
     */
    public void setUcd(final String ucd) {
        this.ucd = ucd;
    }

    /**
     * Get ucd attribute
     * 
     * @return String
     */
    public String getUcd() {
        return str(ucd);
    }

    /**
     * Set utype attribute
     * 
     * @param utype
     */
    public void setUtype(final String utype) {
        this.utype = utype;
    }

    /**
     * Get utype attribute
     * 
     * @return String
     */
    public String getUtype() {
        return str(utype);
    }

    /**
     * Set DESCRIPTION element content
     * 
     * @param description
     */
    public void setDescription(final String description) {
        this.description = description;
    }

    /**
     * Get DESCRIPTION element content
     * 
     * @return String
     */
    public String getDescription() {
        return str(description);
    }

    /**
     * Get PARAM elements set reference
     * 
     * @return ParamSet
     */
    public ParamSet getParams() {
        if (params == null) {
            params = new ParamSet();
        }
        return params;
    }

    /**
     * Set PARAM elements set reference
     * 
     * @param params
     */
    public void setParams(final ParamSet params) {
        this.params = params;
    }

    /**
     * Set PARAMref elements set reference
     * 
     * @param paramsref
     */
    public void setParamsRef(final ParamRefSet paramsref) {
        this.paramsref = paramsref;
    }

    /**
     * Get PARAMref elements set reference
     * 
     * @return ParamRefSet
     */
    public ParamRefSet getParamsRef() {
        if (paramsref == null) {
            paramsref = new ParamRefSet();
        }
        return paramsref;
    }

    /**
     * Get FIELDref elements set reference
     * 
     * @return FieldRefSet
     */
    public FieldRefSet getFieldsRef() {
        if (fieldsref == null) {
            fieldsref = new FieldRefSet();
        }
        return fieldsref;
    }

    /**
     * Set FIELDref elements set reference
     * 
     * @param fieldsref
     */
    public void setFieldsRef(final FieldRefSet fieldsref) {
        this.fieldsref = fieldsref;
    }

    /**
     * Get GROUP elements set reference
     * 
     * @return GroupSet
     */
    public GroupSet getGroups() {
        if (groups == null) {
            groups = new GroupSet();
        }
        return groups;
    }

    /**
     * Set GROUP elements set reference
     * 
     * @param groups
     */
    public void setGroups(final GroupSet groups) {
        this.groups = groups;
    }
} public final class SavotInfo extends MarkupComment implements IDSupport, NameSupport, RefSupport {

    // id attribute
    private String id = null;

    // name attribute
    private String name = null;

    // value attribute
    private String value = null;

    // INFO element content
    private String content = null;

    // xtype attribute @since 1.2
    private String xtype = null;

    // ref attribute @since 1.2
    private String ref = null;

    // unit attribute @since 1.2
    private String unit = null;

    // ucd attribute @since 1.2
    private String ucd = null;

    // utype attribute @since 1.2
    private String utype = null;

    // DESCRIPTION element - since VOTable 1.2 (not in the standard)
    private String description = null;

    // VALUES element - since VOTable 1.2 (not in the standard)
    private SavotValues values = null;

    // LINK elements - since VOTable 1.2 (not in the standard)
    private LinkSet links = null;

    /**
     * Constructor
     */
    public SavotInfo() {
    }

    /**
     * Set ID attribute
     * 
     * @param id
     */
    @Override
    public void setId(final String id) {
        this.id = id;
    }

    /**
     * Get ID attribute
     * 
     * @return String
     */
    @Override
    public String getId() {
        return str(id);
    }

    /**
     * Set name attribute
     * 
     * @param name
     */
    @Override
    public void setName(final String name) {
        this.name = name;
    }

    /**
     * Get name attribute
     * 
     * @return String
     */
    @Override
    public String getName() {
        return str(name);
    }

    /**
     * Set value attribute
     * 
     * @param value
     */
    public void setValue(final String value) {
        this.value = value;
    }

    /**
     * Get value attribute
     * 
     * @return String
     */
    public String getValue() {
        return str(value);
    }

    /**
     * Set xtype attribute
     * 
     * @since VOTable 1.2
     * @param xtype
     */
    public void setXtype(final String xtype) {
        this.xtype = xtype;
    }

    /**
     * Get xtype attribute
     * 
     * @since VOTable 1.2
     * @return String
     */
    public String getXtype() {
        return str(xtype);
    }

    /**
     * Set ref attribute
     * 
     * @since VOTable 1.2
     * @param ref
     */
    @Override
    public void setRef(final String ref) {
        this.ref = ref;
    }

    /**
     * Get ref attribute
     * 
     * @since VOTable 1.2
     * @return String
     */
    @Override
    public String getRef() {
        return str(ref);
    }

    /**
     * Set unit attribute
     * 
     * @since VOTable 1.2
     * @param unit
     */
    public void setUnit(final String unit) {
        this.unit = unit;
    }

    /**
     * Get unit attribute
     * 
     * @since VOTable 1.2
     * @return String
     */
    public String getUnit() {
        return str(unit);
    }

    /**
     * Set ucd attribute
     * 
     * @since VOTable 1.2
     * @param ucd
     */
    public void setUcd(final String ucd) {
        this.ucd = ucd;
    }

    /**
     * Get ucd attribute
     * 
     * @since VOTable 1.2
     * @return String
     */
    public String getUcd() {
        return str(ucd);
    }

    /**
     * Set utype attribute
     * 
     * @since VOTable 1.2
     * @param utype
     */
    public void setUtype(final String utype) {
        this.utype = utype;
    }

    /**
     * Get utype attribute
     * 
     * @since VOTable 1.2
     * @return String
     */
    public String getUtype() {
        return str(utype);
    }

    /**
     * Set element content
     * 
     * @param content
     */
    public void setContent(final String content) {
        this.content = content;
    }

    /**
     * Get element content
     * 
     * @return a String
     */
    public String getContent() {
        return str(content);
    }

    /**
     * Set DESCRIPTION content
     * 
     * @since VOTable 1.2 (not in the standard)
     * @param description
     */
    public void setDescription(final String description) {
        this.description = description;
    }

    /**
     * Get DESCRIPTION content
     * 
     * @since VOTable 1.2 (not in the standard)
     * @return String
     */
    public String getDescription() {
        return str(description);
    }

    /**
     * Set the VALUES element
     * 
     * @since VOTable 1.2 (not in the standard)
     * @param values
     */
    public void setValues(final SavotValues values) {
        this.values = values;
    }

    /**
     * Get the VALUES element
     * 
     * @since VOTable 1.2 (not in the standard)
     * @return SavotValues
     */
    public SavotValues getValues() {
        return values;
    }

    /**
     * Get LINK elements set reference
     * 
     * @since VOTable 1.2 (not in the standard)
     * @return LinkSet
     */
    public LinkSet getLinks() {
        if (links == null) {
            links = new LinkSet();
        }
        return links;
    }

    /**
     * Set LINK elements set reference
     * 
     * @since VOTable 1.2 (not in the standard)
     * @param links
     */
    public void setLinks(final LinkSet links) {
        this.links = links;
    }
} public final class SavotLink extends MarkupComment implements IDSupport {

    // content
    private String content = null;
    // ID attribute
    private String id = null;
    // content-role attribute
    private String contentRole = null;
    // content-type attribute
    private String contentType = null;
    // title attribute
    private String title = null;
    // value attribute
    private String value = null;
    // href attribute
    private String href = null;
    // gref attribute - removed since 1.1
    private String gref = null;
    // action attribute - extension since 1.1
    private String action = null;

    /**
     * Constructor
     */
    public SavotLink() {
    }

    /**
     * Set content
     * 
     * @param content
     */
    public void setContent(final String content) {
        this.content = content;
    }

    /**
     * Get content
     * 
     * @return String
     */
    public String getContent() {
        return str(content);
    }

    /**
     * Set ID attribute
     * 
     * @param id
     */
    @Override
    public void setId(final String id) {
        this.id = id;
    }

    /**
     * Get ID attribute
     * 
     * @return String
     */
    @Override
    public String getId() {
        return str(id);
    }

    /**
     * Set contentRole attribute
     * 
     * @param contentRole
     *            (query, hints, doc, location)
     */
    public void setContentRole(final String contentRole) {
        this.contentRole = contentRole;
    }

    /**
     * Get contentRole attribute
     * 
     * @return String
     */
    public String getContentRole() {
        return str(contentRole);
    }

    /**
     * Set contentType attribute
     * 
     * @param contentType
     */
    public void setContentType(final String contentType) {
        this.contentType = contentType;
    }

    /**
     * Get contentType attribute
     * 
     * @return String
     */
    public String getContentType() {
        return str(contentType);
    }

    /**
     * Set title attribute
     * 
     * @param title
     */
    public void setTitle(final String title) {
        this.title = title;
    }

    /**
     * Get title attribute
     * 
     * @return String
     */
    public String getTitle() {
        return str(title);
    }

    /**
     * Set value attribute
     * 
     * @param value
     */
    public void setValue(final String value) {
        this.value = value;
    }

    /**
     * Get value attribute
     * 
     * @return String
     */
    public String getValue() {
        return str(value);
    }

    /**
     * Set href attribute
     * 
     * @param href
     */
    public void setHref(final String href) {
        this.href = href;
    }

    /**
     * Get href attribute
     * 
     * @return String
     */
    public String getHref() {
        return str(href);
    }

    /**
     * Set gref attribute removed in VOTable 1.1
     * 
     * @param gref
     */
    public void setGref(final String gref) {
        this.gref = gref;
    }

    /**
     * Get gref attribute removed in VOTable 1.1
     * 
     * @return String
     */
    public String getGref() {
        return str(gref);
    }

    /**
     * Set action attribute
     * 
     * @param action
     */
    public void setAction(final String action) {
        this.action = action;
    }

    /**
     * Get action attribute
     * 
     * @return String
     */
    public String getAction() {
        return str(action);
    }
} public final class SavotMax extends Boundary {

    /**
     * Constructor
     */
    public SavotMax() {
    }
} public final class SavotMin extends Boundary {

    /**
     * Constructor
     */
    public SavotMin() {
    }
} public final class SavotOption extends MarkupComment implements NameSupport {

    // name attribute
    private String name = null;
    // value attribute
    private String value = null;
    // OPTION elements
    private OptionSet options = null;

    /**
     * Constructor
     */
    public SavotOption() {
    }

    /**
     * Set name attribute
     * 
     * @param name
     */
    @Override
    public void setName(final String name) {
        this.name = name;
    }

    /**
     * Get name attribute
     * 
     * @return String
     */
    @Override
    public String getName() {
        return str(name);
    }

    /**
     * Set value attribute
     * 
     * @param value
     */
    public void setValue(final String value) {
        this.value = value;
    }

    /**
     * Get value attribute
     * 
     * @return String
     */
    public String getValue() {
        return str(value);
    }

    /**
     * Get OPTION elements reference
     * 
     * @return OptionSet
     */
    public OptionSet getOptions() {
        if (options == null) {
            options = new OptionSet();
        }
        return options;
    }

    /**
     * Set OPTION elements reference
     * 
     * @param options
     */
    public void setOptions(final OptionSet options) {
        this.options = options;
    }
} public final class SavotParam extends MarkupComment implements IDSupport, NameSupport, RefSupport {

    // ID attribute
    private String id = null;
    // unit attribute
    private String unit = null;
    // datatype attribute
    private String datatype = null;
    // precision attribute
    private String precision = null;
    // width attribute
    private String width = null;
    // xtype attribute @since 1.2
    private String xtype = null;
    // ref attribute
    private String ref = null;
    // name attribute
    private String name = null;
    // ucd attribute
    private String ucd = null;
    // utype attribute
    private String utype = null;
    // arraysize attribute
    private String arraysize = null;
    // value attribute
    private String value = null;
    // DESCRIPTION element
    private String description = null;
    // VALUES element
    private SavotValues values = null;
    // LINK element
    private LinkSet links = null;

    /**
     * Constructor
     */
    public SavotParam() {
    }

    /**
     * Set ID attribute
     * 
     * @param id
     */
    @Override
    public void setId(final String id) {
        this.id = id;
    }

    /**
     * Get id attribute
     * 
     * @return String
     */
    @Override
    public String getId() {
        return str(id);
    }

    /**
     * Set unit attribute
     * 
     * @param unit
     */
    public void setUnit(final String unit) {
        this.unit = unit;
    }

    /**
     * Get unit attribute
     * 
     * @return String
     */
    public String getUnit() {
        return str(unit);
    }

    /**
     * Set datatype attribute
     * 
     * @param datatype
     *            (boolean, bit, unsignedByte, short, int, long, char,
     *            unicodeChar, float, double, floatComplex, doubleComplex)
     */
    public void setDataType(final String datatype) {
        this.datatype = datatype;
    }

    /**
     * Get datatype attribute
     * 
     * @return String
     */
    public String getDataType() {
        return str(datatype);
    }

    /**
     * Set precision attribute
     * 
     * @param precision
     *            ([EF]?[1-0][0-9]*)
     */
    public void setPrecision(final String precision) {
        this.precision = precision;
    }

    /**
     * Get precision attribute
     * 
     * @return String
     */
    public String getPrecision() {
        return str(precision);
    }

    /**
     * Set width attribute
     * 
     * @param width
     */
    public void setWidth(final String width) {
        this.width = width;
    }

    /**
     * Set width attribute
     * 
     * @param width
     */
    public void setWidthValue(final int width) {
        this.width = toStr(width);
    }

    /**
     * Get width attribute
     * 
     * @return String
     */
    public String getWidth() {
        return str(width);
    }

    /**
     * Get width attribute
     * 
     * @return String
     */
    public int getWidthValue() {
        return integer(width);
    }

    /**
     * Set xtype attribute
     * 
     * @since VOTable 1.2
     * @param xtype
     */
    public void setXtype(final String xtype) {
        this.xtype = xtype;
    }

    /**
     * Get xtype attribute
     * 
     * @since VOTable 1.2
     * @return String
     */
    public String getXtype() {
        return str(xtype);
    }

    /**
     * Set ref attribute
     * 
     * @param ref
     */
    @Override
    public void setRef(final String ref) {
        this.ref = ref;
    }

    /**
     * Get ref attribute
     * 
     * @return String
     */
    @Override
    public String getRef() {
        return str(ref);
    }

    /**
     * Set name attribute
     * 
     * @param name
     */
    @Override
    public void setName(final String name) {
        this.name = name;
    }

    /**
     * Get name attribute
     * 
     * @return String
     */
    @Override
    public String getName() {
        return str(name);
    }

    /**
     * Set ucd attribute
     * 
     * @param ucd
     *            ([A-Za-z0-9_.,-]*)
     */
    public void setUcd(final String ucd) {
        this.ucd = ucd;
    }

    /**
     * Get ucd attribute
     * 
     * @return String
     */
    public String getUcd() {
        return str(ucd);
    }

    /**
     * Set utype attribute
     * 
     * @param utype
     */
    public void setUtype(final String utype) {
        this.utype = utype;
    }

    /**
     * Get utype attribute
     * 
     * @return String
     */
    public String getUtype() {
        return str(utype);
    }

    /**
     * Set value attribute
     * 
     * @param value
     */
    public void setValue(final String value) {
        this.value = value;
    }

    /**
     * Get value attribute
     * 
     * @return String
     */
    public String getValue() {
        return str(value);
    }

    /**
     * Set arraysize attribute
     * 
     * @param arraysize
     *            (([0-9]+x)*[0-9]*[*]?(s\W)?)
     */
    public void setArraySize(final String arraysize) {
        this.arraysize = arraysize;
    }

    /**
     * Get arraysize attribute
     * 
     * @return String
     */
    public String getArraySize() {
        return str(arraysize);
    }

    /**
     * Set DESCRIPTION content
     * 
     * @param description
     */
    public void setDescription(final String description) {
        this.description = description;
    }

    /**
     * Get DESCRIPTION content
     * 
     * @return String
     */
    public String getDescription() {
        return str(description);
    }

    /**
     * Set VALUES element
     * 
     * @param values
     */
    public void setValues(final SavotValues values) {
        this.values = values;
    }

    /**
     * Get VALUES element
     * 
     * @return a SavotValues object
     */
    public SavotValues getValues() {
        return values;
    }

    /**
     * Get Link set reference
     * 
     * @return a set of LINK elements
     */
    public LinkSet getLinks() {
        if (links == null) {
            links = new LinkSet();
        }
        return links;
    }

    /**
     * Set Link set reference
     * 
     * @param links
     */
    public void setLinks(LinkSet links) {
        this.links = links;
    }
} public final class SavotParamRef extends MarkupComment implements RefSupport {

    // ref attribute
    private String ref = null;
    // ucd attribute - since VOTable 1.2
    private String ucd = null;
    // utype attribute - since VOTable 1.2
    private String utype = null;

    /**
     * Constructor
     */
    public SavotParamRef() {
    }

    /**
     * Set ref attribute
     * 
     * @param ref
     */
    @Override
    public void setRef(final String ref) {
        this.ref = ref;
    }

    /**
     * Get ref attribute
     * 
     * @return String
     */
    @Override
    public String getRef() {
        return str(ref);
    }

    /**
     * Set ucd attribute
     * 
     * @param ucd
     * @since VOTable 1.2
     */
    public void setUcd(final String ucd) {
        this.ucd = ucd;
    }

    /**
     * Get ucd attribute
     * 
     * @return String
     * @since VOTable 1.2
     */
    public String getUcd() {
        return str(ucd);
    }

    /**
     * Set utype attribute
     * 
     * @param utype
     * @since VOTable 1.2
     */
    public void setUtype(final String utype) {
        this.utype = utype;
    }

    /**
     * Get utype attribute
     * 
     * @return String
     * @since VOTable 1.2
     */
    public String getUtype() {
        return str(utype);
    }
} public final class SavotResource extends MarkupComment implements IDSupport, NameSupport {

    // name attribute
    private String name = null;

    // id attribute
    private String id = null;

    // type attribute (results, meta)
    private String type = "results"; // default

    // utype attribute
    private String utype = null;

    // DESCRIPTION element
    private String description = null;

    // COOSYS element set - deprecated since 1.2
    private CoosysSet coosys = null;

    // GROUP element set - since VOTable 1.2
    private GroupSet groups = null;

    // PARAM element set
    private ParamSet params = null;

    // INFO element set
    private InfoSet infos = null;

    // LINK element set
    private LinkSet links = null;

    // TABLE element set
    private TableSet tables = null;

    // RESOURCE element set (recursive usage)
    private ResourceSet resources = null;

    // INFO (at End) element set - since VOTable 1.2
    private InfoSet infosAtEnd = null;

    /**
     * Constructor
     */
    public SavotResource() {
    }

    /**
     * init a SavotResource object
     */
    public void init() {
        name = null;
        id = null;
        type = null;
        utype = null;
        description = null;

        coosys = null;
        groups = null;
        params = null;
        infos = null;
        links = null;
        tables = null;
        resources = null;
        infosAtEnd = null;
    }

    /**
     * Set the description
     * 
     * @param description
     *            String
     */
    public void setDescription(final String description) {
        this.description = description;
    }

    /**
     * Get the description
     * 
     * @return a String
     */
    public String getDescription() {
        return str(description);
    }

    /**
     * Set the Coosys elements
     * 
     * @deprecated since VOTable 1.2
     * @param coosys
     */
    public void setCoosys(final CoosysSet coosys) {
        this.coosys = coosys;
    }

    /**
     * Get the Coosys elements
     * 
     * @deprecated since VOTable 1.2
     * @return a CoosysSet object
     */
    public CoosysSet getCoosys() {
        if (coosys == null) {
            coosys = new CoosysSet();
        }
        return coosys;
    }

    /**
     * Set GROUP element set reference
     * 
     * @since VOTable 1.2
     * @param groups
     */
    public void setGroups(final GroupSet groups) {
        this.groups = groups;
    }

    /**
     * Get GROUP element set reference
     * 
     * @since VOTable 1.2
     * @return GroupSet
     */
    public GroupSet getGroups() {
        if (groups == null) {
            groups = new GroupSet();
        }
        return groups;
    }

    /**
     * Set the Infos elements
     * 
     * @param infos
     */
    public void setInfos(final InfoSet infos) {
        this.infos = infos;
    }

    /**
     * Get the Infos elements
     * 
     * @return a InfoSet object
     */
    public InfoSet getInfos() {
        if (infos == null) {
            infos = new InfoSet();
        }
        return infos;
    }

    /**
     * Set the Param elements
     * 
     * @param params
     */
    public void setParams(final ParamSet params) {
        this.params = params;
    }

    /**
     * Get the Param elements
     * 
     * @return a ParamSet object
     */
    public ParamSet getParams() {
        if (params == null) {
            params = new ParamSet();
        }
        return params;
    }

    /**
     * Set the Link elements
     * 
     * @param links
     */
    public void setLinks(final LinkSet links) {
        this.links = links;
    }

    /**
     * Get the Link elements
     * 
     * @return a LinkSet object
     */
    public LinkSet getLinks() {
        if (links == null) {
            links = new LinkSet();
        }
        return links;
    }

    /**
     * Set the Table elements
     * 
     * @param tables
     */
    public void setTables(final TableSet tables) {
        this.tables = tables;
    }

    /**
     * Get the Table elements
     * 
     * @return a TableSet object
     */
    public TableSet getTables() {
        if (tables == null) {
            tables = new TableSet();
        }
        return tables;
    }

    /**
     * Set the Resource elements
     * 
     * @param resources
     */
    public void setResources(final ResourceSet resources) {
        this.resources = resources;
    }

    /**
     * Get the Resource elements
     * 
     * @return a ResourceSet object
     */
    public ResourceSet getResources() {
        if (resources == null) {
            resources = new ResourceSet();
        }
        return resources;
    }

    /**
     * Set the InfosAtEnd elements
     * 
     * @param infosAtEnd
     * @since VOTable 1.2
     */
    public void setInfosAtEnd(final InfoSet infosAtEnd) {
        this.infosAtEnd = infosAtEnd;
    }

    /**
     * Get the InfosAtEnd elements
     * 
     * @return a InfoSet object
     * @since VOTable 1.2
     */
    public InfoSet getInfosAtEnd() {
        if (infosAtEnd == null) {
            infosAtEnd = new InfoSet();
        }
        return infosAtEnd;
    }

    /**
     * Set the name attribute
     * 
     * @param name
     *            String
     */
    @Override
    public void setName(final String name) {
        this.name = name;
    }

    /**
     * Get the name attribute
     * 
     * @return a String
     */
    @Override
    public String getName() {
        return str(name);
    }

    /**
     * Set the id attribute
     * 
     * @param id
     *            String
     */
    @Override
    public void setId(final String id) {
        this.id = id;
    }

    /**
     * Get the id attribute
     * 
     * @return String
     */
    @Override
    public String getId() {
        return str(id);
    }

    /**
     * Set the type attribute
     * 
     * @param type
     *            String (results, meta)
     */
    public void setType(final String type) {
        this.type = type;
    }

    /**
     * Get the type attribute
     * 
     * @return a String
     */
    public String getType() {
        return str(type);
    }

    /**
     * Set the utype attribute
     * 
     * @param utype
     *            String
     */
    public void setUtype(final String utype) {
        this.utype = utype;
    }

    /**
     * Get the utype attribute
     * 
     * @return a String
     */
    public String getUtype() {
        return str(utype);
    }

    /**
     * Get the number of TR object for table index tableIndex (shortcut)
     * 
     * @param tableIndex
     * @return int
     */
    public int getTRCount(final int tableIndex) {
        return getTables().getItemAt(tableIndex).getData().getTableData().getTRs().getItemCount();
    }

    /**
     * Get a TRSet object for table index tableIndex (shortcut)
     * 
     * @param tableIndex
     * @return TRSet
     */
    public TRSet getTRSet(final int tableIndex) {
        return getTables().getItemAt(tableIndex).getData().getTableData().getTRs();
    }

    /**
     * Get a TR object for table index tableIndex and the corresponding row
     * index rowIndex of this table (shortcut)
     * 
     * @param tableIndex
     * @param rowIndex
     * @return SavotTR
     */
    public SavotTR getTR(final int tableIndex, final int rowIndex) {
        return getTables().getItemAt(tableIndex).getData().getTableData().getTRs().getItemAt(rowIndex);
    }

    /**
     * Return the number of tables contained in the resource this value doesn't
     * contain the tables of included resources (shortcut)
     * 
     * @return int
     */
    public int getTableCount() {
        return getTables().getItemCount();
    }

    /**
     * Get a FieldSet object for table index tableIndex (shortcut)
     * 
     * @param tableIndex
     * @return FieldSet
     */
    public FieldSet getFieldSet(final int tableIndex) {
        return getTables().getItemAt(tableIndex).getFields();
    }

    /**
     * Get a LinkSet object for table index tableIndex (shortcut)
     * 
     * @param tableIndex
     * @return LinkSet
     */
    public LinkSet getLinkSet(final int tableIndex) {
        return getTables().getItemAt(tableIndex).getLinks();
    }

    /**
     * Get a Description object (String) for table index tableIndex (shortcut)
     * 
     * @param tableIndex
     * @return String
     */
    public String getDescription(final int tableIndex) {
        return getTables().getItemAt(tableIndex).getDescription();
    }

    /**
     * Get a SavotData object for table index tableIndex (shortcut)
     * 
     * @param tableIndex
     * @return SavotData
     */
    public SavotData getData(final int tableIndex) {
        return getTables().getItemAt(tableIndex).getData();
    }
} public final class SavotStream extends MarkupComment {

    // content
    private String content = null;
    // type attribute (locator, other)
    private String type = "locator"; // default
    // href attribute
    private String href = null;
    // actuate attribute
    private String actuate = null;
    // width encoding
    private String encoding = null;
    // expires attribute
    private String expires = null;
    // rights attribute
    private String rights = null;

    /**
     * Constructor
     */
    public SavotStream() {
    }

    /**
     * Set type attribute
     * 
     * @param type
     *            (locator, other)
     */
    public void setType(final String type) {
        this.type = type;
    }

    /**
     * Get type attribute
     * 
     * @return String
     */
    public String getType() {
        return str(type);
    }

    /**
     * Set href attribute
     * 
     * @param href
     *            (URI)
     */
    public void setHref(final String href) {
        this.href = href;
    }

    /**
     * Get href attribute
     * 
     * @return String
     */
    public String getHref() {
        return str(href);
    }

    /**
     * Set actuate attribute
     * 
     * @param actuate
     *            (onLoad, onRequest, other, none)
     */
    public void setActuate(final String actuate) {
        this.actuate = actuate;
    }

    /**
     * Get actuate attribute
     * 
     * @return String
     */
    public String getActuate() {
        return str(actuate);
    }

    /**
     * Set encoding attribute
     * 
     * @param encoding
     *            (gzip, base64, dynamic, none)
     */
    public void setEncoding(final String encoding) {
        this.encoding = encoding;
    }

    /**
     * Get encoding attribute
     * 
     * @return String
     */
    public String getEncoding() {
        return str(encoding);
    }

    /**
     * Set expires attribute
     * 
     * @param expires
     */
    public void setExpires(final String expires) {
        this.expires = expires;
    }

    /**
     * Get width attribute
     * 
     * @return String
     */
    public String getExpires() {
        return str(expires);
    }

    /**
     * Set rights attribute
     * 
     * @param rights
     */
    public void setRights(final String rights) {
        this.rights = rights;
    }

    /**
     * Get rights attribute
     * 
     * @return String
     */
    public String getRights() {
        return str(rights);
    }

    /**
     * Set content
     * 
     * @param content
     */
    public void setContent(final String content) {
        this.content = content;
    }

    /**
     * Get content
     * 
     * @return String
     */
    public String getContent() {
        return str(content);
    }
} public final class SavotTD extends SavotBase {
    // TD content

    private String content = null;

    /**
     * Constructor
     */
    public SavotTD() {
    }

    /**
     * Constructor with content
     * @param content
     */
    public SavotTD(final String content) {
        this.content = content;
    }

    /**
     * Set element content
     * 
     * @param content
     */
    public void setContent(final String content) {
        this.content = content;
    }

    /**
     * Get element content
     * 
     * @return a String
     */
    public String getContent() {
        return str(content);
    }

    /**
     * Get the raw content value (maybe null)
     *
     * @return a String or null
     */
    public String getRawContent() {
        return content;
    }
} public final class SavotTR extends SavotBase {

    // TR element set
    private TDSet TDs = null;
    private int lineInXMLFile = 0;

    /**
     * Constructor
     */
    public SavotTR() {
    }

    /**
     * Create a TR element from a Separated Value String
     * 
     * @param svline
     *            String, line with separated values
     * @param sv
     *            char, separated value
     */
    public void SVtoTR(final String svline, final char sv) {
        String line = svline;

        int index;
        String token;
        TDs = new TDSet();
        // cut sv following the separator

        // tabulation
        do {
            if ((index = line.indexOf(sv)) >= 0) {
                token = line.substring(0, index);
                line = line.substring(index + 1);
            } else {
                // last element
                token = line;
            }
            SavotTD td = new SavotTD();
            td.setContent(token);
            TDs.addItem(td);
        } while (index >= 0);
    }

    /**
     * Get the TD set (same as getTDSet) TDSet
     *
     * @return TDSet
     */
    public TDSet getTDs() {
        if (TDs == null) {
            TDs = new TDSet();
        }
        return TDs;
    }

    /**
     * Get the TD set (same as getTDs) TDSet
     * @param capacity minimal capacity to provide 
     * @return TDSet
     */
    public TDSet getTDSet(final int capacity) {
        if (TDs == null) {
            TDs = new TDSet();
            TDs.ensureCapacity(capacity);
        }
        return TDs;
    }

    /**
     * Get the TD set (same as getTDs) TDSet
     * @see #getTDSet(int)
     * 
     * @return TDSet
     */
    public TDSet getTDSet() {
        if (TDs == null) {
            TDs = new TDSet();
        }
        return TDs;
    }

    /**
     * Set the TD set (same as setTDSet) TDSet
     * 
     * @param TDs
     */
    public void setTDs(final TDSet TDs) {
        this.TDs = TDs;
    }

    /**
     * Set the TD set (same as setTDs) TDSet
     * 
     * @param TDs
     */
    public void setTDSet(final TDSet TDs) {
        this.TDs = TDs;
    }

    /**
     * Get the corresponding line in the XML file or flow
     * 
     * @return lineInXMLFile
     */
    public int getLineInXMLFile() {
        return lineInXMLFile;
    }

    /**
     * Set the corresponding line in the XML file or flow during the parsing
     * 
     * @param lineInXMLFile
     */
    public void setLineInXMLFile(final int lineInXMLFile) {
        this.lineInXMLFile = lineInXMLFile;
    }

    /**
     * Clear this TR instance to recycle it
     */
    public void clear() {
        if (TDs != null) {
            TDs.removeAllItems(); // recycle TDSet (same capacity)
        }
        lineInXMLFile = 0;
    }
} public final class SavotTable extends MarkupComment implements IDSupport, NameSupport, RefSupport {

    // id attribute
    private String id = null;
    // name attribute
    private String name = null;
    // ucd attribute
    private String ucd = null;
    // utype attribute
    private String utype = null;
    // ref attribute
    private String ref = null;
    // nrows attribute
    private String nrows = null;
    // DESCRIPTION element
    private String description = null;
    // FIELD element
    private FieldSet fields = null;
    // PARAM element
    private ParamSet params = null;
    // GROUP element - since VOTable 1.1
    private GroupSet groups = null;
    // LINK element
    private LinkSet links = null;
    // DATA element
    private SavotData data = null;
    // INFO element at the end - since VOTable 1.2
    private InfoSet infosAtEnd = null;

    /**
     * Constructor
     */
    public SavotTable() {
    }

    /**
     * Set ID attribute
     * 
     * @param id
     */
    @Override
    public void setId(final String id) {
        this.id = id;
    }

    /**
     * Get ID attribute
     * 
     * @return a String
     */
    @Override
    public String getId() {
        return str(id);
    }

    /**
     * Set name attribute
     * 
     * @param name
     */
    @Override
    public void setName(final String name) {
        this.name = name;
    }

    /**
     * Get name attribute
     * 
     * @return a String
     */
    @Override
    public String getName() {
        return str(name);
    }

    /**
     * Set ucd attribute
     * 
     * @param ucd
     */
    public void setUcd(final String ucd) {
        this.ucd = ucd;
    }

    /**
     * Get ucd attribute
     * 
     * @return a String
     */
    public String getUcd() {
        return str(ucd);
    }

    /**
     * Set utype attribute
     * 
     * @param utype
     */
    public void setUtype(final String utype) {
        this.utype = utype;
    }

    /**
     * Get utype attribute
     * 
     * @return a String
     */
    public String getUtype() {
        return str(utype);
    }

    /**
     * Set ref attribute
     * 
     * @param ref
     */
    @Override
    public void setRef(final String ref) {
        this.ref = ref;
    }

    /**
     * Get ref attribute
     * 
     * @return a String
     */
    @Override
    public String getRef() {
        return str(ref);
    }

    /**
     * Set nrows attribute
     * 
     * @param nrows
     */
    public void setNrows(final String nrows) {
        this.nrows = nrows;
    }

    /**
     * Set nrows attribute
     * 
     * @param nrows
     */
    public void setNrowsValue(final int nrows) {
        this.nrows = toStr(nrows);
    }

    /**
     * Get nrows attribute
     * 
     * @return a String
     */
    public String getNrows() {
        return str(nrows);
    }

    /**
     * Get nrows attribute
     * 
     * @return an int
     */
    public int getNrowsValue() {
        return integer(nrows);
    }

    /**
     * Set DESCRIPTION content
     * 
     * @param description
     */
    public void setDescription(final String description) {
        this.description = description;
    }

    /**
     * Get DESCRIPTION content
     * 
     * @return a String
     */
    public String getDescription() {
        return str(description);
    }

    /**
     * Get FIELD element set reference
     * 
     * @return FieldSet
     */
    public FieldSet getFields() {
        if (fields == null) {
            fields = new FieldSet();
        }
        return fields;
    }

    /**
     * Set FIELD element set reference
     * 
     * @param fields
     */
    public void setFields(final FieldSet fields) {
        this.fields = fields;
    }

    /**
     * Get PARAM element set reference
     * 
     * @return ParamSet
     */
    public ParamSet getParams() {
        if (params == null) {
            params = new ParamSet();
        }
        return params;
    }

    /**
     * Set PARAM element set reference
     * 
     * @param params
     */
    public void setParams(final ParamSet params) {
        this.params = params;
    }

    /**
     * Get GROUP element set reference
     * 
     * @since VOTable 1.1
     * @return GroupSet
     */
    public GroupSet getGroups() {
        if (groups == null) {
            groups = new GroupSet();
        }
        return groups;
    }

    /**
     * Set GROUP element set reference
     * 
     * @since VOTable 1.1
     * @param groups
     */
    public void setGroups(final GroupSet groups) {
        this.groups = groups;
    }

    /**
     * Get LINK element set reference
     * 
     * @return LinkSet
     */
    public LinkSet getLinks() {
        if (links == null) {
            links = new LinkSet();
        }
        return links;
    }

    /**
     * Set LINK element set reference
     * 
     * @param links
     */
    public void setLinks(final LinkSet links) {
        this.links = links;
    }

    /**
     * Set DATA element
     * 
     * @param data
     */
    public void setData(final SavotData data) {
        this.data = data;
    }

    /**
     * Get DATA element
     * 
     * @return SavotData
     */
    public SavotData getData() {
        return data;
    }

    /**
     * Set the InfosAtEnd elements
     * 
     * @param infosAtEnd
     * @since VOTable 1.2
     */
    public void setInfosAtEnd(final InfoSet infosAtEnd) {
        this.infosAtEnd = infosAtEnd;
    }

    /**
     * Get the InfosAtEnd elements
     * 
     * @return an InfoSet object
     * @since VOTable 1.2
     */
    public InfoSet getInfosAtEnd() {
        if (infosAtEnd == null) {
            infosAtEnd = new InfoSet();
        }
        return infosAtEnd;
    }
} public final class SavotTableData extends MarkupComment {

    private TRSet TRs = null;

    /**
     * Constructor
     */
    public SavotTableData() {
    }

    /**
     * Get the TR set reference
     * 
     * @return TRs
     */
    public TRSet getTRs() {
        if (TRs == null) {
            TRs = new TRSet();
        }
        return TRs;
    }

    /**
     * Set the TR set reference
     * 
     * @param TRs
     */
    public void setTRs(final TRSet TRs) {
        this.TRs = TRs;
    }
} public final class SavotVOTable extends MarkupComment implements IDSupport {

    // xmlns attribute
    private String xmlns = null;
    // xmlns:xsi attribute
    private String xmlnsxsi = null;
    // xsi:NoNamespaceSchemaLocation attribute
    private String xsinoschema = null;
    // xsi:schemaLocation attribute
    private String xsischema = null;
    // id attribute
    private String id = null;
    // version attribute (default : 1.2)
    private String version = "1.2";
    // DESCRIPTION element
    private String description = null;
    // COOSYS element set - deprecated since 1.2
    private CoosysSet coosys = null;
    // PARAM element set
    private ParamSet params = null;
    // GROUP element set
    private GroupSet groups = null;
    // INFO element set
    private InfoSet infos = null;
    // DEFINITIONS element
    @SuppressWarnings("deprecation")
    private SavotDefinitions definitions = null;
    // RESOURCE element
    private ResourceSet resources = null;
    // INFO element set at the end - since VOTable1.2
    private InfoSet infosAtEnd = null;

    /**
     * Constructor
     */
    public SavotVOTable() {
    }

    /**
     * Set the global attributes (<VOTABLE .. global attributes ..
     * version="1.1">) (used for the writer)
     * 
     * @param xmlns
     *            String
     */
    public void setXmlns(final String xmlns) {
        this.xmlns = xmlns;
    }

    /**
     * Get the global attributes (<VOTABLE .. global attributes ..
     * version="1.1"> (used for the writer)
     * 
     * @return String
     */
    public String getXmlns() {
        return str(xmlns);
    }

    /**
     * Set the global attributes (<VOTABLE .. global attributes ..
     * version="1.1">) (used for the writer)
     * 
     * @param xmlnsxsi
     *            String
     */
    public void setXmlnsxsi(final String xmlnsxsi) {
        this.xmlnsxsi = xmlnsxsi;
    }

    /**
     * Get the global attributes (<VOTABLE .. global attributes ..
     * version="1.1"> (used for the writer)
     * 
     * @return String
     */
    public String getXmlnsxsi() {
        return str(xmlnsxsi);
    }

    /**
     * Set the global attributes (<VOTABLE .. global attributes ..
     * version="1.1">) (used for the writer)
     * 
     * @param xsinoschema
     *            String
     */
    public void setXsinoschema(final String xsinoschema) {
        this.xsinoschema = xsinoschema;
    }

    /**
     * Get the global attributes (<VOTABLE .. global attributes ..
     * version="1.1"> (used for the writer)
     * 
     * @return String
     */
    public String getXsinoschema() {
        return str(xsinoschema);
    }

    /**
     * Set the global attributes (<VOTABLE .. global attributes ..
     * version="1.1">) (used for the writer)
     * 
     * @param xsischema
     *            String
     */
    public void setXsischema(final String xsischema) {
        this.xsischema = xsischema;
    }

    /**
     * Get the global attributes (<VOTABLE .. global attributes ..
     * version="1.1"> (used for the writer)
     * 
     * @return String
     */
    public String getXsischema() {
        return str(xsischema);
    }

    /**
     * Set the id attribute
     * 
     * @param id
     *            String
     */
    @Override
    public void setId(final String id) {
        this.id = id;
    }

    /**
     * Get the id attribute
     * 
     * @return String
     */
    @Override
    public String getId() {
        return str(id);
    }

    /**
     * Set the version attribute
     * 
     * @param version
     *            String
     */
    public void setVersion(final String version) {
        this.version = version;
    }

    /**
     * Get the version attribute
     * 
     * @return String
     */
    public String getVersion() {
        return str(version);
    }

    /**
     * Set DESCRIPTION element
     * 
     * @param description
     */
    public void setDescription(final String description) {
        this.description = description;
    }

    /**
     * Get DESCRIPTION element
     * 
     * @return a String
     */
    public String getDescription() {
        return str(description);
    }

    /**
     * Set DEFINITIONS element
     * 
     * @deprecated since VOTable 1.1
     * @param definitions
     */
    public void setDefinitions(final SavotDefinitions definitions) {
        this.definitions = definitions;
    }

    /**
     * Get DEFINITIONS element
     * 
     * @deprecated since VOTable 1.1
     * @return SavotDefinitions
     */
    public SavotDefinitions getDefinitions() {
        return definitions;
    }

    /**
     * Set the Coosys elements
     * 
     * @deprecated since VOTable 1.2
     * @param coosys
     */
    public void setCoosys(final CoosysSet coosys) {
        this.coosys = coosys;
    }

    /**
     * Get the Coosys elements
     * 
     * @deprecated since VOTable 1.2
     * @return a CoosysSet object
     */
    public CoosysSet getCoosys() {
        if (coosys == null) {
            coosys = new CoosysSet();
        }
        return coosys;
    }

    /**
     * Set the Infos elements
     * 
     * @param infos
     */
    public void setInfos(final InfoSet infos) {
        this.infos = infos;
    }

    /**
     * Get the Infos elements
     * 
     * @return a InfoSet object
     */
    public InfoSet getInfos() {
        if (infos == null) {
            infos = new InfoSet();
        }
        return infos;
    }

    /**
     * Set the Param elements
     * 
     * @param params
     */
    public void setParams(final ParamSet params) {
        this.params = params;
    }

    /**
     * Get the Param elements
     * 
     * @return a ParamSet object
     */
    public ParamSet getParams() {
        if (params == null) {
            params = new ParamSet();
        }
        return params;
    }

    /**
     * Set GROUP element set reference
     * 
     * @since VOTable 1.2
     * @param groups
     */
    public void setGroups(final GroupSet groups) {
        this.groups = groups;
    }

    /**
     * Get GROUP element set reference
     * 
     * @since VOTable 1.2
     * @return GroupSet
     */
    public GroupSet getGroups() {
        if (groups == null) {
            groups = new GroupSet();
        }
        return groups;
    }

    /**
     * Get RESOURCE set reference (FULL mode only)
     * 
     * @return ResourceSet (always NULL in SEQUENTIAL mode)
     */
    public ResourceSet getResources() {
        if (resources == null) {
            resources = new ResourceSet();
        }
        return resources;
    }

    /**
     * Set RESOURCE set reference
     * 
     * @param resources
     */
    public void setResources(final ResourceSet resources) {
        this.resources = resources;
    }

    /**
     * Set the InfosAtEnd elements
     * 
     * @param infosAtEnd
     * @since VOTable 1.2
     */
    public void setInfosAtEnd(final InfoSet infosAtEnd) {
        this.infosAtEnd = infosAtEnd;
    }

    /**
     * Get the InfosAtEnd elements
     * 
     * @return a InfoSet object
     * @since VOTable 1.2
     */
    public InfoSet getInfosAtEnd() {
        if (infosAtEnd == null) {
            infosAtEnd = new InfoSet();
        }
        return infosAtEnd;
    }
} public final class SavotValues extends MarkupComment implements IDSupport, RefSupport {

    // ID attribute
    private String id = null;
    // type attribute
    private String type = "legal";
    // null content
    private String nul = null;
    // ref content
    private String ref = null;
    // invalid content - deprecated since VOTable 1.1
    private String invalid = null;
    // MIN element
    private SavotMin min = null;
    // MAX element
    private SavotMax max = null;
    // OPTION element
    private OptionSet options = null;

    /**
     * Constructor
     */
    public SavotValues() {
    }

    /**
     * Set the id attribute
     * 
     * @param id
     *            String
     */
    @Override
    public void setId(final String id) {
        this.id = id;
    }

    /**
     * Get the id attribute
     * 
     * @return a String
     */
    @Override
    public String getId() {
        return str(id);
    }

    /**
     * Set the type attribute
     * 
     * @param type
     *            String (legal, actual)
     */
    public void setType(final String type) {
        this.type = type;
    }

    /**
     * Get the type attribute
     * 
     * @return a String
     */
    public String getType() {
        return str(type);
    }

    /**
     * Set the null attribute
     * 
     * @param nul
     *            String
     */
    public void setNull(final String nul) {
        this.nul = nul;
    }

    /**
     * Get the null attribute
     * 
     * @return a String
     */
    public String getNull() {
        return str(nul);
    }

    /**
     * Set the ref attribute
     * 
     * @param ref
     *            ref
     */
    @Override
    public void setRef(final String ref) {
        this.ref = ref;
    }

    /**
     * Get the ref attribute
     * 
     * @return a String
     */
    @Override
    public String getRef() {
        return str(ref);
    }

    /**
     * Set the invalid attribute deprecated since VOTable 1.1
     * 
     * @param invalid
     *            String
     */
    public void setInvalid(final String invalid) {
        this.invalid = invalid;
    }

    /**
     * Get the invalid attribute deprecated since VOTable 1.1
     * 
     * @return a String
     */
    public String getInvalid() {
        return str(invalid);
    }

    /**
     * Set MIN element
     * 
     * @param min
     */
    public void setMin(final SavotMin min) {
        this.min = min;
    }

    /**
     * Get MIN element
     * 
     * @return a SavotMin object
     */
    public SavotMin getMin() {
        return min;
    }

    /**
     * Set MAX element
     * 
     * @param max
     */
    public void setMax(final SavotMax max) {
        this.max = max;
    }

    /**
     * Get MAX element
     * 
     * @return a SavotMax object
     */
    public SavotMax getMax() {
        return max;
    }

    /**
     * Get OPTION element set reference
     * 
     * @return OptionSet object
     */
    public OptionSet getOptions() {
        if (options == null) {
            options = new OptionSet();
        }
        return options;
    }

    /**
     * Set OPTION element set reference
     * 
     * @param options
     */
    public void setOptions(final OptionSet options) {
        this.options = options;
    }
} public final class TDSet extends SavotSet<SavotTD> {

    /**
     * Constructor
     */
    public TDSet() {
    }

    /**
     * Get the content at the TDIndex position of the TDSet
     * 
     * @param TDIndex
     * @return String
     */
    public String getContent(final int TDIndex) {
        final SavotTD td = getItemAt(TDIndex);
        if (td == null) {
            return "";
        }
        return td.getContent();
    }

    /**
     * Get the raw content at the TDIndex position of the TDSet (maybe null)
     * 
     * @param TDIndex
     * @return a String or null
     */
    public String getRawContent(final int TDIndex) {
        final SavotTD td = getItemAt(TDIndex);
        if (td == null) {
            return null;
        }
        return td.getRawContent();
    }
}
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.ArrayList;
import org.xmlpull.v1.XmlPullParser;
import cds.savot.common.Markups;
import cds.savot.common.SavotStatistics;
import cds.savot.common.VOTableTag;
import cds.savot.model.SavotBinary;
import cds.savot.model.SavotCoosys;
import cds.savot.model.SavotData;
import cds.savot.model.SavotDefinitions;
import cds.savot.model.SavotField;
import cds.savot.model.SavotFieldRef;
import cds.savot.model.SavotFits;
import cds.savot.model.SavotGroup;
import cds.savot.model.SavotInfo;
import cds.savot.model.SavotLink;
import cds.savot.model.SavotMax;
import cds.savot.model.SavotMin;
import cds.savot.model.SavotOption;
import cds.savot.model.SavotParam;
import cds.savot.model.SavotParamRef;
import cds.savot.model.SavotResource;
import cds.savot.model.SavotStream;
import cds.savot.model.SavotTD;
import cds.savot.model.SavotTR;
import cds.savot.model.SavotTable;
import cds.savot.model.SavotTableData;
import cds.savot.model.SavotVOTable;
import cds.savot.model.SavotValues;
import cds.savot.model.TDSet;
import java.io.Reader;
import java.util.HashMap;
import java.util.Map;
import java.util.logging.Level;
import java.util.zip.GZIPInputStream;
package cds.savot.pull;

//Copyright 2002-2014 - UDS/CNRS
//The SAVOT library is distributed under the terms
//of the GNU General Public License version 3.
//
//This file is part of SAVOT.
//
//SAVOT is free software: you can redistribute it and/or modify
//it under the terms of the GNU General Public License as published by
//the Free Software Foundation, version 3 of the License.
//
//SAVOT is distributed in the hope that it will be useful,
//but WITHOUT ANY WARRANTY; without even the implied warranty of
//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//GNU General Public License for more details.
//
//The GNU General Public License is available in COPYING file
//along with SAVOT.
//
//SAVOT - Simple Access to VOTable - Parser
//
//Author, Co-Author:  Andre Schaaff (CDS), Laurent Bourges (JMMC)

// XML pull parser

// VOTable internal data model

/**
 * <p>
 * It has been tested with kXML Pull parser implementation
 * </p>
 * <p>
 * but it is possible to use other pull parsers
 * </p>
 * <p>
 * Designed to use with Pull parsers complient with Standard Pull Implementation
 * v1
 * </p>
 * 
 * LBO: Note: equalsIgnoreCase() vs() equals as XML is case sensitive and VOTable specification says that clearly
 * 
 * @author Andre Schaaff
 */
@SuppressWarnings({"deprecation", "UseOfSystemOutOrSystemErr"})
public final class SavotPullEngine implements Markups {

    /** Logger associated to SavotPullEngine classes */
    private final static java.util.logging.Logger logger = java.util.logging.Logger.getLogger(SavotPullEngine.class.getName());
    /** flag to enable / disable usage of String.trim() on every value (enabled by default) */
    private static final boolean doTrimValues = false;
    /** flag to enable / disable line numbers (TR) */
    private static final boolean doLineInfo = false;
    /** flag to enable / disable statistics */
    private static final boolean doStats = false;

    /* parsing modes */
    /** FULL parsing mode: deprecated and replaced by FULLREAD */
    public static final int FULL = 0;
    /** FULLREAD parsing mode all in memory */
    public static final int FULLREAD = 0;
    /** SEQUENTIAL parsing mode: deprecated and replaced by RESOURCEREAD */
    public static final int SEQUENTIAL = 1;
    /** RESOURCEREAD parsing mode: row per row reading */
    public static final int RESOURCEREAD = 1;
    /** ROWREAD parsing mode: row per row reading */
    public static final int ROWREAD = 2;

    /** default stack capacity = 4 slots */
    public final static int DEFAULT_STACK_CAPACITY = 4;
    /** empty TD instance */
    private final static SavotTD EMPTY_TD = new SavotTD();

    /* members */
    /** statistics dedicated to this parser */
    private final SavotStatistics statistics;
    /** xml pull parser needed for sequential parsing */
    private XmlPullParser xmlParser = null;
    /** input stream used to close it anyway */
    private InputStream inputStream = null;
    /** reader used to close it anyway */
    private Reader reader = null;
    /** debug mode */
    private boolean debugMode = false;
    // data model objects
    private SavotVOTable _currentVOTable = new SavotVOTable();
    private SavotResource _currentResource = new SavotResource(); // RESOURCEREAD mode only
    private SavotTR _currentTR = new SavotTR(); 		  // ROWREAD mode only
    // used for statistics
    private int resourceCounter = 0;
    private int tableCounter = 0;
    private int rowCounter = 0;
    private int dataCounter = 0;

    // used for recursive management
    private final ArrayList<VOTableTag> fatherTags = new ArrayList<VOTableTag>(DEFAULT_STACK_CAPACITY);
    // used for recursive resources, LIFO mode
    private final ArrayList<SavotResource> resourcestack = new ArrayList<SavotResource>(DEFAULT_STACK_CAPACITY);
    // used for recursive options, LIFO mode
    private final ArrayList<SavotOption> optionstack = new ArrayList<SavotOption>(DEFAULT_STACK_CAPACITY);
    // used for recursives groups, LIFO mode
    private final ArrayList<SavotGroup> groupstack = new ArrayList<SavotGroup>(DEFAULT_STACK_CAPACITY);