protected HashMap<String, ArrayList<String>> CollectSingleTableData(
      UserData data, String struct) {
    LinkedHashSet<String> s;
    List<String> tmp;

    MetaType mt = data.getUserDataType();
    s = new LinkedHashSet<String>(data.getUserData().keySet());
    HashMap<String, ArrayList<String>> tableVales = new HashMap<String, ArrayList<String>>();
    tmp = new ArrayList<String>();
    /* strip [] from userdata */
    for (String key : s) {

      String newKey = mt.removeIndicesFromStruct(key, struct);
      tmp.add(newKey);
      if (tableVales.containsKey(newKey)) {
        ArrayList<String> tmpVal = tableVales.get(newKey);
        tmpVal.add(data.getUserData().get(key));
        tableVales.put(newKey, tmpVal);
      } else {
        ArrayList<String> tmpVal = new ArrayList<String>();
        tmpVal.add(data.getUserData().get(key));
        tableVales.put(newKey, tmpVal);
      }
    }
    return tableVales;
  }
  @Override
  public synchronized String serializeUserData(UserData data) throws TransformationException {
    if (data == null) {
      throw new TransformationException("Supplied UserData is not valid.");
    }
    StringWriter writer = new StringWriter();
    type = data.getUserDataType();
    MetaField[] fields = type.getFields();
    MetaField field;

    writer.write("<object>");

    for (int i = 0; i < fields.length; i++) {
      field = fields[i];
      this.serializeType(writer, field.getName(), field, data, true);
    }

    writer.write("</object>");
    writer.flush();
    /*
     * logger.logp(java.util.logging.Level.FINEST, "UserDataSerializerXML",
     * "serializeUserData", "Serialized data:\n" + writer.toString());
     */
    return writer.toString();
  }
  private void serializePrimitive(
      StringWriter writer, String nestedFieldName, UserData data, MetaField mf) {
    String value = data.getFieldValue(nestedFieldName);

    if (value == null) {

      String typeName = ((MetaPrimitive) mf).getTypeName();

      if ("c_bool".equals(typeName)) {
        value = "TRUE";
      } else if ("c_char".equals(typeName)) {
        value = "a";
      } else if ("c_voidp".equals(typeName)) {
        value = "NULL";
      } else {
        value = "0";
      }
      logger.logp(
          Level.SEVERE,
          "UserDataSerializerXML",
          "serializePrimitive",
          "Could not find value for field: "
              + nestedFieldName
              + " initializing with default value: "
              + value);
    }
    writer.write(value);
  }
 private void serializeString(StringWriter writer, String nestedFieldName, UserData data) {
   String strData = data.getFieldValue(nestedFieldName);
   if (strData != null) {
     strData = strData.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;");
   }
   writer.write(strData);
 }
  /**
   * Serializes the contents of the supplied union.
   *
   * @param nestedFieldName The name of the union, including its scope.
   * @param field The union field to serialize the contents of.
   * @param data The data to serialize.
   */
  private void serializeUnionContents(
      StringWriter writer, String nestedFieldName, MetaUnion field, UserData data) {
    String value = data.getFieldValue(nestedFieldName + ".switch");

    MetaUnionCase c = field.getCase(value);

    writer.write("<switch>" + value + "</switch>");
    this.walkType(writer, nestedFieldName + "." + c.getField().getName(), c.getField(), data);
  }
  /**
   * Sets the supplied data in the model.
   *
   * @param sample The sample to administrate in this model.
   * @return true if the data != null and the type of the data equals the type of this model.
   * @todo TODO: Compare data types.
   */
  public boolean setData(Sample sample) {
    UserData data;
    boolean result = false;

    if (sample != null) {
      data = sample.getMessage().getUserData();
      int rowCount = this.getRowCount();

      for (int i = 0; i < rowCount; i++) {
        String fieldName = (String) this.getValueAt(i, 1);
        String fieldValue = data.getFieldValue(fieldName);
        this.setValueAt(fieldValue, i, 2);
      }
      ud = data;
      result = true;
    }
    return result;
  }
  /**
   * Serializes an unbounded sequence.
   *
   * @param nestedFieldName The name of the field (including scope)
   * @param seqType The type of the sequence.
   * @param data The data to serialize.
   */
  private void serializeUnboundedSequence(
      StringWriter writer, String nestedFieldName, MetaCollection seqType, UserData data) {
    String value;
    String typeName;
    StringTokenizer tokenizer;
    MetaField subType = seqType.getSubType();
    String token;
    String seqTypeName;

    seqTypeName = seqType.getTypeName();

    if (subType instanceof MetaPrimitive) {
      value = data.getFieldValue(nestedFieldName);

      if (value != null) {
        if (value.equals("NULL")) {
          writer.write("&lt;NULL&gt;");
        } else if (value.equals("[]")) {
          writer.write("<size>0</size>");
        } else {
          tokenizer = new StringTokenizer(value.substring(1, value.length() - 1), ",");
          int size = tokenizer.countTokens();

          writer.write("<size>" + size + "</size>");

          for (int i = 0; i < size; i++) {
            token = tokenizer.nextToken();
            writer.write("<element>" + token + "</element>");
          }
        }
      } else {
        // also check for the alternative notation
        value = data.getFieldValue(nestedFieldName + "[0]");
        if (value != null) {
          List<String> values = new ArrayList<String>();
          int index = 1;
          while (value != null) {
            values.add(value);
            value = data.getFieldValue(nestedFieldName + "[" + index + "]");
            index++;
          }
          writer.write("<size>" + values.size() + "</size>");
          Iterator<String> it = values.iterator();
          while (it.hasNext()) {
            writer.write("<element>" + it.next() + "</element>");
          }
        } else {
          writer.write("&lt;NULL&gt;");
        }
      }
    } else if (subType instanceof MetaCollection) {
      typeName = subType.getTypeName();

      if ((typeName.equals("c_string"))
          || (typeName.equals("c_wstring"))
          || (typeName.startsWith("C_STRING<"))
          || (typeName.startsWith("C_WSTRING<"))) {
        value = data.getFieldValue(nestedFieldName);

        if (value != null) {
          if (value.equals("NULL")) {
            writer.write("&lt;NULL&gt;");
          } else if (value.equals("[]")) {
            if (!(seqTypeName.startsWith("C_ARRAY"))) {
              writer.write("<size>0</size>");
            }
          } else {
            tokenizer = new StringTokenizer(value.substring(1, value.length() - 1), ",");
            int size = tokenizer.countTokens();

            if (!(seqTypeName.startsWith("C_ARRAY"))) {
              writer.write("<size>" + size + "</size>");
            }
            for (int i = 0; i < size; i++) {
              token = tokenizer.nextToken();
              writer.write("<element>" + token + "</element>");
            }
          }
        } else {
          writer.write("&lt;NULL&gt;");
        }
      }
    } else if (subType instanceof MetaStruct) {
      int size = 0;
      StringWriter localWriter = new StringWriter();
      // Verify if member "size" exists, if so, then serialize and
      // increment
      LinkedHashSet<String> fields = data.getFieldNames();
      boolean found = true;
      while (found) {
        String entryFieldName = nestedFieldName + "[" + size + "]";
        boolean fieldExists = false;
        Iterator<String> it = fields.iterator();
        while (!fieldExists && it.hasNext()) {
          if (it.next().startsWith(entryFieldName)) {
            fieldExists = true;
          }
        }
        if (fieldExists) {
          localWriter.write("<element>");
          serializeStruct(localWriter, entryFieldName, (MetaStruct) subType, data);
          localWriter.write("</element>");
          size++;
        } else {
          found = false;
        }
      }
      if (size == 0) {
        writer.write("&lt;NULL&gt;");
      } else {
        writer.write("<size>" + size + "</size>");
      }
      writer.write(localWriter.toString());
    } else if (subType instanceof MetaUnion) {
      int size = 0;
      StringWriter localWriter = new StringWriter();
      // Verify if member "size" exists, if so, then serialize and
      // increment
      LinkedHashSet<String> fields = data.getFieldNames();
      boolean found = true;
      while (found) {
        String entryFieldName = nestedFieldName + "[" + size + "]";
        boolean fieldExists = false;
        Iterator<String> it = fields.iterator();
        while (!fieldExists && it.hasNext()) {
          if (it.next().startsWith(entryFieldName)) {
            fieldExists = true;
          }
        }
        if (fieldExists) {
          localWriter.write("<element>");
          this.serializeUnion(localWriter, entryFieldName, (MetaUnion) subType, data);
          localWriter.write("</element>");
          size++;
        } else {
          found = false;
        }
      }
      if (size == 0) {
        writer.write("&lt;NULL&gt;");
      } else {
        writer.write("<size>" + size + "</size>");
      }
      writer.write(localWriter.toString());

    } else {
      writer.write("&lt;NULL&gt;");
    }
    return;
  }
  /**
   * Acquires the number of elements of the supplied sequence.
   *
   * @param nestedFieldName The name of the field (including scope)
   * @param seqType The type of the sequence.
   * @param data The data that is being serialized.
   * @return The number of elements in the given sequence.
   */
  private int getSequenceSize(String nestedFieldName, MetaCollection seqType, UserData data) {
    /*
     * This is very much based on how serializeUnboundedSequence get
     * the size of its unbounded sequence.
     * The same actions can be used on bounded sequences as well to
     * get their actual size (which can be less then their maximum
     * size).
     */
    int size = 0;

    StringTokenizer tokenizer;
    String typeName;
    String value;
    String token;
    MetaField subType = seqType.getSubType();

    if (subType instanceof MetaPrimitive) {
      value = data.getFieldValue(nestedFieldName);

      if (value != null) {
        if (!(value.equals("NULL") || value.equals("[]"))) {
          tokenizer = new StringTokenizer(value.substring(1, value.length() - 1), ",");
          size = tokenizer.countTokens();
        }
      } else {
        // also check for the alternative notation
        value = data.getFieldValue(nestedFieldName + "[0]");
        if (value != null) {
          List<String> values = new ArrayList<String>();
          int index = 1;
          while (value != null) {
            values.add(value);
            value = data.getFieldValue(nestedFieldName + "[" + index + "]");
            index++;
          }
          size = values.size();
        }
      }
    } else if (subType instanceof MetaCollection) {
      typeName = subType.getTypeName();

      if ((typeName.equals("c_string"))
          || (typeName.equals("c_wstring"))
          || (typeName.startsWith("C_STRING<"))
          || (typeName.startsWith("C_WSTRING<"))) {
        value = data.getFieldValue(nestedFieldName);

        if (value != null) {
          if (!(value.equals("NULL") || value.equals("[]"))) {
            tokenizer = new StringTokenizer(value.substring(1, value.length() - 1), ",");
            size = tokenizer.countTokens();
          }
        }
      }
    } else if ((subType instanceof MetaStruct) || (subType instanceof MetaUnion)) {
      // Verify if member "size" exists, if so, then serialize and
      // increment
      LinkedHashSet<String> fields = data.getFieldNames();
      boolean found = true;
      while (found) {
        String entryFieldName = nestedFieldName + "[" + size + "]";
        boolean fieldExists = false;
        Iterator<String> it = fields.iterator();
        while (!fieldExists && it.hasNext()) {
          if (it.next().startsWith(entryFieldName)) {
            fieldExists = true;
          }
        }
        if (fieldExists) {
          size++;
        } else {
          found = false;
        }
      }
    }
    return size;
  }
  /**
   * Serializes the contents of the supplied collection.
   *
   * @param nestedFieldName The name of the collection field in the data.
   * @param colType The type of the collection.
   * @param data The data to serialize.
   * @return The serialized representation of the collection data.
   */
  private String getSerializedStringCollection(
      String nestedFieldName, MetaCollection colType, UserData data) {
    String result = null;
    String size = null;
    String typeName = colType.getTypeName();
    int index = nestedFieldName.indexOf('[');
    String temp = null;

    if ((typeName.equals("c_string"))
        || (typeName.equals("c_wstring"))
        || (typeName.startsWith("C_STRING<"))
        || (typeName.startsWith("C_WSTRING<"))) {
      String strData = data.getFieldValue(nestedFieldName);
      result = strData.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;");
    } else if (colType.getSubType() instanceof MetaCollection) {
      result = "";

      if (colType.getSubType().getTypeName().startsWith("C_SEQUENCE<")) {
        size = "<size>" + ((MetaCollection) colType.getSubType()).getMaxSize() + "</size>";
      }

      if (index != -1) {
        temp = nestedFieldName.substring(0, index);

        for (int i = 0; i < colType.getMaxSize(); i++) {
          result += "<element>";

          if (size != null) {
            result += size;
          }
          result +=
              getSerializedStringCollection(
                  temp + "[" + i + "]" + nestedFieldName.substring(index),
                  (MetaCollection) colType.getSubType(),
                  data);
          result += "</element>";
        }
      } else {
        for (int i = 0; i < colType.getMaxSize(); i++) {
          result += "<element>";

          if (size != null) {
            result += size;
          }
          result +=
              getSerializedStringCollection(
                  nestedFieldName + "[" + i + "]", (MetaCollection) colType.getSubType(), data);
          result += "</element>";
        }
      }
    } else {
      result = "";

      if (index != -1) {
        temp = nestedFieldName.substring(0, index);

        for (int i = 0; i < colType.getMaxSize(); i++) {
          result += "<element>";
          result += data.getFieldValue(temp + "[" + i + "]" + nestedFieldName.substring(index));
          result += "</element>";
        }
      } else {
        for (int i = 0; i < colType.getMaxSize(); i++) {
          result += "<element>";
          result += data.getFieldValue(nestedFieldName + "[" + i + "]");
          result += "</element>";
        }
      }
    }
    return result;
  }
  /**
   * Serializes the contents of the supplied field. This is done be looking up the field in the type
   * of the data and retrieving the value of the field in the userdata.
   *
   * @param nestedFieldName The name of the field including its scope.
   * @param data The data to serialize.
   */
  private void serializeMemberContents(StringWriter writer, String nestedFieldName, UserData data) {
    boolean isString = false;
    String nestedFieldTypeName = this.removeIndices(nestedFieldName);
    MetaField typeField = type.getField(nestedFieldTypeName);
    MetaField originalType = typeField;
    String value = null;

    value = data.getFieldValue(nestedFieldName);
    logger.logp(
        java.util.logging.Level.FINEST,
        "UserDataSerializerXML",
        "serializeMemberContents",
        "Fieldname: " + nestedFieldName + " Value: " + value);

    if (typeField instanceof MetaCollection) {
      MetaCollection colType = (MetaCollection) typeField;

      while ((typeField instanceof MetaCollection) && (!isString)) {
        String typeName = typeField.getTypeName();

        if ((typeName.equals("c_string"))
            || (typeName.equals("c_wstring"))
            || (typeName.startsWith("C_STRING<"))
            || (typeName.startsWith("C_WSTRING<"))) {
          value = this.getSerializedStringCollection(nestedFieldName, colType, data);
          isString = true;
        } else {
          typeField = ((MetaCollection) typeField).getSubType();
        }
      }

      if (!isString) { // Type is not a string and does not contain
        // strings
        if ((originalType instanceof MetaCollection) && (typeField instanceof MetaStruct)) {
          MetaField field2;
          MetaField[] fields = typeField.getFields();
          int size = ((MetaCollection) originalType).getMaxSize();

          for (int i = 0; i < size; i++) {
            writer.write("<element>");

            for (int j = 0; j < fields.length; j++) {
              field2 = fields[j];
              this.walkType(
                  writer, nestedFieldName + "[" + i + "]." + field2.getName(), field2, data);
            }
            writer.write("</element>");
          }
          value = "";
        } else if ((originalType instanceof MetaCollection)
            && (originalType.getTypeName().startsWith("C_SEQUENCE<"))) {
          value = this.getSerializedStringCollection(nestedFieldName, colType, data);
        } else {
          value = value.replaceAll("\\[", "<element>");
          value = value.replaceAll("\\]", "</element>");
          value = value.replaceAll(",", "</element><element>");
        }
      } else {
        // Do nothing.
      }
    }
    writer.write(value);
  }
 private void serializeEnum(StringWriter writer, String nestedFieldName, UserData data) {
   writer.write(data.getFieldValue(nestedFieldName));
 }
  public boolean setData(Sample sample, String colName, int index) {
    UserData data;
    boolean result = true;
    if (sample != null) {
      data = sample.getMessage().getUserData();
      int rowCount = this.getRowCount();
      if (data == null) {
        return false;
      }
      HashMap<String, ArrayList<String>> tableData = CollectSingleTableData(data, colName);
      for (int i = 0; i < rowCount; i++) {
        String fName = (String) this.getValueAt(i, 1);
        if (index >= 0) {
          if (fName.startsWith(colName)) {
            String tmp = fName.substring(colName.length());
            fName = colName + "[" + index + "]" + tmp;
          }
        }

        if (tableData.containsKey(fName)) {
          ArrayList<String> colVals = tableData.get(fName);
          if (index >= 0) {
            this.setValueAt(colVals.get(index), i, 2);
          } else {
            this.setValueAt(colVals.toString(), i, 2);
          }
        } else if (tableData.containsKey(colName)) {
          ArrayList<String> colVals = tableData.get(colName);
          if (index >= 0) {
            this.setValueAt(colVals.get(index), i, 2);
          } else {
            this.setValueAt(colVals.toString(), i, 2);
          }
        } else {
          LinkedHashSet<String> s = new LinkedHashSet<String>(data.getUserData().keySet());
          String value = null;
          for (String key : s) {
            if (key.startsWith(fName)) {
              if (value != null) {
                value = value + "," + data.getUserData().get(key);
              } else {
                value = data.getUserData().get(key);
              }
            }
          }
          if (value == null) {
            LinkedHashSet<String> td = new LinkedHashSet<String>(tableData.keySet());
            for (String key : td) {
              if (key.startsWith(fName)) {
                if (value != null) {
                  value = value + "," + tableData.get(key).toString();
                } else {
                  value = tableData.get(key).toString();
                }
              }
            }
          }
          this.setValueAt(value, i, 2);
        }
      }
      ud = data;
    }

    return result;
  }