diff --git a/frontend/Makefile b/frontend/Makefile
index 7ed2459cae4bce2b73a7585caee544aca75ac833..c896165bddec02db09e9ea9399b6e627b6594c57 100644
--- a/frontend/Makefile
+++ b/frontend/Makefile
@@ -1,5 +1,11 @@
+# Note on linking:
+# Client only needs to link with -lprotobuf
+# Server also needs to link with -lprotoc
+
 CPPFLAGS=-I/usr/include/xrootd -I/usr/include/protobuf3 -fPIC -std=c++1y -pedantic -Wall -Wextra -Werror -Wno-unused-parameter
 LDFLAGS=-L/usr/lib64/protobuf3 -lXrdSsi-4 -lXrdSsiLib
+#LDLIBS=-lprotobuf -lprotoc
+LDLIBS=-lprotobuf 
 LINK.o=$(LINK.cc)
 
 all: test_client frontend_ssi.so
@@ -13,13 +19,11 @@ frontend_ssi.so: TestSsiServiceProvider.o TestSsiRequestProc.o test.pb.o
 
 all: test_client
 
-LDLIBS=-lprotobuf 
-
 test_client: test_client.o test.pb.o
 
 test_client.o: test_client.cpp TestSsiClient.h TestSsiRequest.h test.pb.h
 
-test.pb.o: test.pb.h
+test.pb.o: test.pb.cc test.pb.h
 
 test.pb.h: test.proto
 	#protoc3 --cpp_out=. --plugin=protoc-gen-XrdSsi=./protoc-gen-XrdSsi --XrdSsi_out=. test.proto
@@ -27,8 +31,6 @@ test.pb.h: test.proto
 
 # Protobuf3 plugin (to parse services in .proto file)
 
-LDLIBS=-lprotobuf -lprotoc
-
 protoc-gen-XrdSsi: protoc-gen-XrdSsi.cpp
 
 clean:
diff --git a/frontend/TestSsiClient.h b/frontend/TestSsiClient.h
index 5b649cca543574de1c7c8b861f0f4c36a441cedd..a7f0ee7c184c460b9774d756295fddd3128a2592 100644
--- a/frontend/TestSsiClient.h
+++ b/frontend/TestSsiClient.h
@@ -8,11 +8,6 @@
 #include "XrdSsiException.h"
 #include "TestSsiRequest.h"
 
-// Perhaps we want to allow multiple resources, e.g. streaming and non-streaming versions of the service?
-// Can this be defined in the protobuf definition?
-
-const std::string TestSsiResource("/test");
-
 
 
 // XrdSsiProviderClient is instantiated and managed by the SSI library
@@ -31,7 +26,7 @@ public:
 
    // constructor to be used on the client side (to establish a connection to the server):
 
-   TestSsiClient(std::string hostname, int port, int to = 15) : resource(TestSsiResource), timeout(to)
+   TestSsiClient(std::string hostname, int port, std::string _resource, int _timeout = 15) : resource(_resource), timeout(_timeout)
    {
       XrdSsiErrInfo eInfo;
 
@@ -83,6 +78,26 @@ public:
       // Note: it is safe to delete the XrdSsiResource object after ProcessRequest() returns. I don't delete it because
       // I am assuming I can reuse it, but I need to check if that is a safe assumption. Perhaps I need to create a new
       // resource object for each request?
+      //
+      // See SSI ref p.10 on configuring a resource to be reusable
+      // Do I need more than one resource? I could have a single resource called "/default" with some default options and
+      // if necessary I can add other resources with other options later.
+      //
+      // Possible useful options:
+      //
+      // For specifying the tapeserver callback:
+      // XrdSsiResource::rInfo
+      // This option allows you to send additional out-of-band information to the
+      // server that will be executing the request. The information should be specified
+      // in CGI format (i.e. key=value[&key=value[...]]). This information is supplied
+      // to the server-side service in its corresponding request resource object. Note
+      // that restrictions apply for reusable resources.
+      //
+      // XrdSsiResource::rUser
+      // This is an arbitrary string that is meant to further identify the request. The
+      // SSI framework normally uses this information to tag log messages. It is also
+      // supplied to the server-side service in its corresponding request resource
+      // object.
    }
 
 private:
