C# route guide
diff --git a/csharp/route_guide/.gitignore b/csharp/route_guide/.gitignore
new file mode 100644
index 0000000..585000e
--- /dev/null
+++ b/csharp/route_guide/.gitignore
@@ -0,0 +1,5 @@
+bin/
+obj/
+packages/
+*.suo
+*.userprefs
diff --git a/csharp/route_guide/README.md b/csharp/route_guide/README.md
new file mode 100644
index 0000000..cdde835
--- /dev/null
+++ b/csharp/route_guide/README.md
@@ -0,0 +1,392 @@
+#gRPC Basics: C#
+
+This tutorial provides a basic C# programmer's introduction to working with gRPC. By walking through this example you'll learn how to:
+
+- Define a service in a .proto file.
+- Generate server and client code using the protocol buffer compiler.
+- Use the C# gRPC API to write a simple client and server for your service.
+
+It assumes that you have read the [Getting started](https://github.com/grpc/grpc-common) guide and are familiar with [protocol buffers] (https://developers.google.com/protocol-buffers/docs/overview). Note that the example in this tutorial only uses the proto2 version of the protocol buffers language, as proto3 support for C# is not ready yet (see [protobuf C# README](https://github.com/google/protobuf/tree/master/csharp#proto2--proto3)).
+
+This isn't a comprehensive guide to using gRPC in C#: more reference documentation is coming soon.
+
+## Why use gRPC?
+
+Our example is a simple route mapping application that lets clients get information about features on their route, create a summary of their route, and exchange route information such as traffic updates with the server and other clients.
+
+With gRPC we can define our service once in a .proto file and implement clients and servers in any of gRPC's supported languages, which in turn can be run in environments ranging from servers inside Google to your own tablet - all the complexity of communication between different languages and environments is handled for you by gRPC. We also get all the advantages of working with protocol buffers, including efficient serialization, a simple IDL, and easy interface updating.
+
+## Example code and setup
+
+The example code for our tutorial is in [grpc/grpc-common/csharp/route_guide](https://github.com/grpc/grpc-common/tree/master/csharp/route_guide). To download the example, clone the `grpc-common` repository by running the following command:
+```shell
+$ git clone https://github.com/google/grpc-common.git
+```
+
+All the files for this tutorial are in the directory  `grpc-common/csharp/route_guide`.
+Open the solution `grpc-common/csharp/route_guide/RouteGuide.sln` from Visual Studio (or Monodevelop on Linux).
+
+You also should have the relevant tools installed to generate the server and client interface code.
+
+**TODO: more on how to install protoc**
+
+## Defining the service
+
+Our first step (as you'll know from [Getting started](https://github.com/grpc/grpc-common)) is to define the gRPC *service* and the method *request* and *response* types using [protocol buffers] (https://developers.google.com/protocol-buffers/docs/overview). You can see the complete .proto file in [`grpc-common/csharp/route_guide/RouteGuide/protos/route_guide.proto`](https://github.com/grpc/grpc-common/blob/master/sharp/route_guide/RouteGuide/protos/route_guide.proto).
+
+To define a service, you specify a named `service` in your .proto file:
+
+```protobuf
+service RouteGuide {
+   ...
+}
+```
+
+Then you define `rpc` methods inside your service definition, specifying their request and response types. gRPC lets you define four kinds of service method, all of which are used in the `RouteGuide` service:
+
+- A *simple RPC* where the client sends a request to the server using the stub and waits for a response to come back, just like a normal function call.
+```protobuf
+   // Obtains the feature at a given position.
+   rpc GetFeature(Point) returns (Feature) {}
+```
+
+- A *server-side streaming RPC* where the client sends a request to the server and gets a stream to read a sequence of messages back. The client reads from the returned stream until there are no more messages. As you can see in our example, you specify a server-side streaming method by placing the `stream` keyword before the *response* type.
+```protobuf
+  // Obtains the Features available within the given Rectangle.  Results are
+  // streamed rather than returned at once (e.g. in a response message with a
+  // repeated field), as the rectangle may cover a large area and contain a
+  // huge number of features.
+  rpc ListFeatures(Rectangle) returns (stream Feature) {}
+```
+
+- A *client-side streaming RPC* where the client writes a sequence of messages and sends them to the server, again using a provided stream. Once the client has finished writing the messages, it waits for the server to read them all and return its response. You specify a server-side streaming method by placing the `stream` keyword before the *request* type.
+```protobuf
+  // Accepts a stream of Points on a route being traversed, returning a
+  // RouteSummary when traversal is completed.
+  rpc RecordRoute(stream Point) returns (RouteSummary) {}
+```
+
+- A *bidirectional streaming RPC* where both sides send a sequence of messages using a read-write stream. The two streams operate independently, so clients and servers can read and write in whatever order they like: for example, the server could wait to receive all the client messages before writing its responses, or it could alternately read a message then write a message, or some other combination of reads and writes. The order of messages in each stream is preserved. You specify this type of method by placing the `stream` keyword before both the request and the response.
+```protobuf
+  // Accepts a stream of RouteNotes sent while a route is being traversed,
+  // while receiving other RouteNotes (e.g. from other users).
+  rpc RouteChat(stream RouteNote) returns (stream RouteNote) {}
+```
+
+Our .proto file also contains protocol buffer message type definitions for all the request and response types used in our service methods - for example, here's the `Point` message type:
+```protobuf
+// Points are represented as latitude-longitude pairs in the E7 representation
+// (degrees multiplied by 10**7 and rounded to the nearest integer).
+// Latitudes should be in the range +/- 90 degrees and longitude should be in
+// the range +/- 180 degrees (inclusive).
+message Point {
+  int32 latitude = 1;
+  int32 longitude = 2;
+}
+```
+
+
+## Generating client and server code
+
+Next we need to generate the gRPC client and server interfaces from our .proto service definition. We do this using the protocol buffer compiler `protoc` with a special gRPC C# plugin.
+
+If you want to run this yourself, make sure you've installed protoc and followed the gRPC C# plugin [installation instructions](https://github.com/grpc/grpc/blob/master/INSTALL) first.
+
+**TODO: more on how to install protoc and grpc_csharp_plugin**
+
+Once that's done, the following command can be used to generate the C# code.
+
+```shell
+$ protoc -I RouteGuide/protos --csharp_out=RouteGuide --grpc_out=RouteGuide --plugin=protoc-gen-grpc=`which grpc_csharp_plugin` RouteGuide/protos/route_guide.proto
+```
+
+**TODO: command for windows**
+
+Running this command regenerates the following files in the RouteGuide directory:
+- `RouteGuide/RouteGuide.cs` defines a namespace `examples`
+  - This contains all the protocol buffer code to populate, serialize, and retrieve our request and response message types
+- `RouteGuide/RouteGuideGrpc.cs`, provides stub and service classes
+   - an interface `RouteGuide.IRouteGuide` to inherit from when defining RouteGuide service implementations
+   - a class `RouteGuide.RouteGuideClient` that can be used to access remote RouteGuide instances
+
+
+<a name="server"></a>
+## Creating the server
+
+First let's look at how we create a `RouteGuide` server. If you're only interested in creating gRPC clients, you can skip this section and go straight to [Creating the client](#client) (though you might find it interesting anyway!).
+
+There are two parts to making our `RouteGuide` service do its job:
+- Implementing the service interface generated from our service definition: doing the actual "work" of our service.
+- Running a gRPC server to listen for requests from clients and return the service responses.
+
+You can find our example `RouteGuide` server in [grpc-common/csharp/route_guide/RouteGuideServer/RouteGuideImpl.cs](https://github.com/grpc/grpc-common/blob/master/csharp/route_guide/RouteGuideServer/RouteGuideServerImpl.cs). Let's take a closer look at how it works.
+
+### Implementing RouteGuide
+
+As you can see, our server has a `RouteGuideImpl` class that implements the generated `RouteGuide.IRouteGuide`:
+
+```csharp
+// RouteGuideImpl provides an implementation of the RouteGuide service.
+public class RouteGuideImpl : RouteGuide.IRouteGuide
+```
+
+`RouteGuideImpl` implements all our service methods. Let's look at the simplest type first, `GetFeature`, which just gets a `Point` from the client and returns the corresponding feature information from its database in a `Feature`.
+
+```csharp
+    public Task<Feature> GetFeature(Grpc.Core.ServerCallContext context, Point request)
+    {
+        return Task.FromResult(CheckFeature(request));
+    }
+```
+
+The method is passed a context for the RPC (which is empty in the alpha release), the client's `Point` protocol buffer request, and returns a `Feature` protocol buffer. In the method we create the `Feature` with the appropriate information, and then return it. To allow asynchronous
+implementation, the method returns `Task<Feature>` rather than just `Feature`. You are free to perform your computations synchronously and return
+the result once you've finished, just as we do in the example.
+
+Now let's look at something a bit more complicated - a streaming RPC. `ListFeatures` is a server-side streaming RPC, so we need to send back multiple `Feature` protocol buffers to our client.
+
+```csharp
+    // in RouteGuideImpl
+    public async Task ListFeatures(Grpc.Core.ServerCallContext context, Rectangle request,
+	    Grpc.Core.IServerStreamWriter<Feature> responseStream)
+    {
+        int left = Math.Min(request.Lo.Longitude, request.Hi.Longitude);
+        int right = Math.Max(request.Lo.Longitude, request.Hi.Longitude);
+        int top = Math.Max(request.Lo.Latitude, request.Hi.Latitude);
+        int bottom = Math.Min(request.Lo.Latitude, request.Hi.Latitude);
+
+        foreach (var feature in features)
+        {
+            if (!RouteGuideUtil.Exists(feature))
+            {
+                continue;
+            }
+
+            int lat = feature.Location.Latitude;
+            int lon = feature.Location.Longitude;
+            if (lon >= left && lon <= right && lat >= bottom && lat <= top)
+            {
+                await responseStream.WriteAsync(feature);
+            }
+        }
+    }
+```
+
+As you can see, here the request object is a `Rectangle` in which our client wants to find `Feature`s, but instead of returning a simple response we need to write responses to an asynchronous stream `IServerStreamWriter` using async method `WriteAsync`.
+
+Similarly, the client-side streaming method `RecordRoute` uses an [IAsyncEnumerator](https://github.com/Reactive-Extensions/Rx.NET/blob/master/Ix.NET/Source/System.Interactive.Async/IAsyncEnumerator.cs), to read the stream of requests using async method `MoveNext` and property `Current`.
+
+```csharp
+    public async Task<RouteSummary> RecordRoute(Grpc.Core.ServerCallContext context,
+	    Grpc.Core.IAsyncStreamReader<Point> requestStream)
+    {
+        int pointCount = 0;
+        int featureCount = 0;
+        int distance = 0;
+        Point previous = null;
+        var stopwatch = new Stopwatch();
+        stopwatch.Start();
+
+        while (await requestStream.MoveNext())
+        {
+            var point = requestStream.Current;
+            pointCount++;
+            if (RouteGuideUtil.Exists(CheckFeature(point)))
+            {
+                featureCount++;
+            }
+            if (previous != null)
+            {
+                distance += (int) CalcDistance(previous, point);
+            }
+            previous = point;
+        }
+
+        stopwatch.Stop();
+        return RouteSummary.CreateBuilder().SetPointCount(pointCount)
+            .SetFeatureCount(featureCount).SetDistance(distance)
+            .SetElapsedTime((int) (stopwatch.ElapsedMilliseconds / 1000)).Build();
+    }
+```
+Finally, let's look at our bidirectional streaming RPC `RouteChat`.
+
+```csharp
+    public async Task RouteChat(Grpc.Core.ServerCallContext context,
+	    Grpc.Core.IAsyncStreamReader<RouteNote> requestStream, Grpc.Core.IServerStreamWriter<RouteNote> responseStream)
+    {
+        while (await requestStream.MoveNext())
+        {
+            var note = requestStream.Current;
+            List<RouteNote> notes = GetOrCreateNotes(note.Location);
+
+			List<RouteNote> prevNotes;
+            lock (notes)
+            {
+                prevNotes = new List<RouteNote>(notes);
+            }
+
+            foreach (var prevNote in prevNotes)
+            {
+                await responseStream.WriteAsync(prevNote);
+            }                
+                
+            lock (notes)
+            {
+                notes.Add(note);
+            }
+        }
+    }
+```
+
+Here the method receives both `requestStream` and `responseStream` as an argument.  Reading the requests is done in a same way as in the `RecordRoute` example.  Writing the responses is done the same way as in the `ListFeatures` example.
+
+### Starting the server
+
+Once we've implemented all our methods, we also need to start up a gRPC server so that clients can actually use our service. The following snippet shows how we do this for our `RouteGuide` service:
+
+```csharp
+var features = RouteGuideUtil.ParseFeatures(RouteGuideUtil.DefaultFeaturesFile);
+GrpcEnvironment.Initialize();
+
+Server server = new Server();
+server.AddServiceDefinition(RouteGuide.BindService(new RouteGuideImpl(features)));
+int port = server.AddListeningPort("localhost", 50052);
+server.Start();
+
+Console.WriteLine("RouteGuide server listening on port " + port);
+Console.WriteLine("Press any key to stop the server...");
+Console.ReadKey();
+
+server.ShutdownAsync().Wait();
+GrpcEnvironment.Shutdown();
+```
+As you can see, we build and start our server using `Grpc.Core.Server` class. To do this, we:
+
+1. Create an instance of `Grpc.Core.Server`.
+1. Create an instance of our service implementation class `RouteGuideImpl`.
+3. Register our service implementation with the server using method `AddServiceDefinition` and the generated method `RouteGuide.BindService`.
+2. Specify the address and port we want to use to listen for client requests using the `AddListeningPort` method.
+4. Call `Start` on the server instance to start an RPC server for our service.
+
+<a name="client"></a>
+## Creating the client
+
+In this section, we'll look at creating a C# client for our `RouteGuide` service. You can see our complete example client code in [grpc-common/csharp/route_guide/RouteGuideClient/Program.cs](https://github.com/grpc/grpc-common/blob/master/csharp/route_guide/RouteGuideClient/Program.cs).
+
+### Creating a stub
+
+To call service methods, we first need to create a *stub*.
+
+First, we need to create a gRPC client channel that will connect to gRPC server. Then, we use the `RouteGuide.NewStub` method of the `RouteGuide` class generated from our .proto.
+
+```csharp
+GrpcEnvironment.Initialize();
+
+using (Channel channel = new Channel("127.0.0.1:50052"))
+{
+    var client = RouteGuide.NewStub(channel);
+ 
+    // YOUR CODE GOES HERE
+}
+
+GrpcEnvironment.Shutdown();
+```
+
+### Calling service methods
+
+Now let's look at how we call our service methods. gRPC C# provides asynchronous versions of each of the supported method types. For convenience,
+gRPC C# also provides a synchronous method stub, but only for simple (single request/single response) RPCs.
+
+#### Simple RPC
+
+Calling the simple RPC `GetFeature` in a synchronous way is nearly as straightforward as calling a local method.
+
+```csharp
+Point request = Point.CreateBuilder().SetLatitude(409146138).SetLongitude(-746188906).Build();
+Feature feature = client.GetFeature(request);
+```
+
+As you can see, we create and populate a request protocol buffer object (in our case `Point`), and call the desired method on the client object, passing it the request. If the RPC finishes with success, the response protocol buffer (in our case `Feature`) will be returned. Otherwise, an exception of type `RpcException` will be thrown, indicating the status code of the problem.
+
+Alternatively, if you are in async context, you can call an asynchronous version of the method (and use `await` keyword to await the result):
+```csharp
+Point request = Point.CreateBuilder().SetLatitude(409146138).SetLongitude(-746188906).Build();
+Feature feature = await client.GetFeatureAsync(request);
+```
+
+#### Streaming RPCs
+
+Now let's look at our streaming methods. If you've already read [Creating the server](#server) some of this may look very familiar - streaming RPCs are implemented in a similar way on both sides. The difference with respect to simple call is that the client methods return an instance of a call object, that provides access to request/response streams and/or asynchronous result (depending on the streaming type you are using).
+
+Here's where we call the server-side streaming method `ListFeatures`, which has property `ReponseStream` of type `IAsyncEnumerator<Feature>`
+
+```csharp
+using (var call = client.ListFeatures(request))
+{
+    while (await call.ResponseStream.MoveNext())
+    {
+        Feature feature = call.ResponseStream.Current;
+        Console.WriteLine("Received " + feature.ToString());
+    }
+}
+```
+
+The client-side streaming method `RecordRoute` is similar, except we use the property `RequestStream` to write the requests one by one using `WriteAsync` and eventually signal that no more request will be send using `CompleteAsync`. The method result can be obtained through the property
+`Result`.
+```csharp
+using (var call = client.RecordRoute())
+{
+    foreach (var point in points)
+	{
+        await call.RequestStream.WriteAsync(point);
+    }
+    await call.RequestStream.CompleteAsync();
+
+    RouteSummary summary = await call.Result;
+}
+```
+
+Finally, let's look at our bidirectional streaming RPC `RouteChat`. In this case, we write the request to `RequestStream` and receive the responses from `ResponseStream`. As you can see from the example, the streams are independent of each other. 
+
+```csharp
+ using (var call = client.RouteChat())
+ {
+    var responseReaderTask = Task.Run(async () =>
+    {
+        while (await call.ResponseStream.MoveNext())
+        {
+            var note = call.ResponseStream.Current;
+            Console.WriteLine("Received " + note);
+		}
+    });
+
+    foreach (RouteNote request in requests)
+    {
+        await call.RequestStream.WriteAsync(request);
+    }
+    await call.RequestStream.CompleteAsync();
+	await responseReaderTask;
+}
+```
+
+## Try it out!
+
+Build client and server:
+
+Open the solution `grpc-common/csharp/route_guide/RouteGuide.sln` from Visual Studio (or Monodevelop on Linux) and hit "Build".
+
+Run the server, which will listen on port 50052:
+```
+> cd RouteGuideServer/bin/Debug
+> RouteGuideServer.exe
+```
+
+Run the client (in a different terminal):
+```
+> cd RouteGuideClient/bin/Debug
+> RouteGuideClient.exe
+```
+
+You can also run the server and client directly from Visual Studio.
+
+On Linux or Mac, use `mono RouteGuideServer.exe` and `mono RouteGuideClient.exe` to run the server and client.
\ No newline at end of file
diff --git a/csharp/route_guide/RouteGuide.sln b/csharp/route_guide/RouteGuide.sln
new file mode 100644
index 0000000..00065b0
--- /dev/null
+++ b/csharp/route_guide/RouteGuide.sln
@@ -0,0 +1,34 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 2013
+VisualStudioVersion = 12.0.31101.0
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RouteGuide", "RouteGuide\RouteGuide.csproj", "{49954D9C-5F17-4662-96B2-73BE833DD81A}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RouteGuideClient", "RouteGuideClient\RouteGuideClient.csproj", "{D47BE663-4DE3-4206-B7A8-EA3FA066DADC}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RouteGuideServer", "RouteGuideServer\RouteGuideServer.csproj", "{4B7C7794-BE24-4477-ACE7-18259EB73D27}"
+EndProject
+Global
+	GlobalSection(SolutionConfigurationPlatforms) = preSolution
+		Debug|Any CPU = Debug|Any CPU
+		Release|Any CPU = Release|Any CPU
+	EndGlobalSection
+	GlobalSection(ProjectConfigurationPlatforms) = postSolution
+		{49954D9C-5F17-4662-96B2-73BE833DD81A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{49954D9C-5F17-4662-96B2-73BE833DD81A}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{49954D9C-5F17-4662-96B2-73BE833DD81A}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{49954D9C-5F17-4662-96B2-73BE833DD81A}.Release|Any CPU.Build.0 = Release|Any CPU
+		{D47BE663-4DE3-4206-B7A8-EA3FA066DADC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{D47BE663-4DE3-4206-B7A8-EA3FA066DADC}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{D47BE663-4DE3-4206-B7A8-EA3FA066DADC}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{D47BE663-4DE3-4206-B7A8-EA3FA066DADC}.Release|Any CPU.Build.0 = Release|Any CPU
+		{4B7C7794-BE24-4477-ACE7-18259EB73D27}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{4B7C7794-BE24-4477-ACE7-18259EB73D27}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{4B7C7794-BE24-4477-ACE7-18259EB73D27}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{4B7C7794-BE24-4477-ACE7-18259EB73D27}.Release|Any CPU.Build.0 = Release|Any CPU
+	EndGlobalSection
+	GlobalSection(SolutionProperties) = preSolution
+		HideSolutionNode = FALSE
+	EndGlobalSection
+EndGlobal
diff --git a/csharp/route_guide/RouteGuide/Properties/AssemblyInfo.cs b/csharp/route_guide/RouteGuide/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..9c3441e
--- /dev/null
+++ b/csharp/route_guide/RouteGuide/Properties/AssemblyInfo.cs
@@ -0,0 +1,36 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following 
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("RouteGuide")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("RouteGuide")]
+[assembly: AssemblyCopyright("Copyright ©  2015")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible 
+// to COM components.  If you need to access a type in this assembly from 
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("ef6b85bc-ac27-46de-8714-a658236cc6fb")]
+
+// Version information for an assembly consists of the following four values:
+//
+//      Major Version
+//      Minor Version 
+//      Build Number
+//      Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers 
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/csharp/route_guide/RouteGuide/RouteGuide.cs b/csharp/route_guide/RouteGuide/RouteGuide.cs
new file mode 100644
index 0000000..80508bc
--- /dev/null
+++ b/csharp/route_guide/RouteGuide/RouteGuide.cs
@@ -0,0 +1,1873 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: route_guide.proto
+#pragma warning disable 1591, 0612, 3021
+#region Designer generated code
+
+using pb = global::Google.ProtocolBuffers;
+using pbc = global::Google.ProtocolBuffers.Collections;
+using pbd = global::Google.ProtocolBuffers.Descriptors;
+using scg = global::System.Collections.Generic;
+namespace examples {
+
+  namespace Proto {
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+    public static partial class RouteGuide {
+
+      #region Extension registration
+      public static void RegisterAllExtensions(pb::ExtensionRegistry registry) {
+      }
+      #endregion
+      #region Static variables
+      internal static pbd::MessageDescriptor internal__static_examples_Point__Descriptor;
+      internal static pb::FieldAccess.FieldAccessorTable<global::examples.Point, global::examples.Point.Builder> internal__static_examples_Point__FieldAccessorTable;
+      internal static pbd::MessageDescriptor internal__static_examples_Rectangle__Descriptor;
+      internal static pb::FieldAccess.FieldAccessorTable<global::examples.Rectangle, global::examples.Rectangle.Builder> internal__static_examples_Rectangle__FieldAccessorTable;
+      internal static pbd::MessageDescriptor internal__static_examples_Feature__Descriptor;
+      internal static pb::FieldAccess.FieldAccessorTable<global::examples.Feature, global::examples.Feature.Builder> internal__static_examples_Feature__FieldAccessorTable;
+      internal static pbd::MessageDescriptor internal__static_examples_RouteNote__Descriptor;
+      internal static pb::FieldAccess.FieldAccessorTable<global::examples.RouteNote, global::examples.RouteNote.Builder> internal__static_examples_RouteNote__FieldAccessorTable;
+      internal static pbd::MessageDescriptor internal__static_examples_RouteSummary__Descriptor;
+      internal static pb::FieldAccess.FieldAccessorTable<global::examples.RouteSummary, global::examples.RouteSummary.Builder> internal__static_examples_RouteSummary__FieldAccessorTable;
+      #endregion
+      #region Descriptor
+      public static pbd::FileDescriptor Descriptor {
+        get { return descriptor; }
+      }
+      private static pbd::FileDescriptor descriptor;
+
+      static RouteGuide() {
+        byte[] descriptorData = global::System.Convert.FromBase64String(
+            string.Concat(
+              "ChFyb3V0ZV9ndWlkZS5wcm90bxIIZXhhbXBsZXMiLAoFUG9pbnQSEAoIbGF0", 
+              "aXR1ZGUYASABKAUSEQoJbG9uZ2l0dWRlGAIgASgFIkUKCVJlY3RhbmdsZRIb", 
+              "CgJsbxgBIAEoCzIPLmV4YW1wbGVzLlBvaW50EhsKAmhpGAIgASgLMg8uZXhh", 
+              "bXBsZXMuUG9pbnQiOgoHRmVhdHVyZRIMCgRuYW1lGAEgASgJEiEKCGxvY2F0", 
+              "aW9uGAIgASgLMg8uZXhhbXBsZXMuUG9pbnQiPwoJUm91dGVOb3RlEiEKCGxv", 
+              "Y2F0aW9uGAEgASgLMg8uZXhhbXBsZXMuUG9pbnQSDwoHbWVzc2FnZRgCIAEo", 
+              "CSJiCgxSb3V0ZVN1bW1hcnkSEwoLcG9pbnRfY291bnQYASABKAUSFQoNZmVh", 
+              "dHVyZV9jb3VudBgCIAEoBRIQCghkaXN0YW5jZRgDIAEoBRIUCgxlbGFwc2Vk", 
+              "X3RpbWUYBCABKAUy9QEKClJvdXRlR3VpZGUSMgoKR2V0RmVhdHVyZRIPLmV4", 
+              "YW1wbGVzLlBvaW50GhEuZXhhbXBsZXMuRmVhdHVyZSIAEjoKDExpc3RGZWF0", 
+              "dXJlcxITLmV4YW1wbGVzLlJlY3RhbmdsZRoRLmV4YW1wbGVzLkZlYXR1cmUi", 
+              "ADABEjoKC1JlY29yZFJvdXRlEg8uZXhhbXBsZXMuUG9pbnQaFi5leGFtcGxl", 
+              "cy5Sb3V0ZVN1bW1hcnkiACgBEjsKCVJvdXRlQ2hhdBITLmV4YW1wbGVzLlJv", 
+            "dXRlTm90ZRoTLmV4YW1wbGVzLlJvdXRlTm90ZSIAKAEwAQ=="));
+        pbd::FileDescriptor.InternalDescriptorAssigner assigner = delegate(pbd::FileDescriptor root) {
+          descriptor = root;
+          internal__static_examples_Point__Descriptor = Descriptor.MessageTypes[0];
+          internal__static_examples_Point__FieldAccessorTable = 
+              new pb::FieldAccess.FieldAccessorTable<global::examples.Point, global::examples.Point.Builder>(internal__static_examples_Point__Descriptor,
+                  new string[] { "Latitude", "Longitude", });
+          internal__static_examples_Rectangle__Descriptor = Descriptor.MessageTypes[1];
+          internal__static_examples_Rectangle__FieldAccessorTable = 
+              new pb::FieldAccess.FieldAccessorTable<global::examples.Rectangle, global::examples.Rectangle.Builder>(internal__static_examples_Rectangle__Descriptor,
+                  new string[] { "Lo", "Hi", });
+          internal__static_examples_Feature__Descriptor = Descriptor.MessageTypes[2];
+          internal__static_examples_Feature__FieldAccessorTable = 
+              new pb::FieldAccess.FieldAccessorTable<global::examples.Feature, global::examples.Feature.Builder>(internal__static_examples_Feature__Descriptor,
+                  new string[] { "Name", "Location", });
+          internal__static_examples_RouteNote__Descriptor = Descriptor.MessageTypes[3];
+          internal__static_examples_RouteNote__FieldAccessorTable = 
+              new pb::FieldAccess.FieldAccessorTable<global::examples.RouteNote, global::examples.RouteNote.Builder>(internal__static_examples_RouteNote__Descriptor,
+                  new string[] { "Location", "Message", });
+          internal__static_examples_RouteSummary__Descriptor = Descriptor.MessageTypes[4];
+          internal__static_examples_RouteSummary__FieldAccessorTable = 
+              new pb::FieldAccess.FieldAccessorTable<global::examples.RouteSummary, global::examples.RouteSummary.Builder>(internal__static_examples_RouteSummary__Descriptor,
+                  new string[] { "PointCount", "FeatureCount", "Distance", "ElapsedTime", });
+          pb::ExtensionRegistry registry = pb::ExtensionRegistry.CreateInstance();
+          RegisterAllExtensions(registry);
+          return registry;
+        };
+        pbd::FileDescriptor.InternalBuildGeneratedFileFrom(descriptorData,
+            new pbd::FileDescriptor[] {
+            }, assigner);
+      }
+      #endregion
+
+    }
+  }
+  #region Messages
+  [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+  public sealed partial class Point : pb::GeneratedMessage<Point, Point.Builder> {
+    private Point() { }
+    private static readonly Point defaultInstance = new Point().MakeReadOnly();
+    private static readonly string[] _pointFieldNames = new string[] { "latitude", "longitude" };
+    private static readonly uint[] _pointFieldTags = new uint[] { 8, 16 };
+    public static Point DefaultInstance {
+      get { return defaultInstance; }
+    }
+
+    public override Point DefaultInstanceForType {
+      get { return DefaultInstance; }
+    }
+
+    protected override Point ThisMessage {
+      get { return this; }
+    }
+
+    public static pbd::MessageDescriptor Descriptor {
+      get { return global::examples.Proto.RouteGuide.internal__static_examples_Point__Descriptor; }
+    }
+
+    protected override pb::FieldAccess.FieldAccessorTable<Point, Point.Builder> InternalFieldAccessors {
+      get { return global::examples.Proto.RouteGuide.internal__static_examples_Point__FieldAccessorTable; }
+    }
+
+    public const int LatitudeFieldNumber = 1;
+    private bool hasLatitude;
+    private int latitude_;
+    public bool HasLatitude {
+      get { return hasLatitude; }
+    }
+    public int Latitude {
+      get { return latitude_; }
+    }
+
+    public const int LongitudeFieldNumber = 2;
+    private bool hasLongitude;
+    private int longitude_;
+    public bool HasLongitude {
+      get { return hasLongitude; }
+    }
+    public int Longitude {
+      get { return longitude_; }
+    }
+
+    public override bool IsInitialized {
+      get {
+        return true;
+      }
+    }
+
+    public override void WriteTo(pb::ICodedOutputStream output) {
+      CalcSerializedSize();
+      string[] field_names = _pointFieldNames;
+      if (hasLatitude) {
+        output.WriteInt32(1, field_names[0], Latitude);
+      }
+      if (hasLongitude) {
+        output.WriteInt32(2, field_names[1], Longitude);
+      }
+      UnknownFields.WriteTo(output);
+    }
+
+    private int memoizedSerializedSize = -1;
+    public override int SerializedSize {
+      get {
+        int size = memoizedSerializedSize;
+        if (size != -1) return size;
+        return CalcSerializedSize();
+      }
+    }
+
+    private int CalcSerializedSize() {
+      int size = memoizedSerializedSize;
+      if (size != -1) return size;
+
+      size = 0;
+      if (hasLatitude) {
+        size += pb::CodedOutputStream.ComputeInt32Size(1, Latitude);
+      }
+      if (hasLongitude) {
+        size += pb::CodedOutputStream.ComputeInt32Size(2, Longitude);
+      }
+      size += UnknownFields.SerializedSize;
+      memoizedSerializedSize = size;
+      return size;
+    }
+    public static Point ParseFrom(pb::ByteString data) {
+      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
+    }
+    public static Point ParseFrom(pb::ByteString data, pb::ExtensionRegistry extensionRegistry) {
+      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
+    }
+    public static Point ParseFrom(byte[] data) {
+      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
+    }
+    public static Point ParseFrom(byte[] data, pb::ExtensionRegistry extensionRegistry) {
+      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
+    }
+    public static Point ParseFrom(global::System.IO.Stream input) {
+      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
+    }
+    public static Point ParseFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
+      return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
+    }
+    public static Point ParseDelimitedFrom(global::System.IO.Stream input) {
+      return CreateBuilder().MergeDelimitedFrom(input).BuildParsed();
+    }
+    public static Point ParseDelimitedFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
+      return CreateBuilder().MergeDelimitedFrom(input, extensionRegistry).BuildParsed();
+    }
+    public static Point ParseFrom(pb::ICodedInputStream input) {
+      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
+    }
+    public static Point ParseFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
+      return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
+    }
+    private Point MakeReadOnly() {
+      return this;
+    }
+
+    public static Builder CreateBuilder() { return new Builder(); }
+    public override Builder ToBuilder() { return CreateBuilder(this); }
+    public override Builder CreateBuilderForType() { return new Builder(); }
+    public static Builder CreateBuilder(Point prototype) {
+      return new Builder(prototype);
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+    public sealed partial class Builder : pb::GeneratedBuilder<Point, Builder> {
+      protected override Builder ThisBuilder {
+        get { return this; }
+      }
+      public Builder() {
+        result = DefaultInstance;
+        resultIsReadOnly = true;
+      }
+      internal Builder(Point cloneFrom) {
+        result = cloneFrom;
+        resultIsReadOnly = true;
+      }
+
+      private bool resultIsReadOnly;
+      private Point result;
+
+      private Point PrepareBuilder() {
+        if (resultIsReadOnly) {
+          Point original = result;
+          result = new Point();
+          resultIsReadOnly = false;
+          MergeFrom(original);
+        }
+        return result;
+      }
+
+      public override bool IsInitialized {
+        get { return result.IsInitialized; }
+      }
+
+      protected override Point MessageBeingBuilt {
+        get { return PrepareBuilder(); }
+      }
+
+      public override Builder Clear() {
+        result = DefaultInstance;
+        resultIsReadOnly = true;
+        return this;
+      }
+
+      public override Builder Clone() {
+        if (resultIsReadOnly) {
+          return new Builder(result);
+        } else {
+          return new Builder().MergeFrom(result);
+        }
+      }
+
+      public override pbd::MessageDescriptor DescriptorForType {
+        get { return global::examples.Point.Descriptor; }
+      }
+
+      public override Point DefaultInstanceForType {
+        get { return global::examples.Point.DefaultInstance; }
+      }
+
+      public override Point BuildPartial() {
+        if (resultIsReadOnly) {
+          return result;
+        }
+        resultIsReadOnly = true;
+        return result.MakeReadOnly();
+      }
+
+      public override Builder MergeFrom(pb::IMessage other) {
+        if (other is Point) {
+          return MergeFrom((Point) other);
+        } else {
+          base.MergeFrom(other);
+          return this;
+        }
+      }
+
+      public override Builder MergeFrom(Point other) {
+        if (other == global::examples.Point.DefaultInstance) return this;
+        PrepareBuilder();
+        if (other.HasLatitude) {
+          Latitude = other.Latitude;
+        }
+        if (other.HasLongitude) {
+          Longitude = other.Longitude;
+        }
+        this.MergeUnknownFields(other.UnknownFields);
+        return this;
+      }
+
+      public override Builder MergeFrom(pb::ICodedInputStream input) {
+        return MergeFrom(input, pb::ExtensionRegistry.Empty);
+      }
+
+      public override Builder MergeFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
+        PrepareBuilder();
+        pb::UnknownFieldSet.Builder unknownFields = null;
+        uint tag;
+        string field_name;
+        while (input.ReadTag(out tag, out field_name)) {
+          if(tag == 0 && field_name != null) {
+            int field_ordinal = global::System.Array.BinarySearch(_pointFieldNames, field_name, global::System.StringComparer.Ordinal);
+            if(field_ordinal >= 0)
+              tag = _pointFieldTags[field_ordinal];
+            else {
+              if (unknownFields == null) {
+                unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
+              }
+              ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);
+              continue;
+            }
+          }
+          switch (tag) {
+            case 0: {
+              throw pb::InvalidProtocolBufferException.InvalidTag();
+            }
+            default: {
+              if (pb::WireFormat.IsEndGroupTag(tag)) {
+                if (unknownFields != null) {
+                  this.UnknownFields = unknownFields.Build();
+                }
+                return this;
+              }
+              if (unknownFields == null) {
+                unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
+              }
+              ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);
+              break;
+            }
+            case 8: {
+              result.hasLatitude = input.ReadInt32(ref result.latitude_);
+              break;
+            }
+            case 16: {
+              result.hasLongitude = input.ReadInt32(ref result.longitude_);
+              break;
+            }
+          }
+        }
+
+        if (unknownFields != null) {
+          this.UnknownFields = unknownFields.Build();
+        }
+        return this;
+      }
+
+
+      public bool HasLatitude {
+        get { return result.hasLatitude; }
+      }
+      public int Latitude {
+        get { return result.Latitude; }
+        set { SetLatitude(value); }
+      }
+      public Builder SetLatitude(int value) {
+        PrepareBuilder();
+        result.hasLatitude = true;
+        result.latitude_ = value;
+        return this;
+      }
+      public Builder ClearLatitude() {
+        PrepareBuilder();
+        result.hasLatitude = false;
+        result.latitude_ = 0;
+        return this;
+      }
+
+      public bool HasLongitude {
+        get { return result.hasLongitude; }
+      }
+      public int Longitude {
+        get { return result.Longitude; }
+        set { SetLongitude(value); }
+      }
+      public Builder SetLongitude(int value) {
+        PrepareBuilder();
+        result.hasLongitude = true;
+        result.longitude_ = value;
+        return this;
+      }
+      public Builder ClearLongitude() {
+        PrepareBuilder();
+        result.hasLongitude = false;
+        result.longitude_ = 0;
+        return this;
+      }
+    }
+    static Point() {
+      object.ReferenceEquals(global::examples.Proto.RouteGuide.Descriptor, null);
+    }
+  }
+
+  [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+  public sealed partial class Rectangle : pb::GeneratedMessage<Rectangle, Rectangle.Builder> {
+    private Rectangle() { }
+    private static readonly Rectangle defaultInstance = new Rectangle().MakeReadOnly();
+    private static readonly string[] _rectangleFieldNames = new string[] { "hi", "lo" };
+    private static readonly uint[] _rectangleFieldTags = new uint[] { 18, 10 };
+    public static Rectangle DefaultInstance {
+      get { return defaultInstance; }
+    }
+
+    public override Rectangle DefaultInstanceForType {
+      get { return DefaultInstance; }
+    }
+
+    protected override Rectangle ThisMessage {
+      get { return this; }
+    }
+
+    public static pbd::MessageDescriptor Descriptor {
+      get { return global::examples.Proto.RouteGuide.internal__static_examples_Rectangle__Descriptor; }
+    }
+
+    protected override pb::FieldAccess.FieldAccessorTable<Rectangle, Rectangle.Builder> InternalFieldAccessors {
+      get { return global::examples.Proto.RouteGuide.internal__static_examples_Rectangle__FieldAccessorTable; }
+    }
+
+    public const int LoFieldNumber = 1;
+    private bool hasLo;
+    private global::examples.Point lo_;
+    public bool HasLo {
+      get { return hasLo; }
+    }
+    public global::examples.Point Lo {
+      get { return lo_ ?? global::examples.Point.DefaultInstance; }
+    }
+
+    public const int HiFieldNumber = 2;
+    private bool hasHi;
+    private global::examples.Point hi_;
+    public bool HasHi {
+      get { return hasHi; }
+    }
+    public global::examples.Point Hi {
+      get { return hi_ ?? global::examples.Point.DefaultInstance; }
+    }
+
+    public override bool IsInitialized {
+      get {
+        return true;
+      }
+    }
+
+    public override void WriteTo(pb::ICodedOutputStream output) {
+      CalcSerializedSize();
+      string[] field_names = _rectangleFieldNames;
+      if (hasLo) {
+        output.WriteMessage(1, field_names[1], Lo);
+      }
+      if (hasHi) {
+        output.WriteMessage(2, field_names[0], Hi);
+      }
+      UnknownFields.WriteTo(output);
+    }
+
+    private int memoizedSerializedSize = -1;
+    public override int SerializedSize {
+      get {
+        int size = memoizedSerializedSize;
+        if (size != -1) return size;
+        return CalcSerializedSize();
+      }
+    }
+
+    private int CalcSerializedSize() {
+      int size = memoizedSerializedSize;
+      if (size != -1) return size;
+
+      size = 0;
+      if (hasLo) {
+        size += pb::CodedOutputStream.ComputeMessageSize(1, Lo);
+      }
+      if (hasHi) {
+        size += pb::CodedOutputStream.ComputeMessageSize(2, Hi);
+      }
+      size += UnknownFields.SerializedSize;
+      memoizedSerializedSize = size;
+      return size;
+    }
+    public static Rectangle ParseFrom(pb::ByteString data) {
+      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
+    }
+    public static Rectangle ParseFrom(pb::ByteString data, pb::ExtensionRegistry extensionRegistry) {
+      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
+    }
+    public static Rectangle ParseFrom(byte[] data) {
+      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
+    }
+    public static Rectangle ParseFrom(byte[] data, pb::ExtensionRegistry extensionRegistry) {
+      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
+    }
+    public static Rectangle ParseFrom(global::System.IO.Stream input) {
+      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
+    }
+    public static Rectangle ParseFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
+      return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
+    }
+    public static Rectangle ParseDelimitedFrom(global::System.IO.Stream input) {
+      return CreateBuilder().MergeDelimitedFrom(input).BuildParsed();
+    }
+    public static Rectangle ParseDelimitedFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
+      return CreateBuilder().MergeDelimitedFrom(input, extensionRegistry).BuildParsed();
+    }
+    public static Rectangle ParseFrom(pb::ICodedInputStream input) {
+      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
+    }
+    public static Rectangle ParseFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
+      return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
+    }
+    private Rectangle MakeReadOnly() {
+      return this;
+    }
+
+    public static Builder CreateBuilder() { return new Builder(); }
+    public override Builder ToBuilder() { return CreateBuilder(this); }
+    public override Builder CreateBuilderForType() { return new Builder(); }
+    public static Builder CreateBuilder(Rectangle prototype) {
+      return new Builder(prototype);
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+    public sealed partial class Builder : pb::GeneratedBuilder<Rectangle, Builder> {
+      protected override Builder ThisBuilder {
+        get { return this; }
+      }
+      public Builder() {
+        result = DefaultInstance;
+        resultIsReadOnly = true;
+      }
+      internal Builder(Rectangle cloneFrom) {
+        result = cloneFrom;
+        resultIsReadOnly = true;
+      }
+
+      private bool resultIsReadOnly;
+      private Rectangle result;
+
+      private Rectangle PrepareBuilder() {
+        if (resultIsReadOnly) {
+          Rectangle original = result;
+          result = new Rectangle();
+          resultIsReadOnly = false;
+          MergeFrom(original);
+        }
+        return result;
+      }
+
+      public override bool IsInitialized {
+        get { return result.IsInitialized; }
+      }
+
+      protected override Rectangle MessageBeingBuilt {
+        get { return PrepareBuilder(); }
+      }
+
+      public override Builder Clear() {
+        result = DefaultInstance;
+        resultIsReadOnly = true;
+        return this;
+      }
+
+      public override Builder Clone() {
+        if (resultIsReadOnly) {
+          return new Builder(result);
+        } else {
+          return new Builder().MergeFrom(result);
+        }
+      }
+
+      public override pbd::MessageDescriptor DescriptorForType {
+        get { return global::examples.Rectangle.Descriptor; }
+      }
+
+      public override Rectangle DefaultInstanceForType {
+        get { return global::examples.Rectangle.DefaultInstance; }
+      }
+
+      public override Rectangle BuildPartial() {
+        if (resultIsReadOnly) {
+          return result;
+        }
+        resultIsReadOnly = true;
+        return result.MakeReadOnly();
+      }
+
+      public override Builder MergeFrom(pb::IMessage other) {
+        if (other is Rectangle) {
+          return MergeFrom((Rectangle) other);
+        } else {
+          base.MergeFrom(other);
+          return this;
+        }
+      }
+
+      public override Builder MergeFrom(Rectangle other) {
+        if (other == global::examples.Rectangle.DefaultInstance) return this;
+        PrepareBuilder();
+        if (other.HasLo) {
+          MergeLo(other.Lo);
+        }
+        if (other.HasHi) {
+          MergeHi(other.Hi);
+        }
+        this.MergeUnknownFields(other.UnknownFields);
+        return this;
+      }
+
+      public override Builder MergeFrom(pb::ICodedInputStream input) {
+        return MergeFrom(input, pb::ExtensionRegistry.Empty);
+      }
+
+      public override Builder MergeFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
+        PrepareBuilder();
+        pb::UnknownFieldSet.Builder unknownFields = null;
+        uint tag;
+        string field_name;
+        while (input.ReadTag(out tag, out field_name)) {
+          if(tag == 0 && field_name != null) {
+            int field_ordinal = global::System.Array.BinarySearch(_rectangleFieldNames, field_name, global::System.StringComparer.Ordinal);
+            if(field_ordinal >= 0)
+              tag = _rectangleFieldTags[field_ordinal];
+            else {
+              if (unknownFields == null) {
+                unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
+              }
+              ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);
+              continue;
+            }
+          }
+          switch (tag) {
+            case 0: {
+              throw pb::InvalidProtocolBufferException.InvalidTag();
+            }
+            default: {
+              if (pb::WireFormat.IsEndGroupTag(tag)) {
+                if (unknownFields != null) {
+                  this.UnknownFields = unknownFields.Build();
+                }
+                return this;
+              }
+              if (unknownFields == null) {
+                unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
+              }
+              ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);
+              break;
+            }
+            case 10: {
+              global::examples.Point.Builder subBuilder = global::examples.Point.CreateBuilder();
+              if (result.hasLo) {
+                subBuilder.MergeFrom(Lo);
+              }
+              input.ReadMessage(subBuilder, extensionRegistry);
+              Lo = subBuilder.BuildPartial();
+              break;
+            }
+            case 18: {
+              global::examples.Point.Builder subBuilder = global::examples.Point.CreateBuilder();
+              if (result.hasHi) {
+                subBuilder.MergeFrom(Hi);
+              }
+              input.ReadMessage(subBuilder, extensionRegistry);
+              Hi = subBuilder.BuildPartial();
+              break;
+            }
+          }
+        }
+
+        if (unknownFields != null) {
+          this.UnknownFields = unknownFields.Build();
+        }
+        return this;
+      }
+
+
+      public bool HasLo {
+       get { return result.hasLo; }
+      }
+      public global::examples.Point Lo {
+        get { return result.Lo; }
+        set { SetLo(value); }
+      }
+      public Builder SetLo(global::examples.Point value) {
+        pb::ThrowHelper.ThrowIfNull(value, "value");
+        PrepareBuilder();
+        result.hasLo = true;
+        result.lo_ = value;
+        return this;
+      }
+      public Builder SetLo(global::examples.Point.Builder builderForValue) {
+        pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
+        PrepareBuilder();
+        result.hasLo = true;
+        result.lo_ = builderForValue.Build();
+        return this;
+      }
+      public Builder MergeLo(global::examples.Point value) {
+        pb::ThrowHelper.ThrowIfNull(value, "value");
+        PrepareBuilder();
+        if (result.hasLo &&
+            result.lo_ != global::examples.Point.DefaultInstance) {
+            result.lo_ = global::examples.Point.CreateBuilder(result.lo_).MergeFrom(value).BuildPartial();
+        } else {
+          result.lo_ = value;
+        }
+        result.hasLo = true;
+        return this;
+      }
+      public Builder ClearLo() {
+        PrepareBuilder();
+        result.hasLo = false;
+        result.lo_ = null;
+        return this;
+      }
+
+      public bool HasHi {
+       get { return result.hasHi; }
+      }
+      public global::examples.Point Hi {
+        get { return result.Hi; }
+        set { SetHi(value); }
+      }
+      public Builder SetHi(global::examples.Point value) {
+        pb::ThrowHelper.ThrowIfNull(value, "value");
+        PrepareBuilder();
+        result.hasHi = true;
+        result.hi_ = value;
+        return this;
+      }
+      public Builder SetHi(global::examples.Point.Builder builderForValue) {
+        pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
+        PrepareBuilder();
+        result.hasHi = true;
+        result.hi_ = builderForValue.Build();
+        return this;
+      }
+      public Builder MergeHi(global::examples.Point value) {
+        pb::ThrowHelper.ThrowIfNull(value, "value");
+        PrepareBuilder();
+        if (result.hasHi &&
+            result.hi_ != global::examples.Point.DefaultInstance) {
+            result.hi_ = global::examples.Point.CreateBuilder(result.hi_).MergeFrom(value).BuildPartial();
+        } else {
+          result.hi_ = value;
+        }
+        result.hasHi = true;
+        return this;
+      }
+      public Builder ClearHi() {
+        PrepareBuilder();
+        result.hasHi = false;
+        result.hi_ = null;
+        return this;
+      }
+    }
+    static Rectangle() {
+      object.ReferenceEquals(global::examples.Proto.RouteGuide.Descriptor, null);
+    }
+  }
+
+  [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+  public sealed partial class Feature : pb::GeneratedMessage<Feature, Feature.Builder> {
+    private Feature() { }
+    private static readonly Feature defaultInstance = new Feature().MakeReadOnly();
+    private static readonly string[] _featureFieldNames = new string[] { "location", "name" };
+    private static readonly uint[] _featureFieldTags = new uint[] { 18, 10 };
+    public static Feature DefaultInstance {
+      get { return defaultInstance; }
+    }
+
+    public override Feature DefaultInstanceForType {
+      get { return DefaultInstance; }
+    }
+
+    protected override Feature ThisMessage {
+      get { return this; }
+    }
+
+    public static pbd::MessageDescriptor Descriptor {
+      get { return global::examples.Proto.RouteGuide.internal__static_examples_Feature__Descriptor; }
+    }
+
+    protected override pb::FieldAccess.FieldAccessorTable<Feature, Feature.Builder> InternalFieldAccessors {
+      get { return global::examples.Proto.RouteGuide.internal__static_examples_Feature__FieldAccessorTable; }
+    }
+
+    public const int NameFieldNumber = 1;
+    private bool hasName;
+    private string name_ = "";
+    public bool HasName {
+      get { return hasName; }
+    }
+    public string Name {
+      get { return name_; }
+    }
+
+    public const int LocationFieldNumber = 2;
+    private bool hasLocation;
+    private global::examples.Point location_;
+    public bool HasLocation {
+      get { return hasLocation; }
+    }
+    public global::examples.Point Location {
+      get { return location_ ?? global::examples.Point.DefaultInstance; }
+    }
+
+    public override bool IsInitialized {
+      get {
+        return true;
+      }
+    }
+
+    public override void WriteTo(pb::ICodedOutputStream output) {
+      CalcSerializedSize();
+      string[] field_names = _featureFieldNames;
+      if (hasName) {
+        output.WriteString(1, field_names[1], Name);
+      }
+      if (hasLocation) {
+        output.WriteMessage(2, field_names[0], Location);
+      }
+      UnknownFields.WriteTo(output);
+    }
+
+    private int memoizedSerializedSize = -1;
+    public override int SerializedSize {
+      get {
+        int size = memoizedSerializedSize;
+        if (size != -1) return size;
+        return CalcSerializedSize();
+      }
+    }
+
+    private int CalcSerializedSize() {
+      int size = memoizedSerializedSize;
+      if (size != -1) return size;
+
+      size = 0;
+      if (hasName) {
+        size += pb::CodedOutputStream.ComputeStringSize(1, Name);
+      }
+      if (hasLocation) {
+        size += pb::CodedOutputStream.ComputeMessageSize(2, Location);
+      }
+      size += UnknownFields.SerializedSize;
+      memoizedSerializedSize = size;
+      return size;
+    }
+    public static Feature ParseFrom(pb::ByteString data) {
+      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
+    }
+    public static Feature ParseFrom(pb::ByteString data, pb::ExtensionRegistry extensionRegistry) {
+      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
+    }
+    public static Feature ParseFrom(byte[] data) {
+      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
+    }
+    public static Feature ParseFrom(byte[] data, pb::ExtensionRegistry extensionRegistry) {
+      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
+    }
+    public static Feature ParseFrom(global::System.IO.Stream input) {
+      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
+    }
+    public static Feature ParseFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
+      return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
+    }
+    public static Feature ParseDelimitedFrom(global::System.IO.Stream input) {
+      return CreateBuilder().MergeDelimitedFrom(input).BuildParsed();
+    }
+    public static Feature ParseDelimitedFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
+      return CreateBuilder().MergeDelimitedFrom(input, extensionRegistry).BuildParsed();
+    }
+    public static Feature ParseFrom(pb::ICodedInputStream input) {
+      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
+    }
+    public static Feature ParseFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
+      return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
+    }
+    private Feature MakeReadOnly() {
+      return this;
+    }
+
+    public static Builder CreateBuilder() { return new Builder(); }
+    public override Builder ToBuilder() { return CreateBuilder(this); }
+    public override Builder CreateBuilderForType() { return new Builder(); }
+    public static Builder CreateBuilder(Feature prototype) {
+      return new Builder(prototype);
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+    public sealed partial class Builder : pb::GeneratedBuilder<Feature, Builder> {
+      protected override Builder ThisBuilder {
+        get { return this; }
+      }
+      public Builder() {
+        result = DefaultInstance;
+        resultIsReadOnly = true;
+      }
+      internal Builder(Feature cloneFrom) {
+        result = cloneFrom;
+        resultIsReadOnly = true;
+      }
+
+      private bool resultIsReadOnly;
+      private Feature result;
+
+      private Feature PrepareBuilder() {
+        if (resultIsReadOnly) {
+          Feature original = result;
+          result = new Feature();
+          resultIsReadOnly = false;
+          MergeFrom(original);
+        }
+        return result;
+      }
+
+      public override bool IsInitialized {
+        get { return result.IsInitialized; }
+      }
+
+      protected override Feature MessageBeingBuilt {
+        get { return PrepareBuilder(); }
+      }
+
+      public override Builder Clear() {
+        result = DefaultInstance;
+        resultIsReadOnly = true;
+        return this;
+      }
+
+      public override Builder Clone() {
+        if (resultIsReadOnly) {
+          return new Builder(result);
+        } else {
+          return new Builder().MergeFrom(result);
+        }
+      }
+
+      public override pbd::MessageDescriptor DescriptorForType {
+        get { return global::examples.Feature.Descriptor; }
+      }
+
+      public override Feature DefaultInstanceForType {
+        get { return global::examples.Feature.DefaultInstance; }
+      }
+
+      public override Feature BuildPartial() {
+        if (resultIsReadOnly) {
+          return result;
+        }
+        resultIsReadOnly = true;
+        return result.MakeReadOnly();
+      }
+
+      public override Builder MergeFrom(pb::IMessage other) {
+        if (other is Feature) {
+          return MergeFrom((Feature) other);
+        } else {
+          base.MergeFrom(other);
+          return this;
+        }
+      }
+
+      public override Builder MergeFrom(Feature other) {
+        if (other == global::examples.Feature.DefaultInstance) return this;
+        PrepareBuilder();
+        if (other.HasName) {
+          Name = other.Name;
+        }
+        if (other.HasLocation) {
+          MergeLocation(other.Location);
+        }
+        this.MergeUnknownFields(other.UnknownFields);
+        return this;
+      }
+
+      public override Builder MergeFrom(pb::ICodedInputStream input) {
+        return MergeFrom(input, pb::ExtensionRegistry.Empty);
+      }
+
+      public override Builder MergeFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
+        PrepareBuilder();
+        pb::UnknownFieldSet.Builder unknownFields = null;
+        uint tag;
+        string field_name;
+        while (input.ReadTag(out tag, out field_name)) {
+          if(tag == 0 && field_name != null) {
+            int field_ordinal = global::System.Array.BinarySearch(_featureFieldNames, field_name, global::System.StringComparer.Ordinal);
+            if(field_ordinal >= 0)
+              tag = _featureFieldTags[field_ordinal];
+            else {
+              if (unknownFields == null) {
+                unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
+              }
+              ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);
+              continue;
+            }
+          }
+          switch (tag) {
+            case 0: {
+              throw pb::InvalidProtocolBufferException.InvalidTag();
+            }
+            default: {
+              if (pb::WireFormat.IsEndGroupTag(tag)) {
+                if (unknownFields != null) {
+                  this.UnknownFields = unknownFields.Build();
+                }
+                return this;
+              }
+              if (unknownFields == null) {
+                unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
+              }
+              ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);
+              break;
+            }
+            case 10: {
+              result.hasName = input.ReadString(ref result.name_);
+              break;
+            }
+            case 18: {
+              global::examples.Point.Builder subBuilder = global::examples.Point.CreateBuilder();
+              if (result.hasLocation) {
+                subBuilder.MergeFrom(Location);
+              }
+              input.ReadMessage(subBuilder, extensionRegistry);
+              Location = subBuilder.BuildPartial();
+              break;
+            }
+          }
+        }
+
+        if (unknownFields != null) {
+          this.UnknownFields = unknownFields.Build();
+        }
+        return this;
+      }
+
+
+      public bool HasName {
+        get { return result.hasName; }
+      }
+      public string Name {
+        get { return result.Name; }
+        set { SetName(value); }
+      }
+      public Builder SetName(string value) {
+        pb::ThrowHelper.ThrowIfNull(value, "value");
+        PrepareBuilder();
+        result.hasName = true;
+        result.name_ = value;
+        return this;
+      }
+      public Builder ClearName() {
+        PrepareBuilder();
+        result.hasName = false;
+        result.name_ = "";
+        return this;
+      }
+
+      public bool HasLocation {
+       get { return result.hasLocation; }
+      }
+      public global::examples.Point Location {
+        get { return result.Location; }
+        set { SetLocation(value); }
+      }
+      public Builder SetLocation(global::examples.Point value) {
+        pb::ThrowHelper.ThrowIfNull(value, "value");
+        PrepareBuilder();
+        result.hasLocation = true;
+        result.location_ = value;
+        return this;
+      }
+      public Builder SetLocation(global::examples.Point.Builder builderForValue) {
+        pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
+        PrepareBuilder();
+        result.hasLocation = true;
+        result.location_ = builderForValue.Build();
+        return this;
+      }
+      public Builder MergeLocation(global::examples.Point value) {
+        pb::ThrowHelper.ThrowIfNull(value, "value");
+        PrepareBuilder();
+        if (result.hasLocation &&
+            result.location_ != global::examples.Point.DefaultInstance) {
+            result.location_ = global::examples.Point.CreateBuilder(result.location_).MergeFrom(value).BuildPartial();
+        } else {
+          result.location_ = value;
+        }
+        result.hasLocation = true;
+        return this;
+      }
+      public Builder ClearLocation() {
+        PrepareBuilder();
+        result.hasLocation = false;
+        result.location_ = null;
+        return this;
+      }
+    }
+    static Feature() {
+      object.ReferenceEquals(global::examples.Proto.RouteGuide.Descriptor, null);
+    }
+  }
+
+  [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+  public sealed partial class RouteNote : pb::GeneratedMessage<RouteNote, RouteNote.Builder> {
+    private RouteNote() { }
+    private static readonly RouteNote defaultInstance = new RouteNote().MakeReadOnly();
+    private static readonly string[] _routeNoteFieldNames = new string[] { "location", "message" };
+    private static readonly uint[] _routeNoteFieldTags = new uint[] { 10, 18 };
+    public static RouteNote DefaultInstance {
+      get { return defaultInstance; }
+    }
+
+    public override RouteNote DefaultInstanceForType {
+      get { return DefaultInstance; }
+    }
+
+    protected override RouteNote ThisMessage {
+      get { return this; }
+    }
+
+    public static pbd::MessageDescriptor Descriptor {
+      get { return global::examples.Proto.RouteGuide.internal__static_examples_RouteNote__Descriptor; }
+    }
+
+    protected override pb::FieldAccess.FieldAccessorTable<RouteNote, RouteNote.Builder> InternalFieldAccessors {
+      get { return global::examples.Proto.RouteGuide.internal__static_examples_RouteNote__FieldAccessorTable; }
+    }
+
+    public const int LocationFieldNumber = 1;
+    private bool hasLocation;
+    private global::examples.Point location_;
+    public bool HasLocation {
+      get { return hasLocation; }
+    }
+    public global::examples.Point Location {
+      get { return location_ ?? global::examples.Point.DefaultInstance; }
+    }
+
+    public const int MessageFieldNumber = 2;
+    private bool hasMessage;
+    private string message_ = "";
+    public bool HasMessage {
+      get { return hasMessage; }
+    }
+    public string Message {
+      get { return message_; }
+    }
+
+    public override bool IsInitialized {
+      get {
+        return true;
+      }
+    }
+
+    public override void WriteTo(pb::ICodedOutputStream output) {
+      CalcSerializedSize();
+      string[] field_names = _routeNoteFieldNames;
+      if (hasLocation) {
+        output.WriteMessage(1, field_names[0], Location);
+      }
+      if (hasMessage) {
+        output.WriteString(2, field_names[1], Message);
+      }
+      UnknownFields.WriteTo(output);
+    }
+
+    private int memoizedSerializedSize = -1;
+    public override int SerializedSize {
+      get {
+        int size = memoizedSerializedSize;
+        if (size != -1) return size;
+        return CalcSerializedSize();
+      }
+    }
+
+    private int CalcSerializedSize() {
+      int size = memoizedSerializedSize;
+      if (size != -1) return size;
+
+      size = 0;
+      if (hasLocation) {
+        size += pb::CodedOutputStream.ComputeMessageSize(1, Location);
+      }
+      if (hasMessage) {
+        size += pb::CodedOutputStream.ComputeStringSize(2, Message);
+      }
+      size += UnknownFields.SerializedSize;
+      memoizedSerializedSize = size;
+      return size;
+    }
+    public static RouteNote ParseFrom(pb::ByteString data) {
+      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
+    }
+    public static RouteNote ParseFrom(pb::ByteString data, pb::ExtensionRegistry extensionRegistry) {
+      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
+    }
+    public static RouteNote ParseFrom(byte[] data) {
+      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
+    }
+    public static RouteNote ParseFrom(byte[] data, pb::ExtensionRegistry extensionRegistry) {
+      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
+    }
+    public static RouteNote ParseFrom(global::System.IO.Stream input) {
+      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
+    }
+    public static RouteNote ParseFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
+      return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
+    }
+    public static RouteNote ParseDelimitedFrom(global::System.IO.Stream input) {
+      return CreateBuilder().MergeDelimitedFrom(input).BuildParsed();
+    }
+    public static RouteNote ParseDelimitedFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
+      return CreateBuilder().MergeDelimitedFrom(input, extensionRegistry).BuildParsed();
+    }
+    public static RouteNote ParseFrom(pb::ICodedInputStream input) {
+      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
+    }
+    public static RouteNote ParseFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
+      return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
+    }
+    private RouteNote MakeReadOnly() {
+      return this;
+    }
+
+    public static Builder CreateBuilder() { return new Builder(); }
+    public override Builder ToBuilder() { return CreateBuilder(this); }
+    public override Builder CreateBuilderForType() { return new Builder(); }
+    public static Builder CreateBuilder(RouteNote prototype) {
+      return new Builder(prototype);
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+    public sealed partial class Builder : pb::GeneratedBuilder<RouteNote, Builder> {
+      protected override Builder ThisBuilder {
+        get { return this; }
+      }
+      public Builder() {
+        result = DefaultInstance;
+        resultIsReadOnly = true;
+      }
+      internal Builder(RouteNote cloneFrom) {
+        result = cloneFrom;
+        resultIsReadOnly = true;
+      }
+
+      private bool resultIsReadOnly;
+      private RouteNote result;
+
+      private RouteNote PrepareBuilder() {
+        if (resultIsReadOnly) {
+          RouteNote original = result;
+          result = new RouteNote();
+          resultIsReadOnly = false;
+          MergeFrom(original);
+        }
+        return result;
+      }
+
+      public override bool IsInitialized {
+        get { return result.IsInitialized; }
+      }
+
+      protected override RouteNote MessageBeingBuilt {
+        get { return PrepareBuilder(); }
+      }
+
+      public override Builder Clear() {
+        result = DefaultInstance;
+        resultIsReadOnly = true;
+        return this;
+      }
+
+      public override Builder Clone() {
+        if (resultIsReadOnly) {
+          return new Builder(result);
+        } else {
+          return new Builder().MergeFrom(result);
+        }
+      }
+
+      public override pbd::MessageDescriptor DescriptorForType {
+        get { return global::examples.RouteNote.Descriptor; }
+      }
+
+      public override RouteNote DefaultInstanceForType {
+        get { return global::examples.RouteNote.DefaultInstance; }
+      }
+
+      public override RouteNote BuildPartial() {
+        if (resultIsReadOnly) {
+          return result;
+        }
+        resultIsReadOnly = true;
+        return result.MakeReadOnly();
+      }
+
+      public override Builder MergeFrom(pb::IMessage other) {
+        if (other is RouteNote) {
+          return MergeFrom((RouteNote) other);
+        } else {
+          base.MergeFrom(other);
+          return this;
+        }
+      }
+
+      public override Builder MergeFrom(RouteNote other) {
+        if (other == global::examples.RouteNote.DefaultInstance) return this;
+        PrepareBuilder();
+        if (other.HasLocation) {
+          MergeLocation(other.Location);
+        }
+        if (other.HasMessage) {
+          Message = other.Message;
+        }
+        this.MergeUnknownFields(other.UnknownFields);
+        return this;
+      }
+
+      public override Builder MergeFrom(pb::ICodedInputStream input) {
+        return MergeFrom(input, pb::ExtensionRegistry.Empty);
+      }
+
+      public override Builder MergeFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
+        PrepareBuilder();
+        pb::UnknownFieldSet.Builder unknownFields = null;
+        uint tag;
+        string field_name;
+        while (input.ReadTag(out tag, out field_name)) {
+          if(tag == 0 && field_name != null) {
+            int field_ordinal = global::System.Array.BinarySearch(_routeNoteFieldNames, field_name, global::System.StringComparer.Ordinal);
+            if(field_ordinal >= 0)
+              tag = _routeNoteFieldTags[field_ordinal];
+            else {
+              if (unknownFields == null) {
+                unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
+              }
+              ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);
+              continue;
+            }
+          }
+          switch (tag) {
+            case 0: {
+              throw pb::InvalidProtocolBufferException.InvalidTag();
+            }
+            default: {
+              if (pb::WireFormat.IsEndGroupTag(tag)) {
+                if (unknownFields != null) {
+                  this.UnknownFields = unknownFields.Build();
+                }
+                return this;
+              }
+              if (unknownFields == null) {
+                unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
+              }
+              ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);
+              break;
+            }
+            case 10: {
+              global::examples.Point.Builder subBuilder = global::examples.Point.CreateBuilder();
+              if (result.hasLocation) {
+                subBuilder.MergeFrom(Location);
+              }
+              input.ReadMessage(subBuilder, extensionRegistry);
+              Location = subBuilder.BuildPartial();
+              break;
+            }
+            case 18: {
+              result.hasMessage = input.ReadString(ref result.message_);
+              break;
+            }
+          }
+        }
+
+        if (unknownFields != null) {
+          this.UnknownFields = unknownFields.Build();
+        }
+        return this;
+      }
+
+
+      public bool HasLocation {
+       get { return result.hasLocation; }
+      }
+      public global::examples.Point Location {
+        get { return result.Location; }
+        set { SetLocation(value); }
+      }
+      public Builder SetLocation(global::examples.Point value) {
+        pb::ThrowHelper.ThrowIfNull(value, "value");
+        PrepareBuilder();
+        result.hasLocation = true;
+        result.location_ = value;
+        return this;
+      }
+      public Builder SetLocation(global::examples.Point.Builder builderForValue) {
+        pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
+        PrepareBuilder();
+        result.hasLocation = true;
+        result.location_ = builderForValue.Build();
+        return this;
+      }
+      public Builder MergeLocation(global::examples.Point value) {
+        pb::ThrowHelper.ThrowIfNull(value, "value");
+        PrepareBuilder();
+        if (result.hasLocation &&
+            result.location_ != global::examples.Point.DefaultInstance) {
+            result.location_ = global::examples.Point.CreateBuilder(result.location_).MergeFrom(value).BuildPartial();
+        } else {
+          result.location_ = value;
+        }
+        result.hasLocation = true;
+        return this;
+      }
+      public Builder ClearLocation() {
+        PrepareBuilder();
+        result.hasLocation = false;
+        result.location_ = null;
+        return this;
+      }
+
+      public bool HasMessage {
+        get { return result.hasMessage; }
+      }
+      public string Message {
+        get { return result.Message; }
+        set { SetMessage(value); }
+      }
+      public Builder SetMessage(string value) {
+        pb::ThrowHelper.ThrowIfNull(value, "value");
+        PrepareBuilder();
+        result.hasMessage = true;
+        result.message_ = value;
+        return this;
+      }
+      public Builder ClearMessage() {
+        PrepareBuilder();
+        result.hasMessage = false;
+        result.message_ = "";
+        return this;
+      }
+    }
+    static RouteNote() {
+      object.ReferenceEquals(global::examples.Proto.RouteGuide.Descriptor, null);
+    }
+  }
+
+  [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+  public sealed partial class RouteSummary : pb::GeneratedMessage<RouteSummary, RouteSummary.Builder> {
+    private RouteSummary() { }
+    private static readonly RouteSummary defaultInstance = new RouteSummary().MakeReadOnly();
+    private static readonly string[] _routeSummaryFieldNames = new string[] { "distance", "elapsed_time", "feature_count", "point_count" };
+    private static readonly uint[] _routeSummaryFieldTags = new uint[] { 24, 32, 16, 8 };
+    public static RouteSummary DefaultInstance {
+      get { return defaultInstance; }
+    }
+
+    public override RouteSummary DefaultInstanceForType {
+      get { return DefaultInstance; }
+    }
+
+    protected override RouteSummary ThisMessage {
+      get { return this; }
+    }
+
+    public static pbd::MessageDescriptor Descriptor {
+      get { return global::examples.Proto.RouteGuide.internal__static_examples_RouteSummary__Descriptor; }
+    }
+
+    protected override pb::FieldAccess.FieldAccessorTable<RouteSummary, RouteSummary.Builder> InternalFieldAccessors {
+      get { return global::examples.Proto.RouteGuide.internal__static_examples_RouteSummary__FieldAccessorTable; }
+    }
+
+    public const int PointCountFieldNumber = 1;
+    private bool hasPointCount;
+    private int pointCount_;
+    public bool HasPointCount {
+      get { return hasPointCount; }
+    }
+    public int PointCount {
+      get { return pointCount_; }
+    }
+
+    public const int FeatureCountFieldNumber = 2;
+    private bool hasFeatureCount;
+    private int featureCount_;
+    public bool HasFeatureCount {
+      get { return hasFeatureCount; }
+    }
+    public int FeatureCount {
+      get { return featureCount_; }
+    }
+
+    public const int DistanceFieldNumber = 3;
+    private bool hasDistance;
+    private int distance_;
+    public bool HasDistance {
+      get { return hasDistance; }
+    }
+    public int Distance {
+      get { return distance_; }
+    }
+
+    public const int ElapsedTimeFieldNumber = 4;
+    private bool hasElapsedTime;
+    private int elapsedTime_;
+    public bool HasElapsedTime {
+      get { return hasElapsedTime; }
+    }
+    public int ElapsedTime {
+      get { return elapsedTime_; }
+    }
+
+    public override bool IsInitialized {
+      get {
+        return true;
+      }
+    }
+
+    public override void WriteTo(pb::ICodedOutputStream output) {
+      CalcSerializedSize();
+      string[] field_names = _routeSummaryFieldNames;
+      if (hasPointCount) {
+        output.WriteInt32(1, field_names[3], PointCount);
+      }
+      if (hasFeatureCount) {
+        output.WriteInt32(2, field_names[2], FeatureCount);
+      }
+      if (hasDistance) {
+        output.WriteInt32(3, field_names[0], Distance);
+      }
+      if (hasElapsedTime) {
+        output.WriteInt32(4, field_names[1], ElapsedTime);
+      }
+      UnknownFields.WriteTo(output);
+    }
+
+    private int memoizedSerializedSize = -1;
+    public override int SerializedSize {
+      get {
+        int size = memoizedSerializedSize;
+        if (size != -1) return size;
+        return CalcSerializedSize();
+      }
+    }
+
+    private int CalcSerializedSize() {
+      int size = memoizedSerializedSize;
+      if (size != -1) return size;
+
+      size = 0;
+      if (hasPointCount) {
+        size += pb::CodedOutputStream.ComputeInt32Size(1, PointCount);
+      }
+      if (hasFeatureCount) {
+        size += pb::CodedOutputStream.ComputeInt32Size(2, FeatureCount);
+      }
+      if (hasDistance) {
+        size += pb::CodedOutputStream.ComputeInt32Size(3, Distance);
+      }
+      if (hasElapsedTime) {
+        size += pb::CodedOutputStream.ComputeInt32Size(4, ElapsedTime);
+      }
+      size += UnknownFields.SerializedSize;
+      memoizedSerializedSize = size;
+      return size;
+    }
+    public static RouteSummary ParseFrom(pb::ByteString data) {
+      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
+    }
+    public static RouteSummary ParseFrom(pb::ByteString data, pb::ExtensionRegistry extensionRegistry) {
+      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
+    }
+    public static RouteSummary ParseFrom(byte[] data) {
+      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
+    }
+    public static RouteSummary ParseFrom(byte[] data, pb::ExtensionRegistry extensionRegistry) {
+      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
+    }
+    public static RouteSummary ParseFrom(global::System.IO.Stream input) {
+      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
+    }
+    public static RouteSummary ParseFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
+      return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
+    }
+    public static RouteSummary ParseDelimitedFrom(global::System.IO.Stream input) {
+      return CreateBuilder().MergeDelimitedFrom(input).BuildParsed();
+    }
+    public static RouteSummary ParseDelimitedFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
+      return CreateBuilder().MergeDelimitedFrom(input, extensionRegistry).BuildParsed();
+    }
+    public static RouteSummary ParseFrom(pb::ICodedInputStream input) {
+      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
+    }
+    public static RouteSummary ParseFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
+      return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
+    }
+    private RouteSummary MakeReadOnly() {
+      return this;
+    }
+
+    public static Builder CreateBuilder() { return new Builder(); }
+    public override Builder ToBuilder() { return CreateBuilder(this); }
+    public override Builder CreateBuilderForType() { return new Builder(); }
+    public static Builder CreateBuilder(RouteSummary prototype) {
+      return new Builder(prototype);
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+    public sealed partial class Builder : pb::GeneratedBuilder<RouteSummary, Builder> {
+      protected override Builder ThisBuilder {
+        get { return this; }
+      }
+      public Builder() {
+        result = DefaultInstance;
+        resultIsReadOnly = true;
+      }
+      internal Builder(RouteSummary cloneFrom) {
+        result = cloneFrom;
+        resultIsReadOnly = true;
+      }
+
+      private bool resultIsReadOnly;
+      private RouteSummary result;
+
+      private RouteSummary PrepareBuilder() {
+        if (resultIsReadOnly) {
+          RouteSummary original = result;
+          result = new RouteSummary();
+          resultIsReadOnly = false;
+          MergeFrom(original);
+        }
+        return result;
+      }
+
+      public override bool IsInitialized {
+        get { return result.IsInitialized; }
+      }
+
+      protected override RouteSummary MessageBeingBuilt {
+        get { return PrepareBuilder(); }
+      }
+
+      public override Builder Clear() {
+        result = DefaultInstance;
+        resultIsReadOnly = true;
+        return this;
+      }
+
+      public override Builder Clone() {
+        if (resultIsReadOnly) {
+          return new Builder(result);
+        } else {
+          return new Builder().MergeFrom(result);
+        }
+      }
+
+      public override pbd::MessageDescriptor DescriptorForType {
+        get { return global::examples.RouteSummary.Descriptor; }
+      }
+
+      public override RouteSummary DefaultInstanceForType {
+        get { return global::examples.RouteSummary.DefaultInstance; }
+      }
+
+      public override RouteSummary BuildPartial() {
+        if (resultIsReadOnly) {
+          return result;
+        }
+        resultIsReadOnly = true;
+        return result.MakeReadOnly();
+      }
+
+      public override Builder MergeFrom(pb::IMessage other) {
+        if (other is RouteSummary) {
+          return MergeFrom((RouteSummary) other);
+        } else {
+          base.MergeFrom(other);
+          return this;
+        }
+      }
+
+      public override Builder MergeFrom(RouteSummary other) {
+        if (other == global::examples.RouteSummary.DefaultInstance) return this;
+        PrepareBuilder();
+        if (other.HasPointCount) {
+          PointCount = other.PointCount;
+        }
+        if (other.HasFeatureCount) {
+          FeatureCount = other.FeatureCount;
+        }
+        if (other.HasDistance) {
+          Distance = other.Distance;
+        }
+        if (other.HasElapsedTime) {
+          ElapsedTime = other.ElapsedTime;
+        }
+        this.MergeUnknownFields(other.UnknownFields);
+        return this;
+      }
+
+      public override Builder MergeFrom(pb::ICodedInputStream input) {
+        return MergeFrom(input, pb::ExtensionRegistry.Empty);
+      }
+
+      public override Builder MergeFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
+        PrepareBuilder();
+        pb::UnknownFieldSet.Builder unknownFields = null;
+        uint tag;
+        string field_name;
+        while (input.ReadTag(out tag, out field_name)) {
+          if(tag == 0 && field_name != null) {
+            int field_ordinal = global::System.Array.BinarySearch(_routeSummaryFieldNames, field_name, global::System.StringComparer.Ordinal);
+            if(field_ordinal >= 0)
+              tag = _routeSummaryFieldTags[field_ordinal];
+            else {
+              if (unknownFields == null) {
+                unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
+              }
+              ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);
+              continue;
+            }
+          }
+          switch (tag) {
+            case 0: {
+              throw pb::InvalidProtocolBufferException.InvalidTag();
+            }
+            default: {
+              if (pb::WireFormat.IsEndGroupTag(tag)) {
+                if (unknownFields != null) {
+                  this.UnknownFields = unknownFields.Build();
+                }
+                return this;
+              }
+              if (unknownFields == null) {
+                unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
+              }
+              ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);
+              break;
+            }
+            case 8: {
+              result.hasPointCount = input.ReadInt32(ref result.pointCount_);
+              break;
+            }
+            case 16: {
+              result.hasFeatureCount = input.ReadInt32(ref result.featureCount_);
+              break;
+            }
+            case 24: {
+              result.hasDistance = input.ReadInt32(ref result.distance_);
+              break;
+            }
+            case 32: {
+              result.hasElapsedTime = input.ReadInt32(ref result.elapsedTime_);
+              break;
+            }
+          }
+        }
+
+        if (unknownFields != null) {
+          this.UnknownFields = unknownFields.Build();
+        }
+        return this;
+      }
+
+
+      public bool HasPointCount {
+        get { return result.hasPointCount; }
+      }
+      public int PointCount {
+        get { return result.PointCount; }
+        set { SetPointCount(value); }
+      }
+      public Builder SetPointCount(int value) {
+        PrepareBuilder();
+        result.hasPointCount = true;
+        result.pointCount_ = value;
+        return this;
+      }
+      public Builder ClearPointCount() {
+        PrepareBuilder();
+        result.hasPointCount = false;
+        result.pointCount_ = 0;
+        return this;
+      }
+
+      public bool HasFeatureCount {
+        get { return result.hasFeatureCount; }
+      }
+      public int FeatureCount {
+        get { return result.FeatureCount; }
+        set { SetFeatureCount(value); }
+      }
+      public Builder SetFeatureCount(int value) {
+        PrepareBuilder();
+        result.hasFeatureCount = true;
+        result.featureCount_ = value;
+        return this;
+      }
+      public Builder ClearFeatureCount() {
+        PrepareBuilder();
+        result.hasFeatureCount = false;
+        result.featureCount_ = 0;
+        return this;
+      }
+
+      public bool HasDistance {
+        get { return result.hasDistance; }
+      }
+      public int Distance {
+        get { return result.Distance; }
+        set { SetDistance(value); }
+      }
+      public Builder SetDistance(int value) {
+        PrepareBuilder();
+        result.hasDistance = true;
+        result.distance_ = value;
+        return this;
+      }
+      public Builder ClearDistance() {
+        PrepareBuilder();
+        result.hasDistance = false;
+        result.distance_ = 0;
+        return this;
+      }
+
+      public bool HasElapsedTime {
+        get { return result.hasElapsedTime; }
+      }
+      public int ElapsedTime {
+        get { return result.ElapsedTime; }
+        set { SetElapsedTime(value); }
+      }
+      public Builder SetElapsedTime(int value) {
+        PrepareBuilder();
+        result.hasElapsedTime = true;
+        result.elapsedTime_ = value;
+        return this;
+      }
+      public Builder ClearElapsedTime() {
+        PrepareBuilder();
+        result.hasElapsedTime = false;
+        result.elapsedTime_ = 0;
+        return this;
+      }
+    }
+    static RouteSummary() {
+      object.ReferenceEquals(global::examples.Proto.RouteGuide.Descriptor, null);
+    }
+  }
+
+  #endregion
+
+}
+
+#endregion Designer generated code
diff --git a/csharp/route_guide/RouteGuide/RouteGuide.csproj b/csharp/route_guide/RouteGuide/RouteGuide.csproj
new file mode 100644
index 0000000..9b5daa6
--- /dev/null
+++ b/csharp/route_guide/RouteGuide/RouteGuide.csproj
@@ -0,0 +1,99 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <Import Project="..\packages\grpc.native.csharp_ext.0.9.0.0\build\portable-net45\grpc.native.csharp_ext.props" Condition="Exists('..\packages\grpc.native.csharp_ext.0.9.0.0\build\portable-net45\grpc.native.csharp_ext.props')" />
+  <Import Project="..\packages\grpc.dependencies.openssl.redist.1.0.2.2\build\portable-net45\grpc.dependencies.openssl.redist.props" Condition="Exists('..\packages\grpc.dependencies.openssl.redist.1.0.2.2\build\portable-net45\grpc.dependencies.openssl.redist.props')" />
+  <Import Project="..\packages\grpc.dependencies.zlib.redist.1.2.8.9\build\portable-net45\grpc.dependencies.zlib.redist.props" Condition="Exists('..\packages\grpc.dependencies.zlib.redist.1.2.8.9\build\portable-net45\grpc.dependencies.zlib.redist.props')" />
+  <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <ProjectGuid>{49954D9C-5F17-4662-96B2-73BE833DD81A}</ProjectGuid>
+    <OutputType>Library</OutputType>
+    <AppDesignerFolder>Properties</AppDesignerFolder>
+    <RootNamespace>RouteGuide</RootNamespace>
+    <AssemblyName>RouteGuide</AssemblyName>
+    <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
+    <FileAlignment>512</FileAlignment>
+    <NuGetPackageImportStamp>247686dc</NuGetPackageImportStamp>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+    <DebugSymbols>true</DebugSymbols>
+    <DebugType>full</DebugType>
+    <Optimize>false</Optimize>
+    <OutputPath>bin\Debug\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+    <DebugType>pdbonly</DebugType>
+    <Optimize>true</Optimize>
+    <OutputPath>bin\Release\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+  </PropertyGroup>
+  <ItemGroup>
+    <Reference Include="Google.ProtocolBuffers">
+      <HintPath>..\packages\Google.ProtocolBuffers.2.4.1.555\lib\net40\Google.ProtocolBuffers.dll</HintPath>
+    </Reference>
+    <Reference Include="Google.ProtocolBuffers.Serialization">
+      <HintPath>..\packages\Google.ProtocolBuffers.2.4.1.555\lib\net40\Google.ProtocolBuffers.Serialization.dll</HintPath>
+    </Reference>
+    <Reference Include="Grpc.Core">
+      <HintPath>..\packages\Grpc.Core.0.5.0\lib\net45\Grpc.Core.dll</HintPath>
+    </Reference>
+    <Reference Include="Newtonsoft.Json, Version=7.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\packages\Newtonsoft.Json.7.0.1-beta2\lib\net45\Newtonsoft.Json.dll</HintPath>
+    </Reference>
+    <Reference Include="System" />
+    <Reference Include="System.Collections.Immutable">
+      <HintPath>..\packages\Microsoft.Bcl.Immutable.1.0.34\lib\portable-net45+win8+wp8+wpa81\System.Collections.Immutable.dll</HintPath>
+    </Reference>
+    <Reference Include="System.Core" />
+    <Reference Include="System.Interactive.Async">
+      <HintPath>..\packages\Ix-Async.1.2.3\lib\net45\System.Interactive.Async.dll</HintPath>
+    </Reference>
+    <Reference Include="System.Xml.Linq" />
+    <Reference Include="System.Data.DataSetExtensions" />
+    <Reference Include="Microsoft.CSharp" />
+    <Reference Include="System.Data" />
+    <Reference Include="System.Xml" />
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="Properties\AssemblyInfo.cs" />
+    <Compile Include="RouteGuide.cs" />
+    <Compile Include="RouteGuideGrpc.cs" />
+    <Compile Include="RouteGuideUtil.cs" />
+  </ItemGroup>
+  <ItemGroup>
+    <None Include="packages.config" />
+    <None Include="protos\route_guide.proto" />
+    <None Include="route_guide_db.json">
+      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+    </None>
+  </ItemGroup>
+  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+  <Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
+    <PropertyGroup>
+      <ErrorText>This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them.  For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
+    </PropertyGroup>
+    <Error Condition="!Exists('..\packages\grpc.dependencies.zlib.redist.1.2.8.9\build\portable-net45\grpc.dependencies.zlib.redist.props')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\grpc.dependencies.zlib.redist.1.2.8.9\build\portable-net45\grpc.dependencies.zlib.redist.props'))" />
+    <Error Condition="!Exists('..\packages\grpc.dependencies.zlib.redist.1.2.8.9\build\portable-net45\grpc.dependencies.zlib.redist.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\grpc.dependencies.zlib.redist.1.2.8.9\build\portable-net45\grpc.dependencies.zlib.redist.targets'))" />
+    <Error Condition="!Exists('..\packages\grpc.dependencies.openssl.redist.1.0.2.2\build\portable-net45\grpc.dependencies.openssl.redist.props')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\grpc.dependencies.openssl.redist.1.0.2.2\build\portable-net45\grpc.dependencies.openssl.redist.props'))" />
+    <Error Condition="!Exists('..\packages\grpc.dependencies.openssl.redist.1.0.2.2\build\portable-net45\grpc.dependencies.openssl.redist.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\grpc.dependencies.openssl.redist.1.0.2.2\build\portable-net45\grpc.dependencies.openssl.redist.targets'))" />
+    <Error Condition="!Exists('..\packages\grpc.native.csharp_ext.0.9.0.0\build\portable-net45\grpc.native.csharp_ext.props')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\grpc.native.csharp_ext.0.9.0.0\build\portable-net45\grpc.native.csharp_ext.props'))" />
+    <Error Condition="!Exists('..\packages\grpc.native.csharp_ext.0.9.0.0\build\portable-net45\grpc.native.csharp_ext.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\grpc.native.csharp_ext.0.9.0.0\build\portable-net45\grpc.native.csharp_ext.targets'))" />
+  </Target>
+  <Import Project="..\packages\grpc.dependencies.zlib.redist.1.2.8.9\build\portable-net45\grpc.dependencies.zlib.redist.targets" Condition="Exists('..\packages\grpc.dependencies.zlib.redist.1.2.8.9\build\portable-net45\grpc.dependencies.zlib.redist.targets')" />
+  <Import Project="..\packages\grpc.dependencies.openssl.redist.1.0.2.2\build\portable-net45\grpc.dependencies.openssl.redist.targets" Condition="Exists('..\packages\grpc.dependencies.openssl.redist.1.0.2.2\build\portable-net45\grpc.dependencies.openssl.redist.targets')" />
+  <Import Project="..\packages\grpc.native.csharp_ext.0.9.0.0\build\portable-net45\grpc.native.csharp_ext.targets" Condition="Exists('..\packages\grpc.native.csharp_ext.0.9.0.0\build\portable-net45\grpc.native.csharp_ext.targets')" />
+  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
+       Other similar extension points exist, see Microsoft.Common.targets.
+  <Target Name="BeforeBuild">
+  </Target>
+  <Target Name="AfterBuild">
+  </Target>
+  -->
+</Project>
\ No newline at end of file
diff --git a/csharp/route_guide/RouteGuide/RouteGuideGrpc.cs b/csharp/route_guide/RouteGuide/RouteGuideGrpc.cs
new file mode 100644
index 0000000..c4b3900
--- /dev/null
+++ b/csharp/route_guide/RouteGuide/RouteGuideGrpc.cs
@@ -0,0 +1,123 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: route_guide.proto
+#region Designer generated code
+
+using System;
+using System.Threading;
+using System.Threading.Tasks;
+using Grpc.Core;
+
+namespace examples {
+  public static class RouteGuide
+  {
+    static readonly string __ServiceName = "examples.RouteGuide";
+
+    static readonly Marshaller<global::examples.Point> __Marshaller_Point = Marshallers.Create((arg) => arg.ToByteArray(), global::examples.Point.ParseFrom);
+    static readonly Marshaller<global::examples.Feature> __Marshaller_Feature = Marshallers.Create((arg) => arg.ToByteArray(), global::examples.Feature.ParseFrom);
+    static readonly Marshaller<global::examples.Rectangle> __Marshaller_Rectangle = Marshallers.Create((arg) => arg.ToByteArray(), global::examples.Rectangle.ParseFrom);
+    static readonly Marshaller<global::examples.RouteSummary> __Marshaller_RouteSummary = Marshallers.Create((arg) => arg.ToByteArray(), global::examples.RouteSummary.ParseFrom);
+    static readonly Marshaller<global::examples.RouteNote> __Marshaller_RouteNote = Marshallers.Create((arg) => arg.ToByteArray(), global::examples.RouteNote.ParseFrom);
+
+    static readonly Method<global::examples.Point, global::examples.Feature> __Method_GetFeature = new Method<global::examples.Point, global::examples.Feature>(
+        MethodType.Unary,
+        "GetFeature",
+        __Marshaller_Point,
+        __Marshaller_Feature);
+
+    static readonly Method<global::examples.Rectangle, global::examples.Feature> __Method_ListFeatures = new Method<global::examples.Rectangle, global::examples.Feature>(
+        MethodType.ServerStreaming,
+        "ListFeatures",
+        __Marshaller_Rectangle,
+        __Marshaller_Feature);
+
+    static readonly Method<global::examples.Point, global::examples.RouteSummary> __Method_RecordRoute = new Method<global::examples.Point, global::examples.RouteSummary>(
+        MethodType.ClientStreaming,
+        "RecordRoute",
+        __Marshaller_Point,
+        __Marshaller_RouteSummary);
+
+    static readonly Method<global::examples.RouteNote, global::examples.RouteNote> __Method_RouteChat = new Method<global::examples.RouteNote, global::examples.RouteNote>(
+        MethodType.DuplexStreaming,
+        "RouteChat",
+        __Marshaller_RouteNote,
+        __Marshaller_RouteNote);
+
+    // client-side stub interface
+    public interface IRouteGuideClient
+    {
+      global::examples.Feature GetFeature(global::examples.Point request, CancellationToken token = default(CancellationToken));
+      Task<global::examples.Feature> GetFeatureAsync(global::examples.Point request, CancellationToken token = default(CancellationToken));
+      AsyncServerStreamingCall<global::examples.Feature> ListFeatures(global::examples.Rectangle request, CancellationToken token = default(CancellationToken));
+      AsyncClientStreamingCall<global::examples.Point, global::examples.RouteSummary> RecordRoute(CancellationToken token = default(CancellationToken));
+      AsyncDuplexStreamingCall<global::examples.RouteNote, global::examples.RouteNote> RouteChat(CancellationToken token = default(CancellationToken));
+    }
+
+    // server-side interface
+    public interface IRouteGuide
+    {
+      Task<global::examples.Feature> GetFeature(ServerCallContext context, global::examples.Point request);
+      Task ListFeatures(ServerCallContext context, global::examples.Rectangle request, IServerStreamWriter<global::examples.Feature> responseStream);
+      Task<global::examples.RouteSummary> RecordRoute(ServerCallContext context, IAsyncStreamReader<global::examples.Point> requestStream);
+      Task RouteChat(ServerCallContext context, IAsyncStreamReader<global::examples.RouteNote> requestStream, IServerStreamWriter<global::examples.RouteNote> responseStream);
+    }
+
+    // client stub
+    public class RouteGuideClient : AbstractStub<RouteGuideClient, StubConfiguration>, IRouteGuideClient
+    {
+      public RouteGuideClient(Channel channel) : this(channel, StubConfiguration.Default)
+      {
+      }
+      public RouteGuideClient(Channel channel, StubConfiguration config) : base(channel, config)
+      {
+      }
+      public global::examples.Feature GetFeature(global::examples.Point request, CancellationToken token = default(CancellationToken))
+      {
+        var call = CreateCall(__ServiceName, __Method_GetFeature);
+        return Calls.BlockingUnaryCall(call, request, token);
+      }
+      public Task<global::examples.Feature> GetFeatureAsync(global::examples.Point request, CancellationToken token = default(CancellationToken))
+      {
+        var call = CreateCall(__ServiceName, __Method_GetFeature);
+        return Calls.AsyncUnaryCall(call, request, token);
+      }
+      public AsyncServerStreamingCall<global::examples.Feature> ListFeatures(global::examples.Rectangle request, CancellationToken token = default(CancellationToken))
+      {
+        var call = CreateCall(__ServiceName, __Method_ListFeatures);
+        return Calls.AsyncServerStreamingCall(call, request, token);
+      }
+      public AsyncClientStreamingCall<global::examples.Point, global::examples.RouteSummary> RecordRoute(CancellationToken token = default(CancellationToken))
+      {
+        var call = CreateCall(__ServiceName, __Method_RecordRoute);
+        return Calls.AsyncClientStreamingCall(call, token);
+      }
+      public AsyncDuplexStreamingCall<global::examples.RouteNote, global::examples.RouteNote> RouteChat(CancellationToken token = default(CancellationToken))
+      {
+        var call = CreateCall(__ServiceName, __Method_RouteChat);
+        return Calls.AsyncDuplexStreamingCall(call, token);
+      }
+    }
+
+    // creates service definition that can be registered with a server
+    public static ServerServiceDefinition BindService(IRouteGuide serviceImpl)
+    {
+      return ServerServiceDefinition.CreateBuilder(__ServiceName)
+          .AddMethod(__Method_GetFeature, serviceImpl.GetFeature)
+          .AddMethod(__Method_ListFeatures, serviceImpl.ListFeatures)
+          .AddMethod(__Method_RecordRoute, serviceImpl.RecordRoute)
+          .AddMethod(__Method_RouteChat, serviceImpl.RouteChat).Build();
+    }
+
+    // creates a new client stub
+    public static IRouteGuideClient NewStub(Channel channel)
+    {
+      return new RouteGuideClient(channel);
+    }
+
+    // creates a new client stub
+    public static IRouteGuideClient NewStub(Channel channel, StubConfiguration config)
+    {
+      return new RouteGuideClient(channel, config);
+    }
+  }
+}
+#endregion
diff --git a/csharp/route_guide/RouteGuide/RouteGuideUtil.cs b/csharp/route_guide/RouteGuide/RouteGuideUtil.cs
new file mode 100644
index 0000000..6fb8b1e
--- /dev/null
+++ b/csharp/route_guide/RouteGuide/RouteGuideUtil.cs
@@ -0,0 +1,67 @@
+using Newtonsoft.Json;
+using Newtonsoft.Json.Linq;
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace examples
+{
+    public static class RouteGuideUtil
+    {
+        public const string DefaultFeaturesFile = "route_guide_db.json";
+
+        private const double CoordFactor = 1e7;
+
+        /// <summary>
+        /// Indicates whether the given feature exists (i.e. has a valid name).
+        /// </summary>
+        public static bool Exists(Feature feature)
+        {
+            return feature != null && (feature.Name.Length != 0);
+        }
+
+        public static double GetLatitude(Point point)
+        {
+            return point.Latitude / CoordFactor;
+        }
+
+        public static double GetLongitude(Point point)
+        {
+            return point.Longitude / CoordFactor;
+        }
+
+        /// <summary>
+        /// Parses features from a JSON file.
+        /// </summary>
+        public static List<Feature> ParseFeatures(string filename)
+        {
+            var features = new List<Feature>();
+            var jsonFeatures = JsonConvert.DeserializeObject<List<JsonFeature>>(File.ReadAllText(filename));
+
+
+            foreach(var jsonFeature in jsonFeatures)
+            {
+                features.Add(Feature.CreateBuilder().SetName(jsonFeature.name).SetLocation(
+                    Point.CreateBuilder()
+                        .SetLongitude(jsonFeature.location.longitude)
+                        .SetLatitude(jsonFeature.location.latitude).Build()).Build());
+            }
+            return features;
+        }
+
+        private class JsonFeature
+        {
+            public string name;
+            public JsonLocation location;
+        }
+
+        private class JsonLocation
+        {
+            public int longitude;
+            public int latitude;
+        }
+    }
+}
diff --git a/csharp/route_guide/RouteGuide/packages.config b/csharp/route_guide/RouteGuide/packages.config
new file mode 100644
index 0000000..b3efb8a
--- /dev/null
+++ b/csharp/route_guide/RouteGuide/packages.config
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8"?>
+<packages>
+  <package id="Google.ProtocolBuffers" version="2.4.1.555" targetFramework="net45" />
+  <package id="Grpc" version="0.5.0" targetFramework="net45" />
+  <package id="Grpc.Core" version="0.5.0" targetFramework="net45" />
+  <package id="grpc.dependencies.openssl.redist" version="1.0.2.2" targetFramework="net45" />
+  <package id="grpc.dependencies.zlib.redist" version="1.2.8.9" targetFramework="net45" />
+  <package id="grpc.native.csharp_ext" version="0.9.0.0" targetFramework="net45" />
+  <package id="Ix-Async" version="1.2.3" targetFramework="net45" />
+  <package id="Microsoft.Bcl.Immutable" version="1.0.34" targetFramework="net45" />
+  <package id="Newtonsoft.Json" version="7.0.1-beta2" targetFramework="net45" />
+</packages>
\ No newline at end of file
diff --git a/csharp/route_guide/RouteGuide/protos/route_guide.proto b/csharp/route_guide/RouteGuide/protos/route_guide.proto
new file mode 100644
index 0000000..f4110b5
--- /dev/null
+++ b/csharp/route_guide/RouteGuide/protos/route_guide.proto
@@ -0,0 +1,123 @@
+// Copyright 2015, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// TODO(jtattermusch): as of now, C# protobufs don't officially support
+// proto3.
+syntax = "proto2";
+
+package examples;
+
+// Interface exported by the server.
+service RouteGuide {
+  // A simple RPC.
+  //
+  // Obtains the feature at a given position.
+  //
+  // A feature with an empty name is returned if there's no feature at the given
+  // position.
+  rpc GetFeature(Point) returns (Feature) {}
+
+  // A server-to-client streaming RPC.
+  //
+  // Obtains the Features available within the given Rectangle.  Results are
+  // streamed rather than returned at once (e.g. in a response message with a
+  // repeated field), as the rectangle may cover a large area and contain a
+  // huge number of features.
+  rpc ListFeatures(Rectangle) returns (stream Feature) {}
+
+  // A client-to-server streaming RPC.
+  //
+  // Accepts a stream of Points on a route being traversed, returning a
+  // RouteSummary when traversal is completed.
+  rpc RecordRoute(stream Point) returns (RouteSummary) {}
+
+  // A Bidirectional streaming RPC.
+  //
+  // Accepts a stream of RouteNotes sent while a route is being traversed,
+  // while receiving other RouteNotes (e.g. from other users).
+  rpc RouteChat(stream RouteNote) returns (stream RouteNote) {}
+}
+
+// Points are represented as latitude-longitude pairs in the E7 representation
+// (degrees multiplied by 10**7 and rounded to the nearest integer).
+// Latitudes should be in the range +/- 90 degrees and longitude should be in
+// the range +/- 180 degrees (inclusive).
+message Point {
+  optional int32 latitude = 1;
+  optional int32 longitude = 2;
+}
+
+// A latitude-longitude rectangle, represented as two diagonally opposite
+// points "lo" and "hi".
+message Rectangle {
+  // One corner of the rectangle.
+  optional Point lo = 1;
+
+  // The other corner of the rectangle.
+  optional Point hi = 2;
+}
+
+// A feature names something at a given point.
+//
+// If a feature could not be named, the name is empty.
+message Feature {
+  // The name of the feature.
+  optional string name = 1;
+
+  // The point where the feature is detected.
+  optional Point location = 2;
+}
+
+// A RouteNote is a message sent while at a given point.
+message RouteNote {
+  // The location from which the message is sent.
+  optional Point location = 1;
+
+  // The message to be sent.
+  optional string message = 2;
+}
+
+// A RouteSummary is received in response to a RecordRoute rpc.
+//
+// It contains the number of individual points received, the number of
+// detected features, and the total distance covered as the cumulative sum of
+// the distance between each point.
+message RouteSummary {
+  // The number of points received.
+  optional int32 point_count = 1;
+
+  // The number of known features passed while traversing the route.
+  optional int32 feature_count = 2;
+
+  // The distance covered in metres.
+  optional int32 distance = 3;
+
+  // The duration of the traversal in seconds.
+  optional int32 elapsed_time = 4;
+}
diff --git a/csharp/route_guide/RouteGuide/route_guide_db.json b/csharp/route_guide/RouteGuide/route_guide_db.json
new file mode 100644
index 0000000..209f016
--- /dev/null
+++ b/csharp/route_guide/RouteGuide/route_guide_db.json
@@ -0,0 +1,601 @@
+[{
+    "location": {
+        "latitude": 407838351,
+        "longitude": -746143763
+    },
+    "name": "Patriots Path, Mendham, NJ 07945, USA"
+}, {
+    "location": {
+        "latitude": 408122808,
+        "longitude": -743999179
+    },
+    "name": "101 New Jersey 10, Whippany, NJ 07981, USA"
+}, {
+    "location": {
+        "latitude": 413628156,
+        "longitude": -749015468
+    },
+    "name": "U.S. 6, Shohola, PA 18458, USA"
+}, {
+    "location": {
+        "latitude": 419999544,
+        "longitude": -740371136
+    },
+    "name": "5 Conners Road, Kingston, NY 12401, USA"
+}, {
+    "location": {
+        "latitude": 414008389,
+        "longitude": -743951297
+    },
+    "name": "Mid Hudson Psychiatric Center, New Hampton, NY 10958, USA"
+}, {
+    "location": {
+        "latitude": 419611318,
+        "longitude": -746524769
+    },
+    "name": "287 Flugertown Road, Livingston Manor, NY 12758, USA"
+}, {
+    "location": {
+        "latitude": 406109563,
+        "longitude": -742186778
+    },
+    "name": "4001 Tremley Point Road, Linden, NJ 07036, USA"
+}, {
+    "location": {
+        "latitude": 416802456,
+        "longitude": -742370183
+    },
+    "name": "352 South Mountain Road, Wallkill, NY 12589, USA"
+}, {
+    "location": {
+        "latitude": 412950425,
+        "longitude": -741077389
+    },
+    "name": "Bailey Turn Road, Harriman, NY 10926, USA"
+}, {
+    "location": {
+        "latitude": 412144655,
+        "longitude": -743949739
+    },
+    "name": "193-199 Wawayanda Road, Hewitt, NJ 07421, USA"
+}, {
+    "location": {
+        "latitude": 415736605,
+        "longitude": -742847522
+    },
+    "name": "406-496 Ward Avenue, Pine Bush, NY 12566, USA"
+}, {
+    "location": {
+        "latitude": 413843930,
+        "longitude": -740501726
+    },
+    "name": "162 Merrill Road, Highland Mills, NY 10930, USA"
+}, {
+    "location": {
+        "latitude": 410873075,
+        "longitude": -744459023
+    },
+    "name": "Clinton Road, West Milford, NJ 07480, USA"
+}, {
+    "location": {
+        "latitude": 412346009,
+        "longitude": -744026814
+    },
+    "name": "16 Old Brook Lane, Warwick, NY 10990, USA"
+}, {
+    "location": {
+        "latitude": 402948455,
+        "longitude": -747903913
+    },
+    "name": "3 Drake Lane, Pennington, NJ 08534, USA"
+}, {
+    "location": {
+        "latitude": 406337092,
+        "longitude": -740122226
+    },
+    "name": "6324 8th Avenue, Brooklyn, NY 11220, USA"
+}, {
+    "location": {
+        "latitude": 406421967,
+        "longitude": -747727624
+    },
+    "name": "1 Merck Access Road, Whitehouse Station, NJ 08889, USA"
+}, {
+    "location": {
+        "latitude": 416318082,
+        "longitude": -749677716
+    },
+    "name": "78-98 Schalck Road, Narrowsburg, NY 12764, USA"
+}, {
+    "location": {
+        "latitude": 415301720,
+        "longitude": -748416257
+    },
+    "name": "282 Lakeview Drive Road, Highland Lake, NY 12743, USA"
+}, {
+    "location": {
+        "latitude": 402647019,
+        "longitude": -747071791
+    },
+    "name": "330 Evelyn Avenue, Hamilton Township, NJ 08619, USA"
+}, {
+    "location": {
+        "latitude": 412567807,
+        "longitude": -741058078
+    },
+    "name": "New York State Reference Route 987E, Southfields, NY 10975, USA"
+}, {
+    "location": {
+        "latitude": 416855156,
+        "longitude": -744420597
+    },
+    "name": "103-271 Tempaloni Road, Ellenville, NY 12428, USA"
+}, {
+    "location": {
+        "latitude": 404663628,
+        "longitude": -744820157
+    },
+    "name": "1300 Airport Road, North Brunswick Township, NJ 08902, USA"
+}, {
+    "location": {
+        "latitude": 407113723,
+        "longitude": -749746483
+    },
+    "name": ""
+}, {
+    "location": {
+        "latitude": 402133926,
+        "longitude": -743613249
+    },
+    "name": ""
+}, {
+    "location": {
+        "latitude": 400273442,
+        "longitude": -741220915
+    },
+    "name": ""
+}, {
+    "location": {
+        "latitude": 411236786,
+        "longitude": -744070769
+    },
+    "name": ""
+}, {
+    "location": {
+        "latitude": 411633782,
+        "longitude": -746784970
+    },
+    "name": "211-225 Plains Road, Augusta, NJ 07822, USA"
+}, {
+    "location": {
+        "latitude": 415830701,
+        "longitude": -742952812
+    },
+    "name": ""
+}, {
+    "location": {
+        "latitude": 413447164,
+        "longitude": -748712898
+    },
+    "name": "165 Pedersen Ridge Road, Milford, PA 18337, USA"
+}, {
+    "location": {
+        "latitude": 405047245,
+        "longitude": -749800722
+    },
+    "name": "100-122 Locktown Road, Frenchtown, NJ 08825, USA"
+}, {
+    "location": {
+        "latitude": 418858923,
+        "longitude": -746156790
+    },
+    "name": ""
+}, {
+    "location": {
+        "latitude": 417951888,
+        "longitude": -748484944
+    },
+    "name": "650-652 Willi Hill Road, Swan Lake, NY 12783, USA"
+}, {
+    "location": {
+        "latitude": 407033786,
+        "longitude": -743977337
+    },
+    "name": "26 East 3rd Street, New Providence, NJ 07974, USA"
+}, {
+    "location": {
+        "latitude": 417548014,
+        "longitude": -740075041
+    },
+    "name": ""
+}, {
+    "location": {
+        "latitude": 410395868,
+        "longitude": -744972325
+    },
+    "name": ""
+}, {
+    "location": {
+        "latitude": 404615353,
+        "longitude": -745129803
+    },
+    "name": ""
+}, {
+    "location": {
+        "latitude": 406589790,
+        "longitude": -743560121
+    },
+    "name": "611 Lawrence Avenue, Westfield, NJ 07090, USA"
+}, {
+    "location": {
+        "latitude": 414653148,
+        "longitude": -740477477
+    },
+    "name": "18 Lannis Avenue, New Windsor, NY 12553, USA"
+}, {
+    "location": {
+        "latitude": 405957808,
+        "longitude": -743255336
+    },
+    "name": "82-104 Amherst Avenue, Colonia, NJ 07067, USA"
+}, {
+    "location": {
+        "latitude": 411733589,
+        "longitude": -741648093
+    },
+    "name": "170 Seven Lakes Drive, Sloatsburg, NY 10974, USA"
+}, {
+    "location": {
+        "latitude": 412676291,
+        "longitude": -742606606
+    },
+    "name": "1270 Lakes Road, Monroe, NY 10950, USA"
+}, {
+    "location": {
+        "latitude": 409224445,
+        "longitude": -748286738
+    },
+    "name": "509-535 Alphano Road, Great Meadows, NJ 07838, USA"
+}, {
+    "location": {
+        "latitude": 406523420,
+        "longitude": -742135517
+    },
+    "name": "652 Garden Street, Elizabeth, NJ 07202, USA"
+}, {
+    "location": {
+        "latitude": 401827388,
+        "longitude": -740294537
+    },
+    "name": "349 Sea Spray Court, Neptune City, NJ 07753, USA"
+}, {
+    "location": {
+        "latitude": 410564152,
+        "longitude": -743685054
+    },
+    "name": "13-17 Stanley Street, West Milford, NJ 07480, USA"
+}, {
+    "location": {
+        "latitude": 408472324,
+        "longitude": -740726046
+    },
+    "name": "47 Industrial Avenue, Teterboro, NJ 07608, USA"
+}, {
+    "location": {
+        "latitude": 412452168,
+        "longitude": -740214052
+    },
+    "name": "5 White Oak Lane, Stony Point, NY 10980, USA"
+}, {
+    "location": {
+        "latitude": 409146138,
+        "longitude": -746188906
+    },
+    "name": "Berkshire Valley Management Area Trail, Jefferson, NJ, USA"
+}, {
+    "location": {
+        "latitude": 404701380,
+        "longitude": -744781745
+    },
+    "name": "1007 Jersey Avenue, New Brunswick, NJ 08901, USA"
+}, {
+    "location": {
+        "latitude": 409642566,
+        "longitude": -746017679
+    },
+    "name": "6 East Emerald Isle Drive, Lake Hopatcong, NJ 07849, USA"
+}, {
+    "location": {
+        "latitude": 408031728,
+        "longitude": -748645385
+    },
+    "name": "1358-1474 New Jersey 57, Port Murray, NJ 07865, USA"
+}, {
+    "location": {
+        "latitude": 413700272,
+        "longitude": -742135189
+    },
+    "name": "367 Prospect Road, Chester, NY 10918, USA"
+}, {
+    "location": {
+        "latitude": 404310607,
+        "longitude": -740282632
+    },
+    "name": "10 Simon Lake Drive, Atlantic Highlands, NJ 07716, USA"
+}, {
+    "location": {
+        "latitude": 409319800,
+        "longitude": -746201391
+    },
+    "name": "11 Ward Street, Mount Arlington, NJ 07856, USA"
+}, {
+    "location": {
+        "latitude": 406685311,
+        "longitude": -742108603
+    },
+    "name": "300-398 Jefferson Avenue, Elizabeth, NJ 07201, USA"
+}, {
+    "location": {
+        "latitude": 419018117,
+        "longitude": -749142781
+    },
+    "name": "43 Dreher Road, Roscoe, NY 12776, USA"
+}, {
+    "location": {
+        "latitude": 412856162,
+        "longitude": -745148837
+    },
+    "name": "Swan Street, Pine Island, NY 10969, USA"
+}, {
+    "location": {
+        "latitude": 416560744,
+        "longitude": -746721964
+    },
+    "name": "66 Pleasantview Avenue, Monticello, NY 12701, USA"
+}, {
+    "location": {
+        "latitude": 405314270,
+        "longitude": -749836354
+    },
+    "name": ""
+}, {
+    "location": {
+        "latitude": 414219548,
+        "longitude": -743327440
+    },
+    "name": ""
+}, {
+    "location": {
+        "latitude": 415534177,
+        "longitude": -742900616
+    },
+    "name": "565 Winding Hills Road, Montgomery, NY 12549, USA"
+}, {
+    "location": {
+        "latitude": 406898530,
+        "longitude": -749127080
+    },
+    "name": "231 Rocky Run Road, Glen Gardner, NJ 08826, USA"
+}, {
+    "location": {
+        "latitude": 407586880,
+        "longitude": -741670168
+    },
+    "name": "100 Mount Pleasant Avenue, Newark, NJ 07104, USA"
+}, {
+    "location": {
+        "latitude": 400106455,
+        "longitude": -742870190
+    },
+    "name": "517-521 Huntington Drive, Manchester Township, NJ 08759, USA"
+}, {
+    "location": {
+        "latitude": 400066188,
+        "longitude": -746793294
+    },
+    "name": ""
+}, {
+    "location": {
+        "latitude": 418803880,
+        "longitude": -744102673
+    },
+    "name": "40 Mountain Road, Napanoch, NY 12458, USA"
+}, {
+    "location": {
+        "latitude": 414204288,
+        "longitude": -747895140
+    },
+    "name": ""
+}, {
+    "location": {
+        "latitude": 414777405,
+        "longitude": -740615601
+    },
+    "name": ""
+}, {
+    "location": {
+        "latitude": 415464475,
+        "longitude": -747175374
+    },
+    "name": "48 North Road, Forestburgh, NY 12777, USA"
+}, {
+    "location": {
+        "latitude": 404062378,
+        "longitude": -746376177
+    },
+    "name": ""
+}, {
+    "location": {
+        "latitude": 405688272,
+        "longitude": -749285130
+    },
+    "name": ""
+}, {
+    "location": {
+        "latitude": 400342070,
+        "longitude": -748788996
+    },
+    "name": ""
+}, {
+    "location": {
+        "latitude": 401809022,
+        "longitude": -744157964
+    },
+    "name": ""
+}, {
+    "location": {
+        "latitude": 404226644,
+        "longitude": -740517141
+    },
+    "name": "9 Thompson Avenue, Leonardo, NJ 07737, USA"
+}, {
+    "location": {
+        "latitude": 410322033,
+        "longitude": -747871659
+    },
+    "name": ""
+}, {
+    "location": {
+        "latitude": 407100674,
+        "longitude": -747742727
+    },
+    "name": ""
+}, {
+    "location": {
+        "latitude": 418811433,
+        "longitude": -741718005
+    },
+    "name": "213 Bush Road, Stone Ridge, NY 12484, USA"
+}, {
+    "location": {
+        "latitude": 415034302,
+        "longitude": -743850945
+    },
+    "name": ""
+}, {
+    "location": {
+        "latitude": 411349992,
+        "longitude": -743694161
+    },
+    "name": ""
+}, {
+    "location": {
+        "latitude": 404839914,
+        "longitude": -744759616
+    },
+    "name": "1-17 Bergen Court, New Brunswick, NJ 08901, USA"
+}, {
+    "location": {
+        "latitude": 414638017,
+        "longitude": -745957854
+    },
+    "name": "35 Oakland Valley Road, Cuddebackville, NY 12729, USA"
+}, {
+    "location": {
+        "latitude": 412127800,
+        "longitude": -740173578
+    },
+    "name": ""
+}, {
+    "location": {
+        "latitude": 401263460,
+        "longitude": -747964303
+    },
+    "name": ""
+}, {
+    "location": {
+        "latitude": 412843391,
+        "longitude": -749086026
+    },
+    "name": ""
+}, {
+    "location": {
+        "latitude": 418512773,
+        "longitude": -743067823
+    },
+    "name": ""
+}, {
+    "location": {
+        "latitude": 404318328,
+        "longitude": -740835638
+    },
+    "name": "42-102 Main Street, Belford, NJ 07718, USA"
+}, {
+    "location": {
+        "latitude": 419020746,
+        "longitude": -741172328
+    },
+    "name": ""
+}, {
+    "location": {
+        "latitude": 404080723,
+        "longitude": -746119569
+    },
+    "name": ""
+}, {
+    "location": {
+        "latitude": 401012643,
+        "longitude": -744035134
+    },
+    "name": ""
+}, {
+    "location": {
+        "latitude": 404306372,
+        "longitude": -741079661
+    },
+    "name": ""
+}, {
+    "location": {
+        "latitude": 403966326,
+        "longitude": -748519297
+    },
+    "name": ""
+}, {
+    "location": {
+        "latitude": 405002031,
+        "longitude": -748407866
+    },
+    "name": ""
+}, {
+    "location": {
+        "latitude": 409532885,
+        "longitude": -742200683
+    },
+    "name": ""
+}, {
+    "location": {
+        "latitude": 416851321,
+        "longitude": -742674555
+    },
+    "name": ""
+}, {
+    "location": {
+        "latitude": 406411633,
+        "longitude": -741722051
+    },
+    "name": "3387 Richmond Terrace, Staten Island, NY 10303, USA"
+}, {
+    "location": {
+        "latitude": 413069058,
+        "longitude": -744597778
+    },
+    "name": "261 Van Sickle Road, Goshen, NY 10924, USA"
+}, {
+    "location": {
+        "latitude": 418465462,
+        "longitude": -746859398
+    },
+    "name": ""
+}, {
+    "location": {
+        "latitude": 411733222,
+        "longitude": -744228360
+    },
+    "name": ""
+}, {
+    "location": {
+        "latitude": 410248224,
+        "longitude": -747127767
+    },
+    "name": "3 Hasta Way, Newton, NJ 07860, USA"
+}]
\ No newline at end of file
diff --git a/csharp/route_guide/RouteGuideClient/App.config b/csharp/route_guide/RouteGuideClient/App.config
new file mode 100644
index 0000000..8e15646
--- /dev/null
+++ b/csharp/route_guide/RouteGuideClient/App.config
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<configuration>
+    <startup> 
+        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
+    </startup>
+</configuration>
\ No newline at end of file
diff --git a/csharp/route_guide/RouteGuideClient/Program.cs b/csharp/route_guide/RouteGuideClient/Program.cs
new file mode 100644
index 0000000..0352c78
--- /dev/null
+++ b/csharp/route_guide/RouteGuideClient/Program.cs
@@ -0,0 +1,223 @@
+using Grpc.Core;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace examples
+{
+    class Program
+    {
+        /// <summary>
+        /// Sample client code that makes gRPC calls to the server.
+        /// </summary>
+        public class RouteGuideClient
+        {
+            readonly RouteGuide.IRouteGuideClient client;
+
+            public RouteGuideClient(RouteGuide.IRouteGuideClient client)
+            {
+                this.client = client;
+            }
+
+            /// <summary>
+            /// Blocking unary call example.  Calls GetFeature and prints the response.
+            /// </summary>
+            public void GetFeature(int lat, int lon)
+            {
+                try
+                {
+                    Log("*** GetFeature: lat={0} lon={1}", lat, lon);
+
+                    Point request = Point.CreateBuilder().SetLatitude(lat).SetLongitude(lon).Build();
+                    
+                    Feature feature = client.GetFeature(request);
+                    if (RouteGuideUtil.Exists(feature))
+                    {
+                        Log("Found feature called \"{0}\" at {1}, {2}",
+                            feature.Name,
+                            RouteGuideUtil.GetLatitude(feature.Location),
+                            RouteGuideUtil.GetLongitude(feature.Location));
+                    }
+                    else
+                    {
+                        Log("Found no feature at {0}, {1}",
+                            RouteGuideUtil.GetLatitude(feature.Location),
+                            RouteGuideUtil.GetLongitude(feature.Location));
+                    }
+                }
+                catch (RpcException e)
+                {
+                    Log("RPC failed " + e);
+                    throw e;
+                }
+            }
+
+  
+            /// <summary>
+            /// Server-streaming example. Calls listFeatures with a rectangle of interest. Prints each response feature as it arrives.
+            /// </summary>
+            public async Task ListFeatures(int lowLat, int lowLon, int hiLat, int hiLon)
+            {
+                try
+                {
+                    Log("*** ListFeatures: lowLat={0} lowLon={1} hiLat={2} hiLon={3}", lowLat, lowLon, hiLat,
+                        hiLon);
+
+                    Rectangle request =
+                        Rectangle.CreateBuilder()
+                            .SetLo(Point.CreateBuilder().SetLatitude(lowLat).SetLongitude(lowLon).Build())
+                            .SetHi(Point.CreateBuilder().SetLatitude(hiLat).SetLongitude(hiLon).Build()).Build();
+                    
+                    using (var call = client.ListFeatures(request))
+                    {
+                        StringBuilder responseLog = new StringBuilder("Result: ");
+
+                        while (await call.ResponseStream.MoveNext())
+                        {
+                            Feature feature = call.ResponseStream.Current;
+                            responseLog.Append(feature.ToString());
+                        }
+                        Log(responseLog.ToString());
+                    }
+                }
+                catch (RpcException e)
+                {
+                    Log("RPC failed " + e); 
+                    throw e;
+                }
+            }
+
+            /// <summary>
+            /// Client-streaming example. Sends numPoints randomly chosen points from features 
+            /// with a variable delay in between. Prints the statistics when they are sent from the server.
+            /// </summary>
+            public async Task RecordRoute(List<Feature> features, int numPoints)
+            {
+                try
+                {
+                    Log("*** RecordRoute");
+                    using (var call = client.RecordRoute())
+                    {
+                        // Send numPoints points randomly selected from the features list.
+                        StringBuilder numMsg = new StringBuilder();
+                        Random rand = new Random();
+                        for (int i = 0; i < numPoints; ++i)
+                        {
+                            int index = rand.Next(features.Count);
+                            Point point = features[index].Location;
+                            Log("Visiting point {0}, {1}", RouteGuideUtil.GetLatitude(point),
+                                RouteGuideUtil.GetLongitude(point));
+
+                            await call.RequestStream.WriteAsync(point);
+
+                            // A bit of delay before sending the next one.
+                            await Task.Delay(rand.Next(1000) + 500);    
+                        }
+                        await call.RequestStream.CompleteAsync();
+
+                        RouteSummary summary = await call.Result;
+                        Log("Finished trip with {0} points. Passed {1} features. "
+                            + "Travelled {2} meters. It took {3} seconds.", summary.PointCount,
+                            summary.FeatureCount, summary.Distance, summary.ElapsedTime);
+
+                        Log("Finished RecordRoute");
+                    }
+                }
+                catch (RpcException e)
+                {
+                    Log("RPC failed", e);
+                    throw e;
+                }
+            }
+
+            /// <summary>
+            /// Bi-directional streaming example. Send some chat messages, and print any
+            /// chat messages that are sent from the server.
+            /// </summary>
+            public async Task RouteChat()
+            {
+                try
+                {
+                    Log("*** RouteChat");
+                    var requests =
+                        new List<RouteNote> { NewNote("First message", 0, 0), NewNote("Second message", 0, 1), NewNote("Third message", 1, 0), NewNote("Fourth message", 1, 1) };
+
+                    using (var call = client.RouteChat())
+                    {
+                        var responseReaderTask = Task.Run(async () =>
+                        {
+                            while (await call.ResponseStream.MoveNext())
+                            {
+                                var note = call.ResponseStream.Current;
+                                Log("Got message \"{0}\" at {1}, {2}", note.Message, 
+                                    note.Location.Latitude, note.Location.Longitude);
+                            }
+                        });
+
+                        foreach (RouteNote request in requests)
+                        {
+                            Log("Sending message \"{0}\" at {1}, {2}", request.Message,
+                                request.Location.Latitude, request.Location.Longitude);
+
+                            await call.RequestStream.WriteAsync(request);
+                        }
+                        await call.RequestStream.CompleteAsync();
+                        await responseReaderTask;
+
+                        Log("Finished RouteChat");
+                    }
+                }
+                catch (RpcException e)
+                {
+                    Log("RPC failed", e);
+                    throw e;
+                }
+            }
+
+            private void Log(string s, params object[] args)
+            {
+                Console.WriteLine(string.Format(s, args));
+            }
+
+            private void Log(string s)
+            {
+                Console.WriteLine(s);
+            }
+
+            private RouteNote NewNote(string message, int lat, int lon)
+            {
+                return RouteNote.CreateBuilder().SetMessage(message).SetLocation(
+                    Point.CreateBuilder().SetLatitude(lat).SetLongitude(lat).Build()).Build();
+            }
+        }
+
+        static void Main(string[] args)
+        {
+            GrpcEnvironment.Initialize();
+
+            using (Channel channel = new Channel("127.0.0.1:50052"))
+            {
+                var client = new RouteGuideClient(RouteGuide.NewStub(channel));
+
+                // Looking for a valid feature
+                client.GetFeature(409146138, -746188906);
+
+                // Feature missing.
+                client.GetFeature(0, 0);
+
+                // Looking for features between 40, -75 and 42, -73.
+                client.ListFeatures(400000000, -750000000, 420000000, -730000000).Wait();
+
+                // Record a few randomly selected points from the features file.
+                client.RecordRoute(RouteGuideUtil.ParseFeatures(RouteGuideUtil.DefaultFeaturesFile), 10).Wait();
+
+                // Send and receive some notes.
+                client.RouteChat().Wait();
+            }
+
+            GrpcEnvironment.Shutdown();
+        }
+    }
+}
diff --git a/csharp/route_guide/RouteGuideClient/Properties/AssemblyInfo.cs b/csharp/route_guide/RouteGuideClient/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..a17e164
--- /dev/null
+++ b/csharp/route_guide/RouteGuideClient/Properties/AssemblyInfo.cs
@@ -0,0 +1,36 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following 
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("RouteGuideClient")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("RouteGuideClient")]
+[assembly: AssemblyCopyright("Copyright ©  2015")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible 
+// to COM components.  If you need to access a type in this assembly from 
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("914644eb-47cd-4a37-9fba-5e62dd432333")]
+
+// Version information for an assembly consists of the following four values:
+//
+//      Major Version
+//      Minor Version 
+//      Build Number
+//      Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers 
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/csharp/route_guide/RouteGuideClient/RouteGuideClient.csproj b/csharp/route_guide/RouteGuideClient/RouteGuideClient.csproj
new file mode 100644
index 0000000..988db6a
--- /dev/null
+++ b/csharp/route_guide/RouteGuideClient/RouteGuideClient.csproj
@@ -0,0 +1,98 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <Import Project="..\packages\grpc.native.csharp_ext.0.9.0.0\build\portable-net45\grpc.native.csharp_ext.props" Condition="Exists('..\packages\grpc.native.csharp_ext.0.9.0.0\build\portable-net45\grpc.native.csharp_ext.props')" />
+  <Import Project="..\packages\grpc.dependencies.openssl.redist.1.0.2.2\build\portable-net45\grpc.dependencies.openssl.redist.props" Condition="Exists('..\packages\grpc.dependencies.openssl.redist.1.0.2.2\build\portable-net45\grpc.dependencies.openssl.redist.props')" />
+  <Import Project="..\packages\grpc.dependencies.zlib.redist.1.2.8.9\build\portable-net45\grpc.dependencies.zlib.redist.props" Condition="Exists('..\packages\grpc.dependencies.zlib.redist.1.2.8.9\build\portable-net45\grpc.dependencies.zlib.redist.props')" />
+  <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <ProjectGuid>{D47BE663-4DE3-4206-B7A8-EA3FA066DADC}</ProjectGuid>
+    <OutputType>Exe</OutputType>
+    <AppDesignerFolder>Properties</AppDesignerFolder>
+    <RootNamespace>RouteGuideClient</RootNamespace>
+    <AssemblyName>RouteGuideClient</AssemblyName>
+    <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
+    <FileAlignment>512</FileAlignment>
+    <NuGetPackageImportStamp>c0fbb9f1</NuGetPackageImportStamp>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+    <PlatformTarget>AnyCPU</PlatformTarget>
+    <DebugSymbols>true</DebugSymbols>
+    <DebugType>full</DebugType>
+    <Optimize>false</Optimize>
+    <OutputPath>bin\Debug\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+    <PlatformTarget>AnyCPU</PlatformTarget>
+    <DebugType>pdbonly</DebugType>
+    <Optimize>true</Optimize>
+    <OutputPath>bin\Release\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+  </PropertyGroup>
+  <ItemGroup>
+    <Reference Include="Google.ProtocolBuffers">
+      <HintPath>..\packages\Google.ProtocolBuffers.2.4.1.555\lib\net40\Google.ProtocolBuffers.dll</HintPath>
+    </Reference>
+    <Reference Include="Google.ProtocolBuffers.Serialization">
+      <HintPath>..\packages\Google.ProtocolBuffers.2.4.1.555\lib\net40\Google.ProtocolBuffers.Serialization.dll</HintPath>
+    </Reference>
+    <Reference Include="Grpc.Core">
+      <HintPath>..\packages\Grpc.Core.0.5.0\lib\net45\Grpc.Core.dll</HintPath>
+    </Reference>
+    <Reference Include="System" />
+    <Reference Include="System.Collections.Immutable">
+      <HintPath>..\packages\Microsoft.Bcl.Immutable.1.0.34\lib\portable-net45+win8+wp8+wpa81\System.Collections.Immutable.dll</HintPath>
+    </Reference>
+    <Reference Include="System.Core" />
+    <Reference Include="System.Interactive.Async">
+      <HintPath>..\packages\Ix-Async.1.2.3\lib\net45\System.Interactive.Async.dll</HintPath>
+    </Reference>
+    <Reference Include="System.Xml.Linq" />
+    <Reference Include="System.Data.DataSetExtensions" />
+    <Reference Include="Microsoft.CSharp" />
+    <Reference Include="System.Data" />
+    <Reference Include="System.Xml" />
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="Program.cs" />
+    <Compile Include="Properties\AssemblyInfo.cs" />
+  </ItemGroup>
+  <ItemGroup>
+    <None Include="App.config" />
+    <None Include="packages.config" />
+  </ItemGroup>
+  <ItemGroup>
+    <ProjectReference Include="..\RouteGuide\RouteGuide.csproj">
+      <Project>{49954d9c-5f17-4662-96b2-73be833dd81a}</Project>
+      <Name>RouteGuide</Name>
+    </ProjectReference>
+  </ItemGroup>
+  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+  <Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
+    <PropertyGroup>
+      <ErrorText>This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them.  For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
+    </PropertyGroup>
+    <Error Condition="!Exists('..\packages\grpc.dependencies.zlib.redist.1.2.8.9\build\portable-net45\grpc.dependencies.zlib.redist.props')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\grpc.dependencies.zlib.redist.1.2.8.9\build\portable-net45\grpc.dependencies.zlib.redist.props'))" />
+    <Error Condition="!Exists('..\packages\grpc.dependencies.zlib.redist.1.2.8.9\build\portable-net45\grpc.dependencies.zlib.redist.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\grpc.dependencies.zlib.redist.1.2.8.9\build\portable-net45\grpc.dependencies.zlib.redist.targets'))" />
+    <Error Condition="!Exists('..\packages\grpc.dependencies.openssl.redist.1.0.2.2\build\portable-net45\grpc.dependencies.openssl.redist.props')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\grpc.dependencies.openssl.redist.1.0.2.2\build\portable-net45\grpc.dependencies.openssl.redist.props'))" />
+    <Error Condition="!Exists('..\packages\grpc.dependencies.openssl.redist.1.0.2.2\build\portable-net45\grpc.dependencies.openssl.redist.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\grpc.dependencies.openssl.redist.1.0.2.2\build\portable-net45\grpc.dependencies.openssl.redist.targets'))" />
+    <Error Condition="!Exists('..\packages\grpc.native.csharp_ext.0.9.0.0\build\portable-net45\grpc.native.csharp_ext.props')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\grpc.native.csharp_ext.0.9.0.0\build\portable-net45\grpc.native.csharp_ext.props'))" />
+    <Error Condition="!Exists('..\packages\grpc.native.csharp_ext.0.9.0.0\build\portable-net45\grpc.native.csharp_ext.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\grpc.native.csharp_ext.0.9.0.0\build\portable-net45\grpc.native.csharp_ext.targets'))" />
+  </Target>
+  <Import Project="..\packages\grpc.dependencies.zlib.redist.1.2.8.9\build\portable-net45\grpc.dependencies.zlib.redist.targets" Condition="Exists('..\packages\grpc.dependencies.zlib.redist.1.2.8.9\build\portable-net45\grpc.dependencies.zlib.redist.targets')" />
+  <Import Project="..\packages\grpc.dependencies.openssl.redist.1.0.2.2\build\portable-net45\grpc.dependencies.openssl.redist.targets" Condition="Exists('..\packages\grpc.dependencies.openssl.redist.1.0.2.2\build\portable-net45\grpc.dependencies.openssl.redist.targets')" />
+  <Import Project="..\packages\grpc.native.csharp_ext.0.9.0.0\build\portable-net45\grpc.native.csharp_ext.targets" Condition="Exists('..\packages\grpc.native.csharp_ext.0.9.0.0\build\portable-net45\grpc.native.csharp_ext.targets')" />
+  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
+       Other similar extension points exist, see Microsoft.Common.targets.
+  <Target Name="BeforeBuild">
+  </Target>
+  <Target Name="AfterBuild">
+  </Target>
+  -->
+</Project>
\ No newline at end of file
diff --git a/csharp/route_guide/RouteGuideClient/packages.config b/csharp/route_guide/RouteGuideClient/packages.config
new file mode 100644
index 0000000..b1f8c69
--- /dev/null
+++ b/csharp/route_guide/RouteGuideClient/packages.config
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="utf-8"?>
+<packages>
+  <package id="Google.ProtocolBuffers" version="2.4.1.555" targetFramework="net45" />
+  <package id="Grpc" version="0.5.0" targetFramework="net45" />
+  <package id="Grpc.Core" version="0.5.0" targetFramework="net45" />
+  <package id="grpc.dependencies.openssl.redist" version="1.0.2.2" targetFramework="net45" />
+  <package id="grpc.dependencies.zlib.redist" version="1.2.8.9" targetFramework="net45" />
+  <package id="grpc.native.csharp_ext" version="0.9.0.0" targetFramework="net45" />
+  <package id="Ix-Async" version="1.2.3" targetFramework="net45" />
+  <package id="Microsoft.Bcl.Immutable" version="1.0.34" targetFramework="net45" />
+</packages>
\ No newline at end of file
diff --git a/csharp/route_guide/RouteGuideServer/App.config b/csharp/route_guide/RouteGuideServer/App.config
new file mode 100644
index 0000000..8e15646
--- /dev/null
+++ b/csharp/route_guide/RouteGuideServer/App.config
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<configuration>
+    <startup> 
+        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
+    </startup>
+</configuration>
\ No newline at end of file
diff --git a/csharp/route_guide/RouteGuideServer/Program.cs b/csharp/route_guide/RouteGuideServer/Program.cs
new file mode 100644
index 0000000..e00b4d6
--- /dev/null
+++ b/csharp/route_guide/RouteGuideServer/Program.cs
@@ -0,0 +1,30 @@
+using Grpc.Core;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace examples
+{
+    class Program
+    {
+        static void Main(string[] args)
+        {
+            var features = RouteGuideUtil.ParseFeatures(RouteGuideUtil.DefaultFeaturesFile);
+            GrpcEnvironment.Initialize();
+
+            Server server = new Server();
+            server.AddServiceDefinition(RouteGuide.BindService(new RouteGuideImpl(features)));
+            int port = server.AddListeningPort("localhost", 50052);
+            server.Start();
+
+            Console.WriteLine("RouteGuide server listening on port " + port);
+            Console.WriteLine("Press any key to stop the server...");
+            Console.ReadKey();
+
+            server.ShutdownAsync().Wait();
+            GrpcEnvironment.Shutdown();
+        }
+    }
+}
diff --git a/csharp/route_guide/RouteGuideServer/Properties/AssemblyInfo.cs b/csharp/route_guide/RouteGuideServer/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..a161b1d
--- /dev/null
+++ b/csharp/route_guide/RouteGuideServer/Properties/AssemblyInfo.cs
@@ -0,0 +1,36 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following 
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("RouteGuideServer")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("RouteGuideServer")]
+[assembly: AssemblyCopyright("Copyright ©  2015")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible 
+// to COM components.  If you need to access a type in this assembly from 
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("908bdeef-05cc-42bf-9498-c4c573df8925")]
+
+// Version information for an assembly consists of the following four values:
+//
+//      Major Version
+//      Minor Version 
+//      Build Number
+//      Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers 
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/csharp/route_guide/RouteGuideServer/RouteGuideImpl.cs b/csharp/route_guide/RouteGuideServer/RouteGuideImpl.cs
new file mode 100644
index 0000000..0bdf386
--- /dev/null
+++ b/csharp/route_guide/RouteGuideServer/RouteGuideImpl.cs
@@ -0,0 +1,184 @@
+using System;
+using System.Collections.Concurrent;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace examples
+{
+    /// <summary>
+    /// Example implementation of RouteGuide server.
+    /// </summary>
+    public class RouteGuideImpl : RouteGuide.IRouteGuide
+    {
+        readonly List<Feature> features;
+        private readonly ConcurrentDictionary<Point, List<RouteNote>> routeNotes =
+            new ConcurrentDictionary<Point, List<RouteNote>>();
+
+        public RouteGuideImpl(List<Feature> features)
+        {
+            this.features = features;
+        }
+
+        /// <summary>
+        /// Gets the feature at the requested point. If no feature at that location
+        /// exists, an unnammed feature is returned at the provided location.
+        /// </summary>
+        public Task<Feature> GetFeature(Grpc.Core.ServerCallContext context, Point request)
+        {
+            return Task.FromResult(CheckFeature(request));
+        }
+
+        /// <summary>
+        /// Gets all features contained within the given bounding rectangle.
+        /// </summary>
+        public async Task ListFeatures(Grpc.Core.ServerCallContext context, Rectangle request, Grpc.Core.IServerStreamWriter<Feature> responseStream)
+        {
+            int left = Math.Min(request.Lo.Longitude, request.Hi.Longitude);
+            int right = Math.Max(request.Lo.Longitude, request.Hi.Longitude);
+            int top = Math.Max(request.Lo.Latitude, request.Hi.Latitude);
+            int bottom = Math.Min(request.Lo.Latitude, request.Hi.Latitude);
+
+            foreach (var feature in features)
+            {
+                if (!RouteGuideUtil.Exists(feature))
+                {
+                    continue;
+                }
+
+                int lat = feature.Location.Latitude;
+                int lon = feature.Location.Longitude;
+                if (lon >= left && lon <= right && lat >= bottom && lat <= top)
+                {
+                    await responseStream.WriteAsync(feature);
+                }
+            }
+        }
+
+        /// <summary>
+        /// Gets a stream of points, and responds with statistics about the "trip": number of points,
+        /// number of known features visited, total distance traveled, and total time spent.
+        /// </summary>
+        public async Task<RouteSummary> RecordRoute(Grpc.Core.ServerCallContext context, Grpc.Core.IAsyncStreamReader<Point> requestStream)
+        {
+            int pointCount = 0;
+            int featureCount = 0;
+            int distance = 0;
+            Point previous = null;
+            var stopwatch = new Stopwatch();
+            stopwatch.Start();
+
+            while (await requestStream.MoveNext())
+            {
+                var point = requestStream.Current;
+                pointCount++;
+                if (RouteGuideUtil.Exists(CheckFeature(point)))
+                {
+                    featureCount++;
+                }
+                if (previous != null)
+                {
+                    distance += (int) CalcDistance(previous, point);
+                }
+                previous = point;
+            }
+
+            stopwatch.Stop();
+            return RouteSummary.CreateBuilder().SetPointCount(pointCount)
+                .SetFeatureCount(featureCount).SetDistance(distance)
+                .SetElapsedTime((int) (stopwatch.ElapsedMilliseconds / 1000)).Build();
+        }
+
+        /// <summary>
+        /// Receives a stream of message/location pairs, and responds with a stream of all previous
+        /// messages at each of those locations.
+        /// </summary>
+        public async Task RouteChat(Grpc.Core.ServerCallContext context, Grpc.Core.IAsyncStreamReader<RouteNote> requestStream, Grpc.Core.IServerStreamWriter<RouteNote> responseStream)
+        {
+            while (await requestStream.MoveNext())
+            {
+                var note = requestStream.Current;
+                List<RouteNote> notes = GetOrCreateNotes(note.Location);
+
+                List<RouteNote> prevNotes;
+                lock (notes)
+                {
+                    prevNotes = new List<RouteNote>(notes);
+                }
+
+                foreach (var prevNote in prevNotes)
+                {
+                    await responseStream.WriteAsync(prevNote);
+                }                
+                
+                lock (notes)
+                {
+                    notes.Add(note);
+                }
+            }
+        }
+
+        
+        /// <summary>
+        /// Get the notes list for the given location. If missing, create it.
+        /// </summary>
+        private List<RouteNote> GetOrCreateNotes(Point location)
+        {
+            List<RouteNote> notes = new List<RouteNote>();
+            routeNotes.TryAdd(location, notes);
+            return routeNotes[location];
+        }
+
+        /// <summary>
+        /// Gets the feature at the given point.
+        /// </summary>
+        /// <param name="location">the location to check</param>
+        /// <returns>The feature object at the point Note that an empty name indicates no feature.</returns>
+        private Feature CheckFeature(Point location)
+        {
+            foreach (var feature in features)
+            {
+                if (feature.Location.Latitude == location.Latitude
+                    && feature.Location.Longitude == location.Longitude)
+                {
+                    return feature;
+                }
+            }
+
+            // No feature was found, return an unnamed feature.
+            return Feature.CreateBuilder().SetName("").SetLocation(location).Build();
+        }
+
+        /// <summary>
+        /// Calculate the distance between two points using the "haversine" formula.
+        /// This code was taken from http://www.movable-type.co.uk/scripts/latlong.html.
+        /// </summary>
+        /// <param name="start">the starting point</param>
+        /// <param name="end">the end point</param>
+        /// <returns>the distance between the points in meters</returns>
+        private static double CalcDistance(Point start, Point end)
+        {
+            double lat1 = RouteGuideUtil.GetLatitude(start);
+            double lat2 = RouteGuideUtil.GetLatitude(end);
+            double lon1 = RouteGuideUtil.GetLongitude(start);
+            double lon2 = RouteGuideUtil.GetLongitude(end);
+            int r = 6371000; // metres
+            double φ1 = ToRadians(lat1);
+            double φ2 = ToRadians(lat2);
+            double Δφ = ToRadians(lat2 - lat1);
+            double Δλ = ToRadians(lon2 - lon1);
+
+            double a = Math.Sin(Δφ / 2) * Math.Sin(Δφ / 2) + Math.Cos(φ1) * Math.Cos(φ2) * Math.Sin(Δλ / 2) * Math.Sin(Δλ / 2);
+            double c = 2 * Math.Atan2(Math.Sqrt(a), Math.Sqrt(1 - a));
+
+            return r * c;
+        }
+
+        private static double ToRadians(double val)
+        {
+            return (Math.PI / 180) * val;
+        }
+    }
+}
diff --git a/csharp/route_guide/RouteGuideServer/RouteGuideServer.csproj b/csharp/route_guide/RouteGuideServer/RouteGuideServer.csproj
new file mode 100644
index 0000000..3fb7740
--- /dev/null
+++ b/csharp/route_guide/RouteGuideServer/RouteGuideServer.csproj
@@ -0,0 +1,99 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <Import Project="..\packages\grpc.native.csharp_ext.0.9.0.0\build\portable-net45\grpc.native.csharp_ext.props" Condition="Exists('..\packages\grpc.native.csharp_ext.0.9.0.0\build\portable-net45\grpc.native.csharp_ext.props')" />
+  <Import Project="..\packages\grpc.dependencies.openssl.redist.1.0.2.2\build\portable-net45\grpc.dependencies.openssl.redist.props" Condition="Exists('..\packages\grpc.dependencies.openssl.redist.1.0.2.2\build\portable-net45\grpc.dependencies.openssl.redist.props')" />
+  <Import Project="..\packages\grpc.dependencies.zlib.redist.1.2.8.9\build\portable-net45\grpc.dependencies.zlib.redist.props" Condition="Exists('..\packages\grpc.dependencies.zlib.redist.1.2.8.9\build\portable-net45\grpc.dependencies.zlib.redist.props')" />
+  <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <ProjectGuid>{4B7C7794-BE24-4477-ACE7-18259EB73D27}</ProjectGuid>
+    <OutputType>Exe</OutputType>
+    <AppDesignerFolder>Properties</AppDesignerFolder>
+    <RootNamespace>RouteGuideServer</RootNamespace>
+    <AssemblyName>RouteGuideServer</AssemblyName>
+    <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
+    <FileAlignment>512</FileAlignment>
+    <NuGetPackageImportStamp>93b8fc4b</NuGetPackageImportStamp>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+    <PlatformTarget>AnyCPU</PlatformTarget>
+    <DebugSymbols>true</DebugSymbols>
+    <DebugType>full</DebugType>
+    <Optimize>false</Optimize>
+    <OutputPath>bin\Debug\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+    <PlatformTarget>AnyCPU</PlatformTarget>
+    <DebugType>pdbonly</DebugType>
+    <Optimize>true</Optimize>
+    <OutputPath>bin\Release\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+  </PropertyGroup>
+  <ItemGroup>
+    <Reference Include="Google.ProtocolBuffers">
+      <HintPath>..\packages\Google.ProtocolBuffers.2.4.1.555\lib\net40\Google.ProtocolBuffers.dll</HintPath>
+    </Reference>
+    <Reference Include="Google.ProtocolBuffers.Serialization">
+      <HintPath>..\packages\Google.ProtocolBuffers.2.4.1.555\lib\net40\Google.ProtocolBuffers.Serialization.dll</HintPath>
+    </Reference>
+    <Reference Include="Grpc.Core">
+      <HintPath>..\packages\Grpc.Core.0.5.0\lib\net45\Grpc.Core.dll</HintPath>
+    </Reference>
+    <Reference Include="System" />
+    <Reference Include="System.Collections.Immutable">
+      <HintPath>..\packages\Microsoft.Bcl.Immutable.1.0.34\lib\portable-net45+win8+wp8+wpa81\System.Collections.Immutable.dll</HintPath>
+    </Reference>
+    <Reference Include="System.Core" />
+    <Reference Include="System.Interactive.Async">
+      <HintPath>..\packages\Ix-Async.1.2.3\lib\net45\System.Interactive.Async.dll</HintPath>
+    </Reference>
+    <Reference Include="System.Xml.Linq" />
+    <Reference Include="System.Data.DataSetExtensions" />
+    <Reference Include="Microsoft.CSharp" />
+    <Reference Include="System.Data" />
+    <Reference Include="System.Xml" />
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="Program.cs" />
+    <Compile Include="Properties\AssemblyInfo.cs" />
+    <Compile Include="RouteGuideImpl.cs" />
+  </ItemGroup>
+  <ItemGroup>
+    <None Include="App.config" />
+    <None Include="packages.config" />
+  </ItemGroup>
+  <ItemGroup>
+    <ProjectReference Include="..\RouteGuide\RouteGuide.csproj">
+      <Project>{49954d9c-5f17-4662-96b2-73be833dd81a}</Project>
+      <Name>RouteGuide</Name>
+    </ProjectReference>
+  </ItemGroup>
+  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+  <Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
+    <PropertyGroup>
+      <ErrorText>This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them.  For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
+    </PropertyGroup>
+    <Error Condition="!Exists('..\packages\grpc.dependencies.zlib.redist.1.2.8.9\build\portable-net45\grpc.dependencies.zlib.redist.props')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\grpc.dependencies.zlib.redist.1.2.8.9\build\portable-net45\grpc.dependencies.zlib.redist.props'))" />
+    <Error Condition="!Exists('..\packages\grpc.dependencies.zlib.redist.1.2.8.9\build\portable-net45\grpc.dependencies.zlib.redist.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\grpc.dependencies.zlib.redist.1.2.8.9\build\portable-net45\grpc.dependencies.zlib.redist.targets'))" />
+    <Error Condition="!Exists('..\packages\grpc.dependencies.openssl.redist.1.0.2.2\build\portable-net45\grpc.dependencies.openssl.redist.props')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\grpc.dependencies.openssl.redist.1.0.2.2\build\portable-net45\grpc.dependencies.openssl.redist.props'))" />
+    <Error Condition="!Exists('..\packages\grpc.dependencies.openssl.redist.1.0.2.2\build\portable-net45\grpc.dependencies.openssl.redist.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\grpc.dependencies.openssl.redist.1.0.2.2\build\portable-net45\grpc.dependencies.openssl.redist.targets'))" />
+    <Error Condition="!Exists('..\packages\grpc.native.csharp_ext.0.9.0.0\build\portable-net45\grpc.native.csharp_ext.props')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\grpc.native.csharp_ext.0.9.0.0\build\portable-net45\grpc.native.csharp_ext.props'))" />
+    <Error Condition="!Exists('..\packages\grpc.native.csharp_ext.0.9.0.0\build\portable-net45\grpc.native.csharp_ext.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\grpc.native.csharp_ext.0.9.0.0\build\portable-net45\grpc.native.csharp_ext.targets'))" />
+  </Target>
+  <Import Project="..\packages\grpc.dependencies.zlib.redist.1.2.8.9\build\portable-net45\grpc.dependencies.zlib.redist.targets" Condition="Exists('..\packages\grpc.dependencies.zlib.redist.1.2.8.9\build\portable-net45\grpc.dependencies.zlib.redist.targets')" />
+  <Import Project="..\packages\grpc.dependencies.openssl.redist.1.0.2.2\build\portable-net45\grpc.dependencies.openssl.redist.targets" Condition="Exists('..\packages\grpc.dependencies.openssl.redist.1.0.2.2\build\portable-net45\grpc.dependencies.openssl.redist.targets')" />
+  <Import Project="..\packages\grpc.native.csharp_ext.0.9.0.0\build\portable-net45\grpc.native.csharp_ext.targets" Condition="Exists('..\packages\grpc.native.csharp_ext.0.9.0.0\build\portable-net45\grpc.native.csharp_ext.targets')" />
+  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
+       Other similar extension points exist, see Microsoft.Common.targets.
+  <Target Name="BeforeBuild">
+  </Target>
+  <Target Name="AfterBuild">
+  </Target>
+  -->
+</Project>
\ No newline at end of file
diff --git a/csharp/route_guide/RouteGuideServer/packages.config b/csharp/route_guide/RouteGuideServer/packages.config
new file mode 100644
index 0000000..b1f8c69
--- /dev/null
+++ b/csharp/route_guide/RouteGuideServer/packages.config
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="utf-8"?>
+<packages>
+  <package id="Google.ProtocolBuffers" version="2.4.1.555" targetFramework="net45" />
+  <package id="Grpc" version="0.5.0" targetFramework="net45" />
+  <package id="Grpc.Core" version="0.5.0" targetFramework="net45" />
+  <package id="grpc.dependencies.openssl.redist" version="1.0.2.2" targetFramework="net45" />
+  <package id="grpc.dependencies.zlib.redist" version="1.2.8.9" targetFramework="net45" />
+  <package id="grpc.native.csharp_ext" version="0.9.0.0" targetFramework="net45" />
+  <package id="Ix-Async" version="1.2.3" targetFramework="net45" />
+  <package id="Microsoft.Bcl.Immutable" version="1.0.34" targetFramework="net45" />
+</packages>
\ No newline at end of file