@Override
  public void validate(
      final Processor<FullData, FullData> processor,
      final ProcessingReport report,
      final MessageBundle bundle,
      final FullData data)
      throws ProcessingException {
    final SchemaTree tree = data.getSchema();
    final JsonPointer schemaPointer = tree.getPointer();
    final JsonNode schemas = tree.getNode().get(keyword);
    final int size = schemas.size();
    final ObjectNode fullReport = FACTORY.objectNode();

    int nrSuccess = 0;
    ListProcessingReport subReport;
    JsonPointer ptr;
    FullData newData;

    for (int index = 0; index < size; index++) {
      subReport = new ListProcessingReport(report.getLogLevel(), LogLevel.FATAL);
      ptr = schemaPointer.append(JsonPointer.of(keyword, index));
      newData = data.withSchema(tree.setPointer(ptr));
      processor.process(subReport, newData);
      fullReport.put(ptr.toString(), subReport.asJson());
      if (subReport.isSuccess()) nrSuccess++;
    }

    if (nrSuccess == 0)
      report.error(
          newMsg(data, bundle, "err.common.schema.noMatch")
              .putArgument("nrSchemas", size)
              .put("reports", fullReport));
  }
 @Override
 protected JsonNode loadSample() {
   final int index = RND.nextInt(SAMPLE_DATA_SIZE);
   final JsonNode sample = SAMPLE_DATA.get(index);
   final ObjectNode ret = FACTORY.objectNode();
   ret.put(ResponseFields.INPUT, JacksonUtils.prettyPrint(sample));
   return ret;
 }
  @Override
  public JsonNode digest(final JsonNode schema) {
    // TODO: return an array directly (same for "required" in v4)
    final ObjectNode ret = FACTORY.objectNode();
    final ArrayNode required = FACTORY.arrayNode();
    ret.put("required", required);

    final JsonNode node = schema.get(keyword);
    final List<String> list = Lists.newArrayList(node.fieldNames());

    Collections.sort(list);

    for (final String field : list)
      if (node.get(field).path("required").asBoolean(false)) required.add(field);

    return ret;
  }
  @Override
  public JsonNode digest(final JsonNode schema) {
    final ObjectNode ret = FACTORY.objectNode();
    final ArrayNode simpleTypes = FACTORY.arrayNode();
    ret.put(keyword, simpleTypes);
    final ArrayNode schemas = FACTORY.arrayNode();
    ret.put("schemas", schemas);

    final JsonNode node = schema.get(keyword);

    final EnumSet<NodeType> set = EnumSet.noneOf(NodeType.class);

    if (node.isTextual()) // Single type
    putType(set, node.textValue());
    else { // More than one type, and possibly schemas
      final int size = node.size();
      JsonNode element;
      for (int index = 0; index < size; index++) {
        element = node.get(index);
        if (element.isTextual()) putType(set, element.textValue());
        else schemas.add(index);
      }
    }

    /*
     * If all types are there, no need to collect schemas
     */
    if (EnumSet.complementOf(set).isEmpty()) schemas.removeAll();

    /*
     * Note that as this is an enumset, order is guaranteed
     */
    for (final NodeType type : set) simpleTypes.add(type.toString());

    return ret;
  }