diff --git a/ChangeLog.md b/ChangeLog.md
--- a/ChangeLog.md
+++ b/ChangeLog.md
@@ -1,5 +1,10 @@
 # Revision history for haskell-lsp-types
 
+## 0.17.0.0 -- 2019-10-18
+
+* Update progress reporting to match the LSP 3.15 specification (@cocreature)
+* Ensure ResponseMessage has either a result or an error (@cocreature)
+
 ## 0.16.0.0 -- 2019-09-07
 
 * Add support for CodeActionOptions (@thomasjm)
diff --git a/haskell-lsp-types.cabal b/haskell-lsp-types.cabal
--- a/haskell-lsp-types.cabal
+++ b/haskell-lsp-types.cabal
@@ -1,5 +1,5 @@
 name:                haskell-lsp-types
-version:             0.16.0.0
+version:             0.17.0.0
 synopsis:            Haskell library for the Microsoft Language Server Protocol, data types
 
 description:         An implementation of the types to allow language implementors to
@@ -36,6 +36,7 @@
                      , Language.Haskell.LSP.Types.Location
                      , Language.Haskell.LSP.Types.MarkupContent
                      , Language.Haskell.LSP.Types.Message
+                     , Language.Haskell.LSP.Types.Progress
                      , Language.Haskell.LSP.Types.Symbol
                      , Language.Haskell.LSP.Types.TextDocument
                      , Language.Haskell.LSP.Types.Uri
diff --git a/src/Language/Haskell/LSP/Types.hs b/src/Language/Haskell/LSP/Types.hs
--- a/src/Language/Haskell/LSP/Types.hs
+++ b/src/Language/Haskell/LSP/Types.hs
@@ -11,6 +11,7 @@
   , module Language.Haskell.LSP.Types.Location
   , module Language.Haskell.LSP.Types.MarkupContent
   , module Language.Haskell.LSP.Types.Message
+  , module Language.Haskell.LSP.Types.Progress
   , module Language.Haskell.LSP.Types.Symbol
   , module Language.Haskell.LSP.Types.TextDocument
   , module Language.Haskell.LSP.Types.Uri
@@ -32,6 +33,7 @@
 import           Language.Haskell.LSP.Types.Location
 import           Language.Haskell.LSP.Types.MarkupContent
 import           Language.Haskell.LSP.Types.Message
+import           Language.Haskell.LSP.Types.Progress
 import           Language.Haskell.LSP.Types.Symbol
 import           Language.Haskell.LSP.Types.TextDocument
 import           Language.Haskell.LSP.Types.Uri
diff --git a/src/Language/Haskell/LSP/Types/ClientCapabilities.hs b/src/Language/Haskell/LSP/Types/ClientCapabilities.hs
--- a/src/Language/Haskell/LSP/Types/ClientCapabilities.hs
+++ b/src/Language/Haskell/LSP/Types/ClientCapabilities.hs
@@ -1018,7 +1018,7 @@
 data WindowClientCapabilities = 
   WindowClientCapabilities
     { -- | Whether client supports handling progress notifications.
-      _progress :: Maybe Bool
+      _workDoneProgress :: Maybe Bool
     } deriving (Show, Read, Eq)
 
 $(deriveJSON lspOptions ''WindowClientCapabilities)
diff --git a/src/Language/Haskell/LSP/Types/CodeAction.hs b/src/Language/Haskell/LSP/Types/CodeAction.hs
--- a/src/Language/Haskell/LSP/Types/CodeAction.hs
+++ b/src/Language/Haskell/LSP/Types/CodeAction.hs
@@ -4,7 +4,6 @@
 module Language.Haskell.LSP.Types.CodeAction where
 
 import           Control.Applicative
-import qualified Data.Aeson                    as A
 import           Data.Aeson.TH
 import           Data.Aeson.Types
 import           Data.Text                      ( Text )
@@ -14,6 +13,7 @@
 import           Language.Haskell.LSP.Types.List
 import           Language.Haskell.LSP.Types.Location
 import           Language.Haskell.LSP.Types.Message
+import           Language.Haskell.LSP.Types.Progress
 import           Language.Haskell.LSP.Types.TextDocument
 import           Language.Haskell.LSP.Types.WorkspaceEdit
 
@@ -256,6 +256,7 @@
     { _textDocument :: TextDocumentIdentifier
     , _range        :: Range
     , _context      :: CodeActionContext
+    , _workDoneToken :: Maybe ProgressToken -- ^ An optional token that a server can use to report work done progress.
     } deriving (Read,Show,Eq)
 
 deriveJSON lspOptions ''CodeActionParams
diff --git a/src/Language/Haskell/LSP/Types/Color.hs b/src/Language/Haskell/LSP/Types/Color.hs
--- a/src/Language/Haskell/LSP/Types/Color.hs
+++ b/src/Language/Haskell/LSP/Types/Color.hs
@@ -8,6 +8,7 @@
 import           Language.Haskell.LSP.Types.List
 import           Language.Haskell.LSP.Types.Location
 import           Language.Haskell.LSP.Types.Message
