This is an automated email from the ASF dual-hosted git repository.

nightowl888 pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/lucenenet.git


The following commit(s) were added to refs/heads/master by this push:
     new 2dd9b14  BREAKING: Moved all Document extensions to the 
Lucene.Net.Documents.Extensions namespace. Added tests for DocumentExtensions 
in Lucene.Net.Tests._J-S, Lucene.Net.Tests.ICU and Lucene.Net.Tests.Facet. 
Added guard clauses and updated documentation of Document extension methods and 
some related fields. Closes #407.
2dd9b14 is described below

commit 2dd9b14c276647448d1ed7748623f42854e6fdfc
Author: Shad Storhaug <[email protected]>
AuthorDate: Fri Apr 16 11:43:13 2021 +0700

    BREAKING: Moved all Document extensions to the 
Lucene.Net.Documents.Extensions namespace. Added tests for DocumentExtensions 
in Lucene.Net.Tests._J-S, Lucene.Net.Tests.ICU and Lucene.Net.Tests.Facet. 
Added guard clauses and updated documentation of Document extension methods and 
some related fields. Closes #407.
---
 .../Collation/ICUCollationDocValuesField.cs        |   7 +-
 .../Facet/AssociationsFacetsExample.cs             |   1 +
 .../{ => Extensions}/DocumentExtensions.cs         |  23 +-
 .../Lucene.Net.Tests.Facet.csproj                  |   2 +-
 .../Document/Extensions/TestDocumentExtensions.cs  | 104 +++++
 .../Document/Extensions/TestDocumentExtensions.cs  | 433 +++++++++++++++++++++
 src/Lucene.Net/Document/BinaryDocValuesField.cs    |   4 +-
 src/Lucene.Net/Document/Field.cs                   |   5 +-
 src/Lucene.Net/Document/FloatField.cs              |   4 +-
 src/Lucene.Net/Document/IntField.cs                |   4 +-
 src/Lucene.Net/Document/LongField.cs               |   4 +-
 .../Document/Extensions/DocumentExtensions.cs      | 138 +++++--
 .../{ => Extensions}/DocumentExtensions.cs         |   7 +-
 .../Lucene.Net.Tests.ICU.csproj                    |   6 +-
 .../Document/Extensions/TestDocumentExtensions.cs  |  55 +++
 15 files changed, 754 insertions(+), 43 deletions(-)

diff --git 
a/src/Lucene.Net.Analysis.ICU/Collation/ICUCollationDocValuesField.cs 
b/src/Lucene.Net.Analysis.ICU/Collation/ICUCollationDocValuesField.cs
index 3d5fdeb..e170e4b 100644
--- a/src/Lucene.Net.Analysis.ICU/Collation/ICUCollationDocValuesField.cs
+++ b/src/Lucene.Net.Analysis.ICU/Collation/ICUCollationDocValuesField.cs
@@ -3,6 +3,7 @@ using ICU4N.Text;
 using Lucene.Net.Documents;
 using Lucene.Net.Support;
 using Lucene.Net.Util;
