THRIFT-4405: sanity tests relating to sequence numbers

- prove all servers return the sequence ID given
- prove that sequences that wrap around the int32_t space are handled ok
diff --git a/CHANGES.md b/CHANGES.md
index b77003b..77893e0 100644
--- a/CHANGES.md
+++ b/CHANGES.md
@@ -16,18 +16,18 @@
 	
 ### Breaking Changes
 
-- [THRIFT-4743](https://issues.apache.org/jira/browse/THRIFT-4743) - compiler: remove plug-in mechanism
+- [THRIFT-4743](https://issues.apache.org/jira/browse/THRIFT-4743) - compiler: removed the plug-in mechanism
 - [THRIFT-4720](https://issues.apache.org/jira/browse/THRIFT-4720) - cpp: C++03/C++98 support has been removed; also removed boost as a runtime dependency
 - [THRIFT-4730](https://issues.apache.org/jira/browse/THRIFT-4730) - cpp: BoostThreadFactory, PosixThreadFactory, StdThreadFactory removed
 - [THRIFT-4732](https://issues.apache.org/jira/browse/THRIFT-4732) - cpp: CMake build changed to use BUILD_SHARED_LIBS
 - [THRIFT-4735](https://issues.apache.org/jira/browse/THRIFT-4735) - cpp: Removed Qt4 support
 - [THRIFT-4740](https://issues.apache.org/jira/browse/THRIFT-4740) - cpp: Use std::chrono::duration for timeouts
+- [THRIFT-4672](https://issues.apache.org/jira/browse/THRIFT-4672) - cpp: TTransport::getOrigin() is now const
 - [THRIFT-4702](https://issues.apache.org/jira/browse/THRIFT-4702) - java: class org.apache.thrift.AutoExpandingBuffer is no longer public
 - [THRIFT-4709](https://issues.apache.org/jira/browse/THRIFT-4709) - java: changes to UTF-8 handling require JDK 1.7 at a minimum
 - [THRIFT-4712](https://issues.apache.org/jira/browse/THRIFT-4712) - java: class org.apache.thrift.ShortStack is no longer public
 - [THRIFT-4725](https://issues.apache.org/jira/browse/THRIFT-4725) - java: change return type signature of 'process' methods
 - [THRIFT-4675](https://issues.apache.org/jira/browse/THRIFT-4675) - js: now uses node-int64 for 64 bit integer constants
-- [THRIFT-4672](https://issues.apache.org/jira/browse/THRIFT-4672) - C++: TTransport::getOrigin() is now const
 
 ### Known Issues (Blocker or Critical)
 
diff --git a/Makefile.am b/Makefile.am
index 1f2d483..bacd008 100755
--- a/Makefile.am
+++ b/Makefile.am
@@ -43,6 +43,7 @@
 DISTCLEANFILES = \
 	Makefile \
 	Makefile.in \
+	aclocal.m4 \
 	apache-thrift-test-library \
 	autoscan.log \
 	compile \
diff --git a/lib/cpp/src/thrift/TBase.h b/lib/cpp/src/thrift/TBase.h
index cc31c34..e2e78e7 100644
--- a/lib/cpp/src/thrift/TBase.h
+++ b/lib/cpp/src/thrift/TBase.h
@@ -28,7 +28,7 @@
 
 class TBase {
 public:
-  virtual ~TBase()= default;;
+  virtual ~TBase() = default;
   virtual uint32_t read(protocol::TProtocol* iprot) = 0;
   virtual uint32_t write(protocol::TProtocol* oprot) const = 0;
 };
diff --git a/lib/cpp/src/thrift/Thrift.h b/lib/cpp/src/thrift/Thrift.h
index 951cc28..6cb24e6 100644
--- a/lib/cpp/src/thrift/Thrift.h
+++ b/lib/cpp/src/thrift/Thrift.h
@@ -98,7 +98,7 @@
   template <class E>
   static TDelayedException* delayException(const E& e);
   virtual void throw_it() = 0;
-  virtual ~TDelayedException()= default;;
+  virtual ~TDelayedException() = default;
 };
 
 template <class E>
diff --git a/lib/cpp/src/thrift/concurrency/Thread.h b/lib/cpp/src/thrift/concurrency/Thread.h
index bced240..e803a82 100644
--- a/lib/cpp/src/thrift/concurrency/Thread.h
+++ b/lib/cpp/src/thrift/concurrency/Thread.h
@@ -39,7 +39,7 @@
 class Runnable {
 
 public:
-  virtual ~Runnable()= default;;
+  virtual ~Runnable() = default;
   virtual void run() = 0;
 
   /**
diff --git a/lib/cpp/src/thrift/protocol/TJSONProtocol.cpp b/lib/cpp/src/thrift/protocol/TJSONProtocol.cpp
index dcd498f..53cc140 100644
--- a/lib/cpp/src/thrift/protocol/TJSONProtocol.cpp
+++ b/lib/cpp/src/thrift/protocol/TJSONProtocol.cpp
@@ -303,9 +303,9 @@
 class TJSONContext {
 
 public:
-  TJSONContext()= default;;
+  TJSONContext() = default;
 
-  virtual ~TJSONContext()= default;;
+  virtual ~TJSONContext() = default;
 
   /**
    * Write context data to the transport. Default is to do nothing.
diff --git a/test/cpp/src/TestClient.cpp b/test/cpp/src/TestClient.cpp
index 2a06578..f7c4912 100644
--- a/test/cpp/src/TestClient.cpp
+++ b/test/cpp/src/TestClient.cpp
@@ -60,6 +60,53 @@
 using namespace apache::thrift::transport;
 using namespace thrift::test;
 
+//
+// A pedantic protocol that checks to make sure the response sequence ID
+// is the same as the sent sequence ID.  lib/cpp always sends zero for
+// synchronous clients, so this bumps the number to make sure it gets
+// returned properly from the remote server.  Any server that does not
+// respond with the same sequence number is violating the sequence ID
+// agreement between client and server.
+//
+
+template<class _P>
+class TPedanticProtocol : public _P
+{
+    public:
+        TPedanticProtocol(std::shared_ptr<TTransport>& transport)
+          : _P(transport), m_last_seqid(std::numeric_limits<int32_t>::max() - 10) { }
+
+        virtual uint32_t writeMessageBegin_virt(const std::string& name,
+                                           const TMessageType messageType,
+                                           const int32_t in_seqid) override
+        {
+            int32_t seqid = in_seqid;
+            if (!seqid) { // this is typical for normal cpp generated code
+                seqid = ++m_last_seqid;
+            }
+
+            return _P::writeMessageBegin_virt(name, messageType, seqid);
+        }
+
+        virtual uint32_t readMessageBegin_virt(std::string& name,
+                                          TMessageType& messageType,
+                                          int32_t& seqid) override
+        {
+            uint32_t result = _P::readMessageBegin_virt(name, messageType, seqid);
+            if (seqid != m_last_seqid) {
+                std::stringstream ss;
+                ss << "ERROR: send request with seqid " << m_last_seqid << " and got reply with seqid " << seqid;
+                throw std::logic_error(ss.str());
+            } /* else {
+                std::cout << "verified seqid " << m_last_seqid << " round trip OK" << std::endl;
+            } */
+            return result;
+        }
+
+    private:
+        int32_t m_last_seqid;
+};
+
 // Current time, microseconds since the epoch
 uint64_t now() {
   int64_t ret;
@@ -299,19 +346,23 @@
   }
 
   if (protocol_type == "json" || protocol_type == "multij") {
-    protocol = std::make_shared<TJSONProtocol>(transport);
+    typedef TPedanticProtocol<TJSONProtocol> TPedanticJSONProtocol;
+    protocol = std::make_shared<TPedanticJSONProtocol>(transport);
   } else if (protocol_type == "compact" || protocol_type == "multic") {
-    protocol = std::make_shared<TCompactProtocol>(transport);
+    typedef TPedanticProtocol<TCompactProtocol> TPedanticCompactProtocol;
+    protocol = std::make_shared<TPedanticCompactProtocol>(transport);
   } else if (protocol_type == "header" || protocol_type == "multih") {
-    protocol = std::make_shared<THeaderProtocol>(transport);
+    typedef TPedanticProtocol<THeaderProtocol> TPedanticHeaderProtocol;
+    protocol = std::make_shared<TPedanticHeaderProtocol>(transport);
   } else {
-    protocol = std::make_shared<TBinaryProtocol>(transport);
+    typedef TPedanticProtocol<TBinaryProtocol> TPedanticBinaryProtocol;
+    protocol = std::make_shared<TPedanticBinaryProtocol>(transport);
   }
 
   if (boost::starts_with(protocol_type, "multi")) {
-  protocol2 = std::make_shared<TMultiplexedProtocol>(protocol, "SecondService");
-  // we don't need access to the original protocol any more, so...
-  protocol = std::make_shared<TMultiplexedProtocol>(protocol, "ThriftTest");
+    protocol2 = std::make_shared<TMultiplexedProtocol>(protocol, "SecondService");
+    // we don't need access to the original protocol any more, so...
+    protocol = std::make_shared<TMultiplexedProtocol>(protocol, "ThriftTest");
   }
 
   // Connection info