diff --git a/lib/Makefile.am b/lib/Makefile.am
index cd62d19..f95428f 100644
--- a/lib/Makefile.am
+++ b/lib/Makefile.am
@@ -62,6 +62,10 @@
 SUBDIRS += php
 endif
 
+if WITH_D
+SUBDIRS += d
+endif
+
 # All of the libs that don't use Automake need to go in here
 # so they will end up in our release tarballs.
 EXTRA_DIST = \
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_;
+}
