Index: src/test/org/apache/solr/search/TestDocSet.java
===================================================================
--- src/test/org/apache/solr/search/TestDocSet.java	(revisión: 713743)
+++ src/test/org/apache/solr/search/TestDocSet.java	(copia de trabajo)
@@ -88,10 +88,17 @@
     checkEqual(a_and, b1.intersection(b2));
     checkEqual(a_or, b1.union(b2));
     checkEqual(a_andn, b1.andNot(b2));
-
+    
     assertEquals(a_and.cardinality(), b1.intersectionSize(b2));
     assertEquals(a_or.cardinality(), b1.unionSize(b2));
     assertEquals(a_andn.cardinality(), b1.andNotSize(b2));
+    
+    checkEqual(a1, NegatedDocSet.negation(NegatedDocSet.negation(b1)));
+    //checkEqual(a_and, b1.andNot(NegatedDocSet.negation(b2)));
+    //checkEqual(a_andn, b1.intersection(NegatedDocSet.negation(b2)));
+    checkEqual(a_andn, NegatedDocSet.negation(b2).intersection(b1));
+    checkEqual(a_or, NegatedDocSet.negation(NegatedDocSet.negation(b1).andNot(b2)));
+    //checkEqual(a_and, NegatedDocSet.negation(NegatedDocSet.negation(b1).union(NegatedDocSet.negation(b2))));
   }
 
 
