improve test coverage
diff --git a/csharp/src/Google.Protobuf.Test/ExtensionSetTest.cs b/csharp/src/Google.Protobuf.Test/ExtensionSetTest.cs
index 33dc504..2607811 100644
--- a/csharp/src/Google.Protobuf.Test/ExtensionSetTest.cs
+++ b/csharp/src/Google.Protobuf.Test/ExtensionSetTest.cs
@@ -1,4 +1,4 @@
-using Google.Protobuf.TestProtos.Proto2;
+using Google.Protobuf.TestProtos.Proto2;

 using NUnit.Framework;

 

 using static Google.Protobuf.TestProtos.Proto2.UnittestExtensions;

@@ -34,12 +34,14 @@
             message.SetExtension(OptionalBoolExtension, true);

             var serialized = message.ToByteArray();

 

-            var other = TestAllExtensions.Parser

-                .WithExtensionRegistry(new ExtensionRegistry() { OptionalBoolExtension })

-                .ParseFrom(serialized);

-

-            Assert.AreEqual(message, other);

-            Assert.AreEqual(message.CalculateSize(), other.CalculateSize());

+            MessageParsingHelpers.AssertReadingMessage(

+                TestAllExtensions.Parser.WithExtensionRegistry(new ExtensionRegistry() { OptionalBoolExtension }),

+                serialized,

+                other =>

+                {

+                    Assert.AreEqual(message, other);

+                    Assert.AreEqual(message.CalculateSize(), other.CalculateSize());

+                });

         }

 

         [Test]

diff --git a/csharp/src/Google.Protobuf.Test/GeneratedMessageTest.Proto2.cs b/csharp/src/Google.Protobuf.Test/GeneratedMessageTest.Proto2.cs
index 718c3ed..5f90c94 100644
--- a/csharp/src/Google.Protobuf.Test/GeneratedMessageTest.Proto2.cs
+++ b/csharp/src/Google.Protobuf.Test/GeneratedMessageTest.Proto2.cs
@@ -269,8 +269,8 @@
         [Test]

         public void RequiredFieldsNoThrow()

         {

-            Assert.DoesNotThrow(() => TestRequired.Parser.ParseFrom(new byte[0]));

-            Assert.DoesNotThrow(() => (TestRequired.Parser as MessageParser).ParseFrom(new byte[0]));

+            Assert.DoesNotThrow(() => MessageParsingHelpers.AssertReadingMessage(TestRequired.Parser, new byte[0], m => { }));

+            Assert.DoesNotThrow(() => MessageParsingHelpers.AssertReadingMessage(TestRequired.Parser as MessageParser, new byte[0], m => { }));

         }

 

         [Test]

@@ -344,9 +344,7 @@
                 }

             };

 

-            byte[] bytes = message.ToByteArray();

-            TestAllTypes parsed = Proto2.TestAllTypes.Parser.ParseFrom(bytes);

-            Assert.AreEqual(message, parsed);

+            MessageParsingHelpers.AssertRoundtrip(Proto2.TestAllTypes.Parser, message);

         }

 

         [Test]

@@ -361,9 +359,9 @@
                 new RepeatedGroup_extension { A = 30 }

             });

 

-            byte[] bytes = message.ToByteArray();

-            TestAllExtensions extendable_parsed = TestAllExtensions.Parser.WithExtensionRegistry(new ExtensionRegistry() { UnittestExtensions.OptionalGroupExtension, UnittestExtensions.RepeatedGroupExtension }).ParseFrom(bytes);

-            Assert.AreEqual(message, extendable_parsed);

+            MessageParsingHelpers.AssertRoundtrip(

+                TestAllExtensions.Parser.WithExtensionRegistry(new ExtensionRegistry() { UnittestExtensions.OptionalGroupExtension, UnittestExtensions.RepeatedGroupExtension }),

+                message);

         }

 

         [Test]

@@ -372,9 +370,9 @@
             var message = new TestGroupExtension();

             message.SetExtension(TestNestedExtension.Extensions.OptionalGroupExtension, new TestNestedExtension.Types.OptionalGroup_extension { A = 10 });

 

-            byte[] bytes = message.ToByteArray();

-            TestGroupExtension extendable_parsed = TestGroupExtension.Parser.WithExtensionRegistry(new ExtensionRegistry() { TestNestedExtension.Extensions.OptionalGroupExtension }).ParseFrom(bytes);

-            Assert.AreEqual(message, extendable_parsed);

+            MessageParsingHelpers.AssertRoundtrip(

+                TestGroupExtension.Parser.WithExtensionRegistry(new ExtensionRegistry() { TestNestedExtension.Extensions.OptionalGroupExtension }),

+                message);

         }

     }

 }

diff --git a/csharp/src/Google.Protobuf.Test/MessageParsingHelpers.cs b/csharp/src/Google.Protobuf.Test/MessageParsingHelpers.cs
index d629d9c..4877ae6 100644
--- a/csharp/src/Google.Protobuf.Test/MessageParsingHelpers.cs
+++ b/csharp/src/Google.Protobuf.Test/MessageParsingHelpers.cs
@@ -54,6 +54,21 @@
             assert(parsedStream);
         }
 
