Reorganize some tests
diff --git a/csharp/src/Google.Protobuf.Test/Reflection/CustomOptionsTest.cs b/csharp/src/Google.Protobuf.Test/Reflection/CustomOptionsTest.cs
index 527fa8a..02fe778 100644
--- a/csharp/src/Google.Protobuf.Test/Reflection/CustomOptionsTest.cs
+++ b/csharp/src/Google.Protobuf.Test/Reflection/CustomOptionsTest.cs
@@ -73,8 +73,8 @@
         [Test]
         public void ScalarOptions()
         {
-            var options = CustomOptionOtherValues.Descriptor.CustomOptions;
             var d = CustomOptionOtherValues.Descriptor;
+            var options = d.CustomOptions;
             AssertOption(-100, options.TryGetInt32, Int32Opt, d.GetOption);
             AssertOption(12.3456789f, options.TryGetFloat, FloatOpt, d.GetOption);
             AssertOption(1.234567890123456789d, options.TryGetDouble, DoubleOpt, d.GetOption);
@@ -86,8 +86,9 @@
         [Test]
         public void MessageOptions()
         {
-            var options = VariousComplexOptions.Descriptor.CustomOptions;
-            AssertOption(new ComplexOptionType1 { Foo = 42, Foo4 = { 99, 88 } }, options.TryGetMessage, ComplexOpt1, VariousComplexOptions.Descriptor.GetOption);
+            var d = VariousComplexOptions.Descriptor;
+            var options = d.CustomOptions;
+            AssertOption(new ComplexOptionType1 { Foo = 42, Foo4 = { 99, 88 } }, options.TryGetMessage, ComplexOpt1, d.GetOption);
             AssertOption(new ComplexOptionType2
             {
                 Baz = 987,
@@ -95,8 +96,8 @@
                 Fred = new ComplexOptionType4 { Waldo = 321 },
                 Barney = { new ComplexOptionType4 { Waldo = 101 }, new ComplexOptionType4 { Waldo = 212 } }
             },
-                options.TryGetMessage, ComplexOpt2, VariousComplexOptions.Descriptor.GetOption);
-            AssertOption(new ComplexOptionType3 { Qux = 9 }, options.TryGetMessage, ComplexOpt3, VariousComplexOptions.Descriptor.GetOption);
+                options.TryGetMessage, ComplexOpt2, d.GetOption);
+            AssertOption(new ComplexOptionType3 { Qux = 9 }, options.TryGetMessage, ComplexOpt3, d.GetOption);
         }
 
         [Test]
