docs: public JBPMMessages.ProcessInstance writeProcessInstance(MarshallerWriteContext context,
                                                               ProcessInstance processInstance) throws IOException {
          WorkflowProcessInstanceImpl workFlow = (WorkflowProcessInstanceImpl) processInstance;
          
          JBPMMessages.ProcessInstance.Builder _instance = JBPMMessages.ProcessInstance.newBuilder()
                  .setId( workFlow.getId() )
                  .setProcessId( workFlow.getProcessId() )
                  .setState( workFlow.getState() )
                  .setNodeInstanceCounter( workFlow.getNodeInstanceCounter() )
                  .setProcessType( workFlow.getProcess().getType() )
                  .setParentProcessInstanceId(workFlow.getParentProcessInstanceId())
                  .setSignalCompletion(workFlow.isSignalCompletion())
                  .setSlaCompliance(workFlow.getSlaCompliance());
          if (workFlow.getProcessXml() != null) {
              _instance.setProcessXml( workFlow.getProcessXml());
          }
          if (workFlow.getDescription() != null) {
              _instance.setDescription(workFlow.getDescription());
          }
          if (workFlow.getDeploymentId() != null) {
              _instance.setDeploymentId(workFlow.getDeploymentId());
          }
          _instance.addAllCompletedNodeIds(workFlow.getCompletedNodeIds());
          if (workFlow.getCorrelationKey() != null) {
              _instance.setCorrelationKey(workFlow.getCorrelationKey());
          }
          if (workFlow.getSlaDueDate() != null) {
              _instance.setSlaDueDate(workFlow.getSlaDueDate().getTime());
          }
          if (workFlow.getSlaTimerId() != null) {
              _instance.setSlaTimerId(workFlow.getSlaTimerId());
          }
  
          SwimlaneContextInstance swimlaneContextInstance = (SwimlaneContextInstance) workFlow.getContextInstance( SwimlaneContext.SWIMLANE_SCOPE );
          if ( swimlaneContextInstance != null ) {
              Map<String, String> swimlaneActors = swimlaneContextInstance.getSwimlaneActors();
              for ( Map.Entry<String, String> entry : swimlaneActors.entrySet() ) {
                  _instance.addSwimlaneContext( JBPMMessages.ProcessInstance.SwimlaneContextInstance.newBuilder()
                          .setSwimlane( entry.getKey() )
                          .setActorId( entry.getValue() )
                          .build() );
              }
          }
  
          List<NodeInstance> nodeInstances = new ArrayList<NodeInstance>( workFlow.getNodeInstances() );
          Collections.sort( nodeInstances,
                            new Comparator<NodeInstance>() {
  
                                public int compare(NodeInstance o1,
                                                   NodeInstance o2) {
                                    return (int) (o1.getId() - o2.getId());
                                }
                            } );
          for ( NodeInstance nodeInstance : nodeInstances ) {
              _instance.addNodeInstance( writeNodeInstance( context,
                                                            nodeInstance ) );
          }
  
          List<ContextInstance> exclusiveGroupInstances =
                  workFlow.getContextInstances( ExclusiveGroup.EXCLUSIVE_GROUP );
          if ( exclusiveGroupInstances != null ) {
              for ( ContextInstance contextInstance : exclusiveGroupInstances ) {
                  JBPMMessages.ProcessInstance.ExclusiveGroupInstance.Builder _exclusive = JBPMMessages.ProcessInstance.ExclusiveGroupInstance.newBuilder();
                  ExclusiveGroupInstance exclusiveGroupInstance = (ExclusiveGroupInstance) contextInstance;
                  Collection<NodeInstance> groupNodeInstances = exclusiveGroupInstance.getNodeInstances();
                  for ( NodeInstance nodeInstance : groupNodeInstances ) {
                      _exclusive.addGroupNodeInstanceId( nodeInstance.getId() );
                  }
                  _instance.addExclusiveGroup( _exclusive.build() );
              }
          }
  
          VariableScopeInstance variableScopeInstance = (VariableScopeInstance) workFlow.getContextInstance( VariableScope.VARIABLE_SCOPE );
          List<Map.Entry<String, Object>> variables = new ArrayList<Map.Entry<String, Object>>( variableScopeInstance.getVariables().entrySet() );
          Collections.sort( variables,
                            new Comparator<Map.Entry<String, Object>>() {
                                public int compare(Map.Entry<String, Object> o1,
                                                   Map.Entry<String, Object> o2) {
                                    return o1.getKey().compareTo( o2.getKey() );
                                }
                            } );
  
          for ( Map.Entry<String, Object> variable : variables ) {
              if ( variable.getValue() != null ) {
                  _instance.addVariable( ProtobufProcessMarshaller.marshallVariable( context, variable.getKey(), variable.getValue() ) );
              }
          }
          
          List<Map.Entry<String, Integer>> iterationlevels = new ArrayList<Map.Entry<String, Integer>>( workFlow.getIterationLevels().entrySet() );
          Collections.sort( iterationlevels,
                            new Comparator<Map.Entry<String, Integer>>() {
                                public int compare(Map.Entry<String, Integer> o1,
                                                   Map.Entry<String, Integer> o2) {
                                    return o1.getKey().compareTo( o2.getKey() );
                                }
                            } );
  
          for ( Map.Entry<String, Integer> level : iterationlevels ) {
              if ( level.getValue() != null ) {
                  _instance.addIterationLevels( 
                          JBPMMessages.IterationLevel.newBuilder()
                          .setId(level.getKey())
                          .setLevel(level.getValue()) );
              }
          }
          
          return _instance.build();
      }