+        public static void AssertReadingMessage(MessageParser parser, byte[] bytes, Action<IMessage> assert)
+        {
+            var parsedStream = parser.ParseFrom(bytes);
+
+            // Load content as single segment
+            var parsedBuffer = parser.ParseFrom(new ReadOnlySequence<byte>(bytes));
+            assert(parsedBuffer);
+
+            // Load content as multiple segments
+            parsedBuffer = parser.ParseFrom(ReadOnlySequenceFactory.CreateWithContent(bytes));
+            assert(parsedBuffer);
+            
+            assert(parsedStream);
+        }
+
         public static void AssertReadingMessageThrows<TMessage, TException>(MessageParser<TMessage> parser, byte[] bytes)
             where TMessage : IMessage<TMessage>
             where TException : Exception
diff --git a/csharp/src/Google.Protobuf.Test/UnknownFieldSetTest.cs b/csharp/src/Google.Protobuf.Test/UnknownFieldSetTest.cs
index 886937d..15debc1 100644
--- a/csharp/src/Google.Protobuf.Test/UnknownFieldSetTest.cs
+++ b/csharp/src/Google.Protobuf.Test/UnknownFieldSetTest.cs
@@ -161,10 +161,10 @@
             MessageParser discardingParser2 = retainingParser2.WithDiscardUnknownFields(true);
 
             // Test parse from byte[]
-            assertFull(retainingParser1.ParseFrom(data));
-            assertFull(retainingParser2.ParseFrom(data));
-            assertEmpty(discardingParser1.ParseFrom(data));
-            assertEmpty(discardingParser2.ParseFrom(data));
+            MessageParsingHelpers.AssertReadingMessage(retainingParser1, data, m => assertFull(m));
+            MessageParsingHelpers.AssertReadingMessage(retainingParser2, data, m => assertFull(m));
+            MessageParsingHelpers.AssertReadingMessage(discardingParser1, data, m => assertEmpty(m));
+            MessageParsingHelpers.AssertReadingMessage(discardingParser2, data, m => assertEmpty(m));
 
             // Test parse from byte[] with offset
             assertFull(retainingParser1.ParseFrom(data, 0, data.Length));
diff --git a/csharp/src/Google.Protobuf.Test/WellKnownTypes/WrappersTest.cs b/csharp/src/Google.Protobuf.Test/WellKnownTypes/WrappersTest.cs
index 4a425f7..47ff2a1 100644
--- a/csharp/src/Google.Protobuf.Test/WellKnownTypes/WrappersTest.cs
+++ b/csharp/src/Google.Protobuf.Test/WellKnownTypes/WrappersTest.cs
@@ -71,18 +71,18 @@
                 Uint64Field = 4
             };
 
-            var bytes = message.ToByteArray();
-            var parsed = TestWellKnownTypes.Parser.ParseFrom(bytes);
-
-            Assert.AreEqual("x", parsed.StringField);
-            Assert.AreEqual(ByteString.CopyFrom(1, 2, 3), parsed.BytesField);
-            Assert.AreEqual(true, parsed.BoolField);
-            Assert.AreEqual(12.5f, parsed.FloatField);
-            Assert.AreEqual(12.25d, parsed.DoubleField);
-            Assert.AreEqual(1, parsed.Int32Field);
-            Assert.AreEqual(2L, parsed.Int64Field);
-            Assert.AreEqual(3U, parsed.Uint32Field);
-            Assert.AreEqual(4UL, parsed.Uint64Field);
+            MessageParsingHelpers.AssertRoundtrip(TestWellKnownTypes.Parser, message, parsed =>
+            {
+                Assert.AreEqual("x", parsed.StringField);
+                Assert.AreEqual(ByteString.CopyFrom(1, 2, 3), parsed.BytesField);
+                Assert.AreEqual(true, parsed.BoolField);
+                Assert.AreEqual(12.5f, parsed.FloatField);
+                Assert.AreEqual(12.25d, parsed.DoubleField);
+                Assert.AreEqual(1, parsed.Int32Field);
+                Assert.AreEqual(2L, parsed.Int64Field);
+                Assert.AreEqual(3U, parsed.Uint32Field);
+                Assert.AreEqual(4UL, parsed.Uint64Field);
+            });
         }
 
         [Test]
@@ -101,18 +101,18 @@
                 Uint64Field = 0
             };
 
