/**
   * Method for re-sorting lists of bean properties such that attributes are strictly written before
   * elements.
   */
  protected static int _orderAttributesFirst(
      BeanPropertyWriter[] properties, BeanPropertyWriter[] filteredProperties) {
    int attrCount = 0;

    for (int i = 0, len = properties.length; i < len; ++i) {
      BeanPropertyWriter bpw = properties[i];

      if (!_isAttribute(bpw)) {
        continue;
      }

      // Move attribute a few places done as necessary
      int moveBy = i - attrCount;
      if (moveBy > 0) {
        System.arraycopy(properties, attrCount, properties, attrCount + 1, moveBy);
        properties[attrCount] = bpw;
        if (filteredProperties != null) {
          BeanPropertyWriter fbpw = filteredProperties[i];
          System.arraycopy(
              filteredProperties, attrCount, filteredProperties, attrCount + 1, moveBy);
          filteredProperties[attrCount] = fbpw;
        }
      }
      ++attrCount;
    }
    return attrCount;
  }
  @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;
  }
 protected final double _testRawDeser(int reps, byte[] json, ObjectReader reader)
     throws IOException {
   long start = System.nanoTime();
   final JsonFactory f = reader.getFactory();
   while (--reps >= 0) {
     JsonParser p = f.createParser(new ByteArrayInputStream(json));
     JsonToken t;
     while ((t = p.nextToken()) != null) {
       if (t == JsonToken.VALUE_STRING) {
         p.getText();
       } else if (t.isNumeric()) {
         p.getNumberValue();
       }
       ;
     }
     p.close();
   }
   hash = f.hashCode();
   return _msecsFromNanos(System.nanoTime() - start);
 }
  public static void main(String[] args) throws Exception {
    if (args.length != 1) {
      System.err.println("Usage: java [input]");
      System.exit(1);
    }
    byte[] data = readAll(args[0]);

    JsonFactory f = new JsonFactory();
    boolean doIntern = true;

    f.configure(JsonFactory.Feature.CANONICALIZE_FIELD_NAMES, doIntern);
    f.configure(JsonFactory.Feature.INTERN_FIELD_NAMES, doIntern);

    ObjectMapper m = new ObjectMapper();
    Object input1 = m.readValue(data, Object.class);
    JsonNode input2 = m.readTree(data);

    new ManualReadPerfUntypedStream()
        .testFromBytes(
            //            .testFromString(
            m, "JSON-as-Object", input1, Object.class, m, "JSON-as-Object2", input2, Object.class
            //               ,m, "JSON-as-Node", input2, JsonNode.class
            );
  }