docs: @Override
  	public void process(ResponseBuilder rb) throws IOException {
  		// System.out
  		// .println(System.nanoTime() + " - " + Thread.currentThread().getId()
  		// + " - " + rb.req.getParams().getBool(ShardParams.IS_SHARD, false)
  		// + " PROCESS " + rb.stage + " " + rb.req.getParamString());
  		MtasSolrStatus solrStatus = Objects
  				.requireNonNull((MtasSolrStatus) rb.req.getContext().get(MtasSolrStatus.class), "couldn't find status");
  		solrStatus.setStage(rb.stage);
  		try {
  			if (rb.req.getParams().getBool(PARAM_MTAS, false)) {
  				try {
  					ComponentFields mtasFields = getMtasFields(rb);
  					if (mtasFields != null) {
  						DocSet docSet = rb.getResults().docSet;
  						DocList docList = rb.getResults().docList;
  						if (mtasFields.doStats || mtasFields.doDocument || mtasFields.doKwic || mtasFields.doList
  								|| mtasFields.doGroup || mtasFields.doFacet || mtasFields.doCollection
  								|| mtasFields.doTermVector || mtasFields.doPrefix || mtasFields.doStatus
  								|| mtasFields.doVersion) {
  							SolrIndexSearcher searcher = rb.req.getSearcher();
  							ArrayList<Integer> docSetList = null;
  							ArrayList<Integer> docListList = null;
  							// initialise docSetList
  							if (docSet != null) {
  								docSetList = new ArrayList<>();
  								Iterator<Integer> docSetIterator = docSet.iterator();
  								while (docSetIterator.hasNext()) {
  									docSetList.add(docSetIterator.next());
  								}
  								Collections.sort(docSetList);
  							}
  							// initialise docListList
  							if (docList != null) {
  								docListList = new ArrayList<>();
  								Iterator<Integer> docListIterator = docList.iterator();
  								while (docListIterator.hasNext()) {
  									docListList.add(docListIterator.next());
  								}
  								Collections.sort(docListList);
  							}
  							solrStatus.status().addSubs(mtasFields.list.keySet());
  							for (String field : mtasFields.list.keySet()) {
  								try {
  									CodecUtil.collectField(field, searcher, searcher.getRawReader(), docListList,
  											docSetList, mtasFields.list.get(field), solrStatus.status());
  								} catch (IllegalAccessException | IllegalArgumentException
  										| InvocationTargetException e) {
  									log.error(e);
  									throw new IOException(e);
  								}
  							}
  							for (ComponentCollection collection : mtasFields.collection) {
  								CodecUtil.collectCollection(searcher.getRawReader(), docSetList, collection);
  							}
  							NamedList<Object> mtasResponse = new SimpleOrderedMap<>();
  							if (mtasFields.doVersion) {
  								SimpleOrderedMap<Object> versionResponse = searchVersion.create(mtasFields.version,
  										false);
  								mtasResponse.add(MtasSolrComponentVersion.NAME, versionResponse);
  							}
  							if (mtasFields.doStatus) {
  								// add to response
  								SimpleOrderedMap<Object> statusResponse = searchStatus.create(mtasFields.status, false);
  								if (statusResponse != null) {
  									mtasResponse.add(MtasSolrComponentStatus.NAME,
  											searchStatus.create(mtasFields.status, false));
  								}
  							}
  							if (mtasFields.doDocument) {
  								ArrayList<NamedList<?>> mtasDocumentResponses = new ArrayList<>();
  								for (String field : mtasFields.list.keySet()) {
  									for (ComponentDocument document : mtasFields.list.get(field).documentList) {
  										mtasDocumentResponses.add(searchDocument.create(document, false));
  									}
  								}
  								// add to response
  								mtasResponse.add(MtasSolrComponentDocument.NAME, mtasDocumentResponses);
  							}
  							if (mtasFields.doKwic) {
  								ArrayList<NamedList<?>> mtasKwicResponses = new ArrayList<>();
  								for (String field : mtasFields.list.keySet()) {
  									for (ComponentKwic kwic : mtasFields.list.get(field).kwicList) {
  										mtasKwicResponses.add(searchKwic.create(kwic, false));
  									}
  								}
  								// add to response
  								mtasResponse.add(MtasSolrComponentKwic.NAME, mtasKwicResponses);
  							}
  							if (mtasFields.doFacet) {
  								ArrayList<NamedList<?>> mtasFacetResponses = new ArrayList<>();
  								for (String field : mtasFields.list.keySet()) {
  									for (ComponentFacet facet : mtasFields.list.get(field).facetList) {
  										if (rb.req.getParams().getBool(ShardParams.IS_SHARD, false)) {
  											mtasFacetResponses.add(searchFacet.create(facet, true));
  										} else {
  											mtasFacetResponses.add(searchFacet.create(facet, false));
  										}
  									}
  								}
  								// add to response
  								mtasResponse.add(MtasSolrComponentFacet.NAME, mtasFacetResponses);
  							}
  							if (mtasFields.doCollection) {
  								ArrayList<NamedList<?>> mtasCollectionResponses = new ArrayList<>();
  								for (ComponentCollection collection : mtasFields.collection) {
  									if (rb.req.getParams().getBool(ShardParams.IS_SHARD, false)) {
  										mtasCollectionResponses.add(searchCollection.create(collection, true));
  									} else {
  										mtasCollectionResponses.add(searchCollection.create(collection, false));
  									}
  								}
  								// add to response
  								mtasResponse.add(MtasSolrComponentCollection.NAME, mtasCollectionResponses);
  							}
  							if (mtasFields.doList) {
  								ArrayList<NamedList<?>> mtasListResponses = new ArrayList<>();
  								for (String field : mtasFields.list.keySet()) {
  									for (ComponentList list : mtasFields.list.get(field).listList) {
  										mtasListResponses.add(searchList.create(list, false));
  									}
  								}
  								// add to response
  								mtasResponse.add(MtasSolrComponentList.NAME, mtasListResponses);
  							}
  							if (mtasFields.doGroup) {
  								ArrayList<NamedList<?>> mtasGroupResponses = new ArrayList<>();
  								for (String field : mtasFields.list.keySet()) {
  									for (ComponentGroup group : mtasFields.list.get(field).groupList) {
  										if (rb.req.getParams().getBool(ShardParams.IS_SHARD, false)) {
  											mtasGroupResponses.add(searchGroup.create(group, true));
  										} else {
  											mtasGroupResponses.add(searchGroup.create(group, false));
  										}
  									}
  								}
  								// add to response
  								mtasResponse.add(MtasSolrComponentGroup.NAME, mtasGroupResponses);
  							}
  							if (mtasFields.doTermVector) {
  								ArrayList<NamedList<?>> mtasTermVectorResponses = new ArrayList<>();
  								for (String field : mtasFields.list.keySet()) {
  									for (ComponentTermVector termVector : mtasFields.list.get(field).termVectorList) {
  										if (rb.req.getParams().getBool(ShardParams.IS_SHARD, false)) {
  											mtasTermVectorResponses.add(searchTermvector.create(termVector, true));
  										} else {
  											mtasTermVectorResponses.add(searchTermvector.create(termVector, false));
  										}
  									}
  								}
  								// add to response
  								mtasResponse.add(MtasSolrComponentTermvector.NAME, mtasTermVectorResponses);
  							}
  							if (mtasFields.doPrefix) {
  								ArrayList<NamedList<?>> mtasPrefixResponses = new ArrayList<>();
  								for (String field : mtasFields.list.keySet()) {
  									if (mtasFields.list.get(field).prefix != null) {
  										if (rb.req.getParams().getBool(ShardParams.IS_SHARD, false)) {
  											mtasPrefixResponses
  													.add(searchPrefix.create(mtasFields.list.get(field).prefix, true));
  										} else {
  											mtasPrefixResponses
  													.add(searchPrefix.create(mtasFields.list.get(field).prefix, false));
  										}
  									}
  								}
  								mtasResponse.add(MtasSolrComponentPrefix.NAME, mtasPrefixResponses);
  							}
  							if (mtasFields.doStats) {
  								NamedList<Object> mtasStatsResponse = new SimpleOrderedMap<>();
  								if (mtasFields.doStatsPositions || mtasFields.doStatsTokens
  										|| mtasFields.doStatsSpans) {
  									if (mtasFields.doStatsTokens) {
  										ArrayList<Object> mtasStatsTokensResponses = new ArrayList<>();
  										for (String field : mtasFields.list.keySet()) {
  											for (ComponentToken token : mtasFields.list.get(field).statsTokenList) {
  												if (rb.req.getParams().getBool(ShardParams.IS_SHARD, false)) {
  													mtasStatsTokensResponses.add(searchStats.create(token, true));
  												} else {
  													mtasStatsTokensResponses.add(searchStats.create(token, false));
  												}
  											}
  										}
  										mtasStatsResponse.add(MtasSolrComponentStats.NAME_TOKENS,
  												mtasStatsTokensResponses);
  									}
  									if (mtasFields.doStatsPositions) {
  										ArrayList<Object> mtasStatsPositionsResponses = new ArrayList<>();
  										for (String field : mtasFields.list.keySet()) {
  											for (ComponentPosition position : mtasFields.list
  													.get(field).statsPositionList) {
  												if (rb.req.getParams().getBool(ShardParams.IS_SHARD, false)) {
  													mtasStatsPositionsResponses.add(searchStats.create(position, true));
  												} else {
  													mtasStatsPositionsResponses
  															.add(searchStats.create(position, false));
  												}
  											}
  										}
  										mtasStatsResponse.add(MtasSolrComponentStats.NAME_POSITIONS,
  												mtasStatsPositionsResponses);
  									}
  									if (mtasFields.doStatsSpans) {
  										ArrayList<Object> mtasStatsSpansResponses = new ArrayList<>();
  										for (String field : mtasFields.list.keySet()) {
  											for (ComponentSpan span : mtasFields.list.get(field).statsSpanList) {
  												if (rb.req.getParams().getBool(ShardParams.IS_SHARD, false)) {
  													mtasStatsSpansResponses.add(searchStats.create(span, true));
  												} else {
  													mtasStatsSpansResponses.add(searchStats.create(span, false));
  												}
  											}
  										}
  										mtasStatsResponse.add(MtasSolrComponentStats.NAME_SPANS,
  												mtasStatsSpansResponses);
  									}
  									// add to response
  									mtasResponse.add(MtasSolrComponentStats.NAME, mtasStatsResponse);
  								}
  							}
  							// add to response
  							if (mtasResponse.size() > 0) {
  								rb.rsp.add(NAME, mtasResponse);
  							}
  						}
  					}
  				} catch (IOException e) {
  					errorStatus(solrStatus, e);
  				}
  			}
  			if (!solrStatus.error()) {
  				// always set status segments
  				if (solrStatus.status().numberSegmentsTotal == null) {
  					solrStatus.status().numberSegmentsTotal = rb.req.getSearcher().getRawReader().leaves().size();
  					solrStatus.status().numberSegmentsFinished = solrStatus.status().numberSegmentsTotal;
  				}
  				// always try to set number of documents
  				if (solrStatus.status().numberDocumentsTotal == null) {
  					SolrIndexSearcher searcher;
  					if ((searcher = rb.req.getSearcher()) != null) {
  						solrStatus.status().numberDocumentsTotal = (long) searcher.numDocs();
  						if (rb.getResults().docList != null) {
  							solrStatus.status().numberDocumentsFinished = rb.getResults().docList.matches();
  							solrStatus.status().numberDocumentsFound = rb.getResults().docList.matches();
  						} else if (rb.getResults().docSet != null) {
  							solrStatus.status().numberDocumentsFinished = (long) rb.getResults().docSet.size();
  							solrStatus.status().numberDocumentsFound = (long) rb.getResults().docSet.size();
  						}
  					}
  				}
  			}
  		} catch (ExitableDirectoryReader.ExitingReaderException e) {
  			solrStatus.setError(e.getMessage());
  		} finally {
  			checkStatus(solrStatus);
  			finishStatus(solrStatus);
  		}
  	}