public static Procedure<?> convertToProcedure(ProcedureProtos.Procedure proto)
    throws IOException {
    // Procedure from class name
    Procedure<?> proc = newProcedure(proto.getClassName());

    // set fields
    proc.setProcId(proto.getProcId());
    proc.setState(proto.getState());
    proc.setSubmittedTime(proto.getSubmittedTime());
    proc.setLastUpdate(proto.getLastUpdate());

    if (proto.hasParentId()) {
      proc.setParentProcId(proto.getParentId());
    }

    if (proto.hasOwner()) {
      proc.setOwner(proto.getOwner());
    }

    if (proto.hasTimeout()) {
      proc.setTimeout(proto.getTimeout());
    }

    if (proto.getStackIdCount() > 0) {
      proc.setStackIndexes(proto.getStackIdList());
    }
    if (proto.getExecuted()) {
      proc.setExecuted();
    }

    if (proto.hasException()) {
      assert proc.getState() == ProcedureProtos.ProcedureState.FAILED
        || proc.getState() == ProcedureProtos.ProcedureState.ROLLEDBACK
        : "The procedure must be failed (waiting to rollback) or rolledback";
      proc.setFailure(RemoteProcedureException.fromProto(proto.getException()));
    }

    if (proto.hasResult()) {
      proc.setResult(proto.getResult().toByteArray());
    }

    if (proto.getNonce() != HConstants.NO_NONCE) {
      proc.setNonceKey(new NonceKey(proto.getNonceGroup(), proto.getNonce()));
    }

    if (proto.getLocked()) {
      proc.lockedWhenLoading();
    }

    if (proto.getBypass()) {
      proc.bypass(null);
    }

    ProcedureStateSerializer serializer = null;

    if (proto.getStateMessageCount() > 0) {
      serializer = new StateSerializer(proto.toBuilder());
    } else if (proto.hasStateData()) {
      InputStream inputStream = proto.getStateData().newInput();
      serializer = new CompatStateSerializer(inputStream);
    }

    if (serializer != null) {
      proc.deserializeStateData(serializer);
    }

    return proc;
  }
Helper to convert the protobuf procedure.
<p/>
Used by ProcedureStore implementations.
<p/>
TODO: OPTIMIZATION: some of the field never change during the execution (e.g. className,
procId, parentId, ...). We can split in 'data' and 'state', and the store may take advantage of
it by storing the data only on insert().
hbase-procedure/src/main/java/org/apache/hadoop/hbase/procedure2/ProcedureUtil.java