public static InternalFactHandle[] orderFacts(ObjectStore objectStore) {
    // this method is just needed for testing purposes, to allow round tripping
    int size = objectStore.size();
    InternalFactHandle[] handles = new InternalFactHandle[size];
    int i = 0;
    for (Iterator it = objectStore.iterateFactHandles(); it.hasNext(); ) {
      handles[i++] = (InternalFactHandle) it.next();
    }

    Arrays.sort(handles, new HandleSorter());

    return handles;
  }
 public Iterator<?> iterator() {
   Iterator it = null;
   if (type == OBJECT) {
     if (filter != null) {
       it = store.iterateObjects(filter);
     } else {
       it = store.iterateObjects();
     }
   } else {
     if (filter != null) {
       it = store.iterateFactHandles(filter);
     } else {
       it = store.iterateFactHandles();
     }
   }
   return it;
 }
  public static void writeFactHandles(MarshallerWriteContext context, ObjectStore objectStore)
      throws IOException {
    ObjectOutputStream stream = context.stream;
    InternalWorkingMemory wm = context.wm;
    ObjectMarshallingStrategyStore objectMarshallingStrategyStore =
        context.objectMarshallingStrategyStore;

    List<InternalFactHandle> matchFactHandles = null;

    if (((InternalAgenda) wm.getAgenda()).isDeclarativeAgenda()) {
      ActivationIterator it = ActivationIterator.iterator(wm);
      matchFactHandles = new ArrayList<InternalFactHandle>(100);
      for (Activation item = (Activation) it.next(); item != null; item = (Activation) it.next()) {
        matchFactHandles.add(item.getFactHandle());
      }
    }

    stream.writeInt(
        objectStore.size() + ((matchFactHandles == null) ? 0 : matchFactHandles.size()));

    // Write out FactHandles
    for (InternalFactHandle handle : orderFacts(objectStore)) {
      // stream.writeShort( PersisterEnums.FACT_HANDLE );
      // InternalFactHandle handle = (InternalFactHandle) it.next();
      writeFactHandle(context, stream, objectMarshallingStrategyStore, handle);

      writeRightTuples(handle, context);
    }

    if (matchFactHandles != null) {
      for (InternalFactHandle handle : orderFacts(matchFactHandles)) {
        Object object = handle.getObject();
        handle.setObject(
            null); // we must set it to null as we don't want to write out the Activation
        writeFactHandle(context, stream, objectMarshallingStrategyStore, handle);
        handle.setObject(object); // restore object
        writeRightTuples(handle, context);
      }
    }

    // writeLeftTuples( context );
    writeLeftTuples(context, orderFacts(objectStore));

    if (matchFactHandles != null) {
      stream.writeBoolean(true);
      writeLeftTuples(context, orderFacts(matchFactHandles));
    } else {
      stream.writeBoolean(false);
    }
  }
  public static void readFactHandles(MarshallerReaderContext context, ObjectStore objectStore)
      throws IOException, ClassNotFoundException {
    ObjectInputStream stream = context.stream;
    InternalWorkingMemory wm = context.wm;

    int size = stream.readInt();

    // load the handles
    InternalFactHandle[] handles = new InternalFactHandle[size];
    for (int i = 0; i < size; i++) {
      InternalFactHandle handle = readFactHandle(context);

      context.handles.put(handle.getId(), handle);
      handles[i] = handle;

      if (handle.getObject() != null) {
        objectStore.addHandle(handle, handle.getObject());
      }

      readRightTuples(handle, context);
    }

    readLeftTuples(context); // object store

    if (stream.readBoolean()) {
      readLeftTuples(context); // activation fact handles
    }

    // add handles to object type nodes
    for (InternalFactHandle factHandle : handles) {
      Object object = factHandle.getObject();

      EntryPoint ep =
          ((InternalWorkingMemoryEntryPoint) factHandle.getEntryPoint()).getEntryPoint();

      ObjectTypeConf typeConf =
          ((InternalWorkingMemoryEntryPoint) factHandle.getEntryPoint())
              .getObjectTypeConfigurationRegistry()
              .getObjectTypeConf(ep, object);
      ObjectTypeNode[] cachedNodes = typeConf.getObjectTypeNodes();
      for (int i = 0, length = cachedNodes.length; i < length; i++) {
        ObjectHashSet set = (ObjectHashSet) wm.getNodeMemory(cachedNodes[i]);
        set.add(factHandle, false);
      }
    }
  }