You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucenenet.apache.org by pn...@apache.org on 2014/09/21 18:53:32 UTC

[6/7] Cleanup of codes, mostly SimpleText in this commit

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/cf1df6be/src/Lucene.Net.Codecs/SimpleText/SimpleTextDocValuesReader.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Codecs/SimpleText/SimpleTextDocValuesReader.cs b/src/Lucene.Net.Codecs/SimpleText/SimpleTextDocValuesReader.cs
index 63c3cf8..f8f9e97 100644
--- a/src/Lucene.Net.Codecs/SimpleText/SimpleTextDocValuesReader.cs
+++ b/src/Lucene.Net.Codecs/SimpleText/SimpleTextDocValuesReader.cs
@@ -1,489 +1,768 @@
-package org.apache.lucene.codecs.simpletext;
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-import static org.apache.lucene.codecs.simpletext.SimpleTextDocValuesWriter.END;
-import static org.apache.lucene.codecs.simpletext.SimpleTextDocValuesWriter.FIELD;
-import static org.apache.lucene.codecs.simpletext.SimpleTextDocValuesWriter.LENGTH;
-import static org.apache.lucene.codecs.simpletext.SimpleTextDocValuesWriter.MAXLENGTH;
-import static org.apache.lucene.codecs.simpletext.SimpleTextDocValuesWriter.MINVALUE;
-import static org.apache.lucene.codecs.simpletext.SimpleTextDocValuesWriter.NUMVALUES;
-import static org.apache.lucene.codecs.simpletext.SimpleTextDocValuesWriter.ORDPATTERN;
-import static org.apache.lucene.codecs.simpletext.SimpleTextDocValuesWriter.PATTERN;
-import static org.apache.lucene.codecs.simpletext.SimpleTextDocValuesWriter.TYPE;
-
-import java.io.IOException;
-import java.math.BigDecimal;
-import java.math.BigInteger;
-import java.nio.charset.StandardCharsets;
-import java.text.DecimalFormat;
-import java.text.DecimalFormatSymbols;
-import java.text.ParseException;
-import java.util.HashMap;
-import java.util.Locale;
-import java.util.Map;
-
-import org.apache.lucene.codecs.DocValuesProducer;
-import org.apache.lucene.index.BinaryDocValues;
-import org.apache.lucene.index.CorruptIndexException;
-import org.apache.lucene.index.DocValues;
-import org.apache.lucene.index.FieldInfo;
-import org.apache.lucene.index.FieldInfo.DocValuesType;
-import org.apache.lucene.index.IndexFileNames;
-import org.apache.lucene.index.NumericDocValues;
-import org.apache.lucene.index.SegmentReadState;
-import org.apache.lucene.index.SortedDocValues;
-import org.apache.lucene.index.SortedSetDocValues;
-import org.apache.lucene.store.BufferedChecksumIndexInput;
-import org.apache.lucene.store.ChecksumIndexInput;
-import org.apache.lucene.store.IndexInput;
-import org.apache.lucene.util.Bits;
-import org.apache.lucene.util.BytesRef;
-import org.apache.lucene.util.StringHelper;
-
-class SimpleTextDocValuesReader extends DocValuesProducer {
-
-  static class OneField {
-    long dataStartFilePointer;
-    String pattern;
-    String ordPattern;
-    int maxLength;
-    bool fixedLength;
-    long minValue;
-    long numValues;
-  }
-
-  final int maxDoc;
-  final IndexInput data;
-  final BytesRef scratch = new BytesRef();
-  final Map<String,OneField> fields = new HashMap<>();
-  
-  public SimpleTextDocValuesReader(SegmentReadState state, String ext)  {
-    // System.out.println("dir=" + state.directory + " seg=" + state.segmentInfo.name + " file=" + IndexFileNames.segmentFileName(state.segmentInfo.name, state.segmentSuffix, ext));
-    data = state.directory.openInput(IndexFileNames.segmentFileName(state.segmentInfo.name, state.segmentSuffix, ext), state.context);
-    maxDoc = state.segmentInfo.getDocCount();
-    while(true) {
-      readLine();
-      //System.out.println("READ field=" + scratch.utf8ToString());
-      if (scratch.equals(END)) {
-        break;
-      }
-      Debug.Assert( startsWith(FIELD) : scratch.utf8ToString();
-      String fieldName = stripPrefix(FIELD);
-      //System.out.println("  field=" + fieldName);
-
-      OneField field = new OneField();
-      fields.put(fieldName, field);
-
-      readLine();
-      Debug.Assert( startsWith(TYPE) : scratch.utf8ToString();
-
-      DocValuesType dvType = DocValuesType.valueOf(stripPrefix(TYPE));
-      Debug.Assert( dvType != null;
-      if (dvType == DocValuesType.NUMERIC) {
-        readLine();
-        Debug.Assert( startsWith(MINVALUE): "got " + scratch.utf8ToString() + " field=" + fieldName + " ext=" + ext;
-        field.minValue = Long.parseLong(stripPrefix(MINVALUE));
-        readLine();
-        Debug.Assert( startsWith(PATTERN);
-        field.pattern = stripPrefix(PATTERN);
-        field.dataStartFilePointer = data.getFilePointer();
-        data.seek(data.getFilePointer() + (1+field.pattern.length()+2) * maxDoc);
-      } else if (dvType == DocValuesType.BINARY) {
-        readLine();
-        Debug.Assert( startsWith(MAXLENGTH);
-        field.maxLength = Integer.parseInt(stripPrefix(MAXLENGTH));
-        readLine();
-        Debug.Assert( startsWith(PATTERN);
-        field.pattern = stripPrefix(PATTERN);
-        field.dataStartFilePointer = data.getFilePointer();
-        data.seek(data.getFilePointer() + (9+field.pattern.length()+field.maxLength+2) * maxDoc);
-      } else if (dvType == DocValuesType.SORTED || dvType == DocValuesType.SORTED_SET) {
-        readLine();
-        Debug.Assert( startsWith(NUMVALUES);
-        field.numValues = Long.parseLong(stripPrefix(NUMVALUES));
-        readLine();
-        Debug.Assert( startsWith(MAXLENGTH);
-        field.maxLength = Integer.parseInt(stripPrefix(MAXLENGTH));
-        readLine();
-        Debug.Assert( startsWith(PATTERN);
-        field.pattern = stripPrefix(PATTERN);
-        readLine();
-        Debug.Assert( startsWith(ORDPATTERN);
-        field.ordPattern = stripPrefix(ORDPATTERN);
-        field.dataStartFilePointer = data.getFilePointer();
-        data.seek(data.getFilePointer() + (9+field.pattern.length()+field.maxLength) * field.numValues + (1+field.ordPattern.length())*maxDoc);
-      } else {
-        throw new Debug.Assert(ionError();
-      }
-    }
-
-    // We should only be called from above if at least one
-    // field has DVs:
-    Debug.Assert( !fields.isEmpty();
-  }
-
-  @Override
-  public NumericDocValues getNumeric(FieldInfo fieldInfo)  {
-    final OneField field = fields.get(fieldInfo.name);
-    Debug.Assert( field != null;
-
-    // SegmentCoreReaders already verifies this field is
-    // valid:
-    Debug.Assert( field != null: "field=" + fieldInfo.name + " fields=" + fields;
-
-    final IndexInput in = data.clone();
-    final BytesRef scratch = new BytesRef();
-    final DecimalFormat decoder = new DecimalFormat(field.pattern, new DecimalFormatSymbols(Locale.ROOT));
-
-    decoder.setParseBigDecimal(true);
-
-    return new NumericDocValues() {
-      @Override
-      public long get(int docID) {
-        try {
-          //System.out.println(Thread.currentThread().getName() + ": get docID=" + docID + " in=" + in);
-          if (docID < 0 || docID >= maxDoc) {
-            throw new IndexOutOfBoundsException("docID must be 0 .. " + (maxDoc-1) + "; got " + docID);
-          }
-          in.seek(field.dataStartFilePointer + (1+field.pattern.length()+2)*docID);
-          SimpleTextUtil.readLine(in, scratch);
-          //System.out.println("parsing delta: " + scratch.utf8ToString());
-          BigDecimal bd;
-          try {
-            bd = (BigDecimal) decoder.parse(scratch.utf8ToString());
-          } catch (ParseException pe) {
-            CorruptIndexException e = new CorruptIndexException("failed to parse BigDecimal value (resource=" + in + ")");
-            e.initCause(pe);
-            throw e;
-          }
-          SimpleTextUtil.readLine(in, scratch); // read the line telling us if its real or not
-          return BigInteger.valueOf(field.minValue).add(bd.toBigIntegerExact()).longValue();
-        } catch (IOException ioe) {
-          throw new RuntimeException(ioe);
-        }
-      }
-    };
-  }
-  
-  private Bits getNumericDocsWithField(FieldInfo fieldInfo)  {
-    final OneField field = fields.get(fieldInfo.name);
-    final IndexInput in = data.clone();
-    final BytesRef scratch = new BytesRef();
-    return new Bits() {
-      @Override
-      public bool get(int index) {
-        try {
-          in.seek(field.dataStartFilePointer + (1+field.pattern.length()+2)*index);
-          SimpleTextUtil.readLine(in, scratch); // data
-          SimpleTextUtil.readLine(in, scratch); // 'T' or 'F'
-          return scratch.bytes[scratch.offset] == (byte) 'T';
-        } catch (IOException e) {
-          throw new RuntimeException(e);
-        }
-      }
-
-      @Override
-      public int length() {
-        return maxDoc;
-      }
-    };
-  }
-
-  @Override
-  public BinaryDocValues getBinary(FieldInfo fieldInfo)  {
-    final OneField field = fields.get(fieldInfo.name);
-
-    // SegmentCoreReaders already verifies this field is
-    // valid:
-    Debug.Assert( field != null;
-
-    final IndexInput in = data.clone();
-    final BytesRef scratch = new BytesRef();
-    final DecimalFormat decoder = new DecimalFormat(field.pattern, new DecimalFormatSymbols(Locale.ROOT));
-
-    return new BinaryDocValues() {
-      @Override
-      public void get(int docID, BytesRef result) {
-        try {
-          if (docID < 0 || docID >= maxDoc) {
-            throw new IndexOutOfBoundsException("docID must be 0 .. " + (maxDoc-1) + "; got " + docID);
-          }
-          in.seek(field.dataStartFilePointer + (9+field.pattern.length() + field.maxLength+2)*docID);
-          SimpleTextUtil.readLine(in, scratch);
-          Debug.Assert( StringHelper.startsWith(scratch, LENGTH);
-          int len;
-          try {
-            len = decoder.parse(new String(scratch.bytes, scratch.offset + LENGTH.length, scratch.length - LENGTH.length, StandardCharsets.UTF_8)).intValue();
-          } catch (ParseException pe) {
-            CorruptIndexException e = new CorruptIndexException("failed to parse int length (resource=" + in + ")");
-            e.initCause(pe);
-            throw e;
-          }
-          result.bytes = new byte[len];
-          result.offset = 0;
-          result.length = len;
-          in.readBytes(result.bytes, 0, len);
-        } catch (IOException ioe) {
-          throw new RuntimeException(ioe);
-        }
-      }
-    };
-  }
-  
-  private Bits getBinaryDocsWithField(FieldInfo fieldInfo)  {
-    final OneField field = fields.get(fieldInfo.name);
-    final IndexInput in = data.clone();
-    final BytesRef scratch = new BytesRef();
-    final DecimalFormat decoder = new DecimalFormat(field.pattern, new DecimalFormatSymbols(Locale.ROOT));
-
-    return new Bits() {
-      @Override
-      public bool get(int index) {
-        try {
-          in.seek(field.dataStartFilePointer + (9+field.pattern.length() + field.maxLength+2)*index);
-          SimpleTextUtil.readLine(in, scratch);
-          Debug.Assert( StringHelper.startsWith(scratch, LENGTH);
-          int len;
-          try {
-            len = decoder.parse(new String(scratch.bytes, scratch.offset + LENGTH.length, scratch.length - LENGTH.length, StandardCharsets.UTF_8)).intValue();
-          } catch (ParseException pe) {
-            CorruptIndexException e = new CorruptIndexException("failed to parse int length (resource=" + in + ")");
-            e.initCause(pe);
-            throw e;
-          }
-          // skip past bytes
-          byte bytes[] = new byte[len];
-          in.readBytes(bytes, 0, len);
-          SimpleTextUtil.readLine(in, scratch); // newline
-          SimpleTextUtil.readLine(in, scratch); // 'T' or 'F'
-          return scratch.bytes[scratch.offset] == (byte) 'T';
-        } catch (IOException ioe) {
-          throw new RuntimeException(ioe);
-        }
-      }
-
-      @Override
-      public int length() {
-        return maxDoc;
-      }
-    };
-  }
-
-  @Override
-  public SortedDocValues getSorted(FieldInfo fieldInfo)  {
-    final OneField field = fields.get(fieldInfo.name);
-
-    // SegmentCoreReaders already verifies this field is
-    // valid:
-    Debug.Assert( field != null;
-
-    final IndexInput in = data.clone();
-    final BytesRef scratch = new BytesRef();
-    final DecimalFormat decoder = new DecimalFormat(field.pattern, new DecimalFormatSymbols(Locale.ROOT));
-    final DecimalFormat ordDecoder = new DecimalFormat(field.ordPattern, new DecimalFormatSymbols(Locale.ROOT));
-
-    return new SortedDocValues() {
-      @Override
-      public int getOrd(int docID) {
-        if (docID < 0 || docID >= maxDoc) {
-          throw new IndexOutOfBoundsException("docID must be 0 .. " + (maxDoc-1) + "; got " + docID);
-        }
-        try {
-          in.seek(field.dataStartFilePointer + field.numValues * (9 + field.pattern.length() + field.maxLength) + docID * (1 + field.ordPattern.length()));
-          SimpleTextUtil.readLine(in, scratch);
-          try {
-            return (int) ordDecoder.parse(scratch.utf8ToString()).longValue()-1;
-          } catch (ParseException pe) {
-            CorruptIndexException e = new CorruptIndexException("failed to parse ord (resource=" + in + ")");
-            e.initCause(pe);
-            throw e;
-          }
-        } catch (IOException ioe) {
-          throw new RuntimeException(ioe);
-        }
-      }
-
-      @Override
-      public void lookupOrd(int ord, BytesRef result) {
-        try {
-          if (ord < 0 || ord >= field.numValues) {
-            throw new IndexOutOfBoundsException("ord must be 0 .. " + (field.numValues-1) + "; got " + ord);
-          }
-          in.seek(field.dataStartFilePointer + ord * (9 + field.pattern.length() + field.maxLength));
-          SimpleTextUtil.readLine(in, scratch);
-          Debug.Assert( StringHelper.startsWith(scratch, LENGTH): "got " + scratch.utf8ToString() + " in=" + in;
-          int len;
-          try {
-            len = decoder.parse(new String(scratch.bytes, scratch.offset + LENGTH.length, scratch.length - LENGTH.length, StandardCharsets.UTF_8)).intValue();
-          } catch (ParseException pe) {
-            CorruptIndexException e = new CorruptIndexException("failed to parse int length (resource=" + in + ")");
-            e.initCause(pe);
-            throw e;
-          }
-          result.bytes = new byte[len];
-          result.offset = 0;
-          result.length = len;
-          in.readBytes(result.bytes, 0, len);
-        } catch (IOException ioe) {
-          throw new RuntimeException(ioe);
-        }
-      }
-
-      @Override
-      public int getValueCount() {
-        return (int)field.numValues;
-      }
-    };
-  }
-
-  @Override
-  public SortedSetDocValues getSortedSet(FieldInfo fieldInfo)  {
-    final OneField field = fields.get(fieldInfo.name);
-
-    // SegmentCoreReaders already verifies this field is
-    // valid:
-    Debug.Assert( field != null;
-
-    final IndexInput in = data.clone();
-    final BytesRef scratch = new BytesRef();
-    final DecimalFormat decoder = new DecimalFormat(field.pattern, new DecimalFormatSymbols(Locale.ROOT));
-    
-    return new SortedSetDocValues() {
-      String[] currentOrds = new String[0];
-      int currentIndex = 0;
-      
-      @Override
-      public long nextOrd() {
-        if (currentIndex == currentOrds.length) {
-          return NO_MORE_ORDS;
-        } else {
-          return Long.parseLong(currentOrds[currentIndex++]);
-        }
-      }
-
-      @Override
-      public void setDocument(int docID) {
-        if (docID < 0 || docID >= maxDoc) {
-          throw new IndexOutOfBoundsException("docID must be 0 .. " + (maxDoc-1) + "; got " + docID);
-        }
-        try {
-          in.seek(field.dataStartFilePointer + field.numValues * (9 + field.pattern.length() + field.maxLength) + docID * (1 + field.ordPattern.length()));
-          SimpleTextUtil.readLine(in, scratch);
-          String ordList = scratch.utf8ToString().trim();
-          if (ordList.isEmpty()) {
-            currentOrds = new String[0];
-          } else {
-            currentOrds = ordList.split(",");
-          }
-          currentIndex = 0;
-        } catch (IOException ioe) {
-          throw new RuntimeException(ioe);
-        }
-      }
-
-      @Override
-      public void lookupOrd(long ord, BytesRef result) {
-        try {
-          if (ord < 0 || ord >= field.numValues) {
-            throw new IndexOutOfBoundsException("ord must be 0 .. " + (field.numValues-1) + "; got " + ord);
-          }
-          in.seek(field.dataStartFilePointer + ord * (9 + field.pattern.length() + field.maxLength));
-          SimpleTextUtil.readLine(in, scratch);
-          Debug.Assert( StringHelper.startsWith(scratch, LENGTH): "got " + scratch.utf8ToString() + " in=" + in;
-          int len;
-          try {
-            len = decoder.parse(new String(scratch.bytes, scratch.offset + LENGTH.length, scratch.length - LENGTH.length, StandardCharsets.UTF_8)).intValue();
-          } catch (ParseException pe) {
-            CorruptIndexException e = new CorruptIndexException("failed to parse int length (resource=" + in + ")");
-            e.initCause(pe);
-            throw e;
-          }
-          result.bytes = new byte[len];
-          result.offset = 0;
-          result.length = len;
-          in.readBytes(result.bytes, 0, len);
-        } catch (IOException ioe) {
-          throw new RuntimeException(ioe);
-        }
-      }
-
-      @Override
-      public long getValueCount() {
-        return field.numValues;
-      }
-    };
-  }
-  
-  @Override
-  public Bits getDocsWithField(FieldInfo field)  {
-    switch (field.getDocValuesType()) {
-      case SORTED_SET:
-        return DocValues.docsWithValue(getSortedSet(field), maxDoc);
-      case SORTED:
-        return DocValues.docsWithValue(getSorted(field), maxDoc);
-      case BINARY:
-        return getBinaryDocsWithField(field);
-      case NUMERIC:
-        return getNumericDocsWithField(field);
-      default:
-        throw new Debug.Assert(ionError();
-    }
-  }
-
-  @Override
-  public void close()  {
-    data.close();
-  }
-
-  /** Used only in ctor: */
-  private void readLine()  {
-    SimpleTextUtil.readLine(data, scratch);
-    //System.out.println("line: " + scratch.utf8ToString());
-  }
-
-  /** Used only in ctor: */
-  private bool startsWith(BytesRef prefix) {
-    return StringHelper.startsWith(scratch, prefix);
-  }
-
-  /** Used only in ctor: */
-  private String stripPrefix(BytesRef prefix)  {
-    return new String(scratch.bytes, scratch.offset + prefix.length, scratch.length - prefix.length, StandardCharsets.UTF_8);
-  }
-
-  @Override
-  public long ramBytesUsed() {
-    return 0;
-  }
-
-  @Override
-  public void checkIntegrity()  {
-    BytesRef scratch = new BytesRef();
-    IndexInput clone = data.clone();
-    clone.seek(0);
-    ChecksumIndexInput input = new BufferedChecksumIndexInput(clone);
-    while(true) {
-      SimpleTextUtil.readLine(input, scratch);
-      if (scratch.equals(END)) {
-        SimpleTextUtil.checkFooter(input);
-        break;
-      }
-    }
-  }
-}
+using System;
+using System.Diagnostics;
+using System.Collections.Generic;
+
+namespace Lucene.Net.Codecs.SimpleText
+{
+
+	/*
+	 * 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.
+	 */
+
+////JAVA TO C# CONVERTER TODO TASK: This Java 'import static' statement cannot be converted to .NET:
+//    import static Lucene.Net.Codecs.SimpleText.SimpleTextDocValuesWriter.END;
+////JAVA TO C# CONVERTER TODO TASK: This Java 'import static' statement cannot be converted to .NET:
+//    import static Lucene.Net.Codecs.SimpleText.SimpleTextDocValuesWriter.FIELD;
+////JAVA TO C# CONVERTER TODO TASK: This Java 'import static' statement cannot be converted to .NET:
+//    import static Lucene.Net.Codecs.SimpleText.SimpleTextDocValuesWriter.LENGTH;
+////JAVA TO C# CONVERTER TODO TASK: This Java 'import static' statement cannot be converted to .NET:
+//    import static Lucene.Net.Codecs.SimpleText.SimpleTextDocValuesWriter.MAXLENGTH;
+////JAVA TO C# CONVERTER TODO TASK: This Java 'import static' statement cannot be converted to .NET:
+//    import static Lucene.Net.Codecs.SimpleText.SimpleTextDocValuesWriter.MINVALUE;
+////JAVA TO C# CONVERTER TODO TASK: This Java 'import static' statement cannot be converted to .NET:
+//    import static Lucene.Net.Codecs.SimpleText.SimpleTextDocValuesWriter.NUMVALUES;
+////JAVA TO C# CONVERTER TODO TASK: This Java 'import static' statement cannot be converted to .NET:
+//    import static Lucene.Net.Codecs.SimpleText.SimpleTextDocValuesWriter.ORDPATTERN;
+////JAVA TO C# CONVERTER TODO TASK: This Java 'import static' statement cannot be converted to .NET:
+//    import static Lucene.Net.Codecs.SimpleText.SimpleTextDocValuesWriter.PATTERN;
+////JAVA TO C# CONVERTER TODO TASK: This Java 'import static' statement cannot be converted to .NET:
+//    import static Lucene.Net.Codecs.SimpleText.SimpleTextDocValuesWriter.TYPE;
+
+
+	using BinaryDocValues = Index.BinaryDocValues;
+	using CorruptIndexException = Index.CorruptIndexException;
+	using DocValues = Index.DocValues;
+	using FieldInfo = Index.FieldInfo;
+	using DocValuesType = Index.FieldInfo.DocValuesType;
+	using IndexFileNames = Index.IndexFileNames;
+	using NumericDocValues = Index.NumericDocValues;
+	using SegmentReadState = Index.SegmentReadState;
+	using SortedDocValues = Index.SortedDocValues;
+	using SortedSetDocValues = Index.SortedSetDocValues;
+	using BufferedChecksumIndexInput = Store.BufferedChecksumIndexInput;
+	using ChecksumIndexInput = Store.ChecksumIndexInput;
+	using IndexInput = Store.IndexInput;
+	using Bits = Util.Bits;
+	using BytesRef = Util.BytesRef;
+	using StringHelper = Util.StringHelper;
+
+	public class SimpleTextDocValuesReader : DocValuesProducer
+	{
+
+	  internal class OneField
+	  {
+		internal long dataStartFilePointer;
+		internal string pattern;
+		internal string ordPattern;
+		internal int maxLength;
+		internal bool fixedLength;
+		internal long minValue;
+		internal long numValues;
+	  }
+
+	  internal readonly int maxDoc;
+	  internal readonly IndexInput data;
+	  internal readonly BytesRef scratch = new BytesRef();
+	  internal readonly IDictionary<string, OneField> fields = new Dictionary<string, OneField>();
+
+//JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in .NET:
+//ORIGINAL LINE: public SimpleTextDocValuesReader(index.SegmentReadState state, String ext) throws java.io.IOException
+	  public SimpleTextDocValuesReader(SegmentReadState state, string ext)
+	  {
+		// System.out.println("dir=" + state.directory + " seg=" + state.segmentInfo.name + " file=" + IndexFileNames.segmentFileName(state.segmentInfo.name, state.segmentSuffix, ext));
+		data = state.directory.openInput(IndexFileNames.segmentFileName(state.segmentInfo.name, state.segmentSuffix, ext), state.context);
+		maxDoc = state.segmentInfo.DocCount;
+		while (true)
+		{
+		  readLine();
+		  //System.out.println("READ field=" + scratch.utf8ToString());
+		  if (scratch.Equals(END))
+		  {
+			break;
+		  }
+		  Debug.Assert(startsWith(FIELD), scratch.utf8ToString());
+		  string fieldName = stripPrefix(FIELD);
+		  //System.out.println("  field=" + fieldName);
+
+		  OneField field = new OneField();
+		  fields[fieldName] = field;
+
+		  readLine();
+		  Debug.Assert(startsWith(TYPE), scratch.utf8ToString());
+
+		  FieldInfo.DocValuesType dvType = FieldInfo.DocValuesType.valueOf(stripPrefix(TYPE));
+		  Debug.Assert(dvType != null);
+		  if (dvType == FieldInfo.DocValuesType.NUMERIC)
+		  {
+			readLine();
+			Debug.Assert(startsWith(MINVALUE), "got " + scratch.utf8ToString() + " field=" + fieldName + " ext=" + ext);
+			field.minValue = Convert.ToInt64(stripPrefix(MINVALUE));
+			readLine();
+			Debug.Assert(startsWith(PATTERN));
+			field.pattern = stripPrefix(PATTERN);
+			field.dataStartFilePointer = data.FilePointer;
+			data.seek(data.FilePointer + (1 + field.pattern.Length + 2) * maxDoc);
+		  }
+		  else if (dvType == FieldInfo.DocValuesType.BINARY)
+		  {
+			readLine();
+			Debug.Assert(startsWith(MAXLENGTH));
+			field.maxLength = Convert.ToInt32(stripPrefix(MAXLENGTH));
+			readLine();
+			Debug.Assert(startsWith(PATTERN));
+			field.pattern = stripPrefix(PATTERN);
+			field.dataStartFilePointer = data.FilePointer;
+			data.seek(data.FilePointer + (9 + field.pattern.Length + field.maxLength + 2) * maxDoc);
+		  }
+		  else if (dvType == FieldInfo.DocValuesType.SORTED || dvType == FieldInfo.DocValuesType.SORTED_SET)
+		  {
+			readLine();
+			Debug.Assert(startsWith(NUMVALUES));
+			field.numValues = Convert.ToInt64(stripPrefix(NUMVALUES));
+			readLine();
+			Debug.Assert(startsWith(MAXLENGTH));
+			field.maxLength = Convert.ToInt32(stripPrefix(MAXLENGTH));
+			readLine();
+			Debug.Assert(startsWith(PATTERN));
+			field.pattern = stripPrefix(PATTERN);
+			readLine();
+			Debug.Assert(startsWith(ORDPATTERN));
+			field.ordPattern = stripPrefix(ORDPATTERN);
+			field.dataStartFilePointer = data.FilePointer;
+			data.seek(data.FilePointer + (9 + field.pattern.Length + field.maxLength) * field.numValues + (1 + field.ordPattern.Length) * maxDoc);
+		  }
+		  else
+		  {
+			throw new AssertionError();
+		  }
+		}
+
+		// We should only be called from above if at least one
+		// field has DVs:
+		Debug.Assert(fields.Count > 0);
+	  }
+
+//JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in .NET:
+//ORIGINAL LINE: @Override public index.NumericDocValues getNumeric(index.FieldInfo fieldInfo) throws java.io.IOException
+	  public override NumericDocValues getNumeric(FieldInfo fieldInfo)
+	  {
+//JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final':
+//ORIGINAL LINE: final OneField field = fields.get(fieldInfo.name);
+		OneField field = fields[fieldInfo.name];
+		Debug.Assert(field != null);
+
+		// SegmentCoreReaders already verifies this field is
+		// valid:
+		Debug.Assert(field != null, "field=" + fieldInfo.name + " fields=" + fields);
+
+//JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final':
+//ORIGINAL LINE: final store.IndexInput in = data.clone();
+		IndexInput @in = data.clone();
+//JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final':
+//ORIGINAL LINE: final util.BytesRef scratch = new util.BytesRef();
+		BytesRef scratch = new BytesRef();
+//JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final':
+//ORIGINAL LINE: final java.text.DecimalFormat decoder = new java.text.DecimalFormat(field.pattern, new java.text.DecimalFormatSymbols(java.util.Locale.ROOT));
+		DecimalFormat decoder = new DecimalFormat(field.pattern, new DecimalFormatSymbols(Locale.ROOT));
+
+		decoder.ParseBigDecimal = true;
+
+		return new NumericDocValuesAnonymousInnerClassHelper(this, field, @in, scratch, decoder);
+	  }
+
+	  private class NumericDocValuesAnonymousInnerClassHelper : NumericDocValues
+	  {
+		  private readonly SimpleTextDocValuesReader outerInstance;
+
+		  private Lucene.Net.Codecs.SimpleText.SimpleTextDocValuesReader.OneField field;
+		  private IndexInput @in;
+		  private BytesRef scratch;
+		  private DecimalFormat decoder;
+
+		  public NumericDocValuesAnonymousInnerClassHelper(SimpleTextDocValuesReader outerInstance, Lucene.Net.Codecs.SimpleText.SimpleTextDocValuesReader.OneField field, IndexInput @in, BytesRef scratch, DecimalFormat decoder)
+		  {
+			  this.outerInstance = outerInstance;
+			  this.field = field;
+			  this.@in = @in;
+			  this.scratch = scratch;
+			  this.decoder = decoder;
+		  }
+
+		  public override long get(int docID)
+		  {
+			try
+			{
+			  //System.out.println(Thread.currentThread().getName() + ": get docID=" + docID + " in=" + in);
+			  if (docID < 0 || docID >= outerInstance.maxDoc)
+			  {
+				throw new System.IndexOutOfRangeException("docID must be 0 .. " + (outerInstance.maxDoc - 1) + "; got " + docID);
+			  }
+			  @in.seek(field.dataStartFilePointer + (1 + field.pattern.Length + 2) * docID);
+			  SimpleTextUtil.ReadLine(@in, scratch);
+			  //System.out.println("parsing delta: " + scratch.utf8ToString());
+			  decimal bd;
+			  try
+			  {
+				bd = (decimal) decoder.parse(scratch.utf8ToString());
+			  }
+			  catch (ParseException pe)
+			  {
+				CorruptIndexException e = new CorruptIndexException("failed to parse BigDecimal value (resource=" + @in + ")");
+				e.initCause(pe);
+				throw e;
+			  }
+			  SimpleTextUtil.ReadLine(@in, scratch); // read the line telling us if its real or not
+			  return System.Numerics.BigInteger.valueOf(field.minValue) + (long)bd.toBigIntegerExact();
+			}
+			catch (IOException ioe)
+			{
+			  throw new Exception(ioe);
+			}
+		  }
+	  }
+
+//JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in .NET:
+//ORIGINAL LINE: private util.Bits getNumericDocsWithField(index.FieldInfo fieldInfo) throws java.io.IOException
+	  private Bits getNumericDocsWithField(FieldInfo fieldInfo)
+	  {
+//JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final':
+//ORIGINAL LINE: final OneField field = fields.get(fieldInfo.name);
+		OneField field = fields[fieldInfo.name];
+//JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final':
+//ORIGINAL LINE: final store.IndexInput in = data.clone();
+		IndexInput @in = data.clone();
+//JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final':
+//ORIGINAL LINE: final util.BytesRef scratch = new util.BytesRef();
+		BytesRef scratch = new BytesRef();
+		return new BitsAnonymousInnerClassHelper(this, field, @in, scratch);
+	  }
+
+	  private class BitsAnonymousInnerClassHelper : Bits
+	  {
+		  private readonly SimpleTextDocValuesReader outerInstance;
+
+		  private Lucene.Net.Codecs.SimpleText.SimpleTextDocValuesReader.OneField field;
+		  private IndexInput @in;
+		  private BytesRef scratch;
+
+		  public BitsAnonymousInnerClassHelper(SimpleTextDocValuesReader outerInstance, Lucene.Net.Codecs.SimpleText.SimpleTextDocValuesReader.OneField field, IndexInput @in, BytesRef scratch)
+		  {
+			  this.outerInstance = outerInstance;
+			  this.field = field;
+			  this.@in = @in;
+			  this.scratch = scratch;
+		  }
+
+		  public override bool get(int index)
+		  {
+			try
+			{
+			  @in.seek(field.dataStartFilePointer + (1 + field.pattern.Length + 2) * index);
+			  SimpleTextUtil.ReadLine(@in, scratch); // data
+			  SimpleTextUtil.ReadLine(@in, scratch); // 'T' or 'F'
+			  return scratch.bytes[scratch.offset] == (sbyte) 'T';
+			}
+			catch (IOException e)
+			{
+			  throw new Exception(e);
+			}
+		  }
+
+		  public override int length()
+		  {
+			return outerInstance.maxDoc;
+		  }
+	  }
+
+//JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in .NET:
+//ORIGINAL LINE: @Override public index.BinaryDocValues getBinary(index.FieldInfo fieldInfo) throws java.io.IOException
+	  public override BinaryDocValues getBinary(FieldInfo fieldInfo)
+	  {
+//JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final':
+//ORIGINAL LINE: final OneField field = fields.get(fieldInfo.name);
+		OneField field = fields[fieldInfo.name];
+
+		// SegmentCoreReaders already verifies this field is
+		// valid:
+		Debug.Assert(field != null);
+
+//JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final':
+//ORIGINAL LINE: final store.IndexInput in = data.clone();
+		IndexInput @in = data.clone();
+//JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final':
+//ORIGINAL LINE: final util.BytesRef scratch = new util.BytesRef();
+		BytesRef scratch = new BytesRef();
+//JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final':
+//ORIGINAL LINE: final java.text.DecimalFormat decoder = new java.text.DecimalFormat(field.pattern, new java.text.DecimalFormatSymbols(java.util.Locale.ROOT));
+		DecimalFormat decoder = new DecimalFormat(field.pattern, new DecimalFormatSymbols(Locale.ROOT));
+
+		return new BinaryDocValuesAnonymousInnerClassHelper(this, field, @in, scratch, decoder);
+	  }
+
+	  private class BinaryDocValuesAnonymousInnerClassHelper : BinaryDocValues
+	  {
+		  private readonly SimpleTextDocValuesReader outerInstance;
+
+		  private Lucene.Net.Codecs.SimpleText.SimpleTextDocValuesReader.OneField field;
+		  private IndexInput @in;
+		  private BytesRef scratch;
+		  private DecimalFormat decoder;
+
+		  public BinaryDocValuesAnonymousInnerClassHelper(SimpleTextDocValuesReader outerInstance, Lucene.Net.Codecs.SimpleText.SimpleTextDocValuesReader.OneField field, IndexInput @in, BytesRef scratch, DecimalFormat decoder)
+		  {
+			  this.outerInstance = outerInstance;
+			  this.field = field;
+			  this.@in = @in;
+			  this.scratch = scratch;
+			  this.decoder = decoder;
+		  }
+
+		  public override void get(int docID, BytesRef result)
+		  {
+			try
+			{
+			  if (docID < 0 || docID >= outerInstance.maxDoc)
+			  {
+				throw new System.IndexOutOfRangeException("docID must be 0 .. " + (outerInstance.maxDoc - 1) + "; got " + docID);
+			  }
+			  @in.seek(field.dataStartFilePointer + (9 + field.pattern.Length + field.maxLength + 2) * docID);
+			  SimpleTextUtil.ReadLine(@in, scratch);
+			  Debug.Assert(StringHelper.StartsWith(scratch, LENGTH));
+			  int len;
+			  try
+			  {
+				len = (int)decoder.parse(new string(scratch.bytes, scratch.offset + LENGTH.length, scratch.length - LENGTH.length, StandardCharsets.UTF_8));
+			  }
+			  catch (ParseException pe)
+			  {
+				CorruptIndexException e = new CorruptIndexException("failed to parse int length (resource=" + @in + ")");
+				e.initCause(pe);
+				throw e;
+			  }
+			  result.bytes = new sbyte[len];
+			  result.offset = 0;
+			  result.length = len;
+			  @in.readBytes(result.bytes, 0, len);
+			}
+			catch (IOException ioe)
+			{
+			  throw new Exception(ioe);
+			}
+		  }
+	  }
+
+//JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in .NET:
+//ORIGINAL LINE: private util.Bits getBinaryDocsWithField(index.FieldInfo fieldInfo) throws java.io.IOException
+	  private Bits getBinaryDocsWithField(FieldInfo fieldInfo)
+	  {
+//JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final':
+//ORIGINAL LINE: final OneField field = fields.get(fieldInfo.name);
+		OneField field = fields[fieldInfo.name];
+//JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final':
+//ORIGINAL LINE: final store.IndexInput in = data.clone();
+		IndexInput @in = data.clone();
+//JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final':
+//ORIGINAL LINE: final util.BytesRef scratch = new util.BytesRef();
+		BytesRef scratch = new BytesRef();
+//JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final':
+//ORIGINAL LINE: final java.text.DecimalFormat decoder = new java.text.DecimalFormat(field.pattern, new java.text.DecimalFormatSymbols(java.util.Locale.ROOT));
+		DecimalFormat decoder = new DecimalFormat(field.pattern, new DecimalFormatSymbols(Locale.ROOT));
+
+		return new BitsAnonymousInnerClassHelper2(this, field, @in, scratch, decoder);
+	  }
+
+	  private class BitsAnonymousInnerClassHelper2 : Bits
+	  {
+		  private readonly SimpleTextDocValuesReader outerInstance;
+
+		  private Lucene.Net.Codecs.SimpleText.SimpleTextDocValuesReader.OneField field;
+		  private IndexInput @in;
+		  private BytesRef scratch;
+		  private DecimalFormat decoder;
+
+		  public BitsAnonymousInnerClassHelper2(SimpleTextDocValuesReader outerInstance, Lucene.Net.Codecs.SimpleText.SimpleTextDocValuesReader.OneField field, IndexInput @in, BytesRef scratch, DecimalFormat decoder)
+		  {
+			  this.outerInstance = outerInstance;
+			  this.field = field;
+			  this.@in = @in;
+			  this.scratch = scratch;
+			  this.decoder = decoder;
+		  }
+
+		  public override bool get(int index)
+		  {
+			try
+			{
+			  @in.seek(field.dataStartFilePointer + (9 + field.pattern.Length + field.maxLength + 2) * index);
+			  SimpleTextUtil.ReadLine(@in, scratch);
+			  Debug.Assert(StringHelper.StartsWith(scratch, LENGTH));
+			  int len;
+			  try
+			  {
+				len = (int)decoder.parse(new string(scratch.bytes, scratch.offset + LENGTH.length, scratch.length - LENGTH.length, StandardCharsets.UTF_8));
+			  }
+			  catch (ParseException pe)
+			  {
+				CorruptIndexException e = new CorruptIndexException("failed to parse int length (resource=" + @in + ")");
+				e.initCause(pe);
+				throw e;
+			  }
+			  // skip past bytes
+			  sbyte[] bytes = new sbyte[len];
+			  @in.readBytes(bytes, 0, len);
+			  SimpleTextUtil.ReadLine(@in, scratch); // newline
+			  SimpleTextUtil.ReadLine(@in, scratch); // 'T' or 'F'
+			  return scratch.bytes[scratch.offset] == (sbyte) 'T';
+			}
+			catch (IOException ioe)
+			{
+			  throw new Exception(ioe);
+			}
+		  }
+
+		  public override int length()
+		  {
+			return outerInstance.maxDoc;
+		  }
+	  }
+
+//JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in .NET:
+//ORIGINAL LINE: @Override public index.SortedDocValues getSorted(index.FieldInfo fieldInfo) throws java.io.IOException
+	  public override SortedDocValues getSorted(FieldInfo fieldInfo)
+	  {
+//JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final':
+//ORIGINAL LINE: final OneField field = fields.get(fieldInfo.name);
+		OneField field = fields[fieldInfo.name];
+
+		// SegmentCoreReaders already verifies this field is
+		// valid:
+		Debug.Assert(field != null);
+
+//JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final':
+//ORIGINAL LINE: final store.IndexInput in = data.clone();
+		IndexInput @in = data.clone();
+//JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final':
+//ORIGINAL LINE: final util.BytesRef scratch = new util.BytesRef();
+		BytesRef scratch = new BytesRef();
+//JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final':
+//ORIGINAL LINE: final java.text.DecimalFormat decoder = new java.text.DecimalFormat(field.pattern, new java.text.DecimalFormatSymbols(java.util.Locale.ROOT));
+		DecimalFormat decoder = new DecimalFormat(field.pattern, new DecimalFormatSymbols(Locale.ROOT));
+//JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final':
+//ORIGINAL LINE: final java.text.DecimalFormat ordDecoder = new java.text.DecimalFormat(field.ordPattern, new java.text.DecimalFormatSymbols(java.util.Locale.ROOT));
+		DecimalFormat ordDecoder = new DecimalFormat(field.ordPattern, new DecimalFormatSymbols(Locale.ROOT));
+
+		return new SortedDocValuesAnonymousInnerClassHelper(this, field, @in, scratch, decoder, ordDecoder);
+	  }
+
+	  private class SortedDocValuesAnonymousInnerClassHelper : SortedDocValues
+	  {
+		  private readonly SimpleTextDocValuesReader outerInstance;
+
+		  private Lucene.Net.Codecs.SimpleText.SimpleTextDocValuesReader.OneField field;
+		  private IndexInput @in;
+		  private BytesRef scratch;
+		  private DecimalFormat decoder;
+		  private DecimalFormat ordDecoder;
+
+		  public SortedDocValuesAnonymousInnerClassHelper(SimpleTextDocValuesReader outerInstance, Lucene.Net.Codecs.SimpleText.SimpleTextDocValuesReader.OneField field, IndexInput @in, BytesRef scratch, DecimalFormat decoder, DecimalFormat ordDecoder)
+		  {
+			  this.outerInstance = outerInstance;
+			  this.field = field;
+			  this.@in = @in;
+			  this.scratch = scratch;
+			  this.decoder = decoder;
+			  this.ordDecoder = ordDecoder;
+		  }
+
+		  public override int getOrd(int docID)
+		  {
+			if (docID < 0 || docID >= outerInstance.maxDoc)
+			{
+			  throw new System.IndexOutOfRangeException("docID must be 0 .. " + (outerInstance.maxDoc - 1) + "; got " + docID);
+			}
+			try
+			{
+			  @in.seek(field.dataStartFilePointer + field.numValues * (9 + field.pattern.Length + field.maxLength) + docID * (1 + field.ordPattern.Length));
+			  SimpleTextUtil.ReadLine(@in, scratch);
+			  try
+			  {
+				return (long)(int) ordDecoder.parse(scratch.utf8ToString()) - 1;
+			  }
+			  catch (ParseException pe)
+			  {
+				CorruptIndexException e = new CorruptIndexException("failed to parse ord (resource=" + @in + ")");
+				e.initCause(pe);
+				throw e;
+			  }
+			}
+			catch (IOException ioe)
+			{
+			  throw new Exception(ioe);
+			}
+		  }
+
+		  public override void lookupOrd(int ord, BytesRef result)
+		  {
+			try
+			{
+			  if (ord < 0 || ord >= field.numValues)
+			  {
+				throw new System.IndexOutOfRangeException("ord must be 0 .. " + (field.numValues - 1) + "; got " + ord);
+			  }
+			  @in.seek(field.dataStartFilePointer + ord * (9 + field.pattern.Length + field.maxLength));
+			  SimpleTextUtil.ReadLine(@in, scratch);
+			  Debug.Assert(StringHelper.StartsWith(scratch, LENGTH), "got " + scratch.utf8ToString() + " in=" + @in);
+			  int len;
+			  try
+			  {
+				len = (int)decoder.parse(new string(scratch.bytes, scratch.offset + LENGTH.length, scratch.length - LENGTH.length, StandardCharsets.UTF_8));
+			  }
+			  catch (ParseException pe)
+			  {
+				CorruptIndexException e = new CorruptIndexException("failed to parse int length (resource=" + @in + ")");
+				e.initCause(pe);
+				throw e;
+			  }
+			  result.bytes = new sbyte[len];
+			  result.offset = 0;
+			  result.length = len;
+			  @in.readBytes(result.bytes, 0, len);
+			}
+			catch (IOException ioe)
+			{
+			  throw new Exception(ioe);
+			}
+		  }
+
+		  public override int ValueCount
+		  {
+			  get
+			  {
+				return (int)field.numValues;
+			  }
+		  }
+	  }
+
+//JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in .NET:
+//ORIGINAL LINE: @Override public index.SortedSetDocValues getSortedSet(index.FieldInfo fieldInfo) throws java.io.IOException
+	  public override SortedSetDocValues getSortedSet(FieldInfo fieldInfo)
+	  {
+//JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final':
+//ORIGINAL LINE: final OneField field = fields.get(fieldInfo.name);
+		OneField field = fields[fieldInfo.name];
+
+		// SegmentCoreReaders already verifies this field is
+		// valid:
+		Debug.Assert(field != null);
+
+//JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final':
+//ORIGINAL LINE: final store.IndexInput in = data.clone();
+		IndexInput @in = data.clone();
+//JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final':
+//ORIGINAL LINE: final util.BytesRef scratch = new util.BytesRef();
+		BytesRef scratch = new BytesRef();
+//JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final':
+//ORIGINAL LINE: final java.text.DecimalFormat decoder = new java.text.DecimalFormat(field.pattern, new java.text.DecimalFormatSymbols(java.util.Locale.ROOT));
+		DecimalFormat decoder = new DecimalFormat(field.pattern, new DecimalFormatSymbols(Locale.ROOT));
+
+		return new SortedSetDocValuesAnonymousInnerClassHelper(this, field, @in, scratch, decoder);
+	  }
+
+	  private class SortedSetDocValuesAnonymousInnerClassHelper : SortedSetDocValues
+	  {
+		  private readonly SimpleTextDocValuesReader outerInstance;
+
+		  private Lucene.Net.Codecs.SimpleText.SimpleTextDocValuesReader.OneField field;
+		  private IndexInput @in;
+		  private BytesRef scratch;
+		  private DecimalFormat decoder;
+
+		  public SortedSetDocValuesAnonymousInnerClassHelper(SimpleTextDocValuesReader outerInstance, Lucene.Net.Codecs.SimpleText.SimpleTextDocValuesReader.OneField field, IndexInput @in, BytesRef scratch, DecimalFormat decoder)
+		  {
+			  this.outerInstance = outerInstance;
+			  this.field = field;
+			  this.@in = @in;
+			  this.scratch = scratch;
+			  this.decoder = decoder;
+			  currentOrds = new string[0];
+			  currentIndex = 0;
+		  }
+
+		  internal string[] currentOrds;
+		  internal int currentIndex;
+
+		  public override long nextOrd()
+		  {
+			if (currentIndex == currentOrds.length)
+			{
+			  return NO_MORE_ORDS;
+			}
+			else
+			{
+			  return Convert.ToInt64(currentOrds[currentIndex++]);
+			}
+		  }
+
+		  public override int Document
+		  {
+			  set
+			  {
+				if (value < 0 || value >= outerInstance.maxDoc)
+				{
+				  throw new System.IndexOutOfRangeException("docID must be 0 .. " + (outerInstance.maxDoc - 1) + "; got " + value);
+				}
+				try
+				{
+				  @in.seek(field.dataStartFilePointer + field.numValues * (9 + field.pattern.Length + field.maxLength) + value * (1 + field.ordPattern.Length));
+				  SimpleTextUtil.ReadLine(@in, scratch);
+				  string ordList = scratch.utf8ToString().Trim();
+				  if (ordList.Length == 0)
+				  {
+					currentOrds = new string[0];
+				  }
+				  else
+				  {
+					currentOrds = ordList.Split(",", true);
+				  }
+				  currentIndex = 0;
+				}
+				catch (IOException ioe)
+				{
+				  throw new Exception(ioe);
+				}
+			  }
+		  }
+
+		  public override void lookupOrd(long ord, BytesRef result)
+		  {
+			try
+			{
+			  if (ord < 0 || ord >= field.numValues)
+			  {
+				throw new System.IndexOutOfRangeException("ord must be 0 .. " + (field.numValues - 1) + "; got " + ord);
+			  }
+			  @in.seek(field.dataStartFilePointer + ord * (9 + field.pattern.Length + field.maxLength));
+			  SimpleTextUtil.ReadLine(@in, scratch);
+			  Debug.Assert(StringHelper.StartsWith(scratch, LENGTH), "got " + scratch.utf8ToString() + " in=" + @in);
+			  int len;
+			  try
+			  {
+				len = (int)decoder.parse(new string(scratch.bytes, scratch.offset + LENGTH.length, scratch.length - LENGTH.length, StandardCharsets.UTF_8));
+			  }
+			  catch (ParseException pe)
+			  {
+				CorruptIndexException e = new CorruptIndexException("failed to parse int length (resource=" + @in + ")");
+				e.initCause(pe);
+				throw e;
+			  }
+			  result.bytes = new sbyte[len];
+			  result.offset = 0;
+			  result.length = len;
+			  @in.readBytes(result.bytes, 0, len);
+			}
+			catch (IOException ioe)
+			{
+			  throw new Exception(ioe);
+			}
+		  }
+
+		  public override long ValueCount
+		  {
+			  get
+			  {
+				return field.numValues;
+			  }
+		  }
+	  }
+
+//JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in .NET:
+//ORIGINAL LINE: @Override public util.Bits getDocsWithField(index.FieldInfo field) throws java.io.IOException
+	  public override Bits getDocsWithField(FieldInfo field)
+	  {
+		switch (field.DocValuesType)
+		{
+		  case SORTED_SET:
+			return DocValues.docsWithValue(getSortedSet(field), maxDoc);
+		  case SORTED:
+			return DocValues.docsWithValue(getSorted(field), maxDoc);
+		  case BINARY:
+			return getBinaryDocsWithField(field);
+		  case NUMERIC:
+			return getNumericDocsWithField(field);
+		  default:
+			throw new AssertionError();
+		}
+	  }
+
+//JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in .NET:
+//ORIGINAL LINE: @Override public void close() throws java.io.IOException
+	  public override void close()
+	  {
+		data.close();
+	  }
+
+	  /// <summary>
+	  /// Used only in ctor: </summary>
+//JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in .NET:
+//ORIGINAL LINE: private void readLine() throws java.io.IOException
+	  private void readLine()
+	  {
+		SimpleTextUtil.ReadLine(data, scratch);
+		//System.out.println("line: " + scratch.utf8ToString());
+	  }
+
+	  /// <summary>
+	  /// Used only in ctor: </summary>
+	  private bool StartsWith(BytesRef prefix)
+	  {
+		return StringHelper.StartsWith(scratch, prefix);
+	  }
+
+	  /// <summary>
+	  /// Used only in ctor: </summary>
+//JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in .NET:
+//ORIGINAL LINE: private String stripPrefix(util.BytesRef prefix) throws java.io.IOException
+	  private string stripPrefix(BytesRef prefix)
+	  {
+		return new string(scratch.bytes, scratch.offset + prefix.length, scratch.length - prefix.length, StandardCharsets.UTF_8);
+	  }
+
+	  public override long ramBytesUsed()
+	  {
+		return 0;
+	  }
+
+//JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in .NET:
+//ORIGINAL LINE: @Override public void checkIntegrity() throws java.io.IOException
+	  public override void checkIntegrity()
+	  {
+		BytesRef scratch = new BytesRef();
+		IndexInput clone = data.clone();
+		clone.seek(0);
+		ChecksumIndexInput input = new BufferedChecksumIndexInput(clone);
+		while (true)
+		{
+		  SimpleTextUtil.ReadLine(input, scratch);
+		  if (scratch.Equals(END))
+		  {
+			SimpleTextUtil.CheckFooter(input);
+			break;
+		  }
+		}
+	  }
+	}
+
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/cf1df6be/src/Lucene.Net.Codecs/SimpleText/SimpleTextDocValuesWriter.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Codecs/SimpleText/SimpleTextDocValuesWriter.cs b/src/Lucene.Net.Codecs/SimpleText/SimpleTextDocValuesWriter.cs
index 6f89c10..1afcd00 100644
--- a/src/Lucene.Net.Codecs/SimpleText/SimpleTextDocValuesWriter.cs
+++ b/src/Lucene.Net.Codecs/SimpleText/SimpleTextDocValuesWriter.cs
@@ -1,411 +1,485 @@
-package org.apache.lucene.codecs.simpletext;
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-import java.io.IOException;
-import java.math.BigInteger;
-import java.text.DecimalFormat;
-import java.text.DecimalFormatSymbols;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.Locale;
-import java.util.Set;
-
-import org.apache.lucene.codecs.DocValuesConsumer;
-import org.apache.lucene.index.FieldInfo;
-import org.apache.lucene.index.IndexFileNames;
-import org.apache.lucene.index.SegmentWriteState;
-import org.apache.lucene.index.FieldInfo.DocValuesType;
-import org.apache.lucene.store.IndexOutput;
-import org.apache.lucene.util.BytesRef;
-import org.apache.lucene.util.IOUtils;
-
-class SimpleTextDocValuesWriter extends DocValuesConsumer {
-  final static BytesRef END     = new BytesRef("END");
-  final static BytesRef FIELD   = new BytesRef("field ");
-  final static BytesRef TYPE    = new BytesRef("  type ");
-  // used for numerics
-  final static BytesRef MINVALUE = new BytesRef("  minvalue ");
-  final static BytesRef PATTERN  = new BytesRef("  pattern ");
-  // used for bytes
-  final static BytesRef LENGTH = new BytesRef("length ");
-  final static BytesRef MAXLENGTH = new BytesRef("  maxlength ");
-  // used for sorted bytes
-  final static BytesRef NUMVALUES = new BytesRef("  numvalues ");
-  final static BytesRef ORDPATTERN = new BytesRef("  ordpattern ");
-  
-  IndexOutput data;
-  final BytesRef scratch = new BytesRef();
-  final int numDocs;
-  private final Set<String> fieldsSeen = new HashSet<>(); // for Debug.Assert(ing
-  
-  public SimpleTextDocValuesWriter(SegmentWriteState state, String ext)  {
-    // System.out.println("WRITE: " + IndexFileNames.segmentFileName(state.segmentInfo.name, state.segmentSuffix, ext) + " " + state.segmentInfo.getDocCount() + " docs");
-    data = state.directory.createOutput(IndexFileNames.segmentFileName(state.segmentInfo.name, state.segmentSuffix, ext), state.context);
-    numDocs = state.segmentInfo.getDocCount();
-  }
-
-  // for Debug.Assert(ing
-  private bool fieldSeen(String field) {
-    Debug.Assert( !fieldsSeen.contains(field): "field \"" + field + "\" was added more than once during flush";
-    fieldsSeen.add(field);
-    return true;
-  }
-
-  @Override
-  public void addNumericField(FieldInfo field, Iterable<Number> values)  {
-    Debug.Assert( fieldSeen(field.name);
-    Debug.Assert( (field.getDocValuesType() == FieldInfo.DocValuesType.NUMERIC ||
-            field.getNormType() == FieldInfo.DocValuesType.NUMERIC);
-    writeFieldEntry(field, FieldInfo.DocValuesType.NUMERIC);
-
-    // first pass to find min/max
-    long minValue = Long.MAX_VALUE;
-    long maxValue = Long.MIN_VALUE;
-    for(Number n : values) {
-      long v = n == null ? 0 : n.longValue();
-      minValue = Math.min(minValue, v);
-      maxValue = Math.max(maxValue, v);
-    }
-    
-    // write our minimum value to the .dat, all entries are deltas from that
-    SimpleTextUtil.write(data, MINVALUE);
-    SimpleTextUtil.write(data, Long.toString(minValue), scratch);
-    SimpleTextUtil.writeNewline(data);
-    
-    // build up our fixed-width "simple text packed ints"
-    // format
-    BigInteger maxBig = BigInteger.valueOf(maxValue);
-    BigInteger minBig = BigInteger.valueOf(minValue);
-    BigInteger diffBig = maxBig.subtract(minBig);
-    int maxBytesPerValue = diffBig.toString().length();
-    StringBuilder sb = new StringBuilder();
-    for (int i = 0; i < maxBytesPerValue; i++) {
-      sb.append('0');
-    }
-    
-    // write our pattern to the .dat
-    SimpleTextUtil.write(data, PATTERN);
-    SimpleTextUtil.write(data, sb.toString(), scratch);
-    SimpleTextUtil.writeNewline(data);
-
-    final String patternString = sb.toString();
-    
-    final DecimalFormat encoder = new DecimalFormat(patternString, new DecimalFormatSymbols(Locale.ROOT));
-    
-    int numDocsWritten = 0;
-
-    // second pass to write the values
-    for(Number n : values) {
-      long value = n == null ? 0 : n.longValue();
-      Debug.Assert( value >= minValue;
-      Number delta = BigInteger.valueOf(value).subtract(BigInteger.valueOf(minValue));
-      String s = encoder.format(delta);
-      Debug.Assert( s.length() == patternString.length();
-      SimpleTextUtil.write(data, s, scratch);
-      SimpleTextUtil.writeNewline(data);
-      if (n == null) {
-        SimpleTextUtil.write(data, "F", scratch);
-      } else {
-        SimpleTextUtil.write(data, "T", scratch);
-      }
-      SimpleTextUtil.writeNewline(data);
-      numDocsWritten++;
-      Debug.Assert( numDocsWritten <= numDocs;
-    }
-
-    Debug.Assert( numDocs == numDocsWritten: "numDocs=" + numDocs + " numDocsWritten=" + numDocsWritten;
-  }
-
-  @Override
-  public void addBinaryField(FieldInfo field, Iterable<BytesRef> values)  {
-    Debug.Assert( fieldSeen(field.name);
-    Debug.Assert( field.getDocValuesType() == DocValuesType.BINARY;
-    int maxLength = 0;
-    for(BytesRef value : values) {
-      final int length = value == null ? 0 : value.length;
-      maxLength = Math.max(maxLength, length);
-    }
-    writeFieldEntry(field, FieldInfo.DocValuesType.BINARY);
-
-    // write maxLength
-    SimpleTextUtil.write(data, MAXLENGTH);
-    SimpleTextUtil.write(data, Integer.toString(maxLength), scratch);
-    SimpleTextUtil.writeNewline(data);
-    
-    int maxBytesLength = Long.toString(maxLength).length();
-    StringBuilder sb = new StringBuilder();
-    for (int i = 0; i < maxBytesLength; i++) {
-      sb.append('0');
-    }
-    // write our pattern for encoding lengths
-    SimpleTextUtil.write(data, PATTERN);
-    SimpleTextUtil.write(data, sb.toString(), scratch);
-    SimpleTextUtil.writeNewline(data);
-    final DecimalFormat encoder = new DecimalFormat(sb.toString(), new DecimalFormatSymbols(Locale.ROOT));
-
-    int numDocsWritten = 0;
-    for(BytesRef value : values) {
-      // write length
-      final int length = value == null ? 0 : value.length;
-      SimpleTextUtil.write(data, LENGTH);
-      SimpleTextUtil.write(data, encoder.format(length), scratch);
-      SimpleTextUtil.writeNewline(data);
-        
-      // write bytes -- don't use SimpleText.write
-      // because it escapes:
-      if (value != null) {
-        data.writeBytes(value.bytes, value.offset, value.length);
-      }
-
-      // pad to fit
-      for (int i = length; i < maxLength; i++) {
-        data.writeByte((byte)' ');
-      }
-      SimpleTextUtil.writeNewline(data);
-      if (value == null) {
-        SimpleTextUtil.write(data, "F", scratch);
-      } else {
-        SimpleTextUtil.write(data, "T", scratch);
-      }
-      SimpleTextUtil.writeNewline(data);
-      numDocsWritten++;
-    }
-
-    Debug.Assert( numDocs == numDocsWritten;
-  }
-  
-  @Override
-  public void addSortedField(FieldInfo field, Iterable<BytesRef> values, Iterable<Number> docToOrd)  {
-    Debug.Assert( fieldSeen(field.name);
-    Debug.Assert( field.getDocValuesType() == DocValuesType.SORTED;
-    writeFieldEntry(field, FieldInfo.DocValuesType.SORTED);
-
-    int valueCount = 0;
-    int maxLength = -1;
-    for(BytesRef value : values) {
-      maxLength = Math.max(maxLength, value.length);
-      valueCount++;
-    }
-
-    // write numValues
-    SimpleTextUtil.write(data, NUMVALUES);
-    SimpleTextUtil.write(data, Integer.toString(valueCount), scratch);
-    SimpleTextUtil.writeNewline(data);
-    
-    // write maxLength
-    SimpleTextUtil.write(data, MAXLENGTH);
-    SimpleTextUtil.write(data, Integer.toString(maxLength), scratch);
-    SimpleTextUtil.writeNewline(data);
-    
-    int maxBytesLength = Integer.toString(maxLength).length();
-    StringBuilder sb = new StringBuilder();
-    for (int i = 0; i < maxBytesLength; i++) {
-      sb.append('0');
-    }
-    
-    // write our pattern for encoding lengths
-    SimpleTextUtil.write(data, PATTERN);
-    SimpleTextUtil.write(data, sb.toString(), scratch);
-    SimpleTextUtil.writeNewline(data);
-    final DecimalFormat encoder = new DecimalFormat(sb.toString(), new DecimalFormatSymbols(Locale.ROOT));
-    
-    int maxOrdBytes = Long.toString(valueCount+1L).length();
-    sb.setLength(0);
-    for (int i = 0; i < maxOrdBytes; i++) {
-      sb.append('0');
-    }
-    
-    // write our pattern for ords
-    SimpleTextUtil.write(data, ORDPATTERN);
-    SimpleTextUtil.write(data, sb.toString(), scratch);
-    SimpleTextUtil.writeNewline(data);
-    final DecimalFormat ordEncoder = new DecimalFormat(sb.toString(), new DecimalFormatSymbols(Locale.ROOT));
-
-    // for Debug.Assert(s:
-    int valuesSeen = 0;
-
-    for(BytesRef value : values) {
-      // write length
-      SimpleTextUtil.write(data, LENGTH);
-      SimpleTextUtil.write(data, encoder.format(value.length), scratch);
-      SimpleTextUtil.writeNewline(data);
-        
-      // write bytes -- don't use SimpleText.write
-      // because it escapes:
-      data.writeBytes(value.bytes, value.offset, value.length);
-
-      // pad to fit
-      for (int i = value.length; i < maxLength; i++) {
-        data.writeByte((byte)' ');
-      }
-      SimpleTextUtil.writeNewline(data);
-      valuesSeen++;
-      Debug.Assert( valuesSeen <= valueCount;
-    }
-
-    Debug.Assert( valuesSeen == valueCount;
-
-    for(Number ord : docToOrd) {
-      SimpleTextUtil.write(data, ordEncoder.format(ord.longValue()+1), scratch);
-      SimpleTextUtil.writeNewline(data);
-    }
-  }
-
-  @Override
-  public void addSortedSetField(FieldInfo field, Iterable<BytesRef> values, Iterable<Number> docToOrdCount, Iterable<Number> ords)  {
-    Debug.Assert( fieldSeen(field.name);
-    Debug.Assert( field.getDocValuesType() == DocValuesType.SORTED_SET;
-    writeFieldEntry(field, FieldInfo.DocValuesType.SORTED_SET);
-
-    long valueCount = 0;
-    int maxLength = 0;
-    for(BytesRef value : values) {
-      maxLength = Math.max(maxLength, value.length);
-      valueCount++;
-    }
-
-    // write numValues
-    SimpleTextUtil.write(data, NUMVALUES);
-    SimpleTextUtil.write(data, Long.toString(valueCount), scratch);
-    SimpleTextUtil.writeNewline(data);
-    
-    // write maxLength
-    SimpleTextUtil.write(data, MAXLENGTH);
-    SimpleTextUtil.write(data, Integer.toString(maxLength), scratch);
-    SimpleTextUtil.writeNewline(data);
-    
-    int maxBytesLength = Integer.toString(maxLength).length();
-    StringBuilder sb = new StringBuilder();
-    for (int i = 0; i < maxBytesLength; i++) {
-      sb.append('0');
-    }
-    
-    // write our pattern for encoding lengths
-    SimpleTextUtil.write(data, PATTERN);
-    SimpleTextUtil.write(data, sb.toString(), scratch);
-    SimpleTextUtil.writeNewline(data);
-    final DecimalFormat encoder = new DecimalFormat(sb.toString(), new DecimalFormatSymbols(Locale.ROOT));
-    
-    // compute ord pattern: this is funny, we encode all values for all docs to find the maximum length
-    int maxOrdListLength = 0;
-    StringBuilder sb2 = new StringBuilder();
-    Iterator<Number> ordStream = ords.iterator();
-    for (Number n : docToOrdCount) {
-      sb2.setLength(0);
-      int count = n.intValue();
-      for (int i = 0; i < count; i++) {
-        long ord = ordStream.next().longValue();
-        if (sb2.length() > 0) {
-          sb2.append(",");
-        }
-        sb2.append(Long.toString(ord));
-      }
-      maxOrdListLength = Math.max(maxOrdListLength, sb2.length());
-    }
-     
-    sb2.setLength(0);
-    for (int i = 0; i < maxOrdListLength; i++) {
-      sb2.append('X');
-    }
-    
-    // write our pattern for ord lists
-    SimpleTextUtil.write(data, ORDPATTERN);
-    SimpleTextUtil.write(data, sb2.toString(), scratch);
-    SimpleTextUtil.writeNewline(data);
-    
-    // for Debug.Assert(s:
-    long valuesSeen = 0;
-
-    for(BytesRef value : values) {
-      // write length
-      SimpleTextUtil.write(data, LENGTH);
-      SimpleTextUtil.write(data, encoder.format(value.length), scratch);
-      SimpleTextUtil.writeNewline(data);
-        
-      // write bytes -- don't use SimpleText.write
-      // because it escapes:
-      data.writeBytes(value.bytes, value.offset, value.length);
-
-      // pad to fit
-      for (int i = value.length; i < maxLength; i++) {
-        data.writeByte((byte)' ');
-      }
-      SimpleTextUtil.writeNewline(data);
-      valuesSeen++;
-      Debug.Assert( valuesSeen <= valueCount;
-    }
-
-    Debug.Assert( valuesSeen == valueCount;
-
-    ordStream = ords.iterator();
-    
-    // write the ords for each doc comma-separated
-    for(Number n : docToOrdCount) {
-      sb2.setLength(0);
-      int count = n.intValue();
-      for (int i = 0; i < count; i++) {
-        long ord = ordStream.next().longValue();
-        if (sb2.length() > 0) {
-          sb2.append(",");
-        }
-        sb2.append(Long.toString(ord));
-      }
-      // now pad to fit: these are numbers so spaces work well. reader calls trim()
-      int numPadding = maxOrdListLength - sb2.length();
-      for (int i = 0; i < numPadding; i++) {
-        sb2.append(' ');
-      }
-      SimpleTextUtil.write(data, sb2.toString(), scratch);
-      SimpleTextUtil.writeNewline(data);
-    }
-  }
-
-  /** write the header for this field */
-  private void writeFieldEntry(FieldInfo field, FieldInfo.DocValuesType type)  {
-    SimpleTextUtil.write(data, FIELD);
-    SimpleTextUtil.write(data, field.name, scratch);
-    SimpleTextUtil.writeNewline(data);
-    
-    SimpleTextUtil.write(data, TYPE);
-    SimpleTextUtil.write(data, type.toString(), scratch);
-    SimpleTextUtil.writeNewline(data);
-  }
-  
-  @Override
-  public void close()  {
-    if (data != null) {
-      bool success = false;
-      try {
-        Debug.Assert( !fieldsSeen.isEmpty();
-        // TODO: sheisty to do this here?
-        SimpleTextUtil.write(data, END);
-        SimpleTextUtil.writeNewline(data);
-        SimpleTextUtil.writeChecksum(data, scratch);
-        success = true;
-      } finally {
-        if (success) {
-          IOUtils.close(data);
-        } else {
-          IOUtils.closeWhileHandlingException(data);
-        }
-        data = null;
-      }
-    }
-  }
-}
+using System;
+using System.Diagnostics;
+using System.Collections.Generic;
+using System.Text;
+
+namespace Lucene.Net.Codecs.SimpleText
+{
+
+	/*
+	 * 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.
+	 */
+
+
+	using FieldInfo = Index.FieldInfo;
+	using IndexFileNames = Index.IndexFileNames;
+	using SegmentWriteState = Index.SegmentWriteState;
+	using DocValuesType = Index.FieldInfo.DocValuesType;
+	using IndexOutput = Store.IndexOutput;
+	using BytesRef = Util.BytesRef;
+	using IOUtils = Util.IOUtils;
+
+	public class SimpleTextDocValuesWriter : DocValuesConsumer
+	{
+	  internal static readonly BytesRef END = new BytesRef("END");
+	  internal static readonly BytesRef FIELD = new BytesRef("field ");
+	  internal static readonly BytesRef TYPE = new BytesRef("  type ");
+	  // used for numerics
+	  internal static readonly BytesRef MINVALUE = new BytesRef("  minvalue ");
+	  internal static readonly BytesRef PATTERN = new BytesRef("  pattern ");
+	  // used for bytes
+	  internal static readonly BytesRef LENGTH = new BytesRef("length ");
+	  internal static readonly BytesRef MAXLENGTH = new BytesRef("  maxlength ");
+	  // used for sorted bytes
+	  internal static readonly BytesRef NUMVALUES = new BytesRef("  numvalues ");
+	  internal static readonly BytesRef ORDPATTERN = new BytesRef("  ordpattern ");
+
+	  internal IndexOutput data;
+	  internal readonly BytesRef scratch = new BytesRef();
+	  internal readonly int numDocs;
+	  private readonly HashSet<string> fieldsSeen = new HashSet<string>(); // for asserting
+
+//JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in .NET:
+//ORIGINAL LINE: public SimpleTextDocValuesWriter(index.SegmentWriteState state, String ext) throws java.io.IOException
+	  public SimpleTextDocValuesWriter(SegmentWriteState state, string ext)
+	  {
+		// System.out.println("WRITE: " + IndexFileNames.segmentFileName(state.segmentInfo.name, state.segmentSuffix, ext) + " " + state.segmentInfo.getDocCount() + " docs");
+		data = state.directory.createOutput(IndexFileNames.segmentFileName(state.segmentInfo.name, state.segmentSuffix, ext), state.context);
+		numDocs = state.segmentInfo.DocCount;
+	  }
+
+	  // for asserting
+	  private bool fieldSeen(string field)
+	  {
+		Debug.Assert(!fieldsSeen.Contains(field), "field \"" + field + "\" was added more than once during flush");
+		fieldsSeen.Add(field);
+		return true;
+	  }
+
+//JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in .NET:
+//ORIGINAL LINE: @Override public void addNumericField(index.FieldInfo field, Iterable<Number> values) throws java.io.IOException
+	  public override void addNumericField(FieldInfo field, IEnumerable<Number> values)
+	  {
+		Debug.Assert(fieldSeen(field.name));
+		assert(field.DocValuesType == FieldInfo.DocValuesType.NUMERIC || field.NormType == FieldInfo.DocValuesType.NUMERIC);
+		writeFieldEntry(field, FieldInfo.DocValuesType.NUMERIC);
+
+		// first pass to find min/max
+		long minValue = long.MaxValue;
+		long maxValue = long.MinValue;
+		foreach (Number n in values)
+		{
+		  long v = n == null ? 0 : (long)n;
+		  minValue = Math.Min(minValue, v);
+		  maxValue = Math.Max(maxValue, v);
+		}
+
+		// write our minimum value to the .dat, all entries are deltas from that
+		SimpleTextUtil.write(data, MINVALUE);
+		SimpleTextUtil.write(data, Convert.ToString(minValue), scratch);
+		SimpleTextUtil.WriteNewline(data);
+
+		// build up our fixed-width "simple text packed ints"
+		// format
+		System.Numerics.BigInteger maxBig = System.Numerics.BigInteger.valueOf(maxValue);
+		System.Numerics.BigInteger minBig = System.Numerics.BigInteger.valueOf(minValue);
+		System.Numerics.BigInteger diffBig = maxBig - minBig;
+		int maxBytesPerValue = diffBig.ToString().Length;
+		StringBuilder sb = new StringBuilder();
+		for (int i = 0; i < maxBytesPerValue; i++)
+		{
+		  sb.Append('0');
+		}
+
+		// write our pattern to the .dat
+		SimpleTextUtil.write(data, PATTERN);
+		SimpleTextUtil.write(data, sb.ToString(), scratch);
+		SimpleTextUtil.WriteNewline(data);
+
+//JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final':
+//ORIGINAL LINE: final String patternString = sb.toString();
+		string patternString = sb.ToString();
+
+//JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final':
+//ORIGINAL LINE: final java.text.DecimalFormat encoder = new java.text.DecimalFormat(patternString, new java.text.DecimalFormatSymbols(java.util.Locale.ROOT));
+		DecimalFormat encoder = new DecimalFormat(patternString, new DecimalFormatSymbols(Locale.ROOT));
+
+		int numDocsWritten = 0;
+
+		// second pass to write the values
+		foreach (Number n in values)
+		{
+		  long value = n == null ? 0 : (long)n;
+		  Debug.Assert(value >= minValue);
+		  Number delta = System.Numerics.BigInteger.valueOf(value) - System.Numerics.BigInteger.valueOf(minValue);
+		  string s = encoder.format(delta);
+		  Debug.Assert(s.Length == patternString.Length);
+		  SimpleTextUtil.write(data, s, scratch);
+		  SimpleTextUtil.WriteNewline(data);
+		  if (n == null)
+		  {
+			SimpleTextUtil.write(data, "F", scratch);
+		  }
+		  else
+		  {
+			SimpleTextUtil.write(data, "T", scratch);
+		  }
+		  SimpleTextUtil.WriteNewline(data);
+		  numDocsWritten++;
+		  Debug.Assert(numDocsWritten <= numDocs);
+		}
+
+		Debug.Assert(numDocs == numDocsWritten, "numDocs=" + numDocs + " numDocsWritten=" + numDocsWritten);
+	  }
+
+//JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in .NET:
+//ORIGINAL LINE: @Override public void addBinaryField(index.FieldInfo field, Iterable<util.BytesRef> values) throws java.io.IOException
+	  public override void addBinaryField(FieldInfo field, IEnumerable<BytesRef> values)
+	  {
+		Debug.Assert(fieldSeen(field.name));
+		Debug.Assert(field.DocValuesType == FieldInfo.DocValuesType.BINARY);
+		int maxLength = 0;
+		foreach (BytesRef value in values)
+		{
+//JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final':
+//ORIGINAL LINE: final int length = value == null ? 0 : value.length;
+		  int length = value == null ? 0 : value.length;
+		  maxLength = Math.Max(maxLength, length);
+		}
+		writeFieldEntry(field, FieldInfo.DocValuesType.BINARY);
+
+		// write maxLength
+		SimpleTextUtil.write(data, MAXLENGTH);
+		SimpleTextUtil.write(data, Convert.ToString(maxLength), scratch);
+		SimpleTextUtil.WriteNewline(data);
+
+		int maxBytesLength = Convert.ToString(maxLength).Length;
+		StringBuilder sb = new StringBuilder();
+		for (int i = 0; i < maxBytesLength; i++)
+		{
+		  sb.Append('0');
+		}
+		// write our pattern for encoding lengths
+		SimpleTextUtil.write(data, PATTERN);
+		SimpleTextUtil.write(data, sb.ToString(), scratch);
+		SimpleTextUtil.WriteNewline(data);
+//JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final':
+//ORIGINAL LINE: final java.text.DecimalFormat encoder = new java.text.DecimalFormat(sb.toString(), new java.text.DecimalFormatSymbols(java.util.Locale.ROOT));
+		DecimalFormat encoder = new DecimalFormat(sb.ToString(), new DecimalFormatSymbols(Locale.ROOT));
+
+		int numDocsWritten = 0;
+		foreach (BytesRef value in values)
+		{
+		  // write length
+//JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final':
+//ORIGINAL LINE: final int length = value == null ? 0 : value.length;
+		  int length = value == null ? 0 : value.length;
+		  SimpleTextUtil.write(data, LENGTH);
+		  SimpleTextUtil.write(data, encoder.format(length), scratch);
+		  SimpleTextUtil.WriteNewline(data);
+
+		  // write bytes -- don't use SimpleText.write
+		  // because it escapes:
+		  if (value != null)
+		  {
+			data.writeBytes(value.bytes, value.offset, value.length);
+		  }
+
+		  // pad to fit
+		  for (int i = length; i < maxLength; i++)
+		  {
+			data.writeByte((sbyte)' ');
+		  }
+		  SimpleTextUtil.WriteNewline(data);
+		  if (value == null)
+		  {
+			SimpleTextUtil.write(data, "F", scratch);
+		  }
+		  else
+		  {
+			SimpleTextUtil.write(data, "T", scratch);
+		  }
+		  SimpleTextUtil.WriteNewline(data);
+		  numDocsWritten++;
+		}
+
+		Debug.Assert(numDocs == numDocsWritten);
+	  }
+
+//JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in .NET:
+//ORIGINAL LINE: @Override public void addSortedField(index.FieldInfo field, Iterable<util.BytesRef> values, Iterable<Number> docToOrd) throws java.io.IOException
+	  public override void addSortedField(FieldInfo field, IEnumerable<BytesRef> values, IEnumerable<Number> docToOrd)
+	  {
+		Debug.Assert(fieldSeen(field.name));
+		Debug.Assert(field.DocValuesType == FieldInfo.DocValuesType.SORTED);
+		writeFieldEntry(field, FieldInfo.DocValuesType.SORTED);
+
+		int valueCount = 0;
+		int maxLength = -1;
+		foreach (BytesRef value in values)
+		{
+		  maxLength = Math.Max(maxLength, value.length);
+		  valueCount++;
+		}
+
+		// write numValues
+		SimpleTextUtil.write(data, NUMVALUES);
+		SimpleTextUtil.write(data, Convert.ToString(valueCount), scratch);
+		SimpleTextUtil.WriteNewline(data);
+
+		// write maxLength
+		SimpleTextUtil.write(data, MAXLENGTH);
+		SimpleTextUtil.write(data, Convert.ToString(maxLength), scratch);
+		SimpleTextUtil.WriteNewline(data);
+
+		int maxBytesLength = Convert.ToString(maxLength).Length;
+		StringBuilder sb = new StringBuilder();
+		for (int i = 0; i < maxBytesLength; i++)
+		{
+		  sb.Append('0');
+		}
+
+		// write our pattern for encoding lengths
+		SimpleTextUtil.write(data, PATTERN);
+		SimpleTextUtil.write(data, sb.ToString(), scratch);
+		SimpleTextUtil.WriteNewline(data);
+//JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final':
+//ORIGINAL LINE: final java.text.DecimalFormat encoder = new java.text.DecimalFormat(sb.toString(), new java.text.DecimalFormatSymbols(java.util.Locale.ROOT));
+		DecimalFormat encoder = new DecimalFormat(sb.ToString(), new DecimalFormatSymbols(Locale.ROOT));
+
+		int maxOrdBytes = Convert.ToString(valueCount + 1L).Length;
+		sb.Length = 0;
+		for (int i = 0; i < maxOrdBytes; i++)
+		{
+		  sb.Append('0');
+		}
+
+		// write our pattern for ords
+		SimpleTextUtil.write(data, ORDPATTERN);
+		SimpleTextUtil.write(data, sb.ToString(), scratch);
+		SimpleTextUtil.WriteNewline(data);
+//JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final':
+//ORIGINAL LINE: final java.text.DecimalFormat ordEncoder = new java.text.DecimalFormat(sb.toString(), new java.text.DecimalFormatSymbols(java.util.Locale.ROOT));
+		DecimalFormat ordEncoder = new DecimalFormat(sb.ToString(), new DecimalFormatSymbols(Locale.ROOT));
+
+		// for asserts:
+		int valuesSeen = 0;
+
+		foreach (BytesRef value in values)
+		{
+		  // write length
+		  SimpleTextUtil.write(data, LENGTH);
+		  SimpleTextUtil.write(data, encoder.format(value.length), scratch);
+		  SimpleTextUtil.WriteNewline(data);
+
+		  // write bytes -- don't use SimpleText.write
+		  // because it escapes:
+		  data.writeBytes(value.bytes, value.offset, value.length);
+
+		  // pad to fit
+		  for (int i = value.length; i < maxLength; i++)
+		  {
+			data.writeByte((sbyte)' ');
+		  }
+		  SimpleTextUtil.WriteNewline(data);
+		  valuesSeen++;
+		  Debug.Assert(valuesSeen <= valueCount);
+		}
+
+		Debug.Assert(valuesSeen == valueCount);
+
+		foreach (Number ord in docToOrd)
+		{
+		  SimpleTextUtil.write(data, ordEncoder.format((long)ord + 1), scratch);
+		  SimpleTextUtil.WriteNewline(data);
+		}
+	  }
+
+//JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in .NET:
+//ORIGINAL LINE: @Override public void addSortedSetField(index.FieldInfo field, Iterable<util.BytesRef> values, Iterable<Number> docToOrdCount, Iterable<Number> ords) throws java.io.IOException
+	  public override void addSortedSetField(FieldInfo field, IEnumerable<BytesRef> values, IEnumerable<Number> docToOrdCount, IEnumerable<Number> ords)
+	  {
+		Debug.Assert(fieldSeen(field.name));
+		Debug.Assert(field.DocValuesType == FieldInfo.DocValuesType.SORTED_SET);
+		writeFieldEntry(field, FieldInfo.DocValuesType.SORTED_SET);
+
+		long valueCount = 0;
+		int maxLength = 0;
+		foreach (BytesRef value in values)
+		{
+		  maxLength = Math.Max(maxLength, value.length);
+		  valueCount++;
+		}
+
+		// write numValues
+		SimpleTextUtil.write(data, NUMVALUES);
+		SimpleTextUtil.write(data, Convert.ToString(valueCount), scratch);
+		SimpleTextUtil.WriteNewline(data);
+
+		// write maxLength
+		SimpleTextUtil.write(data, MAXLENGTH);
+		SimpleTextUtil.write(data, Convert.ToString(maxLength), scratch);
+		SimpleTextUtil.WriteNewline(data);
+
+		int maxBytesLength = Convert.ToString(maxLength).Length;
+		StringBuilder sb = new StringBuilder();
+		for (int i = 0; i < maxBytesLength; i++)
+		{
+		  sb.Append('0');
+		}
+
+		// write our pattern for encoding lengths
+		SimpleTextUtil.write(data, PATTERN);
+		SimpleTextUtil.write(data, sb.ToString(), scratch);
+		SimpleTextUtil.WriteNewline(data);
+//JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final':
+//ORIGINAL LINE: final java.text.DecimalFormat encoder = new java.text.DecimalFormat(sb.toString(), new java.text.DecimalFormatSymbols(java.util.Locale.ROOT));
+		DecimalFormat encoder = new DecimalFormat(sb.ToString(), new DecimalFormatSymbols(Locale.ROOT));
+
+		// compute ord pattern: this is funny, we encode all values for all docs to find the maximum length
+		int maxOrdListLength = 0;
+		StringBuilder sb2 = new StringBuilder();
+		IEnumerator<Number> ordStream = ords.GetEnumerator();
+		foreach (Number n in docToOrdCount)
+		{
+		  sb2.Length = 0;
+		  int count = (int)n;
+		  for (int i = 0; i < count; i++)
+		  {
+//JAVA TO C# CONVERTER TODO TASK: Java iterators are only converted within the context of 'while' and 'for' loops:
+			long ord = (long)ordStream.next();
+			if (sb2.Length > 0)
+			{
+			  sb2.Append(",");
+			}
+			sb2.Append(Convert.ToString(ord));
+		  }
+		  maxOrdListLength = Math.Max(maxOrdListLength, sb2.Length);
+		}
+
+		sb2.Length = 0;
+		for (int i = 0; i < maxOrdListLength; i++)
+		{
+		  sb2.Append('X');
+		}
+
+		// write our pattern for ord lists
+		SimpleTextUtil.write(data, ORDPATTERN);
+		SimpleTextUtil.write(data, sb2.ToString(), scratch);
+		SimpleTextUtil.WriteNewline(data);
+
+		// for asserts:
+		long valuesSeen = 0;
+
+		foreach (BytesRef value in values)
+		{
+		  // write length
+		  SimpleTextUtil.write(data, LENGTH);
+		  SimpleTextUtil.write(data, encoder.format(value.length), scratch);
+		  SimpleTextUtil.WriteNewline(data);
+
+		  // write bytes -- don't use SimpleText.write
+		  // because it escapes:
+		  data.writeBytes(value.bytes, value.offset, value.length);
+
+		  // pad to fit
+		  for (int i = value.length; i < maxLength; i++)
+		  {
+			data.writeByte((sbyte)' ');
+		  }
+		  SimpleTextUtil.WriteNewline(data);
+		  valuesSeen++;
+		  Debug.Assert(valuesSeen <= valueCount);
+		}
+
+		Debug.Assert(valuesSeen == valueCount);
+
+		ordStream = ords.GetEnumerator();
+
+		// write the ords for each doc comma-separated
+		foreach (Number n in docToOrdCount)
+		{
+		  sb2.Length = 0;
+		  int count = (int)n;
+		  for (int i = 0; i < count; i++)
+		  {
+//JAVA TO C# CONVERTER TODO TASK: Java iterators are only converted within the context of 'while' and 'for' loops:
+			long ord = (long)ordStream.next();
+			if (sb2.Length > 0)
+			{
+			  sb2.Append(",");
+			}
+			sb2.Append(Convert.ToString(ord));
+		  }
+		  // now pad to fit: these are numbers so spaces work well. reader calls trim()
+		  int numPadding = maxOrdListLength - sb2.Length;
+		  for (int i = 0; i < numPadding; i++)
+		  {
+			sb2.Append(' ');
+		  }
+		  SimpleTextUtil.write(data, sb2.ToString(), scratch);
+		  SimpleTextUtil.WriteNewline(data);
+		}
+	  }
+
+	  /// <summary>
+	  /// write the header for this field </summary>
+//JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in .NET:
+//ORIGINAL LINE: private void writeFieldEntry(index.FieldInfo field, index.FieldInfo.DocValuesType type) throws java.io.IOException
+	  private void writeFieldEntry(FieldInfo field, FieldInfo.DocValuesType type)
+	  {
+		SimpleTextUtil.write(data, FIELD);
+		SimpleTextUtil.write(data, field.name, scratch);
+		SimpleTextUtil.WriteNewline(data);
+
+		SimpleTextUtil.write(data, TYPE);
+		SimpleTextUtil.write(data, type.ToString(), scratch);
+		SimpleTextUtil.WriteNewline(data);
+	  }
+
+//JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in .NET:
+//ORIGINAL LINE: @Override public void close() throws java.io.IOException
+	  public override void close()
+	  {
+		if (data != null)
+		{
+		  bool success = false;
+		  try
+		  {
+			Debug.Assert(fieldsSeen.Count > 0);
+			// TODO: sheisty to do this here?
+			SimpleTextUtil.write(data, END);
+			SimpleTextUtil.WriteNewline(data);
+			SimpleTextUtil.WriteChecksum(data, scratch);
+			success = true;
+		  }
+		  finally
+		  {
+			if (success)
+			{
+			  IOUtils.close(data);
+			}
+			else
+			{
+			  IOUtils.closeWhileHandlingException(data);
+			}
+			data = null;
+		  }
+		}
+	  }
+	}
+
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/cf1df6be/src/Lucene.Net.Codecs/SimpleText/SimpleTextFieldInfosFormat.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Codecs/SimpleText/SimpleTextFieldInfosFormat.cs b/src/Lucene.Net.Codecs/SimpleText/SimpleTextFieldInfosFormat.cs
index 9c6b0e3..f8852ea 100644
--- a/src/Lucene.Net.Codecs/SimpleText/SimpleTextFieldInfosFormat.cs
+++ b/src/Lucene.Net.Codecs/SimpleText/SimpleTextFieldInfosFormat.cs
@@ -1,6 +1,4 @@
-package org.apache.lucene.codecs.simpletext;
-
-/*
+/*
  * 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.
@@ -17,29 +15,29 @@ package org.apache.lucene.codecs.simpletext;
  * limitations under the License.
  */
 
-import java.io.IOException;
-
-import org.apache.lucene.codecs.FieldInfosFormat;
-import org.apache.lucene.codecs.FieldInfosReader;
-import org.apache.lucene.codecs.FieldInfosWriter;
+namespace Lucene.Net.Codecs.SimpleText
+{
 
-/**
- * plaintext field infos format
- * <p>
- * <b><font color="red">FOR RECREATIONAL USE ONLY</font></B>
- * @lucene.experimental
- */
-public class SimpleTextFieldInfosFormat extends FieldInfosFormat {
-  private final FieldInfosReader reader = new SimpleTextFieldInfosReader();
-  private final FieldInfosWriter writer = new SimpleTextFieldInfosWriter();
+    /// <summary>
+    /// plaintext field infos format
+    /// <para>
+    /// <b><font color="red">FOR RECREATIONAL USE ONLY</font></B>
+    /// @lucene.experimental
+    /// </para>
+    /// </summary>
+    public class SimpleTextFieldInfosFormat : FieldInfosFormat
+    {
+        private readonly FieldInfosReader _reader = new SimpleTextFieldInfosReader();
+        private readonly FieldInfosWriter _writer = new SimpleTextFieldInfosWriter();
 
-  @Override
-  public FieldInfosReader getFieldInfosReader()  {
-    return reader;
-  }
+        public override FieldInfosReader FieldInfosReader
+        {
+            get { return _reader; }
+        }
 
-  @Override
-  public FieldInfosWriter getFieldInfosWriter()  {
-    return writer;
-  }
-}
+        public override FieldInfosWriter FieldInfosWriter
+        {
+            get { return _writer; }
+        }
+    }
+}
\ No newline at end of file