public static void readAgenda(
      MarshallerReaderContext context, RuleData _ruleData, DefaultAgenda agenda) {
    ProtobufMessages.Agenda _agenda = _ruleData.getAgenda();

    for (org.drools.core.marshalling.impl.ProtobufMessages.Agenda.AgendaGroup _agendaGroup :
        _agenda.getAgendaGroupList()) {
      InternalAgendaGroup group =
          (InternalAgendaGroup) agenda.getAgendaGroup(_agendaGroup.getName(), context.ruleBase);
      group.setActive(_agendaGroup.getIsActive());
      agenda.getAgendaGroupsMap().put(group.getName(), group);
    }

    for (String _groupName : _agenda.getFocusStack().getGroupNameList()) {
      agenda.addAgendaGroupOnStack(agenda.getAgendaGroup(_groupName));
    }

    for (ProtobufMessages.Agenda.RuleFlowGroup _ruleFlowGroup : _agenda.getRuleFlowGroupList()) {
      RuleFlowGroupImpl rfgi =
          new RuleFlowGroupImpl(
              _ruleFlowGroup.getName(),
              _ruleFlowGroup.getIsActive(),
              _ruleFlowGroup.getIsAutoDeactivate());
      agenda.getRuleFlowGroupsMap().put(_ruleFlowGroup.getName(), rfgi);

      //            readActivations( context,
      //                             _ruleFlowGroup.getActivationList() );

      for (NodeInstance _nodeInstance : _ruleFlowGroup.getNodeInstanceList()) {
        rfgi.addNodeInstance(
            _nodeInstance.getProcessInstanceId(), _nodeInstance.getNodeInstanceId());
      }
    }

    readActivations(context, _agenda.getActivationList(), _agenda.getRneaList());
    agenda.setActivationsFilter(context.filter);
  }
  public static ReteooStatefulSession readSession(
      ProtobufMessages.KnowledgeSession _session,
      ReteooStatefulSession session,
      DefaultAgenda agenda,
      MarshallerReaderContext context)
      throws IOException, ClassNotFoundException {
    GlobalResolver globalResolver = (GlobalResolver) context.env.get(EnvironmentName.GLOBALS);
    if (globalResolver != null) {
      session.setGlobalResolver(globalResolver);
    }

    if (session.getTimerService() instanceof PseudoClockScheduler) {
      PseudoClockScheduler clock = (PseudoClockScheduler) session.getTimerService();
      clock.advanceTime(_session.getTime(), TimeUnit.MILLISECONDS);
    }

    // RuleFlowGroups need to reference the session
    for (RuleFlowGroup group : agenda.getRuleFlowGroupsMap().values()) {
      ((RuleFlowGroupImpl) group).setWorkingMemory(session);
    }

    context.wm = session;

    // need to read node memories before reading the fact handles
    // because this data is required during fact propagation
    readNodeMemories(context, _session.getRuleData());

    List<PropagationContextImpl> pctxs = new ArrayList<PropagationContextImpl>();

    readInitialFactHandle(context, _session.getRuleData(), pctxs);

    for (ProtobufMessages.EntryPoint _ep : _session.getRuleData().getEntryPointList()) {
      SessionEntryPoint wmep = context.wm.getEntryPoints().get(_ep.getEntryPointId());
      readFactHandles(context, _ep, ((NamedEntryPoint) wmep).getObjectStore(), pctxs);
      readTruthMaintenanceSystem(context, wmep, _ep, pctxs);
    }

    cleanReaderContexts(pctxs);

    readActionQueue(context, _session.getRuleData());

    if (processMarshaller != null) {
      if (_session.hasProcessData()) {
        context.parameterObject = _session.getProcessData();
        processMarshaller.readProcessInstances(context);

        context.parameterObject = _session.getProcessData();
        processMarshaller.readWorkItems(context);

        // This actually does ALL timers, due to backwards compatability issues
        // It will read in old JBPM binaries, but always write to the new binary format.
        context.parameterObject = _session.getProcessData();
        processMarshaller.readProcessTimers(context);
      }
    } else {
      if (_session.hasProcessData()) {
        throw new IllegalStateException(
            "No process marshaller, unable to unmarshall process data.");
      }
    }

    if (_session.hasTimers()) {
      for (ProtobufMessages.Timers.Timer _timer : _session.getTimers().getTimerList()) {
        readTimer(context, _timer);
      }
    }

    // remove the activations filter
    agenda.setActivationsFilter(null);

    return session;
  }