+import           Language.Haskell.LSP.Types.Progress
 import           Language.Haskell.LSP.Types.TextDocument
 import           Language.Haskell.LSP.Types.WorkspaceEdit
 
@@ -99,6 +100,7 @@
 data DocumentColorParams =
   DocumentColorParams
     { _textDocument :: TextDocumentIdentifier -- ^ The text document.
+    , _workDoneToken :: Maybe ProgressToken -- ^ An optional token that a server can use to report work done progress.
     } deriving (Read, Show, Eq)
 
 deriveJSON lspOptions ''DocumentColorParams
@@ -173,6 +175,7 @@
       -- | The range where the color would be inserted.
       -- Serves as a context.
     , _range        :: Range
+    , _workDoneToken :: Maybe ProgressToken -- ^ An optional token that a server can use to report work done progress.
     } deriving (Read, Show, Eq)
 
 deriveJSON lspOptions ''ColorPresentationParams
diff --git a/src/Language/Haskell/LSP/Types/Completion.hs b/src/Language/Haskell/LSP/Types/Completion.hs
--- a/src/Language/Haskell/LSP/Types/Completion.hs
+++ b/src/Language/Haskell/LSP/Types/Completion.hs
@@ -15,6 +15,7 @@
 import           Language.Haskell.LSP.Types.Location
 import           Language.Haskell.LSP.Types.MarkupContent
 import           Language.Haskell.LSP.Types.Message
+import           Language.Haskell.LSP.Types.Progress
 import           Language.Haskell.LSP.Types.TextDocument
 import           Language.Haskell.LSP.Types.Utils
 import           Language.Haskell.LSP.Types.WorkspaceEdit
@@ -435,6 +436,7 @@
     , _context      :: Maybe CompletionContext
       -- ^ The completion context. This is only available if the client specifies
       -- to send this using `ClientCapabilities.textDocument.completion.contextSupport === true`
+    , _workDoneToken :: Maybe ProgressToken -- ^ An optional token that a server can use to report work done progress.
     }
   deriving (Read, Show, Eq)
 
diff --git a/src/Language/Haskell/LSP/Types/DataTypesJSON.hs b/src/Language/Haskell/LSP/Types/DataTypesJSON.hs
--- a/src/Language/Haskell/LSP/Types/DataTypesJSON.hs
+++ b/src/Language/Haskell/LSP/Types/DataTypesJSON.hs
@@ -27,6 +27,7 @@
 import           Language.Haskell.LSP.Types.Location
 import           Language.Haskell.LSP.Types.MarkupContent
 import           Language.Haskell.LSP.Types.Message
+import           Language.Haskell.LSP.Types.Progress
 import           Language.Haskell.LSP.Types.Symbol
 import           Language.Haskell.LSP.Types.TextDocument
 import           Language.Haskell.LSP.Types.Uri
@@ -2008,9 +2009,10 @@
 
 data ReferenceParams =
   ReferenceParams