+using System;
 
 namespace Lucene.Net.Collation
 {
@@ -37,7 +38,7 @@ namespace Lucene.Net.Collation
     public sealed class ICUCollationDocValuesField : Field
     {
         private readonly string name;
-        private readonly Collator collator;
+        internal readonly Collator collator; // LUCENENET: marked internal for 
testing
         private readonly BytesRef bytes = new BytesRef();
         private RawCollationKey key = new RawCollationKey();
 
@@ -50,11 +51,15 @@ namespace Lucene.Net.Collation
         /// </summary>
         /// <param name="name">Field name.</param>
         /// <param name="collator">Collator for generating collation 
keys.</param>
+        /// <exception cref="ArgumentNullException">if <paramref name="name"/> 
or <paramref name="collator"/> is <c>null</c>.</exception>
         // TODO: can we make this trap-free? maybe just synchronize on the 
collator
         // instead? 
         public ICUCollationDocValuesField(string name, Collator collator)
             : base(name, SortedDocValuesField.TYPE)
         {
+            if (collator is null)
+                throw new ArgumentNullException(nameof(collator));
+
             this.name = name;
             this.collator = (Collator)collator.Clone();
             FieldsData = bytes; // so wrong setters cannot be called
diff --git a/src/Lucene.Net.Demo/Facet/AssociationsFacetsExample.cs 
b/src/Lucene.Net.Demo/Facet/AssociationsFacetsExample.cs
index 168baf1..e8ac0b1 100644
--- a/src/Lucene.Net.Demo/Facet/AssociationsFacetsExample.cs
+++ b/src/Lucene.Net.Demo/Facet/AssociationsFacetsExample.cs
@@ -22,6 +22,7 @@
 
 using Lucene.Net.Analysis.Core;
 using Lucene.Net.Documents;
+using Lucene.Net.Documents.Extensions;
 using Lucene.Net.Facet;
 using Lucene.Net.Facet.Taxonomy;
 using Lucene.Net.Facet.Taxonomy.Directory;
diff --git a/src/Lucene.Net.Facet/Support/Document/DocumentExtensions.cs 
b/src/Lucene.Net.Facet/Support/Document/Extensions/DocumentExtensions.cs
similarity index 82%
rename from src/Lucene.Net.Facet/Support/Document/DocumentExtensions.cs
rename to src/Lucene.Net.Facet/Support/Document/Extensions/DocumentExtensions.cs
index 3ce202e..8e2e44e 100644
--- a/src/Lucene.Net.Facet/Support/Document/DocumentExtensions.cs
+++ b/src/Lucene.Net.Facet/Support/Document/Extensions/DocumentExtensions.cs
@@ -2,8 +2,9 @@
 using Lucene.Net.Facet.SortedSet;
 using Lucene.Net.Facet.Taxonomy;
 using Lucene.Net.Util;
+using System;
 
-namespace Lucene.Net.Documents
+namespace Lucene.Net.Documents.Extensions
 {
     /*
      * Licensed to the Apache Software Foundation (ASF) under one or more
@@ -38,8 +39,12 @@ namespace Lucene.Net.Documents
         /// <param name="dim">Dimension for this field.</param>
         /// <param name="label">Label for this field.</param>
         /// <returns>The field that was added to this <see 
cref="Document"/>.</returns>
+        /// <exception cref="ArgumentNullException">This <paramref 
name="document"/> is <c>null</c>. </exception>
         public static SortedSetDocValuesFacetField 
AddSortedSetDocValuesFacetField(this Document document, string dim, string 
label)
         {
+            if (document is null)
+                throw new ArgumentNullException(nameof(document));
+
             var field = new SortedSetDocValuesFacetField(dim, label);
             document.Add(field);
             return field;
@@ -54,8 +59,12 @@ namespace Lucene.Net.Documents
         /// <param name="dim">Dimension for this field.</param>
         /// <param name="path">Facet path for this field.</param>
         /// <returns>The field that was added to this <see 
cref="Document"/>.</returns>
+        /// <exception cref="ArgumentNullException">This <paramref 
name="document"/> is <c>null</c>. </exception>
         public static AssociationFacetField AddAssociationFacetField(this 
Document document, BytesRef assoc, string dim, params string[] path)
         {
+            if (document is null)
+                throw new ArgumentNullException(nameof(document));
+
             var field = new AssociationFacetField(assoc, dim, path);
             document.Add(field);
             return field;
@@ -70,8 +79,12 @@ namespace Lucene.Net.Documents
         /// <param name="dim">Dimension for this field.</param>
         /// <param name="path">Facet path for this field.</param>
         /// <returns>The field that was added to this <see 
cref="Document"/>.</returns>
+        /// <exception cref="ArgumentNullException">This <paramref 
name="document"/> is <c>null</c>. </exception>
         public static Int32AssociationFacetField 
AddInt32AssociationFacetField(this Document document, int assoc, string dim, 
params string[] path)
         {
+            if (document is null)
+                throw new ArgumentNullException(nameof(document));
+
             var field = new Int32AssociationFacetField(assoc, dim, path);
             document.Add(field);
             return field;
@@ -86,8 +99,12 @@ namespace Lucene.Net.Documents
         /// <param name="dim">Dimension for this field.</param>
         /// <param name="path">Facet path for this field.</param>
         /// <returns>The field that was added to this <see 
cref="Document"/>.</returns>
+        /// <exception cref="ArgumentNullException">This <paramref 
name="document"/> is <c>null</c>. </exception>
         public static SingleAssociationFacetField 
AddSingleAssociationFacetField(this Document document, float assoc, string dim, 
params string[] path)
         {
+            if (document is null)
+                throw new ArgumentNullException(nameof(document));
+
             var field = new SingleAssociationFacetField(assoc, dim, path);
             document.Add(field);
             return field;
@@ -101,8 +118,12 @@ namespace Lucene.Net.Documents
         /// <param name="dim">Dimension for this field.</param>
         /// <param name="path">Facet path for this field.</param>
         /// <returns>The field that was added to this <see 
cref="Document"/>.</returns>
+        /// <exception cref="ArgumentNullException">This <paramref 
name="document"/> is <c>null</c>. </exception>
         public static FacetField AddFacetField(this Document document, string 
dim, params string[] path)
         {
+            if (document is null)
+                throw new ArgumentNullException(nameof(document));
+
             var field = new FacetField(dim, path);
             document.Add(field);
             return field;
diff --git a/src/Lucene.Net.Tests.Facet/Lucene.Net.Tests.Facet.csproj 
b/src/Lucene.Net.Tests.Facet/Lucene.Net.Tests.Facet.csproj
index b427400..765112f 100644
--- a/src/Lucene.Net.Tests.Facet/Lucene.Net.Tests.Facet.csproj
+++ b/src/Lucene.Net.Tests.Facet/Lucene.Net.Tests.Facet.csproj
@@ -36,7 +36,7 @@
   <Import Project="$(SolutionDir)build/TestReferences.Common.targets" />
 
   <ItemGroup Condition=" '$(TargetFramework)' == 'netcoreapp3.1' ">
-    <PackageReference Include="System.Net.Primitives" 
Version="$(SystemNetPrimitivesPackageVersion)"/>
+    <PackageReference Include="System.Net.Primitives" 
Version="$(SystemNetPrimitivesPackageVersion)" />
   </ItemGroup>
 
 </Project>
diff --git 
a/src/Lucene.Net.Tests.Facet/Support/Document/Extensions/TestDocumentExtensions.cs
 
b/src/Lucene.Net.Tests.Facet/Support/Document/Extensions/TestDocumentExtensions.cs
new file mode 100644
index 0000000..873a371
--- /dev/null
+++ 
b/src/Lucene.Net.Tests.Facet/Support/Document/Extensions/TestDocumentExtensions.cs
@@ -0,0 +1,104 @@
+using Lucene.Net.Attributes;
+using Lucene.Net.Facet;
+using Lucene.Net.Facet.SortedSet;
+using Lucene.Net.Facet.Taxonomy;
+using Lucene.Net.Index;
+using Lucene.Net.Util;
+using NUnit.Framework;
+using System;
+using Assert = Lucene.Net.TestFramework.Assert;
+
+namespace Lucene.Net.Documents.Extensions
+{
+    /*
+     * 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.
+     */
+
+    public class TestDocumentExtensions : LuceneTestCase
+    {
+        [Test]
+        [LuceneNetSpecific]
+        public void TestAddSortedSetDocValuesFacetField()
+        {
+            SortedSetDocValuesFacetField field = null;
+            AssertDocumentExtensionAddsToDocument(document => field = 
document.AddSortedSetDocValuesFacetField("theDim", "theLabel"));
+            Assert.AreEqual("theDim", field.Dim);
+            Assert.AreEqual("theLabel", field.Label);
+        }
+
+        [Test]
+        [LuceneNetSpecific]
+        public void TestAddAssociationFacetField()
+        {
+            AssociationFacetField field = null;
+            BytesRef assoc = new BytesRef("theAssoc");
+            string[] path = new[] { "thePath0", "thePath1", "thePath2" };
+            AssertDocumentExtensionAddsToDocument(document => field = 
document.AddAssociationFacetField(assoc, "theDim", path));
+            Assert.AreSame(assoc, field.Assoc);
+            Assert.AreEqual("theDim", field.Dim);
+            Assert.AreEqual(path, field.Path);
+        }
+
+        [Test]
+        [LuceneNetSpecific]
+        public void TestAddInt32AssociationFacetField()
+        {
+            Int32AssociationFacetField field = null;
+            int assoc = 1234;
+            string[] path = new[] { "thePath0", "thePath1", "thePath2" };
+            AssertDocumentExtensionAddsToDocument(document => field = 
document.AddInt32AssociationFacetField(assoc, "theDim", path));
+            Assert.AreEqual(Int32AssociationFacetField.Int32ToBytesRef(assoc), 
field.Assoc);
+            Assert.AreEqual("theDim", field.Dim);
+            Assert.AreEqual(path, field.Path);
+        }
+
+        [Test]
+        [LuceneNetSpecific]
+        public void TestAddSingleAssociationFacetField()
+        {
+            SingleAssociationFacetField field = null;
+            float assoc = 1234.5678f;
+            string[] path = new[] { "thePath0", "thePath1", "thePath2" };
+            AssertDocumentExtensionAddsToDocument(document => field = 
document.AddSingleAssociationFacetField(assoc, "theDim", path));
+            
Assert.AreEqual(SingleAssociationFacetField.SingleToBytesRef(assoc), 
field.Assoc);
+            Assert.AreEqual("theDim", field.Dim);
+            Assert.AreEqual(path, field.Path);
+        }
+
+        [Test]
+        [LuceneNetSpecific]
+        public void TestAddFacetField()
+        {
+            FacetField field = null;
+            string[] path = new[] { "thePath0", "thePath1", "thePath2" };
+            AssertDocumentExtensionAddsToDocument(document => field = 
document.AddFacetField("theDim", path));
+            Assert.AreEqual("theDim", field.Dim);
+            Assert.AreEqual(path, field.Path);
+        }
+
+        private void AssertDocumentExtensionAddsToDocument<T>(Func<Document, 
T> extension) where T : IIndexableField
+        {
+            var document = new Document();
+            var field = extension(document);
+            Assert.IsNotNull(field);
+            Assert.AreEqual(1, document.Fields.Count);
+            Assert.AreSame(field, document.Fields[0]);
+
+            document = null;
+            Assert.Throws<ArgumentNullException>(() => extension(document));
+        }
+    }
+}
diff --git 
a/src/Lucene.Net.Tests/Support/Document/Extensions/TestDocumentExtensions.cs 
b/src/Lucene.Net.Tests/Support/Document/Extensions/TestDocumentExtensions.cs
new file mode 100644
index 0000000..9cac099
--- /dev/null
+++ b/src/Lucene.Net.Tests/Support/Document/Extensions/TestDocumentExtensions.cs
@@ -0,0 +1,433 @@
+using Lucene.Net.Analysis;
+using Lucene.Net.Attributes;
+using Lucene.Net.Index;
+using Lucene.Net.Util;
+using NUnit.Framework;
+using System;
+using System.IO;
+using System.Text;
+using Assert = Lucene.Net.TestFramework.Assert;
+
+namespace Lucene.Net.Documents.Extensions
+{
+    /*
+     * 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.
+     */
+
+    public class TestDocumentExtensions : LuceneTestCase
+    {
+        [Test]
+        [LuceneNetSpecific]
+        public void TestGetField()
+        {
+            var target = new BinaryDocValuesField("theName", new 
BytesRef("Foobar"));
+            Document document = new Document
+            {
+                new BinaryDocValuesField("someOtherName", new 
BytesRef("Foobar2")),
+                target
+            };
+            
+            BinaryDocValuesField field = 
document.GetField<BinaryDocValuesField>("theName");
+            Assert.AreSame(target, field);
+
+            
Assert.IsNull(document.GetField<BinaryDocValuesField>("nonExistantName"));
+
+#pragma warning disable CS0618 // Type or member is obsolete
+            Assert.Throws<InvalidCastException>(() => 
document.GetField<Int32DocValuesField>("theName"));
+#pragma warning restore CS0618 // Type or member is obsolete
+
+            document = null;
+            Assert.Throws<ArgumentNullException>(() => 
document.GetField<BinaryDocValuesField>("theName"));
+        }
+
+        [Test]
+        [LuceneNetSpecific]
+        public void TestGetFields()
+        {
+            Document document = new Document
+            {
+                new TextField("someOtherName", "Foobar2", Field.Store.YES),
+                new TextField("theName", "Foobar", Field.Store.YES),
+                new TextField("theName", "Crowbar", Field.Store.YES)
+            };
+
+            TextField[] fields = document.GetFields<TextField>("theName");
+            Assert.AreEqual(2, fields.Length);
+            Assert.AreEqual("Foobar", fields[0].GetStringValue());
+            Assert.AreEqual("Crowbar", fields[1].GetStringValue());
+
+            fields = document.GetFields<TextField>("nonExistantName");
+            Assert.IsNotNull(fields);
+            Assert.AreEqual(0, fields.Length);
+
+            Assert.Throws<InvalidCastException>(() => 
document.GetFields<NumericDocValuesField>("theName"));
+
+            document = null;
+            Assert.Throws<ArgumentNullException>(() => 
document.GetFields<TextField>("theName"));
+        }
+
+        [Test]
+        [LuceneNetSpecific]
+        public void TestAddBinaryDocValuesField()
+        {
+            BinaryDocValuesField field = null;
+            BytesRef value = new BytesRef("Foobar");
+            AssertDocumentExtensionAddsToDocument(document => field = 
document.AddBinaryDocValuesField("theName", value));
+            Assert.AreEqual("theName", field.Name);
+            Assert.AreSame(value, field.FieldsData);
+        }
+
+        [Test]
+        [LuceneNetSpecific]
+        public void TestAddDoubleDocValuesField()
+        {
+            DoubleDocValuesField field = null;
+            double value = 123.456d;
+            AssertDocumentExtensionAddsToDocument(document => field = 
document.AddDoubleDocValuesField("theName", value));
+            Assert.AreEqual("theName", field.Name);
+            Assert.AreEqual(J2N.BitConversion.DoubleToRawInt64Bits(value), 
field.GetDoubleValueOrDefault());
+        }
+
+        [Test]
+        [LuceneNetSpecific]
+        public void TestAddDoubleField_Stored()
+        {
+            DoubleField field = null;
+            double value = 123.456d;
+            var stored = Field.Store.YES;
+            AssertDocumentExtensionAddsToDocument(document => field = 
document.AddDoubleField("theName", value, stored));
+            Assert.AreEqual("theName", field.Name);
+            Assert.AreEqual(value, field.GetDoubleValueOrDefault(), 
0.0000001d); // We don't really care about precision, just checking to see if 
the value got passed through
+            Assert.AreSame(DoubleField.TYPE_STORED, field.FieldType);
+        }
+
+        [Test]
+        [LuceneNetSpecific]
+        public void TestAddDoubleField_FieldType()
+        {
+            DoubleField field = null;
+            double value = 123.456d;
+            var fieldType = new FieldType
+            {
+                IsIndexed = true,
+                IsTokenized = true,
+                OmitNorms = false,
+                IndexOptions = IndexOptions.DOCS_ONLY,
+                NumericType = NumericType.DOUBLE,
+                IsStored = true
+            };
+            fieldType.Freeze();
+            AssertDocumentExtensionAddsToDocument(document => field = 
document.AddDoubleField("theName", value, fieldType));
+            Assert.AreEqual("theName", field.Name);
+            Assert.AreEqual(value, field.GetDoubleValueOrDefault(), 
0.0000001d); // We don't really care about precision, just checking to see if 
the value got passed through
+            Assert.AreSame(fieldType, field.FieldType);
+        }
+
+        [Test]
+        [LuceneNetSpecific]
+        public void TestAddSingleDocValuesField()
+        {
+            SingleDocValuesField field = null;
+            float value = 123.456f;
+            AssertDocumentExtensionAddsToDocument(document => field = 
document.AddSingleDocValuesField("theName", value));
+            Assert.AreEqual("theName", field.Name);
+            Assert.AreEqual(J2N.BitConversion.SingleToRawInt32Bits(value), 
field.GetSingleValueOrDefault());
+        }
+
+        [Test]
+        [LuceneNetSpecific]
+        public void TestAddSingleField_Stored()
+        {
+            SingleField field = null;
+            float value = 123.456f;
+            var stored = Field.Store.YES;
+            AssertDocumentExtensionAddsToDocument(document => field = 
document.AddSingleField("theName", value, stored));
+            Assert.AreEqual("theName", field.Name);
+            Assert.AreEqual(value, field.GetSingleValueOrDefault(), 
0.0000001f); // We don't really care about precision, just checking to see if 
the value got passed through
+            Assert.AreSame(SingleField.TYPE_STORED, field.FieldType);
+        }
+
+        [Test]
+        [LuceneNetSpecific]
+        public void TestAddSingleField_FieldType()
+        {
+            SingleField field = null;
+            float value = 123.456f;
+            var fieldType = new FieldType
+            {
+                IsIndexed = true,
+                IsTokenized = true,
+                OmitNorms = false,
+                IndexOptions = IndexOptions.DOCS_ONLY,
+                NumericType = NumericType.SINGLE,
+                IsStored = true
+            };
+            fieldType.Freeze();
+            AssertDocumentExtensionAddsToDocument(document => field = 
document.AddSingleField("theName", value, fieldType));
+            Assert.AreEqual("theName", field.Name);
+            Assert.AreEqual(value, field.GetSingleValueOrDefault(), 
0.0000001f); // We don't really care about precision, just checking to see if 
the value got passed through
+            Assert.AreSame(fieldType, field.FieldType);
+        }
+
+        // LUCENENET: Int32DocValuesField is obsolete, so we didn't build 
extension methods
+
+        [Test]
+        [LuceneNetSpecific]
+        public void TestAddInt32Field_Stored()
+        {
+            Int32Field field = null;
+            int value = 123;
+            var stored = Field.Store.YES;
+            AssertDocumentExtensionAddsToDocument(document => field = 
document.AddInt32Field("theName", value, stored));
+            Assert.AreEqual("theName", field.Name);
+            Assert.AreEqual(value, field.GetInt32ValueOrDefault());
+            Assert.AreSame(Int32Field.TYPE_STORED, field.FieldType);
+        }
+
+        [Test]
+        [LuceneNetSpecific]
+        public void TestAddInt32Field_FieldType()
+        {
+            Int32Field field = null;
+            int value = 123;
+            var fieldType = new FieldType
+            {
+                IsIndexed = true,
+                IsTokenized = true,
+                OmitNorms = false,
+                IndexOptions = IndexOptions.DOCS_ONLY,
+                NumericType = NumericType.INT32,
+                IsStored = true
+            };
+            fieldType.Freeze();
+            AssertDocumentExtensionAddsToDocument(document => field = 
document.AddInt32Field("theName", value, fieldType));
+            Assert.AreEqual("theName", field.Name);
+            Assert.AreEqual(value, field.GetInt32ValueOrDefault());
+            Assert.AreSame(fieldType, field.FieldType);
+        }
+
+        // LUCENENET: Int64DocValuesField is obsolete, so we didn't build 
extension methods
+
+        [Test]
+        [LuceneNetSpecific]
+        public void TestAddInt64Field_Stored()
+        {
+            Int64Field field = null;
+            long value = 123;
+            var stored = Field.Store.YES;
+            AssertDocumentExtensionAddsToDocument(document => field = 
document.AddInt64Field("theName", value, stored));
+            Assert.AreEqual("theName", field.Name);
+            Assert.AreEqual(value, field.GetInt64ValueOrDefault());
+            Assert.AreSame(Int64Field.TYPE_STORED, field.FieldType);
+        }
+
+        [Test]
+        [LuceneNetSpecific]
+        public void TestAddInt64Field_FieldType()
+        {
+            Int64Field field = null;
+            long value = 123;
+            var fieldType = new FieldType
+            {
+                IsIndexed = true,
+                IsTokenized = true,
+                OmitNorms = false,
+                IndexOptions = IndexOptions.DOCS_ONLY,
+                NumericType = NumericType.INT64,
+                IsStored = true
+            };
+            fieldType.Freeze();
+            AssertDocumentExtensionAddsToDocument(document => field = 
document.AddInt64Field("theName", value, fieldType));
+            Assert.AreEqual("theName", field.Name);
+            Assert.AreEqual(value, field.GetInt64ValueOrDefault());
+            Assert.AreSame(fieldType, field.FieldType);
+        }
+
+        [Test]
+        [LuceneNetSpecific]
+        public void TestAddNumericDocValuesField()
+        {
+            NumericDocValuesField field = null;
+            long value = 123;
+            AssertDocumentExtensionAddsToDocument(document => field = 
document.AddNumericDocValuesField("theName", value));
+            Assert.AreEqual("theName", field.Name);
+            Assert.AreEqual(value, field.GetInt64ValueOrDefault());
+        }
+
+        [Test]
+        [LuceneNetSpecific]
+        public void TestAddSortedDocValuesField()
+        {
+            SortedDocValuesField field = null;
+            BytesRef bytes = new BytesRef("Foobar");
+            AssertDocumentExtensionAddsToDocument(document => field = 
document.AddSortedDocValuesField("theName", bytes));
+            Assert.AreEqual("theName", field.Name);
+            Assert.AreSame(bytes, field.FieldsData);
+        }
+
+        [Test]
+        [LuceneNetSpecific]
+        public void TestAddStoredField_ByteArray()
+        {
+            StoredField field = null;
+            byte[] bytes = Encoding.UTF8.GetBytes("Foobar");
+            AssertDocumentExtensionAddsToDocument(document => field = 
document.AddStoredField("theName", bytes));
+            Assert.AreEqual("theName", field.Name);
+            Assert.AreEqual(bytes, field.GetBinaryValue().Bytes);
+            Assert.AreEqual(0, field.GetBinaryValue().Offset);
+            Assert.AreEqual(bytes.Length, field.GetBinaryValue().Length);
+        }
+
+        [Test]
+        [LuceneNetSpecific]
+        public void TestAddStoredField_ByteArray_WithOffset()
+        {
+            StoredField field = null;
+            byte[] bytes = Encoding.UTF8.GetBytes("FoobarAgain");
+            int offset = 3;
+            int length = 3;
+            AssertDocumentExtensionAddsToDocument(document => field = 
document.AddStoredField("theName", bytes, offset, length));
+            Assert.AreEqual("theName", field.Name);
+            Assert.AreEqual(bytes, field.GetBinaryValue().Bytes);
+            Assert.AreEqual(offset, field.GetBinaryValue().Offset);
+            Assert.AreEqual(length, field.GetBinaryValue().Length);
+        }
+
+        [Test]
+        [LuceneNetSpecific]
+        public void TestAddStoredField_BytesRef()
+        {
+            StoredField field = null;
+            BytesRef bytes = new BytesRef("Foobar");
+            AssertDocumentExtensionAddsToDocument(document => field = 
document.AddStoredField("theName", bytes));
+            Assert.AreEqual("theName", field.Name);
+            Assert.AreSame(bytes, field.GetBinaryValue());
+        }
+
+        [Test]
+        [LuceneNetSpecific]
+        public void TestAddStoredField_String()
+        {
+            StoredField field = null;
+            string value = "Foobar";
+            AssertDocumentExtensionAddsToDocument(document => field = 
document.AddStoredField("theName", value));
+            Assert.AreEqual("theName", field.Name);
+            Assert.AreEqual(value, field.GetStringValue());
+        }
+
+        [Test]
+        [LuceneNetSpecific]
+        public void TestAddStoredField_Int32()
+        {
+            StoredField field = null;
+            int value = 123;
+            AssertDocumentExtensionAddsToDocument(document => field = 
document.AddStoredField("theName", value));
+            Assert.AreEqual("theName", field.Name);
+            Assert.AreEqual(value, field.GetInt32ValueOrDefault());
+        }
+
+        [Test]
+        [LuceneNetSpecific]
+        public void TestAddStoredField_Single()
+        {
+            StoredField field = null;
+            float value = 123.456f;
+            AssertDocumentExtensionAddsToDocument(document => field = 
document.AddStoredField("theName", value));
+            Assert.AreEqual("theName", field.Name);
+            Assert.AreEqual(value, field.GetSingleValueOrDefault(), 
0.0000001f); // We don't really care about precision, just checking to see if 
the value got passed through
+        }
+
+        [Test]
+        [LuceneNetSpecific]
+        public void TestAddStoredField_Int64()
+        {
+            StoredField field = null;
+            long value = 123;
+            AssertDocumentExtensionAddsToDocument(document => field = 
document.AddStoredField("theName", value));
+            Assert.AreEqual("theName", field.Name);
+            Assert.AreEqual(value, field.GetInt64ValueOrDefault());
+        }
+
+        [Test]
+        [LuceneNetSpecific]
+        public void TestAddStoredField_Double()
+        {
+            StoredField field = null;
+            double value = 123.456d;
+            AssertDocumentExtensionAddsToDocument(document => field = 
document.AddStoredField("theName", value));
+            Assert.AreEqual("theName", field.Name);
+            Assert.AreEqual(value, field.GetDoubleValueOrDefault(), 
0.0000001d); // We don't really care about precision, just checking to see if 
the value got passed through
+        }
+
+        [Test]
+        [LuceneNetSpecific]
+        public void TestAddStringField()
+        {
+            StringField field = null;
+            string value = "Foobar";
+            AssertDocumentExtensionAddsToDocument(document => field = 
document.AddStringField("theName", value, Field.Store.YES));
+            Assert.AreEqual("theName", field.Name);
+            Assert.AreEqual(value, field.GetStringValue());
+            Assert.AreSame(StringField.TYPE_STORED, field.FieldType);
+        }
+
+        [Test]
+        [LuceneNetSpecific]
+        public void TestAddTextField_TextReader()
+        {
+            TextField field = null;
+            TextReader reader = new StringReader("Foobar");
+            AssertDocumentExtensionAddsToDocument(document => field = 
document.AddTextField("theName", reader));
+            Assert.AreEqual("theName", field.Name);
+            Assert.AreSame(reader, field.GetReaderValue());
+        }
+
+        [Test]
+        [LuceneNetSpecific]
+        public void TestAddTextField_Stored()
+        {
+            TextField field = null;
+            string value = "Foobar";
+            AssertDocumentExtensionAddsToDocument(document => field = 
document.AddTextField("theName", value, Field.Store.YES));
+            Assert.AreEqual("theName", field.Name);
+            Assert.AreEqual(value, field.GetStringValue());
+            Assert.AreSame(TextField.TYPE_STORED, field.FieldType);
+        }
+
+        [Test]
+        [LuceneNetSpecific]
+        public void TestAddTextField_TokenStream()
+        {
+            TextField field = null;
+            TokenStream tokenStream = new CannedBinaryTokenStream(new 
BinaryToken(new BytesRef("Foobar")));
+            AssertDocumentExtensionAddsToDocument(document => field = 
document.AddTextField("theName", tokenStream));
+            Assert.AreEqual("theName", field.Name);
+            Assert.AreSame(tokenStream, field.GetTokenStreamValue());
+        }
+
+        private void AssertDocumentExtensionAddsToDocument<T>(Func<Document, 
T> extension) where T : IIndexableField
+        {
+            var document = new Document();
+            var field = extension(document);
+            Assert.IsNotNull(field);
+            Assert.AreEqual(1, document.Fields.Count);
+            Assert.AreSame(field, document.Fields[0]);
+
+            document = null;
+            Assert.Throws<ArgumentNullException>(() => extension(document));
+        }
+    }
+}
\ No newline at end of file
diff --git a/src/Lucene.Net/Document/BinaryDocValuesField.cs 
b/src/Lucene.Net/Document/BinaryDocValuesField.cs
index e620368..004afe0 100644
--- a/src/Lucene.Net/Document/BinaryDocValuesField.cs
+++ b/src/Lucene.Net/Document/BinaryDocValuesField.cs
@@ -1,4 +1,4 @@
-using Lucene.Net.Index;
+using Lucene.Net.Index;
 using Lucene.Net.Util;
 using System;
 
@@ -54,7 +54,7 @@ namespace Lucene.Net.Documents
         /// Create a new binary <see cref="DocValues"/> field. </summary>
         /// <param name="name"> field name </param>
         /// <param name="value"> binary content </param>
-        /// <exception cref="ArgumentNullException"> if the field name is null 
</exception>
+        /// <exception cref="ArgumentNullException"> if the field <paramref 
name="name"/> is <c>null</c>. </exception>
         public BinaryDocValuesField(string name, BytesRef value)
             : base(name, fType)
         {
diff --git a/src/Lucene.Net/Document/Field.cs b/src/Lucene.Net/Document/Field.cs
index 5b4447c..f6b59f9 100644
--- a/src/Lucene.Net/Document/Field.cs
+++ b/src/Lucene.Net/Document/Field.cs
@@ -1,4 +1,4 @@
-using Lucene.Net.Analysis;
+using Lucene.Net.Analysis;
 using Lucene.Net.Analysis.TokenAttributes;
 using Lucene.Net.Index;
 using Lucene.Net.Util;
@@ -72,7 +72,8 @@ namespace Lucene.Net.Documents
         /// </summary>
         // LUCENENET specific: Made into a property
         // so we can set the data type when it is set.
-        protected object FieldsData
+        // Marked internal for testing.
+        protected internal object FieldsData
         {
             get => fieldsData;
             set
diff --git a/src/Lucene.Net/Document/FloatField.cs 
b/src/Lucene.Net/Document/FloatField.cs
index 807eb10..cdb8c16 100644
--- a/src/Lucene.Net/Document/FloatField.cs
+++ b/src/Lucene.Net/Document/FloatField.cs
@@ -1,4 +1,4 @@
-using Lucene.Net.Index;
+using Lucene.Net.Index;
 using System;
 
 namespace Lucene.Net.Documents
@@ -177,7 +177,7 @@ namespace Lucene.Net.Documents
         /// <param name="value"> 32-bit <see cref="float"/> value </param>
         /// <param name="type"> customized field type: must have <see 
cref="FieldType.NumericType"/>
         ///         of <see cref="NumericType.SINGLE"/>. </param>
-        /// <exception cref="ArgumentNullException"> if the field <paramref 
name="name"/> or <paramref name="type"/> is <see cref="NumericType.NONE"/> 
</exception>
+        /// <exception cref="ArgumentNullException"> if the field <paramref 
name="name"/> or <paramref name="type"/> is <c>null</c>. </exception>
         /// <exception cref="ArgumentException">if the field type does not 
have a <see cref="NumericType.SINGLE"/> <see 
cref="FieldType.NumericType"/></exception>
         public SingleField(string name, float value, FieldType type)
             : base(name, type)
diff --git a/src/Lucene.Net/Document/IntField.cs 
b/src/Lucene.Net/Document/IntField.cs
index 576e849..8a53a34 100644
--- a/src/Lucene.Net/Document/IntField.cs
+++ b/src/Lucene.Net/Document/IntField.cs
@@ -1,4 +1,4 @@
-using Lucene.Net.Index;
+using Lucene.Net.Index;
 using System;
 
 namespace Lucene.Net.Documents
@@ -177,7 +177,7 @@ namespace Lucene.Net.Documents
         /// <param name="value"> 32-bit <see cref="int"/> value </param>
         /// <param name="type"> customized field type: must have <see 
cref="FieldType.NumericType"/>
         ///         of <see cref="NumericType.INT32"/>. </param>
-        /// <exception cref="ArgumentNullException"> if the field <paramref 
name="name"/> or <paramref name="type"/> is <see cref="NumericType.NONE"/> 
</exception>
+        /// <exception cref="ArgumentNullException"> if the field <paramref 
name="name"/> or <paramref name="type"/> is <c>null</c>. </exception>
         /// <exception cref="ArgumentException">if the field type does not 
have a 
         ///         <see cref="FieldType.NumericType"/> of <see 
cref="NumericType.INT32"/> </exception>
         public Int32Field(string name, int value, FieldType type)
diff --git a/src/Lucene.Net/Document/LongField.cs 
b/src/Lucene.Net/Document/LongField.cs
index 9dd4aa8..0e006a5 100644
--- a/src/Lucene.Net/Document/LongField.cs
+++ b/src/Lucene.Net/Document/LongField.cs
@@ -1,4 +1,4 @@
-using Lucene.Net.Index;
+using Lucene.Net.Index;
 using System;
 
 namespace Lucene.Net.Documents
@@ -187,7 +187,7 @@ namespace Lucene.Net.Documents
         /// <param name="value"> 64-bit <see cref="long"/> value </param>
         /// <param name="type"> customized field type: must have <see 
cref="FieldType.NumericType"/>
         ///         of <see cref="NumericType.INT64"/>. </param>
-        /// <exception cref="ArgumentNullException"> if the field <paramref 
name="name"/> or <paramref name="type"/> is <see cref="NumericType.NONE"/> 
</exception>
+        /// <exception cref="ArgumentNullException"> if the field <paramref 
name="name"/> or <paramref name="type"/> is <c>null</c>. </exception>
         /// <exception cref="ArgumentException"> if the field type does not 
have a 
         /// <see cref="FieldType.NumericType"/> of <see 
cref="NumericType.INT64"/> </exception>
         public Int64Field(string name, long value, FieldType type)
diff --git a/src/Lucene.Net/Support/Document/Extensions/DocumentExtensions.cs 
b/src/Lucene.Net/Support/Document/Extensions/DocumentExtensions.cs
index 8e43620..b9209ef 100644
--- a/src/Lucene.Net/Support/Document/Extensions/DocumentExtensions.cs
+++ b/src/Lucene.Net/Support/Document/Extensions/DocumentExtensions.cs
@@ -36,8 +36,12 @@ namespace Lucene.Net.Documents.Extensions
         /// <param name="document">This <see cref="Document"/>.</param>
         /// <param name="name">Field name</param>
         /// <exception cref="InvalidCastException">If the field type cannot be 
cast to <typeparamref name="T"/>.</exception>
+        /// <exception cref="ArgumentNullException">This <paramref 
name="document"/> is <c>null</c>.</exception>
         public static T GetField<T>(this Document document, string name) where 
T : IIndexableField
         {
+            if (document is null)
+                throw new ArgumentNullException(nameof(document));
+
             return (T)document.GetField(name);
         }
 
@@ -50,8 +54,12 @@ namespace Lucene.Net.Documents.Extensions
         /// <param name="name"> the name of the field </param>
         /// <returns> a <see cref="T:IndexableField[]"/> array </returns>
         /// <exception cref="InvalidCastException">If the field type cannot be 
cast to <typeparam name="T"/>.</exception>
+        /// <exception cref="ArgumentNullException">This <paramref 
name="document"/> is <c>null</c>.</exception>
         public static T[] GetFields<T>(this Document document, string name) 
where T : IIndexableField
         {
+            if (document is null)
+                throw new ArgumentNullException(nameof(document));
+
             var fields = document.GetFields(name);
             var result = new T[fields.Length];
             fields.CopyTo(result, 0);
@@ -65,9 +73,12 @@ namespace Lucene.Net.Documents.Extensions
         /// <param name="name"> field name </param>
         /// <param name="value"> binary content </param>
         /// <returns>The field that was added to this <see 
cref="Document"/>.</returns>
-        /// <exception cref="ArgumentNullException"> if the field name is null 
</exception>
+        /// <exception cref="ArgumentNullException"> if this <paramref 
name="document"/> or the field <paramref name="name"/> is <c>null</c>. 
</exception>
         public static BinaryDocValuesField AddBinaryDocValuesField(this 
Document document, string name, BytesRef value)
         {
+            if (document is null)
+                throw new ArgumentNullException(nameof(document));
+
             var field = new BinaryDocValuesField(name, value);
             document.Add(field);
             return field;
@@ -90,9 +101,12 @@ namespace Lucene.Net.Documents.Extensions
         /// <param name="name"> field name </param>
         /// <param name="value"> 64-bit double value </param>
         /// <returns>The field that was added to this <see 
cref="Document"/>.</returns>
-        /// <exception cref="ArgumentNullException"> if the field name is 
<c>null</c> </exception>
+        /// <exception cref="ArgumentNullException"> if this <paramref 
name="document"/> or the field <paramref name="name"/> is <c>null</c> 
</exception>
         public static DoubleDocValuesField AddDoubleDocValuesField(this 
Document document, string name, double value)
         {
+            if (document is null)
+                throw new ArgumentNullException(nameof(document));
+
             var field = new DoubleDocValuesField(name, value);
             document.Add(field);
             return field;
@@ -108,9 +122,12 @@ namespace Lucene.Net.Documents.Extensions
         /// <param name="value"> 64-bit <see cref="double"/> value </param>
         /// <param name="stored"> <see cref="Field.Store.YES"/> if the content 
should also be stored </param>
         /// <returns>The field that was added to this <see 
cref="Document"/>.</returns>
-        /// <exception cref="ArgumentNullException"> if the field name is 
<c>null</c>.  </exception>
+        /// <exception cref="ArgumentNullException"> if this <paramref 
name="document"/> or the field <paramref name="name"/> is <c>null</c>.  
</exception>
         public static DoubleField AddDoubleField(this Document document, 
string name, double value, Field.Store stored)
         {
+            if (document is null)
+                throw new ArgumentNullException(nameof(document));
+
             var field = new DoubleField(name, value, stored);
             document.Add(field);
             return field;
@@ -127,10 +144,13 @@ namespace Lucene.Net.Documents.Extensions
         /// <param name="type"> customized field type: must have <see 
cref="FieldType.NumericType"/>
         ///         of <see cref="NumericType.DOUBLE"/>. </param>
         /// <returns>The field that was added to this <see 
cref="Document"/>.</returns>
-        /// <exception cref="ArgumentNullException"> if the field name or type 
is <c>null</c>, or
+        /// <exception cref="ArgumentNullException"> if this <paramref 
name="document"/>, the field <paramref name="name"/> or <paramref name="type"/> 
is <c>null</c>, or
         ///          if the field type does not have a <see 
cref="NumericType.DOUBLE"/> <see cref="FieldType.NumericType"/> </exception>
         public static DoubleField AddDoubleField(this Document document, 
string name, double value, FieldType type)
         {
+            if (document is null)
+                throw new ArgumentNullException(nameof(document));
+
             var field = new DoubleField(name, value, type);
             document.Add(field);
             return field;
@@ -142,9 +162,12 @@ namespace Lucene.Net.Documents.Extensions
         /// <param name="name"> field name </param>
         /// <param name="value"> 32-bit <see cref="float"/> value </param>
         /// <returns>The field that was added to this <see 
cref="Document"/>.</returns>
-        /// <exception cref="ArgumentNullException"> if the field name is 
<c>null</c> </exception>
+        /// <exception cref="ArgumentNullException"> if this <paramref 
name="document"/> or the field <paramref name="name"/> is <c>null</c> 
</exception>
         public static SingleDocValuesField AddSingleDocValuesField(this 
Document document, string name, float value)
         {
+            if (document is null)
+                throw new ArgumentNullException(nameof(document));
+
             var field = new SingleDocValuesField(name, value);
             document.Add(field);
             return field;
@@ -160,9 +183,12 @@ namespace Lucene.Net.Documents.Extensions
         /// <param name="value"> 32-bit <see cref="float"/> value </param>
         /// <param name="stored"> <see cref="Field.Store.YES"/> if the content 
should also be stored </param>
         /// <returns>The field that was added to this <see 
cref="Document"/>.</returns>
-        /// <exception cref="ArgumentNullException"> if the field <paramref 
name="name"/> is <c>null</c>. </exception>
+        /// <exception cref="ArgumentNullException"> if this <paramref 
name="document"/> or the field <paramref name="name"/> is <c>null</c>. 
</exception>
         public static SingleField AddSingleField(this Document document, 
string name, float value, Field.Store stored)
         {
+            if (document is null)
+                throw new ArgumentNullException(nameof(document));
+
             var field = new SingleField(name, value, stored);
             document.Add(field);
             return field;
@@ -179,10 +205,13 @@ namespace Lucene.Net.Documents.Extensions
         /// <param name="type"> customized field type: must have <see 
cref="FieldType.NumericType"/>
         ///         of <see cref="NumericType.SINGLE"/>. </param>
         /// <returns>The field that was added to this <see 
cref="Document"/>.</returns>
-        /// <exception cref="ArgumentNullException"> if the field <paramref 
name="name"/> or <paramref name="type"/> is <see cref="NumericType.NONE"/> 
</exception>
+        /// <exception cref="ArgumentNullException"> if this <paramref 
name="document"/>, the field <paramref name="name"/> or <paramref name="type"/> 
is <c>null</c>. </exception>
         /// <exception cref="ArgumentException">if the field type does not 
have a <see cref="NumericType.SINGLE"/> <see 
cref="FieldType.NumericType"/></exception>
         public static SingleField AddSingleField(this Document document, 
string name, float value, FieldType type)
         {
+            if (document is null)
+                throw new ArgumentNullException(nameof(document));
+
             var field = new SingleField(name, value, type);
             document.Add(field);
             return field;
@@ -198,9 +227,12 @@ namespace Lucene.Net.Documents.Extensions
         /// <param name="value"> 32-bit <see cref="int"/> value </param>
         /// <param name="stored"> <see cref="Field.Store.YES"/> if the content 
should also be stored </param>
         /// <returns>The field that was added to this <see 
cref="Document"/>.</returns>
-        /// <exception cref="ArgumentNullException"> if the field <paramref 
name="name"/> is <c>null</c>. </exception>
+        /// <exception cref="ArgumentNullException"> if this <paramref 
name="document"/> or the field <paramref name="name"/> is <c>null</c>. 
</exception>
         public static Int32Field AddInt32Field(this Document document, string 
name, int value, Field.Store stored)
         {
+            if (document is null)
+                throw new ArgumentNullException(nameof(document));
+
             var field = new Int32Field(name, value, stored);
             document.Add(field);
             return field;
@@ -218,11 +250,14 @@ namespace Lucene.Net.Documents.Extensions
         /// <param name="type"> customized field type: must have <see 
cref="FieldType.NumericType"/>
         ///         of <see cref="NumericType.INT32"/>. </param>
         /// <returns>The field that was added to this <see 
cref="Document"/>.</returns>
-        /// <exception cref="ArgumentNullException"> if the field <paramref 
name="name"/> or <paramref name="type"/> is <see cref="NumericType.NONE"/> 
</exception>
+        /// <exception cref="ArgumentNullException"> if this <paramref 
name="document"/>, the field <paramref name="name"/> or <paramref name="type"/> 
is <c>null</c>. </exception>
         /// <exception cref="ArgumentException">if the field type does not 
have a 
         ///         <see cref="FieldType.NumericType"/> of <see 
cref="NumericType.INT32"/> </exception>
         public static Int32Field AddInt32Field(this Document document, string 
name, int value, FieldType type)
         {
+            if (document is null)
+                throw new ArgumentNullException(nameof(document));
+
             var field = new Int32Field(name, value, type);
             document.Add(field);
             return field;
@@ -238,9 +273,12 @@ namespace Lucene.Net.Documents.Extensions
         /// <param name="value"> 64-bit <see cref="long"/> value </param>
         /// <param name="stored"> <see cref="Field.Store.YES"/> if the content 
should also be stored </param>
         /// <returns>The field that was added to this <see 
cref="Document"/>.</returns>
-        /// <exception cref="ArgumentNullException"> if the field <paramref 
name="name"/> is <c>null</c>. </exception>
+        /// <exception cref="ArgumentNullException"> if this <paramref 
name="document"/> or the field <paramref name="name"/> is <c>null</c>. 
</exception>
         public static Int64Field AddInt64Field(this Document document, string 
name, long value, Field.Store stored)
         {
+            if (document is null)
+                throw new ArgumentNullException(nameof(document));
+
             var field = new Int64Field(name, value, stored);
             document.Add(field);
             return field;
@@ -257,11 +295,14 @@ namespace Lucene.Net.Documents.Extensions
         /// <param name="type"> customized field type: must have <see 
cref="FieldType.NumericType"/>
         ///         of <see cref="NumericType.INT64"/>. </param>
         /// <returns>The field that was added to this <see 
cref="Document"/>.</returns>
-        /// <exception cref="ArgumentNullException"> if the field <paramref 
name="name"/> or <paramref name="type"/> is <see cref="NumericType.NONE"/> 
</exception>
+        /// <exception cref="ArgumentNullException"> if this <paramref 
name="document"/>, the field <paramref name="name"/> or <paramref name="type"/> 
is <c>null</c>. </exception>
         /// <exception cref="ArgumentException"> if the field type does not 
have a 
         /// <see cref="FieldType.NumericType"/> of <see 
cref="NumericType.INT64"/> </exception>
         public static Int64Field AddInt64Field(this Document document, string 
name, long value, FieldType type)
         {
+            if (document is null)
+                throw new ArgumentNullException(nameof(document));
+
             var field = new Int64Field(name, value, type);
             document.Add(field);
             return field;
@@ -277,9 +318,12 @@ namespace Lucene.Net.Documents.Extensions
         /// <param name="name"> field name </param>
         /// <param name="value"> 64-bit <see cref="long"/> value </param>
         /// <returns>The field that was added to this <see 
cref="Document"/>.</returns>
-        /// <exception cref="ArgumentNullException"> if the field <paramref 
name="name"/> is <c>null</c> </exception>
+        /// <exception cref="ArgumentNullException"> if this <paramref 
name="document"/>, the field <paramref name="name"/> is <c>null</c>. 
</exception>
         public static NumericDocValuesField AddNumericDocValuesField(this 
Document document, string name, long value)
         {
+            if (document is null)
+                throw new ArgumentNullException(nameof(document));
+
             var field = new NumericDocValuesField(name, value);
             document.Add(field);
             return field;
@@ -295,9 +339,12 @@ namespace Lucene.Net.Documents.Extensions
         /// <param name="name"> field name </param>
         /// <param name="bytes"> binary content </param>
         /// <returns>The field that was added to this <see 
cref="Document"/>.</returns>
-        /// <exception cref="ArgumentNullException"> if the field <paramref 
name="name"/> is <c>null</c> </exception>
+        /// <exception cref="ArgumentNullException"> if this <paramref 
name="document"/>, the field <paramref name="name"/> is <c>null</c>. 
</exception>
         public static SortedDocValuesField AddSortedDocValuesField(this 
Document document, string name, BytesRef bytes)
         {
+            if (document is null)
+                throw new ArgumentNullException(nameof(document));
+
             var field = new SortedDocValuesField(name, bytes);
             document.Add(field);
             return field;
@@ -313,9 +360,12 @@ namespace Lucene.Net.Documents.Extensions
         /// <param name="name"> field name </param>
         /// <param name="bytes"> binary content </param>
         /// <returns>The field that was added to this <see 
cref="Document"/>.</returns>
-        /// <exception cref="ArgumentNullException"> if the field <paramref 
name="name"/> is <c>null</c> </exception>
+        /// <exception cref="ArgumentNullException"> if this <paramref 
name="document"/>, the field <paramref name="name"/> is <c>null</c>. 
</exception>
         public static SortedSetDocValuesField AddSortedSetDocValuesField(this 
Document document, string name, BytesRef bytes)
         {
+            if (document is null)
+                throw new ArgumentNullException(nameof(document));
+
             var field = new SortedSetDocValuesField(name, bytes);
             document.Add(field);
             return field;
@@ -330,9 +380,12 @@ namespace Lucene.Net.Documents.Extensions
         /// <param name="name"> field name </param>
         /// <param name="value"> byte array pointing to binary content (not 
copied) </param>
         /// <returns>The field that was added to this <see 
cref="Document"/>.</returns>
-        /// <exception cref="ArgumentNullException"> if the field <paramref 
name="name"/> is <c>null</c>. </exception>
+        /// <exception cref="ArgumentNullException"> if this <paramref 
name="document"/>, the field <paramref name="name"/> is <c>null</c>. 
</exception>
         public static StoredField AddStoredField(this Document document, 
string name, byte[] value)
         {
+            if (document is null)
+                throw new ArgumentNullException(nameof(document));
+
             var field = new StoredField(name, value);
             document.Add(field);
             return field;
@@ -349,9 +402,12 @@ namespace Lucene.Net.Documents.Extensions
         /// <param name="offset"> starting position of the byte array </param>
         /// <param name="length"> valid length of the byte array </param>
         /// <returns>The field that was added to this <see 
cref="Document"/>.</returns>
-        /// <exception cref="ArgumentNullException"> if the field <paramref 
name="name"/> is <c>null</c>. </exception>
+        /// <exception cref="ArgumentNullException"> if this <paramref 
name="document"/>, the field <paramref name="name"/> is <c>null</c>. 
</exception>
         public static StoredField AddStoredField(this Document document, 
string name, byte[] value, int offset, int length)
         {
+            if (document is null)
+                throw new ArgumentNullException(nameof(document));
+
             var field = new StoredField(name, value, offset, length);
             document.Add(field);
             return field;
@@ -366,9 +422,12 @@ namespace Lucene.Net.Documents.Extensions
         /// <param name="name"> field name </param>
         /// <param name="value"> <see cref="BytesRef"/> pointing to binary 
content (not copied) </param>
         /// <returns>The field that was added to this <see 
cref="Document"/>.</returns>
-        /// <exception cref="ArgumentNullException"> if the field <paramref 
name="name"/> is <c>null</c>. </exception>
+        /// <exception cref="ArgumentNullException"> if this <paramref 
name="document"/>, the field <paramref name="name"/> is <c>null</c>. 
</exception>
         public static StoredField AddStoredField(this Document document, 
string name, BytesRef value)
         {
+            if (document is null)
+                throw new ArgumentNullException(nameof(document));
+
             var field = new StoredField(name, value);
             document.Add(field);
             return field;
@@ -380,9 +439,12 @@ namespace Lucene.Net.Documents.Extensions
         /// <param name="name"> field name </param>
         /// <param name="value"> <see cref="string"/> value </param>
         /// <returns>The field that was added to this <see 
cref="Document"/>.</returns>
-        /// <exception cref="ArgumentNullException"> if the field <paramref 
name="name"/> or <paramref name="value"/> is <c>null</c>. </exception>
+        /// <exception cref="ArgumentNullException"> if this <paramref 
name="document"/>, the field <paramref name="name"/> or <paramref 
name="value"/> is <c>null</c>. </exception>
         public static StoredField AddStoredField(this Document document, 
string name, string value)
         {
+            if (document is null)
+                throw new ArgumentNullException(nameof(document));
+
             var field = new StoredField(name, value);
             document.Add(field);
             return field;
@@ -394,9 +456,12 @@ namespace Lucene.Net.Documents.Extensions
         /// <param name="name"> field name </param>
         /// <param name="value"> <see cref="int"/> value </param>
         /// <returns>The field that was added to this <see 
cref="Document"/>.</returns>
-        /// <exception cref="ArgumentNullException"> if the field <paramref 
name="name"/> is <c>null</c>. </exception>
+        /// <exception cref="ArgumentNullException"> if this <paramref 
name="document"/>, the field <paramref name="name"/> is <c>null</c>. 
</exception>
         public static StoredField AddStoredField(this Document document, 
string name, int value)
         {
+            if (document is null)
+                throw new ArgumentNullException(nameof(document));
+
             var field = new StoredField(name, value);
             document.Add(field);
             return field;
@@ -408,9 +473,12 @@ namespace Lucene.Net.Documents.Extensions
         /// <param name="name"> field name </param>
         /// <param name="value"> <see cref="float"/> value </param>
         /// <returns>The field that was added to this <see 
cref="Document"/>.</returns>
-        /// <exception cref="ArgumentNullException"> if the field <paramref 
name="name"/> is <c>null</c>. </exception>
+        /// <exception cref="ArgumentNullException"> if this <paramref 
name="document"/>, the field <paramref name="name"/> is <c>null</c>. 
</exception>
         public static StoredField AddStoredField(this Document document, 
string name, float value)
         {
+            if (document is null)
+                throw new ArgumentNullException(nameof(document));
+
             var field = new StoredField(name, value);
             document.Add(field);
             return field;
@@ -422,9 +490,12 @@ namespace Lucene.Net.Documents.Extensions
         /// <param name="name"> field name </param>
         /// <param name="value"> <see cref="long"/> value </param>
         /// <returns>The field that was added to this <see 
cref="Document"/>.</returns>
-        /// <exception cref="ArgumentNullException"> if the field <paramref 
name="name"/> is <c>null</c>. </exception>
+        /// <exception cref="ArgumentNullException"> if this <paramref 
name="document"/>, the field <paramref name="name"/> is <c>null</c>. 
</exception>
         public static StoredField AddStoredField(this Document document, 
string name, long value)
         {
+            if (document is null)
+                throw new ArgumentNullException(nameof(document));
+
             var field = new StoredField(name, value);
             document.Add(field);
             return field;
@@ -436,9 +507,12 @@ namespace Lucene.Net.Documents.Extensions
         /// <param name="name"> field name </param>
         /// <param name="value"> <see cref="double"/> value </param>
         /// <returns>The field that was added to this <see 
cref="Document"/>.</returns>
-        /// <exception cref="ArgumentNullException"> if the field <paramref 
name="name"/> is <c>null</c>. </exception>
+        /// <exception cref="ArgumentNullException"> if this <paramref 
name="document"/>, the field <paramref name="name"/> is <c>null</c>. 
</exception>
         public static StoredField AddStoredField(this Document document, 
string name, double value)
         {
+            if (document is null)
+                throw new ArgumentNullException(nameof(document));
+
             var field = new StoredField(name, value);
             document.Add(field);
             return field;
@@ -452,9 +526,12 @@ namespace Lucene.Net.Documents.Extensions
         /// <param name="value"> <see cref="string"/> value </param>
         /// <param name="stored"> <see cref="Field.Store.YES"/> if the content 
should also be stored </param>
         /// <returns>The field that was added to this <see 
cref="Document"/>.</returns>
-        /// <exception cref="ArgumentNullException"> if the field <paramref 
name="name"/> or <paramref name="value"/> is <c>null</c>. </exception>
+        /// <exception cref="ArgumentNullException"> if this <paramref 
name="document"/>, the field <paramref name="name"/> or <paramref 
name="value"/> is <c>null</c>. </exception>
         public static StringField AddStringField(this Document document, 
string name, string value, Field.Store stored)
         {
+            if (document is null)
+                throw new ArgumentNullException(nameof(document));
+
             var field = new StringField(name, value, stored);
             document.Add(field);
             return field;
@@ -466,9 +543,12 @@ namespace Lucene.Net.Documents.Extensions
         /// <param name="name"> field name </param>
         /// <param name="reader"> <see cref="TextReader"/> value </param>
         /// <returns>The field that was added to this <see 
cref="Document"/>.</returns>
-        /// <exception cref="ArgumentNullException"> if the field <paramref 
name="name"/> or <paramref name="reader"/> is <c>null</c> </exception>
+        /// <exception cref="ArgumentNullException"> if this <paramref 
name="document"/>, the field <paramref name="name"/> or <paramref 
name="reader"/> is <c>null</c>. </exception>
         public static TextField AddTextField(this Document document, string 
name, TextReader reader)
         {
+            if (document is null)
+                throw new ArgumentNullException(nameof(document));
+
             var field = new TextField(name, reader);
             document.Add(field);
             return field;
@@ -481,9 +561,12 @@ namespace Lucene.Net.Documents.Extensions
         /// <param name="value"> <see cref="string"/> value </param>
         /// <param name="stored"> <see cref="Field.Store.YES"/> if the content 
should also be stored </param>
         /// <returns>The field that was added to this <see 
cref="Document"/>.</returns>
-        /// <exception cref="ArgumentNullException"> if the field <paramref 
name="name"/> or <paramref name="value"/> is <c>null</c>. </exception>
+        /// <exception cref="ArgumentNullException"> if this <paramref 
name="document"/>, the field <paramref name="name"/> or <paramref 
name="value"/> is <c>null</c>. </exception>
         public static TextField AddTextField(this Document document, string 
name, string value, Field.Store stored)
         {
+            if (document is null)
+                throw new ArgumentNullException(nameof(document));
+
             var field = new TextField(name, value, stored);
             document.Add(field);
             return field;
@@ -495,9 +578,12 @@ namespace Lucene.Net.Documents.Extensions
         /// <param name="name"> field name </param>
         /// <param name="stream"> <see cref="TokenStream"/> value </param>
         /// <returns>The field that was added to this <see 
cref="Document"/>.</returns>
-        /// <exception cref="ArgumentNullException"> if the field <paramref 
name="name"/> or <paramref name="stream"/> is <c>null</c>. </exception>
+        /// <exception cref="ArgumentNullException"> if this <paramref 
name="document"/>, the field <paramref name="name"/> or <paramref 
name="stream"/> is <c>null</c>. </exception>
         public static TextField AddTextField(this Document document, string 
name, TokenStream stream)
         {
+            if (document is null)
+                throw new ArgumentNullException(nameof(document));
+
             var field = new TextField(name, stream);
             document.Add(field);
             return field;
diff --git a/src/dotnet/Lucene.Net.ICU/Support/Document/DocumentExtensions.cs 
b/src/dotnet/Lucene.Net.ICU/Support/Document/Extensions/DocumentExtensions.cs
similarity index 86%
rename from src/dotnet/Lucene.Net.ICU/Support/Document/DocumentExtensions.cs
rename to 
src/dotnet/Lucene.Net.ICU/Support/Document/Extensions/DocumentExtensions.cs
index 31f070c..67dc9d9 100644
--- a/src/dotnet/Lucene.Net.ICU/Support/Document/DocumentExtensions.cs
+++ 
b/src/dotnet/Lucene.Net.ICU/Support/Document/Extensions/DocumentExtensions.cs
@@ -1,7 +1,8 @@
 using ICU4N.Text;
 using Lucene.Net.Collation;
+using System;
 
-namespace Lucene.Net.Documents
+namespace Lucene.Net.Documents.Extensions
 {
     /*
      * Licensed to the Apache Software Foundation (ASF) under one or more
@@ -36,8 +37,12 @@ namespace Lucene.Net.Documents
         /// <param name="name">Field name.</param>
         /// <param name="collator">Collator for generating collation 
keys.</param>
         /// <returns>The field that was added to this <see 
cref="Document"/>.</returns>
+        /// <exception cref="ArgumentNullException">This <paramref 
name="document"/>, <paramref name="name"/> or <paramref name="collator"/> is 
<c>null</c>. </exception>
         public static ICUCollationDocValuesField 
AddICUCollationDocValuesField(this Document document, string name, Collator 
collator)
         {
+            if (document is null)
+                throw new ArgumentNullException(nameof(document));
+
             var field = new ICUCollationDocValuesField(name, collator);
             document.Add(field);
             return field;
diff --git a/src/dotnet/Lucene.Net.Tests.ICU/Lucene.Net.Tests.ICU.csproj 
b/src/dotnet/Lucene.Net.Tests.ICU/Lucene.Net.Tests.ICU.csproj
index 45bb7d7..50d6248 100644
--- a/src/dotnet/Lucene.Net.Tests.ICU/Lucene.Net.Tests.ICU.csproj
+++ b/src/dotnet/Lucene.Net.Tests.ICU/Lucene.Net.Tests.ICU.csproj
@@ -65,12 +65,12 @@
   </ItemGroup>
 
   <ItemGroup Condition=" '$(TargetFramework)' == 'netcoreapp3.1' ">
-    <PackageReference Include="System.Net.Primitives" 
Version="$(SystemNetPrimitivesPackageVersion)"/>
+    <PackageReference Include="System.Net.Primitives" 
Version="$(SystemNetPrimitivesPackageVersion)" />
   </ItemGroup>
 
   <ItemGroup Condition=" '$(TargetFramework)' == 'net48' ">
-    <PackageReference 
Include="Microsoft.Extensions.DependencyInjection.Abstractions" 
Version="$(MicrosoftExtensionsDependencyInjectionAbstractionsPackageVersion)"/>
-    <PackageReference Include="Microsoft.Extensions.Options" 
Version="$(MicrosoftExtensionsOptionsPackageVersion)"/>
+    <PackageReference 
Include="Microsoft.Extensions.DependencyInjection.Abstractions" 
Version="$(MicrosoftExtensionsDependencyInjectionAbstractionsPackageVersion)" />
+    <PackageReference Include="Microsoft.Extensions.Options" 
Version="$(MicrosoftExtensionsOptionsPackageVersion)" />
   </ItemGroup>
 
 </Project>
diff --git 
a/src/dotnet/Lucene.Net.Tests.ICU/Support/Document/Extensions/TestDocumentExtensions.cs
 
b/src/dotnet/Lucene.Net.Tests.ICU/Support/Document/Extensions/TestDocumentExtensions.cs
new file mode 100644
index 0000000..fbc259c
--- /dev/null
+++ 
b/src/dotnet/Lucene.Net.Tests.ICU/Support/Document/Extensions/TestDocumentExtensions.cs
@@ -0,0 +1,55 @@
+using ICU4N.Text;
+using Lucene.Net.Attributes;
+using Lucene.Net.Collation;
+using Lucene.Net.Index;
+using Lucene.Net.Util;
+using NUnit.Framework;
+using System;
+using System.Globalization;
+using Assert = Lucene.Net.TestFramework.Assert;
+
+namespace Lucene.Net.Documents.Extensions
+{
+    /*
+     * 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.
+     */
+
+    public class TestDocumentExtensions : LuceneTestCase
+    {
+        [Test]
+        [LuceneNetSpecific]
+        public void TestAddICUCollationDocValuesField()
+        {
+            ICUCollationDocValuesField field = null;
+            Collator collator = Collator.GetInstance(new CultureInfo("en"));
+            AssertDocumentExtensionAddsToDocument(document => field = 
document.AddICUCollationDocValuesField("theName", collator));
+            Assert.AreEqual("theName", field.Name);
+            Assert.AreEqual(collator, field.collator); // Collator is cloned, 
so we don't expect them to be the same instance
+        }
+
+        private void AssertDocumentExtensionAddsToDocument<T>(Func<Document, 
T> extension) where T : IIndexableField
+        {
+            var document = new Document();
+            var field = extension(document);
+            Assert.IsNotNull(field);
+            Assert.AreEqual(1, document.Fields.Count);
+            Assert.AreSame(field, document.Fields[0]);
+
+            document = null;
+            Assert.Throws<ArgumentNullException>(() => extension(document));
+        }
+    }
+}

Reply via email to