diff --git a/BookingService.java b/BookingService.java
new file mode 100644
index 0000000..5124027
--- /dev/null
+++ b/BookingService.java
@@ -0,0 +1,472 @@
+/*
+ * Copyright 2018, 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.
+ */
+
+package ext.maps.booking.partner.v2;
+
+import ext.maps.booking.partner.v2.ApitemplateV2BookingService.AvailabilityUpdate;
+import ext.maps.booking.partner.v2.ApitemplateV2BookingService.Booking;
+import ext.maps.booking.partner.v2.ApitemplateV2BookingService.BookingStatus;
+import ext.maps.booking.partner.v2.ApitemplateV2BookingService.CheckAvailabilityRequest;
+import ext.maps.booking.partner.v2.ApitemplateV2BookingService.CheckAvailabilityResponse;
+import ext.maps.booking.partner.v2.ApitemplateV2BookingService.CheckAvailabilityResponse.DurationRequirement;
+import ext.maps.booking.partner.v2.ApitemplateV2BookingService.CreateBookingRequest;
+import ext.maps.booking.partner.v2.ApitemplateV2BookingService.CreateBookingResponse;
+import ext.maps.booking.partner.v2.ApitemplateV2BookingService.GetBookingStatusRequest;
+import ext.maps.booking.partner.v2.ApitemplateV2BookingService.GetBookingStatusResponse;
+import ext.maps.booking.partner.v2.ApitemplateV2BookingService.ListBookingsRequest;
+import ext.maps.booking.partner.v2.ApitemplateV2BookingService.ListBookingsResponse;
+import ext.maps.booking.partner.v2.ApitemplateV2BookingService.PrepaymentStatus;
+import ext.maps.booking.partner.v2.ApitemplateV2BookingService.Slot;
+import ext.maps.booking.partner.v2.ApitemplateV2BookingService.UpdateBookingRequest;
+import ext.maps.booking.partner.v2.ApitemplateV2BookingService.UpdateBookingResponse;
+import ext.maps.booking.partner.v2.ApitemplateV2BookingService.UserPaymentOption;
+import grpc.health.v1.Health.HealthImpl;
+import io.grpc.Grpc;
+import io.grpc.Metadata;
+import io.grpc.Server;
+import io.grpc.ServerCall;
+import io.grpc.ServerCallHandler;
+import io.grpc.ServerInterceptor;
+import io.grpc.ServerInterceptors;
+import io.grpc.Status;
+import io.grpc.netty.GrpcSslContexts;
+import io.grpc.netty.NettyServerBuilder;
+import io.grpc.stub.StreamObserver;
+import io.netty.handler.ssl.ClientAuth;
+import io.netty.handler.ssl.SslContextBuilder;
+import io.netty.handler.ssl.SslProvider;
+import java.io.File;
+import java.io.IOException;
+import java.net.InetSocketAddress;
+import java.security.cert.Certificate;
+import java.security.cert.CertificateEncodingException;
+import java.security.cert.X509Certificate;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.logging.Logger;
+import javax.net.ssl.SSLPeerUnverifiedException;
+import javax.net.ssl.SSLSession;
+import org.bouncycastle.asn1.x500.RDN;
+import org.bouncycastle.asn1.x500.X500Name;
+import org.bouncycastle.asn1.x500.style.BCStyle;
+import org.bouncycastle.asn1.x500.style.IETFUtils;
+import org.bouncycastle.cert.jcajce.JcaX509CertificateHolder;
+
+/** Booking Server with TLS enabled */
+public class BookingService {
+  private static final Logger logger = Logger.getLogger(BookingService.class.getName());
+
+  private Server server;
+
+  private final String host;
+  private final int port;
+  private final String certChainFilePath;
+  private final String privateKeyFilePath;
+  private final String trustedrootsFilePath;
+  private final Set<String> acceptedCNs;
+
+  public BookingService(
+      String host,
+      int port,
+      String certChainFilePath,
+      String privateKeyFilePath,
+      String trustedrootsFilePath,
+      Set<String> acceptedCNs) {
+    this.host = host;
+    this.port = port;
+    this.certChainFilePath = certChainFilePath;
+    this.privateKeyFilePath = privateKeyFilePath;
+    this.trustedrootsFilePath = trustedrootsFilePath;
+    this.acceptedCNs = acceptedCNs;
+  }
+
+  private SslContextBuilder getSslContextBuilder() {
+    SslContextBuilder sslClientContextBuilder =
+        SslContextBuilder.forServer(new File(certChainFilePath), new File(privateKeyFilePath));
+    if (trustedrootsFilePath != null) {
+      sslClientContextBuilder.trustManager(new File(trustedrootsFilePath));
+      sslClientContextBuilder.clientAuth(ClientAuth.OPTIONAL);
+    }
+    return GrpcSslContexts.configure(sslClientContextBuilder, SslProvider.OPENSSL);
+  }
+
+  private void start() throws IOException {
+
+    server =
+        NettyServerBuilder.forAddress(new InetSocketAddress(host, port))
+            .addService(ServerInterceptors.intercept(new BookingServiceImpl(), new MyInterceptor()))
+            .addService(new HealthImpl())
+            .sslContext(getSslContextBuilder().build())
+            .build()
+            .start();
+
+    logger.info("Booking Server started, listening on " + port);
+    Runtime.getRuntime()
+        .addShutdownHook(
+            new Thread() {
+              @Override
+              public void run() {
+                // Use stderr here since the logger may have been reset by its JVM shutdown hook.
+                System.err.println("*** shutting down gRPC server since JVM is shutting down");
+                BookingService.this.stop();
+                System.err.println("*** server shut down");
+              }
+            });
+  }
+
+  private void stop() {
+    if (server != null) {
+      server.shutdown();
+    }
+  }
+
+  /** Await termination on the main thread since the grpc library uses daemon threads. */
+  private void blockUntilShutdown() throws InterruptedException {
+    if (server != null) {
+      server.awaitTermination();
+    }
+  }
+
+  /** Main launches the server. */
+  public static void main(String[] args) throws IOException, InterruptedException {
+    // Set the accepted cns of the server
+    Set<String> acceptedCNs = new HashSet<String>();
+    acceptedCNs.add("mapsbooking.businesslink-3.net");
+
+    // TODO(partner): override your host name, port, server_cert_chain file path,
+    // private_key file path and trusted_client_roots file path here to build the server
+    final BookingService server =
+        new BookingService(
+            "localhost",
+            8443,
+            "src/main/certificates/server_cert_chain.pem",
+            "src/main/certificates/server_private_key.pem",
+            "src/main/certificates/trusted_client_roots.pem",
+            acceptedCNs);
+    server.start();
+    server.blockUntilShutdown();
+  }
+
+  /**
+   * Implement the server interceptor to do peer certificate validation that checks for a specific
+   * CN in the subject name, if the CN check fails, the connection will be closed with
+   * "PERMISSION_DENIED" status message.
+   */
+  private class MyInterceptor implements ServerInterceptor {
+    @Override
+    public <ReqT, RespT> ServerCall.Listener<ReqT> interceptCall(
+        ServerCall<ReqT, RespT> call, Metadata headers, ServerCallHandler<ReqT, RespT> next) {
+      SSLSession sslSession = call.getAttributes().get(Grpc.TRANSPORT_ATTR_SSL_SESSION);
+      try {
+        Certificate[] peerCerts = sslSession.getPeerCertificates();
+        if (peerCerts[0] instanceof java.security.cert.X509Certificate) {
+          X509Certificate peerCert = (X509Certificate) peerCerts[0];
+          X500Name x500Name = new JcaX509CertificateHolder(peerCert).getSubject();
+          RDN cn = x500Name.getRDNs(BCStyle.CN)[0];
+          String peerCN = IETFUtils.valueToString(cn.getFirst().getValue());
+          if (!acceptedCNs.contains(peerCN)) {
+            throw new SSLPeerUnverifiedException("Invalid CN");
+          }
+        } else {
+          throw new SSLPeerUnverifiedException("Invalid certificate type");
+        }
+      } catch (SSLPeerUnverifiedException se) {
+        System.err.println(se.getMessage());
+        call.close(Status.PERMISSION_DENIED, headers);
+        return new ServerCall.Listener<ReqT>() {};
+      } catch (CertificateEncodingException ce) {
+        System.err.println(ce.getMessage());
+        call.close(Status.PERMISSION_DENIED, headers);
+        return new ServerCall.Listener<ReqT>() {};
+      }
+      return next.startCall(call, headers);
+    }
+  }
+
+  /** The implementation of Booking Service. */
+  static class BookingServiceImpl extends BookingServiceGrpc.BookingServiceImplBase {
+    @Override
+    public void checkAvailability(
+        CheckAvailabilityRequest request,
+        StreamObserver<CheckAvailabilityResponse> responseObserver) {
+
+      Slot requestedSlot = request.getSlot();
+
+      // TODO(partner): perform availability check
+      //
+      // Error conditions: response with corresponding canonical gRPC error code
+      // example:
+      //  responseObserver.onError(
+      //      new StatusException(
+      //          io.grpc.Status.INVALID_ARGUMENT.withDescription("Invalid merchant id")
+      //      )
+      //  );
+      //
+      // Happy path: implement the helper functions, populate the response
+
+      CheckAvailabilityResponse response =
+          CheckAvailabilityResponse.newBuilder()
+              .setSlot(requestedSlot)
+              .setCountAvailable(getAvailableSpots(requestedSlot))
+              .setDurationRequirement(getDurationRequirement(requestedSlot)) // optional
+              .setAvailabilityUpdate(getAvailabilityUpdate(requestedSlot)) // optional
+              .build();
+
+      responseObserver.onNext(response);
+      responseObserver.onCompleted();
+    }
+
+    private int getAvailableSpots(Slot slot) {
+      // TODO(partner): get the available spots for the given slot
+      //
+      // int available_spots = ...
+      // return available_spots;
+
+      throw new UnsupportedOperationException("Not implemented yet");
+    }
+
+    private DurationRequirement getDurationRequirement(Slot slot) {
+      // TODO(partner): optional, get the duration requirment for the given slot
+      //
+      // DurationRequirement durationRequirement = ...
+      // return durationRequirement;
+
+      throw new UnsupportedOperationException("Not implemented yet");
+    }
+
+    private AvailabilityUpdate getAvailabilityUpdate(Slot slot) {
+      // TODO(partner): optional, get the availability update for the given slot
+      //
+      // AvailabilityUpdate availabilityUpdate = ...
+      // return availabilityUpdate;
+
+      throw new UnsupportedOperationException("Not implemented yet");
+    }
+
+    @Override
+    public void createBooking(
+        CreateBookingRequest request, StreamObserver<CreateBookingResponse> responseObserver) {
+
+      // TODO(partner): create a booking based on the request
+      //
+      // Error conditions:
+      // unexpected error -> response with corresponding canonical gRPC error code
+      // example:
+      //  responseObserver.onError(
+      //      new StatusException(
+      //          io.grpc.Status.INVALID_ARGUMENT.withDescription("Invalid merchant id")
+      //      )
+      //  );
+      // business logic error -> set the BookingFailure in the response
+      // example:
+      // BookingFailure bookingFailure = BookingFailure.newBuilder()
+      //     .setCause(Cause.SLOT_UNAVAILABLE)
+      //     .setDescription("slot is not available now")
+      //     .build();
+      // CreateBookingResponse response = CreateBookingResponse.newBuilder()
+      //     .setBookingFailure(bookingFailure)...
+      //
+      // Happy path: implement the helper functions, populate the response
+
+      Booking booking = createSuccessfulBooking(request);
+
+      CreateBookingResponse response =
+          CreateBookingResponse.newBuilder()
+              .setBooking(booking)
+              .setUserPaymentOption(getUserPaymentOption(booking)) // optional
+              .build();
+
+      responseObserver.onNext(response);
+      responseObserver.onCompleted();
+    }
+
+    private Booking createSuccessfulBooking(CreateBookingRequest request) {
+      // TODO(partner): create a booking based on the create booking request and return the
+      // created booking instance
+      //
+      // Booking created = ...(e.g.
+      // Booking.newBuilder()
+      //     .setBookingId("sampleBooking1")
+      //     .setSlot(request.getSlot())
+      //     .setUserInformation(request.getUserInformation())
+      //     .setStatus(BookingStatus.CONFIRMED)
+      //     .setPaymentInformation(request.getPaymentInformation())
+      //     .build()
+      // )
+      // return created;
+
+      throw new UnsupportedOperationException("Not implemented yet");
+    }
+
+    private UserPaymentOption getUserPaymentOption(Booking booking) {
+      // TODO(partner): optional, get the user payment option for the given booking
+      //
+      // UserPaymentOption paymentOption = ...
+      // return paymentOption;
+
+      throw new UnsupportedOperationException("Not implemented yet");
+    }
+
+    @Override
+    public void updateBooking(
+        UpdateBookingRequest request, StreamObserver<UpdateBookingResponse> responseObserver) {
+
+      // TODO(partner): update the booking based on the request
+      //
+      // Error conditions:
+      // unexpected error -> response with corresponding canonical gRPC error code
+      // example:
+      //  responseObserver.onError(
+      //      new StatusException(
+      //          io.grpc.Status.NOT_FOUND.withDescription("Unknown booking id")
+      //      )
+      //  );
+      // business logic error -> set the BookingFailure in the response
+      // example:
+      // BookingFailure bookingFailure = BookingFailure.newBuilder()
+      //     .setCause(Cause.SLOT_UNAVAILABLE)
+      //     .setDescription("slot is not available now")
+      //     .build();
+      // CreateBookingResponse response = CreateBookingResponse.newBuilder()
+      //     .setBookingFailure(bookingFailure)...
+      //
+      // Happy path: implement the helper functions, populate the response
+
+      Booking booking = updateSuccessfulBooking(request);
+
+      UpdateBookingResponse response =
+          UpdateBookingResponse.newBuilder()
+              .setBooking(booking)
+              .setUserPaymentOption(getUserPaymentOption(booking)) // option
+              .build();
+
+      responseObserver.onNext(response);
+      responseObserver.onCompleted();
+    }
+
+    private Booking updateSuccessfulBooking(UpdateBookingRequest request) {
+      // TODO(partner): look up the booking with bookingId, update fields according to
+      // updateMask and return the updated booking instance
+      //
+      // String bookingId = request.getBooking().getBookingId();
+      // FieldMask updateMask = request.getUpdateMask();
+      // Booking updated = ...
+      // return updated;
+
+      throw new UnsupportedOperationException("Not implemented yet");
+    }
+
+    @Override
+    public void getBookingStatus(
+        GetBookingStatusRequest request,
+        StreamObserver<GetBookingStatusResponse> responseObserver) {
+
+      String bookingId = request.getBookingId();
+
+      // TODO(partner): look up the booking status and prepayment status with bookingId
+      //
+      // Error conditions:
+      // unexpected error -> response with corresponding canonical gRPC error code
+      // example:
+      //  responseObserver.onError(
+      //      new StatusException(
+      //          io.grpc.Status.NOT_FOUND.withDescription("Unknown booking id")
+      //      )
+      //  );
+      //
+      // Happy path: implement the helper functions, populate the response
+
+      GetBookingStatusResponse response =
+          GetBookingStatusResponse.newBuilder()
+              .setBookingId(bookingId)
+              .setBookingStatus(getBookingStatus(bookingId))
+              .setPrepaymentStatus(getPrepaymentStatus(bookingId))
+              .build();
+
+      responseObserver.onNext(response);
+      responseObserver.onCompleted();
+    }
+
+    private BookingStatus getBookingStatus(String bookingId) {
+      // TODO(partner): get the booking status for the given bookingId
+      //
+      // BookingStatus bookingStatus = ...
+      // return bookingStatus;
+
+      throw new UnsupportedOperationException("Not implemented yet");
+    }
+
+    private PrepaymentStatus getPrepaymentStatus(String bookingId) {
+      // TODO(partner): get the prepayment status for the given bookingId
+      //
+      // Prepayment prepaymentStatus = ...
+      // return prepaymentStatus;
+
+      throw new UnsupportedOperationException("Not implemented yet");
+    }
+
+    @Override
+    public void listBookings(
+        ListBookingsRequest request, StreamObserver<ListBookingsResponse> responseObserver) {
+
+      String userId = request.getUserId();
+
+      // TODO(partner): look up all bookings with the given userId
+      //
+      // Error conditions:
+      // unexpected error -> response with corresponding canonical gRPC error code
+      // example:
+      //  responseObserver.onError(
+      //      new StatusException(
+      //          io.grpc.Status.NOT_FOUND.withDescription("Unknown user id")
+      //      )
+      //  );
+      //
+      // Happy path: implement the helper function, populate the response
+
+      ListBookingsResponse response =
+          ListBookingsResponse.newBuilder().addAllBookings(getListBooking(userId)).build();
+
+      responseObserver.onNext(response);
+      responseObserver.onCompleted();
+    }
+
+    private List<Booking> getListBooking(String userId) {
+      // TODO(partner): get the bookings list for the given userId
+      //
+      // List<Booking> bookings = ...
+      // return bookings;
+
+      throw new UnsupportedOperationException("Not implemented yet");
+    }
+  }
+}
diff --git a/Health.java b/Health.java
new file mode 100644
index 0000000..81788b6
--- /dev/null
+++ b/Health.java
@@ -0,0 +1,73 @@
+/*
+ * Copyright 2018, 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.
+ */
+
+package grpc.health.v1;
+
+import grpc.health.v1.HealthOuterClass.HealthCheckRequest;
+import grpc.health.v1.HealthOuterClass.HealthCheckResponse;
+import grpc.health.v1.HealthOuterClass.HealthCheckResponse.ServingStatus;
+import io.grpc.Status;
+import io.grpc.StatusException;
+import io.grpc.stub.StreamObserver;
+import java.util.logging.Logger;
+
+/** gRPC Health Checking Protocol */
+public class Health {
+  private static final Logger logger = Logger.getLogger(Health.class.getName());
+  private static final String ACCEPTED_SERVICE = "ext.maps.booking.partner.v2.BookingService";
+
+  /** The implementation of Health Checking Service. */
+  public static class HealthImpl extends HealthGrpc.HealthImplBase {
+    @Override
+    public void check(
+        HealthCheckRequest request, StreamObserver<HealthCheckResponse> responseObserver) {
+      String service = request.getService();
+      if (!service.equals(ACCEPTED_SERVICE)) {
+        responseObserver.onError(
+            new StatusException(Status.NOT_FOUND.withDescription("Unknown service")));
+      } else {
+        HealthCheckResponse response =
+            HealthCheckResponse.newBuilder().setStatus(getServingStatus()).build();
+        responseObserver.onNext(response);
+        responseObserver.onCompleted();
+      }
+    }
+
+    private ServingStatus getServingStatus() {
+      // TODO(partner): check the health status of the service
+      //
+      // ServingStatus status = ... (e.g. ServingStatus.SERVING)
+      // return status;
+
+      throw new UnsupportedOperationException("Not implemented yet");
+    }
+  }
+}
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..6fefbd1
--- /dev/null
+++ b/README.md
@@ -0,0 +1,163 @@
+# gRPC Server Skeleton for Java
+
+### Get Started
+
+1.  Create a java gradle project (grpc-booking-service), under the src/main,
+    create a 'proto' directory.
+
+2.  Download the [booking service
+    definition](https://developers.google.com/maps-booking/download/apitemplate.v2.booking_service.proto)
+    and [health checking
+    protocol](https://github.com/grpc/grpc/blob/master/src/proto/grpc/health/v1/health.proto),
+    place them under src/main/proto. These files define the gRPC methods and
+    messages for the Reserve with Google API and Health Check.
+
+3.  Update the ***build.gradle*** file, add dependencies and the protobuf plugin
+    for Gradle. The introduction and guide for protobuf-gradle-plugin can be
+    found [here](https://github.com/google/protobuf-gradle-plugin).
+
+            apply plugin: 'java'
+            apply plugin: 'com.google.protobuf'
+
+            repositories {
+                mavenCentral()
+            }
+
+            // updating the version in our release process.
+            def grpcVersion = '1.8.0' // CURRENT_GRPC_VERSION
+            def nettyTcNativeVersion = '2.0.7.Final'
+
+            dependencies {
+                compile "com.google.api.grpc:proto-google-common-protos:0.1.9"
+                compile "io.grpc:grpc-netty:${grpcVersion}"
+                compile "io.grpc:grpc-protobuf:${grpcVersion}"
+                compile "io.grpc:grpc-stub:${grpcVersion}"
+                compile "io.netty:netty-tcnative-boringssl-static:${nettyTcNativeVersion}"
+                compile "org.bouncycastle:bcmail-jdk15:1.46"
+
+                testCompile "io.grpc:grpc-testing:${grpcVersion}"
+                testCompile "junit:junit:4.12"
+                testCompile "org.mockito:mockito-core:1.9.5"
+            }
+
+            buildscript {
+                repositories {
+                    mavenCentral()
+                }
+                dependencies {
+                    // ASSUMES GRADLE 2.12 OR HIGHER. Use plugin version 0.7.5 with earlier
+                    // gradle versions
+                    classpath 'com.google.protobuf:protobuf-gradle-plugin:0.8.1'
+                }
+            }
+
+            protobuf {
+                protoc {
+                    artifact = 'com.google.protobuf:protoc:3.4.0'
+                }
+                plugins {
+                    grpc {
+                        artifact = "io.grpc:protoc-gen-grpc-java:${grpcVersion}"
+                    }
+                }
+                generateProtoTasks {
+                    all()*.plugins {
+                        grpc {}
+                    }
+                }
+            }
+
+            // Inform IDEs like IntelliJ IDEA, Eclipse or NetBeans about the generated code.
+            sourceSets {
+                main {
+                    java {
+                        srcDirs 'build/generated/source/proto/main/grpc'
+                        srcDirs 'build/generated/source/proto/main/java'
+                    }
+                }
+            }
+
+            // Generate IntelliJ IDEA's .idea & .iml project files
+            apply plugin: 'idea'
+
+            // Provide convenience executables for trying out the examples.
+            apply plugin: 'application'
+
+            startScripts.enabled = false
+
+4.  Run the following command to build the library and auto-generate code from
+    protoc build plugin:
+
+          ./gradlew build
+
+5.  To enable TLS on the server, under ***src/main/certificates/*** the
+    following files are required:
+
+    *   ***server_cert_chain.pem*** your server certificate chain in PEM format
+    *   ***server_private_key.pem*** your private key for the server certificate
+        chain, needs to be the PKCS#8 private key
+    *   ***trusted_client_roots.pem*** the root certificates that are trusted
+        when authenticating clients, you can choose to obtain this set of
+        trusted roots from an authority like
+        [Mozilla](https://wiki.mozilla.org/CA:IncludedCAs), or install the [set
+        of roots currently recommended by the Google Internet Authority
+        G2](https://pki.google.com/roots.pem). In the latter case, you may have
+        to manually update the root certificate at times
+
+6.  Retrieve the sample code, place the **BookingService.java** under
+    *src/main/java/ext/maps/booking/partner/v2*, place **Health.java** under
+    *src/main/java/grpc/health/v1*. In both files, follow the ***TODOs*** to
+    complete your implementations.
+
+7.  Update the gradle.build file to specify the generation of server executable
+    by adding the following code:
+
+        task bookingService(type: CreateStartScripts) {
+            mainClassName = 'ext.maps.booking.partner.v2.BookingService'
+            applicationName = 'booking-service'
+            outputDir = new File(project.buildDir, 'tmp')
+            classpath = jar.outputs.files + project.configurations.runtime
+        }
+
+        applicationDistribution.into('bin') {
+            from(bookingService)
+            fileMode = 0755
+        }
+
+8.  Compile the server:
+
+        ./gradlew installDist
+
+9.  Run the booking server:
+
+        ./build/install/grpc-booking-service/bin/booking-service
+
+### Final Directory Structure
+
+    src
+    |---main
+        |---certificates
+            |---server_cert_chain.pem
+            |---server_private_key.pem
+            |---trusted_client_roots.pem
+        |---java
+            |---ext.maps.booking.partner.v2.BookingService.java
+            |---grpc.health.v1.Health.java
+        |---proto
+            |---booking_service.proto
+            |---health.proto
+    |---test
+
+### Other Reference
+
+*   For other building tools, visit the
+    [gRPC-java](https://grpc.io/docs/quickstart/java.html) and download the
+    example, check grpc-java/examples.
+
+         git clone -b v1.9.0 https://github.com/grpc/grpc-java
+
+*   [gRPC java Transport Security
+    (TLS)](https://github.com/grpc/grpc-java/blob/master/SECURITY.md).
+
+*   [gRPC API
+    V2](https://developers.google.com/maps-booking/reference/grpc-api-v2/slot-specification).
