diff --git a/ext/executor.cpp b/ext/executor.cpp
--- a/ext/executor.cpp
+++ b/ext/executor.cpp
@@ -146,7 +146,7 @@
 	return driver->sendStatusUpdate(*status);
 }
 
-int sendExecutorDriverFrameworkMessage(ExecutorDriver* driver, int stringLength, char* stringData)
+int sendExecutorDriverFrameworkMessage(ExecutorDriver* driver, char* stringData, int stringLength)
 {
 	std::string message(stringData, stringLength);
 	return driver->sendFrameworkMessage(message);
diff --git a/ext/executor.h b/ext/executor.h
new file mode 100644
--- /dev/null
+++ b/ext/executor.h
@@ -0,0 +1,46 @@
+#include <mesos/executor.hpp>
+#include "types.h"
+
+typedef void OnExecutorRegisteredCallback(mesos::ExecutorDriver*,
+		const mesos::ExecutorInfo*,
+		const mesos::FrameworkInfo*,
+		const mesos::SlaveInfo*);
+
+typedef void OnExecutorReRegisteredCallback(mesos::ExecutorDriver*,
+		const mesos::SlaveInfo*);
+typedef void OnExecutorDisconnectedCallback(mesos::ExecutorDriver*);
+typedef void OnExecutorLaunchTaskCallback(mesos::ExecutorDriver*,
+		const mesos::TaskInfo*);
+typedef void OnExecutorTaskKilledCallback(mesos::ExecutorDriver*,
+		const mesos::TaskID*);
+typedef void OnExecutorFrameworkMessageCallback(mesos::ExecutorDriver*, int, const char*);
+typedef void OnExecutorShutdownCallback(mesos::ExecutorDriver*);
+typedef void OnExecutorErrorCallback(mesos::ExecutorDriver*, int, const char*);
+
+typedef mesos::Executor *ExecutorPtr;
+typedef mesos::ExecutorDriver *ExecutorDriverPtr;
+extern "C" {
+
+extern ExecutorPtr createExecutor(
+	OnExecutorRegisteredCallback*,
+	OnExecutorReRegisteredCallback*,
+	OnExecutorDisconnectedCallback*,
+	OnExecutorLaunchTaskCallback*,
+	OnExecutorTaskKilledCallback*,
+	OnExecutorFrameworkMessageCallback*,
+	OnExecutorShutdownCallback*,
+	OnExecutorErrorCallback*
+);
+
+extern void destroyExecutor(ExecutorPtr);
+
+extern ExecutorDriverPtr createExecutorDriver(ExecutorPtr);
+extern void destroyExecutorDriver(ExecutorDriverPtr);
+extern int startExecutorDriver(ExecutorDriverPtr);
+extern int stopExecutorDriver(ExecutorDriverPtr);
+extern int abortExecutorDriver(ExecutorDriverPtr);
+extern int joinExecutorDriver(ExecutorDriverPtr);
+extern int runExecutorDriver(ExecutorDriverPtr);
+extern int sendExecutorDriverStatusUpdate(ExecutorDriverPtr, TaskStatusPtr);
+extern int sendExecutorDriverFrameworkMessage(ExecutorDriverPtr, char*, int);
+}
diff --git a/ext/scheduler.h b/ext/scheduler.h
new file mode 100644
--- /dev/null
+++ b/ext/scheduler.h
@@ -0,0 +1,110 @@
+#include <mesos/scheduler.hpp>
+
+typedef mesos::Scheduler *SchedulerPtr;
+typedef mesos::SchedulerDriver *SchedulerDriverPtr;
+typedef const mesos::FrameworkID *FrameworkIDPtr;
+typedef const mesos::MasterInfo *MasterInfoPtr;
+typedef const mesos::Offer *OfferPtr;
+typedef const mesos::OfferID *OfferIDPtr;
+typedef const mesos::TaskStatus *TaskStatusPtr;
+typedef const mesos::SlaveID *SlaveIDPtr;
+typedef const mesos::ExecutorID *ExecutorIDPtr;
+typedef mesos::FrameworkInfo *FrameworkInfoPtr;
+typedef mesos::Credential *CredentialPtr;
+typedef mesos::Filters *FiltersPtr;
+typedef mesos::Request *RequestPtr;
+typedef mesos::TaskInfo *TaskInfoPtr;
+typedef mesos::TaskID *TaskIDPtr;
+
+typedef void OnSchedulerRegisteredCallback(SchedulerDriverPtr,
+		const FrameworkIDPtr,
+		const MasterInfoPtr);
+
+typedef void OnSchedulerReRegisteredCallback(SchedulerDriverPtr,
+		const MasterInfoPtr);
+
+typedef void OnSchedulerDisconnectedCallback(SchedulerDriverPtr);
+
+typedef void OnSchedulerResourceOffers(SchedulerDriverPtr,
+		const OfferPtr*,
+		int);
+
+typedef void OnOfferRescinded(SchedulerDriverPtr,
+		const OfferIDPtr);
+
+typedef void OnStatusUpdate(SchedulerDriverPtr,
+		const TaskStatusPtr);
+
+typedef void OnFrameworkMessage(SchedulerDriverPtr,
+		const ExecutorIDPtr,
+		const SlaveIDPtr,
+		const char*,
+		int);
+
+typedef void OnSlaveLost(SchedulerDriverPtr,
+		const SlaveIDPtr);
+
+typedef void OnExecutorLost(SchedulerDriverPtr,
+		const ExecutorIDPtr,
+		const SlaveIDPtr,
+		int status);
+
+typedef void OnSchedulerError(SchedulerDriverPtr,
+		const char*,
+		int);
+
+extern "C" {
+	extern SchedulerPtr createScheduler(OnSchedulerRegisteredCallback*,
+			OnSchedulerReRegisteredCallback*,
+			OnSchedulerDisconnectedCallback*,
+			OnSchedulerResourceOffers*,
+			OnOfferRescinded*,
+			OnStatusUpdate*,
+			OnFrameworkMessage*,
+			OnSlaveLost*,
+			OnExecutorLost*,
+			OnSchedulerError*);
+
+	extern void destroyScheduler(SchedulerPtr);
+	extern void exerciseMethods(SchedulerPtr);
+
+	extern SchedulerDriverPtr createSchedulerDriver(
+			SchedulerPtr,
+			FrameworkInfoPtr,
+			char*,
+			int);
+
+	extern SchedulerDriverPtr createSchedulerDriverWithCredentials(
+			SchedulerPtr,
+			FrameworkInfoPtr,
+			char*,
+			int,
+			CredentialPtr);
+
+	extern void destroySchedulerDriver(SchedulerDriverPtr);	
+	extern int startSchedulerDriver(SchedulerDriverPtr);
+	extern int stopSchedulerDriver(SchedulerDriverPtr, bool failover);
+	extern int abortSchedulerDriver(SchedulerDriverPtr);
+	extern int joinSchedulerDriver(SchedulerDriverPtr);
+	extern int runSchedulerDriver(SchedulerDriverPtr);
+	extern int requestResources(SchedulerDriverPtr, RequestPtr*, int);
+	extern int launchTasks(SchedulerDriverPtr,
+			OfferIDPtr*,
+			int,
+			TaskInfoPtr*,
+			int,
+			FiltersPtr);
+	extern int killTask(SchedulerDriverPtr, TaskIDPtr);
+	extern int declineOffer(SchedulerDriverPtr,
+			OfferIDPtr,
+			FiltersPtr);
+	extern int reviveOffers(SchedulerDriverPtr);
+	extern int schedulerDriverSendFrameworkMessage(SchedulerDriverPtr,
+			ExecutorIDPtr,
+			SlaveIDPtr,
+			char*,
+			int);
+	extern int reconcileTasks(SchedulerDriverPtr,
+			TaskStatusPtr*,
+			int);
+}
diff --git a/hs-mesos.cabal b/hs-mesos.cabal
--- a/hs-mesos.cabal
+++ b/hs-mesos.cabal
@@ -1,5 +1,5 @@
 name:                hs-mesos
-version:             0.20.0.0
+version:             0.20.0.2
 
 description:         Bindings to the Apache Mesos platform.
                      .
@@ -63,6 +63,8 @@
   hs-source-dirs:      src
   default-language:    Haskell2010
   include-dirs:        ext, /usr/include, /usr/local/include/mesos
+  install-includes:    ext/executor.h,
+                       ext/scheduler.h
   c-sources:           ext/executor.cpp,
                        ext/scheduler.cpp,
                        ext/types/attribute.cpp,
@@ -102,13 +104,13 @@
   extra-libraries:     mesos stdc++
   extra-lib-dirs:      /usr/local/lib
   cc-options:          -fPIC -std=c++11
-  ghc-options:         -fPIC
+  ghc-options:         -fPIC -funbox-strict-fields
 
 test-suite test
   type:                exitcode-stdio-1.0
   main-is:             Main.hs
   hs-source-dirs:      test
-  build-depends:       base, hs-mesos, QuickCheck, bytestring, lens, managed
+  build-depends:       base, hs-mesos, tasty, tasty-quickcheck, tasty-hunit, QuickCheck, bytestring, lens, managed
   default-language:    Haskell2010
 
 executable test-executor
diff --git a/src/System/Mesos/Types.hs b/src/System/Mesos/Types.hs
--- a/src/System/Mesos/Types.hs
+++ b/src/System/Mesos/Types.hs
@@ -18,8 +18,10 @@
   filters,
   -- ** Launching Tasks
   TaskInfo(..),
+  taskInfo,
   TaskExecutionInfo(..),
   CommandInfo(..),
+  commandInfo,
   CommandURI(..),
   commandURI,
   CommandValue (..),
@@ -222,6 +224,9 @@
   }
   deriving (Show, Eq)
 
