From 2579edf45ff315ca94f2ea7f8be073d3ce15fb80 Mon Sep 17 00:00:00 2001
From: Robert Muir <rmuir@apache.org>
Date: Sat, 2 Oct 2010 20:32:16 +0000
Subject: [PATCH] add missing eol-style

git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1003877 13f79535-47bb-0310-9956-ffa450edef68
---
 .../search/cache/TestEntryCreators.java       | 448 ++++++------
 .../component/PivotFacetComponent.java        | 556 +++++++--------
 .../apache/solr/search/MutableValueLong.java  | 112 +--
 .../function/JoinDocFreqValueSource.java      | 200 +++---
 .../solrj/StreamingResponseCallback.java      |  74 +-
 .../impl/StreamingBinaryResponseParser.java   | 178 ++---
 .../client/solrj/response/PivotField.java     | 148 ++--
 .../test/org/apache/solr/JSONTestUtil.java    | 660 +++++++++---------
 .../solr/response/TestCSVResponseWriter.java  | 328 ++++-----
 .../solr/search/TestSolrQueryParser.java      | 106 +--
 10 files changed, 1405 insertions(+), 1405 deletions(-)

diff --git a/lucene/src/test/org/apache/lucene/search/cache/TestEntryCreators.java b/lucene/src/test/org/apache/lucene/search/cache/TestEntryCreators.java
index 4267d969b09..7556065071b 100644
--- a/lucene/src/test/org/apache/lucene/search/cache/TestEntryCreators.java
+++ b/lucene/src/test/org/apache/lucene/search/cache/TestEntryCreators.java
@@ -1,224 +1,224 @@
-package org.apache.lucene.search.cache;
-
-/**
- * Copyright 2004 The Apache Software Foundation
- *
- * Licensed 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.IOException;
-import java.lang.reflect.Constructor;
-import java.lang.reflect.Method;
-import java.util.HashSet;
-import java.util.Set;
-
-import org.apache.lucene.document.Document;
-import org.apache.lucene.document.Field;
-import org.apache.lucene.index.IndexReader;
-import org.apache.lucene.index.RandomIndexWriter;
-import org.apache.lucene.search.FieldCache;
-import org.apache.lucene.search.FieldCache.*;
-import org.apache.lucene.store.Directory;
-import org.apache.lucene.util.LuceneTestCase;
-import org.apache.lucene.util.OpenBitSet;
-
-import static org.hamcrest.CoreMatchers.*;
-
-public class TestEntryCreators extends LuceneTestCase {
-  protected IndexReader reader;
-  private static final int NUM_DOCS = 500 * RANDOM_MULTIPLIER;
-  private Directory directory;
-
-  static class NumberTypeTester {
-    String funcName;
-    Class<? extends CachedArrayCreator> creator;
-    Class<? extends Parser> parser;
-    String field;
-    Number[] values;
-    
-    public NumberTypeTester( String f, String func, Class<? extends CachedArrayCreator> creator, Class<? extends Parser> parser ) {
-      field = f;
-      funcName = func;
-      this.creator = creator;
-      this.parser = parser;
-      values = new Number[NUM_DOCS];
-    }
-    public String toString()
-    {
-      return field;
-    }
-  }
-  private NumberTypeTester[] typeTests;
-  
-  
-  @Override
-  public void setUp() throws Exception {
-    super.setUp();
-    directory = newDirectory();
-    RandomIndexWriter writer= new RandomIndexWriter(random, directory);
-
-    typeTests = new NumberTypeTester[] {
-        new NumberTypeTester( "theRandomByte",   "getBytes",   ByteValuesCreator.class,   ByteParser.class ),
-        new NumberTypeTester( "theRandomShort",  "getShorts",  ShortValuesCreator.class,  ShortParser.class  ),
-        new NumberTypeTester( "theRandomInt",    "getInts",    IntValuesCreator.class,    IntParser.class  ),
-        new NumberTypeTester( "theRandomLong",   "getLongs",   LongValuesCreator.class,   LongParser.class  ),
-        new NumberTypeTester( "theRandomFloat",  "getFloats",  FloatValuesCreator.class,  FloatParser.class  ),
-        new NumberTypeTester( "theRandomDouble", "getDoubles", DoubleValuesCreator.class, DoubleParser.class  ),
-    };
-    
-    for (int i = 0; i < NUM_DOCS; i++){
-      Document doc = new Document();
-      
-      // Test the valid bits
-      for( NumberTypeTester tester : typeTests ) {
-        if (random.nextInt(20) != 17 && i > 1) {
-          tester.values[i] = 10 + random.nextInt( 20 ); // get some field overlap
-          doc.add(newField(tester.field, String.valueOf(tester.values[i]), 
-              Field.Store.NO, Field.Index.NOT_ANALYZED ));
-        }
-      }
-      writer.addDocument(doc);
-    }
-
-    reader = writer.getReader();
-    writer.close();
-  }
-
-  @Override
-  public void tearDown() throws Exception {
-    reader.close();
-    directory.close();
-    super.tearDown();
-  }
-
-  public void testKeys() throws IOException {
-    // Check that the keys are unique for different fields
-
-    EntryKey key_1 = new ByteValuesCreator( "field1", null ).getCacheKey();
-    EntryKey key_2 = new ByteValuesCreator( "field2", null ).getCacheKey();
-    assertThat("different fields should have a different key", key_1, not(key_2) );
-
-    key_1 = new ByteValuesCreator(  "field1", null ).getCacheKey();
-    key_2 = new ShortValuesCreator( "field1", null ).getCacheKey();
-    assertThat( "same field different type should have different key", key_1, not( key_2 ) );
-
-    key_1 = new ByteValuesCreator( "ff", null ).getCacheKey();
-    key_2 = new ByteValuesCreator( "ff", null ).getCacheKey();
-    assertThat( "same args should have same key", key_1, is( key_2 ) );
-
-    key_1 = new ByteValuesCreator( "ff", null, ByteValuesCreator.OPTION_CACHE_BITS ^ ByteValuesCreator.OPTION_CACHE_VALUES ).getCacheKey();
-    key_2 = new ByteValuesCreator( "ff", null ).getCacheKey();
-    assertThat( "different options should share same key", key_1, is( key_2 ) );
-
-    key_1 = new IntValuesCreator( "ff", FieldCache.DEFAULT_INT_PARSER ).getCacheKey();
-    key_2 = new IntValuesCreator( "ff", FieldCache.NUMERIC_UTILS_INT_PARSER ).getCacheKey();
-    assertThat( "diferent parser should have same key", key_1, is( key_2 ) );
-  }
-  
-  private CachedArray getWithReflection( FieldCache cache, NumberTypeTester tester, int flags ) throws IOException 
-  {
-    try {
-      Method getXXX = cache.getClass().getMethod( tester.funcName, IndexReader.class, String.class, EntryCreator.class );
-      Constructor constructor = tester.creator.getConstructor( String.class, tester.parser, Integer.TYPE );
-      CachedArrayCreator creator = (CachedArrayCreator)constructor.newInstance( tester.field, null, flags );
-      return (CachedArray) getXXX.invoke(cache, reader, tester.field, creator );
-    }
-    catch( Exception ex ) {
-      throw new RuntimeException( "Reflection failed", ex );
-    }
-  }
-
-  public void testCachedArrays() throws IOException 
-  {
-    FieldCache cache = FieldCache.DEFAULT;
-
-    // Check the Different CachedArray Types
-    CachedArray last = null;
-    CachedArray justbits = null;
-    String field;
-    
-    for( NumberTypeTester tester : typeTests ) {
-      justbits = getWithReflection( cache, tester, CachedArrayCreator.OPTION_CACHE_BITS );
-      assertNull( "should not get values : "+tester, justbits.getRawArray() );
-      assertNotNull( "should get bits : "+tester, justbits.valid );
-      last = getWithReflection( cache, tester, CachedArrayCreator.CACHE_VALUES_AND_BITS );
-      assertEquals( "should use same cached object : "+tester, justbits, last );
-      assertNull( "Validate=false shoudl not regenerate : "+tester, justbits.getRawArray() ); 
-      last = getWithReflection( cache, tester, CachedArrayCreator.CACHE_VALUES_AND_BITS_VALIDATE );
-      assertEquals( "should use same cached object : "+tester, justbits, last );
-      assertNotNull( "Validate=true should add the Array : "+tester, justbits.getRawArray() ); 
-      checkCachedArrayValuesAndBits( tester, last );
-    }
-    
-    // Now switch the the parser (for the same type) and expect an error
-    cache.purgeAllCaches();
-    int flags = CachedArrayCreator.CACHE_VALUES_AND_BITS_VALIDATE;
-    field = "theRandomInt";
-    last = cache.getInts(reader, field, new IntValuesCreator( field, FieldCache.DEFAULT_INT_PARSER, flags ) );
-    checkCachedArrayValuesAndBits( typeTests[2], last );
-    try {
-      cache.getInts(reader, field, new IntValuesCreator( field, FieldCache.NUMERIC_UTILS_INT_PARSER, flags ) );
-      fail( "Should fail if you ask for the same type with a different parser : " + field );
-    } catch( Exception ex ) {} // expected
-
-    field = "theRandomLong";
-    last = cache.getLongs(reader,   field, new LongValuesCreator( field, FieldCache.DEFAULT_LONG_PARSER, flags ) );
-    checkCachedArrayValuesAndBits( typeTests[3], last );
-    try {
-      cache.getLongs(reader, field, new LongValuesCreator( field, FieldCache.NUMERIC_UTILS_LONG_PARSER, flags ) );
-      fail( "Should fail if you ask for the same type with a different parser : " + field );
-    } catch( Exception ex ) {} // expected
-
-    field = "theRandomFloat";
-    last = cache.getFloats(reader,   field, new FloatValuesCreator( field, FieldCache.DEFAULT_FLOAT_PARSER, flags ) );
-    checkCachedArrayValuesAndBits( typeTests[4], last );
-    try {
-      cache.getFloats(reader, field, new FloatValuesCreator( field, FieldCache.NUMERIC_UTILS_FLOAT_PARSER, flags ) );
-      fail( "Should fail if you ask for the same type with a different parser : " + field );
-    } catch( Exception ex ) {} // expected
-
-    field = "theRandomDouble";
-    last = cache.getDoubles(reader,   field, new DoubleValuesCreator( field, FieldCache.DEFAULT_DOUBLE_PARSER, flags ) );
-    checkCachedArrayValuesAndBits( typeTests[5], last );
-    try {
-      cache.getDoubles(reader, field, new DoubleValuesCreator( field, FieldCache.NUMERIC_UTILS_DOUBLE_PARSER, flags ) );
-      fail( "Should fail if you ask for the same type with a different parser : " + field );
-    } catch( Exception ex ) {} // expected
-  }
-
-  private void checkCachedArrayValuesAndBits( NumberTypeTester tester, CachedArray cachedVals )
-  {
-//    for( int i=0; i<NUM_DOCS; i++ ) {
-//      System.out.println( i + "] "+ tester.values[i] + " :: " + cachedVals.valid.get(i) );
-//    }
-    
-    int numDocs =0;
-    Set<Number> distinctTerms = new HashSet<Number>();
-    for( int i=0; i<NUM_DOCS; i++ ) {
-      Number v = tester.values[i];
-      boolean isValid = cachedVals.valid.get(i);
-      if( v != null ) {
-        numDocs++;
-        distinctTerms.add( v );
-        assertTrue( "Valid bit should be true ("+i+"="+tester.values[i]+") "+tester, isValid );        
-      }
-      else {
-        assertFalse( "Valid bit should be false ("+i+") "+tester, isValid );        
-      }
-    }
-    assertEquals( "Cached numTerms does not match : "+tester, distinctTerms.size(), cachedVals.numTerms );
-    assertEquals( "Cached numDocs does not match : "+tester, numDocs, cachedVals.numDocs );
-    assertEquals( "Ordinal should match numDocs : "+tester, numDocs, ((OpenBitSet)cachedVals.valid).cardinality() );
-  }
-
-}
+package org.apache.lucene.search.cache;
+
+/**
+ * Copyright 2004 The Apache Software Foundation
+ *
+ * Licensed 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.IOException;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Method;
+import java.util.HashSet;
+import java.util.Set;
+
+import org.apache.lucene.document.Document;
+import org.apache.lucene.document.Field;
+import org.apache.lucene.index.IndexReader;
+import org.apache.lucene.index.RandomIndexWriter;
+import org.apache.lucene.search.FieldCache;
+import org.apache.lucene.search.FieldCache.*;
+import org.apache.lucene.store.Directory;
+import org.apache.lucene.util.LuceneTestCase;
+import org.apache.lucene.util.OpenBitSet;
+
+import static org.hamcrest.CoreMatchers.*;
+
+public class TestEntryCreators extends LuceneTestCase {
+  protected IndexReader reader;
+  private static final int NUM_DOCS = 500 * RANDOM_MULTIPLIER;
+  private Directory directory;
+
+  static class NumberTypeTester {
+    String funcName;
+    Class<? extends CachedArrayCreator> creator;
+    Class<? extends Parser> parser;
+    String field;
+    Number[] values;
+    
+    public NumberTypeTester( String f, String func, Class<? extends CachedArrayCreator> creator, Class<? extends Parser> parser ) {
+      field = f;
+      funcName = func;
+      this.creator = creator;
+      this.parser = parser;
+      values = new Number[NUM_DOCS];
+    }
+    public String toString()
+    {
+      return field;
+    }
+  }
+  private NumberTypeTester[] typeTests;
+  
+  
+  @Override
+  public void setUp() throws Exception {
+    super.setUp();
+    directory = newDirectory();
+    RandomIndexWriter writer= new RandomIndexWriter(random, directory);
+
+    typeTests = new NumberTypeTester[] {
+        new NumberTypeTester( "theRandomByte",   "getBytes",   ByteValuesCreator.class,   ByteParser.class ),
+        new NumberTypeTester( "theRandomShort",  "getShorts",  ShortValuesCreator.class,  ShortParser.class  ),
+        new NumberTypeTester( "theRandomInt",    "getInts",    IntValuesCreator.class,    IntParser.class  ),
+        new NumberTypeTester( "theRandomLong",   "getLongs",   LongValuesCreator.class,   LongParser.class  ),
+        new NumberTypeTester( "theRandomFloat",  "getFloats",  FloatValuesCreator.class,  FloatParser.class  ),
+        new NumberTypeTester( "theRandomDouble", "getDoubles", DoubleValuesCreator.class, DoubleParser.class  ),
+    };
+    
+    for (int i = 0; i < NUM_DOCS; i++){
+      Document doc = new Document();
+      
+      // Test the valid bits
+      for( NumberTypeTester tester : typeTests ) {
+        if (random.nextInt(20) != 17 && i > 1) {
+          tester.values[i] = 10 + random.nextInt( 20 ); // get some field overlap
+          doc.add(newField(tester.field, String.valueOf(tester.values[i]), 
+              Field.Store.NO, Field.Index.NOT_ANALYZED ));
+        }
+      }
+      writer.addDocument(doc);
+    }
+
+    reader = writer.getReader();
+    writer.close();
+  }
+
+  @Override
+  public void tearDown() throws Exception {
+    reader.close();
+    directory.close();
+    super.tearDown();
+  }
+
+  public void testKeys() throws IOException {
+    // Check that the keys are unique for different fields
+
+    EntryKey key_1 = new ByteValuesCreator( "field1", null ).getCacheKey();
+    EntryKey key_2 = new ByteValuesCreator( "field2", null ).getCacheKey();
+    assertThat("different fields should have a different key", key_1, not(key_2) );
+
+    key_1 = new ByteValuesCreator(  "field1", null ).getCacheKey();
+    key_2 = new ShortValuesCreator( "field1", null ).getCacheKey();
+    assertThat( "same field different type should have different key", key_1, not( key_2 ) );
+
+    key_1 = new ByteValuesCreator( "ff", null ).getCacheKey();
+    key_2 = new ByteValuesCreator( "ff", null ).getCacheKey();
+    assertThat( "same args should have same key", key_1, is( key_2 ) );
+
+    key_1 = new ByteValuesCreator( "ff", null, ByteValuesCreator.OPTION_CACHE_BITS ^ ByteValuesCreator.OPTION_CACHE_VALUES ).getCacheKey();
+    key_2 = new ByteValuesCreator( "ff", null ).getCacheKey();
+    assertThat( "different options should share same key", key_1, is( key_2 ) );
+
+    key_1 = new IntValuesCreator( "ff", FieldCache.DEFAULT_INT_PARSER ).getCacheKey();
+    key_2 = new IntValuesCreator( "ff", FieldCache.NUMERIC_UTILS_INT_PARSER ).getCacheKey();
+    assertThat( "diferent parser should have same key", key_1, is( key_2 ) );
+  }
+  
+  private CachedArray getWithReflection( FieldCache cache, NumberTypeTester tester, int flags ) throws IOException 
+  {
+    try {
+      Method getXXX = cache.getClass().getMethod( tester.funcName, IndexReader.class, String.class, EntryCreator.class );
+      Constructor constructor = tester.creator.getConstructor( String.class, tester.parser, Integer.TYPE );
+      CachedArrayCreator creator = (CachedArrayCreator)constructor.newInstance( tester.field, null, flags );
+      return (CachedArray) getXXX.invoke(cache, reader, tester.field, creator );
+    }
+    catch( Exception ex ) {
+      throw new RuntimeException( "Reflection failed", ex );
+    }
+  }
+
+  public void testCachedArrays() throws IOException 
+  {
+    FieldCache cache = FieldCache.DEFAULT;
+
+    // Check the Different CachedArray Types
+    CachedArray last = null;
+    CachedArray justbits = null;
+    String field;
+    
+    for( NumberTypeTester tester : typeTests ) {
+      justbits = getWithReflection( cache, tester, CachedArrayCreator.OPTION_CACHE_BITS );
+      assertNull( "should not get values : "+tester, justbits.getRawArray() );
+      assertNotNull( "should get bits : "+tester, justbits.valid );
+      last = getWithReflection( cache, tester, CachedArrayCreator.CACHE_VALUES_AND_BITS );
+      assertEquals( "should use same cached object : "+tester, justbits, last );
+      assertNull( "Validate=false shoudl not regenerate : "+tester, justbits.getRawArray() ); 
+      last = getWithReflection( cache, tester, CachedArrayCreator.CACHE_VALUES_AND_BITS_VALIDATE );
+      assertEquals( "should use same cached object : "+tester, justbits, last );
+      assertNotNull( "Validate=true should add the Array : "+tester, justbits.getRawArray() ); 
+      checkCachedArrayValuesAndBits( tester, last );
+    }
+    
+    // Now switch the the parser (for the same type) and expect an error
+    cache.purgeAllCaches();
+    int flags = CachedArrayCreator.CACHE_VALUES_AND_BITS_VALIDATE;
+    field = "theRandomInt";
+    last = cache.getInts(reader, field, new IntValuesCreator( field, FieldCache.DEFAULT_INT_PARSER, flags ) );
+    checkCachedArrayValuesAndBits( typeTests[2], last );
+    try {
+      cache.getInts(reader, field, new IntValuesCreator( field, FieldCache.NUMERIC_UTILS_INT_PARSER, flags ) );
+      fail( "Should fail if you ask for the same type with a different parser : " + field );
+    } catch( Exception ex ) {} // expected
+
+    field = "theRandomLong";
+    last = cache.getLongs(reader,   field, new LongValuesCreator( field, FieldCache.DEFAULT_LONG_PARSER, flags ) );
+    checkCachedArrayValuesAndBits( typeTests[3], last );
+    try {
+      cache.getLongs(reader, field, new LongValuesCreator( field, FieldCache.NUMERIC_UTILS_LONG_PARSER, flags ) );
+      fail( "Should fail if you ask for the same type with a different parser : " + field );
+    } catch( Exception ex ) {} // expected
+
+    field = "theRandomFloat";
+    last = cache.getFloats(reader,   field, new FloatValuesCreator( field, FieldCache.DEFAULT_FLOAT_PARSER, flags ) );
+    checkCachedArrayValuesAndBits( typeTests[4], last );
+    try {
+      cache.getFloats(reader, field, new FloatValuesCreator( field, FieldCache.NUMERIC_UTILS_FLOAT_PARSER, flags ) );
+      fail( "Should fail if you ask for the same type with a different parser : " + field );
+    } catch( Exception ex ) {} // expected
+
+    field = "theRandomDouble";
+    last = cache.getDoubles(reader,   field, new DoubleValuesCreator( field, FieldCache.DEFAULT_DOUBLE_PARSER, flags ) );
+    checkCachedArrayValuesAndBits( typeTests[5], last );
+    try {
+      cache.getDoubles(reader, field, new DoubleValuesCreator( field, FieldCache.NUMERIC_UTILS_DOUBLE_PARSER, flags ) );
+      fail( "Should fail if you ask for the same type with a different parser : " + field );
+    } catch( Exception ex ) {} // expected
+  }
+
+  private void checkCachedArrayValuesAndBits( NumberTypeTester tester, CachedArray cachedVals )
+  {
+//    for( int i=0; i<NUM_DOCS; i++ ) {
+//      System.out.println( i + "] "+ tester.values[i] + " :: " + cachedVals.valid.get(i) );
+//    }
+    
+    int numDocs =0;
+    Set<Number> distinctTerms = new HashSet<Number>();
+    for( int i=0; i<NUM_DOCS; i++ ) {
+      Number v = tester.values[i];
+      boolean isValid = cachedVals.valid.get(i);
+      if( v != null ) {
+        numDocs++;
+        distinctTerms.add( v );
+        assertTrue( "Valid bit should be true ("+i+"="+tester.values[i]+") "+tester, isValid );        
+      }
+      else {
+        assertFalse( "Valid bit should be false ("+i+") "+tester, isValid );        
+      }
+    }
+    assertEquals( "Cached numTerms does not match : "+tester, distinctTerms.size(), cachedVals.numTerms );
+    assertEquals( "Cached numDocs does not match : "+tester, numDocs, cachedVals.numDocs );
+    assertEquals( "Ordinal should match numDocs : "+tester, numDocs, ((OpenBitSet)cachedVals.valid).cardinality() );
+  }
+
+}
diff --git a/solr/src/java/org/apache/solr/handler/component/PivotFacetComponent.java b/solr/src/java/org/apache/solr/handler/component/PivotFacetComponent.java
index 9f8a714678b..404dcab9b5a 100644
--- a/solr/src/java/org/apache/solr/handler/component/PivotFacetComponent.java
+++ b/solr/src/java/org/apache/solr/handler/component/PivotFacetComponent.java
@@ -1,278 +1,278 @@
-/**
- * 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.search.SolrIndexSearcher;
-import org.apache.solr.search.DocSet;
-import org.apache.solr.common.SolrException;
-import org.apache.solr.common.util.NamedList;
-import org.apache.solr.common.util.SimpleOrderedMap;
-import org.apache.solr.common.SolrException.ErrorCode;
-import org.apache.solr.common.params.SolrParams;
-import org.apache.solr.common.params.FacetParams;
-import org.apache.solr.request.SimpleFacets;
-import org.apache.solr.request.SolrQueryRequest;
-import org.apache.solr.schema.FieldType;
-import org.apache.lucene.search.Query;
-import org.apache.lucene.search.TermQuery;
-import org.apache.lucene.index.Term;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Deque;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-
-/**
- * 
- * @since solr 4.0
- */
-public class PivotFacetComponent extends SearchComponent 
-{
-  public static final String COMPONENT_NAME = "pivot";
-
-  static final String PIVOT_KEY = "facet_pivot";
-
-  
-  /**
-   * Designed to be overridden by subclasses that provide different faceting implementations.
-   * TODO: Currently this is returning a SimpleFacets object, but those capabilities would
-   *       be better as an extracted abstract class or interface.
-   */
-  protected SimpleFacets getFacetImplementation(SolrQueryRequest req,
-                                                DocSet docs,
-                                                SolrParams params) {
-    return new SimpleFacets(req, docs, params);
-  }
-
-  @Override
-  public void prepare(ResponseBuilder rb) throws IOException
-  {
-    if (rb.req.getParams().getBool(FacetParams.FACET,false)) {
-      rb.setNeedDocSet( true );
-      rb.doFacets = true;
-    }
-  }
-
-  public void process(ResponseBuilder rb) throws IOException {
-    if (!rb.doFacets) return;
-
-    SolrParams params = rb.req.getParams();
-    String[] pivots = params.getParams(FacetParams.FACET_PIVOT);  // example: author,type  (for types by author / types within author)
-    if (pivots == null) return;
-    
-    int minMatch = params.getInt( FacetParams.FACET_PIVOT_MINCOUNT, 1 );
-    
-    SimpleOrderedMap<List<NamedList<Object>>> pivotResponse = new SimpleOrderedMap<List<NamedList<Object>>>();
-    for (String pivot : pivots) {
-      String[] fields = pivot.split(",");  // only support two levels for now
-      
-      if( fields.length < 2 ) {
-        throw new SolrException( ErrorCode.BAD_REQUEST, 
-            "Pivot Facet needs at least two fields: "+pivot );
-      }
-      
-      DocSet docs = rb.getResults().docSet;
-      String field = fields[0];
-      String subField = fields[1];
-      Deque<String> fnames = new LinkedList<String>();
-      for( int i=fields.length-1; i>1; i-- ) {
-        fnames.push( fields[i] );
-      }
-      
-      SimpleFacets sf = getFacetImplementation(rb.req, rb.getResults().docSet, rb.req.getParams());
-      NamedList<Integer> superFacets = sf.getTermCounts(field);
-      
-      pivotResponse.add(pivot, doPivots(superFacets, field, subField, fnames, rb, docs, minMatch));
-    }
-    NamedList facetCounts = (NamedList) rb.rsp.getValues().get("facet_counts");
-    if (facetCounts == null) {
-      facetCounts = new NamedList();
-      rb.rsp.add("facet_counts", facetCounts);
-    }
-    facetCounts.add( PIVOT_KEY, pivotResponse);
-  }
-  
-  /**
-   * Recursive function to do all the pivots
-   */
-  protected List<NamedList<Object>> doPivots( NamedList<Integer> superFacets, String field, String subField, Deque<String> fnames, ResponseBuilder rb, DocSet docs, int minMatch ) throws IOException
-  {
-    SolrIndexSearcher searcher = rb.req.getSearcher();
-    // TODO: optimize to avoid converting to an external string and then having to convert back to internal below
-    FieldType ftype = null;
-
- //   SimpleFacets sf = getFacetImplementation(rb.req, docs, rb.req.getParams());
-    String nextField = fnames.poll();
-
-    List<NamedList<Object>> values = new ArrayList<NamedList<Object>>( superFacets.size() );
-    for (Map.Entry<String, Integer> kv : superFacets) {
-      // Only sub-facet if parent facet has positive count - still may not be any values for the sub-field though
-      if (kv.getValue() > minMatch ) {  
-        SimpleOrderedMap<Object> pivot = new SimpleOrderedMap<Object>();
-        pivot.add( "field", field );
-        pivot.add( "value", kv.getKey() );
-        pivot.add( "count", kv.getValue() );
-        
-        if( subField == null ) {
-          values.add( pivot );
-        }
-        else {
-          String s = kv.getKey();
-          if( ftype == null ) {
-            ftype = searcher.getSchema().getField(field).getType();
-          }
-          
-          Query query = new TermQuery(new Term(field, ftype.toInternal(s)));
-          DocSet subset = searcher.getDocSet(query, docs);
-          SimpleFacets sf = getFacetImplementation(rb.req, subset, rb.req.getParams());
-          
-          NamedList<Integer> nl = sf.getTermCounts(subField);
-          if (nl.size() > minMatch ) {
-            pivot.add( "pivot", doPivots( nl, subField, nextField, fnames, rb, subset, minMatch ) );
-            values.add( pivot ); // only add response if there are some counts
-          }
-        }
-      }
-    }
-    
-    // put the field back on the list
-    fnames.push( nextField );
-    return values;
-  }
-
-  @Override
-  public int distributedProcess(ResponseBuilder rb) throws IOException {
-    if (!rb.doFacets) {
-      return ResponseBuilder.STAGE_DONE;
-    }
-
-    if (rb.stage == ResponseBuilder.STAGE_GET_FIELDS) {
-      SolrParams params = rb.req.getParams();
-      String[] pivots = params.getParams(FacetParams.FACET_PIVOT);
-      for ( ShardRequest sreq : rb.outgoing ) {
-        if (( sreq.purpose & ShardRequest.PURPOSE_GET_FIELDS ) != 0
-            && sreq.shards != null && sreq.shards.length == 1 ) {
-          sreq.params.set( FacetParams.FACET, "true" );
-          sreq.params.set( FacetParams.FACET_PIVOT, pivots );
-          sreq.params.set( FacetParams.FACET_PIVOT_MINCOUNT, 1 ); // keep this at 1 regardless so that it accumulates everything
-            }
-      }
-    }
-    return ResponseBuilder.STAGE_DONE;
-  }
-
-  @Override
-  public void handleResponses(ResponseBuilder rb, ShardRequest sreq) {
-    if (!rb.doFacets) return;
-
-
-    if ((sreq.purpose & ShardRequest.PURPOSE_GET_FACETS)!=0) {
-      SimpleOrderedMap<List<NamedList<Object>>> tf = rb._pivots;
-      if ( null == tf ) {
-        tf = new SimpleOrderedMap<List<NamedList<Object>>>();
-        rb._pivots = tf;
-      }
-      for (ShardResponse srsp: sreq.responses) {
-        int shardNum = rb.getShardNum(srsp.getShard());
-
-        NamedList facet_counts = (NamedList)srsp.getSolrResponse().getResponse().get("facet_counts");
-
-        // handle facet trees from shards
-        SimpleOrderedMap<List<NamedList<Object>>> shard_pivots = 
-          (SimpleOrderedMap<List<NamedList<Object>>>)facet_counts.get( PIVOT_KEY );
-        
-        if ( shard_pivots != null ) {
-          for (int j=0; j< shard_pivots.size(); j++) {
-            // TODO -- accumulate the results from each shard
-            // The following code worked to accumulate facets for an previous 
-            // two level patch... it is here for reference till someone can upgrade
-            /**
-            String shard_tree_name = (String) shard_pivots.getName( j );
-            SimpleOrderedMap<NamedList> shard_tree = (SimpleOrderedMap<NamedList>)shard_pivots.getVal( j );
-            SimpleOrderedMap<NamedList> facet_tree = tf.get( shard_tree_name );
-            if ( null == facet_tree) { 
-              facet_tree = new SimpleOrderedMap<NamedList>(); 
-              tf.add( shard_tree_name, facet_tree );
-            }
-
-            for( int o = 0; o < shard_tree.size() ; o++ ) {
-              String shard_outer = (String) shard_tree.getName( o );
-              NamedList shard_innerList = (NamedList) shard_tree.getVal( o );
-              NamedList tree_innerList  = (NamedList) facet_tree.get( shard_outer );
-              if ( null == tree_innerList ) { 
-                tree_innerList = new NamedList();
-                facet_tree.add( shard_outer, tree_innerList );
-              }
-
-              for ( int i = 0 ; i < shard_innerList.size() ; i++ ) {
-                String shard_term = (String) shard_innerList.getName( i );
-                long shard_count  = ((Number) shard_innerList.getVal(i)).longValue();
-                int tree_idx      = tree_innerList.indexOf( shard_term, 0 );
-
-                if ( -1 == tree_idx ) {
-                  tree_innerList.add( shard_term, shard_count );
-                } else {
-                  long tree_count = ((Number) tree_innerList.getVal( tree_idx )).longValue();
-                  tree_innerList.setVal( tree_idx, shard_count + tree_count );
-                }
-              } // innerList loop
-            } // outer loop
-              **/
-          } // each tree loop
-        }
-      }
-    } 
-    return ;
-  }
-
-  @Override
-  public void finishStage(ResponseBuilder rb) {
-    if (!rb.doFacets || rb.stage != ResponseBuilder.STAGE_GET_FIELDS) return;
-    // wait until STAGE_GET_FIELDS
-    // so that "result" is already stored in the response (for aesthetics)
-
-    SimpleOrderedMap<List<NamedList<Object>>> tf = rb._pivots;
-
-    // get 'facet_counts' from the response
-    NamedList facetCounts = (NamedList) rb.rsp.getValues().get("facet_counts");
-    if (facetCounts == null) {
-      facetCounts = new NamedList();
-      rb.rsp.add("facet_counts", facetCounts);
-    }
-    facetCounts.add( PIVOT_KEY, tf );
-    rb._pivots = null;
-  }
-
-  public String getDescription() {
-    return "Handle Pivot (multi-level) Faceting";
-  }
-
-  public String getSourceId() {
-    return "$Id:  $";
-  }
-
-  public String getSource() {
-    return "$URL: $";
-  }
-
-  public String getVersion() {
-    return "$Revision:  $";
-  }
-}
+/**
+ * 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.search.SolrIndexSearcher;
+import org.apache.solr.search.DocSet;
+import org.apache.solr.common.SolrException;
+import org.apache.solr.common.util.NamedList;
+import org.apache.solr.common.util.SimpleOrderedMap;
+import org.apache.solr.common.SolrException.ErrorCode;
+import org.apache.solr.common.params.SolrParams;
+import org.apache.solr.common.params.FacetParams;
+import org.apache.solr.request.SimpleFacets;
+import org.apache.solr.request.SolrQueryRequest;
+import org.apache.solr.schema.FieldType;
+import org.apache.lucene.search.Query;
+import org.apache.lucene.search.TermQuery;
+import org.apache.lucene.index.Term;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Deque;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 
+ * @since solr 4.0
+ */
+public class PivotFacetComponent extends SearchComponent 
+{
+  public static final String COMPONENT_NAME = "pivot";
+
+  static final String PIVOT_KEY = "facet_pivot";
+
+  
+  /**
+   * Designed to be overridden by subclasses that provide different faceting implementations.
+   * TODO: Currently this is returning a SimpleFacets object, but those capabilities would
+   *       be better as an extracted abstract class or interface.
+   */
+  protected SimpleFacets getFacetImplementation(SolrQueryRequest req,
+                                                DocSet docs,
+                                                SolrParams params) {
+    return new SimpleFacets(req, docs, params);
+  }
+
+  @Override
+  public void prepare(ResponseBuilder rb) throws IOException
+  {
+    if (rb.req.getParams().getBool(FacetParams.FACET,false)) {
+      rb.setNeedDocSet( true );
+      rb.doFacets = true;
+    }
+  }
+
+  public void process(ResponseBuilder rb) throws IOException {
+    if (!rb.doFacets) return;
+
+    SolrParams params = rb.req.getParams();
+    String[] pivots = params.getParams(FacetParams.FACET_PIVOT);  // example: author,type  (for types by author / types within author)
+    if (pivots == null) return;
+    
+    int minMatch = params.getInt( FacetParams.FACET_PIVOT_MINCOUNT, 1 );
+    
+    SimpleOrderedMap<List<NamedList<Object>>> pivotResponse = new SimpleOrderedMap<List<NamedList<Object>>>();
+    for (String pivot : pivots) {
+      String[] fields = pivot.split(",");  // only support two levels for now
+      
+      if( fields.length < 2 ) {
+        throw new SolrException( ErrorCode.BAD_REQUEST, 
+            "Pivot Facet needs at least two fields: "+pivot );
+      }
+      
+      DocSet docs = rb.getResults().docSet;
+      String field = fields[0];
+      String subField = fields[1];
+      Deque<String> fnames = new LinkedList<String>();
+      for( int i=fields.length-1; i>1; i-- ) {
+        fnames.push( fields[i] );
+      }
+      
+      SimpleFacets sf = getFacetImplementation(rb.req, rb.getResults().docSet, rb.req.getParams());
+      NamedList<Integer> superFacets = sf.getTermCounts(field);
+      
+      pivotResponse.add(pivot, doPivots(superFacets, field, subField, fnames, rb, docs, minMatch));
+    }
+    NamedList facetCounts = (NamedList) rb.rsp.getValues().get("facet_counts");
+    if (facetCounts == null) {
+      facetCounts = new NamedList();
+      rb.rsp.add("facet_counts", facetCounts);
+    }
+    facetCounts.add( PIVOT_KEY, pivotResponse);
+  }
+  
+  /**
+   * Recursive function to do all the pivots
+   */
+  protected List<NamedList<Object>> doPivots( NamedList<Integer> superFacets, String field, String subField, Deque<String> fnames, ResponseBuilder rb, DocSet docs, int minMatch ) throws IOException
+  {
+    SolrIndexSearcher searcher = rb.req.getSearcher();
+    // TODO: optimize to avoid converting to an external string and then having to convert back to internal below
+    FieldType ftype = null;
+
+ //   SimpleFacets sf = getFacetImplementation(rb.req, docs, rb.req.getParams());
+    String nextField = fnames.poll();
+
+    List<NamedList<Object>> values = new ArrayList<NamedList<Object>>( superFacets.size() );
+    for (Map.Entry<String, Integer> kv : superFacets) {
+      // Only sub-facet if parent facet has positive count - still may not be any values for the sub-field though
+      if (kv.getValue() > minMatch ) {  
+        SimpleOrderedMap<Object> pivot = new SimpleOrderedMap<Object>();
+        pivot.add( "field", field );
+        pivot.add( "value", kv.getKey() );
+        pivot.add( "count", kv.getValue() );
+        
+        if( subField == null ) {
+          values.add( pivot );
+        }
+        else {
+          String s = kv.getKey();
+          if( ftype == null ) {
+            ftype = searcher.getSchema().getField(field).getType();
+          }
+          
+          Query query = new TermQuery(new Term(field, ftype.toInternal(s)));
+          DocSet subset = searcher.getDocSet(query, docs);
+          SimpleFacets sf = getFacetImplementation(rb.req, subset, rb.req.getParams());
+          
+          NamedList<Integer> nl = sf.getTermCounts(subField);
+          if (nl.size() > minMatch ) {
+            pivot.add( "pivot", doPivots( nl, subField, nextField, fnames, rb, subset, minMatch ) );
+            values.add( pivot ); // only add response if there are some counts
+          }
+        }
+      }
+    }
+    
+    // put the field back on the list
+    fnames.push( nextField );
+    return values;
+  }
+
+  @Override
+  public int distributedProcess(ResponseBuilder rb) throws IOException {
+    if (!rb.doFacets) {
+      return ResponseBuilder.STAGE_DONE;
+    }
+
+    if (rb.stage == ResponseBuilder.STAGE_GET_FIELDS) {
+      SolrParams params = rb.req.getParams();
+      String[] pivots = params.getParams(FacetParams.FACET_PIVOT);
+      for ( ShardRequest sreq : rb.outgoing ) {
+        if (( sreq.purpose & ShardRequest.PURPOSE_GET_FIELDS ) != 0
+            && sreq.shards != null && sreq.shards.length == 1 ) {
+          sreq.params.set( FacetParams.FACET, "true" );
+          sreq.params.set( FacetParams.FACET_PIVOT, pivots );
+          sreq.params.set( FacetParams.FACET_PIVOT_MINCOUNT, 1 ); // keep this at 1 regardless so that it accumulates everything
+            }
+      }
+    }
+    return ResponseBuilder.STAGE_DONE;
+  }
+
+  @Override
+  public void handleResponses(ResponseBuilder rb, ShardRequest sreq) {
+    if (!rb.doFacets) return;
+
+
+    if ((sreq.purpose & ShardRequest.PURPOSE_GET_FACETS)!=0) {
+      SimpleOrderedMap<List<NamedList<Object>>> tf = rb._pivots;
+      if ( null == tf ) {
+        tf = new SimpleOrderedMap<List<NamedList<Object>>>();
+        rb._pivots = tf;
+      }
+      for (ShardResponse srsp: sreq.responses) {
+        int shardNum = rb.getShardNum(srsp.getShard());
+
+        NamedList facet_counts = (NamedList)srsp.getSolrResponse().getResponse().get("facet_counts");
+
+        // handle facet trees from shards
+        SimpleOrderedMap<List<NamedList<Object>>> shard_pivots = 
+          (SimpleOrderedMap<List<NamedList<Object>>>)facet_counts.get( PIVOT_KEY );
+        
+        if ( shard_pivots != null ) {
+          for (int j=0; j< shard_pivots.size(); j++) {
+            // TODO -- accumulate the results from each shard
+            // The following code worked to accumulate facets for an previous 
+            // two level patch... it is here for reference till someone can upgrade
+            /**
+            String shard_tree_name = (String) shard_pivots.getName( j );
+            SimpleOrderedMap<NamedList> shard_tree = (SimpleOrderedMap<NamedList>)shard_pivots.getVal( j );
+            SimpleOrderedMap<NamedList> facet_tree = tf.get( shard_tree_name );
+            if ( null == facet_tree) { 
+              facet_tree = new SimpleOrderedMap<NamedList>(); 
+              tf.add( shard_tree_name, facet_tree );
+            }
+
+            for( int o = 0; o < shard_tree.size() ; o++ ) {
+              String shard_outer = (String) shard_tree.getName( o );
+              NamedList shard_innerList = (NamedList) shard_tree.getVal( o );
+              NamedList tree_innerList  = (NamedList) facet_tree.get( shard_outer );
+              if ( null == tree_innerList ) { 
+                tree_innerList = new NamedList();
+                facet_tree.add( shard_outer, tree_innerList );
+              }
+
+              for ( int i = 0 ; i < shard_innerList.size() ; i++ ) {
+                String shard_term = (String) shard_innerList.getName( i );
+                long shard_count  = ((Number) shard_innerList.getVal(i)).longValue();
+                int tree_idx      = tree_innerList.indexOf( shard_term, 0 );
+
+                if ( -1 == tree_idx ) {
+                  tree_innerList.add( shard_term, shard_count );
+                } else {
+                  long tree_count = ((Number) tree_innerList.getVal( tree_idx )).longValue();
+                  tree_innerList.setVal( tree_idx, shard_count + tree_count );
+                }
+              } // innerList loop
+            } // outer loop
+              **/
+          } // each tree loop
+        }
+      }
+    } 
+    return ;
+  }
+
+  @Override
+  public void finishStage(ResponseBuilder rb) {
+    if (!rb.doFacets || rb.stage != ResponseBuilder.STAGE_GET_FIELDS) return;
+    // wait until STAGE_GET_FIELDS
+    // so that "result" is already stored in the response (for aesthetics)
+
+    SimpleOrderedMap<List<NamedList<Object>>> tf = rb._pivots;
+
+    // get 'facet_counts' from the response
+    NamedList facetCounts = (NamedList) rb.rsp.getValues().get("facet_counts");
+    if (facetCounts == null) {
+      facetCounts = new NamedList();
+      rb.rsp.add("facet_counts", facetCounts);
+    }
+    facetCounts.add( PIVOT_KEY, tf );
+    rb._pivots = null;
+  }
+
+  public String getDescription() {
+    return "Handle Pivot (multi-level) Faceting";
+  }
+
+  public String getSourceId() {
+    return "$Id:  $";
+  }
+
+  public String getSource() {
+    return "$URL: $";
+  }
+
+  public String getVersion() {
+    return "$Revision:  $";
+  }
+}
diff --git a/solr/src/java/org/apache/solr/search/MutableValueLong.java b/solr/src/java/org/apache/solr/search/MutableValueLong.java
index 0688b41e537..8c38b06511b 100644
--- a/solr/src/java/org/apache/solr/search/MutableValueLong.java
+++ b/solr/src/java/org/apache/solr/search/MutableValueLong.java
@@ -1,57 +1,57 @@
-/**
- * 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;
-
-public class MutableValueLong extends MutableValue {
-  public long value;
-
-  @Override
-  public Object toObject() {
-    return value;
-  }
-
-  @Override
-  public void copy(MutableValue source) {
-    value = ((MutableValueLong)source).value;
-  }
-
-  @Override
-  public MutableValue duplicate() {
-    MutableValueLong v = new MutableValueLong();
-    v.value = this.value;
-    return v;
-  }
-
-  @Override
-  public boolean equalsSameType(Object other) {
-    return value == ((MutableValueLong)other).value;
-  }
-
-  @Override
-  public int compareSameType(Object other) {
-    long b = ((MutableValueLong)other).value;
-    if (value<b) return -1;
-    else if (value>b) return 1;
-    else return 0;
-  }
-
-
-  @Override
-  public int hashCode() {
-    return (int)value + (int)(value>>32);
-  }
+/**
+ * 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;
+
+public class MutableValueLong extends MutableValue {
+  public long value;
+
+  @Override
+  public Object toObject() {
+    return value;
+  }
+
+  @Override
+  public void copy(MutableValue source) {
+    value = ((MutableValueLong)source).value;
+  }
+
+  @Override
+  public MutableValue duplicate() {
+    MutableValueLong v = new MutableValueLong();
+    v.value = this.value;
+    return v;
+  }
+
+  @Override
+  public boolean equalsSameType(Object other) {
+    return value == ((MutableValueLong)other).value;
+  }
+
+  @Override
+  public int compareSameType(Object other) {
+    long b = ((MutableValueLong)other).value;
+    if (value<b) return -1;
+    else if (value>b) return 1;
+    else return 0;
+  }
+
+
+  @Override
+  public int hashCode() {
+    return (int)value + (int)(value>>32);
+  }
 }
\ No newline at end of file
diff --git a/solr/src/java/org/apache/solr/search/function/JoinDocFreqValueSource.java b/solr/src/java/org/apache/solr/search/function/JoinDocFreqValueSource.java
index 8dd5a852dcf..fdafedd79b1 100644
--- a/solr/src/java/org/apache/solr/search/function/JoinDocFreqValueSource.java
+++ b/solr/src/java/org/apache/solr/search/function/JoinDocFreqValueSource.java
@@ -1,100 +1,100 @@
-/**
- * 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.function;
-
-import java.io.IOException;
-import java.util.Map;
-
-import org.apache.lucene.index.IndexReader;
-import org.apache.lucene.search.FieldCache.DocTerms;
-import org.apache.lucene.util.BytesRef;
-import org.apache.solr.common.SolrException;
-
-/**
- * Use a field value and find the Document Frequency within another field.
- * 
- * @since solr 4.0
- */
-public class JoinDocFreqValueSource extends FieldCacheSource {
-
-  public static final String NAME = "joindf";
-  
-  protected final String qfield;
-  
-  public JoinDocFreqValueSource(String field, String qfield) {
-    super(field);
-    this.qfield = qfield;
-  }
-
-  public String description() {
-    return NAME + "(" + field +":("+qfield+"))";
-  }
-
-  public DocValues getValues(Map context, final IndexReader reader) throws IOException 
-  {
-    final DocTerms terms = cache.getTerms(reader, field, true );
-    
-    return new DocValues() {
-
-      public int intVal(int doc) 
-      {
-        try {
-          BytesRef ref = new BytesRef();
-          terms.getTerm(doc, ref);
-          int v = reader.docFreq( qfield, ref ); 
-          //System.out.println( NAME+"["+ref.utf8ToString()+"="+v+"]" );
-          return v;
-        } 
-        catch (IOException e) {
-          throw new SolrException(SolrException.ErrorCode.SERVER_ERROR, "caught exception in function "+description()+" : doc="+doc, e);
-        }
-      }
-
-      public float floatVal(int doc) {
-        return (float)intVal(doc);
-      }
-
-      public long longVal(int doc) {
-        return (long)intVal(doc);
-      }
-
-      public double doubleVal(int doc) {
-        return (double)intVal(doc);
-      }
-
-      public String strVal(int doc) {
-        return intVal(doc) + "";
-      }
-
-      public String toString(int doc) {
-        return description() + '=' + intVal(doc);
-      }
-    };
-  }
-  
-  public boolean equals(Object o) {
-    if (o.getClass() !=  JoinDocFreqValueSource.class) return false;
-    JoinDocFreqValueSource other = (JoinDocFreqValueSource)o;
-    if( !qfield.equals( other.qfield ) ) return false;
-    return super.equals(other);
-  }
-
-  public int hashCode() {
-    return qfield.hashCode() + super.hashCode();
-  };
-}
+/**
+ * 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.function;
+
+import java.io.IOException;
+import java.util.Map;
+
+import org.apache.lucene.index.IndexReader;
+import org.apache.lucene.search.FieldCache.DocTerms;
+import org.apache.lucene.util.BytesRef;
+import org.apache.solr.common.SolrException;
+
+/**
+ * Use a field value and find the Document Frequency within another field.
+ * 
+ * @since solr 4.0
+ */
+public class JoinDocFreqValueSource extends FieldCacheSource {
+
+  public static final String NAME = "joindf";
+  
+  protected final String qfield;
+  
+  public JoinDocFreqValueSource(String field, String qfield) {
+    super(field);
+    this.qfield = qfield;
+  }
+
+  public String description() {
+    return NAME + "(" + field +":("+qfield+"))";
+  }
+
+  public DocValues getValues(Map context, final IndexReader reader) throws IOException 
+  {
+    final DocTerms terms = cache.getTerms(reader, field, true );
+    
+    return new DocValues() {
+
+      public int intVal(int doc) 
+      {
+        try {
+          BytesRef ref = new BytesRef();
+          terms.getTerm(doc, ref);
+          int v = reader.docFreq( qfield, ref ); 
+          //System.out.println( NAME+"["+ref.utf8ToString()+"="+v+"]" );
+          return v;
+        } 
+        catch (IOException e) {
+          throw new SolrException(SolrException.ErrorCode.SERVER_ERROR, "caught exception in function "+description()+" : doc="+doc, e);
+        }
+      }
+
+      public float floatVal(int doc) {
+        return (float)intVal(doc);
+      }
+
+      public long longVal(int doc) {
+        return (long)intVal(doc);
+      }
+
+      public double doubleVal(int doc) {
+        return (double)intVal(doc);
+      }
+
+      public String strVal(int doc) {
+        return intVal(doc) + "";
+      }
+
+      public String toString(int doc) {
+        return description() + '=' + intVal(doc);
+      }
+    };
+  }
+  
+  public boolean equals(Object o) {
+    if (o.getClass() !=  JoinDocFreqValueSource.class) return false;
+    JoinDocFreqValueSource other = (JoinDocFreqValueSource)o;
+    if( !qfield.equals( other.qfield ) ) return false;
+    return super.equals(other);
+  }
+
+  public int hashCode() {
+    return qfield.hashCode() + super.hashCode();
+  };
+}
diff --git a/solr/src/solrj/org/apache/solr/client/solrj/StreamingResponseCallback.java b/solr/src/solrj/org/apache/solr/client/solrj/StreamingResponseCallback.java
index 24973fc451c..e9ef6a209b7 100644
--- a/solr/src/solrj/org/apache/solr/client/solrj/StreamingResponseCallback.java
+++ b/solr/src/solrj/org/apache/solr/client/solrj/StreamingResponseCallback.java
@@ -1,37 +1,37 @@
-/**
- * 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;
-
-import org.apache.solr.common.SolrDocument;
-
-/**
- * A callback interface for streaming response
- * 
- * @since solr 4.0
- */
-public abstract class StreamingResponseCallback {
-  /*
-   * Called for each SolrDocument in the response
-   */
-  public abstract void streamSolrDocument( SolrDocument doc );
-
-  /*
-   * Called at the beginning of each DocList (and SolrDocumentList)
-   */
-  public abstract void streamDocListInfo( long numFound, long start, Float maxScore );
-}
+/**
+ * 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;
+
+import org.apache.solr.common.SolrDocument;
+
+/**
+ * A callback interface for streaming response
+ * 
+ * @since solr 4.0
+ */
+public abstract class StreamingResponseCallback {
+  /*
+   * Called for each SolrDocument in the response
+   */
+  public abstract void streamSolrDocument( SolrDocument doc );
+
+  /*
+   * Called at the beginning of each DocList (and SolrDocumentList)
+   */
+  public abstract void streamDocListInfo( long numFound, long start, Float maxScore );
+}
diff --git a/solr/src/solrj/org/apache/solr/client/solrj/impl/StreamingBinaryResponseParser.java b/solr/src/solrj/org/apache/solr/client/solrj/impl/StreamingBinaryResponseParser.java
index db87f126751..bcbf378552f 100644
--- a/solr/src/solrj/org/apache/solr/client/solrj/impl/StreamingBinaryResponseParser.java
+++ b/solr/src/solrj/org/apache/solr/client/solrj/impl/StreamingBinaryResponseParser.java
@@ -1,89 +1,89 @@
-/**
- * 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.impl;
-
-import org.apache.solr.client.solrj.StreamingResponseCallback;
-import org.apache.solr.common.SolrDocument;
-import org.apache.solr.common.SolrDocumentList;
-import org.apache.solr.common.SolrException;
-import org.apache.solr.common.util.FastInputStream;
-import org.apache.solr.common.util.NamedList;
-import org.apache.solr.common.util.JavaBinCodec;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.List;
-
-/**
- * A BinaryResponseParser that sends callback events rather then build
- * a large response 
- * 
- * @version $Id: StreamingBinaryResponseParser.java 990180 2010-08-27 15:40:17Z rmuir $
- * @since solr 4.0
- */
-public class StreamingBinaryResponseParser extends BinaryResponseParser {
-  final StreamingResponseCallback callback;
-  
-  public StreamingBinaryResponseParser( StreamingResponseCallback cb )
-  {
-    this.callback = cb;
-  }
-  
-  @Override
-  public NamedList<Object> processResponse(InputStream body, String encoding) {
-    try {
-      JavaBinCodec codec = new JavaBinCodec() {
-
-        public SolrDocument readSolrDocument(FastInputStream dis) throws IOException {
-          SolrDocument doc = super.readSolrDocument(dis);
-          callback.streamSolrDocument( doc );
-          return null;
-        }
-
-        public SolrDocumentList readSolrDocumentList(FastInputStream dis) throws IOException {
-          SolrDocumentList solrDocs = new SolrDocumentList();
-          List list = (List) readVal(dis);
-          solrDocs.setNumFound((Long) list.get(0));
-          solrDocs.setStart((Long) list.get(1));
-          solrDocs.setMaxScore((Float) list.get(2));
-
-          callback.streamDocListInfo( 
-              solrDocs.getNumFound(), 
-              solrDocs.getStart(), 
-              solrDocs.getMaxScore() );
-          
-          // Read the Array
-          tagByte = dis.readByte();
-          if( (tagByte >>> 5) != (ARR >>> 5) ) {
-            throw new RuntimeException( "doclist must have an array" );
-          } 
-          int sz = readSize(dis);
-          for (int i = 0; i < sz; i++) {
-            // must be a SolrDocument
-            readVal( dis ); 
-          }
-          return solrDocs;
-        }
-      };
-      
-      return (NamedList<Object>) codec.unmarshal(body);
-    } 
-    catch (IOException e) {
-      throw new SolrException(SolrException.ErrorCode.SERVER_ERROR, "parsing error", e);
-    }
-  }
-}
+/**
+ * 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.impl;
+
+import org.apache.solr.client.solrj.StreamingResponseCallback;
+import org.apache.solr.common.SolrDocument;
+import org.apache.solr.common.SolrDocumentList;
+import org.apache.solr.common.SolrException;
+import org.apache.solr.common.util.FastInputStream;
+import org.apache.solr.common.util.NamedList;
+import org.apache.solr.common.util.JavaBinCodec;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.List;
+
+/**
+ * A BinaryResponseParser that sends callback events rather then build
+ * a large response 
+ * 
+ * @version $Id: StreamingBinaryResponseParser.java 990180 2010-08-27 15:40:17Z rmuir $
+ * @since solr 4.0
+ */
+public class StreamingBinaryResponseParser extends BinaryResponseParser {
+  final StreamingResponseCallback callback;
+  
+  public StreamingBinaryResponseParser( StreamingResponseCallback cb )
+  {
+    this.callback = cb;
+  }
+  
+  @Override
+  public NamedList<Object> processResponse(InputStream body, String encoding) {
+    try {
+      JavaBinCodec codec = new JavaBinCodec() {
+
+        public SolrDocument readSolrDocument(FastInputStream dis) throws IOException {
+          SolrDocument doc = super.readSolrDocument(dis);
+          callback.streamSolrDocument( doc );
+          return null;
+        }
+
+        public SolrDocumentList readSolrDocumentList(FastInputStream dis) throws IOException {
+          SolrDocumentList solrDocs = new SolrDocumentList();
+          List list = (List) readVal(dis);
+          solrDocs.setNumFound((Long) list.get(0));
+          solrDocs.setStart((Long) list.get(1));
+          solrDocs.setMaxScore((Float) list.get(2));
+
+          callback.streamDocListInfo( 
+              solrDocs.getNumFound(), 
+              solrDocs.getStart(), 
+              solrDocs.getMaxScore() );
+          
+          // Read the Array
+          tagByte = dis.readByte();
+          if( (tagByte >>> 5) != (ARR >>> 5) ) {
+            throw new RuntimeException( "doclist must have an array" );
+          } 
+          int sz = readSize(dis);
+          for (int i = 0; i < sz; i++) {
+            // must be a SolrDocument
+            readVal( dis ); 
+          }
+          return solrDocs;
+        }
+      };
+      
+      return (NamedList<Object>) codec.unmarshal(body);
+    } 
+    catch (IOException e) {
+      throw new SolrException(SolrException.ErrorCode.SERVER_ERROR, "parsing error", e);
+    }
+  }
+}
diff --git a/solr/src/solrj/org/apache/solr/client/solrj/response/PivotField.java b/solr/src/solrj/org/apache/solr/client/solrj/response/PivotField.java
index b6babe7e259..76621c628b3 100644
--- a/solr/src/solrj/org/apache/solr/client/solrj/response/PivotField.java
+++ b/solr/src/solrj/org/apache/solr/client/solrj/response/PivotField.java
@@ -1,74 +1,74 @@
-/**
- * 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.PrintWriter;
-import java.io.Serializable;
-import java.util.List;
-
-public class PivotField implements Serializable
-{
-  final String  _field;
-  final Object  _value;
-  final int     _count;
-  final List<PivotField> _pivot;
-   
-  public PivotField( String f, Object v, int count, List<PivotField> pivot )
-  {
-    _field = f;
-    _value = v;
-    _count = count;
-    _pivot = pivot;
-  }
-   
-  public String getField() {
-   return _field;
-  }
-
-  public Object getValue() {
-    return _value;
-  }
-
-  public int getCount() {
-    return _count;
-  }
-
-  public List<PivotField> getPivot() {
-    return _pivot;
-  }
-   
-  @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.println( _field + "=" + _value + " ("+_count+")" );
-    if( _pivot != null ) {
-      for( PivotField p : _pivot ) {
-        p.write( out, indent+1 );
-      }
-    }
-  }
-}
+/**
+ * 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.PrintWriter;
+import java.io.Serializable;
+import java.util.List;
+
+public class PivotField implements Serializable
+{
+  final String  _field;
+  final Object  _value;
+  final int     _count;
+  final List<PivotField> _pivot;
+   
+  public PivotField( String f, Object v, int count, List<PivotField> pivot )
+  {
+    _field = f;
+    _value = v;
+    _count = count;
+    _pivot = pivot;
+  }
+   
+  public String getField() {
+   return _field;
+  }
+
+  public Object getValue() {
+    return _value;
+  }
+
+  public int getCount() {
+    return _count;
+  }
+
+  public List<PivotField> getPivot() {
+    return _pivot;
+  }
+   
+  @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.println( _field + "=" + _value + " ("+_count+")" );
+    if( _pivot != null ) {
+      for( PivotField p : _pivot ) {
+        p.write( out, indent+1 );
+      }
+    }
+  }
+}
diff --git a/solr/src/test/org/apache/solr/JSONTestUtil.java b/solr/src/test/org/apache/solr/JSONTestUtil.java
index 097841899e1..5879b81af30 100644
--- a/solr/src/test/org/apache/solr/JSONTestUtil.java
+++ b/solr/src/test/org/apache/solr/JSONTestUtil.java
@@ -1,330 +1,330 @@
-/**
- * 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;
-
-import org.apache.noggit.JSONParser;
-import org.apache.noggit.ObjectBuilder;
-import org.apache.solr.common.util.StrUtils;
-
-import java.io.StringReader;
-import java.util.*;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-
-public class JSONTestUtil {
-
-  public static String match(String input, String pathAndExpected) throws Exception {
-    int pos = pathAndExpected.indexOf("==");
-    String path = pos>=0 ? pathAndExpected.substring(0,pos) : null;
-    String expected = pos>=0 ? pathAndExpected.substring(pos+2) : pathAndExpected;
-    return match(path, input, expected);
-  }
-
-  public static String match(String path, String input, String expected) throws Exception {
-    Object inputObj = ObjectBuilder.fromJSON(input);
-    Object expectObj = ObjectBuilder.fromJSON(expected);
-    return matchObj(path, inputObj, expectObj);
-  }
-
-  /**
-  public static Object fromJSON(String json) {
-    try {
-      Object out = ObjectBuilder.fromJSON(json);
-    } finally {
-
-  }
-  **/
-  
-  public static String matchObj(String path, Object input, Object expected) throws Exception {
-    CollectionTester tester = new CollectionTester(input);
-    if (!tester.seek(path)) {
-      return "Path not found: " + path;
-    }
-    if (expected != null && !tester.match(expected)) {
-      return tester.err + " @ " + tester.getPath();
-    }
-    return null;
-  }
-}
-
-
-/** Tests simple object graphs, like those generated by the noggit JSON parser */
-class CollectionTester {
-  public Object valRoot;
-  public Object val;
-  public Object expectedRoot;
-  public Object expected;
-  public List<Object> path;
-  public String err;
-
-  public CollectionTester(Object val) {
-    this.val = val;
-    this.valRoot = val;
-    path = new ArrayList<Object>();
-  }
-
-  public String getPath() {
-    StringBuilder sb = new StringBuilder();
-    boolean first=true;
-    for (Object seg : path) {
-      if (seg==null) break;
-      if (!first) sb.append('/');
-      else first=false;
-
-      if (seg instanceof Integer) {
-        sb.append('[');
-        sb.append(seg);
-        sb.append(']');
-      } else {
-        sb.append(seg.toString());
-      }
-    }
-    return sb.toString();
-  }
-
-  void setPath(Object lastSeg) {
-    path.set(path.size()-1, lastSeg);
-  }
-  Object popPath() {
-    return path.remove(path.size()-1);
-  }
-  void pushPath(Object lastSeg) {
-    path.add(lastSeg);
-  }
-
-  void setErr(String msg) {
-    err = msg;
-  }
-
-  public boolean match(Object expected) {
-    this.expectedRoot = expected;
-    this.expected = expected;
-    return match();
-  }
-
-  boolean match() {
-    if (expected == null && val == null) {
-      return true;
-    }
-    if (expected instanceof List) {
-      return matchList();
-    }
-    if (expected instanceof Map) {
-      return matchMap();
-    }
-
-    // generic fallback
-    if (!expected.equals(val)) {
-      setErr("mismatch: '" + expected + "'!='" + val + "'");
-      return false;
-    }
-
-    // setErr("unknown expected type " + expected.getClass().getName());
-    return true;
-  }
-
-  boolean matchList() {
-    List expectedList = (List)expected;
-    List v = asList();
-    if (v == null) return false;
-    int a = 0;
-    int b = 0;
-    pushPath(null);
-    for (;;) {
-      if (a >= expectedList.size() &&  b >=v.size()) {
-        break;
-      }
-
-      if (a >= expectedList.size() || b >=v.size()) {
-        popPath();
-        setErr("List size mismatch");
-        return false;
-      }
-
-      expected = expectedList.get(a);
-      val = v.get(b);
-      setPath(b);
-      if (!match()) return false;
-
-      a++; b++;
-    }
-    
-    popPath();
-    return true;
-  }
-
-  private static Set<String> reserved = new HashSet<String>(Arrays.asList("_SKIP_","_MATCH_","_ORDERED_","_UNORDERED_"));
-
-  boolean matchMap() {
-    Map<String,Object> expectedMap = (Map<String,Object>)expected;
-    Map<String,Object> v = asMap();
-    if (v == null) return false;
-
-    boolean ordered = false;
-    String skipList = (String)expectedMap.get("_SKIP_");
-    String matchList = (String)expectedMap.get("_MATCH_");
-    Object orderedStr = expectedMap.get("_ORDERED_");
-    Object unorderedStr = expectedMap.get("_UNORDERED_");
-
-    if (orderedStr != null) ordered = true;
-    if (unorderedStr != null) ordered = false;
-
-    Set<String> match = null;
-    if (matchList != null) {
-      match = new HashSet(StrUtils.splitSmart(matchList,",",false));
-    }
-
-    Set<String> skips = null;
-    if (skipList != null) {
-      skips = new HashSet(StrUtils.splitSmart(skipList,",",false));
-    }
-
-    Set<String> keys = match != null ? match : expectedMap.keySet();
-    Set<String> visited = new HashSet<String>();
-
-    Iterator<Map.Entry<String,Object>> iter = ordered ? v.entrySet().iterator() : null;
-
-    int numExpected=0;
-
-    pushPath(null);
-    for (String expectedKey : keys) {
-      if (reserved.contains(expectedKey)) continue;
-      numExpected++;
-
-      setPath(expectedKey);
-      if (!v.containsKey(expectedKey)) {
-        popPath();
-        setErr("expected key '" + expectedKey + "'");
-        return false;
-      }
-
-      expected = expectedMap.get(expectedKey);
-
-      if (ordered) {
-        Map.Entry<String,Object> entry;
-        String foundKey;
-        for(;;) {
-          if (!iter.hasNext()) {
-            popPath();
-            setErr("expected key '" + expectedKey + "' in ordered map");
-            return false;           
-          }
-          entry = iter.next();
-          foundKey = entry.getKey();
-          if (skips != null && skips.contains(foundKey))continue;
-          if (match != null && !match.contains(foundKey)) continue;
-          break;
-        }
-
-        if (!entry.getKey().equals(expectedKey)) {
-          popPath();          
-          setErr("expected key '" + expectedKey + "' instead of '"+entry.getKey()+"' in ordered map");
-          return false;
-        }
-        val = entry.getValue();
-      } else {
-        if (skips != null && skips.contains(expectedKey)) continue;
-        val = v.get(expectedKey);
-      }
-
-      if (!match()) return false;
-    }
-
-    popPath();
-
-    // now check if there were any extra keys in the value (as long as there wasn't a specific list to include)
-    if (match == null) {
-      int skipped = 0;
-      if (skips != null) {
-        for (String skipStr : skips)
-          if (v.containsKey(skipStr)) skipped++;
-      }
-      if (numExpected != (v.size() - skipped)) {
-        HashSet<String> set = new HashSet<String>(v.keySet());
-        set.removeAll(expectedMap.keySet());
-        setErr("unexpected map keys " + set); 
-        return false;
-      }
-    }
-
-    return true;
-  }
-
-  public boolean seek(String seekPath) {
-    if (path == null) return true;
-    if (seekPath.startsWith("/")) {
-      seekPath = seekPath.substring(1);
-    }
-    if (seekPath.endsWith("/")) {
-      seekPath = seekPath.substring(0,seekPath.length()-1);
-    }
-    List<String> pathList = StrUtils.splitSmart(seekPath, "/", false);
-    return seek(pathList);
-  }
-
-  List asList() {
-    // TODO: handle native arrays
-    if (val instanceof List) {
-      return (List)val;
-    }
-    setErr("expected List");
-    return null;
-  }
-  
-  Map<String,Object> asMap() {
-    // TODO: handle NamedList
-    if (val instanceof Map) {
-      return (Map<String,Object>)val;
-    }
-    setErr("expected Map");
-    return null;
-  }
-
-  public boolean seek(List<String> seekPath) {
-    if (seekPath.size() == 0) return true;
-    String seg = seekPath.get(0);
-
-    if (seg.charAt(0)=='[') {
-      List listVal = asList();
-      if (listVal==null) return false;
-
-      int arrIdx = Integer.parseInt(seg.substring(1, seg.length()-1));
-
-      if (arrIdx >= listVal.size()) return false;
-
-      val = listVal.get(arrIdx);
-      pushPath(arrIdx);
-    } else {
-      Map<String,Object> mapVal = asMap();
-      if (mapVal==null) return false;
-
-      // use containsKey rather than get to handle null values
-      if (!mapVal.containsKey(seg)) return false;
-
-      val = mapVal.get(seg);
-      pushPath(seg);
-    }
-
-    // recurse after removing head of the path
-    return seek(seekPath.subList(1,seekPath.size()));
-  }
-
-
-
-}
+/**
+ * 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;
+
+import org.apache.noggit.JSONParser;
+import org.apache.noggit.ObjectBuilder;
+import org.apache.solr.common.util.StrUtils;
+
+import java.io.StringReader;
+import java.util.*;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+
+public class JSONTestUtil {
+
+  public static String match(String input, String pathAndExpected) throws Exception {
+    int pos = pathAndExpected.indexOf("==");
+    String path = pos>=0 ? pathAndExpected.substring(0,pos) : null;
+    String expected = pos>=0 ? pathAndExpected.substring(pos+2) : pathAndExpected;
+    return match(path, input, expected);
+  }
+
+  public static String match(String path, String input, String expected) throws Exception {
+    Object inputObj = ObjectBuilder.fromJSON(input);
+    Object expectObj = ObjectBuilder.fromJSON(expected);
+    return matchObj(path, inputObj, expectObj);
+  }
+
+  /**
+  public static Object fromJSON(String json) {
+    try {
+      Object out = ObjectBuilder.fromJSON(json);
+    } finally {
+
+  }
+  **/
+  
+  public static String matchObj(String path, Object input, Object expected) throws Exception {
+    CollectionTester tester = new CollectionTester(input);
+    if (!tester.seek(path)) {
+      return "Path not found: " + path;
+    }
+    if (expected != null && !tester.match(expected)) {
+      return tester.err + " @ " + tester.getPath();
+    }
+    return null;
+  }
+}
+
+
+/** Tests simple object graphs, like those generated by the noggit JSON parser */
+class CollectionTester {
+  public Object valRoot;
+  public Object val;
+  public Object expectedRoot;
+  public Object expected;
+  public List<Object> path;
+  public String err;
+
+  public CollectionTester(Object val) {
+    this.val = val;
+    this.valRoot = val;
+    path = new ArrayList<Object>();
+  }
+
+  public String getPath() {
+    StringBuilder sb = new StringBuilder();
+    boolean first=true;
+    for (Object seg : path) {
+      if (seg==null) break;
+      if (!first) sb.append('/');
+      else first=false;
+
+      if (seg instanceof Integer) {
+        sb.append('[');
+        sb.append(seg);
+        sb.append(']');
+      } else {
+        sb.append(seg.toString());
+      }
+    }
+    return sb.toString();
+  }
+
+  void setPath(Object lastSeg) {
+    path.set(path.size()-1, lastSeg);
+  }
+  Object popPath() {
+    return path.remove(path.size()-1);
+  }
+  void pushPath(Object lastSeg) {
+    path.add(lastSeg);
+  }
+
+  void setErr(String msg) {
+    err = msg;
+  }
+
+  public boolean match(Object expected) {
+    this.expectedRoot = expected;
+    this.expected = expected;
+    return match();
+  }
+
+  boolean match() {
+    if (expected == null && val == null) {
+      return true;
+    }
+    if (expected instanceof List) {
+      return matchList();
+    }
+    if (expected instanceof Map) {
+      return matchMap();
+    }
+
+    // generic fallback
+    if (!expected.equals(val)) {
+      setErr("mismatch: '" + expected + "'!='" + val + "'");
+      return false;
+    }
+
+    // setErr("unknown expected type " + expected.getClass().getName());
+    return true;
+  }
+
+  boolean matchList() {
+    List expectedList = (List)expected;
+    List v = asList();
+    if (v == null) return false;
+    int a = 0;
+    int b = 0;
+    pushPath(null);
+    for (;;) {
+      if (a >= expectedList.size() &&  b >=v.size()) {
+        break;
+      }
+
+      if (a >= expectedList.size() || b >=v.size()) {
+        popPath();
+        setErr("List size mismatch");
+        return false;
+      }
+
+      expected = expectedList.get(a);
+      val = v.get(b);
+      setPath(b);
+      if (!match()) return false;
+
+      a++; b++;
+    }
+    
+    popPath();
+    return true;
+  }
+
+  private static Set<String> reserved = new HashSet<String>(Arrays.asList("_SKIP_","_MATCH_","_ORDERED_","_UNORDERED_"));
+
+  boolean matchMap() {
+    Map<String,Object> expectedMap = (Map<String,Object>)expected;
+    Map<String,Object> v = asMap();
+    if (v == null) return false;
+
+    boolean ordered = false;
+    String skipList = (String)expectedMap.get("_SKIP_");
+    String matchList = (String)expectedMap.get("_MATCH_");
+    Object orderedStr = expectedMap.get("_ORDERED_");
+    Object unorderedStr = expectedMap.get("_UNORDERED_");
+
+    if (orderedStr != null) ordered = true;
+    if (unorderedStr != null) ordered = false;
+
+    Set<String> match = null;
+    if (matchList != null) {
+      match = new HashSet(StrUtils.splitSmart(matchList,",",false));
+    }
+
+    Set<String> skips = null;
+    if (skipList != null) {
+      skips = new HashSet(StrUtils.splitSmart(skipList,",",false));
+    }
+
+    Set<String> keys = match != null ? match : expectedMap.keySet();
+    Set<String> visited = new HashSet<String>();
+
+    Iterator<Map.Entry<String,Object>> iter = ordered ? v.entrySet().iterator() : null;
+
+    int numExpected=0;
+
+    pushPath(null);
+    for (String expectedKey : keys) {
+      if (reserved.contains(expectedKey)) continue;
+      numExpected++;
+
+      setPath(expectedKey);
+      if (!v.containsKey(expectedKey)) {
+        popPath();
+        setErr("expected key '" + expectedKey + "'");
+        return false;
+      }
+
+      expected = expectedMap.get(expectedKey);
+
+      if (ordered) {
+        Map.Entry<String,Object> entry;
+        String foundKey;
+        for(;;) {
+          if (!iter.hasNext()) {
+            popPath();
+            setErr("expected key '" + expectedKey + "' in ordered map");
+            return false;           
+          }
+          entry = iter.next();
+          foundKey = entry.getKey();
+          if (skips != null && skips.contains(foundKey))continue;
+          if (match != null && !match.contains(foundKey)) continue;
+          break;
+        }
+
+        if (!entry.getKey().equals(expectedKey)) {
+          popPath();          
+          setErr("expected key '" + expectedKey + "' instead of '"+entry.getKey()+"' in ordered map");
+          return false;
+        }
+        val = entry.getValue();
+      } else {
+        if (skips != null && skips.contains(expectedKey)) continue;
+        val = v.get(expectedKey);
+      }
+
+      if (!match()) return false;
+    }
+
+    popPath();
+
+    // now check if there were any extra keys in the value (as long as there wasn't a specific list to include)
+    if (match == null) {
+      int skipped = 0;
+      if (skips != null) {
+        for (String skipStr : skips)
+          if (v.containsKey(skipStr)) skipped++;
+      }
+      if (numExpected != (v.size() - skipped)) {
+        HashSet<String> set = new HashSet<String>(v.keySet());
+        set.removeAll(expectedMap.keySet());
+        setErr("unexpected map keys " + set); 
+        return false;
+      }
+    }
+
+    return true;
+  }
+
+  public boolean seek(String seekPath) {
+    if (path == null) return true;
+    if (seekPath.startsWith("/")) {
+      seekPath = seekPath.substring(1);
+    }
+    if (seekPath.endsWith("/")) {
+      seekPath = seekPath.substring(0,seekPath.length()-1);
+    }
+    List<String> pathList = StrUtils.splitSmart(seekPath, "/", false);
+    return seek(pathList);
+  }
+
+  List asList() {
+    // TODO: handle native arrays
+    if (val instanceof List) {
+      return (List)val;
+    }
+    setErr("expected List");
+    return null;
+  }
+  
+  Map<String,Object> asMap() {
+    // TODO: handle NamedList
+    if (val instanceof Map) {
+      return (Map<String,Object>)val;
+    }
+    setErr("expected Map");
+    return null;
+  }
+
+  public boolean seek(List<String> seekPath) {
+    if (seekPath.size() == 0) return true;
+    String seg = seekPath.get(0);
+
+    if (seg.charAt(0)=='[') {
+      List listVal = asList();
+      if (listVal==null) return false;
+
+      int arrIdx = Integer.parseInt(seg.substring(1, seg.length()-1));
+
+      if (arrIdx >= listVal.size()) return false;
+
+      val = listVal.get(arrIdx);
+      pushPath(arrIdx);
+    } else {
+      Map<String,Object> mapVal = asMap();
+      if (mapVal==null) return false;
+
+      // use containsKey rather than get to handle null values
+      if (!mapVal.containsKey(seg)) return false;
+
+      val = mapVal.get(seg);
+      pushPath(seg);
+    }
+
+    // recurse after removing head of the path
+    return seek(seekPath.subList(1,seekPath.size()));
+  }
+
+
+
+}
diff --git a/solr/src/test/org/apache/solr/response/TestCSVResponseWriter.java b/solr/src/test/org/apache/solr/response/TestCSVResponseWriter.java
index c85bad44c3f..ee8f735649d 100644
--- a/solr/src/test/org/apache/solr/response/TestCSVResponseWriter.java
+++ b/solr/src/test/org/apache/solr/response/TestCSVResponseWriter.java
@@ -1,165 +1,165 @@
-/**
- * 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.response;
-
-import org.apache.solr.SolrTestCaseJ4;
-import org.apache.solr.common.SolrDocument;
-import org.apache.solr.common.SolrDocumentList;
-import org.apache.solr.common.util.DateUtil;
-import org.apache.solr.request.SolrQueryRequest;
-import org.apache.solr.util.SolrPluginUtils;
-import org.junit.*;
-
-import java.io.StringWriter;
-
-import static org.junit.Assert.*;
-
-import static org.junit.Assert.assertEquals;
-
-public class TestCSVResponseWriter extends SolrTestCaseJ4 {
-  @BeforeClass
-  public static void beforeClass() throws Exception {
-    initCore("solrconfig.xml","schema12.xml");
-    createIndex();
-  }
-
-  public static void createIndex() {
-    assertU(adoc("id","1", "foo_i","-1", "foo_s","hi", "foo_l","12345678987654321", "foo_b","false", "foo_f","1.414","foo_d","-1.0E300","foo_dt","2000-01-02T03:04:05Z"));
-    assertU(adoc("id","2", "v_ss","hi",  "v_ss","there", "v2_ss","nice", "v2_ss","output"));
-    assertU(commit());
-  }
-
-  
-  @Test
-  public void testCSVOutput() throws Exception {
-    // test our basic types,and that fields come back in the requested order
-    assertEquals("id,foo_s,foo_i,foo_l,foo_b,foo_f,foo_d,foo_dt\n1,hi,-1,12345678987654321,false,1.414,-1.0E300,2000-01-02T03:04:05Z\n"
-    , h.query(req("q","id:1", "wt","csv", "fl","id,foo_s,foo_i,foo_l,foo_b,foo_f,foo_d,foo_dt")));
-
-    // test retrieving score, csv.header
-    assertEquals("1,0.0,hi\n"
-    , h.query(req("q","id:1^0", "wt","csv", "csv.header","false", "fl","id,score,foo_s")));
-
-    // test multivalued
-    assertEquals("2,\"hi,there\"\n"
-    , h.query(req("q","id:2", "wt","csv", "csv.header","false", "fl","id,v_ss")));
-
-    // test separator change
-    assertEquals("2|\"hi|there\"\n"
-    , h.query(req("q","id:2", "wt","csv", "csv.header","false", "csv.separator","|", "fl","id,v_ss")));
-
-    // test mv separator change
-    assertEquals("2,hi|there\n"
-    , h.query(req("q","id:2", "wt","csv", "csv.header","false", "csv.mv.separator","|", "fl","id,v_ss")));
-
-    // test mv separator change for a single field
-    assertEquals("2,hi|there,nice:output\n"
-    , h.query(req("q","id:2", "wt","csv", "csv.header","false", "csv.mv.separator","|", "f.v2_ss.csv.separator",":", "fl","id,v_ss,v2_ss")));
-
-    // test retrieving fields from index
-    String result = h.query(req("q","*:*", "wt","csv", "csv.header","true", "fl","*,score"));
-    for (String field : "id,foo_s,foo_i,foo_l,foo_b,foo_f,foo_d,foo_dt,v_ss,v2_ss,score".split(",")) {
-      assertTrue(result.indexOf(field) >= 0);
-    }
-
-    // test null values
-    assertEquals("2,,hi|there\n"
-    , h.query(req("q","id:2", "wt","csv", "csv.header","false", "csv.mv.separator","|", "fl","id,foo_s,v_ss")));
-
-    // test alternate null value
-    assertEquals("2,NULL,hi|there\n"
-    , h.query(req("q","id:2", "wt","csv", "csv.header","false", "csv.mv.separator","|", "csv.null","NULL","fl","id,foo_s,v_ss")));
-
-    // test alternate newline
-    assertEquals("2,\"hi,there\"\r\n"
-    , h.query(req("q","id:2", "wt","csv", "csv.header","false", "csv.newline","\r\n", "fl","id,v_ss")));
-
-    // test alternate encapsulator
-    assertEquals("2,'hi,there'\n"
-    , h.query(req("q","id:2", "wt","csv", "csv.header","false", "csv.encapsulator","'", "fl","id,v_ss")));
-
-    // test using escape instead of encapsulator
-    assertEquals("2,hi\\,there\n"
-    , h.query(req("q","id:2", "wt","csv", "csv.header","false", "csv.escape","\\", "fl","id,v_ss")));
-
-    // test multiple lines
-    assertEquals("1,,hi\n2,\"hi,there\",\n"
-    , h.query(req("q","id:[1 TO 2]", "wt","csv", "csv.header","false", "fl","id,v_ss,foo_s")));
-
-
-    // now test SolrDocumentList
-    SolrDocument d = new SolrDocument();
-    SolrDocument d1 = d;
-    d.addField("id","1");
-    d.addField("foo_i",-1);
-    d.addField("foo_s","hi");
-    d.addField("foo_l","12345678987654321L");
-    d.addField("foo_b",false);
-    d.addField("foo_f",1.414f);
-    d.addField("foo_d",-1.0E300);
-    d.addField("foo_dt", DateUtil.parseDate("2000-01-02T03:04:05Z"));
-    d.addField("score", "2.718");
-
-    d = new SolrDocument();
-    SolrDocument d2 = d;
-    d.addField("id","2");
-    d.addField("v_ss","hi");
-    d.addField("v_ss","there");
-    d.addField("v2_ss","nice");
-    d.addField("v2_ss","output");
-    d.addField("score", "89.83");
-
-    SolrDocumentList sdl = new SolrDocumentList();
-    sdl.add(d1);
-    sdl.add(d2);
-    
-    SolrQueryRequest req = req("q","*:*");
-    SolrQueryResponse rsp = new SolrQueryResponse();
-    rsp.add("response", sdl);
-    QueryResponseWriter w = new CSVResponseWriter();
-    
-    SolrPluginUtils.setReturnFields("id,foo_s", rsp);
-    StringWriter buf = new StringWriter();
-    w.write(buf, req, rsp);
-    assertEquals("id,foo_s\n1,hi\n2,\n", buf.toString());
-
-    // try scores
-    SolrPluginUtils.setReturnFields("id,score,foo_s", rsp);
-    buf = new StringWriter();
-    w.write(buf, req, rsp);
-    assertEquals("id,score,foo_s\n1,2.718,hi\n2,89.83,\n", buf.toString());
-
-    // get field values from docs... should be ordered and not include score unless requested
-    SolrPluginUtils.setReturnFields("*", rsp);
-    buf = new StringWriter();
-    w.write(buf, req, rsp);
-    assertEquals("id,foo_i,foo_s,foo_l,foo_b,foo_f,foo_d,foo_dt,v_ss,v2_ss\n" +
-        "1,-1,hi,12345678987654321L,false,1.414,-1.0E300,2000-01-02T03:04:05Z,,\n" +
-        "2,,,,,,,,\"hi,there\",\"nice,output\"\n",
-      buf.toString());
-    
-
-    // get field values and scores - just check that the scores are there... we don't guarantee where
-    SolrPluginUtils.setReturnFields("*,score", rsp);
-    buf = new StringWriter();
-    w.write(buf, req, rsp);
-    String s = buf.toString();
-    assertTrue(s.indexOf("score") >=0 && s.indexOf("2.718") > 0 && s.indexOf("89.83") > 0 );
-  }
-
+/**
+ * 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.response;
+
+import org.apache.solr.SolrTestCaseJ4;
+import org.apache.solr.common.SolrDocument;
+import org.apache.solr.common.SolrDocumentList;
+import org.apache.solr.common.util.DateUtil;
+import org.apache.solr.request.SolrQueryRequest;
+import org.apache.solr.util.SolrPluginUtils;
+import org.junit.*;
+
+import java.io.StringWriter;
+
+import static org.junit.Assert.*;
+
+import static org.junit.Assert.assertEquals;
+
+public class TestCSVResponseWriter extends SolrTestCaseJ4 {
+  @BeforeClass
+  public static void beforeClass() throws Exception {
+    initCore("solrconfig.xml","schema12.xml");
+    createIndex();
+  }
+
+  public static void createIndex() {
+    assertU(adoc("id","1", "foo_i","-1", "foo_s","hi", "foo_l","12345678987654321", "foo_b","false", "foo_f","1.414","foo_d","-1.0E300","foo_dt","2000-01-02T03:04:05Z"));
+    assertU(adoc("id","2", "v_ss","hi",  "v_ss","there", "v2_ss","nice", "v2_ss","output"));
+    assertU(commit());
+  }
+
+  
+  @Test
+  public void testCSVOutput() throws Exception {
+    // test our basic types,and that fields come back in the requested order
+    assertEquals("id,foo_s,foo_i,foo_l,foo_b,foo_f,foo_d,foo_dt\n1,hi,-1,12345678987654321,false,1.414,-1.0E300,2000-01-02T03:04:05Z\n"
+    , h.query(req("q","id:1", "wt","csv", "fl","id,foo_s,foo_i,foo_l,foo_b,foo_f,foo_d,foo_dt")));
+
+    // test retrieving score, csv.header
+    assertEquals("1,0.0,hi\n"
+    , h.query(req("q","id:1^0", "wt","csv", "csv.header","false", "fl","id,score,foo_s")));
+
+    // test multivalued
+    assertEquals("2,\"hi,there\"\n"
+    , h.query(req("q","id:2", "wt","csv", "csv.header","false", "fl","id,v_ss")));
+
+    // test separator change
+    assertEquals("2|\"hi|there\"\n"
+    , h.query(req("q","id:2", "wt","csv", "csv.header","false", "csv.separator","|", "fl","id,v_ss")));
+
+    // test mv separator change
+    assertEquals("2,hi|there\n"
+    , h.query(req("q","id:2", "wt","csv", "csv.header","false", "csv.mv.separator","|", "fl","id,v_ss")));
+
+    // test mv separator change for a single field
+    assertEquals("2,hi|there,nice:output\n"
+    , h.query(req("q","id:2", "wt","csv", "csv.header","false", "csv.mv.separator","|", "f.v2_ss.csv.separator",":", "fl","id,v_ss,v2_ss")));
+
+    // test retrieving fields from index
+    String result = h.query(req("q","*:*", "wt","csv", "csv.header","true", "fl","*,score"));
+    for (String field : "id,foo_s,foo_i,foo_l,foo_b,foo_f,foo_d,foo_dt,v_ss,v2_ss,score".split(",")) {
+      assertTrue(result.indexOf(field) >= 0);
+    }
+
+    // test null values
+    assertEquals("2,,hi|there\n"
+    , h.query(req("q","id:2", "wt","csv", "csv.header","false", "csv.mv.separator","|", "fl","id,foo_s,v_ss")));
+
+    // test alternate null value
+    assertEquals("2,NULL,hi|there\n"
+    , h.query(req("q","id:2", "wt","csv", "csv.header","false", "csv.mv.separator","|", "csv.null","NULL","fl","id,foo_s,v_ss")));
+
+    // test alternate newline
+    assertEquals("2,\"hi,there\"\r\n"
+    , h.query(req("q","id:2", "wt","csv", "csv.header","false", "csv.newline","\r\n", "fl","id,v_ss")));
+
+    // test alternate encapsulator
+    assertEquals("2,'hi,there'\n"
+    , h.query(req("q","id:2", "wt","csv", "csv.header","false", "csv.encapsulator","'", "fl","id,v_ss")));
+
+    // test using escape instead of encapsulator
+    assertEquals("2,hi\\,there\n"
+    , h.query(req("q","id:2", "wt","csv", "csv.header","false", "csv.escape","\\", "fl","id,v_ss")));
+
+    // test multiple lines
+    assertEquals("1,,hi\n2,\"hi,there\",\n"
+    , h.query(req("q","id:[1 TO 2]", "wt","csv", "csv.header","false", "fl","id,v_ss,foo_s")));
+
+
+    // now test SolrDocumentList
+    SolrDocument d = new SolrDocument();
+    SolrDocument d1 = d;
+    d.addField("id","1");
+    d.addField("foo_i",-1);
+    d.addField("foo_s","hi");
+    d.addField("foo_l","12345678987654321L");
+    d.addField("foo_b",false);
+    d.addField("foo_f",1.414f);
+    d.addField("foo_d",-1.0E300);
+    d.addField("foo_dt", DateUtil.parseDate("2000-01-02T03:04:05Z"));
+    d.addField("score", "2.718");
+
+    d = new SolrDocument();
+    SolrDocument d2 = d;
+    d.addField("id","2");
+    d.addField("v_ss","hi");
+    d.addField("v_ss","there");
+    d.addField("v2_ss","nice");
+    d.addField("v2_ss","output");
+    d.addField("score", "89.83");
+
+    SolrDocumentList sdl = new SolrDocumentList();
+    sdl.add(d1);
+    sdl.add(d2);
+    
+    SolrQueryRequest req = req("q","*:*");
+    SolrQueryResponse rsp = new SolrQueryResponse();
+    rsp.add("response", sdl);
+    QueryResponseWriter w = new CSVResponseWriter();
+    
+    SolrPluginUtils.setReturnFields("id,foo_s", rsp);
+    StringWriter buf = new StringWriter();
+    w.write(buf, req, rsp);
+    assertEquals("id,foo_s\n1,hi\n2,\n", buf.toString());
+
+    // try scores
+    SolrPluginUtils.setReturnFields("id,score,foo_s", rsp);
+    buf = new StringWriter();
+    w.write(buf, req, rsp);
+    assertEquals("id,score,foo_s\n1,2.718,hi\n2,89.83,\n", buf.toString());
+
+    // get field values from docs... should be ordered and not include score unless requested
+    SolrPluginUtils.setReturnFields("*", rsp);
+    buf = new StringWriter();
+    w.write(buf, req, rsp);
+    assertEquals("id,foo_i,foo_s,foo_l,foo_b,foo_f,foo_d,foo_dt,v_ss,v2_ss\n" +
+        "1,-1,hi,12345678987654321L,false,1.414,-1.0E300,2000-01-02T03:04:05Z,,\n" +
+        "2,,,,,,,,\"hi,there\",\"nice,output\"\n",
+      buf.toString());
+    
+
+    // get field values and scores - just check that the scores are there... we don't guarantee where
+    SolrPluginUtils.setReturnFields("*,score", rsp);
+    buf = new StringWriter();
+    w.write(buf, req, rsp);
+    String s = buf.toString();
+    assertTrue(s.indexOf("score") >=0 && s.indexOf("2.718") > 0 && s.indexOf("89.83") > 0 );
+  }
+
 }
\ No newline at end of file
diff --git a/solr/src/test/org/apache/solr/search/TestSolrQueryParser.java b/solr/src/test/org/apache/solr/search/TestSolrQueryParser.java
index 8b39e91a619..d1061bb4316 100644
--- a/solr/src/test/org/apache/solr/search/TestSolrQueryParser.java
+++ b/solr/src/test/org/apache/solr/search/TestSolrQueryParser.java
@@ -1,53 +1,53 @@
-/**
- * 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.SolrTestCaseJ4;
-import org.junit.BeforeClass;
-import org.junit.After;
-import org.junit.Test;
-
-
-public class TestSolrQueryParser extends SolrTestCaseJ4 {
-  @BeforeClass
-  public static void beforeClass() throws Exception {
-    initCore("solrconfig.xml", "schema12.xml");
-    createIndex();
-  }
-
-  public static void createIndex() {
-    String v;
-    v="how now brown cow";
-    assertU(adoc("id","1", "text",v,  "text_np",v));
-    v="now cow";
-    assertU(adoc("id","2", "text",v,  "text_np",v));
-    assertU(commit());
-  }
-
-  @Test
-  public void testPhrase() {
-    // should generate a phrase of "now cow" and match only one doc
-    assertQ(req("q","text:now-cow", "indent","true")
-        ,"//*[@numFound='1']"
-    );
-    // should generate a query of (now OR cow) and match both docs
-    assertQ(req("q","text_np:now-cow", "indent","true")
-        ,"//*[@numFound='2']"
-    );
-  }
-
-}
+/**
+ * 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.SolrTestCaseJ4;
+import org.junit.BeforeClass;
+import org.junit.After;
+import org.junit.Test;
+
+
+public class TestSolrQueryParser extends SolrTestCaseJ4 {
+  @BeforeClass
+  public static void beforeClass() throws Exception {
+    initCore("solrconfig.xml", "schema12.xml");
+    createIndex();
+  }
+
+  public static void createIndex() {
+    String v;
+    v="how now brown cow";
+    assertU(adoc("id","1", "text",v,  "text_np",v));
+    v="now cow";
+    assertU(adoc("id","2", "text",v,  "text_np",v));
+    assertU(commit());
+  }
+
+  @Test
+  public void testPhrase() {
+    // should generate a phrase of "now cow" and match only one doc
+    assertQ(req("q","text:now-cow", "indent","true")
+        ,"//*[@numFound='1']"
+    );
+    // should generate a query of (now OR cow) and match both docs
+    assertQ(req("q","text_np:now-cow", "indent","true")
+        ,"//*[@numFound='2']"
+    );
+  }
+
+}