diff --git a/lib/d/Makefile.am b/lib/d/Makefile.am
new file mode 100644
index 0000000..d76a07e
--- /dev/null
+++ b/lib/d/Makefile.am
@@ -0,0 +1,181 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+
+SUBDIRS = . test
+
+#
+# Enumeration of all the public and private modules.
+#
+# We unconditionally install all of them, even if libevent or OpenSSL are
+# not available, but build the respective libraries only if the Deimos headers
+# could be found.
+#
+d_thriftmodules = $(addprefix thrift/, base)
+d_thriftdir = $(D_IMPORT_PREFIX)/thrift
+d_thrift_DATA = $(addprefix src/, $(addsuffix .d, $(d_thriftmodules)))
+
+d_asyncmodules = $(addprefix thrift/async/, base libevent socket ssl)
+d_asyncdir = $(d_thriftdir)/async
+d_async_DATA = $(addprefix src/, $(addsuffix .d, $(d_asyncmodules)))
+
+d_codegenmodules = $(addprefix thrift/codegen/, async_client \
+	async_client_pool base client client_pool idlgen processor)
+d_codegendir = $(d_thriftdir)/codegen
+d_codegen_DATA = $(addprefix src/, $(addsuffix .d, $(d_codegenmodules)))
+
+d_protocolmodules = $(addprefix thrift/protocol/, base binary compact json \
+	processor)
+d_protocoldir = $(d_thriftdir)/protocol
+d_protocol_DATA = $(addprefix src/, $(addsuffix .d, $(d_protocolmodules)))
+
+d_servermodules = $(addprefix thrift/server/, base simple nonblocking \
+	taskpool threaded)
+d_serverdir = $(d_thriftdir)/server
+d_server_DATA = $(addprefix src/, $(addsuffix .d, $(d_servermodules)))
+
+d_servertransportmodules = $(addprefix thrift/server/transport/, base socket ssl)
+d_servertransportdir = $(d_thriftdir)/server/transport
+d_servertransport_DATA = $(addprefix src/, $(addsuffix .d, \
+	$(d_servertransportmodules)))
+
+d_transportmodules = $(addprefix thrift/transport/, base buffered file \
+	framed http memory piped range socket ssl zlib)
+d_transportdir = $(d_thriftdir)/transport
+d_transport_DATA = $(addprefix src/, $(addsuffix .d, $(d_transportmodules)))
+
+d_utilmodules = $(addprefix thrift/util/, awaitable cancellation future \
+	hashset)
+d_utildir = $(d_thriftdir)/util
+d_util_DATA = $(addprefix src/, $(addsuffix .d, $(d_utilmodules)))
+
+d_internalmodules = $(addprefix thrift/internal/, algorithm codegen ctfe \
+	endian resource_pool socket ssl ssl_bio traits)
+d_internaldir = $(d_thriftdir)/internal
+d_internal_DATA = $(addprefix src/, $(addsuffix .d, $(d_internalmodules)))
+
+d_testmodules = $(addprefix thrift/internal/test/, protocol server)
+d_testdir = $(d_internaldir)/test
+d_test_DATA = $(addprefix src/, $(addsuffix .d, $(d_testmodules)))
+
+d_publicmodules = $(d_thriftmodules) $(d_asyncmodules) \
+	$(d_codegenmodules) $(d_protocolmodules) $(d_servermodules) \
+	$(d_servertransportmodules) $(d_transportmodules) $(d_utilmodules)
+d_publicsources = $(addprefix src/, $(addsuffix .d, $(d_publicmodules)))
+
+d_modules = $(d_publicmodules) $(d_internalmodules) $(d_testmodules)
+
+# List modules with external dependencies and remove them from the main list
+d_libevent_dependent_modules = thrift/async/libevent thrift/server/nonblocking
+d_openssl_dependent_modules = thrift/async/ssl thrift/internal/ssl \
+	thrift/internal/ssl_bio thrift/transport/ssl thrift/server/transport/ssl
+d_main_modules = $(filter-out $(d_libevent_dependent_modules) \
+	$(d_openssl_dependent_modules),$(d_modules))
+
+
+d_lib_flags = -w -wi -Isrc -lib
+all_targets =
+
+#
+# libevent-dependent modules.
+#
+if HAVE_DEIMOS_EVENT2
+$(D_EVENT_LIB_NAME): $(addprefix src/, $(addsuffix .d, $(d_libevent_dependent_modules)))
+	$(DMD) -of$(D_EVENT_LIB_NAME) $(d_lib_flags) $^
+all_targets += $(D_EVENT_LIB_NAME)
+endif
+
+#
+# OpenSSL-dependent modules.
+#
+if HAVE_DEIMOS_OPENSSL
+$(D_SSL_LIB_NAME): $(addprefix src/, $(addsuffix .d, $(d_openssl_dependent_modules)))
+	$(DMD) -of$(D_SSL_LIB_NAME) $(d_lib_flags) $^
+all_targets += $(D_SSL_LIB_NAME)
+endif
+
+#
+# Main library target.
+#
+$(D_LIB_NAME): $(addprefix src/, $(addsuffix .d, $(d_main_modules)))
+	$(DMD) -of$(D_LIB_NAME) $(d_lib_flags) $^
+all_targets += $(D_LIB_NAME)
+
+
+#
+# Documentation target (requires Dil).
+#
+docs: $(d_publicsources) src/thrift/index.d
+	dil ddoc docs -hl --kandil $^
+
+
+#
+# Hook custom library targets into the automake all/install targets.
+#
+all-local: $(all_targets)
+
+install-exec-local:
+	$(INSTALL_PROGRAM) $(all_targets) $(DESTDIR)$(libdir)
+
+
+clean-local:
+	$(RM) -rf docs $(D_LIB_NAME) $(D_EVENT_LIB_NAME) $(D_SSL_LIB_NAME) unittest
+
+
+#
+# Unit tests (built both in debug and release mode).
+#
+d_test_flags = -unittest -w -wi -I$(top_srcdir)/lib/d/src
+
+# There just must be some way to reassign a variable without warnings in
+# Automake...
+d_test_modules__ = $(d_modules)
+
+if WITH_D_EVENT_TESTS
+d_test_flags += $(DMD_LIBEVENT_FLAGS)
+d_test_modules_ = $(d_test_modules__)
+else
+d_test_modules_ = $(filter-out $(d_libevent_dependent_modules), $(d_test_modules__))
+endif
+
+if WITH_D_SSL_TESTS
+d_test_flags += $(DMD_OPENSSL_FLAGS)
+d_test_modules = $(d_test_modules_)
+else
+d_test_modules = $(filter-out $(d_openssl_dependent_modules), $(d_test_modules_))
+endif
+
+unittest/emptymain.d: unittest/.directory
+	@echo 'void main(){}' >$@
+
+unittest/.directory:
+	mkdir -p unittest || exists unittest
+	touch $@
+
+unittest/debug/%: src/%.d $(all_targets) unittest/emptymain.d
+	$(DMD) -gc -of$(subst /,$(DMD_OF_DIRSEP),$@) $(d_test_flags) $^
+
+unittest/release/%: src/%.d $(all_targets) unittest/emptymain.d
+	$(DMD) -O -release -of$(subst /,$(DMD_OF_DIRSEP),$@) $(d_test_flags) $^
+
+TESTS = $(addprefix unittest/debug/, $(d_test_modules)) \
+	$(addprefix unittest/release/, $(d_test_modules))
+
+
+EXTRA_DIST = \
+	README
diff --git a/lib/d/README b/lib/d/README
new file mode 100644
index 0000000..5d37e4f
--- /dev/null
+++ b/lib/d/README
@@ -0,0 +1,58 @@
+Thrift D Software Library
+=========================
+
+License
+-------
+
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+
+Testing
+-------
+
+D support in Thrift is covered by two sets of tests: first,
+the unit test blocks contained in the D source files, and
+second, the more extensive testing applications in the test/
+subdirectory, which also make use of the Thrift compiler.
+Both are built when running "make check", but only the
+unit tests are immediately run, however – the separate test
+cases typically run longer or require manual intervention.
+It might also be prudent to run the independent tests,
+which typically consist of a server and a client part,
+against the other language implementations.
+
+To build the unit tests on Windows, the easiest way might
+be to manually create a file containing an empty main() and
+invoke the compiler by running the following in the src/
+directory (PowerShell syntax):
+
+dmd -ofunittest -unittest -w $(dir -r -filter '*.d' -name)
+
+If you want to run the test clients/servers in OpenSSL
+mode, you have to provide »server-private-key.pem« and
+»server-certificate.pem« files in the directory the server
+executable resides in, and a »trusted-ca-certificate.pem«
+file for the client. The easiest way is to generate a new
+self signed certificate using the provided config file
+(openssl.test.cnf):
+
+openssl req -new -x509 -nodes -config openssl.test.cnf \
+  -out server-certificate.pem
+cat server-certificate.pem > trusted-ca-certificate.pem
+
+This steps are also performed automatically by the
+Autotools build system if the files are not present.
diff --git a/lib/d/src/thrift/async/base.d b/lib/d/src/thrift/async/base.d
new file mode 100644
index 0000000..8debc3b
--- /dev/null
+++ b/lib/d/src/thrift/async/base.d
@@ -0,0 +1,228 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/**
+ * Defines the interface used for client-side handling of asynchronous
+ * I/O operations, based on coroutines.
+ *
+ * The main piece of the »client side« (e.g. for TAsyncClient users) of the
+ * API is TFuture, which represents an asynchronously executed operation,
+ * which can have a return value, throw exceptions, and which can be waited
+ * upon.
+ *
+ * On the »implementation side«, the idea is that by using a TAsyncTransport
+ * instead of a normal TTransport and executing the work through a
+ * TAsyncManager, the same code as for synchronous I/O can be used for
+ * asynchronous operation as well, for example:
+ *
+ * ---
+ * auto socket = new TAsyncSocket(someTAsyncSocketManager(), host, port);
+ * // …
+ * socket.asyncManager.execute(socket, {
+ *   SomeThriftStruct s;
+ *
+ *   // Waiting for socket I/O will not block an entire thread but cause
+ *   // the async manager to execute another task in the meantime, because
+ *   // we are using TAsyncSocket instead of TSocket.
+ *   s.read(socket);
+ *
+ *   // Do something with s, e.g. set a TPromise result to it.
+ *   writeln(s);
+ * });
+ * ---
+ */
+module thrift.async.base;
+
+import core.time : Duration, dur;
+import std.socket/+ : Socket+/; // DMD @@BUG314@@
+import thrift.base;
+import thrift.transport.base;
+import thrift.util.cancellation;
+
+/**
+ * Manages one or more asynchronous transport resources (e.g. sockets in the
+ * case of TAsyncSocketManager) and allows work items to be submitted for them.
+ *
+ * Implementations will typically run one or more background threads for
+ * executing the work, which is one of the reasons for a TAsyncManager to be
+ * used. Each work item is run in its own fiber and is expected to yield() away
+ * while waiting for time-consuming operations.
+ *
+ * The second important purpose of TAsyncManager is to serialize access to
+ * the transport resources – without taking care of that, e.g. issuing multiple
+ * RPC calls over the same connection in rapid succession would likely lead to
+ * more than one request being written at the same time, causing only garbage
+ * to arrive at the remote end.
+ *
+ * All methods are thread-safe.
+ */
+interface TAsyncManager {
+  /**
+   * Submits a work item to be executed asynchronously.
+   *
+   * Access to asnyc transports is serialized – if two work items associated
+   * with the same transport are submitted, the second delegate will not be
+   * invoked until the first has returned, even it the latter context-switches
+   * away (because it is waiting for I/O) and the async manager is idle
+   * otherwise.
+   *
+   * Optionally, a TCancellation instance can be specified. If present,
+   * triggering it will be considered a request to cancel the work item, if it
+   * is still waiting for the associated transport to become available.
+   * Delegates which are already being processed (i.e. waiting for I/O) are not
+   * affected because this would bring the connection into an undefined state
+   * (as probably half-written request or a half-read response would be left
+   * behind).
+   *
+   * Params:
+   *   transport = The TAsyncTransport the work delegate will operate on. Must
+   *     be associated with this TAsyncManager instance.
+   *   work = The operations to execute on the given transport. Must never
+   *     throw, errors should be handled in another way. nothrow semantics are
+   *     difficult to enforce in combination with fibres though, so currently
+   *     exceptions are just swallowed by TAsyncManager implementations.
+   *   cancellation = If set, can be used to request cancellatinon of this work
+   *     item if it is still waiting to be executed.
+   *
+   * Note: The work item will likely be executed in a different thread, so make
+   *   sure the code it relies on is thread-safe. An exception are the async
+   *   transports themselves, to which access is serialized as noted above.
+   */
+  void execute(TAsyncTransport transport, void delegate() work,
+    TCancellation cancellation = null
+  ) in {
+    assert(transport.asyncManager is this,
+      "The given transport must be associated with this TAsyncManager.");
+  }
+
+  /**
+   * Submits a delegate to be executed after a certain amount of time has
+   * passed.
+   *
+   * The actual amount of time elapsed can be higher if the async manager
+   * instance is busy and thus should not be relied on. The
+   *
+   * Params:
+   *   duration = The amount of time to wait before starting to execute the
+   *     work delegate.
+   *   work = The code to execute after the specified amount of time has passed.
+   *
+   * Example:
+   * ---
+   * // A very basic example – usually, the actuall work item would enqueue
+   * // some async transport operation.
+   * auto asyncMangager = someAsyncManager();
+   *
+   * TFuture!int calculate() {
+   *   // Create a promise and asynchronously set its value after three
+   *   // seconds have passed.
+   *   auto promise = new TPromise!int;
+   *   asyncManager.delay(dur!"seconds"(3), {
+   *     promise.succeed(42);
+   *   });
+   *
+   *   // Immediately return it to the caller.
+   *   return promise;
+   * }
+   *
+   * // This will wait until the result is available and then print it.
+   * writeln(calculate().waitGet());
+   * ---
+   */
+  void delay(Duration duration, void delegate() work);
+
+  /**
+   * Shuts down all background threads or other facilities that might have
+   * been started in order to execute work items. This function is typically
+   * called during program shutdown.
+   *
+   * If there are still tasks to be executed when the timeout expires, any
+   * currently executed work items will never receive any notifications
+   * for async transports managed by this instance, queued work items will
+   * be silently dropped, and implementations are allowed to leak resources.
+   *
+   * Params:
+   *   waitFinishTimeout = If positive, waits for all work items to be
+   *     finished for the specified amount of time, if negative, waits for
+   *     completion without ever timing out, if zero, immediately shuts down
+   *     the background facilities.
+   */
+  bool stop(Duration waitFinishTimeout = dur!"hnsecs"(-1));
+}
+
+/**
+ * A TTransport which uses a TAsyncManager to schedule non-blocking operations.
+ *
+ * The actual type of device is not specified; typically, implementations will
+ * depend on an interface derived from TAsyncManager to be notified of changes
+ * in the transport state.
+ *
+ * The peeking, reading, writing and flushing methods must always be called
+ * from within the associated async manager.
+ */
+interface TAsyncTransport : TTransport {
+  /**
+   * The TAsyncManager associated with this transport.
+   */
+  TAsyncManager asyncManager() @property;
+}
+
+/**
+ * A TAsyncManager providing notificiations for socket events.
+ */
+interface TAsyncSocketManager : TAsyncManager {
+  /**
+   * Adds a listener that is triggered once when an event of the specified type
+   * occurs, and removed afterwards.
+   *
+   * Params:
+   *   socket = The socket to listen for events at.
+   *   eventType = The type of the event to listen for.
+   *   timeout = The period of time after which the listener will be called
+   *     with TAsyncEventReason.TIMED_OUT if no event happened.
+   *   listener = The delegate to call when an event happened.
+   */
+  void addOneshotListener(Socket socket, TAsyncEventType eventType,
+    Duration timeout, TSocketEventListener listener);
+
+  /// Ditto
+  void addOneshotListener(Socket socket, TAsyncEventType eventType,
+    TSocketEventListener listener);
+}
+
+/**
+ * Types of events that can happen for an asynchronous transport.
+ */
+enum TAsyncEventType {
+  READ, /// New data became available to read.
+  WRITE /// The transport became ready to be written to.
+}
+
+/**
+ * The type of the delegates used to register socket event handlers.
+ */
+alias void delegate(TAsyncEventReason callReason) TSocketEventListener;
+
+/**
+ * The reason a listener was called.
+ */
+enum TAsyncEventReason : byte {
+  NORMAL, /// The event listened for was triggered normally.
+  TIMED_OUT /// A timeout for the event was set, and it expired.
+}
diff --git a/lib/d/src/thrift/async/libevent.d b/lib/d/src/thrift/async/libevent.d
new file mode 100644
index 0000000..3358bef
--- /dev/null
+++ b/lib/d/src/thrift/async/libevent.d
@@ -0,0 +1,461 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+module thrift.async.libevent;
+
+import core.atomic;
+import core.time : Duration, dur;
+import core.exception : onOutOfMemoryError;
+import core.memory : GC;
+import core.thread : Fiber, Thread;
+import core.sync.condition;
+import core.sync.mutex;
+import core.stdc.stdlib : free, malloc;
+import deimos.event2.event;
+import std.array : empty, front, popFront;
+import std.conv : text, to;
+import std.exception : enforce;
+import std.socket : Socket, socketPair;
+import thrift.base;
+import thrift.async.base;
+import thrift.internal.socket;
+import thrift.internal.traits;
+import thrift.util.cancellation;
+
+// To avoid DMD @@BUG6395@@.
+import thrift.internal.algorithm;
+
+/**
+ * A TAsyncManager implementation based on libevent.
+ *
+ * The libevent loop for handling non-blocking sockets is run in a background
+ * thread, which is lazily spawned. The thread is not daemonized to avoid
+ * crashes on program shutdown, it is only stopped when the manager instance
+ * is destroyed. So, to ensure a clean program teardown, either make sure this
+ * instance gets destroyed (e.g. by using scope), or manually call stop() at
+ * the end.
+ */
+class TLibeventAsyncManager : TAsyncSocketManager {
+  this() {
+    eventBase_ = event_base_new();
+
+    // Set up the socket pair for transferring control messages to the event
+    // loop.
+    auto pair = socketPair();
+    controlSendSocket_ = pair[0];
+    controlReceiveSocket_ = pair[1];
+    controlReceiveSocket_.blocking = false;
+
+    // Register an event for receiving control messages.
+    controlReceiveEvent_ = event_new(eventBase_, controlReceiveSocket_.handle,
+      EV_READ | EV_PERSIST | EV_ET, assumeNothrow(&controlMsgReceiveCallback),
+      cast(void*)this);
+    event_add(controlReceiveEvent_, null);
+
+    queuedCountMutex_ = new Mutex;
+    zeroQueuedCondition_ = new Condition(queuedCountMutex_);
+  }
+
+  ~this() {
+    // stop() should be safe to call, because either we don't have a worker
+    // thread running and it is a no-op anyway, or it is guaranteed to be
+    // still running (blocked in event_base_loop), and thus guaranteed not to
+    // be garbage collected yet.
+    stop(dur!"hnsecs"(0));
+
+    event_free(controlReceiveEvent_);
+    event_base_free(eventBase_);
+    eventBase_ = null;
+  }
+
+  override void execute(TAsyncTransport transport, Work work,
+    TCancellation cancellation = null
+  ) {
+    if (cancellation && cancellation.triggered) return;
+
+    // Keep track that there is a new work item to be processed.
+    incrementQueuedCount();
+
+    ensureWorkerThreadRunning();
+
+    // We should be able to send the control message as a whole – we currently
+    // assume to be able to receive it at once as well. If this proves to be
+    // unstable (e.g. send could possibly return early if the receiving buffer
+    // is full and the blocking call gets interrupted by a signal), it could
+    // be changed to a more sophisticated scheme.
+
+    // Make sure the delegate context doesn't get GCd while the work item is
+    // on the wire.
+    GC.addRoot(work.ptr);
+
+    // Send work message.
+    sendControlMsg(ControlMsg(MsgType.WORK, work, transport));
+
+    if (cancellation) {
+      cancellation.triggering.addCallback({
+        sendControlMsg(ControlMsg(MsgType.CANCEL, work, transport));
+      });
+    }
+  }
+
+  override void delay(Duration duration, void delegate() work) {
+    incrementQueuedCount();
+
+    ensureWorkerThreadRunning();
+
+    const tv = toTimeval(duration);
+
+    // DMD @@BUG@@: Cannot deduce T to void delegate() here.
+    registerOneshotEvent!(void delegate())(
+      -1, 0, assumeNothrow(&delayCallback), &tv,
+      {
+        work();
+        decrementQueuedCount();
+      }
+    );
+  }
+
+  override bool stop(Duration waitFinishTimeout = dur!"hnsecs"(-1)) {
+    bool cleanExit = true;
+
+    synchronized (this) {
+      if (workerThread_) {
+        synchronized (queuedCountMutex_) {
+          if (waitFinishTimeout > dur!"hnsecs"(0)) {
+            if (queuedCount_ > 0) {
+              zeroQueuedCondition_.wait(waitFinishTimeout);
+            }
+          } else if (waitFinishTimeout < dur!"hnsecs"(0)) {
+            while (queuedCount_ > 0) zeroQueuedCondition_.wait();
+          } else {
+            // waitFinishTimeout is zero, immediately exit in all cases.
+          }
+          cleanExit = (queuedCount_ == 0);
+        }
+
+        event_base_loopbreak(eventBase_);
+        sendControlMsg(ControlMsg(MsgType.SHUTDOWN));
+        workerThread_.join();
+        workQueues_ = null;
+        // We have nuked all currently enqueued items, so set the count to
+        // zero. This is safe to do without locking, since the worker thread
+        // is down.
+        queuedCount_ = 0;
+        atomicStore(*(cast(shared)&workerThread_), cast(shared(Thread))null);
+      }
+    }
+
+    return cleanExit;
+  }
+
+  override void addOneshotListener(Socket socket, TAsyncEventType eventType,
+     TSocketEventListener listener
+  ) {
+    addOneshotListenerImpl(socket, eventType, null, listener);
+  }
+
+  override void addOneshotListener(Socket socket, TAsyncEventType eventType,
+    Duration timeout, TSocketEventListener listener
+  ) {
+    if (timeout <= dur!"hnsecs"(0)) {
+      addOneshotListenerImpl(socket, eventType, null, listener);
+    } else {
+      // This is not really documented well, but libevent does not require to
+      // keep the timeval around after the event was added.
+      auto tv = toTimeval(timeout);
+      addOneshotListenerImpl(socket, eventType, &tv, listener);
+    }
+  }
+
+private:
+  alias void delegate() Work;
+
+  void addOneshotListenerImpl(Socket socket, TAsyncEventType eventType,
+     const(timeval)* timeout, TSocketEventListener listener
+  ) {
+    registerOneshotEvent(socket.handle, libeventEventType(eventType),
+      assumeNothrow(&socketCallback), timeout, listener);
+  }
+
+  void registerOneshotEvent(T)(evutil_socket_t fd, short type,
+    event_callback_fn callback, const(timeval)* timeout, T payload
+  ) {
+    // Create a copy of the payload on the C heap.
+    auto payloadMem = malloc(payload.sizeof);
+    if (!payloadMem) onOutOfMemoryError();
+    (cast(T*)payloadMem)[0 .. 1] = payload;
+    GC.addRange(payloadMem, payload.sizeof);
+
+    auto result = event_base_once(eventBase_, fd, type, callback,
+      payloadMem, timeout);
+
+    // Assuming that we didn't get our arguments wrong above, the only other
+    // situation in which event_base_once can fail is when it can't allocate
+    // memory.
+    if (result != 0) onOutOfMemoryError();
+  }
+
+  enum MsgType : ubyte {
+    SHUTDOWN,
+    WORK,
+    CANCEL
+  }
+
+  struct ControlMsg {
+    MsgType type;
+    Work work;
+    TAsyncTransport transport;
+  }
+
+  /**
+   * Starts the worker thread if it is not already running.
+   */
+  void ensureWorkerThreadRunning() {
+    // Technically, only half barriers would be required here, but adding the
+    // argument seems to trigger a DMD template argument deduction @@BUG@@.
+    if (!atomicLoad(*(cast(shared)&workerThread_))) {
+      synchronized (this) {
+        if (!workerThread_) {
+          auto thread = new Thread({ event_base_loop(eventBase_, 0); });
+          thread.start();
+          atomicStore(*(cast(shared)&workerThread_), cast(shared)thread);
+        }
+      }
+    }
+  }
+
+  /**
+   * Sends a control message to the worker thread.
+   */
+  void sendControlMsg(const(ControlMsg) msg) {
+    auto result = controlSendSocket_.send((&msg)[0 .. 1]);
+    enum size = msg.sizeof;
+    enforce(result == size, new TException(text(
+      "Sending control message of type ", msg.type, " failed (", result,
+      " bytes instead of ", size, " transmitted).")));
+  }
+
+  /**
+   * Receives messages from the control message socket and acts on them. Called
+   * from the worker thread.
+   */
+  void receiveControlMsg() {
+    // Read as many new work items off the socket as possible (at least one
+    // should be available, as we got notified by libevent).
+    ControlMsg msg;
+    ptrdiff_t bytesRead;
+    while (true) {
+      bytesRead = controlReceiveSocket_.receive(cast(ubyte[])((&msg)[0 .. 1]));
+
+      if (bytesRead < 0) {
+        auto errno = getSocketErrno();
+        if (errno != WOULD_BLOCK_ERRNO) {
+          logError("Reading control message, some work item will possibly " ~
+            "never be executed: %s", socketErrnoString(errno));
+        }
+      }
+      if (bytesRead != msg.sizeof) break;
+
+      // Everything went fine, we received a new control message.
+      final switch (msg.type) {
+        case MsgType.SHUTDOWN:
+          // The message was just intended to wake us up for shutdown.
+          break;
+
+        case MsgType.CANCEL:
+          // When processing a cancellation, we must not touch the first item,
+          // since it is already being processed.
+          auto queue = workQueues_[msg.transport];
+          if (queue.length > 0) {
+            workQueues_[msg.transport] = [queue[0]] ~
+              removeEqual(queue[1 .. $], msg.work);
+          }
+          break;
+
+        case MsgType.WORK:
+          // Now that the work item is back in the D world, we don't need the
+          // extra GC root for the context pointer anymore (see execute()).
+          GC.removeRoot(msg.work.ptr);
+
+          // Add the work item to the queue and execute it.
+          auto queue = msg.transport in workQueues_;
+          if (queue is null || (*queue).empty) {
+            // If the queue is empty, add the new work item to the queue as well,
+            // but immediately start executing it.
+            workQueues_[msg.transport] = [msg.work];
+            executeWork(msg.transport, msg.work);
+          } else {
+            (*queue) ~= msg.work;
+          }
+          break;
+      }
+    }
+
+    // If the last read was successful, but didn't read enough bytes, we got
+    // a problem.
+    if (bytesRead > 0) {
+      logError("Unexpected partial control message read (%s byte(s) " ~
+        "instead of %s), some work item will possibly never be executed.",
+        bytesRead, msg.sizeof);
+    }
+  }
+
+  /**
+   * Executes the given work item and all others enqueued for the same
+   * transport in a new fiber. Called from the worker thread.
+   */
+  void executeWork(TAsyncTransport transport, Work work) {
+    (new Fiber({
+      auto item = work;
+      while (true) {
+        try {
+          // Execute the actual work. It will possibly add listeners to the
+          // event loop and yield away if it has to wait for blocking
+          // operations. It is quite possible that another fiber will modify
+          // the work queue for the current transport.
+          item();
+        } catch (Exception e) {
+          // This should never happen, just to be sure the worker thread
+          // doesn't stop working in mysterious ways because of an unhandled
+          // exception.
+          logError("Exception thrown by work item: %s", e);
+        }
+
+        // Remove the item from the work queue.
+        // Note: Due to the value semantics of array slices, we have to
+        // re-lookup this on every iteration. This could be solved, but I'd
+        // rather replace this directly with a queue type once one becomes
+        // available in Phobos.
+        auto queue = workQueues_[transport];
+        assert(queue.front == item);
+        queue.popFront();
+        workQueues_[transport] = queue;
+
+        // Now that the work item is done, no longer count it as queued.
+        decrementQueuedCount();
+
+        if (queue.empty) break;
+
+        // If the queue is not empty, execute the next waiting item.
+        item = queue.front;
+      }
+    })).call();
+  }
+
+  /**
+   * Increments the amount of queued items.
+   */
+  void incrementQueuedCount() {
+    synchronized (queuedCountMutex_) {
+      ++queuedCount_;
+    }
+  }
+
+  /**
+   * Decrements the amount of queued items.
+   */
+  void decrementQueuedCount() {
+    synchronized (queuedCountMutex_) {
+      assert(queuedCount_ > 0);
+      --queuedCount_;
+      if (queuedCount_ == 0) {
+        zeroQueuedCondition_.notifyAll();
+      }
+    }
+  }
+
+  static extern(C) void controlMsgReceiveCallback(evutil_socket_t, short,
+    void *managerThis
+  ) {
+    (cast(TLibeventAsyncManager)managerThis).receiveControlMsg();
+  }
+
+  static extern(C) void socketCallback(evutil_socket_t, short flags,
+    void *arg
+  ) {
+    auto reason = (flags & EV_TIMEOUT) ? TAsyncEventReason.TIMED_OUT :
+      TAsyncEventReason.NORMAL;
+    (*(cast(TSocketEventListener*)arg))(reason);
+    GC.removeRange(arg);
+    clear(arg);
+    free(arg);
+  }
+
+  static extern(C) void delayCallback(evutil_socket_t, short flags,
+    void *arg
+  ) {
+    assert(flags & EV_TIMEOUT);
+    (*(cast(void delegate()*)arg))();
+    GC.removeRange(arg);
+    clear(arg);
+    free(arg);
+  }
+
+  Thread workerThread_;
+
+  event_base* eventBase_;
+
+  /// The socket used for receiving new work items in the event loop. Paired
+  /// with controlSendSocket_. Invalid (i.e. TAsyncWorkItem.init) items are
+  /// ignored and can be used to wake up the worker thread.
+  Socket controlReceiveSocket_;
+  event* controlReceiveEvent_;
+
+  /// The socket used to send new work items to the event loop. It is
+  /// expected that work items can always be read at once from it, i.e. that
+  /// there will never be short reads.
+  Socket controlSendSocket_;
+
+  /// Queued up work delegates for async transports. This also includes
+  /// currently active ones, they are removed from the queue on completion,
+  /// which is relied on by the control message receive fiber (the main one)
+  /// to decide whether to immediately start executing items or not.
+  // TODO: This should really be of some queue type, not an array slice, but
+  // std.container doesn't have anything.
+  Work[][TAsyncTransport] workQueues_;
+
+  /// The total number of work items not yet finished (queued and currently
+  /// excecuted) and delays not yet executed.
+  uint queuedCount_;
+
+  /// Protects queuedCount_.
+  Mutex queuedCountMutex_;
+
+  /// Triggered when queuedCount_ reaches zero, protected by queuedCountMutex_.
+  Condition zeroQueuedCondition_;
+}
+
+private {
+  timeval toTimeval(const(Duration) dur) {
+    timeval tv = {tv_sec: cast(int)dur.total!"seconds"(),
+      tv_usec: dur.fracSec.usecs};
+    return tv;
+  }
+
+  /**
+   * Returns the libevent flags combination to represent a given TAsyncEventType.
+   */
+  short libeventEventType(TAsyncEventType type) {
+    final switch (type) {
+      case TAsyncEventType.READ:
+        return EV_READ | EV_ET;
+      case TAsyncEventType.WRITE:
+        return EV_WRITE | EV_ET;
+    }
+  }
+}
diff --git a/lib/d/src/thrift/async/socket.d b/lib/d/src/thrift/async/socket.d
new file mode 100644
index 0000000..6de13d9
--- /dev/null
+++ b/lib/d/src/thrift/async/socket.d
@@ -0,0 +1,357 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+module thrift.async.socket;
+
+import core.thread : Fiber;
+import core.time : dur, Duration;
+import std.array : empty;
+import std.conv : to;
+import std.exception : enforce;
+import std.socket;
+import thrift.base;
+import thrift.async.base;
+import thrift.transport.base;
+import thrift.transport.socket : TSocketBase;
+import thrift.internal.endian;
+import thrift.internal.socket;
+
+version (Windows) {
+  import std.c.windows.winsock : connect;
+} else version (Posix) {
+  import core.sys.posix.sys.socket : connect;
+} else static assert(0, "Don't know connect on this platform.");
+
+/**
+ * Non-blocking socket implementation of the TTransport interface.
+ *
+ * Whenever a socket operation would block, TAsyncSocket registers a callback
+ * with the specified TAsyncSocketManager and yields.
+ *
+ * As for thrift.transport.socket, due to the limitations of std.socket,
+ * currently only TCP/IP sockets are supported (i.e. Unix domain sockets are
+ * not).
+ */
+class TAsyncSocket : TSocketBase, TAsyncTransport {
+  /**
+   * Constructor that takes an already created, connected (!) socket.
+   *
+   * Params:
+   *   asyncManager = The TAsyncSocketManager to use for non-blocking I/O.
+   *   socket = Already created, connected socket object. Will be switched to
+   *     non-blocking mode if it isn't already.
+   */
+  this(TAsyncSocketManager asyncManager, Socket socket) {
+    asyncManager_ = asyncManager;
+    socket.blocking = false;
+    super(socket);
+  }
+
+  /**
+   * Creates a new unconnected socket that will connect to the given host
+   * on the given port.
+   *
+   * Params:
+   *   asyncManager = The TAsyncSocketManager to use for non-blocking I/O.
+   *   host = Remote host.
+   *   port = Remote port.
+   */
+  this(TAsyncSocketManager asyncManager, string host, ushort port) {
+    asyncManager_ = asyncManager;
+    super(host, port);
+  }
+
+  override TAsyncManager asyncManager() @property {
+    return asyncManager_;
+  }
+
+  /**
+   * Asynchronously connects the socket.
+   *
+   * Completes without blocking and defers further operations on the socket
+   * until the connection is established. If connecting fails, this is
+   * currently not indicated in any way other than every call to read/write
+   * failing.
+   */
+  override void open() {
+    if (isOpen) return;
+
+    enforce(!host_.empty, new TTransportException(
+      "Cannot open null host.", TTransportException.Type.NOT_OPEN));
+    enforce(port_ != 0, new TTransportException(
+      "Cannot open with null port.", TTransportException.Type.NOT_OPEN));
+
+
+    // Cannot use std.socket.Socket.connect here because it hides away
+    // EINPROGRESS/WSAWOULDBLOCK.
+    Address addr;
+    try {
+      // Currently, we just go with the first address returned, could be made
+      // more intelligent though – IPv6?
+      addr = getAddress(host_, port_)[0];
+    } catch (Exception e) {
+      throw new TTransportException(`Unable to resolve host "` ~ host_ ~ `".`,
+        TTransportException.Type.NOT_OPEN, __FILE__, __LINE__, e);
+    }
+
+    socket_ = new TcpSocket(addr.addressFamily);
+    socket_.blocking = false;
+    setSocketOpts();
+
+    auto errorCode = connect(socket_.handle, addr.name(), addr.nameLen());
+    if (errorCode == 0) {
+      // If the connection could be established immediately, just return. I
+      // don't know if this ever happens.
+      return;
+    }
+
+    auto errno = getSocketErrno();
+    if (errno != CONNECT_INPROGRESS_ERRNO) {
+      throw new TTransportException(`Could not establish connection to "` ~
+        host_ ~ `": ` ~ socketErrnoString(errno),
+        TTransportException.Type.NOT_OPEN);
+    }
+
+    // This is the expected case: connect() signalled that the connection
+    // is being established in the background. Queue up a work item with the
+    // async manager which just defers any other operations on this
+    // TAsyncSocket instance until the socket is ready.
+    asyncManager_.execute(this,
+      {
+        auto fiber = Fiber.getThis();
+        TAsyncEventReason reason = void;
+        asyncManager_.addOneshotListener(socket_, TAsyncEventType.WRITE,
+          connectTimeout,
+          scopedDelegate((TAsyncEventReason r){ reason = r; fiber.call(); })
+        );
+        Fiber.yield();
+
+        if (reason == TAsyncEventReason.TIMED_OUT) {
+          // Close the connection, so that subsequent work items fail immediately.
+          closeImmediately();
+          return;
+        }
+
+        int errorCode = void;
+        socket_.getOption(SocketOptionLevel.SOCKET, cast(SocketOption)SO_ERROR,
+          errorCode);
+
+        if (errorCode) {
+          logInfo("Could not connect TAsyncSocket: %s",
+            socketErrnoString(errorCode));
+
+          // Close the connection, so that subsequent work items fail immediately.
+          closeImmediately();
+          return;
+        }
+
+      }
+    );
+  }
+
+  /**
+   * Closes the socket.
+   *
+   * Will block until all currently active operations are finished before the
+   * socket is closed.
+   */
+  override void close() {
+    if (!isOpen) return;
+
+    import core.sync.condition;
+    import core.sync.mutex;
+
+    auto doneMutex = new Mutex;
+    auto doneCond = new Condition(doneMutex);
+    synchronized (doneMutex) {
+      asyncManager_.execute(this,
+        scopedDelegate(
+          {
+            closeImmediately();
+            synchronized (doneMutex) doneCond.notifyAll();
+          }
+        )
+      );
+      doneCond.wait();
+    }
+  }
+
+  override bool peek() {
+    if (!isOpen) return false;
+
+    ubyte buf;
+    auto r = socket_.receive((&buf)[0..1], SocketFlags.PEEK);
+    if (r == Socket.ERROR) {
+      auto lastErrno = getSocketErrno();
+      static if (connresetOnPeerShutdown) {
+        if (lastErrno == ECONNRESET) {
+          closeImmediately();
+          return false;
+        }
+      }
+      throw new TTransportException("Peeking into socket failed: " ~
+        socketErrnoString(lastErrno), TTransportException.Type.UNKNOWN);
+    }
+    return (r > 0);
+  }
+
+  override size_t read(ubyte[] buf) {
+    enforce(isOpen, new TTransportException(
+      "Cannot read if socket is not open.", TTransportException.Type.NOT_OPEN));
+
+    typeof(getSocketErrno()) lastErrno;
+
+    auto r = yieldOnBlock(socket_.receive(cast(void[])buf),
+      TAsyncEventType.READ);
+
+    // If recv went fine, immediately return.
+    if (r >= 0) return r;
+
+    // Something went wrong, find out how to handle it.
+    lastErrno = getSocketErrno();
+
+    static if (connresetOnPeerShutdown) {
+      // See top comment.
+      if (lastErrno == ECONNRESET) {
+        return 0;
+      }
+    }
+
+    throw new TTransportException("Receiving from socket failed: " ~
+      socketErrnoString(lastErrno), TTransportException.Type.UNKNOWN);
+  }
+
+  override void write(in ubyte[] buf) {
+    size_t sent;
+    while (sent < buf.length) {
+      sent += writeSome(buf[sent .. $]);
+    }
+    assert(sent == buf.length);
+  }
+
+  override size_t writeSome(in ubyte[] buf) {
+    enforce(isOpen, new TTransportException(
+      "Cannot write if socket is not open.", TTransportException.Type.NOT_OPEN));
+
+    auto r = yieldOnBlock(socket_.send(buf), TAsyncEventType.WRITE);
+
+    // Everything went well, just return the number of bytes written.
+    if (r > 0) return r;
+
+    // Handle error conditions.
+    if (r < 0) {
+      auto lastErrno = getSocketErrno();
+
+      auto type = TTransportException.Type.UNKNOWN;
+      if (isSocketCloseErrno(lastErrno)) {
+        type = TTransportException.Type.NOT_OPEN;
+        closeImmediately();
+      }
+
+      throw new TTransportException("Sending to socket failed: " ~
+        socketErrnoString(lastErrno), type);
+    }
+
+    // send() should never return 0.
+    throw new TTransportException("Sending to socket failed (0 bytes written).",
+      TTransportException.Type.UNKNOWN);
+  }
+
+  /// The amount of time in which a conncetion must be established before the
+  /// open() call times out.
+  Duration connectTimeout = dur!"seconds"(5);
+
+private:
+  void closeImmediately() {
+    socket_.close();
+    socket_ = null;
+  }
+
+  T yieldOnBlock(T)(lazy T call, TAsyncEventType eventType) {
+    while (true) {
+      auto result = call();
+      if (result != Socket.ERROR || getSocketErrno() != WOULD_BLOCK_ERRNO) return result;
+
+      // We got an EAGAIN result, register a callback to return here once some
+      // event happens and yield.
+
+      Duration timeout = void;
+      final switch (eventType) {
+        case TAsyncEventType.READ:
+          timeout = recvTimeout_;
+          break;
+        case TAsyncEventType.WRITE:
+          timeout = sendTimeout_;
+          break;
+      }
+
+      auto fiber = Fiber.getThis();
+      assert(fiber, "Current fiber null – not running in TAsyncManager?");
+      TAsyncEventReason eventReason = void;
+      asyncManager_.addOneshotListener(socket_, eventType, timeout,
+        scopedDelegate((TAsyncEventReason reason) {
+          eventReason = reason;
+          fiber.call();
+        })
+      );
+
+      // Yields execution back to the async manager, will return back here once
+      // the above listener is called.
+      Fiber.yield();
+
+      if (eventReason == TAsyncEventReason.TIMED_OUT) {
+        // If we are cancelling the request due to a timed out operation, the
+        // connection is in an undefined state, because the server could decide
+        // to send the requested data later, or we could have already been half-
+        // way into writing a request. Thus, we close the connection to make any
+        // possibly queued up work items fail immediately. Besides, the server
+        // is not very likely to immediately recover after a socket-level
+        // timeout has expired anyway.
+        closeImmediately();
+
+        throw new TTransportException("Timed out while waiting for socket " ~
+          "to get ready to " ~ to!string(eventType) ~ ".",
+          TTransportException.Type.TIMED_OUT);
+      }
+    }
+  }
+
+  /// The TAsyncSocketManager to use for non-blocking I/O.
+  TAsyncSocketManager asyncManager_;
+}
+
+private {
+  // std.socket doesn't include SO_ERROR for reasons unknown.
+  version (linux) {
+    enum SO_ERROR = 4;
+  } else version (OSX) {
+    enum SO_ERROR = 0x1007;
+  } else version (FreeBSD) {
+    enum SO_ERROR = 0x1007;
+  } else version (Win32) {
+    import std.c.windows.winsock : SO_ERROR;
+  } else static assert(false, "Don't know SO_ERROR on this platform.");
+
+  // This hack forces a delegate literal to be scoped, even if it is passed to
+  // a function accepting normal delegates as well. DMD likes to allocate the
+  // context on the heap anyway, but it seems to work for LDC.
+  import std.traits : isDelegate;
+  auto scopedDelegate(D)(scope D d) if (isDelegate!D) {
+    return d;
+  }
+}
diff --git a/lib/d/src/thrift/async/ssl.d b/lib/d/src/thrift/async/ssl.d
new file mode 100644
index 0000000..fe62426
--- /dev/null
+++ b/lib/d/src/thrift/async/ssl.d
@@ -0,0 +1,292 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+module thrift.async.ssl;
+
+import core.thread : Fiber;
+import core.time : Duration;
+import std.array : empty;
+import std.conv : to;
+import std.exception : enforce;
+import std.socket;
+import deimos.openssl.err;
+import deimos.openssl.ssl;
+import thrift.base;
+import thrift.async.base;
+import thrift.async.socket;
+import thrift.internal.ssl;
+import thrift.internal.ssl_bio;
+import thrift.transport.base;
+import thrift.transport.ssl;
+
+/**
+ * Provides SSL/TLS encryption for async sockets.
+ *
+ * This implementation should be considered experimental, as it context-switches
+ * between fibers from within OpenSSL calls, and the safety of this has not yet
+ * been verified.
+ *
+ * For obvious reasons (the SSL connection is stateful), more than one instance
+ * should never be used on a given socket at the same time.
+ */
+// Note: This could easily be extended to other transports in the future as well.
+// There are only two parts of the implementation which don't work with a generic
+// TTransport: 1) the certificate verification, for which peer name/address are
+// needed from the socket, and 2) the connection shutdown, where the associated
+// async manager is needed because close() is not usually called from within a
+// work item.
+final class TAsyncSSLSocket : TBaseTransport {
+  /**
+   * Constructor.
+   *
+   * Params:
+   *   context = The SSL socket context to use. A reference to it is stored so
+   *     that it does not get cleaned up while the socket is used.
+   *   transport = The underlying async network transport to use for
+   *     communication.
+   */
+  this(TAsyncSocket underlyingSocket, TSSLContext context) {
+    socket_ = underlyingSocket;
+    context_ = context;
+    serverSide_ = context.serverSide;
+    accessManager_ = context.accessManager;
+  }
+
+  override bool isOpen() @property {
+    if (ssl_ is null || !socket_.isOpen) return false;
+
+    auto shutdown = SSL_get_shutdown(ssl_);
+    bool shutdownReceived = (shutdown & SSL_RECEIVED_SHUTDOWN) != 0;
+    bool shutdownSent = (shutdown & SSL_SENT_SHUTDOWN) != 0;
+    return !(shutdownReceived && shutdownSent);
+  }
+
+  override bool peek() {
+    if (!isOpen) return false;
+    checkHandshake();
+
+    byte bt = void;
+    auto rc = SSL_peek(ssl_, &bt, bt.sizeof);
+    sslEnforce(rc >= 0, "SSL_peek");
+
+    if (rc == 0) {
+      ERR_clear_error();
+    }
+    return (rc > 0);
+  }
+
+  override void open() {
+    enforce(!serverSide_, "Cannot open a server-side SSL socket.");
+    if (isOpen) return;
+
+    if (ssl_) {
+      // If the underlying socket was automatically closed because of an error
+      // (i.e. close() was called from inside a socket method), we can land
+      // here with the SSL object still allocated; delete it here.
+      cleanupSSL();
+    }
+
+    socket_.open();
+  }
+
+  override void close() {
+    if (!isOpen) return;
+
+    if (ssl_ !is null) {
+      // SSL needs to send/receive data over the socket as part of the shutdown
+      // protocol, so we must execute the calls in the context of the associated
+      // async manager. On the other hand, TTransport clients expect the socket
+      // to be closed when close() returns, so we have to block until the
+      // shutdown work item has been executed.
+      import core.sync.condition;
+      import core.sync.mutex;
+
+      int rc = void;
+      auto doneMutex = new Mutex;
+      auto doneCond = new Condition(doneMutex);
+      synchronized (doneMutex) {
+        socket_.asyncManager.execute(socket_, {
+          rc = SSL_shutdown(ssl_);
+          if (rc == 0) {
+            rc = SSL_shutdown(ssl_);
+          }
+          synchronized (doneMutex) doneCond.notifyAll();
+        });
+        doneCond.wait();
+      }
+
+      if (rc < 0) {
+        // Do not throw an exception here as leaving the transport "open" will
+        // probably produce only more errors, and the chance we can do
+        // something about the error e.g. by retrying is very low.
+        logError("Error while shutting down SSL: %s", getSSLException());
+      }
+
+      cleanupSSL();
+    }
+
+    socket_.close();
+  }
+
+  override size_t read(ubyte[] buf) {
+    checkHandshake();
+    auto rc = SSL_read(ssl_, buf.ptr, cast(int)buf.length);
+    sslEnforce(rc >= 0, "SSL_read");
+    return rc;
+  }
+
+  override void write(in ubyte[] buf) {
+    checkHandshake();
+
+    // Loop in case SSL_MODE_ENABLE_PARTIAL_WRITE is set in SSL_CTX.
+    size_t written = 0;
+    while (written < buf.length) {
+      auto bytes = SSL_write(ssl_, buf.ptr + written,
+        cast(int)(buf.length - written));
+      sslEnforce(bytes > 0, "SSL_write");
+      written += bytes;
+    }
+  }
+
+  override void flush() {
+    checkHandshake();
+
+    auto bio = SSL_get_wbio(ssl_);
+    enforce(bio !is null, new TSSLException("SSL_get_wbio returned null"));
+
+    auto rc = BIO_flush(bio);
+    sslEnforce(rc == 1, "BIO_flush");
+  }
+
+  /**
+   * Whether to use client or server side SSL handshake protocol.
+   */
+  bool serverSide() @property const {
+    return serverSide_;
+  }
+
+  /// Ditto
+  void serverSide(bool value) @property {
+    serverSide_ = value;
+  }
+
+  /**
+   * The access manager to use.
+   */
+  void accessManager(TAccessManager value) @property {
+    accessManager_ = value;
+  }
+
+private:
+  /**
+   * If the condition is false, cleans up the SSL connection and throws the
+   * exception for the last SSL error.
+   */
+  void sslEnforce(bool condition, string location) {
+    if (!condition) {
+      // We need to fetch the error first, as the error stack will be cleaned
+      // when shutting down SSL.
+      auto e = getSSLException(location);
+      cleanupSSL();
+      throw e;
+    }
+  }
+
+  /**
+   * Frees the SSL connection object and clears the SSL error state.
+   */
+  void cleanupSSL() {
+    SSL_free(ssl_);
+    ssl_ = null;
+    ERR_remove_state(0);
+  }
+
+  /**
+   * Makes sure the SSL connection is up and running, and initializes it if not.
+   */
+  void checkHandshake() {
+    enforce(socket_.isOpen, new TTransportException(
+      TTransportException.Type.NOT_OPEN));
+
+    if (ssl_ !is null) return;
+    ssl_ = context_.createSSL();
+
+    auto bio = createTTransportBIO(socket_, false);
+    SSL_set_bio(ssl_, bio, bio);
+
+    int rc = void;
+    if (serverSide_) {
+      rc = SSL_accept(ssl_);
+    } else {
+      rc = SSL_connect(ssl_);
+    }
+    enforce(rc > 0, getSSLException());
+
+    auto addr = socket_.getPeerAddress();
+    authorize(ssl_, accessManager_, addr,
+      (serverSide_ ? addr.toHostNameString() : socket_.host));
+  }
+
+  TAsyncSocket socket_;
+  bool serverSide_;
+  SSL* ssl_;
+  TSSLContext context_;
+  TAccessManager accessManager_;
+}
+
+/**
+ * Wraps passed TAsyncSocket instances into TAsyncSSLSockets.
+ *
+ * Typically used with TAsyncClient. As an unfortunate consequence of the
+ * async client design, the passed transports cannot be statically verified to
+ * be of type TAsyncSocket. Instead, the type is verified at runtime – if a
+ * transport of an unexpected type is passed to getTransport(), it fails,
+ * throwing a TTransportException.
+ *
+ * Example:
+ * ---
+ * auto context = nwe TSSLContext();
+ * ... // Configure SSL context.
+ * auto factory = new TAsyncSSLSocketFactory(context);
+ *
+ * auto socket = new TAsyncSocket(someAsyncManager, host, port);
+ * socket.open();
+ *
+ * auto client = new TAsyncClient!Service(transport, factory,
+ *   new TBinaryProtocolFactory!());
+ * ---
+ */
+class TAsyncSSLSocketFactory : TTransportFactory {
+  ///
+  this(TSSLContext context) {
+    context_ = context;
+  }
+
+  override TAsyncSSLSocket getTransport(TTransport transport) {
+    auto socket = cast(TAsyncSocket)transport;
+    enforce(socket, new TTransportException(
+      "TAsyncSSLSocketFactory requires a TAsyncSocket to work on, not a " ~
+      to!string(typeid(transport)) ~ ".",
+      TTransportException.Type.INTERNAL_ERROR
+    ));
+    return new TAsyncSSLSocket(socket, context_);
+  }
+
+private:
+  TSSLContext context_;
+}
diff --git a/lib/d/src/thrift/base.d b/lib/d/src/thrift/base.d
new file mode 100644
index 0000000..266201b
--- /dev/null
+++ b/lib/d/src/thrift/base.d
@@ -0,0 +1,123 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+module thrift.base;
+
+/**
+ * Common base class for all Thrift exceptions.
+ */
+class TException : Exception {
+  ///
+  this(string msg = "", string file = __FILE__, size_t line = __LINE__,
+    Throwable next = null)
+  {
+    super(msg, file, line, next);
+  }
+}
+
+/**
+ * An operation failed because one or more sub-tasks failed.
+ */
+class TCompoundOperationException : TException {
+  ///
+  this(string msg, Exception[] exceptions, string file = __FILE__,
+    size_t line = __LINE__, Throwable next = null)
+  {
+    super(msg, file, line, next);
+    this.exceptions = exceptions;
+  }
+
+  /// The exceptions thrown by the children of the operation. If applicable,
+  /// the list is ordered in the same way the exceptions occured.
+  Exception[] exceptions;
+}
+
+/// The Thrift version string, used for informative purposes.
+// Note: This is currently hardcoded, but will likely be filled in by the build
+// system in future versions.
+enum VERSION = "0.9.0 dev";
+
+/**
+ * Functions used for logging inside Thrift.
+ *
+ * By default, the formatted messages are written to stdout/stderr, but this
+ * behavior can be overwritten by providing custom g_{Info, Error}LogSink
+ * handlers.
+ *
+ * Examples:
+ * ---
+ * logInfo("An informative message.");
+ * logError("Some error occured: %s", e);
+ * ---
+ */
+alias logFormatted!g_infoLogSink logInfo;
+alias logFormatted!g_errorLogSink logError; /// Ditto
+
+/**
+ * Error and info log message sinks.
+ *
+ * These delegates are called with the log message passed as const(char)[]
+ * argument, and can be overwritten to hook the Thrift libraries up with a
+ * custom logging system. By default, they forward all output to stdout/stderr.
+ */
+__gshared void delegate(const(char)[]) g_infoLogSink;
+__gshared void delegate(const(char)[]) g_errorLogSink; /// Ditto
+
+shared static this() {
+  import std.stdio;
+
+  g_infoLogSink = (const(char)[] text) {
+    stdout.writeln(text);
+  };
+
+  g_errorLogSink = (const(char)[] text) {
+    stderr.writeln(text);
+  };
+}
+
+// This should be private, if it could still be used through the aliases then.
+template logFormatted(alias target) {
+  void logFormatted(string file = __FILE__, int line = __LINE__,
+    T...)(string format, T args) if (
+    __traits(compiles, { target(""); })
+  ) {
+    import std.format, std.stdio;
+    if (target !is null) {
+      scope(exit) g_formatBuffer.clear();
+
+      // Phobos @@BUG@@: If the empty string put() is removed, Appender.data
+      // stays empty.
+      g_formatBuffer.put("");
+
+      formattedWrite(g_formatBuffer, "%s:%s: ", file, line);
+
+      static if (T.length == 0) {
+        g_formatBuffer.put(format);
+      } else {
+        formattedWrite(g_formatBuffer, format, args);
+      }
+      target(g_formatBuffer.data);
+    }
+  }
+}
+
+private {
+  // Use a global, but thread-local buffer for constructing log messages.
+  import std.array : Appender;
+  Appender!(char[]) g_formatBuffer;
+}
diff --git a/lib/d/src/thrift/codegen/async_client.d b/lib/d/src/thrift/codegen/async_client.d
new file mode 100644
index 0000000..e916dea
--- /dev/null
+++ b/lib/d/src/thrift/codegen/async_client.d
@@ -0,0 +1,255 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+module thrift.codegen.async_client;
+
+import std.conv : text, to;
+import std.traits : ParameterStorageClass, ParameterStorageClassTuple,
+  ParameterTypeTuple, ReturnType;
+import thrift.base;
+import thrift.async.base;
+import thrift.codegen.base;
+import thrift.codegen.client;
+import thrift.internal.codegen;
+import thrift.internal.ctfe;
+import thrift.protocol.base;
+import thrift.transport.base;
+import thrift.util.cancellation;
+import thrift.util.future;
+
+/**
+ * Asynchronous Thrift service client which returns the results as TFutures an
+ * uses a TAsyncManager to perform the actual work.
+ *
+ * TAsyncClientBase serves as a supertype for all TAsyncClients for the same
+ * service, which might be instantiated with different concrete protocol types
+ * (there is no covariance for template type parameters), and extends
+ * TFutureInterface!Interface. If Interface is derived from another service
+ * BaseInterface, it also extends TAsyncClientBase!BaseInterface.
+ *
+ * TAsyncClient implements TAsyncClientBase and offers two constructors with
+ * the following signatures:
+ * ---
+ * this(TAsyncTransport trans, TTransportFactory tf, TProtocolFactory pf);
+ * this(TAsyncTransport trans, TTransportFactory itf, TTransportFactory otf,
+ *   TProtocolFactory ipf, TProtocolFactory opf);
+ * ---
+ *
+ * Again, if Interface represents a derived Thrift service,
+ * TAsyncClient!Interface is also derived from TAsyncClient!BaseInterface.
+ *
+ * TAsyncClient can exclusively be used with TAsyncTransports, as it needs to
+ * access the associated TAsyncManager. To set up any wrapper transports
+ * (e.g. buffered, framed) on top of it and to instanciate the protocols to use,
+ * TTransportFactory and TProtocolFactory instances are passed to the
+ * constructors – the three argument constructor is a shortcut if the same
+ * transport and protocol are to be used for both input and output, which is
+ * the most common case.
+ *
+ * If the same transport factory is passed for both input and output transports,
+ * only a single wrapper transport will be created and used for both directions.
+ * This allows easy implementation of protocols like SSL.
+ *
+ * Just as TClient does, TAsyncClient also takes two optional template
+ * arguments which can be used for specifying the actual TProtocol
+ * implementation used for optimization purposes, as virtual calls can
+ * completely be eliminated then. If the actual types of the protocols
+ * instantiated by the factories used does not match the ones statically
+ * specified in the template parameters, a TException is thrown during
+ * construction.
+ *
+ * Example:
+ * ---
+ * // A simple Thrift service.
+ * interface Foo { int foo(); }
+ *
+ * // Create a TAsyncSocketManager – thrift.async.libevent is used for this
+ * // example.
+ * auto manager = new TLibeventAsyncManager;
+ *
+ * // Set up an async transport to use.
+ * auto socket = new TAsyncSocket(manager, host, port);
+ *
+ * // Create a client instance.
+ * auto client = new TAsyncClient!Foo(
+ *   socket,
+ *   new TBufferedTransportFactory, // Wrap the socket in a TBufferedTransport.
+ *   new TBinaryProtocolFactory!() // Use the Binary protocol.
+ * );
+ *
+ * // Call foo and use the returned future.
+ * auto result = client.foo();
+ * pragma(msg, typeof(result)); // TFuture!int
+ * int resultValue = result.waitGet(); // Waits until the result is available.
+ * ---
+ */
+interface TAsyncClientBase(Interface) if (isBaseService!Interface) :
+  TFutureInterface!Interface
+{
+  /**
+   * The underlying TAsyncTransport used by this client instance.
+   */
+  TAsyncTransport transport() @property;
+}
+
+/// Ditto
+interface TAsyncClientBase(Interface) if (isDerivedService!Interface) :
+  TAsyncClientBase!(BaseService!Interface), TFutureInterface!Interface
+{}
+
+/// Ditto
+template TAsyncClient(Interface, InputProtocol = TProtocol, OutputProtocol = void) if (
+  isService!Interface && isTProtocol!InputProtocol &&
+  (isTProtocol!OutputProtocol || is(OutputProtocol == void))
+) {
+  mixin({
+    static if (isDerivedService!Interface) {
+      string code = "class TAsyncClient : " ~
+        "TAsyncClient!(BaseService!Interface, InputProtocol, OutputProtocol), " ~
+        "TAsyncClientBase!Interface {\n";
+      code ~= q{
+        this(TAsyncTransport trans, TTransportFactory tf, TProtocolFactory pf) {
+          this(trans, tf, tf, pf, pf);
+        }
+
+        this(TAsyncTransport trans, TTransportFactory itf,
+          TTransportFactory otf, TProtocolFactory ipf, TProtocolFactory opf
+        ) {
+          super(trans, itf, otf, ipf, opf);
+          client_ = new typeof(client_)(iprot_, oprot_);
+        }
+
+        private TClient!(Interface, IProt, OProt) client_;
+      };
+    } else {
+      string code = "class TAsyncClient : TAsyncClientBase!Interface {";
+      code ~= q{
+        alias InputProtocol IProt;
+        static if (isTProtocol!OutputProtocol) {
+          alias OutputProtocol OProt;
+        } else {
+          static assert(is(OutputProtocol == void));
+          alias InputProtocol OProt;
+        }
+
+        this(TAsyncTransport trans, TTransportFactory tf, TProtocolFactory pf) {
+          this(trans, tf, tf, pf, pf);
+        }
+
+        this(TAsyncTransport trans, TTransportFactory itf,
+          TTransportFactory otf, TProtocolFactory ipf, TProtocolFactory opf
+        ) {
+          import std.exception;
+          transport_ = trans;
+
+          auto ip = itf.getTransport(trans);
+          TTransport op = void;
+          if (itf == otf) {
+            op = ip;
+          } else {
+            op = otf.getTransport(trans);
+          }
+
+          auto iprot = ipf.getProtocol(ip);
+          iprot_ = cast(IProt)iprot;
+          enforce(iprot_, new TException(text("Input protocol not of the " ~
+            "specified concrete type (", IProt.stringof, ").")));
+
+          auto oprot = opf.getProtocol(op);
+          oprot_ = cast(OProt)oprot;
+          enforce(oprot_, new TException(text("Output protocol not of the " ~
+            "specified concrete type (", OProt.stringof, ").")));
+
+          client_ = new typeof(client_)(iprot_, oprot_);
+        }
+
+        override TAsyncTransport transport() @property {
+          return transport_;
+        }
+
+        protected TAsyncTransport transport_;
+        protected IProt iprot_;
+        protected OProt oprot_;
+        private TClient!(Interface, IProt, OProt) client_;
+      };
+    }
+
+    foreach (methodName;
+      FilterMethodNames!(Interface, __traits(derivedMembers, Interface))
+    ) {
+      string[] paramList;
+      string[] paramNames;
+      foreach (i, _; ParameterTypeTuple!(mixin("Interface." ~ methodName))) {
+        immutable paramName = "param" ~ to!string(i + 1);
+        immutable storage = ParameterStorageClassTuple!(
+          mixin("Interface." ~ methodName))[i];
+
+        paramList ~= ((storage & ParameterStorageClass.ref_) ? "ref " : "") ~
+          "ParameterTypeTuple!(Interface." ~ methodName ~ ")[" ~
+          to!string(i) ~ "] " ~ paramName;
+        paramNames ~= paramName;
+      }
+      paramList ~= "TCancellation cancellation = null";
+
+      immutable returnTypeCode = "ReturnType!(Interface." ~ methodName ~ ")";
+      code ~= "TFuture!(" ~ returnTypeCode ~ ") " ~ methodName ~ "(" ~
+        ctfeJoin(paramList) ~ ") {\n";
+
+      // Create the future instance that will repesent the result.
+      code ~= "auto promise = new TPromise!(" ~ returnTypeCode ~ ");\n";
+
+      // Prepare delegate which executes the TClient method call.
+      code ~= "auto work = {\n";
+      code ~= "try {\n";
+      code ~= "static if (is(ReturnType!(Interface." ~ methodName ~
+        ") == void)) {\n";
+      code ~= "client_." ~ methodName ~ "(" ~ ctfeJoin(paramNames) ~ ");\n";
+      code ~= "promise.succeed();\n";
+      code ~= "} else {\n";
+      code ~= "auto result = client_." ~ methodName ~ "(" ~
+        ctfeJoin(paramNames) ~ ");\n";
+      code ~= "promise.succeed(result);\n";
+      code ~= "}\n";
+      code ~= "} catch (Exception e) {\n";
+      code ~= "promise.fail(e);\n";
+      code ~= "}\n";
+      code ~= "};\n";
+
+      // If the request is cancelled, set the result promise to cancelled
+      // as well. This could be moved into an additional TAsyncWorkItem
+      // delegate parameter.
+      code ~= q{
+        if (cancellation) {
+          cancellation.triggering.addCallback({
+            promise.cancel();
+          });
+        }
+      };
+
+      // Enqueue the work item and immediately return the promise (resp. its
+      // future interface).
+      code ~= "transport_.asyncManager.execute(transport_, work, cancellation);\n";
+      code ~= "return promise;\n";
+      code ~= "}\n";
+
+    }
+
+    code ~= "}\n";
+    return code;
+  }());
+}
diff --git a/lib/d/src/thrift/codegen/async_client_pool.d b/lib/d/src/thrift/codegen/async_client_pool.d
new file mode 100644
index 0000000..26cb975
--- /dev/null
+++ b/lib/d/src/thrift/codegen/async_client_pool.d
@@ -0,0 +1,906 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/**
+ * Utilities for asynchronously querying multiple servers, building on
+ * TAsyncClient.
+ *
+ * Terminology note: The names of the artifacts defined in this module are
+ *   derived from »client pool«, because they operate on a pool of
+ *   TAsyncClients. However, from a architectural point of view, they often
+ *   represent a pool of hosts a Thrift client application communicates with
+ *   using RPC calls.
+ */
+module thrift.codegen.async_client_pool;
+
+import core.sync.mutex;
+import core.time : Duration, dur;
+import std.algorithm : map;
+import std.array : array, empty;
+import std.exception : enforce;
+import std.traits : ParameterTypeTuple, ReturnType;
+import thrift.base;
+import thrift.codegen.base;
+import thrift.codegen.async_client;
+import thrift.internal.algorithm;
+import thrift.internal.codegen;
+import thrift.util.awaitable;
+import thrift.util.cancellation;
+import thrift.util.future;
+import thrift.internal.resource_pool;
+
+/**
+ * Represents a generic client pool which implements TFutureInterface!Interface
+ * using multiple TAsyncClients.
+ */
+interface TAsyncClientPoolBase(Interface) if (isService!Interface) :
+  TFutureInterface!Interface
+{
+  /// Shorthand for the client type this pool operates on.
+  alias TAsyncClientBase!Interface Client;
+
+  /**
+   * Adds a client to the pool.
+   */
+  void addClient(Client client);
+
+  /**
+   * Removes a client from the pool.
+   *
+   * Returns: Whether the client was found in the pool.
+   */
+  bool removeClient(Client client);
+
+  /**
+   * Called to determine whether an exception comes from a client from the
+   * pool not working properly, or if it an exception thrown at the
+   * application level.
+   *
+   * If the delegate returns true, the server/connection is considered to be
+   * at fault, if it returns false, the exception is just passed on to the
+   * caller.
+   *
+   * By default, returns true for instances of TTransportException and
+   * TApplicationException, false otherwise.
+   */
+  bool delegate(Exception) rpcFaultFilter() const @property;
+  void rpcFaultFilter(bool delegate(Exception)) @property; /// Ditto
+
+  /**
+   * Whether to open the underlying transports of a client before trying to
+   * execute a method if they are not open. This is usually desirable
+   * because it allows e.g. to automatically reconnect to a remote server
+   * if the network connection is dropped.
+   *
+   * Defaults to true.
+   */
+  bool reopenTransports() const @property;
+  void reopenTransports(bool) @property; /// Ditto
+}
+
+immutable bool delegate(Exception) defaultRpcFaultFilter;
+static this() {
+  defaultRpcFaultFilter = (Exception e) {
+    import thrift.protocol.base;
+    import thrift.transport.base;
+    return (
+      (cast(TTransportException)e !is null) ||
+      (cast(TApplicationException)e !is null)
+    );
+  };
+}
+
+/**
+ * A TAsyncClientPoolBase implementation which queries multiple servers in a
+ * row until a request succeeds, the result of which is then returned.
+ *
+ * The definition of »success« can be customized using the rpcFaultFilter()
+ * delegate property. If it is non-null and calling it for an exception set by
+ * a failed method invocation returns true, the error is considered to be
+ * caused by the RPC layer rather than the application layer, and the next
+ * server in the pool is tried. If there are no more clients to try, the
+ * operation is marked as failed with a TCompoundOperationException.
+ *
+ * If a TAsyncClient in the pool fails with an RPC exception for a number of
+ * consecutive tries, it is temporarily disabled (not tried any longer) for
+ * a certain duration. Both the limit and the timeout can be configured. If all
+ * clients fail (and keepTrying is false), the operation fails with a
+ * TCompoundOperationException which contains the collected RPC exceptions.
+ */
+final class TAsyncClientPool(Interface) if (isService!Interface) :
+  TAsyncClientPoolBase!Interface
+{
+  ///
+  this(Client[] clients) {
+    pool_ = new TResourcePool!Client(clients);
+    rpcFaultFilter_ = defaultRpcFaultFilter;
+    reopenTransports_ = true;
+  }
+
+  /+override+/ void addClient(Client client) {
+    pool_.add(client);
+  }
+
+  /+override+/ bool removeClient(Client client) {
+    return pool_.remove(client);
+  }
+
+  /**
+   * Whether to keep trying to find a working client if all have failed in a
+   * row.
+   *
+   * Defaults to false.
+   */
+  bool keepTrying() const @property {
+    return pool_.cycle;
+  }
+
+  /// Ditto
+  void keepTrying(bool value) @property {
+    pool_.cycle = value;
+  }
+
+  /**
+   * Whether to use a random permutation of the client pool on every call to
+   * execute(). This can be used e.g. as a simple form of load balancing.
+   *
+   * Defaults to true.
+   */
+  bool permuteClients() const @property {
+    return pool_.permute;
+  }
+
+  /// Ditto
+  void permuteClients(bool value) @property {
+    pool_.permute = value;
+  }
+
+  /**
+   * The number of consecutive faults after which a client is disabled until
+   * faultDisableDuration has passed. 0 to never disable clients.
+   *
+   * Defaults to 0.
+   */
+  ushort faultDisableCount() const @property {
+    return pool_.faultDisableCount;
+  }
+
+  /// Ditto
+  void faultDisableCount(ushort value) @property {
+    pool_.faultDisableCount = value;
+  }
+
+  /**
+   * The duration for which a client is no longer considered after it has
+   * failed too often.
+   *
+   * Defaults to one second.
+   */
+  Duration faultDisableDuration() const @property {
+    return pool_.faultDisableDuration;
+  }
+
+  /// Ditto
+  void faultDisableDuration(Duration value) @property {
+    pool_.faultDisableDuration = value;
+  }
+
+  /+override+/ bool delegate(Exception) rpcFaultFilter() const @property {
+    return rpcFaultFilter_;
+  }
+
+  /+override+/ void rpcFaultFilter(bool delegate(Exception) value) @property {
+    rpcFaultFilter_ = value;
+  }
+
+  /+override+/ bool reopenTransports() const @property {
+    return reopenTransports_;
+  }
+
+  /+override+/ void reopenTransports(bool value) @property {
+    reopenTransports_ = value;
+  }
+
+  mixin(fallbackPoolForwardCode!Interface());
+
+protected:
+  // The actual worker implementation to which RPC method calls are forwarded.
+  auto executeOnPool(string method, Args...)(Args args,
+    TCancellation cancellation
+  ) {
+    auto clients = pool_[];
+    if (clients.empty) {
+      throw new TException("No clients available to try.");
+    }
+
+    auto promise = new TPromise!(ReturnType!(MemberType!(Interface, method)));
+    Exception[] rpcExceptions;
+
+    void tryNext() {
+      while (clients.empty) {
+        Client next;
+        Duration waitTime;
+        if (clients.willBecomeNonempty(next, waitTime)) {
+          if (waitTime > dur!"hnsecs"(0)) {
+            if (waitTime < dur!"usecs"(10)) {
+              import core.thread;
+              Thread.sleep(waitTime);
+            } else {
+              next.transport.asyncManager.delay(waitTime, { tryNext(); });
+              return;
+            }
+          }
+        } else {
+          promise.fail(new TCompoundOperationException("All clients failed.",
+            rpcExceptions));
+          return;
+        }
+      }
+
+      auto client = clients.front;
+      clients.popFront;
+
+      if (reopenTransports) {
+        if (!client.transport.isOpen) {
+          try {
+            client.transport.open();
+          } catch (Exception e) {
+            pool_.recordFault(client);
+            tryNext();
+            return;
+          }
+        }
+      }
+
+      auto future = mixin("client." ~ method)(args, cancellation);
+      future.completion.addCallback({
+        if (future.status == TFutureStatus.CANCELLED) {
+          promise.cancel();
+          return;
+        }
+
+        auto e = future.getException();
+        if (e) {
+          if (rpcFaultFilter_ && rpcFaultFilter_(e)) {
+            pool_.recordFault(client);
+            rpcExceptions ~= e;
+            tryNext();
+            return;
+          }
+        }
+        pool_.recordSuccess(client);
+        promise.complete(future);
+      });
+    }
+
+    tryNext();
+    return promise;
+  }
+
+private:
+  TResourcePool!Client pool_;
+  bool delegate(Exception) rpcFaultFilter_;
+  bool reopenTransports_;
+}
+
+/**
+ * TAsyncClientPool construction helper to avoid having to explicitly
+ * specify the interface type, i.e. to allow the constructor being called
+ * using IFTI (see $(DMDBUG 6082, D Bugzilla enhancement request 6082)).
+ */
+TAsyncClientPool!Interface tAsyncClientPool(Interface)(
+  TAsyncClientBase!Interface[] clients
+) if (isService!Interface) {
+  return new typeof(return)(clients);
+}
+
+private {
+  // Cannot use an anonymous delegate literal for this because they aren't
+  // allowed in class scope.
+  string fallbackPoolForwardCode(Interface)() {
+    string code = "";
+
+    foreach (methodName; AllMemberMethodNames!Interface) {
+      enum qn = "Interface." ~ methodName;
+      code ~= "TFuture!(ReturnType!(" ~ qn ~ ")) " ~ methodName ~
+        "(ParameterTypeTuple!(" ~ qn ~ ") args, TCancellation cancellation = null) {\n";
+      code ~= "return executeOnPool!(`" ~ methodName ~ "`)(args, cancellation);\n";
+      code ~= "}\n";
+    }
+
+    return code;
+  }
+}
+
+/**
+ * A TAsyncClientPoolBase implementation which queries multiple servers at
+ * the same time and returns the first success response.
+ *
+ * The definition of »success« can be customized using the rpcFaultFilter()
+ * delegate property. If it is non-null and calling it for an exception set by
+ * a failed method invocation returns true, the error is considered to be
+ * caused by the RPC layer rather than the application layer, and the next
+ * server in the pool is tried. If all clients fail, the operation is marked
+ * as failed with a TCompoundOperationException.
+ */
+final class TAsyncFastestClientPool(Interface) if (isService!Interface) :
+  TAsyncClientPoolBase!Interface
+{
+  ///
+  this(Client[] clients) {
+    clients_ = clients;
+    rpcFaultFilter_ = defaultRpcFaultFilter;
+    reopenTransports_ = true;
+  }
+
+  /+override+/ void addClient(Client client) {
+    clients_ ~= client;
+  }
+
+  /+override+/ bool removeClient(Client client) {
+    auto oldLength = clients_.length;
+    clients_ = removeEqual(clients_, client);
+    return clients_.length < oldLength;
+  }
+
+
+  /+override+/ bool delegate(Exception) rpcFaultFilter() const @property {
+    return rpcFaultFilter_;
+  }
+
+  /+override+/ void rpcFaultFilter(bool delegate(Exception) value) @property {
+    rpcFaultFilter_ = value;
+  }
+
+  /+override+/bool reopenTransports() const @property {
+    return reopenTransports_;
+  }
+
+  /+override+/ void reopenTransports(bool value) @property {
+    reopenTransports_ = value;
+  }
+
+  mixin(fastestPoolForwardCode!Interface());
+
+private:
+  Client[] clients_;
+  bool delegate(Exception) rpcFaultFilter_;
+  bool reopenTransports_;
+}
+
+/**
+ * TAsyncFastestClientPool construction helper to avoid having to explicitly
+ * specify the interface type, i.e. to allow the constructor being called
+ * using IFTI (see $(DMDBUG 6082, D Bugzilla enhancement request 6082)).
+ */
+TAsyncFastestClientPool!Interface tAsyncFastestClientPool(Interface)(
+  TAsyncClientBase!Interface[] clients
+) if (isService!Interface) {
+  return new typeof(return)(clients);
+}
+
+private {
+  // Cannot use an anonymous delegate literal for this because they aren't
+  // allowed in class scope.
+  string fastestPoolForwardCode(Interface)() {
+    string code = "";
+
+    foreach (methodName; AllMemberMethodNames!Interface) {
+      enum qn = "Interface." ~ methodName;
+      code ~= "TFuture!(ReturnType!(" ~ qn ~ ")) " ~ methodName ~
+        "(ParameterTypeTuple!(" ~ qn ~ ") args, " ~
+        "TCancellation cancellation = null) {\n";
+      code ~= "enum methodName = `" ~ methodName ~ "`;\n";
+      code ~= q{
+        alias ReturnType!(MemberType!(Interface, methodName)) ResultType;
+
+        auto childCancellation = new TCancellationOrigin;
+
+        TFuture!ResultType[] futures;
+        futures.reserve(clients_.length);
+
+        foreach (c; clients_) {
+          if (reopenTransports) {
+            if (!c.transport.isOpen) {
+              try {
+                c.transport.open();
+              } catch (Exception e) {
+                continue;
+              }
+            }
+          }
+          futures ~= mixin("c." ~ methodName)(args, childCancellation);
+        }
+
+        return new FastestPoolJob!(ResultType)(
+          futures, rpcFaultFilter, cancellation, childCancellation);
+      };
+      code ~= "}\n";
+    }
+
+    return code;
+  }
+
+  final class FastestPoolJob(Result) : TFuture!Result {
+    this(TFuture!Result[] poolFutures, bool delegate(Exception) rpcFaultFilter,
+      TCancellation cancellation, TCancellationOrigin childCancellation
+    ) {
+      resultPromise_ = new TPromise!Result;
+      poolFutures_ = poolFutures;
+      rpcFaultFilter_ = rpcFaultFilter;
+      childCancellation_ = childCancellation;
+
+      foreach (future; poolFutures) {
+        future.completion.addCallback({
+          auto f = future;
+          return { completionCallback(f); };
+        }());
+        if (future.status != TFutureStatus.RUNNING) {
+          // If the current future is already completed, we are done, don't
+          // bother adding callbacks for the others (they would just return
+          // immediately after acquiring the lock).
+          return;
+        }
+      }
+
+      if (cancellation) {
+        cancellation.triggering.addCallback({
+          resultPromise_.cancel();
+          childCancellation.trigger();
+        });
+      }
+    }
+
+    TFutureStatus status() const @property {
+      return resultPromise_.status;
+    }
+
+    TAwaitable completion() @property {
+      return resultPromise_.completion;
+    }
+
+    Result get() {
+      return resultPromise_.get();
+    }
+
+    Exception getException() {
+      return resultPromise_.getException();
+    }
+
+  private:
+    void completionCallback(TFuture!Result future) {
+      synchronized {
+        if (future.status == TFutureStatus.CANCELLED) {
+          assert(resultPromise_.status != TFutureStatus.RUNNING);
+          return;
+        }
+
+        if (resultPromise_.status != TFutureStatus.RUNNING) {
+          // The operation has already been completed. This can happen if
+          // another client completed first, but this callback was already
+          // waiting for the lock when it called cancel().
+          return;
+        }
+
+        if (future.status == TFutureStatus.FAILED) {
+          auto e = future.getException();
+          if (rpcFaultFilter_ && rpcFaultFilter_(e)) {
+            rpcExceptions_ ~= e;
+
+            if (rpcExceptions_.length == poolFutures_.length) {
+              resultPromise_.fail(new TCompoundOperationException(
+                "All child operations failed, unable to retrieve a result.",
+                rpcExceptions_
+              ));
+            }
+
+            return;
+          }
+        }
+
+        // Store the result to the target promise.
+        resultPromise_.complete(future);
+
+        // Cancel the other futures, we would just discard their results.
+        // Note: We do this after we have stored the results to our promise,
+        // see the assert at the top of the function.
+        childCancellation_.trigger();
+      }
+    }
+
+    TPromise!Result resultPromise_;
+    TFuture!Result[] poolFutures_;
+    Exception[] rpcExceptions_;
+    bool delegate(Exception) rpcFaultFilter_;
+    TCancellationOrigin childCancellation_;
+  }
+}
+
+/**
+ * Allows easily aggregating results from a number of TAsyncClients.
+ *
+ * Contrary to TAsync{Fallback, Fastest}ClientPool, this class does not
+ * simply implement TFutureInterface!Interface. It manages a pool of clients,
+ * but allows the user to specify a custom accumulator function to use or to
+ * iterate over the results using a TFutureAggregatorRange.
+ *
+ * For each service method, TAsyncAggregator offers a method
+ * accepting the same arguments, and an optional TCancellation instance, just
+ * like with TFutureInterface. The return type, however, is a proxy object
+ * that offers the following methods:
+ * ---
+ * /++
+ *  + Returns a thrift.util.future.TFutureAggregatorRange for the results of
+ *  + the client pool method invocations.
+ *  +
+ *  + The [] (slicing) operator can also be used to obtain the range.
+ *  +
+ *  + Params:
+ *  +   timeout = A timeout to pass to the TFutureAggregatorRange constructor,
+ *  +     defaults to zero (no timeout).
+ *  +/
+ * TFutureAggregatorRange!ReturnType range(Duration timeout = dur!"hnsecs"(0));
+ * auto opSlice() { return range(); } /// Ditto
+ *
+ * /++
+ *  + Returns a future that gathers the results from the clients in the pool
+ *  + and invokes a user-supplied accumulator function on them, returning its
+ *  + return value to the client.
+ *  +
+ *  + In addition to the TFuture!AccumulatedType interface (where
+ *  + AccumulatedType is the return type of the accumulator function), the
+ *  + returned object also offers two additional methods, finish() and
+ *  + finishGet(): By default, the accumulator functions is called after all
+ *  + the results from the pool clients have become available. Calling finish()
+ *  + causes the accumulator future to stop waiting for other results and
+ *  + immediately invoking the accumulator function on the results currently
+ *  + available. If all results are already available, finish() is a no-op.
+ *  + finishGet() is a convenience shortcut for combining it with
+ *  + a call to get() immediately afterwards, like waitGet() is for wait().
+ *  +
+ *  + The acc alias can point to any callable accepting either an array of
+ *  + return values or an array of return values and an array of exceptions;
+ *  + see isAccumulator!() for details. The default accumulator concatenates
+ *  + return values that can be concatenated with each others (e.g. arrays),
+ *  + and simply returns an array of values otherwise, failing with a
+ *  + TCompoundOperationException no values were returned.
+ *  +
+ *  + The accumulator function is not executed in any of the async manager
+ *  + worker threads associated with the async clients, but instead it is
+ *  + invoked when the actual result is requested for the first time after the
+ *  + operation has been completed. This also includes checking the status
+ *  + of the operation once it is no longer running, since the accumulator
+ *  + has to be run to determine whether the operation succeeded or failed.
+ *  +/
+ * auto accumulate(alias acc = defaultAccumulator)() if (isAccumulator!acc);
+ * ---
+ *
+ * Example:
+ * ---
+ * // Some Thrift service.
+ * interface Foo {
+ *   int foo(string name);
+ *   byte[] bar();
+ * }
+ *
+ * // Create the aggregator pool – client0, client1, client2 are some
+ * // TAsyncClient!Foo instances, but in theory could also be other
+ * // TFutureInterface!Foo implementations (e.g. some async client pool).
+ * auto pool = new TAsyncAggregator!Foo([client0, client1, client2]);
+ *
+ * foreach (val; pool.foo("baz").range(dur!"seconds"(1))) {
+ *   // Process all the results that are available before a second has passed,
+ *   // in the order they arrive.
+ *   writeln(val);
+ * }
+ *
+ * auto sumRoots = pool.foo("baz").accumulate!((int[] vals, Exceptions[] exs){
+ *   if (vals.empty) {
+ *     throw new TCompoundOperationException("All clients failed", exs);
+ *   }
+ *
+ *   // Just to illustrate that the type of the values can change, convert the
+ *   // numbers to double and sum up their roots.
+ *   double result = 0;
+ *   foreach (v; vals) result += sqrt(cast(double)v);
+ *   return result;
+ * })();
+ *
+ * // Wait up to three seconds for the result, and then accumulate what has
+ * // arrived so far.
+ * sumRoots.completion.wait(dur!"seconds"(3));
+ * writeln(sumRoots.finishGet());
+ *
+ * // For scalars, the default accumulator returns an array of the values.
+ * pragma(msg, typeof(pool.foo("").accumulate().get()); // int[].
+ *
+ * // For lists, etc., it concatenates the results together.
+ * pragma(msg, typeof(pool.bar().accumulate().get())); // byte[].
+ * ---
+ *
+ * Note: For the accumulate!() interface, you might currently hit a »cannot use
+ * local '…' as parameter to non-global template accumulate«-error, see
+ * $(DMDBUG 5710, DMD issue 5710). If your accumulator function does not need
+ * to access the surrounding scope, you might want to use a function literal
+ * instead of a delegate to avoid the issue.
+ */
+class TAsyncAggregator(Interface) if (isBaseService!Interface) {
+  /// Shorthand for the client type this instance operates on.
+  alias TAsyncClientBase!Interface Client;
+
+  ///
+  this(Client[] clients) {
+    clients_ = clients;
+  }
+
+  /// Whether to open the underlying transports of a client before trying to
+  /// execute a method if they are not open. This is usually desirable
+  /// because it allows e.g. to automatically reconnect to a remote server
+  /// if the network connection is dropped.
+  ///
+  /// Defaults to true.
+  bool reopenTransports = true;
+
+  mixin AggregatorOpDispatch!();
+
+private:
+  Client[] clients_;
+}
+
+/// Ditto
+class TAsyncAggregator(Interface) if (isDerivedService!Interface) :
+  TAsyncAggregator!(BaseService!Interface)
+{
+  /// Shorthand for the client type this instance operates on.
+  alias TAsyncClientBase!Interface Client;
+
+  ///
+  this(Client[] clients) {
+    super(cast(TAsyncClientBase!(BaseService!Interface)[])clients);
+  }
+
+  mixin AggregatorOpDispatch!();
+}
+
+/**
+ * Whether fun is a valid accumulator function for values of type ValueType.
+ *
+ * For this to be true, fun must be a callable matching one of the following
+ * argument lists:
+ * ---
+ * fun(ValueType[] values);
+ * fun(ValueType[] values, Exception[] exceptions);
+ * ---
+ *
+ * The second version is passed the collected array exceptions from all the
+ * clients in the pool.
+ *
+ * The return value of the accumulator function is passed to the client (via
+ * the result future). If it throws an exception, the operation is marked as
+ * failed with the given exception instead.
+ */
+template isAccumulator(ValueType, alias fun) {
+  enum isAccumulator = is(typeof(fun(cast(ValueType[])[]))) ||
+    is(typeof(fun(cast(ValueType[])[], cast(Exception[])[])));
+}
+
+/**
+ * TAsyncAggregator construction helper to avoid having to explicitly
+ * specify the interface type, i.e. to allow the constructor being called
+ * using IFTI (see $(DMDBUG 6082, D Bugzilla enhancement request 6082)).
+ */
+TAsyncAggregator!Interface tAsyncAggregator(Interface)(
+  TAsyncClientBase!Interface[] clients
+) if (isService!Interface) {
+  return new typeof(return)(clients);
+}
+
+private {
+  mixin template AggregatorOpDispatch() {
+    auto opDispatch(string name, Args...)(Args args) if (
+      is(typeof(mixin("Interface.init." ~ name)(args)))
+    ) {
+      alias ReturnType!(MemberType!(Interface, name)) ResultType;
+
+      auto childCancellation = new TCancellationOrigin;
+
+      TFuture!ResultType[] futures;
+      futures.reserve(clients_.length);
+
+      foreach (c; cast(Client[])clients_) {
+        if (reopenTransports) {
+          if (!c.transport.isOpen) {
+            try {
+              c.transport.open();
+            } catch (Exception e) {
+              continue;
+            }
+          }
+        }
+        futures ~= mixin("c." ~ name)(args, childCancellation);
+      }
+
+      return AggregationResult!ResultType(futures, childCancellation);
+    }
+  }
+
+  struct AggregationResult(T) {
+    auto opSlice() {
+      return range();
+    }
+
+    auto range(Duration timeout = dur!"hnsecs"(0)) {
+      return tFutureAggregatorRange(futures_, childCancellation_, timeout);
+    }
+
+    auto accumulate(alias acc = defaultAccumulator)() if (isAccumulator!(T, acc)) {
+      return new AccumulatorJob!(T, acc)(futures_, childCancellation_);
+    }
+
+  private:
+    TFuture!T[] futures_;
+    TCancellationOrigin childCancellation_;
+  }
+
+  auto defaultAccumulator(T)(T[] values, Exception[] exceptions) {
+    if (values.empty) {
+      throw new TCompoundOperationException("All clients failed",
+        exceptions);
+    }
+
+    static if (is(typeof(T.init ~ T.init))) {
+      import std.algorithm;
+      return reduce!"a ~ b"(values);
+    } else {
+      return values;
+    }
+  }
+
+  final class AccumulatorJob(T, alias accumulator) if (
+    isAccumulator!(T, accumulator)
+  ) : TFuture!(AccumulatorResult!(T, accumulator)) {
+    this(TFuture!T[] futures, TCancellationOrigin childCancellation) {
+      futures_ = futures;
+      childCancellation_ = childCancellation;
+      resultMutex_ = new Mutex;
+      completionEvent_ = new TOneshotEvent;
+
+      foreach (future; futures) {
+        future.completion.addCallback({
+          auto f = future;
+          return {
+            synchronized (resultMutex_) {
+              if (f.status == TFutureStatus.CANCELLED) {
+                if (!finished_) {
+                  status_ = TFutureStatus.CANCELLED;
+                  finished_ = true;
+                }
+                return;
+              }
+
+              if (f.status == TFutureStatus.FAILED) {
+                exceptions_ ~= f.getException();
+              } else {
+                results_ ~= f.get();
+              }
+
+              if (results_.length + exceptions_.length == futures_.length) {
+                finished_ = true;
+                completionEvent_.trigger();
+              }
+            }
+          };
+        }());
+      }
+    }
+
+    TFutureStatus status() @property {
+      synchronized (resultMutex_) {
+        if (!finished_) return TFutureStatus.RUNNING;
+        if (status_ != TFutureStatus.RUNNING) return status_;
+
+        try {
+          result_ = invokeAccumulator!accumulator(results_, exceptions_);
+          status_ = TFutureStatus.SUCCEEDED;
+        } catch (Exception e) {
+          exception_ = e;
+          status_ = TFutureStatus.FAILED;
+        }
+
+        return status_;
+      }
+    }
+
+    TAwaitable completion() @property {
+      return completionEvent_;
+    }
+
+    AccumulatorResult!(T, accumulator) get() {
+      auto s = status;
+
+      enforce(s != TFutureStatus.RUNNING,
+        new TFutureException("Operation not yet completed."));
+
+      if (s == TFutureStatus.CANCELLED) throw new TCancelledException;
+      if (s == TFutureStatus.FAILED) throw exception_;
+      return result_;
+    }
+
+    Exception getException() {
+      auto s = status;
+      enforce(s != TFutureStatus.RUNNING,
+        new TFutureException("Operation not yet completed."));
+
+      if (s == TFutureStatus.CANCELLED) throw new TCancelledException;
+
+      if (s == TFutureStatus.SUCCEEDED) {
+        return null;
+      }
+      return exception_;
+    }
+
+    void finish() {
+      synchronized (resultMutex_) {
+        if (!finished_) {
+          finished_ = true;
+          childCancellation_.trigger();
+          completionEvent_.trigger();
+        }
+      }
+    }
+
+    auto finishGet() {
+      finish();
+      return get();
+    }
+
+  private:
+    TFuture!T[] futures_;
+    TCancellationOrigin childCancellation_;
+
+    bool finished_;
+    T[] results_;
+    Exception[] exceptions_;
+
+    TFutureStatus status_;
+    Mutex resultMutex_;
+    union {
+      AccumulatorResult!(T, accumulator) result_;
+      Exception exception_;
+    }
+    TOneshotEvent completionEvent_;
+  }
+
+  auto invokeAccumulator(alias accumulator, T)(
+    T[] values, Exception[] exceptions
+  ) if (
+    isAccumulator!(T, accumulator)
+  ) {
+    static if (is(typeof(accumulator(values, exceptions)))) {
+      return accumulator(values, exceptions);
+    } else {
+      return accumulator(values);
+    }
+  }
+
+  template AccumulatorResult(T, alias acc) {
+    alias typeof(invokeAccumulator!acc(cast(T[])[], cast(Exception[])[]))
+      AccumulatorResult;
+  }
+}
diff --git a/lib/d/src/thrift/codegen/base.d b/lib/d/src/thrift/codegen/base.d
new file mode 100644
index 0000000..e7e3ead
--- /dev/null
+++ b/lib/d/src/thrift/codegen/base.d
@@ -0,0 +1,950 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/**
+ * Code generation metadata and templates used for implementing struct
+ * serialization.
+ *
+ * Many templates can be customized using field meta data, which is read from
+ * a manifest constant member of the given type called fieldMeta (if present),
+ * and is concatenated with the elements from the optional fieldMetaData
+ * template alias parameter.
+ *
+ * Some code generation templates take account of the optional TVerboseCodegen
+ * version declaration, which causes warning messages to be emitted if no
+ * metadata for a field/method has been found and the default behavior is
+ * used instead. If this version is not defined, the templates just silently
+ * behave like the Thrift compiler does in this situation, i.e. automatically
+ * assign negative ids (starting at -1) for fields and assume TReq.AUTO as
+ * requirement level.
+ */
+// Implementation note: All the templates in here taking a field metadata
+// parameter should ideally have a constraint that restricts the alias to
+// TFieldMeta[]-typed values, but the is() expressions seems to always fail.
+module thrift.codegen.base;
+
+import std.algorithm : find;
+import std.array : empty, front;
+import std.conv : to;
+import std.exception : enforce;
+import std.traits : BaseTypeTuple, isPointer, isSomeFunction, pointerTarget,
+  ReturnType;
+import thrift.base;
+import thrift.internal.codegen;
+import thrift.protocol.base;
+
+/*
+ * Thrift struct/service meta data, which is used to store information from
+ * the interface definition files not representable in plain D, i.e. field
+ * requirement levels, Thrift field IDs, etc.
+ */
+
+/**
+ * Struct field requirement levels.
+ */
+enum TReq {
+  /// Detect the requiredness from the field type: if it is nullable, treat
+  /// the field as optional, if it is non-nullable, treat the field as
+  /// required. This is the default used for handling structs not generated
+  /// from an IDL file, and never emitted by the Thrift compiler. TReq.AUTO
+  /// shouldn't be specified explicitly.
+  // Implementation note: thrift.codegen templates use
+  // thrift.internal.codegen.memberReq to resolve AUTO to REQUIRED/OPTIONAL
+  // instead of handling it directly.
+  AUTO,
+
+  /// The field is treated as optional when deserializing/receiving the struct
+  /// and as required when serializing/sending. This is the Thrift default if
+  /// neither "required" nor "optional" are specified in the IDL file.
+  OPT_IN_REQ_OUT,
+
+  /// The field is optional.
+  OPTIONAL,
+
+  /// The field is required.
+  REQUIRED,
+
+  /// Ignore the struct field when serializing/deserializing.
+  IGNORE
+}
+
+/**
+ * The way how methods are called.
+ */
+enum TMethodType {
+  /// Called in the normal two-way scheme consisting of a request and a
+  /// response.
+  REGULAR,
+
+  /// A fire-and-forget one-way method, where no response is sent and the
+  /// client immediately returns.
+  ONEWAY
+}
+
+/**
+ * Compile-time metadata for a struct field.
+ */
+struct TFieldMeta {
+  /// The name of the field. Used for matching a TFieldMeta with the actual
+  /// D struct member during code generation.
+  string name;
+
+  /// The (Thrift) id of the field.
+  short id;
+
+  /// Whether the field is requried.
+  TReq req;
+
+  /// A code string containing a D expression for the default value, if there
+  /// is one.
+  string defaultValue;
+}
+
+/**
+ * Compile-time metadata for a service method.
+ */
+struct TMethodMeta {
+  /// The name of the method. Used for matching a TMethodMeta with the actual
+  /// method during code generation.
+  string name;
+
+  /// Meta information for the parameteres.
+  TParamMeta[] params;
+
+  /// Specifies which exceptions can be thrown by the method. All other
+  /// exceptions are converted to a TApplicationException instead.
+  TExceptionMeta[] exceptions;
+
+  /// The fundamental type of the method.
+  TMethodType type;
+}
+
+/**
+ * Compile-time metadata for a service method parameter.
+ */
+struct TParamMeta {
+  /// The name of the parameter. Contrary to TFieldMeta, it only serves
+  /// decorative purposes here.
+  string name;
+
+  /// The Thrift id of the parameter in the param struct.
+  short id;
+
+  /// A code string containing a D expression for the default value for the
+  /// parameter, if any.
+  string defaultValue;
+}
+
+/**
+ * Compile-time metadata for a service method exception annotation.
+ */
+struct TExceptionMeta {
+  /// The name of the exception »return value«. Contrary to TFieldMeta, it
+  /// only serves decorative purposes here, as it is only used in code not
+  /// visible to processor implementations/service clients.
+  string name;
+
+  /// The Thrift id of the exception field in the return value struct.
+  short id;
+
+  /// The name of the exception type.
+  string type;
+}
+
+/**
+ * A pair of two TPorotocols. To be used in places where a list of protocols
+ * is expected, for specifying different protocols for input and output.
+ */
+struct TProtocolPair(InputProtocol, OutputProtocol) if (
+  isTProtocol!InputProtocol && isTProtocol!OutputProtocol
+) {}
+
+/**
+ * true if T is a TProtocolPair.
+ */
+template isTProtocolPair(T) {
+  static if (is(T _ == TProtocolPair!(I, O), I, O)) {
+    enum isTProtocolPair = true;
+  } else {
+    enum isTProtocolPair = false;
+  }
+}
+
+unittest {
+  static assert(isTProtocolPair!(TProtocolPair!(TProtocol, TProtocol)));
+  static assert(!isTProtocolPair!TProtocol);
+}
+
+/**
+ * true if T is a TProtocol or a TProtocolPair.
+ */
+template isTProtocolOrPair(T) {
+  enum isTProtocolOrPair = isTProtocol!T || isTProtocolPair!T;
+}
+
+unittest {
+  static assert(isTProtocolOrPair!TProtocol);
+  static assert(isTProtocolOrPair!(TProtocolPair!(TProtocol, TProtocol)));
+  static assert(!isTProtocolOrPair!void);
+}
+
+/**
+ * true if T represents a Thrift service.
+ */
+template isService(T) {
+  enum isService = isBaseService!T || isDerivedService!T;
+}
+
+/**
+ * true if T represents a Thrift service not derived from another service.
+ */
+template isBaseService(T) {
+  static if(is(T _ == interface) &&
+    (!is(T TBases == super) || TBases.length == 0)
+  ) {
+    enum isBaseService = true;
+  } else {
+    enum isBaseService = false;
+  }
+}
+
+/**
+ * true if T represents a Thrift service derived from another service.
+ */
+template isDerivedService(T) {
+  static if(is(T _ == interface) &&
+    is(T TBases == super) && TBases.length == 1
+  ) {
+    enum isDerivedService = isService!(TBases[0]);
+  } else {
+    enum isDerivedService = false;
+  }
+}
+
+/**
+ * For derived services, gets the base service interface.
+ */
+template BaseService(T) if (isDerivedService!T) {
+  alias BaseTypeTuple!T[0] BaseService;
+}
+
+
+/*
+ * Code generation templates.
+ */
+
+/**
+ * Mixin template defining additional helper methods for using a struct with
+ * Thrift, and a member called isSetFlags if the struct contains any fields
+ * for which an »is set« flag is needed.
+ *
+ * It can only be used inside structs or Exception classes.
+ *
+ * For example, consider the following struct definition:
+ * ---
+ * struct Foo {
+ *   string a;
+ *   int b;
+ *   int c;
+ *
+ *   mixin TStructHelpers!([
+ *     TFieldMeta("a", 1), // Implicitly optional (nullable).
+ *     TFieldMeta("b", 2), // Implicitly required (non-nullable).
+ *     TFieldMeta("c", 3, TReq.REQUIRED, "4")
+ *   ]);
+ * }
+ * ---
+ *
+ * TStructHelper adds the following methods to the struct:
+ * ---
+ * /++
+ *  + Sets member fieldName to the given value and marks it as set.
+ *  +
+ *  + Examples:
+ *  + ---
+ *  + auto f = Foo();
+ *  + f.set!"b"(12345);
+ *  + assert(f.isSet!"b");
+ *  + ---
+ *  +/
+ * void set(string fieldName)(MemberType!(This, fieldName) value);
+ *
+ * /++
+ *  + Resets member fieldName to the init property of its type and marks it as
+ *  + not set.
+ *  +
+ *  + Examples:
+ *  + ---
+ *  + // Set f.b to some value.
+ *  + auto f = Foo();
+ *  + f.set!"b"(12345);
+ *  +
+ *  + f.unset!b();
+ *  +
+ *  + // f.b is now unset again.
+ *  + assert(!f.isSet!"b");
+ *  + ---
+ *  +/
+ * void unset(string fieldName)();
+ *
+ * /++
+ *  + Returns whether member fieldName is set.
+ *  +
+ *  + Examples:
+ *  + ---
+ *  + auto f = Foo();
+ *  + assert(!f.isSet!"b");
+ *  + f.set!"b"(12345);
+ *  + assert(f.isSet!"b");
+ *  + ---
+ *  +/
+ * bool isSet(string fieldName)() const @property;
+ *
+ * /++
+ *  + Returns a string representation of the struct.
+ *  +
+ *  + Examples:
+ *  + ---
+ *  + auto f = Foo();
+ *  + f.a = "a string";
+ *  + assert(f.toString() == `Foo("a string", 0 (unset), 4)`);
+ *  + ---
+ *  +/
+ * string toString() const;
+ *
+ * /++
+ *  + Deserializes the struct, setting its members to the values read from the
+ *  + protocol. Forwards to readStruct(this, proto);
+ *  +/
+ * void read(Protocol)(Protocol proto) if (isTProtocol!Protocol);
+ *
+ * /++
+ *  + Serializes the struct to the target protocol. Forwards to
+ *  + writeStruct(this, proto);
+ *  +/
+ * void write(Protocol)(Protocol proto) const if (isTProtocol!Protocol);
+ * ---
+ *
+ * Additionally, an opEquals() implementation is provided which simply
+ * compares all fields, but disregards the is set struct, if any (the exact
+ * signature obviously differs between structs and exception classes). The
+ * metadata is stored in a manifest constant called fieldMeta.
+ *
+ * Note: To set the default values for fields where one has been specified in
+ * the field metadata, a parameterless static opCall is generated, because D
+ * does not allow parameterless (default) constructors for structs. Thus, be
+ * always to use to initialize structs:
+ * ---
+ * Foo foo; // Wrong!
+ * auto foo = Foo(); // Correct.
+ * ---
+ */
+mixin template TStructHelpers(alias fieldMetaData = cast(TFieldMeta[])null) if (
+  is(typeof(fieldMetaData) : TFieldMeta[])
+) {
+  import std.algorithm : canFind;
+  import thrift.codegen.base;
+  import thrift.internal.codegen : isNullable, MemberType, mergeFieldMeta,
+    FieldNames;
+  import thrift.protocol.base : TProtocol, isTProtocol;
+
+  alias typeof(this) This;
+  static assert(is(This == struct) || is(This : Exception),
+    "TStructHelpers can only be used inside a struct or an Exception class.");
+
+  static if (is(TIsSetFlags!(This, fieldMetaData))) {
+    // If we need to keep isSet flags around, create an instance of the
+    // container struct.
+    TIsSetFlags!(This, fieldMetaData) isSetFlags;
+    enum fieldMeta = fieldMetaData ~ [TFieldMeta("isSetFlags", 0, TReq.IGNORE)];
+  } else {
+    enum fieldMeta = fieldMetaData;
+  }
+
+  void set(string fieldName)(MemberType!(This, fieldName) value) if (
+    is(MemberType!(This, fieldName))
+  ) {
+    __traits(getMember, this, fieldName) = value;
+    static if (is(typeof(mixin("this.isSetFlags." ~ fieldName)) : bool)) {
+      __traits(getMember, this.isSetFlags, fieldName) = true;
+    }
+  }
+
+  void unset(string fieldName)() if (is(MemberType!(This, fieldName))) {
+    static if (is(typeof(mixin("this.isSetFlags." ~ fieldName)) : bool)) {
+      __traits(getMember, this.isSetFlags, fieldName) = false;
+    }
+    __traits(getMember, this, fieldName) = MemberType!(This, fieldName).init;
+  }
+
+  bool isSet(string fieldName)() const @property if (
+    is(MemberType!(This, fieldName))
+  ) {
+    static if (isNullable!(MemberType!(This, fieldName))) {
+      return __traits(getMember, this, fieldName) !is null;
+    } else static if (is(typeof(mixin("this.isSetFlags." ~ fieldName)) : bool)) {
+      return __traits(getMember, this.isSetFlags, fieldName);
+    } else {
+      // This is a required field, which is always set.
+      return true;
+    }
+  }
+
+  static if (is(This _ == class)) {
+    override string toString() const {
+      return thriftToStringImpl();
+    }
+
+    override bool opEquals(Object other) const {
+      auto rhs = cast(This)other;
+      if (rhs) {
+        return thriftOpEqualsImpl(rhs);
+      }
+
+      return (cast()super).opEquals(other);
+    }
+  } else {
+    string toString() const {
+      return thriftToStringImpl();
+    }
+
+    bool opEquals(ref const This other) const {
+      return thriftOpEqualsImpl(other);
+    }
+  }
+
+  private string thriftToStringImpl() const {
+    import std.conv : to;
+    string result = This.stringof ~ "(";
+    mixin({
+      string code = "";
+      bool first = true;
+      foreach (name; FieldNames!(This, fieldMeta)) {
+        if (first) {
+          first = false;
+        } else {
+          code ~= "result ~= `, `;\n";
+        }
+        code ~= "result ~= `" ~ name ~ ": ` ~ to!string(cast()this." ~ name ~ ");\n";
+        code ~= "if (!isSet!q{" ~ name ~ "}) {\n";
+        code ~= "result ~= ` (unset)`;\n";
+        code ~= "}\n";
+      }
+      return code;
+    }());
+    result ~= ")";
+    return result;
+  }
+
+  private bool thriftOpEqualsImpl(const ref This rhs) const {
+    foreach (name; FieldNames!This) {
+      if (mixin("this." ~ name) != mixin("rhs." ~ name)) return false;
+    }
+    return true;
+  }
+
+  static if (canFind!`!a.defaultValue.empty`(mergeFieldMeta!(This, fieldMetaData))) {
+    static if (is(This _ == class)) {
+      this() {
+        mixin(thriftFieldInitCode!(mergeFieldMeta!(This, fieldMetaData))("this"));
+      }
+    } else {
+      // DMD @@BUG@@: Have to use auto here to avoid »no size yet for forward
+      // reference« errors.
+      static auto opCall() {
+        auto result = This.init;
+        mixin(thriftFieldInitCode!(mergeFieldMeta!(This, fieldMetaData))("result"));
+        return result;
+      }
+    }
+  }
+
+  void read(Protocol)(Protocol proto) if (isTProtocol!Protocol) {
+    // Need to explicitly specify fieldMetaData here, since it isn't already
+    // picked up in some situations (e.g. the TArgs struct for methods with
+    // multiple parameters in async_test_servers) otherwise. Due to a DMD
+    // @@BUG@@, we need to explicitly specify the other template parameters
+    // as well.
+    readStruct!(This, Protocol, fieldMetaData, false)(this, proto);
+  }
+
+  void write(Protocol)(Protocol proto) const if (isTProtocol!Protocol) {
+    writeStruct!(This, Protocol, fieldMetaData, false)(this, proto);
+  }
+}
+
+// DMD @@BUG@@: Having this inside TStructHelpers leads to weird lookup errors
+// (e.g. for std.arry.empty).
+string thriftFieldInitCode(alias fieldMeta)(string thisName) {
+  string code = "";
+  foreach (field; fieldMeta) {
+    if (field.defaultValue.empty) continue;
+    code ~= thisName ~ "." ~ field.name ~ " = " ~ field.defaultValue ~ ";\n";
+  }
+  return code;
+}
+
+version (unittest) {
+  // Cannot make this nested in the unittest block due to a »no size yet for
+  // forward reference« error.
+  struct Foo {
+    string a;
+    int b;
+    int c;
+
+    mixin TStructHelpers!([
+      TFieldMeta("a", 1),
+      TFieldMeta("b", 2, TReq.OPT_IN_REQ_OUT),
+      TFieldMeta("c", 3, TReq.REQUIRED, "4")
+    ]);
+  }
+}
+unittest {
+  auto f = Foo();
+
+  f.set!"b"(12345);
+  assert(f.isSet!"b");
+  f.unset!"b"();
+  assert(!f.isSet!"b");
+  f.set!"b"(12345);
+  assert(f.isSet!"b");
+  f.unset!"b"();
+
+  f.a = "a string";
+  assert(f.toString() == `Foo(a: a string, b: 0 (unset), c: 4)`);
+}
+
+/**
+ * Generates an eponymous struct with boolean flags for the non-required
+ * non-nullable fields of T, if any, or nothing otherwise (i.e. the template
+ * body is empty).
+ *
+ * Nullable fields are just set to null to signal »not set«.
+ *
+ * In most cases, you do not want to use this directly, but via TStructHelpers
+ * instead.
+ */
+// DMD @@BUG@@: Using getFieldMeta!T in here horribly breaks things to the point
+// where getFieldMeta is *instantiated twice*, with different bodies. This is
+// connected to the position of »enum fieldMeta« in TStructHelpers.
+template TIsSetFlags(T, alias fieldMetaData) {
+  mixin({
+    string boolDefinitions;
+    foreach (name; __traits(derivedMembers, T)) {
+      static if (!is(MemberType!(T, name)) || is(MemberType!(T, name) == void)) {
+        // We hit something strange like the TStructHelpers template itself,
+        // just ignore.
+      } else static if (isNullable!(MemberType!(T, name))) {
+        // If the field is nullable, we don't need an isSet flag as we can map
+        // unset to null.
+      } else static if (memberReq!(T, name, fieldMetaData) != TReq.REQUIRED) {
+        boolDefinitions ~= "bool " ~ name ~ ";\n";
+      }
+    }
+    if (!boolDefinitions.empty) {
+      return "struct TIsSetFlags {\n" ~ boolDefinitions ~ "}";
+    } else {
+      return "";
+    }
+  }());
+}
+
+/**
+ * Deserializes a Thrift struct from a protocol.
+ *
+ * Using the Protocol template parameter, the concrete TProtocol to use can be
+ * be specified. If the pointerStruct parameter is set to true, the struct
+ * fields are expected to be pointers to the actual data. This is used
+ * internally (combined with TPResultStruct) and usually should not be used in
+ * user code.
+ *
+ * This is a free function to make it possible to read exisiting structs from
+ * the wire without altering their definitions.
+ */
+void readStruct(T, Protocol, alias fieldMetaData = cast(TFieldMeta[])null,
+  bool pointerStruct = false)(ref T s, Protocol p) if (isTProtocol!Protocol)
+{
+  mixin({
+    string code;
+
+    // Check that all fields for which there is meta info are actually in the
+    // passed struct type.
+    foreach (field; mergeFieldMeta!(T, fieldMetaData)) {
+      code ~= "static assert(is(MemberType!(T, `" ~ field.name ~ "`)));\n";
+    }
+
+    // Returns the code string for reading a value of type F off the wire and
+    // assigning it to v. The level parameter is used to make sure that there
+    // are no conflicting variable names on recursive calls.
+    string readValueCode(ValueType)(string v, size_t level = 0) {
+      // Some non-ambigous names to use (shadowing is not allowed in D).
+      immutable i = "i" ~ to!string(level);
+      immutable elem = "elem" ~ to!string(level);
+      immutable key = "key" ~ to!string(level);
+      immutable list = "list" ~ to!string(level);
+      immutable map = "map" ~ to!string(level);
+      immutable set = "set" ~ to!string(level);
+      immutable value = "value" ~ to!string(level);
+
+      alias FullyUnqual!ValueType F;
+
+      static if (is(F == bool)) {
+        return v ~ " = p.readBool();";
+      } else static if (is(F == byte)) {
+        return v ~ " = p.readByte();";
+      } else static if (is(F == double)) {
+        return v ~ " = p.readDouble();";
+      } else static if (is(F == short)) {
+        return v ~ " = p.readI16();";
+      } else static if (is(F == int)) {
+        return v ~ " = p.readI32();";
+      } else static if (is(F == long)) {
+        return v ~ " = p.readI64();";
+      } else static if (is(F : string)) {
+        return v ~ " = p.readString();";
+      } else static if (is(F == enum)) {
+        return v ~ " = cast(typeof(" ~ v ~ "))p.readI32();";
+      } else static if (is(F _ : E[], E)) {
+        return "{\n" ~
+          "auto " ~ list ~ " = p.readListBegin();\n" ~
+          // TODO: Check element type here?
+          v ~ " = new typeof(" ~ v ~ "[0])[" ~ list ~ ".size];\n" ~
+          "foreach (" ~ i ~ "; 0 .. " ~ list ~ ".size) {\n" ~
+            readValueCode!E(v ~ "[" ~ i ~ "]", level + 1) ~ "\n" ~
+          "}\n" ~
+          "p.readListEnd();\n" ~
+        "}";
+      } else static if (is(F _ : V[K], K, V)) {
+        return "{\n" ~
+          "auto " ~ map ~ " = p.readMapBegin();" ~
+          v ~ " = null;\n" ~
+          // TODO: Check key/value types here?
+          "foreach (" ~ i ~ "; 0 .. " ~ map ~ ".size) {\n" ~
+            "FullyUnqual!(typeof(" ~ v ~ ".keys[0])) " ~ key ~ ";\n" ~
+            readValueCode!K(key, level + 1) ~ "\n" ~
+            "typeof(" ~ v ~ ".values[0]) " ~ value ~ ";\n" ~
+            readValueCode!V(value, level + 1) ~ "\n" ~
+            v ~ "[cast(typeof(" ~ v ~ ".keys[0]))" ~ key ~ "] = " ~ value ~ ";\n" ~
+          "}\n" ~
+          "p.readMapEnd();" ~
+        "}";
+      } else static if (is(F _ : HashSet!(E), E)) {
+        return "{\n" ~
+          "auto " ~ set ~ " = p.readSetBegin();" ~
+          // TODO: Check element type here?
+          v ~ " = new typeof(" ~ v ~ ")();\n" ~
+          "foreach (" ~ i ~ "; 0 .. " ~ set ~ ".size) {\n" ~
+            "typeof(" ~ v ~ "[][0]) " ~ elem ~ ";\n" ~
+            readValueCode!E(elem, level + 1) ~ "\n" ~
+            v ~ " ~= " ~ elem ~ ";\n" ~
+          "}\n" ~
+          "p.readSetEnd();" ~
+        "}";
+      } else static if (is(F == struct) || is(F : TException)) {
+        static if (is(F == struct)) {
+          auto result = v ~ " = typeof(" ~ v ~ ")();\n";
+        } else {
+          auto result = v ~ " = new typeof(" ~ v ~ ")();\n";
+        }
+
+        static if (__traits(compiles, F.init.read(TProtocol.init))) {
+          result ~= v ~ ".read(p);";
+        } else {
+          result ~= "readStruct(" ~ v ~ ", p);";
+        }
+        return result;
+      } else {
+        static assert(false, "Cannot represent type in Thrift: " ~ F.stringof);
+      }
+    }
+
+    string readFieldCode(FieldType)(string name, short id, TReq req) {
+      static if (pointerStruct && isPointer!FieldType) {
+        immutable v = "(*s." ~ name ~ ")";
+        alias pointerTarget!FieldType F;
+      } else {
+        immutable v = "s." ~ name;
+        alias FieldType F;
+      }
+
+      string code = "case " ~ to!string(id) ~ ":\n";
+      code ~= "if (f.type == " ~ dToTTypeString!F ~ ") {\n";
+      code ~= readValueCode!F(v) ~ "\n";
+      if (req == TReq.REQUIRED) {
+        // For required fields, set the corresponding local isSet variable.
+        code ~= "isSet_" ~ name ~ " = true;\n";
+      } else if (!isNullable!F){
+        code ~= "s.isSetFlags." ~ name ~ " = true;\n";
+      }
+      code ~= "} else skip(p, f.type);\n";
+      code ~= "break;\n";
+      return code;
+    }
+
+    // Code for the local boolean flags used to make sure required fields have
+    // been found.
+    string isSetFlagCode = "";
+
+    // Code for checking whether the flags for the required fields are true.
+    string isSetCheckCode = "";
+
+    /// Code for the case statements storing the fields to the result struct.
+    string readMembersCode = "";
+
+    // The last automatically assigned id – fields with no meta information
+    // are assigned (in lexical order) descending negative ids, starting with
+    // -1, just like the Thrift compiler does.
+    short lastId;
+
+    foreach (name; FieldNames!T) {
+      enum req = memberReq!(T, name, fieldMetaData);
+      if (req == TReq.REQUIRED) {
+        // For required fields, generate local bool flags to keep track
+        // whether the field has been encountered.
+        immutable n = "isSet_" ~ name;
+        isSetFlagCode ~= "bool " ~ n ~ ";\n";
+        isSetCheckCode ~= "enforce(" ~ n ~ ", new TProtocolException(" ~
+          "`Required field '" ~ name ~ "' not found in serialized data`, " ~
+          "TProtocolException.Type.INVALID_DATA));\n";
+      }
+
+      enum meta = find!`a.name == b`(mergeFieldMeta!(T, fieldMetaData), name);
+      static if (meta.empty) {
+        --lastId;
+        version (TVerboseCodegen) {
+          code ~= "pragma(msg, `[thrift.codegen.base.readStruct] Warning: No " ~
+            "meta information for field '" ~ name ~ "' in struct '" ~
+            T.stringof ~ "'. Assigned id: " ~ to!string(lastId) ~ ".`);\n";
+        }
+        readMembersCode ~= readFieldCode!(MemberType!(T, name))(
+          name, lastId, req);
+      } else static if (req != TReq.IGNORE) {
+        readMembersCode ~= readFieldCode!(MemberType!(T, name))(
+          name, meta.front.id, req);
+      }
+    }
+
+    code ~= isSetFlagCode;
+    code ~= "p.readStructBegin();\n";
+    code ~= "while (true) {\n";
+    code ~= "auto f = p.readFieldBegin();\n";
+    code ~= "if (f.type == TType.STOP) break;\n";
+    code ~= "switch(f.id) {\n";
+    code ~= readMembersCode;
+    code ~= "default: skip(p, f.type);\n";
+    code ~= "}\n";
+    code ~= "p.readFieldEnd();\n";
+    code ~= "}\n";
+    code ~= "p.readStructEnd();\n";
+    code ~= isSetCheckCode;
+
+    return code;
+  }());
+}
+
+/**
+ * Serializes a struct to the target protocol.
+ *
+ * Using the Protocol template parameter, the concrete TProtocol to use can be
+ * be specified. If the pointerStruct parameter is set to true, the struct
+ * fields are expected to be pointers to the actual data. This is used
+ * internally (combined with TPargsStruct) and usually should not be used in
+ * user code.
+ *
+ * This is a free function to make it possible to read exisiting structs from
+ * the wire without altering their definitions.
+ */
+void writeStruct(T, Protocol, alias fieldMetaData = cast(TFieldMeta[])null,
+  bool pointerStruct = false) (const T s, Protocol p) if (isTProtocol!Protocol)
+{
+  mixin({
+    // Check that all fields for which there is meta info are actually in the
+    // passed struct type.
+    string code = "";
+    foreach (field; mergeFieldMeta!(T, fieldMetaData)) {
+      code ~= "static assert(is(MemberType!(T, `" ~ field.name ~ "`)));\n";
+    }
+
+    // Check that required nullable members are non-null.
+    // WORKAROUND: To stop LDC from emitting the manifest constant »meta« below
+    // into the writeStruct function body this is inside the string mixin
+    // block – the code wouldn't depend on it (this is an LDC bug, and because
+    // of it a new array would be allocate on each method invocation at runtime).
+    foreach (name; StaticFilter!(
+      Compose!(isNullable, PApply!(MemberType, T)),
+      FieldNames!T
+    )) {
+       static if (memberReq!(T, name, fieldMetaData) == TReq.REQUIRED) {
+         code ~= `enforce(__traits(getMember, s, name) !is null,
+           new TException("Required field '` ~ name ~ `' is null."));\n`;
+       }
+    }
+
+    return code;
+  }());
+
+  p.writeStructBegin(TStruct(T.stringof));
+  mixin({
+    string writeValueCode(ValueType)(string v, size_t level = 0) {
+      // Some non-ambigous names to use (shadowing is not allowed in D).
+      immutable elem = "elem" ~ to!string(level);
+      immutable key = "key" ~ to!string(level);
+      immutable value = "value" ~ to!string(level);
+
+      alias FullyUnqual!ValueType F;
+      static if (is(F == bool)) {
+        return "p.writeBool(" ~ v ~ ");";
+      } else static if (is(F == byte)) {
+        return "p.writeByte(" ~ v ~ ");";
+      } else static if (is(F == double)) {
+        return "p.writeDouble(" ~ v ~ ");";
+      } else static if (is(F == short)) {
+        return "p.writeI16(" ~ v ~ ");";
+      } else static if (is(F == int)) {
+        return "p.writeI32(" ~ v ~ ");";
+      } else static if (is(F == long)) {
+        return "p.writeI64(" ~ v ~ ");";
+      } else static if (is(F : string)) {
+        return "p.writeString(" ~ v ~ ");";
+      } else static if (is(F == enum)) {
+        return "p.writeI32(cast(int)" ~ v ~ ");";
+      } else static if (is(F _ : E[], E)) {
+        return "p.writeListBegin(TList(" ~ dToTTypeString!E ~ ", " ~ v ~
+          ".length));\n" ~
+          "foreach (" ~ elem ~ "; " ~ v ~ ") {\n" ~
+            writeValueCode!E(elem, level + 1) ~ "\n" ~
+          "}\n" ~
+          "p.writeListEnd();";
+      } else static if (is(F _ : V[K], K, V)) {
+        return "p.writeMapBegin(TMap(" ~ dToTTypeString!K ~ ", " ~
+          dToTTypeString!V ~ ", " ~ v ~ ".length));\n" ~
+          "foreach (" ~ key ~ ", " ~ value ~ "; " ~ v ~ ") {\n" ~
+            writeValueCode!K(key, level + 1) ~ "\n" ~
+            writeValueCode!V(value, level + 1) ~ "\n" ~
+          "}\n" ~
+          "p.writeMapEnd();";
+      } else static if (is(F _ : HashSet!E, E)) {
+        return "p.writeSetBegin(TSet(" ~ dToTTypeString!E ~ ", " ~ v ~
+          ".length));\n" ~
+          "foreach (" ~ elem ~ "; " ~ v ~ "[]) {\n" ~
+            writeValueCode!E(elem, level + 1) ~ "\n" ~
+          "}\n" ~
+          "p.writeSetEnd();";
+      } else static if (is(F == struct) || is(F : TException)) {
+        static if (__traits(compiles, F.init.write(TProtocol.init))) {
+          return v ~ ".write(p);";
+        } else {
+          return "writeStruct(" ~ v ~ ", p);";
+        }
+      } else {
+        static assert(false, "Cannot represent type in Thrift: " ~ F.stringof);
+      }
+    }
+
+    string writeFieldCode(FieldType)(string name, short id, TReq req) {
+      string code;
+      if (!pointerStruct && req == TReq.OPTIONAL) {
+        code ~= "if (s.isSet!`" ~ name ~ "`) {\n";
+      }
+
+      static if (pointerStruct && isPointer!FieldType) {
+        immutable v = "(*s." ~ name ~ ")";
+        alias pointerTarget!FieldType F;
+      } else {
+        immutable v = "s." ~ name;
+        alias FieldType F;
+      }
+
+      code ~= "p.writeFieldBegin(TField(`" ~ name ~ "`, " ~ dToTTypeString!F ~
+        ", " ~ to!string(id) ~ "));\n";
+      code ~= writeValueCode!F(v) ~ "\n";
+      code ~= "p.writeFieldEnd();\n";
+
+      if (!pointerStruct && req == TReq.OPTIONAL) {
+        code ~= "}\n";
+      }
+      return code;
+    }
+
+    // The last automatically assigned id – fields with no meta information
+    // are assigned (in lexical order) descending negative ids, starting with
+    // -1, just like the Thrift compiler does.
+    short lastId;
+
+    string code = "";
+    foreach (name; FieldNames!T) {
+      alias MemberType!(T, name) F;
+      enum req = memberReq!(T, name, fieldMetaData);
+      enum meta = find!`a.name == b`(mergeFieldMeta!(T, fieldMetaData), name);
+      if (meta.empty) {
+        --lastId;
+        version (TVerboseCodegen) {
+          code ~= "pragma(msg, `[thrift.codegen.base.writeStruct] Warning: No " ~
+            "meta information for field '" ~ name ~ "' in struct '" ~
+            T.stringof ~ "'. Assigned id: " ~ to!string(lastId) ~ ".`);\n";
+        }
+        code ~= writeFieldCode!F(name, lastId, req);
+      } else if (req != TReq.IGNORE) {
+        code ~= writeFieldCode!F(name, meta.front.id, req);
+      }
+    }
+
+    return code;
+  }());
+  p.writeFieldStop();
+  p.writeStructEnd();
+}
+
+private {
+  /*
+   * Returns a D code string containing the matching TType value for a passed
+   * D type, e.g. dToTTypeString!byte == "TType.BYTE".
+   */
+  template dToTTypeString(T) {
+    static if (is(FullyUnqual!T == bool)) {
+      enum dToTTypeString = "TType.BOOL";
+    } else static if (is(FullyUnqual!T == byte)) {
+      enum dToTTypeString = "TType.BYTE";
+    } else static if (is(FullyUnqual!T == double)) {
+      enum dToTTypeString = "TType.DOUBLE";
+    } else static if (is(FullyUnqual!T == short)) {
+      enum dToTTypeString = "TType.I16";
+    } else static if (is(FullyUnqual!T == int)) {
+      enum dToTTypeString = "TType.I32";
+    } else static if (is(FullyUnqual!T == long)) {
+      enum dToTTypeString = "TType.I64";
+    } else static if (is(FullyUnqual!T : string)) {
+      enum dToTTypeString = "TType.STRING";
+    } else static if (is(FullyUnqual!T == enum)) {
+      enum dToTTypeString = "TType.I32";
+    } else static if (is(FullyUnqual!T _ : U[], U)) {
+      enum dToTTypeString = "TType.LIST";
+    } else static if (is(FullyUnqual!T _ : V[K], K, V)) {
+      enum dToTTypeString = "TType.MAP";
+    } else static if (is(FullyUnqual!T _ : HashSet!E, E)) {
+      enum dToTTypeString = "TType.SET";
+    } else static if (is(FullyUnqual!T == struct)) {
+      enum dToTTypeString = "TType.STRUCT";
+    } else static if (is(FullyUnqual!T : TException)) {
+      enum dToTTypeString = "TType.STRUCT";
+    } else {
+      static assert(false, "Cannot represent type in Thrift: " ~ T.stringof);
+    }
+  }
+}
diff --git a/lib/d/src/thrift/codegen/client.d b/lib/d/src/thrift/codegen/client.d
new file mode 100644
index 0000000..9755ea8
--- /dev/null
+++ b/lib/d/src/thrift/codegen/client.d
@@ -0,0 +1,484 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+module thrift.codegen.client;
+
+import std.algorithm : find;
+import std.array : empty, front;
+import std.conv : to;
+import std.traits : isSomeFunction, ParameterStorageClass,
+  ParameterStorageClassTuple, ParameterTypeTuple, ReturnType;
+import thrift.codegen.base;
+import thrift.internal.codegen;
+import thrift.internal.ctfe;
+import thrift.protocol.base;
+
+/**
+ * Thrift service client, which implements an interface by synchronously
+ * calling a server over a TProtocol.
+ *
+ * TClientBase simply extends Interface with generic input/output protocol
+ * properties to serve as a supertype for all TClients for the same service,
+ * which might be instantiated with different concrete protocol types (there
+ * is no covariance for template type parameters). If Interface is derived
+ * from another interface BaseInterface, it also extends
+ * TClientBase!BaseInterface.
+ *
+ * TClient is the class that actually implements TClientBase. Just as
+ * TClientBase, it is also derived from TClient!BaseInterface for inheriting
+ * services.
+ *
+ * TClient takes two optional template arguments which can be used for
+ * specifying the actual TProtocol implementation used for optimization
+ * purposes, as virtual calls can completely be eliminated then. If
+ * OutputProtocol is not specified, it is assumed to be the same as
+ * InputProtocol. The protocol properties defined by TClientBase are exposed
+ * with their concrete type (return type covariance).
+ *
+ * In addition to implementing TClientBase!Interface, TClient offers the
+ * following constructors:
+ * ---
+ * this(InputProtocol iprot, OutputProtocol oprot);
+ * // Only if is(InputProtocol == OutputProtocol), to use the same protocol
+ * // for both input and output:
+ * this(InputProtocol prot);
+ * ---
+ *
+ * The sequence id of the method calls starts at zero and is automatically
+ * incremented.
+ */
+interface TClientBase(Interface) if (isBaseService!Interface) : Interface {
+  /**
+   * The input protocol used by the client.
+   */
+  TProtocol inputProtocol() @property;
+
+  /**
+   * The output protocol used by the client.
+   */
+  TProtocol outputProtocol() @property;
+}
+
+/// Ditto
+interface TClientBase(Interface) if (isDerivedService!Interface) :
+  TClientBase!(BaseService!Interface), Interface {}
+
+/// Ditto
+template TClient(Interface, InputProtocol = TProtocol, OutputProtocol = void) if (
+  isService!Interface && isTProtocol!InputProtocol &&
+  (isTProtocol!OutputProtocol || is(OutputProtocol == void))
+) {
+  mixin({
+    static if (isDerivedService!Interface) {
+      string code = "class TClient : TClient!(BaseService!Interface, " ~
+        "InputProtocol, OutputProtocol), TClientBase!Interface {\n";
+      code ~= q{
+        this(IProt iprot, OProt oprot) {
+          super(iprot, oprot);
+        }
+
+        static if (is(IProt == OProt)) {
+          this(IProt prot) {
+            super(prot);
+          }
+        }
+
+        // DMD @@BUG@@: If these are not present in this class (would be)
+        // inherited anyway, »not implemented« errors are raised.
+        override IProt inputProtocol() @property {
+          return super.inputProtocol;
+        }
+        override OProt outputProtocol() @property {
+          return super.outputProtocol;
+        }
+      };
+    } else {
+      string code = "class TClient : TClientBase!Interface {";
+      code ~= q{
+        alias InputProtocol IProt;
+        static if (isTProtocol!OutputProtocol) {
+          alias OutputProtocol OProt;
+        } else {
+          static assert(is(OutputProtocol == void));
+          alias InputProtocol OProt;
+        }
+
+        this(IProt iprot, OProt oprot) {
+          iprot_ = iprot;
+          oprot_ = oprot;
+        }
+
+        static if (is(IProt == OProt)) {
+          this(IProt prot) {
+            this(prot, prot);
+          }
+        }
+
+        IProt inputProtocol() @property {
+          return iprot_;
+        }
+
+        OProt outputProtocol() @property {
+          return oprot_;
+        }
+
+        protected IProt iprot_;
+        protected OProt oprot_;
+        protected int seqid_;
+      };
+    }
+
+    foreach (methodName; __traits(derivedMembers, Interface)) {
+      static if (isSomeFunction!(mixin("Interface." ~ methodName))) {
+        bool methodMetaFound;
+        TMethodMeta methodMeta;
+        static if (is(typeof(Interface.methodMeta) : TMethodMeta[])) {
+          enum meta = find!`a.name == b`(Interface.methodMeta, methodName);
+          if (!meta.empty) {
+            methodMetaFound = true;
+            methodMeta = meta.front;
+          }
+        }
+
+        // Generate the code for sending.
+        string[] paramList;
+        string paramAssignCode;
+        foreach (i, _; ParameterTypeTuple!(mixin("Interface." ~ methodName))) {
+          // Use the param name speficied in the meta information if any –
+          // just cosmetics in this case.
+          string paramName;
+          if (methodMetaFound && i < methodMeta.params.length) {
+            paramName = methodMeta.params[i].name;
+          } else {
+            paramName = "param" ~ to!string(i + 1);
+          }
+
+          immutable storage = ParameterStorageClassTuple!(
+            mixin("Interface." ~ methodName))[i];
+          paramList ~= ((storage & ParameterStorageClass.ref_) ? "ref " : "") ~
+            "ParameterTypeTuple!(Interface." ~ methodName ~ ")[" ~
+            to!string(i) ~ "] " ~ paramName;
+          paramAssignCode ~= "args." ~ paramName ~ " = &" ~ paramName ~ ";\n";
+        }
+        code ~= "ReturnType!(Interface." ~ methodName ~ ") " ~ methodName ~
+          "(" ~ ctfeJoin(paramList) ~ ") {\n";
+
+        code ~= "immutable methodName = `" ~ methodName ~ "`;\n";
+
+        immutable paramStructType =
+          "TPargsStruct!(Interface, `" ~ methodName ~ "`)";
+        code ~= paramStructType ~ " args = " ~ paramStructType ~ "();\n";
+        code ~= paramAssignCode;
+        code ~= "oprot_.writeMessageBegin(TMessage(`" ~ methodName ~
+          "`, TMessageType.CALL, ++seqid_));\n";
+        code ~= "args.write(oprot_);\n";
+        code ~= "oprot_.writeMessageEnd();\n";
+        code ~= "oprot_.transport.flush();\n";
+
+        // If this is not a oneway method, generate the recieving code.
+        if (!methodMetaFound || methodMeta.type != TMethodType.ONEWAY) {
+          code ~= "TPresultStruct!(Interface, `" ~ methodName ~ "`) result;\n";
+
+          if (!is(ReturnType!(mixin("Interface." ~ methodName)) == void)) {
+            code ~= "ReturnType!(Interface." ~ methodName ~ ") _return;\n";
+            code ~= "result.success = &_return;\n";
+          }
+
+          // TODO: The C++ implementation checks for matching method name here,
+          // should we do as well?
+          code ~= q{
+            auto msg = iprot_.readMessageBegin();
+            scope (exit) {
+              iprot_.readMessageEnd();
+              iprot_.transport.readEnd();
+            }
+
+            if (msg.type == TMessageType.EXCEPTION) {
+              auto x = new TApplicationException(null);
+              x.read(iprot_);
+              iprot_.transport.readEnd();
+              throw x;
+            }
+            if (msg.type != TMessageType.REPLY) {
+              skip(iprot_, TType.STRUCT);
+              iprot_.transport.readEnd();
+            }
+            if (msg.seqid != seqid_) {
+              throw new TApplicationException(
+                methodName ~ " failed: Out of sequence response.",
+                TApplicationException.Type.BAD_SEQUENCE_ID
+              );
+            }
+            result.read(iprot_);
+          };
+
+          if (methodMetaFound) {
+            foreach (e; methodMeta.exceptions) {
+              code ~= "if (result.isSet!`" ~ e.name ~ "`) throw result." ~
+                e.name ~ ";\n";
+            }
+          }
+
+          if (!is(ReturnType!(mixin("Interface." ~ methodName)) == void)) {
+            code ~= q{
+              if (result.isSet!`success`) return _return;
+              throw new TApplicationException(
+                methodName ~ " failed: Unknown result.",
+                TApplicationException.Type.MISSING_RESULT
+              );
+            };
+          }
+        }
+        code ~= "}\n";
+      }
+    }
+
+    code ~= "}\n";
+    return code;
+  }());
+}
+
+/**
+ * TClient construction helper to avoid having to explicitly specify
+ * the protocol types, i.e. to allow the constructor being called using IFTI
+ * (see $(DMDBUG 6082, D Bugzilla enhancement requet 6082)).
+ */
+TClient!(Interface, Prot) tClient(Interface, Prot)(Prot prot) if (
+  isService!Interface && isTProtocol!Prot
+) {
+  return new TClient!(Interface, Prot)(prot);
+}
+
+/// Ditto
+TClient!(Interface, IProt, Oprot) tClient(Interface, IProt, OProt)
+  (IProt iprot, OProt oprot) if (
+  isService!Interface && isTProtocol!IProt && isTProtocol!OProt
+) {
+  return new TClient!(Interface, IProt, OProt)(iprot, oprot);
+}
+
+/**
+ * Represents the arguments of a Thrift method call, as pointers to the (const)
+ * parameter type to avoid copying.
+ *
+ * There should usually be no reason to use this struct directly without the
+ * help of TClient, but it is documented publicly to help debugging in case
+ * of CTFE errors.
+ *
+ * Consider this example:
+ * ---
+ * interface Foo {
+ *   int bar(string a, bool b);
+ *
+ *   enum methodMeta = [
+ *     TMethodMeta("bar", [TParamMeta("a", 1), TParamMeta("b", 2)])
+ *   ];
+ * }
+ *
+ * alias TPargsStruct!(Foo, "bar") FooBarPargs;
+ * ---
+ *
+ * The definition of FooBarPargs is equivalent to (ignoring the necessary
+ * metadata to assign the field IDs):
+ * ---
+ * struct FooBarPargs {
+ *   const(string)* a;
+ *   const(bool)* b;
+ *
+ *   void write(Protocol)(Protocol proto) const if (isTProtocol!Protocol);
+ * }
+ * ---
+ */
+template TPargsStruct(Interface, string methodName) {
+  static assert(is(typeof(mixin("Interface." ~ methodName))),
+    "Could not find method '" ~ methodName ~ "' in '" ~ Interface.stringof ~ "'.");
+  mixin({
+    bool methodMetaFound;
+    TMethodMeta methodMeta;
+    static if (is(typeof(Interface.methodMeta) : TMethodMeta[])) {
+      auto meta = find!`a.name == b`(Interface.methodMeta, methodName);
+      if (!meta.empty) {
+        methodMetaFound = true;
+        methodMeta = meta.front;
+      }
+    }
+
+    string memberCode;
+    string[] fieldMetaCodes;
+    foreach (i, _; ParameterTypeTuple!(mixin("Interface." ~ methodName))) {
+      // If we have no meta information, just use param1, param2, etc. as
+      // field names, it shouldn't really matter anyway. 1-based »indexing«
+      // is used to match the common scheme in the Thrift world.
+      string memberId;
+      string memberName;
+      if (methodMetaFound && i < methodMeta.params.length) {
+        memberId = to!string(methodMeta.params[i].id);
+        memberName = methodMeta.params[i].name;
+      } else {
+        memberId = to!string(i + 1);
+        memberName = "param" ~ to!string(i + 1);
+      }
+
+      // Workaround for DMD @@BUG@@ 6056: make an intermediary alias for the
+      // parameter type, and declare the member using const(memberNameType)*.
+      memberCode ~= "alias ParameterTypeTuple!(Interface." ~ methodName ~
+        ")[" ~ to!string(i) ~ "] " ~ memberName ~ "Type;\n";
+      memberCode ~= "const(" ~ memberName ~ "Type)* " ~ memberName ~ ";\n";
+
+      fieldMetaCodes ~= "TFieldMeta(`" ~ memberName ~ "`, " ~ memberId ~
+        ", TReq.OPT_IN_REQ_OUT)";
+    }
+
+    string code = "struct TPargsStruct {\n";
+    code ~= memberCode;
+    version (TVerboseCodegen) {
+      if (!methodMetaFound &&
+        ParameterTypeTuple!(mixin("Interface." ~ methodName)).length > 0)
+      {
+        code ~= "pragma(msg, `[thrift.codegen.base.TPargsStruct] Warning: No " ~
+          "meta information for method '" ~ methodName ~ "' in service '" ~
+          Interface.stringof ~ "' found.`);\n";
+      }
+    }
+    code ~= "void write(P)(P proto) const if (isTProtocol!P) {\n";
+    code ~= "writeStruct!(typeof(this), P, [" ~ ctfeJoin(fieldMetaCodes) ~
+      "], true)(this, proto);\n";
+    code ~= "}\n";
+    code ~= "}\n";
+    return code;
+  }());
+}
+
+/**
+ * Represents the result of a Thrift method call, using a pointer to the return
+ * value to avoid copying.
+ *
+ * There should usually be no reason to use this struct directly without the
+ * help of TClient, but it is documented publicly to help debugging in case
+ * of CTFE errors.
+ *
+ * Consider this example:
+ * ---
+ * interface Foo {
+ *   int bar(string a);
+ *
+ *   alias .FooException FooException;
+ *
+ *   enum methodMeta = [
+ *     TMethodMeta("bar",
+ *       [TParamMeta("a", 1)],
+ *       [TExceptionMeta("fooe", 1, "FooException")]
+ *     )
+ *   ];
+ * }
+ * alias TPresultStruct!(Foo, "bar") FooBarPresult;
+ * ---
+ *
+ * The definition of FooBarPresult is equivalent to (ignoring the necessary
+ * metadata to assign the field IDs):
+ * ---
+ * struct FooBarPresult {
+ *   int* success;
+ *   Foo.FooException fooe;
+ *
+ *   struct IsSetFlags {
+ *     bool success;
+ *   }
+ *   IsSetFlags isSetFlags;
+ *
+ *   bool isSet(string fieldName)() const @property;
+ *   void read(Protocol)(Protocol proto) if (isTProtocol!Protocol);
+ * }
+ * ---
+ */
+template TPresultStruct(Interface, string methodName) {
+  static assert(is(typeof(mixin("Interface." ~ methodName))),
+    "Could not find method '" ~ methodName ~ "' in '" ~ Interface.stringof ~ "'.");
+
+  mixin({
+    string code = "struct TPresultStruct {\n";
+
+    string[] fieldMetaCodes;
+
+    alias ReturnType!(mixin("Interface." ~ methodName)) ResultType;
+    static if (!is(ResultType == void)) {
+      code ~= q{
+        ReturnType!(mixin("Interface." ~ methodName))* success;
+      };
+      fieldMetaCodes ~= "TFieldMeta(`success`, 0, TReq.OPTIONAL)";
+
+      static if (!isNullable!ResultType) {
+        code ~= q{
+          struct IsSetFlags {
+            bool success;
+          }
+          IsSetFlags isSetFlags;
+        };
+        fieldMetaCodes ~= "TFieldMeta(`isSetFlags`, 0, TReq.IGNORE)";
+      }
+    }
+
+    bool methodMetaFound;
+    static if (is(typeof(Interface.methodMeta) : TMethodMeta[])) {
+      auto meta = find!`a.name == b`(Interface.methodMeta, methodName);
+      if (!meta.empty) {
+        foreach (e; meta.front.exceptions) {
+          code ~= "Interface." ~ e.type ~ " " ~ e.name ~ ";\n";
+          fieldMetaCodes ~= "TFieldMeta(`" ~ e.name ~ "`, " ~ to!string(e.id) ~
+            ", TReq.OPTIONAL)";
+        }
+        methodMetaFound = true;
+      }
+    }
+
+    version (TVerboseCodegen) {
+      if (!methodMetaFound &&
+        ParameterTypeTuple!(mixin("Interface." ~ methodName)).length > 0)
+      {
+        code ~= "pragma(msg, `[thrift.codegen.base.TPresultStruct] Warning: No " ~
+          "meta information for method '" ~ methodName ~ "' in service '" ~
+          Interface.stringof ~ "' found.`);\n";
+      }
+    }
+
+    code ~= q{
+      bool isSet(string fieldName)() const @property if (
+        is(MemberType!(typeof(this), fieldName))
+      ) {
+        static if (fieldName == "success") {
+          static if (isNullable!(typeof(*success))) {
+            return *success !is null;
+          } else {
+            return isSetFlags.success;
+          }
+        } else {
+          // We are dealing with an exception member, which, being a nullable
+          // type (exceptions are always classes), has no isSet flag.
+          return __traits(getMember, this, fieldName) !is null;
+        }
+      }
+    };
+
+    code ~= "void read(P)(P proto) if (isTProtocol!P) {\n";
+    code ~= "readStruct!(typeof(this), P, [" ~ ctfeJoin(fieldMetaCodes) ~
+      "], true)(this, proto);\n";
+    code ~= "}\n";
+    code ~= "}\n";
+    return code;
+  }());
+}
diff --git a/lib/d/src/thrift/codegen/client_pool.d b/lib/d/src/thrift/codegen/client_pool.d
new file mode 100644
index 0000000..ebf5b60
--- /dev/null
+++ b/lib/d/src/thrift/codegen/client_pool.d
@@ -0,0 +1,262 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+module thrift.codegen.client_pool;
+
+import core.time : dur, Duration, TickDuration;
+import std.traits : ParameterTypeTuple, ReturnType;
+import thrift.base;
+import thrift.codegen.base;
+import thrift.codegen.client;
+import thrift.internal.codegen;
+import thrift.internal.resource_pool;
+
+/**
+ * Manages a pool of TClients for the given interface, forwarding RPC calls to
+ * members of the pool.
+ *
+ * If a request fails, another client from the pool is tried, and optionally,
+ * a client is disabled for a configurable amount of time if it fails too
+ * often. If all clients fail (and keepTrying is false), a
+ * TCompoundOperationException is thrown, containing all the collected RPC
+ * exceptions.
+ */
+class TClientPool(Interface) if (isService!Interface) : Interface {
+  /// Shorthand for TClientBase!Interface, the client type this instance
+  /// operates on.
+  alias TClientBase!Interface Client;
+
+  /**
+   * Creates a new instance and adds the given clients to the pool.
+   */
+  this(Client[] clients) {
+    pool_ = new TResourcePool!Client(clients);
+
+    rpcFaultFilter = (Exception e) {
+      import thrift.protocol.base;
+      import thrift.transport.base;
+      return (
+        (cast(TTransportException)e !is null) ||
+        (cast(TApplicationException)e !is null)
+      );
+    };
+  }
+
+  /**
+   * Executes an operation on the first currently active client.
+   *
+   * If the operation fails (throws an exception for which rpcFaultFilter is
+   * true), the failure is recorded and the next client in the pool is tried.
+   *
+   * Throws: Any non-rpc exception that occurs, a TCompoundOperationException
+   *   if all clients failed with an rpc exception (if keepTrying is false).
+   *
+   * Example:
+   * ---
+   * interface Foo { string bar(); }
+   * auto poolClient = tClientPool([tClient!Foo(someProtocol)]);
+   * auto result = poolClient.execute((c){ return c.bar(); });
+   * ---
+   */
+  ResultType execute(ResultType)(scope ResultType delegate(Client) work) {
+    return executeOnPool!Client(work);
+  }
+
+  /**
+   * Adds a client to the pool.
+   */
+  void addClient(Client client) {
+    pool_.add(client);
+  }
+
+  /**
+   * Removes a client from the pool.
+   *
+   * Returns: Whether the client was found in the pool.
+   */
+  bool removeClient(Client client) {
+    return pool_.remove(client);
+  }
+
+  mixin(poolForwardCode!Interface());
+
+  /// Whether to open the underlying transports of a client before trying to
+  /// execute a method if they are not open. This is usually desirable
+  /// because it allows e.g. to automatically reconnect to a remote server
+  /// if the network connection is dropped.
+  ///
+  /// Defaults to true.
+  bool reopenTransports = true;
+
+  /// Called to determine whether an exception comes from a client from the
+  /// pool not working properly, or if it an exception thrown at the
+  /// application level.
+  ///
+  /// If the delegate returns true, the server/connection is considered to be
+  /// at fault, if it returns false, the exception is just passed on to the
+  /// caller.
+  ///
+  /// By default, returns true for instances of TTransportException and
+  /// TApplicationException, false otherwise.
+  bool delegate(Exception) rpcFaultFilter;
+
+  /**
+   * Whether to keep trying to find a working client if all have failed in a
+   * row.
+   *
+   * Defaults to false.
+   */
+  bool keepTrying() const @property {
+    return pool_.cycle;
+  }
+
+  /// Ditto
+  void keepTrying(bool value) @property {
+    pool_.cycle = value;
+  }
+
+  /**
+   * Whether to use a random permutation of the client pool on every call to
+   * execute(). This can be used e.g. as a simple form of load balancing.
+   *
+   * Defaults to true.
+   */
+  bool permuteClients() const @property {
+    return pool_.permute;
+  }
+
+  /// Ditto
+  void permuteClients(bool value) @property {
+    pool_.permute = value;
+  }
+
+  /**
+   * The number of consecutive faults after which a client is disabled until
+   * faultDisableDuration has passed. 0 to never disable clients.
+   *
+   * Defaults to 0.
+   */
+  ushort faultDisableCount() @property {
+    return pool_.faultDisableCount;
+  }
+
+  /// Ditto
+  void faultDisableCount(ushort value) @property {
+    pool_.faultDisableCount = value;
+  }
+
+  /**
+   * The duration for which a client is no longer considered after it has
+   * failed too often.
+   *
+   * Defaults to one second.
+   */
+  Duration faultDisableDuration() @property {
+    return pool_.faultDisableDuration;
+  }
+
+  /// Ditto
+  void faultDisableDuration(Duration value) @property {
+    pool_.faultDisableDuration = value;
+  }
+
+protected:
+  ResultType executeOnPool(ResultType)(scope ResultType delegate(Client) work) {
+    auto clients = pool_[];
+    if (clients.empty) {
+      throw new TException("No clients available to try.");
+    }
+
+    while (true) {
+      Exception[] rpcExceptions;
+      while (!clients.empty) {
+        auto c = clients.front;
+        clients.popFront;
+        try {
+          scope (success) {
+            pool_.recordSuccess(c);
+          }
+
+          if (reopenTransports) {
+            c.inputProtocol.transport.open();
+            c.outputProtocol.transport.open();
+          }
+
+          return work(c);
+        } catch (Exception e) {
+          if (rpcFaultFilter && rpcFaultFilter(e)) {
+            pool_.recordFault(c);
+            rpcExceptions ~= e;
+          } else {
+            // We are dealing with a normal exception thrown by the
+            // server-side method, just pass it on. As far as we are
+            // concerned, the method call succeded.
+            pool_.recordSuccess(c);
+            throw e;
+          }
+        }
+      }
+
+      // If we get here, no client succeeded during the current iteration.
+      Duration waitTime;
+      Client dummy;
+      if (clients.willBecomeNonempty(dummy, waitTime)) {
+        if (waitTime > dur!"hnsecs"(0)) {
+          import core.thread;
+          Thread.sleep(waitTime);
+        }
+      } else {
+        throw new TCompoundOperationException("All clients failed.",
+          rpcExceptions);
+      }
+    }
+  }
+
+private:
+  TResourcePool!Client pool_;
+}
+
+private {
+  // Cannot use an anonymous delegate literal for this because they aren't
+  // allowed in class scope.
+  string poolForwardCode(Interface)() {
+    string code = "";
+
+    foreach (methodName; AllMemberMethodNames!Interface) {
+      enum qn = "Interface." ~ methodName;
+      code ~= "ReturnType!(" ~ qn ~ ") " ~ methodName ~
+        "(ParameterTypeTuple!(" ~ qn ~ ") args) {\n";
+      code ~= "return executeOnPool((Client c){ return c." ~
+        methodName ~ "(args); });\n";
+      code ~= "}\n";
+    }
+
+    return code;
+  }
+}
+
+/**
+ * TClientPool construction helper to avoid having to explicitly specify
+ * the interface type, i.e. to allow the constructor being called using IFTI
+ * (see $(DMDBUG 6082, D Bugzilla enhancement requet 6082)).
+ */
+TClientPool!Interface tClientPool(Interface)(
+  TClientBase!Interface[] clients
+) if (isService!Interface) {
+  return new typeof(return)(clients);
+}
diff --git a/lib/d/src/thrift/codegen/idlgen.d b/lib/d/src/thrift/codegen/idlgen.d
new file mode 100644
index 0000000..03e9b90
--- /dev/null
+++ b/lib/d/src/thrift/codegen/idlgen.d
@@ -0,0 +1,767 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/**
+ * Contains <b>experimental</b> functionality for generating Thrift IDL files
+ * (.thrift) from existing D data structures, i.e. the reverse of what the
+ * Thrift compiler does.
+ */
+module thrift.codegen.idlgen;
+
+import std.algorithm : find;
+import std.array : empty, front;
+import std.conv : to;
+import std.traits : EnumMembers, isSomeFunction, OriginalType,
+  ParameterTypeTuple, ReturnType;
+import std.typetuple : allSatisfy, staticIndexOf, staticMap, NoDuplicates,
+  TypeTuple;
+import thrift.base;
+import thrift.codegen.base;
+import thrift.internal.codegen;
+import thrift.internal.ctfe;
+import thrift.util.hashset;
+
+/**
+ * True if the passed type is a Thrift entity (struct, exception, enum,
+ * service).
+ */
+alias Any!(isStruct, isException, isEnum, isService) isThriftEntity;
+
+/**
+ * Returns an IDL string describing the passed »root« entities and all types
+ * they depend on.
+ */
+template idlString(Roots...) if (allSatisfy!(isThriftEntity, Roots)) {
+  enum idlString = idlStringImpl!Roots.result;
+}
+
+private {
+  template idlStringImpl(Roots...) if (allSatisfy!(isThriftEntity, Roots)) {
+    alias ForAllWithList!(
+      ConfinedTuple!(StaticFilter!(isService, Roots)),
+      AddBaseServices
+    ) Services;
+
+    alias TypeTuple!(
+      StaticFilter!(isEnum, Roots),
+      ForAllWithList!(
+        ConfinedTuple!(
+          StaticFilter!(Any!(isException, isStruct), Roots),
+          staticMap!(CompositeTypeDeps, staticMap!(ServiceTypeDeps, Services))
+        ),
+        AddStructWithDeps
+      )
+    ) Types;
+
+    enum result = ctfeJoin(
+      [
+        staticMap!(
+          enumIdlString,
+          StaticFilter!(isEnum, Types)
+        ),
+        staticMap!(
+          structIdlString,
+          StaticFilter!(Any!(isStruct, isException), Types)
+        ),
+        staticMap!(
+          serviceIdlString,
+          Services
+        )
+      ],
+      "\n"
+    );
+  }
+
+  template ServiceTypeDeps(T) if (isService!T) {
+    alias staticMap!(
+      PApply!(MethodTypeDeps, T),
+      FilterMethodNames!(T, __traits(derivedMembers, T))
+    ) ServiceTypeDeps;
+  }
+
+  template MethodTypeDeps(T, string name) if (
+    isService!T && isSomeFunction!(MemberType!(T, name))
+  ) {
+    alias TypeTuple!(
+      ReturnType!(MemberType!(T, name)),
+      ParameterTypeTuple!(MemberType!(T, name)),
+      ExceptionTypes!(T, name)
+    ) MethodTypeDeps;
+  }
+
+  template ExceptionTypes(T, string name) if (
+    isService!T && isSomeFunction!(MemberType!(T, name))
+  ) {
+    mixin({
+      enum meta = find!`a.name == b`(getMethodMeta!T, name);
+      if (meta.empty) return "alias TypeTuple!() ExceptionTypes;";
+
+      string result = "alias TypeTuple!(";
+      foreach (i, e; meta.front.exceptions) {
+        if (i > 0) result ~= ", ";
+        result ~= "mixin(`T." ~ e.type ~ "`)";
+      }
+      result ~= ") ExceptionTypes;";
+      return result;
+    }());
+  }
+
+  template AddBaseServices(T, List...) {
+    static if (staticIndexOf!(T, List) == -1) {
+      alias NoDuplicates!(BaseServices!T, List) AddBaseServices;
+    } else {
+      alias List AddStructWithDeps;
+    }
+  }
+
+  unittest {
+    interface A {}
+    interface B : A {}
+    interface C : B {}
+    interface D : A {}
+
+    static assert(is(AddBaseServices!(C) == TypeTuple!(A, B, C)));
+    static assert(is(ForAllWithList!(ConfinedTuple!(C, D), AddBaseServices) ==
+      TypeTuple!(A, D, B, C)));
+  }
+
+  template BaseServices(T, Rest...) if (isService!T) {
+    static if (isDerivedService!T) {
+      alias BaseServices!(BaseService!T, T, Rest) BaseServices;
+    } else {
+      alias TypeTuple!(T, Rest) BaseServices;
+    }
+  }
+
+  template AddStructWithDeps(T, List...) {
+    static if (staticIndexOf!(T, List) == -1) {
+      // T is not already in the List, so add T and the types it depends on in
+      // the front. Because with the Thrift compiler types can only depend on
+      // other types that have already been defined, we collect all the
+      // dependencies, prepend them to the list, and then prune the duplicates
+      // (keeping the first occurences). If this requirement should ever be
+      // dropped from Thrift, this could be easily adapted to handle circular
+      // dependencies by passing TypeTuple!(T, List) to ForAllWithList instead
+      // of appending List afterwards, and removing the now unneccesary
+      // NoDuplicates.
+      alias NoDuplicates!(
+        ForAllWithList!(
+          ConfinedTuple!(
+            staticMap!(
+              CompositeTypeDeps,
+              staticMap!(
+                PApply!(MemberType, T),
+                FieldNames!T
+              )
+            )
+          ),
+          .AddStructWithDeps,
+          T
+        ),
+        List
+      ) AddStructWithDeps;
+    } else {
+      alias List AddStructWithDeps;
+    }
+  }
+
+  version (unittest) {
+    struct A {}
+    struct B {
+      A a;
+      int b;
+      A c;
+      string d;
+    }
+    struct C {
+      B b;
+      A a;
+    }
+
+    static assert(is(AddStructWithDeps!C == TypeTuple!(A, B, C)));
+
+    struct D {
+      C c;
+      mixin TStructHelpers!([TFieldMeta("c", 0, TReq.IGNORE)]);
+    }
+    static assert(is(AddStructWithDeps!D == TypeTuple!(D)));
+  }
+
+  version (unittest) {
+    // Circles in the type dependency graph are not allowed in Thrift, but make
+    // sure we fail in a sane way instead of crashing the compiler.
+
+    struct Rec1 {
+      Rec2[] other;
+    }
+
+    struct Rec2 {
+      Rec1[] other;
+    }
+
+    static assert(!__traits(compiles, AddStructWithDeps!Rec1));
+  }
+
+  /*
+   * Returns the non-primitive types T directly depends on.
+   *
+   * For example, CompositeTypeDeps!int would yield an empty type tuple,
+   * CompositeTypeDeps!SomeStruct would give SomeStruct, and
+   * CompositeTypeDeps!(A[B]) both CompositeTypeDeps!A and CompositeTypeDeps!B.
+   */
+  template CompositeTypeDeps(T) {
+    static if (is(FullyUnqual!T == bool) || is(FullyUnqual!T == byte) ||
+      is(FullyUnqual!T == short) || is(FullyUnqual!T == int) ||
+      is(FullyUnqual!T == long) || is(FullyUnqual!T : string) ||
+      is(FullyUnqual!T == double) || is(FullyUnqual!T == void)
+    ) {
+      alias TypeTuple!() CompositeTypeDeps;
+    } else static if (is(FullyUnqual!T _ : U[], U)) {
+      alias CompositeTypeDeps!U CompositeTypeDeps;
+    } else static if (is(FullyUnqual!T _ : HashSet!E, E)) {
+      alias CompositeTypeDeps!E CompositeTypeDeps;
+    } else static if (is(FullyUnqual!T _ : V[K], K, V)) {
+      alias TypeTuple!(CompositeTypeDeps!K, CompositeTypeDeps!V) CompositeTypeDeps;
+    } else static if (is(FullyUnqual!T == enum) || is(FullyUnqual!T == struct) ||
+      is(FullyUnqual!T : TException)
+    ) {
+      alias TypeTuple!(FullyUnqual!T) CompositeTypeDeps;
+    } else {
+      static assert(false, "Cannot represent type in Thrift: " ~ T.stringof);
+    }
+  }
+}
+
+/**
+ * Returns an IDL string describing the passed service. IDL code for any type
+ * dependcies is not included.
+ */
+template serviceIdlString(T) if (isService!T) {
+  enum serviceIdlString = {
+    string result = "service " ~ T.stringof;
+    static if (isDerivedService!T) {
+      result ~= " extends " ~ BaseService!T.stringof;
+    }
+    result ~= " {\n";
+
+    foreach (methodName; FilterMethodNames!(T, __traits(derivedMembers, T))) {
+      result ~= "  ";
+
+      enum meta = find!`a.name == b`(T.methodMeta, methodName);
+
+      static if (!meta.empty && meta.front.type == TMethodType.ONEWAY) {
+        result ~= "oneway ";
+      }
+
+      alias ReturnType!(MemberType!(T, methodName)) RT;
+      static if (is(RT == void)) {
+        // We special-case this here instead of adding void to dToIdlType to
+        // avoid accepting things like void[].
+        result ~= "void ";
+      } else {
+        result ~= dToIdlType!RT ~ " ";
+      }
+      result ~= methodName ~ "(";
+
+      short lastId;
+      foreach (i, ParamType; ParameterTypeTuple!(MemberType!(T, methodName))) {
+        static if (!meta.empty && i < meta.front.params.length) {
+          enum havePM = true;
+        } else {
+          enum havePM = false;
+        }
+
+        short id;
+        static if (havePM) {
+          id = meta.front.params[i].id;
+        } else {
+          id = --lastId;
+        }
+
+        string paramName;
+        static if (havePM) {
+          paramName = meta.front.params[i].name;
+        } else {
+          paramName = "param" ~ to!string(i + 1);
+        }
+
+        result ~= to!string(id) ~ ": " ~ dToIdlType!ParamType ~ " " ~ paramName;
+
+        static if (havePM && !meta.front.params[i].defaultValue.empty) {
+          result ~= " = " ~ dToIdlConst(mixin(meta.front.params[i].defaultValue));
+        } else {
+          // Unfortunately, getting the default value for parameters from a
+          // function alias isn't possible – we can't transfer the default
+          // value to the IDL e.g. for interface Foo { void foo(int a = 5); }
+          // without the user explicitly declaring it in metadata.
+        }
+        result ~= ", ";
+      }
+      result ~= ")";
+
+      static if (!meta.empty && !meta.front.exceptions.empty) {
+        result ~= " throws (";
+        foreach (e; meta.front.exceptions) {
+          result ~= to!string(e.id) ~ ": " ~ e.type ~ " " ~ e.name ~ ", ";
+        }
+        result ~= ")";
+      }
+
+      result ~= ",\n";
+    }
+
+    result ~= "}\n";
+    return result;
+  }();
+}
+
+/**
+ * Returns an IDL string describing the passed enum. IDL code for any type
+ * dependcies is not included.
+ */
+template enumIdlString(T) if (isEnum!T) {
+  enum enumIdlString = {
+    static assert(is(OriginalType!T : long),
+      "Can only have integer enums in Thrift (not " ~ OriginalType!T.stringof ~
+      ", for " ~ T.stringof ~ ").");
+
+    string result = "enum " ~ T.stringof ~ " {\n";
+
+    foreach (name; __traits(derivedMembers, T)) {
+      result ~= "  " ~ name ~ " = " ~ dToIdlConst(GetMember!(T, name)) ~ ",\n";
+    }
+
+    result ~= "}\n";
+    return result;
+  }();
+}
+
+/**
+ * Returns an IDL string describing the passed struct. IDL code for any type
+ * dependcies is not included.
+ */
+template structIdlString(T) if (isStruct!T || isException!T) {
+  enum structIdlString = {
+    mixin({
+      string code = "";
+      foreach (field; getFieldMeta!T) {
+        code ~= "static assert(is(MemberType!(T, `" ~ field.name ~ "`)));\n";
+      }
+      return code;
+    }());
+
+    string result;
+    static if (isException!T) {
+      result = "exception ";
+    } else {
+      result = "struct ";
+    }
+    result ~= T.stringof ~ " {\n";
+
+    // The last automatically assigned id – fields with no meta information
+    // are assigned (in lexical order) descending negative ids, starting with
+    // -1, just like the Thrift compiler does.
+    short lastId;
+
+    foreach (name; FieldNames!T) {
+      enum meta = find!`a.name == b`(getFieldMeta!T, name);
+
+      static if (meta.empty || meta.front.req != TReq.IGNORE) {
+        short id;
+        static if (meta.empty) {
+          id = --lastId;
+        } else {
+          id = meta.front.id;
+        }
+
+        result ~= "  " ~ to!string(id) ~ ":";
+        static if (!meta.empty) {
+          result ~= dToIdlReq(meta.front.req);
+        }
+        result ~= " " ~ dToIdlType!(MemberType!(T, name)) ~ " " ~ name;
+
+        static if (!meta.empty && !meta.front.defaultValue.empty) {
+          result ~= " = " ~ dToIdlConst(mixin(meta.front.defaultValue));
+        } else static if (__traits(compiles, fieldInitA!(T, name))) {
+          static if (is(typeof(fieldInitA!(T, name))) &&
+            !is(typeof(fieldInitA!(T, name)) == void)
+          ) {
+            result ~= " = " ~ dToIdlConst(fieldInitA!(T, name));
+          }
+        } else static if (is(typeof(fieldInitB!(T, name))) &&
+          !is(typeof(fieldInitB!(T, name)) == void)
+        ) {
+          result ~= " = " ~ dToIdlConst(fieldInitB!(T, name));
+        }
+        result ~= ",\n";
+      }
+    }
+
+    result ~= "}\n";
+    return result;
+  }();
+}
+
+private {
+  // This very convoluted way of doing things was chosen because putting the
+  // static if directly into structIdlString caused »not evaluatable at compile
+  // time« errors to slip through even though typeof() was used, resp. the
+  // condition to be true even though the value couldn't actually be read at
+  // compile time due to a @@BUG@@ in DMD 2.055.
+  // The extra »compiled« field in fieldInitA is needed because we must not try
+  // to use != if !is compiled as well (but was false), e.g. for floating point
+  // types.
+  template fieldInitA(T, string name) {
+    static if (mixin("T.init." ~ name) !is MemberType!(T, name).init) {
+      enum fieldInitA = mixin("T.init." ~ name);
+    }
+  }
+
+  template fieldInitB(T, string name) {
+    static if (mixin("T.init." ~ name) != MemberType!(T, name).init) {
+      enum fieldInitB = mixin("T.init." ~ name);
+    }
+  }
+
+  template dToIdlType(T) {
+    static if (is(FullyUnqual!T == bool)) {
+      enum dToIdlType = "bool";
+    } else static if (is(FullyUnqual!T == byte)) {
+      enum dToIdlType = "byte";
+    } else static if (is(FullyUnqual!T == double)) {
+      enum dToIdlType = "double";
+    } else static if (is(FullyUnqual!T == short)) {
+      enum dToIdlType = "i16";
+    } else static if (is(FullyUnqual!T == int)) {
+      enum dToIdlType = "i32";
+    } else static if (is(FullyUnqual!T == long)) {
+      enum dToIdlType = "i64";
+    } else static if (is(FullyUnqual!T : string)) {
+      enum dToIdlType = "string";
+    } else static if (is(FullyUnqual!T _ : U[], U)) {
+      enum dToIdlType = "list<" ~ dToIdlType!U ~ ">";
+    } else static if (is(FullyUnqual!T _ : V[K], K, V)) {
+      enum dToIdlType = "map<" ~ dToIdlType!K ~ ", " ~ dToIdlType!V ~ ">";
+    } else static if (is(FullyUnqual!T _ : HashSet!E, E)) {
+      enum dToIdlType = "set<" ~ dToIdlType!E ~ ">";
+    } else static if (is(FullyUnqual!T == struct) || is(FullyUnqual!T == enum) ||
+      is(FullyUnqual!T : TException)
+    ) {
+      enum dToIdlType = FullyUnqual!(T).stringof;
+    } else {
+      static assert(false, "Cannot represent type in Thrift: " ~ T.stringof);
+    }
+  }
+
+  string dToIdlReq(TReq req) {
+    switch (req) {
+      case TReq.REQUIRED: return " required";
+      case TReq.OPTIONAL: return " optional";
+      default: return "";
+    }
+  }
+
+  string dToIdlConst(T)(T value) {
+    static if (is(FullyUnqual!T == bool)) {
+      return value ? "1" : "0";
+    } else static if (is(FullyUnqual!T == byte) ||
+      is(FullyUnqual!T == short) || is(FullyUnqual!T == int) ||
+      is(FullyUnqual!T == long)
+    ) {
+      return to!string(value);
+    } else static if (is(FullyUnqual!T : string)) {
+      return `"` ~ to!string(value) ~ `"`;
+    } else static if (is(FullyUnqual!T == double)) {
+      return ctfeToString(value);
+    } else static if (is(FullyUnqual!T _ : U[], U) ||
+      is(FullyUnqual!T _ : HashSet!E, E)
+    ) {
+      string result = "[";
+      foreach (e; value) {
+        result ~= dToIdlConst(e) ~ ", ";
+      }
+      result ~= "]";
+      return result;
+    } else static if (is(FullyUnqual!T _ : V[K], K, V)) {
+      string result = "{";
+      foreach (key, val; value) {
+        result ~= dToIdlConst(key) ~ ": " ~ dToIdlConst(val) ~ ", ";
+      }
+      result ~= "}";
+      return result;
+    } else static if (is(FullyUnqual!T == enum)) {
+      import std.conv;
+      import std.traits;
+      return to!string(cast(OriginalType!T)value);
+    } else static if (is(FullyUnqual!T == struct) ||
+      is(FullyUnqual!T : TException)
+    ) {
+      string result = "{";
+      foreach (name; __traits(derivedMembers, T)) {
+        static if (memberReq!(T, name) != TReq.IGNORE) {
+          result ~= name ~ ": " ~ dToIdlConst(mixin("value." ~ name)) ~ ", ";
+        }
+      }
+      result ~= "}";
+      return result;
+    } else {
+      static assert(false, "Cannot represent type in Thrift: " ~ T.stringof);
+    }
+  }
+}
+
+version (unittest) {
+  enum Foo {
+    a = 1,
+    b = 10,
+    c = 5
+  }
+
+  static assert(enumIdlString!Foo ==
+`enum Foo {
+  a = 1,
+  b = 10,
+  c = 5,
+}
+`);
+}
+
+
+version (unittest) {
+  struct WithoutMeta {
+    string a;
+    int b;
+  }
+
+  struct WithDefaults {
+    string a = "asdf";
+    double b = 3.1415;
+    WithoutMeta c;
+
+    mixin TStructHelpers!([
+      TFieldMeta("c", 1, TReq.init, `WithoutMeta("foo", 3)`)
+    ]);
+  }
+
+  // These are from DebugProtoTest.thrift.
+  struct OneOfEach {
+    bool im_true;
+    bool im_false;
+    byte a_bite;
+    short integer16;
+    int integer32;
+    long integer64;
+    double double_precision;
+    string some_characters;
+    string zomg_unicode;
+    bool what_who;
+    string base64;
+    byte[] byte_list;
+    short[] i16_list;
+    long[] i64_list;
+
+    mixin TStructHelpers!([
+      TFieldMeta(`im_true`, 1),
+      TFieldMeta(`im_false`, 2),
+      TFieldMeta(`a_bite`, 3, TReq.OPT_IN_REQ_OUT, q{cast(byte)127}),
+      TFieldMeta(`integer16`, 4, TReq.OPT_IN_REQ_OUT, q{cast(short)32767}),
+      TFieldMeta(`integer32`, 5),
+      TFieldMeta(`integer64`, 6, TReq.OPT_IN_REQ_OUT, q{10000000000L}),
+      TFieldMeta(`double_precision`, 7),
+      TFieldMeta(`some_characters`, 8),
+      TFieldMeta(`zomg_unicode`, 9),
+      TFieldMeta(`what_who`, 10),
+      TFieldMeta(`base64`, 11),
+      TFieldMeta(`byte_list`, 12, TReq.OPT_IN_REQ_OUT, q{{
+        byte[] v;
+        v ~= cast(byte)1;
+        v ~= cast(byte)2;
+        v ~= cast(byte)3;
+        return v;
+      }()}),
+      TFieldMeta(`i16_list`, 13, TReq.OPT_IN_REQ_OUT, q{{
+        short[] v;
+        v ~= cast(short)1;
+        v ~= cast(short)2;
+        v ~= cast(short)3;
+        return v;
+      }()}),
+      TFieldMeta(`i64_list`, 14, TReq.OPT_IN_REQ_OUT, q{{
+        long[] v;
+        v ~= 1L;
+        v ~= 2L;
+        v ~= 3L;
+        return v;
+      }()})
+    ]);
+  }
+
+  struct Bonk {
+    int type;
+    string message;
+
+    mixin TStructHelpers!([
+      TFieldMeta(`type`, 1),
+      TFieldMeta(`message`, 2)
+    ]);
+  }
+
+  struct HolyMoley {
+    OneOfEach[] big;
+    HashSet!(string[]) contain;
+    Bonk[][string] bonks;
+
+    mixin TStructHelpers!([
+      TFieldMeta(`big`, 1),
+      TFieldMeta(`contain`, 2),
+      TFieldMeta(`bonks`, 3)
+    ]);
+  }
+
+  static assert(structIdlString!WithoutMeta ==
+`struct WithoutMeta {
+  -1: string a,
+  -2: i32 b,
+}
+`);
+
+  static assert(structIdlString!WithDefaults ==
+`struct WithDefaults {
+  -1: string a = "asdf",
+  -2: double b = 3.1415,
+  1: WithoutMeta c = {a: "foo", b: 3, },
+}
+`);
+
+  static assert(structIdlString!OneOfEach ==
+`struct OneOfEach {
+  1: bool im_true,
+  2: bool im_false,
+  3: byte a_bite = 127,
+  4: i16 integer16 = 32767,
+  5: i32 integer32,
+  6: i64 integer64 = 10000000000,
+  7: double double_precision,
+  8: string some_characters,
+  9: string zomg_unicode,
+  10: bool what_who,
+  11: string base64,
+  12: list<byte> byte_list = [1, 2, 3, ],
+  13: list<i16> i16_list = [1, 2, 3, ],
+  14: list<i64> i64_list = [1, 2, 3, ],
+}
+`);
+
+  static assert(structIdlString!Bonk ==
+`struct Bonk {
+  1: i32 type,
+  2: string message,
+}
+`);
+
+  static assert(structIdlString!HolyMoley ==
+`struct HolyMoley {
+  1: list<OneOfEach> big,
+  2: set<list<string>> contain,
+  3: map<string, list<Bonk>> bonks,
+}
+`);
+}
+
+version (unittest) {
+  class ExceptionWithAMap : TException {
+    string blah;
+    string[string] map_field;
+
+    mixin TStructHelpers!([
+      TFieldMeta(`blah`, 1),
+      TFieldMeta(`map_field`, 2)
+    ]);
+  }
+
+  interface Srv {
+    void voidMethod();
+    int primitiveMethod();
+    OneOfEach structMethod();
+    void methodWithDefaultArgs(int something);
+    void onewayMethod();
+    void exceptionMethod();
+
+    alias .ExceptionWithAMap ExceptionWithAMap;
+
+    enum methodMeta = [
+      TMethodMeta(`methodWithDefaultArgs`,
+        [TParamMeta(`something`, 1, q{2})]
+      ),
+      TMethodMeta(`onewayMethod`,
+        [],
+        [],
+        TMethodType.ONEWAY
+      ),
+      TMethodMeta(`exceptionMethod`,
+        [],
+        [
+          TExceptionMeta("a", 1, "ExceptionWithAMap"),
+          TExceptionMeta("b", 2, "ExceptionWithAMap")
+        ]
+      )
+    ];
+  }
+
+  interface ChildSrv : Srv {
+    int childMethod(int arg);
+  }
+
+  static assert(idlString!ChildSrv ==
+`exception ExceptionWithAMap {
+  1: string blah,
+  2: map<string, string> map_field,
+}
+
+struct OneOfEach {
+  1: bool im_true,
+  2: bool im_false,
+  3: byte a_bite = 127,
+  4: i16 integer16 = 32767,
+  5: i32 integer32,
+  6: i64 integer64 = 10000000000,
+  7: double double_precision,
+  8: string some_characters,
+  9: string zomg_unicode,
+  10: bool what_who,
+  11: string base64,
+  12: list<byte> byte_list = [1, 2, 3, ],
+  13: list<i16> i16_list = [1, 2, 3, ],
+  14: list<i64> i64_list = [1, 2, 3, ],
+}
+
+service Srv {
+  void voidMethod(),
+  i32 primitiveMethod(),
+  OneOfEach structMethod(),
+  void methodWithDefaultArgs(1: i32 something = 2, ),
+  oneway void onewayMethod(),
+  void exceptionMethod() throws (1: ExceptionWithAMap a, 2: ExceptionWithAMap b, ),
+}
+
+service ChildSrv extends Srv {
+  i32 childMethod(-1: i32 param1, ),
+}
+`);
+}
diff --git a/lib/d/src/thrift/codegen/processor.d b/lib/d/src/thrift/codegen/processor.d
new file mode 100644
index 0000000..e6b77fa
--- /dev/null
+++ b/lib/d/src/thrift/codegen/processor.d
@@ -0,0 +1,497 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+module thrift.codegen.processor;
+
+import std.algorithm : find;
+import std.array : empty, front;
+import std.conv : to;
+import std.traits : ParameterTypeTuple, ReturnType, Unqual;
+import std.typetuple : allSatisfy, TypeTuple;
+import std.variant : Variant;
+import thrift.base;
+import thrift.codegen.base;
+import thrift.internal.codegen;
+import thrift.internal.ctfe;
+import thrift.protocol.base;
+import thrift.protocol.processor;
+
+/**
+ * Service processor for Interface, which implements TProcessor by
+ * synchronously forwarding requests for the service methods to a handler
+ * implementing Interface.
+ *
+ * The generated class implements TProcessor and additionally allows a
+ * TProcessorEventHandler to be specified via the public eventHandler property.
+ * The constructor takes a single argument of type Interface, which is the
+ * handler to forward the requests to:
+ * ---
+ * this(Interface iface);
+ * TProcessorEventHandler eventHandler;
+ * ---
+ *
+ * If Interface is derived from another service BaseInterface, this class is
+ * also derived from TServiceProcessor!BaseInterface.
+ *
+ * The optional Protocols template tuple parameter can be used to specify
+ * one or more TProtocol implementations to specifically generate code for. If
+ * the actual types of the protocols passed to process() at runtime match one
+ * of the items from the list, the optimized code paths are taken, otherwise,
+ * a generic TProtocol version is used as fallback. For cases where the input
+ * and output protocols differ, TProtocolPair!(InputProtocol, OutputProtocol)
+ * can be used in the Protocols list:
+ * ---
+ * interface FooService { void foo(); }
+ * class FooImpl { override void foo {} }
+ *
+ * // Provides fast path if TBinaryProtocol!TBufferedTransport is used for
+ * // both input and output:
+ * alias TServiceProcessor!(FooService, TBinaryProtocol!TBufferedTransport)
+ *   BinaryProcessor;
+ *
+ * auto proc = new BinaryProcessor(new FooImpl());
+ *
+ * // Low overhead.
+ * proc.process(tBinaryProtocol(tBufferTransport(someSocket)));
+ *
+ * // Not in the specialization list – higher overhead.
+ * proc.process(tBinaryProtocol(tFramedTransport(someSocket)));
+ *
+ * // Same as above, but optimized for the Compact protocol backed by a
+ * // TPipedTransport for input and a TBufferedTransport for output.
+ * alias TServiceProcessor!(FooService, TProtocolPair!(
+ *   TCompactProtocol!TPipedTransport, TCompactProtocol!TBufferedTransport)
+ * ) MixedProcessor;
+ * ---
+ */
+template TServiceProcessor(Interface, Protocols...) if (
+  isService!Interface && allSatisfy!(isTProtocolOrPair, Protocols)
+) {
+  mixin({
+    static if (is(Interface BaseInterfaces == super) && BaseInterfaces.length > 0) {
+      static assert(BaseInterfaces.length == 1,
+        "Services cannot be derived from more than one parent.");
+
+      string code = "class TServiceProcessor : " ~
+        "TServiceProcessor!(BaseService!Interface) {\n";
+      code ~= "private Interface iface_;\n";
+
+      string constructorCode = "this(Interface iface) {\n";
+      constructorCode ~= "super(iface);\n";
+      constructorCode ~= "iface_ = iface;\n";
+    } else {
+      string code = "class TServiceProcessor : TProcessor {";
+      code ~= q{
+        override bool process(TProtocol iprot, TProtocol oprot,
+          Variant context = Variant()
+        ) {
+          auto msg = iprot.readMessageBegin();
+
+          void writeException(TApplicationException e) {
+            oprot.writeMessageBegin(TMessage(msg.name, TMessageType.EXCEPTION,
+              msg.seqid));
+            e.write(oprot);
+            oprot.writeMessageEnd();
+            oprot.transport.writeEnd();
+            oprot.transport.flush();
+          }
+
+          if (msg.type != TMessageType.CALL && msg.type != TMessageType.ONEWAY) {
+            skip(iprot, TType.STRUCT);
+            iprot.readMessageEnd();
+            iprot.transport.readEnd();
+
+            writeException(new TApplicationException(
+              TApplicationException.Type.INVALID_MESSAGE_TYPE));
+            return false;
+          }
+
+          auto dg = msg.name in processMap_;
+          if (!dg) {
+            skip(iprot, TType.STRUCT);
+            iprot.readMessageEnd();
+            iprot.transport.readEnd();
+
+            writeException(new TApplicationException("Invalid method name: '" ~
+              msg.name ~ "'.", TApplicationException.Type.INVALID_MESSAGE_TYPE));
+
+            return false;
+          }
+
+          (*dg)(msg.seqid, iprot, oprot, context);
+          return true;
+        }
+
+        TProcessorEventHandler eventHandler;
+
+        alias void delegate(int, TProtocol, TProtocol, Variant) ProcessFunc;
+        protected ProcessFunc[string] processMap_;
+        private Interface iface_;
+      };
+
+      string constructorCode = "this(Interface iface) {\n";
+      constructorCode ~= "iface_ = iface;\n";
+    }
+
+    // Generate the handling code for each method, consisting of the dispatch
+    // function, registering it in the constructor, and the actual templated
+    // handler function.
+    foreach (methodName;
+      FilterMethodNames!(Interface, __traits(derivedMembers, Interface))
+    ) {
+      // Register the processing function in the constructor.
+      immutable procFuncName = "process_" ~ methodName;
+      immutable dispatchFuncName = procFuncName ~ "_protocolDispatch";
+      constructorCode ~= "processMap_[`" ~ methodName ~ "`] = &" ~
+        dispatchFuncName ~ ";\n";
+
+      bool methodMetaFound;
+      TMethodMeta methodMeta;
+      static if (is(typeof(Interface.methodMeta) : TMethodMeta[])) {
+        enum meta = find!`a.name == b`(Interface.methodMeta, methodName);
+        if (!meta.empty) {
+          methodMetaFound = true;
+          methodMeta = meta.front;
+        }
+      }
+
+      // The dispatch function to call the specialized handler functions. We
+      // test the protocols if they can be converted to one of the passed
+      // protocol types, and if not, fall back to the generic TProtocol
+      // version of the processing function.
+      code ~= "void " ~ dispatchFuncName ~
+        "(int seqid, TProtocol iprot, TProtocol oprot, Variant context) {\n";
+      code ~= "foreach (Protocol; TypeTuple!(Protocols, TProtocol)) {\n";
+      code ~= q{
+        static if (is(Protocol _ : TProtocolPair!(I, O), I, O)) {
+          alias I IProt;
+          alias O OProt;
+        } else {
+          alias Protocol IProt;
+          alias Protocol OProt;
+        }
+        auto castedIProt = cast(IProt)iprot;
+        auto castedOProt = cast(OProt)oprot;
+      };
+      code ~= "if (castedIProt && castedOProt) {\n";
+      code ~= procFuncName ~
+        "!(IProt, OProt)(seqid, castedIProt, castedOProt, context);\n";
+      code ~= "return;\n";
+      code ~= "}\n";
+      code ~= "}\n";
+      code ~= "throw new TException(`Internal error: Null iprot/oprot " ~
+        "passed to processor protocol dispatch function.`);\n";
+      code ~= "}\n";
+
+      // The actual handler function, templated on the input and output
+      // protocol types.
+      code ~= "void " ~ procFuncName ~ "(IProt, OProt)(int seqid, IProt " ~
+        "iprot, OProt oprot, Variant connectionContext) " ~
+        "if (isTProtocol!IProt && isTProtocol!OProt) {\n";
+      code ~= "TArgsStruct!(Interface, `" ~ methodName ~ "`) args;\n";
+
+      // Store the (qualified) method name in a manifest constant to avoid
+      // having to litter the code below with lots of string manipulation.
+      code ~= "enum methodName = `" ~ methodName ~ "`;\n";
+
+      code ~= q{
+        enum qName = Interface.stringof ~ "." ~ methodName;
+
+        Variant callContext;
+        if (eventHandler) {
+          callContext = eventHandler.createContext(qName, connectionContext);
+        }
+
+        scope (exit) {
+          if (eventHandler) {
+            eventHandler.deleteContext(callContext, qName);
+          }
+        }
+
+        if (eventHandler) eventHandler.preRead(callContext, qName);
+
+        args.read(iprot);
+        iprot.readMessageEnd();
+        iprot.transport.readEnd();
+
+        if (eventHandler) eventHandler.postRead(callContext, qName);
+      };
+
+      code ~= "TResultStruct!(Interface, `" ~ methodName ~ "`) result;\n";
+      code ~= "try {\n";
+
+      // Generate the parameter list to pass to the called iface function.
+      string[] paramList;
+      foreach (i, _; ParameterTypeTuple!(mixin("Interface." ~ methodName))) {
+        string paramName;
+        if (methodMetaFound && i < methodMeta.params.length) {
+          paramName = methodMeta.params[i].name;
+        } else {
+          paramName = "param" ~ to!string(i + 1);
+        }
+        paramList ~= "args." ~ paramName;
+      }
+
+      immutable call = "iface_." ~ methodName ~ "(" ~ ctfeJoin(paramList) ~ ")";
+      if (is(ReturnType!(mixin("Interface." ~ methodName)) == void)) {
+        code ~= call ~ ";\n";
+      } else {
+        code ~= "result.set!`success`(" ~ call ~ ");\n";
+      }
+
+      // If this is not a oneway method, generate the recieving code.
+      if (!methodMetaFound || methodMeta.type != TMethodType.ONEWAY) {
+        if (methodMetaFound) {
+          foreach (e; methodMeta.exceptions) {
+            code ~= "} catch (Interface." ~ e.type ~ " " ~ e.name ~ ") {\n";
+            code ~= "result.set!`" ~ e.name ~ "`(" ~ e.name ~ ");\n";
+          }
+        }
+        code ~= "}\n";
+
+        code ~= q{
+          catch (Exception e) {
+            if (eventHandler) {
+              eventHandler.handlerError(callContext, qName, e);
+            }
+
+            auto x = new TApplicationException(to!string(e));
+            oprot.writeMessageBegin(
+              TMessage(methodName, TMessageType.EXCEPTION, seqid));
+            x.write(oprot);
+            oprot.writeMessageEnd();
+            oprot.transport.writeEnd();
+            oprot.transport.flush();
+            return;
+          }
+
+          if (eventHandler) eventHandler.preWrite(callContext, qName);
+
+          oprot.writeMessageBegin(TMessage(methodName,
+            TMessageType.REPLY, seqid));
+          result.write(oprot);
+          oprot.writeMessageEnd();
+          oprot.transport.writeEnd();
+          oprot.transport.flush();
+
+          if (eventHandler) eventHandler.postWrite(callContext, qName);
+        };
+      } else {
+        // For oneway methods, we obviously cannot notify the client of any
+        // exceptions, just call the event handler if one is set.
+        code ~= "}\n";
+        code ~= q{
+          catch (Exception e) {
+            if (eventHandler) {
+              eventHandler.handlerError(callContext, qName, e);
+            }
+            return;
+          }
+
+          if (eventHandler) eventHandler.onewayComplete(callContext, qName);
+        };
+      }
+      code ~= "}\n";
+
+    }
+
+    code ~= constructorCode ~ "}\n";
+    code ~= "}\n";
+
+    return code;
+  }());
+}
+
+/**
+ * A struct representing the arguments of a Thrift method call.
+ *
+ * There should usually be no reason to use this directly without the help of
+ * TServiceProcessor, but it is documented publicly to help debugging in case
+ * of CTFE errors.
+ *
+ * Consider this example:
+ * ---
+ * interface Foo {
+ *   int bar(string a, bool b);
+ *
+ *   enum methodMeta = [
+ *     TMethodMeta("bar", [TParamMeta("a", 1), TParamMeta("b", 2)])
+ *   ];
+ * }
+ *
+ * alias TArgsStruct!(Foo, "bar") FooBarArgs;
+ * ---
+ *
+ * The definition of FooBarArgs is equivalent to:
+ * ---
+ * struct FooBarArgs {
+ *   string a;
+ *   bool b;
+ *
+ *   mixin TStructHelpers!([TFieldMeta("a", 1, TReq.OPT_IN_REQ_OUT),
+ *     TFieldMeta("b", 2, TReq.OPT_IN_REQ_OUT)]);
+ * }
+ * ---
+ *
+ * If the TVerboseCodegen version is defined, a warning message is issued at
+ * compilation if no TMethodMeta for Interface.methodName is found.
+ */
+template TArgsStruct(Interface, string methodName) {
+  static assert(is(typeof(mixin("Interface." ~ methodName))),
+    "Could not find method '" ~ methodName ~ "' in '" ~ Interface.stringof ~ "'.");
+  mixin({
+    bool methodMetaFound;
+    TMethodMeta methodMeta;
+    static if (is(typeof(Interface.methodMeta) : TMethodMeta[])) {
+      auto meta = find!`a.name == b`(Interface.methodMeta, methodName);
+      if (!meta.empty) {
+        methodMetaFound = true;
+        methodMeta = meta.front;
+      }
+    }
+
+    string memberCode;
+    string[] fieldMetaCodes;
+    foreach (i, _; ParameterTypeTuple!(mixin("Interface." ~ methodName))) {
+      // If we have no meta information, just use param1, param2, etc. as
+      // field names, it shouldn't really matter anyway. 1-based »indexing«
+      // is used to match the common scheme in the Thrift world.
+      string memberId;
+      string memberName;
+      if (methodMetaFound && i < methodMeta.params.length) {
+        memberId = to!string(methodMeta.params[i].id);
+        memberName = methodMeta.params[i].name;
+      } else {
+        memberId = to!string(i + 1);
+        memberName = "param" ~ to!string(i + 1);
+      }
+
+      // Unqual!() is needed to generate mutable fields for ref const()
+      // struct parameters.
+      memberCode ~= "Unqual!(ParameterTypeTuple!(Interface." ~ methodName ~
+        ")[" ~ to!string(i) ~ "])" ~ memberName ~ ";\n";
+
+      fieldMetaCodes ~= "TFieldMeta(`" ~ memberName ~ "`, " ~ memberId ~
+        ", TReq.OPT_IN_REQ_OUT)";
+    }
+
+    string code = "struct TArgsStruct {\n";
+    code ~= memberCode;
+    version (TVerboseCodegen) {
+      if (!methodMetaFound &&
+        ParameterTypeTuple!(mixin("Interface." ~ methodName)).length > 0)
+      {
+        code ~= "pragma(msg, `[thrift.codegen.processor.TArgsStruct] Warning: No " ~
+          "meta information for method '" ~ methodName ~ "' in service '" ~
+          Interface.stringof ~ "' found.`);\n";
+      }
+    }
+    immutable fieldMetaCode =
+      fieldMetaCodes.empty ? "" : "[" ~ ctfeJoin(fieldMetaCodes) ~ "]";
+    code ~= "mixin TStructHelpers!(" ~ fieldMetaCode  ~ ");\n";
+    code ~= "}\n";
+    return code;
+  }());
+}
+
+/**
+ * A struct representing the result of a Thrift method call.
+ *
+ * It contains a field called "success" for the return value of the function
+ * (with id 0), and additional fields for the exceptions declared for the
+ * method, if any.
+ *
+ * There should usually be no reason to use this directly without the help of
+ * TServiceProcessor, but it is documented publicly to help debugging in case
+ * of CTFE errors.
+ *
+ * Consider the following example:
+ * ---
+ * interface Foo {
+ *   int bar(string a);
+ *
+ *   alias .FooException FooException;
+ *
+ *   enum methodMeta = [
+ *     TMethodMeta("bar",
+ *       [TParamMeta("a", 1)],
+ *       [TExceptionMeta("fooe", 1, "FooException")]
+ *     )
+ *   ];
+ * }
+ * alias TResultStruct!(Foo, "bar") FooBarResult;
+ * ---
+ *
+ * The definition of FooBarResult is equivalent to:
+ * ---
+ * struct FooBarResult {
+ *   int success;
+ *   FooException fooe;
+ *
+ *   mixin(TStructHelpers!([TFieldMeta("success", 0, TReq.OPTIONAL),
+ *     TFieldMeta("fooe", 1, TReq.OPTIONAL)]));
+ * }
+ * ---
+ *
+ * If the TVerboseCodegen version is defined, a warning message is issued at
+ * compilation if no TMethodMeta for Interface.methodName is found.
+ */
+template TResultStruct(Interface, string methodName) {
+  static assert(is(typeof(mixin("Interface." ~ methodName))),
+    "Could not find method '" ~ methodName ~ "' in '" ~ Interface.stringof ~ "'.");
+
+  mixin({
+    string code = "struct TResultStruct {\n";
+
+    string[] fieldMetaCodes;
+
+    static if (!is(ReturnType!(mixin("Interface." ~ methodName)) == void)) {
+      code ~= "ReturnType!(Interface." ~ methodName ~ ") success;\n";
+      fieldMetaCodes ~= "TFieldMeta(`success`, 0, TReq.OPTIONAL)";
+    }
+
+    bool methodMetaFound;
+    static if (is(typeof(Interface.methodMeta) : TMethodMeta[])) {
+      auto meta = find!`a.name == b`(Interface.methodMeta, methodName);
+      if (!meta.empty) {
+        foreach (e; meta.front.exceptions) {
+          code ~= "Interface." ~ e.type ~ " " ~ e.name ~ ";\n";
+          fieldMetaCodes ~= "TFieldMeta(`" ~ e.name ~ "`, " ~ to!string(e.id) ~
+            ", TReq.OPTIONAL)";
+        }
+        methodMetaFound = true;
+      }
+    }
+
+    version (TVerboseCodegen) {
+      if (!methodMetaFound &&
+        ParameterTypeTuple!(mixin("Interface." ~ methodName)).length > 0)
+      {
+        code ~= "pragma(msg, `[thrift.codegen.processor.TResultStruct] Warning: No " ~
+          "meta information for method '" ~ methodName ~ "' in service '" ~
+          Interface.stringof ~ "' found.`);\n";
+      }
+    }
+
+    immutable fieldMetaCode =
+      fieldMetaCodes.empty ? "" : "[" ~ ctfeJoin(fieldMetaCodes) ~ "]";
+    code ~= "mixin TStructHelpers!(" ~ fieldMetaCode  ~ ");\n";
+    code ~= "}\n";
+    return code;
+  }());
+}
diff --git a/lib/d/src/thrift/index.d b/lib/d/src/thrift/index.d
new file mode 100644
index 0000000..12914b6
--- /dev/null
+++ b/lib/d/src/thrift/index.d
@@ -0,0 +1,33 @@
+Ddoc
+
+<h2>Package overview</h2>
+
+<dl>
+  <dt>$(D_CODE thrift.async)</dt>
+  <dd>Support infrastructure for handling client-side asynchronous operations using non-blocking I/O and coroutines.</dd>
+
+  <dt>$(D_CODE thrift.codegen)</dt>
+  <dd>
+    <p>Templates used for generating Thrift clients/processors from regular D struct and interface definitions.</p>
+    <p><strong>Note:</strong> Several artifacts in these modules have options for specifying the exact protocol types used. In this case, the amount of virtual calls can be greatly reduced and as a result, the code also can be optimized better. If performance is not a concern or the actual protocol type is not known at compile time, these parameters can just be left at their defaults.
+    </p>
+  </dd>
+
+  <dt>$(D_CODE thrift.internal)</dt>
+  <dd>Internal helper modules used by the Thrift library. This package is not part of the public API, and no stability guarantees are given whatsoever.</dd>
+
+  <dt>$(D_CODE thrift.protocol)</dt>
+  <dd>The Thrift protocol implemtations which specify how to pass messages over a TTransport.</dd>
+
+  <dt>$(D_CODE thrift.server)</dt>
+  <dd>Generic Thrift server implementations handling clients over a TTransport interface and forwarding requests to a TProcessor (which is in turn usually provided by thrift.codegen).</dd>
+
+  <dt>$(D_CODE thrift.transport)</dt>
+  <dd>The TTransport data source/sink interface used in the Thrift library and its imiplementations.</dd>
+
+  <dt>$(D_CODE thrift.util)</dt>
+  <dd>General-purpose utility modules not specific to Thrift, part of the public API.</dd>
+</dl>
+
+Macros:
+  TITLE = Thrift D Software Library
diff --git a/lib/d/src/thrift/internal/algorithm.d b/lib/d/src/thrift/internal/algorithm.d
new file mode 100644
index 0000000..0938ac2
--- /dev/null
+++ b/lib/d/src/thrift/internal/algorithm.d
@@ -0,0 +1,55 @@
+/**
+ * Contains a modified version of std.algorithm.remove that doesn't take an
+ * alias parameter to avoid DMD @@BUG6395@@.
+ */
+module thrift.internal.algorithm;
+
+import std.algorithm : move;
+import std.exception;
+import std.functional;
+import std.range;
+import std.traits;
+
+enum SwapStrategy
+{
+    unstable,
+    semistable,
+    stable,
+}
+
+Range removeEqual(SwapStrategy s = SwapStrategy.stable, Range, E)(Range range, E e)
+if (isBidirectionalRange!Range)
+{
+    auto result = range;
+    static if (s != SwapStrategy.stable)
+    {
+        for (;!range.empty;)
+        {
+            if (range.front !is e)
+            {
+                range.popFront;
+                continue;
+            }
+            move(range.back, range.front);
+            range.popBack;
+            result.popBack;
+        }
+    }
+    else
+    {
+        auto tgt = range;
+        for (; !range.empty; range.popFront)
+        {
+            if (range.front is e)
+            {
+                // yank this guy
+                result.popBack;
+                continue;
+            }
+            // keep this guy
+            move(range.front, tgt.front);
+            tgt.popFront;
+        }
+    }
+    return result;
+}
diff --git a/lib/d/src/thrift/internal/codegen.d b/lib/d/src/thrift/internal/codegen.d
new file mode 100644
index 0000000..d6ce0a9
--- /dev/null
+++ b/lib/d/src/thrift/internal/codegen.d
@@ -0,0 +1,438 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+module thrift.internal.codegen;
+
+import std.traits : InterfacesTuple, isSomeFunction, isSomeString;
+import std.typetuple : staticIndexOf, staticMap, NoDuplicates, TypeTuple;
+import thrift.codegen.base;
+
+/**
+ * Removes all type qualifiers from T.
+ *
+ * In contrast to std.traits.Unqual, FullyUnqual also removes qualifiers from
+ * array elements (e.g. immutable(byte[]) -> byte[], not immutable(byte)[]),
+ * excluding strings (string isn't reduced to char[]).
+ */
+template FullyUnqual(T) {
+  static if (is(T _ == const(U), U)) {
+    alias FullyUnqual!U FullyUnqual;
+  } else static if (is(T _ == immutable(U), U)) {
+    alias FullyUnqual!U FullyUnqual;
+  } else static if (is(T _ == shared(U), U)) {
+    alias FullyUnqual!U FullyUnqual;
+  } else static if (is(T _ == U[], U) && !isSomeString!T) {
+    alias FullyUnqual!(U)[] FullyUnqual;
+  } else static if (is(T _ == V[K], K, V)) {
+    alias FullyUnqual!(V)[FullyUnqual!K] FullyUnqual;
+  } else {
+    alias T FullyUnqual;
+  }
+}
+
+/**
+ * true if null can be assigned to the passed type, false if not.
+ */
+template isNullable(T) {
+  enum isNullable = __traits(compiles, { T t = null; });
+}
+
+template isStruct(T) {
+  enum isStruct = is(T == struct);
+}
+
+template isException(T) {
+ enum isException = is(T : Exception);
+}
+
+template isEnum(T) {
+  enum isEnum = is(T == enum);
+}
+
+/**
+ * Aliases itself to T.name.
+ */
+template GetMember(T, string name) {
+  mixin("alias T." ~ name ~ " GetMember;");
+}
+
+/**
+ * Aliases itself to typeof(symbol).
+ */
+template TypeOf(alias symbol) {
+  alias typeof(symbol) TypeOf;
+}
+
+/**
+ * Aliases itself to the type of the T member called name.
+ */
+alias Compose!(TypeOf, GetMember) MemberType;
+
+/**
+ * Returns the field metadata array for T if any, or an empty array otherwise.
+ */
+template getFieldMeta(T) if (isStruct!T || isException!T) {
+  static if (is(typeof(T.fieldMeta) == TFieldMeta[])) {
+    enum getFieldMeta = T.fieldMeta;
+  } else {
+    enum TFieldMeta[] getFieldMeta = [];
+  }
+}
+
+/**
+ * Merges the field metadata array for D with the passed array.
+ */
+template mergeFieldMeta(T, alias fieldMetaData = cast(TFieldMeta[])null) {
+  // Note: We don't use getFieldMeta here to avoid bug if it is instantiated
+  // from TIsSetFlags, see comment there.
+  static if (is(typeof(T.fieldMeta) == TFieldMeta[])) {
+    enum mergeFieldMeta = T.fieldMeta ~ fieldMetaData;
+  } else {
+    enum TFieldMeta[] mergeFieldMeta = fieldMetaData;
+  }
+}
+
+/**
+ * Returns the field requirement level for T.name.
+ */
+template memberReq(T, string name, alias fieldMetaData = cast(TFieldMeta[])null) {
+  enum memberReq = memberReqImpl!(T, name, fieldMetaData).result;
+}
+
+private {
+  import std.algorithm : find;
+  // DMD @@BUG@@: Missing import leads to failing build without error
+  // message in unittest/debug/thrift/codegen/async_client.
+  import std.array : empty, front;
+
+  template memberReqImpl(T, string name, alias fieldMetaData) {
+    enum meta = find!`a.name == b`(mergeFieldMeta!(T, fieldMetaData), name);
+    static if (meta.empty || meta.front.req == TReq.AUTO) {
+      static if (isNullable!(MemberType!(T, name))) {
+        enum result = TReq.OPTIONAL;
+      } else {
+        enum result = TReq.REQUIRED;
+      }
+    } else {
+      enum result = meta.front.req;
+    }
+  }
+}
+
+
+template notIgnored(T, string name, alias fieldMetaData = cast(TFieldMeta[])null) {
+  enum notIgnored = memberReq!(T, name, fieldMetaData) != TReq.IGNORE;
+}
+
+/**
+ * Returns the method metadata array for T if any, or an empty array otherwise.
+ */
+template getMethodMeta(T) if (isService!T) {
+  static if (is(typeof(T.methodMeta) == TMethodMeta[])) {
+    enum getMethodMeta = T.methodMeta;
+  } else {
+    enum TMethodMeta[] getMethodMeta = [];
+  }
+}
+
+
+/**
+ * true if T.name is a member variable. Exceptions include methods, static
+ * members, artifacts like package aliases, …
+ */
+template isValueMember(T, string name) {
+  static if (!is(MemberType!(T, name))) {
+    enum isValueMember = false;
+  } else static if (
+    is(MemberType!(T, name) == void) ||
+    isSomeFunction!(MemberType!(T, name)) ||
+    __traits(compiles, { return mixin("T." ~ name); }())
+  ) {
+    enum isValueMember = false;
+  } else {
+    enum isValueMember = true;
+  }
+}
+
+/**
+ * Returns a tuple containing the names of the fields of T, not including
+ * inherited fields. If a member is marked as TReq.IGNORE, it is not included
+ * as well.
+ */
+template FieldNames(T, alias fieldMetaData = cast(TFieldMeta[])null) {
+  alias StaticFilter!(
+    All!(
+      PApply!(isValueMember, T),
+      PApply!(notIgnored, T, PApplySkip, fieldMetaData)
+    ),
+    __traits(derivedMembers, T)
+  ) FieldNames;
+}
+
+template derivedMembers(T) {
+  alias TypeTuple!(__traits(derivedMembers, T)) derivedMembers;
+}
+
+template AllMemberMethodNames(T) if (isService!T) {
+  alias NoDuplicates!(
+    FilterMethodNames!(
+      T,
+      staticMap!(
+        derivedMembers,
+        TypeTuple!(T, InterfacesTuple!T)
+      )
+    )
+  ) AllMemberMethodNames;
+}
+
+private template FilterMethodNames(T, MemberNames...) {
+  alias StaticFilter!(
+    CompilesAndTrue!(
+      Compose!(isSomeFunction, TypeOf, PApply!(GetMember, T))
+    ),
+    MemberNames
+  ) FilterMethodNames;
+}
+
+/**
+ * Returns a type tuple containing only the elements of T for which the
+ * eponymous template predicate pred is true.
+ *
+ * Example:
+ * ---
+ * alias StaticFilter!(isIntegral, int, string, long, float[]) Filtered;
+ * static assert(is(Filtered == TypeTuple!(int, long)));
+ * ---
+ */
+template StaticFilter(alias pred, T...) {
+  static if (T.length == 0) {
+    alias TypeTuple!() StaticFilter;
+  } else static if (pred!(T[0])) {
+    alias TypeTuple!(T[0], StaticFilter!(pred, T[1 .. $])) StaticFilter;
+  } else {
+    alias StaticFilter!(pred, T[1 .. $]) StaticFilter;
+  }
+}
+
+/**
+ * Binds the first n arguments of a template to a particular value (where n is
+ * the number of arguments passed to PApply).
+ *
+ * The passed arguments are always applied starting from the left. However,
+ * the special PApplySkip marker template can be used to indicate that an
+ * argument should be skipped, so that e.g. the first and third argument
+ * to a template can be fixed, but the second and remaining arguments would
+ * still be left undefined.
+ *
+ * Skipping a number of parameters, but not providing enough arguments to
+ * assign all of them during instantiation of the resulting template is an
+ * error.
+ *
+ * Example:
+ * ---
+ * struct Foo(T, U, V) {}
+ * alias PApply!(Foo, int, long) PartialFoo;
+ * static assert(is(PartialFoo!float == Foo!(int, long, float)));
+ *
+ * alias PApply!(Test, int, PApplySkip, float) SkippedTest;
+ * static assert(is(SkippedTest!long == Test!(int, long, float)));
+ * ---
+ */
+template PApply(alias Target, T...) {
+  template PApply(U...) {
+    alias Target!(PApplyMergeArgs!(ConfinedTuple!T, U).Result) PApply;
+  }
+}
+
+/// Ditto.
+template PApplySkip() {}
+
+private template PApplyMergeArgs(alias Preset, Args...) {
+  static if (Preset.length == 0) {
+    alias Args Result;
+  } else {
+    enum nextSkip = staticIndexOf!(PApplySkip, Preset.Tuple);
+    static if (nextSkip == -1) {
+      alias TypeTuple!(Preset.Tuple, Args) Result;
+    } else static if (Args.length == 0) {
+      // Have to use a static if clause instead of putting the condition
+      // directly into the assert to avoid DMD trying to access Args[0]
+      // nevertheless below.
+      static assert(false,
+        "PArgsSkip encountered, but no argument left to bind.");
+    } else {
+      alias TypeTuple!(
+        Preset.Tuple[0 .. nextSkip],
+        Args[0],
+        PApplyMergeArgs!(
+          ConfinedTuple!(Preset.Tuple[nextSkip + 1 .. $]),
+          Args[1 .. $]
+        ).Result
+      ) Result;
+    }
+  }
+}
+
+unittest {
+  struct Test(T, U, V) {}
+  alias PApply!(Test, int, long) PartialTest;
+  static assert(is(PartialTest!float == Test!(int, long, float)));
+
+  alias PApply!(Test, int, PApplySkip, float) SkippedTest;
+  static assert(is(SkippedTest!long == Test!(int, long, float)));
+
+  alias PApply!(Test, int, PApplySkip, PApplySkip) TwoSkipped;
+  static assert(!__traits(compiles, TwoSkipped!long));
+}
+
+
+/**
+ * Composes a number of templates. The result is a template equivalent to
+ * all the passed templates evaluated from right to left, akin to the
+ * mathematical function composition notation: Instantiating Compose!(A, B, C)
+ * is the same as instantiating A!(B!(C!(…))).
+ *
+ * This is especially useful for creating a template to use with staticMap/
+ * StaticFilter, as demonstrated below.
+ *
+ * Example:
+ * ---
+ * template AllMethodNames(T) {
+ *   alias StaticFilter!(
+ *     CompilesAndTrue!(
+ *       Compose!(isSomeFunction, TypeOf, PApply!(GetMember, T))
+ *     ),
+ *     __traits(allMembers, T)
+ *   ) AllMethodNames;
+ * }
+ *
+ * pragma(msg, AllMethodNames!Object);
+ * ---
+ */
+template Compose(T...) {
+  static if (T.length == 0) {
+    template Compose(U...) {
+      alias U Compose;
+    }
+  } else {
+    template Compose(U...) {
+      alias Instantiate!(T[0], Instantiate!(.Compose!(T[1 .. $]), U)) Compose;
+    }
+  }
+}
+
+/**
+ * Instantiates the given template with the given list of parameters.
+ *
+ * Used to work around syntactic limiations of D with regard to instantiating
+ * a template from a type tuple (e.g. T[0]!(...) is not valid) or a template
+ * returning another template (e.g. Foo!(Bar)!(Baz) is not allowed).
+ */
+template Instantiate(alias Template, Params...) {
+  alias Template!Params Instantiate;
+}
+
+/**
+ * Combines several template predicates using logical AND, i.e. instantiating
+ * All!(a, b, c) with parameters P for some templates a, b, c is equivalent to
+ * a!P && b!P && c!P.
+ *
+ * The templates are evaluated from left to right, aborting evaluation in a
+ * shurt-cut manner if a false result is encountered, in which case the latter
+ * instantiations do not need to compile.
+ */
+template All(T...) {
+  static if (T.length == 0) {
+    template All(U...) {
+      enum All = true;
+    }
+  } else {
+    template All(U...) {
+      static if (Instantiate!(T[0], U)) {
+        alias Instantiate!(.All!(T[1 .. $]), U) All;
+      } else {
+        enum All = false;
+      }
+    }
+  }
+}
+
+/**
+ * Combines several template predicates using logical OR, i.e. instantiating
+ * Any!(a, b, c) with parameters P for some templates a, b, c is equivalent to
+ * a!P || b!P || c!P.
+ *
+ * The templates are evaluated from left to right, aborting evaluation in a
+ * shurt-cut manner if a true result is encountered, in which case the latter
+ * instantiations do not need to compile.
+ */
+template Any(T...) {
+  static if (T.length == 0) {
+    template Any(U...) {
+      enum Any = false;
+    }
+  } else {
+    template Any(U...) {
+      static if (Instantiate!(T[0], U)) {
+        enum Any = true;
+      } else {
+        alias Instantiate!(.Any!(T[1 .. $]), U) Any;
+      }
+    }
+  }
+}
+
+template ConfinedTuple(T...) {
+  alias T Tuple;
+  enum length = T.length;
+}
+
+/*
+ * foreach (Item; Items) {
+ *   List = Operator!(Item, List);
+ * }
+ * where Items is a ConfinedTuple and List is a type tuple.
+ */
+template ForAllWithList(alias Items, alias Operator, List...) if (
+  is(typeof(Items.length) : size_t)
+){
+  static if (Items.length == 0) {
+    alias List ForAllWithList;
+  } else {
+    alias .ForAllWithList!(
+      ConfinedTuple!(Items.Tuple[1 .. $]),
+      Operator,
+      Operator!(Items.Tuple[0], List)
+    ) ForAllWithList;
+  }
+}
+
+/**
+ * Wraps the passed template predicate so it returns true if it compiles and
+ * evaluates to true, false it it doesn't compile or evaluates to false.
+ */
+template CompilesAndTrue(alias T) {
+  template CompilesAndTrue(U...) {
+    static if (is(typeof(T!U) : bool)) {
+      enum bool CompilesAndTrue = T!U;
+    } else {
+      enum bool CompilesAndTrue = false;
+    }
+  }
+}
diff --git a/lib/d/src/thrift/internal/ctfe.d b/lib/d/src/thrift/internal/ctfe.d
new file mode 100644
index 0000000..3b10a78
--- /dev/null
+++ b/lib/d/src/thrift/internal/ctfe.d
@@ -0,0 +1,96 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+module thrift.internal.ctfe;
+
+import std.conv : to;
+import std.traits;
+
+/*
+ * Simple eager join() for strings, std.algorithm.join isn't CTFEable yet.
+ */
+string ctfeJoin(string[] strings, string separator = ", ") {
+  string result;
+  if (strings.length > 0) {
+    result ~= strings[0];
+    foreach (s; strings[1..$]) {
+      result ~= separator ~ s;
+    }
+  }
+  return result;
+}
+
+/*
+ * A very primitive to!string() implementation for floating point numbers that
+ * is evaluatable at compile time.
+ *
+ * There is a wealth of problems associated with the algorithm used (e.g. 5.0
+ * prints as 4.999…, incorrect rounding, etc.), but a better alternative should
+ * be included with the D standard library instead of implementing it here.
+ */
+string ctfeToString(T)(T val) if (isFloatingPoint!T) {
+  if (val is T.nan) return "nan";
+  if (val is T.infinity) return "inf";
+  if (val is -T.infinity) return "-inf";
+  if (val is 0.0) return "0";
+  if (val is -0.0) return "-0";
+
+  auto b = val;
+
+  string result;
+  if (b < 0) {
+    result ~= '-';
+    b *= -1;
+  }
+
+  short magnitude;
+  while (b >= 10) {
+    ++magnitude;
+    b /= 10;
+  }
+  while (b < 1) {
+    --magnitude;
+    b *= 10;
+  }
+
+  foreach (i; 0 .. T.dig) {
+    if (i == 1) result ~= '.';
+
+    auto first = cast(ubyte)b;
+    result ~= to!string(first);
+
+    b -= first;
+    import std.math;
+    if (b < pow(10.0, i - T.dig)) break;
+    b *= 10;
+  }
+
+  if (magnitude != 0) result ~= "e" ~ to!string(magnitude);
+  return result;
+}
+
+unittest {
+  static assert(ctfeToString(double.infinity) == "inf");
+  static assert(ctfeToString(-double.infinity) == "-inf");
+  static assert(ctfeToString(double.nan) == "nan");
+  static assert(ctfeToString(0.0) == "0");
+  static assert(ctfeToString(-0.0) == "-0");
+  static assert(ctfeToString(3.1415) == "3.1415");
+  static assert(ctfeToString(2e-200) == "2e-200");
+}
diff --git a/lib/d/src/thrift/internal/endian.d b/lib/d/src/thrift/internal/endian.d
new file mode 100644
index 0000000..31b9814
--- /dev/null
+++ b/lib/d/src/thrift/internal/endian.d
@@ -0,0 +1,75 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/*
+ * Simple helpers for handling typical byte order-related issues.
+ */
+module thrift.internal.endian;
+
+import core.bitop : bswap;
+import std.traits : isIntegral;
+
+union IntBuf(T) {
+  ubyte[T.sizeof] bytes;
+  T value;
+}
+
+T byteSwap(T)(T t) pure nothrow @trusted if (isIntegral!T) {
+  static if (T.sizeof == 2) {
+    return cast(T)((t & 0xff) << 8) | cast(T)((t & 0xff00) >> 8);
+  } else static if (T.sizeof == 4) {
+    return cast(T)bswap(cast(uint)t);
+  } else static if (T.sizeof == 8) {
+    return cast(T)byteSwap(cast(uint)(t & 0xffffffff)) << 32 |
+      cast(T)bswap(cast(uint)(t >> 32));
+  } else static assert(false, "Type of size " ~ to!string(T.sizeof) ~ " not supported.");
+}
+
+T doNothing(T)(T val) { return val; }
+
+version (BigEndian) {
+  alias doNothing hostToNet;
+  alias doNothing netToHost;
+  alias byteSwap hostToLe;
+  alias byteSwap leToHost;
+} else {
+  alias byteSwap hostToNet;
+  alias byteSwap netToHost;
+  alias doNothing hostToLe;
+  alias doNothing leToHost;
+}
+
+unittest {
+  import std.exception;
+
+  IntBuf!short s;
+  s.bytes = [1, 2];
+  s.value = byteSwap(s.value);
+  enforce(s.bytes == [2, 1]);
+
+  IntBuf!int i;
+  i.bytes = [1, 2, 3, 4];
+  i.value = byteSwap(i.value);
+  enforce(i.bytes == [4, 3, 2, 1]);
+
+  IntBuf!long l;
+  l.bytes = [1, 2, 3, 4, 5, 6, 7, 8];
+  l.value = byteSwap(l.value);
+  enforce(l.bytes == [8, 7, 6, 5, 4, 3, 2, 1]);
+}
diff --git a/lib/d/src/thrift/internal/resource_pool.d b/lib/d/src/thrift/internal/resource_pool.d
new file mode 100644
index 0000000..8bd6ac5
--- /dev/null
+++ b/lib/d/src/thrift/internal/resource_pool.d
@@ -0,0 +1,419 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+module thrift.internal.resource_pool;
+
+import core.time : Duration, dur, TickDuration;
+import std.algorithm : minPos, reduce, remove;
+import std.array : array, empty;
+import std.exception : enforce;
+import std.conv : to;
+import std.random : randomCover, rndGen;
+import std.range : zip;
+import thrift.internal.algorithm : removeEqual;
+
+/**
+ * A pool of resources, which can be iterated over, and where resources that
+ * have failed too often can be temporarily disabled.
+ *
+ * This class is oblivious to the actual resource type managed.
+ */
+final class TResourcePool(Resource) {
+  /**
+   * Constructs a new instance.
+   *
+   * Params:
+   *   resources = The initial members of the pool.
+   */
+  this(Resource[] resources) {
+    resources_ = resources;
+  }
+
+  /**
+   * Adds a resource to the pool.
+   */
+  void add(Resource resource) {
+    resources_ ~= resource;
+  }
+
+  /**
+   * Removes a resource from the pool.
+   *
+   * Returns: Whether the resource could be found in the pool.
+   */
+  bool remove(Resource resource) {
+    auto oldLength = resources_.length;
+    resources_ = removeEqual(resources_, resource);
+    return resources_.length < oldLength;
+  }
+
+  /**
+   * Returns an »enriched« input range to iterate over the pool members.
+   */
+  struct Range {
+    /**
+     * Whether the range is empty.
+     *
+     * This is the case if all members of the pool have been popped (or skipped
+     * because they were disabled) and TResourcePool.cycle is false, or there
+     * is no element to return in cycle mode because all have been temporarily
+     * disabled.
+     */
+    bool empty() @property {
+      // If no resources are in the pool, the range will never become non-empty.
+      if (resources_.empty) return true;
+
+      // If we already got the next resource in the cache, it doesn't matter
+      // whether there are more.
+      if (cached_) return false;
+
+      size_t examineCount;
+      if (parent_.cycle) {
+        // We want to check all the resources, but not iterate more than once
+        // to avoid spinning in a loop if nothing is available.
+        examineCount = resources_.length;
+      } else {
+        // When not in cycle mode, we just iterate the list exactly once. If all
+        // items have been consumed, the interval below is empty.
+        examineCount = resources_.length - nextIndex_;
+      }
+
+      foreach (i; 0 .. examineCount) {
+        auto r = resources_[(nextIndex_ + i) % resources_.length];
+        auto fi = r in parent_.faultInfos_;
+
+        if (fi && fi.resetTime != fi.resetTime.init) {
+          // The argument to < needs to be an lvalue…
+          auto currentTick = TickDuration.currSystemTick;
+          if (fi.resetTime < currentTick) {
+            // The timeout expired, remove the resource from the list and go
+            // ahead trying it.
+            parent_.faultInfos_.remove(r);
+          } else {
+            // The timeout didn't expire yet, try the next resource.
+            continue;
+          }
+        }
+
+        cache_ = r;
+        cached_ = true;
+        nextIndex_ = nextIndex_ + i + 1;
+        return false;
+      }
+
+      // If we get here, all resources are currently inactive or the non-cycle
+      // pool has been exhausted, so there is nothing we can do.
+      nextIndex_ = nextIndex_ + examineCount;
+      return true;
+    }
+
+    /**
+     * Returns the first resource in the range.
+     */
+    Resource front() @property {
+      enforce(!empty);
+      return cache_;
+    }
+
+    /**
+     * Removes the first resource from the range.
+     *
+     * Usually, this is combined with a call to TResourcePool.recordSuccess()
+     * or recordFault().
+     */
+    void popFront() {
+      enforce(!empty);
+      cached_ = false;
+    }
+
+    /**
+     * Returns whether the range will become non-empty at some point in the
+     * future, and provides additional information when this will happen and
+     * what will be the next resource.
+     *
+     * Makes only sense to call on empty ranges.
+     *
+     * Params:
+     *   next = The next resource that will become available.
+     *   waitTime = The duration until that resource will become available.
+     */
+    bool willBecomeNonempty(out Resource next, out Duration waitTime) {
+      // If no resources are in the pool, the range will never become non-empty.
+      if (resources_.empty) return true;
+
+      // If cycle mode is not enabled, a range never becomes non-empty after
+      // being empty once, because all the elements have already been
+      // used/skipped in order to become empty.
+      if (!parent_.cycle) return false;
+
+      auto fi = parent_.faultInfos_;
+      auto nextPair = minPos!"a[1].resetTime < b[1].resetTime"(
+        zip(fi.keys, fi.values)
+      ).front;
+
+      next = nextPair[0];
+      waitTime = to!Duration(nextPair[1].resetTime - TickDuration.currSystemTick);
+
+      return true;
+    }
+
+  private:
+    this(TResourcePool parent, Resource[] resources) {
+      parent_ = parent;
+      resources_ = resources;
+    }
+
+    TResourcePool parent_;
+
+    /// All available resources. We keep a copy of it as to not get confused
+    /// when resources are added to/removed from the parent pool.
+    Resource[] resources_;
+
+    /// After we have determined the next element in empty(), we store it here.
+    Resource cache_;
+
+    /// Whether there is currently something in the cache.
+    bool cached_;
+
+    /// The index to start searching from at the next call to empty().
+    size_t nextIndex_;
+  }
+
+  /// Ditto
+  Range opSlice() {
+    auto res = resources_;
+    if (permute) {
+      res = array(randomCover(res, rndGen));
+    }
+    return Range(this, res);
+  }
+
+  /**
+   * Records a success for an operation on the given resource, cancelling a
+   * fault streak, if any.
+   */
+  void recordSuccess(Resource resource) {
+    if (resource in faultInfos_) {
+      faultInfos_.remove(resource);
+    }
+  }
+
+  /**
+   * Records a fault for the given resource.
+   *
+   * If a resource fails consecutively for more than faultDisableCount times,
+   * it is temporarily disabled (no longer considered) until
+   * faultDisableDuration has passed.
+   */
+  void recordFault(Resource resource) {
+    auto fi = resource in faultInfos_;
+
+    if (!fi) {
+      faultInfos_[resource] = FaultInfo();
+      fi = resource in faultInfos_;
+    }
+
+    ++fi.count;
+    if (fi.count >= faultDisableCount) {
+      // If the resource has hit the fault count limit, disable it for
+      // specified duration.
+      fi.resetTime = TickDuration.currSystemTick +
+        TickDuration.from!"hnsecs"(faultDisableDuration.total!"hnsecs");
+    }
+  }
+
+  /**
+   * Whether to randomly permute the order of the resources in the pool when
+   * taking a range using opSlice().
+   *
+   * This can be used e.g. as a simple form of load balancing.
+   */
+  bool permute = true;
+
+  /**
+   * Whether to keep iterating over the pool members after all have been
+   * returned/have failed once.
+   */
+  bool cycle = false;
+
+  /**
+   * The number of consecutive faults after which a resource is disabled until
+   * faultDisableDuration has passed. Zero to never disable resources.
+   *
+   * Defaults to zero.
+   */
+  ushort faultDisableCount = 0;
+
+  /**
+   * The duration for which a resource is no longer considered after it has
+   * failed too often.
+   *
+   * Defaults to one second.
+   */
+  Duration faultDisableDuration = dur!"seconds"(1);
+
+private:
+  Resource[] resources_;
+  FaultInfo[Resource] faultInfos_;
+}
+
+private {
+  struct FaultInfo {
+    ushort count;
+    TickDuration resetTime;
+  }
+}
+
+import std.datetime;
+import thrift.base;
+
+unittest {
+  import core.thread;
+
+  auto a = new Object;
+  auto b = new Object;
+  auto c = new Object;
+  auto objs = [a, b, c];
+  auto pool = new TResourcePool!Object(objs);
+  pool.permute = false;
+  pool.faultDisableDuration = dur!"msecs"(5);
+  Object dummyRes = void;
+  Duration dummyDur = void;
+
+  {
+    auto r = pool[];
+
+    foreach (i, o; objs) {
+      enforce(!r.empty);
+      enforce(r.front == o);
+      r.popFront();
+    }
+
+    enforce(r.empty);
+    enforce(!r.willBecomeNonempty(dummyRes, dummyDur));
+  }
+
+  {
+    pool.faultDisableCount = 2;
+
+    enforce(pool[].front == a);
+    pool.recordFault(a);
+    enforce(pool[].front == a);
+    pool.recordSuccess(a);
+    enforce(pool[].front == a);
+    pool.recordFault(a);
+    enforce(pool[].front == a);
+    pool.recordFault(a);
+
+    auto r = pool[];
+    enforce(r.front == b);
+    r.popFront();
+    enforce(r.front == c);
+    r.popFront();
+    enforce(r.empty);
+    enforce(!r.willBecomeNonempty(dummyRes, dummyDur));
+
+    Thread.sleep(dur!"msecs"(5));
+    // Not in cycle mode, has to be still empty after the timeouts expired.
+    enforce(r.empty);
+    enforce(!r.willBecomeNonempty(dummyRes, dummyDur));
+
+    foreach (o; objs) pool.recordSuccess(o);
+  }
+
+  {
+    pool.faultDisableCount = 1;
+
+    pool.recordFault(a);
+    Thread.sleep(dur!"usecs"(1));
+    pool.recordFault(b);
+    Thread.sleep(dur!"usecs"(1));
+    pool.recordFault(c);
+
+    auto r = pool[];
+    enforce(r.empty);
+    enforce(!r.willBecomeNonempty(dummyRes, dummyDur));
+
+    foreach (o; objs) pool.recordSuccess(o);
+  }
+
+  pool.cycle = true;
+
+  {
+    auto r = pool[];
+
+    foreach (o; objs ~ objs) {
+      enforce(!r.empty);
+      enforce(r.front == o);
+      r.popFront();
+    }
+  }
+
+  {
+    pool.faultDisableCount = 2;
+
+    enforce(pool[].front == a);
+    pool.recordFault(a);
+    enforce(pool[].front == a);
+    pool.recordSuccess(a);
+    enforce(pool[].front == a);
+    pool.recordFault(a);
+    enforce(pool[].front == a);
+    pool.recordFault(a);
+
+    auto r = pool[];
+    enforce(r.front == b);
+    r.popFront();
+    enforce(r.front == c);
+    r.popFront();
+    enforce(r.front == b);
+
+    Thread.sleep(dur!"msecs"(5));
+
+    r.popFront();
+    enforce(r.front == c);
+
+    r.popFront();
+    enforce(r.front == a);
+
+    enforce(pool[].front == a);
+
+    foreach (o; objs) pool.recordSuccess(o);
+  }
+
+  {
+    pool.faultDisableCount = 1;
+
+    pool.recordFault(a);
+    Thread.sleep(dur!"usecs"(1));
+    pool.recordFault(b);
+    Thread.sleep(dur!"usecs"(1));
+    pool.recordFault(c);
+
+    auto r = pool[];
+    enforce(r.empty);
+
+    Object nextRes;
+    Duration nextWait;
+    enforce(r.willBecomeNonempty(nextRes, nextWait));
+    enforce(nextRes == a);
+    enforce(nextWait > dur!"hnsecs"(0));
+
+    foreach (o; objs) pool.recordSuccess(o);
+  }
+}
diff --git a/lib/d/src/thrift/internal/socket.d b/lib/d/src/thrift/internal/socket.d
new file mode 100644
index 0000000..43e1ca8
--- /dev/null
+++ b/lib/d/src/thrift/internal/socket.d
@@ -0,0 +1,96 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/**
+ * Abstractions over OS-dependent socket functionality.
+ */
+module thrift.internal.socket;
+
+import std.conv : to;
+
+// FreeBSD and OS X return -1 and set ECONNRESET if socket was closed by
+// the other side, we need to check for that before throwing an exception.
+version (FreeBSD) {
+  enum connresetOnPeerShutdown = true;
+} else version (OSX) {
+  enum connresetOnPeerShutdown = true;
+} else {
+  enum connresetOnPeerShutdown = false;
+}
+
+version (Win32) {
+  import std.c.windows.winsock : WSAGetLastError, WSAEINTR, WSAEWOULDBLOCK;
+  import std.windows.syserror : sysErrorString;
+
+  // These are unfortunately not defined in std.c.windows.winsock, see
+  // http://msdn.microsoft.com/en-us/library/ms740668.aspx.
+  enum WSAECONNRESET = 10054;
+  enum WSAENOTCONN = 10057;
+  enum WSAETIMEDOUT = 10060;
+} else {
+  import core.stdc.errno : getErrno, EAGAIN, ECONNRESET, EINPROGRESS, EINTR,
+    ENOTCONN, EPIPE;
+  import core.stdc.string : strerror;
+}
+
+/*
+ * CONNECT_INPROGRESS_ERRNO: set by connect() for non-blocking sockets if the
+ *   connection could not be immediately established.
+ * INTERRUPTED_ERRNO: set when blocking system calls are interrupted by
+ *   signals or similar.
+ * TIMEOUT_ERRNO: set when a socket timeout has been exceeded.
+ * WOULD_BLOCK_ERRNO: set when send/recv would block on non-blocking sockets.
+ *
+ * isSocetCloseErrno(errno): returns true if errno indicates that the socket
+ *   is logically in closed state now.
+ */
+version (Win32) {
+  alias WSAGetLastError getSocketErrno;
+  enum CONNECT_INPROGRESS_ERRNO = WSAEWOULDBLOCK;
+  enum INTERRUPTED_ERRNO = WSAEINTR;
+  enum TIMEOUT_ERRNO = WSAETIMEDOUT;
+  enum WOULD_BLOCK_ERRNO = WSAEWOULDBLOCK;
+
+  bool isSocketCloseErrno(typeof(getSocketErrno()) errno) {
+    return (errno == WSAECONNRESET || errno == WSAENOTCONN);
+  }
+} else {
+  alias getErrno getSocketErrno;
+  enum CONNECT_INPROGRESS_ERRNO = EINPROGRESS;
+  enum INTERRUPTED_ERRNO = EINTR;
+  enum WOULD_BLOCK_ERRNO = EAGAIN;
+
+  // TODO: The C++ TSocket implementation mentions that EAGAIN can also be
+  // set (undocumentedly) in out of resource conditions; it would be a good
+  // idea to contact the original authors of the C++ code for details and adapt
+  // the code accordingly.
+  enum TIMEOUT_ERRNO = EAGAIN;
+
+  bool isSocketCloseErrno(typeof(getSocketErrno()) errno) {
+    return (errno == EPIPE || errno == ECONNRESET || errno == ENOTCONN);
+  }
+}
+
+string socketErrnoString(uint errno) {
+  version (Win32) {
+    return sysErrorString(errno);
+  } else {
+    return to!string(strerror(errno));
+  }
+}
diff --git a/lib/d/src/thrift/internal/ssl.d b/lib/d/src/thrift/internal/ssl.d
new file mode 100644
index 0000000..47a7cde
--- /dev/null
+++ b/lib/d/src/thrift/internal/ssl.d
@@ -0,0 +1,240 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+module thrift.internal.ssl;
+
+import core.memory : GC;
+import core.stdc.config;
+import core.stdc.errno : getErrno;
+import core.stdc.string : strerror;
+import deimos.openssl.err;
+import deimos.openssl.ssl;
+import deimos.openssl.x509v3;
+import std.array : empty, appender;
+import std.conv : to;
+import std.socket : Address;
+import thrift.transport.ssl;
+
+/**
+ * Checks if the peer is authorized after the SSL handshake has been
+ * completed on the given conncetion and throws an TSSLException if not.
+ *
+ * Params:
+ *   ssl = The SSL connection to check.
+ *   accessManager = The access manager to check the peer againts.
+ *   peerAddress = The (IP) address of the peer.
+ *   hostName = The host name of the peer.
+ */
+void authorize(SSL* ssl, TAccessManager accessManager,
+  Address peerAddress, lazy string hostName
+) {
+  alias TAccessManager.Decision Decision;
+
+  auto rc = SSL_get_verify_result(ssl);
+  if (rc != X509_V_OK) {
+    throw new TSSLException("SSL_get_verify_result(): " ~
+      to!string(X509_verify_cert_error_string(rc)));
+  }
+
+  auto cert = SSL_get_peer_certificate(ssl);
+  if (cert is null) {
+    // Certificate is not present.
+    if (SSL_get_verify_mode(ssl) & SSL_VERIFY_FAIL_IF_NO_PEER_CERT) {
+      throw new TSSLException(
+        "Authorize: Required certificate not present.");
+    }
+
+    // If we don't have an access manager set, we don't intend to authorize
+    // the client, so everything's fine.
+    if (accessManager) {
+      throw new TSSLException(
+        "Authorize: Certificate required for authorization.");
+    }
+    return;
+  }
+
+  if (accessManager is null) {
+    // No access manager set, can return immediately as the cert is valid
+    // and all peers are authorized.
+    X509_free(cert);
+    return;
+  }
+
+  // both certificate and access manager are present
+  auto decision = accessManager.verify(peerAddress);
+
+  if (decision != Decision.SKIP) {
+    X509_free(cert);
+    if (decision != Decision.ALLOW) {
+      throw new TSSLException("Authorize: Access denied based on remote IP.");
+    }
+    return;
+  }
+
+  // Check subjectAltName(s), if present.
+  auto alternatives = cast(STACK_OF!(GENERAL_NAME)*)
+    X509_get_ext_d2i(cert, NID_subject_alt_name, null, null);
+  if (alternatives != null) {
+    auto count = sk_GENERAL_NAME_num(alternatives);
+    for (int i = 0; decision == Decision.SKIP && i < count; i++) {
+      auto name = sk_GENERAL_NAME_value(alternatives, i);
+      if (name is null) {
+        continue;
+      }
+      auto data = ASN1_STRING_data(name.d.ia5);
+      auto length = ASN1_STRING_length(name.d.ia5);
+      switch (name.type) {
+        case GENERAL_NAME.GEN_DNS:
+          decision = accessManager.verify(hostName, cast(char[])data[0 .. length]);
+          break;
+        case GENERAL_NAME.GEN_IPADD:
+          decision = accessManager.verify(peerAddress, data[0 .. length]);
+          break;
+        default:
+          // Do nothing.
+      }
+    }
+
+    // DMD @@BUG@@: Empty template arguments parens should not be needed.
+    sk_GENERAL_NAME_pop_free!()(alternatives, &GENERAL_NAME_free);
+  }
+
+  // If we are alredy done, return.
+  if (decision != Decision.SKIP) {
+    X509_free(cert);
+    if (decision != Decision.ALLOW) {
+      throw new TSSLException("Authorize: Access denied.");
+    }
+    return;
+  }
+
+  // Check commonName.
+  auto name = X509_get_subject_name(cert);
+  if (name !is null) {
+    X509_NAME_ENTRY* entry;
+    char* utf8;
+    int last = -1;
+    while (decision == Decision.SKIP) {
+      last = X509_NAME_get_index_by_NID(name, NID_commonName, last);
+      if (last == -1)
+        break;
+      entry = X509_NAME_get_entry(name, last);
+      if (entry is null)
+        continue;
+      auto common = X509_NAME_ENTRY_get_data(entry);
+      auto size = ASN1_STRING_to_UTF8(&utf8, common);
+      decision = accessManager.verify(hostName, utf8[0 .. size]);
+      CRYPTO_free(utf8);
+    }
+  }
+  X509_free(cert);
+  if (decision != Decision.ALLOW) {
+    throw new TSSLException("Authorize: Could not authorize peer.");
+  }
+}
+
+/*
+ * OpenSSL error information used for storing D exceptions on the OpenSSL
+ * error stack.
+ */
+enum ERR_LIB_D_EXCEPTION = ERR_LIB_USER;
+enum ERR_F_D_EXCEPTION = 0; // function id - what to use here?
+enum ERR_R_D_EXCEPTION = 1234; // 99 and above are reserved for applications
+enum ERR_FILE_D_EXCEPTION = "d_exception";
+enum ERR_LINE_D_EXCEPTION = 0;
+enum ERR_FLAGS_D_EXCEPTION = 0;
+
+/**
+ * Returns an exception for the last.
+ *
+ * Params:
+ *   location = An optional "location" to add to the error message (typically
+ *     the last SSL API call).
+ */
+Exception getSSLException(string location = null, string clientFile = __FILE__,
+  size_t clientLine = __LINE__
+) {
+  // We can return either an exception saved from D BIO code, or a "true"
+  // OpenSSL error. Because there can possibly be more than one error on the
+  // error stack, we have to fetch all of them, and pick the last, i.e. newest
+  // one. We concatenate multiple successive OpenSSL error messages into a
+  // single one, but always just return the last D expcetion.
+  string message; // Probably better use an Appender here.
+  bool hadMessage;
+  Exception exception;
+
+  void initMessage() {
+    message.clear();
+    hadMessage = false;
+    if (!location.empty) {
+      message ~= location;
+      message ~= ": ";
+    }
+  }
+  initMessage();
+
+  auto errn = getErrno();
+
+  const(char)* file = void;
+  int line = void;
+  const(char)* data = void;
+  int flags = void;
+  c_ulong code = void;
+  while ((code = ERR_get_error_line_data(&file, &line, &data, &flags)) != 0) {
+    if (ERR_GET_REASON(code) == ERR_R_D_EXCEPTION) {
+      initMessage();
+      GC.removeRoot(cast(void*)data);
+      exception = cast(Exception)data;
+    } else {
+      exception = null;
+
+      if (hadMessage) {
+        message ~= ", ";
+      }
+
+      auto reason = ERR_reason_error_string(code);
+      if (reason) {
+        message ~= "SSL error: " ~ to!string(reason);
+      } else {
+        message ~= "SSL error #" ~ to!string(code);
+      }
+
+      hadMessage = true;
+    }
+  }
+
+  // If the last item from the stack was a D exception, throw it.
+  if (exception) return exception;
+
+  // We are dealing with an OpenSSL error that doesn't root in a D exception.
+  if (!hadMessage) {
+    // If we didn't get an actual error from the stack yet, try errno.
+    string errnString;
+    if (errn != 0) {
+      errnString = to!string(strerror(errn));
+    }
+    if (errnString.empty) {
+      message ~= "Unknown error";
+    } else {
+      message ~= errnString;
+    }
+  }
+
+  message ~= ".";
+  return new TSSLException(message, clientFile, clientLine);
+}
diff --git a/lib/d/src/thrift/internal/ssl_bio.d b/lib/d/src/thrift/internal/ssl_bio.d
new file mode 100644
index 0000000..796be91
--- /dev/null
+++ b/lib/d/src/thrift/internal/ssl_bio.d
@@ -0,0 +1,190 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/**
+ * Provides a SSL BIO implementation wrapping a Thrift transport.
+ *
+ * This way, SSL I/O can be relayed over Thrift transport without introducing
+ * an additional layer of buffering, especially for the non-blocking
+ * transports.
+ *
+ * For the Thrift transport incarnations of the SSL entities, "tt" is used as
+ * prefix for clarity.
+ */
+module thrift.internal.ssl_bio;
+
+import core.stdc.config;
+import core.stdc.string : strlen;
+import core.memory : GC;
+import deimos.openssl.bio;
+import deimos.openssl.err;
+import thrift.base;
+import thrift.internal.ssl;
+import thrift.transport.base;
+
+/**
+ * Creates an SSL BIO object wrapping the given transport.
+ *
+ * Exceptions thrown by the transport are pushed onto the OpenSSL error stack,
+ * using the location/reason values from thrift.internal.ssl.ERR_*_D_EXCEPTION.
+ *
+ * The transport is assumed to be ready for reading and writing when the BIO
+ * functions are called, it is not opened by the implementation.
+ *
+ * Params:
+ *   transport = The transport to wrap.
+ *   closeTransport = Whether the close the transport when the SSL BIO is
+ *     closed.
+ */
+BIO* createTTransportBIO(TTransport transport, bool closeTransport) {
+  auto result = BIO_new(cast(BIO_METHOD*)&ttBioMethod);
+  if (!result) return null;
+
+  GC.addRoot(cast(void*)transport);
+  BIO_set_fd(result, closeTransport, cast(c_long)cast(void*)transport);
+
+  return result;
+}
+
+private {
+  // Helper to get the Thrift transport assigned with the given BIO.
+  TTransport trans(BIO* b) nothrow {
+    auto result = cast(TTransport)b.ptr;
+    assert(result);
+    return result;
+  }
+
+  void setError(Exception e) nothrow {
+    ERR_put_error(ERR_LIB_D_EXCEPTION, ERR_F_D_EXCEPTION, ERR_R_D_EXCEPTION,
+      ERR_FILE_D_EXCEPTION, ERR_LINE_D_EXCEPTION);
+    try { GC.addRoot(cast(void*)e); } catch {}
+    ERR_set_error_data(cast(char*)e, ERR_FLAGS_D_EXCEPTION);
+  }
+
+  extern(C) int ttWrite(BIO* b, const(char)* data, int length) nothrow {
+    assert(b);
+    if (!data || length <= 0) return 0;
+    try {
+      trans(b).write((cast(ubyte*)data)[0 .. length]);
+      return length;
+    } catch (Exception e) {
+      setError(e);
+      return -1;
+    }
+  }
+
+  extern(C) int ttRead(BIO* b, char* data, int length) nothrow {
+    assert(b);
+    if (!data || length <= 0) return 0;
+    try {
+      return cast(int)trans(b).read((cast(ubyte*)data)[0 .. length]);
+    } catch (Exception e) {
+      setError(e);
+      return -1;
+    }
+  }
+
+  extern(C) int ttPuts(BIO* b, const(char)* str) nothrow {
+    return ttWrite(b, str, cast(int)strlen(str));
+  }
+
+  extern(C) c_long ttCtrl(BIO* b, int cmd, c_long num, void* ptr) nothrow {
+    assert(b);
+
+    switch (cmd) {
+      case BIO_C_SET_FD:
+        // Note that close flag and "fd" are actually reversed here because we
+        // need 64 bit width for the pointer – should probably drop BIO_set_fd
+        // altogether.
+        ttDestroy(b);
+        b.ptr = cast(void*)num;
+        b.shutdown = cast(int)ptr;
+        b.init_ = 1;
+        return 1;
+      case BIO_C_GET_FD:
+        if (!b.init_) return -1;
+        *(cast(void**)ptr) = b.ptr;
+        return cast(c_long)b.ptr;
+      case BIO_CTRL_GET_CLOSE:
+        return b.shutdown;
+      case BIO_CTRL_SET_CLOSE:
+        b.shutdown = cast(int)num;
+        return 1;
+      case BIO_CTRL_FLUSH:
+        try {
+          trans(b).flush();
+          return 1;
+        } catch (Exception e) {
+          setError(e);
+          return -1;
+        }
+      case BIO_CTRL_DUP:
+        // Seems like we have nothing to do on duplication, but couldn't find
+        // any documentation if this actually ever happens during normal SSL
+        // usage.
+        return 1;
+      default:
+        return 0;
+    }
+  }
+
+  extern(C) int ttCreate(BIO* b) nothrow {
+    assert(b);
+    b.init_ = 0;
+    b.num = 0; // User-defined number field, unused here.
+    b.ptr = null;
+    b.flags = 0;
+    return 1;
+  }
+
+  extern(C) int ttDestroy(BIO* b) nothrow {
+    if (!b) return 0;
+
+    int rc = 1;
+    if (b.shutdown) {
+      if (b.init_) {
+        try {
+          trans(b).close();
+          GC.removeRoot(cast(void*)trans(b));
+          b.ptr = null;
+        } catch (Exception e) {
+          setError(e);
+          rc = -1;
+        }
+      }
+      b.init_ = 0;
+      b.flags = 0;
+    }
+
+    return rc;
+  }
+
+  immutable BIO_METHOD ttBioMethod = {
+    BIO_TYPE_SOURCE_SINK,
+    "TTransport",
+    &ttWrite,
+    &ttRead,
+    &ttPuts,
+    null, // gets
+    &ttCtrl,
+    &ttCreate,
+    &ttDestroy,
+    null // callback_ctrl
+  };
+}
diff --git a/lib/d/src/thrift/internal/test/protocol.d b/lib/d/src/thrift/internal/test/protocol.d
new file mode 100644
index 0000000..2d25154
--- /dev/null
+++ b/lib/d/src/thrift/internal/test/protocol.d
@@ -0,0 +1,183 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+module thrift.internal.test.protocol;
+
+import std.exception;
+import thrift.transport.memory;
+import thrift.protocol.base;
+
+version (unittest):
+
+void testContainerSizeLimit(Protocol)() if (isTProtocol!Protocol) {
+  auto buffer = new TMemoryBuffer;
+  auto prot = new Protocol(buffer);
+
+  // Make sure reading fails if a container larger than the size limit is read.
+  prot.containerSizeLimit = 3;
+
+  {
+    prot.writeListBegin(TList(TType.I32, 4));
+    prot.writeI32(0); // Make sure size can be read e.g. for JSON protocol.
+    prot.reset();
+
+    auto e = cast(TProtocolException)collectException(prot.readListBegin());
+    enforce(e && e.type == TProtocolException.Type.SIZE_LIMIT);
+    prot.reset();
+    buffer.reset();
+  }
+
+  {
+    prot.writeMapBegin(TMap(TType.I32, TType.I32, 4));
+    prot.writeI32(0); // Make sure size can be read e.g. for JSON protocol.
+    prot.reset();
+
+    auto e = cast(TProtocolException)collectException(prot.readMapBegin());
+    enforce(e && e.type == TProtocolException.Type.SIZE_LIMIT);
+    prot.reset();
+    buffer.reset();
+  }
+
+  {
+    prot.writeSetBegin(TSet(TType.I32, 4));
+    prot.writeI32(0); // Make sure size can be read e.g. for JSON protocol.
+    prot.reset();
+
+    auto e = cast(TProtocolException)collectException(prot.readSetBegin());
+    enforce(e && e.type == TProtocolException.Type.SIZE_LIMIT);
+    prot.reset();
+    buffer.reset();
+  }
+
+  // Make sure reading works if the containers are smaller than the limit or
+  // no limit is set.
+  foreach (limit; [3, 0, -1]) {
+    prot.containerSizeLimit = limit;
+
+    {
+      prot.writeListBegin(TList(TType.I32, 2));
+      prot.writeI32(0);
+      prot.writeI32(1);
+      prot.writeListEnd();
+      prot.reset();
+
+      auto list = prot.readListBegin();
+      enforce(list.elemType == TType.I32);
+      enforce(list.size == 2);
+      enforce(prot.readI32() == 0);
+      enforce(prot.readI32() == 1);
+      prot.readListEnd();
+
+      prot.reset();
+      buffer.reset();
+    }
+
+    {
+      prot.writeMapBegin(TMap(TType.I32, TType.I32, 2));
+      prot.writeI32(0);
+      prot.writeI32(1);
+      prot.writeI32(2);
+      prot.writeI32(3);
+      prot.writeMapEnd();
+      prot.reset();
+
+      auto map = prot.readMapBegin();
+      enforce(map.keyType == TType.I32);
+      enforce(map.valueType == TType.I32);
+      enforce(map.size == 2);
+      enforce(prot.readI32() == 0);
+      enforce(prot.readI32() == 1);
+      enforce(prot.readI32() == 2);
+      enforce(prot.readI32() == 3);
+      prot.readMapEnd();
+
+      prot.reset();
+      buffer.reset();
+    }
+
+    {
+      prot.writeSetBegin(TSet(TType.I32, 2));
+      prot.writeI32(0);
+      prot.writeI32(1);
+      prot.writeSetEnd();
+      prot.reset();
+
+      auto set = prot.readSetBegin();
+      enforce(set.elemType == TType.I32);
+      enforce(set.size == 2);
+      enforce(prot.readI32() == 0);
+      enforce(prot.readI32() == 1);
+      prot.readSetEnd();
+
+      prot.reset();
+      buffer.reset();
+    }
+  }
+}
+
+void testStringSizeLimit(Protocol)() if (isTProtocol!Protocol) {
+  auto buffer = new TMemoryBuffer;
+  auto prot = new Protocol(buffer);
+
+  // Make sure reading fails if a string larger than the size limit is read.
+  prot.stringSizeLimit = 3;
+
+  {
+    prot.writeString("asdf");
+    prot.reset();
+
+    auto e = cast(TProtocolException)collectException(prot.readString());
+    enforce(e && e.type == TProtocolException.Type.SIZE_LIMIT);
+    prot.reset();
+    buffer.reset();
+  }
+
+  {
+    prot.writeBinary([1, 2, 3, 4]);
+    prot.reset();
+
+    auto e = cast(TProtocolException)collectException(prot.readBinary());
+    enforce(e && e.type == TProtocolException.Type.SIZE_LIMIT);
+    prot.reset();
+    buffer.reset();
+  }
+
+  // Make sure reading works if the containers are smaller than the limit or
+  // no limit is set.
+  foreach (limit; [3, 0, -1]) {
+    prot.containerSizeLimit = limit;
+
+    {
+      prot.writeString("as");
+      prot.reset();
+
+      enforce(prot.readString() == "as");
+      prot.reset();
+      buffer.reset();
+    }
+
+    {
+      prot.writeBinary([1, 2]);
+      prot.reset();
+
+      enforce(prot.readBinary() == [1, 2]);
+      prot.reset();
+      buffer.reset();
+    }
+  }
+}
diff --git a/lib/d/src/thrift/internal/test/server.d b/lib/d/src/thrift/internal/test/server.d
new file mode 100644
index 0000000..b5393f0
--- /dev/null
+++ b/lib/d/src/thrift/internal/test/server.d
@@ -0,0 +1,110 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+module thrift.internal.test.server;
+
+import core.sync.condition;
+import core.sync.mutex;
+import core.thread : Thread;
+import std.datetime;
+import std.exception : enforce;
+import std.typecons : WhiteHole;
+import std.variant : Variant;
+import thrift.protocol.base;
+import thrift.protocol.binary;
+import thrift.protocol.processor;
+import thrift.server.base;
+import thrift.server.transport.socket;
+import thrift.transport.base;
+import thrift.util.cancellation;
+
+version(unittest):
+
+/**
+ * Tests if serving is stopped correctly if the cancellation passed to serve()
+ * is triggered.
+ *
+ * Because the tests are run many times in a loop, this is indirectly also a
+ * test whether socket, etc. handles are cleaned up correctly, because the
+ * application will likely run out of handles otherwise.
+ */
+void testServeCancel(Server)(void delegate(Server) serverSetup = null) if (
+  is(Server : TServer)
+) {
+  auto proc = new WhiteHole!TProcessor;
+  auto tf = new TTransportFactory;
+  auto pf = new TBinaryProtocolFactory!();
+
+  // Need a special case for TNonblockingServer which doesn't use
+  // TServerTransport.
+  static if (__traits(compiles, new Server(proc, 0, tf, pf))) {
+    auto server = new Server(proc, 0, tf, pf);
+  } else {
+    auto server = new Server(proc, new TServerSocket(0), tf, pf);
+  }
+
+  // On Windows, we use TCP sockets to replace socketpair(). Since they stay
+  // in TIME_WAIT for some time even if they are properly closed, we have to use
+  // a lower number of iterations to avoid running out of ports/buffer space.
+  version (Windows) {
+    enum ITERATIONS = 100;
+  } else {
+    enum ITERATIONS = 10000;
+  }
+
+  if (serverSetup) serverSetup(server);
+
+  auto servingMutex = new Mutex;
+  auto servingCondition = new Condition(servingMutex);
+  auto doneMutex = new Mutex;
+  auto doneCondition = new Condition(doneMutex);
+
+  class CancellingHandler : TServerEventHandler {
+    void preServe() {
+      synchronized (servingMutex) {
+        servingCondition.notifyAll();
+      }
+    }
+    Variant createContext(TProtocol input, TProtocol output) { return Variant.init; }
+    void deleteContext(Variant serverContext, TProtocol input, TProtocol output) {}
+    void preProcess(Variant serverContext, TTransport transport) {}
+  }
+  server.eventHandler = new CancellingHandler;
+
+  foreach (i; 0 .. ITERATIONS) {
+    synchronized (servingMutex) {
+      auto cancel = new TCancellationOrigin;
+      synchronized (doneMutex) {
+        auto serverThread = new Thread({
+          server.serve(cancel);
+          synchronized (doneMutex) {
+            doneCondition.notifyAll();
+          }
+        });
+        serverThread.isDaemon = true;
+        serverThread.start();
+
+        servingCondition.wait();
+
+        cancel.trigger();
+        enforce(doneCondition.wait(dur!"msecs"(100)));
+        serverThread.join();
+      }
+    }
+  }
+}
diff --git a/lib/d/src/thrift/internal/traits.d b/lib/d/src/thrift/internal/traits.d
new file mode 100644
index 0000000..11e98c5
--- /dev/null
+++ b/lib/d/src/thrift/internal/traits.d
@@ -0,0 +1,141 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+module thrift.internal.traits;
+
+import std.traits;
+
+/**
+ * Adds or removes attributes from the given function (pointer) or delegate
+ * type.
+ *
+ * Besides the base type, two std.traits.FunctionAttribute bitfields are
+ * accepted, representing the attributes to add to the function signature
+ * resp. to remove from it. If an attribute appears in both fields, an error
+ * is raised.
+ *
+ * Params:
+ *   T = The base type.
+ *   setAttrs = The attributes to add to the type, if not already present.
+ *   clearAttrs = The attributes to remove from the type, if present.
+ */
+template ChangeFuncAttrs(
+  T,
+  FunctionAttribute setAttrs = FunctionAttribute.none,
+  FunctionAttribute clearAttrs = FunctionAttribute.none
+) if (isFunctionPointer!T || isDelegate!T) {
+  static assert(!(setAttrs & clearAttrs),
+    "Cannot set and clear attributes at the same time.");
+  mixin({
+    enum newAttrs = (functionAttributes!T | setAttrs) & ~clearAttrs;
+    static assert(!(newAttrs & FunctionAttribute.trusted) ||
+      !(newAttrs & FunctionAttribute.safe),
+      "Cannot have a function/delegate that is both trusted and safe.");
+
+    string result = "alias ";
+
+    static if (functionLinkage!T != "D") {
+      result ~= "extern(" ~ functionLinkage!T ~ ") ";
+    }
+
+    static if (newAttrs & FunctionAttribute.ref_) {
+      result ~= "ref ";
+    }
+
+    result ~= "ReturnType!T";
+
+    static if (isDelegate!T) {
+      result ~= " delegate";
+    } else {
+      result ~= " function";
+    }
+
+    result ~= "(ParameterTypeTuple!T)";
+
+    static if (newAttrs & FunctionAttribute.pure_) {
+      result ~= " pure";
+    }
+    static if (newAttrs & FunctionAttribute.nothrow_) {
+      result ~= " nothrow";
+    }
+    static if (newAttrs & FunctionAttribute.property) {
+      result ~= " @property";
+    }
+    static if (newAttrs & FunctionAttribute.trusted) {
+      result ~= " @trusted";
+    }
+    static if (newAttrs & FunctionAttribute.safe) {
+      result ~= " @safe";
+    }
+
+    result ~= " ChangeFuncAttrs;";
+    return result;
+  }());
+}
+
+/// Ditto
+template ChangeFuncAttrs(
+  T,
+  FunctionAttribute setAttrs = FunctionAttribute.none,
+  FunctionAttribute clearAttrs = FunctionAttribute.none
+) if (is(T == function)) {
+  // To avoid a lot of syntactic headaches, we just use the above version to
+  // operate on the corresponding function pointer type and then remove the
+  // pointer again.
+  alias FunctionTypeOf!(ChangeFuncAttrs!(T*, setAttrs, clearAttrs))
+    ChangeFuncAttrs;
+}
+
+version (unittest) {
+  import std.algorithm;
+  import std.metastrings;
+  import std.typetuple;
+}
+unittest {
+  alias FunctionAttribute FA;
+  foreach (T0; TypeTuple!(
+    int function(int),
+    int delegate(int),
+    FunctionTypeOf!(int function(int))
+  )) {
+    alias ChangeFuncAttrs!(T0, FA.safe) T1;
+    static assert(functionAttributes!T1 == FA.safe);
+
+    alias ChangeFuncAttrs!(T1, FA.nothrow_ | FA.ref_, FA.safe) T2;
+    static assert(functionAttributes!T2 == (FA.nothrow_ | FA.ref_));
+
+    enum allAttrs = reduce!"a | b"([EnumMembers!FA]) & ~FA.safe;
+
+    alias ChangeFuncAttrs!(T2, allAttrs) T3;
+    static assert(functionAttributes!T3 == allAttrs);
+
+    alias ChangeFuncAttrs!(T3, FA.none, allAttrs) T4;
+    static assert(is(T4 == T0));
+  }
+}
+
+/**
+ * Adds »nothrow« to the type of the passed function pointer/delegate, if it
+ * is not already present.
+ *
+ * Technically, assumeNothrow just performs a cast, but using it has the
+ * advantage of being explicitly about the operation that is performed.
+ */
+auto assumeNothrow(T)(T t) if (isFunctionPointer!T || isDelegate!T) {
+  return cast(ChangeFuncAttrs!(T, FunctionAttribute.nothrow_))t;
+}
diff --git a/lib/d/src/thrift/protocol/base.d b/lib/d/src/thrift/protocol/base.d
new file mode 100644
index 0000000..809c847
--- /dev/null
+++ b/lib/d/src/thrift/protocol/base.d
@@ -0,0 +1,436 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/**
+ * Defines the basic interface for a Thrift protocol and associated exception
+ * types.
+ *
+ * Most parts of the protocol API are typically not used in client code, as
+ * the actual serialization code is generated by thrift.codegen.* – the only
+ * interesting thing usually is that there are protocols which can be created
+ * from transports and passed around.
+ */
+module thrift.protocol.base;
+
+import thrift.base;
+import thrift.transport.base;
+
+/**
+ * The field types Thrift protocols support.
+ */
+enum TType : byte {
+  STOP   = 0, /// Used to mark the end of a sequence of fields.
+  VOID   = 1, ///
+  BOOL   = 2, ///
+  BYTE   = 3, ///
+  DOUBLE = 4, ///
+  I16    = 6, ///
+  I32    = 8, ///
+  I64    = 10, ///
+  STRING = 11, ///
+  STRUCT = 12, ///
+  MAP    = 13, ///
+  SET    = 14, ///
+  LIST   = 15 ///
+}
+
+/**
+ * Types of Thrift RPC messages.
+ */
+enum TMessageType : byte {
+  CALL = 1, /// Call of a normal, two-way RPC method.
+  REPLY = 2, /// Reply to a normal method call.
+  EXCEPTION = 3, /// Reply to a method call if target raised a TApplicationException.
+  ONEWAY = 4 /// Call of a one-way RPC method which is not followed by a reply.
+}
+
+/**
+ * Descriptions of Thrift entities.
+ */
+struct TField {
+  string name;
+  TType type;
+  short id;
+}
+
+/// ditto
+struct TList {
+  TType elemType;
+  size_t size;
+}
+
+/// ditto
+struct TMap {
+  TType keyType;
+  TType valueType;
+  size_t size;
+}
+
+/// ditto
+struct TMessage {
+  string name;
+  TMessageType type;
+  int seqid;
+}
+
+/// ditto
+struct TSet {
+  TType elemType;
+  size_t size;
+}
+
+/// ditto
+struct TStruct {
+  string name;
+}
+
+/**
+ * Interface for a Thrift protocol implementation. Essentially, it defines
+ * a way of reading and writing all the base types, plus a mechanism for
+ * writing out structs with indexed fields.
+ *
+ * TProtocol objects should not be shared across multiple encoding contexts,
+ * as they may need to maintain internal state in some protocols (e.g. JSON).
+ * Note that is is acceptable for the TProtocol module to do its own internal
+ * buffered reads/writes to the underlying TTransport where appropriate (i.e.
+ * when parsing an input XML stream, reading could be batched rather than
+ * looking ahead character by character for a close tag).
+ */
+interface TProtocol {
+  /// The underlying transport used by the protocol.
+  TTransport transport() @property;
+
+  /*
+   * Writing methods.
+   */
+
+  void writeBool(bool b); ///
+  void writeByte(byte b); ///
+  void writeI16(short i16); ///
+  void writeI32(int i32); ///
+  void writeI64(long i64); ///
+  void writeDouble(double dub); ///
+  void writeString(string str); ///
+  void writeBinary(ubyte[] buf); ///
+
+  void writeMessageBegin(TMessage message); ///
+  void writeMessageEnd(); ///
+  void writeStructBegin(TStruct tstruct); ///
+  void writeStructEnd(); ///
+  void writeFieldBegin(TField field); ///
+  void writeFieldEnd(); ///
+  void writeFieldStop(); ///
+  void writeListBegin(TList list); ///
+  void writeListEnd(); ///
+  void writeMapBegin(TMap map); ///
+  void writeMapEnd(); ///
+  void writeSetBegin(TSet set); ///
+  void writeSetEnd(); ///
+
+  /*
+   * Reading methods.
+   */
+
+  bool readBool(); ///
+  byte readByte(); ///
+  short readI16(); ///
+  int readI32(); ///
+  long readI64(); ///
+  double readDouble(); ///
+  string readString(); ///
+  ubyte[] readBinary(); ///
+
+  TMessage readMessageBegin(); ///
+  void readMessageEnd(); ///
+  TStruct readStructBegin(); ///
+  void readStructEnd(); ///
+  TField readFieldBegin(); ///
+  void readFieldEnd(); ///
+  TList readListBegin(); ///
+  void readListEnd(); ///
+  TMap readMapBegin(); ///
+  void readMapEnd(); ///
+  TSet readSetBegin(); ///
+  void readSetEnd(); ///
+
+  /**
+   * Reset any internal state back to a blank slate, if the protocol is
+   * stateful.
+   */
+  void reset();
+}
+
+/**
+ * true if T is a TProtocol.
+ */
+template isTProtocol(T) {
+  enum isTProtocol = is(T : TProtocol);
+}
+
+unittest {
+  static assert(isTProtocol!TProtocol);
+  static assert(!isTProtocol!void);
+}
+
+/**
+ * Creates a protocol operating on a given transport.
+ */
+interface TProtocolFactory {
+  ///
+  TProtocol getProtocol(TTransport trans);
+}
+
+/**
+ * A protocol-level exception.
+ */
+class TProtocolException : TException {
+  /// The possible exception types.
+  enum Type {
+    UNKNOWN, ///
+    INVALID_DATA, ///
+    NEGATIVE_SIZE, ///
+    SIZE_LIMIT, ///
+    BAD_VERSION, ///
+    NOT_IMPLEMENTED ///
+  }
+
+  ///
+  this(Type type, string file = __FILE__, size_t line = __LINE__, Throwable next = null) {
+    static string msgForType(Type type) {
+      switch (type) {
+        case Type.UNKNOWN: return "Unknown protocol exception";
+        case Type.INVALID_DATA: return "Invalid data";
+        case Type.NEGATIVE_SIZE: return "Negative size";
+        case Type.SIZE_LIMIT: return "Exceeded size limit";
+        case Type.BAD_VERSION: return "Invalid version";
+        case Type.NOT_IMPLEMENTED: return "Not implemented";
+        default: return "(Invalid exception type)";
+      }
+    }
+    this(msgForType(type), type, file, line, next);
+  }
+
+  ///
+  this(string msg, string file = __FILE__, size_t line = __LINE__,
+    Throwable next = null)
+  {
+    this(msg, Type.UNKNOWN, file, line, next);
+  }
+
+  ///
+  this(string msg, Type type, string file = __FILE__, size_t line = __LINE__,
+    Throwable next = null)
+  {
+    super(msg, file, line, next);
+    type_ = type;
+  }
+
+  ///
+  Type type() const @property {
+    return type_;
+  }
+
+protected:
+  Type type_;
+}
+
+/**
+ * Skips a field of the given type on the protocol.
+ *
+ * The main purpose of skip() is to allow treating struct and cotainer types,
+ * (where multiple primitive types have to be skipped) the same as scalar types
+ * in generated code.
+ */
+void skip(Protocol)(Protocol prot, TType type) if (is(Protocol : TProtocol)) {
+  final switch (type) {
+    case TType.BOOL:
+      prot.readBool();
+      break;
+
+    case TType.BYTE:
+      prot.readByte();
+      break;
+
+    case TType.I16:
+      prot.readI16();
+      break;
+
+    case TType.I32:
+      prot.readI32();
+      break;
+
+    case TType.I64:
+      prot.readI64();
+      break;
+
+    case TType.DOUBLE:
+      prot.readDouble();
+      break;
+
+    case TType.STRING:
+      prot.readBinary();
+      break;
+
+    case TType.STRUCT:
+      prot.readStructBegin();
+      while (true) {
+        auto f = prot.readFieldBegin();
+        if (f.type == TType.STOP) break;
+        skip(prot, f.type);
+        prot.readFieldEnd();
+      }
+      prot.readStructEnd();
+      break;
+
+    case TType.LIST:
+      auto l = prot.readListBegin();
+      foreach (i; 0 .. l.size) {
+        skip(prot, l.elemType);
+      }
+      prot.readListEnd();
+      break;
+
+    case TType.MAP:
+      auto m = prot.readMapBegin();
+      foreach (i; 0 .. m.size) {
+        skip(prot, m.keyType);
+        skip(prot, m.valueType);
+      }
+      prot.readMapEnd();
+      break;
+
+    case TType.SET:
+      auto s = prot.readSetBegin();
+      foreach (i; 0 .. s.size) {
+        skip(prot, s.elemType);
+      }
+      prot.readSetEnd();
+      break;
+  }
+}
+
+/**
+ * Application-level exception.
+ *
+ * It is thrown if an RPC call went wrong on the application layer, e.g. if
+ * the receiver does not know the method name requested or a method invoked by
+ * the service processor throws an exception not part of the Thrift API.
+ */
+class TApplicationException : TException {
+  /// The possible exception types.
+  enum Type {
+    UNKNOWN = 0, ///
+    UNKNOWN_METHOD = 1, ///
+    INVALID_MESSAGE_TYPE = 2, ///
+    WRONG_METHOD_NAME = 3, ///
+    BAD_SEQUENCE_ID = 4, ///
+    MISSING_RESULT = 5, ///
+    INTERNAL_ERROR = 6, ///
+    PROTOCOL_ERROR = 7 ///
+  }
+
+  ///
+  this(Type type, string file = __FILE__, size_t line = __LINE__, Throwable next = null) {
+    static string msgForType(Type type) {
+      switch (type) {
+        case Type.UNKNOWN: return "Unknown application exception";
+        case Type.UNKNOWN_METHOD: return "Unknown method";
+        case Type.INVALID_MESSAGE_TYPE: return "Invalid message type";
+        case Type.WRONG_METHOD_NAME: return "Wrong method name";
+        case Type.BAD_SEQUENCE_ID: return "Bad sequence identifier";
+        case Type.MISSING_RESULT: return "Missing result";
+        default: return "(Invalid exception type)";
+      }
+    }
+    this(msgForType(type), type, file, line, next);
+  }
+
+  ///
+  this(string msg, string file = __FILE__, size_t line = __LINE__,
+    Throwable next = null)
+  {
+    this(msg, Type.UNKNOWN, file, line, next);
+  }
+
+  ///
+  this(string msg, Type type, string file = __FILE__, size_t line = __LINE__,
+    Throwable next = null)
+  {
+    super(msg, file, line, next);
+    type_ = type;
+  }
+
+  ///
+  Type type() @property const {
+    return type_;
+  }
+
+  // TODO: Replace hand-written read()/write() with thrift.codegen templates.
+
+  ///
+  void read(TProtocol iprot) {
+    iprot.readStructBegin();
+    while (true) {
+      auto f = iprot.readFieldBegin();
+      if (f.type == TType.STOP) break;
+
+      switch (f.id) {
+        case 1:
+          if (f.type == TType.STRING) {
+            msg = iprot.readString();
+          } else {
+            skip(iprot, f.type);
+          }
+          break;
+        case 2:
+          if (f.type == TType.I32) {
+            type_ = cast(Type)iprot.readI32();
+          } else {
+            skip(iprot, f.type);
+          }
+          break;
+        default:
+          skip(iprot, f.type);
+          break;
+      }
+    }
+    iprot.readStructEnd();
+  }
+
+  ///
+  void write(TProtocol oprot) const {
+    oprot.writeStructBegin(TStruct("TApplicationException"));
+
+    if (msg != null) {
+      oprot.writeFieldBegin(TField("message", TType.STRING, 1));
+      oprot.writeString(msg);
+      oprot.writeFieldEnd();
+    }
+
+    oprot.writeFieldBegin(TField("type", TType.I32, 2));
+    oprot.writeI32(type_);
+    oprot.writeFieldEnd();
+
+    oprot.writeFieldStop();
+    oprot.writeStructEnd();
+  }
+
+private:
+  Type type_;
+}
diff --git a/lib/d/src/thrift/protocol/binary.d b/lib/d/src/thrift/protocol/binary.d
new file mode 100644
index 0000000..13d8fe8
--- /dev/null
+++ b/lib/d/src/thrift/protocol/binary.d
@@ -0,0 +1,414 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+module thrift.protocol.binary;
+
+import std.array : uninitializedArray;
+import std.typetuple : allSatisfy, TypeTuple;
+import thrift.protocol.base;
+import thrift.transport.base;
+import thrift.internal.endian;
+
+/**
+ * TProtocol implementation of the Binary Thrift protocol.
+ */
+final class TBinaryProtocol(Transport = TTransport) if (
+  isTTransport!Transport
+) : TProtocol {
+
+  /**
+   * Constructs a new instance.
+   *
+   * Params:
+   *   trans = The transport to use.
+   *   containerSizeLimit = If positive, the container size is limited to the
+   *     given number of items.
+   *   stringSizeLimit = If positive, the string length is limited to the
+   *     given number of bytes.
+   *   strictRead = If false, old peers which do not include the protocol
+   *     version are tolerated.
+   *   strictWrite = Whether to include the protocol version in the header.
+   */
+  this(Transport trans, int containerSizeLimit = 0, int stringSizeLimit = 0,
+    bool strictRead = false, bool strictWrite = true
+  ) {
+    trans_ = trans;
+    this.containerSizeLimit = containerSizeLimit;
+    this.stringSizeLimit = stringSizeLimit;
+    this.strictRead = strictRead;
+    this.strictWrite = strictWrite;
+  }
+
+  Transport transport() @property {
+    return trans_;
+  }
+
+  void reset() {}
+
+  /**
+   * If false, old peers which do not include the protocol version in the
+   * message header are tolerated.
+   *
+   * Defaults to false.
+   */
+  bool strictRead;
+
+  /**
+   * Whether to include the protocol version in the message header (older
+   * versions didn't).
+   *
+   * Defaults to true.
+   */
+  bool strictWrite;
+
+  /**
+   * If positive, limits the number of items of deserialized containers to the
+   * given amount.
+   *
+   * This is useful to avoid allocating excessive amounts of memory when broken
+   * data is received. If the limit is exceeded, a SIZE_LIMIT-type
+   * TProtocolException is thrown.
+   *
+   * Defaults to zero (no limit).
+   */
+  int containerSizeLimit;
+
+  /**
+   * If positive, limits the length of deserialized strings/binary data to the
+   * given number of bytes.
+   *
+   * This is useful to avoid allocating excessive amounts of memory when broken
+   * data is received. If the limit is exceeded, a SIZE_LIMIT-type
+   * TProtocolException is thrown.
+   *
+   * Defaults to zero (no limit).
+   */
+  int stringSizeLimit;
+
+  /*
+   * Writing methods.
+   */
+
+  void writeBool(bool b) {
+    writeByte(b ? 1 : 0);
+  }
+
+  void writeByte(byte b) {
+    trans_.write((cast(ubyte*)&b)[0 .. 1]);
+  }
+
+  void writeI16(short i16) {
+    short net = hostToNet(i16);
+    trans_.write((cast(ubyte*)&net)[0 .. 2]);
+  }
+
+  void writeI32(int i32) {
+    int net = hostToNet(i32);
+    trans_.write((cast(ubyte*)&net)[0 .. 4]);
+  }
+
+  void writeI64(long i64) {
+    long net = hostToNet(i64);
+    trans_.write((cast(ubyte*)&net)[0 .. 8]);
+  }
+
+  void writeDouble(double dub) {
+    static assert(double.sizeof == ulong.sizeof);
+    auto bits = hostToNet(*cast(ulong*)(&dub));
+    trans_.write((cast(ubyte*)&bits)[0 .. 8]);
+  }
+
+  void writeString(string str) {
+    writeBinary(cast(ubyte[])str);
+  }
+
+  void writeBinary(ubyte[] buf) {
+    assert(buf.length <= int.max);
+    writeI32(cast(int)buf.length);
+    trans_.write(buf);
+  }
+
+  void writeMessageBegin(TMessage message) {
+    if (strictWrite) {
+      int versn = VERSION_1 | message.type;
+      writeI32(versn);
+      writeString(message.name);
+      writeI32(message.seqid);
+    } else {
+      writeString(message.name);
+      writeByte(message.type);
+      writeI32(message.seqid);
+    }
+  }
+  void writeMessageEnd() {}
+
+  void writeStructBegin(TStruct tstruct) {}
+  void writeStructEnd() {}
+
+  void writeFieldBegin(TField field) {
+    writeByte(field.type);
+    writeI16(field.id);
+  }
+  void writeFieldEnd() {}
+
+  void writeFieldStop() {
+    writeByte(TType.STOP);
+  }
+
+  void writeListBegin(TList list) {
+    assert(list.size <= int.max);
+    writeByte(list.elemType);
+    writeI32(cast(int)list.size);
+  }
+  void writeListEnd() {}
+
+  void writeMapBegin(TMap map) {
+    assert(map.size <= int.max);
+    writeByte(map.keyType);
+    writeByte(map.valueType);
+    writeI32(cast(int)map.size);
+  }
+  void writeMapEnd() {}
+
+  void writeSetBegin(TSet set) {
+    assert(set.size <= int.max);
+    writeByte(set.elemType);
+    writeI32(cast(int)set.size);
+  }
+  void writeSetEnd() {}
+
+
+  /*
+   * Reading methods.
+   */
+
+  bool readBool() {
+    return readByte() != 0;
+  }
+
+  byte readByte() {
+    ubyte[1] b = void;
+    trans_.readAll(b);
+    return cast(byte)b[0];
+  }
+
+  short readI16() {
+    IntBuf!short b = void;
+    trans_.readAll(b.bytes);
+    return netToHost(b.value);
+  }
+
+  int readI32() {
+    IntBuf!int b = void;
+    trans_.readAll(b.bytes);
+    return netToHost(b.value);
+  }
+
+  long readI64() {
+    IntBuf!long b = void;
+    trans_.readAll(b.bytes);
+    return netToHost(b.value);
+  }
+
+  double readDouble() {
+    IntBuf!long b = void;
+    trans_.readAll(b.bytes);
+    b.value = netToHost(b.value);
+    return *cast(double*)(&b.value);
+  }
+
+  string readString() {
+    return cast(string)readBinary();
+  }
+
+  ubyte[] readBinary() {
+    return readBinaryBody(readSize(stringSizeLimit));
+  }
+
+  TMessage readMessageBegin() {
+    TMessage msg = void;
+
+    int size = readI32();
+    if (size < 0) {
+      int versn = size & VERSION_MASK;
+      if (versn != VERSION_1) {
+        throw new TProtocolException("Bad protocol version.",
+          TProtocolException.Type.BAD_VERSION);
+      }
+
+      msg.type = cast(TMessageType)(size & MESSAGE_TYPE_MASK);
+      msg.name = readString();
+      msg.seqid = readI32();
+    } else {
+      if (strictRead) {
+        throw new TProtocolException(
+          "Protocol version missing, old client?",
+          TProtocolException.Type.BAD_VERSION);
+      } else {
+        if (size < 0) {
+          throw new TProtocolException(TProtocolException.Type.NEGATIVE_SIZE);
+        }
+        msg.name = cast(string)readBinaryBody(size);
+        msg.type = cast(TMessageType)(readByte());
+        msg.seqid = readI32();
+      }
+    }
+
+    return msg;
+  }
+  void readMessageEnd() {}
+
+  TStruct readStructBegin() {
+    return TStruct();
+  }
+  void readStructEnd() {}
+
+  TField readFieldBegin() {
+    TField f = void;
+    f.name = null;
+    f.type = cast(TType)readByte();
+    if (f.type == TType.STOP) return f;
+    f.id = readI16();
+    return f;
+  }
+  void readFieldEnd() {}
+
+  TList readListBegin() {
+    return TList(cast(TType)readByte(), readSize(containerSizeLimit));
+  }
+  void readListEnd() {}
+
+  TMap readMapBegin() {
+    return TMap(cast(TType)readByte(), cast(TType)readByte(),
+      readSize(containerSizeLimit));
+  }
+  void readMapEnd() {}
+
+  TSet readSetBegin() {
+    return TSet(cast(TType)readByte(), readSize(containerSizeLimit));
+  }
+  void readSetEnd() {}
+
+private:
+  ubyte[] readBinaryBody(int size) {
+    if (size == 0) {
+      return null;
+    }
+
+    auto buf = uninitializedArray!(ubyte[])(size);
+    trans_.readAll(buf);
+    return buf;
+  }
+
+  int readSize(int limit) {
+    auto size = readI32();
+    if (size < 0) {
+      throw new TProtocolException(TProtocolException.Type.NEGATIVE_SIZE);
+    } else if (limit > 0 && size > limit) {
+      throw new TProtocolException(TProtocolException.Type.SIZE_LIMIT);
+    }
+    return size;
+  }
+
+  enum MESSAGE_TYPE_MASK = 0x000000ff;
+  enum VERSION_MASK = 0xffff0000;
+  enum VERSION_1 = 0x80010000;
+
+  Transport trans_;
+}
+
+/**
+ * TBinaryProtocol construction helper to avoid having to explicitly specify
+ * the transport type, i.e. to allow the constructor being called using IFTI
+ * (see $(LINK2 http://d.puremagic.com/issues/show_bug.cgi?id=6082, D Bugzilla
+ * enhancement requet 6082)).
+ */
+TBinaryProtocol!Transport tBinaryProtocol(Transport)(Transport trans,
+  int containerSizeLimit = 0, int stringSizeLimit = 0,
+  bool strictRead = false, bool strictWrite = true
+) if (isTTransport!Transport) {
+  return new TBinaryProtocol!Transport(trans, containerSizeLimit,
+    stringSizeLimit, strictRead, strictWrite);
+}
+
+unittest {
+  import std.exception;
+  import thrift.transport.memory;
+
+  // Check the message header format.
+  auto buf = new TMemoryBuffer;
+  auto binary = tBinaryProtocol(buf);
+  binary.writeMessageBegin(TMessage("foo", TMessageType.CALL, 0));
+
+  auto header = new ubyte[15];
+  buf.readAll(header);
+  enforce(header == [
+    128, 1, 0, 1, // Version 1, TMessageType.CALL
+    0, 0, 0, 3, // Method name length
+    102, 111, 111, // Method name ("foo")
+    0, 0, 0, 0, // Sequence id
+  ]);
+}
+
+unittest {
+  import thrift.internal.test.protocol;
+  testContainerSizeLimit!(TBinaryProtocol!())();
+  testStringSizeLimit!(TBinaryProtocol!())();
+}
+
+/**
+ * TProtocolFactory creating a TBinaryProtocol instance for passed in
+ * transports.
+ *
+ * The optional Transports template tuple parameter can be used to specify
+ * one or more TTransport implementations to specifically instantiate
+ * TBinaryProtocol for. If the actual transport types encountered at
+ * runtime match one of the transports in the list, a specialized protocol
+ * instance is created. Otherwise, a generic TTransport version is used.
+ */
+class TBinaryProtocolFactory(Transports...) if (
+  allSatisfy!(isTTransport, Transports)
+) : TProtocolFactory {
+  ///
+  this (int containerSizeLimit = 0, int stringSizeLimit = 0,
+    bool strictRead = false, bool strictWrite = true
+  ) {
+    strictRead_ = strictRead;
+    strictWrite_ = strictWrite;
+    containerSizeLimit_ = containerSizeLimit;
+    stringSizeLimit_ = stringSizeLimit;
+  }
+
+  TProtocol getProtocol(TTransport trans) const {
+    foreach (Transport; TypeTuple!(Transports, TTransport)) {
+      auto concreteTrans = cast(Transport)trans;
+      if (concreteTrans) {
+        return new TBinaryProtocol!Transport(concreteTrans,
+          containerSizeLimit_, stringSizeLimit_, strictRead_, strictWrite_);
+      }
+    }
+    throw new TProtocolException(
+      "Passed null transport to TBinaryProtocolFactoy.");
+  }
+
+protected:
+  bool strictRead_;
+  bool strictWrite_;
+  int containerSizeLimit_;
+  int stringSizeLimit_;
+}
diff --git a/lib/d/src/thrift/protocol/compact.d b/lib/d/src/thrift/protocol/compact.d
new file mode 100644
index 0000000..5122f61
--- /dev/null
+++ b/lib/d/src/thrift/protocol/compact.d
@@ -0,0 +1,695 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+module thrift.protocol.compact;
+
+import std.array : uninitializedArray;
+import std.typetuple : allSatisfy, TypeTuple;
+import thrift.protocol.base;
+import thrift.transport.base;
+import thrift.internal.endian;
+
+/**
+ * D implementation of the Compact protocol.
+ *
+ * See THRIFT-110 for a protocol description. This implementation is based on
+ * the C++ one.
+ */
+final class TCompactProtocol(Transport = TTransport) if (
+  isTTransport!Transport
+) : TProtocol {
+  /**
+   * Constructs a new instance.
+   *
+   * Params:
+   *   trans = The transport to use.
+   *   containerSizeLimit = If positive, the container size is limited to the
+   *     given number of items.
+   *   stringSizeLimit = If positive, the string length is limited to the
+   *     given number of bytes.
+   */
+  this(Transport trans, int containerSizeLimit = 0, int stringSizeLimit = 0) {
+    trans_ = trans;
+    this.containerSizeLimit = containerSizeLimit;
+    this.stringSizeLimit = stringSizeLimit;
+  }
+
+  Transport transport() @property {
+    return trans_;
+  }
+
+  void reset() {
+    lastFieldId_ = 0;
+    fieldIdStack_ = null;
+    booleanField_ = TField.init;
+    hasBoolValue_ = false;
+  }
+
+  /**
+   * If positive, limits the number of items of deserialized containers to the
+   * given amount.
+   *
+   * This is useful to avoid allocating excessive amounts of memory when broken
+   * data is received. If the limit is exceeded, a SIZE_LIMIT-type
+   * TProtocolException is thrown.
+   *
+   * Defaults to zero (no limit).
+   */
+  int containerSizeLimit;
+
+  /**
+   * If positive, limits the length of deserialized strings/binary data to the
+   * given number of bytes.
+   *
+   * This is useful to avoid allocating excessive amounts of memory when broken
+   * data is received. If the limit is exceeded, a SIZE_LIMIT-type
+   * TProtocolException is thrown.
+   *
+   * Defaults to zero (no limit).
+   */
+  int stringSizeLimit;
+
+  /*
+   * Writing methods.
+   */
+
+  void writeBool(bool b) {
+    if (booleanField_.name !is null) {
+      // we haven't written the field header yet
+      writeFieldBeginInternal(booleanField_,
+        b ? CType.BOOLEAN_TRUE : CType.BOOLEAN_FALSE);
+      booleanField_.name = null;
+    } else {
+      // we're not part of a field, so just write the value
+      writeByte(b ? CType.BOOLEAN_TRUE : CType.BOOLEAN_FALSE);
+    }
+  }
+
+  void writeByte(byte b) {
+    trans_.write((cast(ubyte*)&b)[0..1]);
+  }
+
+  void writeI16(short i16) {
+    writeVarint32(i32ToZigzag(i16));
+  }
+
+  void writeI32(int i32) {
+    writeVarint32(i32ToZigzag(i32));
+  }
+
+  void writeI64(long i64) {
+    writeVarint64(i64ToZigzag(i64));
+  }
+
+  void writeDouble(double dub) {
+    ulong bits = hostToLe(*cast(ulong*)(&dub));
+    trans_.write((cast(ubyte*)&bits)[0 .. 8]);
+  }
+
+  void writeString(string str) {
+    writeBinary(cast(ubyte[])str);
+  }
+
+  void writeBinary(ubyte[] buf) {
+    assert(buf.length <= int.max);
+    writeVarint32(cast(int)buf.length);
+    trans_.write(buf);
+  }
+
+  void writeMessageBegin(TMessage msg) {
+    writeByte(cast(byte)PROTOCOL_ID);
+    writeByte((VERSION_N & VERSION_MASK) |
+      ((cast(int)msg.type << TYPE_SHIFT_AMOUNT) & TYPE_MASK));
+    writeVarint32(msg.seqid);
+    writeString(msg.name);
+  }
+  void writeMessageEnd() {}
+
+  void writeStructBegin(TStruct tstruct) {
+    fieldIdStack_ ~= lastFieldId_;
+    lastFieldId_ = 0;
+  }
+
+  void writeStructEnd() {
+    lastFieldId_ = fieldIdStack_[$ - 1];
+    fieldIdStack_ = fieldIdStack_[0 .. $ - 1];
+    fieldIdStack_.assumeSafeAppend();
+  }
+
+  void writeFieldBegin(TField field) {
+    if (field.type == TType.BOOL) {
+      booleanField_.name = field.name;
+      booleanField_.type = field.type;
+      booleanField_.id = field.id;
+    } else {
+      return writeFieldBeginInternal(field);
+    }
+  }
+  void writeFieldEnd() {}
+
+  void writeFieldStop() {
+    writeByte(TType.STOP);
+  }
+
+  void writeListBegin(TList list) {
+    writeCollectionBegin(list.elemType, list.size);
+  }
+  void writeListEnd() {}
+
+  void writeMapBegin(TMap map) {
+    if (map.size == 0) {
+      writeByte(0);
+    } else {
+      assert(map.size <= int.max);
+      writeVarint32(cast(int)map.size);
+      writeByte(cast(byte)(toCType(map.keyType) << 4 | toCType(map.valueType)));
+    }
+  }
+  void writeMapEnd() {}
+
+  void writeSetBegin(TSet set) {
+    writeCollectionBegin(set.elemType, set.size);
+  }
+  void writeSetEnd() {}
+
+
+  /*
+   * Reading methods.
+   */
+
+  bool readBool() {
+    if (hasBoolValue_ == true) {
+      hasBoolValue_ = false;
+      return boolValue_;
+    }
+
+    return readByte() == CType.BOOLEAN_TRUE;
+  }
+
+  byte readByte() {
+    ubyte[1] b = void;
+    trans_.readAll(b);
+    return cast(byte)b[0];
+  }
+
+  short readI16() {
+    return cast(short)zigzagToI32(readVarint32());
+  }
+
+  int readI32() {
+    return zigzagToI32(readVarint32());
+  }
+
+  long readI64() {
+    return zigzagToI64(readVarint64());
+  }
+
+  double readDouble() {
+    IntBuf!long b = void;
+    trans_.readAll(b.bytes);
+    b.value = leToHost(b.value);
+    return *cast(double*)(&b.value);
+  }
+
+  string readString() {
+    return cast(string)readBinary();
+  }
+
+  ubyte[] readBinary() {
+    auto size = readVarint32();
+    checkSize(size, stringSizeLimit);
+
+    if (size == 0) {
+      return null;
+    }
+
+    auto buf = uninitializedArray!(ubyte[])(size);
+    trans_.readAll(buf);
+    return buf;
+  }
+
+  TMessage readMessageBegin() {
+    TMessage msg = void;
+
+    auto protocolId = readByte();
+    if (protocolId != cast(byte)PROTOCOL_ID) {
+      throw new TProtocolException("Bad protocol identifier",
+        TProtocolException.Type.BAD_VERSION);
+    }
+
+    auto versionAndType = readByte();
+    auto ver = versionAndType & VERSION_MASK;
+    if (ver != VERSION_N) {
+      throw new TProtocolException("Bad protocol version",
+        TProtocolException.Type.BAD_VERSION);
+    }
+
+    msg.type = cast(TMessageType)((versionAndType >> TYPE_SHIFT_AMOUNT) & 0x03);
+    msg.seqid = readVarint32();
+    msg.name = readString();
+
+    return msg;
+  }
+  void readMessageEnd() {}
+
+  TStruct readStructBegin() {
+    fieldIdStack_ ~= lastFieldId_;
+    lastFieldId_ = 0;
+    return TStruct();
+  }
+
+  void readStructEnd() {
+    lastFieldId_ = fieldIdStack_[$ - 1];
+    fieldIdStack_ = fieldIdStack_[0 .. $ - 1];
+  }
+
+  TField readFieldBegin() {
+    TField f = void;
+    f.name = null;
+
+    auto bite = readByte();
+    auto type = cast(CType)(bite & 0x0f);
+
+    if (type == CType.STOP) {
+      // Struct stop byte, nothing more to do.
+      f.id = 0;
+      f.type = TType.STOP;
+      return f;
+    }
+
+    // Mask off the 4 MSB of the type header, which could contain a field id
+    // delta.
+    auto modifier = cast(short)((bite & 0xf0) >> 4);
+    if (modifier > 0) {
+      f.id = cast(short)(lastFieldId_ + modifier);
+    } else {
+      // Delta encoding not used, just read the id as usual.
+      f.id = readI16();
+    }
+    f.type = getTType(type);
+
+    if (type == CType.BOOLEAN_TRUE || type == CType.BOOLEAN_FALSE) {
+      // For boolean fields, the value is encoded in the type – keep it around
+      // for the readBool() call.
+      hasBoolValue_ = true;
+      boolValue_ = (type == CType.BOOLEAN_TRUE ? true : false);
+    }
+
+    lastFieldId_ = f.id;
+    return f;
+  }
+  void readFieldEnd() {}
+
+  TList readListBegin() {
+    auto sizeAndType = readByte();
+
+    auto lsize = (sizeAndType >> 4) & 0xf;
+    if (lsize == 0xf) {
+      lsize = readVarint32();
+    }
+    checkSize(lsize, containerSizeLimit);
+
+    TList l = void;
+    l.elemType = getTType(cast(CType)(sizeAndType & 0x0f));
+    l.size = cast(size_t)lsize;
+
+    return l;
+  }
+  void readListEnd() {}
+
+  TMap readMapBegin() {
+    TMap m = void;
+
+    auto size = readVarint32();
+    ubyte kvType;
+    if (size != 0) {
+      kvType = readByte();
+    }
+    checkSize(size, containerSizeLimit);
+
+    m.size = size;
+    m.keyType = getTType(cast(CType)(kvType >> 4));
+    m.valueType = getTType(cast(CType)(kvType & 0xf));
+
+    return m;
+  }
+  void readMapEnd() {}
+
+  TSet readSetBegin() {
+    auto sizeAndType = readByte();
+
+    auto lsize = (sizeAndType >> 4) & 0xf;
+    if (lsize == 0xf) {
+      lsize = readVarint32();
+    }
+    checkSize(lsize, containerSizeLimit);
+
+    TSet s = void;
+    s.elemType = getTType(cast(CType)(sizeAndType & 0xf));
+    s.size = cast(size_t)lsize;
+
+    return s;
+  }
+  void readSetEnd() {}
+
+private:
+  void writeFieldBeginInternal(TField field, byte typeOverride = -1) {
+    // If there's a type override, use that.
+    auto typeToWrite = (typeOverride == -1 ? toCType(field.type) : typeOverride);
+
+    // check if we can use delta encoding for the field id
+    if (field.id > lastFieldId_ && (field.id - lastFieldId_) <= 15) {
+      // write them together
+      writeByte(cast(byte)((field.id - lastFieldId_) << 4 | typeToWrite));
+    } else {
+      // write them separate
+      writeByte(cast(byte)typeToWrite);
+      writeI16(field.id);
+    }
+
+    lastFieldId_ = field.id;
+  }
+
+
+  void writeCollectionBegin(TType elemType, size_t size) {
+    if (size <= 14) {
+      writeByte(cast(byte)(size << 4 | toCType(elemType)));
+    } else {
+      assert(size <= int.max);
+      writeByte(0xf0 | toCType(elemType));
+      writeVarint32(cast(int)size);
+    }
+  }
+
+  void writeVarint32(uint n) {
+    ubyte[5] buf = void;
+    ubyte wsize;
+
+    while (true) {
+      if ((n & ~0x7F) == 0) {
+        buf[wsize++] = cast(ubyte)n;
+        break;
+      } else {
+        buf[wsize++] = cast(ubyte)((n & 0x7F) | 0x80);
+        n >>= 7;
+      }
+    }
+
+    trans_.write(buf[0 .. wsize]);
+  }
+
+  /*
+   * Write an i64 as a varint. Results in 1-10 bytes on the wire.
+   */
+  void writeVarint64(ulong n) {
+    ubyte[10] buf = void;
+    ubyte wsize;
+
+    while (true) {
+      if ((n & ~0x7FL) == 0) {
+        buf[wsize++] = cast(ubyte)n;
+        break;
+      } else {
+        buf[wsize++] = cast(ubyte)((n & 0x7F) | 0x80);
+        n >>= 7;
+      }
+    }
+
+    trans_.write(buf[0 .. wsize]);
+  }
+
+  /*
+   * Convert l into a zigzag long. This allows negative numbers to be
+   * represented compactly as a varint.
+   */
+  ulong i64ToZigzag(long l) {
+    return (l << 1) ^ (l >> 63);
+  }
+
+  /*
+   * Convert n into a zigzag int. This allows negative numbers to be
+   * represented compactly as a varint.
+   */
+  uint i32ToZigzag(int n) {
+    return (n << 1) ^ (n >> 31);
+  }
+
+  CType toCType(TType type) {
+    final switch (type) {
+      case TType.STOP:
+        return CType.STOP;
+      case TType.BOOL:
+        return CType.BOOLEAN_TRUE;
+      case TType.BYTE:
+        return CType.BYTE;
+      case TType.DOUBLE:
+        return CType.DOUBLE;
+      case TType.I16:
+        return CType.I16;
+      case TType.I32:
+        return CType.I32;
+      case TType.I64:
+        return CType.I64;
+      case TType.STRING:
+        return CType.BINARY;
+      case TType.STRUCT:
+        return CType.STRUCT;
+      case TType.MAP:
+        return CType.MAP;
+      case TType.SET:
+        return CType.SET;
+      case TType.LIST:
+        return CType.LIST;
+    }
+  }
+
+  int readVarint32() {
+    return cast(int)readVarint64();
+  }
+
+  long readVarint64() {
+    ulong val;
+    ubyte shift;
+    ubyte[10] buf = void;  // 64 bits / (7 bits/byte) = 10 bytes.
+    auto bufSize = buf.sizeof;
+    auto borrowed = trans_.borrow(buf.ptr, bufSize);
+
+    ubyte rsize;
+
+    if (borrowed) {
+      // Fast path.
+      while (true) {
+        auto bite = borrowed[rsize];
+        rsize++;
+        val |= cast(ulong)(bite & 0x7f) << shift;
+        shift += 7;
+        if (!(bite & 0x80)) {
+          trans_.consume(rsize);
+          return val;
+        }
+        // Have to check for invalid data so we don't crash.
+        if (rsize == buf.sizeof) {
+          throw new TProtocolException(TProtocolException.Type.INVALID_DATA,
+            "Variable-length int over 10 bytes.");
+        }
+      }
+    } else {
+      // Slow path.
+      while (true) {
+        ubyte[1] bite;
+        trans_.readAll(bite);
+        ++rsize;
+
+        val |= cast(ulong)(bite[0] & 0x7f) << shift;
+        shift += 7;
+        if (!(bite[0] & 0x80)) {
+          return val;
+        }
+
+        // Might as well check for invalid data on the slow path too.
+        if (rsize >= buf.sizeof) {
+          throw new TProtocolException(TProtocolException.Type.INVALID_DATA,
+            "Variable-length int over 10 bytes.");
+        }
+      }
+    }
+  }
+
+  /*
+   * Convert from zigzag int to int.
+   */
+  int zigzagToI32(uint n) {
+    return (n >> 1) ^ -(n & 1);
+  }
+
+  /*
+   * Convert from zigzag long to long.
+   */
+  long zigzagToI64(ulong n) {
+    return (n >> 1) ^ -(n & 1);
+  }
+
+  TType getTType(CType type) {
+    final switch (type) {
+      case CType.STOP:
+        return TType.STOP;
+      case CType.BOOLEAN_FALSE:
+        return TType.BOOL;
+      case CType.BOOLEAN_TRUE:
+        return TType.BOOL;
+      case CType.BYTE:
+        return TType.BYTE;
+      case CType.I16:
+        return TType.I16;
+      case CType.I32:
+        return TType.I32;
+      case CType.I64:
+        return TType.I64;
+      case CType.DOUBLE:
+        return TType.DOUBLE;
+      case CType.BINARY:
+        return TType.STRING;
+      case CType.LIST:
+        return TType.LIST;
+      case CType.SET:
+        return TType.SET;
+      case CType.MAP:
+        return TType.MAP;
+      case CType.STRUCT:
+        return TType.STRUCT;
+    }
+  }
+
+  void checkSize(int size, int limit) {
+    if (size < 0) {
+      throw new TProtocolException(TProtocolException.Type.NEGATIVE_SIZE);
+    } else if (limit > 0 && size > limit) {
+      throw new TProtocolException(TProtocolException.Type.SIZE_LIMIT);
+    }
+  }
+
+  enum PROTOCOL_ID = 0x82;
+  enum VERSION_N = 1;
+  enum VERSION_MASK = 0b0001_1111;
+  enum TYPE_MASK = 0b1110_0000;
+  enum TYPE_SHIFT_AMOUNT = 5;
+
+  // Probably need to implement a better stack at some point.
+  short[] fieldIdStack_;
+  short lastFieldId_;
+
+  TField booleanField_;
+
+  bool hasBoolValue_;
+  bool boolValue_;
+
+  Transport trans_;
+}
+
+/**
+ * TCompactProtocol construction helper to avoid having to explicitly specify
+ * the transport type, i.e. to allow the constructor being called using IFTI
+ * (see $(LINK2 http://d.puremagic.com/issues/show_bug.cgi?id=6082, D Bugzilla
+ * enhancement requet 6082)).
+ */
+TCompactProtocol!Transport tCompactProtocol(Transport)(Transport trans,
+  int containerSizeLimit = 0, int stringSizeLimit = 0
+) if (isTTransport!Transport)
+{
+  return new TCompactProtocol!Transport(trans,
+    containerSizeLimit, stringSizeLimit);
+}
+
+private {
+  enum CType : ubyte {
+    STOP = 0x0,
+    BOOLEAN_TRUE = 0x1,
+    BOOLEAN_FALSE = 0x2,
+    BYTE = 0x3,
+    I16 = 0x4,
+    I32 = 0x5,
+    I64 = 0x6,
+    DOUBLE = 0x7,
+    BINARY = 0x8,
+    LIST = 0x9,
+    SET = 0xa,
+    MAP = 0xb,
+    STRUCT = 0xc
+  }
+  static assert(CType.max <= 0xf,
+    "Compact protocol wire type representation must fit into 4 bits.");
+}
+
+unittest {
+  import std.exception;
+  import thrift.transport.memory;
+
+  // Check the message header format.
+  auto buf = new TMemoryBuffer;
+  auto compact = tCompactProtocol(buf);
+  compact.writeMessageBegin(TMessage("foo", TMessageType.CALL, 0));
+
+  auto header = new ubyte[7];
+  buf.readAll(header);
+  enforce(header == [
+    130, // Protocol id.
+    33, // Version/type byte.
+    0, // Sequence id.
+    3, 102, 111, 111 // Method name.
+  ]);
+}
+
+unittest {
+  import thrift.internal.test.protocol;
+  testContainerSizeLimit!(TCompactProtocol!())();
+  testStringSizeLimit!(TCompactProtocol!())();
+}
+
+/**
+ * TProtocolFactory creating a TCompactProtocol instance for passed in
+ * transports.
+ *
+ * The optional Transports template tuple parameter can be used to specify
+ * one or more TTransport implementations to specifically instantiate
+ * TCompactProtocol for. If the actual transport types encountered at
+ * runtime match one of the transports in the list, a specialized protocol
+ * instance is created. Otherwise, a generic TTransport version is used.
+ */
+class TCompactProtocolFactory(Transports...) if (
+  allSatisfy!(isTTransport, Transports)
+) : TProtocolFactory {
+  ///
+  this(int containerSizeLimit = 0, int stringSizeLimit = 0) {
+    containerSizeLimit_ = 0;
+    stringSizeLimit_ = 0;
+  }
+
+  TProtocol getProtocol(TTransport trans) const {
+    foreach (Transport; TypeTuple!(Transports, TTransport)) {
+      auto concreteTrans = cast(Transport)trans;
+      if (concreteTrans) {
+        return new TCompactProtocol!Transport(concreteTrans);
+      }
+    }
+    throw new TProtocolException(
+      "Passed null transport to TCompactProtocolFactory.");
+  }
+
+  int containerSizeLimit_;
+  int stringSizeLimit_;
+}
diff --git a/lib/d/src/thrift/protocol/json.d b/lib/d/src/thrift/protocol/json.d
new file mode 100644
index 0000000..7d35ba2
--- /dev/null
+++ b/lib/d/src/thrift/protocol/json.d
@@ -0,0 +1,979 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+module thrift.protocol.json;
+
+import std.algorithm;
+import std.array;
+import std.base64;
+import std.conv;
+import std.range;
+import std.string : format;
+import std.traits : isIntegral;
+import std.typetuple : allSatisfy, TypeTuple;
+import thrift.protocol.base;
+import thrift.transport.base;
+
+alias Base64Impl!('+', '/', Base64.NoPadding) Base64NoPad;
+
+/**
+ * Implementation of the Thrift JSON protocol.
+ */
+final class TJsonProtocol(Transport = TTransport) if (
+  isTTransport!Transport
+) : TProtocol {
+  /**
+   * Constructs a new instance.
+   *
+   * Params:
+   *   trans = The transport to use.
+   *   containerSizeLimit = If positive, the container size is limited to the
+   *     given number of items.
+   *   stringSizeLimit = If positive, the string length is limited to the
+   *     given number of bytes.
+   */
+  this(Transport trans, int containerSizeLimit = 0, int stringSizeLimit = 0) {
+    trans_ = trans;
+    this.containerSizeLimit = containerSizeLimit;
+    this.stringSizeLimit = stringSizeLimit;
+
+    context_ = new Context();
+    reader_ = new LookaheadReader(trans);
+  }
+
+  Transport transport() @property {
+    return trans_;
+  }
+
+  void reset() {
+    contextStack_.clear();
+    context_ = new Context();
+    reader_ = new LookaheadReader(trans_);
+  }
+
+  /**
+   * If positive, limits the number of items of deserialized containers to the
+   * given amount.
+   *
+   * This is useful to avoid allocating excessive amounts of memory when broken
+   * data is received. If the limit is exceeded, a SIZE_LIMIT-type
+   * TProtocolException is thrown.
+   *
+   * Defaults to zero (no limit).
+   */
+  int containerSizeLimit;
+
+  /**
+   * If positive, limits the length of deserialized strings/binary data to the
+   * given number of bytes.
+   *
+   * This is useful to avoid allocating excessive amounts of memory when broken
+   * data is received. If the limit is exceeded, a SIZE_LIMIT-type
+   * TProtocolException is thrown.
+   *
+   * Note: For binary data, the limit applies to the length of the
+   * Base64-encoded string data, not the resulting byte array.
+   *
+   * Defaults to zero (no limit).
+   */
+  int stringSizeLimit;
+
+  /*
+   * Writing methods.
+   */
+
+  void writeBool(bool b) {
+    writeJsonInteger(b ? 1 : 0);
+  }
+
+  void writeByte(byte b) {
+    writeJsonInteger(b);
+  }
+
+  void writeI16(short i16) {
+    writeJsonInteger(i16);
+  }
+
+  void writeI32(int i32) {
+    writeJsonInteger(i32);
+  }
+
+  void writeI64(long i64) {
+    writeJsonInteger(i64);
+  }
+
+  void writeDouble(double dub) {
+    context_.write(trans_);
+
+    string value;
+    if (dub is double.nan) {
+      value = NAN_STRING;
+    } else if (dub is double.infinity) {
+      value = INFINITY_STRING;
+    } else if (dub is -double.infinity) {
+      value = NEG_INFINITY_STRING;
+    }
+
+    bool escapeNum = value !is null || context_.escapeNum;
+
+    if (value is null) {
+      value = format("%.16g", dub);
+    }
+
+    if (escapeNum) trans_.write(STRING_DELIMITER);
+    trans_.write(cast(ubyte[])value);
+    if (escapeNum) trans_.write(STRING_DELIMITER);
+  }
+
+  void writeString(string str) {
+    context_.write(trans_);
+    trans_.write(STRING_DELIMITER);
+    foreach (c; str) {
+      writeJsonChar(c);
+    }
+    trans_.write(STRING_DELIMITER);
+  }
+
+  void writeBinary(ubyte[] buf) {
+    context_.write(trans_);
+
+    trans_.write(STRING_DELIMITER);
+    ubyte[4] b;
+    while (!buf.empty) {
+      auto toWrite = take(buf, 3);
+      Base64NoPad.encode(toWrite, b[]);
+      trans_.write(b[0 .. toWrite.length + 1]);
+      buf.popFrontN(toWrite.length);
+    }
+    trans_.write(STRING_DELIMITER);
+  }
+
+  void writeMessageBegin(TMessage msg) {
+    writeJsonArrayBegin();
+    writeJsonInteger(THRIFT_JSON_VERSION);
+    writeString(msg.name);
+    writeJsonInteger(cast(byte)msg.type);
+    writeJsonInteger(msg.seqid);
+  }
+
+  void writeMessageEnd() {
+    writeJsonArrayEnd();
+  }
+
+  void writeStructBegin(TStruct tstruct) {
+    writeJsonObjectBegin();
+  }
+
+  void writeStructEnd() {
+    writeJsonObjectEnd();
+  }
+
+  void writeFieldBegin(TField field) {
+    writeJsonInteger(field.id);
+    writeJsonObjectBegin();
+    writeString(getNameFromTType(field.type));
+  }
+
+  void writeFieldEnd() {
+    writeJsonObjectEnd();
+  }
+
+  void writeFieldStop() {}
+
+  void writeListBegin(TList list) {
+    writeJsonArrayBegin();
+    writeString(getNameFromTType(list.elemType));
+    writeJsonInteger(list.size);
+  }
+
+  void writeListEnd() {
+    writeJsonArrayEnd();
+  }
+
+  void writeMapBegin(TMap map) {
+    writeJsonArrayBegin();
+    writeString(getNameFromTType(map.keyType));
+    writeString(getNameFromTType(map.valueType));
+    writeJsonInteger(map.size);
+    writeJsonObjectBegin();
+  }
+
+  void writeMapEnd() {
+    writeJsonObjectEnd();
+    writeJsonArrayEnd();
+  }
+
+  void writeSetBegin(TSet set) {
+    writeJsonArrayBegin();
+    writeString(getNameFromTType(set.elemType));
+    writeJsonInteger(set.size);
+  }
+
+  void writeSetEnd() {
+    writeJsonArrayEnd();
+  }
+
+
+  /*
+   * Reading methods.
+   */
+
+  bool readBool() {
+    return readJsonInteger!byte() ? true : false;
+  }
+
+  byte readByte() {
+    return readJsonInteger!byte();
+  }
+
+  short readI16() {
+    return readJsonInteger!short();
+  }
+
+  int readI32() {
+    return readJsonInteger!int();
+  }
+
+  long readI64() {
+    return readJsonInteger!long();
+  }
+
+  double readDouble() {
+    context_.read(reader_);
+
+    if (reader_.peek() == STRING_DELIMITER) {
+      auto str = readJsonString(true);
+      if (str == NAN_STRING) {
+        return double.nan;
+      }
+      if (str == INFINITY_STRING) {
+        return double.infinity;
+      }
+      if (str == NEG_INFINITY_STRING) {
+        return -double.infinity;
+      }
+
+      if (!context_.escapeNum) {
+        // Throw exception -- we should not be in a string in this case
+        throw new TProtocolException("Numeric data unexpectedly quoted",
+          TProtocolException.Type.INVALID_DATA);
+      }
+      try {
+        return to!double(str);
+      } catch (ConvException e) {
+        throw new TProtocolException(`Expected numeric value; got "` ~ str ~
+          `".`, TProtocolException.Type.INVALID_DATA);
+      }
+    }
+    else {
+      if (context_.escapeNum) {
+        // This will throw - we should have had a quote if escapeNum == true
+        readJsonSyntaxChar(STRING_DELIMITER);
+      }
+
+      auto str = readJsonNumericChars();
+      try {
+        return to!double(str);
+      } catch (ConvException e) {
+        throw new TProtocolException(`Expected numeric value; got "` ~ str ~
+          `".`, TProtocolException.Type.INVALID_DATA);
+      }
+    }
+  }
+
+  string readString() {
+    return readJsonString(false);
+  }
+
+  ubyte[] readBinary() {
+    return Base64NoPad.decode(readString());
+  }
+
+  TMessage readMessageBegin() {
+    TMessage msg = void;
+
+    readJsonArrayBegin();
+
+    auto ver = readJsonInteger!short();
+    if (ver != THRIFT_JSON_VERSION) {
+      throw new TProtocolException("Message contained bad version.",
+        TProtocolException.Type.BAD_VERSION);
+    }
+
+    msg.name = readString();
+    msg.type = cast(TMessageType)readJsonInteger!byte();
+    msg.seqid = readJsonInteger!short();
+
+    return msg;
+  }
+
+  void readMessageEnd() {
+    readJsonArrayEnd();
+  }
+
+  TStruct readStructBegin() {
+    readJsonObjectBegin();
+    return TStruct();
+  }
+
+  void readStructEnd() {
+    readJsonObjectEnd();
+  }
+
+  TField readFieldBegin() {
+    TField f = void;
+    f.name = null;
+
+    auto ch = reader_.peek();
+    if (ch == OBJECT_END) {
+      f.type = TType.STOP;
+    } else {
+      f.id = readJsonInteger!short();
+      readJsonObjectBegin();
+      f.type = getTTypeFromName(readString());
+    }
+
+    return f;
+  }
+
+  void readFieldEnd() {
+    readJsonObjectEnd();
+  }
+
+  TList readListBegin() {
+    readJsonArrayBegin();
+    auto type = getTTypeFromName(readString());
+    auto size = readContainerSize();
+    return TList(type, size);
+  }
+
+  void readListEnd() {
+    readJsonArrayEnd();
+  }
+
+  TMap readMapBegin() {
+    readJsonArrayBegin();
+    auto keyType = getTTypeFromName(readString());
+    auto valueType = getTTypeFromName(readString());
+    auto size = readContainerSize();
+    readJsonObjectBegin();
+    return TMap(keyType, valueType, size);
+  }
+
+  void readMapEnd() {
+    readJsonObjectEnd();
+    readJsonArrayEnd();
+  }
+
+  TSet readSetBegin() {
+    readJsonArrayBegin();
+    auto type = getTTypeFromName(readString());
+    auto size = readContainerSize();
+    return TSet(type, size);
+  }
+
+  void readSetEnd() {
+    readJsonArrayEnd();
+  }
+
+private:
+  void pushContext(Context c) {
+    contextStack_ ~= context_;
+    context_ = c;
+  }
+
+  void popContext() {
+    context_ = contextStack_.back;
+    contextStack_.popBack();
+    contextStack_.assumeSafeAppend();
+  }
+
+  /*
+   * Writing functions
+   */
+
+  // Write the character ch as a Json escape sequence ("\u00xx")
+  void writeJsonEscapeChar(ubyte ch) {
+    trans_.write(ESCAPE_PREFIX);
+    trans_.write(ESCAPE_PREFIX);
+    auto outCh = hexChar(cast(ubyte)(ch >> 4));
+    trans_.write((&outCh)[0 .. 1]);
+    outCh = hexChar(ch);
+    trans_.write((&outCh)[0 .. 1]);
+  }
+
+  // Write the character ch as part of a Json string, escaping as appropriate.
+  void writeJsonChar(ubyte ch) {
+    if (ch >= 0x30) {
+      if (ch == '\\') { // Only special character >= 0x30 is '\'
+        trans_.write(BACKSLASH);
+        trans_.write(BACKSLASH);
+      } else {
+        trans_.write((&ch)[0 .. 1]);
+      }
+    }
+    else {
+      auto outCh = kJsonCharTable[ch];
+      // Check if regular character, backslash escaped, or Json escaped
+      if (outCh == 1) {
+        trans_.write((&ch)[0 .. 1]);
+      } else if (outCh > 1) {
+        trans_.write(BACKSLASH);
+        trans_.write((&outCh)[0 .. 1]);
+      } else {
+        writeJsonEscapeChar(ch);
+      }
+    }
+  }
+
+  // Convert the given integer type to a Json number, or a string
+  // if the context requires it (eg: key in a map pair).
+  void writeJsonInteger(T)(T num) if (isIntegral!T) {
+    context_.write(trans_);
+
+    auto escapeNum = context_.escapeNum();
+    if (escapeNum) trans_.write(STRING_DELIMITER);
+    trans_.write(cast(ubyte[])to!string(num));
+    if (escapeNum) trans_.write(STRING_DELIMITER);
+  }
+
+  void writeJsonObjectBegin() {
+    context_.write(trans_);
+    trans_.write(OBJECT_BEGIN);
+    pushContext(new PairContext());
+  }
+
+  void writeJsonObjectEnd() {
+    popContext();
+    trans_.write(OBJECT_END);
+  }
+
+  void writeJsonArrayBegin() {
+    context_.write(trans_);
+    trans_.write(ARRAY_BEGIN);
+    pushContext(new ListContext());
+  }
+
+  void writeJsonArrayEnd() {
+    popContext();
+    trans_.write(ARRAY_END);
+  }
+
+  /*
+   * Reading functions
+   */
+
+  int readContainerSize() {
+    auto size = readJsonInteger!int();
+    if (size < 0) {
+      throw new TProtocolException(TProtocolException.Type.NEGATIVE_SIZE);
+    } else if (containerSizeLimit > 0 && size > containerSizeLimit) {
+      throw new TProtocolException(TProtocolException.Type.SIZE_LIMIT);
+    }
+    return size;
+  }
+
+  void readJsonSyntaxChar(ubyte[1] ch) {
+    return readSyntaxChar(reader_, ch);
+  }
+
+  ubyte readJsonEscapeChar() {
+    readJsonSyntaxChar(ZERO_CHAR);
+    readJsonSyntaxChar(ZERO_CHAR);
+    auto a = reader_.read();
+    auto b = reader_.read();
+    return cast(ubyte)((hexVal(a[0]) << 4) + hexVal(b[0]));
+  }
+
+  string readJsonString(bool skipContext = false) {
+    if (!skipContext) context_.read(reader_);
+
+    readJsonSyntaxChar(STRING_DELIMITER);
+    auto buffer = appender!string();
+
+    int bytesRead;
+    while (true) {
+      auto ch = reader_.read();
+      if (ch == STRING_DELIMITER) {
+        break;
+      }
+
+      ++bytesRead;
+      if (stringSizeLimit > 0 && bytesRead > stringSizeLimit) {
+        throw new TProtocolException(TProtocolException.Type.SIZE_LIMIT);
+      }
+
+      if (ch == BACKSLASH) {
+        ch = reader_.read();
+        if (ch == ESCAPE_CHAR) {
+          ch = readJsonEscapeChar();
+        } else {
+          auto pos = countUntil(kEscapeChars[], ch[0]);
+          if (pos == -1) {
+            throw new TProtocolException("Expected control char, got '" ~
+              cast(char)ch[0] ~ "'.", TProtocolException.Type.INVALID_DATA);
+          }
+          ch = kEscapeCharVals[pos];
+        }
+      }
+      buffer.put(ch[0]);
+    }
+
+    return buffer.data;
+  }
+
+  // Reads a sequence of characters, stopping at the first one that is not
+  // a valid Json numeric character.
+  string readJsonNumericChars() {
+    string str;
+    while (true) {
+      auto ch = reader_.peek();
+      if (!isJsonNumeric(ch[0])) {
+        break;
+      }
+      reader_.read();
+      str ~= ch;
+    }
+    return str;
+  }
+
+  // Reads a sequence of characters and assembles them into a number,
+  // returning them via num
+  T readJsonInteger(T)() if (isIntegral!T) {
+    context_.read(reader_);
+    if (context_.escapeNum()) {
+      readJsonSyntaxChar(STRING_DELIMITER);
+    }
+    auto str = readJsonNumericChars();
+    T num;
+    try {
+      num = to!T(str);
+    } catch (ConvException e) {
+      throw new TProtocolException(`Expected numeric value, got "` ~ str ~ `".`,
+        TProtocolException.Type.INVALID_DATA);
+    }
+    if (context_.escapeNum()) {
+      readJsonSyntaxChar(STRING_DELIMITER);
+    }
+    return num;
+  }
+
+  void readJsonObjectBegin() {
+    context_.read(reader_);
+    readJsonSyntaxChar(OBJECT_BEGIN);
+    pushContext(new PairContext());
+  }
+
+  void readJsonObjectEnd() {
+    readJsonSyntaxChar(OBJECT_END);
+    popContext();
+  }
+
+  void readJsonArrayBegin() {
+    context_.read(reader_);
+    readJsonSyntaxChar(ARRAY_BEGIN);
+    pushContext(new ListContext());
+  }
+
+  void readJsonArrayEnd() {
+    readJsonSyntaxChar(ARRAY_END);
+    popContext();
+  }
+
+  static {
+    final class LookaheadReader {
+      this(Transport trans) {
+        trans_ = trans;
+      }
+
+      ubyte[1] read() {
+        if (hasData_) {
+          hasData_ = false;
+        } else {
+          trans_.readAll(data_);
+        }
+        return data_;
+      }
+
+      ubyte[1] peek() {
+        if (!hasData_) {
+          trans_.readAll(data_);
+          hasData_ = true;
+        }
+        return data_;
+      }
+
+     private:
+      Transport trans_;
+      bool hasData_;
+      ubyte[1] data_;
+    }
+
+    /*
+     * Class to serve as base Json context and as base class for other context
+     * implementations
+     */
+    class Context {
+      /**
+       * Write context data to the transport. Default is to do nothing.
+       */
+      void write(Transport trans) {}
+
+      /**
+       * Read context data from the transport. Default is to do nothing.
+       */
+      void read(LookaheadReader reader) {}
+
+      /**
+       * Return true if numbers need to be escaped as strings in this context.
+       * Default behavior is to return false.
+       */
+      bool escapeNum() @property {
+        return false;
+      }
+    }
+
+    // Context class for object member key-value pairs
+    class PairContext : Context {
+      this() {
+        first_ = true;
+        colon_ = true;
+      }
+
+      override void write(Transport trans) {
+        if (first_) {
+          first_ = false;
+          colon_ = true;
+        } else {
+          trans.write(colon_ ? PAIR_SEP : ELEM_SEP);
+          colon_ = !colon_;
+        }
+      }
+
+      override void read(LookaheadReader reader) {
+        if (first_) {
+          first_ = false;
+          colon_ = true;
+        } else {
+          auto ch = (colon_ ? PAIR_SEP : ELEM_SEP);
+          colon_ = !colon_;
+          return readSyntaxChar(reader, ch);
+        }
+      }
+
+      // Numbers must be turned into strings if they are the key part of a pair
+      override bool escapeNum() @property {
+        return colon_;
+      }
+
+    private:
+      bool first_;
+      bool colon_;
+    }
+
+    class ListContext : Context {
+      this() {
+        first_ = true;
+      }
+
+      override void write(Transport trans) {
+        if (first_) {
+          first_ = false;
+        } else {
+          trans.write(ELEM_SEP);
+        }
+      }
+
+      override void read(LookaheadReader reader) {
+        if (first_) {
+          first_ = false;
+        } else {
+          readSyntaxChar(reader, ELEM_SEP);
+        }
+      }
+
+    private:
+      bool first_;
+    }
+
+    // Read 1 character from the transport trans and verify that it is the
+    // expected character ch.
+    // Throw a protocol exception if it is not.
+    void readSyntaxChar(LookaheadReader reader, ubyte[1] ch) {
+      auto ch2 = reader.read();
+      if (ch2 != ch) {
+        throw new TProtocolException("Expected '" ~ cast(char)ch[0] ~ "', got '" ~
+          cast(char)ch2[0] ~ "'.", TProtocolException.Type.INVALID_DATA);
+      }
+    }
+  }
+
+  // Probably need to implement a better stack at some point.
+  Context[] contextStack_;
+  Context context_;
+
+  Transport trans_;
+  LookaheadReader reader_;
+}
+
+/**
+ * TJsonProtocol construction helper to avoid having to explicitly specify
+ * the transport type, i.e. to allow the constructor being called using IFTI
+ * (see $(LINK2 http://d.puremagic.com/issues/show_bug.cgi?id=6082, D Bugzilla
+ * enhancement requet 6082)).
+ */
+TJsonProtocol!Transport tJsonProtocol(Transport)(Transport trans,
+  int containerSizeLimit = 0, int stringSizeLimit = 0
+) if (isTTransport!Transport) {
+  return new TJsonProtocol!Transport(trans, containerSizeLimit, stringSizeLimit);
+}
+
+unittest {
+  import std.exception;
+  import thrift.transport.memory;
+
+  // Check the message header format.
+  auto buf = new TMemoryBuffer;
+  auto json = tJsonProtocol(buf);
+  json.writeMessageBegin(TMessage("foo", TMessageType.CALL, 0));
+  json.writeMessageEnd();
+
+  auto header = new ubyte[13];
+  buf.readAll(header);
+  enforce(cast(char[])header == `[1,"foo",1,0]`);
+}
+
+unittest {
+  import std.exception;
+  import thrift.transport.memory;
+
+  // Check that short binary data is read correctly (the Thrift JSON format
+  // does not include padding chars in the Base64 encoded data).
+  auto buf = new TMemoryBuffer;
+  auto json = tJsonProtocol(buf);
+  json.writeBinary([1, 2]);
+  json.reset();
+  enforce(json.readBinary() == [1, 2]);
+}
+
+unittest {
+  import thrift.internal.test.protocol;
+  testContainerSizeLimit!(TJsonProtocol!())();
+  testStringSizeLimit!(TJsonProtocol!())();
+}
+
+/**
+ * TProtocolFactory creating a TJsonProtocol instance for passed in
+ * transports.
+ *
+ * The optional Transports template tuple parameter can be used to specify
+ * one or more TTransport implementations to specifically instantiate
+ * TJsonProtocol for. If the actual transport types encountered at
+ * runtime match one of the transports in the list, a specialized protocol
+ * instance is created. Otherwise, a generic TTransport version is used.
+ */
+class TJsonProtocolFactory(Transports...) if (
+  allSatisfy!(isTTransport, Transports)
+) : TProtocolFactory {
+  TProtocol getProtocol(TTransport trans) const {
+    foreach (Transport; TypeTuple!(Transports, TTransport)) {
+      auto concreteTrans = cast(Transport)trans;
+      if (concreteTrans) {
+        auto p = new TJsonProtocol!Transport(concreteTrans);
+        return p;
+      }
+    }
+    throw new TProtocolException(
+      "Passed null transport to TJsonProtocolFactoy.");
+  }
+}
+
+private {
+  immutable ubyte[1] OBJECT_BEGIN = '{';
+  immutable ubyte[1] OBJECT_END = '}';
+  immutable ubyte[1] ARRAY_BEGIN = '[';
+  immutable ubyte[1] ARRAY_END = ']';
+  immutable ubyte[1] NEWLINE = '\n';
+  immutable ubyte[1] PAIR_SEP = ':';
+  immutable ubyte[1] ELEM_SEP = ',';
+  immutable ubyte[1] BACKSLASH = '\\';
+  immutable ubyte[1] STRING_DELIMITER = '"';
+  immutable ubyte[1] ZERO_CHAR = '0';
+  immutable ubyte[1] ESCAPE_CHAR = 'u';
+  immutable ubyte[4] ESCAPE_PREFIX = cast(ubyte[4])r"\u00";
+
+  enum THRIFT_JSON_VERSION = 1;
+
+  immutable NAN_STRING = "NaN";
+  immutable INFINITY_STRING = "Infinity";
+  immutable NEG_INFINITY_STRING = "-Infinity";
+
+  string getNameFromTType(TType typeID) {
+    final switch (typeID) {
+      case TType.BOOL:
+        return "tf";
+      case TType.BYTE:
+        return "i8";
+      case TType.I16:
+        return "i16";
+      case TType.I32:
+        return "i32";
+      case TType.I64:
+        return "i64";
+      case TType.DOUBLE:
+        return "dbl";
+      case TType.STRING:
+        return "str";
+      case TType.STRUCT:
+        return "rec";
+      case TType.MAP:
+        return "map";
+      case TType.LIST:
+        return "lst";
+      case TType.SET:
+        return "set";
+    }
+  }
+
+  TType getTTypeFromName(string name) {
+    TType result;
+    if (name.length > 1) {
+      switch (name[0]) {
+        case 'd':
+          result = TType.DOUBLE;
+          break;
+        case 'i':
+          switch (name[1]) {
+            case '8':
+              result = TType.BYTE;
+              break;
+            case '1':
+              result = TType.I16;
+              break;
+            case '3':
+              result = TType.I32;
+              break;
+            case '6':
+              result = TType.I64;
+              break;
+            default:
+              // Do nothing.
+          }
+          break;
+        case 'l':
+          result = TType.LIST;
+          break;
+        case 'm':
+          result = TType.MAP;
+          break;
+        case 'r':
+          result = TType.STRUCT;
+          break;
+        case 's':
+          if (name[1] == 't') {
+            result = TType.STRING;
+          }
+          else if (name[1] == 'e') {
+            result = TType.SET;
+          }
+          break;
+        case 't':
+          result = TType.BOOL;
+          break;
+        default:
+          // Do nothing.
+      }
+    }
+    if (result == TType.STOP) {
+      throw new TProtocolException("Unrecognized type",
+        TProtocolException.Type.NOT_IMPLEMENTED);
+    }
+    return result;
+  }
+
+  // This table describes the handling for the first 0x30 characters
+  //  0 : escape using "\u00xx" notation
+  //  1 : just output index
+  // <other> : escape using "\<other>" notation
+  immutable ubyte[0x30] kJsonCharTable = [
+  //  0   1   2   3   4   5   6   7   8   9   A   B   C   D   E   F
+      0,  0,  0,  0,  0,  0,  0,  0,'b','t','n',  0,'f','r',  0,  0, // 0
+      0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, // 1
+      1,  1,'"',  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1, // 2
+  ];
+
+  // This string's characters must match up with the elements in kEscapeCharVals.
+  // I don't have '/' on this list even though it appears on www.json.org --
+  // it is not in the RFC
+  immutable kEscapeChars = cast(ubyte[7]) `"\\bfnrt`;
+
+  // The elements of this array must match up with the sequence of characters in
+  // kEscapeChars
+  immutable ubyte[7] kEscapeCharVals = [
+    '"', '\\', '\b', '\f', '\n', '\r', '\t',
+  ];
+
+  // Return the integer value of a hex character ch.
+  // Throw a protocol exception if the character is not [0-9a-f].
+  ubyte hexVal(ubyte ch) {
+    if ((ch >= '0') && (ch <= '9')) {
+      return cast(ubyte)(ch - '0');
+    } else if ((ch >= 'a') && (ch <= 'f')) {
+      return cast(ubyte)(ch - 'a' + 10);
+    }
+    else {
+      throw new TProtocolException("Expected hex val ([0-9a-f]), got '" ~
+        ch ~ "'.", TProtocolException.Type.INVALID_DATA);
+    }
+  }
+
+  // Return the hex character representing the integer val. The value is masked
+  // to make sure it is in the correct range.
+  ubyte hexChar(ubyte val) {
+    val &= 0x0F;
+    if (val < 10) {
+      return cast(ubyte)(val + '0');
+    } else {
+      return cast(ubyte)(val - 10 + 'a');
+    }
+  }
+
+  // Return true if the character ch is in [-+0-9.Ee]; false otherwise
+  bool isJsonNumeric(ubyte ch) {
+    switch (ch) {
+      case '+':
+      case '-':
+      case '.':
+      case '0':
+      case '1':
+      case '2':
+      case '3':
+      case '4':
+      case '5':
+      case '6':
+      case '7':
+      case '8':
+      case '9':
+      case 'E':
+      case 'e':
+        return true;
+      default:
+        return false;
+    }
+  }
+}
diff --git a/lib/d/src/thrift/protocol/processor.d b/lib/d/src/thrift/protocol/processor.d
new file mode 100644
index 0000000..887421c
--- /dev/null
+++ b/lib/d/src/thrift/protocol/processor.d
@@ -0,0 +1,145 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+module thrift.protocol.processor;
+
+// Use selective import once DMD @@BUG314@@ is fixed.
+import std.variant /+ : Variant +/;
+import thrift.protocol.base;
+import thrift.transport.base;
+
+/**
+ * A processor is a generic object which operates upon an input stream and
+ * writes to some output stream.
+ *
+ * The definition of this object is loose, though the typical case is for some
+ * sort of server that either generates responses to an input stream or
+ * forwards data from one pipe onto another.
+ *
+ * An implementation can optionally allow one or more TProcessorEventHandlers
+ * to be attached, providing an interface to hook custom code into the
+ * handling process, which can be used e.g. for gathering statistics.
+ */
+interface TProcessor {
+  ///
+  bool process(TProtocol iprot, TProtocol oprot,
+    Variant connectionContext = Variant()
+  ) in {
+    assert(iprot);
+    assert(oprot);
+  }
+
+  ///
+  final bool process(TProtocol prot, Variant connectionContext = Variant()) {
+    return process(prot, prot, connectionContext);
+  }
+}
+
+/**
+ * Handles events from a processor.
+ */
+interface TProcessorEventHandler {
+  /**
+   * Called before calling other callback methods.
+   *
+   * Expected to return some sort of »call context«, which is passed to all
+   * other callbacks for that function invocation.
+   */
+  Variant createContext(string methodName, Variant connectionContext);
+
+  /**
+   * Called when handling the method associated with a context has been
+   * finished – can be used to perform clean up work.
+   */
+  void deleteContext(Variant callContext, string methodName);
+
+  /**
+   * Called before reading arguments.
+   */
+  void preRead(Variant callContext, string methodName);
+
+  /**
+   * Called between reading arguments and calling the handler.
+   */
+  void postRead(Variant callContext, string methodName);
+
+  /**
+   * Called between calling the handler and writing the response.
+   */
+  void preWrite(Variant callContext, string methodName);
+
+  /**
+   * Called after writing the response.
+   */
+  void postWrite(Variant callContext, string methodName);
+
+  /**
+   * Called when handling a one-way function call is completed successfully.
+   */
+  void onewayComplete(Variant callContext, string methodName);
+
+  /**
+   * Called if the handler throws an undeclared exception.
+   */
+  void handlerError(Variant callContext, string methodName, Exception e);
+}
+
+struct TConnectionInfo {
+  /// The input and output protocols.
+  TProtocol input;
+  TProtocol output; /// Ditto.
+
+  /// The underlying transport used for the connection
+  /// This is the transport that was returned by TServerTransport.accept(),
+  /// and it may be different than the transport pointed to by the input and
+  /// output protocols.
+  TTransport transport;
+}
+
+interface TProcessorFactory {
+  /**
+   * Get the TProcessor to use for a particular connection.
+   *
+   * This method is always invoked in the same thread that the connection was
+   * accepted on, which is always the same thread for all current server
+   * implementations.
+   */
+  TProcessor getProcessor(ref const(TConnectionInfo) connInfo);
+}
+
+/**
+ * The default processor factory which always returns the same instance.
+ */
+class TSingletonProcessorFactory : TProcessorFactory {
+  /**
+   * Creates a new instance.
+   *
+   * Params:
+   *   processor = The processor object to return from getProcessor().
+   */
+  this(TProcessor processor) {
+    processor_ = processor;
+  }
+
+  override TProcessor getProcessor(ref const(TConnectionInfo) connInfo) {
+    return processor_;
+  }
+
+private:
+  TProcessor processor_;
+}
diff --git a/lib/d/src/thrift/server/base.d b/lib/d/src/thrift/server/base.d
new file mode 100644
index 0000000..b56ae66
--- /dev/null
+++ b/lib/d/src/thrift/server/base.d
@@ -0,0 +1,147 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+module thrift.server.base;
+
+import std.variant : Variant;
+import thrift.protocol.base;
+import thrift.protocol.binary;
+import thrift.protocol.processor;
+import thrift.server.transport.base;
+import thrift.transport.base;
+import thrift.util.cancellation;
+
+/**
+ * Base class for all Thrift servers.
+ *
+ * By setting the eventHandler property to a TServerEventHandler
+ * implementation, custom code can be integrated into the processing pipeline,
+ * which can be used e.g. for gathering statistics.
+ */
+class TServer {
+  /**
+   * Starts serving.
+   *
+   * Blocks until the server finishes, i.e. a serious problem occured or the
+   * cancellation request has been triggered.
+   *
+   * Server implementations are expected to implement cancellation in a best-
+   * effort way – usually, it should be possible to immediately stop accepting
+   * connections and return after all currently active clients have been
+   * processed, but this might not be the case for every conceivable
+   * implementation.
+   */
+  abstract void serve(TCancellation cancellation = null);
+
+  /// The server event handler to notify. Null by default.
+  TServerEventHandler eventHandler;
+
+protected:
+  this(
+    TProcessor processor,
+    TServerTransport serverTransport,
+    TTransportFactory transportFactory,
+    TProtocolFactory protocolFactory
+  ) {
+    this(processor, serverTransport, transportFactory, transportFactory,
+      protocolFactory, protocolFactory);
+  }
+
+  this(
+    TProcessorFactory processorFactory,
+    TServerTransport serverTransport,
+    TTransportFactory transportFactory,
+    TProtocolFactory protocolFactory
+  ) {
+    this(processorFactory, serverTransport, transportFactory, transportFactory,
+      protocolFactory, protocolFactory);
+  }
+
+  this(
+    TProcessor processor,
+    TServerTransport serverTransport,
+    TTransportFactory inputTransportFactory,
+    TTransportFactory outputTransportFactory,
+    TProtocolFactory inputProtocolFactory,
+    TProtocolFactory outputProtocolFactory
+  ) {
+    this(new TSingletonProcessorFactory(processor), serverTransport,
+      inputTransportFactory, outputTransportFactory,
+      inputProtocolFactory, outputProtocolFactory);
+  }
+
+  this(
+    TProcessorFactory processorFactory,
+    TServerTransport serverTransport,
+    TTransportFactory inputTransportFactory,
+    TTransportFactory outputTransportFactory,
+    TProtocolFactory inputProtocolFactory,
+    TProtocolFactory outputProtocolFactory
+  ) {
+    import std.exception;
+    import thrift.base;
+    enforce(inputTransportFactory,
+      new TException("Input transport factory must not be null."));
+    enforce(outputTransportFactory,
+      new TException("Output transport factory must not be null."));
+    enforce(inputProtocolFactory,
+      new TException("Input protocol factory must not be null."));
+    enforce(outputProtocolFactory,
+      new TException("Output protocol factory must not be null."));
+
+    processorFactory_ = processorFactory;
+    serverTransport_ = serverTransport;
+    inputTransportFactory_ = inputTransportFactory;
+    outputTransportFactory_ = outputTransportFactory;
+    inputProtocolFactory_ = inputProtocolFactory;
+    outputProtocolFactory_ = outputProtocolFactory;
+  }
+
+  TProcessorFactory processorFactory_;
+  TServerTransport serverTransport_;
+  TTransportFactory inputTransportFactory_;
+  TTransportFactory outputTransportFactory_;
+  TProtocolFactory inputProtocolFactory_;
+  TProtocolFactory outputProtocolFactory_;
+}
+
+/**
+ * Handles events from a TServer core.
+ */
+interface TServerEventHandler {
+  /**
+   * Called before the server starts accepting connections.
+   */
+  void preServe();
+
+  /**
+   * Called when a new client has connected and processing is about to begin.
+   */
+  Variant createContext(TProtocol input, TProtocol output);
+
+  /**
+   * Called when request handling for a client has been finished – can be used
+   * to perform clean up work.
+   */
+  void deleteContext(Variant serverContext, TProtocol input, TProtocol output);
+
+  /**
+   * Called when the processor for a client call is about to be invoked.
+   */
+  void preProcess(Variant serverContext, TTransport transport);
+}
diff --git a/lib/d/src/thrift/server/nonblocking.d b/lib/d/src/thrift/server/nonblocking.d
new file mode 100644
index 0000000..0216799
--- /dev/null
+++ b/lib/d/src/thrift/server/nonblocking.d
@@ -0,0 +1,1397 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/**
+ * A non-blocking server implementation that operates a set of I/O threads (by
+ * default only one) and either does processing »in-line« or off-loads it to a
+ * task pool.
+ *
+ * It *requires* TFramedTransport to be used on the client side, as it expects
+ * a 4 byte length indicator and writes out responses using the same framing.
+ *
+ * Because I/O is done asynchronous/event based, unfortunately
+ * TServerTransport can't be used.
+ *
+ * This implementation is based on the C++ one, with the exception of request
+ * timeouts and the drain task queue overload handling strategy not being
+ * implemented yet.
+ */
+// This really should use a D non-blocking I/O library, once one becomes
+// available.
+module thrift.server.nonblocking;
+
+import core.atomic : atomicLoad, atomicStore, atomicOp;
+import core.exception : onOutOfMemoryError;
+import core.memory : GC;
+import core.sync.mutex;
+import core.stdc.stdlib : free, realloc;
+import core.time : Duration, dur;
+import core.thread : Thread, ThreadGroup;
+import deimos.event2.event;
+import std.array : empty;
+import std.conv : emplace, to;
+import std.exception : enforce;
+import std.parallelism : TaskPool, task;
+import std.socket : Socket, socketPair, SocketAcceptException,
+  SocketException, TcpSocket;
+import std.variant : Variant;
+import thrift.base;
+import thrift.internal.endian;
+import thrift.internal.socket;
+import thrift.internal.traits;
+import thrift.protocol.base;
+import thrift.protocol.binary;
+import thrift.protocol.processor;
+import thrift.server.base;
+import thrift.server.transport.socket;
+import thrift.transport.base;
+import thrift.transport.memory;
+import thrift.transport.range;
+import thrift.transport.socket;
+import thrift.util.cancellation;
+
+/**
+ * Possible actions taken on new incoming connections when the server is
+ * overloaded.
+ */
+enum TOverloadAction {
+  /// Do not take any special actions while the server is overloaded, just
+  /// continue accepting connections.
+  NONE,
+
+  /// Immediately drop new connections after they have been accepted if the
+  /// server is overloaded.
+  CLOSE_ON_ACCEPT
+}
+
+///
+class TNonblockingServer : TServer {
+  ///
+  this(TProcessor processor, ushort port, TTransportFactory transportFactory,
+    TProtocolFactory protocolFactory, TaskPool taskPool = null
+  ) {
+    this(new TSingletonProcessorFactory(processor), port, transportFactory,
+      transportFactory, protocolFactory, protocolFactory, taskPool);
+  }
+
+  ///
+  this(TProcessorFactory processorFactory, ushort port,
+    TTransportFactory transportFactory, TProtocolFactory protocolFactory,
+    TaskPool taskPool = null
+  ) {
+    this(processorFactory, port, transportFactory, transportFactory,
+      protocolFactory, protocolFactory, taskPool);
+  }
+
+  ///
+  this(
+    TProcessor processor,
+    ushort port,
+    TTransportFactory inputTransportFactory,
+    TTransportFactory outputTransportFactory,
+    TProtocolFactory inputProtocolFactory,
+    TProtocolFactory outputProtocolFactory,
+    TaskPool taskPool = null
+  ) {
+    this(new TSingletonProcessorFactory(processor), port,
+      inputTransportFactory, outputTransportFactory,
+      inputProtocolFactory, outputProtocolFactory, taskPool);
+  }
+
+  ///
+  this(
+    TProcessorFactory processorFactory,
+    ushort port,
+    TTransportFactory inputTransportFactory,
+    TTransportFactory outputTransportFactory,
+    TProtocolFactory inputProtocolFactory,
+    TProtocolFactory outputProtocolFactory,
+    TaskPool taskPool = null
+  ) {
+    super(processorFactory, null, inputTransportFactory,
+      outputTransportFactory, inputProtocolFactory, outputProtocolFactory);
+    port_ = port;
+
+    this.taskPool = taskPool;
+
+    connectionMutex_ = new Mutex;
+
+    connectionStackLimit = DEFAULT_CONNECTION_STACK_LIMIT;
+    maxActiveProcessors = DEFAULT_MAX_ACTIVE_PROCESSORS;
+    maxConnections = DEFAULT_MAX_CONNECTIONS;
+    overloadHysteresis = DEFAULT_OVERLOAD_HYSTERESIS;
+    overloadAction = DEFAULT_OVERLOAD_ACTION;
+    writeBufferDefaultSize = DEFAULT_WRITE_BUFFER_DEFAULT_SIZE;
+    idleReadBufferLimit = DEFAULT_IDLE_READ_BUFFER_LIMIT;
+    idleWriteBufferLimit = DEFAULT_IDLE_WRITE_BUFFER_LIMIT;
+    resizeBufferEveryN = DEFAULT_RESIZE_BUFFER_EVERY_N;
+    maxFrameSize = DEFAULT_MAX_FRAME_SIZE;
+    numIOThreads_ = DEFAULT_NUM_IO_THREADS;
+  }
+
+  override void serve(TCancellation cancellation = null) {
+    if (cancellation && cancellation.triggered) return;
+
+    // Initialize the listening socket.
+    // TODO: SO_KEEPALIVE, TCP_LOW_MIN_RTO, etc.
+    listenSocket_ = makeSocketAndListen(port_, TServerSocket.ACCEPT_BACKLOG,
+      BIND_RETRY_LIMIT, BIND_RETRY_DELAY, 0, 0, ipv6Only_);
+    listenSocket_.blocking = false;
+
+    logInfo("Using %s I/O thread(s).", numIOThreads_);
+    if (taskPool_) {
+      logInfo("Using task pool with size: %s.", numIOThreads_, taskPool_.size);
+    }
+
+    assert(numIOThreads_ > 0);
+    assert(ioLoops_.empty);
+    foreach (id; 0 .. numIOThreads_) {
+      // The IO loop on the first IO thread (this thread, i.e. the one serve()
+      // is called from) also accepts new connections.
+      auto listenSocket = (id == 0 ? listenSocket_ : null);
+      ioLoops_ ~= new IOLoop(this, listenSocket);
+    }
+
+    if (cancellation) {
+      cancellation.triggering.addCallback({
+        foreach (i, loop; ioLoops_) loop.stop();
+
+        // Stop accepting new connections right away.
+        listenSocket_.close();
+        listenSocket_ = null;
+      });
+    }
+
+    // Start the IO helper threads for all but the first loop, which we will run
+    // ourselves. Note that the threads run forever, only terminating if stop()
+    // is called.
+    auto threads = new ThreadGroup();
+    foreach (loop; ioLoops_[1 .. $]) {
+      auto t = new Thread(&loop.run);
+      threads.add(t);
+      t.start();
+    }
+
+    if (eventHandler) eventHandler.preServe();
+
+    // Run the primary (listener) IO thread loop in our main thread; this will
+    // block until the server is shutting down.
+    ioLoops_[0].run();
+
+    // Ensure all threads are finished before leaving serve().
+    threads.joinAll();
+
+    ioLoops_ = null;
+  }
+
+  /**
+   * Returns the number of currently active connections, i.e. open sockets.
+   */
+  size_t numConnections() const @property {
+    return numConnections_;
+  }
+
+  /**
+   * Returns the number of connection objects allocated, but not in use.
+   */
+  size_t numIdleConnections() const @property {
+    return connectionStack_.length;
+  }
+
+  /**
+   * Return count of number of connections which are currently processing.
+   *
+   * This is defined as a connection where all data has been received, and the
+   * processor was invoked but has not yet completed.
+   */
+  size_t numActiveProcessors() const @property {
+    return numActiveProcessors_;
+  }
+
+  /// Number of bind() retries.
+  enum BIND_RETRY_LIMIT = 0;
+
+  /// Duration between bind() retries.
+  enum BIND_RETRY_DELAY = dur!"hnsecs"(0);
+
+  /// Whether to listen on IPv6 only, if IPv6 support is detected
+  // (default: false).
+  void ipv6Only(bool value) @property {
+    ipv6Only_ = value;
+  }
+
+  /**
+   * The task pool to use for processing requests. If null, no additional
+   * threads are used and request are processed »inline«.
+   *
+   * Can safely be set even when the server is already running.
+   */
+  TaskPool taskPool() @property {
+    return taskPool_;
+  }
+
+  /// ditto
+  void taskPool(TaskPool pool) @property {
+    taskPool_ = pool;
+  }
+
+  /**
+   * Hysteresis for overload state.
+   *
+   * This is the fraction of the overload value that needs to be reached
+   * before the overload state is cleared. It must be between 0 and 1,
+   * practical choices probably lie between 0.5 and 0.9.
+   */
+  double overloadHysteresis() const @property {
+    return overloadHysteresis_;
+  }
+
+  /// Ditto
+  void overloadHysteresis(double value) @property {
+    enforce(0 < value && value <= 1,
+      "Invalid value for overload hysteresis: " ~ to!string(value));
+    overloadHysteresis_ = value;
+  }
+
+  /// Ditto
+  enum DEFAULT_OVERLOAD_HYSTERESIS = 0.8;
+
+  /**
+   * The action which will be taken on overload.
+   */
+  TOverloadAction overloadAction;
+
+  /// Ditto
+  enum DEFAULT_OVERLOAD_ACTION = TOverloadAction.NONE;
+
+  /**
+   * The write buffer is initialized (and when idleWriteBufferLimit_ is checked
+   * and found to be exceeded, reinitialized) to this size.
+   */
+  size_t writeBufferDefaultSize;
+
+  /// Ditto
+  enum size_t DEFAULT_WRITE_BUFFER_DEFAULT_SIZE = 1024;
+
+  /**
+   * Max read buffer size for an idle Connection. When we place an idle
+   * Connection into connectionStack_ or on every resizeBufferEveryN_ calls,
+   * we will free the buffer (such that it will be reinitialized by the next
+   * received frame) if it has exceeded this limit. 0 disables this check.
+   */
+  size_t idleReadBufferLimit;
+
+  /// Ditto
+  enum size_t DEFAULT_IDLE_READ_BUFFER_LIMIT = 1024;
+
+  /**
+   * Max write buffer size for an idle connection.  When we place an idle
+   * Connection into connectionStack_ or on every resizeBufferEveryN_ calls,
+   * we ensure that its write buffer is <= to this size; otherwise we
+   * replace it with a new one of writeBufferDefaultSize_ bytes to ensure that
+   * idle connections don't hog memory. 0 disables this check.
+   */
+  size_t idleWriteBufferLimit;
+
+  /// Ditto
+  enum size_t DEFAULT_IDLE_WRITE_BUFFER_LIMIT = 1024;
+
+  /**
+   * Every N calls we check the buffer size limits on a connected Connection.
+   * 0 disables (i.e. the checks are only done when a connection closes).
+   */
+  uint resizeBufferEveryN;
+
+  /// Ditto
+  enum uint DEFAULT_RESIZE_BUFFER_EVERY_N = 512;
+
+  /// Limit for how many Connection objects to cache.
+  size_t connectionStackLimit;
+
+  /// Ditto
+  enum size_t DEFAULT_CONNECTION_STACK_LIMIT = 1024;
+
+  /// Limit for number of open connections before server goes into overload
+  /// state.
+  size_t maxConnections;
+
+  /// Ditto
+  enum size_t DEFAULT_MAX_CONNECTIONS = int.max;
+
+  /// Limit for number of connections processing or waiting to process
+  size_t maxActiveProcessors;
+
+  /// Ditto
+  enum size_t DEFAULT_MAX_ACTIVE_PROCESSORS = int.max;
+
+  /// Maximum frame size, in bytes.
+  ///
+  /// If a client tries to send a message larger than this limit, its
+  /// connection will be closed. This helps to avoid allocating huge buffers
+  /// on bogous input.
+  uint maxFrameSize;
+
+  /// Ditto
+  enum uint DEFAULT_MAX_FRAME_SIZE = 256 * 1024 * 1024;
+
+
+  size_t numIOThreads() @property {
+    return numIOThreads_;
+  }
+
+  void numIOThreads(size_t value) @property {
+    enforce(value >= 1, new TException("Must use at least one I/O thread."));
+    numIOThreads_ = value;
+  }
+
+  enum DEFAULT_NUM_IO_THREADS = 1;
+
+private:
+  /**
+   * C callback wrapper around acceptConnections(). Expects the custom argument
+   * to be the this pointer of the associated server instance.
+   */
+  extern(C) static void acceptConnectionsCallback(int fd, short which,
+    void* serverThis
+  ) {
+    (cast(TNonblockingServer)serverThis).acceptConnections(fd, which);
+  }
+
+  /**
+   * Called by libevent (IO loop 0/serve() thread only) when something
+   * happened on the listening socket.
+   */
+  void acceptConnections(int fd, short eventFlags) {
+    if (atomicLoad(ioLoops_[0].shuttingDown_)) return;
+
+    assert(!!listenSocket_,
+      "Server should be shutting down if listen socket is null.");
+    assert(fd == listenSocket_.handle);
+    assert(eventFlags & EV_READ);
+
+    // Accept as many new clients as possible, even though libevent signaled
+    // only one. This helps the number of calls into libevent space.
+    while (true) {
+      // It is lame to use exceptions for regular control flow (failing is
+      // excepted due to non-blocking mode of operation), but that's the
+      // interface std.socket offers…
+      Socket clientSocket;
+      try {
+        clientSocket = listenSocket_.accept();
+      } catch (SocketAcceptException e) {
+        if (e.errorCode != WOULD_BLOCK_ERRNO) {
+          logError("Error accepting connection: %s", e);
+        }
+        break;
+      }
+
+      // If the server is overloaded, this is the point to take the specified
+      // action.
+      if (overloadAction != TOverloadAction.NONE && checkOverloaded()) {
+        nConnectionsDropped_++;
+        nTotalConnectionsDropped_++;
+        if (overloadAction == TOverloadAction.CLOSE_ON_ACCEPT) {
+          clientSocket.close();
+          return;
+        }
+      }
+
+      try {
+        clientSocket.blocking = false;
+      } catch (SocketException e) {
+        logError("Couldn't set client socket to non-blocking mode: %s", e);
+        clientSocket.close();
+        return;
+      }
+
+      // Create a new Connection for this client socket.
+      Connection conn = void;
+      IOLoop loop = void;
+      bool thisThread = void;
+      synchronized (connectionMutex_) {
+        // Assign an I/O loop to the connection (round-robin).
+        assert(nextIOLoop_ >= 0);
+        assert(nextIOLoop_ < ioLoops_.length);
+        auto selectedThreadIdx = nextIOLoop_;
+        nextIOLoop_ = (nextIOLoop_ + 1) % ioLoops_.length;
+
+        loop = ioLoops_[selectedThreadIdx];
+        thisThread = (selectedThreadIdx == 0);
+
+        // Check the connection stack to see if we can re-use an existing one.
+        if (connectionStack_.empty) {
+          ++numConnections_;
+          conn = new Connection(clientSocket, loop);
+
+          // Make sure the connection does not get collected while it is active,
+          // i.e. hooked up with libevent.
+          GC.addRoot(cast(void*)conn);
+        } else {
+          conn = connectionStack_[$ - 1];
+          connectionStack_ = connectionStack_[0 .. $ - 1];
+          connectionStack_.assumeSafeAppend();
+          conn.init(clientSocket, loop);
+        }
+      }
+
+      loop.addConnection();
+
+      // Either notify the ioThread that is assigned this connection to
+      // start processing, or if it is us, we'll just ask this
+      // connection to do its initial state change here.
+      //
+      // (We need to avoid writing to our own notification pipe, to
+      // avoid possible deadlocks if the pipe is full.)
+      if (thisThread) {
+        conn.transition();
+      } else {
+        loop.notifyCompleted(conn);
+      }
+    }
+  }
+
+  /// Increment the count of connections currently processing.
+  void incrementActiveProcessors() {
+    atomicOp!"+="(numActiveProcessors_, 1);
+  }
+
+  /// Decrement the count of connections currently processing.
+  void decrementActiveProcessors() {
+    assert(numActiveProcessors_ > 0);
+    atomicOp!"-="(numActiveProcessors_, 1);
+  }
+
+  /**
+   * Determines if the server is currently overloaded.
+   *
+   * If the number of open connections or »processing« connections is over the
+   * respective limit, the server will enter overload handling mode and a
+   * warning will be logged. If below values are below the hysteresis curve,
+   * this will cause the server to exit it again.
+   *
+   * Returns: Whether the server is currently overloaded.
+   */
+  bool checkOverloaded() {
+    auto activeConnections = numConnections_ - connectionStack_.length;
+    if (numActiveProcessors_ > maxActiveProcessors ||
+        activeConnections > maxConnections) {
+      if (!overloaded_) {
+        logInfo("Entering overloaded state.");
+        overloaded_ = true;
+      }
+    } else {
+      if (overloaded_ &&
+        (numActiveProcessors_ <= overloadHysteresis_ * maxActiveProcessors) &&
+        (activeConnections <= overloadHysteresis_ * maxConnections))
+      {
+        logInfo("Exiting overloaded state, %s connection(s) dropped (% total).",
+          nConnectionsDropped_, nTotalConnectionsDropped_);
+        nConnectionsDropped_ = 0;
+        overloaded_ = false;
+      }
+    }
+
+    return overloaded_;
+  }
+
+  /**
+   * Marks a connection as inactive and either puts it back into the
+   * connection pool or leaves it for garbage collection.
+   */
+  void disposeConnection(Connection connection) {
+    synchronized (connectionMutex_) {
+      if (!connectionStackLimit ||
+        (connectionStack_.length < connectionStackLimit))
+      {
+        connection.checkIdleBufferLimit(idleReadBufferLimit,
+          idleWriteBufferLimit);
+        connectionStack_ ~= connection;
+      } else {
+        assert(numConnections_ > 0);
+        --numConnections_;
+
+        // Leave the connection object for collection now.
+        GC.removeRoot(cast(void*)connection);
+      }
+    }
+  }
+
+  /// Socket used to listen for connections and accepting them.
+  Socket listenSocket_;
+
+  /// Port to listen on.
+  ushort port_;
+
+  /// Whether to listen on IPv6 only.
+  bool ipv6Only_;
+
+  /// The total number of connections existing, both active and idle.
+  size_t numConnections_;
+
+  /// The number of connections which are currently waiting for the processor
+  /// to return.
+  shared size_t numActiveProcessors_;
+
+  /// Hysteresis for leaving overload state.
+  double overloadHysteresis_;
+
+  /// Whether the server is currently overloaded.
+  bool overloaded_;
+
+  /// Number of connections dropped since the server entered the current
+  /// overloaded state.
+  uint nConnectionsDropped_;
+
+  /// Number of connections dropped due to overload since the server started.
+  ulong nTotalConnectionsDropped_;
+
+  /// The task pool used for processing requests.
+  TaskPool taskPool_;
+
+  /// Number of IO threads this server will use (>= 1).
+  size_t numIOThreads_;
+
+  /// The IOLoops among which socket handling work is distributed.
+  IOLoop[] ioLoops_;
+
+  /// The index of the loop in ioLoops_ which will handle the next accepted
+  /// connection.
+  size_t nextIOLoop_;
+
+  /// All the connection objects which have been created but are not currently
+  /// in use. When a connection is closed, it it placed here to enable object
+  /// (resp. buffer) reuse.
+  Connection[] connectionStack_;
+
+  /// This mutex protects the connection stack.
+  Mutex connectionMutex_;
+}
+
+private {
+  /*
+   * Encapsulates a libevent event loop.
+   *
+   * The design is a bit of a mess, since the first loop is actually run on the
+   * server thread itself and is special because it is the only instance for
+   * which listenSocket_ is not null.
+   */
+  final class IOLoop {
+    /**
+     * Creates a new instance and set up the event base.
+     *
+     * If listenSocket is not null, the thread will also accept new
+     * connections itself.
+     */
+    this(TNonblockingServer server, Socket listenSocket) {
+      server_ = server;
+      listenSocket_ = listenSocket;
+      initMutex_ = new Mutex;
+    }
+
+    /**
+     * Runs the event loop; only returns after a call to stop().
+     */
+    void run() {
+      assert(!atomicLoad(initialized_), "IOLoop already running?!");
+
+      synchronized (initMutex_) {
+        if (atomicLoad(shuttingDown_)) return;
+        atomicStore(initialized_, true);
+
+        assert(!eventBase_);
+        eventBase_ = event_base_new();
+
+        if (listenSocket_) {
+          // Log the libevent version and backend.
+          logInfo("libevent version %s, using method %s.",
+            to!string(event_get_version()), to!string(event_base_get_method(eventBase_)));
+
+          // Register the event for the listening socket.
+          listenEvent_ = event_new(eventBase_, listenSocket_.handle,
+            EV_READ | EV_PERSIST | EV_ET,
+            assumeNothrow(&TNonblockingServer.acceptConnectionsCallback),
+            cast(void*)server_);
+          if (event_add(listenEvent_, null) == -1) {
+            throw new TException("event_add for the listening socket event failed.");
+          }
+        }
+
+        auto pair = socketPair();
+        foreach (s; pair) s.blocking = false;
+        completionSendSocket_ = pair[0];
+        completionReceiveSocket_ = pair[1];
+
+        // Register an event for the task completion notification socket.
+        completionEvent_ = event_new(eventBase_, completionReceiveSocket_.handle,
+          EV_READ | EV_PERSIST | EV_ET, assumeNothrow(&completedCallback),
+          cast(void*)this);
+
+        if (event_add(completionEvent_, null) == -1) {
+          throw new TException("event_add for the notification socket failed.");
+        }
+      }
+
+      // Run libevent engine, returns only after stop().
+      event_base_dispatch(eventBase_);
+
+      if (listenEvent_) {
+        event_free(listenEvent_);
+        listenEvent_ = null;
+      }
+
+      event_free(completionEvent_);
+      completionEvent_ = null;
+
+      completionSendSocket_.close();
+      completionSendSocket_ = null;
+
+      completionReceiveSocket_.close();
+      completionReceiveSocket_ = null;
+
+      event_base_free(eventBase_);
+      eventBase_ = null;
+
+      atomicStore(shuttingDown_, false);
+
+      initialized_ = false;
+    }
+
+    /**
+     * Adds a new connection handled by this loop.
+     */
+    void addConnection() {
+      ++numActiveConnections_;
+    }
+
+    /**
+     * Disposes a connection object (typically after it has been closed).
+     */
+    void disposeConnection(Connection conn) {
+      server_.disposeConnection(conn);
+      assert(numActiveConnections_ > 0);
+      --numActiveConnections_;
+      if (numActiveConnections_ == 0) {
+        if (atomicLoad(shuttingDown_)) {
+          event_base_loopbreak(eventBase_);
+        }
+      }
+    }
+
+    /**
+     * Notifies the event loop that the current step (initialization,
+     * processing of a request) on a certain connection has been completed.
+     *
+     * This function is thread-safe, but should never be called from the
+     * thread running the loop itself.
+     */
+    void notifyCompleted(Connection conn) {
+      assert(!!completionSendSocket_);
+      auto bytesSent = completionSendSocket_.send(cast(ubyte[])((&conn)[0 .. 1]));
+
+      if (bytesSent != Connection.sizeof) {
+        logError("Sending completion notification failed, connection will " ~
+          "not be properly terminated.");
+      }
+    }
+
+    /**
+     * Exits the event loop after all currently active connections have been
+     * closed.
+     *
+     * This function is thread-safe.
+     */
+    void stop() {
+      // There is a bug in either libevent or its documentation, having no
+      // events registered doesn't actually terminate the loop, because
+      // event_base_new() registers some internal one by calling
+      // evthread_make_base_notifiable().
+      // Due to this, we can't simply remove all events and expect the event
+      // loop to terminate. Instead, we ping the event loop using a null
+      // completion message. This way, we make sure to wake up the libevent
+      // thread if it not currently processing any connections. It will break
+      // out of the loop in disposeConnection() after the last active
+      // connection has been closed.
+      synchronized (initMutex_) {
+        atomicStore(shuttingDown_, true);
+        if (atomicLoad(initialized_)) notifyCompleted(null);
+      }
+    }
+
+  private:
+    /**
+     * C callback to call completed() from libevent.
+     *
+     * Expects the custom argument to be the this pointer of the associated
+     * IOLoop instance.
+     */
+    extern(C) static void completedCallback(int fd, short what, void* loopThis) {
+      assert(what & EV_READ);
+      auto loop = cast(IOLoop)loopThis;
+      assert(fd == loop.completionReceiveSocket_.handle);
+      loop.completed();
+    }
+
+    /**
+     * Reads from the completion receive socket and appropriately transitions
+     * the connections and shuts down the loop if requested.
+     */
+    void completed() {
+      Connection connection;
+      ptrdiff_t bytesRead;
+      while (true) {
+        bytesRead = completionReceiveSocket_.receive(
+          cast(ubyte[])((&connection)[0 .. 1]));
+        if (bytesRead < 0) {
+          auto errno = getSocketErrno();
+
+          if (errno != WOULD_BLOCK_ERRNO) {
+            logError("Reading from completion socket failed, some connection " ~
+              "will never be properly terminated: %s", socketErrnoString(errno));
+          }
+        }
+
+        if (bytesRead != Connection.sizeof) break;
+
+        if (!connection) {
+          assert(atomicLoad(shuttingDown_));
+          if (numActiveConnections_ == 0) {
+            event_base_loopbreak(eventBase_);
+          }
+          continue;
+        }
+
+        connection.transition();
+      }
+
+      if (bytesRead > 0) {
+        logError("Unexpected partial read from completion socket " ~
+          "(%s bytes instead of %s).", bytesRead, Connection.sizeof);
+      }
+    }
+
+    /// associated server
+    TNonblockingServer server_;
+
+    /// The managed listening socket, if any.
+    Socket listenSocket_;
+
+    /// The libevent event base for the loop.
+    event_base* eventBase_;
+
+    /// Triggered on listen socket events.
+    event* listenEvent_;
+
+    /// Triggered on completion receive socket events.
+    event* completionEvent_;
+
+    /// Socket used to send completion notification messages. Paired with
+    /// completionReceiveSocket_.
+    Socket completionSendSocket_;
+
+    /// Socket used to send completion notification messages. Paired with
+    /// completionSendSocket_.
+    Socket completionReceiveSocket_;
+
+    /// Whether the server is currently shutting down (i.e. the cancellation has
+    /// been triggered, but not all client connections have been closed yet).
+    shared bool shuttingDown_;
+
+    /// The number of currently active client connections.
+    size_t numActiveConnections_;
+
+    /// Guards loop startup so that the loop can be reliably shut down even if
+    /// another thread has just started to execute run(). Locked during
+    /// initialization in run(). When unlocked, the completion mechanism is
+    /// expected to be fully set up.
+    Mutex initMutex_;
+    shared bool initialized_; /// Ditto
+  }
+
+  /*
+   * I/O states a socket can be in.
+   */
+  enum SocketState {
+    RECV_FRAME_SIZE, /// The frame size is received.
+    RECV, /// The payload is received.
+    SEND /// The response is written back out.
+  }
+
+  /*
+   * States a connection can be in.
+   */
+  enum ConnectionState {
+    INIT, /// The connection will be initialized.
+    READ_FRAME_SIZE, /// The four frame size bytes are being read.
+    READ_REQUEST, /// The request payload itself is being read.
+    WAIT_PROCESSOR, /// The connection waits for the processor to finish.
+    SEND_RESULT /// The result is written back out.
+  }
+
+  /*
+   * A connection that is handled via libevent.
+   *
+   * Data received is buffered until the request is complete (returning back to
+   * libevent if not), at which point the processor is invoked.
+   */
+  final class Connection {
+    /**
+     * Constructs a new instance.
+     *
+     * To reuse a connection object later on, the init() function can be used
+     * to the same effect on the internal state.
+     */
+    this(Socket socket, IOLoop loop) {
+      // The input and output transport objects are reused between clients
+      // connections, so initialize them here rather than in init().
+      inputTransport_ = new TInputRangeTransport!(ubyte[])([]);
+      outputTransport_ = new TMemoryBuffer(loop.server_.writeBufferDefaultSize);
+
+      init(socket, loop);
+    }
+
+    /**
+     * Initializes the connection.
+     *
+     * Params:
+     *   socket = The socket to work on.
+     *   eventFlags = Any flags to pass to libevent.
+     *   s = The server this connection is part of.
+     */
+    void init(Socket socket, IOLoop loop) {
+      // TODO: This allocation could be avoided.
+      socket_ = new TSocket(socket);
+
+      loop_ = loop;
+      server_ = loop_.server_;
+      connState_ = ConnectionState.INIT;
+      eventFlags_ = 0;
+
+      readBufferPos_ = 0;
+      readWant_ = 0;
+
+      writeBuffer_ = null;
+      writeBufferPos_ = 0;
+      largestWriteBufferSize_ = 0;
+
+      socketState_ = SocketState.RECV_FRAME_SIZE;
+      callsSinceResize_ = 0;
+
+      factoryInputTransport_ =
+        server_.inputTransportFactory_.getTransport(inputTransport_);
+      factoryOutputTransport_ =
+        server_.outputTransportFactory_.getTransport(outputTransport_);
+
+      inputProtocol_ =
+        server_.inputProtocolFactory_.getProtocol(factoryInputTransport_);
+      outputProtocol_ =
+        server_.outputProtocolFactory_.getProtocol(factoryOutputTransport_);
+
+      if (server_.eventHandler) {
+        connectionContext_ =
+          server_.eventHandler.createContext(inputProtocol_, outputProtocol_);
+      }
+
+      auto info = TConnectionInfo(inputProtocol_, outputProtocol_, socket_);
+      processor_ = server_.processorFactory_.getProcessor(info);
+    }
+
+    ~this() {
+      free(readBuffer_);
+      if (event_) {
+        event_free(event_);
+        event_ = null;
+      }
+    }
+
+    /**
+     * Check buffers against the size limits and shrink them if exceeded.
+     *
+     * Params:
+     *   readLimit = Read buffer size limit (in bytes, 0 to ignore).
+     *   writeLimit = Write buffer size limit (in bytes, 0 to ignore).
+     */
+    void checkIdleBufferLimit(size_t readLimit, size_t writeLimit) {
+      if (readLimit > 0 && readBufferSize_ > readLimit) {
+        free(readBuffer_);
+        readBuffer_ = null;
+        readBufferSize_ = 0;
+      }
+
+      if (writeLimit > 0 && largestWriteBufferSize_ > writeLimit) {
+        // just start over
+        outputTransport_.reset(server_.writeBufferDefaultSize);
+        largestWriteBufferSize_ = 0;
+      }
+    }
+
+    /**
+     * Transitions the connection to the next state.
+     *
+     * This is called e.g. when the request has been read completely or all
+     * the data has been written back.
+     */
+    void transition() {
+      assert(!!loop_);
+      assert(!!server_);
+
+      // Switch upon the state that we are currently in and move to a new state
+      final switch (connState_) {
+        case ConnectionState.READ_REQUEST:
+          // We are done reading the request, package the read buffer into transport
+          // and get back some data from the dispatch function
+          inputTransport_.reset(readBuffer_[0 .. readBufferPos_]);
+          outputTransport_.reset();
+
+          // Prepend four bytes of blank space to the buffer so we can
+          // write the frame size there later.
+          // Strictly speaking, we wouldn't have to write anything, just
+          // increment the TMemoryBuffer writeOffset_. This would yield a tiny
+          // performance gain.
+          ubyte[4] space = void;
+          outputTransport_.write(space);
+
+          server_.incrementActiveProcessors();
+
+          taskPool_ = server_.taskPool;
+          if (taskPool_) {
+            // Create a new task and add it to the task pool queue.
+            auto processingTask = task!processRequest(this);
+            connState_ = ConnectionState.WAIT_PROCESSOR;
+            taskPool_.put(processingTask);
+
+            // We don't want to process any more data while the task is active.
+            unregisterEvent();
+            return;
+          }
+
+          // Just process it right now if there is no task pool set.
+          processRequest(this);
+          goto case;
+        case ConnectionState.WAIT_PROCESSOR:
+          // We have now finished processing the request, set the frame size
+          // for the outputTransport_ contents and set everything up to write
+          // it out via libevent.
+          server_.decrementActiveProcessors();
+
+          // Acquire the data written to the transport.
+          // KLUDGE: To avoid copying, we simply cast the const away and
+          // modify the internal buffer of the TMemoryBuffer – works with the
+          // current implementation, but isn't exactly beautiful.
+          writeBuffer_ = cast(ubyte[])outputTransport_.getContents();
+
+          assert(writeBuffer_.length >= 4, "The write buffer should have " ~
+            "least the initially added dummy length bytes.");
+          if (writeBuffer_.length == 4) {
+            // The request was one-way, no response to write.
+            goto case ConnectionState.INIT;
+          }
+
+          // Write the frame size into the four bytes reserved for it.
+          auto size = hostToNet(cast(uint)(writeBuffer_.length - 4));
+          writeBuffer_[0 .. 4] = cast(ubyte[])((&size)[0 .. 1]);
+
+          writeBufferPos_ = 0;
+          socketState_ = SocketState.SEND;
+          connState_ = ConnectionState.SEND_RESULT;
+          registerEvent(EV_WRITE | EV_PERSIST);
+
+          return;
+        case ConnectionState.SEND_RESULT:
+          // The result has been sent back to the client, we don't need the
+          // buffers anymore.
+          if (writeBuffer_.length > largestWriteBufferSize_) {
+            largestWriteBufferSize_ = writeBuffer_.length;
+          }
+
+          if (server_.resizeBufferEveryN > 0 &&
+              ++callsSinceResize_ >= server_.resizeBufferEveryN
+          ) {
+            checkIdleBufferLimit(server_.idleReadBufferLimit,
+              server_.idleWriteBufferLimit);
+            callsSinceResize_ = 0;
+          }
+
+          goto case;
+        case ConnectionState.INIT:
+          writeBuffer_ = null;
+          writeBufferPos_ = 0;
+          socketState_ = SocketState.RECV_FRAME_SIZE;
+          connState_ = ConnectionState.READ_FRAME_SIZE;
+          readBufferPos_ = 0;
+          registerEvent(EV_READ | EV_PERSIST);
+
+          return;
+        case ConnectionState.READ_FRAME_SIZE:
+          // We just read the request length, set up the buffers for reading
+          // the payload.
+          if (readWant_ > readBufferSize_) {
+            // The current buffer is too small, exponentially grow the buffer
+            // until it is big enough.
+
+            if (readBufferSize_ == 0) {
+              readBufferSize_ = 1;
+            }
+
+            auto newSize = readBufferSize_;
+            while (readWant_ > newSize) {
+              newSize *= 2;
+            }
+
+            auto newBuffer = cast(ubyte*)realloc(readBuffer_, newSize);
+            if (!newBuffer) onOutOfMemoryError();
+
+            readBuffer_ = newBuffer;
+            readBufferSize_ = newSize;
+          }
+
+          readBufferPos_= 0;
+
+          socketState_ = SocketState.RECV;
+          connState_ = ConnectionState.READ_REQUEST;
+
+          return;
+      }
+    }
+
+  private:
+    /**
+     * C callback to call workSocket() from libevent.
+     *
+     * Expects the custom argument to be the this pointer of the associated
+     * connection.
+     */
+    extern(C) static void workSocketCallback(int fd, short flags, void* connThis) {
+      auto conn = cast(Connection)connThis;
+      assert(fd == conn.socket_.socketHandle);
+      conn.workSocket();
+    }
+
+    /**
+     * Invoked by libevent when something happens on the socket.
+     */
+    void workSocket() {
+      final switch (socketState_) {
+        case SocketState.RECV_FRAME_SIZE:
+          // If some bytes have already been read, they have been kept in
+          // readWant_.
+          auto frameSize = readWant_;
+
+          try {
+            // Read from the socket
+            auto bytesRead = socket_.read(
+              (cast(ubyte[])((&frameSize)[0 .. 1]))[readBufferPos_ .. $]);
+            if (bytesRead == 0) {
+              // Couldn't read anything, but we have been notified – client
+              // has disconnected.
+              close();
+              return;
+            }
+
+            readBufferPos_ += bytesRead;
+          } catch (TTransportException te) {
+            logError("Failed to read frame size from client connection: %s", te);
+            close();
+            return;
+          }
+
+          if (readBufferPos_ < frameSize.sizeof) {
+            // Frame size not complete yet, save the current buffer in
+            // readWant_ so that the remaining bytes can be read later.
+            readWant_ = frameSize;
+            return;
+          }
+
+          auto size = netToHost(frameSize);
+          if (size > server_.maxFrameSize) {
+            logError("Frame size too large (%s > %s), client %s not using " ~
+              "TFramedTransport?", size, server_.maxFrameSize,
+              socket_.getPeerAddress().toHostNameString());
+            close();
+            return;
+          }
+          readWant_ = size;
+
+          // Now we know the frame size, set everything up for reading the
+          // payload.
+          transition();
+          return;
+
+        case SocketState.RECV:
+          // If we already got all the data, we should be in the SEND state.
+          assert(readBufferPos_ < readWant_);
+
+          size_t bytesRead;
+          try {
+            // Read as much as possible from the socket.
+            bytesRead = socket_.read(readBuffer_[readBufferPos_ .. readWant_]);
+          } catch (TTransportException te) {
+            logError("Failed to read from client socket: %s", te);
+            close();
+            return;
+          }
+
+          if (bytesRead == 0) {
+            // We were notified, but no bytes could be read -> the client
+            // disconnected.
+            close();
+            return;
+          }
+
+          readBufferPos_ += bytesRead;
+          assert(readBufferPos_ <= readWant_);
+
+          if (readBufferPos_ == readWant_) {
+            // The payload has been read completely, move on.
+            transition();
+          }
+
+          return;
+        case SocketState.SEND:
+          assert(writeBufferPos_ <= writeBuffer_.length);
+
+          if (writeBufferPos_ == writeBuffer_.length) {
+            // Nothing left to send – this shouldn't happen, just move on.
+            logInfo("WARNING: In send state, but no data to send.\n");
+            transition();
+            return;
+          }
+
+          size_t bytesSent;
+          try {
+            bytesSent = socket_.writeSome(writeBuffer_[writeBufferPos_ .. $]);
+          } catch (TTransportException te) {
+            logError("Failed to write to client socket: %s", te);
+            close();
+            return;
+          }
+
+          writeBufferPos_ += bytesSent;
+          assert(writeBufferPos_ <= writeBuffer_.length);
+
+          if (writeBufferPos_ == writeBuffer_.length) {
+            // The whole response has been written out, we are done.
+            transition();
+          }
+
+          return;
+      }
+    }
+
+    /**
+     * Registers a libevent event for workSocket() with the passed flags,
+     * unregistering the previous one (if any).
+     */
+    void registerEvent(short eventFlags) {
+      if (eventFlags_ == eventFlags) {
+        // Nothing to do if flags are the same.
+        return;
+      }
+
+      // Delete the previously existing event.
+      unregisterEvent();
+
+      eventFlags_ = eventFlags;
+
+      if (eventFlags == 0) return;
+
+      if (!event_) {
+        // If the event was not already allocated, do it now.
+        event_ = event_new(loop_.eventBase_, socket_.socketHandle,
+          eventFlags_, assumeNothrow(&workSocketCallback), cast(void*)this);
+      } else {
+        event_assign(event_, loop_.eventBase_, socket_.socketHandle,
+          eventFlags_, assumeNothrow(&workSocketCallback), cast(void*)this);
+      }
+
+      // Add the event
+      if (event_add(event_, null) == -1) {
+        logError("event_add() for client socket failed.");
+      }
+    }
+
+    /**
+     * Unregisters the current libevent event, if any.
+     */
+    void unregisterEvent() {
+      if (event_ && eventFlags_ != 0) {
+        eventFlags_ = 0;
+        if (event_del(event_) == -1) {
+          logError("event_del() for client socket failed.");
+          return;
+        }
+      }
+    }
+
+    /**
+     * Closes this connection and returns it back to the server.
+     */
+    void close() {
+      unregisterEvent();
+
+      if (server_.eventHandler) {
+        server_.eventHandler.deleteContext(
+          connectionContext_, inputProtocol_, outputProtocol_);
+      }
+
+      // Close the socket
+      socket_.close();
+
+      // close any factory produced transports.
+      factoryInputTransport_.close();
+      factoryOutputTransport_.close();
+
+      // This connection object can now be reused.
+      loop_.disposeConnection(this);
+    }
+
+    /// The server this connection belongs to.
+    TNonblockingServer server_;
+
+    /// The task pool used for this connection. This is cached instead of
+    /// directly using server_.taskPool to avoid confusion if it is changed in
+    /// another thread while the request is processed.
+    TaskPool taskPool_;
+
+    /// The I/O thread handling this connection.
+    IOLoop loop_;
+
+    /// The socket managed by this connection.
+    TSocket socket_;
+
+    /// The libevent object used for registering the workSocketCallback.
+    event* event_;
+
+    /// Libevent flags
+    short eventFlags_;
+
+    /// Socket mode
+    SocketState socketState_;
+
+    /// Application state
+    ConnectionState connState_;
+
+    /// The size of the frame to read. If still in READ_FRAME_SIZE state, some
+    /// of the bytes might not have been written, and the value might still be
+    /// in network byte order. An uint (not a size_t) because the frame size on
+    /// the wire is specified as one.
+    uint readWant_;
+
+    /// The position in the read buffer, i.e. the number of payload bytes
+    /// already received from the socket in READ_REQUEST state, resp. the
+    /// number of size bytes in READ_FRAME_SIZE state.
+    uint readBufferPos_;
+
+    /// Read buffer
+    ubyte* readBuffer_;
+
+    /// Read buffer size
+    size_t readBufferSize_;
+
+    /// Write buffer
+    ubyte[] writeBuffer_;
+
+    /// How far through writing are we?
+    size_t writeBufferPos_;
+
+    /// Largest size of write buffer seen since buffer was constructed
+    size_t largestWriteBufferSize_;
+
+    /// Number of calls since the last time checkIdleBufferLimit has been
+    /// invoked (see TServer.resizeBufferEveryN).
+    uint callsSinceResize_;
+
+    /// Base transports the processor reads from/writes to.
+    TInputRangeTransport!(ubyte[]) inputTransport_;
+    TMemoryBuffer outputTransport_;
+
+    /// The actual transports passed to the processor obtained via the
+    /// transport factory.
+    TTransport factoryInputTransport_;
+    TTransport factoryOutputTransport_; /// Ditto
+
+    /// Input/output protocols, connected to factory{Input, Output}Transport.
+    TProtocol inputProtocol_;
+    TProtocol outputProtocol_; /// Ditto.
+
+    /// Connection context optionally created by the server event handler.
+    Variant connectionContext_;
+
+    /// The processor used for this connection.
+    TProcessor processor_;
+  }
+}
+
+/*
+ * The request processing function, which invokes the processor for the server
+ * for all the RPC messages received over a connection.
+ *
+ * Must be public because it is passed as alias to std.parallelism.task().
+ */
+void processRequest(Connection connection) {
+  try {
+    while (true) {
+      with (connection) {
+        if (server_.eventHandler) {
+          server_.eventHandler.preProcess(connectionContext_, socket_);
+        }
+
+        if (!processor_.process(inputProtocol_, outputProtocol_,
+          connectionContext_) || !inputProtocol_.transport.peek()
+        ) {
+          // Something went fundamentally wrong or there is nothing more to
+          // process, close the connection.
+          break;
+        }
+      }
+    }
+  } catch (TTransportException ttx) {
+    logError("Client died: %s", ttx);
+  } catch (Exception e) {
+    logError("Uncaught exception: %s", e);
+  }
+
+  if (connection.taskPool_) connection.loop_.notifyCompleted(connection);
+}
+
+unittest {
+  import thrift.internal.test.server;
+
+  // Temporarily disable info log output in order not to spam the test results
+  // with startup info messages.
+  auto oldInfoLogSink = g_infoLogSink;
+  g_infoLogSink = null;
+  scope (exit) g_infoLogSink = oldInfoLogSink;
+
+  // Test in-line processing shutdown with one as well as several I/O threads.
+  testServeCancel!(TNonblockingServer)();
+  testServeCancel!(TNonblockingServer)((TNonblockingServer s) {
+    s.numIOThreads = 4;
+  });
+
+  // Test task pool processing shutdown with one as well as several I/O threads.
+  auto tp = new TaskPool(4);
+  tp.isDaemon = true;
+  testServeCancel!(TNonblockingServer)((TNonblockingServer s) {
+    s.taskPool = tp;
+  });
+  testServeCancel!(TNonblockingServer)((TNonblockingServer s) {
+    s.taskPool = tp;
+    s.numIOThreads = 4;
+  });
+}
diff --git a/lib/d/src/thrift/server/simple.d b/lib/d/src/thrift/server/simple.d
new file mode 100644
index 0000000..f7183a7
--- /dev/null
+++ b/lib/d/src/thrift/server/simple.d
@@ -0,0 +1,181 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+module thrift.server.simple;
+
+import std.variant : Variant;
+import thrift.base;
+import thrift.protocol.base;
+import thrift.protocol.processor;
+import thrift.server.base;
+import thrift.server.transport.base;
+import thrift.transport.base;
+import thrift.util.cancellation;
+
+/**
+ * The most basic server.
+ *
+ * It is single-threaded and after it accepts a connections, it processes
+ * requests on it until it closes, then waiting for the next connection.
+ *
+ * It is not so much of use in production than it is for writing unittests, or
+ * as an example on how to provide a custom TServer implementation.
+ */
+class TSimpleServer : TServer {
+  ///
+  this(
+    TProcessor processor,
+    TServerTransport serverTransport,
+    TTransportFactory transportFactory,
+    TProtocolFactory protocolFactory
+  ) {
+    super(processor, serverTransport, transportFactory, protocolFactory);
+  }
+
+  ///
+  this(
+    TProcessorFactory processorFactory,
+    TServerTransport serverTransport,
+    TTransportFactory transportFactory,
+    TProtocolFactory protocolFactory
+  ) {
+    super(processorFactory, serverTransport, transportFactory, protocolFactory);
+  }
+
+  ///
+  this(
+    TProcessor processor,
+    TServerTransport serverTransport,
+    TTransportFactory inputTransportFactory,
+    TTransportFactory outputTransportFactory,
+    TProtocolFactory inputProtocolFactory,
+    TProtocolFactory outputProtocolFactory
+  ) {
+    super(processor, serverTransport, inputTransportFactory,
+      outputTransportFactory, inputProtocolFactory, outputProtocolFactory);
+  }
+
+  this(
+    TProcessorFactory processorFactory,
+    TServerTransport serverTransport,
+    TTransportFactory inputTransportFactory,
+    TTransportFactory outputTransportFactory,
+    TProtocolFactory inputProtocolFactory,
+    TProtocolFactory outputProtocolFactory
+  ) {
+    super(processorFactory, serverTransport, inputTransportFactory,
+      outputTransportFactory, inputProtocolFactory, outputProtocolFactory);
+  }
+
+  override void serve(TCancellation cancellation = null) {
+    serverTransport_.listen();
+
+    if (eventHandler) eventHandler.preServe();
+
+    while (true) {
+      TTransport client;
+      TTransport inputTransport;
+      TTransport outputTransport;
+      TProtocol inputProtocol;
+      TProtocol outputProtocol;
+
+      try {
+        client = serverTransport_.accept(cancellation);
+        scope(failure) client.close();
+
+        inputTransport = inputTransportFactory_.getTransport(client);
+        scope(failure) inputTransport.close();
+
+        outputTransport = outputTransportFactory_.getTransport(client);
+        scope(failure) outputTransport.close();
+
+        inputProtocol = inputProtocolFactory_.getProtocol(inputTransport);
+        outputProtocol = outputProtocolFactory_.getProtocol(outputTransport);
+      } catch (TCancelledException tcx) {
+        break;
+      } catch (TTransportException ttx) {
+        logError("TServerTransport failed on accept: %s", ttx);
+        continue;
+      } catch (TException tx) {
+        logError("Caught TException on accept: %s", tx);
+        continue;
+      }
+
+      auto info = TConnectionInfo(inputProtocol, outputProtocol, client);
+      auto processor = processorFactory_.getProcessor(info);
+
+      Variant connectionContext;
+      if (eventHandler) {
+        connectionContext =
+          eventHandler.createContext(inputProtocol, outputProtocol);
+      }
+
+      try {
+        while (true) {
+          if (eventHandler) {
+            eventHandler.preProcess(connectionContext, client);
+          }
+
+          if (!processor.process(inputProtocol, outputProtocol,
+            connectionContext) || !inputProtocol.transport.peek()
+          ) {
+            // Something went fundamentlly wrong or there is nothing more to
+            // process, close the connection.
+            break;
+          }
+        }
+      } catch (TTransportException ttx) {
+        logError("Client died: %s", ttx);
+      } catch (Exception e) {
+        logError("Uncaught exception: %s", e);
+      }
+
+      if (eventHandler) {
+        eventHandler.deleteContext(connectionContext, inputProtocol,
+          outputProtocol);
+      }
+
+      try {
+        inputTransport.close();
+      } catch (TTransportException ttx) {
+        logError("Input close failed: %s", ttx);
+      }
+      try {
+        outputTransport.close();
+      } catch (TTransportException ttx) {
+        logError("Output close failed: %s", ttx);
+      }
+      try {
+        client.close();
+      } catch (TTransportException ttx) {
+        logError("Client close failed: %s", ttx);
+      }
+    }
+
+    try {
+      serverTransport_.close();
+    } catch (TServerTransportException e) {
+      logError("Server transport failed to close(): %s", e);
+    }
+  }
+}
+
+unittest {
+  import thrift.internal.test.server;
+  testServeCancel!TSimpleServer();
+}
diff --git a/lib/d/src/thrift/server/taskpool.d b/lib/d/src/thrift/server/taskpool.d
new file mode 100644
index 0000000..b4720a4
--- /dev/null
+++ b/lib/d/src/thrift/server/taskpool.d
@@ -0,0 +1,302 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+module thrift.server.taskpool;
+
+import core.sync.condition;
+import core.sync.mutex;
+import std.exception : enforce;
+import std.parallelism;
+import std.variant : Variant;
+import thrift.base;
+import thrift.protocol.base;
+import thrift.protocol.processor;
+import thrift.server.base;
+import thrift.server.transport.base;
+import thrift.transport.base;
+import thrift.util.cancellation;
+
+/**
+ * A server which dispatches client requests to a std.parallelism TaskPool.
+ */
+class TTaskPoolServer : TServer {
+  ///
+  this(
+    TProcessor processor,
+    TServerTransport serverTransport,
+    TTransportFactory transportFactory,
+    TProtocolFactory protocolFactory,
+    TaskPool taskPool = null
+  ) {
+    this(processor, serverTransport, transportFactory, transportFactory,
+      protocolFactory, protocolFactory, taskPool);
+  }
+
+  ///
+  this(
+    TProcessorFactory processorFactory,
+    TServerTransport serverTransport,
+    TTransportFactory transportFactory,
+    TProtocolFactory protocolFactory,
+    TaskPool taskPool = null
+  ) {
+    this(processorFactory, serverTransport, transportFactory, transportFactory,
+      protocolFactory, protocolFactory, taskPool);
+  }
+
+  ///
+  this(
+    TProcessor processor,
+    TServerTransport serverTransport,
+    TTransportFactory inputTransportFactory,
+    TTransportFactory outputTransportFactory,
+    TProtocolFactory inputProtocolFactory,
+    TProtocolFactory outputProtocolFactory,
+    TaskPool taskPool = null
+  ) {
+    this(new TSingletonProcessorFactory(processor), serverTransport,
+      inputTransportFactory, outputTransportFactory,
+      inputProtocolFactory, outputProtocolFactory);
+  }
+
+  ///
+  this(
+    TProcessorFactory processorFactory,
+    TServerTransport serverTransport,
+    TTransportFactory inputTransportFactory,
+    TTransportFactory outputTransportFactory,
+    TProtocolFactory inputProtocolFactory,
+    TProtocolFactory outputProtocolFactory,
+    TaskPool taskPool = null
+  ) {
+    super(processorFactory, serverTransport, inputTransportFactory,
+      outputTransportFactory, inputProtocolFactory, outputProtocolFactory);
+
+    if (taskPool) {
+      this.taskPool = taskPool;
+    } else {
+      auto ptp = std.parallelism.taskPool;
+      if (ptp.size > 0) {
+        taskPool_ = ptp;
+      } else {
+        // If the global task pool is empty (default on a single-core machine),
+        // create a new one with a single worker thread. The rationale for this
+        // is to avoid that an application which worked fine with no task pool
+        // explicitly set on the multi-core developer boxes suddenly fails on a
+        // single-core user machine.
+        taskPool_ = new TaskPool(1);
+        taskPool_.isDaemon = true;
+      }
+    }
+  }
+
+  override void serve(TCancellation cancellation = null) {
+    serverTransport_.listen();
+
+    if (eventHandler) eventHandler.preServe();
+
+    auto queueState = QueueState();
+
+    while (true) {
+      // Check if we can still handle more connections.
+      if (maxActiveConns) {
+        synchronized (queueState.mutex) {
+          while (queueState.activeConns >= maxActiveConns) {
+            queueState.connClosed.wait();
+          }
+        }
+      }
+
+      TTransport client;
+      TTransport inputTransport;
+      TTransport outputTransport;
+      TProtocol inputProtocol;
+      TProtocol outputProtocol;
+
+      try {
+        client = serverTransport_.accept(cancellation);
+        scope(failure) client.close();
+
+        inputTransport = inputTransportFactory_.getTransport(client);
+        scope(failure) inputTransport.close();
+
+        outputTransport = outputTransportFactory_.getTransport(client);
+        scope(failure) outputTransport.close();
+
+        inputProtocol = inputProtocolFactory_.getProtocol(inputTransport);
+        outputProtocol = outputProtocolFactory_.getProtocol(outputTransport);
+      } catch (TCancelledException tce) {
+        break;
+      } catch (TTransportException ttx) {
+        logError("TServerTransport failed on accept: %s", ttx);
+        continue;
+      } catch (TException tx) {
+        logError("Caught TException on accept: %s", tx);
+        continue;
+      }
+
+      auto info = TConnectionInfo(inputProtocol, outputProtocol, client);
+      auto processor = processorFactory_.getProcessor(info);
+
+      synchronized (queueState.mutex) {
+        ++queueState.activeConns;
+      }
+      taskPool_.put(task!worker(queueState, client, inputProtocol,
+        outputProtocol, processor, eventHandler));
+    }
+
+    // First, stop accepting new connections.
+    try {
+      serverTransport_.close();
+    } catch (TServerTransportException e) {
+      logError("Server transport failed to close: %s", e);
+    }
+
+    // Then, wait until all active connections are finished.
+    synchronized (queueState.mutex) {
+      while (queueState.activeConns > 0) {
+        queueState.connClosed.wait();
+      }
+    }
+  }
+
+  /**
+   * Sets the task pool to use.
+   *
+   * By default, the global std.parallelism taskPool instance is used, which
+   * might not be appropriate for many applications, e.g. where tuning the
+   * number of worker threads is desired. (On single-core systems, a private
+   * task pool with a single thread is used by default, since the global
+   * taskPool instance has no worker threads then.)
+   *
+   * Note: TTaskPoolServer expects that tasks are never dropped from the pool,
+   * e.g. by calling TaskPool.close() while there are still tasks in the
+   * queue. If this happens, serve() will never return.
+   */
+  void taskPool(TaskPool pool) @property {
+    enforce(pool !is null, "Cannot use a null task pool.");
+    enforce(pool.size > 0, "Cannot use a task pool with no worker threads.");
+    taskPool_ = pool;
+  }
+
+  /**
+   * The maximum number of client connections open at the same time. Zero for
+   * no limit, which is the default.
+   *
+   * If this limit is reached, no clients are accept()ed from the server
+   * transport any longer until another connection has been closed again.
+   */
+  size_t maxActiveConns;
+
+protected:
+  TaskPool taskPool_;
+}
+
+// Cannot be private as worker has to be passed as alias parameter to
+// another module.
+// private {
+  /*
+   * The state of the »connection queue«, i.e. used for keeping track of how
+   * many client connections are currently processed.
+   */
+  struct QueueState {
+    /// Protects the queue state.
+    Mutex mutex;
+
+    /// The number of active connections (from the time they are accept()ed
+    /// until they are closed when the worked task finishes).
+    size_t activeConns;
+
+    /// Signals that the number of active connections has been decreased, i.e.
+    /// that a connection has been closed.
+    Condition connClosed;
+
+    /// Returns an initialized instance.
+    static QueueState opCall() {
+      QueueState q;
+      q.mutex = new Mutex;
+      q.connClosed = new Condition(q.mutex);
+      return q;
+    }
+  }
+
+  void worker(ref QueueState queueState, TTransport client,
+    TProtocol inputProtocol, TProtocol outputProtocol,
+    TProcessor processor, TServerEventHandler eventHandler)
+  {
+    scope (exit) {
+      synchronized (queueState.mutex) {
+        assert(queueState.activeConns > 0);
+        --queueState.activeConns;
+        queueState.connClosed.notifyAll();
+      }
+    }
+
+    Variant connectionContext;
+    if (eventHandler) {
+      connectionContext =
+        eventHandler.createContext(inputProtocol, outputProtocol);
+    }
+
+    try {
+      while (true) {
+        if (eventHandler) {
+          eventHandler.preProcess(connectionContext, client);
+        }
+
+        if (!processor.process(inputProtocol, outputProtocol,
+          connectionContext) || !inputProtocol.transport.peek()
+        ) {
+          // Something went fundamentlly wrong or there is nothing more to
+          // process, close the connection.
+          break;
+        }
+      }
+    } catch (TTransportException ttx) {
+      logError("Client died: %s", ttx);
+    } catch (Exception e) {
+      logError("Uncaught exception: %s", e);
+    }
+
+    if (eventHandler) {
+      eventHandler.deleteContext(connectionContext, inputProtocol,
+        outputProtocol);
+    }
+
+    try {
+      inputProtocol.transport.close();
+    } catch (TTransportException ttx) {
+      logError("Input close failed: %s", ttx);
+    }
+    try {
+      outputProtocol.transport.close();
+    } catch (TTransportException ttx) {
+      logError("Output close failed: %s", ttx);
+    }
+    try {
+      client.close();
+    } catch (TTransportException ttx) {
+      logError("Client close failed: %s", ttx);
+    }
+  }
+// }
+
+unittest {
+  import thrift.internal.test.server;
+  testServeCancel!TTaskPoolServer();
+}
diff --git a/lib/d/src/thrift/server/threaded.d b/lib/d/src/thrift/server/threaded.d
new file mode 100644
index 0000000..1cde983
--- /dev/null
+++ b/lib/d/src/thrift/server/threaded.d
@@ -0,0 +1,215 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+module thrift.server.threaded;
+
+import core.thread;
+import std.variant : Variant;
+import thrift.base;
+import thrift.protocol.base;
+import thrift.protocol.processor;
+import thrift.server.base;
+import thrift.server.transport.base;
+import thrift.transport.base;
+import thrift.util.cancellation;
+
+/**
+ * A simple threaded server which spawns a new thread per connection.
+ */
+class TThreadedServer : TServer {
+  ///
+  this(
+    TProcessor processor,
+    TServerTransport serverTransport,
+    TTransportFactory transportFactory,
+    TProtocolFactory protocolFactory
+  ) {
+    super(processor, serverTransport, transportFactory, protocolFactory);
+  }
+
+  ///
+  this(
+    TProcessorFactory processorFactory,
+    TServerTransport serverTransport,
+    TTransportFactory transportFactory,
+    TProtocolFactory protocolFactory
+  ) {
+    super(processorFactory, serverTransport, transportFactory, protocolFactory);
+  }
+
+  ///
+  this(
+    TProcessor processor,
+    TServerTransport serverTransport,
+    TTransportFactory inputTransportFactory,
+    TTransportFactory outputTransportFactory,
+    TProtocolFactory inputProtocolFactory,
+    TProtocolFactory outputProtocolFactory
+  ) {
+    super(processor, serverTransport, inputTransportFactory,
+      outputTransportFactory, inputProtocolFactory, outputProtocolFactory);
+  }
+
+  ///
+  this(
+    TProcessorFactory processorFactory,
+    TServerTransport serverTransport,
+    TTransportFactory inputTransportFactory,
+    TTransportFactory outputTransportFactory,
+    TProtocolFactory inputProtocolFactory,
+    TProtocolFactory outputProtocolFactory
+  ) {
+    super(processorFactory, serverTransport, inputTransportFactory,
+      outputTransportFactory, inputProtocolFactory, outputProtocolFactory);
+  }
+
+  override void serve(TCancellation cancellation = null) {
+    try {
+      // Start the server listening
+      serverTransport_.listen();
+    } catch (TTransportException ttx) {
+      logError("listen() failed: %s", ttx);
+      return;
+    }
+
+    if (eventHandler) eventHandler.preServe();
+
+    auto workerThreads = new ThreadGroup();
+
+    while (true) {
+      TTransport client;
+      TTransport inputTransport;
+      TTransport outputTransport;
+      TProtocol inputProtocol;
+      TProtocol outputProtocol;
+
+      try {
+        client = serverTransport_.accept(cancellation);
+        scope(failure) client.close();
+
+        inputTransport = inputTransportFactory_.getTransport(client);
+        scope(failure) inputTransport.close();
+
+        outputTransport = outputTransportFactory_.getTransport(client);
+        scope(failure) outputTransport.close();
+
+        inputProtocol = inputProtocolFactory_.getProtocol(inputTransport);
+        outputProtocol = outputProtocolFactory_.getProtocol(outputTransport);
+      } catch (TCancelledException tce) {
+        break;
+      } catch (TTransportException ttx) {
+        logError("TServerTransport failed on accept: %s", ttx);
+        continue;
+      } catch (TException tx) {
+        logError("Caught TException on accept: %s", tx);
+        continue;
+      }
+
+      auto info = TConnectionInfo(inputProtocol, outputProtocol, client);
+      auto processor = processorFactory_.getProcessor(info);
+      auto worker = new WorkerThread(client, inputProtocol, outputProtocol,
+        processor, eventHandler);
+      workerThreads.add(worker);
+      worker.start();
+    }
+
+    try {
+      serverTransport_.close();
+    } catch (TServerTransportException e) {
+      logError("Server transport failed to close: %s", e);
+    }
+    workerThreads.joinAll();
+  }
+}
+
+// The worker thread handling a client connection.
+private class WorkerThread : Thread {
+  this(TTransport client, TProtocol inputProtocol, TProtocol outputProtocol,
+    TProcessor processor, TServerEventHandler eventHandler)
+  {
+    client_ = client;
+    inputProtocol_ = inputProtocol;
+    outputProtocol_ = outputProtocol;
+    processor_ = processor;
+    eventHandler_ = eventHandler;
+
+    super(&run);
+  }
+
+  void run() {
+    Variant connectionContext;
+    if (eventHandler_) {
+      connectionContext =
+        eventHandler_.createContext(inputProtocol_, outputProtocol_);
+    }
+
+    try {
+      while (true) {
+        if (eventHandler_) {
+          eventHandler_.preProcess(connectionContext, client_);
+        }
+
+        if (!processor_.process(inputProtocol_, outputProtocol_,
+          connectionContext) || !inputProtocol_.transport.peek()
+        ) {
+          // Something went fundamentlly wrong or there is nothing more to
+          // process, close the connection.
+          break;
+        }
+      }
+    } catch (TTransportException ttx) {
+      logError("Client died: %s", ttx);
+    } catch (Exception e) {
+      logError("Uncaught exception: %s", e);
+    }
+
+    if (eventHandler_) {
+      eventHandler_.deleteContext(connectionContext, inputProtocol_,
+        outputProtocol_);
+    }
+
+    try {
+      inputProtocol_.transport.close();
+    } catch (TTransportException ttx) {
+      logError("Input close failed: %s", ttx);
+    }
+    try {
+      outputProtocol_.transport.close();
+    } catch (TTransportException ttx) {
+      logError("Output close failed: %s", ttx);
+    }
+    try {
+      client_.close();
+    } catch (TTransportException ttx) {
+      logError("Client close failed: %s", ttx);
+    }
+  }
+
+private:
+  TTransport client_;
+  TProtocol inputProtocol_;
+  TProtocol outputProtocol_;
+  TProcessor processor_;
+  TServerEventHandler eventHandler_;
+}
+
+unittest {
+  import thrift.internal.test.server;
+  testServeCancel!TThreadedServer();
+}
+
diff --git a/lib/d/src/thrift/server/transport/base.d b/lib/d/src/thrift/server/transport/base.d
new file mode 100644
index 0000000..da165d3
--- /dev/null
+++ b/lib/d/src/thrift/server/transport/base.d
@@ -0,0 +1,133 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+module thrift.server.transport.base;
+
+import thrift.base;
+import thrift.transport.base;
+import thrift.util.cancellation;
+
+/**
+ * Some kind of I/O device enabling servers to listen for incoming client
+ * connections and communicate with them via a TTransport interface.
+ */
+interface TServerTransport {
+  /**
+   * Starts listening for server connections.
+   *
+   * Just as simliar functions commonly found in socket libraries, this
+   * function does not block.
+   *
+   * If the socket is already listening, nothing happens.
+   *
+   * Throws: TServerTransportException if listening failed or the transport
+   *   was already listening.
+   */
+  void listen();
+
+  /**
+   * Closes the server transport, causing it to stop listening.
+   *
+   * Throws: TServerTransportException if the transport was not listening.
+   */
+  void close();
+
+  /**
+   * Returns whether the server transport is currently listening.
+   */
+  bool isListening() @property;
+
+  /**
+   * Accepts a client connection and returns an opened TTransport for it,
+   * never returning null.
+   *
+   * Blocks until a client connection is available.
+   *
+   * Params:
+   *   cancellation = If triggered, requests the call to stop blocking and
+   *     return with a TCancelledException. Implementations are free to
+   *     ignore this if they cannot provide a reasonable.
+   *
+   * Throws: TServerTransportException if accepting failed,
+   *   TCancelledException if it was cancelled.
+   */
+  TTransport accept(TCancellation cancellation = null) out (result) {
+    assert(result !is null);
+  }
+}
+
+/**
+ * Server transport exception.
+ */
+class TServerTransportException : TException {
+  /**
+   * Error codes for the various types of exceptions.
+   */
+  enum Type {
+    ///
+    UNKNOWN,
+
+    /// The server socket is not listening, but excepted to be.
+    NOT_LISTENING,
+
+    /// The server socket is already listening, but expected not to be.
+    ALREADY_LISTENING,
+
+    /// An operation on the primary underlying resource, e.g. a socket used
+    /// for accepting connections, failed.
+    RESOURCE_FAILED
+  }
+
+  ///
+  this(Type type, string file = __FILE__, size_t line = __LINE__, Throwable next = null) {
+    string msg = "TTransportException: ";
+    switch (type) {
+      case Type.UNKNOWN: msg ~= "Unknown server transport exception"; break;
+      case Type.NOT_LISTENING: msg ~= "Server transport not listening"; break;
+      case Type.ALREADY_LISTENING: msg ~= "Server transport already listening"; break;
+      case Type.RESOURCE_FAILED: msg ~= "An underlying resource failed"; break;
+      default: msg ~= "(Invalid exception type)"; break;
+    }
+
+    this(msg, type, file, line, next);
+  }
+
+  ///
+  this(string msg, string file = __FILE__, size_t line = __LINE__,
+    Throwable next = null)
+  {
+    this(msg, Type.UNKNOWN, file, line, next);
+  }
+
+  ///
+  this(string msg, Type type, string file = __FILE__, size_t line = __LINE__,
+    Throwable next = null)
+  {
+    super(msg, file, line, next);
+    type_ = type;
+  }
+
+  ///
+  Type type() const nothrow @property {
+    return type_;
+  }
+
+protected:
+  Type type_;
+}
+
diff --git a/lib/d/src/thrift/server/transport/socket.d b/lib/d/src/thrift/server/transport/socket.d
new file mode 100644
index 0000000..0cbca41
--- /dev/null
+++ b/lib/d/src/thrift/server/transport/socket.d
@@ -0,0 +1,380 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+module thrift.server.transport.socket;
+
+import core.thread : dur, Duration, Thread;
+import core.stdc.string : strerror;
+import std.array : empty;
+import std.conv : text, to;
+import std.exception : enforce;
+import std.socket;
+import thrift.base;
+import thrift.internal.socket;
+import thrift.server.transport.base;
+import thrift.transport.base;
+import thrift.transport.socket;
+import thrift.util.awaitable;
+import thrift.util.cancellation;
+
+private alias TServerTransportException STE;
+
+/**
+ * Server socket implementation of TServerTransport.
+ *
+ * Maps to std.socket listen()/accept(); only provides TCP/IP sockets (i.e. no
+ * Unix sockets) for now, because they are not supported in std.socket.
+ */
+class TServerSocket : TServerTransport {
+  /**
+   * Constructs a new instance.
+   *
+   * Params:
+   *   port = The TCP port to listen at (host is always 0.0.0.0).
+   *   sendTimeout = The socket sending timeout.
+   *   recvTimout = The socket receiving timeout.
+   */
+  this(ushort port, Duration sendTimeout = dur!"hnsecs"(0),
+    Duration recvTimeout = dur!"hnsecs"(0))
+  {
+    port_ = port;
+    sendTimeout_ = sendTimeout;
+    recvTimeout_ = recvTimeout;
+
+    cancellationNotifier_ = new TSocketNotifier;
+
+    socketSet_ = new SocketSet;
+  }
+
+  /// The port the server socket listens at.
+  ushort port() const @property {
+    return port_;
+  }
+
+  /// The socket sending timeout, zero to block infinitely.
+  void sendTimeout(Duration sendTimeout) @property {
+    sendTimeout_ = sendTimeout;
+  }
+
+  /// The socket receiving timeout, zero to block infinitely.
+  void recvTimeout(Duration recvTimeout) @property {
+    recvTimeout_ = recvTimeout;
+  }
+
+  /// The maximum number of listening retries if it fails.
+  void retryLimit(ushort retryLimit) @property {
+    retryLimit_ = retryLimit;
+  }
+
+  /// The delay between a listening attempt failing and retrying it.
+  void retryDelay(Duration retryDelay) @property {
+    retryDelay_ = retryDelay;
+  }
+
+  /// The size of the TCP send buffer, in bytes.
+  void tcpSendBuffer(int tcpSendBuffer) @property {
+    tcpSendBuffer_ = tcpSendBuffer;
+  }
+
+  /// The size of the TCP receiving buffer, in bytes.
+  void tcpRecvBuffer(int tcpRecvBuffer) @property {
+    tcpRecvBuffer_ = tcpRecvBuffer;
+  }
+
+  /// Whether to listen on IPv6 only, if IPv6 support is detected
+  /// (default: false).
+  void ipv6Only(bool value) @property {
+    ipv6Only_ = value;
+  }
+
+  override void listen() {
+    enforce(!isListening, new STE(STE.Type.ALREADY_LISTENING));
+
+    serverSocket_ = makeSocketAndListen(port_, ACCEPT_BACKLOG, retryLimit_,
+      retryDelay_, tcpSendBuffer_, tcpRecvBuffer_, ipv6Only_);
+  }
+
+  override void close() {
+    enforce(isListening, new STE(STE.Type.NOT_LISTENING));
+
+    serverSocket_.shutdown(SocketShutdown.BOTH);
+    serverSocket_.close();
+    serverSocket_ = null;
+  }
+
+  override bool isListening() @property {
+    return serverSocket_ !is null;
+  }
+
+  /// Number of connections listen() backlogs.
+  enum ACCEPT_BACKLOG = 1024;
+
+  override TTransport accept(TCancellation cancellation = null) {
+    enforce(isListening, new STE(STE.Type.NOT_LISTENING));
+
+    if (cancellation) cancellationNotifier_.attach(cancellation.triggering);
+    scope (exit) if (cancellation) cancellationNotifier_.detach();
+
+
+    // Too many EINTRs is a fault condition and would need to be handled
+    // manually by our caller, but we can tolerate a certain number.
+    enum MAX_EINTRS = 10;
+    uint numEintrs;
+
+    while (true) {
+      socketSet_.reset();
+      socketSet_.add(serverSocket_);
+      socketSet_.add(cancellationNotifier_.socket);
+
+      auto ret = Socket.select(socketSet_, null, null);
+      enforce(ret != 0, new STE("Socket.select() returned 0.",
+        STE.Type.RESOURCE_FAILED));
+
+      if (ret < 0) {
+        // Select itself failed, check if it was just due to an interrupted
+        // syscall.
+        if (getSocketErrno() == INTERRUPTED_ERRNO) {
+          if (numEintrs++ < MAX_EINTRS) {
+            continue;
+          } else {
+            throw new STE("Socket.select() was interrupted by a signal (EINTR) " ~
+              "more than " ~ to!string(MAX_EINTRS) ~ " times.",
+              STE.Type.RESOURCE_FAILED
+            );
+          }
+        }
+        throw new STE("Unknown error on Socket.select(): " ~
+          socketErrnoString(getSocketErrno()), STE.Type.RESOURCE_FAILED);
+      } else {
+        // Check for a ping on the interrupt socket.
+        if (socketSet_.isSet(cancellationNotifier_.socket)) {
+          cancellation.throwIfTriggered();
+        }
+
+        // Check for the actual server socket having a connection waiting.
+        if (socketSet_.isSet(serverSocket_)) {
+          break;
+        }
+      }
+    }
+
+    try {
+      auto client = createTSocket(serverSocket_.accept());
+      client.sendTimeout = sendTimeout_;
+      client.recvTimeout = recvTimeout_;
+      return client;
+    } catch (SocketException e) {
+      throw new STE("Unknown error on accepting: " ~ to!string(e),
+        STE.Type.RESOURCE_FAILED);
+    }
+  }
+
+protected:
+  /**
+   * Allows derived classes to create a different TSocket type.
+   */
+  TSocket createTSocket(Socket socket) {
+    return new TSocket(socket);
+  }
+
+private:
+  ushort port_;
+  Duration sendTimeout_;
+  Duration recvTimeout_;
+  ushort retryLimit_;
+  Duration retryDelay_;
+  uint tcpSendBuffer_;
+  uint tcpRecvBuffer_;
+  bool ipv6Only_;
+
+  Socket serverSocket_;
+  TSocketNotifier cancellationNotifier_;
+
+  // Keep socket set between accept() calls to avoid reallocating.
+  SocketSet socketSet_;
+}
+
+Socket makeSocketAndListen(ushort port, int backlog, ushort retryLimit,
+  Duration retryDelay, uint tcpSendBuffer = 0, uint tcpRecvBuffer = 0,
+  bool ipv6Only = false
+) {
+  Address localAddr;
+  try {
+    // null represents the wildcard address.
+    auto addrInfos = getAddressInfo(null, to!string(port),
+      AddressInfoFlags.PASSIVE, SocketType.STREAM, ProtocolType.TCP);
+    foreach (i, ai; addrInfos) {
+      // Prefer to bind to IPv6 addresses, because then IPv4 is listened to as
+      // well, but not the other way round.
+      if (ai.family == AddressFamily.INET6 || i == (addrInfos.length - 1)) {
+        localAddr = ai.address;
+        break;
+      }
+    }
+  } catch (Exception e) {
+    throw new STE("Could not determine local address to listen on.",
+      STE.Type.RESOURCE_FAILED, __FILE__, __LINE__, e);
+  }
+
+  Socket socket;
+  try {
+    socket = new Socket(localAddr.addressFamily, SocketType.STREAM,
+      ProtocolType.TCP);
+  } catch (SocketException e) {
+    throw new STE("Could not create accepting socket: " ~ to!string(e),
+      STE.Type.RESOURCE_FAILED);
+  }
+
+  try {
+    socket.setOption(SocketOptionLevel.IPV6, SocketOption.IPV6_V6ONLY, ipv6Only);
+  } catch (SocketException e) {
+    // This is somewhat expected on older systems (e.g. pre-Vista Windows),
+    // which do not support the IPV6_V6ONLY flag yet. Racy flag just to avoid
+    // log spew in unit tests.
+    shared static warned = false;
+    if (!warned) {
+      logError("Could not set IPV6_V6ONLY socket option: %s", e);
+      warned = true;
+    }
+  }
+
+  alias SocketOptionLevel.SOCKET lvlSock;
+
+  // Prevent 2 maximum segement lifetime delay on accept.
+  try {
+    socket.setOption(lvlSock, SocketOption.REUSEADDR, true);
+  } catch (SocketException e) {
+    throw new STE("Could not set REUSEADDR socket option: " ~ to!string(e),
+      STE.Type.RESOURCE_FAILED);
+  }
+
+  // Set TCP buffer sizes.
+  if (tcpSendBuffer > 0) {
+    try {
+      socket.setOption(lvlSock, SocketOption.SNDBUF, tcpSendBuffer);
+    } catch (SocketException e) {
+      throw new STE("Could not set socket send buffer size: " ~ to!string(e),
+        STE.Type.RESOURCE_FAILED);
+    }
+  }
+
+  if (tcpRecvBuffer > 0) {
+    try {
+      socket.setOption(lvlSock, SocketOption.RCVBUF, tcpRecvBuffer);
+    } catch (SocketException e) {
+      throw new STE("Could not set receive send buffer size: " ~ to!string(e),
+        STE.Type.RESOURCE_FAILED);
+    }
+  }
+
+  // Turn linger off to avoid blocking on socket close.
+  try {
+    linger l;
+    l.on = 0;
+    l.time = 0;
+    socket.setOption(lvlSock, SocketOption.LINGER, l);
+  } catch (SocketException e) {
+    throw new STE("Could not disable socket linger: " ~ to!string(e),
+      STE.Type.RESOURCE_FAILED);
+  }
+
+  // Set TCP_NODELAY.
+  try {
+    socket.setOption(SocketOptionLevel.TCP, SocketOption.TCP_NODELAY, true);
+  } catch (SocketException e) {
+    throw new STE("Could not disable Nagle's algorithm: " ~ to!string(e),
+      STE.Type.RESOURCE_FAILED);
+  }
+
+  ushort retries;
+  while (true) {
+    try {
+      socket.bind(localAddr);
+      break;
+    } catch (SocketException) {}
+
+    // If bind() worked, we breaked outside the loop above.
+    retries++;
+    if (retries < retryLimit) {
+      Thread.sleep(retryDelay);
+    } else {
+      throw new STE(text("Could not bind to address: ", localAddr),
+        STE.Type.RESOURCE_FAILED);
+    }
+  }
+
+  socket.listen(backlog);
+  return socket;
+}
+
+unittest {
+  // Test interrupt().
+  {
+    auto sock = new TServerSocket(0);
+    sock.listen();
+    scope (exit) sock.close();
+
+    auto cancellation = new TCancellationOrigin;
+
+    auto intThread = new Thread({
+      // Sleep for a bit until the socket is accepting.
+      Thread.sleep(dur!"msecs"(50));
+      cancellation.trigger();
+    });
+    intThread.start();
+
+    import std.exception;
+    assertThrown!TCancelledException(sock.accept(cancellation));
+  }
+
+  // Test receive() timeout on accepted client sockets.
+  {
+    immutable port = 11122;
+    auto timeout = dur!"msecs"(500);
+    auto serverSock = new TServerSocket(port, timeout, timeout);
+    serverSock.listen();
+    scope (exit) serverSock.close();
+
+    auto clientSock = new TSocket("127.0.0.1", port);
+    clientSock.open();
+    scope (exit) clientSock.close();
+
+    shared bool hasTimedOut;
+    auto recvThread = new Thread({
+      auto sock = serverSock.accept();
+      ubyte[1] data;
+      try {
+        sock.read(data);
+      } catch (TTransportException e) {
+        if (e.type == TTransportException.Type.TIMED_OUT) {
+          hasTimedOut = true;
+        } else {
+          import std.stdio;
+          stderr.writeln(e);
+        }
+      }
+    });
+    recvThread.isDaemon = true;
+    recvThread.start();
+
+    // Wait for the timeout, with a little bit of spare time.
+    Thread.sleep(timeout + dur!"msecs"(50));
+    enforce(hasTimedOut,
+      "Client socket receive() blocked for longer than recvTimeout.");
+  }
+}
diff --git a/lib/d/src/thrift/server/transport/ssl.d b/lib/d/src/thrift/server/transport/ssl.d
new file mode 100644
index 0000000..2dd9d23
--- /dev/null
+++ b/lib/d/src/thrift/server/transport/ssl.d
@@ -0,0 +1,88 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+module thrift.server.transport.ssl;
+
+import std.datetime : Duration;
+import std.exception : enforce;
+import std.socket : Socket;
+import thrift.server.transport.socket;
+import thrift.transport.base;
+import thrift.transport.socket;
+import thrift.transport.ssl;
+
+/**
+ * A server transport implementation using SSL-encrypted sockets.
+ *
+ * Note:
+ * On Posix systems which do not have the BSD-specific SO_NOSIGPIPE flag, you
+ * might want to ignore the SIGPIPE signal, as OpenSSL might try to write to
+ * a closed socket if the peer disconnects abruptly:
+ * ---
+ * import core.stdc.signal;
+ * import core.sys.posix.signal;
+ * signal(SIGPIPE, SIG_IGN);
+ * ---
+ *
+ * See: thrift.transport.ssl.
+ */
+class TSSLServerSocket : TServerSocket {
+  /**
+   * Creates a new TSSLServerSocket.
+   *
+   * Params:
+   *   port = The port on which to listen.
+   *   sslContext = The TSSLContext to use for creating client
+   *     sockets. Must be in server-side mode.
+   */
+  this(ushort port, TSSLContext sslContext) {
+    super(port);
+    setSSLContext(sslContext);
+  }
+
+  /**
+   * Creates a new TSSLServerSocket.
+   *
+   * Params:
+   *   port = The port on which to listen.
+   *   sendTimeout = The send timeout to set on the client sockets.
+   *   recvTimeout = The receive timeout to set on the client sockets.
+   *   sslContext = The TSSLContext to use for creating client
+   *     sockets. Must be in server-side mode.
+   */
+  this(ushort port, Duration sendTimeout, Duration recvTimeout,
+    TSSLContext sslContext)
+  {
+    super(port, sendTimeout, recvTimeout);
+    setSSLContext(sslContext);
+  }
+
+protected:
+  override TSocket createTSocket(Socket socket) {
+    return new TSSLSocket(sslContext_, socket);
+  }
+
+private:
+  void setSSLContext(TSSLContext sslContext) {
+    enforce(sslContext.serverSide, new TTransportException(
+      "Need server-side SSL socket factory for TSSLServerSocket"));
+    sslContext_ = sslContext;
+  }
+
+  TSSLContext sslContext_;
+}
diff --git a/lib/d/src/thrift/transport/base.d b/lib/d/src/thrift/transport/base.d
new file mode 100644
index 0000000..7e76a59
--- /dev/null
+++ b/lib/d/src/thrift/transport/base.d
@@ -0,0 +1,370 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+module thrift.transport.base;
+
+import core.stdc.string : strerror;
+import std.conv : text;
+import thrift.base;
+
+/**
+ * An entity data can be read from and/or written to.
+ *
+ * A TTransport implementation may capable of either reading or writing, but
+ * not necessarily both.
+ */
+interface TTransport {
+  /**
+   * Whether this transport is open.
+   *
+   * If a transport is closed, it can be opened by calling open(), and vice
+   * versa for close().
+   *
+   * While a transport should always be open when trying to read/write data,
+   * the related functions do not necessarily fail when called for a closed
+   * transport. Situations like this could occur e.g. with a wrapper
+   * transport which buffers data when the underlying transport has already
+   * been closed (possibly because the connection was abruptly closed), but
+   * there is still data left to be read in the buffers. This choice has been
+   * made to simplify transport implementations, in terms of both  code
+   * complexity and runtime overhead.
+   */
+  bool isOpen() @property;
+
+  /**
+   * Tests whether there is more data to read or if the remote side is
+   * still open.
+   *
+   * A typical use case would be a server checking if it should process
+   * another request on the transport.
+   */
+  bool peek();
+
+  /**
+   * Opens the transport for communications.
+   *
+   * If the transport is already open, nothing happens.
+   *
+   * Throws: TTransportException if opening fails.
+   */
+  void open();
+
+  /**
+   * Closes the transport.
+   *
+   * If the transport is not open, nothing happens.
+   *
+   * Throws: TTransportException if closing fails.
+   */
+  void close();
+
+  /**
+   * Attempts to fill the given buffer by reading data.
+   *
+   * For potentially blocking data sources (e.g. sockets), read() will only
+   * block if no data is available at all. If there is some data available,
+   * but waiting for new data to arrive would be required to fill the whole
+   * buffer, the readily available data will be immediately returned – use
+   * readAll() if you want to wait until the whole buffer is filled.
+   *
+   * Params:
+   *   buf = Slice to use as buffer.
+   *
+   * Returns: How many bytes were actually read
+   *
+   * Throws: TTransportException if an error occurs.
+   */
+  size_t read(ubyte[] buf);
+
+  /**
+   * Fills the given buffer by reading data into it, failing if not enough
+   * data is available.
+   *
+   * Params:
+   *   buf = Slice to use as buffer.
+   *
+   * Throws: TTransportException if insufficient data is available or reading
+   *   fails altogether.
+   */
+  void readAll(ubyte[] buf);
+
+  /**
+   * Must be called by clients when read is completed.
+   *
+   * Implementations can choose to perform a transport-specific action, e.g.
+   * logging the request to a file.
+   *
+   * Returns: The number of bytes read if available, 0 otherwise.
+   */
+  size_t readEnd();
+
+  /**
+   * Writes the passed slice of data.
+   *
+   * Note: You must call flush() to ensure the data is actually written,
+   * and available to be read back in the future.  Destroying a TTransport
+   * object does not automatically flush pending data – if you destroy a
+   * TTransport object with written but unflushed data, that data may be
+   * discarded.
+   *
+   * Params:
+   *   buf = Slice of data to write.
+   *
+   * Throws: TTransportException if an error occurs.
+   */
+  void write(in ubyte[] buf);
+
+  /**
+   * Must be called by clients when write is completed.
+   *
+   * Implementations can choose to perform a transport-specific action, e.g.
+   * logging the request to a file.
+   *
+   * Returns: The number of bytes written if available, 0 otherwise.
+   */
+  size_t writeEnd();
+
+  /**
+   * Flushes any pending data to be written.
+   *
+   * Must be called before destruction to ensure writes are actually complete,
+   * otherwise pending data may be discarded. Typically used with buffered
+   * transport mechanisms.
+   *
+   * Throws: TTransportException if an error occurs.
+   */
+  void flush();
+
+  /**
+   * Attempts to return a slice of <code>len</code> bytes of incoming data,
+   * possibly copied into buf, not consuming them (i.e.: a later read will
+   * return the same data).
+   *
+   * This method is meant to support protocols that need to read variable-
+   * length fields. They can attempt to borrow the maximum amount of data that
+   * they will need, then <code>consume()</code> what they actually use. Some
+   * transports will not support this method and others will fail occasionally,
+   * so protocols must be prepared to fall back to <code>read()</code> if
+   * borrow fails.
+   *
+   * The transport must be open when calling this.
+   *
+   * Params:
+   *   buf = A buffer where the data can be stored if needed, or null to
+   *     indicate that the caller is not supplying storage, but would like a
+   *     slice of an internal buffer, if available.
+   *   len = The number of bytes to borrow.
+   *
+   * Returns: If the borrow succeeds, a slice containing the borrowed data,
+   *   null otherwise. The slice will be at least as long as requested, but
+   *   may be longer if the returned slice points into an internal buffer
+   *   rather than buf.
+   *
+   * Throws: TTransportException if an error occurs.
+   */
+  const(ubyte)[] borrow(ubyte* buf, size_t len) out (result) {
+    // FIXME: Commented out because len gets corrupted in
+    // thrift.transport.memory borrow() unittest.
+    version(none) assert(result is null || result.length >= len,
+       "Buffer returned by borrow() too short.");
+  }
+
+  /**
+   * Remove len bytes from the transport. This must always follow a borrow
+   * of at least len bytes, and should always succeed.
+   *
+   * The transport must be open when calling this.
+   *
+   * Params:
+   *   len = Number of bytes to consume.
+   *
+   * Throws: TTransportException if an error occurs.
+   */
+  void consume(size_t len);
+}
+
+/**
+ * Provides basic fall-back implementations of the TTransport interface.
+ */
+class TBaseTransport : TTransport {
+  override bool isOpen() @property {
+    return false;
+  }
+
+  override bool peek() {
+    return isOpen;
+  }
+
+  override void open() {
+    throw new TTransportException("Cannot open TBaseTransport.",
+      TTransportException.Type.NOT_IMPLEMENTED);
+  }
+
+  override void close() {
+    throw new TTransportException("Cannot close TBaseTransport.",
+      TTransportException.Type.NOT_IMPLEMENTED);
+  }
+
+  override size_t read(ubyte[] buf) {
+    throw new TTransportException("Cannot read from a TBaseTransport.",
+      TTransportException.Type.NOT_IMPLEMENTED);
+  }
+
+  override void readAll(ubyte[] buf) {
+    size_t have;
+    while (have < buf.length) {
+      size_t get = read(buf[have..$]);
+      if (get <= 0) {
+        throw new TTransportException(text("Could not readAll() ", buf.length,
+          " bytes as no more data was available after ", have, " bytes."),
+          TTransportException.Type.END_OF_FILE);
+      }
+      have += get;
+    }
+  }
+
+  override size_t readEnd() {
+    // Do nothing by default, not needed by all implementations.
+    return 0;
+  }
+
+  override void write(in ubyte[] buf) {
+    throw new TTransportException("Cannot write to a TBaseTransport.",
+      TTransportException.Type.NOT_IMPLEMENTED);
+  }
+
+  override size_t writeEnd() {
+    // Do nothing by default, not needed by all implementations.
+    return 0;
+  }
+
+  override void flush() {
+    // Do nothing by default, not needed by all implementations.
+  }
+
+  override const(ubyte)[] borrow(ubyte* buf, size_t len) {
+    // borrow() is allowed to fail anyway, so just return null.
+    return null;
+  }
+
+  override void consume(size_t len) {
+    throw new TTransportException("Cannot consume from a TBaseTransport.",
+      TTransportException.Type.NOT_IMPLEMENTED);
+  }
+
+protected:
+  this() {}
+}
+
+/**
+ * Makes a TTransport which wraps a given source transport in some way.
+ *
+ * A common use case is inside server implementations, where the raw client
+ * connections accepted from e.g. TServerSocket need to be wrapped into
+ * buffered or compressed transports.
+ */
+class TTransportFactory {
+  /**
+   * Default implementation does nothing, just returns the transport given.
+   */
+  TTransport getTransport(TTransport trans) {
+    return trans;
+  }
+}
+
+/**
+ * Transport factory for transports which simply wrap an underlying TTransport
+ * without requiring additional configuration.
+ */
+class TWrapperTransportFactory(T) if (
+  is(T : TTransport) && __traits(compiles, new T(TTransport.init))
+)  : TTransportFactory {
+  override T getTransport(TTransport trans) {
+    return new T(trans);
+  }
+}
+
+/**
+ * Transport-level exception.
+ */
+class TTransportException : TException {
+  /**
+   * Error codes for the various types of exceptions.
+   */
+  enum Type {
+    UNKNOWN, ///
+    NOT_OPEN, ///
+    TIMED_OUT, ///
+    END_OF_FILE, ///
+    INTERRUPTED, ///
+    BAD_ARGS, ///
+    CORRUPTED_DATA, ///
+    INTERNAL_ERROR, ///
+    NOT_IMPLEMENTED ///
+  }
+
+  ///
+  this(Type type, string file = __FILE__, size_t line = __LINE__, Throwable next = null) {
+    static string msgForType(Type type) {
+      switch (type) {
+        case Type.UNKNOWN: return "Unknown transport exception";
+        case Type.NOT_OPEN: return "Transport not open";
+        case Type.TIMED_OUT: return "Timed out";
+        case Type.END_OF_FILE: return "End of file";
+        case Type.INTERRUPTED: return "Interrupted";
+        case Type.BAD_ARGS: return "Invalid arguments";
+        case Type.CORRUPTED_DATA: return "Corrupted Data";
+        case Type.INTERNAL_ERROR: return "Internal error";
+        case Type.NOT_IMPLEMENTED: return "Not implemented";
+        default: return "(Invalid exception type)";
+      }
+    }
+    this(msgForType(type), type, file, line, next);
+  }
+
+  ///
+  this(string msg, string file = __FILE__, size_t line = __LINE__,
+    Throwable next = null)
+  {
+    this(msg, Type.UNKNOWN, file, line, next);
+  }
+
+  ///
+  this(string msg, Type type, string file = __FILE__, size_t line = __LINE__,
+    Throwable next = null)
+  {
+    super(msg, file, line, next);
+    type_ = type;
+  }
+
+  ///
+  Type type() const nothrow @property {
+    return type_;
+  }
+
+protected:
+  Type type_;
+}
+
+/**
+ * Meta-programming helper returning whether the passed type is a TTransport
+ * implementation.
+ */
+template isTTransport(T) {
+  enum isTTransport = is(T : TTransport);
+}
diff --git a/lib/d/src/thrift/transport/buffered.d b/lib/d/src/thrift/transport/buffered.d
new file mode 100644
index 0000000..cabfbdc
--- /dev/null
+++ b/lib/d/src/thrift/transport/buffered.d
@@ -0,0 +1,215 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+module thrift.transport.buffered;
+
+import std.algorithm : min;
+import std.array : empty;
+import std.exception : enforce;
+import thrift.transport.base;
+
+/**
+ * Wraps another transport and buffers reads and writes until the internal
+ * buffers are exhausted, at which point new data is fetched resp. the
+ * accumulated data is written out at once.
+ */
+final class TBufferedTransport : TBaseTransport {
+  /**
+   * Constructs a new instance, using the default buffer sizes.
+   *
+   * Params:
+   *   transport = The underlying transport to wrap.
+   */
+  this(TTransport transport) {
+    this(transport, DEFAULT_BUFFER_SIZE);
+  }
+
+  /**
+   * Constructs a new instance, using the specified buffer size.
+   *
+   * Params:
+   *   transport = The underlying transport to wrap.
+   *   bufferSize = The size of the read and write buffers to use, in bytes.
+   */
+  this(TTransport transport, size_t bufferSize) {
+    this(transport, bufferSize, bufferSize);
+  }
+
+  /**
+   * Constructs a new instance, using the specified buffer size.
+   *
+   * Params:
+   *   transport = The underlying transport to wrap.
+   *   readBufferSize = The size of the read buffer to use, in bytes.
+   *   writeBufferSize = The size of the write buffer to use, in bytes.
+   */
+  this(TTransport transport, size_t readBufferSize, size_t writeBufferSize) {
+    transport_ = transport;
+    readBuffer_ = new ubyte[readBufferSize];
+    writeBuffer_ = new ubyte[writeBufferSize];
+    writeAvail_ = writeBuffer_;
+  }
+
+  /// The default size of the read/write buffers, in bytes.
+  enum int DEFAULT_BUFFER_SIZE = 512;
+
+  override bool isOpen() @property {
+    return transport_.isOpen();
+  }
+
+  override bool peek() {
+    if (readAvail_.empty) {
+      // If there is nothing available to read, see if we can get something
+      // from the underlying transport.
+      auto bytesRead = transport_.read(readBuffer_);
+      readAvail_ = readBuffer_[0 .. bytesRead];
+    }
+
+    return !readAvail_.empty;
+  }
+
+  override void open() {
+    transport_.open();
+  }
+
+  override void close() {
+    if (!isOpen) return;
+    flush();
+    transport_.close();
+  }
+
+  override size_t read(ubyte[] buf) {
+    if (readAvail_.empty) {
+      // No data left in our buffer, fetch some from the underlying transport.
+
+      if (buf.length > readBuffer_.length) {
+        // If the amount of data requested is larger than our reading buffer,
+        // directly read to the passed buffer. This probably doesn't occur too
+        // often in practice (and even if it does, the underlying transport
+        // probably cannot fulfill the request at once anyway), but it can't
+        // harm to try…
+        return transport_.read(buf);
+      }
+
+      auto bytesRead = transport_.read(readBuffer_);
+      readAvail_ = readBuffer_[0 .. bytesRead];
+    }
+
+    // Hand over whatever we have.
+    auto give = min(readAvail_.length, buf.length);
+    buf[0 .. give] = readAvail_[0 .. give];
+    readAvail_ = readAvail_[give .. $];
+    return give;
+  }
+
+  /**
+   * Shortcut version of readAll.
+   */
+  override void readAll(ubyte[] buf) {
+    if (readAvail_.length >= buf.length) {
+      buf[] = readAvail_[0 .. buf.length];
+      readAvail_ = readAvail_[buf.length .. $];
+      return;
+    }
+
+    super.readAll(buf);
+  }
+
+  override void write(in ubyte[] buf) {
+    if (writeAvail_.length >= buf.length) {
+      // If the data fits in the buffer, just save it there.
+      writeAvail_[0 .. buf.length] = buf;
+      writeAvail_ = writeAvail_[buf.length .. $];
+      return;
+    }
+
+    // We have to decide if we copy data from buf to our internal buffer, or
+    // just directly write them out. The same considerations about avoiding
+    // syscalls as for C++ apply here.
+    auto bytesAvail = writeAvail_.ptr - writeBuffer_.ptr;
+    if ((bytesAvail + buf.length >= 2 * writeBuffer_.length) || (bytesAvail == 0)) {
+      // We would immediately need two syscalls anyway (or we don't have
+      // anything) in our buffer to write, so just write out both buffers.
+      if (bytesAvail > 0) {
+        transport_.write(writeBuffer_[0 .. bytesAvail]);
+        writeAvail_ = writeBuffer_;
+      }
+
+      transport_.write(buf);
+      return;
+    }
+
+    // Fill up our internal buffer for a write.
+    writeAvail_[] = buf[0 .. writeAvail_.length];
+    auto left = buf[writeAvail_.length .. $];
+    transport_.write(writeBuffer_);
+
+    // Copy the rest into our buffer.
+    writeBuffer_[0 .. left.length] = left[];
+    writeAvail_ = writeBuffer_[left.length .. $];
+  }
+
+  override void flush() {
+    // Write out any data waiting in the write buffer.
+    auto bytesAvail = writeAvail_.ptr - writeBuffer_.ptr;
+    if (bytesAvail > 0) {
+      // Note that we reset writeAvail_ prior to calling the underlying protocol
+      // to make sure the buffer is cleared even if the transport throws an
+      // exception.
+      writeAvail_ = writeBuffer_;
+      transport_.write(writeBuffer_[0 .. bytesAvail]);
+    }
+
+    // Flush the underlying transport.
+    transport_.flush();
+  }
+
+  override const(ubyte)[] borrow(ubyte* buf, size_t len) {
+    if (len <= readAvail_.length) {
+      return readAvail_;
+    }
+    return null;
+  }
+
+  override void consume(size_t len) {
+    enforce(len <= readBuffer_.length, new TTransportException(
+      "Invalid consume length.", TTransportException.Type.BAD_ARGS));
+    readAvail_ = readAvail_[len .. $];
+  }
+
+  /**
+   * The wrapped transport.
+   */
+  TTransport underlyingTransport() @property {
+    return transport_;
+  }
+
+private:
+  TTransport transport_;
+
+  ubyte[] readBuffer_;
+  ubyte[] writeBuffer_;
+
+  ubyte[] readAvail_;
+  ubyte[] writeAvail_;
+}
+
+/**
+ * Wraps given transports into TBufferedTransports.
+ */
+alias TWrapperTransportFactory!TBufferedTransport TBufferedTransportFactory;
diff --git a/lib/d/src/thrift/transport/file.d b/lib/d/src/thrift/transport/file.d
new file mode 100644
index 0000000..7c6705a
--- /dev/null
+++ b/lib/d/src/thrift/transport/file.d
@@ -0,0 +1,1100 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/**
+ * Transports for reading from/writing to Thrift »log files«.
+ *
+ * These transports are not »stupid« sources and sinks just reading and
+ * writing bytes from a file verbatim, but organize the contents in the form
+ * of so-called »events«, which refers to the data written between two flush()
+ * calls.
+ *
+ * Chunking is supported, events are guaranteed to never span chunk boundaries.
+ * As a consequence, an event can never be larger than the chunk size. The
+ * chunk size used is not saved with the file, so care has to be taken to make
+ * sure the same chunk size is used for reading and writing.
+ */
+module thrift.transport.file;
+
+import core.thread : Thread;
+import std.array : empty;
+import std.algorithm : min, max;
+import std.concurrency;
+import std.conv : to;
+import std.datetime : AutoStart, dur, Duration, StopWatch;
+import std.exception;
+import std.stdio : File;
+import thrift.base;
+import thrift.transport.base;
+
+/// The default chunk size, in bytes.
+enum DEFAULT_CHUNK_SIZE = 16 * 1024 * 1024;
+
+/// The type used to represent event sizes in the file.
+alias uint EventSize;
+
+version (BigEndian) {
+  static assert(false,
+    "Little endian byte order is assumed in thrift.transport.file.");
+}
+
+/**
+ * A transport used to read log files. It can never be written to, calling
+ * write() throws.
+ *
+ * Contrary to the C++ design, explicitly opening the transport/file before
+ * using is necessary to allow manually closing the file without relying on the
+ * object lifetime. Otherwise, it's a straight port of the C++ implementation.
+ */
+final class TFileReaderTransport : TBaseTransport {
+  /**
+   * Creates a new file writer transport.
+   *
+   * Params:
+   *   path = Path of the file to opperate on.
+   */
+  this(string path) {
+    path_ = path;
+    chunkSize_ = DEFAULT_CHUNK_SIZE;
+    readBufferSize_ = DEFAULT_READ_BUFFER_SIZE;
+    readTimeout_ = DEFAULT_READ_TIMEOUT;
+    corruptedEventSleepDuration_ = DEFAULT_CORRUPTED_EVENT_SLEEP_DURATION;
+    maxEventSize = DEFAULT_MAX_EVENT_SIZE;
+  }
+
+  override bool isOpen() @property {
+    return isOpen_;
+  }
+
+  override bool peek() {
+    if (!isOpen) return false;
+
+    // If there is no event currently processed, try fetching one from the
+    // file.
+    if (!currentEvent_) {
+      currentEvent_ = readEvent();
+
+      if (!currentEvent_) {
+        // Still nothing there, couldn't read a new event.
+        return false;
+      }
+    }
+    // check if there is anything to read
+    return (currentEvent_.length - currentEventPos_) > 0;
+  }
+
+  override void open() {
+    if (isOpen) return;
+    try {
+      file_ = File(path_, "rb");
+    } catch (Exception e) {
+      throw new TTransportException("Error on opening input file.",
+        TTransportException.Type.NOT_OPEN, __FILE__, __LINE__, e);
+    }
+    isOpen_ = true;
+  }
+
+  override void close() {
+    if (!isOpen) return;
+
+    file_.close();
+    isOpen_ = false;
+    readState_.resetAllValues();
+  }
+
+  override size_t read(ubyte[] buf) {
+    enforce(isOpen, new TTransportException(
+      "Cannot read if file is not open.", TTransportException.Type.NOT_OPEN));
+
+    // If there is no event currently processed, try fetching one from the
+    // file.
+    if (!currentEvent_) {
+      currentEvent_ = readEvent();
+
+      if (!currentEvent_) {
+        // Still nothing there, couldn't read a new event.
+        return 0;
+      }
+    }
+
+    auto len = buf.length;
+    auto remaining = currentEvent_.length - currentEventPos_;
+
+    if (remaining <= len) {
+      // If less than the requested length is available, read as much as
+      // possible.
+      buf[0 .. remaining] = currentEvent_[currentEventPos_ .. $];
+      currentEvent_ = null;
+      currentEventPos_ = 0;
+      return remaining;
+    }
+
+    // There will still be data left in the buffer after reading, pass out len
+    // bytes.
+    buf[] = currentEvent_[currentEventPos_ .. currentEventPos_ + len];
+    currentEventPos_ += len;
+    return len;
+  }
+
+  ulong getNumChunks() {
+    enforce(isOpen, new TTransportException(
+      "Cannot get number of chunks if file not open.",
+      TTransportException.Type.NOT_OPEN));
+
+    try {
+      auto fileSize = file_.size();
+      if (fileSize == 0) {
+        // Empty files have no chunks.
+        return 0;
+      }
+      return ((fileSize)/chunkSize_) + 1;
+    } catch (Exception e) {
+      throw new TTransportException("Error getting file size.", __FILE__,
+        __LINE__, e);
+    }
+  }
+
+  ulong getCurChunk() {
+    return offset_ / chunkSize_;
+  }
+
+  void seekToChunk(long chunk) {
+    enforce(isOpen, new TTransportException(
+      "Cannot get number of chunks if file not open.",
+      TTransportException.Type.NOT_OPEN));
+
+    auto numChunks = getNumChunks();
+
+    if (chunk < 0) {
+      // Count negative indices from the end.
+      chunk += numChunks;
+    }
+
+    if (chunk < 0) {
+      logError("Incorrect chunk number for reverse seek, seeking to " ~
+       "beginning instead: %s", chunk);
+      chunk = 0;
+    }
+
+    bool seekToEnd;
+    long minEndOffset;
+    if (chunk >= numChunks) {
+      logError("Trying to seek to non-existing chunk, seeking to " ~
+       "end of file instead: %s", chunk);
+      seekToEnd = true;
+      chunk = numChunks - 1;
+      // this is the min offset to process events till
+      minEndOffset = file_.size();
+    }
+
+    readState_.resetAllValues();
+    currentEvent_ = null;
+
+    try {
+      file_.seek(chunk * chunkSize_);
+      offset_ = chunk * chunkSize_;
+    } catch (Exception e) {
+      throw new TTransportException("Error seeking to chunk", __FILE__,
+        __LINE__, e);
+    }
+
+    if (seekToEnd) {
+      // Never wait on the end of the file for new content, we just want to
+      // find the last one.
+      auto oldReadTimeout = readTimeout_;
+      scope (exit) readTimeout_ = oldReadTimeout;
+      readTimeout_ = dur!"hnsecs"(0);
+
+      // Keep on reading unti the last event at point of seekToChunk call.
+      while ((offset_ + readState_.bufferPos_) < minEndOffset) {
+        if (readEvent() is null) {
+          break;
+        }
+      }
+    }
+  }
+
+  void seekToEnd() {
+    seekToChunk(getNumChunks());
+  }
+
+  /**
+   * The size of the chunks the file is divided into, in bytes.
+   */
+  ulong chunkSize() @property const {
+    return chunkSize_;
+  }
+
+  /// ditto
+  void chunkSize(ulong value) @property {
+    enforce(!isOpen, new TTransportException(
+      "Cannot set chunk size after TFileReaderTransport has been opened."));
+    enforce(value > EventSize.sizeof, new TTransportException("Chunks must " ~
+      "be large enough to accomodate at least a single byte of payload data."));
+    chunkSize_ = value;
+  }
+
+  /**
+   * If positive, wait the specified duration for new data when arriving at
+   * end of file. If negative, wait forever (tailing mode), waking up to check
+   * in the specified interval. If zero, do not wait at all.
+   *
+   * Defaults to 500 ms.
+   */
+  Duration readTimeout() @property const {
+    return readTimeout_;
+  }
+
+  /// ditto
+  void readTimeout(Duration value) @property {
+    readTimeout_ = value;
+  }
+
+  /// ditto
+  enum DEFAULT_READ_TIMEOUT = dur!"msecs"(500);
+
+  /**
+   * Read buffer size, in bytes.
+   *
+   * Defaults to 1 MiB.
+   */
+  size_t readBufferSize() @property const {
+    return readBufferSize_;
+  }
+
+  /// ditto
+  void readBufferSize(size_t value) @property {
+    if (readBuffer_) {
+      enforce(value <= readBufferSize_,
+        "Cannot shrink read buffer after first read.");
+      readBuffer_.length = value;
+    }
+    readBufferSize_ = value;
+  }
+
+  /// ditto
+  enum DEFAULT_READ_BUFFER_SIZE = 1 * 1024 * 1024;
+
+  /**
+   * Arbitrary event size limit, in bytes. Must be smaller than chunk size.
+   *
+   * Defaults to zero (no limit).
+   */
+  size_t maxEventSize() @property const {
+    return maxEventSize_;
+  }
+
+  /// ditto
+  void maxEventSize(size_t value) @property {
+    enforce(value <= chunkSize_ - EventSize.sizeof, "Events cannot span " ~
+      "mutiple chunks, maxEventSize must be smaller than chunk size.");
+    maxEventSize_ = value;
+  }
+
+  /// ditto
+  enum DEFAULT_MAX_EVENT_SIZE = 0;
+
+  /**
+   * The interval at which the thread wakes up to check for the next chunk
+   * in tailing mode.
+   *
+   * Defaults to one second.
+   */
+  Duration corruptedEventSleepDuration() const {
+    return corruptedEventSleepDuration_;
+  }
+
+  /// ditto
+  void corruptedEventSleepDuration(Duration value) {
+    corruptedEventSleepDuration_ = value;
+  }
+
+  /// ditto
+  enum DEFAULT_CORRUPTED_EVENT_SLEEP_DURATION = dur!"seconds"(1);
+
+  /**
+   * The maximum number of corrupted events tolerated before the whole chunk
+   * is skipped.
+   *
+   * Defaults to zero.
+   */
+  uint maxCorruptedEvents() @property const {
+    return maxCorruptedEvents_;
+  }
+
+  /// ditto
+  void maxCorruptedEvents(uint value) @property {
+    maxCorruptedEvents_ = value;
+  }
+
+  /// ditto
+  enum DEFAULT_MAX_CORRUPTED_EVENTS = 0;
+
+private:
+  ubyte[] readEvent() {
+    if (!readBuffer_) {
+      readBuffer_ = new ubyte[readBufferSize_];
+    }
+
+    bool timeoutExpired;
+    while (1) {
+      // read from the file if read buffer is exhausted
+      if (readState_.bufferPos_ == readState_.bufferLen_) {
+        // advance the offset pointer
+        offset_ += readState_.bufferLen_;
+
+        try {
+          // Need to clear eof flag before reading, otherwise tailing a file
+          // does not work.
+          file_.clearerr();
+
+          auto usedBuf = file_.rawRead(readBuffer_);
+          readState_.bufferLen_ = usedBuf.length;
+        } catch (Exception e) {
+          readState_.resetAllValues();
+          throw new TTransportException("Error while reading from file",
+            __FILE__, __LINE__, e);
+        }
+
+        readState_.bufferPos_ = 0;
+        readState_.lastDispatchPos_ = 0;
+
+        if (readState_.bufferLen_ == 0) {
+          // Reached end of file.
+          if (readTimeout_ < dur!"hnsecs"(0)) {
+            // Tailing mode, sleep for the specified duration and try again.
+            Thread.sleep(-readTimeout_);
+            continue;
+          } else if (readTimeout_ == dur!"hnsecs"(0) || timeoutExpired) {
+            // Either no timeout set, or it has already expired.
+            readState_.resetState(0);
+            return null;
+          } else {
+            // Timeout mode, sleep for the specified amount of time and retry.
+            Thread.sleep(readTimeout_);
+            timeoutExpired = true;
+            continue;
+          }
+        }
+      }
+
+      // Attempt to read an event from the buffer.
+      while (readState_.bufferPos_ < readState_.bufferLen_) {
+        if (readState_.readingSize_) {
+          if (readState_.eventSizeBuffPos_ == 0) {
+            if ((offset_ + readState_.bufferPos_)/chunkSize_ !=
+              ((offset_ + readState_.bufferPos_ + 3)/chunkSize_))
+            {
+              readState_.bufferPos_++;
+              continue;
+            }
+          }
+
+          readState_.eventSizeBuff_[readState_.eventSizeBuffPos_++] =
+            readBuffer_[readState_.bufferPos_++];
+
+          if (readState_.eventSizeBuffPos_ == 4) {
+            auto size = (cast(uint[])readState_.eventSizeBuff_)[0];
+
+            if (size == 0) {
+              // This is part of the zero padding between chunks.
+              readState_.resetState(readState_.lastDispatchPos_);
+              continue;
+            }
+
+            // got a valid event
+            readState_.readingSize_ = false;
+            readState_.eventLen_ = size;
+            readState_.eventPos_ = 0;
+
+            // check if the event is corrupted and perform recovery if required
+            if (isEventCorrupted()) {
+              performRecovery();
+              // start from the top
+              break;
+            }
+          }
+        } else {
+          if (!readState_.event_) {
+            readState_.event_ = new ubyte[readState_.eventLen_];
+          }
+
+          // take either the entire event or the remaining bytes in the buffer
+          auto reclaimBuffer = min(readState_.bufferLen_ - readState_.bufferPos_,
+            readState_.eventLen_ - readState_.eventPos_);
+
+          // copy data from read buffer into event buffer
+          readState_.event_[
+            readState_.eventPos_ .. readState_.eventPos_ + reclaimBuffer
+          ] = readBuffer_[
+            readState_.bufferPos_ .. readState_.bufferPos_ + reclaimBuffer
+          ];
+
+          // increment position ptrs
+          readState_.eventPos_ += reclaimBuffer;
+          readState_.bufferPos_ += reclaimBuffer;
+
+          // check if the event has been read in full
+          if (readState_.eventPos_ == readState_.eventLen_) {
+            // Reset the read state and return the completed event.
+            auto completeEvent = readState_.event_;
+            readState_.event_ = null;
+            readState_.resetState(readState_.bufferPos_);
+            return completeEvent;
+          }
+        }
+      }
+    }
+  }
+
+  bool isEventCorrupted() {
+    if ((maxEventSize_ > 0) && (readState_.eventLen_ > maxEventSize_)) {
+      // Event size is larger than user-speficied max-event size
+      logError("Corrupt event read: Event size (%s) greater than max " ~
+        "event size (%s)", readState_.eventLen_, maxEventSize_);
+      return true;
+    } else if (readState_.eventLen_ > chunkSize_) {
+      // Event size is larger than chunk size
+      logError("Corrupt event read: Event size (%s) greater than chunk " ~
+        "size (%s)", readState_.eventLen_, chunkSize_);
+      return true;
+    } else if (((offset_ + readState_.bufferPos_ - EventSize.sizeof) / chunkSize_) !=
+      ((offset_ + readState_.bufferPos_ + readState_.eventLen_ - EventSize.sizeof) / chunkSize_))
+    {
+      // Size indicates that event crosses chunk boundary
+      logError("Read corrupt event. Event crosses chunk boundary. " ~
+        "Event size: %s. Offset: %s", readState_.eventLen_,
+        (offset_ + readState_.bufferPos_ + EventSize.sizeof)
+      );
+
+      return true;
+    }
+
+    return false;
+  }
+
+  void performRecovery() {
+    // perform some kickass recovery
+    auto curChunk = getCurChunk();
+    if (lastBadChunk_ == curChunk) {
+      numCorruptedEventsInChunk_++;
+    } else {
+      lastBadChunk_ = curChunk;
+      numCorruptedEventsInChunk_ = 1;
+    }
+
+    if (numCorruptedEventsInChunk_ < maxCorruptedEvents_) {
+      // maybe there was an error in reading the file from disk
+      // seek to the beginning of chunk and try again
+      seekToChunk(curChunk);
+    } else {
+      // Just skip ahead to the next chunk if we not already at the last chunk.
+      if (curChunk != (getNumChunks() - 1)) {
+        seekToChunk(curChunk + 1);
+      } else if (readTimeout_ < dur!"hnsecs"(0)) {
+        // We are in tailing mode, wait until there is enough data to start
+        // the next chunk.
+        while(curChunk == (getNumChunks() - 1)) {
+          Thread.sleep(corruptedEventSleepDuration_);
+        }
+        seekToChunk(curChunk + 1);
+      } else {
+        // Pretty hosed at this stage, rewind the file back to the last
+        // successful point and punt on the error.
+        readState_.resetState(readState_.lastDispatchPos_);
+        currentEvent_ = null;
+        currentEventPos_ = 0;
+
+        throw new TTransportException("File corrupted at offset: " ~
+          to!string(offset_ + readState_.lastDispatchPos_),
+          TTransportException.Type.CORRUPTED_DATA);
+      }
+    }
+  }
+
+  string path_;
+  File file_;
+  bool isOpen_;
+  long offset_;
+  ubyte[] currentEvent_;
+  size_t currentEventPos_;
+  ulong chunkSize_;
+  Duration readTimeout_;
+  size_t maxEventSize_;
+
+  // Read buffer – lazily allocated on the first read().
+  ubyte[] readBuffer_;
+  size_t readBufferSize_;
+
+  static struct ReadState {
+    ubyte[] event_;
+    size_t eventLen_;
+    size_t eventPos_;
+
+    // keep track of event size
+    ubyte[4] eventSizeBuff_;
+    ubyte eventSizeBuffPos_;
+    bool readingSize_ = true;
+
+    // read buffer variables
+    size_t bufferPos_;
+    size_t bufferLen_;
+
+    // last successful dispatch point
+    size_t lastDispatchPos_;
+
+    void resetState(size_t lastDispatchPos) {
+      readingSize_ = true;
+      eventSizeBuffPos_ = 0;
+      lastDispatchPos_ = lastDispatchPos;
+    }
+
+    void resetAllValues() {
+      resetState(0);
+      bufferPos_ = 0;
+      bufferLen_ = 0;
+      event_ = null;
+    }
+  }
+  ReadState readState_;
+
+  ulong lastBadChunk_;
+  uint maxCorruptedEvents_;
+  uint numCorruptedEventsInChunk_;
+  Duration corruptedEventSleepDuration_;
+}
+
+/**
+ * A transport used to write log files. It can never be read from, calling
+ * read() throws.
+ *
+ * Contrary to the C++ design, explicitly opening the transport/file before
+ * using is necessary to allow manually closing the file without relying on the
+ * object lifetime.
+ */
+final class TFileWriterTransport : TBaseTransport {
+  /**
+   * Creates a new file writer transport.
+   *
+   * Params:
+   *   path = Path of the file to opperate on.
+   */
+  this(string path) {
+    path_ = path;
+
+    chunkSize_ = DEFAULT_CHUNK_SIZE;
+    eventBufferSize_ = DEFAULT_EVENT_BUFFER_SIZE;
+    ioErrorSleepDuration = DEFAULT_IO_ERROR_SLEEP_DURATION;
+    maxFlushBytes_ = DEFAULT_MAX_FLUSH_BYTES;
+    maxFlushInterval_ = DEFAULT_MAX_FLUSH_INTERVAL;
+  }
+
+  override bool isOpen() @property {
+    return isOpen_;
+  }
+
+  /**
+   * A file writer transport can never be read from.
+   */
+  override bool peek() {
+    return false;
+  }
+
+  override void open() {
+    if (isOpen) return;
+
+    writerThread_ = spawn(
+      &writerThread,
+      path_,
+      chunkSize_,
+      maxFlushBytes_,
+      maxFlushInterval_,
+      ioErrorSleepDuration_
+    );
+    setMaxMailboxSize(writerThread_, eventBufferSize_, OnCrowding.block);
+    isOpen_ = true;
+  }
+
+  /**
+   * Closes the transport, i.e. the underlying file and the writer thread.
+   */
+  override void close() {
+    if (!isOpen) return;
+
+    prioritySend(writerThread_, ShutdownMessage(), thisTid); // FIXME: Should use normal send here.
+    receive((ShutdownMessage msg, Tid tid){});
+    isOpen_ = false;
+  }
+
+  /**
+   * Enqueues the passed slice of data for writing and immediately returns.
+   * write() only blocks if the event buffer has been exhausted.
+   *
+   * The transport must be open when calling this.
+   *
+   * Params:
+   *   buf = Slice of data to write.
+   */
+  override void write(in ubyte[] buf) {
+    enforce(isOpen, new TTransportException(
+      "Cannot write to non-open file.", TTransportException.Type.NOT_OPEN));
+
+    if (buf.empty) {
+      logError("Cannot write empty event, skipping.");
+      return;
+    }
+
+    auto maxSize = chunkSize - EventSize.sizeof;
+    enforce(buf.length <= maxSize, new TTransportException(
+      "Cannot write more than " ~ to!string(maxSize) ~
+      "bytes at once due to chunk size."));
+
+    send(writerThread_, buf.idup);
+  }
+
+  /**
+   * Flushes any pending data to be written.
+   *
+   * The transport must be open when calling this.
+   *
+   * Throws: TTransportException if an error occurs.
+   */
+  override void flush() {
+    enforce(isOpen, new TTransportException(
+      "Cannot flush file if not open.", TTransportException.Type.NOT_OPEN));
+
+    send(writerThread_, FlushMessage(), thisTid);
+    receive((FlushMessage msg, Tid tid){});
+  }
+
+  /**
+   * The size of the chunks the file is divided into, in bytes.
+   *
+   * A single event (write call) never spans multiple chunks – this
+   * effectively limits the event size to chunkSize - EventSize.sizeof.
+   */
+  ulong chunkSize() @property {
+    return chunkSize_;
+  }
+
+  /// ditto
+  void chunkSize(ulong value) @property {
+    enforce(!isOpen, new TTransportException(
+      "Cannot set chunk size after TFileWriterTransport has been opened."));
+    chunkSize_ = value;
+  }
+
+  /**
+   * The maximum number of write() calls buffered, or zero for no limit.
+   *
+   * If the buffer is exhausted, write() will block until space becomes
+   * available.
+   */
+  size_t eventBufferSize() @property {
+    return eventBufferSize_;
+  }
+
+  /// ditto
+  void eventBufferSize(size_t value) @property {
+    eventBufferSize_ = value;
+    if (isOpen) {
+      setMaxMailboxSize(writerThread_, value, OnCrowding.throwException);
+    }
+  }
+
+  /// ditto
+  enum DEFAULT_EVENT_BUFFER_SIZE = 10_000;
+
+  /**
+   * Maximum number of bytes buffered before writing and flushing the file
+   * to disk.
+   *
+   * Currently cannot be set after the first call to write().
+   */
+  size_t maxFlushBytes() @property {
+    return maxFlushBytes_;
+  }
+
+  /// ditto
+  void maxFlushBytes(size_t value) @property {
+    maxFlushBytes_ = value;
+    if (isOpen) {
+      send(writerThread_, FlushBytesMessage(value));
+    }
+  }
+
+  /// ditto
+  enum DEFAULT_MAX_FLUSH_BYTES = 1000 * 1024;
+
+  /**
+   * Maximum interval between flushing the file to disk.
+   *
+   * Currenlty cannot be set after the first call to write().
+   */
+  Duration maxFlushInterval() @property {
+    return maxFlushInterval_;
+  }
+
+  /// ditto
+  void maxFlushInterval(Duration value) @property {
+    maxFlushInterval_ = value;
+    if (isOpen) {
+      send(writerThread_, FlushIntervalMessage(value));
+    }
+  }
+
+  /// ditto
+  enum DEFAULT_MAX_FLUSH_INTERVAL = dur!"seconds"(3);
+
+  /**
+   * When the writer thread encounteres an I/O error, it goes pauses for a
+   * short time before trying to reopen the output file. This controls the
+   * sleep duration.
+   */
+  Duration ioErrorSleepDuration() @property {
+    return ioErrorSleepDuration_;
+  }
+
+  /// ditto
+  void ioErrorSleepDuration(Duration value) @property {
+    ioErrorSleepDuration_ = value;
+    if (isOpen) {
+      send(writerThread_, FlushIntervalMessage(value));
+    }
+  }
+
+  /// ditto
+  enum DEFAULT_IO_ERROR_SLEEP_DURATION = dur!"msecs"(500);
+
+private:
+  string path_;
+  ulong chunkSize_;
+  size_t eventBufferSize_;
+  Duration ioErrorSleepDuration_;
+  size_t maxFlushBytes_;
+  Duration maxFlushInterval_;
+  bool isOpen_;
+  Tid writerThread_;
+}
+
+private {
+  // Signals that the file should be flushed on disk. Sent to the writer
+  // thread and sent back along with the tid for confirmation.
+  struct FlushMessage {}
+
+  // Signals that the writer thread should close the file and shut down. Sent
+  // to the writer thread and sent back along with the tid for confirmation.
+  struct ShutdownMessage {}
+
+  struct FlushBytesMessage {
+    size_t value;
+  }
+
+  struct FlushIntervalMessage {
+    Duration value;
+  }
+
+  struct IoErrorSleepDurationMessage {
+    Duration value;
+  }
+
+  void writerThread(
+    string path,
+    ulong chunkSize,
+    size_t maxFlushBytes,
+    Duration maxFlushInterval,
+    Duration ioErrorSleepDuration
+  ) {
+    bool errorOpening;
+    File file;
+    ulong offset;
+    try {
+      // Open file in appending and binary mode.
+      file = File(path, "ab");
+      offset = file.tell();
+    } catch (Exception e) {
+      logError("Error on opening output file in writer thread: %s", e);
+      errorOpening = true;
+    }
+
+    auto flushTimer = StopWatch(AutoStart.yes);
+    size_t unflushedByteCount;
+
+    Tid shutdownRequestTid;
+    bool shutdownRequested;
+    while (true) {
+      if (shutdownRequested) break;
+
+      bool forceFlush;
+      Tid flushRequestTid;
+      receiveTimeout(max(dur!"hnsecs"(0), maxFlushInterval - flushTimer.peek()),
+        (immutable(ubyte)[] data) {
+          while (errorOpening) {
+            logError("Writer thread going to sleep for %s µs due to IO errors",
+              ioErrorSleepDuration.fracSec.usecs);
+
+            // Sleep for ioErrorSleepDuration, being ready to be interrupted
+            // by shutdown requests.
+            auto timedOut = receiveTimeout(ioErrorSleepDuration,
+              (ShutdownMessage msg, Tid tid){ shutdownRequestTid = tid; });
+            if (!timedOut) {
+              // We got a shutdown request, just drop all events and exit the
+              // main loop as to not block application shutdown with our tries
+              // which we must assume to fail.
+              break;
+            }
+
+            try {
+              file = File(path, "ab");
+              unflushedByteCount = 0;
+              errorOpening = false;
+              logError("Output file %s reopened during writer thread error " ~
+                "recovery", path);
+            } catch (Exception e) {
+              logError("Unable to reopen output file %s during writer " ~
+                "thread error recovery", path);
+            }
+          }
+
+          // Make sure the event does not cross the chunk boundary by writing
+          // a padding consisting of zeroes if it would.
+          auto chunk1 = offset / chunkSize;
+          auto chunk2 = (offset + EventSize.sizeof + data.length - 1) / chunkSize;
+
+          if (chunk1 != chunk2) {
+            // TODO: The C++ implementation refetches the offset here to »keep
+            // in sync« – why would this be needed?
+            auto padding = cast(size_t)
+              ((((offset / chunkSize) + 1) * chunkSize) - offset);
+            auto zeroes = new ubyte[padding];
+            file.rawWrite(zeroes);
+            unflushedByteCount += padding;
+            offset += padding;
+          }
+
+          // TODO: 2 syscalls here, is this a problem performance-wise?
+          // Probably abysmal performance on Windows due to rawWrite
+          // implementation.
+          uint len = cast(uint)data.length;
+          file.rawWrite(cast(ubyte[])(&len)[0..1]);
+          file.rawWrite(data);
+
+          auto bytesWritten = EventSize.sizeof + data.length;
+          unflushedByteCount += bytesWritten;
+          offset += bytesWritten;
+        }, (FlushBytesMessage msg) {
+          maxFlushBytes = msg.value;
+        }, (FlushIntervalMessage msg) {
+          maxFlushInterval = msg.value;
+        }, (IoErrorSleepDurationMessage msg) {
+          ioErrorSleepDuration = msg.value;
+        }, (FlushMessage msg, Tid tid) {
+          forceFlush = true;
+          flushRequestTid = tid;
+        }, (OwnerTerminated msg) {
+          shutdownRequested = true;
+        }, (ShutdownMessage msg, Tid tid) {
+          shutdownRequested = true;
+          shutdownRequestTid = tid;
+        }
+      );
+
+      if (errorOpening) continue;
+
+      bool flush;
+      if (forceFlush || shutdownRequested || unflushedByteCount > maxFlushBytes) {
+        flush = true;
+      } else if (cast(Duration)flushTimer.peek() > maxFlushInterval) {
+        if (unflushedByteCount == 0) {
+          // If the flush timer is due, but no data has been written, don't
+          // needlessly fsync, but do reset the timer.
+          flushTimer.reset();
+        } else {
+          flush = true;
+        }
+      }
+
+      if (flush) {
+        file.flush();
+        flushTimer.reset();
+        unflushedByteCount = 0;
+        if (forceFlush) send(flushRequestTid, FlushMessage(), thisTid);
+      }
+    }
+
+    file.close();
+
+    if (shutdownRequestTid != Tid.init) {
+      send(shutdownRequestTid, ShutdownMessage(), thisTid);
+    }
+  }
+}
+
+version (unittest) {
+  import core.memory : GC;
+  import std.file;
+}
+
+unittest {
+  void tryRemove(string fileName) {
+    try {
+      remove(fileName);
+    } catch (Exception) {}
+  }
+
+  immutable fileName = "unittest.dat.tmp";
+  enforce(!exists(fileName), "Unit test output file " ~ fileName ~
+    " already exists.");
+
+  /*
+   * Check the most basic reading/writing operations.
+   */
+  {
+    scope (exit) tryRemove(fileName);
+
+    auto writer = new TFileWriterTransport(fileName);
+    writer.open();
+    scope (exit) writer.close();
+
+    writer.write([1, 2]);
+    writer.write([3, 4]);
+    writer.write([5, 6, 7]);
+    writer.flush();
+
+    auto reader = new TFileReaderTransport(fileName);
+    reader.open();
+    scope (exit) reader.close();
+
+    auto buf = new ubyte[7];
+    reader.readAll(buf);
+    enforce(buf == [1, 2, 3, 4, 5, 6, 7]);
+  }
+
+  /*
+   * Check that chunking works as expected.
+   */
+  {
+    scope (exit) tryRemove(fileName);
+
+    static assert(EventSize.sizeof == 4);
+    enum CHUNK_SIZE = 10;
+
+    // Write some contents to the file.
+    {
+      auto writer = new TFileWriterTransport(fileName);
+      writer.chunkSize = CHUNK_SIZE;
+      writer.open();
+      scope (exit) writer.close();
+
+      writer.write([0xde]);
+      writer.write([0xad]);
+      // Chunk boundary here.
+      writer.write([0xbe]);
+      // The next write doesn't fit in the five bytes remaining, so we expect
+      // padding zero bytes to be written.
+      writer.write([0xef, 0x12]);
+
+      try {
+        writer.write(new ubyte[CHUNK_SIZE]);
+        enforce(false, "Could write event not fitting in a single chunk.");
+      } catch (TTransportException e) {}
+
+      writer.flush();
+    }
+
+    // Check the raw contents of the file to see if chunk padding was written
+    // as expected.
+    auto file = File(fileName, "r");
+    enforce(file.size == 26);
+    auto written = new ubyte[26];
+    file.rawRead(written);
+    enforce(written == [
+      1, 0, 0, 0, 0xde,
+      1, 0, 0, 0, 0xad,
+      1, 0, 0, 0, 0xbe,
+      0, 0, 0, 0, 0,
+      2, 0, 0, 0, 0xef, 0x12
+    ]);
+
+    // Read the data back in, getting all the events at once.
+    {
+      auto reader = new TFileReaderTransport(fileName);
+      reader.chunkSize = CHUNK_SIZE;
+      reader.open();
+      scope (exit) reader.close();
+
+      auto buf = new ubyte[5];
+      reader.readAll(buf);
+      enforce(buf == [0xde, 0xad, 0xbe, 0xef, 0x12]);
+    }
+  }
+
+  /*
+   * Make sure that close() exits "quickly", i.e. that there is no problem
+   * with the worker thread waking up.
+   */
+  {
+    import std.conv : text;
+    enum NUM_ITERATIONS = 1000;
+
+    uint numOver = 0;
+    foreach (n; 0 .. NUM_ITERATIONS) {
+      scope (exit) tryRemove(fileName);
+
+      auto transport = new TFileWriterTransport(fileName);
+      transport.open();
+
+      // Write something so that the writer thread gets started.
+      transport.write(cast(ubyte[])"foo");
+
+      // Every other iteration, also call flush(), just in case that potentially
+      // has any effect on how the writer thread wakes up.
+      if (n & 0x1) {
+        transport.flush();
+      }
+
+      // Time the call to close().
+      auto sw = StopWatch(AutoStart.yes);
+      transport.close();
+      sw.stop();
+
+      // If any attempt takes more than 500ms, treat that as a fatal failure to
+      // avoid looping over a potentially very slow operation.
+      enforce(sw.peek().msecs < 500,
+        text("close() took ", sw.peek().msecs, "ms."));
+
+      // Normally, it takes less than 5ms on my dev box.
+      // However, if the box is heavily loaded, some of the test runs can take
+      // longer. Additionally, on a Windows Server 2008 instance running in
+      // a VirtualBox VM, it has been observed that about a quarter of the runs
+      // takes (217 ± 1) ms, for reasons not yet known.
+      if (sw.peek().msecs > 5) {
+        ++numOver;
+      }
+
+      // Force garbage collection runs every now and then to make sure we
+      // don't run out of OS thread handles.
+      if (!(n % 100)) GC.collect();
+    }
+
+    // Make sure fewer than a third of the runs took longer than 5ms.
+    enforce(numOver < NUM_ITERATIONS / 3,
+      text(numOver, " iterations took more than 10 ms."));
+  }
+}
diff --git a/lib/d/src/thrift/transport/framed.d b/lib/d/src/thrift/transport/framed.d
new file mode 100644
index 0000000..94effbb
--- /dev/null
+++ b/lib/d/src/thrift/transport/framed.d
@@ -0,0 +1,334 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+module thrift.transport.framed;
+
+import core.bitop : bswap;
+import std.algorithm : min;
+import std.array : empty;
+import std.exception : enforce;
+import thrift.transport.base;
+
+/**
+ * Framed transport.
+ *
+ * All writes go into an in-memory buffer until flush is called, at which point
+ * the transport writes the length of the entire binary chunk followed by the
+ * data payload. The receiver on the other end then performs a single
+ * »fixed-length« read to get the whole message off the wire.
+ */
+final class TFramedTransport : TBaseTransport {
+  /**
+   * Constructs a new framed transport.
+   *
+   * Params:
+   *   transport = The underlying transport to wrap.
+   */
+  this(TTransport transport) {
+    transport_ = transport;
+  }
+
+  /**
+   * Returns the wrapped transport.
+   */
+  TTransport underlyingTransport() @property {
+    return transport_;
+  }
+
+  override bool isOpen() @property {
+    return transport_.isOpen;
+  }
+
+  override bool peek() {
+    return rBuf_.length > 0 || transport_.peek();
+  }
+
+  override void open() {
+    transport_.open();
+  }
+
+  override void close() {
+    flush();
+    transport_.close();
+  }
+
+  /**
+   * Attempts to read data into the given buffer, stopping when the buffer is
+   * exhausted or the frame end is reached.
+   *
+   * TODO: Contrary to the C++ implementation, this never does cross-frame
+   * reads – is there actually a valid use case for that?
+   *
+   * Params:
+   *   buf = Slice to use as buffer.
+   *
+   * Returns: How many bytes were actually read.
+   *
+   * Throws: TTransportException if an error occurs.
+   */
+  override size_t read(ubyte[] buf) {
+    // If the buffer is empty, read a new frame off the wire.
+    if (rBuf_.empty) {
+      bool gotFrame = readFrame();
+      if (!gotFrame) return 0;
+    }
+
+    auto size = min(rBuf_.length, buf.length);
+    buf[0..size] = rBuf_[0..size];
+    rBuf_ = rBuf_[size..$];
+    return size;
+  }
+
+  override void write(in ubyte[] buf) {
+    wBuf_ ~= buf;
+  }
+
+  override void flush() {
+    if (wBuf_.empty) return;
+
+    // Properly reset the write buffer even some of the protocol operations go
+    // wrong.
+    scope (exit) {
+      wBuf_.length = 0;
+      wBuf_.assumeSafeAppend();
+    }
+
+    int len = bswap(cast(int)wBuf_.length);
+    transport_.write(cast(ubyte[])(&len)[0..1]);
+    transport_.write(wBuf_);
+    transport_.flush();
+  }
+
+  override const(ubyte)[] borrow(ubyte* buf, size_t len) {
+    if (len <= rBuf_.length) {
+      return rBuf_;
+    } else {
+      // Don't try attempting cross-frame borrows, trying that does not make
+      // much sense anyway.
+      return null;
+    }
+  }
+
+  override void consume(size_t len) {
+    enforce(len <= rBuf_.length, new TTransportException(
+      "Invalid consume length", TTransportException.Type.BAD_ARGS));
+    rBuf_ = rBuf_[len .. $];
+  }
+
+private:
+  bool readFrame() {
+    // Read the size of the next frame. We can't use readAll() since that
+    // always throws an exception on EOF, but want to throw an exception only
+    // if EOF occurs after partial size data.
+    int size;
+    size_t size_read;
+    while (size_read < size.sizeof) {
+      auto data = (cast(ubyte*)&size)[size_read..size.sizeof];
+      auto read = transport_.read(data);
+      if (read == 0) {
+        if (size_read == 0) {
+          // EOF before any data was read.
+          return false;
+        } else {
+          // EOF after a partial frame header – illegal.
+          throw new TTransportException(
+            "No more data to read after partial frame header",
+            TTransportException.Type.END_OF_FILE
+          );
+        }
+      }
+      size_read += read;
+    }
+
+    size = bswap(size);
+    enforce(size >= 0, new TTransportException("Frame size has negative value",
+      TTransportException.Type.CORRUPTED_DATA));
+
+    // TODO: Benchmark this.
+    rBuf_.length = size;
+    rBuf_.assumeSafeAppend();
+
+    transport_.readAll(rBuf_);
+    return true;
+  }
+
+  TTransport transport_;
+  ubyte[] rBuf_;
+  ubyte[] wBuf_;
+}
+
+/**
+ * Wraps given transports into TFramedTransports.
+ */
+alias TWrapperTransportFactory!TFramedTransport TFramedTransportFactory;
+
+version (unittest) {
+  import std.random : Mt19937, uniform;
+  import thrift.transport.memory;
+}
+
+// Some basic random testing, always starting with the same seed for
+// deterministic unit test results – more tests in transport_test.
+unittest {
+  auto randGen = Mt19937(42);
+
+  // 32 kiB of data to work with.
+  auto data = new ubyte[1 << 15];
+  foreach (ref b; data) {
+    b = uniform!"[]"(cast(ubyte)0, cast(ubyte)255, randGen);
+  }
+
+  // Generate a list of chunk sizes to split the data into. A uniform
+  // distribution is not quite realistic, but std.random doesn't have anything
+  // else yet.
+  enum MAX_FRAME_LENGTH = 512;
+  auto chunkSizesList = new size_t[][2];
+  foreach (ref chunkSizes; chunkSizesList) {
+    size_t sum;
+    while (true) {
+      auto curLen = uniform(0, MAX_FRAME_LENGTH, randGen);
+      sum += curLen;
+      if (sum > data.length) break;
+      chunkSizes ~= curLen;
+    }
+  }
+  chunkSizesList ~= [data.length]; // Also test whole chunk at once.
+
+  // Test writing data.
+  {
+    foreach (chunkSizes; chunkSizesList) {
+      auto buf = new TMemoryBuffer;
+      auto framed = new TFramedTransport(buf);
+
+      auto remainingData = data;
+      foreach (chunkSize; chunkSizes) {
+        framed.write(remainingData[0..chunkSize]);
+        remainingData = remainingData[chunkSize..$];
+      }
+      framed.flush();
+
+      auto writtenData = data[0..($ - remainingData.length)];
+      auto actualData = buf.getContents();
+
+      // Check frame size.
+      int frameSize = bswap((cast(int[])(actualData[0..int.sizeof]))[0]);
+      enforce(frameSize == writtenData.length);
+
+      // Check actual data.
+      enforce(actualData[int.sizeof..$] == writtenData);
+    }
+  }
+
+  // Test reading data.
+  {
+    foreach (chunkSizes; chunkSizesList) {
+      auto buf = new TMemoryBuffer;
+
+      auto size = bswap(cast(int)data.length);
+      buf.write(cast(ubyte[])(&size)[0..1]);
+      buf.write(data);
+
+      auto framed = new TFramedTransport(buf);
+      ubyte[] readData;
+      readData.reserve(data.length);
+      foreach (chunkSize; chunkSizes) {
+        // This should work with read because we have one huge frame.
+        auto oldReadLen = readData.length;
+        readData.length += chunkSize;
+        framed.read(readData[oldReadLen..$]);
+      }
+
+      enforce(readData == data[0..readData.length]);
+    }
+  }
+
+  // Test combined reading/writing of multiple frames.
+  foreach (flushProbability; [1, 2, 4, 8, 16, 32]) {
+    foreach (chunkSizes; chunkSizesList) {
+      auto buf = new TMemoryBuffer;
+      auto framed = new TFramedTransport(buf);
+
+      size_t[] frameSizes;
+
+      // Write the data.
+      size_t frameSize;
+      auto remainingData = data;
+      foreach (chunkSize; chunkSizes) {
+        framed.write(remainingData[0..chunkSize]);
+        remainingData = remainingData[chunkSize..$];
+
+        frameSize += chunkSize;
+        if (frameSize > 0 && uniform(0, flushProbability, randGen) == 0) {
+          frameSizes ~= frameSize;
+          frameSize = 0;
+          framed.flush();
+        }
+      }
+      if (frameSize > 0) {
+        frameSizes ~= frameSize;
+        frameSize = 0;
+        framed.flush();
+      }
+
+      // Read it back.
+      auto readData = new ubyte[data.length - remainingData.length];
+      auto remainToRead = readData;
+      foreach (fSize; frameSizes) {
+        // We are exploiting an implementation detail of TFramedTransport:
+        // The read buffer starts empty and it will never return more than one
+        // frame per read, so by just requesting all of the data, we should
+        // always get exactly one frame.
+        auto got = framed.read(remainToRead);
+        enforce(got == fSize);
+        remainToRead = remainToRead[fSize..$];
+      }
+
+      enforce(remainToRead.empty);
+      enforce(readData == data[0..readData.length]);
+    }
+  }
+}
+
+// Test flush()ing an empty buffer.
+unittest {
+  auto buf = new TMemoryBuffer();
+  auto framed = new TFramedTransport(buf);
+  immutable out1 = [0, 0, 0, 1, 'a'];
+  immutable out2 = [0, 0, 0, 1, 'a', 0, 0, 0, 2, 'b', 'c'];
+
+  framed.flush();
+  enforce(buf.getContents() == []);
+  framed.flush();
+  framed.flush();
+  enforce(buf.getContents() == []);
+  framed.write(cast(ubyte[])"a");
+  enforce(buf.getContents() == []);
+  framed.flush();
+  enforce(buf.getContents() == out1);
+  framed.flush();
+  framed.flush();
+  enforce(buf.getContents() == out1);
+  framed.write(cast(ubyte[])"bc");
+  enforce(buf.getContents() == out1);
+  framed.flush();
+  enforce(buf.getContents() == out2);
+  framed.flush();
+  framed.flush();
+  enforce(buf.getContents() == out2);
+}
diff --git a/lib/d/src/thrift/transport/http.d b/lib/d/src/thrift/transport/http.d
new file mode 100644
index 0000000..5186f3d
--- /dev/null
+++ b/lib/d/src/thrift/transport/http.d
@@ -0,0 +1,459 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/**
+ * HTTP tranpsort implementation, modelled after the C++ one.
+ *
+ * Unfortunately, libcurl is quite heavyweight and supports only client-side
+ * applications. This is an implementation of the basic HTTP/1.1 parts
+ * supporting HTTP 100 Continue, chunked transfer encoding, keepalive, etc.
+ */
+module thrift.transport.http;
+
+import std.algorithm : canFind, countUntil, endsWith, findSplit, min, startsWith;
+import std.ascii : toLower;
+import std.array : empty;
+import std.conv : parse, to;
+import std.datetime : Clock, UTC;
+import std.string : stripLeft;
+import thrift.base : VERSION;
+import thrift.transport.base;
+import thrift.transport.memory;
+import thrift.transport.socket;
+
+/**
+ * Base class for both client- and server-side HTTP transports.
+ */
+abstract class THttpTransport : TBaseTransport {
+  this(TTransport transport) {
+    transport_ = transport;
+    readHeaders_ = true;
+    httpBuf_ = new ubyte[HTTP_BUFFER_SIZE];
+    httpBufRemaining_ = httpBuf_[0 .. 0];
+    readBuffer_ = new TMemoryBuffer;
+    writeBuffer_ = new TMemoryBuffer;
+  }
+
+  override bool isOpen() {
+    return transport_.isOpen();
+  }
+
+  override bool peek() {
+    return transport_.peek();
+  }
+
+  override void open() {
+    transport_.open();
+  }
+
+  override void close() {
+    transport_.close();
+  }
+
+  override size_t read(ubyte[] buf) {
+    if (!readBuffer_.peek()) {
+      readBuffer_.reset();
+
+      if (!refill()) return 0;
+
+      if (readHeaders_) {
+        readHeaders();
+      }
+
+      size_t got;
+      if (chunked_) {
+        got = readChunked();
+      } else {
+        got = readContent(contentLength_);
+      }
+      readHeaders_ = true;
+
+      if (got == 0) return 0;
+    }
+    return readBuffer_.read(buf);
+  }
+
+  override size_t readEnd() {
+    // Read any pending chunked data (footers etc.)
+    if (chunked_) {
+      while (!chunkedDone_) {
+        readChunked();
+      }
+    }
+    return 0;
+  }
+
+  override void write(in ubyte[] buf) {
+    writeBuffer_.write(buf);
+  }
+
+  override void flush() {
+    auto data = writeBuffer_.getContents();
+    string header = getHeader(data.length);
+
+    transport_.write(cast(const(ubyte)[]) header);
+    transport_.write(data);
+    transport_.flush();
+
+    // Reset the buffer and header variables.
+    writeBuffer_.reset();
+    readHeaders_ = true;
+  }
+
+  /**
+   * The size of the buffer to read HTTP requests into, in bytes. Will expand
+   * as required.
+   */
+  enum HTTP_BUFFER_SIZE = 1024;
+
+protected:
+  abstract string getHeader(size_t dataLength);
+  abstract bool parseStatusLine(const(ubyte)[] status);
+
+  void parseHeader(const(ubyte)[] header) {
+    auto split = findSplit(header, [':']);
+    if (split[1].empty) {
+      // No colon found.
+      return;
+    }
+
+    static bool compToLower(ubyte a, ubyte b) {
+      return a == toLower(cast(char)b);
+    }
+
+    if (startsWith!compToLower(split[0], cast(ubyte[])"transfer-encoding")) {
+      if (endsWith!compToLower(split[2], cast(ubyte[])"chunked")) {
+        chunked_ = true;
+      }
+    } else if (startsWith!compToLower(split[0], cast(ubyte[])"content-length")) {
+      chunked_ = false;
+      auto lengthString = stripLeft(cast(const(char)[])split[2]);
+      contentLength_ = parse!size_t(lengthString);
+    }
+  }
+
+private:
+  ubyte[] readLine() {
+    while (true) {
+      auto split = findSplit(httpBufRemaining_, cast(ubyte[])"\r\n");
+
+      if (split[1].empty) {
+        // No CRLF yet, move whatever we have now to front and refill.
+        if (httpBufRemaining_.empty) {
+          httpBufRemaining_ = httpBuf_[0 .. 0];
+        } else {
+          httpBuf_[0 .. httpBufRemaining_.length] = httpBufRemaining_;
+          httpBufRemaining_ = httpBuf_[0 .. httpBufRemaining_.length];
+        }
+
+        if (!refill()) {
+          auto buf = httpBufRemaining_;
+          httpBufRemaining_ = httpBufRemaining_[$ - 1 .. $ - 1];
+          return buf;
+        }
+      } else {
+        // Set the remaining buffer to the part after \r\n and return the part
+        // (line) before it.
+        httpBufRemaining_ = split[2];
+        return split[0];
+      }
+    }
+  }
+
+  void readHeaders() {
+    // Initialize headers state variables
+    contentLength_ = 0;
+    chunked_ = false;
+    chunkedDone_ = false;
+    chunkSize_ = 0;
+
+    // Control state flow
+    bool statusLine = true;
+    bool finished;
+
+    // Loop until headers are finished
+    while (true) {
+      auto line = readLine();
+
+      if (line.length == 0) {
+        if (finished) {
+          readHeaders_ = false;
+          return;
+        } else {
+          // Must have been an HTTP 100, keep going for another status line
+          statusLine = true;
+        }
+      } else {
+        if (statusLine) {
+          statusLine = false;
+          finished = parseStatusLine(line);
+        } else {
+          parseHeader(line);
+        }
+      }
+    }
+  }
+
+  size_t readChunked() {
+    size_t length;
+
+    auto line = readLine();
+    size_t chunkSize;
+    try {
+      auto charLine = cast(char[])line;
+      chunkSize = parse!size_t(charLine, 16);
+    } catch (Exception e) {
+      throw new TTransportException("Invalid chunk size: " ~ to!string(line),
+        TTransportException.Type.CORRUPTED_DATA);
+    }
+
+    if (chunkSize == 0) {
+      readChunkedFooters();
+    } else {
+      // Read data content
+      length += readContent(chunkSize);
+      // Read trailing CRLF after content
+      readLine();
+    }
+    return length;
+  }
+
+  void readChunkedFooters() {
+    while (true) {
+      auto line = readLine();
+      if (line.length == 0) {
+        chunkedDone_ = true;
+        break;
+      }
+    }
+  }
+
+  size_t readContent(size_t size) {
+    auto need = size;
+    while (need > 0) {
+      if (httpBufRemaining_.length == 0) {
+        // We have given all the data, reset position to head of the buffer.
+        httpBufRemaining_ = httpBuf_[0 .. 0];
+        if (!refill()) return size - need;
+      }
+
+      auto give = min(httpBufRemaining_.length, need);
+      readBuffer_.write(cast(ubyte[])httpBufRemaining_[0 .. give]);
+      httpBufRemaining_ = httpBufRemaining_[give .. $];
+      need -= give;
+    }
+    return size;
+  }
+
+  bool refill() {
+    // Is there a nicer way to do this?
+    auto indexBegin = httpBufRemaining_.ptr - httpBuf_.ptr;
+    auto indexEnd = indexBegin + httpBufRemaining_.length;
+
+    if (httpBuf_.length - indexEnd <= (httpBuf_.length / 4)) {
+      httpBuf_.length *= 2;
+    }
+
+    // Read more data.
+    auto got = transport_.read(cast(ubyte[])httpBuf_[indexEnd .. $]);
+    if (got == 0) return false;
+    httpBufRemaining_ = httpBuf_[indexBegin .. indexEnd + got];
+    return true;
+  }
+
+  TTransport transport_;
+
+  TMemoryBuffer writeBuffer_;
+  TMemoryBuffer readBuffer_;
+
+  bool readHeaders_;
+  bool chunked_;
+  bool chunkedDone_;
+  size_t chunkSize_;
+  size_t contentLength_;
+
+  ubyte[] httpBuf_;
+  ubyte[] httpBufRemaining_;
+}
+
+/**
+ * HTTP client transport.
+ */
+final class TClientHttpTransport : THttpTransport {
+  /**
+   * Constructs a client http transport operating on the passed underlying
+   * transport.
+   *
+   * Params:
+   *   transport = The underlying transport used for the actual I/O.
+   *   host = The HTTP host string.
+   *   path = The HTTP path string.
+   */
+  this(TTransport transport, string host, string path) {
+    super(transport);
+    host_ = host;
+    path_ = path;
+  }
+
+  /**
+   * Convenience overload for constructing a client HTTP transport using a
+   * TSocket connecting to the specified host and port.
+   *
+   * Params:
+   *   host = The server to connect to, also used as HTTP host string.
+   *   port = The port to connect to.
+   *   path = The HTTP path string.
+   */
+  this(string host, ushort port, string path) {
+    this(new TSocket(host, port), host, path);
+  }
+
+protected:
+  override string getHeader(size_t dataLength) {
+    return "POST " ~ path_ ~ " HTTP/1.1\r\n" ~
+      "Host: " ~ host_ ~ "\r\n" ~
+      "Content-Type: application/x-thrift\r\n" ~
+      "Content-Length: " ~ to!string(dataLength) ~ "\r\n" ~
+      "Accept: application/x-thrift\r\n"
+      "User-Agent: Thrift/" ~ VERSION ~ " (D/TClientHttpTransport)\r\n" ~
+      "\r\n";
+  }
+
+  override bool parseStatusLine(const(ubyte)[] status) {
+    // HTTP-Version SP Status-Code SP Reason-Phrase CRLF
+    auto firstSplit = findSplit(status, [' ']);
+    if (firstSplit[1].empty) {
+      throw new TTransportException("Bad status: " ~ to!string(status),
+        TTransportException.Type.CORRUPTED_DATA);
+    }
+
+    auto codeReason = firstSplit[2][countUntil!"a != b"(firstSplit[2], ' ') .. $];
+    auto secondSplit = findSplit(codeReason, [' ']);
+    if (secondSplit[1].empty) {
+      throw new TTransportException("Bad status: " ~ to!string(status),
+        TTransportException.Type.CORRUPTED_DATA);
+    }
+
+    if (secondSplit[0] == "200") {
+      // HTTP 200 = OK, we got the response
+      return true;
+    } else if (secondSplit[0] == "100") {
+      // HTTP 100 = continue, just keep reading
+      return false;
+    }
+
+    throw new TTransportException("Bad status (unhandled status code): " ~
+      to!string(cast(const(char[]))status), TTransportException.Type.CORRUPTED_DATA);
+  }
+
+private:
+  string host_;
+  string path_;
+}
+
+/**
+ * HTTP server transport.
+ */
+final class TServerHttpTransport : THttpTransport {
+  /**
+   * Constructs a new instance.
+   *
+   * Param:
+   *   transport = The underlying transport used for the actual I/O.
+   */
+  this(TTransport transport) {
+    super(transport);
+  }
+
+protected:
+  override string getHeader(size_t dataLength) {
+    return "HTTP/1.1 200 OK\r\n" ~
+      "Date: " ~ getRFC1123Time() ~ "\r\n" ~
+      "Server: Thrift/" ~ VERSION ~ "\r\n" ~
+      "Content-Type: application/x-thrift\r\n" ~
+      "Content-Length: " ~ to!string(dataLength) ~ "\r\n" ~
+      "Connection: Keep-Alive\r\n" ~
+      "\r\n";
+  }
+
+  override bool parseStatusLine(const(ubyte)[] status) {
+    // Method SP Request-URI SP HTTP-Version CRLF.
+    auto split = findSplit(status, [' ']);
+    if (split[1].empty) {
+      throw new TTransportException("Bad status: " ~ to!string(status),
+        TTransportException.Type.CORRUPTED_DATA);
+    }
+
+    auto uriVersion = split[2][countUntil!"a != b"(split[2], ' ') .. $];
+    if (!canFind(uriVersion, ' ')) {
+      throw new TTransportException("Bad status: " ~ to!string(status),
+        TTransportException.Type.CORRUPTED_DATA);
+    }
+
+    if (split[0] == "POST") {
+      // POST method ok, looking for content.
+      return true;
+    }
+
+    throw new TTransportException("Bad status (unsupported method): " ~
+      to!string(status), TTransportException.Type.CORRUPTED_DATA);
+  }
+}
+
+/**
+ * Wraps a transport into a HTTP server protocol.
+ */
+alias TWrapperTransportFactory!TServerHttpTransport TServerHttpTransportFactory;
+
+private {
+  import std.string : format;
+  string getRFC1123Time() {
+    auto sysTime = Clock.currTime(UTC());
+
+    auto dayName = capMemberName(sysTime.dayOfWeek);
+    auto monthName = capMemberName(sysTime.month);
+
+    return format("%s, %s %s %s %s:%s:%s GMT", dayName, sysTime.day,
+      monthName, sysTime.year, sysTime.hour, sysTime.minute, sysTime.second);
+  }
+
+  import std.ascii : toUpper;
+  import std.traits : EnumMembers;
+  string capMemberName(T)(T val) if (is(T == enum)) {
+    foreach (i, e; EnumMembers!T) {
+      enum name = __traits(derivedMembers, T)[i];
+      enum capName = cast(char) toUpper(name[0]) ~ name [1 .. $];
+      if (val == e) {
+        return capName;
+      }
+    }
+    throw new Exception("Not a member of " ~ T.stringof ~ ": " ~ to!string(val));
+  }
+
+  unittest {
+    enum Foo {
+      bar,
+      bAZ
+    }
+
+    import std.exception;
+    enforce(capMemberName(Foo.bar) == "Bar");
+    enforce(capMemberName(Foo.bAZ) == "BAZ");
+  }
+}
diff --git a/lib/d/src/thrift/transport/memory.d b/lib/d/src/thrift/transport/memory.d
new file mode 100644
index 0000000..cdf0807
--- /dev/null
+++ b/lib/d/src/thrift/transport/memory.d
@@ -0,0 +1,233 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+module thrift.transport.memory;
+
+import core.exception : onOutOfMemoryError;
+import core.stdc.stdlib : free, realloc;
+import std.algorithm : min;
+import std.conv : text;
+import thrift.transport.base;
+
+/**
+ * A transport that simply reads from and writes to an in-memory buffer. Every
+ * time you call write on it, the data is simply placed into a buffer, and
+ * every time you call read, data is consumed from that buffer.
+ *
+ * Currently, the storage for written data is never reclaimed, even if the
+ * buffer contents have already been read out again.
+ */
+final class TMemoryBuffer : TBaseTransport {
+  /**
+   * Constructs a new memory transport with an empty internal buffer.
+   */
+  this() {}
+
+  /**
+   * Constructs a new memory transport with an empty internal buffer,
+   * reserving space for capacity bytes in advance.
+   *
+   * If the amount of data which will be written to the buffer is already
+   * known on construction, this can better performance over the default
+   * constructor because reallocations can be avoided.
+   *
+   * If the preallocated buffer is exhausted, data can still be written to the
+   * transport, but reallocations will happen.
+   *
+   * Params:
+   *   capacity = Size of the initially reserved buffer (in bytes).
+   */
+  this(size_t capacity) {
+    reset(capacity);
+  }
+
+  /**
+   * Constructs a new memory transport initially containing the passed data.
+   *
+   * For now, the passed buffer is not intelligently used, the data is just
+   * copied to the internal buffer.
+   *
+   * Params:
+   *   buffer = Initial contents available to be read.
+   */
+  this(in ubyte[] contents) {
+    auto size = contents.length;
+    reset(size);
+    buffer_[0 .. size] = contents[];
+    writeOffset_ = size;
+  }
+
+  /**
+   * Destructor, frees the internally allocated buffer.
+   */
+  ~this() {
+    free(buffer_);
+  }
+
+  /**
+   * Returns a read-only view of the current buffer contents.
+   *
+   * Note: For performance reasons, the returned slice is only valid for the
+   * life of this object, and may be invalidated on the next write() call at
+   * will – you might want to immediately .dup it if you intend to keep it
+   * around.
+   */
+  const(ubyte)[] getContents() {
+    return buffer_[readOffset_ .. writeOffset_];
+  }
+
+  /**
+   * A memory transport is always open.
+   */
+  override bool isOpen() @property {
+    return true;
+  }
+
+  override bool peek() {
+    return writeOffset_ - readOffset_ > 0;
+  }
+
+  /**
+   * Opening is a no-op() for a memory buffer.
+   */
+  override void open() {}
+
+  /**
+   * Closing is a no-op() for a memory buffer, it is always open.
+   */
+  override void close() {}
+
+  override size_t read(ubyte[] buf) {
+    auto size = min(buf.length, writeOffset_ - readOffset_);
+    buf[0 .. size] = buffer_[readOffset_ .. readOffset_ + size];
+    readOffset_ += size;
+    return size;
+  }
+
+  /**
+   * Shortcut version of readAll() – using this over TBaseTransport.readAll()
+   * can give us a nice speed increase because gives us a nice speed increase
+   * because it is typically a very hot path during deserialization.
+   */
+  override void readAll(ubyte[] buf) {
+    auto available = writeOffset_ - readOffset_;
+    if (buf.length > available) {
+      throw new TTransportException(text("Cannot readAll() ", buf.length,
+        " bytes of data because only ", available, " bytes are available."),
+        TTransportException.Type.END_OF_FILE);
+    }
+
+    buf[] = buffer_[readOffset_ .. readOffset_ + buf.length];
+    readOffset_ += buf.length;
+  }
+
+  override void write(in ubyte[] buf) {
+    auto need = buf.length;
+    if (bufferLen_ - writeOffset_ < need) {
+      // Exponential growth.
+      auto newLen = bufferLen_ + 1;
+      while (newLen - writeOffset_ < need) newLen *= 2;
+      cRealloc(buffer_, newLen);
+      bufferLen_ = newLen;
+    }
+
+    buffer_[writeOffset_ .. writeOffset_ + need] = buf[];
+    writeOffset_ += need;
+  }
+
+  override const(ubyte)[] borrow(ubyte* buf, size_t len) {
+    if (len <= writeOffset_ - readOffset_) {
+      return buffer_[readOffset_ .. writeOffset_];
+    } else {
+      return null;
+    }
+  }
+
+  override void consume(size_t len) {
+    readOffset_ += len;
+  }
+
+  void reset() {
+    readOffset_ = 0;
+    writeOffset_ = 0;
+  }
+
+  void reset(size_t capacity) {
+    readOffset_ = 0;
+    writeOffset_ = 0;
+    if (bufferLen_ < capacity) {
+      cRealloc(buffer_, capacity);
+      bufferLen_ = capacity;
+    }
+  }
+
+private:
+  ubyte* buffer_;
+  size_t bufferLen_;
+  size_t readOffset_;
+  size_t writeOffset_;
+}
+
+private {
+  void cRealloc(ref ubyte* data, size_t newSize) {
+    auto result = realloc(data, newSize);
+    if (result is null) onOutOfMemoryError();
+    data = cast(ubyte*)result;
+  }
+}
+
+version (unittest) {
+  import std.exception;
+}
+
+unittest {
+  auto a = new TMemoryBuffer(5);
+  immutable(ubyte[]) testData = [1, 2, 3, 4];
+  auto buf = new ubyte[testData.length];
+  enforce(a.isOpen);
+
+  // a should be empty.
+  enforce(!a.peek());
+  enforce(a.read(buf) == 0);
+  assertThrown!TTransportException(a.readAll(buf));
+
+  // Write some data and read it back again.
+  a.write(testData);
+  enforce(a.peek());
+  enforce(a.getContents() == testData);
+  enforce(a.read(buf) == testData.length);
+  enforce(buf == testData);
+
+  // a should be empty again.
+  enforce(!a.peek());
+  enforce(a.read(buf) == 0);
+  assertThrown!TTransportException(a.readAll(buf));
+
+  // Test the constructor which directly accepts initial data.
+  auto b = new TMemoryBuffer(testData);
+  enforce(b.isOpen);
+  enforce(b.peek());
+  enforce(b.getContents() == testData);
+
+  // Test borrow().
+  auto borrowed = b.borrow(null, testData.length);
+  enforce(borrowed == testData);
+  enforce(b.peek());
+  b.consume(testData.length);
+  enforce(!b.peek());
+}
diff --git a/lib/d/src/thrift/transport/piped.d b/lib/d/src/thrift/transport/piped.d
new file mode 100644
index 0000000..9fe1432
--- /dev/null
+++ b/lib/d/src/thrift/transport/piped.d
@@ -0,0 +1,219 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+module thrift.transport.piped;
+
+import thrift.transport.base;
+import thrift.transport.memory;
+
+/**
+ * Pipes data request from one transport to another when readEnd()
+ * or writeEnd() is called.
+ *
+ * A typical use case would be to log requests on e.g. a socket to
+ * disk (i. e. pipe them to a TFileWriterTransport).
+ *
+ * The implementation keeps an internal buffer which expands to
+ * hold the whole amount of data read/written until the corresponding *End()
+ * method is called.
+ *
+ * Contrary to the C++ implementation, this doesn't introduce yet another layer
+ * of input/output buffering, all calls are passed to the underlying source
+ * transport verbatim.
+ */
+final class TPipedTransport(Source = TTransport) if (
+  isTTransport!Source
+) : TBaseTransport {
+  /// The default initial buffer size if not explicitly specified, in bytes.
+  enum DEFAULT_INITIAL_BUFFER_SIZE = 512;
+
+  /**
+   * Constructs a new instance.
+   *
+   * By default, only reads are piped (pipeReads = true, pipeWrites = false).
+   *
+   * Params:
+   *   srcTrans = The transport to which all requests are forwarded.
+   *   dstTrans = The transport the read/written data is copied to.
+   *   initialBufferSize = The default size of the read/write buffers, for
+   *     performance tuning.
+   */
+  this(Source srcTrans, TTransport dstTrans,
+    size_t initialBufferSize = DEFAULT_INITIAL_BUFFER_SIZE
+  ) {
+    srcTrans_ = srcTrans;
+    dstTrans_ = dstTrans;
+
+    readBuffer_ = new TMemoryBuffer(initialBufferSize);
+    writeBuffer_ = new TMemoryBuffer(initialBufferSize);
+
+    pipeReads_ = true;
+    pipeWrites_ = false;
+  }
+
+  bool pipeReads() @property const {
+    return pipeReads_;
+  }
+
+  void pipeReads(bool value) @property {
+    if (!value) {
+      readBuffer_.reset();
+    }
+    pipeReads_ = value;
+  }
+
+  bool pipeWrites() @property const {
+    return pipeWrites_;
+  }
+
+  void pipeWrites(bool value) @property {
+    if (!value) {
+      writeBuffer_.reset();
+    }
+    pipeWrites_ = value;
+  }
+
+  override bool isOpen() {
+    return srcTrans_.isOpen();
+  }
+
+  override bool peek() {
+    return srcTrans_.peek();
+  }
+
+  override void open() {
+    srcTrans_.open();
+  }
+
+  override void close() {
+    srcTrans_.close();
+  }
+
+  override size_t read(ubyte[] buf) {
+    auto bytesRead = srcTrans_.read(buf);
+
+    if (pipeReads_) {
+      readBuffer_.write(buf[0 .. bytesRead]);
+    }
+
+    return bytesRead;
+  }
+
+  override size_t readEnd() {
+    if (pipeReads_) {
+      auto data = readBuffer_.getContents();
+      dstTrans_.write(data);
+      dstTrans_.flush();
+      readBuffer_.reset();
+
+      srcTrans_.readEnd();
+
+      // Return data.length instead of the readEnd() result of the source
+      // transports because it might not be available from it.
+      return data.length;
+    }
+
+    return srcTrans_.readEnd();
+  }
+
+  override void write(in ubyte[] buf) {
+    if (pipeWrites_) {
+      writeBuffer_.write(buf);
+    }
+
+    srcTrans_.write(buf);
+  }
+
+  override size_t writeEnd() {
+    if (pipeWrites_) {
+      auto data = writeBuffer_.getContents();
+      dstTrans_.write(data);
+      dstTrans_.flush();
+      writeBuffer_.reset();
+
+      srcTrans_.writeEnd();
+
+      // Return data.length instead of the readEnd() result of the source
+      // transports because it might not be available from it.
+      return data.length;
+    }
+
+    return srcTrans_.writeEnd();
+  }
+
+  override void flush() {
+    srcTrans_.flush();
+  }
+
+private:
+  Source srcTrans_;
+  TTransport dstTrans_;
+
+  TMemoryBuffer readBuffer_;
+  TMemoryBuffer writeBuffer_;
+
+  bool pipeReads_;
+  bool pipeWrites_;
+}
+
+/**
+ * TPipedTransport construction helper to avoid having to explicitly
+ * specify the transport types, i.e. to allow the constructor being called
+ * using IFTI (see $(DMDBUG 6082, D Bugzilla enhancement request 6082)).
+ */
+TPipedTransport!Source tPipedTransport(Source)(
+  Source srcTrans, TTransport dstTrans
+) if (isTTransport!Source) {
+  return new typeof(return)(srcTrans, dstTrans);
+}
+
+version (unittest) {
+  // DMD @@BUG@@: UFCS for std.array.empty doesn't work when import is moved
+  // into unittest block.
+  import std.array;
+  import std.exception : enforce;
+}
+
+unittest {
+  auto underlying = new TMemoryBuffer;
+  auto pipeTarget = new TMemoryBuffer;
+  auto trans = tPipedTransport(underlying, pipeTarget);
+
+  underlying.write(cast(ubyte[])"abcd");
+
+  ubyte[4] buffer;
+  trans.readAll(buffer[0 .. 2]);
+  enforce(buffer[0 .. 2] == "ab");
+  enforce(pipeTarget.getContents().empty);
+
+  trans.readEnd();
+  enforce(pipeTarget.getContents() == "ab");
+  pipeTarget.reset();
+
+  underlying.write(cast(ubyte[])"ef");
+  trans.readAll(buffer[0 .. 2]);
+  enforce(buffer[0 .. 2] == "cd");
+  enforce(pipeTarget.getContents().empty);
+
+  trans.readAll(buffer[0 .. 2]);
+  enforce(buffer[0 .. 2] == "ef");
+  enforce(pipeTarget.getContents().empty);
+
+  trans.readEnd();
+  enforce(pipeTarget.getContents() == "cdef");
+}
diff --git a/lib/d/src/thrift/transport/range.d b/lib/d/src/thrift/transport/range.d
new file mode 100644
index 0000000..761cea1
--- /dev/null
+++ b/lib/d/src/thrift/transport/range.d
@@ -0,0 +1,147 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/**
+ * Transports which operate on generic D ranges.
+ */
+module thrift.transport.range;
+
+import std.array : empty;
+import std.range;
+import std.traits : Unqual;
+import thrift.transport.base;
+
+/**
+ * Adapts an ubyte input range for reading via the TTransport interface.
+ *
+ * The case where R is a plain ubyte[] is reasonably optimized, so a possible
+ * use case for TInputRangeTransport would be to deserialize some data held in
+ * a memory buffer.
+ */
+final class TInputRangeTransport(R) if (
+  isInputRange!(Unqual!R) && is(ElementType!R : const(ubyte))
+) : TBaseTransport {
+  /**
+   * Constructs a new instance.
+   *
+   * Params:
+   *   data = The input range to use as data.
+   */
+  this(R data) {
+    data_ = data;
+  }
+
+  /**
+   * An input range transport is always open.
+   */
+  override bool isOpen() @property {
+    return true;
+  }
+
+  override bool peek() {
+    return !data_.empty;
+  }
+
+  /**
+   * Opening is a no-op() for an input range transport.
+   */
+  override void open() {}
+
+  /**
+   * Closing is a no-op() for a memory buffer.
+   */
+  override void close() {}
+
+  override size_t read(ubyte[] buf) {
+    auto data = data_.take(buf.length);
+    auto bytes = data.length;
+
+    static if (is(typeof(R.init[1 .. 2]) : const(ubyte)[])) {
+      // put() is currently unnecessarily slow if both ranges are sliceable.
+      buf[0 .. bytes] = data[];
+      data_ = data_[bytes .. $];
+    } else {
+      buf.put(data);
+    }
+
+    return bytes;
+  }
+
+  /**
+   * Shortcut version of readAll() for slicable ranges.
+   *
+   * Because readAll() is typically a very hot path during deserialization,
+   * using this over TBaseTransport.readAll() gives us a nice increase in
+   * speed due to the reduced amount of indirections.
+   */
+  override void readAll(ubyte[] buf) {
+    static if (is(typeof(R.init[1 .. 2]) : const(ubyte)[])) {
+      if (buf.length <= data_.length) {
+        buf[] = data_[0 .. buf.length];
+        data_ = data_[buf.length .. $];
+        return;
+      }
+    }
+    super.readAll(buf);
+  }
+
+  override const(ubyte)[] borrow(ubyte* buf, size_t len) {
+    static if (is(R : const(ubyte)[])) {
+      // Can only borrow if our data type is actually an ubyte array.
+      if (len <= data_.length) {
+        return data_;
+      }
+    }
+    return null;
+  }
+
+  override void consume(size_t len) {
+    static if (is(R : const(ubyte)[])) {
+      if (len > data_.length) {
+        throw new TTransportException("Invalid consume length",
+          TTransportException.Type.BAD_ARGS);
+      }
+      data_ = data_[len .. $];
+    } else {
+      super.consume(len);
+    }
+  }
+
+  /**
+   * Sets a new data range to use.
+   */
+  void reset(R data) {
+    data_ = data;
+  }
+
+private:
+  R data_;
+}
+
+/**
+ * TInputRangeTransport construction helper to avoid having to explicitly
+ * specify the argument type, i.e. to allow the constructor being called using
+ * IFTI (see $(LINK2 http://d.puremagic.com/issues/show_bug.cgi?id=6082, D
+ * Bugzilla enhancement requet 6082)).
+ */
+TInputRangeTransport!R tInputRangeTransport(R)(R data) if (
+  is (TInputRangeTransport!R)
+) {
+  return new TInputRangeTransport!R(data);
+}
diff --git a/lib/d/src/thrift/transport/socket.d b/lib/d/src/thrift/transport/socket.d
new file mode 100644
index 0000000..2b252c2
--- /dev/null
+++ b/lib/d/src/thrift/transport/socket.d
@@ -0,0 +1,453 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+module thrift.transport.socket;
+
+import core.thread : Thread;
+import core.time : dur, Duration;
+import std.array : empty;
+import std.conv : text, to;
+import std.exception : enforce;
+import std.socket;
+import thrift.base;
+import thrift.transport.base;
+import thrift.internal.socket;
+
+/**
+ * Common parts of a socket TTransport implementation, regardless of how the
+ * actual I/O is performed (sync/async).
+ */
+abstract class TSocketBase : TBaseTransport {
+  /**
+   * Constructor that takes an already created, connected (!) socket.
+   *
+   * Params:
+   *   socket = Already created, connected socket object.
+   */
+  this(Socket socket) {
+    socket_ = socket;
+    setSocketOpts();
+  }
+
+  /**
+   * Creates a new unconnected socket that will connect to the given host
+   * on the given port.
+   *
+   * Params:
+   *   host = Remote host.
+   *   port = Remote port.
+   */
+  this(string host, ushort port) {
+    host_ = host;
+    port_ = port;
+  }
+
+  /**
+   * Checks whether the socket is connected.
+   */
+  override bool isOpen() @property {
+    return socket_ !is null;
+  }
+
+  /**
+   * Writes as much data to the socket as there can be in a single OS call.
+   *
+   * Params:
+   *   buf = Data to write.
+   *
+   * Returns: The actual number of bytes written. Never more than buf.length.
+   */
+  abstract size_t writeSome(in ubyte[] buf) out (written) {
+    // DMD @@BUG@@: Enabling this e.g. fails the contract in the
+    // async_test_server, because buf.length evaluates to 0 here, even though
+    // in the method body it correctly is 27 (equal to the return value).
+    version (none) assert(written <= buf.length, text("Implementation wrote " ~
+      "more data than requested to?! (", written, " vs. ", buf.length, ")"));
+  } body {
+    assert(0, "DMD bug? – Why would contracts work for interfaces, but not "
+      "for abstract methods? "
+      "(Error: function […] in and out contracts require function body");
+  }
+
+  /**
+   * Returns the actual address of the peer the socket is connected to.
+   *
+   * In contrast, the host and port properties contain the address used to
+   * establish the connection, and are not updated after the connection.
+   *
+   * The socket must be open when calling this.
+   */
+  Address getPeerAddress() {
+    enforce(isOpen, new TTransportException("Cannot get peer host for " ~
+      "closed socket.", TTransportException.Type.NOT_OPEN));
+
+    if (!peerAddress_) {
+      peerAddress_ = socket_.remoteAddress();
+      assert(peerAddress_);
+    }
+
+    return peerAddress_;
+  }
+
+  /**
+   * The host the socket is connected to or will connect to. Null if an
+   * already connected socket was used to construct the object.
+   */
+  string host() const @property {
+    return host_;
+  }
+
+  /**
+   * The port the socket is connected to or will connect to. Zero if an
+   * already connected socket was used to construct the object.
+   */
+  ushort port() const @property {
+    return port_;
+  }
+
+  /// The socket send timeout.
+  Duration sendTimeout() const @property {
+    return sendTimeout_;
+  }
+
+  /// Ditto
+  void sendTimeout(Duration value) @property {
+    sendTimeout_ = value;
+  }
+
+  /// The socket receiving timeout. Values smaller than 500 ms are not
+  /// supported on Windows.
+  Duration recvTimeout() const @property {
+    return recvTimeout_;
+  }
+
+  /// Ditto
+  void recvTimeout(Duration value) @property {
+    recvTimeout_ = value;
+  }
+
+  /**
+   * Returns the OS handle of the underlying socket.
+   *
+   * Should not usually be used directly, but access to it can be necessary
+   * to interface with C libraries.
+   */
+  typeof(socket_.handle()) socketHandle() @property {
+    return socket_.handle();
+  }
+
+protected:
+  /**
+   * Sets the needed socket options.
+   */
+  void setSocketOpts() {
+    try {
+      alias SocketOptionLevel.SOCKET lvlSock;
+      linger l;
+      l.on = 0;
+      l.time = 0;
+      socket_.setOption(lvlSock, SocketOption.LINGER, l);
+    } catch (SocketException e) {
+      logError("Could not set socket option: %s", e);
+    }
+
+    // Just try to disable Nagle's algorithm – this will fail if we are passed
+    // in a non-TCP socket via the Socket-accepting constructor.
+    try {
+      socket_.setOption(SocketOptionLevel.TCP, SocketOption.TCP_NODELAY, true);
+    } catch (SocketException e) {}
+  }
+
+  /// Remote host.
+  string host_;
+
+  /// Remote port.
+  ushort port_;
+
+  /// Timeout for sending.
+  Duration sendTimeout_;
+
+  /// Timeout for receiving.
+  Duration recvTimeout_;
+
+  /// Cached peer address.
+  Address peerAddress_;
+
+  /// Cached peer host name.
+  string peerHost_;
+
+  /// Cached peer port.
+  ushort peerPort_;
+
+  /// Wrapped socket object.
+  Socket socket_;
+}
+
+/**
+ * Socket implementation of the TTransport interface.
+ *
+ * Due to the limitations of std.socket, currently only TCP/IP sockets are
+ * supported (i.e. Unix domain sockets are not).
+ */
+class TSocket : TSocketBase {
+  ///
+  this(Socket socket) {
+    super(socket);
+  }
+
+  ///
+  this(string host, ushort port) {
+    super(host, port);
+  }
+
+  /**
+   * Connects the socket.
+   */
+  override void open() {
+    if (isOpen) return;
+
+    enforce(!host_.empty, new TTransportException(
+      "Cannot open socket to null host.", TTransportException.Type.NOT_OPEN));
+    enforce(port_ != 0, new TTransportException(
+      "Cannot open socket to port zero.", TTransportException.Type.NOT_OPEN));
+
+    Address[] addrs;
+    try {
+      addrs = getAddress(host_, port_);
+    } catch (SocketException e) {
+      throw new TTransportException("Could not resolve given host string.",
+        TTransportException.Type.NOT_OPEN, __FILE__, __LINE__, e);
+    }
+
+    Exception[] errors;
+    foreach (addr; addrs) {
+      try {
+        socket_ = new TcpSocket(addr.addressFamily);
+        setSocketOpts();
+        socket_.connect(addr);
+        break;
+      } catch (SocketException e) {
+        errors ~= e;
+      }
+    }
+    if (errors.length == addrs.length) {
+      socket_ = null;
+      // Need to throw a TTransportException to abide the TTransport API.
+      import std.algorithm, std.range;
+      throw new TTransportException(
+        text("Failed to connect to ", host_, ":", port_, "."),
+        TTransportException.Type.NOT_OPEN,
+        __FILE__, __LINE__,
+        new TCompoundOperationException(
+          text(
+            "All addresses tried failed (",
+            joiner(map!q{text(a._0, `: "`, a._1.msg, `"`)}(zip(addrs, errors)), ", "),
+            ")."
+          ),
+          errors
+        )
+      );
+    }
+  }
+
+  /**
+   * Closes the socket.
+   */
+  override void close() {
+    if (!isOpen) return;
+
+    socket_.close();
+    socket_ = null;
+  }
+
+  override bool peek() {
+    if (!isOpen) return false;
+
+    ubyte buf;
+    auto r = socket_.receive((&buf)[0 .. 1], SocketFlags.PEEK);
+    if (r == -1) {
+      auto lastErrno = getSocketErrno();
+      static if (connresetOnPeerShutdown) {
+        if (lastErrno == ECONNRESET) {
+          close();
+          return false;
+        }
+      }
+      throw new TTransportException("Peeking into socket failed: " ~
+        socketErrnoString(lastErrno), TTransportException.Type.UNKNOWN);
+    }
+    return (r > 0);
+  }
+
+  override size_t read(ubyte[] buf) {
+    enforce(isOpen, new TTransportException(
+      "Cannot read if socket is not open.", TTransportException.Type.NOT_OPEN));
+
+    typeof(getSocketErrno()) lastErrno;
+    ushort tries;
+    while (tries++ <= maxRecvRetries_) {
+      auto r = socket_.receive(cast(void[])buf);
+
+      // If recv went fine, immediately return.
+      if (r >= 0) return r;
+
+      // Something went wrong, find out how to handle it.
+      lastErrno = getSocketErrno();
+
+      if (lastErrno == INTERRUPTED_ERRNO) {
+        // If the syscall was interrupted, just try again.
+        continue;
+      }
+
+      static if (connresetOnPeerShutdown) {
+        // See top comment.
+        if (lastErrno == ECONNRESET) {
+          return 0;
+        }
+      }
+
+      // Not an error which is handled in a special way, just leave the loop.
+      break;
+    }
+
+    if (isSocketCloseErrno(lastErrno)) {
+      close();
+      throw new TTransportException("Receiving failed, closing socket: " ~
+        socketErrnoString(lastErrno), TTransportException.Type.NOT_OPEN);
+    } else if (lastErrno == TIMEOUT_ERRNO) {
+      throw new TTransportException(TTransportException.Type.TIMED_OUT);
+    } else {
+      throw new TTransportException("Receiving from socket failed: " ~
+        socketErrnoString(lastErrno), TTransportException.Type.UNKNOWN);
+    }
+  }
+
+  override void write(in ubyte[] buf) {
+    size_t sent;
+    while (sent < buf.length) {
+      auto b = writeSome(buf[sent .. $]);
+      if (b == 0) {
+        // This should only happen if the timeout set with SO_SNDTIMEO expired.
+        throw new TTransportException("send() timeout expired.",
+          TTransportException.Type.TIMED_OUT);
+      }
+      sent += b;
+    }
+    assert(sent == buf.length);
+  }
+
+  override size_t writeSome(in ubyte[] buf) {
+    enforce(isOpen, new TTransportException(
+      "Cannot write if file is not open.", TTransportException.Type.NOT_OPEN));
+
+    auto r = socket_.send(buf);
+
+    // Everything went well, just return the number of bytes written.
+    if (r > 0) return r;
+
+    // Handle error conditions.
+    if (r < 0) {
+      auto lastErrno = getSocketErrno();
+
+      if (lastErrno == WOULD_BLOCK_ERRNO) {
+        // Not an exceptional error per se – even with blocking sockets,
+        // EAGAIN apparently is returned sometimes on out-of-resource
+        // conditions (see the C++ implementation for details). Also, this
+        // allows using TSocket with non-blocking sockets e.g. in
+        // TNonblockingServer.
+        return 0;
+      }
+
+      auto type = TTransportException.Type.UNKNOWN;
+      if (isSocketCloseErrno(lastErrno)) {
+        type = TTransportException.Type.NOT_OPEN;
+        close();
+      }
+
+      throw new TTransportException("Sending to socket failed: " ~
+        socketErrnoString(lastErrno), type);
+    }
+
+    // send() should never return 0.
+    throw new TTransportException("Sending to socket failed (0 bytes written).",
+      TTransportException.Type.UNKNOWN);
+  }
+
+  override void sendTimeout(Duration value) @property {
+    super.sendTimeout(value);
+    setTimeout(SocketOption.SNDTIMEO, value);
+  }
+
+  override void recvTimeout(Duration value) @property {
+    super.recvTimeout(value);
+    setTimeout(SocketOption.RCVTIMEO, value);
+  }
+
+  /**
+   * Maximum number of retries for receiving from socket on read() in case of
+   * EAGAIN/EINTR.
+   */
+  ushort maxRecvRetries() @property const {
+    return maxRecvRetries_;
+  }
+
+  /// Ditto
+  void maxRecvRetries(ushort value) @property {
+    maxRecvRetries_ = value;
+  }
+
+  /// Ditto
+  enum DEFAULT_MAX_RECV_RETRIES = 5;
+
+protected:
+  override void setSocketOpts() {
+    super.setSocketOpts();
+    setTimeout(SocketOption.SNDTIMEO, sendTimeout_);
+    setTimeout(SocketOption.RCVTIMEO, recvTimeout_);
+  }
+
+  void setTimeout(SocketOption type, Duration value) {
+    assert(type == SocketOption.SNDTIMEO || type == SocketOption.RCVTIMEO);
+    version (Win32) {
+      if (value > dur!"hnsecs"(0) && value < dur!"msecs"(500)) {
+        logError(
+          "Socket %s timeout of %s ms might be raised to 500 ms on Windows.",
+          (type == SocketOption.SNDTIMEO) ? "send" : "receive",
+          value.total!"msecs"
+        );
+      }
+    }
+
+    if (socket_) {
+      try {
+        socket_.setOption(SocketOptionLevel.SOCKET, type, value);
+      } catch (SocketException e) {
+        throw new TTransportException(
+          "Could not set send timeout: " ~ socketErrnoString(e.errorCode),
+          TTransportException.Type.UNKNOWN,
+          __FILE__,
+          __LINE__,
+          e
+        );
+      }
+    }
+  }
+
+  /// Maximum number of recv() retries.
+  ushort maxRecvRetries_  = DEFAULT_MAX_RECV_RETRIES;
+}
diff --git a/lib/d/src/thrift/transport/ssl.d b/lib/d/src/thrift/transport/ssl.d
new file mode 100644
index 0000000..da0eb27
--- /dev/null
+++ b/lib/d/src/thrift/transport/ssl.d
@@ -0,0 +1,680 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/**
+ * OpenSSL socket implementation, in large parts ported from C++.
+ */
+module thrift.transport.ssl;
+
+import core.exception : onOutOfMemoryError;
+import core.stdc.errno : getErrno, EINTR;
+import core.sync.mutex : Mutex;
+import core.memory : GC;
+import core.stdc.config;
+import core.stdc.stdlib : free, malloc;
+import std.ascii : toUpper;
+import std.array : empty, front, popFront;
+import std.conv : emplace, to;
+import std.exception : enforce;
+import std.socket : Address, InternetAddress, Internet6Address, Socket;
+import std.string : toStringz;
+import deimos.openssl.err;
+import deimos.openssl.rand;
+import deimos.openssl.ssl;
+import deimos.openssl.x509v3;
+import thrift.base;
+import thrift.internal.ssl;
+import thrift.transport.base;
+import thrift.transport.socket;
+
+/**
+ * SSL encrypted socket implementation using OpenSSL.
+ *
+ * Note:
+ * On Posix systems which do not have the BSD-specific SO_NOSIGPIPE flag, you
+ * might want to ignore the SIGPIPE signal, as OpenSSL might try to write to
+ * a closed socket if the peer disconnects abruptly:
+ * ---
+ * import core.stdc.signal;
+ * import core.sys.posix.signal;
+ * signal(SIGPIPE, SIG_IGN);
+ * ---
+ */
+final class TSSLSocket : TSocket {
+  /**
+   * Creates an instance that wraps an already created, connected (!) socket.
+   *
+   * Params:
+   *   context = The SSL socket context to use. A reference to it is stored so
+   *     that it doesn't get cleaned up while the socket is used.
+   *   socket = Already created, connected socket object.
+   */
+  this(TSSLContext context, Socket socket) {
+    super(socket);
+    context_ = context;
+    serverSide_ = context.serverSide;
+    accessManager_ = context.accessManager;
+  }
+
+  /**
+   * Creates a new unconnected socket that will connect to the given host
+   * on the given port.
+   *
+   * Params:
+   *   context = The SSL socket context to use. A reference to it is stored so
+    *     that it doesn't get cleaned up while the socket is used.
+   *   host = Remote host.
+   *   port = Remote port.
+   */
+  this(TSSLContext context, string host, ushort port) {
+    super(host, port);
+    context_ = context;
+    serverSide_ = context.serverSide;
+    accessManager_ = context.accessManager;
+  }
+
+  override bool isOpen() @property {
+    if (ssl_ is null || !super.isOpen()) return false;
+
+    auto shutdown = SSL_get_shutdown(ssl_);
+    bool shutdownReceived = (shutdown & SSL_RECEIVED_SHUTDOWN) != 0;
+    bool shutdownSent = (shutdown & SSL_SENT_SHUTDOWN) != 0;
+    return !(shutdownReceived && shutdownSent);
+  }
+
+  override bool peek() {
+    if (!isOpen) return false;
+    checkHandshake();
+
+    byte bt;
+    auto rc = SSL_peek(ssl_, &bt, bt.sizeof);
+    enforce(rc >= 0, getSSLException("SSL_peek"));
+
+    if (rc == 0) {
+      ERR_clear_error();
+    }
+    return (rc > 0);
+  }
+
+  override void open() {
+    enforce(!serverSide_, "Cannot open a server-side SSL socket.");
+    if (isOpen) return;
+    super.open();
+  }
+
+  override void close() {
+    if (!isOpen) return;
+
+    if (ssl_ !is null) {
+      // Two-step SSL shutdown.
+      auto rc = SSL_shutdown(ssl_);
+      if (rc == 0) {
+        rc = SSL_shutdown(ssl_);
+      }
+      if (rc < 0) {
+        // Do not throw an exception here as leaving the transport "open" will
+        // probably produce only more errors, and the chance we can do
+        // something about the error e.g. by retrying is very low.
+        logError("Error shutting down SSL: %s", getSSLException());
+      }
+
+      SSL_free(ssl_);
+      ssl_ = null;
+      ERR_remove_state(0);
+    }
+    super.close();
+  }
+
+  override size_t read(ubyte[] buf) {
+    checkHandshake();
+
+    int bytes;
+    foreach (_; 0 .. maxRecvRetries) {
+      bytes = SSL_read(ssl_, buf.ptr, cast(int)buf.length);
+      if (bytes >= 0) break;
+
+      auto errnoCopy = getErrno();
+      if (SSL_get_error(ssl_, bytes) == SSL_ERROR_SYSCALL) {
+        if (ERR_get_error() == 0 && errnoCopy == EINTR) {
+          // FIXME: Windows.
+          continue;
+        }
+      }
+      throw getSSLException("SSL_read");
+    }
+    return bytes;
+  }
+
+  override void write(in ubyte[] buf) {
+    checkHandshake();
+
+    // Loop in case SSL_MODE_ENABLE_PARTIAL_WRITE is set in SSL_CTX.
+    size_t written = 0;
+    while (written < buf.length) {
+      auto bytes = SSL_write(ssl_, buf.ptr + written,
+        cast(int)(buf.length - written));
+      if (bytes <= 0) {
+        throw getSSLException("SSL_write");
+      }
+      written += bytes;
+    }
+  }
+
+  override void flush() {
+    checkHandshake();
+
+    auto bio = SSL_get_wbio(ssl_);
+    enforce(bio !is null, new TSSLException("SSL_get_wbio returned null"));
+
+    auto rc = BIO_flush(bio);
+    enforce(rc == 1, getSSLException("BIO_flush"));
+  }
+
+  /**
+   * Whether to use client or server side SSL handshake protocol.
+   */
+  bool serverSide() @property const {
+    return serverSide_;
+  }
+
+  /// Ditto
+  void serverSide(bool value) @property {
+    serverSide_ = value;
+  }
+
+  /**
+   * The access manager to use.
+   */
+  void accessManager(TAccessManager value) @property {
+    accessManager_ = value;
+  }
+
+private:
+  void checkHandshake() {
+    enforce(super.isOpen(), new TTransportException(
+      TTransportException.Type.NOT_OPEN));
+
+    if (ssl_ !is null) return;
+    ssl_ = context_.createSSL();
+
+    SSL_set_fd(ssl_, socketHandle);
+    int rc;
+    if (serverSide_) {
+      rc = SSL_accept(ssl_);
+    } else {
+      rc = SSL_connect(ssl_);
+    }
+    enforce(rc > 0, getSSLException());
+    authorize(ssl_, accessManager_, getPeerAddress(),
+      (serverSide_ ? getPeerAddress().toHostNameString() : host));
+  }
+
+  bool serverSide_;
+  SSL* ssl_;
+  TSSLContext context_;
+  TAccessManager accessManager_;
+}
+
+/**
+ * Represents an OpenSSL context with certification settings, etc. and handles
+ * initialization/teardown.
+ *
+ * OpenSSL is initialized when the first instance of this class is created
+ * and shut down when the last one is destroyed (thread-safe).
+ */
+class TSSLContext {
+  this() {
+    initMutex_.lock();
+    scope(exit) initMutex_.unlock();
+
+    if (count_ == 0) {
+      initializeOpenSSL();
+      randomize();
+    }
+    count_++;
+
+    ctx_ = SSL_CTX_new(TLSv1_method());
+    enforce(ctx_, getSSLException("SSL_CTX_new"));
+    SSL_CTX_set_mode(ctx_, SSL_MODE_AUTO_RETRY);
+  }
+
+  ~this() {
+    initMutex_.lock();
+    scope(exit) initMutex_.unlock();
+
+    if (ctx_ !is null) {
+      SSL_CTX_free(ctx_);
+      ctx_ = null;
+    }
+
+    count_--;
+    if (count_ == 0) {
+      cleanupOpenSSL();
+    }
+  }
+
+  /**
+   * Ciphers to be used in SSL handshake process.
+   *
+   * The string must be in the colon-delimited OpenSSL notation described in
+   * ciphers(1), for example: "ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH".
+   */
+  void ciphers(string enable) @property {
+    auto rc = SSL_CTX_set_cipher_list(ctx_, toStringz(enable));
+
+    enforce(ERR_peek_error() == 0, getSSLException("SSL_CTX_set_cipher_list"));
+    enforce(rc > 0, new TSSLException("None of specified ciphers are supported"));
+  }
+
+  /**
+   * Whether peer is required to present a valid certificate.
+   */
+  void authenticate(bool required) @property {
+    int mode;
+    if (required) {
+      mode = SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT |
+        SSL_VERIFY_CLIENT_ONCE;
+    } else {
+      mode = SSL_VERIFY_NONE;
+    }
+    SSL_CTX_set_verify(ctx_, mode, null);
+  }
+
+  /**
+   * Load server certificate.
+   *
+   * Params:
+   *   path = Path to the certificate file.
+   *   format = Certificate file format. Defaults to PEM, which is currently
+   *     the only one supported.
+   */
+  void loadCertificate(string path, string format = "PEM") {
+    enforce(path !is null && format !is null, new TTransportException(
+      "loadCertificateChain: either <path> or <format> is null",
+      TTransportException.Type.BAD_ARGS));
+
+    if (format == "PEM") {
+      enforce(SSL_CTX_use_certificate_chain_file(ctx_, toStringz(path)),
+        getSSLException(
+          `Could not load SSL server certificate from file "` ~ path ~ `"`
+        )
+      );
+    } else {
+      throw new TSSLException("Unsupported certificate format: " ~ format);
+    }
+  }
+
+  /*
+   * Load private key.
+   *
+   * Params:
+   *   path = Path to the certificate file.
+   *   format = Private key file format. Defaults to PEM, which is currently
+   *     the only one supported.
+   */
+  void loadPrivateKey(string path, string format = "PEM") {
+    enforce(path !is null && format !is null, new TTransportException(
+      "loadPrivateKey: either <path> or <format> is NULL",
+      TTransportException.Type.BAD_ARGS));
+
+    if (format == "PEM") {
+      enforce(SSL_CTX_use_PrivateKey_file(ctx_, toStringz(path), SSL_FILETYPE_PEM),
+        getSSLException(
+          `Could not load SSL private key from file "` ~ path ~ `"`
+        )
+      );
+    } else {
+      throw new TSSLException("Unsupported certificate format: " ~ format);
+    }
+  }
+
+  /**
+   * Load trusted certificates from specified file (in PEM format).
+   *
+   * Params.
+   *   path = Path to the file containing the trusted certificates.
+   */
+  void loadTrustedCertificates(string path) {
+    enforce(path !is null, new TTransportException(
+      "loadTrustedCertificates: <path> is NULL",
+      TTransportException.Type.BAD_ARGS));
+
+    enforce(SSL_CTX_load_verify_locations(ctx_, toStringz(path), null),
+      getSSLException(
+        `Could not load SSL trusted certificate list from file "` ~ path ~ `"`
+      )
+    );
+  }
+
+  /**
+   * Called during OpenSSL initialization to seed the OpenSSL entropy pool.
+   *
+   * Defaults to simply calling RAND_poll(), but it can be overwritten if a
+   * different, perhaps more secure implementation is desired.
+   */
+  void randomize() {
+    RAND_poll();
+  }
+
+  /**
+   * Whether to use client or server side SSL handshake protocol.
+   */
+  bool serverSide() @property const {
+    return serverSide_;
+  }
+
+  /// Ditto
+  void serverSide(bool value) @property {
+    serverSide_ = value;
+  }
+
+  /**
+   * The access manager to use.
+   */
+  TAccessManager accessManager() @property {
+    if (!serverSide_ && !accessManager_) {
+      accessManager_ = new TDefaultClientAccessManager;
+    }
+    return accessManager_;
+  }
+
+  /// Ditto
+  void accessManager(TAccessManager value) @property {
+    accessManager_ = value;
+  }
+
+  SSL* createSSL() out (result) {
+    assert(result);
+  } body {
+    auto result = SSL_new(ctx_);
+    enforce(result, getSSLException("SSL_new"));
+    return result;
+  }
+
+protected:
+  /**
+   * Override this method for custom password callback. It may be called
+   * multiple times at any time during a session as necessary.
+   *
+   * Params:
+   *   size = Maximum length of password, including null byte.
+   */
+  string getPassword(int size) nothrow out(result) {
+    assert(result.length < size);
+  } body {
+    return "";
+  }
+
+  /**
+   * Notifies OpenSSL to use getPassword() instead of the default password
+   * callback with getPassword().
+   */
+  void overrideDefaultPasswordCallback() {
+    SSL_CTX_set_default_passwd_cb(ctx_, &passwordCallback);
+    SSL_CTX_set_default_passwd_cb_userdata(ctx_, cast(void*)this);
+  }
+
+  SSL_CTX* ctx_;
+
+private:
+  bool serverSide_;
+  TAccessManager accessManager_;
+
+  shared static this() {
+    initMutex_ = new Mutex();
+  }
+
+  static void initializeOpenSSL() {
+    if (initialized_) {
+      return;
+    }
+    initialized_ = true;
+
+    SSL_library_init();
+    SSL_load_error_strings();
+
+    mutexes_ = new Mutex[CRYPTO_num_locks()];
+    foreach (ref m; mutexes_) {
+      m = new Mutex;
+    }
+
+    import thrift.internal.traits;
+    // As per the OpenSSL threads manpage, this isn't needed on Windows.
+    version (Posix) {
+      CRYPTO_set_id_callback(assumeNothrow(&threadIdCallback));
+    }
+    CRYPTO_set_locking_callback(assumeNothrow(&lockingCallback));
+    CRYPTO_set_dynlock_create_callback(assumeNothrow(&dynlockCreateCallback));
+    CRYPTO_set_dynlock_lock_callback(assumeNothrow(&dynlockLockCallback));
+    CRYPTO_set_dynlock_destroy_callback(assumeNothrow(&dynlockDestroyCallback));
+  }
+
+  static void cleanupOpenSSL() {
+    if (!initialized_) return;
+
+    initialized_ = false;
+    CRYPTO_set_locking_callback(null);
+    CRYPTO_set_dynlock_create_callback(null);
+    CRYPTO_set_dynlock_lock_callback(null);
+    CRYPTO_set_dynlock_destroy_callback(null);
+    CRYPTO_cleanup_all_ex_data();
+    ERR_free_strings();
+    ERR_remove_state(0);
+  }
+
+  static extern(C) {
+    version (Posix) {
+      import core.sys.posix.pthread : pthread_self;
+      c_ulong threadIdCallback() {
+        return cast(c_ulong)pthread_self();
+      }
+    }
+
+    void lockingCallback(int mode, int n, const(char)* file, int line) {
+      if (mode & CRYPTO_LOCK) {
+        mutexes_[n].lock();
+      } else {
+        mutexes_[n].unlock();
+      }
+    }
+
+    CRYPTO_dynlock_value* dynlockCreateCallback(const(char)* file, int line) {
+      enum size =  __traits(classInstanceSize, Mutex);
+      auto mem = malloc(size)[0 .. size];
+      if (!mem) onOutOfMemoryError();
+      GC.addRange(mem.ptr, size);
+      auto mutex = emplace!Mutex(mem);
+      return cast(CRYPTO_dynlock_value*)mutex;
+    }
+
+    void dynlockLockCallback(int mode, CRYPTO_dynlock_value* l,
+      const(char)* file, int line)
+    {
+      if (l is null) return;
+      if (mode & CRYPTO_LOCK) {
+        (cast(Mutex)l).lock();
+      } else {
+        (cast(Mutex)l).unlock();
+      }
+    }
+
+    void dynlockDestroyCallback(CRYPTO_dynlock_value* l,
+      const(char)* file, int line)
+    {
+      GC.removeRange(l);
+      clear(cast(Mutex)l);
+      free(l);
+    }
+
+    int passwordCallback(char* password, int size, int, void* data) nothrow {
+      auto context = cast(TSSLContext) data;
+      auto userPassword = context.getPassword(size);
+      auto len = userPassword.length;
+      if (len > size) {
+        len = size;
+      }
+      password[0 .. len] = userPassword[0 .. len]; // TODO: \0 handling correct?
+      return cast(int)len;
+    }
+  }
+
+  static __gshared bool initialized_;
+  static __gshared Mutex initMutex_;
+  static __gshared Mutex[] mutexes_;
+  static __gshared uint count_;
+}
+
+/**
+ * Decides whether a remote host is legitimate or not.
+ *
+ * It is usually set at a TSSLContext, which then passes it to all the created
+ * TSSLSockets.
+ */
+class TAccessManager {
+  ///
+  enum Decision {
+    DENY = -1, /// Deny access.
+    SKIP =  0, /// Cannot decide, move on to next check (deny if last).
+    ALLOW = 1  /// Allow access.
+  }
+
+  /**
+   * Determines whether a peer should be granted access or not based on its
+   * IP address.
+   *
+   * Called once after SSL handshake is completes successfully and before peer
+   * certificate is examined.
+   *
+   * If a valid decision (ALLOW or DENY) is returned, the peer certificate
+   * will not be verified.
+   */
+  Decision verify(Address address) {
+    return Decision.DENY;
+  }
+
+  /**
+   * Determines whether a peer should be granted access or not based on a
+   * name from its certificate.
+   *
+   * Called every time a DNS subjectAltName/common name is extracted from the
+   * peer's certificate.
+   *
+   * Params:
+   *   host = The actual host name string from the socket connection.
+   *   certHost = A host name string from the certificate.
+   */
+  Decision verify(string host, const(char)[] certHost) {
+    return Decision.DENY;
+  }
+
+  /**
+   * Determines whether a peer should be granted access or not based on an IP
+   * address from its certificate.
+   *
+   * Called every time an IP subjectAltName is extracted from the peer's
+   * certificate.
+   *
+   * Params:
+   *   address = The actual address from the socket connection.
+   *   certHost = A host name string from the certificate.
+   */
+  Decision verify(Address address, ubyte[] certAddress) {
+    return Decision.DENY;
+  }
+}
+
+/**
+ * Default access manager implementation, which just checks the host name
+ * resp. IP address of the connection against the certificate.
+ */
+class TDefaultClientAccessManager : TAccessManager {
+  override Decision verify(Address address) {
+    return Decision.SKIP;
+  }
+
+  override Decision verify(string host, const(char)[] certHost) {
+    if (host.empty || certHost.empty) {
+      return Decision.SKIP;
+    }
+    return (matchName(host, certHost) ? Decision.ALLOW : Decision.SKIP);
+  }
+
+  override Decision verify(Address address, ubyte[] certAddress) {
+    bool match;
+    if (certAddress.length == 4) {
+      if (auto ia = cast(InternetAddress)address) {
+        match = ((cast(ubyte*)ia.addr())[0 .. 4] == certAddress[]);
+      }
+    } else if (certAddress.length == 16) {
+      if (auto ia = cast(Internet6Address)address) {
+        match = (ia.addr() == certAddress[]);
+      }
+    }
+    return (match ? Decision.ALLOW : Decision.SKIP);
+  }
+}
+
+private {
+  /**
+   * Matches a name with a pattern. The pattern may include wildcard. A single
+   * wildcard "*" can match up to one component in the domain name.
+   *
+   * Params:
+   *   host = Host name to match, typically the SSL remote peer.
+   *   pattern = Host name pattern, typically from the SSL certificate.
+   *
+   * Returns: true if host matches pattern, false otherwise.
+   */
+  bool matchName(const(char)[] host, const(char)[] pattern) {
+    while (!host.empty && !pattern.empty) {
+      if (toUpper(pattern.front) == toUpper(host.front)) {
+        host.popFront;
+        pattern.popFront;
+      } else if (pattern.front == '*') {
+        while (!host.empty && host.front != '.') {
+          host.popFront;
+        }
+        pattern.popFront;
+      } else {
+        break;
+      }
+    }
+    return (host.empty && pattern.empty);
+  }
+
+  unittest {
+    enforce(matchName("thrift.apache.org", "*.apache.org"));
+    enforce(!matchName("thrift.apache.org", "apache.org"));
+    enforce(matchName("thrift.apache.org", "thrift.*.*"));
+    enforce(matchName("", ""));
+    enforce(!matchName("", "*"));
+  }
+}
+
+/**
+ * SSL-level exception.
+ */
+class TSSLException : TTransportException {
+  ///
+  this(string msg, string file = __FILE__, size_t line = __LINE__,
+    Throwable next = null)
+  {
+    super(msg, TTransportException.Type.INTERNAL_ERROR, file, line, next);
+  }
+}
diff --git a/lib/d/src/thrift/transport/zlib.d b/lib/d/src/thrift/transport/zlib.d
new file mode 100644
index 0000000..9496f9b
--- /dev/null
+++ b/lib/d/src/thrift/transport/zlib.d
@@ -0,0 +1,497 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+module thrift.transport.zlib;
+
+import core.bitop : bswap;
+import etc.c.zlib;
+import std.algorithm : min;
+import std.array : empty;
+import std.conv : to;
+import std.exception : enforce;
+import thrift.base;
+import thrift.transport.base;
+
+/**
+ * zlib transport. Compresses (deflates) data before writing it to the
+ * underlying transport, and decompresses (inflates) it after reading.
+ */
+final class TZlibTransport : TBaseTransport {
+  // These defaults have yet to be optimized.
+  enum DEFAULT_URBUF_SIZE = 128;
+  enum DEFAULT_CRBUF_SIZE = 1024;
+  enum DEFAULT_UWBUF_SIZE = 128;
+  enum DEFAULT_CWBUF_SIZE = 1024;
+
+  /**
+   * Constructs a new zlib transport.
+   *
+   * Params:
+   *   transport = The underlying transport to wrap.
+   *   urbufSize = The size of the uncompressed reading buffer, in bytes.
+   *   crbufSize = The size of the compressed reading buffer, in bytes.
+   *   uwbufSize = The size of the uncompressed writing buffer, in bytes.
+   *   cwbufSize = The size of the compressed writing buffer, in bytes.
+   */
+  this(
+    TTransport transport,
+    size_t urbufSize = DEFAULT_URBUF_SIZE,
+    size_t crbufSize = DEFAULT_CRBUF_SIZE,
+    size_t uwbufSize = DEFAULT_UWBUF_SIZE,
+    size_t cwbufSize = DEFAULT_CWBUF_SIZE
+  ) {
+    transport_ = transport;
+
+    enforce(uwbufSize >= MIN_DIRECT_DEFLATE_SIZE, new TTransportException(
+      "TZLibTransport: uncompressed write buffer must be at least " ~
+      to!string(MIN_DIRECT_DEFLATE_SIZE) ~ "bytes in size.",
+      TTransportException.Type.BAD_ARGS));
+
+    urbuf_ = new ubyte[urbufSize];
+    crbuf_ = new ubyte[crbufSize];
+    uwbuf_ = new ubyte[uwbufSize];
+    cwbuf_ = new ubyte[cwbufSize];
+
+    rstream_ = new z_stream;
+    rstream_.next_in = crbuf_.ptr;
+    rstream_.avail_in  = 0;
+    rstream_.next_out = urbuf_.ptr;
+    rstream_.avail_out = to!uint(urbuf_.length);
+
+    wstream_ = new z_stream;
+    wstream_.next_in = uwbuf_.ptr;
+    wstream_.avail_in = 0;
+    wstream_.next_out = cwbuf_.ptr;
+    wstream_.avail_out = to!uint(crbuf_.length);
+
+    zlibEnforce(inflateInit(rstream_), rstream_);
+    scope (failure) {
+      zlibLogError(inflateEnd(rstream_), rstream_);
+    }
+
+    zlibEnforce(deflateInit(wstream_, Z_DEFAULT_COMPRESSION), wstream_);
+  }
+
+  ~this() {
+    zlibLogError(inflateEnd(rstream_), rstream_);
+
+    auto result = deflateEnd(wstream_);
+    // Z_DATA_ERROR may indicate unflushed data, so just ignore it.
+    if (result != Z_DATA_ERROR) {
+      zlibLogError(result, wstream_);
+    }
+  }
+
+  /**
+   * Returns the wrapped transport.
+   */
+  TTransport underlyingTransport() @property {
+    return transport_;
+  }
+
+  override bool isOpen() @property {
+    return readAvail > 0 || transport_.isOpen;
+  }
+
+  override bool peek() {
+    return readAvail > 0 || transport_.peek();
+  }
+
+  override void open() {
+    transport_.open();
+  }
+
+  override void close() {
+    transport_.close();
+  }
+
+  override size_t read(ubyte[] buf) {
+    // The C++ implementation suggests to skip urbuf on big reads in future
+    // versions, we would benefit from it as well.
+    auto origLen = buf.length;
+    while (true) {
+      auto give = min(readAvail, buf.length);
+
+      // If std.range.put was optimized for slicable ranges, it could be used
+      // here as well.
+      buf[0 .. give] = urbuf_[urpos_ .. urpos_ + give];
+      buf = buf[give .. $];
+      urpos_ += give;
+
+      auto need = buf.length;
+      if (need == 0) {
+        // We could manage to get the all the data requested.
+        return origLen;
+      }
+
+      if (inputEnded_ || (need < origLen && rstream_.avail_in == 0)) {
+        // We didn't fill buf completely, but there is no more data available.
+        return origLen - need;
+      }
+
+      // Refill our buffer by reading more data through zlib.
+      rstream_.next_out = urbuf_.ptr;
+      rstream_.avail_out = to!uint(urbuf_.length);
+      urpos_ = 0;
+
+      if (!readFromZlib()) {
+        // Couldn't get more data from the underlying transport.
+        return origLen - need;
+      }
+    }
+  }
+
+  override void write(in ubyte[] buf) {
+    enforce(!outputFinished_, new TTransportException(
+      "write() called after finish()", TTransportException.Type.BAD_ARGS));
+
+    auto len = buf.length;
+    if (len > MIN_DIRECT_DEFLATE_SIZE) {
+      flushToZlib(uwbuf_[0 .. uwpos_], Z_NO_FLUSH);
+      uwpos_ = 0;
+      flushToZlib(buf, Z_NO_FLUSH);
+    } else if (len > 0) {
+      if (uwbuf_.length - uwpos_ < len) {
+        flushToZlib(uwbuf_[0 .. uwpos_], Z_NO_FLUSH);
+        uwpos_ = 0;
+      }
+      uwbuf_[uwpos_ .. uwpos_ + len] = buf[];
+      uwpos_ += len;
+    }
+  }
+
+  override void flush() {
+    enforce(!outputFinished_, new TTransportException(
+      "flush() called after finish()", TTransportException.Type.BAD_ARGS));
+
+    flushToTransport(Z_SYNC_FLUSH);
+  }
+
+  override const(ubyte)[] borrow(ubyte* buf, size_t len) {
+    if (len <= readAvail) {
+      return urbuf_[urpos_ .. $];
+    }
+    return null;
+  }
+
+  override void consume(size_t len) {
+    enforce(readAvail >= len, new TTransportException(
+      "consume() did not follow a borrow().", TTransportException.Type.BAD_ARGS));
+    urpos_ += len;
+  }
+
+  /**
+   * Finalize the zlib stream.
+   *
+   * This causes zlib to flush any pending write data and write end-of-stream
+   * information, including the checksum.  Once finish() has been called, no
+   * new data can be written to the stream.
+   */
+  void finish() {
+    enforce(!outputFinished_, new TTransportException(
+      "flush() called on already finished TZlibTransport",
+      TTransportException.Type.BAD_ARGS));
+    flushToTransport(Z_FINISH);
+  }
+
+  /**
+   * Verify the checksum at the end of the zlib stream (by finish()).
+   *
+   * May only be called after all data has been read.
+   *
+   * Throws: TTransportException when the checksum is corrupted or there is
+   *   still unread data left.
+   */
+  void verifyChecksum() {
+    // If zlib has already reported the end of the stream, the checksum has
+    // been verified, no.
+    if (inputEnded_) return;
+
+    enforce(!readAvail, new TTransportException(
+      "verifyChecksum() called before end of zlib stream",
+      TTransportException.Type.CORRUPTED_DATA));
+
+    rstream_.next_out = urbuf_.ptr;
+    rstream_.avail_out = to!uint(urbuf_.length);
+    urpos_ = 0;
+
+    // readFromZlib() will throw an exception if the checksum is bad.
+    enforce(readFromZlib(), new TTransportException(
+      "checksum not available yet in verifyChecksum()",
+      TTransportException.Type.CORRUPTED_DATA));
+
+    enforce(inputEnded_, new TTransportException(
+      "verifyChecksum() called before end of zlib stream",
+      TTransportException.Type.CORRUPTED_DATA));
+
+    // If we get here, we are at the end of the stream and thus zlib has
+    // successfully verified the checksum.
+  }
+
+private:
+  size_t readAvail() const @property {
+    return urbuf_.length - rstream_.avail_out - urpos_;
+  }
+
+  bool readFromZlib() {
+    assert(!inputEnded_);
+
+    if (rstream_.avail_in == 0) {
+      // zlib has used up all the compressed data we provided in crbuf, read
+      // some more from the underlying transport.
+      auto got = transport_.read(crbuf_);
+      if (got == 0) return false;
+      rstream_.next_in = crbuf_.ptr;
+      rstream_.avail_in = to!uint(got);
+    }
+
+    // We have some compressed data now, uncompress it.
+    auto zlib_result = inflate(rstream_, Z_SYNC_FLUSH);
+    if (zlib_result == Z_STREAM_END) {
+      inputEnded_ = true;
+    } else {
+      zlibEnforce(zlib_result, rstream_);
+    }
+
+    return true;
+  }
+
+  void flushToTransport(int type)  {
+    // Compress remaining data in uwbuf_ to cwbuf_.
+    flushToZlib(uwbuf_[0 .. uwpos_], type);
+    uwpos_ = 0;
+
+    // Write all compressed data to the transport.
+    transport_.write(cwbuf_[0 .. $ - wstream_.avail_out]);
+    wstream_.next_out = cwbuf_.ptr;
+    wstream_.avail_out = to!uint(cwbuf_.length);
+
+    // Flush the transport.
+    transport_.flush();
+  }
+
+  void flushToZlib(in ubyte[] buf, int type) {
+    wstream_.next_in = cast(ubyte*)buf.ptr; // zlib only reads, cast is safe.
+    wstream_.avail_in = to!uint(buf.length);
+
+    while (true) {
+      if (type == Z_NO_FLUSH && wstream_.avail_in == 0) {
+        break;
+      }
+
+      if (wstream_.avail_out == 0) {
+        // cwbuf has been exhausted by zlib, flush to the underlying transport.
+        transport_.write(cwbuf_);
+        wstream_.next_out = cwbuf_.ptr;
+        wstream_.avail_out = to!uint(cwbuf_.length);
+      }
+
+      auto zlib_result = deflate(wstream_, type);
+
+      if (type == Z_FINISH && zlib_result == Z_STREAM_END) {
+        assert(wstream_.avail_in == 0);
+        outputFinished_ = true;
+        break;
+      }
+
+      zlibEnforce(zlib_result, wstream_);
+
+      if ((type == Z_SYNC_FLUSH || type == Z_FULL_FLUSH) &&
+          wstream_.avail_in == 0 && wstream_.avail_out != 0) {
+        break;
+      }
+    }
+  }
+
+  static void zlibEnforce(int status, z_stream* stream) {
+    if (status != Z_OK) {
+      throw new TZlibException(status, stream.msg);
+    }
+  }
+
+  static void zlibLogError(int status, z_stream* stream) {
+    if (status != Z_OK) {
+      logError("TZlibTransport: zlib failure in destructor: %s",
+        TZlibException.errorMessage(status, stream.msg));
+    }
+  }
+
+  // Writes smaller than this are buffered up (due to zlib handling overhead).
+  // Larger (or equal) writes are dumped straight to zlib.
+  enum MIN_DIRECT_DEFLATE_SIZE = 32;
+
+  TTransport transport_;
+  z_stream* rstream_;
+  z_stream* wstream_;
+
+  /// Whether zlib has reached the end of the input stream.
+  bool inputEnded_;
+
+  /// Whether the output stream was already finish()ed.
+  bool outputFinished_;
+
+  /// Compressed input data buffer.
+  ubyte[] crbuf_;
+
+  /// Uncompressed input data buffer.
+  ubyte[] urbuf_;
+  size_t urpos_;
+
+  /// Uncompressed output data buffer (where small writes are accumulated
+  /// before handing over to zlib).
+  ubyte[] uwbuf_;
+  size_t uwpos_;
+
+  /// Compressed output data buffer (filled by zlib, we flush it to the
+  /// underlying transport).
+  ubyte[] cwbuf_;
+}
+
+/**
+ * Wraps given transports into TZlibTransports.
+ */
+alias TWrapperTransportFactory!TZlibTransport TZlibTransportFactory;
+
+/**
+ * An INTERNAL_ERROR-type TTransportException originating from an error
+ * signaled by zlib.
+ */
+class TZlibException : TTransportException {
+  this(int statusCode, const(char)* msg) {
+    super(errorMessage(statusCode, msg), TTransportException.Type.INTERNAL_ERROR);
+    zlibStatusCode = statusCode;
+    zlibMsg = msg ? to!string(msg) : "(null)";
+  }
+
+  int zlibStatusCode;
+  string zlibMsg;
+
+  static string errorMessage(int statusCode, const(char)* msg) {
+    string result = "zlib error: ";
+
+    if (msg) {
+      result ~= to!string(msg);
+    } else {
+      result ~= "(no message)";
+    }
+
+    result ~= " (status code = " ~ to!string(statusCode) ~ ")";
+    return result;
+  }
+}
+
+version (unittest) {
+  import std.exception : collectException;
+  import thrift.transport.memory;
+}
+
+// Make sure basic reading/writing works.
+unittest {
+  auto buf = new TMemoryBuffer;
+  auto zlib = new TZlibTransport(buf);
+
+  immutable ubyte[] data = [1, 2, 3, 4, 5];
+  zlib.write(data);
+  zlib.finish();
+
+  auto result = new ubyte[data.length];
+  zlib.readAll(result);
+  enforce(data == result);
+  zlib.verifyChecksum();
+}
+
+// Make sure there is no data is written if write() is never called.
+unittest {
+  auto buf = new TMemoryBuffer;
+  {
+    scope zlib = new TZlibTransport(buf);
+  }
+  enforce(buf.getContents().length == 0);
+}
+
+// Make sure calling write()/flush()/finish() again after finish() throws.
+unittest {
+  auto buf = new TMemoryBuffer;
+  auto zlib = new TZlibTransport(buf);
+
+  zlib.write([1, 2, 3, 4, 5]);
+  zlib.finish();
+
+  auto ex = collectException!TTransportException(zlib.write([6]));
+  enforce(ex && ex.type == TTransportException.Type.BAD_ARGS);
+
+  ex = collectException!TTransportException(zlib.flush());
+  enforce(ex && ex.type == TTransportException.Type.BAD_ARGS);
+
+  ex = collectException!TTransportException(zlib.finish());
+  enforce(ex && ex.type == TTransportException.Type.BAD_ARGS);
+}
+
+// Make sure verifying the checksum works even if it requires starting a new
+// reading buffer after reading the payload has already been completed.
+unittest {
+  auto buf = new TMemoryBuffer;
+  auto zlib = new TZlibTransport(buf);
+
+  immutable ubyte[] data = [1, 2, 3, 4, 5];
+  zlib.write(data);
+  zlib.finish();
+
+  zlib = new TZlibTransport(buf, TZlibTransport.DEFAULT_URBUF_SIZE,
+    buf.getContents().length - 1); // The last byte belongs to the checksum.
+
+  auto result = new ubyte[data.length];
+  zlib.readAll(result);
+  enforce(data == result);
+
+  zlib.verifyChecksum();
+}
+
+// Make sure verifyChecksum() throws if we messed with the checksum.
+unittest {
+  import std.stdio;
+  import thrift.transport.range;
+
+  auto buf = new TMemoryBuffer;
+  auto zlib = new TZlibTransport(buf);
+
+  immutable ubyte[] data = [1, 2, 3, 4, 5];
+  zlib.write(data);
+  zlib.finish();
+
+  void testCorrupted(const(ubyte)[] corruptedData) {
+    auto reader = new TZlibTransport(tInputRangeTransport(corruptedData));
+    auto result = new ubyte[data.length];
+    try {
+      reader.readAll(result);
+
+      // If it does read without complaining, the result should be correct.
+      enforce(result == data);
+    } catch (TZlibException e) {}
+
+    auto ex = collectException!TTransportException(reader.verifyChecksum());
+    enforce(ex && ex.type == TTransportException.Type.CORRUPTED_DATA);
+  }
+
+  testCorrupted(buf.getContents()[0 .. $ - 1]);
+
+  auto modified = buf.getContents().dup;
+  ++modified[$ - 1];
+  testCorrupted(modified);
+}
diff --git a/lib/d/src/thrift/util/awaitable.d b/lib/d/src/thrift/util/awaitable.d
new file mode 100644
index 0000000..38436ee
--- /dev/null
+++ b/lib/d/src/thrift/util/awaitable.d
@@ -0,0 +1,212 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+module thrift.util.awaitable;
+
+import core.sync.condition;
+import core.sync.mutex;
+import core.time : Duration;
+import std.exception : enforce;
+import std.socket/+ : Socket, socketPair+/; // DMD @@BUG314@@
+import thrift.base;
+
+// To avoid DMD @@BUG6395@@.
+import thrift.internal.algorithm;
+
+/**
+ * An event that can occur at some point in the future and which can be
+ * awaited, either by blocking until it occurs, or by registering a callback
+ * delegate.
+ */
+interface TAwaitable {
+  /**
+   * Waits until the event occurs.
+   *
+   * Calling wait() for an event that has already occurred is a no-op.
+   */
+  void wait();
+
+  /**
+   * Waits until the event occurs or the specified timeout expires.
+   *
+   * Calling wait() for an event that has already occurred is a no-op.
+   *
+   * Returns: Whether the event was triggered before the timeout expired.
+   */
+  bool wait(Duration timeout);
+
+  /**
+   * Registers a callback that is called if the event occurs.
+   *
+   * The delegate will likely be invoked from a different thread, and is
+   * expected not to perform expensive work as it will usually be invoked
+   * synchronously by the notifying thread. The order in which registered
+   * callbacks are invoked is not specified.
+   *
+   * The callback must never throw, but nothrow semantics are difficult to
+   * enforce, so currently exceptions are just swallowed by
+   * TAwaitable implementations.
+   *
+   * If the event has already occurred, the delegate is immediately executed
+   * in the current thread.
+   */
+  void addCallback(void delegate() dg);
+
+  /**
+   * Removes a previously added callback.
+   *
+   * Returns: Whether the callback could be found in the list, i.e. whether it
+   *   was previously added.
+   */
+  bool removeCallback(void delegate() dg);
+}
+
+/**
+ * A simple TAwaitable event triggered by just calling a trigger() method.
+ */
+class TOneshotEvent : TAwaitable {
+  this() {
+    mutex_ = new Mutex;
+    condition_ = new Condition(mutex_);
+  }
+
+  override void wait() {
+    synchronized (mutex_) {
+      while (!triggered_) condition_.wait();
+    }
+  }
+
+  override bool wait(Duration timeout) {
+    synchronized (mutex_) {
+      if (triggered_) return true;
+      condition_.wait(timeout);
+      return triggered_;
+    }
+  }
+
+  override void addCallback(void delegate() dg) {
+    mutex_.lock();
+    scope (failure) mutex_.unlock();
+
+    callbacks_ ~= dg;
+
+    if (triggered_) {
+      mutex_.unlock();
+      dg();
+      return;
+    }
+
+    mutex_.unlock();
+  }
+
+  override bool removeCallback(void delegate() dg) {
+    synchronized (mutex_) {
+      auto oldLength = callbacks_.length;
+      callbacks_ = removeEqual(callbacks_, dg);
+      return callbacks_.length < oldLength;
+    }
+  }
+
+  /**
+   * Triggers the event.
+   *
+   * Any registered event callbacks are executed synchronously before the
+   * function returns.
+   */
+  void trigger() {
+    synchronized (mutex_) {
+      if (!triggered_) {
+        triggered_ = true;
+        condition_.notifyAll();
+        foreach (c; callbacks_) c();
+      }
+    }
+  }
+
+private:
+  bool triggered_;
+  Mutex mutex_;
+  Condition condition_;
+  void delegate()[] callbacks_;
+}
+
+/**
+ * Translates TAwaitable events into dummy messages on a socket that can be
+ * used e.g. to wake up from a select() call.
+ */
+final class TSocketNotifier {
+  this() {
+    auto socks = socketPair();
+    foreach (s; socks) s.blocking = false;
+    sendSocket_ = socks[0];
+    recvSocket_ = socks[1];
+  }
+
+  /**
+   * The socket the messages will be sent to.
+   */
+  Socket socket() @property {
+    return recvSocket_;
+  }
+
+  /**
+   * Atatches the socket notifier to the specified awaitable, causing it to
+   * write a byte to the notification socket when the awaitable callbacks are
+   * invoked.
+   *
+   * If the event has already been triggered, the dummy byte is written
+   * immediately to the socket.
+   *
+   * A socket notifier can only be attached to a single awaitable at a time.
+   *
+   * Throws: TException if the socket notifier is already attached.
+   */
+  void attach(TAwaitable awaitable) {
+    enforce(!awaitable_, new TException("Already attached."));
+    awaitable.addCallback(&notify);
+    awaitable_ = awaitable;
+  }
+
+  /**
+   * Detaches the socket notifier from the awaitable it is currently attached
+   * to.
+   *
+   * Throws: TException if the socket notifier is not currently attached.
+   */
+  void detach() {
+    enforce(awaitable_, new TException("Not attached."));
+
+    // Soak up any not currently read notification bytes.
+    ubyte[1] dummy = void;
+    while (recvSocket_.receive(dummy) != Socket.ERROR) {}
+
+    auto couldRemove = awaitable_.removeCallback(&notify);
+    assert(couldRemove);
+    awaitable_ = null;
+  }
+
+private:
+  void notify() {
+    ubyte[1] zero;
+    sendSocket_.send(zero);
+  }
+
+  TAwaitable awaitable_;
+  Socket sendSocket_;
+  Socket recvSocket_;
+}
diff --git a/lib/d/src/thrift/util/cancellation.d b/lib/d/src/thrift/util/cancellation.d
new file mode 100644
index 0000000..6255236
--- /dev/null
+++ b/lib/d/src/thrift/util/cancellation.d
@@ -0,0 +1,105 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+module thrift.util.cancellation;
+
+import core.atomic;
+import thrift.base;
+import thrift.util.awaitable;
+
+/**
+ * A cancellation request for asynchronous or blocking synchronous operations.
+ *
+ * It is passed to the entity creating an operation, which will usually monitor
+ * it either by polling or by adding event handlers, and cancel the operation
+ * if it is triggered.
+ *
+ * For synchronous operations, this usually means either throwing a
+ * TCancelledException or immediately returning, depending on whether
+ * cancellation is an expected part of the task outcome or not. For
+ * asynchronous operations, cancellation typically entails stopping background
+ * work and cancelling a result future, if not already completed.
+ *
+ * An operation accepting a TCancellation does not need to guarantee that it
+ * will actually be able to react to the cancellation request.
+ */
+interface TCancellation {
+  /**
+   * Whether the cancellation request has been triggered.
+   */
+  bool triggered() const @property;
+
+  /**
+   * Throws a TCancelledException if the cancellation request has already been
+   * triggered.
+   */
+  void throwIfTriggered() const;
+
+  /**
+   * A TAwaitable that can be used to wait for cancellation triggering.
+   */
+  TAwaitable triggering() @property;
+}
+
+/**
+ * The origin of a cancellation request, which provides a way to actually
+ * trigger it.
+ *
+ * This design allows operations to pass the TCancellation on to sub-tasks,
+ * while making sure that the cancellation can only be triggered by the
+ * »outermost« instance waiting for the result.
+ */
+final class TCancellationOrigin : TCancellation {
+  this() {
+    event_ = new TOneshotEvent;
+  }
+
+  /**
+   * Triggers the cancellation request.
+   */
+  void trigger() {
+    atomicStore(triggered_, true);
+    event_.trigger();
+  }
+
+  /+override+/ bool triggered() const @property {
+    return atomicLoad(triggered_);
+  }
+
+  /+override+/ void throwIfTriggered() const {
+    if (triggered) throw new TCancelledException;
+  }
+
+  /+override+/ TAwaitable triggering() @property {
+    return event_;
+  }
+
+private:
+  shared bool triggered_;
+  TOneshotEvent event_;
+}
+
+///
+class TCancelledException : TException {
+  ///
+  this(string msg = null, string file = __FILE__, size_t line = __LINE__,
+    Throwable next = null
+  ) {
+    super(msg ? msg : "The operation has been cancelled.", file, line, next);
+  }
+}
diff --git a/lib/d/src/thrift/util/future.d b/lib/d/src/thrift/util/future.d
new file mode 100644
index 0000000..7c127c4
--- /dev/null
+++ b/lib/d/src/thrift/util/future.d
@@ -0,0 +1,549 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+module thrift.util.future;
+
+import core.atomic;
+import core.sync.condition;
+import core.sync.mutex;
+import core.time : Duration;
+import std.array : empty, front, popFront;
+import std.conv : to;
+import std.exception : enforce;
+import std.traits : BaseTypeTuple, isSomeFunction, ParameterTypeTuple, ReturnType;
+import thrift.base;
+import thrift.util.awaitable;
+import thrift.util.cancellation;
+
+/**
+ * Represents an operation which is executed asynchronously and the result of
+ * which will become available at some point in the future.
+ *
+ * Once a operation is completed, the result of the operation can be fetched
+ * via the get() family of methods. There are three possible cases: Either the
+ * operation succeeded, then its return value is returned, or it failed by
+ * throwing, in which case the exception is rethrown, or it was cancelled
+ * before, then a TCancelledException is thrown. There might be TFuture
+ * implementations which never possibly enter the cancelled state.
+ *
+ * All methods are thread-safe, but keep in mind that any exception object or
+ * result (if it is a reference type, of course) is shared between all
+ * get()-family invocations.
+ */
+interface TFuture(ResultType) {
+  /**
+   * The status the operation is currently in.
+   *
+   * An operation starts out in RUNNING status, and changes state to one of the
+   * others at most once afterwards.
+   */
+  TFutureStatus status() @property;
+
+  /**
+   * A TAwaitable triggered when the operation leaves the RUNNING status.
+   */
+  TAwaitable completion() @property;
+
+  /**
+   * Convenience shorthand for waiting until the result is available and then
+   * get()ing it.
+   *
+   * If the operation has already completed, the result is immediately
+   * returned.
+   *
+   * The result of this method is »alias this«'d to the interface, so that
+   * TFuture can be used as a drop-in replacement for a simple value in
+   * synchronous code.
+   */
+  final ResultType waitGet() {
+    completion.wait();
+    return get();
+  }
+  final @property auto waitGetProperty() { return waitGet(); }
+  alias waitGetProperty this;
+
+  /**
+   * Convenience shorthand for waiting until the result is available and then
+   * get()ing it.
+   *
+   * If the operation completes in time, returns its result (resp. throws an
+   * exception for the failed/cancelled cases). If not, throws a
+   * TFutureException.
+   */
+  final ResultType waitGet(Duration timeout) {
+    enforce(completion.wait(timeout), new TFutureException(
+      "Operation did not complete in time."));
+    return get();
+  }
+
+  /**
+   * Returns the result of the operation.
+   *
+   * Throws: TFutureException if the operation has been cancelled,
+   *   TCancelledException if it is not yet done; the set exception if it
+   *   failed.
+   */
+  ResultType get();
+
+  /**
+   * Returns the captured exception if the operation failed, or null otherwise.
+   *
+   * Throws: TFutureException if not yet done, TCancelledException if the
+   *   operation has been cancelled.
+   */
+  Exception getException();
+}
+
+/**
+ * The states the operation offering a future interface can be in.
+ */
+enum TFutureStatus : byte {
+  RUNNING, /// The operation is still running.
+  SUCCEEDED, /// The operation completed without throwing an exception.
+  FAILED, /// The operation completed by throwing an exception.
+  CANCELLED /// The operation was cancelled.
+}
+
+/**
+ * A TFuture covering the simple but common case where the result is simply
+ * set by a call to succeed()/fail().
+ *
+ * All methods are thread-safe, but usually, succeed()/fail() are only called
+ * from a single thread (different from the thread(s) waiting for the result
+ * using the TFuture interface, though).
+ */
+class TPromise(ResultType) : TFuture!ResultType {
+  this() {
+    statusMutex_ = new Mutex;
+    completionEvent_ = new TOneshotEvent;
+  }
+
+  override S status() const @property {
+    return atomicLoad(status_);
+  }
+
+  override TAwaitable completion() @property {
+    return completionEvent_;
+  }
+
+  override ResultType get() {
+    auto s = atomicLoad(status_);
+    enforce(s != S.RUNNING,
+      new TFutureException("Operation not yet completed."));
+
+    if (s == S.CANCELLED) throw new TCancelledException;
+    if (s == S.FAILED) throw exception_;
+
+    static if (!is(ResultType == void)) {
+      return result_;
+    }
+  }
+
+  override Exception getException() {
+    auto s = atomicLoad(status_);
+    enforce(s != S.RUNNING,
+      new TFutureException("Operation not yet completed."));
+
+    if (s == S.CANCELLED) throw new TCancelledException;
+    if (s == S.SUCCEEDED) return null;
+
+    return exception_;
+  }
+
+  static if (!is(ResultType == void)) {
+    /**
+     * Sets the result of the operation, marks it as done, and notifies any
+     * waiters.
+     *
+     * If the operation has been cancelled before, nothing happens.
+     *
+     * Throws: TFutureException if the operation is already completed.
+     */
+    void succeed(ResultType result) {
+      synchronized (statusMutex_) {
+        auto s = atomicLoad(status_);
+        if (s == S.CANCELLED) return;
+
+        enforce(s == S.RUNNING,
+          new TFutureException("Operation already completed."));
+        result_ = result;
+
+        atomicStore(status_, S.SUCCEEDED);
+      }
+
+      completionEvent_.trigger();
+    }
+  } else {
+    void succeed() {
+      synchronized (statusMutex_) {
+        auto s = atomicLoad(status_);
+        if (s == S.CANCELLED) return;
+
+        enforce(s == S.RUNNING,
+          new TFutureException("Operation already completed."));
+
+        atomicStore(status_, S.SUCCEEDED);
+      }
+
+      completionEvent_.trigger();
+    }
+  }
+
+  /**
+   * Marks the operation as failed with the specified exception and notifies
+   * any waiters.
+   *
+   * If the operation was already cancelled, nothing happens.
+   *
+   * Throws: TFutureException if the operation is already completed.
+   */
+  void fail(Exception exception) {
+    synchronized (statusMutex_) {
+      auto status = atomicLoad(status_);
+      if (status == S.CANCELLED) return;
+
+      enforce(status == S.RUNNING,
+        new TFutureException("Operation already completed."));
+      exception_ = exception;
+
+      atomicStore(status_, S.FAILED);
+    }
+
+    completionEvent_.trigger();
+  }
+
+
+  /**
+   * Marks this operation as completed and takes over the outcome of another
+   * TFuture of the same type.
+   *
+   * If this operation was already cancelled, nothing happens. If the other
+   * operation was cancelled, this operation is marked as failed with a
+   * TCancelledException.
+   *
+   * Throws: TFutureException if the passed in future was not completed or
+   *   this operation is already completed.
+   */
+  void complete(TFuture!ResultType future) {
+    synchronized (statusMutex_) {
+      auto status = atomicLoad(status_);
+      if (status == S.CANCELLED) return;
+      enforce(status == S.RUNNING,
+        new TFutureException("Operation already completed."));
+
+      enforce(future.status != S.RUNNING, new TFutureException(
+        "The passed TFuture is not yet completed."));
+
+      status = future.status;
+      if (status == S.CANCELLED) {
+        status = S.FAILED;
+        exception_ = new TCancelledException;
+      } else if (status == S.FAILED) {
+        exception_ = future.getException();
+      } else static if (!is(ResultType == void)) {
+        result_ = future.get();
+      }
+
+      atomicStore(status_, status);
+    }
+
+    completionEvent_.trigger();
+  }
+
+  /**
+   * Marks this operation as cancelled and notifies any waiters.
+   *
+   * If the operation is already completed, nothing happens.
+   */
+  void cancel() {
+    synchronized (statusMutex_) {
+      auto status = atomicLoad(status_);
+      if (status == S.RUNNING) atomicStore(status_, S.CANCELLED);
+    }
+
+    completionEvent_.trigger();
+  }
+
+private:
+  // Convenience alias because TFutureStatus is ubiquitous in this class.
+  alias TFutureStatus S;
+
+  // The status the promise is currently in.
+  shared S status_;
+
+  union {
+    static if (!is(ResultType == void)) {
+      // Set if status_ is SUCCEEDED.
+      ResultType result_;
+    }
+    // Set if status_ is FAILED.
+    Exception exception_;
+  }
+
+  // Protects status_.
+  // As for result_ and exception_: They are only set once, while status_ is
+  // still RUNNING, so given that the operation has already completed, reading
+  // them is safe without holding some kind of lock.
+  Mutex statusMutex_;
+
+  // Triggered when the event completes.
+  TOneshotEvent completionEvent_;
+}
+
+///
+class TFutureException : TException {
+  ///
+  this(string msg = "", string file = __FILE__, size_t line = __LINE__,
+    Throwable next = null)
+  {
+    super(msg, file, line, next);
+  }
+}
+
+/**
+ * Creates an interface that is similiar to a given one, but accepts an
+ * additional, optional TCancellation parameter each method, and returns
+ * TFutures instead of plain return values.
+ *
+ * For example, given the following declarations:
+ * ---
+ * interface Foo {
+ *   void bar();
+ *   string baz(int a);
+ * }
+ * alias TFutureInterface!Foo FutureFoo;
+ * ---
+ *
+ * FutureFoo would be equivalent to:
+ * ---
+ * interface FutureFoo {
+ *   TFuture!void bar(TCancellation cancellation = null);
+ *   TFuture!string baz(int a, TCancellation cancellation = null);
+ * }
+ * ---
+ */
+template TFutureInterface(Interface) if (is(Interface _ == interface)) {
+  mixin({
+    string code = "interface TFutureInterface \n";
+
+    static if (is(Interface Bases == super) && Bases.length > 0) {
+      code ~= ": ";
+      foreach (i; 0 .. Bases.length) {
+        if (i > 0) code ~= ", ";
+        code ~= "TFutureInterface!(BaseTypeTuple!Interface[" ~ to!string(i) ~ "]) ";
+      }
+    }
+
+    code ~= "{\n";
+
+    foreach (methodName; __traits(derivedMembers, Interface)) {
+      enum qn = "Interface." ~ methodName;
+      static if (isSomeFunction!(mixin(qn))) {
+        code ~= "TFuture!(ReturnType!(" ~ qn ~ ")) " ~ methodName ~
+          "(ParameterTypeTuple!(" ~ qn ~ "), TCancellation cancellation = null);\n";
+      }
+    }
+
+    code ~= "}\n";
+    return code;
+  }());
+}
+
+/**
+ * An input range that aggregates results from multiple asynchronous operations,
+ * returning them in the order they arrive.
+ *
+ * Additionally, a timeout can be set after which results from not yet finished
+ * futures will no longer be waited for, e.g. to ensure the time it takes to
+ * iterate over a set of results is limited.
+ */
+final class TFutureAggregatorRange(T) {
+  /**
+   * Constructs a new instance.
+   *
+   * Params:
+   *   futures = The set of futures to collect results from.
+   *   timeout = If positive, not yet finished futures will be cancelled and
+   *     their results will not be taken into account.
+   */
+  this(TFuture!T[] futures, TCancellationOrigin childCancellation,
+    Duration timeout = dur!"hnsecs"(0)
+  ) {
+    if (timeout > dur!"hnsecs"(0)) {
+      timeoutSysTick_ = TickDuration.currSystemTick +
+        TickDuration.from!"hnsecs"(timeout.total!"hnsecs");
+    } else {
+      timeoutSysTick_ = TickDuration(0);
+    }
+
+    queueMutex_ = new Mutex;
+    queueNonEmptyCondition_ = new Condition(queueMutex_);
+    futures_ = futures;
+    childCancellation_ = childCancellation;
+
+    foreach (future; futures_) {
+      future.completion.addCallback({
+        auto f = future;
+        return {
+          if (f.status == TFutureStatus.CANCELLED) return;
+          assert(f.status != TFutureStatus.RUNNING);
+
+          synchronized (queueMutex_) {
+            completedQueue_ ~= f;
+
+            if (completedQueue_.length == 1) {
+              queueNonEmptyCondition_.notifyAll();
+            }
+          }
+        };
+      }());
+    }
+  }
+
+  /**
+   * Whether the range is empty.
+   *
+   * This is the case if the results from the completed futures not having
+   * failed have already been popped and either all future have been finished
+   * or the timeout has expired.
+   *
+   * Potentially blocks until a new result is available or the timeout has
+   * expired.
+   */
+  bool empty() @property {
+    if (finished_) return true;
+    if (bufferFilled_) return false;
+
+    while (true) {
+      TFuture!T future;
+      synchronized (queueMutex_) {
+        // The while loop is just being cautious about spurious wakeups, in
+        // case they should be possible.
+        while (completedQueue_.empty) {
+          auto remaining = to!Duration(timeoutSysTick_ -
+            TickDuration.currSystemTick);
+
+          if (remaining <= dur!"hnsecs"(0)) {
+            // No time left, but still no element received – we are empty now.
+            finished_ = true;
+            childCancellation_.trigger();
+            return true;
+          }
+
+          queueNonEmptyCondition_.wait(remaining);
+        }
+
+        future = completedQueue_.front;
+        completedQueue_.popFront();
+      }
+
+      ++completedCount_;
+      if (completedCount_ == futures_.length) {
+        // This was the last future in the list, there is no possiblity
+        // another result could ever become available.
+        finished_ = true;
+      }
+
+      if (future.status == TFutureStatus.FAILED) {
+        // This one failed, loop again and try getting another item from
+        // the queue.
+        exceptions_ ~= future.getException();
+      } else {
+        resultBuffer_ = future.get();
+        bufferFilled_ = true;
+        return false;
+      }
+    }
+  }
+
+  /**
+   * Returns the first element from the range.
+   *
+   * Potentially blocks until a new result is available or the timeout has
+   * expired.
+   *
+   * Throws: TException if the range is empty.
+   */
+  T front() {
+    enforce(!empty, new TException(
+      "Cannot get front of an empty future aggregator range."));
+    return resultBuffer_;
+  }
+
+  /**
+   * Removes the first element from the range.
+   *
+   * Potentially blocks until a new result is available or the timeout has
+   * expired.
+   *
+   * Throws: TException if the range is empty.
+   */
+  void popFront() {
+    enforce(!empty, new TException(
+      "Cannot pop front of an empty future aggregator range."));
+    bufferFilled_ = false;
+  }
+
+  /**
+   * The number of futures the result of which has been returned or which have
+   * failed so far.
+   */
+  size_t completedCount() @property const {
+    return completedCount_;
+  }
+
+  /**
+   * The exceptions collected from failed TFutures so far.
+   */
+  Exception[] exceptions() @property {
+    return exceptions_;
+  }
+
+private:
+  TFuture!T[] futures_;
+  TCancellationOrigin childCancellation_;
+
+  // The system tick this operation will time out, or zero if no timeout has
+  // been set.
+  TickDuration timeoutSysTick_;
+
+  bool finished_;
+
+  bool bufferFilled_;
+  T resultBuffer_;
+
+  Exception[] exceptions_;
+  size_t completedCount_;
+
+  // The queue of completed futures. This (and the associated condition) are
+  // the only parts of this class that are accessed by multiple threads.
+  TFuture!T[] completedQueue_;
+  Mutex queueMutex_;
+  Condition queueNonEmptyCondition_;
+}
+
+/**
+ * TFutureAggregatorRange construction helper to avoid having to explicitly
+ * specify the value type, i.e. to allow the constructor being called using IFTI
+ * (see $(DMDBUG 6082, D Bugzilla enhancement requet 6082)).
+ */
+TFutureAggregatorRange!T tFutureAggregatorRange(T)(TFuture!T[] futures,
+  TCancellationOrigin childCancellation, Duration timeout = dur!"hnsecs"(0)
+) {
+  return new TFutureAggregatorRange!T(futures, childCancellation, timeout);
+}
diff --git a/lib/d/src/thrift/util/hashset.d b/lib/d/src/thrift/util/hashset.d
new file mode 100644
index 0000000..127374b
--- /dev/null
+++ b/lib/d/src/thrift/util/hashset.d
@@ -0,0 +1,145 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+module thrift.util.hashset;
+
+import std.algorithm : joiner, map;
+import std.conv : to;
+import std.traits : isImplicitlyConvertible, ParameterTypeTuple;
+import std.range : ElementType, isInputRange;
+
+/**
+ * A quickly hacked together hash set implementation backed by built-in
+ * associative arrays to have something to compile Thrift's set<> to until
+ * std.container gains something suitable.
+ */
+// Note: The funky pointer casts (i.e. *(cast(immutable(E)*)&e) instead of
+// just cast(immutable(E))e) are a workaround for LDC 2 compatibilty.
+final class HashSet(E) {
+  ///
+  this() {}
+
+  ///
+  this(E[] elems...) {
+    insert(elems);
+  }
+
+  ///
+  void insert(Stuff)(Stuff stuff) if (isImplicitlyConvertible!(Stuff, E)) {
+    aa_[*(cast(immutable(E)*)&stuff)] = [];
+  }
+
+  ///
+  void insert(Stuff)(Stuff stuff) if (
+    isInputRange!Stuff && isImplicitlyConvertible!(ElementType!Stuff, E)
+  ) {
+    foreach (e; stuff) {
+      aa_[*(cast(immutable(E)*)&e)] = [];
+    }
+  }
+
+  ///
+  void opOpAssign(string op : "~", Stuff)(Stuff stuff) {
+    insert(stuff);
+  }
+
+  ///
+  void remove(E e) {
+    aa_.remove(*(cast(immutable(E)*)&e));
+  }
+  alias remove removeKey;
+
+  ///
+  void removeAll() {
+    aa_ = null;
+  }
+
+  ///
+  size_t length() @property const {
+    return aa_.length;
+  }
+
+  ///
+  size_t empty() @property const {
+    return !aa_.length;
+  }
+
+  ///
+  bool opBinaryRight(string op : "in")(E e) const {
+    return (e in aa_) !is null;
+  }
+
+  ///
+  auto opSlice() const {
+    // TODO: Implement using AA key range once availabe in release DMD/druntime
+    // to avoid allocation.
+    return cast(E[])(aa_.keys);
+  }
+
+  ///
+  override string toString() const {
+    // Only provide toString() if to!string() is available for E (exceptions are
+    // e.g. delegates).
+    static if (is(typeof(to!string(E.init)) : string)) {
+      return "{" ~ to!string(joiner(map!`to!string(a)`(aa_.keys), ", ")) ~ "}";
+    } else {
+      // Cast to work around Object not being const-correct.
+      return (cast()super).toString();
+    }
+  }
+
+  ///
+  override bool opEquals(Object other) const {
+    auto rhs = cast(const(HashSet))other;
+    if (rhs) {
+      return aa_ == rhs.aa_;
+    }
+
+    // Cast to work around Object not being const-correct.
+    return (cast()super).opEquals(other);
+  }
+
+private:
+  alias void[0] Void;
+  Void[immutable(E)] aa_;
+}
+
+/// Ditto
+auto hashSet(E)(E[] elems...) {
+  return new HashSet!E(elems);
+}
+
+unittest {
+  import std.exception;
+
+  auto a = hashSet(1, 2, 2, 3);
+  enforce(a.length == 3);
+  enforce(2 in a);
+  enforce(5 !in a);
+  enforce(a.toString().length == 9);
+  a.remove(2);
+  enforce(a.length == 2);
+  enforce(2 !in a);
+  a.removeAll();
+  enforce(a.empty);
+  enforce(a.toString() == "{}");
+
+  void delegate() dg;
+  auto b = hashSet(dg);
+  enforce(b.toString() == "thrift.util.hashset.HashSet!(void delegate()).HashSet");
+}
diff --git a/lib/d/test/Makefile.am b/lib/d/test/Makefile.am
new file mode 100644
index 0000000..ff4bd46
--- /dev/null
+++ b/lib/d/test/Makefile.am
@@ -0,0 +1,123 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+
+
+# Thrift compiler rules
+
+THRIFT = $(top_builddir)/compiler/cpp/thrift
+
+debug_proto_gen = $(addprefix gen-d/, DebugProtoTest_types.d)
+
+$(debug_proto_gen): $(top_srcdir)/test/DebugProtoTest.thrift
+	$(THRIFT) --gen d -nowarn $<
+
+stress_test_gen = $(addprefix gen-d/thrift/test/stress/, Service.d \
+	StressTest_types.d)
+
+$(stress_test_gen): $(top_srcdir)/test/StressTest.thrift
+	$(THRIFT) --gen d $<
+
+thrift_test_gen = $(addprefix gen-d/thrift/test/, SecondService.d \
+	ThriftTest.d ThriftTest_constants.d ThriftTest_types.d)
+
+$(thrift_test_gen): $(top_srcdir)/test/ThriftTest.thrift
+	$(THRIFT) --gen d $<
+
+
+# The actual test targets.
+# There just must be some way to reassign a variable without warnings in
+# Automake...
+targets__ = async_test client_pool_test serialization_benchmark \
+	stress_test_server thrift_test_client thrift_test_server transport_test
+ran_tests__ = client_pool_test \
+	transport_test \
+	async_test_runner.sh \
+	thrift_test_runner.sh
+
+libevent_dependent_targets = async_test_client client_pool_test \
+	stress_test_server thrift_test_server
+libevent_dependent_ran_tests = async_test_runner.sh thrift_test_runner.sh
+
+openssl_dependent_targets = async_test thrift_test_client thrift_test_server
+openssl_dependent_ran_tests = async_test_runner.sh thrift_test_runner.sh
+
+d_test_flags =
+
+if WITH_D_EVENT_TESTS
+d_test_flags += $(DMD_LIBEVENT_FLAGS) ../$(D_EVENT_LIB_NAME)
+targets_ = $(targets__)
+ran_tests_ = $(ran_tests__)
+else
+targets_ = $(filter-out $(libevent_dependent_targets), $(targets__))
+ran_tests_ = $(filter-out $(libevent_dependent_ran_tests), $(ran_tests__))
+endif
+
+if WITH_D_SSL_TESTS
+d_test_flags += $(DMD_OPENSSL_FLAGS) ../$(D_SSL_LIB_NAME)
+targets = trusted-ca-certificate.pem server-certificate.pem $(targets_)
+ran_tests = $(ran_tests_)
+else
+targets = $(filter-out $(openssl_dependent_targets), $(targets_))
+ran_tests = $(filter-out $(openssl_dependent_ran_tests), $(ran_tests_))
+endif
+
+d_test_flags += -w -wi -O -release -inline -I$(top_srcdir)/lib/d/src -Igen-d \
+	$(top_builddir)/lib/d/$(D_LIB_NAME)
+
+
+async_test client_pool_test transport_test: %: %.d
+	$(DMD) $(d_test_flags) -of$@ $^
+
+serialization_benchmark: %: %.d $(debug_proto_gen)
+	$(DMD) $(d_test_flags) -of$@ $^
+
+stress_test_server: %: %.d test_utils.d $(stress_test_gen)
+	$(DMD) $(d_test_flags) -of$@ $^
+
+thrift_test_client: %: %.d thrift_test_common.d $(thrift_test_gen)
+	$(DMD) $(d_test_flags) -of$@ $^
+
+thrift_test_server: %: %.d thrift_test_common.d test_utils.d $(thrift_test_gen)
+	$(DMD) $(d_test_flags) -of$@ $^
+
+
+# Certificate generation targets (for the SSL tests).
+# Currently, we just assume that the "openssl" tool is on the path, could be
+# replaced by a more elaborate mechanism.
+
+server-certificate.pem: openssl.test.cnf
+	openssl req -new -x509 -nodes -config openssl.test.cnf \
+		-out server-certificate.pem
+
+trusted-ca-certificate.pem: server-certificate.pem
+	cat server-certificate.pem > $@
+
+check-local: $(targets)
+
+clean-local:
+	$(RM) -rf gen-d $(targets) $(addsuffix .o, $(targets))
+
+
+# Tests ran as part of make check.
+
+async_test_runner.sh: async_test trusted-ca-certificate.pem server-certificate.pem
+thrift_test_runner.sh: thrift_test_client thrift_test_server \
+	trusted-ca-certificate.pem server-certificate.pem
+
+TESTS = $(ran_tests)
diff --git a/lib/d/test/async_test.d b/lib/d/test/async_test.d
new file mode 100644
index 0000000..16db51b
--- /dev/null
+++ b/lib/d/test/async_test.d
@@ -0,0 +1,396 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless enforced by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+module async_test;
+
+import core.atomic;
+import core.sync.condition : Condition;
+import core.sync.mutex : Mutex;
+import core.thread : dur, Thread, ThreadGroup;
+import std.conv : text;
+import std.datetime;
+import std.getopt;
+import std.exception : collectException, enforce;
+import std.parallelism : TaskPool;
+import std.stdio;
+import std.string;
+import std.variant : Variant;
+import thrift.base;
+import thrift.async.base;
+import thrift.async.libevent;
+import thrift.async.socket;
+import thrift.async.ssl;
+import thrift.codegen.async_client;
+import thrift.codegen.async_client_pool;
+import thrift.codegen.base;
+import thrift.codegen.processor;
+import thrift.protocol.base;
+import thrift.protocol.binary;
+import thrift.server.base;
+import thrift.server.simple;
+import thrift.server.transport.socket;
+import thrift.server.transport.ssl;
+import thrift.transport.base;
+import thrift.transport.buffered;
+import thrift.transport.ssl;
+import thrift.util.cancellation;
+
+version (Posix) {
+  import core.stdc.signal;
+  import core.sys.posix.signal;
+
+  // Disable SIGPIPE because SSL server will write to broken socket after
+  // client disconnected (see TSSLSocket docs).
+  shared static this() {
+    signal(SIGPIPE, SIG_IGN);
+  }
+}
+
+interface AsyncTest {
+  string echo(string value);
+  string delayedEcho(string value, long milliseconds);
+
+  void fail(string reason);
+  void delayedFail(string reason, long milliseconds);
+
+  enum methodMeta = [
+    TMethodMeta("fail", [], [TExceptionMeta("ate", 1, "AsyncTestException")]),
+    TMethodMeta("delayedFail", [], [TExceptionMeta("ate", 1, "AsyncTestException")])
+  ];
+  alias .AsyncTestException AsyncTestException;
+}
+
+class AsyncTestException : TException {
+  string reason;
+  mixin TStructHelpers!();
+}
+
+void main(string[] args) {
+  ushort port = 9090;
+  ushort managerCount = 2;
+  ushort serversPerManager = 5;
+  ushort threadsPerServer = 10;
+  uint iterations = 10;
+  bool ssl;
+  bool trace;
+
+  getopt(args,
+    "iterations", &iterations,
+    "managers", &managerCount,
+    "port", &port,
+    "servers-per-manager", &serversPerManager,
+    "ssl", &ssl,
+    "threads-per-server", &threadsPerServer,
+    "trace", &trace,
+  );
+
+  TTransportFactory clientTransportFactory;
+  TSSLContext serverSSLContext;
+  if (ssl) {
+    auto clientSSLContext = new TSSLContext();
+    with (clientSSLContext) {
+      ciphers = "ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH";
+      authenticate = true;
+      loadTrustedCertificates("./trusted-ca-certificate.pem");
+    }
+    clientTransportFactory = new TAsyncSSLSocketFactory(clientSSLContext);
+
+    serverSSLContext = new TSSLContext();
+    with (serverSSLContext) {
+      serverSide = true;
+      loadCertificate("./server-certificate.pem");
+      loadPrivateKey("./server-private-key.pem");
+      ciphers = "ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH";
+    }
+  } else {
+    clientTransportFactory = new TBufferedTransportFactory;
+  }
+
+
+  auto serverCancel = new TCancellationOrigin;
+  scope(exit) {
+    writeln("Triggering server shutdown...");
+    serverCancel.trigger();
+    writeln("done.");
+  }
+
+  auto managers = new TLibeventAsyncManager[managerCount];
+  scope (exit) foreach (ref m; managers) clear(m);
+
+  auto clientsThreads = new ThreadGroup;
+  foreach (managerIndex, ref manager; managers) {
+    manager = new TLibeventAsyncManager;
+    foreach (serverIndex; 0 .. serversPerManager) {
+      auto currentPort = cast(ushort)
+        (port + managerIndex * serversPerManager + serverIndex);
+
+      // Start the server and wait until it is up and running.
+      auto servingMutex = new Mutex;
+      auto servingCondition = new Condition(servingMutex);
+      auto handler = new PreServeNotifyHandler(servingMutex, servingCondition);
+      synchronized (servingMutex) {
+        (new ServerThread!TSimpleServer(currentPort, serverSSLContext, trace,
+          serverCancel, handler)).start();
+        servingCondition.wait();
+      }
+
+      // We only run the timing tests for the first server on each async
+      // manager, so that we don't get spurious timing errors becaue of
+      // ordering issues.
+      auto runTimingTests = (serverIndex == 0);
+
+      auto c = new ClientsThread(manager, currentPort, clientTransportFactory,
+        threadsPerServer, iterations, runTimingTests, trace);
+      clientsThreads.add(c);
+      c.start();
+    }
+  }
+  clientsThreads.joinAll();
+}
+
+class AsyncTestHandler : AsyncTest {
+  this(bool trace) {
+    trace_ = trace;
+  }
+
+  override string echo(string value) {
+    if (trace_) writefln(`echo("%s")`, value);
+    return value;
+  }
+
+  override string delayedEcho(string value, long milliseconds) {
+    if (trace_) writef(`delayedEcho("%s", %s ms)... `, value, milliseconds);
+    Thread.sleep(dur!"msecs"(milliseconds));
+    if (trace_) writeln("returning.");
+
+    return value;
+  }
+
+  override void fail(string reason) {
+    if (trace_) writefln(`fail("%s")`, reason);
+    auto ate = new AsyncTestException;
+    ate.reason = reason;
+    throw ate;
+  }
+
+  override void delayedFail(string reason, long milliseconds) {
+    if (trace_) writef(`delayedFail("%s", %s ms)... `, reason, milliseconds);
+    Thread.sleep(dur!"msecs"(milliseconds));
+    if (trace_) writeln("returning.");
+
+    auto ate = new AsyncTestException;
+    ate.reason = reason;
+    throw ate;
+  }
+
+private:
+  bool trace_;
+  AsyncTestException ate_;
+}
+
+class PreServeNotifyHandler : TServerEventHandler {
+  this(Mutex servingMutex, Condition servingCondition) {
+    servingMutex_ = servingMutex;
+    servingCondition_ = servingCondition;
+  }
+
+  void preServe() {
+    synchronized (servingMutex_) {
+      servingCondition_.notifyAll();
+    }
+  }
+  Variant createContext(TProtocol input, TProtocol output) { return Variant.init; }
+  void deleteContext(Variant serverContext, TProtocol input, TProtocol output) {}
+  void preProcess(Variant serverContext, TTransport transport) {}
+
+private:
+  Mutex servingMutex_;
+  Condition servingCondition_;
+}
+
+class ServerThread(ServerType) : Thread {
+  this(ushort port, TSSLContext sslContext, bool trace,
+    TCancellation cancellation, TServerEventHandler eventHandler
+  ) {
+    port_ = port;
+    sslContext_ = sslContext;
+    trace_ = trace;
+    cancellation_ = cancellation;
+    eventHandler_ = eventHandler;
+
+    super(&run);
+  }
+
+  void run() {
+    TServerSocket serverSocket;
+    if (sslContext_) {
+      serverSocket = new TSSLServerSocket(port_, sslContext_);
+    } else {
+      serverSocket = new TServerSocket(port_);
+    }
+    auto transportFactory = new TBufferedTransportFactory;
+    auto protocolFactory = new TBinaryProtocolFactory!();
+    auto processor = new TServiceProcessor!AsyncTest(new AsyncTestHandler(trace_));
+
+    auto server = new ServerType(processor, serverSocket, transportFactory,
+      protocolFactory);
+    server.eventHandler = eventHandler_;
+
+    writefln("Starting server on port %s...", port_);
+    server.serve(cancellation_);
+    writefln("Server thread on port %s done.", port_);
+  }
+
+private:
+  ushort port_;
+  bool trace_;
+  TCancellation cancellation_;
+  TSSLContext sslContext_;
+  TServerEventHandler eventHandler_;
+}
+
+class ClientsThread : Thread {
+  this(TAsyncSocketManager manager, ushort port, TTransportFactory tf,
+    ushort threads, uint iterations, bool runTimingTests, bool trace
+  ) {
+    manager_ = manager;
+    port_ = port;
+    transportFactory_ = tf;
+    threads_ = threads;
+    iterations_ = iterations;
+    runTimingTests_ = runTimingTests;
+    trace_ = trace;
+    super(&run);
+  }
+
+  void run() {
+    auto transport = new TAsyncSocket(manager_, "localhost", port_);
+
+    {
+      auto client = new TAsyncClient!AsyncTest(
+        transport,
+        transportFactory_,
+        new TBinaryProtocolFactory!()
+      );
+      transport.open();
+      auto clientThreads = new ThreadGroup;
+      foreach (clientId; 0 .. threads_) {
+        clientThreads.create({
+          auto c = clientId;
+          return {
+            foreach (i; 0 .. iterations_) {
+              immutable id = text(port_, ":", c, ":", i);
+
+              {
+                if (trace_) writefln(`Calling echo("%s")... `, id);
+                auto a = client.echo(id);
+                enforce(a == id);
+                if (trace_) writefln(`echo("%s") done.`, id);
+              }
+
+              {
+                if (trace_) writefln(`Calling fail("%s")... `, id);
+                auto a = cast(AsyncTestException)collectException(client.fail(id).waitGet());
+                enforce(a && a.reason == id);
+                if (trace_) writefln(`fail("%s") done.`, id);
+              }
+            }
+          };
+        }());
+      }
+      clientThreads.joinAll();
+      transport.close();
+    }
+
+    if (runTimingTests_) {
+      auto client = new TAsyncClient!AsyncTest(
+        transport,
+        transportFactory_,
+        new TBinaryProtocolFactory!TBufferedTransport
+      );
+
+      // Temporarily redirect error logs to stdout, as SSL errors on the server
+      // side are expected when the client terminates aburptly (as is the case
+      // in the timeout test).
+      auto oldErrorLogSink = g_errorLogSink;
+      g_errorLogSink = g_infoLogSink;
+      scope (exit) g_errorLogSink = oldErrorLogSink;
+
+      foreach (i; 0 .. iterations_) {
+        transport.open();
+
+        immutable id = text(port_, ":", i);
+
+        {
+          if (trace_) writefln(`Calling delayedEcho("%s", 100 ms)...`, id);
+          auto a = client.delayedEcho(id, 100);
+          enforce(!a.completion.wait(dur!"usecs"(1)),
+            text("wait() succeded early (", a.get(), ", ", id, ")."));
+          enforce(!a.completion.wait(dur!"usecs"(1)),
+            text("wait() succeded early (", a.get(), ", ", id, ")."));
+          enforce(a.completion.wait(dur!"msecs"(200)),
+            text("wait() didn't succeed as expected (", id, ")."));
+          enforce(a.get() == id);
+          if (trace_) writefln(`... delayedEcho("%s") done.`, id);
+        }
+
+        {
+          if (trace_) writefln(`Calling delayedFail("%s", 100 ms)... `, id);
+          auto a = client.delayedFail(id, 100);
+          enforce(!a.completion.wait(dur!"usecs"(1)),
+            text("wait() succeded early (", id, ", ", collectException(a.get()), ")."));
+          enforce(!a.completion.wait(dur!"usecs"(1)),
+            text("wait() succeded early (", id, ", ", collectException(a.get()), ")."));
+          enforce(a.completion.wait(dur!"msecs"(200)),
+            text("wait() didn't succeed as expected (", id, ")."));
+          auto e = cast(AsyncTestException)collectException(a.get());
+          enforce(e && e.reason == id);
+          if (trace_) writefln(`... delayedFail("%s") done.`, id);
+        }
+
+        {
+          transport.recvTimeout = dur!"msecs"(50);
+
+          if (trace_) write(`Calling delayedEcho("socketTimeout", 100 ms)... `);
+          auto a = client.delayedEcho("socketTimeout", 100);
+          auto e = cast(TTransportException)collectException(a.waitGet());
+          enforce(e, text("Operation didn't fail as expected (", id, ")."));
+          enforce(e.type == TTransportException.Type.TIMED_OUT,
+            text("Wrong timeout exception type (", id, "): ", e));
+          if (trace_) writeln(`timed out as expected.`);
+
+          // Wait until the server thread reset before the next iteration.
+          Thread.sleep(dur!"msecs"(50));
+          transport.recvTimeout = dur!"hnsecs"(0);
+        }
+
+        transport.close();
+      }
+    }
+
+    writefln("Clients thread for port %s done.", port_);
+  }
+
+  TAsyncSocketManager manager_;
+  ushort port_;
+  TTransportFactory transportFactory_;
+  ushort threads_;
+  uint iterations_;
+  bool runTimingTests_;
+  bool trace_;
+}
diff --git a/lib/d/test/async_test_runner.sh b/lib/d/test/async_test_runner.sh
new file mode 100644
index 0000000..4b9b7c0
--- /dev/null
+++ b/lib/d/test/async_test_runner.sh
@@ -0,0 +1,6 @@
+#!/bin/bash
+# Runs the async test in both SSL and non-SSL mode.
+./async_test > /dev/null || exit 1
+echo "Non-SSL tests done."
+./async_test --ssl > /dev/null || exit 1
+echo "SSL tests done."
diff --git a/lib/d/test/client_pool_test.d b/lib/d/test/client_pool_test.d
new file mode 100644
index 0000000..85bcb29
--- /dev/null
+++ b/lib/d/test/client_pool_test.d
@@ -0,0 +1,416 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+module client_pool_test;
+
+import core.time : Duration, dur;
+import core.thread : Thread;
+import std.algorithm;
+import std.array;
+import std.conv;
+import std.exception;
+import std.getopt;
+import std.range;
+import std.stdio;
+import std.typecons;
+import thrift.base;
+import thrift.async.libevent;
+import thrift.async.socket;
+import thrift.codegen.base;
+import thrift.codegen.async_client;
+import thrift.codegen.async_client_pool;
+import thrift.codegen.client;
+import thrift.codegen.client_pool;
+import thrift.codegen.processor;
+import thrift.protocol.binary;
+import thrift.server.simple;
+import thrift.server.transport.socket;
+import thrift.transport.buffered;
+import thrift.transport.socket;
+import thrift.util.cancellation;
+import thrift.util.future;
+
+// We use this as our RPC-layer exception here to make sure socket/… problems
+// (that would usually considered to be RPC layer faults) cause the tests to
+// fail, even though we are testing the RPC exception handling.
+class TestServiceException : TException {
+  int port;
+}
+
+interface TestService {
+  int getPort();
+  alias .TestServiceException TestServiceException;
+  enum methodMeta = [TMethodMeta("getPort", [],
+    [TExceptionMeta("a", 1, "TestServiceException")])];
+}
+
+// Use some derived service, just to check that the pools handle inheritance
+// correctly.
+interface ExTestService : TestService {
+  int[] getPortInArray();
+  enum methodMeta = [TMethodMeta("getPortInArray", [],
+    [TExceptionMeta("a", 1, "TestServiceException")])];
+}
+
+class ExTestHandler : ExTestService {
+  this(ushort port, Duration delay, bool failing, bool trace) {
+    this.port = port;
+    this.delay = delay;
+    this.failing = failing;
+    this.trace = trace;
+  }
+
+  override int getPort() {
+    if (trace) {
+      stderr.writefln("getPort() called on %s (delay: %s, failing: %s)", port,
+        delay, failing);
+    }
+    sleep();
+    failIfEnabled();
+    return port;
+  }
+
+  override int[] getPortInArray() {
+    return [getPort()];
+  }
+
+  ushort port;
+  Duration delay;
+  bool failing;
+  bool trace;
+
+private:
+  void sleep() {
+    if (delay > dur!"hnsecs"(0)) Thread.sleep(delay);
+  }
+
+  void failIfEnabled() {
+    if (!failing) return;
+
+    auto e = new TestServiceException;
+    e.port = port;
+    throw e;
+  }
+}
+
+class ServerThread : Thread {
+  this(ExTestHandler handler, TCancellation cancellation) {
+    super(&run);
+    handler_ = handler;
+    cancellation_ = cancellation;
+  }
+private:
+  void run() {
+    try {
+      auto protocolFactory = new TBinaryProtocolFactory!();
+      auto processor = new TServiceProcessor!ExTestService(handler_);
+      auto serverTransport = new TServerSocket(handler_.port);
+      serverTransport.recvTimeout = dur!"seconds"(3);
+      auto transportFactory = new TBufferedTransportFactory;
+
+      auto server = new TSimpleServer(
+        processor, serverTransport, transportFactory, protocolFactory);
+      server.serve(cancellation_);
+    } catch (Exception e) {
+      writefln("Server thread on port %s failed: %s", handler_.port, e);
+    }
+  }
+
+  TCancellation cancellation_;
+  ExTestHandler handler_;
+}
+
+void main(string[] args) {
+  bool trace;
+  ushort port = 9090;
+  getopt(args, "port", &port, "trace", &trace);
+
+  auto serverCancellation = new TCancellationOrigin;
+  scope (exit) serverCancellation.trigger();
+
+  immutable ports = cast(immutable)array(map!"cast(ushort)a"(iota(port, port + 6)));
+
+version (none) {
+  // Cannot use this due to multiple DMD @@BUG@@s:
+  // 1. »function D main is a nested function and cannot be accessed from array«
+  //    when calling array() on the result of the outer map() – would have to
+  //    manually do the eager evaluation/array conversion.
+  // 2. »Zip.opSlice cannot get frame pointer to map« for the delay argument,
+  //    can be worked around by calling array() on the map result first.
+  // 3. Even when using the workarounds for the last two points, the DMD-built
+  //    executable crashes when building without (sic!) inlining enabled,
+  //    the backtrace points into the first delegate literal.
+  auto handlers = array(map!((args){
+    return new ExTestHandler(args._0, args._1, args._2, trace);
+  })(zip(
+    ports,
+    map!((a){ return dur!`msecs`(a); })([1, 10, 100, 1, 10, 100]),
+    [false, false, false, true, true, true]
+  )));
+} else {
+  auto handlers = [
+    new ExTestHandler(cast(ushort)(port + 0), dur!"msecs"(1), false, trace),
+    new ExTestHandler(cast(ushort)(port + 1), dur!"msecs"(10), false, trace),
+    new ExTestHandler(cast(ushort)(port + 2), dur!"msecs"(100), false, trace),
+    new ExTestHandler(cast(ushort)(port + 3), dur!"msecs"(1), true, trace),
+    new ExTestHandler(cast(ushort)(port + 4), dur!"msecs"(10), true, trace),
+    new ExTestHandler(cast(ushort)(port + 5), dur!"msecs"(100), true, trace)
+  ];
+}
+
+  // Fire up the server threads.
+  foreach (h; handlers) (new ServerThread(h, serverCancellation)).start();
+
+  // Give the servers some time to get up. This should really be accomplished
+  // via a barrier here and in the preServe() hook.
+  Thread.sleep(dur!"msecs"(10));
+
+  syncClientPoolTest(ports, handlers);
+  asyncClientPoolTest(ports, handlers);
+  asyncFastestClientPoolTest(ports, handlers);
+  asyncAggregatorTest(ports, handlers);
+}
+
+
+void syncClientPoolTest(const(ushort)[] ports, ExTestHandler[] handlers) {
+  auto clients = array(map!((a){
+    return cast(TClientBase!ExTestService)tClient!ExTestService(
+      tBinaryProtocol(new TSocket("127.0.0.1", a))
+    );
+  })(ports));
+
+  scope(exit) foreach (c; clients) c.outputProtocol.transport.close();
+
+  // Try the case where the first client succeeds.
+  {
+    enforce(makePool(clients).getPort() == ports[0]);
+  }
+
+  // Try the case where all clients fail.
+  {
+    auto pool = makePool(clients[3 .. $]);
+    auto e = cast(TCompoundOperationException)collectException(pool.getPort());
+    enforce(e);
+    enforce(equal(map!"a.port"(cast(TestServiceException[])e.exceptions),
+      ports[3 .. $]));
+  }
+
+  // Try the case where the first clients fail, but a later one succeeds.
+  {
+    auto pool = makePool(clients[3 .. $] ~ clients[0 .. 3]);
+    enforce(pool.getPortInArray() == [ports[0]]);
+  }
+
+  // Make sure a client is properly deactivated when it has failed too often.
+  {
+    auto pool = makePool(clients);
+    pool.faultDisableCount = 1;
+    pool.faultDisableDuration = dur!"msecs"(50);
+
+    handlers[0].failing = true;
+    enforce(pool.getPort() == ports[1]);
+
+    handlers[0].failing = false;
+    enforce(pool.getPort() == ports[1]);
+
+    Thread.sleep(dur!"msecs"(50));
+    enforce(pool.getPort() == ports[0]);
+  }
+}
+
+auto makePool(TClientBase!ExTestService[] clients) {
+  auto p = tClientPool(clients);
+  p.permuteClients = false;
+  p.rpcFaultFilter = (Exception e) {
+    return (cast(TestServiceException)e !is null);
+  };
+  return p;
+}
+
+
+void asyncClientPoolTest(const(ushort)[] ports, ExTestHandler[] handlers) {
+  auto manager = new TLibeventAsyncManager;
+  scope (exit) manager.stop(dur!"hnsecs"(0));
+
+  auto clients = makeAsyncClients(manager, ports);
+  scope(exit) foreach (c; clients) c.transport.close();
+
+  // Try the case where the first client succeeds.
+  {
+    enforce(makeAsyncPool(clients).getPort() == ports[0]);
+  }
+
+  // Try the case where all clients fail.
+  {
+    auto pool = makeAsyncPool(clients[3 .. $]);
+    auto e = cast(TCompoundOperationException)collectException(pool.getPort().waitGet());
+    enforce(e);
+    enforce(equal(map!"a.port"(cast(TestServiceException[])e.exceptions),
+      ports[3 .. $]));
+  }
+
+  // Try the case where the first clients fail, but a later one succeeds.
+  {
+    auto pool = makeAsyncPool(clients[3 .. $] ~ clients[0 .. 3]);
+    enforce(pool.getPortInArray() == [ports[0]]);
+  }
+
+  // Make sure a client is properly deactivated when it has failed too often.
+  {
+    auto pool = makeAsyncPool(clients);
+    pool.faultDisableCount = 1;
+    pool.faultDisableDuration = dur!"msecs"(50);
+
+    handlers[0].failing = true;
+    enforce(pool.getPort() == ports[1]);
+
+    handlers[0].failing = false;
+    enforce(pool.getPort() == ports[1]);
+
+    Thread.sleep(dur!"msecs"(50));
+    enforce(pool.getPort() == ports[0]);
+  }
+}
+
+auto makeAsyncPool(TAsyncClientBase!ExTestService[] clients) {
+  auto p = tAsyncClientPool(clients);
+  p.permuteClients = false;
+  p.rpcFaultFilter = (Exception e) {
+    return (cast(TestServiceException)e !is null);
+  };
+  return p;
+}
+
+auto makeAsyncClients(TLibeventAsyncManager manager, in ushort[] ports) {
+  // DMD @@BUG@@ workaround: Using array on the lazyHandlers map result leads
+  // to »function D main is a nested function and cannot be accessed from array«.
+  // Thus, we manually do the array conversion.
+  auto lazyClients = map!((a){
+    return new TAsyncClient!ExTestService(
+      new TAsyncSocket(manager, "127.0.0.1", a),
+      new TBufferedTransportFactory,
+      new TBinaryProtocolFactory!(TBufferedTransport)
+    );
+  })(ports);
+  TAsyncClientBase!ExTestService[] clients;
+  foreach (c; lazyClients) clients ~= c;
+  return clients;
+}
+
+
+void asyncFastestClientPoolTest(const(ushort)[] ports, ExTestHandler[] handlers) {
+  auto manager = new TLibeventAsyncManager;
+  scope (exit) manager.stop(dur!"hnsecs"(0));
+
+  auto clients = makeAsyncClients(manager, ports);
+  scope(exit) foreach (c; clients) c.transport.close();
+
+  // Make sure the fastest client wins, even if they are called in some other
+  // order.
+  {
+    auto result = makeAsyncFastestPool(array(retro(clients))).getPort().waitGet();
+    enforce(result == ports[0]);
+  }
+
+  // Try the case where all clients fail.
+  {
+    auto pool = makeAsyncFastestPool(clients[3 .. $]);
+    auto e = cast(TCompoundOperationException)collectException(pool.getPort().waitGet());
+    enforce(e);
+    enforce(equal(map!"a.port"(cast(TestServiceException[])e.exceptions),
+      ports[3 .. $]));
+  }
+
+  // Try the case where the first clients fail, but a later one succeeds.
+  {
+    auto pool = makeAsyncFastestPool(clients[1 .. $]);
+    enforce(pool.getPortInArray() == [ports[1]]);
+  }
+}
+
+auto makeAsyncFastestPool(TAsyncClientBase!ExTestService[] clients) {
+  auto p = tAsyncFastestClientPool(clients);
+  p.rpcFaultFilter = (Exception e) {
+    return (cast(TestServiceException)e !is null);
+  };
+  return p;
+}
+
+
+void asyncAggregatorTest(const(ushort)[] ports, ExTestHandler[] handlers) {
+  auto manager = new TLibeventAsyncManager;
+  scope (exit) manager.stop(dur!"hnsecs"(0));
+
+  auto clients = makeAsyncClients(manager, ports);
+  scope(exit) foreach (c; clients) c.transport.close();
+
+  auto aggregator = tAsyncAggregator(
+    cast(TAsyncClientBase!ExTestService[])clients);
+
+  // Test aggregator range interface.
+  {
+    auto range = aggregator.getPort().range(dur!"msecs"(50));
+    enforce(equal(range, ports[0 .. 2][]));
+    enforce(equal(map!"a.port"(cast(TestServiceException[])range.exceptions),
+      ports[3 .. $ - 1]));
+    enforce(range.completedCount == 4);
+  }
+
+  // Test default accumulator for scalars.
+  {
+    auto fullResult = aggregator.getPort().accumulate();
+    enforce(fullResult.waitGet() == ports[0 .. 3]);
+
+    auto partialResult = aggregator.getPort().accumulate();
+    Thread.sleep(dur!"msecs"(20));
+    enforce(partialResult.finishGet() == ports[0 .. 2]);
+
+  }
+
+  // Test default accumulator for arrays.
+  {
+    auto fullResult = aggregator.getPortInArray().accumulate();
+    enforce(fullResult.waitGet() == ports[0 .. 3]);
+
+    auto partialResult = aggregator.getPortInArray().accumulate();
+    Thread.sleep(dur!"msecs"(20));
+    enforce(partialResult.finishGet() == ports[0 .. 2]);
+  }
+
+  // Test custom accumulator.
+  {
+    auto fullResult = aggregator.getPort().accumulate!(function(int[] results){
+      return reduce!"a + b"(results);
+    })();
+    enforce(fullResult.waitGet() == ports[0] + ports[1] + ports[2]);
+
+    auto partialResult = aggregator.getPort().accumulate!(
+      function(int[] results, Exception[] exceptions) {
+        // Return a tuple of the parameters so we can check them outside of
+        // this function (to verify the values, we need access to »ports«, but
+        // due to DMD @@BUG5710@@, we can't use a delegate literal).f
+        return tuple(results, exceptions);
+      }
+    )();
+    Thread.sleep(dur!"msecs"(20));
+    auto resultTuple = partialResult.finishGet();
+    enforce(resultTuple._0 == ports[0 .. 2]);
+    enforce(equal(map!"a.port"(cast(TestServiceException[])resultTuple._1),
+      ports[3 .. $ - 1]));
+  }
+}
diff --git a/lib/d/test/openssl.test.cnf b/lib/d/test/openssl.test.cnf
new file mode 100644
index 0000000..2ada30b
--- /dev/null
+++ b/lib/d/test/openssl.test.cnf
@@ -0,0 +1,14 @@
+[ req ]
+default_bits = 2048
+default_keyfile = server-private-key.pem
+distinguished_name = req_distinguished_name
+x509_extensions = v3_ca
+prompt = no
+
+[ req_distinguished_name ]
+CN = localhost
+
+[ v3_ca ]
+# Add ::1 to the list of allowed IPs so we can use ::1 to explicitly connect
+# to localhost via IPv6.
+subjectAltName = IP:::1
diff --git a/lib/d/test/serialization_benchmark.d b/lib/d/test/serialization_benchmark.d
new file mode 100644
index 0000000..35515c8
--- /dev/null
+++ b/lib/d/test/serialization_benchmark.d
@@ -0,0 +1,70 @@
+/**
+ * An implementation of the mini serialization benchmark also available for
+ * C++ and Java.
+ *
+ * For meaningful results, you might want to make sure that
+ * the Thrift library is compiled with release build flags,
+ * e.g. by including the source files with the build instead
+ * of linking libthriftd:
+ *
+   dmd -w -O -release -inline -I../src -Igen-d -ofserialization_benchmark \
+   $(find ../src/thrift -name '*.d' -not -name index.d) \
+   gen-d/DebugProtoTest_types.d serialization_benchmark.d
+ */
+module serialization_benchmark;
+
+import std.datetime : AutoStart, StopWatch;
+import std.math : PI;
+import std.stdio;
+import thrift.protocol.binary;
+import thrift.transport.memory;
+import thrift.transport.range;
+import DebugProtoTest_types;
+
+void main() {
+  auto buf = new TMemoryBuffer;
+  enum ITERATIONS = 10_000_000;
+
+  {
+    auto ooe = OneOfEach();
+    ooe.im_true   = true;
+    ooe.im_false  = false;
+    ooe.a_bite    = 0x7f;
+    ooe.integer16 = 27_000;
+    ooe.integer32 = 1 << 24;
+    ooe.integer64 = 6_000_000_000;
+    ooe.double_precision = PI;
+    ooe.some_characters = "JSON THIS! \"\1";
+    ooe.zomg_unicode = "\xd7\n\a\t";
+    ooe.base64 = "\1\2\3\255";
+
+    auto prot = tBinaryProtocol(buf);
+    auto sw = StopWatch(AutoStart.yes);
+    foreach (i; 0 .. ITERATIONS) {
+      buf.reset(120);
+      ooe.write(prot);
+    }
+    sw.stop();
+
+    auto msecs = sw.peek().msecs;
+    writefln("Write: %s ms (%s kHz)", msecs, ITERATIONS / msecs);
+  }
+
+  auto data = buf.getContents().dup;
+
+  {
+    auto readBuf = tInputRangeTransport(data);
+    auto prot = tBinaryProtocol(readBuf);
+    auto ooe = OneOfEach();
+
+    auto sw = StopWatch(AutoStart.yes);
+    foreach (i; 0 .. ITERATIONS) {
+      readBuf.reset(data);
+      ooe.read(prot);
+    }
+    sw.stop();
+
+    auto msecs = sw.peek().msecs;
+    writefln(" Read: %s ms (%s kHz)", msecs, ITERATIONS / msecs);
+  }
+}
diff --git a/lib/d/test/stress_test_server.d b/lib/d/test/stress_test_server.d
new file mode 100644
index 0000000..ddda098
--- /dev/null
+++ b/lib/d/test/stress_test_server.d
@@ -0,0 +1,81 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+module stress_test_server;
+
+import std.getopt;
+import std.parallelism : totalCPUs;
+import std.stdio;
+import std.typetuple;
+import thrift.codegen.processor;
+import thrift.protocol.binary;
+import thrift.server.base;
+import thrift.server.transport.socket;
+import thrift.transport.buffered;
+import thrift.transport.memory;
+import thrift.transport.socket;
+import thrift.util.hashset;
+import test_utils;
+
+import thrift.test.stress.Service;
+
+class ServiceHandler : Service {
+  void echoVoid() { return; }
+  byte echoByte(byte arg) { return arg; }
+  int echoI32(int arg) { return arg; }
+  long echoI64(long arg) { return arg; }
+  byte[] echoList(byte[] arg) { return arg; }
+  HashSet!byte echoSet(HashSet!byte arg) { return arg; }
+  byte[byte] echoMap(byte[byte] arg) { return arg; }
+
+  string echoString(string arg) {
+    if (arg != "hello") {
+      stderr.writefln(`Wrong string received: %s instead of "hello"`, arg);
+      throw new Exception("Wrong string received.");
+    }
+    return arg;
+  }
+}
+
+void main(string[] args) {
+  ushort port = 9091;
+  auto serverType = ServerType.threaded;
+  TransportType transportType;
+  size_t numIOThreads = 1;
+  size_t taskPoolSize = totalCPUs;
+
+  getopt(args, "port", &port, "server-type", &serverType,
+    "transport-type", &transportType, "task-pool-size", &taskPoolSize,
+    "num-io-threads", &numIOThreads);
+
+  alias TypeTuple!(TBufferedTransport, TMemoryBuffer) AvailableTransports;
+
+  auto processor = new TServiceProcessor!(Service,
+    staticMap!(TBinaryProtocol, AvailableTransports))(new ServiceHandler());
+  auto serverSocket = new TServerSocket(port);
+  auto transportFactory = createTransportFactory(transportType);
+  auto protocolFactory = new TBinaryProtocolFactory!AvailableTransports;
+
+  auto server = createServer(serverType, taskPoolSize, numIOThreads,
+    processor, serverSocket, transportFactory, protocolFactory);
+
+  writefln("Starting %s %s StressTest server on port %s...", transportType,
+    serverType, port);
+  server.serve();
+  writeln("done.");
+}
diff --git a/lib/d/test/test_utils.d b/lib/d/test/test_utils.d
new file mode 100644
index 0000000..174100b
--- /dev/null
+++ b/lib/d/test/test_utils.d
@@ -0,0 +1,96 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/**
+ * Various helpers used by more than a single test.
+ */
+module test_utils;
+
+import std.parallelism : TaskPool;
+import thrift.protocol.base;
+import thrift.protocol.processor;
+import thrift.server.base;
+import thrift.server.nonblocking;
+import thrift.server.simple;
+import thrift.server.taskpool;
+import thrift.server.threaded;
+import thrift.server.transport.socket;
+import thrift.transport.base;
+import thrift.transport.buffered;
+import thrift.transport.framed;
+import thrift.transport.http;
+
+// This is a likely victim of @@BUG4744@@ when used with command argument
+// parsing.
+enum ServerType {
+  simple,
+  nonblocking,
+  pooledNonblocking,
+  taskpool,
+  threaded
+}
+
+TServer createServer(ServerType type, size_t taskPoolSize, size_t numIOThreads,
+  TProcessor processor, TServerSocket serverTransport,
+  TTransportFactory transportFactory, TProtocolFactory protocolFactory)
+{
+  final switch (type) {
+    case ServerType.simple:
+      return new TSimpleServer(processor, serverTransport,
+        transportFactory, protocolFactory);
+    case ServerType.nonblocking:
+      auto nb = new TNonblockingServer(processor, serverTransport.port,
+        transportFactory, protocolFactory);
+      nb.numIOThreads = numIOThreads;
+      return nb;
+    case ServerType.pooledNonblocking:
+      auto nb = new TNonblockingServer(processor, serverTransport.port,
+        transportFactory, protocolFactory, new TaskPool(taskPoolSize));
+      nb.numIOThreads = numIOThreads;
+      return nb;
+    case ServerType.taskpool:
+      auto tps = new TTaskPoolServer(processor, serverTransport,
+        transportFactory, protocolFactory);
+      tps.taskPool = new TaskPool(taskPoolSize);
+      return tps;
+    case ServerType.threaded:
+      return new TThreadedServer(processor, serverTransport,
+        transportFactory, protocolFactory);
+  }
+}
+
+enum TransportType {
+  buffered,
+  framed,
+  http,
+  raw
+}
+
+TTransportFactory createTransportFactory(TransportType type) {
+  final switch (type) {
+    case TransportType.buffered:
+      return new TBufferedTransportFactory;
+    case TransportType.framed:
+      return new TFramedTransportFactory;
+    case TransportType.http:
+      return new TServerHttpTransportFactory;
+    case TransportType.raw:
+      return new TTransportFactory;
+  }
+}
diff --git a/lib/d/test/thrift_test_client.d b/lib/d/test/thrift_test_client.d
new file mode 100644
index 0000000..a258b64
--- /dev/null
+++ b/lib/d/test/thrift_test_client.d
@@ -0,0 +1,372 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+module thrift_test_client;
+
+import std.conv;
+import std.datetime;
+import std.exception : enforce;
+import std.getopt;
+import std.stdio;
+import std.string;
+import std.traits;
+import thrift.codegen.client;
+import thrift.protocol.base;
+import thrift.protocol.binary;
+import thrift.protocol.compact;
+import thrift.protocol.json;
+import thrift.transport.base;
+import thrift.transport.buffered;
+import thrift.transport.framed;
+import thrift.transport.http;
+import thrift.transport.socket;
+import thrift.transport.ssl;
+import thrift.util.hashset;
+
+import thrift_test_common;
+import thrift.test.ThriftTest;
+import thrift.test.ThriftTest_types;
+
+enum TransportType {
+  buffered,
+  framed,
+  http,
+  raw
+}
+
+TProtocol createProtocol(T)(T trans, ProtocolType type) {
+  final switch (type) {
+    case ProtocolType.binary:
+      return tBinaryProtocol(trans);
+    case ProtocolType.compact:
+      return tCompactProtocol(trans);
+    case ProtocolType.json:
+      return tJsonProtocol(trans);
+  }
+}
+
+void main(string[] args) {
+  string host = "localhost";
+  ushort port = 9090;
+  uint numTests = 1;
+  bool ssl;
+  ProtocolType protocolType;
+  TransportType transportType;
+  bool trace;
+
+  getopt(args,
+    "numTests|n", &numTests,
+    "protocol", &protocolType,
+    "ssl", &ssl,
+    "transport", &transportType,
+    "trace", &trace,
+    "host", (string _, string value) {
+      auto parts = split(value, ":");
+      if (parts.length > 1) {
+        // IPv6 addresses can contain colons, so take the last part for the
+        // port.
+        host = join(parts[0 .. $ - 1], ":");
+        port = to!ushort(parts[$ - 1]);
+      } else {
+        host = value;
+      }
+    }
+  );
+
+  TSocket socket;
+  if (ssl) {
+    auto sslContext = new TSSLContext();
+    sslContext.ciphers = "ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH";
+    sslContext.authenticate = true;
+    sslContext.loadTrustedCertificates("./trusted-ca-certificate.pem");
+    socket = new TSSLSocket(sslContext, host, port);
+  } else {
+    socket = new TSocket(host, port);
+  }
+
+  TProtocol protocol;
+  final switch (transportType) {
+    case TransportType.buffered:
+      protocol = createProtocol(new TBufferedTransport(socket), protocolType);
+      break;
+    case TransportType.framed:
+      protocol = createProtocol(new TFramedTransport(socket), protocolType);
+      break;
+    case TransportType.http:
+      protocol = createProtocol(
+        new TClientHttpTransport(socket, host, "/service"), protocolType);
+      break;
+    case TransportType.raw:
+      protocol = createProtocol(socket, protocolType);
+      break;
+  }
+
+  auto client = tClient!ThriftTest(protocol);
+
+  ulong time_min;
+  ulong time_max;
+  ulong time_tot;
+
+  StopWatch sw;
+  foreach(test; 0 .. numTests) {
+    sw.start();
+
+    protocol.transport.open();
+
+    if (trace) writefln("Test #%s, connect %s:%s", test + 1, host, port);
+
+    if (trace) write("testVoid()");
+    client.testVoid();
+    if (trace) writeln(" = void");
+
+    if (trace) write("testString(\"Test\")");
+    string s = client.testString("Test");
+    if (trace) writefln(" = \"%s\"", s);
+    enforce(s == "Test");
+
+    if (trace) write("testByte(1)");
+    byte u8 = client.testByte(1);
+    if (trace) writefln(" = %s", u8);
+    enforce(u8 == 1);
+
+    if (trace) write("testI32(-1)");
+    int i32 = client.testI32(-1);
+    if (trace) writefln(" = %s", i32);
+    enforce(i32 == -1);
+
+    if (trace) write("testI64(-34359738368)");
+    long i64 = client.testI64(-34359738368L);
+    if (trace) writefln(" = %s", i64);
+    enforce(i64 == -34359738368L);
+
+    if (trace) write("testDouble(-5.2098523)");
+    double dub = client.testDouble(-5.2098523);
+    if (trace) writefln(" = %s", dub);
+    enforce(dub == -5.2098523);
+
+    Xtruct out1;
+    out1.string_thing = "Zero";
+    out1.byte_thing = 1;
+    out1.i32_thing = -3;
+    out1.i64_thing = -5;
+    if (trace) writef("testStruct(%s)", out1);
+    auto in1 = client.testStruct(out1);
+    if (trace) writefln(" = %s", in1);
+    enforce(in1 == out1);
+
+    if (trace) write("testNest({1, {\"Zero\", 1, -3, -5}), 5}");
+    Xtruct2 out2;
+    out2.byte_thing = 1;
+    out2.struct_thing = out1;
+    out2.i32_thing = 5;
+    auto in2 = client.testNest(out2);
+    in1 = in2.struct_thing;
+    if (trace) writefln(" = {%s, {\"%s\", %s, %s, %s}, %s}", in2.byte_thing,
+      in1.string_thing, in1.byte_thing, in1.i32_thing, in1.i64_thing,
+      in2.i32_thing);
+    enforce(in2 == out2);
+
+    int[int] mapout;
+    for (int i = 0; i < 5; ++i) {
+      mapout[i] = i - 10;
+    }
+    if (trace) writef("testMap({%s})", mapout);
+    auto mapin = client.testMap(mapout);
+    if (trace) writefln(" = {%s}", mapin);
+    enforce(mapin == mapout);
+
+    auto setout = new HashSet!int;
+    for (int i = -2; i < 3; ++i) {
+      setout ~= i;
+    }
+    if (trace) writef("testSet(%s)", setout);
+    auto setin = client.testSet(setout);
+    if (trace) writefln(" = %s", setin);
+    enforce(setin == setout);
+
+    int[] listout;
+    for (int i = -2; i < 3; ++i) {
+      listout ~= i;
+    }
+    if (trace) writef("testList(%s)", listout);
+    auto listin = client.testList(listout);
+    if (trace) writefln(" = %s", listin);
+    enforce(listin == listout);
+
+    {
+      if (trace) write("testEnum(ONE)");
+      auto ret = client.testEnum(Numberz.ONE);
+      if (trace) writefln(" = %s", ret);
+      enforce(ret == Numberz.ONE);
+
+      if (trace) write("testEnum(TWO)");
+      ret = client.testEnum(Numberz.TWO);
+      if (trace) writefln(" = %s", ret);
+      enforce(ret == Numberz.TWO);
+
+      if (trace) write("testEnum(THREE)");
+      ret = client.testEnum(Numberz.THREE);
+      if (trace) writefln(" = %s", ret);
+      enforce(ret == Numberz.THREE);
+
+      if (trace) write("testEnum(FIVE)");
+      ret = client.testEnum(Numberz.FIVE);
+      if (trace) writefln(" = %s", ret);
+      enforce(ret == Numberz.FIVE);
+
+      if (trace) write("testEnum(EIGHT)");
+      ret = client.testEnum(Numberz.EIGHT);
+      if (trace) writefln(" = %s", ret);
+      enforce(ret == Numberz.EIGHT);
+    }
+
+    if (trace) write("testTypedef(309858235082523)");
+    UserId uid = client.testTypedef(309858235082523L);
+    if (trace) writefln(" = %s", uid);
+    enforce(uid == 309858235082523L);
+
+    if (trace) write("testMapMap(1)");
+    auto mm = client.testMapMap(1);
+    if (trace) writefln(" = {%s}", mm);
+    // Simply doing == doesn't seem to work for nested AAs.
+    foreach (key, value; mm) {
+      enforce(testMapMapReturn[key] == value);
+    }
+    foreach (key, value; testMapMapReturn) {
+      enforce(mm[key] == value);
+    }
+
+    Insanity insane;
+    insane.userMap[Numberz.FIVE] = 5000;
+    Xtruct truck;
+    truck.string_thing = "Truck";
+    truck.byte_thing = 8;
+    truck.i32_thing = 8;
+    truck.i64_thing = 8;
+    insane.xtructs ~= truck;
+    if (trace) write("testInsanity()");
+    auto whoa = client.testInsanity(insane);
+    if (trace) writefln(" = %s", whoa);
+
+    // Commented for now, this is cumbersome to write without opEqual getting
+    // called on AA comparison.
+    // enforce(whoa == testInsanityReturn);
+
+    {
+      try {
+        if (trace) write("client.testException(\"Xception\") =>");
+        client.testException("Xception");
+        if (trace) writeln("  void\nFAILURE");
+        throw new Exception("testException failed.");
+      } catch (Xception e) {
+        if (trace) writefln("  {%s, \"%s\"}", e.errorCode, e.message);
+      }
+
+      try {
+        if (trace) write("client.testException(\"success\") =>");
+        client.testException("success");
+        if (trace) writeln("  void");
+      } catch (Exception e) {
+        if (trace) writeln("  exception\nFAILURE");
+        throw new Exception("testException failed.");
+      }
+    }
+
+    {
+      try {
+        if (trace) write("client.testMultiException(\"Xception\", \"test 1\") =>");
+        auto result = client.testMultiException("Xception", "test 1");
+        if (trace) writeln("  result\nFAILURE");
+        throw new Exception("testMultiException failed.");
+      } catch (Xception e) {
+        if (trace) writefln("  {%s, \"%s\"}", e.errorCode, e.message);
+      }
+
+      try {
+        if (trace) write("client.testMultiException(\"Xception2\", \"test 2\") =>");
+        auto result = client.testMultiException("Xception2", "test 2");
+        if (trace) writeln("  result\nFAILURE");
+        throw new Exception("testMultiException failed.");
+      } catch (Xception2 e) {
+        if (trace) writefln("  {%s, {\"%s\"}}",
+          e.errorCode, e.struct_thing.string_thing);
+      }
+
+      try {
+        if (trace) writef("client.testMultiException(\"success\", \"test 3\") =>");
+        auto result = client.testMultiException("success", "test 3");
+        if (trace) writefln("  {{\"%s\"}}", result.string_thing);
+      } catch (Exception e) {
+        if (trace) writeln("  exception\nFAILURE");
+        throw new Exception("testMultiException failed.");
+      }
+    }
+
+    // Do not run oneway test when doing multiple iterations, as it blocks the
+    // server for three seconds.
+    if (numTests == 1) {
+      if (trace) writef("client.testOneway(3) =>");
+      auto onewayWatch = StopWatch(AutoStart.yes);
+      client.testOneway(3);
+      onewayWatch.stop();
+      if (onewayWatch.peek().msecs > 200) {
+        if (trace) {
+          writefln("  FAILURE - took %s ms", onewayWatch.peek().usecs / 1000.0);
+        }
+        throw new Exception("testOneway failed.");
+      } else {
+        if (trace) {
+          writefln("  success - took %s ms", onewayWatch.peek().usecs / 1000.0);
+        }
+      }
+
+      // Redo a simple test after the oneway to make sure we aren't "off by
+      // one", which would be the case if the server treated oneway methods
+      // like normal ones.
+      if (trace) write("re-test testI32(-1)");
+      i32 = client.testI32(-1);
+      if (trace) writefln(" = %s", i32);
+    }
+
+    // Time metering.
+    sw.stop();
+
+    immutable tot = sw.peek().usecs;
+    if (trace) writefln("Total time: %s us\n", tot);
+
+    time_tot += tot;
+    if (time_min == 0 || tot < time_min) {
+      time_min = tot;
+    }
+    if (tot > time_max) {
+      time_max = tot;
+    }
+    protocol.transport.close();
+
+    sw.reset();
+  }
+
+  writeln("All tests done.");
+
+  if (numTests > 1) {
+    auto time_avg = time_tot / numTests;
+    writefln("Min time: %s us", time_min);
+    writefln("Max time: %s us", time_max);
+    writefln("Avg time: %s us", time_avg);
+  }
+}
diff --git a/lib/d/test/thrift_test_common.d b/lib/d/test/thrift_test_common.d
new file mode 100644
index 0000000..13a5686
--- /dev/null
+++ b/lib/d/test/thrift_test_common.d
@@ -0,0 +1,92 @@
+module thrift_test_common;
+
+import std.stdio;
+import thrift.test.ThriftTest_types;
+
+enum ProtocolType {
+  binary,
+  compact,
+  json
+}
+
+void writeInsanityReturn(in Insanity[Numberz][UserId] insane) {
+  write("{");
+  foreach(key1, value1; insane) {
+    writef("%s => {", key1);
+    foreach(key2, value2; value1) {
+      writef("%s => {", key2);
+      write("{");
+      foreach(key3, value3; value2.userMap) {
+        writef("%s => %s, ", key3, value3);
+      }
+      write("}, ");
+
+      write("{");
+      foreach (x; value2.xtructs) {
+        writef("{\"%s\", %s, %s, %s}, ",
+          x.string_thing, x.byte_thing, x.i32_thing, x.i64_thing);
+      }
+      write("}");
+
+      write("}, ");
+    }
+    write("}, ");
+  }
+  write("}");
+}
+
+Insanity[Numberz][UserId] testInsanityReturn;
+int[int][int] testMapMapReturn;
+
+static this() {
+  testInsanityReturn = {
+    Insanity[Numberz][UserId] insane;
+
+    Xtruct hello;
+    hello.string_thing = "Hello2";
+    hello.byte_thing = 2;
+    hello.i32_thing = 2;
+    hello.i64_thing = 2;
+
+    Xtruct goodbye;
+    goodbye.string_thing = "Goodbye4";
+    goodbye.byte_thing = 4;
+    goodbye.i32_thing = 4;
+    goodbye.i64_thing = 4;
+
+    Insanity crazy;
+    crazy.userMap[Numberz.EIGHT] = 8;
+    crazy.xtructs ~= goodbye;
+
+    Insanity looney;
+    // The C++ TestServer also assigns these to crazy, but that is probably
+    // an oversight.
+    looney.userMap[Numberz.FIVE] = 5;
+    looney.xtructs ~= hello;
+
+    Insanity[Numberz] first_map;
+    first_map[Numberz.TWO] = crazy;
+    first_map[Numberz.THREE] = crazy;
+    insane[1] = first_map;
+
+    Insanity[Numberz] second_map;
+    second_map[Numberz.SIX] = looney;
+    insane[2] = second_map;
+    return insane;
+  }();
+
+  testMapMapReturn = {
+    int[int] pos;
+    int[int] neg;
+
+    for (int i = 1; i < 5; i++) {
+      pos[i] = i;
+      neg[-i] = -i;
+    }
+
+    int[int][int] result;
+    result[4] = pos;
+    result[-4] = neg;
+    return result;
+  }();
+}
diff --git a/lib/d/test/thrift_test_runner.sh b/lib/d/test/thrift_test_runner.sh
new file mode 100644
index 0000000..fbe75f0
--- /dev/null
+++ b/lib/d/test/thrift_test_runner.sh
@@ -0,0 +1,65 @@
+#!/bin/bash
+# Runs the D ThriftTest client and servers for all combinations of transport,
+# protocol, SSL-mode and server type.
+# Pass -k to keep going after failed tests.
+
+protocols="binary compact json"
+transports="buffered framed http raw"
+servers="simple taskpool threaded"
+framed_only_servers="nonblocking pooledNonblocking"
+
+# Don't leave any server instances behind when interrupted (e.g. by Ctrl+C)
+# or terminated.
+trap "kill $(jobs -p) 2>/dev/null" INT TERM
+
+for protocol in $protocols; do
+  for ssl in "" " --ssl"; do
+    for transport in $transports; do
+      for server in $servers $framed_only_servers; do
+        case $framed_only_servers in
+          *$server*) if [ $transport != "framed" ] || [ $ssl != "" ]; then continue; fi;;
+        esac
+
+        args="--transport=$transport --protocol=$protocol$ssl"
+        ./thrift_test_server $args --server-type=$server > /dev/null &
+        server_pid=$!
+
+        # Give the server some time to get up and check if it runs (yes, this
+        # is a huge kludge, should add a connect timeout to test client).
+        client_rc=-1
+        sleep 0.01
+        kill -0 $server_pid 2>/dev/null
+        if [ $? -eq 0 ]; then
+          ./thrift_test_client $args --numTests=10 > /dev/null
+          client_rc=$?
+
+          # Temporarily redirect stderr to null to avoid job control messages,
+          # restore it afterwards.
+          exec 3>&2
+          exec 2>/dev/null
+          kill $server_pid
+          exec 3>&2
+        fi
+
+        # Get the server exit code (wait should immediately return).
+        wait $server_pid
+        server_rc=$?
+
+        if [ $client_rc -ne 0 -o $server_rc -eq 1 ]; then
+          echo -e "\nTests failed for: $args --server-type=$server"
+          failed="true"
+          if [ "$1" != "-k" ]; then
+            exit 1
+          fi
+        else
+           echo -n "."
+        fi
+      done
+    done
+  done
+done
+
+echo
+if [ -z "$failed" ]; then
+  echo "All tests passed."
+fi
diff --git a/lib/d/test/thrift_test_server.d b/lib/d/test/thrift_test_server.d
new file mode 100644
index 0000000..993c063
--- /dev/null
+++ b/lib/d/test/thrift_test_server.d
@@ -0,0 +1,264 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+module thrift_test_server;
+
+import core.thread : dur, Thread;
+import std.algorithm;
+import std.exception : enforce;
+import std.getopt;
+import std.parallelism : totalCPUs;
+import std.string;
+import std.stdio;
+import std.typetuple : TypeTuple, staticMap;
+import thrift.base;
+import thrift.codegen.processor;
+import thrift.protocol.base;
+import thrift.protocol.binary;
+import thrift.protocol.compact;
+import thrift.protocol.json;
+import thrift.server.base;
+import thrift.server.transport.socket;
+import thrift.server.transport.ssl;
+import thrift.transport.base;
+import thrift.transport.buffered;
+import thrift.transport.framed;
+import thrift.transport.http;
+import thrift.transport.ssl;
+import thrift.util.hashset;
+import test_utils;
+
+import thrift_test_common;
+import thrift.test.ThriftTest_types;
+import thrift.test.ThriftTest;
+
+class TestHandler : ThriftTest {
+  this(bool trace) {
+    trace_ = trace;
+  }
+
+  override void testVoid() {
+    if (trace_) writeln("testVoid()");
+  }
+
+  override string testString(string thing) {
+    if (trace_) writefln("testString(\"%s\")", thing);
+    return thing;
+  }
+
+  override byte testByte(byte thing) {
+    if (trace_) writefln("testByte(%s)", thing);
+    return thing;
+  }
+
+  override int testI32(int thing) {
+    if (trace_) writefln("testI32(%s)", thing);
+    return thing;
+  }
+
+  override long testI64(long thing) {
+    if (trace_) writefln("testI64(%s)", thing);
+    return thing;
+  }
+
+  override double testDouble(double thing) {
+    if (trace_) writefln("testDouble(%s)", thing);
+    return thing;
+  }
+
+  override Xtruct testStruct(ref const(Xtruct) thing) {
+    if (trace_) writefln("testStruct({\"%s\", %s, %s, %s})",
+      thing.string_thing, thing.byte_thing, thing.i32_thing, thing.i64_thing);
+    return thing;
+  }
+
+  override Xtruct2 testNest(ref const(Xtruct2) nest) {
+    auto thing = nest.struct_thing;
+    if (trace_) writefln("testNest({%s, {\"%s\", %s, %s, %s}, %s})",
+      nest.byte_thing, thing.string_thing, thing.byte_thing, thing.i32_thing,
+      thing.i64_thing, nest.i32_thing);
+    return nest;
+  }
+
+  override int[int] testMap(int[int] thing) {
+    if (trace_) writefln("testMap({%s})", thing);
+    return thing;
+  }
+
+  override HashSet!int testSet(HashSet!int thing) {
+    if (trace_) writefln("testSet({%s})",
+      join(map!`to!string(a)`(thing[]), ", "));
+    return thing;
+  }
+
+  override int[] testList(int[] thing) {
+    if (trace_) writefln("testList(%s)", thing);
+    return thing;
+  }
+
+  override Numberz testEnum(Numberz thing) {
+    if (trace_) writefln("testEnum(%s)", thing);
+    return thing;
+  }
+
+  override UserId testTypedef(UserId thing) {
+    if (trace_) writefln("testTypedef(%s)", thing);
+    return thing;
+  }
+
+  override string[string] testStringMap(string[string] thing) {
+    if (trace_) writefln("testStringMap(%s)", thing);
+    return thing;
+  }
+
+  override int[int][int] testMapMap(int hello) {
+    if (trace_) writefln("testMapMap(%s)", hello);
+    return testMapMapReturn;
+  }
+
+  override Insanity[Numberz][UserId] testInsanity(ref const(Insanity) argument) {
+    if (trace_) writeln("testInsanity()");
+    return testInsanityReturn;
+  }
+
+  override Xtruct testMulti(byte arg0, int arg1, long arg2, string[short] arg3,
+    Numberz arg4, UserId arg5)
+  {
+    if (trace_) writeln("testMulti()");
+    return Xtruct("Hello2", arg0, arg1, arg2);
+  }
+
+  override void testException(string arg) {
+    if (trace_) writefln("testException(%s)", arg);
+    if (arg == "Xception") {
+      auto e = new Xception();
+      e.errorCode = 1001;
+      e.message = arg;
+      throw e;
+    } else if (arg == "ApplicationException") {
+      throw new TException();
+    }
+  }
+
+  override Xtruct testMultiException(string arg0, string arg1) {
+    if (trace_) writefln("testMultiException(%s, %s)", arg0, arg1);
+
+    if (arg0 == "Xception") {
+      auto e = new Xception();
+      e.errorCode = 1001;
+      e.message = "This is an Xception";
+      throw e;
+    } else if (arg0 == "Xception2") {
+      auto e = new Xception2();
+      e.errorCode = 2002;
+      e.struct_thing.string_thing = "This is an Xception2";
+      throw e;
+    } else {
+      return Xtruct(arg1);
+    }
+  }
+
+  override void testOneway(int sleepFor) {
+    if (trace_) writefln("testOneway(%s): Sleeping...", sleepFor);
+    Thread.sleep(dur!"seconds"(sleepFor));
+    if (trace_) writefln("testOneway(%s): done sleeping!", sleepFor);
+  }
+
+private:
+  bool trace_;
+}
+
+void main(string[] args) {
+  ushort port = 9090;
+  ServerType serverType;
+  ProtocolType protocolType;
+  size_t numIOThreads = 1;
+  TransportType transportType;
+  bool ssl;
+  bool trace;
+  size_t taskPoolSize = totalCPUs;
+
+  getopt(args, "port", &port, "protocol", &protocolType, "server-type",
+    &serverType, "ssl", &ssl, "num-io-threads", &numIOThreads,
+    "task-pool-size", &taskPoolSize, "trace", &trace,
+    "transport", &transportType);
+
+  if (serverType == ServerType.nonblocking ||
+    serverType == ServerType.pooledNonblocking
+  ) {
+    enforce(transportType == TransportType.framed,
+      "Need to use framed transport with non-blocking server.");
+    enforce(!ssl, "The non-blocking server does not support SSL yet.");
+
+    // Don't wrap the contents into another layer of framing.
+    transportType = TransportType.raw;
+  }
+
+  version (ThriftTestTemplates) {
+    // Only exercise the specialized template code paths if explicitly enabled
+    // to reduce memory consumption on regular test suite runs – there should
+    // not be much that can go wrong with that specifically anyway.
+    alias TypeTuple!(TBufferedTransport, TFramedTransport, TServerHttpTransport)
+      AvailableTransports;
+    alias TypeTuple!(
+      staticMap!(TBinaryProtocol, AvailableTransports),
+      staticMap!(TCompactProtocol, AvailableTransports)
+    ) AvailableProtocols;
+  } else {
+    alias TypeTuple!() AvailableTransports;
+    alias TypeTuple!() AvailableProtocols;
+  }
+
+  TProtocolFactory protocolFactory;
+  final switch (protocolType) {
+    case ProtocolType.binary:
+      protocolFactory = new TBinaryProtocolFactory!AvailableTransports;
+      break;
+    case ProtocolType.compact:
+      protocolFactory = new TCompactProtocolFactory!AvailableTransports;
+      break;
+    case ProtocolType.json:
+      protocolFactory = new TJsonProtocolFactory!AvailableTransports;
+      break;
+  }
+
+  auto processor = new TServiceProcessor!(ThriftTest, AvailableProtocols)(
+    new TestHandler(trace));
+
+  TServerSocket serverSocket;
+  if (ssl) {
+    auto sslContext = new TSSLContext();
+    sslContext.serverSide = true;
+    sslContext.loadCertificate("./server-certificate.pem");
+    sslContext.loadPrivateKey("./server-private-key.pem");
+    sslContext.ciphers = "ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH";
+    serverSocket = new TSSLServerSocket(port, sslContext);
+  } else {
+    serverSocket = new TServerSocket(port);
+  }
+
+  auto transportFactory = createTransportFactory(transportType);
+
+  auto server = createServer(serverType, numIOThreads, taskPoolSize,
+    processor, serverSocket, transportFactory, protocolFactory);
+
+  writefln("Starting %s/%s %s ThriftTest server %son port %s...", protocolType,
+    transportType, serverType, ssl ? "(using SSL) ": "", port);
+  server.serve();
+  writeln("done.");
+}
diff --git a/lib/d/test/transport_test.d b/lib/d/test/transport_test.d
new file mode 100644
index 0000000..3f61a5d
--- /dev/null
+++ b/lib/d/test/transport_test.d
@@ -0,0 +1,803 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/**
+ * Exercises various transports, combined with the buffered/framed wrappers.
+ *
+ * Originally ported from the C++ version, with Windows support code added.
+ */
+module transport_test;
+
+import core.atomic;
+import core.time : Duration;
+import core.thread : Thread;
+import std.conv : to;
+import std.datetime;
+import std.exception : enforce;
+static import std.file;
+import std.getopt;
+import std.random : rndGen, uniform, unpredictableSeed;
+import std.socket;
+import std.stdio;
+import std.string;
+import std.typetuple;
+import thrift.transport.base;
+import thrift.transport.buffered;
+import thrift.transport.framed;
+import thrift.transport.file;
+import thrift.transport.http;
+import thrift.transport.memory;
+import thrift.transport.socket;
+import thrift.transport.zlib;
+
+/*
+ * Size generation helpers – used to be able to run the same testing code
+ * with both constant and random total/chunk sizes.
+ */
+
+interface SizeGenerator {
+  size_t nextSize();
+  string toString();
+}
+
+class ConstantSizeGenerator : SizeGenerator {
+  this(size_t value) {
+    value_ = value;
+  }
+
+  override size_t nextSize() {
+    return value_;
+  }
+
+  override string toString() const {
+    return to!string(value_);
+  }
+
+private:
+  size_t value_;
+}
+
+class RandomSizeGenerator : SizeGenerator {
+  this(size_t min, size_t max) {
+    min_ = min;
+    max_ = max;
+  }
+
+  override size_t nextSize() {
+    return uniform!"[]"(min_, max_);
+  }
+
+  override string toString() const {
+    return format("rand(%s, %s)", min_, max_);
+  }
+
+  size_t min() const @property {
+    return min_;
+  }
+
+  size_t max() const @property {
+    return max_;
+  }
+
+private:
+  size_t min_;
+  size_t max_;
+}
+
+
+/*
+ * Classes to set up coupled transports
+ */
+
+/**
+ * Helper class to represent a coupled pair of transports.
+ *
+ * Data written to the output transport can be read from the input transport.
+ *
+ * This is used as the base class for the various coupled transport
+ * implementations. It shouldn't be used directly.
+ */
+class CoupledTransports(Transport) if (isTTransport!Transport) {
+  Transport input;
+  Transport output;
+}
+
+template isCoupledTransports(T) {
+  static if (is(T _ : CoupledTransports!U, U)) {
+    enum isCoupledTransports = true;
+  } else {
+    enum isCoupledTransports = false;
+  }
+}
+
+/**
+ * Helper template class for creating coupled transports that wrap
+ * another transport.
+ */
+class CoupledWrapperTransports(WrapperTransport, InnerCoupledTransports) if (
+  isTTransport!WrapperTransport && isCoupledTransports!InnerCoupledTransports
+) : CoupledTransports!WrapperTransport {
+  this() {
+    inner_ = new InnerCoupledTransports();
+    if (inner_.input) {
+      input = new WrapperTransport(inner_.input);
+    }
+    if (inner_.output) {
+      output = new WrapperTransport(inner_.output);
+    }
+  }
+
+  ~this() {
+    clear(inner_);
+  }
+
+private:
+  InnerCoupledTransports inner_;
+}
+
+import thrift.internal.codegen : PApply;
+alias PApply!(CoupledWrapperTransports, TBufferedTransport) CoupledBufferedTransports;
+alias PApply!(CoupledWrapperTransports, TFramedTransport) CoupledFramedTransports;
+alias PApply!(CoupledWrapperTransports, TZlibTransport) CoupledZlibTransports;
+
+/**
+ * Coupled TMemoryBuffers.
+ */
+class CoupledMemoryBuffers : CoupledTransports!TMemoryBuffer {
+  this() {
+    buf = new TMemoryBuffer;
+    input = buf;
+    output = buf;
+  }
+
+  TMemoryBuffer buf;
+}
+
+/**
+ * Coupled TSockets.
+ */
+class CoupledSocketTransports : CoupledTransports!TSocket {
+  this() {
+    auto sockets = socketPair();
+    input = new TSocket(sockets[0]);
+    output = new TSocket(sockets[1]);
+  }
+
+  ~this() {
+    input.close();
+    output.close();
+  }
+}
+
+/**
+ * Coupled TFileTransports
+ */
+class CoupledFileTransports : CoupledTransports!TTransport {
+  this() {
+    // We actually need the file name of the temp file here, so we can't just
+    // use the usual tempfile facilities.
+    do {
+      fileName_ = tmpDir ~ "/thrift.transport_test." ~ to!string(rndGen().front);
+      rndGen().popFront();
+    } while (std.file.exists(fileName_));
+
+    writefln("Using temp file: %s", fileName_);
+
+    auto writer = new TFileWriterTransport(fileName_);
+    writer.open();
+    output = writer;
+
+    // Wait until the file has been created.
+    writer.flush();
+
+    auto reader = new TFileReaderTransport(fileName_);
+    reader.open();
+    reader.readTimeout(dur!"msecs"(-1));
+    input = reader;
+  }
+
+  ~this() {
+    input.close();
+    output.close();
+    std.file.remove(fileName_);
+  }
+
+  static string tmpDir;
+
+private:
+  string fileName_;
+}
+
+
+/*
+ * Test functions
+ */
+
+/**
+ * Test interleaved write and read calls.
+ *
+ * Generates a buffer totalSize bytes long, then writes it to the transport,
+ * and verifies the written data can be read back correctly.
+ *
+ * Mode of operation:
+ * - call wChunkGenerator to figure out how large of a chunk to write
+ *   - call wSizeGenerator to get the size for individual write() calls,
+ *     and do this repeatedly until the entire chunk is written.
+ * - call rChunkGenerator to figure out how large of a chunk to read
+ *   - call rSizeGenerator to get the size for individual read() calls,
+ *     and do this repeatedly until the entire chunk is read.
+ * - repeat until the full buffer is written and read back,
+ *   then compare the data read back against the original buffer
+ *
+ *
+ * - If any of the size generators return 0, this means to use the maximum
+ *   possible size.
+ *
+ * - If maxOutstanding is non-zero, write chunk sizes will be chosen such that
+ *   there are never more than maxOutstanding bytes waiting to be read back.
+ */
+void testReadWrite(CoupledTransports)(
+  size_t totalSize,
+  SizeGenerator wSizeGenerator,
+  SizeGenerator rSizeGenerator,
+  SizeGenerator wChunkGenerator,
+  SizeGenerator rChunkGenerator,
+  size_t maxOutstanding
+) if (
+  isCoupledTransports!CoupledTransports
+) {
+  scope transports = new CoupledTransports;
+  assert(transports.input);
+  assert(transports.output);
+
+  auto wbuf = new ubyte[totalSize];
+  auto rbuf = new ubyte[totalSize];
+
+  // Store some data in wbuf.
+  foreach (i, ref b; wbuf) {
+    b = i & 0xff;
+  }
+
+  size_t totalWritten;
+  size_t totalRead;
+  while (totalRead < totalSize) {
+    // Determine how large a chunk of data to write.
+    auto wChunkSize = wChunkGenerator.nextSize();
+    if (wChunkSize == 0 || wChunkSize > totalSize - totalWritten) {
+      wChunkSize = totalSize - totalWritten;
+    }
+
+    // Make sure (totalWritten - totalRead) + wChunkSize is less than
+    // maxOutstanding.
+    if (maxOutstanding > 0 &&
+        wChunkSize > maxOutstanding - (totalWritten - totalRead)) {
+      wChunkSize = maxOutstanding - (totalWritten - totalRead);
+    }
+
+    // Write the chunk.
+    size_t chunkWritten = 0;
+    while (chunkWritten < wChunkSize) {
+      auto writeSize = wSizeGenerator.nextSize();
+      if (writeSize == 0 || writeSize > wChunkSize - chunkWritten) {
+        writeSize = wChunkSize - chunkWritten;
+      }
+
+      transports.output.write(wbuf[totalWritten .. totalWritten + writeSize]);
+      chunkWritten += writeSize;
+      totalWritten += writeSize;
+    }
+
+    // Flush the data, so it will be available in the read transport
+    // Don't flush if wChunkSize is 0. (This should only happen if
+    // totalWritten == totalSize already, and we're only reading now.)
+    if (wChunkSize > 0) {
+      transports.output.flush();
+    }
+
+    // Determine how large a chunk of data to read back.
+    auto rChunkSize = rChunkGenerator.nextSize();
+    if (rChunkSize == 0 || rChunkSize > totalWritten - totalRead) {
+      rChunkSize = totalWritten - totalRead;
+    }
+
+    // Read the chunk.
+    size_t chunkRead;
+    while (chunkRead < rChunkSize) {
+      auto readSize = rSizeGenerator.nextSize();
+      if (readSize == 0 || readSize > rChunkSize - chunkRead) {
+        readSize = rChunkSize - chunkRead;
+      }
+
+      size_t bytesRead;
+      try {
+        bytesRead = transports.input.read(
+          rbuf[totalRead .. totalRead + readSize]);
+      } catch (TTransportException e) {
+        throw new Exception(format(`read(pos = %s, size = %s) threw ` ~
+          `exception "%s"; written so far: %s/%s bytes`, totalRead, readSize,
+          e.msg, totalWritten, totalSize));
+      }
+
+      enforce(bytesRead > 0, format(`read(pos = %s, size = %s) returned %s; ` ~
+        `written so far: %s/%s bytes`, totalRead, readSize, bytesRead,
+        totalWritten, totalSize));
+
+      chunkRead += bytesRead;
+      totalRead += bytesRead;
+    }
+  }
+
+  // make sure the data read back is identical to the data written
+  if (rbuf != wbuf) {
+    stderr.writefln("%s vs. %s", wbuf[$ - 4 .. $], rbuf[$ - 4 .. $]);
+    stderr.writefln("rbuf: %s vs. wbuf: %s", rbuf.length, wbuf.length);
+  }
+  enforce(rbuf == wbuf);
+}
+
+void testReadPartAvailable(CoupledTransports)() if (
+  isCoupledTransports!CoupledTransports
+) {
+  scope transports = new CoupledTransports;
+  assert(transports.input);
+  assert(transports.output);
+
+  ubyte[10] writeBuf = 'a';
+  ubyte[10] readBuf;
+
+  // Attemping to read 10 bytes when only 9 are available should return 9
+  // immediately.
+  transports.output.write(writeBuf[0 .. 9]);
+  transports.output.flush();
+
+  auto t = Trigger(dur!"seconds"(3), transports.output, 1);
+  auto bytesRead = transports.input.read(readBuf);
+  enforce(t.fired == 0);
+  enforce(bytesRead == 9);
+}
+
+void testReadPartialMidframe(CoupledTransports)() if (
+  isCoupledTransports!CoupledTransports
+) {
+  scope transports = new CoupledTransports;
+  assert(transports.input);
+  assert(transports.output);
+
+  ubyte[13] writeBuf = 'a';
+  ubyte[14] readBuf;
+
+  // Attempt to read 10 bytes, when only 9 are available, but after we have
+  // already read part of the data that is available.  This exercises a
+  // different code path for several of the transports.
+  //
+  // For transports that add their own framing (e.g., TFramedTransport and
+  // TFileTransport), the two flush calls break up the data in to a 10 byte
+  // frame and a 3 byte frame.  The first read then puts us partway through the
+  // first frame, and then we attempt to read past the end of that frame, and
+  // through the next frame, too.
+  //
+  // For buffered transports that perform read-ahead (e.g.,
+  // TBufferedTransport), the read-ahead will most likely see all 13 bytes
+  // written on the first read.  The next read will then attempt to read past
+  // the end of the read-ahead buffer.
+  //
+  // Flush 10 bytes, then 3 bytes.  This creates 2 separate frames for
+  // transports that track framing internally.
+  transports.output.write(writeBuf[0 .. 10]);
+  transports.output.flush();
+  transports.output.write(writeBuf[10 .. 13]);
+  transports.output.flush();
+
+  // Now read 4 bytes, so that we are partway through the written data.
+  auto bytesRead = transports.input.read(readBuf[0 .. 4]);
+  enforce(bytesRead == 4);
+
+  // Now attempt to read 10 bytes.  Only 9 more are available.
+  //
+  // We should be able to get all 9 bytes, but it might take multiple read
+  // calls, since it is valid for read() to return fewer bytes than requested.
+  // (Most transports do immediately return 9 bytes, but the framing transports
+  // tend to only return to the end of the current frame, which is 6 bytes in
+  // this case.)
+  size_t totalRead = 0;
+  while (totalRead < 9) {
+    auto t = Trigger(dur!"seconds"(3), transports.output, 1);
+    bytesRead = transports.input.read(readBuf[4 + totalRead .. 14]);
+    enforce(t.fired == 0);
+    enforce(bytesRead > 0);
+    totalRead += bytesRead;
+    enforce(totalRead <= 9);
+  }
+
+  enforce(totalRead == 9);
+}
+
+void testBorrowPartAvailable(CoupledTransports)() if (
+  isCoupledTransports!CoupledTransports
+) {
+  scope transports = new CoupledTransports;
+  assert(transports.input);
+  assert(transports.output);
+
+  ubyte[9] writeBuf = 'a';
+  ubyte[10] readBuf;
+
+  // Attemping to borrow 10 bytes when only 9 are available should return NULL
+  // immediately.
+  transports.output.write(writeBuf);
+  transports.output.flush();
+
+  auto t = Trigger(dur!"seconds"(3), transports.output, 1);
+  auto borrowLen = readBuf.length;
+  auto borrowedBuf = transports.input.borrow(readBuf.ptr, borrowLen);
+  enforce(t.fired == 0);
+  enforce(borrowedBuf is null);
+}
+
+void testReadNoneAvailable(CoupledTransports)() if (
+  isCoupledTransports!CoupledTransports
+) {
+  scope transports = new CoupledTransports;
+  assert(transports.input);
+  assert(transports.output);
+
+  // Attempting to read when no data is available should either block until
+  // some data is available, or fail immediately.  (e.g., TSocket blocks,
+  // TMemoryBuffer just fails.)
+  //
+  // If the transport blocks, it should succeed once some data is available,
+  // even if less than the amount requested becomes available.
+  ubyte[10] readBuf;
+
+  auto t = Trigger(dur!"seconds"(1), transports.output, 2);
+  t.add(dur!"seconds"(1), transports.output, 8);
+
+  auto bytesRead = transports.input.read(readBuf);
+  if (bytesRead == 0) {
+    enforce(t.fired == 0);
+  } else {
+    enforce(t.fired == 1);
+    enforce(bytesRead == 2);
+  }
+}
+
+void testBorrowNoneAvailable(CoupledTransports)() if (
+  isCoupledTransports!CoupledTransports
+) {
+  scope transports = new CoupledTransports;
+  assert(transports.input);
+  assert(transports.output);
+
+  ubyte[16] writeBuf = 'a';
+
+  // Attempting to borrow when no data is available should fail immediately
+  auto t = Trigger(dur!"seconds"(1), transports.output, 10);
+
+  auto borrowLen = 10;
+  auto borrowedBuf = transports.input.borrow(null, borrowLen);
+  enforce(borrowedBuf is null);
+  enforce(t.fired == 0);
+}
+
+
+void doRwTest(CoupledTransports)(
+  size_t totalSize,
+  SizeGenerator wSizeGen,
+  SizeGenerator rSizeGen,
+  SizeGenerator wChunkSizeGen = new ConstantSizeGenerator(0),
+  SizeGenerator rChunkSizeGen = new ConstantSizeGenerator(0),
+  size_t maxOutstanding = 0
+) if (
+  isCoupledTransports!CoupledTransports
+) {
+  totalSize = cast(size_t)(totalSize * g_sizeMultiplier);
+
+  scope(failure) {
+    writefln("Test failed for %s: testReadWrite(%s, %s, %s, %s, %s, %s)",
+      CoupledTransports.stringof, totalSize, wSizeGen, rSizeGen,
+      wChunkSizeGen, rChunkSizeGen, maxOutstanding);
+  }
+
+  testReadWrite!CoupledTransports(totalSize, wSizeGen, rSizeGen,
+    wChunkSizeGen, rChunkSizeGen, maxOutstanding);
+}
+
+void doBlockingTest(CoupledTransports)() if (
+  isCoupledTransports!CoupledTransports
+) {
+  void writeFailure(string name) {
+    writefln("Test failed for %s: %s()", CoupledTransports.stringof, name);
+  }
+
+  {
+    scope(failure) writeFailure("testReadPartAvailable");
+    testReadPartAvailable!CoupledTransports();
+  }
+
+  {
+    scope(failure) writeFailure("testReadPartialMidframe");
+    testReadPartialMidframe!CoupledTransports();
+  }
+
+  {
+    scope(failure) writeFailure("testReadNoneAvaliable");
+    testReadNoneAvailable!CoupledTransports();
+  }
+
+  {
+    scope(failure) writeFailure("testBorrowPartAvailable");
+    testBorrowPartAvailable!CoupledTransports();
+  }
+
+  {
+    scope(failure) writeFailure("testBorrowNoneAvailable");
+    testBorrowNoneAvailable!CoupledTransports();
+  }
+}
+
+SizeGenerator getGenerator(T)(T t) {
+  static if (is(T : SizeGenerator)) {
+    return t;
+  } else {
+    return new ConstantSizeGenerator(t);
+  }
+}
+
+template WrappedTransports(T) if (isCoupledTransports!T) {
+  alias TypeTuple!(
+    T,
+    CoupledBufferedTransports!T,
+    CoupledFramedTransports!T,
+    CoupledZlibTransports!T
+  ) WrappedTransports;
+}
+
+void testRw(C, R, S)(
+  size_t totalSize,
+  R wSize,
+  S rSize
+) if (
+  isCoupledTransports!C && is(typeof(getGenerator(wSize))) &&
+  is(typeof(getGenerator(rSize)))
+) {
+  testRw!C(totalSize, wSize, rSize, 0, 0, 0);
+}
+
+void testRw(C, R, S, T, U)(
+  size_t totalSize,
+  R wSize,
+  S rSize,
+  T wChunkSize,
+  U rChunkSize,
+  size_t maxOutstanding = 0
+) if (
+  isCoupledTransports!C && is(typeof(getGenerator(wSize))) &&
+  is(typeof(getGenerator(rSize))) && is(typeof(getGenerator(wChunkSize))) &&
+  is(typeof(getGenerator(rChunkSize)))
+) {
+  foreach (T; WrappedTransports!C) {
+    doRwTest!T(
+      totalSize,
+      getGenerator(wSize),
+      getGenerator(rSize),
+      getGenerator(wChunkSize),
+      getGenerator(rChunkSize),
+      maxOutstanding
+    );
+  }
+}
+
+void testBlocking(C)() if (isCoupledTransports!C) {
+  foreach (T; WrappedTransports!C) {
+    doBlockingTest!T();
+  }
+}
+
+// A quick hack, for the sake of brevity…
+float g_sizeMultiplier = 1;
+
+version (Posix) {
+  immutable defaultTempDir = "/tmp";
+} else version (Windows) {
+  import core.sys.windows.windows;
+  extern(Windows) DWORD GetTempPathA(DWORD nBufferLength, LPTSTR lpBuffer);
+
+  string defaultTempDir() @property {
+    char[MAX_PATH + 1] dir;
+    enforce(GetTempPathA(dir.length, dir.ptr));
+    return to!string(dir.ptr)[0 .. $ - 1];
+  }
+} else static assert(false);
+
+void main(string[] args) {
+  int seed = unpredictableSeed();
+  string tmpDir = defaultTempDir;
+
+  getopt(args, "seed", &seed, "size-multiplier", &g_sizeMultiplier,
+    "tmp-dir", &tmpDir);
+  enforce(g_sizeMultiplier >= 0, "Size multiplier must not be negative.");
+
+  writefln("Using seed: %s", seed);
+  rndGen().seed(seed);
+  CoupledFileTransports.tmpDir = tmpDir;
+
+  auto rand4k = new RandomSizeGenerator(1, 4096);
+
+  /*
+   * We do the basically the same set of tests for each transport type,
+   * although we tweak the parameters in some places.
+   */
+
+  // TMemoryBuffer tests
+  testRw!CoupledMemoryBuffers(1024 * 1024, 0, 0);
+  testRw!CoupledMemoryBuffers(1024 * 256, rand4k, rand4k);
+  testRw!CoupledMemoryBuffers(1024 * 256, 167, 163);
+  testRw!CoupledMemoryBuffers(1024 * 16, 1, 1);
+
+  testRw!CoupledMemoryBuffers(1024 * 256, 0, 0, rand4k, rand4k);
+  testRw!CoupledMemoryBuffers(1024 * 256, rand4k, rand4k, rand4k, rand4k);
+  testRw!CoupledMemoryBuffers(1024 * 256, 167, 163, rand4k, rand4k);
+  testRw!CoupledMemoryBuffers(1024 * 16, 1, 1, rand4k, rand4k);
+
+  testBlocking!CoupledMemoryBuffers();
+
+  // TSocket tests
+  enum socketMaxOutstanding = 4096;
+  testRw!CoupledSocketTransports(1024 * 1024, 0, 0,
+          0, 0, socketMaxOutstanding);
+  testRw!CoupledSocketTransports(1024 * 256, rand4k, rand4k,
+          0, 0, socketMaxOutstanding);
+  testRw!CoupledSocketTransports(1024 * 256, 167, 163,
+          0, 0, socketMaxOutstanding);
+  // Doh.  Apparently writing to a socket has some additional overhead for
+  // each send() call.  If we have more than ~400 outstanding 1-byte write
+  // requests, additional send() calls start blocking.
+  testRw!CoupledSocketTransports(1024 * 16, 1, 1,
+          0, 0, 400);
+  testRw!CoupledSocketTransports(1024 * 256, 0, 0,
+          rand4k, rand4k, socketMaxOutstanding);
+  testRw!CoupledSocketTransports(1024 * 256, rand4k, rand4k,
+          rand4k, rand4k, socketMaxOutstanding);
+  testRw!CoupledSocketTransports(1024 * 256, 167, 163,
+          rand4k, rand4k, socketMaxOutstanding);
+  testRw!CoupledSocketTransports(1024 * 16, 1, 1,
+          rand4k, rand4k, 400);
+
+  testBlocking!CoupledSocketTransports();
+
+  // File transport tests.
+
+  // Cannot write more than the frame size at once.
+  enum maxWriteAtOnce = 1024 * 1024 * 16 - 4;
+
+  testRw!CoupledFileTransports(1024 * 1024, maxWriteAtOnce, 0);
+  testRw!CoupledFileTransports(1024 * 256, rand4k, rand4k);
+  testRw!CoupledFileTransports(1024 * 256, 167, 163);
+  testRw!CoupledFileTransports(1024 * 16, 1, 1);
+
+  testRw!CoupledFileTransports(1024 * 256, 0, 0, rand4k, rand4k);
+  testRw!CoupledFileTransports(1024 * 256, rand4k, rand4k, rand4k, rand4k);
+  testRw!CoupledFileTransports(1024 * 256, 167, 163, rand4k, rand4k);
+  testRw!CoupledFileTransports(1024 * 16, 1, 1, rand4k, rand4k);
+
+  testBlocking!CoupledFileTransports();
+}
+
+
+/*
+ * Timer handling code for use in tests that check the transport blocking
+ * semantics.
+ *
+ * The implementation has been hacked together in a hurry and wastes a lot of
+ * threads, but speed should not be the concern here.
+ */
+
+struct Trigger {
+  this(Duration timeout, TTransport transport, size_t writeLength) {
+    mutex_ = new Mutex;
+    cancelCondition_ = new Condition(mutex_);
+    info_ = new Info(timeout, transport, writeLength);
+    startThread();
+  }
+
+  ~this() {
+    synchronized (mutex_) {
+      info_ = null;
+      cancelCondition_.notifyAll();
+    }
+    if (thread_) thread_.join();
+  }
+
+  @disable this(this) { assert(0); }
+
+  void add(Duration timeout, TTransport transport, size_t writeLength) {
+    synchronized (mutex_) {
+      auto info = new Info(timeout, transport, writeLength);
+      if (info_) {
+        auto prev = info_;
+        while (prev.next) prev = prev.next;
+        prev.next = info;
+      } else {
+        info_ = info;
+        startThread();
+      }
+    }
+  }
+
+  @property short fired() {
+    return atomicLoad(fired_);
+  }
+
+private:
+  void timerThread() {
+    // KLUDGE: Make sure the std.concurrency mbox is initialized on the timer
+    // thread to be able to unblock the file transport.
+    import std.concurrency;
+    thisTid;
+
+    synchronized (mutex_) {
+      while (info_) {
+        auto cancelled = cancelCondition_.wait(info_.timeout);
+        if (cancelled) {
+          info_ = null;
+          break;
+        }
+
+        atomicOp!"+="(fired_, 1);
+
+        // Write some data to the transport to unblock it.
+        auto buf = new ubyte[info_.writeLength];
+        buf[] = 'b';
+        info_.transport.write(buf);
+        info_.transport.flush();
+
+        info_ = info_.next;
+      }
+    }
+
+    thread_ = null;
+  }
+
+  void startThread() {
+    thread_ = new Thread(&timerThread);
+    thread_.start();
+  }
+
+  struct Info {
+    this(Duration timeout, TTransport transport, size_t writeLength) {
+      this.timeout = timeout;
+      this.transport = transport;
+      this.writeLength = writeLength;
+    }
+
+    Duration timeout;
+    TTransport transport;
+    size_t writeLength;
+    Info* next;
+  }
+
+  Info* info_;
+  Thread thread_;
+  shared short fired_;
+
+  import core.sync.mutex;
+  Mutex mutex_;
+  import core.sync.condition;
+  Condition cancelCondition_;
+}
