public static WorkItem readWorkItem(MarshallerReaderContext context) throws IOException {
    ObjectInputStream stream = context.stream;

    WorkItemImpl workItem = new WorkItemImpl();
    workItem.setId(stream.readLong());
    workItem.setProcessInstanceId(stream.readLong());
    workItem.setName(stream.readUTF());
    workItem.setState(stream.readInt());

    // WorkItem Paramaters
    int nbVariables = stream.readInt();
    if (nbVariables > 0) {

      for (int i = 0; i < nbVariables; i++) {
        String name = stream.readUTF();
        try {
          int index = stream.readInt();
          ObjectMarshallingStrategy strategy = null;
          // Old way of retrieving strategy objects
          if (index >= 0) {
            strategy = context.resolverStrategyFactory.getStrategy(index);
            if (strategy == null) {
              throw new IllegalStateException("No strategy of with index " + index + " available.");
            }
          }
          // New way
          else if (index == -2) {
            String strategyClassName = stream.readUTF();
            strategy = context.resolverStrategyFactory.getStrategyObject(strategyClassName);
            if (strategy == null) {
              throw new IllegalStateException(
                  "No strategy of type " + strategyClassName + " available.");
            }
          }

          Object value = strategy.read(stream);
          workItem.setParameter(name, value);
        } catch (ClassNotFoundException e) {
          throw new IllegalArgumentException("Could not reload variable " + name);
        }
      }
    }

    return workItem;
  }
  public static InternalFactHandle readFactHandle(MarshallerReaderContext context)
      throws IOException, ClassNotFoundException {
    int type = context.stream.readInt();
    int id = context.stream.readInt();
    long recency = context.stream.readLong();

    long startTimeStamp = 0;
    long duration = 0;
    boolean expired = false;
    long activationsCount = 0;
    if (type == 2) {
      startTimeStamp = context.stream.readLong();
      duration = context.stream.readLong();
      expired = context.stream.readBoolean();
      activationsCount = context.stream.readLong();
    }

    int strategyIndex = context.stream.readInt();
    Object object = null;
    ObjectMarshallingStrategy strategy = null;
    // This is the old way of de/serializing strategy objects
    if (strategyIndex >= 0) {
      strategy = context.resolverStrategyFactory.getStrategy(strategyIndex);
    }
    // This is the new way
    else if (strategyIndex == -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
    if (strategy != null) {
      object = strategy.read(context.stream);
    }

    WorkingMemoryEntryPoint entryPoint = null;
    if (context.readBoolean()) {
      String entryPointId = context.readUTF();
      if (entryPointId != null && !entryPointId.equals("")) {
        entryPoint = context.wm.getEntryPoints().get(entryPointId);
      }
    }
    InternalFactHandle handle = null;
    switch (type) {
      case 0:
        {
          handle = new DefaultFactHandle(id, object, recency, entryPoint);
          break;
        }
      case 1:
        {
          handle = new QueryElementFactHandle(object, id, recency);
          break;
        }
      case 2:
        {
          handle = new EventFactHandle(id, object, recency, startTimeStamp, duration, entryPoint);
          ((EventFactHandle) handle).setExpired(expired);
          ((EventFactHandle) handle).setActivationsCount(activationsCount);
          break;
        }
      default:
        {
          throw new IllegalStateException(
              "Unable to marshal FactHandle, as type does not exist:" + type);
        }
    }

    return handle;
  }