-    { _textDocument :: TextDocumentIdentifier
-    , _position     :: Position
-    , _context      :: ReferenceContext
+    { _textDocument  :: TextDocumentIdentifier
+    , _position      :: Position
+    , _context       :: ReferenceContext
+    , _workDoneToken :: Maybe ProgressToken -- ^ An optional token that a server can use to report work done progress.
     } deriving (Read,Show,Eq)
 
 deriveJSON lspOptions ''ReferenceParams
@@ -2151,7 +2153,8 @@
 
 data WorkspaceSymbolParams =
   WorkspaceSymbolParams
-    { _query :: Text
+    { _query :: Text -- ^ A query string to filter symbols by. Clients may send an empty string here to request all symbols.
+    , _workDoneToken :: Maybe ProgressToken -- ^ An optional token that a server can use to report work done progress.
     } deriving (Read,Show,Eq)
 
 deriveJSON lspOptions ''WorkspaceSymbolParams
@@ -2216,6 +2219,7 @@
 data CodeLensParams =
   CodeLensParams
     { _textDocument :: TextDocumentIdentifier
+    , _workDoneToken :: Maybe ProgressToken -- ^ An optional token that a server can use to report work done progress.
     } deriving (Read,Show,Eq)
 
 deriveJSON lspOptions ''CodeLensParams
@@ -2338,6 +2342,7 @@
 data DocumentLinkParams =
   DocumentLinkParams
     { _textDocument :: TextDocumentIdentifier
+    , _workDoneToken :: Maybe ProgressToken -- ^ An optional token that a server can use to report work done progress.
     } deriving (Read,Show,Eq)
 
 deriveJSON lspOptions ''DocumentLinkParams
@@ -2446,6 +2451,7 @@
   DocumentFormattingParams
     { _textDocument :: TextDocumentIdentifier
     , _options      :: FormattingOptions
+    , _workDoneToken :: Maybe ProgressToken -- ^ An optional token that a server can use to report work done progress.
     } deriving (Show,Read,Eq)
 
 deriveJSON lspOptions ''DocumentFormattingParams
@@ -2497,6 +2503,7 @@
     { _textDocument :: TextDocumentIdentifier
     , _range        :: Range
     , _options      :: FormattingOptions
+    , _workDoneToken :: Maybe ProgressToken -- ^ An optional token that a server can use to report work done progress.
     } deriving (Read,Show,Eq)
 
 deriveJSON lspOptions ''DocumentRangeFormattingParams
@@ -2628,6 +2635,7 @@
     { _textDocument :: TextDocumentIdentifier
     , _position     :: Position
     , _newName      :: Text
+    , _workDoneToken :: Maybe ProgressToken -- ^ An optional token that a server can use to report work done progress.
     } deriving (Show, Read, Eq)
 
 deriveJSON lspOptions ''RenameParams
@@ -2736,8 +2744,9 @@
 
 data ExecuteCommandParams =
   ExecuteCommandParams
-    { _command   :: Text
-    , _arguments :: Maybe (List A.Value)
+    { _command   :: Text -- ^ The identifier of the actual command handler.
+    , _arguments :: Maybe (List A.Value) -- ^ Arguments that the command should be invoked with.
+    , _workDoneToken :: Maybe ProgressToken -- ^ An optional token that a server can use to report work done progress.
     } deriving (Show, Read, Eq)
 
 deriveJSON lspOptions ''ExecuteCommandParams
diff --git a/src/Language/Haskell/LSP/Types/FoldingRange.hs b/src/Language/Haskell/LSP/Types/FoldingRange.hs
--- a/src/Language/Haskell/LSP/Types/FoldingRange.hs
+++ b/src/Language/Haskell/LSP/Types/FoldingRange.hs
@@ -7,12 +7,14 @@
 import           Data.Text                    (Text)
 import           Language.Haskell.LSP.Types.Constants
 import           Language.Haskell.LSP.Types.List
+import           Language.Haskell.LSP.Types.Progress
 import           Language.Haskell.LSP.Types.TextDocument
 import           Language.Haskell.LSP.Types.Message
 
 data FoldingRangeParams =
   FoldingRangeParams
   { _textDocument :: TextDocumentIdentifier -- ^ The text document.
+  , _workDoneToken :: Maybe ProgressToken -- ^ An optional token that a server can use to report work done progress.
   }
   deriving (Read, Show, Eq)
 
diff --git a/src/Language/Haskell/LSP/Types/Lens.hs b/src/Language/Haskell/LSP/Types/Lens.hs
--- a/src/Language/Haskell/LSP/Types/Lens.hs
+++ b/src/Language/Haskell/LSP/Types/Lens.hs
@@ -193,7 +193,7 @@
 makeFieldsNoPrefix ''MessageActionItem
 makeFieldsNoPrefix ''ShowMessageRequestParams
 makeFieldsNoPrefix ''LogMessageParams
-makeFieldsNoPrefix ''ProgressStartParams
-makeFieldsNoPrefix ''ProgressReportParams
-makeFieldsNoPrefix ''ProgressDoneParams
-makeFieldsNoPrefix ''ProgressCancelParams
+makeFieldsNoPrefix ''ProgressParams
+makeFieldsNoPrefix ''WorkDoneProgressBeginParams
+makeFieldsNoPrefix ''WorkDoneProgressReportParams
+makeFieldsNoPrefix ''WorkDoneProgressEndParams
diff --git a/src/Language/Haskell/LSP/Types/Message.hs b/src/Language/Haskell/LSP/Types/Message.hs
--- a/src/Language/Haskell/LSP/Types/Message.hs
+++ b/src/Language/Haskell/LSP/Types/Message.hs
@@ -3,10 +3,12 @@
 {-# LANGUAGE TemplateHaskell            #-}
 module Language.Haskell.LSP.Types.Message where
 
+import           Control.Monad
 import qualified Data.Aeson                                 as A
 import           Data.Aeson.TH
 import           Data.Aeson.Types
 import           Data.Hashable
+import           Data.Maybe
 -- For <= 8.2.2
 import           Data.Text                                  (Text)
 import           Language.Haskell.LSP.Types.Constants
@@ -83,7 +85,7 @@
  | WorkspaceSymbol
  | WorkspaceExecuteCommand
  -- Progress
- | WindowProgressCancel
+ | WorkDoneProgressCancel
  -- Document
  | TextDocumentDidOpen
  | TextDocumentDidChange
@@ -161,7 +163,7 @@
   parseJSON (A.String "textDocument/rename")              = return TextDocumentRename
   parseJSON (A.String "textDocument/prepareRename")       = return TextDocumentPrepareRename
   parseJSON (A.String "textDocument/foldingRange")        = return TextDocumentFoldingRange
-  parseJSON (A.String "window/progress/cancel")           = return WindowProgressCancel
+  parseJSON (A.String "window/workDoneProgress/cancel")   = return WorkDoneProgressCancel
   parseJSON (A.String x)                                  = return (CustomClientMethod x)
   parseJSON _                                             = mempty
 
@@ -208,7 +210,7 @@
   toJSON TextDocumentFoldingRange        = A.String "textDocument/foldingRange"
   toJSON TextDocumentDocumentLink        = A.String "textDocument/documentLink"
   toJSON DocumentLinkResolve             = A.String "documentLink/resolve"
-  toJSON WindowProgressCancel            = A.String "window/progress/cancel"
+  toJSON WorkDoneProgressCancel          = A.String "window/workDoneProgress/cancel"
   toJSON (CustomClientMethod xs)         = A.String xs
 
 data ServerMethod =
@@ -216,9 +218,8 @@
     WindowShowMessage
   | WindowShowMessageRequest
   | WindowLogMessage
-  | WindowProgressStart
-  | WindowProgressReport
-  | WindowProgressDone
+  | WindowWorkDoneProgressCreate
+  | Progress
   | TelemetryEvent
   -- Client
   | ClientRegisterCapability
@@ -239,9 +240,8 @@
   parseJSON (A.String "window/showMessage")              = return WindowShowMessage
   parseJSON (A.String "window/showMessageRequest")       = return WindowShowMessageRequest
   parseJSON (A.String "window/logMessage")               = return WindowLogMessage
-  parseJSON (A.String "window/progress/start")           = return WindowProgressStart
-  parseJSON (A.String "window/progress/report")          = return WindowProgressReport
-  parseJSON (A.String "window/progress/done")            = return WindowProgressDone
+  parseJSON (A.String "window/workDoneProgress/create")  = return WindowWorkDoneProgressCreate
+  parseJSON (A.String "$/progress")                      = return Progress
   parseJSON (A.String "telemetry/event")                 = return TelemetryEvent
   -- Client
   parseJSON (A.String "client/registerCapability")       = return ClientRegisterCapability
@@ -262,9 +262,8 @@
   toJSON WindowShowMessage        = A.String "window/showMessage"
   toJSON WindowShowMessageRequest = A.String "window/showMessageRequest"
   toJSON WindowLogMessage         = A.String "window/logMessage"
-  toJSON WindowProgressStart      = A.String "window/progress/start"
-  toJSON WindowProgressReport     = A.String "window/progress/report"
-  toJSON WindowProgressDone       = A.String "window/progress/done"
+  toJSON WindowWorkDoneProgressCreate = A.String "window/workDoneProgress/create"
+  toJSON Progress                 = A.String "$/progress"
   toJSON TelemetryEvent           = A.String "telemetry/event"
   -- Client
   toJSON ClientRegisterCapability   = A.String "client/registerCapability"
@@ -377,6 +376,7 @@
 
 -- ---------------------------------------------------------------------
 
+-- | Either result or error must be Just.
 data ResponseMessage a =
   ResponseMessage
     { _jsonrpc :: Text
@@ -388,13 +388,18 @@
 deriveToJSON lspOptions ''ResponseMessage
 
 instance FromJSON a => FromJSON (ResponseMessage a) where
-  parseJSON = withObject "Response" $ \o ->
-    ResponseMessage
+  parseJSON = withObject "Response" $ \o -> do
+    rsp <- ResponseMessage
       <$> o .: "jsonrpc"
       <*> o .: "id"
       -- It is important to use .:! so that result = null gets decoded as Just Nothing
       <*> o .:! "result"
       <*> o .:! "error"
+    -- We make sure that one of them is present. Without this check we can end up
+    -- parsing a Request as a ResponseMessage.
+    unless (isJust (_result rsp) || isJust (_error rsp)) $
+      fail "ResponseMessage must either have a result or an error"
+    pure rsp
 
 type ErrorResponse = ResponseMessage ()
 
diff --git a/src/Language/Haskell/LSP/Types/MessageFuncs.hs b/src/Language/Haskell/LSP/Types/MessageFuncs.hs
--- a/src/Language/Haskell/LSP/Types/MessageFuncs.hs
+++ b/src/Language/Haskell/LSP/Types/MessageFuncs.hs
@@ -17,9 +17,10 @@
   , fmServerShowMessageNotification
   , fmServerShowMessageRequest
   , fmServerLogMessageNotification
-  , fmServerProgressStartNotification
-  , fmServerProgressReportNotification
-  , fmServerProgressDoneNotification
+  , fmServerWorkDoneProgressBeginNotification
+  , fmServerWorkDoneProgressReportNotification
+  , fmServerWorkDoneProgressEndNotification
+  , fmServerWorkDoneProgressCreateRequest
   , fmServerTelemetryNotification
 
   -- * Client
@@ -133,21 +134,25 @@
 
 -- ----------------------------------------------------------------------
 
-fmServerProgressStartNotification :: J.ProgressStartParams -> J.ProgressStartNotification
-fmServerProgressStartNotification params
-  = J.NotificationMessage "2.0" J.WindowProgressStart params
+fmServerWorkDoneProgressBeginNotification :: J.ProgressParams J.WorkDoneProgressBeginParams -> J.WorkDoneProgressBeginNotification
+fmServerWorkDoneProgressBeginNotification params
+  = J.NotificationMessage "2.0" J.Progress params
 
 -- ----------------------------------------------------------------------
 
-fmServerProgressReportNotification :: J.ProgressReportParams -> J.ProgressReportNotification
-fmServerProgressReportNotification params
-  = J.NotificationMessage "2.0" J.WindowProgressReport params
+fmServerWorkDoneProgressReportNotification :: J.ProgressParams J.WorkDoneProgressReportParams -> J.WorkDoneProgressReportNotification
+fmServerWorkDoneProgressReportNotification params
+  = J.NotificationMessage "2.0" J.Progress params
 
 -- ----------------------------------------------------------------------
 
-fmServerProgressDoneNotification :: J.ProgressDoneParams -> J.ProgressDoneNotification
-fmServerProgressDoneNotification params
-  = J.NotificationMessage "2.0" J.WindowProgressDone params
+fmServerWorkDoneProgressEndNotification :: J.ProgressParams J.WorkDoneProgressEndParams -> J.WorkDoneProgressEndNotification
+fmServerWorkDoneProgressEndNotification params
+  = J.NotificationMessage "2.0" J.Progress params
+
+fmServerWorkDoneProgressCreateRequest :: J.LspId -> J.WorkDoneProgressCreateParams -> J.WorkDoneProgressCreateRequest
+fmServerWorkDoneProgressCreateRequest rid params
+  = J.RequestMessage "2.0" rid J.WindowWorkDoneProgressCreate params
 
 -- ----------------------------------------------------------------------
 -- * :arrow_left: [telemetry/event](#telemetry_event)
diff --git a/src/Language/Haskell/LSP/Types/Progress.hs b/src/Language/Haskell/LSP/Types/Progress.hs
new file mode 100644
--- /dev/null
+++ b/src/Language/Haskell/LSP/Types/Progress.hs
@@ -0,0 +1,21 @@
+module Language.Haskell.LSP.Types.Progress where
+
+import qualified Data.Aeson as A
+import Data.Text (Text)
+
+-- | A token used to report progress back or return partial results for a
+-- specific request.
+-- @since 0.17.0.0
+data ProgressToken
+    = ProgressNumericToken Int
+    | ProgressTextToken Text
+    deriving (Show, Read, Eq, Ord)
+
+instance A.ToJSON ProgressToken where
+    toJSON (ProgressNumericToken i) = A.toJSON i
+    toJSON (ProgressTextToken t) = A.toJSON t
+
+instance A.FromJSON ProgressToken where
+    parseJSON (A.String t) = pure $ ProgressTextToken t
+    parseJSON (A.Number i) = ProgressNumericToken <$> A.parseJSON (A.Number i)
+    parseJSON v = fail $ "Invalid progress token: " ++ show v
diff --git a/src/Language/Haskell/LSP/Types/Symbol.hs b/src/Language/Haskell/LSP/Types/Symbol.hs
--- a/src/Language/Haskell/LSP/Types/Symbol.hs
+++ b/src/Language/Haskell/LSP/Types/Symbol.hs
@@ -12,6 +12,7 @@
 import           Language.Haskell.LSP.Types.List
 import           Language.Haskell.LSP.Types.Location
 import           Language.Haskell.LSP.Types.Message
+import           Language.Haskell.LSP.Types.Progress
 
 -- ---------------------------------------------------------------------
 {-
@@ -102,6 +103,7 @@
 data DocumentSymbolParams =
   DocumentSymbolParams
     { _textDocument :: TextDocumentIdentifier
+    , _workDoneToken :: Maybe ProgressToken -- ^ An optional token that a server can use to report work done progress.
     } deriving (Read,Show,Eq)
 
 deriveJSON lspOptions ''DocumentSymbolParams
diff --git a/src/Language/Haskell/LSP/Types/TextDocument.hs b/src/Language/Haskell/LSP/Types/TextDocument.hs
--- a/src/Language/Haskell/LSP/Types/TextDocument.hs
+++ b/src/Language/Haskell/LSP/Types/TextDocument.hs
@@ -6,6 +6,7 @@
 import           Data.Text                      ( Text )
 import           Language.Haskell.LSP.Types.Constants
 import           Language.Haskell.LSP.Types.Location
+import           Language.Haskell.LSP.Types.Progress
 import           Language.Haskell.LSP.Types.Uri
 
 -- ---------------------------------------------------------------------
@@ -98,6 +99,7 @@
   TextDocumentPositionParams
     { _textDocument :: TextDocumentIdentifier
     , _position     :: Position
+    , _workDoneToken :: Maybe ProgressToken -- ^ An optional token that a server can use to report work done progress.
     } deriving (Show, Read, Eq)
 
 deriveJSON lspOptions ''TextDocumentPositionParams
diff --git a/src/Language/Haskell/LSP/Types/Window.hs b/src/Language/Haskell/LSP/Types/Window.hs
--- a/src/Language/Haskell/LSP/Types/Window.hs
+++ b/src/Language/Haskell/LSP/Types/Window.hs
@@ -1,12 +1,17 @@
+{-# LANGUAGE OverloadedStrings          #-}
 {-# LANGUAGE DuplicateRecordFields      #-}
+{-# LANGUAGE RecordWildCards            #-}
 {-# LANGUAGE TemplateHaskell            #-}
 module Language.Haskell.LSP.Types.Window where
 
+import           Control.Monad (unless)
 import qualified Data.Aeson                                 as A
 import           Data.Aeson.TH
+import           Data.Maybe (catMaybes)
 import           Data.Text                                  (Text)
 import           Language.Haskell.LSP.Types.Constants
 import           Language.Haskell.LSP.Types.Message
+import           Language.Haskell.LSP.Types.Progress
 
 -- ---------------------------------------------------------------------
 {-
@@ -195,72 +200,68 @@
 
 type LogMessageNotification = NotificationMessage ServerMethod LogMessageParams
 
--- ---------------------------------------------------------------------
 {-
-Progress Start Notification
-
-The window/progress/start notification is sent from the server to the client to ask the client to start progress.
+Progress Begin Notification
 
-Notification:
+To start progress reporting a $/progress notification with the following payload must be sent:
 
-method: 'window/progress/start'
-params: ProgressStartParams defined as follows:
-export interface ProgressStartParams {
+export interface WorkDoneProgressBegin {
 
-  /**
-   * A unique identifier to associate multiple progress notifications with
-   * the same progress.
-   */
-  id: string;
+	kind: 'begin';
 
-  /**
-   * Mandatory title of the progress operation. Used to briefly inform about
-   * the kind of operation being performed.
-   *
-   * Examples: "Indexing" or "Linking dependencies".
-   */
-  title: string;
+	/**
+	 * Mandatory title of the progress operation. Used to briefly inform about
+	 * the kind of operation being performed.
+	 *
+	 * Examples: "Indexing" or "Linking dependencies".
+	 */
+	title: string;
 
-  /**
-   * Controls if a cancel button should show to allow the user to cancel the
-   * long running operation. Clients that don't support cancellation are allowed
-   * to ignore the setting.
-   */
-  cancellable?: boolean;
+	/**
+	 * Controls if a cancel button should show to allow the user to cancel the
+	 * long running operation. Clients that don't support cancellation are allowed
+	 * to ignore the setting.
+	 */
+	cancellable?: boolean;
 
-  /**
-   * Optional, more detailed associated progress message. Contains
-   * complementary information to the '_title'.
-   *
-   * Examples: "3/25 files", "project/src/module2", "node_modules/some_dep".
-   * If unset, the previous progress message (if any) is still valid.
-   */
-  message?: string;
+	/**
+	 * Optional, more detailed associated progress message. Contains
+	 * complementary information to the `title`.
+	 *
+	 * Examples: "3/25 files", "project/src/module2", "node_modules/some_dep".
+	 * If unset, the previous progress message (if any) is still valid.
+	 */
+	message?: string;
 
-  /**
-   * Optional progress percentage to display (value 100 is considered 100%).
-   * If not provided infinite progress is assumed and clients are allowed
-   * to ignore the '_percentage' value in subsequent in report notifications.
-   *
-   * The value should be steadily rising. Clients are free to ignore values
-   * that are not following this rule.
-   */
-  percentage?: number;
-}
+	/**
+	 * Optional progress percentage to display (value 100 is considered 100%).
+	 * If not provided infinite progress is assumed and clients are allowed
+	 * to ignore the `percentage` value in subsequent in report notifications.
+	 *
+	 * The value should be steadily rising. Clients are free to ignore values
+	 * that are not following this rule.
+	 */
+	percentage?: number;
 -}
 
--- | Parameters for 'ProgressStartNotification'.
+-- | Parameters for a $/progress notification.
+data ProgressParams t =
+    ProgressParams {
+      _token :: ProgressToken
+    , _value :: t
+    } deriving (Show, Read, Eq)
+
+deriveJSON lspOptions{ fieldLabelModifier = customModifier } ''ProgressParams
+
+-- | Parameters for 'WorkDoneProgressBeginNotification'.
 --
 -- @since 0.10.0.0
-data ProgressStartParams =
-  ProgressStartParams {
-  -- | A unique identifier to associate multiple progress
-  -- notifications with the same progress.
-    _id   :: Text
+data WorkDoneProgressBeginParams =
+  WorkDoneProgressBeginParams {
   -- | Mandatory title of the progress operation.
   -- Used to briefly inform about the kind of operation being
   -- performed. Examples: "Indexing" or "Linking dependencies".
-  , _title :: Text
+   _title :: Text
   -- | Controls if a cancel button should show to allow the user to cancel the
   -- long running operation. Clients that don't support cancellation are allowed
   -- to ignore the setting.
@@ -281,59 +282,77 @@
   , _percentage :: Maybe Double
   } deriving (Show, Read, Eq)
 
-deriveJSON lspOptions{ fieldLabelModifier = customModifier } ''ProgressStartParams
+instance A.ToJSON WorkDoneProgressBeginParams where
+    toJSON WorkDoneProgressBeginParams{..} =
+        A.object $ catMaybes
+            [ Just $ "kind" A..= ("begin" :: Text)
+            , Just $ "title" A..= _title
+            , ("cancellable" A..=) <$> _cancellable
+            , ("message" A..=) <$> _message
+            , ("percentage" A..=) <$> _percentage
+            ]
 
--- | The window/progress/start notification is sent from the server to the
+instance A.FromJSON WorkDoneProgressBeginParams where
+    parseJSON = A.withObject "WorkDoneProgressBegin" $ \o -> do
+        kind <- o A..: "kind"
+        unless (kind == ("begin" :: Text)) $ fail $ "Expected kind \"begin\" but got " ++ show kind
+        _title <- o A..: "title"
+        _cancellable <- o A..:? "cancellable"
+        _message <- o A..:? "message"
+        _percentage <- o A..:? "percentage"
+        pure WorkDoneProgressBeginParams{..}
+
+-- | The $/progress begin notification is sent from the server to the
 -- client to ask the client to start progress.
 --
 -- @since 0.10.0.0
-type ProgressStartNotification = NotificationMessage ServerMethod ProgressStartParams
-
+type WorkDoneProgressBeginNotification = NotificationMessage ServerMethod (ProgressParams WorkDoneProgressBeginParams)
 
 {-
 Progress Report Notification
 
-The window/progress/report notification is sent from the server to the client to report progress for a previously started progress.
+Reporting progress is done using the following payload:
 
-Notification:
+export interface WorkDoneProgressReport {
 
-method: 'window/progress/report'
-params: ProgressReportParams defined as follows:
-export interface ProgressReportParams {
+	kind: 'report';
 
-  /**
-   * A unique identifier to associate multiple progress notifications with the same progress.
-   */
-  id: string;
+	/**
+	 * Controls enablement state of a cancel button. This property is only valid if a cancel
+	 * button got requested in the `WorkDoneProgressStart` payload.
+	 *
+	 * Clients that don't support cancellation or don't support control the button's
+	 * enablement state are allowed to ignore the setting.
+	 */
+	cancellable?: boolean;
 
-  /**
-   * Optional, more detailed associated progress message. Contains
-   * complementary information to the '_title'.
-   *
-   * Examples: "3/25 files", "project/src/module2", "node_modules/some_dep".
-   * If unset, the previous progress message (if any) is still valid.
-   */
-  message?: string;
+	/**
+	 * Optional, more detailed associated progress message. Contains
+	 * complementary information to the `title`.
+	 *
+	 * Examples: "3/25 files", "project/src/module2", "node_modules/some_dep".
+	 * If unset, the previous progress message (if any) is still valid.
+	 */
+	message?: string;
 
-  /**
-   * Optional progress percentage to display (value 100 is considered 100%).
-   * If infinite progress was indicated in the start notification client
-   * are allowed to ignore the value. In addition the value should be steadily
-   * rising. Clients are free to ignore values that are not following this rule.
-   */
-  percentage?: number;
+	/**
+	 * Optional progress percentage to display (value 100 is considered 100%).
+	 * If not provided infinite progress is assumed and clients are allowed
+	 * to ignore the `percentage` value in subsequent in report notifications.
+	 *
+	 * The value should be steadily rising. Clients are free to ignore values
+	 * that are not following this rule.
+	 */
+	percentage?: number;
 }
-
 -}
 
--- | Parameters for 'ProgressReportNotification'
+-- | Parameters for 'WorkDoneProgressReportNotification'
 --
 -- @since 0.10.0.0
-data ProgressReportParams =
-  ProgressReportParams {
-  -- | A unique identifier to associate multiple progress
-  -- notifications with the same progress.
-    _id   :: Text
+data WorkDoneProgressReportParams =
+  WorkDoneProgressReportParams {
+    _cancellable :: Maybe Bool
   -- | Optional, more detailed associated progress
   -- message. Contains complementary information to the
   -- '_title'. Examples: "3/25 files",
@@ -348,82 +367,116 @@
   , _percentage :: Maybe Double
   } deriving (Show, Read, Eq)
 
-deriveJSON lspOptions{ fieldLabelModifier = customModifier } ''ProgressReportParams
+instance A.ToJSON WorkDoneProgressReportParams where
+  toJSON WorkDoneProgressReportParams{..} =
+    A.object $ catMaybes
+      [ Just $ "kind" A..= ("report" :: Text)
+      , ("cancellable" A..=) <$> _cancellable
+      , ("message" A..=) <$> _message
+      , ("percentage" A..=) <$> _percentage
+      ]
 
--- | The window/progress/report notification is sent from the server to the
+instance A.FromJSON WorkDoneProgressReportParams where
+  parseJSON = A.withObject "WorkDoneProgressReport" $ \o -> do
+    kind <- o A..: "kind"
+    unless (kind == ("report" :: Text)) $ fail $ "Expected kind \"report\" but got " ++ show kind
+    _cancellable <- o A..:? "cancellable"
+    _message <- o A..:? "message"
+    _percentage <- o A..:? "percentage"
+    pure WorkDoneProgressReportParams{..}
+
+-- | The workdone $/progress report notification is sent from the server to the
 -- client to report progress for a previously started progress.
 --
 -- @since 0.10.0.0
-type ProgressReportNotification = NotificationMessage ServerMethod ProgressReportParams
+type WorkDoneProgressReportNotification = NotificationMessage ServerMethod (ProgressParams WorkDoneProgressReportParams)
 
 {-
-Progress Done Notification
+Progress End Notification
 
-The window/progress/done notification is sent from the server to the client to stop a previously started progress.
+Signaling the end of a progress reporting is done using the following payload:
 
-Notification:
+export interface WorkDoneProgressEnd {
 
-method: 'window/progress/done'
-params: ProgressDoneParams defined as follows:
-export interface ProgressDoneParams {
-  /**
-   * A unique identifier to associate multiple progress notifications with the same progress.
-   */
-  id: string;
+	kind: 'end';
+
+	/**
+	 * Optional, a final message indicating to for example indicate the outcome
+	 * of the operation.
+	 */
+	message?: string;
 }
 -}
 
--- | Parameters for 'ProgressDoneNotification'.
+-- | Parameters for 'WorkDoneProgressEndNotification'.
 --
 -- @since 0.10.0.0
-data ProgressDoneParams =
-  ProgressDoneParams {
-  -- | A unique identifier to associate multiple progress
-  -- notifications with the same progress.
-    _id   :: Text
+data WorkDoneProgressEndParams =
+  WorkDoneProgressEndParams {
+    _message   :: Maybe Text
   } deriving (Show, Read, Eq)
 
-deriveJSON lspOptions{ fieldLabelModifier = customModifier } ''ProgressDoneParams
+instance A.ToJSON WorkDoneProgressEndParams where
+  toJSON WorkDoneProgressEndParams{..} =
+    A.object $ catMaybes
+      [ Just $ "kind" A..= ("end" :: Text)
+      , ("message" A..=) <$> _message
+      ]
 
--- | The window/progress/done notification is sent from the server to the
+instance A.FromJSON WorkDoneProgressEndParams where
+  parseJSON = A.withObject "WorkDoneProgressEnd" $ \o -> do
+    kind <- o A..: "kind"
+    unless (kind == ("end" :: Text)) $ fail $ "Expected kind \"end\" but got " ++ show kind
+    _message <- o A..:? "message"
+    pure WorkDoneProgressEndParams{..}
+
+-- | The $/progress end notification is sent from the server to the
 -- client to stop a previously started progress.
 --
 -- @since 0.10.0.0
-type ProgressDoneNotification = NotificationMessage ServerMethod ProgressDoneParams
+type WorkDoneProgressEndNotification = NotificationMessage ServerMethod (ProgressParams WorkDoneProgressEndParams)
 
 {-
 Progress Cancel Notification
 
-The window/progress/cancel notification is sent from the client to the server to inform the server that the user has pressed the cancel button on the progress UX. A server receiving a cancel request must still close a progress using the done notification.
+The window/workDoneProgress/cancel notification is sent from the client to the server to inform the server that the user has pressed the cancel button on the progress UX. A server receiving a cancel request must still close a progress using the done notification.
 
 Notification:
 
-method: 'window/progress/cancel'
-params: ProgressCancelParams defined as follows:
-export interface ProgressCancelParams {
-  /**
-   * A unique identifier to associate multiple progress notifications with the same progress.
-   */
-  id: string;
+method: 'window/workDoneProgress/cancel'
+params: WorkDoneProgressCancelParams defined as follows:
+export interface WorkDoneProgressCancelParams {
+	/**
+	 * The token to be used to report progress.
+	 */
+	token: ProgressToken;
 }
-
 -}
 
--- | Parameters for 'ProgressCancelNotification'.
+-- | Parameters for 'WorkDoneProgressCancelNotification'.
 --
 -- @since 0.10.0.0
-data ProgressCancelParams =
-  ProgressCancelParams {
+data WorkDoneProgressCancelParams =
+  WorkDoneProgressCancelParams {
   -- | A unique identifier to associate multiple progress
   -- notifications with the same progress.
-    _id   :: Text
+    _token   :: ProgressToken
   } deriving (Show, Read, Eq)
 
-deriveJSON lspOptions{ fieldLabelModifier = customModifier } ''ProgressCancelParams
+deriveJSON lspOptions{ fieldLabelModifier = customModifier } ''WorkDoneProgressCancelParams
 
--- | The window/progress/cancel notification is sent from the client to the server
+-- | The window/workDoneProgress/cancel notification is sent from the client to the server
 -- to inform the server that the user has pressed the cancel button on the progress UX.
 -- A server receiving a cancel request must still close a progress using the done notification.
 --
 -- @since 0.10.0.0
-type ProgressCancelNotification = NotificationMessage ClientMethod ProgressCancelParams
+type WorkDoneProgressCancelNotification = NotificationMessage ClientMethod WorkDoneProgressCancelParams
+
+data WorkDoneProgressCreateParams =
+    WorkDoneProgressCreateParams {
+      _token :: ProgressToken
+    } deriving (Show, Read, Eq)
+
+deriveJSON lspOptions{ fieldLabelModifier = customModifier } ''WorkDoneProgressCreateParams
+
+type WorkDoneProgressCreateRequest = RequestMessage ServerMethod WorkDoneProgressCreateParams ()
