public static void readTruthMaintenanceSystem(MarshallerReaderContext context)
      throws IOException {
    ObjectInputStream stream = context.stream;

    TruthMaintenanceSystem tms = context.wm.getTruthMaintenanceSystem();
    while (stream.readShort() == PersisterEnums.EQUALITY_KEY) {
      int status = stream.readInt();
      int factHandleId = stream.readInt();
      InternalFactHandle handle = (InternalFactHandle) context.handles.get(factHandleId);

      // ObjectTypeConf state is not marshalled, so it needs to be re-determined
      ObjectTypeConf typeConf =
          context
              .wm
              .getObjectTypeConfigurationRegistry()
              .getObjectTypeConf(context.wm.getEntryPoint(), handle.getObject());
      if (!typeConf.isTMSEnabled()) {
        typeConf.enableTMS();
      }

      EqualityKey key = new EqualityKey(handle, status);
      handle.setEqualityKey(key);
      while (stream.readShort() == PersisterEnums.FACT_HANDLE) {
        factHandleId = stream.readInt();
        handle = (InternalFactHandle) context.handles.get(factHandleId);
        key.addFactHandle(handle);
        handle.setEqualityKey(key);
      }
      tms.put(key);
    }
  }
  @Test
  public void testLogicalInsertionsWithModify() throws Exception {
    final PackageBuilder builder = new PackageBuilder();
    builder.addPackageFromDrl(
        new InputStreamReader(
            getClass().getResourceAsStream("test_LogicalInsertionsWithUpdate.drl")));
    if (builder.hasErrors()) {
      fail(builder.getErrors().toString());
    }
    final Package pkg = builder.getPackage();

    RuleBase ruleBase = getRuleBase();
    ruleBase.addPackage(pkg);
    ruleBase = SerializationHelper.serializeObject(ruleBase);
    StatefulSession workingMemory = ruleBase.newStatefulSession();

    List l;
    final Person p = new Person("person");
    p.setAge(2);
    FactHandle h = workingMemory.insert(p);
    assertEquals(1, IteratorToList.convert(workingMemory.iterateObjects()).size());

    workingMemory.fireAllRules();
    workingMemory = getSerialisedStatefulSession(workingMemory);
    assertEquals(2, IteratorToList.convert(workingMemory.iterateObjects()).size());

    l =
        IteratorToList.convert(
            workingMemory.iterateObjects(new ClassObjectFilter(CheeseEqual.class)));
    assertEquals(1, l.size());
    assertEquals(2, ((CheeseEqual) l.get(0)).getPrice());

    h = getFactHandle(h, workingMemory);
    workingMemory.retract(h);
    workingMemory = getSerialisedStatefulSession(workingMemory);
    assertEquals(0, IteratorToList.convert(workingMemory.iterateObjects()).size());

    TruthMaintenanceSystem tms =
        ((InternalWorkingMemory) workingMemory).getTruthMaintenanceSystem();

    final java.lang.reflect.Field field = tms.getClass().getDeclaredField("assertMap");
    field.setAccessible(true);
    final ObjectHashMap m = (ObjectHashMap) field.get(tms);
    field.setAccessible(false);
    assertEquals("assertMap should be empty", 0, m.size());
  }
  public static Activation readActivation(MarshallerReaderContext context) throws IOException {
    ObjectInputStream stream = context.stream;
    InternalRuleBase ruleBase = context.ruleBase;
    InternalWorkingMemory wm = context.wm;

    long activationNumber = stream.readLong();

    int pos = stream.readInt();
    LeftTuple leftTuple = context.terminalTupleMap.get(pos);

    int salience = stream.readInt();

    String pkgName = stream.readUTF();
    String ruleName = stream.readUTF();
    Package pkg = ruleBase.getPackage(pkgName);
    Rule rule = pkg.getRule(ruleName);

    RuleTerminalNode ruleTerminalNode = (RuleTerminalNode) leftTuple.getLeftTupleSink();

    PropagationContext pc = context.propagationContexts.get(stream.readLong());

    AgendaItem activation;

    boolean scheduled = false;
    if (rule.getTimer() != null) {
      activation =
          new ScheduledAgendaItem(
              activationNumber, leftTuple, (InternalAgenda) wm.getAgenda(), pc, ruleTerminalNode);
      scheduled = true;
    } else {
      activation = new AgendaItem(activationNumber, leftTuple, salience, pc, ruleTerminalNode);
    }
    leftTuple.setObject(activation);

    if (stream.readBoolean()) {
      String activationGroupName = stream.readUTF();
      ((DefaultAgenda) wm.getAgenda())
          .getActivationGroup(activationGroupName)
          .addActivation(activation);
    }

    boolean activated = stream.readBoolean();
    activation.setActivated(activated);

    if (stream.readBoolean()) {
      InternalFactHandle handle = context.handles.get(stream.readInt());
      activation.setFactHandle(handle);
      handle.setObject(activation);
    }

    InternalAgendaGroup agendaGroup;
    if (rule.getAgendaGroup() == null
        || rule.getAgendaGroup().equals("")
        || rule.getAgendaGroup().equals(AgendaGroup.MAIN)) {
      // Is the Rule AgendaGroup undefined? If it is use MAIN,
      // which is added to the Agenda by default
      agendaGroup =
          (InternalAgendaGroup) ((DefaultAgenda) wm.getAgenda()).getAgendaGroup(AgendaGroup.MAIN);
    } else {
      // AgendaGroup is defined, so try and get the AgendaGroup
      // from the Agenda
      agendaGroup =
          (InternalAgendaGroup)
              ((DefaultAgenda) wm.getAgenda()).getAgendaGroup(rule.getAgendaGroup());
    }

    activation.setAgendaGroup(agendaGroup);

    if (!scheduled && activated) {
      if (rule.getRuleFlowGroup() == null) {
        agendaGroup.add(activation);
      } else {
        InternalRuleFlowGroup rfg =
            (InternalRuleFlowGroup)
                ((DefaultAgenda) wm.getAgenda()).getRuleFlowGroup(rule.getRuleFlowGroup());
        rfg.addActivation(activation);
      }
    }

    TruthMaintenanceSystem tms = context.wm.getTruthMaintenanceSystem();
    while (stream.readShort() == PersisterEnums.LOGICAL_DEPENDENCY) {
      int factHandleId = stream.readInt();
      InternalFactHandle handle = (InternalFactHandle) context.handles.get(factHandleId);
      ObjectTypeConf typeConf =
          context
              .wm
              .getObjectTypeConfigurationRegistry()
              .getObjectTypeConf(
                  ((NamedEntryPoint) handle.getEntryPoint()).getEntryPoint(), handle.getObject());
      tms.addLogicalDependency(handle, activation, pc, rule, typeConf);
    }

    return activation;
  }