+isNotification :: B.ByteString -> Bool
+isNotification msg = isJust (decode msg :: Maybe (LSP.NotificationMessage Value Value))
+
+whenResponse :: B.ByteString -> (LSP.ResponseMessage Value -> IO ()) -> IO ()
+whenResponse msg f =
+ case decode msg :: Maybe (LSP.ResponseMessage Value) of
+ Just msg' -> when (isJust (msg' ^. LSP.result)) (f msg')
+ _ -> return ()
+
+whenRequest :: B.ByteString -> (LSP.RequestMessage Value Value Value -> IO ()) -> IO ()
+whenRequest msg = forM_ (decode msg :: (Maybe (LSP.RequestMessage Value Value Value)))
+
+-- TODO: QuickCheck tests?
+-- | Checks wether or not the message appears in the right order
+-- @ N1 N2 N3 REQ1 N4 N5 REQ2 RES1 @
+-- given N2, notification order doesn't matter.
+-- @ N1 N3 REQ1 N4 N5 REQ2 RES1 @
+-- given REQ1
+-- @ N1 N3 N4 N5 REQ2 RES1 @
+-- given RES1
+-- @ N1 N3 N4 N5 XXXX RES1 @ False!
+-- Order of requests and responses matter
+inRightOrder :: B.ByteString -> [B.ByteString] -> Bool
+inRightOrder _ [] = error "why is this empty"
+inRightOrder received msgs = received `elem` valid
+ where valid = takeWhile canSkip msgs ++ firstNonSkip
+ -- we don't care about the order of notifications
+ canSkip = isNotification
+ nonSkip = dropWhile canSkip msgs
+ firstNonSkip
+ | null nonSkip = []
+ | otherwise = [head nonSkip]
+
+getAllMessages :: Handle -> IO [B.ByteString]
+getAllMessages h = do
+ done <- hIsEOF h
+ if done
+ then return []
+ else do
+ msg <- getNextMessage h
+ (msg:) <$> getAllMessages h
+