/** Serializes the object to XML */
  public void toXml(XmppStreamWriter out, Serializable object)
      throws IOException, XMLStreamException {
    DataForm form = (DataForm) object;

    out.writeStartElement("", getLocalName(), getNamespaceURI());
    out.writeNamespace("", getNamespaceURI());

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

    if (form.getTitle() != null) {
      out.writeStartElement("title");
      out.writeCharacters(form.getTitle());
      out.writeEndElement(); // </title>
    }

    DataInstructions[] instructions = form.getInstructions();
    if (instructions != null) {
      for (DataInstructions instruction : instructions) {
        toXml(out, instruction);
      }
    }

    DataField[] fields = form.getField();
    if (fields != null) {
      for (DataField field : fields) {
        toXml(out, field);
      }
    }

    if (form.getReported() != null) toXml(out, form.getReported());

    DataItem[] items = form.getItem();
    if (items != null) {
      for (DataItem item : items) {
        toXml(out, item);
      }
    }

    out.writeEndElement(); // </form>
  }
  /** Deserializes the object from XML */
  public Serializable fromXml(XmppStreamReader in) throws IOException, XMLStreamException {
    boolean isFinest = log.isLoggable(Level.FINEST);

    String type = in.getAttributeValue(null, "type");

    DataForm form = new DataForm(type);

    ArrayList<DataField> fieldList = new ArrayList<DataField>();
    ArrayList<DataItem> itemList = new ArrayList<DataItem>();
    ArrayList<DataInstructions> instructionsList = new ArrayList<DataInstructions>();

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

      if (XMLStreamReader.END_ELEMENT == tag) {
        form.setFieldList(fieldList);
        form.setItemList(itemList);
        form.setInstructionsList(instructionsList);

        return form;
      }

      if (XMLStreamReader.START_ELEMENT == tag && "field".equals(in.getLocalName())) {
        fieldList.add(parseField(in));
      } else if (XMLStreamReader.START_ELEMENT == tag && "item".equals(in.getLocalName())) {
        itemList.add(parseItem(in));
      } else if (XMLStreamReader.START_ELEMENT == tag && "reported".equals(in.getLocalName())) {
        form.setReported(parseReported(in));
      } else if (XMLStreamReader.START_ELEMENT == tag && "title".equals(in.getLocalName())) {
        String title = in.getElementText();

        form.setTitle(title);

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

        instructionsList.add(new DataInstructions(value));

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

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

      tag = in.nextTag();
    }

    return null;
  }