private AbstractAggregationBuilder addFieldOrScriptToAggregation(
     MethodField field, ValuesSourceMetricsAggregationBuilder builder) {
   KVValue kvValue = field.getParams().get(0);
   if (kvValue.key != null && kvValue.key.equals("script")) {
     // todo: support different lang script
     return builder.script(((MethodField) kvValue.value).getParams().get(1).toString());
   } else if (kvValue.key != null
       && (kvValue.key.equals("nested") || kvValue.key.equals("reverse_nested"))) {
     NestedType nestedType = (NestedType) kvValue.value;
     builder.field(nestedType.field);
     AggregationBuilder nestedBuilder;
     String nestedAggName = nestedType.field + "@NESTED";
     if (nestedType.isReverse()) {
       if (nestedType.path != null && nestedType.path.startsWith("~")) {
         String realPath = nestedType.path.substring(1);
         nestedBuilder = AggregationBuilders.nested(nestedAggName).path(realPath);
         nestedBuilder = nestedBuilder.subAggregation(builder);
         return AggregationBuilders.reverseNested(nestedAggName + "_REVERSED")
             .subAggregation(nestedBuilder);
       } else {
         nestedBuilder = AggregationBuilders.reverseNested(nestedAggName).path(nestedType.path);
       }
     } else {
       nestedBuilder = AggregationBuilders.nested(nestedAggName).path(nestedType.path);
     }
     return nestedBuilder.subAggregation(builder);
   }
   return builder.field(kvValue.toString());
 }
 private AbstractAggregationBuilder wrapNestedIfNeeded(
     AggregationBuilder nestedBuilder, boolean reverseNested) {
   if (!reverseNested) return nestedBuilder;
   if (reverseNested && !(nestedBuilder instanceof NestedBuilder)) return nestedBuilder;
   // we need to jump back to root
   return AggregationBuilders.reverseNested(nestedBuilder.getName() + "_REVERSED")
       .subAggregation(nestedBuilder);
 }
 private AggregationBuilder createNestedAggregation(Field field) {
   AggregationBuilder nestedBuilder;
   String nestedPath = field.getNestedPath();
   if (field.isReverseNested()) {
     if (nestedPath == null || !nestedPath.startsWith("~"))
       return AggregationBuilders.reverseNested(getNestedAggName(field)).path(nestedPath);
     nestedPath = nestedPath.substring(1);
   }
   nestedBuilder = AggregationBuilders.nested(getNestedAggName(field)).path(nestedPath);
   return nestedBuilder;
 }