@Override
 public Menu deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException {
   if (StringUtil.isBlank(jp.getValueAsString())) {
     return null;
   }
   return new Menu(jp.getValueAsLong());
 }
 @Override
 public Member deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException {
   Long value = jp.getValueAsLong();
   if (StringUtil.isBlank(value)) {
     return null;
   }
   return new Member(value);
 }
 @Override
 public Object deserialize(JsonParser jp, DeserializationContext ctxt)
     throws IOException, JsonProcessingException {
   // couple of accepted types...
   Object value;
   if (_inputType == null) {
     value = jp.getText();
   } else if (_inputType == Integer.class) {
     value = Integer.valueOf(jp.getValueAsInt());
   } else if (_inputType == Long.class) {
     value = Long.valueOf(jp.getValueAsLong());
   } else {
     throw ctxt.mappingException(_enumClass);
   }
   try {
     return _factory.invoke(_enumClass, value);
   } catch (Exception e) {
     ClassUtil.unwrapAndThrowAsIAE(e);
   }
   return null;
 }
  @Override
  public ActionItem deserialize(JsonParser jp, DeserializationContext ctxt)
      throws IOException, JsonProcessingException {
    ObjectNode objectNode = jp.readValueAsTree();
    JsonNode wrapped = objectNode.get("actionItemType");
    JsonParser parser = wrapped.traverse();
    parser.setCodec(jp.getCodec());
    ActionItemType actionItemType = parser.readValueAs(ActionItemType.class);

    wrapped = objectNode.get("actionItemId");
    parser = wrapped.traverse();
    parser.setCodec(jp.getCodec());
    Long actionItemId = parser.getValueAsLong();

    wrapped = objectNode.get("actionItemCreateDate");
    parser = wrapped.traverse();
    parser.setCodec(jp.getCodec());
    Date actionItemCreateDate = new Date(parser.getValueAsLong());

    wrapped = objectNode.get("actionItemName");
    parser = wrapped.traverse();
    parser.setCodec(jp.getCodec());
    String actionItemName = parser.getValueAsString();

    wrapped = objectNode.get("actionItemDueDate");
    parser = wrapped.traverse();
    parser.setCodec(jp.getCodec());
    Date actionItemDueDate = new Date(parser.getValueAsLong());

    wrapped = objectNode.get("discussionId");
    parser = wrapped.traverse();
    parser.setCodec(jp.getCodec());
    Long discussionId = parser.getValueAsLong();

    wrapped = objectNode.get("owner");
    parser = wrapped.traverse();
    parser.setCodec(jp.getCodec());
    MmrActionItemUser owner = parser.readValueAs(MmrActionItemUser.class);

    wrapped = objectNode.get("assignees");
    parser = wrapped.traverse();
    parser.setCodec(jp.getCodec());
    List<MmrActionItemUser> assignees =
        parser.readValueAs(new TypeReference<List<MmrActionItemUser>>() {});

    wrapped = objectNode.get("actionItemStatus");
    parser = wrapped.traverse();
    parser.setCodec(jp.getCodec());
    ActionItemStatus actionItemStatus = parser.readValueAs(ActionItemStatus.class);

    ActionItem actionItem = new UntypedActionItem();
    actionItem.setActionItemType(actionItemType);
    actionItem.setActionItemId(actionItemId);
    actionItem.setActionItemStatus(actionItemStatus);
    actionItem.setAssignees(assignees);
    actionItem.setActionItemCreateDate(actionItemCreateDate);
    actionItem.setActionItemDueDate(actionItemDueDate);
    actionItem.setActionItemName(actionItemName);
    actionItem.setDiscussionId(discussionId);
    actionItem.setOwner(owner);

    return actionItem;
  }