diff --git a/frontend/TestSsiRequest.h b/frontend/TestSsiRequest.h
index 25455251bf93aa6373b1d44284e79d7b97fc5dcc..546599ffa097cab84cb6e66db76b40c17b0b3f34 100644
--- a/frontend/TestSsiRequest.h
+++ b/frontend/TestSsiRequest.h
@@ -8,10 +8,10 @@ class TestSsiRequest : public XrdSsiRequest
 {
 public:
 
-           TestSsiRequest(const std::string &buffer_str, uint16_t tmo=0) : request_buffer(buffer_str.c_str()), request_len(buffer_str.size())
+           TestSsiRequest(const std::string &buffer_str, uint16_t timeout=0) : request_buffer(buffer_str.c_str()), request_len(buffer_str.size())
            {
-              std::cerr << "Creating TestSsiRequest object, setting tmo=" << tmo << std::endl;
-              this->SetTimeOut(tmo);
+              std::cerr << "Creating TestSsiRequest object, setting timeout=" << timeout << std::endl;
+              SetTimeOut(timeout);
            }
    virtual ~TestSsiRequest() 
            {
@@ -54,7 +54,7 @@ private:
 
 // Process the response
 
-template<class RequestType, class ResponseType, class MetadataType, class AlertType>
+template<typename RequestType, typename ResponseType, typename MetadataType, typename AlertType>
 bool TestSsiRequest<RequestType, ResponseType, MetadataType, AlertType>::ProcessResponse(const XrdSsiErrInfo &eInfo, const XrdSsiRespInfo &rInfo)
 {
    using namespace std;
@@ -131,7 +131,7 @@ bool TestSsiRequest<RequestType, ResponseType, MetadataType, AlertType>::Process
 
 
 
-template<class RequestType, class ResponseType, class MetadataType, class AlertType>
+template<typename RequestType, typename ResponseType, typename MetadataType, typename AlertType>
 XrdSsiRequest::PRD_Xeq TestSsiRequest<RequestType, ResponseType, MetadataType, AlertType>::ProcessResponseData(const XrdSsiErrInfo &eInfo, char *myBuff, int myBLen, bool isLast)
 {
    using namespace std;
@@ -176,7 +176,7 @@ XrdSsiRequest::PRD_Xeq TestSsiRequest<RequestType, ResponseType, MetadataType, A
 
 
 
-template<class RequestType, class ResponseType, class MetadataType, class AlertType>
+template<typename RequestType, typename ResponseType, typename MetadataType, typename AlertType>
 void TestSsiRequest<RequestType, ResponseType, MetadataType, AlertType>::Alert(XrdSsiRespInfoMsg &aMsg)
 {
    using namespace std;
diff --git a/frontend/TestSsiRequestProc.cpp b/frontend/TestSsiRequestProc.cpp
index d6d280b0d4fd8be6c5d7b5722c5be47a580517fc..9c18b54a591f7cd110e80186dfe1e803a5d698a0 100644
--- a/frontend/TestSsiRequestProc.cpp
+++ b/frontend/TestSsiRequestProc.cpp
@@ -1,8 +1,9 @@
 #include <iostream>
+#include "test_util.h"
 
+#include "test.pb.h"
 #include "XrdSsiException.h"
 #include "TestSsiRequestProc.h"
-#include "TestSsiProtobuf.h"
 
 // This is for specialized private methods called by RequestProc::Execute to handle actions, alerts
 // and metadata
@@ -13,7 +14,7 @@ void RequestProc<xrdssi::test::Request, xrdssi::test::Result, xrdssi::test::Meta
    // Output message in Json format (for debugging)
 
    std::cerr << "Received message:" << std::endl;
-   std::cerr << xrdssi::test::MessageToJsonString(request);
+   std::cerr << MessageToJsonString(request);
 
    // Set reply
 
@@ -23,7 +24,7 @@ void RequestProc<xrdssi::test::Request, xrdssi::test::Result, xrdssi::test::Meta
    // Output message in Json format (for debugging)
 
    std::cerr << "Preparing response:" << std::endl;
-   std::cerr << xrdssi::test::MessageToJsonString(response);
+   std::cerr << MessageToJsonString(response);
 }
 
 
@@ -42,7 +43,7 @@ void RequestProc<xrdssi::test::Request, xrdssi::test::Result, xrdssi::test::Meta
    // Output message in Json format (for debugging)
 
    std::cerr << "Preparing metadata..." << std::endl;
-   std::cerr << xrdssi::test::MessageToJsonString(metadata);
+   std::cerr << MessageToJsonString(metadata);
 }
 
 
diff --git a/frontend/TestSsiServiceProvider.cpp b/frontend/TestSsiServiceProvider.cpp
index 0c7306800d1136b432d99ea9a43aaba2e1661cf1..a6c30e3267af03938035adf319e060e78a0a061b 100644
--- a/frontend/TestSsiServiceProvider.cpp
+++ b/frontend/TestSsiServiceProvider.cpp
@@ -1,8 +1,8 @@
 #include <iostream>
 
-#include "TestSsiServiceProvider.h"
+#include "test.pb.h"
 #include "TestSsiService.h"
-#include "TestSsiProtobuf.h"
+#include "TestSsiServiceProvider.h"
 
 
 
diff --git a/frontend/test_client.cpp b/frontend/test_client.cpp
index 6c7b438bed3ebf137cd9f442f8baf99c71990883..a2d2131463374bd92c09388a844aae2c22a0c170 100644
--- a/frontend/test_client.cpp
+++ b/frontend/test_client.cpp
@@ -1,15 +1,27 @@
-#include <unistd.h> // for sleep
+#include <unistd.h>    // for sleep
+#include "test_util.h" // for Json output (only needed for debugging)
 
-#include "TestSsiClient.h"
-#include "TestSsiProtobuf.h"
+#include "TestSsiClient.h"   // XRootD SSI Service API
+#include "test.pb.h"         // Auto-generated message types from .proto file
 
-int main(int argc, char *argv[])
-{
-   // Host:port of XRootD server
+// Bind the type of the XrdSsiClient to the types defined in the .proto file
+
+typedef TestSsiClient<xrdssi::test::Request,     // Request message type
+                      xrdssi::test::Result,      // Response message type
+                      xrdssi::test::Metadata,    // Metadata message type
+                      xrdssi::test::Alert>       // Alert message type
+        TestSsiClientType;
+
+// Define the location of the XRootD SSI Service
+
+const std::string host     = "localhost";
+const int         port     = 10400;
+const std::string resource = "/test";
 
-   const std::string host = "localhost";
-   const int         port = 10400;
 
+
+int main(int argc, char *argv[])
+{
    // Verify that the version of the Google Protocol Buffer library that we linked against is
    // compatible with the version of the headers we compiled against
 
@@ -17,9 +29,10 @@ int main(int argc, char *argv[])
 
    try
    {
+
       // Obtain a Service Provider
 
-      TestSsiClient<xrdssi::test::Request, xrdssi::test::Result, xrdssi::test::Metadata, xrdssi::test::Alert> test_ssi_service(host, port);
+      TestSsiClientType test_ssi_service(host, port, resource);
 
       // Create a Request object
 
@@ -27,14 +40,27 @@ int main(int argc, char *argv[])
 
       request.set_message_text("Archive some file");
 
-      // Output message in Json format (for debugging only)
+      // Output message in Json format
 
       std::cout << "Sending message:" << std::endl;
-      std::cout << xrdssi::test::MessageToJsonString(request);
+      std::cout << MessageToJsonString(request);
 
       // Send the Request to the Service
 
       test_ssi_service.send(request);
+
+      // Wait for the response callback.
+      // (When this loop finishes, test_ssi_service will go out-of-scope and the service will be shut down)
+
+      std::cout << "Request sent, going to sleep..." << std::endl;
+
+      int wait_secs = 20;
+
+      while(--wait_secs)
+      {
+         std::cerr << ".";
+         sleep(1);
+      }
    }
    catch (std::exception& e)
    {
@@ -43,18 +69,6 @@ int main(int argc, char *argv[])
       return 1;
    }
 
-   // Wait for the response callback
-
-   std::cout << "Request sent, going to sleep..." << std::endl;
-
-   int wait_secs = 20;
-
-   while(--wait_secs)
-   {
-      std::cerr << ".";
-      sleep(1);
-   }
-
    std::cout << "All done, exiting." << std::endl;
 
    // Optional: Delete all global objects allocated by libprotobuf
diff --git a/frontend/TestSsiProtobuf.h b/frontend/test_util.h
similarity index 74%
rename from frontend/TestSsiProtobuf.h
rename to frontend/test_util.h
index b850ab420fdf25c06295e909c3aa26d8195331bb..3dfb060af0c2d8b0b45dea40df04806691d31aaa 100644
--- a/frontend/TestSsiProtobuf.h
+++ b/frontend/test_util.h
@@ -1,12 +1,9 @@
-#ifndef __TEST_SSI_PROTOBUF_H
-#define __TEST_SSI_PROTOBUF_H
+#ifndef __TEST_UTIL_H
+#define __TEST_UTIL_H
 
 #include <google/protobuf/util/json_util.h>
 
-#include "test.pb.h"
-
-namespace xrdssi {
-namespace test {
+// Helper function for debugging
 
 inline std::string MessageToJsonString(const google::protobuf::Message &message)
 {
@@ -23,7 +20,4 @@ inline std::string MessageToJsonString(const google::protobuf::Message &message)
    return output;
 }
 
-} // test
-} // xrdssi
-
 #endif