Reworked GrpcEnvironment initialization and shutdown to allow running all tests at once.
diff --git a/src/csharp/GrpcApiTests/MathClientServerTests.cs b/src/csharp/GrpcApiTests/MathClientServerTests.cs
index 9b51924..7654ec8 100644
--- a/src/csharp/GrpcApiTests/MathClientServerTests.cs
+++ b/src/csharp/GrpcApiTests/MathClientServerTests.cs
@@ -21,6 +21,8 @@
         [TestFixtureSetUp]
         public void Init()
         {
+            GrpcEnvironment.Initialize();
+
             server = new Server();
             server.AddServiceDefinition(MathGrpc.BindService(new MathServiceImpl()));
             int port = server.AddPort(host + ":0");
diff --git a/src/csharp/GrpcCore/Channel.cs b/src/csharp/GrpcCore/Channel.cs
index b0d8bee..36ebef7 100644
--- a/src/csharp/GrpcCore/Channel.cs
+++ b/src/csharp/GrpcCore/Channel.cs
@@ -8,13 +8,6 @@
 {
 	public class Channel : IDisposable
 	{
-        /// <summary>
-        /// Make sure GPRC environment is initialized before any channels get used.
-        /// </summary>
-        static Channel() {
-            GrpcEnvironment.EnsureInitialized();
-        }
-       
         readonly ChannelSafeHandle handle;
         readonly String target;
 
diff --git a/src/csharp/GrpcCore/GrpcEnvironment.cs b/src/csharp/GrpcCore/GrpcEnvironment.cs
index 7a7ff39..dcd3bc6 100644
--- a/src/csharp/GrpcCore/GrpcEnvironment.cs
+++ b/src/csharp/GrpcCore/GrpcEnvironment.cs
@@ -5,11 +5,9 @@
 namespace Google.GRPC.Core
 {
     /// <summary>
-    /// Encapsulates initialization and shutdown of GRPC C core library.
-    /// You should not need to initialize it manually, as static constructors
-    /// should load the library when needed.
+    /// Encapsulates initialization and shutdown of gRPC library.
     /// </summary>
-    public static class GrpcEnvironment
+    public class GrpcEnvironment
     {
         const int THREAD_POOL_SIZE = 1;
 
@@ -20,21 +18,24 @@
         static extern void grpcsharp_shutdown();
 
         static object staticLock = new object();
-        static bool initCalled = false;
-        static bool shutdownCalled = false;
-
-        static GrpcThreadPool threadPool = new GrpcThreadPool(THREAD_POOL_SIZE);
+        static volatile GrpcEnvironment instance;
+       
+        readonly GrpcThreadPool threadPool;
+        bool isClosed;
 
         /// <summary>
-        /// Makes sure GRPC environment is initialized.
+        /// Makes sure GRPC environment is initialized. Subsequent invocations don't have any
+        /// effect unless you call Shutdown first.
+        /// Although normal use cases assume you will call this just once in your application's
+        /// lifetime (and call Shutdown once you're done), for the sake of easier testing it's 
+        /// allowed to initialize the environment again after it has been successfully shutdown.
         /// </summary>
-        public static void EnsureInitialized() {
+        public static void Initialize() {
             lock(staticLock)
             {
-                if (!initCalled)
+                if (instance == null)
                 {
-                    initCalled = true;
-                    GrpcInit();       
+                    instance = new GrpcEnvironment();
                 }
             }
         }
@@ -47,45 +48,55 @@
         {
             lock(staticLock)
             {
-                if (initCalled && !shutdownCalled)
+                if (instance != null)
                 {
-                    shutdownCalled = true;
-                    GrpcShutdown();
+                    instance.Close();
+                    instance = null;
                 }
             }
-
-        }
-
-        /// <summary>
-        /// Initializes GRPC C Core library.
-        /// </summary>
-        private static void GrpcInit()
-        {
-            grpcsharp_init();
-            threadPool.Start();
-            // TODO: use proper logging here
-            Console.WriteLine("GRPC initialized.");
-        }
-
-        /// <summary>
-        /// Shutdown GRPC C Core library.
-        /// </summary>
-        private static void GrpcShutdown()
-        {
-            threadPool.Stop();
-            grpcsharp_shutdown();
-
-            // TODO: use proper logging here
-            Console.WriteLine("GRPC shutdown.");
         }
 
         internal static GrpcThreadPool ThreadPool
         {
             get
             {
-                return threadPool;
+                var inst = instance;
+                if (inst == null)
+                {
+                    throw new InvalidOperationException("GRPC environment not initialized");
+                }
+                return inst.threadPool;
             }
         }
+
+        /// <summary>
+        /// Creates gRPC environment.
+        /// </summary>
+        private GrpcEnvironment()
+        {
+            grpcsharp_init();
+            threadPool = new GrpcThreadPool(THREAD_POOL_SIZE);
+            threadPool.Start();
+            // TODO: use proper logging here
+            Console.WriteLine("GRPC initialized.");
+        }
+
+        /// <summary>
+        /// Shuts down this environment.
+        /// </summary>
+        private void Close()
+        {
+            if (isClosed)
+            {
+                throw new InvalidOperationException("Close has already been called");
+            }
+            threadPool.Stop();
+            grpcsharp_shutdown();
+            isClosed = true;
+
+            // TODO: use proper logging here
+            Console.WriteLine("GRPC shutdown.");
+        }
     }
 }
 
diff --git a/src/csharp/GrpcCore/Server.cs b/src/csharp/GrpcCore/Server.cs
index d3bc81e..3c4a73a 100644
--- a/src/csharp/GrpcCore/Server.cs
+++ b/src/csharp/GrpcCore/Server.cs
@@ -26,10 +26,6 @@
 
         readonly TaskCompletionSource<object> shutdownTcs = new TaskCompletionSource<object>();
 
-        static Server() {
-            GrpcEnvironment.EnsureInitialized();
-        }
-
         public Server()
         {
             // TODO: what is the tag for server shutdown?
diff --git a/src/csharp/GrpcCore/Utils/RecordingQueue.cs b/src/csharp/GrpcCore/Utils/RecordingQueue.cs
index 0726f00..81e1a82 100644
--- a/src/csharp/GrpcCore/Utils/RecordingQueue.cs
+++ b/src/csharp/GrpcCore/Utils/RecordingQueue.cs
@@ -5,6 +5,7 @@
 
 namespace Google.GRPC.Core.Utils
 {
+    // TODO: replace this by something that implements IAsyncEnumerator.
     /// <summary>
     /// Observer that allows us to await incoming messages one-by-one.
     /// The implementation is not ideal and class will be probably replaced 
diff --git a/src/csharp/GrpcCoreTests/ClientServerTest.cs b/src/csharp/GrpcCoreTests/ClientServerTest.cs
index 513141f..3896686 100644
--- a/src/csharp/GrpcCoreTests/ClientServerTest.cs
+++ b/src/csharp/GrpcCoreTests/ClientServerTest.cs
@@ -21,6 +21,8 @@
         [Test]
         public void EmptyCall()
         {
+            GrpcEnvironment.Initialize();
+
             Server server = new Server();
             server.AddServiceDefinition(
                 ServerServiceDefinition.CreateBuilder("someService")
diff --git a/src/csharp/GrpcCoreTests/GrpcEnvironmentTest.cs b/src/csharp/GrpcCoreTests/GrpcEnvironmentTest.cs
index 136878d..171c13f 100644
--- a/src/csharp/GrpcCoreTests/GrpcEnvironmentTest.cs
+++ b/src/csharp/GrpcCoreTests/GrpcEnvironmentTest.cs
@@ -9,10 +9,30 @@
     {
         [Test]
         public void InitializeAndShutdownGrpcEnvironment() {
-            GrpcEnvironment.EnsureInitialized();
-            Thread.Sleep(500);
+            GrpcEnvironment.Initialize();
             Assert.IsNotNull(GrpcEnvironment.ThreadPool.CompletionQueue);
             GrpcEnvironment.Shutdown();
         }
+
+        [Test]
+        public void SubsequentInvocations() {
+            GrpcEnvironment.Initialize();
+            GrpcEnvironment.Initialize();
+            GrpcEnvironment.Shutdown();
+            GrpcEnvironment.Shutdown();
+        }
+
+        [Test]
+        public void InitializeAfterShutdown() {
+            GrpcEnvironment.Initialize();
+            var tp1 = GrpcEnvironment.ThreadPool;
+            GrpcEnvironment.Shutdown();
+
+            GrpcEnvironment.Initialize();
+            var tp2 = GrpcEnvironment.ThreadPool;
+            GrpcEnvironment.Shutdown();
+
+            Assert.IsFalse(Object.ReferenceEquals(tp1, tp2));
+        }
     }
 }
diff --git a/src/csharp/GrpcCoreTests/ServerTest.cs b/src/csharp/GrpcCoreTests/ServerTest.cs
index b8ec250..a0de9f4 100644
--- a/src/csharp/GrpcCoreTests/ServerTest.cs
+++ b/src/csharp/GrpcCoreTests/ServerTest.cs
@@ -9,7 +9,9 @@
     public class ServerTest
     {
         [Test]
-        public void StartAndShutdownServer() {
+        public void StartAndShutdownServer()
+        {
+            GrpcEnvironment.Initialize();
 
             Server server = new Server();
             int port = server.AddPort("localhost:0");
diff --git a/src/csharp/InteropClient/Client.cs b/src/csharp/InteropClient/Client.cs
index 9f58150..9fd44f9 100644
--- a/src/csharp/InteropClient/Client.cs
+++ b/src/csharp/InteropClient/Client.cs
@@ -60,6 +60,8 @@
 
         private void Run()
         {
+            GrpcEnvironment.Initialize();
+
             string addr = string.Format("{0}:{1}", options.serverHost, options.serverPort);
             using (Channel channel = new Channel(addr))
             {
diff --git a/src/csharp/MathClient/MathClient.cs b/src/csharp/MathClient/MathClient.cs
index 45222ab..52dd2a5 100644
--- a/src/csharp/MathClient/MathClient.cs
+++ b/src/csharp/MathClient/MathClient.cs
@@ -9,6 +9,8 @@
     {
 		public static void Main (string[] args)
 		{
+            GrpcEnvironment.Initialize();
+
 			using (Channel channel = new Channel("127.0.0.1:23456"))
 			{
 				MathGrpc.IMathServiceClient stub = new MathGrpc.MathServiceClientStub(channel);