@Override
  public Collection<String> deserialize(
      JsonParser jp, DeserializationContext ctxt, Collection<String> result) throws IOException {
    // Ok: must point to START_ARRAY
    if (!jp.isExpectedStartArrayToken()) {
      return handleNonArray(jp, ctxt, result);
    }

    if (_valueDeserializer != null) {
      return deserializeUsingCustom(jp, ctxt, result, _valueDeserializer);
    }
    JsonToken t;

    while ((t = jp.nextToken()) != JsonToken.END_ARRAY) {
      String value;
      if (t == JsonToken.VALUE_STRING) {
        value = jp.getText();
      } else if (t == JsonToken.VALUE_NULL) {
        value = null;
      } else {
        value = _parseString(jp, ctxt);
      }
      result.add(value);
    }
    return result;
  }
  @Override
  public String[] deserialize(JsonParser p, DeserializationContext ctxt, String[] intoValue)
      throws IOException {
    // Ok: must point to START_ARRAY (or equivalent)
    if (!p.isExpectedStartArrayToken()) {
      String[] arr = handleNonArray(p, ctxt);
      if (arr == null) {
        return intoValue;
      }
      final int offset = intoValue.length;
      String[] result = new String[offset + arr.length];
      System.arraycopy(intoValue, 0, result, 0, offset);
      System.arraycopy(arr, 0, result, offset, arr.length);
      return result;
    }

    if (_elementDeserializer != null) {
      return _deserializeCustom(p, ctxt, intoValue);
    }
    final ObjectBuffer buffer = ctxt.leaseObjectBuffer();
    int ix = intoValue.length;
    Object[] chunk = buffer.resetAndStart(intoValue, ix);

    try {
      while (true) {
        String value = p.nextTextValue();
        if (value == null) {
          JsonToken t = p.getCurrentToken();
          if (t == JsonToken.END_ARRAY) {
            break;
          }
          if (t != JsonToken.VALUE_NULL) {
            value = _parseString(p, ctxt);
          }
        }
        if (ix >= chunk.length) {
          chunk = buffer.appendCompletedChunk(chunk);
          ix = 0;
        }
        chunk[ix++] = value;
      }
    } catch (Exception e) {
      throw JsonMappingException.wrapWithPath(e, chunk, buffer.bufferedSize() + ix);
    }
    String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class);
    ctxt.returnObjectBuffer(buffer);
    return result;
  }
 @Override
 public OffsetTime deserialize(JsonParser parser, DeserializationContext context)
     throws IOException {
   if (parser.hasToken(JsonToken.VALUE_STRING)) {
     String string = parser.getText().trim();
     if (string.length() == 0) {
       return null;
     }
     try {
       return OffsetTime.parse(string, _formatter);
     } catch (DateTimeException e) {
       _rethrowDateTimeException(parser, context, e, string);
     }
   }
   if (!parser.isExpectedStartArrayToken()) {
     if (parser.hasToken(JsonToken.VALUE_EMBEDDED_OBJECT)) {
       return (OffsetTime) parser.getEmbeddedObject();
     }
     throw context.wrongTokenException(parser, JsonToken.START_ARRAY, "Expected array or string.");
   }
   int hour = parser.nextIntValue(-1);
   if (hour == -1) {
     JsonToken t = parser.getCurrentToken();
     if (t == JsonToken.END_ARRAY) {
       return null;
     }
     if (t != JsonToken.VALUE_NUMBER_INT) {
       _reportWrongToken(parser, context, JsonToken.VALUE_NUMBER_INT, "hours");
     }
     hour = parser.getIntValue();
   }
   int minute = parser.nextIntValue(-1);
   if (minute == -1) {
     JsonToken t = parser.getCurrentToken();
     if (t == JsonToken.END_ARRAY) {
       return null;
     }
     if (t != JsonToken.VALUE_NUMBER_INT) {
       _reportWrongToken(parser, context, JsonToken.VALUE_NUMBER_INT, "minutes");
     }
     minute = parser.getIntValue();
   }
   int partialSecond = 0;
   int second = 0;
   if (parser.nextToken() == JsonToken.VALUE_NUMBER_INT) {
     second = parser.getIntValue();
     if (parser.nextToken() == JsonToken.VALUE_NUMBER_INT) {
       partialSecond = parser.getIntValue();
       if (partialSecond < 1_000
           && !context.isEnabled(DeserializationFeature.READ_DATE_TIMESTAMPS_AS_NANOSECONDS)) {
         partialSecond *= 1_000_000; // value is milliseconds, convert it to nanoseconds
       }
       parser.nextToken();
     }
   }
   if (parser.getCurrentToken() == JsonToken.VALUE_STRING) {
     OffsetTime t =
         OffsetTime.of(hour, minute, second, partialSecond, ZoneOffset.of(parser.getText()));
     if (parser.nextToken() != JsonToken.END_ARRAY) {
       _reportWrongToken(parser, context, JsonToken.END_ARRAY, "timezone");
     }
     return t;
   }
   throw context.wrongTokenException(
       parser, JsonToken.VALUE_STRING, "Expected string for TimeZone after numeric values");
 }