Index: src/java/org/apache/solr/search/CollapseFilter.java
===================================================================
--- src/java/org/apache/solr/search/CollapseFilter.java	(revisión: 0)
+++ src/java/org/apache/solr/search/CollapseFilter.java	(revisión: 0)
@@ -0,0 +1,343 @@
+package org.apache.solr.search;
+
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.lucene.index.IndexReader;
+import org.apache.lucene.search.FieldCache;
+import org.apache.lucene.search.Query;
+import org.apache.lucene.search.Sort;
+import org.apache.lucene.search.SortField;
+import org.apache.solr.common.params.CollapseParams;
+import org.apache.solr.common.params.SolrParams;
+import org.apache.solr.common.params.CollapseParams.CollapseFacet;
+import org.apache.solr.common.params.CollapseParams.CollapseType;
+import org.apache.solr.common.util.NamedList;
+import org.apache.solr.schema.FieldType;
+import org.apache.solr.schema.IndexSchema;
+import org.apache.solr.schema.SchemaField;
+import org.apache.solr.util.OpenBitSet;
+
+/**
+ * @author Emmanuel Keller keller.emmanuel@gmail.com
+ * @version $Id:$
+ * @since solr 1.3
+ */
+public class CollapseFilter {
+  
+  /** Parameters *************************************************** */
+  
+  /**
+   * Field to use to collapse results. Parameter.
+   */
+  private String collapseField;
+  
+  /**
+   * Type of collapsing to do -- collapse all hits or adjacent hits only.
+   * Parameter.
+   */
+  private CollapseType collapseType;
+  
+  /**
+   * Facet before or after collapsing.
+   */
+  private CollapseFacet collapseFacet;
+  
+  /**
+   * Number of documents with the same value for collapseField after which
+   * collapsing kicks in. Parameter.
+   */
+  private int collapseTreshold;
+  
+  /**
+   * Maximum number of documents to process during field collapsing. Parameter.
+   */
+  private int collapseMaxDocs;
+  
+  /**
+   * Return collapse count for each document? Parameter.
+   */
+  private boolean collapseInfoDoc;
+  
+  /**
+   * Return collapse count for each field value? Parameter.
+   */
+  private boolean collapseInfoCount;
+  
+  
+  /** Collapse State *********************************************** */
+  
+  /**
+   * Number of documents that have been collapsed into the key document.
+   */
+  private Map<Integer, Integer> collapseCounts;
+  
+  /**
+   * Maxmimum size for a HashDocSet.
+   */
+  private int hashMaxSize;
+  
+  /**
+   * Buffer for collecting documents. Gets turned into different types of DocSet
+   * depending on the number of documents we end up with.
+   */
+  private int[] docbuf;
+  
+  /**
+   * Number of documents in docbuf.
+   */
+  private int docbufSize = 0;
+  
+  /**
+   * Maximum document id currently in docbuf. Only valid while docbufSize <
+   * hashMaxSize.
+   */
+  private int docbufMaxDoc = 0;
+  
+  /**
+   * Bitset representation of docbuf. Gets created when docbufSize >=
+   * hashMaxSize.
+   */
+  private OpenBitSet docbufBitSet;
+  
+  
+  /** Debug Information ******************************************** */
+  
+  private long timeCollapseAdjacent = 0;
+  
+  private long timeConvertToBitSet = 0;
+  
+  private long timeCreateDocSet = 0;
+  
+  private long timeCreateCollapseInfo = 0;
+  
+  private String debugDocSetInfo = "unknown";
+  
+  
+  /**
+   * Creates a CollapseFilter based on the specified parameters.
+   */
+  public CollapseFilter(SolrIndexSearcher searcher, Query query,
+      List<Query> filters, Sort sort, int flags, SolrParams params)
+      throws IOException {
+    parseParameters(searcher, params);
+    
+    // Allocate data structures
+    hashMaxSize = searcher.getSchema().getSolrConfig().hashDocSetMaxSize;
+    docbuf = new int[hashMaxSize];
+    collapseCounts = new HashMap<Integer, Integer>();
+    
+    // If collapse type is 'adjacent' we can just use the existing
+    // sort, otherwise create a DocList sorted by collapseField.
+    // Perform collapsing of adjacent docs on the result.
+    if (collapseType == CollapseType.NORMAL)
+      sort = new Sort(new SortField(collapseField));
+    DocList docs = searcher.getDocList(query, filters, sort, 0, collapseMaxDocs, flags);
+    String[] values = FieldCache.DEFAULT.getStrings(searcher.getReader(), collapseField);
+    adjacentCollapse(docs, values);
+  }
+  
+  private void adjacentCollapse(DocList docs, String[] values) {
+    int docCount = 0;      // how many documents we have processed
+    int repeatCount = 0;   // how many times we have seen the same value in a row
+    int collapseCount = 0; // how many documents we have collapsed in this run
+    int collapseId = -1;   // the document we're collapsing into
+    String collapseValue = null;
+    
+    long startTime = System.currentTimeMillis();
+    
+    for (DocIterator i = docs.iterator(); i.hasNext();) {
+      int currentId = i.nextDoc();
+      String currentValue = values[currentId];
+
+      // Initializing 
+      if (collapseValue == null) {
+          repeatCount = 0;
+          collapseCount = 0;
+          collapseId = currentId;
+          collapseValue = currentValue;
+
+      // Collapse the document if the field value is the same
+      // and we have a run of at least collapseThreshold docs.
+      } else if (collapseValue.equals(currentValue)) {
+        if (++repeatCount >= collapseTreshold) {
+          collapseCount++;
+        } else {
+        	addDoc(currentId);
+        }
+      } else {
+    	  addDoc(collapseId);
+    	  
+        if (collapseCount > 0)
+          collapseCounts.put(collapseId, collapseCount);
+        
+        repeatCount = 0;
+        collapseCount = 0;
+        collapseId = currentId;
+        collapseValue = currentValue;
+      }
+      
+      // Stop after collapseMaxDocs documents
+      if (++docCount >= collapseMaxDocs)
+        break;
+    }
+    
+    if (collapseId != -1)
+    	addDoc(collapseId);
+    
+    if (collapseCount > 0)
+      collapseCounts.put(collapseId, collapseCount);
+    
+    timeCollapseAdjacent = System.currentTimeMillis() - startTime;
+  }
+  
+  /**
+   * Adds a document to the internal document buffer.
+   */
+  private void addDoc(int doc) {
+    // If we have less than hashMaxSize documents, just
+    // keep adding them to docbuf. We will turn them into
+    // a HashDocSet later.
+    if (docbufSize < hashMaxSize) {
+      docbuf[docbufSize] = doc;
+      if (doc > docbufMaxDoc)
+        docbufMaxDoc = doc;
+    } else {
+      // We have exceeded hashMaxSize. Allocate a bit set
+      // if we don't have one yet, then add to that.
+      if (docbufBitSet == null) {
+        long startTime = System.currentTimeMillis();
+        docbufBitSet = new OpenBitSet(docbufMaxDoc+1);
+        for (int i = 0; i < docbufSize; i++)
+          docbufBitSet.fastSet(docbuf[i]);
+        timeConvertToBitSet = System.currentTimeMillis() - startTime;
+      }
+      docbufBitSet.set(doc);
+    }
+    docbufSize++;
+  }
+  
+  /**
+   * Creates a DocSet representation of the internal document buffer.
+   */
+  public DocSet getDocSet() {
+    long startTime = System.currentTimeMillis();
+    DocSet result = (docbufBitSet != null)
+        ? new BitDocSet(docbufBitSet)
+        : new HashDocSet(docbuf, 0, docbufSize);
+    timeCreateDocSet = System.currentTimeMillis() - startTime;
+    debugDocSetInfo = result.getClass().getSimpleName() + "(" + docbufSize + ")";
+    return result;
+  }
+  
+  /**
+   * Returns timing information for inclusing in the result.
+   */
+  private String getDebugInfo() {
+    return debugDocSetInfo + " Time(ms): " + timeCollapseAdjacent + "/"
+        + timeCreateCollapseInfo + "/" + timeConvertToBitSet + "/"
+        + timeCreateDocSet;
+  }
+  
+  /**
+   * Returns collapse counts for all documents in the specified docList.
+   */
+  public NamedList<Object> getCollapseInfo(SolrIndexSearcher searcher, DocList docs) throws IOException {
+    long startTime = System.currentTimeMillis();
+    
+    NamedList<Object> result = new NamedList<Object>();
+    result.add("field", collapseField);
+    
+    IndexSchema schema = searcher.getSchema();
+    FieldType collapseFieldType = schema.getField(collapseField).getType();
+    SchemaField uniqueKeyField = schema.getUniqueKeyField();
+    String uniqueKeyName = (uniqueKeyField != null) ? uniqueKeyField.getName() : null;
+    
+    if (collapseInfoDoc || collapseInfoCount) {
+      NamedList<Integer> resDoc = null;
+      NamedList<Integer> resCount = null;
+      String[] values = null;
+      IndexReader reader = null;
+      
+      if (collapseInfoDoc) {
+        resDoc = new NamedList<Integer>();
+        result.add("doc", resDoc);
+        reader = searcher.getReader();
+      }
+      
+      if (collapseInfoCount) {
+        resCount = new NamedList<Integer>();
+        result.add("count", resCount);
+        values = FieldCache.DEFAULT.getStrings(searcher.getReader(),
+            collapseField);
+      }
+      
+      for (DocIterator i = docs.iterator(); i.hasNext();) {
+        int id = i.nextDoc();
+        Integer count = collapseCounts.get(id);
+        if (count != null) {
+          if (collapseInfoDoc && uniqueKeyName != null)
+            resDoc.add(reader.document(id).get(uniqueKeyName), count);
+          if (collapseInfoCount)
+            resCount.add(collapseFieldType.indexedToReadable(values[id]), count);
+        }
+      }
+    }
+    
+    timeCreateCollapseInfo = System.currentTimeMillis() - startTime;
+    result.add("debug", getDebugInfo());
+    return result;
+  }
+  
+  
+  private void parseParameters(SolrIndexSearcher searcher, SolrParams params) throws IOException {
+    collapseField = params.required().get(CollapseParams.COLLAPSE_FIELD);
+    String type = params.get(CollapseParams.COLLAPSE_TYPE);
+    collapseType = (type != null) ? CollapseType.get(type) : CollapseType.NORMAL;
+    
+    String facet = params.get(CollapseParams.COLLAPSE_FACET);
+    collapseFacet = (facet != null) ? CollapseFacet.get(facet) : CollapseFacet.AFTER;
+    
+    Integer ct = params.getInt(CollapseParams.COLLAPSE_THRESHOLD);
+    if (ct == null) ct = params.getInt(CollapseParams.COLLAPSE_MAX);
+    collapseTreshold = (ct != null) ? ct.intValue() : 1;
+    
+    collapseMaxDocs = params.getInt(CollapseParams.COLLAPSE_MAXDOCS, 0);
+    if (collapseMaxDocs <= 0)
+      collapseMaxDocs = searcher.maxDoc();
+    
+    collapseInfoDoc = params.getBool(CollapseParams.COLLAPSE_INFO_DOC, true);
+    collapseInfoCount = params.getBool(CollapseParams.COLLAPSE_INFO_COUNT, true);
+  }
+  
+  
+  public CollapseFacet getCollapseFacet() {
+    return collapseFacet;
+  }
+
+  public String getCollapseField() {
+    return collapseField;
+  }
+
+  public boolean isCollapseInfoCount() {
+    return collapseInfoCount;
+  }
+
+  public boolean isCollapseInfoDoc() {
+    return collapseInfoDoc;
+  }
+
+  public int getCollapseMaxDocs() {
+    return collapseMaxDocs;
+  }
+
+  public int getCollapseTreshold() {
+    return collapseTreshold;
+  }
+
+  public CollapseType getCollapseType() {
+    return collapseType;
+  }
+}
Index: src/java/org/apache/solr/search/DocSet.java
===================================================================
--- src/java/org/apache/solr/search/DocSet.java	(revisión: 713743)
+++ src/java/org/apache/solr/search/DocSet.java	(copia de trabajo)
@@ -195,7 +195,7 @@
     if (other instanceof HashDocSet) {
       return other.intersection(this);
     }
