You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ranger.apache.org by bo...@apache.org on 2015/03/18 00:33:32 UTC

[10/17] incubator-ranger git commit: Support for Solr as Audit Destination.

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/40aa090d/ranger_solrj/src/main/java/org/apache/solr/client/solrj/response/FieldAnalysisResponse.java
----------------------------------------------------------------------
diff --git a/ranger_solrj/src/main/java/org/apache/solr/client/solrj/response/FieldAnalysisResponse.java b/ranger_solrj/src/main/java/org/apache/solr/client/solrj/response/FieldAnalysisResponse.java
new file mode 100644
index 0000000..9c542d7
--- /dev/null
+++ b/ranger_solrj/src/main/java/org/apache/solr/client/solrj/response/FieldAnalysisResponse.java
@@ -0,0 +1,204 @@
+/*
+ * 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.client.solrj.response;
+
+import org.apache.solr.common.util.NamedList;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * A response that is returned by processing the {@link org.apache.solr.client.solrj.request.FieldAnalysisRequest}.
+ * Holds a map of {@link Analysis} objects per field name as well as a map of {@link Analysis} objects per field type.
+ *
+ *
+ * @since solr 1.4
+ */
+public class FieldAnalysisResponse extends AnalysisResponseBase {
+
+  private Map<String, Analysis> analysisByFieldTypeName = new HashMap<>();
+  private Map<String, Analysis> analysisByFieldName = new HashMap<>();
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public void setResponse(NamedList<Object> response) {
+    super.setResponse(response);
+
+    @SuppressWarnings("unchecked")
+    NamedList<NamedList<NamedList<NamedList<List<NamedList<Object>>>>>> analysisNL 
+      = (NamedList<NamedList<NamedList<NamedList<List<NamedList<Object>>>>>>) response.get("analysis");
+
+    for (Map.Entry<String, NamedList<NamedList<List<NamedList<Object>>>>> entry 
+           : analysisNL.get("field_types")) {
+
+      analysisByFieldTypeName.put(entry.getKey(), buildAnalysis(entry.getValue()));
+    }
+
+    for (Map.Entry<String, NamedList<NamedList<List<NamedList<Object>>>>> entry 
+           : analysisNL.get("field_names")) {
+
+      analysisByFieldName.put(entry.getKey(), buildAnalysis(entry.getValue()));
+    }
+  }
+
+  private Analysis buildAnalysis(NamedList<NamedList<List<NamedList<Object>>>> value) {
+      Analysis analysis = new Analysis();
+      
+      NamedList<List<NamedList<Object>>> queryNL = value.get("query");
+      List<AnalysisPhase> phases = (queryNL == null) ? null : buildPhases(queryNL);
+      analysis.setQueryPhases(phases);
+
+      NamedList<List<NamedList<Object>>> indexNL = value.get("index");
+      phases = buildPhases(indexNL);
+      analysis.setIndexPhases(phases);
+      
+      return analysis;
+  }
+
+  /**
+   * Returns the number of field type analyses.
+   *
+   * @return The number of field type analyses.
+   */
+  public int getFieldTypeAnalysisCount() {
+    return analysisByFieldTypeName.size();
+  }
+
+  /**
+   * Returns the analysis for the given field type or {@code null} if no such analysis exists.
+   *
+   * @param fieldTypeName The name of the field type.
+   *
+   * @return The analysis for the given field type.
+   */
+  public Analysis getFieldTypeAnalysis(String fieldTypeName) {
+    return analysisByFieldTypeName.get(fieldTypeName);
+  }
+
+  /**
+   * Returns all field type analyses with their associated field types.
+   *
+   * @return All field type analyses with their associated field types.
+   */
+  public Iterable<Map.Entry<String, Analysis>> getAllFieldTypeAnalysis() {
+    return analysisByFieldTypeName.entrySet();
+  }
+
+  /**
+   * Returns the number of field name analyses.
+   *
+   * @return The number of field name analyses.
+   */
+  public int getFieldNameAnalysisCount() {
+    return analysisByFieldName.size();
+  }
+
+  /**
+   * Returns the analysis for the given field name or {@code null} if no such analysis exists.
+   *
+   * @param fieldName The field name.
+   *
+   * @return The analysis for the given field name.
+   */
+  public Analysis getFieldNameAnalysis(String fieldName) {
+    return analysisByFieldName.get(fieldName);
+  }
+
+  /**
+   * Returns all field name analysese with their associated field names.
+   *
+   * @return all field name analysese with their associated field names.
+   */
+  public Iterable<Map.Entry<String, Analysis>> getAllFieldNameAnalysis() {
+    return analysisByFieldName.entrySet();
+  }
+
+
+  //================================================= Inner Classes ==================================================
+
+  /**
+   * The analysis of a field. Holds a list of all the query time analysis phases (if a query analysis was requested)
+   * as well as index time phases.
+   */
+  public static class Analysis {
+
+    private List<AnalysisPhase> queryPhases;
+    private List<AnalysisPhase> indexPhases;
+
+    /**
+     * This class should only be instantiated internally.
+     */
+    private Analysis() {
+    }
+
+    /**
+     * Returns the number of query time analysis phases in this analysis or 
+     * {@code -1} if query time analysis doesn't exist.
+     *
+     * @return Returns the number of query time analysis phases in this 
+     *         analysis or {@code -1} if query time analysis doesn't exist.
+     */
+    public int getQueryPhasesCount() {
+      return queryPhases == null ? -1 : queryPhases.size();
+    }
+
+    /**
+     * Returns the query time analysis phases for this analysis or {@code null}
+     * if query time analysis doesn't exist.
+     * 
+     *
+     * @return The query time analysis phases for this analysis or {@code null}
+     *         if query time analysis doesn't exist.
+     *         
+     */
+    public Iterable<AnalysisPhase> getQueryPhases() {
+      return queryPhases;
+    }
+
+    /**
+     * Returns the index time analysis phases for this analysis.
+     *
+     * @return The index time analysis phases for this analysis.
+     */
+    public int getIndexPhasesCount() {
+      return indexPhases.size();
+    }
+
+    /**
+     * Returns the index time analysis phases for this analysis.
+     *
+     * @return The index time analysis phases for this analysis.
+     */
+    public Iterable<AnalysisPhase> getIndexPhases() {
+      return indexPhases;
+    }
+
+    private void setQueryPhases(List<AnalysisPhase> queryPhases) {
+      this.queryPhases = queryPhases;
+    }
+
+    private void setIndexPhases(List<AnalysisPhase> indexPhases) {
+      this.indexPhases = indexPhases;
+    }
+
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/40aa090d/ranger_solrj/src/main/java/org/apache/solr/client/solrj/response/FieldStatsInfo.java
----------------------------------------------------------------------
diff --git a/ranger_solrj/src/main/java/org/apache/solr/client/solrj/response/FieldStatsInfo.java b/ranger_solrj/src/main/java/org/apache/solr/client/solrj/response/FieldStatsInfo.java
new file mode 100644
index 0000000..9685832
--- /dev/null
+++ b/ranger_solrj/src/main/java/org/apache/solr/client/solrj/response/FieldStatsInfo.java
@@ -0,0 +1,191 @@
+/*
+ * 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.client.solrj.response;
+
+import org.apache.solr.common.util.NamedList;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Holds stats info
+ *
+ *
+ * @since solr 1.4
+ */
+public class FieldStatsInfo implements Serializable {
+  final String name;
+  
+  Object min;
+  Object max;
+  Object sum;
+  Long count;
+  Long countDistinct;
+  Collection<Object> distinctValues;
+  Long missing;
+  Object mean = null;
+  Double sumOfSquares = null;
+  Double stddev = null;
+  
+  Map<String,List<FieldStatsInfo>> facets;
+  
+  public FieldStatsInfo( NamedList<Object> nl, String fname )
+  {
+    name = fname;
+    
+    for( Map.Entry<String, Object> entry : nl ) {
+      if( "min".equals( entry.getKey() ) ) {
+        min = entry.getValue();
+      }
+      else if( "max".equals( entry.getKey() ) ) {
+        max = entry.getValue();
+      }
+      else if( "sum".equals( entry.getKey() ) ) {
+        sum = entry.getValue();
+      }
+      else if( "count".equals( entry.getKey() ) ) {
+        count = (Long)entry.getValue();
+      }
+      else if ("countDistinct".equals(entry.getKey())) {
+        countDistinct = (Long) entry.getValue();
+      }
+      else if ("distinctValues".equals(entry.getKey())) {
+        distinctValues = (Collection<Object>) entry.getValue();
+      }
+      else if( "missing".equals( entry.getKey() ) ) {
+        missing = (Long)entry.getValue();
+      }
+      else if( "mean".equals( entry.getKey() ) ) {
+        mean = entry.getValue();
+      }
+      else if( "sumOfSquares".equals( entry.getKey() ) ) {
+        sumOfSquares = (Double)entry.getValue();
+      }
+      else if( "stddev".equals( entry.getKey() ) ) {
+        stddev = (Double)entry.getValue();
+      }
+      else if( "facets".equals( entry.getKey() ) ) {
+        @SuppressWarnings("unchecked")
+        NamedList<Object> fields = (NamedList<Object>)entry.getValue();
+        facets = new HashMap<>();
+        for( Map.Entry<String, Object> ev : fields ) {
+          List<FieldStatsInfo> vals = new ArrayList<>();
+          facets.put( ev.getKey(), vals );
+          @SuppressWarnings("unchecked")
+          NamedList<NamedList<Object>> vnl = (NamedList<NamedList<Object>>) ev.getValue();
+          for( int i=0; i<vnl.size(); i++ ) {
+            String n = vnl.getName(i);
+            vals.add( new FieldStatsInfo( vnl.getVal(i), n ) );
+          }
+        }
+      }
+      else {
+        throw new RuntimeException( "unknown key: "+entry.getKey() + " ["+entry.getValue()+"]" );
+      }
+    }
+  }
+  
+  @Override
+  public String toString()
+  {
+    StringBuilder sb = new StringBuilder();
+    sb.append( name );
+    sb.append( ": {" );
+    if( min != null ) {
+      sb.append( " min:").append( min );
+    }
+    if( max != null ) {
+      sb.append( " max:").append( max );
+    }
+    if( sum != null ) {
+      sb.append( " sum:").append( sum );
+    }
+    if( count != null ) {
+      sb.append( " count:").append( count );
+    }
+    if (countDistinct != null) {
+      sb.append(" countDistinct:").append(countDistinct);
+    }
+    if (distinctValues != null) {
+      sb.append(" distinctValues:").append(distinctValues);
+    }
+    if( missing != null ) {
+      sb.append( " missing:").append( missing );
+    }
+    if( mean != null ) {
+      sb.append( " mean:").append( mean );
+    }
+    if( stddev != null ) {
+      sb.append( " stddev:").append(stddev);
+    }
+    sb.append( " }" );
+    return sb.toString();
+  }
+
+  public String getName() {
+    return name;
+  }
+
+  public Object getMin() {
+    return min;
+  }
+
+  public Object getMax() {
+    return max;
+  }
+
+  public Object getSum() {
+    return sum;
+  }
+
+  public Long getCount() {
+    return count;
+  }
+
+  public Long getCountDistinct() {
+    return countDistinct;
+  }
+
+  public Collection<Object> getDistinctValues() {
+    return distinctValues;
+  }
+
+  public Long getMissing() {
+    return missing;
+  }
+
+  public Object getMean() {
+    return mean;
+  }
+
+  public Double getStddev() {
+    return stddev;
+  }
+
+  public Double getSumOfSquares() {
+    return sumOfSquares;
+  }
+
+  public Map<String, List<FieldStatsInfo>> getFacets() {
+    return facets;
+  }
+  
+}

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/40aa090d/ranger_solrj/src/main/java/org/apache/solr/client/solrj/response/Group.java
----------------------------------------------------------------------
diff --git a/ranger_solrj/src/main/java/org/apache/solr/client/solrj/response/Group.java b/ranger_solrj/src/main/java/org/apache/solr/client/solrj/response/Group.java
new file mode 100644
index 0000000..2ee0389
--- /dev/null
+++ b/ranger_solrj/src/main/java/org/apache/solr/client/solrj/response/Group.java
@@ -0,0 +1,69 @@
+package org.apache.solr.client.solrj.response;
+
+/*
+ * 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.
+ */
+
+import org.apache.solr.common.SolrDocumentList;
+
+import java.io.Serializable;
+
+/**
+ * Represents a group. A group contains a common group value that all documents inside the group share and
+ * documents that belong to this group.
+ *
+ * A group value can be a field value, function result or a query string depending on the {@link GroupCommand}.
+ * In case of a field value or a function result the value is always a indexed value.
+ *
+ * @since solr 3.4
+ */
+public class Group implements Serializable {
+
+  private final String _groupValue;
+  private final SolrDocumentList _result;
+
+  /**
+   * Creates a Group instance.
+   *
+   * @param groupValue The common group value (indexed value) that all documents share.
+   * @param result The documents to be displayed that belong to this group
+   */
+  public Group(String groupValue, SolrDocumentList result) {
+    _groupValue = groupValue;
+    _result = result;
+  }
+
+  /**
+   * Returns the common group value that all documents share inside this group.
+   * This is an indexed value, not a stored value.
+   *
+   * @return the common group value
+   */
+  public String getGroupValue() {
+    return _groupValue;
+  }
+
+  /**
+   * Returns the documents to be displayed that belong to this group.
+   * How many documents are returned depend on the <code>group.offset</code> and <code>group.limit</code> parameters.
+   *
+   * @return the documents to be displayed that belong to this group
+   */
+  public SolrDocumentList getResult() {
+    return _result;
+  }
+
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/40aa090d/ranger_solrj/src/main/java/org/apache/solr/client/solrj/response/GroupCommand.java
----------------------------------------------------------------------
diff --git a/ranger_solrj/src/main/java/org/apache/solr/client/solrj/response/GroupCommand.java b/ranger_solrj/src/main/java/org/apache/solr/client/solrj/response/GroupCommand.java
new file mode 100644
index 0000000..c2c8127
--- /dev/null
+++ b/ranger_solrj/src/main/java/org/apache/solr/client/solrj/response/GroupCommand.java
@@ -0,0 +1,125 @@
+package org.apache.solr.client.solrj.response;
+
+/*
+ * 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.
+ */
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * This class represents the result of a group command.
+ * This can be the result of the following parameter:
+ * <ul>
+ *   <li> group.field
+ *   <li> group.func
+ *   <li> group.query
+ * </ul>
+ *
+ * An instance of this class contains:
+ * <ul>
+ *   <li> The name of this command. This can be the field, function or query grouped by.
+ *   <li> The total number of documents that have matched.
+ *   <li> The total number of groups that have matched.
+ *   <li> The groups to be displayed. Depending on the start and rows parameter.
+ * </ul>
+ *
+ * In case of <code>group.query</code> only one group is present and ngroups is always <code>null</code>.
+ *
+ * @since solr 3.4
+ */
+public class GroupCommand implements Serializable {
+
+  private final String _name;
+  private final List<Group> _values = new ArrayList<>();
+  private final int _matches;
+  private final Integer _ngroups;
+
+  /**
+   * Creates a GroupCommand instance
+   *
+   * @param name    The name of this command
+   * @param matches The total number of documents found for this command
+   */
+  public GroupCommand(String name, int matches) {
+    _name = name;
+    _matches = matches;
+    _ngroups = null;
+  }
+
+  /**
+   * Creates a GroupCommand instance.
+   *
+   * @param name    The name of this command
+   * @param matches The total number of documents found for this command
+   * @param nGroups The total number of groups found for this command.
+   */
+  public GroupCommand(String name, int matches, int nGroups) {
+    _name = name;
+    _matches = matches;
+    _ngroups = nGroups;
+  }
+
+  /**
+   * Returns the name of this command. This can be the field, function or query grouped by.
+   *
+   * @return the name of this command
+   */
+  public String getName() {
+    return _name;
+  }
+
+  /**
+   * Adds a group to this command.
+   *
+   * @param group A group to be added
+   */
+  public void add(Group group) {
+    _values.add(group);
+  }
+
+  /**
+   * Returns the groups to be displayed.
+   * The number of groups returned depend on the <code>start</code> and <code>rows</code> parameters.
+   *
+   * @return the groups to be displayed.
+   */
+  public List<Group> getValues() {
+    return _values;
+  }
+
+  /**
+   * Returns the total number of documents found for this command.
+   *
+   * @return the total number of documents found for this command.
+   */
+  public int getMatches() {
+    return _matches;
+  }
+
+  /**
+   * Returns the total number of groups found for this command.
+   * Returns <code>null</code> if the <code>group.ngroups</code> parameter is unset or <code>false</code> or
+   * if this is a group command query (parameter = <code>group.query</code>).
+   *
+   * @return the total number of groups found for this command.
+   */
+  public Integer getNGroups() {
+    return _ngroups;
+  }
+
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/40aa090d/ranger_solrj/src/main/java/org/apache/solr/client/solrj/response/GroupResponse.java
----------------------------------------------------------------------
diff --git a/ranger_solrj/src/main/java/org/apache/solr/client/solrj/response/GroupResponse.java b/ranger_solrj/src/main/java/org/apache/solr/client/solrj/response/GroupResponse.java
new file mode 100644
index 0000000..210bb5e
--- /dev/null
+++ b/ranger_solrj/src/main/java/org/apache/solr/client/solrj/response/GroupResponse.java
@@ -0,0 +1,56 @@
+package org.apache.solr.client.solrj.response;
+
+/*
+ * 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.
+ */
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Overall grouping result. Contains a list of {@link GroupCommand} instances that is the result of
+ * one the following parameters:
+ * <ul>
+ *   <li>group.field
+ *   <li>group.func
+ *   <li>group.query
+ * </ul>
+ *
+ * @since solr 3.4
+ */
+public class GroupResponse implements Serializable {
+
+  private final List<GroupCommand> _values = new ArrayList<>();
+
+  /**
+   * Adds a grouping command to the response.
+   *
+   * @param command The grouping command to add
+   */
+  public void add(GroupCommand command) {
+    _values.add(command);
+  }
+
+  /**
+   * Returns all grouping commands.
+   *
+   * @return all grouping commands
+   */
+  public List<GroupCommand> getValues() {
+    return _values;
+  }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/40aa090d/ranger_solrj/src/main/java/org/apache/solr/client/solrj/response/IntervalFacet.java
----------------------------------------------------------------------
diff --git a/ranger_solrj/src/main/java/org/apache/solr/client/solrj/response/IntervalFacet.java b/ranger_solrj/src/main/java/org/apache/solr/client/solrj/response/IntervalFacet.java
new file mode 100644
index 0000000..1f91fe8
--- /dev/null
+++ b/ranger_solrj/src/main/java/org/apache/solr/client/solrj/response/IntervalFacet.java
@@ -0,0 +1,85 @@
+package org.apache.solr.client.solrj.response;
+
+import java.util.List;
+
+/*
+ * 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.
+ */
+/**
+ * Objects of this class will contain the result of all the intervals defined
+ * for a specific field. 
+ */
+public class IntervalFacet {
+ 
+  /**
+   * The field for which interval facets where calculated
+   */
+  private final String field;
+
+  /**
+   * The list of interval facets calculated for {@link #field}
+   */
+  private final List<Count> intervals;
+  
+  IntervalFacet(String field, List<Count> values) {
+    this.field = field;
+    this.intervals = values;
+  }
+  
+  /**
+   * @return The field for which interval facets where calculated
+   */
+  public String getField() {
+    return field;
+  }
+
+  /**
+   * @return The list of interval facets calculated for {@link #field}
+   */
+  public List<Count> getIntervals() {
+    return intervals;
+  }
+  
+  /**
+   * Holds counts for facet intervals defined in a field
+   */
+  public static class Count {
+    /**
+     * The key of this interval. This is the original 
+     * interval string or the value of the "key" local
+     * param
+     */
+    private final String key;
+    /**
+     * The count of this interval
+     */
+    private final int count;
+    
+    Count(String key, int count) {
+      super();
+      this.key = key;
+      this.count = count;
+    }
+    
+    public String getKey() {
+      return key;
+    }
+
+    public int getCount() {
+      return count;
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/40aa090d/ranger_solrj/src/main/java/org/apache/solr/client/solrj/response/LukeResponse.java
----------------------------------------------------------------------
diff --git a/ranger_solrj/src/main/java/org/apache/solr/client/solrj/response/LukeResponse.java b/ranger_solrj/src/main/java/org/apache/solr/client/solrj/response/LukeResponse.java
new file mode 100644
index 0000000..5d2f328
--- /dev/null
+++ b/ranger_solrj/src/main/java/org/apache/solr/client/solrj/response/LukeResponse.java
@@ -0,0 +1,270 @@
+/*
+ * 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.client.solrj.response;
+
+import org.apache.solr.common.luke.FieldFlag;
+import org.apache.solr.common.util.NamedList;
+
+import java.io.Serializable;
+import java.util.*;
+
+
+/**
+ * This is an incomplete representation of the data returned from Luke
+ *
+ *
+ * @since solr 1.3
+ */
+public class LukeResponse extends SolrResponseBase {
+
+  public static class FieldTypeInfo implements Serializable {
+    String name;
+    String className;
+    boolean tokenized;
+    String analyzer;
+    List<String> fields;
+
+
+    public FieldTypeInfo(String name) {
+      this.name = name;
+      fields = Collections.emptyList();
+    }
+
+
+    public String getAnalyzer() {
+      return analyzer;
+    }
+
+    public String getClassName() {
+      return className;
+    }
+
+    public List<String> getFields() {
+      return fields;
+    }
+
+    public String getName() {
+      return name;
+    }
+
+    public boolean isTokenized() {
+      return tokenized;
+    }/*
+     Sample:
+     types={ignored={fields=null,tokenized=false,analyzer=org.apache.solr.schema.FieldType$DefaultAnalyzer@f94934},
+     integer={fields=null,tokenized=false,analyzer=org.apache.solr.schema.FieldType$DefaultAnalyzer@3525a2},
+     sfloat={fields=[price, weight],tokenized=false,analyzer=org.apache.solr.schema.FieldType$DefaultAnalyzer@39cf9c},
+     text_ws={fields=[cat],tokenized=true,analyzer=TokenizerChain(org.apache.solr.analysis.WhitespaceTokenizerFactory@6d3ca2)},
+     alphaOnlySort={fields=[alphaNameSort],tokenized=true,analyzer=TokenizerChain(org.apache.solr.analysis.KeywordTokenizerFactory@a7bd3b,
+      org.apache.solr.analysis.LowerCaseFilterFactory@78aae2, org.apache.solr.analysis.TrimFilterFactory@1b16a7,
+      org.apache.solr.analysis.PatternReplaceFilterFactory@6c6b08)},date={fields=[timestamp],tokenized=false,
+      analyzer=org.apache.solr.schema.FieldType$DefaultAnalyzer@e6e42e},sint={fields=[popularity],
+      tokenized=false,analyzer=org.apache.solr.schema.FieldType$DefaultAnalyzer@8ea21d},
+      boolean={fields=[inStock],tokenized=false,analyzer=org.apache.solr.schema.BoolField$1@354949},
+      textTight={fields=[sku],tokenized=true,analyzer=TokenizerChain(org.apache.solr.analysis.WhitespaceTokenizerFactory@5e88f7,
+       org.apache.solr.analysis.SynonymFilterFactory@723646, org.apache.solr.analysis.StopFilterFactory@492ff1,
+       org.apache.solr.analysis.WordDelimiterFilterFactory@eaabad, org.apache.solr.analysis.LowerCaseFilterFactory@ad1355,
+        org.apache.solr.analysis.EnglishPorterFilterFactory@d03a00, org.apache.solr.analysis.RemoveDuplicatesTokenFilterFactory@900079)},
+        long={fields=null,tokenized=false,analyzer=org.apache.solr.schema.FieldType$DefaultAnalyzer@f3b83},
+        double={fields=null,tokenized=false,analyzer=org.apache.solr.schema.FieldType$DefaultAnalyzer@c2b07},
+
+      */
+
+    @SuppressWarnings("unchecked")
+    public void read(NamedList<Object> nl) {
+      for (Map.Entry<String, Object> entry : nl) {
+        String key = entry.getKey();
+        if ("fields".equals(key) && entry.getValue() != null) {
+          List<String> theFields = (List<String>) entry.getValue();
+          fields = new ArrayList<>(theFields);
+        } else if ("tokenized".equals(key) == true) {
+          tokenized = Boolean.parseBoolean(entry.getValue().toString());
+        } else if ("analyzer".equals(key) == true) {
+          analyzer = entry.getValue().toString();
+        } else if ("className".equals(key) == true) {
+          className = entry.getValue().toString();
+        }
+      }
+    }
+  }
+
+  public static class FieldInfo implements Serializable {
+    String name;
+    String type;
+    String schema;
+    int docs;
+    int distinct;
+    EnumSet<FieldFlag> flags;
+    boolean cacheableFaceting;
+    NamedList<Integer> topTerms;
+
+    public FieldInfo(String n) {
+      name = n;
+    }
+
+    @SuppressWarnings("unchecked")
+    public void read(NamedList<Object> nl) {
+      for (Map.Entry<String, Object> entry : nl) {
+        if ("type".equals(entry.getKey())) {
+          type = (String) entry.getValue();
+        }
+        if ("flags".equals(entry.getKey())) {
+          flags = parseFlags((String) entry.getValue());
+        } else if ("schema".equals(entry.getKey())) {
+          schema = (String) entry.getValue();
+        } else if ("docs".equals(entry.getKey())) {
+          docs = (Integer) entry.getValue();
+        } else if ("distinct".equals(entry.getKey())) {
+          distinct = (Integer) entry.getValue();
+        } else if ("cacheableFaceting".equals(entry.getKey())) {
+          cacheableFaceting = (Boolean) entry.getValue();
+        } else if ("topTerms".equals(entry.getKey())) {
+          topTerms = (NamedList<Integer>) entry.getValue();
+        }
+      }
+    }
+
+    public static EnumSet<FieldFlag> parseFlags(String flagStr) {
+      EnumSet<FieldFlag> result = EnumSet.noneOf(FieldFlag.class);
+      char[] chars = flagStr.toCharArray();
+      for (int i = 0; i < chars.length; i++) {
+        if (chars[i] != '-') {
+          FieldFlag flag = FieldFlag.getFlag(chars[i]);
+          result.add(flag);
+        }
+      }
+      return result;
+    }
+
+    public EnumSet<FieldFlag> getFlags() {
+      return flags;
+    }
+
+    public boolean isCacheableFaceting() {
+      return cacheableFaceting;
+    }
+
+    public String getType() {
+      return type;
+    }
+
+    public int getDistinct() {
+      return distinct;
+    }
+
+    public int getDocs() {
+      return docs;
+    }
+
+    public String getName() {
+      return name;
+    }
+
+    public String getSchema() {
+      return schema;
+    }
+
+    public NamedList<Integer> getTopTerms() {
+      return topTerms;
+    }
+  }
+
+  private NamedList<Object> indexInfo;
+  private Map<String, FieldInfo> fieldInfo;
+  private Map<String, FieldTypeInfo> fieldTypeInfo;
+
+  @Override
+  @SuppressWarnings("unchecked")
+  public void setResponse(NamedList<Object> res) {
+    super.setResponse(res);
+
+    // Parse indexinfo
+    indexInfo = (NamedList<Object>) res.get("index");
+
+    NamedList<Object> schema = (NamedList<Object>) res.get("schema");
+    NamedList<Object> flds = (NamedList<Object>) res.get("fields");
+    if (flds == null && schema != null ) {
+      flds = (NamedList<Object>) schema.get("fields");
+    }
+    if (flds != null) {
+      fieldInfo = new HashMap<>();
+      for (Map.Entry<String, Object> field : flds) {
+        FieldInfo f = new FieldInfo(field.getKey());
+        f.read((NamedList<Object>) field.getValue());
+        fieldInfo.put(field.getKey(), f);
+      }
+    }
+
+    if( schema != null ) {
+      NamedList<Object> fldTypes = (NamedList<Object>) schema.get("types");
+      if (fldTypes != null) {
+        fieldTypeInfo = new HashMap<>();
+        for (Map.Entry<String, Object> fieldType : fldTypes) {
+          FieldTypeInfo ft = new FieldTypeInfo(fieldType.getKey());
+          ft.read((NamedList<Object>) fieldType.getValue());
+          fieldTypeInfo.put(fieldType.getKey(), ft);
+        }
+      }
+    }
+  }
+
+  //----------------------------------------------------------------
+  //----------------------------------------------------------------
+
+  public String getIndexDirectory() {
+    if (indexInfo == null) return null;
+    return (String) indexInfo.get("directory");
+  }
+
+  public Integer getNumDocs() {
+    if (indexInfo == null) return null;
+    return (Integer) indexInfo.get("numDocs");
+  }
+
+  public Integer getMaxDoc() {
+    if (indexInfo == null) return null;
+    return (Integer) indexInfo.get("maxDoc");
+  }
+
+  public Integer getNumTerms() {
+    if (indexInfo == null) return null;
+    return (Integer) indexInfo.get("numTerms");
+  }
+
+  public Map<String, FieldTypeInfo> getFieldTypeInfo() {
+    return fieldTypeInfo;
+  }
+
+  public FieldTypeInfo getFieldTypeInfo(String name) {
+    return fieldTypeInfo.get(name);
+  }
+
+  public NamedList<Object> getIndexInfo() {
+    return indexInfo;
+  }
+
+  public Map<String, FieldInfo> getFieldInfo() {
+    return fieldInfo;
+  }
+
+  public FieldInfo getFieldInfo(String f) {
+    return fieldInfo.get(f);
+  }
+
+  //----------------------------------------------------------------
+}

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/40aa090d/ranger_solrj/src/main/java/org/apache/solr/client/solrj/response/PivotField.java
----------------------------------------------------------------------
diff --git a/ranger_solrj/src/main/java/org/apache/solr/client/solrj/response/PivotField.java b/ranger_solrj/src/main/java/org/apache/solr/client/solrj/response/PivotField.java
new file mode 100644
index 0000000..3b084f6
--- /dev/null
+++ b/ranger_solrj/src/main/java/org/apache/solr/client/solrj/response/PivotField.java
@@ -0,0 +1,97 @@
+/*
+ * 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.client.solrj.response;
+
+import java.io.PrintStream;
+import java.io.Serializable;
+import java.util.List;
+import java.util.Map;
+
+public class PivotField implements Serializable
+{
+  final String  _field;
+  final Object  _value;
+  final int     _count;
+  final List<PivotField> _pivot;
+  final Map<String,FieldStatsInfo> _statsInfo;
+
+  /**
+   * @deprecated Use {@link #PivotField(String,Object,int,List,Map)} with a null <code>statsInfo</code>
+   */
+  @Deprecated
+  public PivotField( String f, Object v, int count, List<PivotField> pivot) {
+    this(f, v, count, pivot, null);
+  }
+
+  public PivotField( String f, Object v, int count, List<PivotField> pivot, Map<String,FieldStatsInfo> statsInfo)
+  {
+    _field = f;
+    _value = v;
+    _count = count;
+    _pivot = pivot;
+    _statsInfo = statsInfo;
+  }
+   
+  public String getField() {
+   return _field;
+  }
+
+  public Object getValue() {
+    return _value;
+  }
+
+  public int getCount() {
+    return _count;
+  }
+
+  public List<PivotField> getPivot() {
+    return _pivot;
+  }
+   
+  public Map<String,FieldStatsInfo> getFieldStatsInfo() {
+    return _statsInfo;
+  }
+
+  @Override
+  public String toString()
+  {
+    return _field + ":" + _value + " ["+_count+"] "+_pivot;
+  }
+
+  public void write( PrintStream out, int indent )
+  {
+    for( int i=0; i<indent; i++ ) {
+      out.print( "  " );
+    }
+    out.print( _field + "=" + _value + " ("+_count+")" );
+    if (null != _statsInfo) {
+      out.print( "->stats:[" ); 
+      for( FieldStatsInfo fieldStatsInfo : _statsInfo.values() ) {
+        out.print(fieldStatsInfo.toString());
+        out.print(",");
+      }
+      out.print("]");
+    }
+    out.println();
+    if( _pivot != null ) {
+      for( PivotField p : _pivot ) {
+        p.write( out, indent+1 );
+      }
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/40aa090d/ranger_solrj/src/main/java/org/apache/solr/client/solrj/response/QueryResponse.java
----------------------------------------------------------------------
diff --git a/ranger_solrj/src/main/java/org/apache/solr/client/solrj/response/QueryResponse.java b/ranger_solrj/src/main/java/org/apache/solr/client/solrj/response/QueryResponse.java
new file mode 100644
index 0000000..89cd971
--- /dev/null
+++ b/ranger_solrj/src/main/java/org/apache/solr/client/solrj/response/QueryResponse.java
@@ -0,0 +1,586 @@
+/*
+ * 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.client.solrj.response;
+
+import org.apache.solr.client.solrj.SolrClient;
+import org.apache.solr.client.solrj.beans.DocumentObjectBinder;
+import org.apache.solr.common.SolrDocumentList;
+import org.apache.solr.common.params.CursorMarkParams;
+import org.apache.solr.common.util.NamedList;
+import org.apache.solr.common.util.SimpleOrderedMap;
+
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.TreeMap;
+
+/**
+ * 
+ *
+ * @since solr 1.3
+ */
+@SuppressWarnings("unchecked")
+public class QueryResponse extends SolrResponseBase 
+{
+  // Direct pointers to known types
+  private NamedList<Object> _header = null;
+  private SolrDocumentList _results = null;
+  private NamedList<ArrayList> _sortvalues = null;
+  private NamedList<Object> _facetInfo = null;
+  private NamedList<Object> _debugInfo = null;
+  private NamedList<Object> _highlightingInfo = null;
+  private NamedList<Object> _spellInfo = null;
+  private NamedList<Object> _statsInfo = null;
+  private NamedList<NamedList<Number>> _termsInfo = null;
+  private String _cursorMarkNext = null;
+
+  // Grouping response
+  private NamedList<Object> _groupedInfo = null;
+  private GroupResponse _groupResponse = null;
+
+  private NamedList<Object> _expandedInfo = null;
+  private Map<String, SolrDocumentList> _expandedResults = null;
+
+  // Facet stuff
+  private Map<String,Integer> _facetQuery = null;
+  private List<FacetField> _facetFields = null;
+  private List<FacetField> _limitingFacets = null;
+  private List<FacetField> _facetDates = null;
+  private List<RangeFacet> _facetRanges = null;
+  private NamedList<List<PivotField>> _facetPivot = null;
+  private List<IntervalFacet> _intervalFacets = null;
+
+  // Highlight Info
+  private Map<String,Map<String,List<String>>> _highlighting = null;
+
+  // SpellCheck Response
+  private SpellCheckResponse _spellResponse = null;
+
+  // Terms Response
+  private TermsResponse _termsResponse = null;
+  
+  // Field stats Response
+  private Map<String,FieldStatsInfo> _fieldStatsInfo = null;
+  
+  // Debug Info
+  private Map<String,Object> _debugMap = null;
+  private Map<String,String> _explainMap = null;
+
+  // utility variable used for automatic binding -- it should not be serialized
+  private transient final SolrClient solrClient;
+  
+  public QueryResponse(){
+    solrClient = null;
+  }
+  
+  /**
+   * Utility constructor to set the solrServer and namedList
+   */
+  public QueryResponse( NamedList<Object> res , SolrClient solrClient){
+    this.setResponse( res );
+    this.solrClient = solrClient;
+  }
+
+  public QueryResponse(SolrClient solrClient) {
+    this.solrClient = solrClient;
+  }
+
+  @Override
+  public void setResponse( NamedList<Object> res )
+  {
+    super.setResponse( res );
+    
+    // Look for known things
+    for( int i=0; i<res.size(); i++ ) {
+      String n = res.getName( i );
+      if( "responseHeader".equals( n ) ) {
+        _header = (NamedList<Object>) res.getVal( i );
+      }
+      else if( "response".equals( n ) ) {
+        _results = (SolrDocumentList) res.getVal( i );
+      }
+      else if( "sort_values".equals( n ) ) {
+        _sortvalues = (NamedList<ArrayList>) res.getVal( i );
+      }
+      else if( "facet_counts".equals( n ) ) {
+        _facetInfo = (NamedList<Object>) res.getVal( i );
+        // extractFacetInfo inspects _results, so defer calling it
+        // in case it hasn't been populated yet.
+      }
+      else if( "debug".equals( n ) ) {
+        _debugInfo = (NamedList<Object>) res.getVal( i );
+        extractDebugInfo( _debugInfo );
+      }
+      else if( "grouped".equals( n ) ) {
+        _groupedInfo = (NamedList<Object>) res.getVal( i );
+        extractGroupedInfo( _groupedInfo );
+      }
+      else if("expanded".equals(n)) {
+        _expandedResults = (Map<String, SolrDocumentList>) res.getVal( i );
+      }
+      else if( "highlighting".equals( n ) ) {
+        _highlightingInfo = (NamedList<Object>) res.getVal( i );
+        extractHighlightingInfo( _highlightingInfo );
+      }
+      else if ( "spellcheck".equals( n ) )  {
+        _spellInfo = (NamedList<Object>) res.getVal( i );
+        extractSpellCheckInfo( _spellInfo );
+      }
+      else if ( "stats".equals( n ) )  {
+        _statsInfo = (NamedList<Object>) res.getVal( i );
+        extractStatsInfo( _statsInfo );
+      }
+      else if ( "terms".equals( n ) ) {
+        _termsInfo = (NamedList<NamedList<Number>>) res.getVal( i );
+        extractTermsInfo( _termsInfo );
+      }
+      else if ( CursorMarkParams.CURSOR_MARK_NEXT.equals( n ) ) {
+        _cursorMarkNext = (String) res.getVal( i );
+      }
+    }
+    if(_facetInfo != null) extractFacetInfo( _facetInfo );
+  }
+
+  private void extractSpellCheckInfo(NamedList<Object> spellInfo) {
+    _spellResponse = new SpellCheckResponse(spellInfo);
+  }
+
+  private void extractTermsInfo(NamedList<NamedList<Number>> termsInfo) {
+    _termsResponse = new TermsResponse(termsInfo);
+  }
+  
+  private void extractStatsInfo(NamedList<Object> info) {
+    _fieldStatsInfo = extractFieldStatsInfo(info);
+  }
+
+  private Map<String, FieldStatsInfo> extractFieldStatsInfo(NamedList<Object> info) {
+    if( info != null ) {
+       Map<String, FieldStatsInfo> fieldStatsInfoMap = new TreeMap<>();
+      NamedList<NamedList<Object>> ff = (NamedList<NamedList<Object>>) info.get( "stats_fields" );
+      if( ff != null ) {
+        for( Map.Entry<String,NamedList<Object>> entry : ff ) {
+          NamedList<Object> v = entry.getValue();
+          if( v != null ) {
+             fieldStatsInfoMap.put( entry.getKey(),
+                new FieldStatsInfo( v, entry.getKey() ) );
+          }
+        }
+      }
+       return fieldStatsInfoMap;
+    }
+    return null;
+  }
+
+  private void extractDebugInfo( NamedList<Object> debug )
+  {
+    _debugMap = new LinkedHashMap<>(); // keep the order
+    for( Map.Entry<String, Object> info : debug ) {
+      _debugMap.put( info.getKey(), info.getValue() );
+    }
+
+    // Parse out interesting bits from the debug info
+    _explainMap = new HashMap<>();
+    NamedList<String> explain = (NamedList<String>)_debugMap.get( "explain" );
+    if( explain != null ) {
+      for( Map.Entry<String, String> info : explain ) {
+        String key = info.getKey();
+        _explainMap.put( key, info.getValue() );
+      }
+    }
+  }
+
+  private void extractGroupedInfo( NamedList<Object> info ) {
+    if ( info != null ) {
+      _groupResponse = new GroupResponse();
+      int size = info.size();
+      for (int i=0; i < size; i++) {
+        String fieldName = info.getName(i);
+        Object fieldGroups =  info.getVal(i);
+        SimpleOrderedMap<Object> simpleOrderedMap = (SimpleOrderedMap<Object>) fieldGroups;
+
+        Object oMatches = simpleOrderedMap.get("matches");
+        Object oNGroups = simpleOrderedMap.get("ngroups");
+        Object oGroups = simpleOrderedMap.get("groups");
+        Object queryCommand = simpleOrderedMap.get("doclist");
+        if (oMatches == null) {
+          continue;
+        }
+
+        if (oGroups != null) {
+          Integer iMatches = (Integer) oMatches;
+          ArrayList<Object> groupsArr = (ArrayList<Object>) oGroups;
+          GroupCommand groupedCommand;
+          if (oNGroups != null) {
+            Integer iNGroups = (Integer) oNGroups;
+            groupedCommand = new GroupCommand(fieldName, iMatches, iNGroups);
+          } else {
+            groupedCommand = new GroupCommand(fieldName, iMatches);
+          }
+
+          for (Object oGrp : groupsArr) {
+            SimpleOrderedMap grpMap = (SimpleOrderedMap) oGrp;
+            Object sGroupValue = grpMap.get( "groupValue");
+            SolrDocumentList doclist = (SolrDocumentList) grpMap.get( "doclist");
+            Group group = new Group(sGroupValue != null ? sGroupValue.toString() : null, doclist) ;
+            groupedCommand.add(group);
+          }
+
+          _groupResponse.add(groupedCommand);
+        } else if (queryCommand != null) {
+          Integer iMatches = (Integer) oMatches;
+          GroupCommand groupCommand;
+          if (oNGroups != null) {
+            Integer iNGroups = (Integer) oNGroups;
+            groupCommand = new GroupCommand(fieldName, iMatches, iNGroups);
+          } else {
+            groupCommand = new GroupCommand(fieldName, iMatches);
+          }
+          SolrDocumentList docList = (SolrDocumentList) queryCommand;
+          groupCommand.add(new Group(fieldName, docList));
+          _groupResponse.add(groupCommand);
+        }
+      }
+    }
+  }
+
+  private void extractHighlightingInfo( NamedList<Object> info )
+  {
+    _highlighting = new HashMap<>();
+    for( Map.Entry<String, Object> doc : info ) {
+      Map<String,List<String>> fieldMap = new HashMap<>();
+      _highlighting.put( doc.getKey(), fieldMap );
+      
+      NamedList<List<String>> fnl = (NamedList<List<String>>)doc.getValue();
+      for( Map.Entry<String, List<String>> field : fnl ) {
+        fieldMap.put( field.getKey(), field.getValue() );
+      }
+    }
+  }
+
+  private void extractFacetInfo( NamedList<Object> info )
+  {
+    // Parse the queries
+    _facetQuery = new LinkedHashMap<>();
+    NamedList<Integer> fq = (NamedList<Integer>) info.get( "facet_queries" );
+    if (fq != null) {
+      for( Map.Entry<String, Integer> entry : fq ) {
+        _facetQuery.put( entry.getKey(), entry.getValue() );
+      }
+    }
+    
+    // Parse the facet info into fields
+    // TODO?? The list could be <int> or <long>?  If always <long> then we can switch to <Long>
+    NamedList<NamedList<Number>> ff = (NamedList<NamedList<Number>>) info.get( "facet_fields" );
+    if( ff != null ) {
+      _facetFields = new ArrayList<>( ff.size() );
+      _limitingFacets = new ArrayList<>( ff.size() );
+      
+      long minsize = _results == null ? Long.MAX_VALUE :_results.getNumFound();
+      for( Map.Entry<String,NamedList<Number>> facet : ff ) {
+        FacetField f = new FacetField( facet.getKey() );
+        for( Map.Entry<String, Number> entry : facet.getValue() ) {
+          f.add( entry.getKey(), entry.getValue().longValue() );
+        }
+        
+        _facetFields.add( f );
+        FacetField nl = f.getLimitingFields( minsize );
+        if( nl.getValueCount() > 0 ) {
+          _limitingFacets.add( nl );
+        }
+      }
+    }
+    
+    //Parse date facets
+    NamedList<NamedList<Object>> df = (NamedList<NamedList<Object>>) info.get("facet_dates");
+    if (df != null) {
+      // System.out.println(df);
+      _facetDates = new ArrayList<>( df.size() );
+      for (Map.Entry<String, NamedList<Object>> facet : df) {
+        // System.out.println("Key: " + facet.getKey() + " Value: " + facet.getValue());
+        NamedList<Object> values = facet.getValue();
+        String gap = (String) values.get("gap");
+        Date end = (Date) values.get("end");
+        FacetField f = new FacetField(facet.getKey(), gap, end);
+        
+        for (Map.Entry<String, Object> entry : values)   {
+          try {
+            f.add(entry.getKey(), Long.parseLong(entry.getValue().toString()));
+          } catch (NumberFormatException e) {
+            //Ignore for non-number responses which are already handled above
+          }
+        }
+        
+        _facetDates.add(f);
+      }
+    }
+
+    //Parse range facets
+    NamedList<NamedList<Object>> rf = (NamedList<NamedList<Object>>) info.get("facet_ranges");
+    if (rf != null) {
+      _facetRanges = new ArrayList<>( rf.size() );
+      for (Map.Entry<String, NamedList<Object>> facet : rf) {
+        NamedList<Object> values = facet.getValue();
+        Object rawGap = values.get("gap");
+
+        RangeFacet rangeFacet;
+        if (rawGap instanceof Number) {
+          Number gap = (Number) rawGap;
+          Number start = (Number) values.get("start");
+          Number end = (Number) values.get("end");
+
+          Number before = (Number) values.get("before");
+          Number after = (Number) values.get("after");
+          Number between = (Number) values.get("between");
+
+          rangeFacet = new RangeFacet.Numeric(facet.getKey(), start, end, gap, before, after, between);
+        } else {
+          String gap = (String) rawGap;
+          Date start = (Date) values.get("start");
+          Date end = (Date) values.get("end");
+
+          Number before = (Number) values.get("before");
+          Number after = (Number) values.get("after");
+          Number between = (Number) values.get("between");
+
+          rangeFacet = new RangeFacet.Date(facet.getKey(), start, end, gap, before, after, between);
+        }
+
+        NamedList<Integer> counts = (NamedList<Integer>) values.get("counts");
+        for (Map.Entry<String, Integer> entry : counts)   {
+          rangeFacet.addCount(entry.getKey(), entry.getValue());
+        }
+
+        _facetRanges.add(rangeFacet);
+      }
+    }
+    
+    //Parse pivot facets
+    NamedList pf = (NamedList) info.get("facet_pivot");
+    if (pf != null) {
+      _facetPivot = new NamedList<>();
+      for( int i=0; i<pf.size(); i++ ) {
+        _facetPivot.add( pf.getName(i), readPivots( (List<NamedList>)pf.getVal(i) ) );
+      }
+    }
+    
+    //Parse interval facets
+    NamedList<NamedList<Object>> intervalsNL = (NamedList<NamedList<Object>>) info.get("facet_intervals");
+    if (intervalsNL != null) {
+      _intervalFacets = new ArrayList<>(intervalsNL.size());
+      for (Map.Entry<String, NamedList<Object>> intervalField : intervalsNL) {
+        String field = intervalField.getKey();
+        List<IntervalFacet.Count> counts = new ArrayList<IntervalFacet.Count>(intervalField.getValue().size());
+        for (Map.Entry<String, Object> interval : intervalField.getValue()) {
+          counts.add(new IntervalFacet.Count(interval.getKey(), (Integer)interval.getValue()));
+        }
+        _intervalFacets.add(new IntervalFacet(field, counts));
+      }
+    }
+  }
+  
+  protected List<PivotField> readPivots( List<NamedList> list )
+  {
+    ArrayList<PivotField> values = new ArrayList<>( list.size() );
+    for( NamedList nl : list ) {
+      // NOTE, this is cheating, but we know the order they are written in, so no need to check
+      assert "field".equals(nl.getName(0));
+      String f = (String)nl.getVal( 0 );
+      assert "value".equals(nl.getName(1));
+      Object v = nl.getVal( 1 );
+      assert "count".equals(nl.getName(2));
+      int cnt = ((Integer)nl.getVal( 2 )).intValue();
+
+      List<PivotField> subPivots = null;
+      Map<String,FieldStatsInfo> fieldStatsInfos = null;
+
+      if (4 <= nl.size()) {
+        for(int index = 3; index < nl.size(); index++) {
+          final String key = nl.getName(index);
+          final Object val = nl.getVal(index);
+          switch (key) {
+
+          case "pivot": {
+            assert null != val : "Server sent back 'null' for sub pivots?";
+            assert val instanceof List : "Server sent non-List for sub pivots?";
+
+            subPivots = readPivots( (List<NamedList>) val );
+            break;
+          }
+          case "stats": {
+            assert null != val : "Server sent back 'null' for stats?";
+            assert val instanceof NamedList : "Server sent non-NamedList for stats?";
+
+            fieldStatsInfos = extractFieldStatsInfo((NamedList<Object>) val);
+            break;
+          }
+          default: 
+            throw new RuntimeException( "unknown key in pivot: "+ key+ " ["+val+"]");
+
+          }
+        }
+      }
+
+      values.add( new PivotField( f, v, cnt, subPivots, fieldStatsInfos ) );
+    }
+    return values;
+  }
+
+  //------------------------------------------------------
+  //------------------------------------------------------
+
+  /**
+   * Remove the field facet info
+   */
+  public void removeFacets() {
+    _facetFields = new ArrayList<>();
+  }
+  
+  //------------------------------------------------------
+  //------------------------------------------------------
+
+  public NamedList<Object> getHeader() {
+    return _header;
+  }
+
+  public SolrDocumentList getResults() {
+    return _results;
+  }
+ 
+  public NamedList<ArrayList> getSortValues(){
+    return _sortvalues;
+  }
+
+  public Map<String, Object> getDebugMap() {
+    return _debugMap;
+  }
+
+  public Map<String, String> getExplainMap() {
+    return _explainMap;
+  }
+
+  public Map<String,Integer> getFacetQuery() {
+    return _facetQuery;
+  }
+
+  public Map<String, SolrDocumentList> getExpandedResults(){
+    return this._expandedResults;
+  }
+
+  /**
+   * Returns the {@link GroupResponse} containing the group commands.
+   * A group command can be the result of one of the following parameters:
+   * <ul>
+   *   <li>group.field
+   *   <li>group.func
+   *   <li>group.query
+   * </ul>
+   *
+   * @return the {@link GroupResponse} containing the group commands
+   */
+  public GroupResponse getGroupResponse() {
+    return _groupResponse;
+  }
+  
+  public Map<String, Map<String, List<String>>> getHighlighting() {
+    return _highlighting;
+  }
+
+  public SpellCheckResponse getSpellCheckResponse() {
+    return _spellResponse;
+  }
+
+  public TermsResponse getTermsResponse() {
+    return _termsResponse;
+  }
+  
+  /**
+   * See also: {@link #getLimitingFacets()}
+   */
+  public List<FacetField> getFacetFields() {
+    return _facetFields;
+  }
+  
+  public List<FacetField> getFacetDates()   {
+    return _facetDates;
+  }
+
+  public List<RangeFacet> getFacetRanges() {
+    return _facetRanges;
+  }
+
+  public NamedList<List<PivotField>> getFacetPivot()   {
+    return _facetPivot;
+  }
+  
+  public List<IntervalFacet> getIntervalFacets() {
+    return _intervalFacets;
+  }
+  
+  /** get
+   * 
+   * @param name the name of the
+   * @return the FacetField by name or null if it does not exist
+   */
+  public FacetField getFacetField(String name) {
+    if (_facetFields==null) return null;
+    for (FacetField f : _facetFields) {
+      if (f.getName().equals(name)) return f;
+    }
+    return null;
+  }
+  
+  public FacetField getFacetDate(String name)   {
+    if (_facetDates == null)
+      return null;
+    for (FacetField f : _facetDates)
+      if (f.getName().equals(name))
+        return f;
+    return null;
+  }
+  
+  /**
+   * @return a list of FacetFields where the count is less then
+   * then #getResults() {@link SolrDocumentList#getNumFound()}
+   * 
+   * If you want all results exactly as returned by solr, use:
+   * {@link #getFacetFields()}
+   */
+  public List<FacetField> getLimitingFacets() {
+    return _limitingFacets;
+  }
+  
+  public <T> List<T> getBeans(Class<T> type){
+    return solrClient == null ?
+      new DocumentObjectBinder().getBeans(type,_results):
+      solrClient.getBinder().getBeans(type, _results);
+  }
+
+  public Map<String, FieldStatsInfo> getFieldStatsInfo() {
+    return _fieldStatsInfo;
+  }
+
+  public String getNextCursorMark() {
+    return _cursorMarkNext;
+  }
+}
+
+
+

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/40aa090d/ranger_solrj/src/main/java/org/apache/solr/client/solrj/response/RangeFacet.java
----------------------------------------------------------------------
diff --git a/ranger_solrj/src/main/java/org/apache/solr/client/solrj/response/RangeFacet.java b/ranger_solrj/src/main/java/org/apache/solr/client/solrj/response/RangeFacet.java
new file mode 100644
index 0000000..52b4e6b
--- /dev/null
+++ b/ranger_solrj/src/main/java/org/apache/solr/client/solrj/response/RangeFacet.java
@@ -0,0 +1,126 @@
+package org.apache.solr.client.solrj.response;
+
+/*
+ * 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.
+ */
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Represents a range facet result
+ */
+public abstract class RangeFacet<B, G> {
+
+  private final String name;
+  private final List<Count> counts = new ArrayList<>();
+
+  private final B start;
+  private final B end;
+  private final G gap;
+
+  private final Number before;
+  private final Number after;
+  private final Number between;
+
+  protected RangeFacet(String name, B start, B end, G gap, Number before, Number after, Number between) {
+    this.name = name;
+    this.start = start;
+    this.end = end;
+    this.gap = gap;
+    this.before = before;
+    this.after = after;
+    this.between = between;
+  }
+
+  public void addCount(String value, int count) {
+    counts.add(new Count(value, count, this));
+  }
+
+  public String getName() {
+    return name;
+  }
+
+  public List<Count> getCounts() {
+    return counts;
+  }
+
+  public B getStart() {
+    return start;
+  }
+
+  public B getEnd() {
+    return end;
+  }
+
+  public G getGap() {
+    return gap;
+  }
+
+  public Number getBefore() {
+    return before;
+  }
+
+  public Number getAfter() {
+    return after;
+  }
+
+  public Number getBetween() {
+    return between;
+  }
+
+  public static class Numeric extends RangeFacet<Number, Number> {
+
+    public Numeric(String name, Number start, Number end, Number gap, Number before, Number after, Number between) {
+      super(name, start, end, gap, before, after, between);
+    }
+
+  }
+
+  public static class Date extends RangeFacet<java.util.Date, String> {
+
+    public Date(String name, java.util.Date start, java.util.Date end, String gap, Number before, Number after, Number between) {
+      super(name, start, end, gap, before, after, between);
+    }
+
+  }
+
+  public static class Count {
+
+    private final String value;
+    private final int count;
+    private final RangeFacet rangeFacet;
+
+    public Count(String value, int count, RangeFacet rangeFacet) {
+      this.value = value;
+      this.count = count;
+      this.rangeFacet = rangeFacet;
+    }
+
+    public String getValue() {
+      return value;
+    }
+
+    public int getCount() {
+      return count;
+    }
+
+    public RangeFacet getRangeFacet() {
+      return rangeFacet;
+    }
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/40aa090d/ranger_solrj/src/main/java/org/apache/solr/client/solrj/response/SolrPingResponse.java
----------------------------------------------------------------------
diff --git a/ranger_solrj/src/main/java/org/apache/solr/client/solrj/response/SolrPingResponse.java b/ranger_solrj/src/main/java/org/apache/solr/client/solrj/response/SolrPingResponse.java
new file mode 100644
index 0000000..cbd892f
--- /dev/null
+++ b/ranger_solrj/src/main/java/org/apache/solr/client/solrj/response/SolrPingResponse.java
@@ -0,0 +1,28 @@
+/*
+ * 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.client.solrj.response;
+
+/**
+ * 
+ *
+ * @since solr 1.3
+ */
+public class SolrPingResponse extends SolrResponseBase
+{
+  // nothing special now...
+}

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/40aa090d/ranger_solrj/src/main/java/org/apache/solr/client/solrj/response/SolrResponseBase.java
----------------------------------------------------------------------
diff --git a/ranger_solrj/src/main/java/org/apache/solr/client/solrj/response/SolrResponseBase.java b/ranger_solrj/src/main/java/org/apache/solr/client/solrj/response/SolrResponseBase.java
new file mode 100644
index 0000000..ca59e54
--- /dev/null
+++ b/ranger_solrj/src/main/java/org/apache/solr/client/solrj/response/SolrResponseBase.java
@@ -0,0 +1,91 @@
+/*
+ * 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.client.solrj.response;
+
+import org.apache.solr.client.solrj.SolrResponse;
+import org.apache.solr.common.util.NamedList;
+
+/**
+ * 
+ *
+ * @since solr 1.3
+ */
+public class SolrResponseBase extends SolrResponse
+{
+  private long elapsedTime = -1;
+  private NamedList<Object> response = null;
+  private String requestUrl = null;
+  
+  @Override
+  public long getElapsedTime() {
+    return elapsedTime;
+  }
+
+  public void setElapsedTime(long elapsedTime) {
+    this.elapsedTime = elapsedTime;
+  }
+
+  @Override
+  public NamedList<Object> getResponse() {
+    return response;
+  }
+
+  @Override
+  public void setResponse(NamedList<Object> response) {
+    this.response = response;
+  }
+
+  @Override
+  public String toString() {
+    return response.toString();
+  }
+  
+  public NamedList getResponseHeader() {
+    return (NamedList) response.get("responseHeader");
+  }
+  
+  // these two methods are based on the logic in SolrCore.setResponseHeaderValues(...)
+  public int getStatus() {
+    NamedList header = getResponseHeader();
+    if (header != null) {
+        return (Integer) header.get("status");
+    }
+    else {
+        return 0;
+    }
+  }
+  
+  public int getQTime() {
+    NamedList header = getResponseHeader();
+    if (header != null) {
+        return (Integer) header.get("QTime");
+    }
+    else {
+        return 0;
+    }
+  }
+
+  public String getRequestUrl() {
+    return requestUrl;
+  }
+
+  public void setRequestUrl(String requestUrl) {
+    this.requestUrl = requestUrl;
+  }
+  
+}

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/40aa090d/ranger_solrj/src/main/java/org/apache/solr/client/solrj/response/SpellCheckResponse.java
----------------------------------------------------------------------
diff --git a/ranger_solrj/src/main/java/org/apache/solr/client/solrj/response/SpellCheckResponse.java b/ranger_solrj/src/main/java/org/apache/solr/client/solrj/response/SpellCheckResponse.java
new file mode 100644
index 0000000..a3ae45d
--- /dev/null
+++ b/ranger_solrj/src/main/java/org/apache/solr/client/solrj/response/SpellCheckResponse.java
@@ -0,0 +1,273 @@
+package org.apache.solr.client.solrj.response;
+/*
+ * 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.
+ */
+
+import org.apache.solr.common.util.NamedList;
+
+import java.util.ArrayList;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Encapsulates responses from SpellCheckComponent
+ *
+ *
+ * @since solr 1.3
+ */
+public class SpellCheckResponse {
+  private boolean correctlySpelled;
+  private List<Collation> collations;
+  private List<Suggestion> suggestions = new ArrayList<>();
+  Map<String, Suggestion> suggestionMap = new LinkedHashMap<>();
+
+  public SpellCheckResponse(NamedList<Object> spellInfo) {
+    @SuppressWarnings("unchecked")
+    NamedList<Object> sugg = (NamedList<Object>) spellInfo.get("suggestions");
+    if (sugg == null) {
+      correctlySpelled = true;
+      return;
+    }
+    for (int i = 0; i < sugg.size(); i++) {
+      String n = sugg.getName(i);
+      @SuppressWarnings("unchecked")
+      Suggestion s = new Suggestion(n, (NamedList<Object>) sugg.getVal(i));
+      suggestionMap.put(n, s);
+      suggestions.add(s);
+    }
+    
+    Boolean correctlySpelled = (Boolean) spellInfo.get("correctlySpelled");
+    if (correctlySpelled != null) {
+      this.correctlySpelled = correctlySpelled;
+    }
+    
+    @SuppressWarnings("unchecked")
+    NamedList<Object> coll = (NamedList<Object>) spellInfo.get("collations");
+    if (coll != null) {
+      // The 'collationInternalRank' values are ignored so we only care 'collation's.
+      List<Object> collationInfo = coll.getAll("collation");
+      collations = new ArrayList<>(collationInfo.size());
+      for (Object o : collationInfo) {
+        if (o instanceof String) {
+          collations.add(new Collation()
+              .setCollationQueryString((String) o));
+        } else if (o instanceof NamedList) {
+          @SuppressWarnings("unchecked")
+          NamedList<Object> expandedCollation = (NamedList<Object>) o;
+          String collationQuery
+            = (String) expandedCollation.get("collationQuery");
+          int hits = (Integer) expandedCollation.get("hits");
+          @SuppressWarnings("unchecked")
+          NamedList<String> misspellingsAndCorrections
+            = (NamedList<String>) expandedCollation.get("misspellingsAndCorrections");
+
+          Collation collation = new Collation();
+          collation.setCollationQueryString(collationQuery);
+          collation.setNumberOfHits(hits);
+
+          for (int ii = 0; ii < misspellingsAndCorrections.size(); ii++) {
+            String misspelling = misspellingsAndCorrections.getName(ii);
+            String correction = misspellingsAndCorrections.getVal(ii);
+            collation.addMisspellingsAndCorrection(new Correction(
+                misspelling, correction));
+          }
+          collations.add(collation);
+        } else {
+          throw new AssertionError(
+              "Should get Lists of Strings or List of NamedLists here.");
+        }
+      }
+    }
+  }
+
+  public boolean isCorrectlySpelled() {
+    return correctlySpelled;
+  }
+
+  public List<Suggestion> getSuggestions() {
+    return suggestions;
+  }
+
+  public Map<String, Suggestion> getSuggestionMap() {
+    return suggestionMap;
+  }
+
+  public Suggestion getSuggestion(String token) {
+    return suggestionMap.get(token);
+  }
+
+  public String getFirstSuggestion(String token) {
+    Suggestion s = suggestionMap.get(token);
+    if (s==null || s.getAlternatives().isEmpty()) return null;
+    return s.getAlternatives().get(0);
+  }
+
+  /**
+   * <p>
+   *  Return the first collated query string.  For convenience and backwards-compatibility.  Use getCollatedResults() for full data.
+   * </p>
+   * @return first collated query string
+   */
+  public String getCollatedResult() {
+    return collations==null || collations.size()==0 ? null : collations.get(0).collationQueryString;
+  }
+  
+  /**
+   * <p>
+   *  Return all collations.  
+   *  Will include # of hits and misspelling-to-correction details if "spellcheck.collateExtendedResults was true.
+   * </p>
+   * @return all collations
+   */
+  public List<Collation> getCollatedResults() {
+    return collations;
+  }
+
+  public static class Suggestion {
+    private String token;
+    private int numFound;
+    private int startOffset;
+    private int endOffset;
+    private int originalFrequency;
+    private List<String> alternatives = new ArrayList<>();
+    private List<Integer> alternativeFrequencies;
+
+    public Suggestion(String token, NamedList<Object> suggestion) {
+      this.token = token;
+      for (int i = 0; i < suggestion.size(); i++) {
+        String n = suggestion.getName(i);
+
+        if ("numFound".equals(n)) {
+          numFound = (Integer) suggestion.getVal(i);
+        } else if ("startOffset".equals(n)) {
+          startOffset = (Integer) suggestion.getVal(i);
+        } else if ("endOffset".equals(n)) {
+          endOffset = (Integer) suggestion.getVal(i);
+        } else if ("origFreq".equals(n)) {
+          originalFrequency = (Integer) suggestion.getVal(i);
+        } else if ("suggestion".equals(n)) {
+          @SuppressWarnings("unchecked")
+          List list = (List)suggestion.getVal(i);
+          if (list.size() > 0 && list.get(0) instanceof NamedList) {
+            // extended results detected
+            @SuppressWarnings("unchecked")
+            List<NamedList> extended = (List<NamedList>)list;
+            alternativeFrequencies = new ArrayList<>();
+            for (NamedList nl : extended) {
+              alternatives.add((String)nl.get("word"));
+              alternativeFrequencies.add((Integer)nl.get("freq"));
+            }
+          } else {
+            @SuppressWarnings("unchecked")
+            List<String> alts = (List<String>) list;
+            alternatives.addAll(alts);
+          }
+        }
+      }
+    }
+
+    public String getToken() {
+      return token;
+    }
+
+    public int getNumFound() {
+      return numFound;
+    }
+
+    public int getStartOffset() {
+      return startOffset;
+    }
+
+    public int getEndOffset() {
+      return endOffset;
+    }
+
+    public int getOriginalFrequency() {
+      return originalFrequency;
+    }
+
+    /** The list of alternatives */
+    public List<String> getAlternatives() {
+      return alternatives;
+    }
+
+    /** The frequencies of the alternatives in the corpus, or null if this information was not returned */
+    public List<Integer> getAlternativeFrequencies() {
+      return alternativeFrequencies;
+    }
+
+  }
+
+  public class Collation {
+    private String collationQueryString;
+    private List<Correction> misspellingsAndCorrections = new ArrayList<>();
+    private long numberOfHits;
+
+    public long getNumberOfHits() {
+      return numberOfHits;
+    }
+
+    public void setNumberOfHits(long numberOfHits) {
+      this.numberOfHits = numberOfHits;
+    }
+
+    public String getCollationQueryString() {
+      return collationQueryString;
+    }
+
+    public Collation setCollationQueryString(String collationQueryString) {
+      this.collationQueryString = collationQueryString;
+      return this;
+    }
+
+    public List<Correction> getMisspellingsAndCorrections() {
+      return misspellingsAndCorrections;
+    }
+
+    public Collation addMisspellingsAndCorrection(Correction correction) {
+      this.misspellingsAndCorrections.add(correction);
+      return this;
+    }
+
+  }
+
+  public class Correction {
+    private String original;
+    private String correction;
+
+    public Correction(String original, String correction) {
+      this.original = original;
+      this.correction = correction;
+    }
+
+    public String getOriginal() {
+      return original;
+    }
+
+    public void setOriginal(String original) {
+      this.original = original;
+    }
+
+    public String getCorrection() {
+      return correction;
+    }
+
+    public void setCorrection(String correction) {
+      this.correction = correction;
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/40aa090d/ranger_solrj/src/main/java/org/apache/solr/client/solrj/response/TermsResponse.java
----------------------------------------------------------------------
diff --git a/ranger_solrj/src/main/java/org/apache/solr/client/solrj/response/TermsResponse.java b/ranger_solrj/src/main/java/org/apache/solr/client/solrj/response/TermsResponse.java
new file mode 100644
index 0000000..5d8c0b7
--- /dev/null
+++ b/ranger_solrj/src/main/java/org/apache/solr/client/solrj/response/TermsResponse.java
@@ -0,0 +1,89 @@
+package org.apache.solr.client.solrj.response;
+/*
+ * 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.
+ */
+
+import org.apache.solr.common.util.NamedList;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Encapsulates responses from TermsComponent
+ */
+public class TermsResponse {
+  private Map<String, List<Term>> termMap = new HashMap<>();
+  
+  public TermsResponse(NamedList<NamedList<Number>> termsInfo) {
+    for (int i = 0; i < termsInfo.size(); i++) {
+      String fieldName = termsInfo.getName(i);
+      List<Term> itemList = new ArrayList<>();
+      NamedList<Number> items = termsInfo.getVal(i);
+      
+      for (int j = 0; j < items.size(); j++) {
+        Term t = new Term(items.getName(j), items.getVal(j).longValue());
+        itemList.add(t);
+      }
+      
+      termMap.put(fieldName, itemList);
+    }
+  }
+
+  /**
+   * Get's the term list for a given field
+   * 
+   * @return the term list or null if no terms for the given field exist
+   */
+  public List<Term> getTerms(String field) {
+    return termMap.get(field);
+  }
+  
+  public Map<String, List<Term>> getTermMap() {
+    return termMap;
+  }
+
+  public static class Term {
+    private String term;
+    private long frequency;
+
+    public Term(String term, long frequency) {
+      this.term = term;
+      this.frequency = frequency;
+    }
+
+    public String getTerm() {
+      return term;
+    }
+
+    public void setTerm(String term) {
+      this.term = term;
+    }
+    
+    public long getFrequency() {
+      return frequency;
+    }
+    
+    public void setFrequency(long frequency) {
+      this.frequency = frequency;
+    }
+    
+    public void addFrequency(long frequency) {
+      this.frequency += frequency;
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/40aa090d/ranger_solrj/src/main/java/org/apache/solr/client/solrj/response/UpdateResponse.java
----------------------------------------------------------------------
diff --git a/ranger_solrj/src/main/java/org/apache/solr/client/solrj/response/UpdateResponse.java b/ranger_solrj/src/main/java/org/apache/solr/client/solrj/response/UpdateResponse.java
new file mode 100644
index 0000000..7a62bc0
--- /dev/null
+++ b/ranger_solrj/src/main/java/org/apache/solr/client/solrj/response/UpdateResponse.java
@@ -0,0 +1,30 @@
+/*
+ * 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.client.solrj.response;
+
+
+/**
+ * TODO -- mostly a stub until we have a defined output format
+ * 
+ *
+ * @since solr 1.3
+ */
+public class UpdateResponse extends SolrResponseBase
+{
+  // nothing special now...
+}

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/40aa090d/ranger_solrj/src/main/java/org/apache/solr/client/solrj/response/package-info.java
----------------------------------------------------------------------
diff --git a/ranger_solrj/src/main/java/org/apache/solr/client/solrj/response/package-info.java b/ranger_solrj/src/main/java/org/apache/solr/client/solrj/response/package-info.java
new file mode 100644
index 0000000..e2bbe3a
--- /dev/null
+++ b/ranger_solrj/src/main/java/org/apache/solr/client/solrj/response/package-info.java
@@ -0,0 +1,24 @@
+/*
+ * 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.
+ */
+ 
+/** 
+ * Convenience classes for dealing with various types of Solr responses.
+
+ */
+package org.apache.solr.client.solrj.response;
+
+