public void writeHiddenClass(
     TreeMapConverter mapConverter, HierarchicalStreamWriter writer, MarshallingContext context) {
   if (Snapshot.getLocal().getFieldSetFromId(id) != null) {
     writer.startNode(nodeName);
     writer.addAttribute(XMLConstants.ID_ATTRIBUTE, id.toString());
     writer.addAttribute(XMLConstants.FIELDSET_ATTRIBUTE, "true");
     mapConverter.marshal(Snapshot.getLocal().getFieldSetFromId(id), writer, context);
     writer.endNode();
   }
 }
  // ----------------------------------------------------------
  public void marshal(Object source, HierarchicalStreamWriter writer, MarshallingContext context) {
    if (source instanceof AbstractPersistentMap) {
      throw new IllegalArgumentException(
          "You cannot store an object that contains a reference to a "
              + source.getClass().getSimpleName());
    }
    writer.addAttribute(XMLConstants.FIELDSET_ATTRIBUTE, "true");
    Map<String, Object> fields = objectToFieldMap(source);
    // BUG: The persistence store will attempt to persist an inner class.
    // This is the same as storing an object that references the Application
    // class
    if (fields.containsKey("this$0")) {
      throw new IllegalArgumentException(
          "The class "
              + source.getClass().getName()
              + " cannot be persisted because the definition of this class is contained within the "
              + fields.get("this$0").getClass().getName()
              + " class.  Move "
              + source.getClass().getName()
              + " to its own JAVA file.");
    }
    checkFields(source.getClass().getName(), fields);
    UUID id = Snapshot.lookupId(source, true);

    writer.addAttribute(XMLConstants.ID_ATTRIBUTE, id.toString());

    Map<String, Object> updatedFieldSets =
        generateUpdatedFieldSet(Snapshot.getLocal(), Snapshot.getNewest(), source, fields);
    List<String> nulledKeys = new ArrayList<String>();
    for (String key : updatedFieldSets.keySet()) {
      if (updatedFieldSets.get(key) instanceof NullableClass) {
        NullableClass nClass = (NullableClass) updatedFieldSets.get(key);
        nClass.writeHiddenClass(mapConverter, writer, context);
        // updatedFieldSets.remove( key );
        nulledKeys.add(key);
      }
    }
    for (String key : nulledKeys) updatedFieldSets.remove(key);
    restoreObjectFromFieldMap(source, updatedFieldSets);
    Snapshot.getLocal().resolveObject(id, source, updatedFieldSets);
    mapConverter.marshal(updatedFieldSets, writer, context);
  }
  // ----------------------------------------------------------
  public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context) {
    //        Object current = context.currentObject();
    Object result = getInstance(context);
    //        Object result = null;
    if (top == true && key != null && cache != null) {
      // This is simply to prevent infinite recursion when you get an
      // object out of the store that references this object. This stored
      // object will be overwritten when everything is finished.
      cache.put(key, new StoredObject(key, "ALIAS", result, Snapshot.getLocal(), Long.MAX_VALUE));
      top = false;
    }
    Map<String, Object> fields = null;
    UUID id = null;
    if (reader.getAttribute(XMLConstants.FIELDSET_ATTRIBUTE) != null) {
      String objId = reader.getAttribute(XMLConstants.ID_ATTRIBUTE);
      id = UUID.fromString(objId);
      @SuppressWarnings("unchecked")
      Map<String, Object> realFields =
          (Map<String, Object>) mapConverter.unmarshal(reader, context);
      fields = realFields;
    } else {
      result = super.unmarshal(reader, context);
      if (result instanceof TreeMap && !TreeMap.class.isAssignableFrom(context.getRequiredType())) {
        @SuppressWarnings("unchecked")
        Map<String, Object> realFields = (Map<String, Object>) result;
        fields = realFields;
      }
    }

    if (fields != null) {
      try {
        Method initFieldsMethod = result.getClass().getMethod("initializeFields", (Class<?>) null);
        initFieldsMethod.invoke(result, (Object[]) null);
      } catch (Exception e) {
        // its ok if this doesnt exist
      }
      //            result = reflectionProvider.newInstance( context.getRequiredType() );
      restoreObjectFromFieldMap(result, fields); /*
                                                               * && pjProvider
                                                               * != null
                                                               */
      //            {
      //                try
      //                {
      //                    Method initFieldsMethod = result.getClass()
      //                        .getMethod( "initializeFields", (Class<?>)null );
      //                    initFieldsMethod.invoke( result, (Object[])null );
      //                }
      //                catch ( Exception e )
      //                {
      //                    try
      //                    {
      //                        Constructor<?> defaultConst = result.getClass()
      //                            .getConstructor();
      //                        Object newResult = defaultConst.newInstance();
      //                        restoreObjectFromFieldMap( newResult, fields );
      //                        result = newResult;
      //
      //                    }
      //                    catch ( SecurityException e1 )
      //                    {
      //                        System.err.println( "You made your default constructor for "
      //                            + result.getClass().getName()
      //                            + " private.  If you would like it to be used"
      //                            + " by the persistence library please make it public" );
      //                    }
      //                    catch ( NoSuchMethodException e2 )
      //                    {
      //                        System.err.println( "The shared object \""
      //                            + result.getClass().getName()
      //                            + "\" you have loaded did not "
      //                            + "contain all of the fields present in your original object.  "
      //                            + "We were also unable to find a method with the signature
      // \"public "
      //                            + "void initializeFields()\" or the "
      //                            + "default constructor \"public "
      //                            + result.getClass().getName()
      //                            + "()\".  If you have made assumptions "
      //                            + "about the state of certain fields in your "
      //                            + result.getClass().getName()
      //                            + " Object please provide one of these methods to initialize the
      // fields "
      //                            + "not present in the datastore." );
      //                    }
      //                    catch ( Exception e3 )
      //                    {
      //                        System.err.println( "An exception occured when initializing your
      // object with the default constructor." );
      //                    }
      //
      //                }
      //            }

      if (result != null) {
        Snapshot.getLocal().resolveObject(id, result, fields);
      }
    }

    return result;
  }