+import System.Process (ProcessHandle())
+import System.Timeout
+
+-- | A session representing one instance of launching and connecting to a server.
+--
+-- You can send and receive messages to the server within 'Session' via
+-- 'Language.Haskell.LSP.Test.message',
+-- 'Language.Haskell.LSP.Test.sendRequest' and
+-- 'Language.Haskell.LSP.Test.sendNotification'.
+
+newtype Session a = Session (ConduitParser FromServerMessage (StateT SessionState (ReaderT SessionContext IO)) a)
+ deriving (Functor, Applicative, Monad, MonadIO, Alternative)
+
+#if __GLASGOW_HASKELL__ >= 806
+instance MonadFail Session where
+ fail s = do
+ lastMsg <- fromJust . lastReceivedMessage <$> get
+ liftIO $ throw (UnexpectedMessage s lastMsg)
+#endif
+
+-- | Stuff you can configure for a 'Session'.
+data SessionConfig = SessionConfig
+ { messageTimeout :: Int -- ^ Maximum time to wait for a message in seconds, defaults to 60.
+ , logStdErr :: Bool -- ^ Redirect the server's stderr to this stdout, defaults to False.
+ , logMessages :: Bool -- ^ Trace the messages sent and received to stdout, defaults to False.
+ , logColor :: Bool -- ^ Add ANSI color to the logged messages, defaults to True.
+ , lspConfig :: Maybe Value -- ^ The initial LSP config as JSON value, defaults to Nothing.
+ }
+
+-- | The configuration used in 'Language.Haskell.LSP.Test.runSession'.
+defaultConfig :: SessionConfig
+defaultConfig = SessionConfig 60 False False True Nothing
+
+instance Default SessionConfig where
+ def = defaultConfig
+
+data SessionMessage = ServerMessage FromServerMessage
+ | TimeoutMessage Int
+ deriving Show