docs: public ProcessInstance readProcessInstance(MarshallerReaderContext context) throws IOException {
          ObjectInputStream stream = context.stream;
          InternalKnowledgeBase kBase = context.kBase;
          InternalWorkingMemory wm = context.wm;
  
          WorkflowProcessInstanceImpl processInstance = createProcessInstance();
          processInstance.setId(stream.readLong());
          String processId = stream.readUTF();
          processInstance.setProcessId(processId);
          Process process = kBase.getProcess(processId);
          if (kBase != null) {
              processInstance.setProcess(process);
          }
          processInstance.setState(stream.readInt());
          long nodeInstanceCounter = stream.readLong();
          processInstance.setKnowledgeRuntime(wm.getKnowledgeRuntime());
  
          int nbSwimlanes = stream.readInt();
          if (nbSwimlanes > 0) {
              Context swimlaneContext = ((org.jbpm.process.core.Process) process).getDefaultContext(SwimlaneContext.SWIMLANE_SCOPE);
              SwimlaneContextInstance swimlaneContextInstance = (SwimlaneContextInstance) processInstance.getContextInstance(swimlaneContext);
              for (int i = 0; i < nbSwimlanes; i++) {
                  String name = stream.readUTF();
                  String value = stream.readUTF();
                  swimlaneContextInstance.setActorId(name, value);
              }
          }
  
          while (stream.readShort() == PersisterEnums.NODE_INSTANCE) {
              readNodeInstance(context, processInstance, processInstance);
          }
  
          int exclusiveGroupInstances = stream.readInt();
      	for (int i = 0; i < exclusiveGroupInstances; i++) {
              ExclusiveGroupInstance exclusiveGroupInstance = new ExclusiveGroupInstance();
              processInstance.addContextInstance(ExclusiveGroup.EXCLUSIVE_GROUP, exclusiveGroupInstance);
              int nodeInstances = stream.readInt();
              for (int j = 0; j < nodeInstances; j++) {
                  long nodeInstanceId = stream.readLong();
                  NodeInstance nodeInstance = processInstance.getNodeInstance(nodeInstanceId);
                  if (nodeInstance == null) {
                  	throw new IllegalArgumentException("Could not find node instance when deserializing exclusive group instance: " + nodeInstanceId);
                  }
                  exclusiveGroupInstance.addNodeInstance(nodeInstance);
              }
      	}
  
          // Process Variables
          // - Number of Variables = keys.size()
          // For Each Variable
              // - Variable Key
              // - Marshalling Strategy Index
              // - Marshalled Object
  		int nbVariables = stream.readInt();
  		if (nbVariables > 0) {
  			Context variableScope = ((org.jbpm.process.core.Process) process)
  					.getDefaultContext(VariableScope.VARIABLE_SCOPE);
  			VariableScopeInstance variableScopeInstance = (VariableScopeInstance) processInstance
  					.getContextInstance(variableScope);
  			for (int i = 0; i < nbVariables; i++) {
  				String name = stream.readUTF();
  				try {
  			        ObjectMarshallingStrategy strategy = null;
  					int index = stream.readInt();
  			        // This is the old way of de/serializing strategy objects
  			        if ( index >= 0 ) {
  			            strategy = context.resolverStrategyFactory.getStrategy( index );
  			        }
  			        // This is the new way 
  			        else if( index == -2 ) { 
  			            String strategyClassName = context.stream.readUTF();
  			            if ( ! StringUtils.isEmpty(strategyClassName) ) { 
  			                strategy = context.resolverStrategyFactory.getStrategyObject(strategyClassName);
  			                if( strategy == null ) { 
  			                    throw new IllegalStateException( "No strategy of type " + strategyClassName + " available." );
  			                }
  			            }
  			        }
  			        // If either way retrieves a strategy, use it
  			        Object value = null;
  			        if( strategy != null ) { 
  			            value = strategy.read( stream );
  			        }
  					variableScopeInstance.internalSetVariable(name, value);
  				} catch (ClassNotFoundException e) {
  					throw new IllegalArgumentException(
  							"Could not reload variable " + name);
  				}
  			}
  		}
          processInstance.internalSetNodeInstanceCounter(nodeInstanceCounter);
          if (wm != null) {
              processInstance.reconnect();
          }
          return processInstance;
      }