-
+    
     // Default... handle with bitsets.
     OpenBitSet newbits = (OpenBitSet)(this.getBits().clone());
     newbits.and(other.getBits());
Index: src/java/org/apache/solr/search/NegatedDocSet.java
===================================================================
--- src/java/org/apache/solr/search/NegatedDocSet.java	(revisión: 0)
+++ src/java/org/apache/solr/search/NegatedDocSet.java	(revisión: 0)
@@ -0,0 +1,87 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.solr.search;
+
+import org.apache.solr.common.SolrException;
+
+
+/**
+ * DocSet that contains all documents that are not in the underlying source DocSet.
+ * Only usable as a filter DocSet as it is not a full implementation.
+ */
+public class NegatedDocSet extends DocSetBase {
+  private DocSet source;
+  
+  private NegatedDocSet(DocSet source) {
+    this.source = source;
+  }
+  
+  /**
+   * Returns the negation of the specified DocSet. This will be an instance of
+   * NegatedDocSet, unless the source is already a NegatedDocSet in which case
+   * it's underlying DocSet will be returned.
+   */
+  public static DocSet negation(DocSet source) {
+    return (source instanceof NegatedDocSet)
+        ? ((NegatedDocSet) source).source
+        : new NegatedDocSet(source);
+  }
+
+  public boolean exists(int docid) {
+    return !source.exists(docid);
+  }
+  
+  public DocSet intersection(DocSet other) {
+    // this & other = !source & other = other & !source  
+    return other.andNot(source);
+  }
+  
+  public int intersectionSize(DocSet other) {
+    return other.andNotSize(source);
+  }
+  
+  public DocSet andNot(DocSet other) {
+    // this & !other = !source & !other = !(source | other)
+    return new NegatedDocSet(source.union(other));
+  }
+  
+  public int andNotSize(DocSet other) {
+    throw new SolrException(SolrException.ErrorCode.SERVER_ERROR, "Unsupported Operation");
+  }
+  
+  public DocSet union(DocSet other) {
+    // this | other = !source | other = !(source & !other)
+    return new NegatedDocSet(source.andNot(other));
+  }
+  
+  public int unionSize(DocSet other) {
+    throw new SolrException(SolrException.ErrorCode.SERVER_ERROR, "Unsupported Operation");
+  }
+
+  public DocIterator iterator() {
+    throw new SolrException(SolrException.ErrorCode.SERVER_ERROR, "Unsupported Operation");
+  }
+
+  public long memSize() {
+    return 0;
+  }
+
+  public int size() {
+    throw new SolrException(SolrException.ErrorCode.SERVER_ERROR, "Unsupported Operation");
+  }
+}
Index: src/java/org/apache/solr/search/SolrIndexSearcher.java
===================================================================
--- src/java/org/apache/solr/search/SolrIndexSearcher.java	(revisión: 713743)
+++ src/java/org/apache/solr/search/SolrIndexSearcher.java	(copia de trabajo)
@@ -1357,6 +1357,43 @@
   }
 
   /**
+   * Returns documents matching both <code>query</code> and the intersection 
+   * of <code>filterList</code>, sorted by <code>sort</code>.  
+   * Also returns the compete set of documents
+   * matching <code>query</code> and <code>filter</code> 
+   * (regardless of <code>offset</code> and <code>len</code>).
+   * <p>
+   * This method is cache aware and may retrieve <code>filter</code> from
+   * the cache or make an insertion into the cache as a result of this call.
+   * <p>
+   * FUTURE: The returned DocList may be retrieved from a cache.
+   * <p>
+   * The DocList and DocSet returned should <b>not</b> be modified.
+   *
+   * @param query
+   * @param filterList   may be null
+   * @param docSet      filter docSet
+   * @param lsort    criteria by which to sort (if null, query relevance is used)
+   * @param offset   offset into the list of documents to return
+   * @param len      maximum number of documents to return
+   * @param flags    user supplied flags for the result set
+   * @return DocListAndSet meeting the specified criteria, should <b>not</b> be modified by the caller.
+   * @throws IOException
+   */
+  public DocListAndSet getDocListAndSet(Query query, List<Query> filterList, DocSet docSet, Sort lsort, int offset, int len, int flags) throws IOException {
+    //DocListAndSet ret = new DocListAndSet();
+    //getDocListC(ret,query,filterList,docSet,lsort,offset,len, flags |= GET_DOCSET);
+    
+    QueryCommand qc = new QueryCommand();
+    qc.setQuery(query).setFilterList(filterList).setFilter(docSet);
+    qc.setSort(lsort).setOffset(offset).setLen(len).setFlags(flags |= GET_DOCSET);
+    QueryResult result = new QueryResult();
+    getDocListC(result,qc);
+    
+    return result.getDocListAndSet();
+  }
+
+  /**
    * Returns documents matching both <code>query</code> and <code>filter</code>
    * and sorted by <code>sort</code>. Also returns the compete set of documents
    * matching <code>query</code> and <code>filter</code> (regardless of <code>offset</code> and <code>len</code>).
Index: src/java/org/apache/solr/common/params/CollapseParams.java
===================================================================
--- src/java/org/apache/solr/common/params/CollapseParams.java	(revisión: 0)
+++ src/java/org/apache/solr/common/params/CollapseParams.java	(revisión: 0)
@@ -0,0 +1,81 @@
+package org.apache.solr.common.params;
+
+import org.apache.solr.common.SolrException;
+
+public interface CollapseParams {
+  
+  /**
+   * The field to collapse results on.
+   */
+  public static final String COLLAPSE_FIELD = "collapse.field";
+  
+  /**
+   * Type of collapsing to perform: "normal" or "adjacent".
+   */
+  public static final String COLLAPSE_TYPE = "collapse.type";
+  
+  public enum CollapseType {
+    NORMAL, ADJACENT;
+    
+    public String toString() {
+      return super.toString().toLowerCase();
+    }
+    
+    public static CollapseType get(String label) {
+      try {
+        return valueOf(label.toUpperCase());
+      } catch (IllegalArgumentException e) {
+        throw new SolrException(SolrException.ErrorCode.BAD_REQUEST, label
+            + " is not a valid type of field collapsing", e);
+      }
+    }
+  }
+  
+  /**
+   * Apply faceting before or after collapsing.
+   */
+  public static final String COLLAPSE_FACET = "collapse.facet";
+  
+  public enum CollapseFacet {
+    BEFORE, AFTER;
+    
+    public String toString() {
+      return super.toString().toLowerCase();
+    }
+    
+    public static CollapseFacet get(String label) {
+      try {
+        return valueOf(label.toUpperCase());
+      } catch (IllegalArgumentException e) {
+        throw new SolrException(SolrException.ErrorCode.BAD_REQUEST, label
+            + " is not a valid faceting mode for field collapsing", e);
+      }
+    }
+  }
+  
+  /**
+   * The number of documents with the same value for collapse.field after which
+   * collapsing kicks in.
+   */
+  public static final String COLLAPSE_THRESHOLD = "collapse.threshold";
+  
+  /**
+   * @deprecated Deprecated in favour of collapse.threshold.
+   */
+  public static final String COLLAPSE_MAX = "collapse.max";
+  
+  /**
+   * Maximum number of documents to process during field collapsing.
+   */
+  public static final String COLLAPSE_MAXDOCS = "collapse.maxdocs";
+  
+  /**
+   * Return collapse count for each document? Defaults to true.
+   */
+  public static final String COLLAPSE_INFO_DOC = "collapse.info.doc";
+  
+  /**
+   * Return collapse count for each field value? Defaults to true.
+   */
+  public static final String COLLAPSE_INFO_COUNT = "collapse.info.count";
+}
Index: src/java/org/apache/solr/handler/component/CollapseComponent.java
===================================================================
--- src/java/org/apache/solr/handler/component/CollapseComponent.java	(revisión: 0)
+++ src/java/org/apache/solr/handler/component/CollapseComponent.java	(revisión: 0)
@@ -0,0 +1,99 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.solr.handler.component;
+
+import org.apache.solr.common.params.SolrParams;
+import org.apache.solr.common.params.CollapseParams;
+import org.apache.solr.common.params.CollapseParams.CollapseFacet;
+import org.apache.solr.request.SolrQueryRequest;
+import org.apache.solr.request.SolrQueryResponse;
+import org.apache.solr.search.*;
+
+
+import java.io.IOException;
+import java.net.URL;
+
+/**
+ * TODO!
+ * 
+ * @version $Id: QueryComponent.java 602341 2007-12-08 07:27:49Z ryan $
+ * @since solr 1.3
+ */
+public class CollapseComponent extends QueryComponent {
+  /**
+   * Actually run the query
+   */
+  @Override
+  public void process(ResponseBuilder builder) throws IOException {
+    SolrQueryRequest req = builder.req;
+    SolrQueryResponse rsp = builder.rsp;
+    SolrIndexSearcher searcher = req.getSearcher();
+    SolrParams params = req.getParams();
+  
+    DocListAndSet results = new DocListAndSet();
+    DocSet collapseFilterDocSet = null;
+    CollapseFilter collapseFilter = null;
+    boolean facetAfterCollapse = true;
+    if (params.get(CollapseParams.COLLAPSE_FIELD) != null) {
+      collapseFilter = new CollapseFilter(searcher, builder.getQuery(), builder.getFilters(),
+        builder.getSortSpec().getSort(), builder.getFieldFlags(), params);
+      collapseFilterDocSet = collapseFilter.getDocSet();
+      facetAfterCollapse = (collapseFilter.getCollapseFacet() == CollapseFacet.AFTER);
+    }
+    DocListAndSet collapseResults = searcher.getDocListAndSet(builder.getQuery(), builder.getFilters(),
+      facetAfterCollapse ? collapseFilterDocSet : null,
+      builder.getSortSpec().getSort(),
+      builder.getSortSpec().getOffset(), builder.getSortSpec().getCount(),
+      builder.getFieldFlags());
+    results = collapseResults;
+    builder.setResults(results);
+    if (null != collapseFilter) {
+      rsp.add("collapse_counts", collapseFilter.getCollapseInfo(searcher, results.docList));
+    }
+  
+    rsp.add("response", results.docList);
+  }
+  
+  
+  /////////////////////////////////////////////
+  ///  SolrInfoMBean
+  ////////////////////////////////////////////
+  @Override
+  public String getDescription() {
+    return "Field Collapsing";
+  }
+  
+  @Override
+  public String getVersion() {
+    return "";
+  }
+  
+  @Override
+  public String getSourceId() {
+    return "";
+  }
+  
+  @Override
+  public String getSource() {
+    return "";
+  }
+  
+  @Override
+  public URL[] getDocs() {
+    return null;
+  }
+}
