/** Deserializes the object from XML */
  public DataField parseField(XMLStreamReader in) throws IOException, XMLStreamException {
    String label = in.getAttributeValue(null, "label");
    String type = in.getAttributeValue(null, "type");
    String var = in.getAttributeValue(null, "var");

    DataField field = new DataField(type, var, label);

    ArrayList<DataValue> valueList = new ArrayList<DataValue>();
    ArrayList<DataOption> optionList = new ArrayList<DataOption>();

    int tag = in.nextTag();
    while (tag > 0) {
      if (_isFinest) debug(in);

      if (XMLStreamReader.END_ELEMENT == tag) {
        field.setValueList(valueList);
        field.setOptionList(optionList);

        return field;
      }

      if (XMLStreamReader.START_ELEMENT == tag && "desc".equals(in.getLocalName())) {
        String desc = in.getElementText();

        field.setDesc(desc);

        skipToEnd(in, "desc");
      } else if (XMLStreamReader.START_ELEMENT == tag && "option".equals(in.getLocalName())) {
        optionList.add(parseOption(in));
      } else if (XMLStreamReader.START_ELEMENT == tag && "required".equals(in.getLocalName())) {
        field.setRequired(true);

        skipToEnd(in, "required");
      } else if (XMLStreamReader.START_ELEMENT == tag && "value".equals(in.getLocalName())) {
        String value = in.getElementText();

        valueList.add(new DataValue(value));

        skipToEnd(in, "value");
      } else if (XMLStreamReader.START_ELEMENT == tag) {
        log.finer(this + " <" + in.getLocalName() + "> is an unknown tag");

        skipToEnd(in, in.getLocalName());
      }

      tag = in.nextTag();
    }

    skipToEnd(in, "field");

    return field;
  }
  private void toXml(XmppStreamWriter out, DataField field) throws IOException, XMLStreamException {
    out.writeStartElement("field");

    if (field.getLabel() != null) out.writeAttribute("label", field.getLabel());

    if (field.getType() != null) out.writeAttribute("type", field.getType());

    if (field.getVar() != null) out.writeAttribute("var", field.getVar());

    if (field.getDesc() != null) {
      out.writeStartElement("desc");
      out.writeCharacters(field.getDesc());
      out.writeEndElement(); // </desc>
    }

    if (field.isRequired()) {
      out.writeStartElement("required");
      out.writeEndElement(); // </required>
    }

    DataValue[] values = field.getValue();
    if (values != null) {
      for (int i = 0; i < values.length; i++) {
        DataValue value = values[i];

        out.writeStartElement("value");
        out.writeCharacters(value.getValue());
        out.writeEndElement(); // </value>
      }
    }

    DataOption[] options = field.getOption();
    if (options != null) {
      for (int i = 0; i < options.length; i++) {
        toXml(out, options[i]);
      }
    }

    out.writeEndElement(); // </field>
  }