+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.
+ -- Can be overriden with @LSP_TEST_LOG_STDERR@.
+ , logMessages :: Bool
+ -- ^ Trace the messages sent and received to stdout, defaults to False.
+ -- Can be overriden with the environment variable @LSP_TEST_LOG_MESSAGES@.
+ , 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.
+ , ignoreLogNotifications :: Bool
+ -- ^ Whether or not to ignore 'Language.Haskell.LSP.Types.ShowMessageNotification' and
+ -- 'Language.Haskell.LSP.Types.LogMessageNotification', defaults to False.
+ --
+ -- @since 0.9.0.0
+ }
+
+-- | The configuration used in 'Language.Haskell.LSP.Test.runSession'.
+defaultConfig :: SessionConfig
+defaultConfig = SessionConfig 60 False False True Nothing False
+
+instance Default SessionConfig where
+ def = defaultConfig
+
+data SessionMessage = ServerMessage FromServerMessage
+ | TimeoutMessage Int
+ deriving Show