// Path: src/main/java/org/elasticsearch/script/SharedMethods.java
// public class SharedMethods {
// 
//     public static Map<String, Object> getSourceAsMap(String source) throws IOException {
//         XContentParser parser = XContentFactory.xContent(XContentType.JSON).createParser(source);
//         return parser.mapOrdered();
//     }
// 
// }


import org.elasticsearch.ElasticsearchException;
import org.elasticsearch.action.ActionListener;
import org.elasticsearch.action.support.ActionFilters;
import org.elasticsearch.action.support.HandledTransportAction;
import org.elasticsearch.client.Client;
import org.elasticsearch.cluster.metadata.IndexNameExpressionResolver;
import org.elasticsearch.common.ParseFieldMatcher;
import org.elasticsearch.common.collect.Tuple;
import org.elasticsearch.common.inject.Inject;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.xcontent.ToXContent;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.indices.query.IndicesQueriesRegistry;
import org.elasticsearch.script.SharedMethods;
import org.elasticsearch.search.SearchExtRegistry;
import org.elasticsearch.search.SearchRequestParsers;
import org.elasticsearch.search.aggregations.AggregatorParsers;
import org.elasticsearch.search.suggest.Suggesters;
import org.elasticsearch.threadpool.ThreadPool;
import org.elasticsearch.transport.TransportService;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder;
        this.client = client;
        this.queryRegistry = queryRegistry;
        this.aggParsers = searchRequestParsers.aggParsers;
        this.suggesters = searchRequestParsers.suggesters;
        this.searchExtRegistry = searchExtRegistry;
        this.parseFieldMatcher = new ParseFieldMatcher(settings);
    }

    @Override
    protected void doExecute(final PrepareSpecRequest request, final ActionListener<PrepareSpecResponse> listener) {
        Tuple<Boolean, List<FieldSpecRequest>> fieldSpecRequests = null;
        try {
            fieldSpecRequests = parseFieldSpecRequests(queryRegistry, aggParsers, suggesters, searchExtRegistry, parseFieldMatcher,
                    request.source());
        } catch (IOException e) {
            listener.onFailure(e);
        }

        final FieldSpecActionListener fieldSpecActionListener = new FieldSpecActionListener(fieldSpecRequests.v2().size(), listener,
                fieldSpecRequests.v1());
        for (final FieldSpecRequest fieldSpecRequest : fieldSpecRequests.v2()) {
            fieldSpecRequest.process(fieldSpecActionListener, client);
        }
    }

    static Tuple<Boolean, List<FieldSpecRequest>> parseFieldSpecRequests(IndicesQueriesRegistry queryRegistry, AggregatorParsers aggParsers,
                                                                         Suggesters suggesters, SearchExtRegistry searchExtRegistry,
                                                                         ParseFieldMatcher parseFieldMatcher,
                                                                         String source) throws IOException {
        List<FieldSpecRequest> fieldSpecRequests = new ArrayList<>();
// Path: src/main/java/org/elasticsearch/script/SharedMethods.java
// public class SharedMethods {
// 
//     public static Map<String, Object> getSourceAsMap(String source) throws IOException {
//         XContentParser parser = XContentFactory.xContent(XContentType.JSON).createParser(source);
//         return parser.mapOrdered();
//     }
// 
// }


// Path: src/main/java/org/elasticsearch/action/preparespec/TransportPrepareSpecAction.java
import org.elasticsearch.ElasticsearchException;
import org.elasticsearch.action.ActionListener;
import org.elasticsearch.action.support.ActionFilters;
import org.elasticsearch.action.support.HandledTransportAction;
import org.elasticsearch.client.Client;
import org.elasticsearch.cluster.metadata.IndexNameExpressionResolver;
import org.elasticsearch.common.ParseFieldMatcher;
import org.elasticsearch.common.collect.Tuple;
import org.elasticsearch.common.inject.Inject;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.xcontent.ToXContent;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.indices.query.IndicesQueriesRegistry;
import org.elasticsearch.script.SharedMethods;
import org.elasticsearch.search.SearchExtRegistry;
import org.elasticsearch.search.SearchRequestParsers;
import org.elasticsearch.search.aggregations.AggregatorParsers;
import org.elasticsearch.search.suggest.Suggesters;
import org.elasticsearch.threadpool.ThreadPool;
import org.elasticsearch.transport.TransportService;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder;

        this.client = client;
        this.queryRegistry = queryRegistry;
        this.aggParsers = searchRequestParsers.aggParsers;
        this.suggesters = searchRequestParsers.suggesters;
        this.searchExtRegistry = searchExtRegistry;
        this.parseFieldMatcher = new ParseFieldMatcher(settings);
    }

    @Override
    protected void doExecute(final PrepareSpecRequest request, final ActionListener<PrepareSpecResponse> listener) {
        Tuple<Boolean, List<FieldSpecRequest>> fieldSpecRequests = null;
        try {
            fieldSpecRequests = parseFieldSpecRequests(queryRegistry, aggParsers, suggesters, searchExtRegistry, parseFieldMatcher,
                    request.source());
        } catch (IOException e) {
            listener.onFailure(e);
        }

        final FieldSpecActionListener fieldSpecActionListener = new FieldSpecActionListener(fieldSpecRequests.v2().size(), listener,
                fieldSpecRequests.v1());
        for (final FieldSpecRequest fieldSpecRequest : fieldSpecRequests.v2()) {
            fieldSpecRequest.process(fieldSpecActionListener, client);
        }
    }

    static Tuple<Boolean, List<FieldSpecRequest>> parseFieldSpecRequests(IndicesQueriesRegistry queryRegistry, AggregatorParsers aggParsers,
                                                                         Suggesters suggesters, SearchExtRegistry searchExtRegistry,
                                                                         ParseFieldMatcher parseFieldMatcher,
                                                                         String source) throws IOException {
        List<FieldSpecRequest> fieldSpecRequests = new ArrayList<>();
        Map<String, Object> parsedSource = SharedMethods.getSourceAsMap(source);