-            var bytes = message.ToByteArray();
-            var parsed = TestWellKnownTypes.Parser.ParseFrom(bytes);
-
-            Assert.AreEqual("", parsed.StringField);
-            Assert.AreEqual(ByteString.Empty, parsed.BytesField);
-            Assert.AreEqual(false, parsed.BoolField);
-            Assert.AreEqual(0f, parsed.FloatField);
-            Assert.AreEqual(0d, parsed.DoubleField);
-            Assert.AreEqual(0, parsed.Int32Field);
-            Assert.AreEqual(0L, parsed.Int64Field);
-            Assert.AreEqual(0U, parsed.Uint32Field);
-            Assert.AreEqual(0UL, parsed.Uint64Field);
+            MessageParsingHelpers.AssertRoundtrip(TestWellKnownTypes.Parser, message, parsed =>
+            {
+                Assert.AreEqual("", parsed.StringField);
+                Assert.AreEqual(ByteString.Empty, parsed.BytesField);
+                Assert.AreEqual(false, parsed.BoolField);
+                Assert.AreEqual(0f, parsed.FloatField);
+                Assert.AreEqual(0d, parsed.DoubleField);
+                Assert.AreEqual(0, parsed.Int32Field);
+                Assert.AreEqual(0L, parsed.Int64Field);
+                Assert.AreEqual(0U, parsed.Uint32Field);
+                Assert.AreEqual(0UL, parsed.Uint64Field);
+            });
         }
 
         [Test]
@@ -140,12 +140,11 @@
                 Uint32Field = { uint.MaxValue, uint.MinValue, 0U },
                 Uint64Field = { ulong.MaxValue, ulong.MinValue, 0UL },
             };
-            var bytes = message.ToByteArray();
-            var parsed = RepeatedWellKnownTypes.Parser.ParseFrom(bytes);
 
-            Assert.AreEqual(message, parsed);
             // Just to test a single value for sanity...
             Assert.AreEqual("Second", message.StringField[1]);
+
+            MessageParsingHelpers.AssertRoundtrip(RepeatedWellKnownTypes.Parser, message);
         }
 
         [Test]
@@ -194,12 +193,10 @@
                 Uint64Field = { { 18, ulong.MaxValue }, { 19, ulong.MinValue }, { 20, 0UL } },
             };
 
-            var bytes = message.ToByteArray();
-            var parsed = MapWellKnownTypes.Parser.ParseFrom(bytes);
-
-            Assert.AreEqual(message, parsed);
             // Just to test a single value for sanity...
             Assert.AreEqual("Second", message.StringField[12]);
+
+            MessageParsingHelpers.AssertRoundtrip(MapWellKnownTypes.Parser, message);
         }
 
         [Test]
@@ -288,10 +285,10 @@
         private void AssertOneofRoundTrip(OneofWellKnownTypes message)
         {
             // Normal roundtrip, but explicitly checking the case...
-            var bytes = message.ToByteArray();
-            var parsed = OneofWellKnownTypes.Parser.ParseFrom(bytes);
-            Assert.AreEqual(message, parsed);
-            Assert.AreEqual(message.OneofFieldCase, parsed.OneofFieldCase);
+            MessageParsingHelpers.AssertRoundtrip(OneofWellKnownTypes.Parser, message, parsed =>
+            {
+                Assert.AreEqual(message.OneofFieldCase, parsed.OneofFieldCase);
+            });
         }
 
         [Test]
@@ -406,8 +403,10 @@
             Assert.AreEqual(8, stream.Length); // tag (1 byte) + length (1 byte) + message (6 bytes)
             stream.Position = 0;
 
-            var message = TestWellKnownTypes.Parser.ParseFrom(stream);
-            Assert.AreEqual(65536, message.Int32Field);
+            MessageParsingHelpers.AssertReadingMessage(
+                TestWellKnownTypes.Parser,
+                stream.ToArray(),
+                message => Assert.AreEqual(65536, message.Int32Field));
         }
 
         [Test]
@@ -431,8 +430,10 @@
             Assert.Less(stream.Length, 8); // tag (1 byte) + length (1 byte) + message
             stream.Position = 0;
 
-            var message = TestWellKnownTypes.Parser.ParseFrom(stream);
-            Assert.AreEqual(6, message.Int32Field);
+            MessageParsingHelpers.AssertReadingMessage(
+                TestWellKnownTypes.Parser,
+                stream.ToArray(),
+                message => Assert.AreEqual(6, message.Int32Field));
         }
 
         [Test]
@@ -456,8 +457,10 @@
             Assert.AreEqual(13, stream.Length); // tag (1 byte) + length (1 byte) + message (11 bytes)
             stream.Position = 0;
 
-            var message = TestWellKnownTypes.Parser.ParseFrom(stream);
-            Assert.AreEqual(0xfffffffffffffL, message.Int64Field);
+            MessageParsingHelpers.AssertReadingMessage(
+                TestWellKnownTypes.Parser,
+                stream.ToArray(),
+                message => Assert.AreEqual(0xfffffffffffffL, message.Int64Field));
         }
 
         [Test]
@@ -481,8 +484,10 @@
             Assert.Less(stream.Length, 12); // tag (1 byte) + length (1 byte) + message
             stream.Position = 0;
 
-            var message = TestWellKnownTypes.Parser.ParseFrom(stream);
-            Assert.AreEqual(6L, message.Int64Field);
+            MessageParsingHelpers.AssertReadingMessage(
+                TestWellKnownTypes.Parser,
+                stream.ToArray(),
+                message => Assert.AreEqual(6L, message.Int64Field));
         }
 
         [Test]