@@ -132,8 +133,8 @@
         [Test]
         public void MinValues()
         {
-            var options = CustomOptionMinIntegerValues.Descriptor.CustomOptions;
             var d = CustomOptionMinIntegerValues.Descriptor;
+            var options = d.CustomOptions;
             AssertOption(false, options.TryGetBool, BoolOpt, d.GetOption);
             AssertOption(int.MinValue, options.TryGetInt32, Int32Opt, d.GetOption);
             AssertOption(long.MinValue, options.TryGetInt64, Int64Opt, d.GetOption);
@@ -150,8 +151,8 @@
         [Test]
         public void MaxValues()
         {
-            var options = CustomOptionMaxIntegerValues.Descriptor.CustomOptions;
             var d = CustomOptionMaxIntegerValues.Descriptor;
+            var options = d.CustomOptions;
             AssertOption(true, options.TryGetBool, BoolOpt, d.GetOption);
             AssertOption(int.MaxValue, options.TryGetInt32, Int32Opt, d.GetOption);
             AssertOption(long.MaxValue, options.TryGetInt64, Int64Opt, d.GetOption);
diff --git a/csharp/src/Google.Protobuf.Test/Reflection/FieldAccessTest.cs b/csharp/src/Google.Protobuf.Test/Reflection/FieldAccessTest.cs
index 6332afc..fcfff4f 100644
--- a/csharp/src/Google.Protobuf.Test/Reflection/FieldAccessTest.cs
+++ b/csharp/src/Google.Protobuf.Test/Reflection/FieldAccessTest.cs
@@ -86,32 +86,113 @@
             var dictionary = (IDictionary) fields[TestMap.MapStringStringFieldNumber].Accessor.GetValue(mapMessage);
             Assert.AreEqual(mapMessage.MapStringString, dictionary);
             Assert.AreEqual("value1", dictionary["key1"]);
+        }

+

+        [Test]
+        public void GetValue_IncorrectType()
+        {
+            IMessage message = SampleMessages.CreateFullTestAllTypes();
+            var fields = message.Descriptor.Fields;
+            Assert.Throws<InvalidCastException>(() => fields[TestProtos.TestAllTypes.SingleBoolFieldNumber].Accessor.GetValue(new TestMap()));
         }
 
         [Test]
-        public void GetExtensionValue()

+        public void HasValue_Proto3()

         {

-            var message = SampleMessages.CreateFullTestAllExtensions();

-

-            // test that the reflector works, since the reflector just runs through IExtendableMessage

-            Assert.AreEqual(message.GetExtension(OptionalBoolExtension), Proto2.TestAllExtensions.Descriptor.FindFieldByNumber(OptionalBoolExtension.FieldNumber).Accessor.GetValue(message));

+            IMessage message = SampleMessages.CreateFullTestAllTypes();

+            var fields = message.Descriptor.Fields;

+            Assert.Throws<InvalidOperationException>(() => fields[TestProtos.TestAllTypes.SingleBoolFieldNumber].Accessor.HasValue(message));

         }
 
         [Test]
-        public void GetRepeatedExtensionValue()

+        public void HasValue()

         {

-            // check to make sure repeated accessor uses GetOrRegister

-            var message = new Proto2.TestAllExtensions();

+            IMessage message = new Proto2.TestAllTypes();

+            var fields = message.Descriptor.Fields;

+            var accessor = fields[Proto2.TestAllTypes.OptionalBoolFieldNumber].Accessor;

 

-            Assert.IsNull(message.GetExtension(RepeatedBoolExtension));

-            Assert.IsNotNull(Proto2.TestAllExtensions.Descriptor.FindFieldByNumber(RepeatedBoolExtension.FieldNumber).Accessor.GetValue(message));

-            Assert.IsNotNull(message.GetExtension(RepeatedBoolExtension));

+            Assert.False(accessor.HasValue(message));

 

-            message.ClearExtension(RepeatedBoolExtension);

-            Assert.IsNull(message.GetExtension(RepeatedBoolExtension));

+            accessor.SetValue(message, true);

+            Assert.True(accessor.HasValue(message));

+

+            accessor.Clear(message);

+            Assert.False(accessor.HasValue(message));

+        }
+

+        [Test]
+        public void SetValue_SingleFields()
+        {
+            // Just a sample (primitives, messages, enums, strings, byte strings)
+            var message = SampleMessages.CreateFullTestAllTypes();
+            var fields = TestProtos.TestAllTypes.Descriptor.Fields;
+            fields[TestProtos.TestAllTypes.SingleBoolFieldNumber].Accessor.SetValue(message, false);
+            fields[TestProtos.TestAllTypes.SingleInt32FieldNumber].Accessor.SetValue(message, 500);
+            fields[TestProtos.TestAllTypes.SingleStringFieldNumber].Accessor.SetValue(message, "It's a string");
+            fields[TestProtos.TestAllTypes.SingleBytesFieldNumber].Accessor.SetValue(message, ByteString.CopyFrom(99, 98, 97));
+            fields[TestProtos.TestAllTypes.SingleForeignEnumFieldNumber].Accessor.SetValue(message, ForeignEnum.ForeignFoo);
+            fields[TestProtos.TestAllTypes.SingleForeignMessageFieldNumber].Accessor.SetValue(message, new ForeignMessage { C = 12345 });
+            fields[TestProtos.TestAllTypes.SingleDoubleFieldNumber].Accessor.SetValue(message, 20150701.5);
+
+            var expected = new TestAllTypes(SampleMessages.CreateFullTestAllTypes())
+            {
+                SingleBool = false,
+                SingleInt32 = 500,
+                SingleString = "It's a string",
+                SingleBytes = ByteString.CopyFrom(99, 98, 97),
+                SingleForeignEnum = ForeignEnum.ForeignFoo,
+                SingleForeignMessage = new ForeignMessage { C = 12345 },
+                SingleDouble = 20150701.5
+            };
+
+            Assert.AreEqual(expected, message);
+        }

+

+        [Test]
+        public void SetValue_SingleFields_WrongType()
+        {
+            IMessage message = SampleMessages.CreateFullTestAllTypes();
+            var fields = message.Descriptor.Fields;
+            Assert.Throws<InvalidCastException>(() => fields[TestProtos.TestAllTypes.SingleBoolFieldNumber].Accessor.SetValue(message, "This isn't a bool"));
         }
 
         [Test]
+        public void SetValue_MapFields()
+        {
+            IMessage message = new TestMap();
+            var fields = message.Descriptor.Fields;
+            Assert.Throws<InvalidOperationException>(() => fields[TestMap.MapStringStringFieldNumber].Accessor.SetValue(message, new Dictionary<string, string>()));
+        }
+
+        [Test]
+        public void SetValue_RepeatedFields()
+        {
+            IMessage message = SampleMessages.CreateFullTestAllTypes();
+            var fields = message.Descriptor.Fields;
+            Assert.Throws<InvalidOperationException>(() => fields[TestProtos.TestAllTypes.RepeatedDoubleFieldNumber].Accessor.SetValue(message, new double[10]));
+        }
+
+        [Test]
+        public void Oneof()
+        {
+            var message = new TestAllTypes();
+            var descriptor = TestProtos.TestAllTypes.Descriptor;
+            Assert.AreEqual(1, descriptor.Oneofs.Count);
+            var oneof = descriptor.Oneofs[0];
+            Assert.AreEqual("oneof_field", oneof.Name);
+            Assert.IsNull(oneof.Accessor.GetCaseFieldDescriptor(message));
+
+            message.OneofString = "foo";
+            Assert.AreSame(descriptor.Fields[TestProtos.TestAllTypes.OneofStringFieldNumber], oneof.Accessor.GetCaseFieldDescriptor(message));
+
+            message.OneofUint32 = 10;
+            Assert.AreSame(descriptor.Fields[TestProtos.TestAllTypes.OneofUint32FieldNumber], oneof.Accessor.GetCaseFieldDescriptor(message));
+
+            oneof.Accessor.Clear(message);
+            Assert.AreEqual(TestProtos.TestAllTypes.OneofFieldOneofCase.None, message.OneofFieldCase);
+        }

+

+        [Test]
         public void Clear()
         {
             var message = SampleMessages.CreateFullTestAllTypes();
@@ -145,86 +226,6 @@
         }
 
         [Test]
-        public void SetValue_SingleFields()
-        {
-            // Just a sample (primitives, messages, enums, strings, byte strings)
-            var message = SampleMessages.CreateFullTestAllTypes();
-            var fields = TestProtos.TestAllTypes.Descriptor.Fields;
-            fields[TestProtos.TestAllTypes.SingleBoolFieldNumber].Accessor.SetValue(message, false);
-            fields[TestProtos.TestAllTypes.SingleInt32FieldNumber].Accessor.SetValue(message, 500);
-            fields[TestProtos.TestAllTypes.SingleStringFieldNumber].Accessor.SetValue(message, "It's a string");
-            fields[TestProtos.TestAllTypes.SingleBytesFieldNumber].Accessor.SetValue(message, ByteString.CopyFrom(99, 98, 97));
-            fields[TestProtos.TestAllTypes.SingleForeignEnumFieldNumber].Accessor.SetValue(message, ForeignEnum.ForeignFoo);
-            fields[TestProtos.TestAllTypes.SingleForeignMessageFieldNumber].Accessor.SetValue(message, new ForeignMessage { C = 12345 });
-            fields[TestProtos.TestAllTypes.SingleDoubleFieldNumber].Accessor.SetValue(message, 20150701.5);
-
-            var expected = new TestAllTypes(SampleMessages.CreateFullTestAllTypes())
-            {
-                SingleBool = false,
-                SingleInt32 = 500,
-                SingleString = "It's a string",
-                SingleBytes = ByteString.CopyFrom(99, 98, 97),
-                SingleForeignEnum = ForeignEnum.ForeignFoo,
-                SingleForeignMessage = new ForeignMessage { C = 12345 },
-                SingleDouble = 20150701.5
-            };
-
-            Assert.AreEqual(expected, message);
-        }
-
-        [Test]
-        public void SetValue_SingleFields_WrongType()
-        {
-            IMessage message = SampleMessages.CreateFullTestAllTypes();
-            var fields = message.Descriptor.Fields;
-            Assert.Throws<InvalidCastException>(() => fields[TestProtos.TestAllTypes.SingleBoolFieldNumber].Accessor.SetValue(message, "This isn't a bool"));
-        }
-
-        [Test]
-        public void SetValue_MapFields()
-        {
-            IMessage message = new TestMap();
-            var fields = message.Descriptor.Fields;
-            Assert.Throws<InvalidOperationException>(() => fields[TestMap.MapStringStringFieldNumber].Accessor.SetValue(message, new Dictionary<string, string>()));
-        }
-
-        [Test]
-        public void SetValue_RepeatedFields()
-        {
-            IMessage message = SampleMessages.CreateFullTestAllTypes();
-            var fields = message.Descriptor.Fields;
-            Assert.Throws<InvalidOperationException>(() => fields[TestProtos.TestAllTypes.RepeatedDoubleFieldNumber].Accessor.SetValue(message, new double[10]));
-        }
-
-        [Test]
-        public void GetValue_IncorrectType()
-        {
-            IMessage message = SampleMessages.CreateFullTestAllTypes();
-            var fields = message.Descriptor.Fields;
-            Assert.Throws<InvalidCastException>(() => fields[TestProtos.TestAllTypes.SingleBoolFieldNumber].Accessor.GetValue(new TestMap()));
-        }
-
-        [Test]
-        public void Oneof()
-        {
-            var message = new TestAllTypes();
-            var descriptor = TestProtos.TestAllTypes.Descriptor;
-            Assert.AreEqual(1, descriptor.Oneofs.Count);
-            var oneof = descriptor.Oneofs[0];
-            Assert.AreEqual("oneof_field", oneof.Name);
-            Assert.IsNull(oneof.Accessor.GetCaseFieldDescriptor(message));
-
-            message.OneofString = "foo";
-            Assert.AreSame(descriptor.Fields[TestProtos.TestAllTypes.OneofStringFieldNumber], oneof.Accessor.GetCaseFieldDescriptor(message));
-
-            message.OneofUint32 = 10;
-            Assert.AreSame(descriptor.Fields[TestProtos.TestAllTypes.OneofUint32FieldNumber], oneof.Accessor.GetCaseFieldDescriptor(message));
-
-            oneof.Accessor.Clear(message);
-            Assert.AreEqual(TestProtos.TestAllTypes.OneofFieldOneofCase.None, message.OneofFieldCase);
-        }
-
-        [Test]
         public void FieldDescriptor_ByName()
         {
             var descriptor = TestProtos.TestAllTypes.Descriptor;
@@ -240,5 +241,28 @@
             Assert.Throws<KeyNotFoundException>(() => descriptor.Fields[999999].ToString());
             Assert.Throws<KeyNotFoundException>(() => descriptor.Fields["not found"].ToString());
         }
+
+        [Test]
+        public void GetExtensionValue()

+        {

+            var message = SampleMessages.CreateFullTestAllExtensions();

+

+            // test that the reflector works, since the reflector just runs through IExtendableMessage

+            Assert.AreEqual(message.GetExtension(OptionalBoolExtension), Proto2.TestAllExtensions.Descriptor.FindFieldByNumber(OptionalBoolExtension.FieldNumber).Accessor.GetValue(message));

+        }
+
+        [Test]
+        public void GetRepeatedExtensionValue()

+        {

+            // check to make sure repeated accessor uses GetOrRegister

+            var message = new Proto2.TestAllExtensions();

+

+            Assert.IsNull(message.GetExtension(RepeatedBoolExtension));

+            Assert.IsNotNull(Proto2.TestAllExtensions.Descriptor.FindFieldByNumber(RepeatedBoolExtension.FieldNumber).Accessor.GetValue(message));

+            Assert.IsNotNull(message.GetExtension(RepeatedBoolExtension));

+

+            message.ClearExtension(RepeatedBoolExtension);

+            Assert.IsNull(message.GetExtension(RepeatedBoolExtension));

+        }
     }
 }