@SuppressWarnings("unchecked")
  private static ProtobufMessages.NodeMemory writeFromNodeMemory(
      final int nodeId, final Memory memory) {
    FromMemory fromMemory = (FromMemory) memory;

    if (fromMemory.betaMemory.getLeftTupleMemory().size() > 0) {
      ProtobufMessages.NodeMemory.FromNodeMemory.Builder _from =
          ProtobufMessages.NodeMemory.FromNodeMemory.newBuilder();

      final org.drools.core.util.Iterator tupleIter =
          fromMemory.betaMemory.getLeftTupleMemory().iterator();
      for (LeftTuple leftTuple = (LeftTuple) tupleIter.next();
          leftTuple != null;
          leftTuple = (LeftTuple) tupleIter.next()) {
        Map<Object, RightTuple> matches = (Map<Object, RightTuple>) leftTuple.getObject();
        ProtobufMessages.NodeMemory.FromNodeMemory.FromContext.Builder _context =
            ProtobufMessages.NodeMemory.FromNodeMemory.FromContext.newBuilder()
                .setTuple(PersisterHelper.createTuple(leftTuple));
        for (RightTuple rightTuple : matches.values()) {
          FactHandle _handle =
              ProtobufMessages.FactHandle.newBuilder()
                  .setId(rightTuple.getFactHandle().getId())
                  .setRecency(rightTuple.getFactHandle().getRecency())
                  .build();
          _context.addHandle(_handle);
        }
        _from.addContext(_context.build());
      }

      return ProtobufMessages.NodeMemory.newBuilder()
          .setNodeId(nodeId)
          .setNodeType(ProtobufMessages.NodeMemory.NodeType.FROM)
          .setFrom(_from.build())
          .build();
    }
    return null;
  }
 private static void readNodeMemories(MarshallerReaderContext context, RuleData _session) {
   for (ProtobufMessages.NodeMemory _node : _session.getNodeMemoryList()) {
     Object memory = null;
     switch (_node.getNodeType()) {
       case ACCUMULATE:
         {
           Map<TupleKey, ProtobufMessages.FactHandle> map =
               new HashMap<TupleKey, ProtobufMessages.FactHandle>();
           for (ProtobufMessages.NodeMemory.AccumulateNodeMemory.AccumulateContext _ctx :
               _node.getAccumulate().getContextList()) {
             map.put(PersisterHelper.createTupleKey(_ctx.getTuple()), _ctx.getResultHandle());
           }
           memory = map;
           break;
         }
       case RIA:
         {
           Map<TupleKey, ProtobufMessages.FactHandle> map =
               new HashMap<TupleKey, ProtobufMessages.FactHandle>();
           for (ProtobufMessages.NodeMemory.RIANodeMemory.RIAContext _ctx :
               _node.getRia().getContextList()) {
             map.put(PersisterHelper.createTupleKey(_ctx.getTuple()), _ctx.getResultHandle());
           }
           memory = map;
           break;
         }
       case FROM:
         {
           Map<TupleKey, List<ProtobufMessages.FactHandle>> map =
               new HashMap<TupleKey, List<ProtobufMessages.FactHandle>>();
           for (ProtobufMessages.NodeMemory.FromNodeMemory.FromContext _ctx :
               _node.getFrom().getContextList()) {
             // have to instantiate a modifiable list
             map.put(
                 PersisterHelper.createTupleKey(_ctx.getTuple()),
                 new LinkedList<ProtobufMessages.FactHandle>(_ctx.getHandleList()));
           }
           memory = map;
           break;
         }
       case QUERY_ELEMENT:
         {
           Map<TupleKey, QueryElementContext> map = new HashMap<TupleKey, QueryElementContext>();
           for (ProtobufMessages.NodeMemory.QueryElementNodeMemory.QueryContext _ctx :
               _node.getQueryElement().getContextList()) {
             // we have to use a "cloned" query element context as we need to write on it during
             // deserialization process and the
             // protobuf one is read-only
             map.put(
                 PersisterHelper.createTupleKey(_ctx.getTuple()), new QueryElementContext(_ctx));
           }
           memory = map;
           break;
         }
       default:
         {
           throw new IllegalArgumentException(
               "Unknown node type " + _node.getNodeType() + " while deserializing session.");
         }
     }
     context.nodeMemories.put(_node.getNodeId(), memory);
   }
 }