+commandInfo :: CommandValue -> CommandInfo
+commandInfo v = CommandInfo [] Nothing v Nothing
+
 data CommandURI = CommandURI
   { commandURIValue      :: !ByteString
   , commandURIExecutable :: !(Maybe Bool)
@@ -506,6 +511,9 @@
   , taskHealthCheck    :: !(Maybe HealthCheck)
   }
   deriving (Show, Eq)
+
+taskInfo :: ByteString -> TaskID -> SlaveID -> [Resource] -> TaskExecutionInfo -> TaskInfo
+taskInfo n t s rs i = TaskInfo n t s rs i Nothing Nothing Nothing
 
 -- | Describes the current status of a task.
 data TaskStatus = TaskStatus
diff --git a/test/Main.hs b/test/Main.hs
--- a/test/Main.hs
+++ b/test/Main.hs
@@ -1,7 +1,7 @@
 {-# LANGUAGE GeneralizedNewtypeDeriving #-}
 {-# LANGUAGE OverloadedStrings          #-}
 {-# LANGUAGE StandaloneDeriving         #-}
-{-# OPTIONS_GHC -fno-warn-orphans #-}
+{-# OPTIONS_GHC -fno-warn-orphans       #-}
 module Main where
 import           Control.Applicative
 import           Control.Monad.Managed
@@ -15,6 +15,9 @@
 import           System.Mesos.Raw.Parameters
 import           System.Mesos.Scheduler
 import           System.Mesos.Types
+import           Test.Tasty
+import qualified Test.Tasty.HUnit             as Unit
+import           Test.Tasty.QuickCheck
 import           Test.QuickCheck
 import           Test.QuickCheck.Arbitrary
 import           Test.QuickCheck.Monadic
@@ -29,7 +32,7 @@
   return x'
 
 main :: IO ()
-main = testIDs
+main = defaultMain $ testGroup "Mesos" [testIDs, executorTests, schedulerTests]
 
 instance Arbitrary CUInt where
   arbitrary = CUInt <$> arbitrary
@@ -301,64 +304,44 @@
         print res
       assert False
 
-qcIM :: (Show a, Eq a, CPPValue a) => Gen a -> IO ()
-qcIM = quickCheck . prop_idempotentMarshalling
+qcIM :: (Show a, Eq a, CPPValue a) => String -> Gen a -> TestTree
+qcIM n = testProperty n . prop_idempotentMarshalling
 
-testIDs = do
-  putStrLn "Testing ExecutorInfo"
-  qcIM (arbitrary :: Gen ExecutorInfo)
-  putStrLn "Testing TaskInfo"
-  qcIM (arbitrary :: Gen TaskInfo)
-  putStrLn "Testing Volume"
-  qcIM (arbitrary :: Gen Volume)
-  putStrLn "Testing HealthCheck"
-  qcIM (arbitrary :: Gen HealthCheck)
-  putStrLn "Testing ContainerInfo"
-  qcIM (arbitrary :: Gen ContainerInfo)
-  putStrLn "Testing Value"
-  qcIM (arbitrary :: Gen Value)
-  putStrLn "Testing FrameworkID"
-  qcIM (arbitrary :: Gen FrameworkID)
-  putStrLn "Testing OfferID"
-  qcIM (arbitrary :: Gen OfferID)
-  putStrLn "Testing SlaveID"
-  qcIM (arbitrary :: Gen SlaveID)
-  putStrLn "Testing TaskID"
-  qcIM (arbitrary :: Gen TaskID)
-  putStrLn "Testing ExecutorID"
-  qcIM (arbitrary :: Gen ExecutorID)
-  putStrLn "Testing ContainerID"
-  qcIM (arbitrary :: Gen ContainerID)
-  putStrLn "Testing Filters"
-  qcIM (arbitrary :: Gen Filters)
-  putStrLn "Testing Environment"
-  qcIM (arbitrary :: Gen Environment)
-  putStrLn "Testing FrameworkInfo"
-  qcIM (arbitrary :: Gen FrameworkInfo)
-  putStrLn "Testing CommandURI"
-  qcIM (arbitrary :: Gen CommandURI)
-  putStrLn "Testing Credential"
-  qcIM (arbitrary :: Gen Credential)
-  putStrLn "Testing TaskStatus"
-  qcIM (arbitrary :: Gen TaskStatus)
-  putStrLn "Testing ResourceUsage"
-  qcIM (arbitrary :: Gen ResourceUsage)
-  putStrLn "Testing ResourceStatistics"
-  qcIM (arbitrary :: Gen ResourceStatistics)
-  putStrLn "Testing Parameters"
-  qcIM (arbitrary :: Gen Parameters)
-  putStrLn "Testing Attribute"
-  qcIM (arbitrary :: Gen Attribute)
-  putStrLn "Testing Resource"
-  qcIM (arbitrary :: Gen Resource)
-  putStrLn "Testing CommandInfo"
-  qcIM (arbitrary :: Gen CommandInfo)
-  putStrLn "Testing MasterInfo"
-  qcIM (arbitrary :: Gen MasterInfo)
-  putStrLn "Testing Request"
-  qcIM (arbitrary :: Gen Request)
-  putStrLn "Testing Offer"
-  qcIM (arbitrary :: Gen Offer)
-  putStrLn "Testing SlaveInfo"
-  qcIM (arbitrary :: Gen SlaveInfo)
+testIDs = testGroup "Marshalling"
+  [ qcIM "ExecutorInfo" (arbitrary :: Gen ExecutorInfo)
+  , qcIM "TaskInfo" (arbitrary :: Gen TaskInfo)
+  , qcIM "Volume" (arbitrary :: Gen Volume)
+  , qcIM "HealthCheck" (arbitrary :: Gen HealthCheck)
+  , qcIM "ContainerInfo" (arbitrary :: Gen ContainerInfo)
+  , qcIM "Value" (arbitrary :: Gen Value)
+  , qcIM "FrameworkInfo" (arbitrary :: Gen FrameworkID)
+  , qcIM "OfferID" (arbitrary :: Gen OfferID)
+  , qcIM "SlaveID" (arbitrary :: Gen SlaveID)
+  , qcIM "TaskID" (arbitrary :: Gen TaskID)
+  , qcIM "ExecutorID" (arbitrary :: Gen ExecutorID)
+  , qcIM "ContainerID" (arbitrary :: Gen ContainerID)
+  , qcIM "Filters" (arbitrary :: Gen Filters)
+  , qcIM "Environment" (arbitrary :: Gen Environment)
+  , qcIM "FrameworkInfo" (arbitrary :: Gen FrameworkInfo)
+  , qcIM "CommandURI" (arbitrary :: Gen CommandURI)
+  , qcIM "Credential" (arbitrary :: Gen Credential)
+  , qcIM "TaskStatus" (arbitrary :: Gen TaskStatus)
+  , qcIM "ResourceUsage" (arbitrary :: Gen ResourceUsage)
+  , qcIM "ResourceStatistics" (arbitrary :: Gen ResourceStatistics)
+  , qcIM "Parameters" (arbitrary :: Gen Parameters)
+  , qcIM "Attribute" (arbitrary :: Gen Attribute)
+  , qcIM "Resource" (arbitrary :: Gen Resource)
+  , qcIM "CommandInfo" (arbitrary :: Gen CommandInfo)
+  , qcIM "MasterInfo" (arbitrary :: Gen MasterInfo)
+  , qcIM "Request" (arbitrary :: Gen Request)
+  , qcIM "Offer" (arbitrary :: Gen Offer)
+  , qcIM "SlaveInfo" (arbitrary :: Gen SlaveInfo)
+  ]
 
+executorTests = testGroup "Executor"
+  [
+  ]
+
+schedulerTests = testGroup "Scheduler"
+  [
+  ]
