Repository: microsoft/terminal (language: cpp)

Issue:
De-duplicate code for TerminalDispatch and AdaptDispatch
Both these classes are doing a _lot_ of the nearly same work at this point. We should probably not, and have more common implementations somehow. 

**IIRC**, when I was writing it, I think part of the idea was to move `ITerminalApi` up and out of the Terminal to be shared, then have one Dispatch that calls into the API, then an adapter between that API and the conhost API

This is a super crude diagram
```
         +------------------+
         |  OutputEngine    |
         +---------+--------+
                   |
         +---------v--------+
         | OutputDispatch   |
         +--------+---------+
                  |
         +--------v---------+
         |   ITerminalApi   |
         +---+------------+-+
             |            |
             |            |
+------------v--+     +---v------------+
|  Terminal     |     |  HostAdapter   |
+---------------+     +-------+--------+
                              |
                      +-------v--------+
                      |   outputStream |
                      |      +         |
                      |      |         |
                      |      v         |
                      |   getset       |
                      +----------------+

```

In this model, `Terminal` and `HostAdapter` both implement `ITerminalApi`, so there only needs to be one Dispatcher. `HostAdapter` then calls into the `conGetSet` API we already have. 

This would pretty horribly break tests that test the existing structure :/

I could be horribly off base with this though. I came up with this idea like 9 months ago and never wrote it down.

* [ ] #5384 (xterm indexed color problem)


Discussion / hints:
This sounds reasonable to me. Doesn't matter if it breaks the test. We've already identified that half of the adapter tests are pretty silly anyway. Probably need to revisit that anyway.
It looks like the TerminalDispatch methods don't really have tests on them either. So it's probably up to this task to consider testing overall.
My initial thought for this was that we would just drop the `TerminalDispatch` code and replace it entirely with `AdaptDispatch`. That already has all of the functionality that `TerminalDispatch` is trying to replicate, and it actually does have tests in place too.

Then the interface that splits the conhost and Terminal implementations could possibly be based on the current `ConGetSet` interface. It'll require quite a lot of cleanup before it's really suitable for that task, but I think that's probably the right place for it.
As I've mentioned elsewhere, I've been investigating ways to simplify the `ConGetSet` interface, with the idea that it could eventually be merged with the `ITerminalApi` interface, and `AdaptDispatch` could then more easily be merged with `TerminalDispatch`. I'm going to go one step at a time on this, so I'm not going to dump a massive PR on you, but the list below covers some of the ideas I'm considering. If there's anything here you definitely _don't_ want me to do, please let me know.

1. Replace `GetConsoleScreenBufferInfoEx` with a set of methods providing the specific properties we actually need, namely the buffer size, the virtual viewport dimensions, and the cursor position. This should also let us get rid of all the `MoveToBottom` calls which I think are only there to make sure the viewport returned by `GetConsoleScreenBufferInfoEx` is aligned with the virtual viewport.
2. Get rid of the `DeleteLines`, `InsertLines`, and `PrivateReverseLineFeed` methods. These operations can easily be implemented in `AdaptDispatch` using existing scrolling and filling APIs, and then Windows Terminal can eventually inherit that functionality without having to implement any additional interfaces.
3. Of the methods we do want to keep, we need to rename them to better match the `ITerminalApi` interface, for example getting rid of all of those `Private` prefixes. And if we're going to be rewriting a lot of the interface, this seems like a good time to try and modernize things a bit, e.g. replacing `COORD` with `til::point`, and `RECT` with `til::rectangle` (assuming that's the current preferred standard). I'm also very keen to get rid of the boolean return values as error indicators - we should be using return values for returning things, and throwing exceptions for errors.
4. Again while we're rewriting things, this might be a good time to consider simplifying some of the bloat in the conhost implementation. Like is it really necessary for every `ConhostInternalGetSet` method to call a separate `DoSrvPrivateXXXX` function to actually do the work. Why not just implement the code right there in the `ConhostInternalGetSet` class?
5. In the interests of future expansion, I'd like to try and coalesce some of the APIs where that seems reasonable. For example, do we really need 5 different mouse mode methods (which will eventually require another 5 matching getter methods), when we could just have one method with a mode parameter? The same thing applies to the various keyboard modes - I think there are only three at the moment, but that list is going to grow. It would make future expansion a lot easier if that just meant adding one more enum value.
I love all 5 of these things, @j4james. Feel free to take them on in whatever staging you deem sensible so we can have them reviewed.

Fix patch:
diff --git a/src/buffer/out/search.cpp b/src/buffer/out/search.cpp
index bb75fc4432f..a5b2b4d9e84 100644
--- a/src/buffer/out/search.cpp
+++ b/src/buffer/out/search.cpp
@@ -140,7 +140,7 @@ std::pair<COORD, COORD> Search::GetFoundLocation() const noexcept
 // - direction - The intended direction of the search
 // Return Value:
 // - Coordinate to start the search from.
-COORD Search::s_GetInitialAnchor(IUiaData& uiaData, const Direction direction)
+COORD Search::s_GetInitialAnchor(const IUiaData& uiaData, const Direction direction)
 {
     const auto& textBuffer = uiaData.GetTextBuffer();
     const auto textBufferEndPosition = uiaData.GetTextBufferEndPosition();
diff --git a/src/buffer/out/search.h b/src/buffer/out/search.h
index 39efc139f40..38e5bb7885c 100644
--- a/src/buffer/out/search.h
+++ b/src/buffer/out/search.h
@@ -66,7 +66,7 @@ class Search final
     void _IncrementCoord(COORD& coord) const noexcept;
     void _DecrementCoord(COORD& coord) const noexcept;
 
-    static COORD s_GetInitialAnchor(Microsoft::Console::Types::IUiaData& uiaData, const Direction dir);
+    static COORD s_GetInitialAnchor(const Microsoft::Console::Types::IUiaData& uiaData, const Direction dir);
 
     static std::vector<std::vector<wchar_t>> s_CreateNeedleFromString(const std::wstring& wstr);
 
diff --git a/src/cascadia/PublicTerminalCore/HwndTerminal.cpp b/src/cascadia/PublicTerminalCore/HwndTerminal.cpp
index 3dd7bfc0563..f25fd86aecc 100644
--- a/src/cascadia/PublicTerminalCore/HwndTerminal.cpp
+++ b/src/cascadia/PublicTerminalCore/HwndTerminal.cpp
@@ -214,7 +214,9 @@ HRESULT HwndTerminal::Initialize()
     _terminal = std::make_unique<::Microsoft::Terminal::Core::Terminal>();
     auto renderThread = std::make_unique<::Microsoft::Console::Render::RenderThread>();
     auto* const localPointerToThread = renderThread.get();
-    const auto& renderSettings = _terminal->GetRenderSettings();
+    auto& renderSettings = _terminal->GetRenderSettings();
+    renderSettings.SetColorTableEntry(TextColor::DEFAULT_BACKGROUND, RGB(12, 12, 12));
+    renderSettings.SetColorTableEntry(TextColor::DEFAULT_FOREGROUND, RGB(204, 204, 204));
     _renderer = std::make_unique<::Microsoft::Console::Render::Renderer>(renderSettings, _terminal.get(), nullptr, 0, std::move(renderThread));
     RETURN_HR_IF_NULL(E_POINTER, localPointerToThread);
     RETURN_IF_FAILED(localPointerToThread->Initialize(_renderer.get()));
@@ -237,11 +239,7 @@ HRESULT HwndTerminal::Initialize()
 
     _renderEngine = std::move(dxEngine);
 
-    _terminal->SetBackgroundCallback([](auto) {});
-
     _terminal->Create(COORD{ 80, 25 }, 1000, *_renderer);
-    _terminal->SetColorTableEntry(TextColor::DEFAULT_BACKGROUND, RGB(12, 12, 12));
-    _terminal->SetColorTableEntry(TextColor::DEFAULT_FOREGROUND, RGB(204, 204, 204));
     _terminal->SetWriteInputCallback([=](std::wstring_view input) noexcept { _WriteTextToConnection(input); });
     localPointerToThread->EnablePainting();
 
@@ -788,15 +786,17 @@ void _stdcall TerminalSetTheme(void* terminal, TerminalTheme theme, LPCWSTR font
     {
         auto lock = publicTerminal->_terminal->LockForWriting();
 
-        publicTerminal->_terminal->SetColorTableEntry(TextColor::DEFAULT_FOREGROUND, theme.DefaultForeground);
-        publicTerminal->_terminal->SetColorTableEntry(TextColor::DEFAULT_BACKGROUND, theme.DefaultBackground);
+        auto& renderSettings = publicTerminal->_terminal->GetRenderSettings();
+        renderSettings.SetColorTableEntry(TextColor::DEFAULT_FOREGROUND, theme.DefaultForeground);
+        renderSettings.SetColorTableEntry(TextColor::DEFAULT_BACKGROUND, theme.DefaultBackground);
+
         publicTerminal->_renderEngine->SetSelectionBackground(theme.DefaultSelectionBackground, theme.SelectionBackgroundAlpha);
 
         // Set the font colors
         for (size_t tableIndex = 0; tableIndex < 16; tableIndex++)
         {
             // It's using gsl::at to check the index is in bounds, but the analyzer still calls this array-to-pointer-decay
-            [[gsl::suppress(bounds .3)]] publicTerminal->_terminal->SetColorTableEntry(tableIndex, gsl::at(theme.ColorTable, tableIndex));
+            [[gsl::suppress(bounds .3)]] renderSettings.SetColorTableEntry(tableIndex, gsl::at(theme.ColorTable, tableIndex));
         }
     }
 
diff --git a/src/cascadia/TerminalControl/ControlCore.cpp b/src/cascadia/TerminalControl/ControlCore.cpp
index 616914bc462..cc14f228770 100644
--- a/src/cascadia/TerminalControl/ControlCore.cpp
+++ b/src/cascadia/TerminalControl/ControlCore.cpp
@@ -96,9 +96,6 @@ namespace winrt::Microsoft::Terminal::Control::implementation
         auto pfnTabColorChanged = std::bind(&ControlCore::_terminalTabColorChanged, this, std::placeholders::_1);
         _terminal->SetTabColorChangedCallback(pfnTabColorChanged);
 
-        auto pfnBackgroundColorChanged = std::bind(&ControlCore::_terminalBackgroundColorChanged, this, std::placeholders::_1);
-        _terminal->SetBackgroundCallback(pfnBackgroundColorChanged);
-
         auto pfnScrollPositionChanged = std::bind(&ControlCore::_terminalScrollPositionChanged, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3);
         _terminal->SetScrollPositionChangedCallback(pfnScrollPositionChanged);
 
@@ -128,6 +125,8 @@ namespace winrt::Microsoft::Terminal::Control::implementation
             const auto& renderSettings = _terminal->GetRenderSettings();
             _renderer = std::make_unique<::Microsoft::Console::Render::Renderer>(renderSettings, _terminal.get(), nullptr, 0, std::move(renderThread));
 
+            _renderer->SetBackgroundColorChangedCallback([this]() { _rendererBackgroundColorChanged(); });
+
             _renderer->SetRendererEnteredErrorStateCallback([weakThis = get_weak()]() {
                 if (auto strongThis{ weakThis.get() })
                 {
@@ -1153,21 +1152,6 @@ namespace winrt::Microsoft::Terminal::Control::implementation
         _TabColorChangedHandlers(*this, nullptr);
     }
 
-    // Method Description:
-    // - Called for the Terminal's BackgroundColorChanged callback. This will
-    //   re-raise a new winrt TypedEvent that can be listened to.
-    // - The listeners to this event will re-query the control for the current
-    //   value of BackgroundColor().
-    // Arguments:
-    // - <unused>
-    // Return Value:
-    // - <none>
-    void ControlCore::_terminalBackgroundColorChanged(const COLORREF /*color*/)
-    {
-        // Raise a BackgroundColorChanged event
-        _BackgroundColorChangedHandlers(*this, nullptr);
-    }
-
     // Method Description:
     // - Update the position and size of the scrollbar to match the given
     //      viewport top, viewport height, and buffer size.
@@ -1360,6 +1344,11 @@ namespace winrt::Microsoft::Terminal::Control::implementation
         _SwapChainChangedHandlers(*this, nullptr);
     }
 
+    void ControlCore::_rendererBackgroundColorChanged()
+    {
+        _BackgroundColorChangedHandlers(*this, nullptr);
+    }
+
     void ControlCore::BlinkAttributeTick()
     {
         auto lock = _terminal->LockForWriting();
@@ -1525,7 +1514,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
     {
         if (clearType == Control::ClearBufferType::Scrollback || clearType == Control::ClearBufferType::All)
         {
-            _terminal->EraseInDisplay(::Microsoft::Console::VirtualTerminal::DispatchTypes::EraseType::Scrollback);
+            _terminal->EraseScrollback();
         }
 
         if (clearType == Control::ClearBufferType::Screen || clearType == Control::ClearBufferType::All)
@@ -1684,8 +1673,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
 
         _renderEngine->SetSelectionBackground(til::color{ _settings->SelectionBackground() });
 
-        _renderer->TriggerRedrawAll();
-        _BackgroundColorChangedHandlers(*this, nullptr);
+        _renderer->TriggerRedrawAll(true);
     }
 
     bool ControlCore::HasUnfocusedAppearance() const
diff --git a/src/cascadia/TerminalControl/ControlCore.h b/src/cascadia/TerminalControl/ControlCore.h
index 36ce7fd1575..dfb40441130 100644
--- a/src/cascadia/TerminalControl/ControlCore.h
+++ b/src/cascadia/TerminalControl/ControlCore.h
@@ -265,7 +265,6 @@ namespace winrt::Microsoft::Terminal::Control::implementation
         void _terminalWarningBell();
         void _terminalTitleChanged(std::wstring_view wstr);
         void _terminalTabColorChanged(const std::optional<til::color> color);
-        void _terminalBackgroundColorChanged(const COLORREF color);
         void _terminalScrollPositionChanged(const int viewTop,
                                             const int viewHeight,
                                             const int bufferSize);
@@ -277,6 +276,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
 #pragma region RendererCallbacks
         void _rendererWarning(const HRESULT hr);
         void _renderEngineSwapChainChanged();
+        void _rendererBackgroundColorChanged();
 #pragma endregion
 
         void _raiseReadOnlyWarning();
diff --git a/src/cascadia/TerminalCore/ITerminalApi.hpp b/src/cascadia/TerminalCore/ITerminalApi.hpp
deleted file mode 100644
index 810e00dfab8..00000000000
--- a/src/cascadia/TerminalCore/ITerminalApi.hpp
+++ /dev/null
@@ -1,80 +0,0 @@
-// Copyright (c) Microsoft Corporation.
-// Licensed under the MIT license.
-#pragma once
-
-#include "../../terminal/adapter/DispatchTypes.hpp"
-#include "../../terminal/input/terminalInput.hpp"
-#include "../../buffer/out/TextAttribute.hpp"
-#include "../../renderer/inc/RenderSettings.hpp"
-#include "../../types/inc/Viewport.hpp"
-
-namespace Microsoft::Terminal::Core
-{
-    class ITerminalApi
-    {
-    public:
-        virtual ~ITerminalApi() {}
-        ITerminalApi(const ITerminalApi&) = default;
-        ITerminalApi(ITerminalApi&&) = default;
-        ITerminalApi& operator=(const ITerminalApi&) = default;
-        ITerminalApi& operator=(ITerminalApi&&) = default;
-
-        virtual void PrintString(std::wstring_view string) = 0;
-
-        virtual bool ReturnResponse(std::wstring_view responseString) = 0;
-
-        virtual TextAttribute GetTextAttributes() const = 0;
-        virtual void SetTextAttributes(const TextAttribute& attrs) = 0;
-
-        virtual Microsoft::Console::Types::Viewport GetBufferSize() = 0;
-        virtual void SetCursorPosition(til::point pos) = 0;
-        virtual til::point GetCursorPosition() = 0;
-        virtual void SetCursorVisibility(const bool visible) = 0;
-        virtual void CursorLineFeed(const bool withReturn) = 0;
-        virtual void EnableCursorBlinking(const bool enable) = 0;
-
-        virtual void DeleteCharacter(const til::CoordType count) = 0;
-        virtual void InsertCharacter(const til::CoordType count) = 0;
-        virtual void EraseCharacters(const til::CoordType numChars) = 0;
-        virtual bool EraseInLine(const ::Microsoft::Console::VirtualTerminal::DispatchTypes::EraseType eraseType) = 0;
-        virtual bool EraseInDisplay(const ::Microsoft::Console::VirtualTerminal::DispatchTypes::EraseType eraseType) = 0;
-
-        virtual void WarningBell() = 0;
-        virtual void SetWindowTitle(std::wstring_view title) = 0;
-
-        virtual COLORREF GetColorTableEntry(const size_t tableIndex) const = 0;
-        virtual void SetColorTableEntry(const size_t tableIndex, const COLORREF color) = 0;
-        virtual void SetColorAliasIndex(const ColorAlias alias, const size_t tableIndex) = 0;
-
-        virtual void SetCursorStyle(const ::Microsoft::Console::VirtualTerminal::DispatchTypes::CursorStyle cursorStyle) = 0;
-
-        virtual void SetInputMode(const ::Microsoft::Console::VirtualTerminal::TerminalInput::Mode mode, const bool enabled) = 0;
-        virtual void SetRenderMode(const ::Microsoft::Console::Render::RenderSettings::Mode mode, const bool enabled) = 0;
-
-        virtual void EnableXtermBracketedPasteMode(const bool enabled) = 0;
-        virtual bool IsXtermBracketedPasteModeEnabled() const = 0;
-
-        virtual bool IsVtInputEnabled() const = 0;
-
-        virtual void CopyToClipboard(std::wstring_view content) = 0;
-
-        virtual void AddHyperlink(std::wstring_view uri, std::wstring_view params) = 0;
-        virtual void EndHyperlink() = 0;
-
-        virtual void SetTaskbarProgress(const ::Microsoft::Console::VirtualTerminal::DispatchTypes::TaskbarState state, const size_t progress) = 0;
-
-        virtual void SetWorkingDirectory(std::wstring_view uri) = 0;
-        virtual std::wstring_view GetWorkingDirectory() = 0;
-
-        virtual void PushGraphicsRendition(const ::Microsoft::Console::VirtualTerminal::VTParameters options) = 0;
-        virtual void PopGraphicsRendition() = 0;
-
-        virtual void ShowWindow(bool showOrHide) = 0;
-
-        virtual void UseAlternateScreenBuffer() = 0;
-        virtual void UseMainScreenBuffer() = 0;
-
-    protected:
-        ITerminalApi() = default;
-    };
-}
diff --git a/src/cascadia/TerminalCore/Terminal.cpp b/src/cascadia/TerminalCore/Terminal.cpp
index 5c6a5f61f0c..648d7fff902 100644
--- a/src/cascadia/TerminalCore/Terminal.cpp
+++ b/src/cascadia/TerminalCore/Terminal.cpp
@@ -3,8 +3,8 @@
 
 #include "pch.h"
 #include "Terminal.hpp"
+#include "../../terminal/adapter/adaptDispatch.hpp"
 #include "../../terminal/parser/OutputStateMachineEngine.hpp"
-#include "TerminalDispatch.hpp"
 #include "../../inc/unicode.hpp"
 #include "../../types/inc/utils.hpp"
 #include "../../types/inc/colorTable.hpp"
@@ -50,19 +50,6 @@ Terminal::Terminal() :
     _taskbarProgress{ 0 },
     _trimBlockSelection{ false }
 {
-    auto dispatch = std::make_unique<TerminalDispatch>(*this);
-    auto engine = std::make_unique<OutputStateMachineEngine>(std::move(dispatch));
-
-    _stateMachine = std::make_unique<StateMachine>(std::move(engine));
-
-    // Until we have a true pass-through mode (GH#1173), the decision as to
-    // whether C1 controls are interpreted or not is made at the conhost level.
-    // If they are being filtered out, then we will simply never receive them.
-    // But if they are being accepted by conhost, there's a chance they may get
-    // passed through in some situations, so it's important that our state
-    // machine is always prepared to accept them.
-    _stateMachine->SetParserMode(StateMachine::Mode::AcceptC1, true);
-
     auto passAlongInput = [&](std::deque<std::unique_ptr<IInputEvent>>& inEventsToWrite) {
         if (!_pfnWriteInput)
         {
@@ -87,6 +74,18 @@ void Terminal::Create(COORD viewportSize, SHORT scrollbackLines, Renderer& rende
     const TextAttribute attr{};
     const UINT cursorSize = 12;
     _mainBuffer = std::make_unique<TextBuffer>(bufferSize, attr, cursorSize, true, renderer);
+
+    auto dispatch = std::make_unique<AdaptDispatch>(*this, renderer, _renderSettings, *_terminalInput);
+    auto engine = std::make_unique<OutputStateMachineEngine>(std::move(dispatch));
+    _stateMachine = std::make_unique<StateMachine>(std::move(engine));
+
+    // Until we have a true pass-through mode (GH#1173), the decision as to
+    // whether C1 controls are interpreted or not is made at the conhost level.
+    // If they are being filtered out, then we will simply never receive them.
+    // But if they are being accepted by conhost, there's a chance they may get
+    // passed through in some situations, so it's important that our state
+    // machine is always prepared to accept them.
+    _stateMachine->SetParserMode(StateMachine::Mode::AcceptC1, true);
 }
 
 // Method Description:
@@ -218,6 +217,28 @@ void Terminal::UpdateAppearance(const ICoreAppearance& appearance)
     _defaultCursorShape = cursorShape;
 }
 
+void Terminal::SetCursorStyle(const DispatchTypes::CursorStyle cursorStyle)
+{
+    auto& engine = reinterpret_cast<OutputStateMachineEngine&>(_stateMachine->Engine());
+    engine.Dispatch().SetCursorStyle(cursorStyle);
+}
+
+void Terminal::EraseScrollback()
+{
+    auto& engine = reinterpret_cast<OutputStateMachineEngine&>(_stateMachine->Engine());
+    engine.Dispatch().EraseInDisplay(DispatchTypes::EraseType::Scrollback);
+}
+
+bool Terminal::IsXtermBracketedPasteModeEnabled() const
+{
+    return _bracketedPasteMode;
+}
+
+std::wstring_view Terminal::GetWorkingDirectory()
+{
+    return _workingDirectory;
+}
+
 // Method Description:
 // - Resize the terminal as the result of some user interaction.
 // Arguments:
@@ -1271,15 +1292,6 @@ void Terminal::SetCursorPositionChangedCallback(std::function<void()> pfn) noexc
     _pfnCursorPositionChanged.swap(pfn);
 }
 
-// Method Description:
-// - Allows setting a callback for when the background color is changed
-// Arguments:
-// - pfn: a function callback that takes a color
-void Terminal::SetBackgroundCallback(std::function<void(const til::color)> pfn) noexcept
-{
-    _pfnBackgroundColorChanged.swap(pfn);
-}
-
 // Method Description:
 // - Allows settings a callback for settings the taskbar progress indicator
 // Arguments:
diff --git a/src/cascadia/TerminalCore/Terminal.hpp b/src/cascadia/TerminalCore/Terminal.hpp
index af936f550f6..99419b2b6f6 100644
--- a/src/cascadia/TerminalCore/Terminal.hpp
+++ b/src/cascadia/TerminalCore/Terminal.hpp
@@ -7,16 +7,14 @@
 
 #include "../../inc/DefaultSettings.h"
 #include "../../buffer/out/textBuffer.hpp"
-#include "../../types/inc/sgrStack.hpp"
 #include "../../renderer/inc/IRenderData.hpp"
-#include "../../renderer/inc/RenderSettings.hpp"
+#include "../../terminal/adapter/ITerminalApi.hpp"
 #include "../../terminal/parser/StateMachine.hpp"
 #include "../../terminal/input/terminalInput.hpp"
 
 #include "../../types/inc/Viewport.hpp"
 #include "../../types/inc/GlyphWidth.hpp"
 #include "../../types/IUiaData.h"
-#include "../../cascadia/terminalcore/ITerminalApi.hpp"
 #include "../../cascadia/terminalcore/ITerminalInput.hpp"
 
 #include <til/ticket_lock.h>
@@ -34,6 +32,11 @@ namespace winrt::Microsoft::Terminal::Core
     struct Scheme;
 }
 
+namespace Microsoft::Console::VirtualTerminal
+{
+    class AdaptDispatch;
+}
+
 namespace Microsoft::Terminal::Core
 {
     class Terminal;
@@ -51,7 +54,7 @@ namespace TerminalCoreUnitTests
 #endif
 
 class Microsoft::Terminal::Core::Terminal final :
-    public Microsoft::Terminal::Core::ITerminalApi,
+    public Microsoft::Console::VirtualTerminal::ITerminalApi,
     public Microsoft::Terminal::Core::ITerminalInput,
     public Microsoft::Console::Render::IRenderData,
     public Microsoft::Console::Types::IUiaData
@@ -76,6 +79,10 @@ class Microsoft::Terminal::Core::Terminal final :
     void UpdateSettings(winrt::Microsoft::Terminal::Core::ICoreSettings settings);
     void UpdateAppearance(const winrt::Microsoft::Terminal::Core::ICoreAppearance& appearance);
     void SetFontInfo(const FontInfo& fontInfo);
+    void SetCursorStyle(const ::Microsoft::Console::VirtualTerminal::DispatchTypes::CursorStyle cursorStyle);
+    void EraseScrollback();
+    bool IsXtermBracketedPasteModeEnabled() const;
+    std::wstring_view GetWorkingDirectory();
 
     // Write comes from the PTY and goes to our parser to be stored in the output buffer
     void Write(std::wstring_view stringView);
@@ -96,53 +103,33 @@ class Microsoft::Terminal::Core::Terminal final :
 
 #pragma region ITerminalApi
     // These methods are defined in TerminalApi.cpp
-    void PrintString(std::wstring_view stringView) override;
-    bool ReturnResponse(std::wstring_view responseString) override;
-    TextAttribute GetTextAttributes() const override;
+    void PrintString(const std::wstring_view string) override;
+    void ReturnResponse(const std::wstring_view response) override;
+    Microsoft::Console::VirtualTerminal::StateMachine& GetStateMachine() override;
+    TextBuffer& GetTextBuffer() override;
+    til::rect GetViewport() const override;
+    void SetViewportPosition(const til::point position) override;
     void SetTextAttributes(const TextAttribute& attrs) override;
-    Microsoft::Console::Types::Viewport GetBufferSize() override;
-    void SetCursorPosition(til::point pos) override;
-    til::point GetCursorPosition() override;
-    void SetCursorVisibility(const bool visible) override;
-    void EnableCursorBlinking(const bool enable) override;
-    void CursorLineFeed(const bool withReturn) override;
-    void DeleteCharacter(const til::CoordType count) override;
-    void InsertCharacter(const til::CoordType count) override;
-    void EraseCharacters(const til::CoordType numChars) override;
-    bool EraseInLine(const ::Microsoft::Console::VirtualTerminal::DispatchTypes::EraseType eraseType) override;
-    bool EraseInDisplay(const ::Microsoft::Console::VirtualTerminal::DispatchTypes::EraseType eraseType) override;
+    void SetAutoWrapMode(const bool wrapAtEOL) override;
+    void SetScrollingRegion(const til::inclusive_rect& scrollMargins) override;
     void WarningBell() override;
-    void SetWindowTitle(std::wstring_view title) override;
-    COLORREF GetColorTableEntry(const size_t tableIndex) const override;
-    void SetColorTableEntry(const size_t tableIndex, const COLORREF color) override;
-    void SetColorAliasIndex(const ColorAlias alias, const size_t tableIndex) override;
-    void SetCursorStyle(const ::Microsoft::Console::VirtualTerminal::DispatchTypes::CursorStyle cursorStyle) override;
-
-    void SetInputMode(const ::Microsoft::Console::VirtualTerminal::TerminalInput::Mode mode, const bool enabled) override;
-    void SetRenderMode(const ::Microsoft::Console::Render::RenderSettings::Mode mode, const bool enabled) override;
-
+    bool GetLineFeedMode() const override;
+    void LineFeed(const bool withReturn) override;
+    void SetWindowTitle(const std::wstring_view title) override;
+    CursorType GetUserDefaultCursorStyle() const override;
+    bool ResizeWindow(const size_t width, const size_t height) override;
+    void SetConsoleOutputCP(const unsigned int codepage) override;
+    unsigned int GetConsoleOutputCP() const override;
     void EnableXtermBracketedPasteMode(const bool enabled) override;
-    bool IsXtermBracketedPasteModeEnabled() const override;
-
-    bool IsVtInputEnabled() const override;
-
     void CopyToClipboard(std::wstring_view content) override;
-
-    void AddHyperlink(std::wstring_view uri, std::wstring_view params) override;
-    void EndHyperlink() override;
-
     void SetTaskbarProgress(const ::Microsoft::Console::VirtualTerminal::DispatchTypes::TaskbarState state, const size_t progress) override;
     void SetWorkingDirectory(std::wstring_view uri) override;
-    std::wstring_view GetWorkingDirectory() override;
-
-    void PushGraphicsRendition(const ::Microsoft::Console::VirtualTerminal::VTParameters options) override;
-    void PopGraphicsRendition() override;
-
     void ShowWindow(bool showOrHide) override;
-
     void UseAlternateScreenBuffer() override;
     void UseMainScreenBuffer() override;
-
+    bool IsConsolePty() const override;
+    bool IsVtInputEnabled() const override;
+    void NotifyAccessibilityChange(const til::rect& changedRect) override;
 #pragma endregion
 
 #pragma region ITerminalInput
@@ -169,8 +156,8 @@ class Microsoft::Terminal::Core::Terminal final :
 #pragma region IBaseData(base to IRenderData and IUiaData)
     Microsoft::Console::Types::Viewport GetViewport() noexcept override;
     COORD GetTextBufferEndPosition() const noexcept override;
-    const TextBuffer& GetTextBuffer() noexcept override;
-    const FontInfo& GetFontInfo() noexcept override;
+    const TextBuffer& GetTextBuffer() const noexcept override;
+    const FontInfo& GetFontInfo() const noexcept override;
 
     void LockConsole() noexcept override;
     void UnlockConsole() noexcept override;
@@ -213,7 +200,6 @@ class Microsoft::Terminal::Core::Terminal final :
     void SetCopyToClipboardCallback(std::function<void(std::wstring_view)> pfn) noexcept;
     void SetScrollPositionChangedCallback(std::function<void(const int, const int, const int)> pfn) noexcept;
     void SetCursorPositionChangedCallback(std::function<void()> pfn) noexcept;
-    void SetBackgroundCallback(std::function<void(const til::color)> pfn) noexcept;
     void TaskbarProgressChangedCallback(std::function<void()> pfn) noexcept;
     void SetShowWindowCallback(std::function<void(bool)> pfn) noexcept;
 
@@ -279,7 +265,6 @@ class Microsoft::Terminal::Core::Terminal final :
 #endif
 
     std::function<void(const int, const int, const int)> _pfnScrollPositionChanged;
-    std::function<void(const til::color)> _pfnBackgroundColorChanged;
     std::function<void()> _pfnCursorPositionChanged;
     std::function<void(const std::optional<til::color>)> _pfnTabColorChanged;
     std::function<void()> _pfnTaskbarProgressChanged;
@@ -404,8 +389,6 @@ class Microsoft::Terminal::Core::Terminal final :
     void _MoveByBuffer(SelectionDirection direction, COORD& pos);
 #pragma endregion
 
-    Microsoft::Console::VirtualTerminal::SgrStack _sgrStack;
-
 #ifdef UNIT_TESTING
     friend class TerminalCoreUnitTests::TerminalBufferTests;
     friend class TerminalCoreUnitTests::TerminalApiTest;
diff --git a/src/cascadia/TerminalCore/TerminalApi.cpp b/src/cascadia/TerminalCore/TerminalApi.cpp
index ff04aff29fd..c8af8f07b2b 100644
--- a/src/cascadia/TerminalCore/TerminalApi.cpp
+++ b/src/cascadia/TerminalCore/TerminalApi.cpp
@@ -11,307 +11,84 @@ using namespace Microsoft::Console::Types;
 using namespace Microsoft::Console::VirtualTerminal;
 
 // Print puts the text in the buffer and moves the cursor
-void Terminal::PrintString(std::wstring_view stringView)
+void Terminal::PrintString(const std::wstring_view string)
 {
-    _WriteBuffer(stringView);
+    _WriteBuffer(string);
 }
 
-TextAttribute Terminal::GetTextAttributes() const
+void Terminal::ReturnResponse(const std::wstring_view response)
 {
-    return _activeBuffer().GetCurrentAttributes();
-}
-
-bool Terminal::ReturnResponse(std::wstring_view responseString)
-{
-    if (!_pfnWriteInput)
+    if (_pfnWriteInput)
     {
-        return false;
+        _pfnWriteInput(response);
     }
-    _pfnWriteInput(responseString);
-    return true;
 }
 
-void Terminal::SetTextAttributes(const TextAttribute& attrs)
+Microsoft::Console::VirtualTerminal::StateMachine& Terminal::GetStateMachine()
 {
-    _activeBuffer().SetCurrentAttributes(attrs);
+    return *_stateMachine;
 }
 
-Viewport Terminal::GetBufferSize()
+TextBuffer& Terminal::GetTextBuffer()
 {
-    return _activeBuffer().GetSize();
+    return _activeBuffer();
 }
 
-void Terminal::SetCursorPosition(til::point pos)
+til::rect Terminal::GetViewport() const
 {
-    const auto viewport = _GetMutableViewport();
-    const til::point viewOrigin{ viewport.Origin() };
-    auto newPos = til::unwrap_coord(viewOrigin + pos);
-    viewport.Clamp(newPos);
-    _activeBuffer().GetCursor().SetPosition(newPos);
+    return til::rect{ _GetMutableViewport().ToInclusive() };
 }
 
-til::point Terminal::GetCursorPosition()
+void Terminal::SetViewportPosition(const til::point position)
 {
-    const til::point absoluteCursorPos{ _activeBuffer().GetCursor().GetPosition() };
-    const auto viewport = _GetMutableViewport();
-    const til::point viewOrigin{ viewport.Origin() };
-    // TODO assert that the coord is > (0, 0) && <(view.W, view.H)
-    return absoluteCursorPos - viewOrigin;
+    const auto dimensions = _GetMutableViewport().Dimensions();
+    _mutableViewport = Viewport::FromDimensions(position.to_win32_coord(), dimensions);
+    Terminal::_NotifyScrollEvent();
 }
 
-// Method Description:
-// - Moves the cursor down one line, and possibly also to the leftmost column.
-// Arguments:
-// - withReturn, set to true if a carriage return should be performed as well.
-// Return value:
-// - <none>
-void Terminal::CursorLineFeed(const bool withReturn)
+void Terminal::SetTextAttributes(const TextAttribute& attrs)
 {
-    auto cursorPos = _activeBuffer().GetCursor().GetPosition();
-
-    // since we explicitly just moved down a row, clear the wrap status on the
-    // row we just came from
-    _activeBuffer().GetRowByOffset(cursorPos.Y).SetWrapForced(false);
-
-    cursorPos.Y++;
-    if (withReturn)
-    {
-        cursorPos.X = 0;
-    }
-    _AdjustCursorPosition(cursorPos);
+    _activeBuffer().SetCurrentAttributes(attrs);
 }
 
-// Method Description:
-// - deletes count characters starting from the cursor's current position
-// - it moves over the remaining text to 'replace' the deleted text
-// - for example, if the buffer looks like this ('|' is the cursor): [abc|def]
-// - calling DeleteCharacter(1) will change it to: [abc|ef],
-// - i.e. the 'd' gets deleted and the 'ef' gets shifted over 1 space and **retain their previous text attributes**
-// Arguments:
-// - count, the number of characters to delete
-// Return value:
-// - <none>
-void Terminal::DeleteCharacter(const til::CoordType count)
+void Terminal::SetAutoWrapMode(const bool /*wrapAtEOL*/)
 {
-    const auto cursorPos = _activeBuffer().GetCursor().GetPosition();
-    const auto copyToPos = cursorPos;
-    const til::point copyFromPos{ cursorPos.X + count, cursorPos.Y };
-    const auto viewport = _GetMutableViewport();
-
-    const auto sourceWidth = viewport.RightExclusive() - copyFromPos.X;
-
-    // Get a rectangle of the source
-    auto source = Viewport::FromDimensions(til::unwrap_coord(copyFromPos), gsl::narrow<short>(sourceWidth), 1);
-
-    // Get a rectangle of the target
-    const auto target = Viewport::FromDimensions(copyToPos, source.Dimensions());
-    const auto walkDirection = Viewport::DetermineWalkDirection(source, target);
-
-    auto sourcePos = source.GetWalkOrigin(walkDirection);
-    auto targetPos = target.GetWalkOrigin(walkDirection);
-
-    // Iterate over the source cell data and copy it over to the target
-    do
-    {
-        const auto data = OutputCell(*(_activeBuffer().GetCellDataAt(sourcePos)));
-        _activeBuffer().Write(OutputCellIterator({ &data, 1 }), targetPos);
-    } while (source.WalkInBounds(sourcePos, walkDirection) && target.WalkInBounds(targetPos, walkDirection));
+    // TODO: This will be needed to support DECAWM.
 }
 
-// Method Description:
-// - Inserts count spaces starting from the cursor's current position, moving over the existing text
-// - for example, if the buffer looks like this ('|' is the cursor): [abc|def]
-// - calling InsertCharacter(1) will change it to: [abc| def],
-// - i.e. the 'def' gets shifted over 1 space and **retain their previous text attributes**
-// Arguments:
-// - count, the number of spaces to insert
-// Return value:
-// - <none>
-void Terminal::InsertCharacter(const til::CoordType count)
+void Terminal::SetScrollingRegion(const til::inclusive_rect& /*scrollMargins*/)
 {
-    // NOTE: the code below is _extremely_ similar to DeleteCharacter
-    // We will want to use this same logic and implement a helper function instead
-    // that does the 'move a region from here to there' operation
-    // TODO: GitHub issue #2163
-    const auto cursorPos = _activeBuffer().GetCursor().GetPosition();
-    const auto copyFromPos = cursorPos;
-    const til::point copyToPos{ cursorPos.X + count, cursorPos.Y };
-    const auto viewport = _GetMutableViewport();
-    const auto sourceWidth = viewport.RightExclusive() - copyFromPos.X;
-
-    // Get a rectangle of the source
-    auto source = Viewport::FromDimensions(copyFromPos, gsl::narrow<short>(sourceWidth), 1);
-
-    // Get a rectangle of the target
-    const auto target = Viewport::FromDimensions(til::unwrap_coord(copyToPos), source.Dimensions());
-    const auto walkDirection = Viewport::DetermineWalkDirection(source, target);
-
-    auto sourcePos = source.GetWalkOrigin(walkDirection);
-    auto targetPos = target.GetWalkOrigin(walkDirection);
-
-    // Iterate over the source cell data and copy it over to the target
-    do
-    {
-        const auto data = OutputCell(*(_activeBuffer().GetCellDataAt(sourcePos)));
-        _activeBuffer().Write(OutputCellIterator({ &data, 1 }), targetPos);
-    } while (source.WalkInBounds(sourcePos, walkDirection) && target.WalkInBounds(targetPos, walkDirection));
-    const auto eraseIter = OutputCellIterator(UNICODE_SPACE, _activeBuffer().GetCurrentAttributes(), count);
-    _activeBuffer().Write(eraseIter, cursorPos);
+    // TODO: This will be needed to fully support DECSTBM.
 }
 
-void Terminal::EraseCharacters(const til::CoordType numChars)
+void Terminal::WarningBell()
 {
-    const auto absoluteCursorPos = _activeBuffer().GetCursor().GetPosition();
-    const auto viewport = _GetMutableViewport();
-    const auto distanceToRight = viewport.RightExclusive() - absoluteCursorPos.X;
-    const auto fillLimit = std::min(numChars, distanceToRight);
-    const auto eraseIter = OutputCellIterator(UNICODE_SPACE, _activeBuffer().GetCurrentAttributes(), fillLimit);
-    _activeBuffer().Write(eraseIter, absoluteCursorPos);
+    _pfnWarningBell();
 }
 
-// Method description:
-// - erases a line of text, either from
-// 1. beginning to the cursor's position
-// 2. cursor's position to end
-// 3. beginning to end
-// - depending on the erase type
-// Arguments:
-// - the erase type
-// Return value:
-// - true if succeeded, false otherwise
-bool Terminal::EraseInLine(const ::Microsoft::Console::VirtualTerminal::DispatchTypes::EraseType eraseType)
+bool Terminal::GetLineFeedMode() const
 {
-    const auto cursorPos = _activeBuffer().GetCursor().GetPosition();
-    const auto viewport = _GetMutableViewport();
-    til::point startPos;
-    startPos.Y = cursorPos.Y;
-    // nlength determines the number of spaces we need to write
-    DWORD nlength = 0;
-
-    // Determine startPos.X and nlength by the eraseType
-    switch (eraseType)
-    {
-    case DispatchTypes::EraseType::FromBeginning:
-        nlength = cursorPos.X - viewport.Left() + 1;
-        break;
-    case DispatchTypes::EraseType::ToEnd:
-        startPos.X = cursorPos.X;
-        nlength = viewport.RightExclusive() - startPos.X;
-        break;
-    case DispatchTypes::EraseType::All:
-        startPos.X = viewport.Left();
-        nlength = viewport.RightExclusive() - startPos.X;
-        break;
-    default:
-        return false;
-    }
-
-    const auto eraseIter = OutputCellIterator(UNICODE_SPACE, _activeBuffer().GetCurrentAttributes(), nlength);
-
-    // Explicitly turn off end-of-line wrap-flag-setting when erasing cells.
-    _activeBuffer().Write(eraseIter, til::unwrap_coord(startPos), false);
-    return true;
+    // TODO: This will be needed to support LNM.
+    return false;
 }
 
-// Method description:
-// - erases text in the buffer in two ways depending on erase type
-// 1. 'erases' all text visible to the user (i.e. the text in the viewport)
-// 2. erases all the text in the scrollback
-// Arguments:
-// - the erase type
-// Return Value:
-// - true if succeeded, false otherwise
-bool Terminal::EraseInDisplay(const DispatchTypes::EraseType eraseType)
+void Terminal::LineFeed(const bool withReturn)
 {
-    // Store the relative cursor position so we can restore it later after we move the viewport
-    const auto cursorPos = _activeBuffer().GetCursor().GetPosition();
-#pragma warning(suppress : 26496) // This is written by ConvertToOrigin, cpp core checks is wrong saying it should be const.
-    auto relativeCursor = cursorPos;
-    const auto viewport = _GetMutableViewport();
-
-    viewport.ConvertToOrigin(&relativeCursor);
-
-    // Initialize the new location of the viewport
-    // the top and bottom parameters are determined by the eraseType
-    SMALL_RECT newWin;
-    newWin.Left = viewport.Left();
-    newWin.Right = viewport.RightExclusive();
-
-    if (eraseType == DispatchTypes::EraseType::All)
-    {
-        // If we're in the alt buffer, take a shortcut. Just increment the buffer enough to cycle the whole thing out and start fresh. This
-        if (_inAltBuffer())
-        {
-            for (auto i = 0; i < viewport.Height(); i++)
-            {
-                _activeBuffer().IncrementCircularBuffer();
-            }
-            return true;
-        }
-        // In this case, we simply move the viewport down, effectively pushing whatever text was on the screen into the scrollback
-        // and thus 'erasing' the text visible to the user
-        const auto coordLastChar = _activeBuffer().GetLastNonSpaceCharacter(viewport);
-        if (coordLastChar.X == 0 && coordLastChar.Y == 0)
-        {
-            // Nothing to clear, just return
-            return true;
-        }
-
-        short sNewTop = coordLastChar.Y + 1;
-
-        // Increment the circular buffer only if the new location of the viewport would be 'below' the buffer
-        const auto delta = (sNewTop + viewport.Height()) - (_activeBuffer().GetSize().Height());
-        for (auto i = 0; i < delta; i++)
-        {
-            _activeBuffer().IncrementCircularBuffer();
-            sNewTop--;
-        }
-
-        newWin.Top = sNewTop;
-        newWin.Bottom = sNewTop + viewport.Height();
-    }
-    else if (eraseType == DispatchTypes::EraseType::Scrollback)
-    {
-        // We only want to erase the scrollback, and leave everything else on the screen as it is
-        // so we grab the text in the viewport and rotate it up to the top of the buffer
-        COORD scrollFromPos{ 0, 0 };
-        viewport.ConvertFromOrigin(&scrollFromPos);
-        _activeBuffer().ScrollRows(scrollFromPos.Y, viewport.Height(), -scrollFromPos.Y);
-
-        // Since we only did a rotation, the text that was in the scrollback is now _below_ where we are going to move the viewport
-        // and we have to make sure we erase that text
-        const auto eraseStart = viewport.Height();
-        const auto eraseEnd = _activeBuffer().GetLastNonSpaceCharacter(viewport).Y;
-        for (auto i = eraseStart; i <= eraseEnd; i++)
-        {
-            _activeBuffer().GetRowByOffset(i).Reset(_activeBuffer().GetCurrentAttributes());
-        }
+    auto cursorPos = _activeBuffer().GetCursor().GetPosition();
 
-        // Reset the scroll offset now because there's nothing for the user to 'scroll' to
-        _scrollOffset = 0;
+    // since we explicitly just moved down a row, clear the wrap status on the
+    // row we just came from
+    _activeBuffer().GetRowByOffset(cursorPos.Y).SetWrapForced(false);
 
-        newWin.Top = 0;
-        newWin.Bottom = viewport.Height();
-    }
-    else
+    cursorPos.Y++;
+    if (withReturn)
     {
-        return false;
+        cursorPos.X = 0;
     }
-
-    // Move the viewport, adjust the scroll bar if needed, and restore the old cursor position
-    _mutableViewport = Viewport::FromExclusive(newWin);
-    Terminal::_NotifyScrollEvent();
-    SetCursorPosition(til::point{ relativeCursor });
-
-    return true;
-}
-
-void Terminal::WarningBell()
-{
-    _pfnWarningBell();
+    _AdjustCursorPosition(cursorPos);
 }
 
-void Terminal::SetWindowTitle(std::wstring_view title)
+void Terminal::SetWindowTitle(const std::wstring_view title)
 {
     if (!_suppressApplicationTitle)
     {
@@ -320,112 +97,26 @@ void Terminal::SetWindowTitle(std::wstring_view title)
     }
 }
 
-// Method Description:
-// - Retrieves the value in the colortable at the specified index.
-// Arguments:
-// - tableIndex: the index of the color table to retrieve.
-// Return Value:
-// - the COLORREF value for the color at that index in the table.
-COLORREF Terminal::GetColorTableEntry(const size_t tableIndex) const
+CursorType Terminal::GetUserDefaultCursorStyle() const
 {
-    return _renderSettings.GetColorTableEntry(tableIndex);
+    return _defaultCursorShape;
 }
 
-// Method Description:
-// - Updates the value in the colortable at index tableIndex to the new color
-//   color. color is a COLORREF, format 0x00BBGGRR.
-// Arguments:
-// - tableIndex: the index of the color table to update.
-// - color: the new COLORREF to use as that color table value.
-// Return Value:
-// - <none>
-void Terminal::SetColorTableEntry(const size_t tableIndex, const COLORREF color)
-{
-    _renderSettings.SetColorTableEntry(tableIndex, color);
-
-    if (tableIndex == _renderSettings.GetColorAliasIndex(ColorAlias::DefaultBackground))
-    {
-        _pfnBackgroundColorChanged(color);
-    }
-
-    // Repaint everything - the colors might have changed
-    _activeBuffer().TriggerRedrawAll();
-}
-
-// Method Description:
-// - Sets the position in the color table for the given color alias.
-// Arguments:
-// - alias: the color alias to update.
-// - tableIndex: the new position of the alias in the color table.
-// Return Value:
-// - <none>
-void Terminal::SetColorAliasIndex(const ColorAlias alias, const size_t tableIndex)
+bool Terminal::ResizeWindow(const size_t /*width*/, const size_t /*height*/)
 {
-    _renderSettings.SetColorAliasIndex(alias, tableIndex);
-}
-
-// Method Description:
-// - Sets the cursor style to the given style.
-// Arguments:
-// - cursorStyle: the style to be set for the cursor
-// Return Value:
-// - <none>
-void Terminal::SetCursorStyle(const DispatchTypes::CursorStyle cursorStyle)
-{
-    auto finalCursorType = CursorType::Legacy;
-    auto shouldBlink = false;
-
-    switch (cursorStyle)
-    {
-    case DispatchTypes::CursorStyle::UserDefault:
-        finalCursorType = _defaultCursorShape;
-        shouldBlink = true;
-        break;
-    case DispatchTypes::CursorStyle::BlinkingBlock:
-        finalCursorType = CursorType::FullBox;
-        shouldBlink = true;
-        break;
-    case DispatchTypes::CursorStyle::SteadyBlock:
-        finalCursorType = CursorType::FullBox;
-        shouldBlink = false;
-        break;
-    case DispatchTypes::CursorStyle::BlinkingUnderline:
-        finalCursorType = CursorType::Underscore;
-        shouldBlink = true;
-        break;
-    case DispatchTypes::CursorStyle::SteadyUnderline:
-        finalCursorType = CursorType::Underscore;
-        shouldBlink = false;
-        break;
-    case DispatchTypes::CursorStyle::BlinkingBar:
-        finalCursorType = CursorType::VerticalBar;
-        shouldBlink = true;
-        break;
-    case DispatchTypes::CursorStyle::SteadyBar:
-        finalCursorType = CursorType::VerticalBar;
-        shouldBlink = false;
-        break;
-
-    default:
-        // Invalid argument should be ignored.
-        return;
-    }
-
-    _activeBuffer().GetCursor().SetType(finalCursorType);
-    _activeBuffer().GetCursor().SetBlinkingAllowed(shouldBlink);
+    // TODO: This will be needed to support various resizing sequences. See also GH#1860.
+    return false;
 }
 
-void Terminal::SetInputMode(const TerminalInput::Mode mode, const bool enabled)
+void Terminal::SetConsoleOutputCP(const unsigned int /*codepage*/)
 {
-    _terminalInput->SetInputMode(mode, enabled);
+    // TODO: This will be needed to support 8-bit charsets and DOCS sequences.
 }
 
-void Terminal::SetRenderMode(const RenderSettings::Mode mode, const bool enabled)
+unsigned int Terminal::GetConsoleOutputCP() const
 {
-    _renderSettings.SetRenderMode(mode, enabled);
-
-    // Repaint everything - the colors will have changed
-    _activeBuffer().TriggerRedrawAll();
+    // TODO: See SetConsoleOutputCP above.
+    return CP_UTF8;
 }
 
 void Terminal::EnableXtermBracketedPasteMode(const bool enabled)
@@ -433,67 +124,11 @@ void Terminal::EnableXtermBracketedPasteMode(const bool enabled)
     _bracketedPasteMode = enabled;
 }
 
-bool Terminal::IsXtermBracketedPasteModeEnabled() const
-{
-    return _bracketedPasteMode;
-}
-
-bool Terminal::IsVtInputEnabled() const
-{
-    // We should never be getting this call in Terminal.
-    FAIL_FAST();
-}
-
-void Terminal::SetCursorVisibility(const bool visible)
-{
-    _activeBuffer().GetCursor().SetIsVisible(visible);
-}
-
-void Terminal::EnableCursorBlinking(const bool enable)
-{
-    _activeBuffer().GetCursor().SetBlinkingAllowed(enable);
-
-    // GH#2642 - From what we've gathered from other terminals, when blinking is
-    // disabled, the cursor should remain On always, and have the visibility
-    // controlled by the IsVisible property. So when you do a printf "\e[?12l"
-    // to disable blinking, the cursor stays stuck On. At this point, only the
-    // cursor visibility property controls whether the user can see it or not.
-    // (Yes, the cursor can be On and NOT Visible)
-    _activeBuffer().GetCursor().SetIsOn(true);
-}
-
 void Terminal::CopyToClipboard(std::wstring_view content)
 {
     _pfnCopyToClipboard(content);
 }
 
-// Method Description:
-// - Updates the buffer's current text attributes to start a hyperlink
-// Arguments:
-// - The hyperlink URI
-// - The customID provided (if there was one)
-// Return Value:
-// - <none>
-void Terminal::AddHyperlink(std::wstring_view uri, std::wstring_view params)
-{
-    auto attr = _activeBuffer().GetCurrentAttributes();
-    const auto id = _activeBuffer().GetHyperlinkId(uri, params);
-    attr.SetHyperlinkId(id);
-    _activeBuffer().SetCurrentAttributes(attr);
-    _activeBuffer().AddHyperlinkToMap(uri, id);
-}
-
-// Method Description:
-// - Updates the buffer's current text attributes to end a hyperlink
-// Return Value:
-// - <none>
-void Terminal::EndHyperlink()
-{
-    auto attr = _activeBuffer().GetCurrentAttributes();
-    attr.SetHyperlinkId(0);
-    _activeBuffer().SetCurrentAttributes(attr);
-}
-
 // Method Description:
 // - Updates the taskbar progress indicator
 // Arguments:
@@ -549,37 +184,6 @@ void Terminal::SetWorkingDirectory(std::wstring_view uri)
     _workingDirectory = uri;
 }
 
-std::wstring_view Terminal::GetWorkingDirectory()
-{
-    return _workingDirectory;
-}
-
-// Method Description:
-// - Saves the current text attributes to an internal stack.
-// Arguments:
-// - options, cOptions: if present, specify which portions of the current text attributes
-//   should be saved. Only a small subset of GraphicsOptions are actually supported;
-//   others are ignored. If no options are specified, all attributes are stored.
-// Return Value:
-// - <none>
-void Terminal::PushGraphicsRendition(const VTParameters options)
-{
-    _sgrStack.Push(_activeBuffer().GetCurrentAttributes(), options);
-}
-
-// Method Description:
-// - Restores text attributes from the internal stack. If only portions of text attributes
-//   were saved, combines those with the current attributes.
-// Arguments:
-// - <none>
-// Return Value:
-// - <none>
-void Terminal::PopGraphicsRendition()
-{
-    const auto current = _activeBuffer().GetCurrentAttributes();
-    _activeBuffer().SetCurrentAttributes(_sgrStack.Pop(current));
-}
-
 void Terminal::UseAlternateScreenBuffer()
 {
     // the new alt buffer is exactly the size of the viewport.
@@ -698,3 +302,18 @@ void Terminal::ShowWindow(bool showOrHide)
         _pfnShowWindowChanged(showOrHide);
     }
 }
+
+bool Terminal::IsConsolePty() const
+{
+    return false;
+}
+
+bool Terminal::IsVtInputEnabled() const
+{
+    return false;
+}
+
+void Terminal::NotifyAccessibilityChange(const til::rect& /*changedRect*/)
+{
+    // This is only needed in conhost. Terminal handles accessibility in another way.
+}
diff --git a/src/cascadia/TerminalCore/TerminalDispatch.cpp b/src/cascadia/TerminalCore/TerminalDispatch.cpp
deleted file mode 100644
index aff4f4efce7..00000000000
--- a/src/cascadia/TerminalCore/TerminalDispatch.cpp
+++ /dev/null
@@ -1,893 +0,0 @@
-// Copyright (c) Microsoft Corporation.
-// Licensed under the MIT license.
-
-#include "pch.h"
-#include "TerminalDispatch.hpp"
-#include "../../types/inc/utils.hpp"
-
-using namespace Microsoft::Console;
-using namespace ::Microsoft::Terminal::Core;
-using namespace ::Microsoft::Console::Render;
-using namespace ::Microsoft::Console::VirtualTerminal;
-
-// NOTE:
-// Functions related to Set Graphics Renditions (SGR) are in
-//      TerminalDispatchGraphics.cpp, not this file
-
-TerminalDispatch::TerminalDispatch(ITerminalApi& terminalApi) noexcept :
-    _terminalApi{ terminalApi }
-{
-}
-
-void TerminalDispatch::Print(const wchar_t wchPrintable)
-{
-    _terminalApi.PrintString({ &wchPrintable, 1 });
-}
-
-void TerminalDispatch::PrintString(const std::wstring_view string)
-{
-    _terminalApi.PrintString(string);
-}
-
-bool TerminalDispatch::CursorPosition(VTInt line,
-                                      VTInt column)
-{
-    _terminalApi.SetCursorPosition({ column - 1, line - 1 });
-    return true;
-}
-
-bool TerminalDispatch::CursorVisibility(const bool isVisible)
-{
-    _terminalApi.SetCursorVisibility(isVisible);
-    return true;
-}
-
-bool TerminalDispatch::EnableCursorBlinking(const bool enable)
-{
-    _terminalApi.EnableCursorBlinking(enable);
-    return true;
-}
-
-bool TerminalDispatch::CursorForward(const VTInt distance)
-{
-    const auto cursorPos = _terminalApi.GetCursorPosition();
-    _terminalApi.SetCursorPosition({ cursorPos.X + distance, cursorPos.Y });
-    return true;
-}
-
-bool TerminalDispatch::CursorBackward(const VTInt distance)
-{
-    const auto cursorPos = _terminalApi.GetCursorPosition();
-    _terminalApi.SetCursorPosition({ cursorPos.X - distance, cursorPos.Y });
-    return true;
-}
-
-bool TerminalDispatch::CursorUp(const VTInt distance)
-{
-    const auto cursorPos = _terminalApi.GetCursorPosition();
-    _terminalApi.SetCursorPosition({ cursorPos.X, cursorPos.Y + distance });
-    return true;
-}
-
-bool TerminalDispatch::LineFeed(const DispatchTypes::LineFeedType lineFeedType)
-{
-    switch (lineFeedType)
-    {
-    case DispatchTypes::LineFeedType::DependsOnMode:
-        // There is currently no need for mode-specific line feeds in the Terminal,
-        // so for now we just treat them as a line feed without carriage return.
-    case DispatchTypes::LineFeedType::WithoutReturn:
-        _terminalApi.CursorLineFeed(false);
-        return true;
-    case DispatchTypes::LineFeedType::WithReturn:
-        _terminalApi.CursorLineFeed(true);
-        return true;
-    default:
-        return false;
-    }
-}
-
-bool TerminalDispatch::EraseCharacters(const VTInt numChars)
-{
-    _terminalApi.EraseCharacters(numChars);
-    return true;
-}
-
-bool TerminalDispatch::WarningBell()
-{
-    _terminalApi.WarningBell();
-    return true;
-}
-
-bool TerminalDispatch::CarriageReturn()
-{
-    const auto cursorPos = _terminalApi.GetCursorPosition();
-    _terminalApi.SetCursorPosition({ 0, cursorPos.Y });
-    return true;
-}
-
-bool TerminalDispatch::SetWindowTitle(std::wstring_view title)
-{
-    _terminalApi.SetWindowTitle(title);
-    return true;
-}
-
-bool TerminalDispatch::HorizontalTabSet()
-{
-    const auto width = _terminalApi.GetBufferSize().Dimensions().X;
-    const auto column = _terminalApi.GetCursorPosition().X;
-
-    _InitTabStopsForWidth(width);
-    _tabStopColumns.at(column) = true;
-    return true;
-}
-
-bool TerminalDispatch::ForwardTab(const VTInt numTabs)
-{
-    const auto width = _terminalApi.GetBufferSize().Dimensions().X;
-    const auto cursorPosition = _terminalApi.GetCursorPosition();
-    auto column = cursorPosition.X;
-    const auto row = cursorPosition.Y;
-    VTInt tabsPerformed = 0;
-    _InitTabStopsForWidth(width);
-    while (column + 1 < width && tabsPerformed < numTabs)
-    {
-        column++;
-        if (til::at(_tabStopColumns, column))
-        {
-            tabsPerformed++;
-        }
-    }
-
-    _terminalApi.SetCursorPosition({ column, row });
-    return true;
-}
-
-bool TerminalDispatch::BackwardsTab(const VTInt numTabs)
-{
-    const auto width = _terminalApi.GetBufferSize().Dimensions().X;
-    const auto cursorPosition = _terminalApi.GetCursorPosition();
-    auto column = cursorPosition.X;
-    const auto row = cursorPosition.Y;
-    VTInt tabsPerformed = 0;
-    _InitTabStopsForWidth(width);
-    while (column > 0 && tabsPerformed < numTabs)
-    {
-        column--;
-        if (til::at(_tabStopColumns, column))
-        {
-            tabsPerformed++;
-        }
-    }
-
-    _terminalApi.SetCursorPosition({ column, row });
-    return true;
-}
-
-bool TerminalDispatch::TabClear(const DispatchTypes::TabClearType clearType)
-{
-    switch (clearType)
-    {
-    case DispatchTypes::TabClearType::ClearCurrentColumn:
-        _ClearSingleTabStop();
-        return true;
-    case DispatchTypes::TabClearType::ClearAllColumns:
-        _ClearAllTabStops();
-        return true;
-    default:
-        return false;
-    }
-}
-
-// Method Description:
-// - Sets a single entry of the colortable to a new value
-// Arguments:
-// - tableIndex: The VT color table index
-// - color: The new RGB color value to use.
-// Return Value:
-// - True.
-bool TerminalDispatch::SetColorTableEntry(const size_t tableIndex,
-                                          const DWORD color)
-{
-    _terminalApi.SetColorTableEntry(tableIndex, color);
-    return true;
-}
-
-bool TerminalDispatch::SetCursorStyle(const DispatchTypes::CursorStyle cursorStyle)
-{
-    _terminalApi.SetCursorStyle(cursorStyle);
-    return true;
-}
-
-bool TerminalDispatch::SetCursorColor(const DWORD color)
-{
-    _terminalApi.SetColorTableEntry(TextColor::CURSOR_COLOR, color);
-    return true;
-}
-
-bool TerminalDispatch::SetClipboard(std::wstring_view content)
-{
-    _terminalApi.CopyToClipboard(content);
-    return true;
-}
-
-// Method Description:
-// - Sets the default foreground color to a new value
-// Arguments:
-// - color: The new RGB color value to use, in 0x00BBGGRR form
-// Return Value:
-// - True.
-bool TerminalDispatch::SetDefaultForeground(const DWORD color)
-{
-    _terminalApi.SetColorAliasIndex(ColorAlias::DefaultForeground, TextColor::DEFAULT_FOREGROUND);
-    _terminalApi.SetColorTableEntry(TextColor::DEFAULT_FOREGROUND, color);
-    return true;
-}
-
-// Method Description:
-// - Sets the default background color to a new value
-// Arguments:
-// - color: The new RGB color value to use, in 0x00BBGGRR form
-// Return Value:
-// - True.
-bool TerminalDispatch::SetDefaultBackground(const DWORD color)
-{
-    _terminalApi.SetColorAliasIndex(ColorAlias::DefaultBackground, TextColor::DEFAULT_BACKGROUND);
-    _terminalApi.SetColorTableEntry(TextColor::DEFAULT_BACKGROUND, color);
-    return true;
-}
-
-// Method Description:
-// - Erases characters in the buffer depending on the erase type
-// Arguments:
-// - eraseType: the erase type (from beginning, to end, or all)
-// Return Value:
-// True if handled successfully. False otherwise.
-bool TerminalDispatch::EraseInLine(const DispatchTypes::EraseType eraseType)
-{
-    return _terminalApi.EraseInLine(eraseType);
-}
-
-// Method Description:
-// - Deletes count number of characters starting from where the cursor is currently
-// Arguments:
-// - count, the number of characters to delete
-// Return Value:
-// - True.
-bool TerminalDispatch::DeleteCharacter(const VTInt count)
-{
-    _terminalApi.DeleteCharacter(count);
-    return true;
-}
-
-// Method Description:
-// - Adds count number of spaces starting from where the cursor is currently
-// Arguments:
-// - count, the number of spaces to add
-// Return Value:
-// - True.
-bool TerminalDispatch::InsertCharacter(const VTInt count)
-{
-    _terminalApi.InsertCharacter(count);
-    return true;
-}
-
-// Method Description:
-// - Moves the viewport and erases text from the buffer depending on the eraseType
-// Arguments:
-// - eraseType: the desired erase type
-// Return Value:
-// True if handled successfully. False otherwise
-bool TerminalDispatch::EraseInDisplay(const DispatchTypes::EraseType eraseType)
-{
-    return _terminalApi.EraseInDisplay(eraseType);
-}
-
-// - DECKPAM, DECKPNM - Sets the keypad input mode to either Application mode or Numeric mode (true, false respectively)
-// Arguments:
-// - applicationMode - set to true to enable Application Mode Input, false for Numeric Mode Input.
-// Return Value:
-// - True.
-bool TerminalDispatch::SetKeypadMode(const bool applicationMode)
-{
-    _terminalApi.SetInputMode(TerminalInput::Mode::Keypad, applicationMode);
-    return true;
-}
-
-// - DECCKM - Sets the cursor keys input mode to either Application mode or Normal mode (true, false respectively)
-// Arguments:
-// - applicationMode - set to true to enable Application Mode Input, false for Normal Mode Input.
-// Return Value:
-// - True.
-bool TerminalDispatch::SetCursorKeysMode(const bool applicationMode)
-{
-    _terminalApi.SetInputMode(TerminalInput::Mode::CursorKey, applicationMode);
-    return true;
-}
-
-// Routine Description:
-// - DECSCNM - Sets the screen mode to either normal or reverse.
-//    When in reverse screen mode, the background and foreground colors are switched.
-// Arguments:
-// - reverseMode - set to true to enable reverse screen mode, false for normal mode.
-// Return Value:
-// - True.
-bool TerminalDispatch::SetScreenMode(const bool reverseMode)
-{
-    _terminalApi.SetRenderMode(RenderSettings::Mode::ScreenReversed, reverseMode);
-    return true;
-}
-
-// Method Description:
-// - win32-input-mode: Enable sending full input records encoded as a string of
-//   characters to the client application.
-// Arguments:
-// - win32InputMode - set to true to enable win32-input-mode, false to disable.
-// Return Value:
-// - True.
-bool TerminalDispatch::EnableWin32InputMode(const bool win32Mode)
-{
-    _terminalApi.SetInputMode(TerminalInput::Mode::Win32, win32Mode);
-    return true;
-}
-
-//Routine Description:
-// Enable VT200 Mouse Mode - Enables/disables the mouse input handler in default tracking mode.
-//Arguments:
-// - enabled - true to enable, false to disable.
-// Return value:
-// - True.
-bool TerminalDispatch::EnableVT200MouseMode(const bool enabled)
-{
-    _terminalApi.SetInputMode(TerminalInput::Mode::DefaultMouseTracking, enabled);
-    return true;
-}
-
-//Routine Description:
-// Enable UTF-8 Extended Encoding - this changes the encoding scheme for sequences
-//      emitted by the mouse input handler. Does not enable/disable mouse mode on its own.
-//Arguments:
-// - enabled - true to enable, false to disable.
-// Return value:
-// - True.
-bool TerminalDispatch::EnableUTF8ExtendedMouseMode(const bool enabled)
-{
-    _terminalApi.SetInputMode(TerminalInput::Mode::Utf8MouseEncoding, enabled);
-    return true;
-}
-
-//Routine Description:
-// Enable SGR Extended Encoding - this changes the encoding scheme for sequences
-//      emitted by the mouse input handler. Does not enable/disable mouse mode on its own.
-//Arguments:
-// - enabled - true to enable, false to disable.
-// Return value:
-// - True.
-bool TerminalDispatch::EnableSGRExtendedMouseMode(const bool enabled)
-{
-    _terminalApi.SetInputMode(TerminalInput::Mode::SgrMouseEncoding, enabled);
-    return true;
-}
-
-//Routine Description:
-// Enable Button Event mode - send mouse move events WITH A BUTTON PRESSED to the input.
-//Arguments:
-// - enabled - true to enable, false to disable.
-// Return value:
-// - True.
-bool TerminalDispatch::EnableButtonEventMouseMode(const bool enabled)
-{
-    _terminalApi.SetInputMode(TerminalInput::Mode::ButtonEventMouseTracking, enabled);
-    return true;
-}
-
-//Routine Description:
-// Enable Any Event mode - send all mouse events to the input.
-//Arguments:
-// - enabled - true to enable, false to disable.
-// Return value:
-// - True.
-bool TerminalDispatch::EnableAnyEventMouseMode(const bool enabled)
-{
-    _terminalApi.SetInputMode(TerminalInput::Mode::AnyEventMouseTracking, enabled);
-    return true;
-}
-
-// Method Description:
-// - Enables/disables focus event mode. A client may enable this if they want to
-//   receive focus events.
-// - ConPTY always enables this mode and never disables it. For more details, see GH#12900.
-// Arguments:
-// - enabled - true to enable, false to disable.
-// Return Value:
-// - True if handled successfully. False otherwise.
-bool TerminalDispatch::EnableFocusEventMode(const bool enabled)
-{
-    _terminalApi.SetInputMode(TerminalInput::Mode::FocusEvent, enabled);
-    return true;
-}
-
-//Routine Description:
-// Enable Alternate Scroll Mode - When in the Alt Buffer, send CUP and CUD on
-//      scroll up/down events instead of the usual sequences
-//Arguments:
-// - enabled - true to enable, false to disable.
-// Return value:
-// - True.
-bool TerminalDispatch::EnableAlternateScroll(const bool enabled)
-{
-    _terminalApi.SetInputMode(TerminalInput::Mode::AlternateScroll, enabled);
-    return true;
-}
-
-//Routine Description:
-// Enable Bracketed Paste Mode -  this changes the behavior of pasting.
-//      See: https://www.xfree86.org/current/ctlseqs.html#Bracketed%20Paste%20Mode
-//Arguments:
-// - enabled - true to enable, false to disable.
-// Return value:
-// - True.
-bool TerminalDispatch::EnableXtermBracketedPasteMode(const bool enabled)
-{
-    _terminalApi.EnableXtermBracketedPasteMode(enabled);
-    return true;
-}
-
-bool TerminalDispatch::SetMode(const DispatchTypes::ModeParams param)
-{
-    return _ModeParamsHelper(param, true);
-}
-
-bool TerminalDispatch::ResetMode(const DispatchTypes::ModeParams param)
-{
-    return _ModeParamsHelper(param, false);
-}
-
-// Routine Description:
-// - DSR - Reports status of a console property back to the STDIN based on the type of status requested.
-//       - This particular routine responds to ANSI status patterns only (CSI # n), not the DEC format (CSI ? # n)
-// Arguments:
-// - statusType - ANSI status type indicating what property we should report back
-// Return Value:
-// - True if handled successfully. False otherwise.
-bool TerminalDispatch::DeviceStatusReport(const DispatchTypes::AnsiStatusType statusType)
-{
-    auto success = false;
-
-    switch (statusType)
-    {
-    case DispatchTypes::AnsiStatusType::OS_OperatingStatus:
-        success = _OperatingStatus();
-        break;
-    case DispatchTypes::AnsiStatusType::CPR_CursorPositionReport:
-        success = _CursorPositionReport();
-        break;
-    }
-
-    return success;
-}
-
-// Routine Description:
-// - DSR-OS - Reports the operating status back to the input channel
-// Arguments:
-// - <none>
-// Return Value:
-// - True if handled successfully. False otherwise.
-bool TerminalDispatch::_OperatingStatus() const
-{
-    // We always report a good operating condition.
-    return _WriteResponse(L"\x1b[0n");
-}
-
-// Routine Description:
-// - DSR-CPR - Reports the current cursor position within the viewport back to the input channel
-// Arguments:
-// - <none>
-// Return Value:
-// - True if handled successfully. False otherwise.
-bool TerminalDispatch::_CursorPositionReport() const
-{
-    // Now send it back into the input channel of the console.
-    // First format the response string.
-    const auto pos = _terminalApi.GetCursorPosition();
-    // VT has origin at 1,1 where as we use 0,0 internally
-    const auto response = wil::str_printf<std::wstring>(L"\x1b[%d;%dR", pos.Y + 1, pos.X + 1);
-    return _WriteResponse(response);
-}
-
-// Method Description:
-// - Start a hyperlink
-// Arguments:
-// - uri - the hyperlink URI
-// - params - the optional custom ID
-// Return Value:
-// - true
-bool TerminalDispatch::AddHyperlink(const std::wstring_view uri, const std::wstring_view params)
-{
-    _terminalApi.AddHyperlink(uri, params);
-    return true;
-}
-
-// Method Description:
-// - End a hyperlink
-// Return Value:
-// - true
-bool TerminalDispatch::EndHyperlink()
-{
-    _terminalApi.EndHyperlink();
-    return true;
-}
-
-// Method Description:
-// - Performs a ConEmu action
-// - Currently, the only action we support is setting the taskbar state/progress
-// Arguments:
-// - string: contains the parameters that define which action we do
-// Return Value:
-// - true
-bool TerminalDispatch::DoConEmuAction(const std::wstring_view string)
-{
-    unsigned int state = 0;
-    unsigned int progress = 0;
-
-    const auto parts = Utils::SplitString(string, L';');
-    unsigned int subParam = 0;
-
-    if (parts.size() < 1 || !Utils::StringToUint(til::at(parts, 0), subParam))
-    {
-        return false;
-    }
-
-    // 4 is SetProgressBar, which sets the taskbar state/progress.
-    if (subParam == 4)
-    {
-        if (parts.size() >= 2)
-        {
-            // A state parameter is defined, parse it out
-            const auto stateSuccess = Utils::StringToUint(til::at(parts, 1), state);
-            if (!stateSuccess && !til::at(parts, 1).empty())
-            {
-                return false;
-            }
-            if (parts.size() >= 3)
-            {
-                // A progress parameter is also defined, parse it out
-                const auto progressSuccess = Utils::StringToUint(til::at(parts, 2), progress);
-                if (!progressSuccess && !til::at(parts, 2).empty())
-                {
-                    return false;
-                }
-            }
-        }
-
-        if (state > TaskbarMaxState)
-        {
-            // state is out of bounds, return false
-            return false;
-        }
-        if (progress > TaskbarMaxProgress)
-        {
-            // progress is greater than the maximum allowed value, clamp it to the max
-            progress = TaskbarMaxProgress;
-        }
-        _terminalApi.SetTaskbarProgress(static_cast<DispatchTypes::TaskbarState>(state), progress);
-        return true;
-    }
-    // 9 is SetWorkingDirectory, which informs the terminal about the current working directory.
-    else if (subParam == 9)
-    {
-        if (parts.size() >= 2)
-        {
-            const auto path = til::at(parts, 1);
-            // The path should be surrounded with '"' according to the documentation of ConEmu.
-            // An example: 9;"D:/"
-            if (path.at(0) == L'"' && path.at(path.size() - 1) == L'"' && path.size() >= 3)
-            {
-                _terminalApi.SetWorkingDirectory(path.substr(1, path.size() - 2));
-            }
-            else
-            {
-                // If we fail to find the surrounding quotation marks, we'll give the path a try anyway.
-                // ConEmu also does this.
-                _terminalApi.SetWorkingDirectory(path);
-            }
-            return true;
-        }
-    }
-
-    return false;
-}
-
-// Routine Description:
-// - Helper to send a string reply to the input stream of the console.
-// - Used by various commands where the program attached would like a reply to one of the commands issued.
-// Arguments:
-// - reply - The reply string to transmit back to the input stream
-// Return Value:
-// - True if the string was sent to the connected application. False otherwise.
-bool TerminalDispatch::_WriteResponse(const std::wstring_view reply) const
-{
-    return _terminalApi.ReturnResponse(reply);
-}
-
-// Routine Description:
-// - Support routine for routing private mode parameters to be set/reset as flags
-// Arguments:
-// - param - mode parameter to set/reset
-// - enable - True for set, false for unset.
-// Return Value:
-// - True if handled successfully. False otherwise.
-bool TerminalDispatch::_ModeParamsHelper(const DispatchTypes::ModeParams param, const bool enable)
-{
-    auto success = false;
-    switch (param)
-    {
-    case DispatchTypes::ModeParams::DECCKM_CursorKeysMode:
-        // set - Enable Application Mode, reset - Normal mode
-        success = SetCursorKeysMode(enable);
-        break;
-    case DispatchTypes::ModeParams::DECSCNM_ScreenMode:
-        success = SetScreenMode(enable);
-        break;
-    case DispatchTypes::ModeParams::VT200_MOUSE_MODE:
-        success = EnableVT200MouseMode(enable);
-        break;
-    case DispatchTypes::ModeParams::BUTTON_EVENT_MOUSE_MODE:
-        success = EnableButtonEventMouseMode(enable);
-        break;
-    case DispatchTypes::ModeParams::ANY_EVENT_MOUSE_MODE:
-        success = EnableAnyEventMouseMode(enable);
-        break;
-    case DispatchTypes::ModeParams::UTF8_EXTENDED_MODE:
-        success = EnableUTF8ExtendedMouseMode(enable);
-        break;
-    case DispatchTypes::ModeParams::SGR_EXTENDED_MODE:
-        success = EnableSGRExtendedMouseMode(enable);
-        break;
-    case DispatchTypes::ModeParams::FOCUS_EVENT_MODE:
-        success = EnableFocusEventMode(enable);
-        break;
-    case DispatchTypes::ModeParams::ALTERNATE_SCROLL:
-        success = EnableAlternateScroll(enable);
-        break;
-    case DispatchTypes::ModeParams::DECTCEM_TextCursorEnableMode:
-        success = CursorVisibility(enable);
-        break;
-    case DispatchTypes::ModeParams::ATT610_StartCursorBlink:
-        success = EnableCursorBlinking(enable);
-        break;
-    case DispatchTypes::ModeParams::XTERM_BracketedPasteMode:
-        success = EnableXtermBracketedPasteMode(enable);
-        break;
-    case DispatchTypes::ModeParams::W32IM_Win32InputMode:
-        success = EnableWin32InputMode(enable);
-        break;
-    case DispatchTypes::ModeParams::ASB_AlternateScreenBuffer:
-        success = enable ? UseAlternateScreenBuffer() : UseMainScreenBuffer();
-        break;
-    default:
-        // If no functions to call, overall dispatch was a failure.
-        success = false;
-        break;
-    }
-    return success;
-}
-
-void TerminalDispatch::_ClearSingleTabStop()
-{
-    const auto width = _terminalApi.GetBufferSize().Dimensions().X;
-    const auto column = _terminalApi.GetCursorPosition().X;
-
-    _InitTabStopsForWidth(width);
-    _tabStopColumns.at(column) = false;
-}
-
-void TerminalDispatch::_ClearAllTabStops()
-{
-    _tabStopColumns.clear();
-    _initDefaultTabStops = false;
-}
-
-void TerminalDispatch::_ResetTabStops()
-{
-    _tabStopColumns.clear();
-    _initDefaultTabStops = true;
-}
-
-void TerminalDispatch::_InitTabStopsForWidth(const size_t width)
-{
-    const auto initialWidth = _tabStopColumns.size();
-    if (width > initialWidth)
-    {
-        _tabStopColumns.resize(width);
-        if (_initDefaultTabStops)
-        {
-            for (auto column = 8u; column < _tabStopColumns.size(); column += 8)
-            {
-                if (column >= initialWidth)
-                {
-                    til::at(_tabStopColumns, column) = true;
-                }
-            }
-        }
-    }
-}
-
-bool TerminalDispatch::SoftReset()
-{
-    // TODO:GH#1883 much of this method is not yet implemented in the Terminal,
-    // because the Terminal _doesn't need to_ yet. The terminal is only ever
-    // connected to conpty, so it doesn't implement most of these things that
-    // Hard/Soft Reset would reset. As those things are implemented, they should
-
-    // also get cleared here.
-    //
-    // This code is left here (from its original form in conhost) as a reminder
-    // of what needs to be done.
-
-    CursorVisibility(true); // Cursor enabled.
-    // SetOriginMode(false); // Absolute cursor addressing.
-    // SetAutoWrapMode(true); // Wrap at end of line.
-    SetCursorKeysMode(false); // Normal characters.
-    SetKeypadMode(false); // Numeric characters.
-
-    // // Top margin = 1; bottom margin = page length.
-    // _DoSetTopBottomScrollingMargins(0, 0);
-
-    // _termOutput = {}; // Reset all character set designations.
-    // if (_initialCodePage.has_value())
-    // {
-    //     // Restore initial code page if previously changed by a DOCS sequence.
-    //     _pConApi->SetConsoleOutputCP(_initialCodePage.value());
-    // }
-
-    SetGraphicsRendition({}); // Normal rendition.
-
-    // // Reset the saved cursor state.
-    // // Note that XTerm only resets the main buffer state, but that
-    // // seems likely to be a bug. Most other terminals reset both.
-    // _savedCursorState.at(0) = {}; // Main buffer
-    // _savedCursorState.at(1) = {}; // Alt buffer
-
-    return true;
-}
-
-bool TerminalDispatch::HardReset()
-{
-    // TODO:GH#1883 much of this method is not yet implemented in the Terminal,
-    // because the Terminal _doesn't need to_ yet. The terminal is only ever
-    // connected to conpty, so it doesn't implement most of these things that
-    // Hard/Soft Reset would reset. As those things ar implemented, they should
-    // also get cleared here.
-    //
-    // This code is left here (from its original form in conhost) as a reminder
-    // of what needs to be done.
-
-    // // If in the alt buffer, switch back to main before doing anything else.
-    // if (_usingAltBuffer)
-    // {
-    //     _pConApi->PrivateUseMainScreenBuffer();
-    //     _usingAltBuffer = false;
-    // }
-
-    // Sets the SGR state to normal - this must be done before EraseInDisplay
-    //      to ensure that it clears with the default background color.
-    SoftReset();
-
-    // Clears the screen - Needs to be done in two operations.
-    EraseInDisplay(DispatchTypes::EraseType::All);
-    EraseInDisplay(DispatchTypes::EraseType::Scrollback);
-
-    // Set the DECSCNM screen mode back to normal.
-    SetScreenMode(false);
-
-    // Cursor to 1,1 - the Soft Reset guarantees this is absolute
-    CursorPosition(1, 1);
-
-    // Reset the mouse mode
-    EnableSGRExtendedMouseMode(false);
-    EnableAnyEventMouseMode(false);
-
-    // Delete all current tab stops and reapply
-    _ResetTabStops();
-
-    return true;
-}
-
-bool TerminalDispatch::WindowManipulation(const DispatchTypes::WindowManipulationType function,
-                                          const VTParameter /*parameter1*/,
-                                          const VTParameter /*parameter2*/)
-{
-    switch (function)
-    {
-    case DispatchTypes::WindowManipulationType::DeIconifyWindow:
-        _terminalApi.ShowWindow(true);
-        return true;
-    case DispatchTypes::WindowManipulationType::IconifyWindow:
-        _terminalApi.ShowWindow(false);
-        return true;
-    default:
-        return false;
-    }
-}
-
-// Routine Description:
-// - DECSC - Saves the current "cursor state" into a memory buffer. This
-//   includes the cursor position, origin mode, graphic rendition, and
-//   active character set.
-// Arguments:
-// - <none>
-// Return Value:
-// - True.
-bool TerminalDispatch::CursorSaveState()
-{
-    // TODO GH#3849: When de-duplicating this, the AdaptDispatch version of this
-    // is more elaborate.
-    const auto attributes = _terminalApi.GetTextAttributes();
-    const auto coordCursor = _terminalApi.GetCursorPosition();
-    // The cursor is given to us by the API as relative to current viewport top.
-
-    // VT is also 1 based, not 0 based, so correct by 1.
-    auto& savedCursorState = _savedCursorState.at(_usingAltBuffer);
-    savedCursorState.Column = coordCursor.X + 1;
-    savedCursorState.Row = coordCursor.Y + 1;
-    savedCursorState.Attributes = attributes;
-
-    return true;
-}
-
-// Routine Description:
-// - DECRC - Restores a saved "cursor state" from the DECSC command back into
-//   the console state. This includes the cursor position, origin mode, graphic
-//   rendition, and active character set.
-// Arguments:
-// - <none>
-// Return Value:
-// - True.
-bool TerminalDispatch::CursorRestoreState()
-{
-    // TODO GH#3849: When de-duplicating this, the AdaptDispatch version of this
-    // is more elaborate.
-    auto& savedCursorState = _savedCursorState.at(_usingAltBuffer);
-
-    auto row = savedCursorState.Row;
-    const auto col = savedCursorState.Column;
-
-    // The saved coordinates are always absolute, so we need reset the origin mode temporarily.
-    CursorPosition(row, col);
-
-    // Restore text attributes.
-    _terminalApi.SetTextAttributes(savedCursorState.Attributes);
-
-    return true;
-}
-
-// - ASBSET - Creates and swaps to the alternate screen buffer. In virtual terminals, there exists both a "main"
-//     screen buffer and an alternate. ASBSET creates a new alternate, and switches to it. If there is an already
-//     existing alternate, it is discarded.
-// Arguments:
-// - None
-// Return Value:
-// - True.
-bool TerminalDispatch::UseAlternateScreenBuffer()
-{
-    CursorSaveState();
-    _terminalApi.UseAlternateScreenBuffer();
-    _usingAltBuffer = true;
-    return true;
-}
-
-// Routine Description:
-// - ASBRST - From the alternate buffer, returns to the main screen buffer.
-//     From the main screen buffer, does nothing. The alternate is discarded.
-// Arguments:
-// - None
-// Return Value:
-// - True.
-bool TerminalDispatch::UseMainScreenBuffer()
-{
-    _terminalApi.UseMainScreenBuffer();
-    _usingAltBuffer = false;
-    CursorRestoreState();
-    return true;
-}
diff --git a/src/cascadia/TerminalCore/TerminalDispatch.hpp b/src/cascadia/TerminalCore/TerminalDispatch.hpp
deleted file mode 100644
index 064a1fce9d1..00000000000
--- a/src/cascadia/TerminalCore/TerminalDispatch.hpp
+++ /dev/null
@@ -1,135 +0,0 @@
-// Copyright (c) Microsoft Corporation.
-// Licensed under the MIT license.
-
-#include "../../terminal/adapter/termDispatch.hpp"
-#include "ITerminalApi.hpp"
-
-static constexpr size_t TaskbarMaxState{ 4 };
-static constexpr size_t TaskbarMaxProgress{ 100 };
-
-class TerminalDispatch : public Microsoft::Console::VirtualTerminal::TermDispatch
-{
-    using VTInt = Microsoft::Console::VirtualTerminal::VTInt;
-
-public:
-    TerminalDispatch(::Microsoft::Terminal::Core::ITerminalApi& terminalApi) noexcept;
-
-    void Print(const wchar_t wchPrintable) override;
-    void PrintString(const std::wstring_view string) override;
-
-    bool SetGraphicsRendition(const ::Microsoft::Console::VirtualTerminal::VTParameters options) override;
-
-    bool PushGraphicsRendition(const ::Microsoft::Console::VirtualTerminal::VTParameters options) override;
-    bool PopGraphicsRendition() override;
-
-    bool CursorPosition(const VTInt line,
-                        const VTInt column) override; // CUP
-
-    bool EnableWin32InputMode(const bool win32InputMode) override; // win32-input-mode
-
-    bool CursorVisibility(const bool isVisible) override; // DECTCEM
-    bool EnableCursorBlinking(const bool enable) override; // ATT610
-
-    bool CursorForward(const VTInt distance) override;
-    bool CursorBackward(const VTInt distance) override;
-    bool CursorUp(const VTInt distance) override;
-
-    bool LineFeed(const ::Microsoft::Console::VirtualTerminal::DispatchTypes::LineFeedType lineFeedType) override;
-
-    bool EraseCharacters(const VTInt numChars) override;
-    bool WarningBell() override;
-    bool CarriageReturn() override;
-    bool SetWindowTitle(std::wstring_view title) override;
-
-    bool UseAlternateScreenBuffer() override; // ASBSET
-    bool UseMainScreenBuffer() override; // ASBRST
-
-    bool HorizontalTabSet() override; // HTS
-    bool ForwardTab(const VTInt numTabs) override; // CHT, HT
-    bool BackwardsTab(const VTInt numTabs) override; // CBT
-    bool TabClear(const ::Microsoft::Console::VirtualTerminal::DispatchTypes::TabClearType clearType) override; // TBC
-
-    bool SetColorTableEntry(const size_t tableIndex, const DWORD color) override;
-    bool SetCursorStyle(const ::Microsoft::Console::VirtualTerminal::DispatchTypes::CursorStyle cursorStyle) override;
-    bool SetCursorColor(const DWORD color) override;
-
-    bool SetClipboard(std::wstring_view content) override;
-
-    bool SetDefaultForeground(const DWORD color) override;
-    bool SetDefaultBackground(const DWORD color) override;
-    bool EraseInLine(const ::Microsoft::Console::VirtualTerminal::DispatchTypes::EraseType eraseType) override; // ED
-    bool DeleteCharacter(const VTInt count) override;
-    bool InsertCharacter(const VTInt count) override;
-    bool EraseInDisplay(const ::Microsoft::Console::VirtualTerminal::DispatchTypes::EraseType eraseType) override;
-
-    bool SetCursorKeysMode(const bool applicationMode) override; // DECCKM
-    bool SetKeypadMode(const bool applicationMode) override; // DECKPAM, DECKPNM
-    bool SetScreenMode(const bool reverseMode) override; // DECSCNM
-
-    bool SoftReset() override; // DECSTR
-    bool HardReset() override; // RIS
-
-    // DTTERM_WindowManipulation
-    bool WindowManipulation(const ::Microsoft::Console::VirtualTerminal::DispatchTypes::WindowManipulationType /*function*/,
-                            const ::Microsoft::Console::VirtualTerminal::VTParameter /*parameter1*/,
-                            const ::Microsoft::Console::VirtualTerminal::VTParameter /*parameter2*/) override;
-
-    bool EnableVT200MouseMode(const bool enabled) override; // ?1000
-    bool EnableUTF8ExtendedMouseMode(const bool enabled) override; // ?1005
-    bool EnableSGRExtendedMouseMode(const bool enabled) override; // ?1006
-    bool EnableButtonEventMouseMode(const bool enabled) override; // ?1002
-    bool EnableAnyEventMouseMode(const bool enabled) override; // ?1003
-    bool EnableFocusEventMode(const bool enabled) override; // ?1004
-    bool EnableAlternateScroll(const bool enabled) override; // ?1007
-    bool EnableXtermBracketedPasteMode(const bool enabled) override; // ?2004
-
-    bool SetMode(const ::Microsoft::Console::VirtualTerminal::DispatchTypes::ModeParams /*param*/) override; // DECSET
-    bool ResetMode(const ::Microsoft::Console::VirtualTerminal::DispatchTypes::ModeParams /*param*/) override; // DECRST
-
-    bool DeviceStatusReport(const ::Microsoft::Console::VirtualTerminal::DispatchTypes::AnsiStatusType /*statusType*/) override; // DSR, DSR-OS, DSR-CPR
-
-    bool AddHyperlink(const std::wstring_view uri, const std::wstring_view params) override;
-    bool EndHyperlink() override;
-
-    bool DoConEmuAction(const std::wstring_view string) override;
-
-    bool CursorSaveState() override;
-    bool CursorRestoreState() override;
-
-private:
-    ::Microsoft::Terminal::Core::ITerminalApi& _terminalApi;
-
-    // Dramatically simplified version of AdaptDispatch::CursorState
-    struct CursorState
-    {
-        unsigned int Row = 1;
-        unsigned int Column = 1;
-        TextAttribute Attributes = {};
-    };
-
-    std::vector<bool> _tabStopColumns;
-    bool _initDefaultTabStops = true;
-
-    // We have two instances of the saved cursor state, because we need
-    // one for the main buffer (at index 0), and another for the alt buffer
-    // (at index 1). The _usingAltBuffer property keeps tracks of which
-    // buffer is active, so can be used as an index into this array to
-    // obtain the saved state that should be currently active.
-    std::array<CursorState, 2> _savedCursorState;
-    bool _usingAltBuffer = false;
-
-    size_t _SetRgbColorsHelper(const ::Microsoft::Console::VirtualTerminal::VTParameters options,
-                               TextAttribute& attr,
-                               const bool isForeground);
-
-    bool _WriteResponse(const std::wstring_view reply) const;
-    bool _ModeParamsHelper(const ::Microsoft::Console::VirtualTerminal::DispatchTypes::ModeParams param, const bool enable);
-
-    bool _OperatingStatus() const;
-    bool _CursorPositionReport() const;
-
-    void _ClearSingleTabStop();
-    void _ClearAllTabStops();
-    void _ResetTabStops();
-    void _InitTabStopsForWidth(const size_t width);
-};
diff --git a/src/cascadia/TerminalCore/TerminalDispatchGraphics.cpp b/src/cascadia/TerminalCore/TerminalDispatchGraphics.cpp
deleted file mode 100644
index aec05b066ff..00000000000
--- a/src/cascadia/TerminalCore/TerminalDispatchGraphics.cpp
+++ /dev/null
@@ -1,267 +0,0 @@
-// Copyright (c) Microsoft Corporation.
-// Licensed under the MIT license.
-
-#include "pch.h"
-#include "TerminalDispatch.hpp"
-
-using namespace Microsoft::Console::VirtualTerminal;
-using namespace Microsoft::Console::VirtualTerminal::DispatchTypes;
-
-// Routine Description:
-// - Helper to parse extended graphics options, which start with 38 (FG) or 48 (BG)
-//     These options are followed by either a 2 (RGB) or 5 (xterm index)
-//      RGB sequences then take 3 MORE params to designate the R, G, B parts of the color
-//      Xterm index will use the param that follows to use a color from the preset 256 color xterm color table.
-// Arguments:
-// - options - An array of options that will be used to generate the RGB color
-// - attr - The attribute that will be updated with the parsed color.
-// - isForeground - Whether or not the parsed color is for the foreground.
-// Return Value:
-// - The number of options consumed, not including the initial 38/48.
-size_t TerminalDispatch::_SetRgbColorsHelper(const VTParameters options,
-                                             TextAttribute& attr,
-                                             const bool isForeground)
-{
-    size_t optionsConsumed = 1;
-    const DispatchTypes::GraphicsOptions typeOpt = options.at(0);
-    if (typeOpt == DispatchTypes::GraphicsOptions::RGBColorOrFaint)
-    {
-        optionsConsumed = 4;
-        const size_t red = options.at(1).value_or(0);
-        const size_t green = options.at(2).value_or(0);
-        const size_t blue = options.at(3).value_or(0);
-        // ensure that each value fits in a byte
-        if (red <= 255 && green <= 255 && blue <= 255)
-        {
-            const auto rgbColor = RGB(red, green, blue);
-            attr.SetColor(rgbColor, isForeground);
-        }
-    }
-    else if (typeOpt == DispatchTypes::GraphicsOptions::BlinkOrXterm256Index)
-    {
-        optionsConsumed = 2;
-        const size_t tableIndex = options.at(1).value_or(0);
-        if (tableIndex <= 255)
-        {
-            const auto adjustedIndex = gsl::narrow_cast<BYTE>(tableIndex);
-            if (isForeground)
-            {
-                attr.SetIndexedForeground256(adjustedIndex);
-            }
-            else
-            {
-                attr.SetIndexedBackground256(adjustedIndex);
-            }
-        }
-    }
-    return optionsConsumed;
-}
-
-// Routine Description:
-// - SGR - Modifies the graphical rendering options applied to the next
-//   characters written into the buffer.
-//       - Options include colors, invert, underlines, and other "font style"
-//         type options.
-// Arguments:
-// - options - An array of options that will be applied from 0 to N, in order,
-//   one at a time by setting or removing flags in the font style properties.
-// Return Value:
-// - True if handled successfully. False otherwise.
-bool TerminalDispatch::SetGraphicsRendition(const VTParameters options)
-{
-    auto attr = _terminalApi.GetTextAttributes();
-
-    // Run through the graphics options and apply them
-    for (size_t i = 0; i < options.size(); i++)
-    {
-        const GraphicsOptions opt = options.at(i);
-        switch (opt)
-        {
-        case Off:
-            attr.SetDefaultForeground();
-            attr.SetDefaultBackground();
-            attr.SetDefaultMetaAttrs();
-            break;
-        case ForegroundDefault:
-            attr.SetDefaultForeground();
-            break;
-        case BackgroundDefault:
-            attr.SetDefaultBackground();
-            break;
-        case Intense:
-            attr.SetIntense(true);
-            break;
-        case RGBColorOrFaint:
-            attr.SetFaint(true);
-            break;
-        case NotIntenseOrFaint:
-            attr.SetIntense(false);
-            attr.SetFaint(false);
-            break;
-        case Italics:
-            attr.SetItalic(true);
-            break;
-        case NotItalics:
-            attr.SetItalic(false);
-            break;
-        case BlinkOrXterm256Index:
-        case RapidBlink: // We just interpret rapid blink as an alias of blink.
-            attr.SetBlinking(true);
-            break;
-        case Steady:
-            attr.SetBlinking(false);
-            break;
-        case Invisible:
-            attr.SetInvisible(true);
-            break;
-        case Visible:
-            attr.SetInvisible(false);
-            break;
-        case CrossedOut:
-            attr.SetCrossedOut(true);
-            break;
-        case NotCrossedOut:
-            attr.SetCrossedOut(false);
-            break;
-        case Negative:
-            attr.SetReverseVideo(true);
-            break;
-        case Positive:
-            attr.SetReverseVideo(false);
-            break;
-        case Underline:
-            attr.SetUnderlined(true);
-            break;
-        case DoublyUnderlined:
-            attr.SetDoublyUnderlined(true);
-            break;
-        case NoUnderline:
-            attr.SetUnderlined(false);
-            attr.SetDoublyUnderlined(false);
-            break;
-        case Overline:
-            attr.SetOverlined(true);
-            break;
-        case NoOverline:
-            attr.SetOverlined(false);
-            break;
-        case ForegroundBlack:
-            attr.SetIndexedForeground(TextColor::DARK_BLACK);
-            break;
-        case ForegroundBlue:
-            attr.SetIndexedForeground(TextColor::DARK_BLUE);
-            break;
-        case ForegroundGreen:
-            attr.SetIndexedForeground(TextColor::DARK_GREEN);
-            break;
-        case ForegroundCyan:
-            attr.SetIndexedForeground(TextColor::DARK_CYAN);
-            break;
-        case ForegroundRed:
-            attr.SetIndexedForeground(TextColor::DARK_RED);
-            break;
-        case ForegroundMagenta:
-            attr.SetIndexedForeground(TextColor::DARK_MAGENTA);
-            break;
-        case ForegroundYellow:
-            attr.SetIndexedForeground(TextColor::DARK_YELLOW);
-            break;
-        case ForegroundWhite:
-            attr.SetIndexedForeground(TextColor::DARK_WHITE);
-            break;
-        case BackgroundBlack:
-            attr.SetIndexedBackground(TextColor::DARK_BLACK);
-            break;
-        case BackgroundBlue:
-            attr.SetIndexedBackground(TextColor::DARK_BLUE);
-            break;
-        case BackgroundGreen:
-            attr.SetIndexedBackground(TextColor::DARK_GREEN);
-            break;
-        case BackgroundCyan:
-            attr.SetIndexedBackground(TextColor::DARK_CYAN);
-            break;
-        case BackgroundRed:
-            attr.SetIndexedBackground(TextColor::DARK_RED);
-            break;
-        case BackgroundMagenta:
-            attr.SetIndexedBackground(TextColor::DARK_MAGENTA);
-            break;
-        case BackgroundYellow:
-            attr.SetIndexedBackground(TextColor::DARK_YELLOW);
-            break;
-        case BackgroundWhite:
-            attr.SetIndexedBackground(TextColor::DARK_WHITE);
-            break;
-        case BrightForegroundBlack:
-            attr.SetIndexedForeground(TextColor::BRIGHT_BLACK);
-            break;
-        case BrightForegroundBlue:
-            attr.SetIndexedForeground(TextColor::BRIGHT_BLUE);
-            break;
-        case BrightForegroundGreen:
-            attr.SetIndexedForeground(TextColor::BRIGHT_GREEN);
-            break;
-        case BrightForegroundCyan:
-            attr.SetIndexedForeground(TextColor::BRIGHT_CYAN);
-            break;
-        case BrightForegroundRed:
-            attr.SetIndexedForeground(TextColor::BRIGHT_RED);
-            break;
-        case BrightForegroundMagenta:
-            attr.SetIndexedForeground(TextColor::BRIGHT_MAGENTA);
-            break;
-        case BrightForegroundYellow:
-            attr.SetIndexedForeground(TextColor::BRIGHT_YELLOW);
-            break;
-        case BrightForegroundWhite:
-            attr.SetIndexedForeground(TextColor::BRIGHT_WHITE);
-            break;
-        case BrightBackgroundBlack:
-            attr.SetIndexedBackground(TextColor::BRIGHT_BLACK);
-            break;
-        case BrightBackgroundBlue:
-            attr.SetIndexedBackground(TextColor::BRIGHT_BLUE);
-            break;
-        case BrightBackgroundGreen:
-            attr.SetIndexedBackground(TextColor::BRIGHT_GREEN);
-            break;
-        case BrightBackgroundCyan:
-            attr.SetIndexedBackground(TextColor::BRIGHT_CYAN);
-            break;
-        case BrightBackgroundRed:
-            attr.SetIndexedBackground(TextColor::BRIGHT_RED);
-            break;
-        case BrightBackgroundMagenta:
-            attr.SetIndexedBackground(TextColor::BRIGHT_MAGENTA);
-            break;
-        case BrightBackgroundYellow:
-            attr.SetIndexedBackground(TextColor::BRIGHT_YELLOW);
-            break;
-        case BrightBackgroundWhite:
-            attr.SetIndexedBackground(TextColor::BRIGHT_WHITE);
-            break;
-        case ForegroundExtended:
-            i += _SetRgbColorsHelper(options.subspan(i + 1), attr, true);
-            break;
-        case BackgroundExtended:
-            i += _SetRgbColorsHelper(options.subspan(i + 1), attr, false);
-            break;
-        }
-    }
-
-    _terminalApi.SetTextAttributes(attr);
-    return true;
-}
-
-bool TerminalDispatch::PushGraphicsRendition(const VTParameters options)
-{
-    _terminalApi.PushGraphicsRendition(options);
-    return true;
-}
-
-bool TerminalDispatch::PopGraphicsRendition()
-{
-    _terminalApi.PopGraphicsRendition();
-    return true;
-}
diff --git a/src/cascadia/TerminalCore/lib/terminalcore-lib.vcxproj b/src/cascadia/TerminalCore/lib/terminalcore-lib.vcxproj
index 7488acf941f..c5d9c969d19 100644
--- a/src/cascadia/TerminalCore/lib/terminalcore-lib.vcxproj
+++ b/src/cascadia/TerminalCore/lib/terminalcore-lib.vcxproj
@@ -39,6 +39,9 @@
     <ProjectReference Include="$(OpenConsoleDir)src\renderer\base\lib\base.vcxproj">
       <Project>{af0a096a-8b3a-4949-81ef-7df8f0fee91f}</Project>
     </ProjectReference>
+    <ProjectReference Include="$(OpenConsoleDir)src\terminal\adapter\lib\adapter.vcxproj">
+      <Project>{dcf55140-ef6a-4736-a403-957e4f7430bb}</Project>
+    </ProjectReference>
     <ProjectReference Include="$(OpenConsoleDir)src\terminal\parser\lib\parser.vcxproj">
       <Project>{3ae13314-1939-4dfa-9c14-38ca0834050c}</Project>
     </ProjectReference>
diff --git a/src/cascadia/TerminalCore/terminalcore-common.vcxitems b/src/cascadia/TerminalCore/terminalcore-common.vcxitems
index 5b777af15c0..7feb43f7d5d 100644
--- a/src/cascadia/TerminalCore/terminalcore-common.vcxitems
+++ b/src/cascadia/TerminalCore/terminalcore-common.vcxitems
@@ -2,8 +2,6 @@
 <Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
 
   <ItemGroup>
-    <ClCompile Include="..\TerminalDispatch.cpp" />
-    <ClCompile Include="..\TerminalDispatchGraphics.cpp" />
     <ClCompile Include="..\TerminalRenderData.cpp" />
     <ClCompile Include="..\TerminalSelection.cpp" />
     <ClCompile Include="..\TerminalApi.cpp" />
@@ -15,8 +13,6 @@
 
   <ItemGroup>
     <ClInclude Include="..\ControlKeyStates.hpp" />
-    <ClInclude Include="..\TerminalDispatch.hpp" />
-    <ClInclude Include="..\ITerminalApi.hpp" />
     <ClInclude Include="..\pch.h" />
     <ClInclude Include="..\Terminal.hpp" />
   </ItemGroup>
diff --git a/src/cascadia/TerminalCore/terminalrenderdata.cpp b/src/cascadia/TerminalCore/terminalrenderdata.cpp
index b2ae0af0991..56b6a058072 100644
--- a/src/cascadia/TerminalCore/terminalrenderdata.cpp
+++ b/src/cascadia/TerminalCore/terminalrenderdata.cpp
@@ -23,12 +23,12 @@ COORD Terminal::GetTextBufferEndPosition() const noexcept
     return endPosition;
 }
 
-const TextBuffer& Terminal::GetTextBuffer() noexcept
+const TextBuffer& Terminal::GetTextBuffer() const noexcept
 {
     return _activeBuffer();
 }
 
-const FontInfo& Terminal::GetFontInfo() noexcept
+const FontInfo& Terminal::GetFontInfo() const noexcept
 {
     return _fontInfo;
 }
diff --git a/src/cascadia/UnitTests_TerminalCore/ConptyRoundtripTests.cpp b/src/cascadia/UnitTests_TerminalCore/ConptyRoundtripTests.cpp
index c9035f91d9b..60d8a725153 100644
--- a/src/cascadia/UnitTests_TerminalCore/ConptyRoundtripTests.cpp
+++ b/src/cascadia/UnitTests_TerminalCore/ConptyRoundtripTests.cpp
@@ -238,7 +238,7 @@ class TerminalCoreUnitTests::ConptyRoundtripTests final
     std::deque<std::string> expectedOutput;
 
     std::unique_ptr<CommonState> m_state;
-    std::unique_ptr<Microsoft::Console::VirtualTerminal::ConGetSet> _pConApi;
+    std::unique_ptr<Microsoft::Console::VirtualTerminal::ITerminalApi> _pConApi;
 
     // Tests can set these variables how they link to configure the behavior of the test harness.
     bool _checkConptyOutput{ true }; // If true, the test class will check that the output from conpty was expected
diff --git a/src/cascadia/UnitTests_TerminalCore/SelectionTest.cpp b/src/cascadia/UnitTests_TerminalCore/SelectionTest.cpp
index 291185203ed..7b458aa06a7 100644
--- a/src/cascadia/UnitTests_TerminalCore/SelectionTest.cpp
+++ b/src/cascadia/UnitTests_TerminalCore/SelectionTest.cpp
@@ -394,7 +394,7 @@ namespace TerminalCoreUnitTests
             const auto burrito = L"\xD83C\xDF2F";
 
             // Insert wide glyph at position (4,10)
-            term.SetCursorPosition({ 4, 10 });
+            term.GetTextBuffer().GetCursor().SetPosition({ 4, 10 });
             term.Write(burrito);
 
             // Simulate click at (x,y) = (5,10)
@@ -417,7 +417,7 @@ namespace TerminalCoreUnitTests
             const auto burrito = L"\xD83C\xDF2F";
 
             // Insert wide glyph at position (4,10)
-            term.SetCursorPosition({ 4, 10 });
+            term.GetTextBuffer().GetCursor().SetPosition({ 4, 10 });
             term.Write(burrito);
 
             // Simulate click at (x,y) = (5,10)
@@ -440,11 +440,11 @@ namespace TerminalCoreUnitTests
             const auto burrito = L"\xD83C\xDF2F";
 
             // Insert wide glyph at position (4,10)
-            term.SetCursorPosition({ 4, 10 });
+            term.GetTextBuffer().GetCursor().SetPosition({ 4, 10 });
             term.Write(burrito);
 
             // Insert wide glyph at position (7,11)
-            term.SetCursorPosition({ 7, 11 });
+            term.GetTextBuffer().GetCursor().SetPosition({ 7, 11 });
             term.Write(burrito);
 
             // Simulate ALT + click at (x,y) = (5,8)
@@ -496,7 +496,7 @@ namespace TerminalCoreUnitTests
 
             // Insert text at position (4,10)
             const std::wstring_view text = L"doubleClickMe";
-            term.SetCursorPosition({ 4, 10 });
+            term.GetTextBuffer().GetCursor().SetPosition({ 4, 10 });
             term.Write(text);
 
             // Simulate double click at (x,y) = (5,10)
@@ -540,7 +540,7 @@ namespace TerminalCoreUnitTests
 
             // Insert text at position (4,10)
             const std::wstring_view text = L"C:\\Terminal>";
-            term.SetCursorPosition({ 4, 10 });
+            term.GetTextBuffer().GetCursor().SetPosition({ 4, 10 });
             term.Write(text);
 
             // Simulate click at (x,y) = (15,10)
@@ -568,7 +568,7 @@ namespace TerminalCoreUnitTests
 
             // Insert text at position (4,10)
             const std::wstring_view text = L"doubleClickMe dragThroughHere";
-            term.SetCursorPosition({ 4, 10 });
+            term.GetTextBuffer().GetCursor().SetPosition({ 4, 10 });
             term.Write(text);
 
             // Simulate double click at (x,y) = (5,10)
@@ -597,7 +597,7 @@ namespace TerminalCoreUnitTests
 
             // Insert text at position (21,10)
             const std::wstring_view text = L"doubleClickMe dragThroughHere";
-            term.SetCursorPosition({ 4, 10 });
+            term.GetTextBuffer().GetCursor().SetPosition({ 4, 10 });
             term.Write(text);
 
             // Simulate double click at (x,y) = (21,10)
@@ -685,7 +685,7 @@ namespace TerminalCoreUnitTests
 
             // Insert text at position (4,10)
             const std::wstring_view text = L"doubleClickMe dragThroughHere";
-            term.SetCursorPosition({ 4, 10 });
+            term.GetTextBuffer().GetCursor().SetPosition({ 4, 10 });
             term.Write(text);
 
             // Step 1: Create a selection on "doubleClickMe"
diff --git a/src/cascadia/UnitTests_TerminalCore/TerminalApiTest.cpp b/src/cascadia/UnitTests_TerminalCore/TerminalApiTest.cpp
index f6d736781c8..384be1034eb 100644
--- a/src/cascadia/UnitTests_TerminalCore/TerminalApiTest.cpp
+++ b/src/cascadia/UnitTests_TerminalCore/TerminalApiTest.cpp
@@ -55,11 +55,11 @@ void TerminalApiTest::SetColorTableEntry()
     auto settings = winrt::make<MockTermSettings>(100, 100, 100);
     term.UpdateSettings(settings);
 
-    VERIFY_NO_THROW(term.SetColorTableEntry(0, 100));
-    VERIFY_NO_THROW(term.SetColorTableEntry(128, 100));
-    VERIFY_NO_THROW(term.SetColorTableEntry(255, 100));
+    VERIFY_NO_THROW(term._renderSettings.SetColorTableEntry(0, 100));
+    VERIFY_NO_THROW(term._renderSettings.SetColorTableEntry(128, 100));
+    VERIFY_NO_THROW(term._renderSettings.SetColorTableEntry(255, 100));
 
-    VERIFY_THROWS(term.SetColorTableEntry(512, 100), std::exception);
+    VERIFY_THROWS(term._renderSettings.SetColorTableEntry(512, 100), std::exception);
 }
 
 // Terminal::_WriteBuffer used to enter infinite loops under certain conditions.
@@ -152,7 +152,7 @@ void TerminalApiTest::CursorVisibility()
     VERIFY_IS_TRUE(term._mainBuffer->GetCursor().IsOn());
     VERIFY_IS_TRUE(term._mainBuffer->GetCursor().IsBlinkingAllowed());
 
-    term.SetCursorVisibility(false);
+    term.GetTextBuffer().GetCursor().SetIsVisible(false);
     VERIFY_IS_FALSE(term._mainBuffer->GetCursor().IsVisible());
     VERIFY_IS_TRUE(term._mainBuffer->GetCursor().IsOn());
     VERIFY_IS_TRUE(term._mainBuffer->GetCursor().IsBlinkingAllowed());
@@ -242,19 +242,19 @@ void TerminalApiTest::CheckDoubleWidthCursor()
     stateMachine.ProcessString(doubleWidthText);
 
     // The last 'A'
-    term.SetCursorPosition({ 97, 0 });
+    cursor.SetPosition({ 97, 0 });
     VERIFY_IS_FALSE(term.IsCursorDoubleWidth());
 
     // This and the next CursorPos are taken up by '我‘
-    term.SetCursorPosition({ 98, 0 });
+    cursor.SetPosition({ 98, 0 });
     VERIFY_IS_TRUE(term.IsCursorDoubleWidth());
-    term.SetCursorPosition({ 99, 0 });
+    cursor.SetPosition({ 99, 0 });
     VERIFY_IS_TRUE(term.IsCursorDoubleWidth());
 
     // This and the next CursorPos are taken up by ’愛‘
-    term.SetCursorPosition({ 0, 1 });
+    cursor.SetPosition({ 0, 1 });
     VERIFY_IS_TRUE(term.IsCursorDoubleWidth());
-    term.SetCursorPosition({ 1, 1 });
+    cursor.SetPosition({ 1, 1 });
     VERIFY_IS_TRUE(term.IsCursorDoubleWidth());
 }
 
diff --git a/src/host/PtySignalInputThread.cpp b/src/host/PtySignalInputThread.cpp
index 2f39e80e398..9f3bd98c2cc 100644
--- a/src/host/PtySignalInputThread.cpp
+++ b/src/host/PtySignalInputThread.cpp
@@ -20,12 +20,11 @@ using namespace Microsoft::Console::VirtualTerminal;
 PtySignalInputThread::PtySignalInputThread(wil::unique_hfile hPipe) :
     _hFile{ std::move(hPipe) },
     _hThread{},
-    _pConApi{ std::make_unique<ConhostInternalGetSet>(ServiceLocator::LocateGlobals().getConsoleInformation()) },
+    _api{ ServiceLocator::LocateGlobals().getConsoleInformation() },
     _dwThreadId{ 0 },
     _consoleConnected{ false }
 {
     THROW_HR_IF(E_HANDLE, _hFile.get() == INVALID_HANDLE_VALUE);
-    THROW_HR_IF_NULL(E_INVALIDARG, _pConApi.get());
 }
 
 PtySignalInputThread::~PtySignalInputThread()
@@ -199,7 +198,7 @@ void PtySignalInputThread::ConnectConsole() noexcept
 // - <none>
 void PtySignalInputThread::_DoResizeWindow(const ResizeWindowData& data)
 {
-    if (_pConApi->ResizeWindow(data.sx, data.sy))
+    if (_api.ResizeWindow(data.sx, data.sy))
     {
         auto& gci = ServiceLocator::LocateGlobals().getConsoleInformation();
         THROW_IF_FAILED(gci.GetVtIo()->SuppressResizeRepaint());
@@ -214,7 +213,7 @@ void PtySignalInputThread::_DoClearBuffer()
 
 void PtySignalInputThread::_DoShowHide(const bool show)
 {
-    _pConApi->ShowWindow(show);
+    _api.ShowWindow(show);
 }
 
 // Method Description:
@@ -228,7 +227,16 @@ void PtySignalInputThread::_DoShowHide(const bool show)
 // - <none>
 void PtySignalInputThread::_DoSetWindowParent(const SetParentData& data)
 {
-    _pConApi->ReparentWindow(data.handle);
+    // This will initialize s_interactivityFactory for us. It will also
+    // conveniently return 0 when we're on OneCore.
+    //
+    // If the window hasn't been created yet, by some other call to
+    // LocatePseudoWindow, then this will also initialize the owner of the
+    // window.
+    if (const auto pseudoHwnd{ ServiceLocator::LocatePseudoWindow(reinterpret_cast<HWND>(data.handle)) })
+    {
+        LOG_LAST_ERROR_IF_NULL(::SetParent(pseudoHwnd, reinterpret_cast<HWND>(data.handle)));
+    }
 }
 
 // Method Description:
diff --git a/src/host/PtySignalInputThread.hpp b/src/host/PtySignalInputThread.hpp
index 4de50e53e9a..1ac12f44f33 100644
--- a/src/host/PtySignalInputThread.hpp
+++ b/src/host/PtySignalInputThread.hpp
@@ -15,10 +15,7 @@ Author(s):
 --*/
 #pragma once
 
-namespace Microsoft::Console::VirtualTerminal
-{
-    class ConGetSet;
-}
+#include "outputStream.hpp"
 
 namespace Microsoft::Console
 {
@@ -76,7 +73,7 @@ namespace Microsoft::Console
         bool _consoleConnected;
         std::optional<ResizeWindowData> _earlyResize;
         std::optional<ShowHideData> _initialShowHide;
-        std::unique_ptr<Microsoft::Console::VirtualTerminal::ConGetSet> _pConApi;
+        ConhostInternalGetSet _api;
 
     public:
         std::optional<SetParentData> _earlyReparent;
diff --git a/src/host/VtInputThread.cpp b/src/host/VtInputThread.cpp
index ad6d86be861..8706ff6f87a 100644
--- a/src/host/VtInputThread.cpp
+++ b/src/host/VtInputThread.cpp
@@ -8,7 +8,6 @@
 #include "../interactivity/inc/ServiceLocator.hpp"
 #include "input.h"
 #include "../terminal/parser/InputStateMachineEngine.hpp"
-#include "outputStream.hpp" // For ConhostInternalGetSet
 #include "../terminal/adapter/InteractDispatch.hpp"
 #include "../types/inc/convert.hpp"
 #include "server.h"
@@ -36,11 +35,7 @@ VtInputThread::VtInputThread(_In_ wil::unique_hfile hPipe,
 {
     THROW_HR_IF(E_HANDLE, _hFile.get() == INVALID_HANDLE_VALUE);
 
-    auto& gci = ServiceLocator::LocateGlobals().getConsoleInformation();
-
-    auto pGetSet = std::make_unique<ConhostInternalGetSet>(gci);
-
-    auto dispatch = std::make_unique<InteractDispatch>(std::move(pGetSet));
+    auto dispatch = std::make_unique<InteractDispatch>();
 
     auto engine = std::make_unique<InputStateMachineEngine>(std::move(dispatch), inheritCursor);
 
diff --git a/src/host/outputStream.cpp b/src/host/outputStream.cpp
index f19e1c13ea5..4074139d3a2 100644
--- a/src/host/outputStream.cpp
+++ b/src/host/outputStream.cpp
@@ -15,8 +15,8 @@
 #pragma hdrstop
 
 using namespace Microsoft::Console;
+using namespace Microsoft::Console::VirtualTerminal;
 using Microsoft::Console::Interactivity::ServiceLocator;
-using Microsoft::Console::VirtualTerminal::StateMachine;
 
 ConhostInternalGetSet::ConhostInternalGetSet(_In_ IIoProvider& io) :
     _io{ io }
@@ -56,6 +56,36 @@ void ConhostInternalGetSet::PrintString(const std::wstring_view string)
     THROW_IF_NTSTATUS_FAILED(ntstatus);
 }
 
+// - Sends a string response to the input stream of the console.
+// - Used by various commands where the program attached would like a reply to one of the commands issued.
+// - This will generate two "key presses" (one down, one up) for every character in the string and place them into the head of the console's input stream.
+// Arguments:
+// - response - The response string to transmit back to the input stream
+// Return Value:
+// - <none>
+void ConhostInternalGetSet::ReturnResponse(const std::wstring_view response)
+{
+    std::deque<std::unique_ptr<IInputEvent>> inEvents;
+
+    // generate a paired key down and key up event for every
+    // character to be sent into the console's input buffer
+    for (const auto& wch : response)
+    {
+        // This wasn't from a real keyboard, so we're leaving key/scan codes blank.
+        KeyEvent keyEvent{ TRUE, 1, 0, 0, wch, 0 };
+
+        inEvents.push_back(std::make_unique<KeyEvent>(keyEvent));
+        keyEvent.SetKeyDown(false);
+        inEvents.push_back(std::make_unique<KeyEvent>(keyEvent));
+    }
+
+    // TODO GH#4954 During the input refactor we may want to add a "priority" input list
+    // to make sure that "response" input is spooled directly into the application.
+    // We switched this to an append (vs. a prepend) to fix GH#1637, a bug where two CPR
+    // could collide with each other.
+    _io.GetActiveInputBuffer()->Write(inEvents);
+}
+
 // Routine Description:
 // - Retrieves the state machine for the active output buffer.
 // Arguments:
@@ -115,19 +145,6 @@ void ConhostInternalGetSet::SetTextAttributes(const TextAttribute& attrs)
     _io.GetActiveOutputBuffer().SetAttributes(attrs);
 }
 
-// Routine Description:
-// - Writes events to the input buffer already formed into IInputEvents
-// Arguments:
-// - events - the input events to be copied into the head of the input
-//            buffer for the underlying attached process
-// - eventsWritten - on output, the number of events written
-// Return Value:
-// - <none>
-void ConhostInternalGetSet::WriteInput(std::deque<std::unique_ptr<IInputEvent>>& events, size_t& eventsWritten)
-{
-    eventsWritten = _io.GetActiveInputBuffer()->Write(events);
-}
-
 // Routine Description:
 // - Sets the ENABLE_WRAP_AT_EOL_OUTPUT mode. This controls whether the cursor moves
 //     to the beginning of the next row when it reaches the end of the current row.
@@ -293,6 +310,51 @@ unsigned int ConhostInternalGetSet::GetConsoleOutputCP() const
     return ServiceLocator::LocateGlobals().getConsoleInformation().OutputCP;
 }
 
+// Routine Description:
+// - Sets the XTerm bracketed paste mode. This controls whether pasted content is
+//     bracketed with control sequences to differentiate it from typed text.
+// Arguments:
+// - enable - set to true to enable bracketing, false to disable.
+// Return Value:
+// - <none>
+void ConhostInternalGetSet::EnableXtermBracketedPasteMode(const bool /*enabled*/)
+{
+    // TODO
+}
+
+// Routine Description:
+// - Copies the given content to the clipboard.
+// Arguments:
+// - content - the text to be copied.
+// Return Value:
+// - <none>
+void ConhostInternalGetSet::CopyToClipboard(const std::wstring_view /*content*/)
+{
+    // TODO
+}
+
+// Routine Description:
+// - Updates the taskbar progress indicator.
+// Arguments:
+// - state: indicates the progress state
+// - progress: indicates the progress value
+// Return Value:
+// - <none>
+void ConhostInternalGetSet::SetTaskbarProgress(const DispatchTypes::TaskbarState /*state*/, const size_t /*progress*/)
+{
+    // TODO
+}
+
+// Routine Description:
+// - Set the active working directory. Not used in conhost.
+// Arguments:
+// - content - the text to be copied.
+// Return Value:
+// - <none>
+void ConhostInternalGetSet::SetWorkingDirectory(const std::wstring_view /*uri*/)
+{
+}
+
 // Routine Description:
 // - Resizes the window to the specified dimensions, in characters.
 // Arguments:
@@ -392,17 +454,3 @@ void ConhostInternalGetSet::NotifyAccessibilityChange(const til::rect& changedRe
             gsl::narrow_cast<short>(changedRect.bottom - 1));
     }
 }
-
-void ConhostInternalGetSet::ReparentWindow(const uint64_t handle)
-{
-    // This will initialize s_interactivityFactory for us. It will also
-    // conveniently return 0 when we're on OneCore.
-    //
-    // If the window hasn't been created yet, by some other call to
-    // LocatePseudoWindow, then this will also initialize the owner of the
-    // window.
-    if (const auto pseudoHwnd{ ServiceLocator::LocatePseudoWindow(reinterpret_cast<HWND>(handle)) })
-    {
-        LOG_LAST_ERROR_IF_NULL(::SetParent(pseudoHwnd, reinterpret_cast<HWND>(handle)));
-    }
-}
diff --git a/src/host/outputStream.hpp b/src/host/outputStream.hpp
index 65f2fde5643..79316f78ea5 100644
--- a/src/host/outputStream.hpp
+++ b/src/host/outputStream.hpp
@@ -14,7 +14,7 @@ Module Name:
 
 #pragma once
 
-#include "../terminal/adapter/conGetSet.hpp"
+#include "../terminal/adapter/ITerminalApi.hpp"
 #include "../types/inc/IInputEvent.hpp"
 #include "../inc/conattrs.hpp"
 #include "IIoProvider.hpp"
@@ -24,12 +24,13 @@ Module Name:
 // the kernelbase/32 exposed public APIs and routed by the console driver (condrv) to this console host.
 // But since we're trying to call them from *inside* the console host itself, we need to get in the way and route them straight to the
 // v-table inside this process instance.
-class ConhostInternalGetSet final : public Microsoft::Console::VirtualTerminal::ConGetSet
+class ConhostInternalGetSet final : public Microsoft::Console::VirtualTerminal::ITerminalApi
 {
 public:
     ConhostInternalGetSet(_In_ Microsoft::Console::IIoProvider& io);
 
     void PrintString(const std::wstring_view string) override;
+    void ReturnResponse(const std::wstring_view response) override;
 
     Microsoft::Console::VirtualTerminal::StateMachine& GetStateMachine() override;
     TextBuffer& GetTextBuffer() override;
@@ -38,8 +39,6 @@ class ConhostInternalGetSet final : public Microsoft::Console::VirtualTerminal::
 
     void SetTextAttributes(const TextAttribute& attrs) override;
 
-    void WriteInput(std::deque<std::unique_ptr<IInputEvent>>& events, size_t& eventsWritten) override;
-
     void SetAutoWrapMode(const bool wrapAtEOL) override;
 
     void SetScrollingRegion(const til::inclusive_rect& scrollMargins) override;
@@ -64,13 +63,16 @@ class ConhostInternalGetSet final : public Microsoft::Console::VirtualTerminal::
     void SetConsoleOutputCP(const unsigned int codepage) override;
     unsigned int GetConsoleOutputCP() const override;
 
+    void EnableXtermBracketedPasteMode(const bool enabled) override;
+    void CopyToClipboard(const std::wstring_view content) override;
+    void SetTaskbarProgress(const ::Microsoft::Console::VirtualTerminal::DispatchTypes::TaskbarState state, const size_t progress) override;
+    void SetWorkingDirectory(const std::wstring_view uri) override;
+
     bool IsConsolePty() const override;
     bool IsVtInputEnabled() const override;
 
     void NotifyAccessibilityChange(const til::rect& changedRect) override;
 
-    void ReparentWindow(const uint64_t handle);
-
 private:
     Microsoft::Console::IIoProvider& _io;
 };
diff --git a/src/host/renderData.cpp b/src/host/renderData.cpp
index 381198bd039..bb7f7135720 100644
--- a/src/host/renderData.cpp
+++ b/src/host/renderData.cpp
@@ -44,7 +44,7 @@ COORD RenderData::GetTextBufferEndPosition() const noexcept
 //   the appropriate windowing.
 // Return Value:
 // - Text buffer with cell information for display
-const TextBuffer& RenderData::GetTextBuffer() noexcept
+const TextBuffer& RenderData::GetTextBuffer() const noexcept
 {
     const auto& gci = ServiceLocator::LocateGlobals().getConsoleInformation();
     return gci.GetActiveOutputBuffer().GetTextBuffer();
@@ -54,7 +54,7 @@ const TextBuffer& RenderData::GetTextBuffer() noexcept
 // - Describes which font should be used for presenting text
 // Return Value:
 // - Font description structure
-const FontInfo& RenderData::GetFontInfo() noexcept
+const FontInfo& RenderData::GetFontInfo() const noexcept
 {
     const auto& gci = ServiceLocator::LocateGlobals().getConsoleInformation();
     return gci.GetActiveOutputBuffer().GetCurrentFont();
diff --git a/src/host/renderData.hpp b/src/host/renderData.hpp
index 7958bc5bf21..bdceed55f8a 100644
--- a/src/host/renderData.hpp
+++ b/src/host/renderData.hpp
@@ -26,8 +26,8 @@ class RenderData final :
 #pragma region BaseData
     Microsoft::Console::Types::Viewport GetViewport() noexcept override;
     COORD GetTextBufferEndPosition() const noexcept override;
-    const TextBuffer& GetTextBuffer() noexcept override;
-    const FontInfo& GetFontInfo() noexcept override;
+    const TextBuffer& GetTextBuffer() const noexcept override;
+    const FontInfo& GetFontInfo() const noexcept override;
 
     std::vector<Microsoft::Console::Types::Viewport> GetSelectionRects() noexcept override;
 
diff --git a/src/host/screenInfo.cpp b/src/host/screenInfo.cpp
index 2c5f2f4c9b3..e4130641172 100644
--- a/src/host/screenInfo.cpp
+++ b/src/host/screenInfo.cpp
@@ -46,6 +46,7 @@ SCREEN_INFORMATION::SCREEN_INFORMATION(
     ScrollScale{ 1ul },
     _pConsoleWindowMetrics{ pMetrics },
     _pAccessibilityNotifier{ pNotifier },
+    _api{ *this },
     _stateMachine{ nullptr },
     _scrollMargins{ Viewport::FromCoord({ 0 }) },
     _viewport(Viewport::Empty()),
@@ -259,8 +260,7 @@ void SCREEN_INFORMATION::s_RemoveScreenBuffer(_In_ SCREEN_INFORMATION* const pSc
         auto& renderer = *g.pRender;
         auto& renderSettings = gci.GetRenderSettings();
         auto& terminalInput = gci.GetActiveInputBuffer()->GetTerminalInput();
-        auto getset = std::make_unique<ConhostInternalGetSet>(*this);
-        auto adapter = std::make_unique<AdaptDispatch>(std::move(getset), renderer, renderSettings, terminalInput);
+        auto adapter = std::make_unique<AdaptDispatch>(_api, renderer, renderSettings, terminalInput);
         auto engine = std::make_unique<OutputStateMachineEngine>(std::move(adapter));
         // Note that at this point in the setup, we haven't determined if we're
         //      in VtIo mode or not yet. We'll set the OutputStateMachine's
diff --git a/src/host/screenInfo.hpp b/src/host/screenInfo.hpp
index 0042c55b530..a9d344a3a4f 100644
--- a/src/host/screenInfo.hpp
+++ b/src/host/screenInfo.hpp
@@ -266,6 +266,8 @@ class SCREEN_INFORMATION : public ConsoleObjectHeader, public Microsoft::Console
     bool _IsInPtyMode() const;
     bool _IsInVTMode() const;
 
+    ConhostInternalGetSet _api;
+
     std::shared_ptr<Microsoft::Console::VirtualTerminal::StateMachine> _stateMachine;
 
     Microsoft::Console::Types::Viewport _scrollMargins; //The margins of the VT specified scroll region. Left and Right are currently unused, but could be in the future.
diff --git a/src/host/ut_host/ScreenBufferTests.cpp b/src/host/ut_host/ScreenBufferTests.cpp
index 030e8f46d8a..27c887d699c 100644
--- a/src/host/ut_host/ScreenBufferTests.cpp
+++ b/src/host/ut_host/ScreenBufferTests.cpp
@@ -2707,8 +2707,7 @@ void ScreenBufferTests::BackspaceDefaultAttrsInPrompt()
     stateMachine.ProcessString(L"\x1b[2D");
     stateMachine.ProcessString(L"\x1b[P");
 
-    COORD expectedCursor{ 1, 1 }; // We're expecting y=1, because the 2J above
-        // should have moved the viewport down a line.
+    COORD expectedCursor{ 1, 0 };
     VERIFY_ARE_EQUAL(expectedCursor, cursor.GetPosition());
 
     const std::vector<TextAttribute> attrs{ attrRow->begin(), attrRow->end() };
diff --git a/src/host/ut_host/VtIoTests.cpp b/src/host/ut_host/VtIoTests.cpp
index 8946990d978..dc464dc1fc0 100644
--- a/src/host/ut_host/VtIoTests.cpp
+++ b/src/host/ut_host/VtIoTests.cpp
@@ -267,12 +267,12 @@ class MockRenderData : public IRenderData, IUiaData
         return COORD{};
     }
 
-    const TextBuffer& GetTextBuffer() noexcept override
+    const TextBuffer& GetTextBuffer() const noexcept override
     {
         FAIL_FAST_HR(E_NOTIMPL);
     }
 
-    const FontInfo& GetFontInfo() noexcept override
+    const FontInfo& GetFontInfo() const noexcept override
     {
         FAIL_FAST_HR(E_NOTIMPL);
     }
diff --git a/src/renderer/base/renderer.cpp b/src/renderer/base/renderer.cpp
index 2424515b991..faea3d531f0 100644
--- a/src/renderer/base/renderer.cpp
+++ b/src/renderer/base/renderer.cpp
@@ -298,10 +298,10 @@ void Renderer::TriggerRedrawCursor(const COORD* const pcoord)
 // - Called when something that changes the output state has occurred and the entire frame is now potentially invalid.
 // - NOTE: Use sparingly. Try to reduce the refresh region where possible. Only use when a global state change has occurred.
 // Arguments:
-// - <none>
+// - backgroundChanged - Set to true if the background color has changed.
 // Return Value:
 // - <none>
-void Renderer::TriggerRedrawAll()
+void Renderer::TriggerRedrawAll(const bool backgroundChanged)
 {
     FOREACH_ENGINE(pEngine)
     {
@@ -309,6 +309,11 @@ void Renderer::TriggerRedrawAll()
     }
 
     NotifyPaintFrame();
+
+    if (backgroundChanged && _pfnBackgroundColorChanged)
+    {
+        _pfnBackgroundColorChanged();
+    }
 }
 
 // Method Description:
@@ -1331,6 +1336,17 @@ void Renderer::AddRenderEngine(_In_ IRenderEngine* const pEngine)
     THROW_HR_MSG(E_UNEXPECTED, "engines array is full");
 }
 
+// Method Description:
+// - Registers a callback for when the background color is changed
+// Arguments:
+// - pfn: the callback
+// Return Value:
+// - <none>
+void Renderer::SetBackgroundColorChangedCallback(std::function<void()> pfn)
+{
+    _pfnBackgroundColorChanged = std::move(pfn);
+}
+
 // Method Description:
 // - Registers a callback that will be called when this renderer gives up.
 //   An application consuming a renderer can use this to display auxiliary Retry UI
diff --git a/src/renderer/base/renderer.hpp b/src/renderer/base/renderer.hpp
index 6d2b33afa80..cd25463bbef 100644
--- a/src/renderer/base/renderer.hpp
+++ b/src/renderer/base/renderer.hpp
@@ -52,7 +52,7 @@ namespace Microsoft::Console::Render
         void TriggerRedraw(const Microsoft::Console::Types::Viewport& region);
         void TriggerRedraw(const COORD* const pcoord);
         void TriggerRedrawCursor(const COORD* const pcoord);
-        void TriggerRedrawAll();
+        void TriggerRedrawAll(const bool backgroundChanged = false);
         void TriggerTeardown() noexcept;
 
         void TriggerSelection();
@@ -84,6 +84,7 @@ namespace Microsoft::Console::Render
 
         void AddRenderEngine(_In_ IRenderEngine* const pEngine);
 
+        void SetBackgroundColorChangedCallback(std::function<void()> pfn);
         void SetRendererEnteredErrorStateCallback(std::function<void()> pfn);
         void ResetErrorStateAndResume();
 
@@ -121,6 +122,7 @@ namespace Microsoft::Console::Render
         Microsoft::Console::Types::Viewport _viewport;
         std::vector<Cluster> _clusterBuffer;
         std::vector<SMALL_RECT> _previousSelection;
+        std::function<void()> _pfnBackgroundColorChanged;
         std::function<void()> _pfnRendererEnteredErrorState;
         bool _destructing = false;
 
diff --git a/src/terminal/adapter/conGetSet.hpp b/src/terminal/adapter/ITerminalApi.hpp
similarity index 67%
rename from src/terminal/adapter/conGetSet.hpp
rename to src/terminal/adapter/ITerminalApi.hpp
index 2b1cee923c9..c2f0d7f71e9 100644
--- a/src/terminal/adapter/conGetSet.hpp
+++ b/src/terminal/adapter/ITerminalApi.hpp
@@ -3,11 +3,10 @@ Copyright (c) Microsoft Corporation
 Licensed under the MIT license.
 
 Module Name:
-- conGetSet.hpp
+- ITerminalApi.hpp
 
 Abstract:
-- This serves as an abstraction layer for the adapters to connect to the console API functions.
-- The abstraction allows for the substitution of the functions for internal/external to Conhost.exe use as well as easy testing.
+- This serves as an abstraction layer for the dispatch class to connect to conhost/terminal API functions.
 
 Author(s):
 - Michael Niksa (MiNiksa) 30-July-2015
@@ -20,21 +19,26 @@ Author(s):
 #include "../../buffer/out/LineRendition.hpp"
 #include "../../buffer/out/textBuffer.hpp"
 #include "../../renderer/inc/RenderSettings.hpp"
-#include "../../inc/conattrs.hpp"
 
 #include <deque>
 #include <memory>
 
 namespace Microsoft::Console::VirtualTerminal
 {
-    class ConGetSet
+    class ITerminalApi
     {
         using RenderSettings = Microsoft::Console::Render::RenderSettings;
 
     public:
-        virtual ~ConGetSet() = default;
+        virtual ~ITerminalApi() = default;
+        ITerminalApi() = default;
+        ITerminalApi(const ITerminalApi&) = delete;
+        ITerminalApi(ITerminalApi&&) = delete;
+        ITerminalApi& operator=(const ITerminalApi&) = delete;
+        ITerminalApi& operator=(ITerminalApi&&) = delete;
 
         virtual void PrintString(const std::wstring_view string) = 0;
+        virtual void ReturnResponse(const std::wstring_view response) = 0;
 
         virtual StateMachine& GetStateMachine() = 0;
         virtual TextBuffer& GetTextBuffer() = 0;
@@ -45,8 +49,6 @@ namespace Microsoft::Console::VirtualTerminal
 
         virtual void SetTextAttributes(const TextAttribute& attrs) = 0;
 
-        virtual void WriteInput(std::deque<std::unique_ptr<IInputEvent>>& events, size_t& eventsWritten) = 0;
-
         virtual void SetAutoWrapMode(const bool wrapAtEOL) = 0;
 
         virtual void SetScrollingRegion(const til::inclusive_rect& scrollMargins) = 0;
@@ -64,11 +66,14 @@ namespace Microsoft::Console::VirtualTerminal
         virtual void SetConsoleOutputCP(const unsigned int codepage) = 0;
         virtual unsigned int GetConsoleOutputCP() const = 0;
 
+        virtual void EnableXtermBracketedPasteMode(const bool enabled) = 0;
+        virtual void CopyToClipboard(const std::wstring_view content) = 0;
+        virtual void SetTaskbarProgress(const DispatchTypes::TaskbarState state, const size_t progress) = 0;
+        virtual void SetWorkingDirectory(const std::wstring_view uri) = 0;
+
         virtual bool ResizeWindow(const size_t width, const size_t height) = 0;
         virtual bool IsConsolePty() const = 0;
 
         virtual void NotifyAccessibilityChange(const til::rect& changedRect) = 0;
-
-        virtual void ReparentWindow(const uint64_t handle) = 0;
     };
 }
diff --git a/src/terminal/adapter/InteractDispatch.cpp b/src/terminal/adapter/InteractDispatch.cpp
index 1c4cb2f5bcb..6c205d3508b 100644
--- a/src/terminal/adapter/InteractDispatch.cpp
+++ b/src/terminal/adapter/InteractDispatch.cpp
@@ -10,7 +10,6 @@
 #pragma warning(disable : 26455)
 
 #include "InteractDispatch.hpp"
-#include "conGetSet.hpp"
 #include "../../host/conddkrefs.h"
 #include "../../interactivity/inc/ServiceLocator.hpp"
 #include "../../interactivity/inc/EventSynthesis.hpp"
@@ -21,11 +20,9 @@ using namespace Microsoft::Console::Interactivity;
 using namespace Microsoft::Console::Types;
 using namespace Microsoft::Console::VirtualTerminal;
 
-// takes ownership of pConApi
-InteractDispatch::InteractDispatch(std::unique_ptr<ConGetSet> pConApi) :
-    _pConApi(std::move(pConApi))
+InteractDispatch::InteractDispatch() :
+    _api{ ServiceLocator::LocateGlobals().getConsoleInformation() }
 {
-    THROW_HR_IF_NULL(E_INVALIDARG, _pConApi.get());
 }
 
 // Method Description:
@@ -40,8 +37,8 @@ InteractDispatch::InteractDispatch(std::unique_ptr<ConGetSet> pConApi) :
 // - True.
 bool InteractDispatch::WriteInput(std::deque<std::unique_ptr<IInputEvent>>& inputEvents)
 {
-    size_t written = 0;
-    _pConApi->WriteInput(inputEvents, written);
+    const auto& gci = ServiceLocator::LocateGlobals().getConsoleInformation();
+    gci.GetActiveInputBuffer()->Write(inputEvents);
     return true;
 }
 
@@ -71,7 +68,7 @@ bool InteractDispatch::WriteString(const std::wstring_view string)
 {
     if (!string.empty())
     {
-        const auto codepage = _pConApi->GetConsoleOutputCP();
+        const auto codepage = _api.GetConsoleOutputCP();
         std::deque<std::unique_ptr<IInputEvent>> keyEvents;
 
         for (const auto& wch : string)
@@ -110,18 +107,18 @@ bool InteractDispatch::WindowManipulation(const DispatchTypes::WindowManipulatio
     switch (function)
     {
     case DispatchTypes::WindowManipulationType::DeIconifyWindow:
-        _pConApi->ShowWindow(true);
+        _api.ShowWindow(true);
         return true;
     case DispatchTypes::WindowManipulationType::IconifyWindow:
-        _pConApi->ShowWindow(false);
+        _api.ShowWindow(false);
         return true;
     case DispatchTypes::WindowManipulationType::RefreshWindow:
-        _pConApi->GetTextBuffer().TriggerRedrawAll();
+        _api.GetTextBuffer().TriggerRedrawAll();
         return true;
     case DispatchTypes::WindowManipulationType::ResizeWindowInCharacters:
         // TODO:GH#1765 We should introduce a better `ResizeConpty` function to
-        // the ConGetSet interface, that specifically handles a conpty resize.
-        if (_pConApi->ResizeWindow(parameter2.value_or(0), parameter1.value_or(0)))
+        // ConhostInternalGetSet, that specifically handles a conpty resize.
+        if (_api.ResizeWindow(parameter2.value_or(0), parameter1.value_or(0)))
         {
             auto& gci = ServiceLocator::LocateGlobals().getConsoleInformation();
             THROW_IF_FAILED(gci.GetVtIo()->SuppressResizeRepaint());
@@ -143,7 +140,7 @@ bool InteractDispatch::WindowManipulation(const DispatchTypes::WindowManipulatio
 bool InteractDispatch::MoveCursor(const VTInt row, const VTInt col)
 {
     // First retrieve some information about the buffer
-    const auto viewport = _pConApi->GetViewport();
+    const auto viewport = _api.GetViewport();
 
     // In VT, the origin is 1,1. For our array, it's 0,0. So subtract 1.
     // Apply boundary tests to ensure the cursor isn't outside the viewport rectangle.
@@ -158,7 +155,7 @@ bool InteractDispatch::MoveCursor(const VTInt row, const VTInt col)
     RETURN_IF_FAILED(gci.GetVtIo()->SetCursorPosition(coordCursorShort));
 
     // Finally, attempt to set the adjusted cursor position back into the console.
-    auto& cursor = _pConApi->GetTextBuffer().GetCursor();
+    auto& cursor = _api.GetTextBuffer().GetCursor();
     cursor.SetPosition(coordCursorShort);
     cursor.SetHasMoved(true);
     return true;
@@ -172,7 +169,7 @@ bool InteractDispatch::MoveCursor(const VTInt row, const VTInt col)
 // - true if enabled (see IsInVirtualTerminalInputMode). false otherwise.
 bool InteractDispatch::IsVtInputEnabled() const
 {
-    return _pConApi->IsVtInputEnabled();
+    return _api.IsVtInputEnabled();
 }
 
 // Method Description:
diff --git a/src/terminal/adapter/InteractDispatch.hpp b/src/terminal/adapter/InteractDispatch.hpp
index 704e51dd1c9..8fd34868211 100644
--- a/src/terminal/adapter/InteractDispatch.hpp
+++ b/src/terminal/adapter/InteractDispatch.hpp
@@ -3,7 +3,7 @@ Copyright (c) Microsoft Corporation
 Licensed under the MIT license.
 
 Module Name:
-- adaptDispatch.hpp
+- InteractDispatch.hpp
 
 Abstract:
 - This serves as the Windows Console API-specific implementation of the
@@ -16,14 +16,14 @@ Author(s):
 
 #include "DispatchTypes.hpp"
 #include "IInteractDispatch.hpp"
-#include "conGetSet.hpp"
+#include "../../host/outputStream.hpp"
 
 namespace Microsoft::Console::VirtualTerminal
 {
     class InteractDispatch : public IInteractDispatch
     {
     public:
-        InteractDispatch(std::unique_ptr<ConGetSet> pConApi);
+        InteractDispatch();
 
         bool WriteInput(std::deque<std::unique_ptr<IInputEvent>>& inputEvents) override;
         bool WriteCtrlKey(const KeyEvent& event) override;
@@ -38,6 +38,6 @@ namespace Microsoft::Console::VirtualTerminal
         bool FocusChanged(const bool focused) const override;
 
     private:
-        std::unique_ptr<ConGetSet> _pConApi;
+        ConhostInternalGetSet _api;
     };
 }
diff --git a/src/terminal/adapter/adaptDispatch.cpp b/src/terminal/adapter/adaptDispatch.cpp
index 4b493a1f21f..2dca06ebe4b 100644
--- a/src/terminal/adapter/adaptDispatch.cpp
+++ b/src/terminal/adapter/adaptDispatch.cpp
@@ -4,7 +4,6 @@
 #include "precomp.h"
 
 #include "adaptDispatch.hpp"
-#include "conGetSet.hpp"
 #include "../../renderer/base/renderer.hpp"
 #include "../../types/inc/Viewport.hpp"
 #include "../../types/inc/utils.hpp"
@@ -15,20 +14,8 @@ using namespace Microsoft::Console::Types;
 using namespace Microsoft::Console::Render;
 using namespace Microsoft::Console::VirtualTerminal;
 
-// Routine Description:
-// - No Operation helper. It's just here to make sure they're always all the same.
-// Arguments:
-// - <none>
-// Return Value:
-// - Always false to signify we didn't handle it.
-bool NoOp() noexcept
-{
-    return false;
-}
-
-// Note: AdaptDispatch will take ownership of pConApi and pDefaults
-AdaptDispatch::AdaptDispatch(std::unique_ptr<ConGetSet> pConApi, Renderer& renderer, RenderSettings& renderSettings, TerminalInput& terminalInput) :
-    _pConApi{ std::move(pConApi) },
+AdaptDispatch::AdaptDispatch(ITerminalApi& api, Renderer& renderer, RenderSettings& renderSettings, TerminalInput& terminalInput) :
+    _api{ api },
     _renderer{ renderer },
     _renderSettings{ renderSettings },
     _terminalInput{ terminalInput },
@@ -37,7 +24,6 @@ AdaptDispatch::AdaptDispatch(std::unique_ptr<ConGetSet> pConApi, Renderer& rende
     _isDECCOLMAllowed(false), // by default, DECCOLM is not allowed.
     _termOutput()
 {
-    THROW_HR_IF_NULL(E_INVALIDARG, _pConApi.get());
     _scrollMargins = { 0 }; // initially, there are no scroll margins.
 }
 
@@ -56,7 +42,7 @@ void AdaptDispatch::Print(const wchar_t wchPrintable)
     // a character is only output if the DEL is translated to something else.
     if (wchTranslated != AsciiChars::DEL)
     {
-        _pConApi->PrintString({ &wchTranslated, 1 });
+        _api.PrintString({ &wchTranslated, 1 });
     }
 }
 
@@ -77,11 +63,11 @@ void AdaptDispatch::PrintString(const std::wstring_view string)
         {
             buffer.push_back(_termOutput.TranslateKey(wch));
         }
-        _pConApi->PrintString(buffer);
+        _api.PrintString(buffer);
     }
     else
     {
-        _pConApi->PrintString(string);
+        _api.PrintString(string);
     }
 }
 
@@ -177,7 +163,7 @@ std::pair<int, int> AdaptDispatch::_GetVerticalMargins(const til::rect& viewport
     if (_scrollMargins.Top >= bottommostRow)
     {
         _scrollMargins.Top = _scrollMargins.Bottom = 0;
-        _pConApi->SetScrollingRegion(_scrollMargins);
+        _api.SetScrollingRegion(_scrollMargins);
     }
     // If margins aren't set, use the full extent of the viewport.
     const auto marginsSet = _scrollMargins.Top < _scrollMargins.Bottom;
@@ -204,8 +190,8 @@ std::pair<int, int> AdaptDispatch::_GetVerticalMargins(const til::rect& viewport
 bool AdaptDispatch::_CursorMovePosition(const Offset rowOffset, const Offset colOffset, const bool clampInMargins)
 {
     // First retrieve some information about the buffer
-    const auto viewport = _pConApi->GetViewport();
-    auto& textBuffer = _pConApi->GetTextBuffer();
+    const auto viewport = _api.GetViewport();
+    auto& textBuffer = _api.GetTextBuffer();
     auto& cursor = textBuffer.GetCursor();
     const auto cursorPosition = cursor.GetPosition();
     const auto [topMargin, bottomMargin] = _GetVerticalMargins(viewport, true);
@@ -352,8 +338,8 @@ bool AdaptDispatch::CursorPosition(const VTInt line, const VTInt column)
 bool AdaptDispatch::CursorSaveState()
 {
     // First retrieve some information about the buffer
-    const auto viewport = _pConApi->GetViewport();
-    const auto& textBuffer = _pConApi->GetTextBuffer();
+    const auto viewport = _api.GetViewport();
+    const auto& textBuffer = _api.GetTextBuffer();
     const auto attributes = textBuffer.GetCurrentAttributes();
 
     // The cursor is given to us by the API as relative to the whole buffer.
@@ -369,7 +355,7 @@ bool AdaptDispatch::CursorSaveState()
     savedCursorState.Attributes = attributes;
     savedCursorState.TermOutput = _termOutput;
     savedCursorState.C1ControlsAccepted = _GetParserMode(StateMachine::Mode::AcceptC1);
-    savedCursorState.CodePage = _pConApi->GetConsoleOutputCP();
+    savedCursorState.CodePage = _api.GetConsoleOutputCP();
 
     return true;
 }
@@ -393,7 +379,7 @@ bool AdaptDispatch::CursorRestoreState()
     // position is clamped within the margins.
     if (savedCursorState.IsOriginModeRelative)
     {
-        const auto viewport = _pConApi->GetViewport();
+        const auto viewport = _api.GetViewport();
         const auto [topMargin, bottomMargin] = _GetVerticalMargins(viewport, false);
         // VT origin is at 1,1 so we need to add 1 to these margins.
         row = std::clamp(row, topMargin + 1, bottomMargin + 1);
@@ -407,7 +393,7 @@ bool AdaptDispatch::CursorRestoreState()
     _isOriginModeRelative = savedCursorState.IsOriginModeRelative;
 
     // Restore text attributes.
-    _pConApi->SetTextAttributes(savedCursorState.Attributes);
+    _api.SetTextAttributes(savedCursorState.Attributes);
 
     // Restore designated character set.
     _termOutput = savedCursorState.TermOutput;
@@ -418,7 +404,7 @@ bool AdaptDispatch::CursorRestoreState()
     // Restore the code page if it was previously saved.
     if (savedCursorState.CodePage != 0)
     {
-        _pConApi->SetConsoleOutputCP(savedCursorState.CodePage);
+        _api.SetConsoleOutputCP(savedCursorState.CodePage);
     }
 
     return true;
@@ -432,7 +418,7 @@ bool AdaptDispatch::CursorRestoreState()
 // - True.
 bool AdaptDispatch::CursorVisibility(const bool fIsVisible)
 {
-    _pConApi->GetTextBuffer().GetCursor().SetIsVisible(fIsVisible);
+    _api.GetTextBuffer().GetCursor().SetIsVisible(fIsVisible);
     return true;
 }
 
@@ -521,7 +507,7 @@ void AdaptDispatch::_ScrollRectHorizontally(TextBuffer& textBuffer, const til::r
 // - <none>
 void AdaptDispatch::_InsertDeleteCharacterHelper(const VTInt delta)
 {
-    auto& textBuffer = _pConApi->GetTextBuffer();
+    auto& textBuffer = _api.GetTextBuffer();
     const auto row = textBuffer.GetCursor().GetPosition().Y;
     const auto startCol = textBuffer.GetCursor().GetPosition().X;
     const auto endCol = textBuffer.GetLineWidth(row);
@@ -574,7 +560,7 @@ void AdaptDispatch::_FillRect(TextBuffer& textBuffer, const til::rect& fillRect,
         {
             textBuffer.WriteLine(fillData, COORD{ col, row }, false);
         }
-        _pConApi->NotifyAccessibilityChange(fillRect);
+        _api.NotifyAccessibilityChange(fillRect);
     }
 }
 
@@ -589,7 +575,7 @@ void AdaptDispatch::_FillRect(TextBuffer& textBuffer, const til::rect& fillRect,
 // - True.
 bool AdaptDispatch::EraseCharacters(const VTInt numChars)
 {
-    auto& textBuffer = _pConApi->GetTextBuffer();
+    auto& textBuffer = _api.GetTextBuffer();
     const auto row = textBuffer.GetCursor().GetPosition().Y;
     const auto startCol = textBuffer.GetCursor().GetPosition().X;
     const auto endCol = std::min<VTInt>(startCol + numChars, textBuffer.GetLineWidth(row));
@@ -627,7 +613,7 @@ bool AdaptDispatch::EraseInDisplay(const DispatchTypes::EraseType eraseType)
         // make the state machine propagate this ED sequence to the connected
         // terminal application. While we're in conpty mode, we don't really
         // have a scrollback, but the attached terminal might.
-        return !_pConApi->IsConsolePty();
+        return !_api.IsConsolePty();
     }
     else if (eraseType == DispatchTypes::EraseType::All)
     {
@@ -638,11 +624,11 @@ bool AdaptDispatch::EraseInDisplay(const DispatchTypes::EraseType eraseType)
         // connected terminal to do the same thing, so that the terminal will
         // move it's own buffer contents into the scrollback.
         _EraseAll();
-        return !_pConApi->IsConsolePty();
+        return !_api.IsConsolePty();
     }
 
-    const auto viewport = _pConApi->GetViewport();
-    auto& textBuffer = _pConApi->GetTextBuffer();
+    const auto viewport = _api.GetViewport();
+    auto& textBuffer = _api.GetTextBuffer();
     const auto bufferWidth = textBuffer.GetSize().Width();
     const auto row = textBuffer.GetCursor().GetPosition().Y;
     const auto col = textBuffer.GetCursor().GetPosition().X;
@@ -680,7 +666,7 @@ bool AdaptDispatch::EraseInDisplay(const DispatchTypes::EraseType eraseType)
 // - True if handled successfully. False otherwise.
 bool AdaptDispatch::EraseInLine(const DispatchTypes::EraseType eraseType)
 {
-    auto& textBuffer = _pConApi->GetTextBuffer();
+    auto& textBuffer = _api.GetTextBuffer();
     const auto row = textBuffer.GetCursor().GetPosition().Y;
     const auto col = textBuffer.GetCursor().GetPosition().X;
 
@@ -711,7 +697,7 @@ bool AdaptDispatch::EraseInLine(const DispatchTypes::EraseType eraseType)
 // - True.
 bool AdaptDispatch::SetLineRendition(const LineRendition rendition)
 {
-    _pConApi->GetTextBuffer().SetCurrentLineRendition(rendition);
+    _api.GetTextBuffer().SetCurrentLineRendition(rendition);
     return true;
 }
 
@@ -747,7 +733,7 @@ bool AdaptDispatch::DeviceStatusReport(const DispatchTypes::AnsiStatusType statu
 bool AdaptDispatch::DeviceAttributes()
 {
     // See: http://vt100.net/docs/vt100-ug/chapter3.html#DA
-    _WriteResponse(L"\x1b[?1;0c");
+    _api.ReturnResponse(L"\x1b[?1;0c");
     return true;
 }
 
@@ -762,7 +748,7 @@ bool AdaptDispatch::DeviceAttributes()
 // - True.
 bool AdaptDispatch::SecondaryDeviceAttributes()
 {
-    _WriteResponse(L"\x1b[>0;10;1c");
+    _api.ReturnResponse(L"\x1b[>0;10;1c");
     return true;
 }
 
@@ -775,7 +761,7 @@ bool AdaptDispatch::SecondaryDeviceAttributes()
 // - True.
 bool AdaptDispatch::TertiaryDeviceAttributes()
 {
-    _WriteResponse(L"\x1bP!|00000000\x1b\\");
+    _api.ReturnResponse(L"\x1bP!|00000000\x1b\\");
     return true;
 }
 
@@ -789,7 +775,7 @@ bool AdaptDispatch::TertiaryDeviceAttributes()
 // - True.
 bool AdaptDispatch::Vt52DeviceAttributes()
 {
-    _WriteResponse(L"\x1b/Z");
+    _api.ReturnResponse(L"\x1b/Z");
     return true;
 }
 
@@ -819,10 +805,10 @@ bool AdaptDispatch::RequestTerminalParameters(const DispatchTypes::ReportingPerm
     switch (permission)
     {
     case DispatchTypes::ReportingPermission::Unsolicited:
-        _WriteResponse(L"\x1b[2;1;1;128;128;1;0x");
+        _api.ReturnResponse(L"\x1b[2;1;1;128;128;1;0x");
         return true;
     case DispatchTypes::ReportingPermission::Solicited:
-        _WriteResponse(L"\x1b[3;1;1;128;128;1;0x");
+        _api.ReturnResponse(L"\x1b[3;1;1;128;128;1;0x");
         return true;
     default:
         return false;
@@ -838,7 +824,7 @@ bool AdaptDispatch::RequestTerminalParameters(const DispatchTypes::ReportingPerm
 void AdaptDispatch::_OperatingStatus() const
 {
     // We always report a good operating condition.
-    _WriteResponse(L"\x1b[0n");
+    _api.ReturnResponse(L"\x1b[0n");
 }
 
 // Routine Description:
@@ -849,8 +835,8 @@ void AdaptDispatch::_OperatingStatus() const
 // - <none>
 void AdaptDispatch::_CursorPositionReport()
 {
-    const auto viewport = _pConApi->GetViewport();
-    const auto& textBuffer = _pConApi->GetTextBuffer();
+    const auto viewport = _api.GetViewport();
+    const auto& textBuffer = _api.GetTextBuffer();
 
     // First pull the cursor position relative to the entire buffer out of the console.
     til::point cursorPosition{ textBuffer.GetCursor().GetPosition() };
@@ -872,39 +858,7 @@ void AdaptDispatch::_CursorPositionReport()
     // Now send it back into the input channel of the console.
     // First format the response string.
     const auto response = wil::str_printf<std::wstring>(L"\x1b[%d;%dR", cursorPosition.Y, cursorPosition.X);
-    _WriteResponse(response);
-}
-
-// Routine Description:
-// - Helper to send a string reply to the input stream of the console.
-// - Used by various commands where the program attached would like a reply to one of the commands issued.
-// - This will generate two "key presses" (one down, one up) for every character in the string and place them into the head of the console's input stream.
-// Arguments:
-// - reply - The reply string to transmit back to the input stream
-// Return Value:
-// - <none>
-void AdaptDispatch::_WriteResponse(const std::wstring_view reply) const
-{
-    std::deque<std::unique_ptr<IInputEvent>> inEvents;
-
-    // generate a paired key down and key up event for every
-    // character to be sent into the console's input buffer
-    for (const auto& wch : reply)
-    {
-        // This wasn't from a real keyboard, so we're leaving key/scan codes blank.
-        KeyEvent keyEvent{ TRUE, 1, 0, 0, wch, 0 };
-
-        inEvents.push_back(std::make_unique<KeyEvent>(keyEvent));
-        keyEvent.SetKeyDown(false);
-        inEvents.push_back(std::make_unique<KeyEvent>(keyEvent));
-    }
-
-    size_t eventsWritten;
-    // TODO GH#4954 During the input refactor we may want to add a "priority" input list
-    // to make sure that "response" input is spooled directly into the application.
-    // We switched this to an append (vs. a prepend) to fix GH#1637, a bug where two CPR
-    // could collide with each other.
-    _pConApi->WriteInput(inEvents, eventsWritten);
+    _api.ReturnResponse(response);
 }
 
 // Routine Description:
@@ -915,8 +869,8 @@ void AdaptDispatch::_WriteResponse(const std::wstring_view reply) const
 // - <none>
 void AdaptDispatch::_ScrollMovement(const VTInt delta)
 {
-    const auto viewport = _pConApi->GetViewport();
-    auto& textBuffer = _pConApi->GetTextBuffer();
+    const auto viewport = _api.GetViewport();
+    auto& textBuffer = _api.GetTextBuffer();
     const auto bufferWidth = textBuffer.GetSize().Width();
     const auto [topMargin, bottomMargin] = _GetVerticalMargins(viewport, true);
     _ScrollRectVertically(textBuffer, { 0, topMargin, bufferWidth, bottomMargin + 1 }, delta);
@@ -956,9 +910,9 @@ bool AdaptDispatch::ScrollDown(const VTInt uiDistance)
 // - True.
 bool AdaptDispatch::SetColumns(const VTInt columns)
 {
-    const auto viewport = _pConApi->GetViewport();
+    const auto viewport = _api.GetViewport();
     const auto viewportHeight = viewport.bottom - viewport.top;
-    _pConApi->ResizeWindow(columns, viewportHeight);
+    _api.ResizeWindow(columns, viewportHeight);
     return true;
 }
 
@@ -991,7 +945,7 @@ bool AdaptDispatch::_DoDECCOLMHelper(const VTInt columns)
 // - true if the mode is enabled. false if disabled.
 bool AdaptDispatch::_GetParserMode(const StateMachine::Mode mode) const
 {
-    return _pConApi->GetStateMachine().GetParserMode(mode);
+    return _api.GetStateMachine().GetParserMode(mode);
 }
 
 // Routine Description:
@@ -1003,7 +957,7 @@ bool AdaptDispatch::_GetParserMode(const StateMachine::Mode mode) const
 // - <none>
 void AdaptDispatch::_SetParserMode(const StateMachine::Mode mode, const bool enable)
 {
-    _pConApi->GetStateMachine().SetParserMode(mode, enable);
+    _api.GetStateMachine().SetParserMode(mode, enable);
 }
 
 // Routine Description:
@@ -1029,14 +983,14 @@ bool AdaptDispatch::_SetInputMode(const TerminalInput::Mode mode, const bool ena
     // GH#12799 - If the app requested that we disable focus events, DON'T pass
     // that through. ConPTY would _always_ like to know about focus events.
 
-    return !_pConApi->IsConsolePty() ||
-           !_pConApi->IsVtInputEnabled() ||
+    return !_api.IsConsolePty() ||
+           !_api.IsVtInputEnabled() ||
            (!enable && mode == TerminalInput::Mode::FocusEvent);
 
     // Another way of writing the above statement is:
     //
-    // const bool inConpty = _pConApi->IsConsolePty();
-    // const bool shouldPassthrough = inConpty && _pConApi->IsVtInputEnabled();
+    // const bool inConpty = _api.IsConsolePty();
+    // const bool shouldPassthrough = inConpty && _api.IsVtInputEnabled();
     // const bool disabledFocusEvents = inConpty && (!enable && mode == TerminalInput::Mode::FocusEvent);
     // return !shouldPassthrough || disabledFocusEvents;
     //
@@ -1110,6 +1064,9 @@ bool AdaptDispatch::_ModeParamsHelper(const DispatchTypes::ModeParams param, con
     case DispatchTypes::ModeParams::ASB_AlternateScreenBuffer:
         success = enable ? UseAlternateScreenBuffer() : UseMainScreenBuffer();
         break;
+    case DispatchTypes::ModeParams::XTERM_BracketedPasteMode:
+        success = EnableXtermBracketedPasteMode(enable);
+        break;
     case DispatchTypes::ModeParams::W32IM_Win32InputMode:
         success = EnableWin32InputMode(enable);
         break;
@@ -1182,7 +1139,7 @@ bool AdaptDispatch::SetCursorKeysMode(const bool applicationMode)
 // - True if handled successfully. False otherwise.
 bool AdaptDispatch::EnableCursorBlinking(const bool enable)
 {
-    auto& cursor = _pConApi->GetTextBuffer().GetCursor();
+    auto& cursor = _api.GetTextBuffer().GetCursor();
     cursor.SetBlinkingAllowed(enable);
 
     // GH#2642 - From what we've gathered from other terminals, when blinking is
@@ -1193,7 +1150,7 @@ bool AdaptDispatch::EnableCursorBlinking(const bool enable)
     // (Yes, the cursor can be On and NOT Visible)
     cursor.SetIsOn(true);
 
-    return !_pConApi->IsConsolePty();
+    return !_api.IsConsolePty();
 }
 
 // Routine Description:
@@ -1205,8 +1162,8 @@ bool AdaptDispatch::EnableCursorBlinking(const bool enable)
 // - <none>
 void AdaptDispatch::_InsertDeleteLineHelper(const int32_t delta)
 {
-    const auto viewport = _pConApi->GetViewport();
-    auto& textBuffer = _pConApi->GetTextBuffer();
+    const auto viewport = _api.GetViewport();
+    auto& textBuffer = _api.GetTextBuffer();
     const auto bufferWidth = textBuffer.GetSize().Width();
 
     auto& cursor = textBuffer.GetCursor();
@@ -1286,7 +1243,7 @@ bool AdaptDispatch::SetAnsiMode(const bool ansiMode)
 bool AdaptDispatch::SetScreenMode(const bool reverseMode)
 {
     // If we're a conpty, always return false
-    if (_pConApi->IsConsolePty())
+    if (_api.IsConsolePty())
     {
         return false;
     }
@@ -1319,7 +1276,7 @@ bool AdaptDispatch::SetOriginMode(const bool relativeMode) noexcept
 // - True.
 bool AdaptDispatch::SetAutoWrapMode(const bool wrapAtEOL)
 {
-    _pConApi->SetAutoWrapMode(wrapAtEOL);
+    _api.SetAutoWrapMode(wrapAtEOL);
     return true;
 }
 
@@ -1346,7 +1303,7 @@ void AdaptDispatch::_DoSetTopBottomScrollingMargins(const VTInt topMargin,
     THROW_IF_FAILED(SizeTToShort(topMargin, &actualTop));
     THROW_IF_FAILED(SizeTToShort(bottomMargin, &actualBottom));
 
-    const auto viewport = _pConApi->GetViewport();
+    const auto viewport = _api.GetViewport();
     const auto screenHeight = gsl::narrow_cast<short>(viewport.bottom - viewport.top);
     // The default top margin is line 1
     if (actualTop == 0)
@@ -1379,7 +1336,7 @@ void AdaptDispatch::_DoSetTopBottomScrollingMargins(const VTInt topMargin,
         }
         _scrollMargins.Top = actualTop;
         _scrollMargins.Bottom = actualBottom;
-        _pConApi->SetScrollingRegion(_scrollMargins);
+        _api.SetScrollingRegion(_scrollMargins);
     }
 }
 
@@ -1412,7 +1369,7 @@ bool AdaptDispatch::SetTopBottomScrollingMargins(const VTInt topMargin,
 // - True.
 bool AdaptDispatch::WarningBell()
 {
-    _pConApi->WarningBell();
+    _api.WarningBell();
     return true;
 }
 
@@ -1440,13 +1397,13 @@ bool AdaptDispatch::LineFeed(const DispatchTypes::LineFeedType lineFeedType)
     switch (lineFeedType)
     {
     case DispatchTypes::LineFeedType::DependsOnMode:
-        _pConApi->LineFeed(_pConApi->GetLineFeedMode());
+        _api.LineFeed(_api.GetLineFeedMode());
         return true;
     case DispatchTypes::LineFeedType::WithoutReturn:
-        _pConApi->LineFeed(false);
+        _api.LineFeed(false);
         return true;
     case DispatchTypes::LineFeedType::WithReturn:
-        _pConApi->LineFeed(true);
+        _api.LineFeed(true);
         return true;
     default:
         return false;
@@ -1462,8 +1419,8 @@ bool AdaptDispatch::LineFeed(const DispatchTypes::LineFeedType lineFeedType)
 // - True.
 bool AdaptDispatch::ReverseLineFeed()
 {
-    const auto viewport = _pConApi->GetViewport();
-    auto& textBuffer = _pConApi->GetTextBuffer();
+    const auto viewport = _api.GetViewport();
+    auto& textBuffer = _api.GetTextBuffer();
     auto& cursor = textBuffer.GetCursor();
     const auto cursorPosition = cursor.GetPosition();
     const auto [topMargin, bottomMargin] = _GetVerticalMargins(viewport, true);
@@ -1493,7 +1450,7 @@ bool AdaptDispatch::ReverseLineFeed()
 // - True.
 bool AdaptDispatch::SetWindowTitle(std::wstring_view title)
 {
-    _pConApi->SetWindowTitle(title);
+    _api.SetWindowTitle(title);
     return true;
 }
 
@@ -1507,7 +1464,7 @@ bool AdaptDispatch::SetWindowTitle(std::wstring_view title)
 bool AdaptDispatch::UseAlternateScreenBuffer()
 {
     CursorSaveState();
-    _pConApi->UseAlternateScreenBuffer();
+    _api.UseAlternateScreenBuffer();
     _usingAltBuffer = true;
     return true;
 }
@@ -1521,7 +1478,7 @@ bool AdaptDispatch::UseAlternateScreenBuffer()
 // - True.
 bool AdaptDispatch::UseMainScreenBuffer()
 {
-    _pConApi->UseMainScreenBuffer();
+    _api.UseMainScreenBuffer();
     _usingAltBuffer = false;
     CursorRestoreState();
     return true;
@@ -1535,7 +1492,7 @@ bool AdaptDispatch::UseMainScreenBuffer()
 // - True.
 bool AdaptDispatch::HorizontalTabSet()
 {
-    const auto& textBuffer = _pConApi->GetTextBuffer();
+    const auto& textBuffer = _api.GetTextBuffer();
     const auto width = textBuffer.GetSize().Dimensions().X;
     const auto column = textBuffer.GetCursor().GetPosition().X;
 
@@ -1556,7 +1513,7 @@ bool AdaptDispatch::HorizontalTabSet()
 // - True.
 bool AdaptDispatch::ForwardTab(const VTInt numTabs)
 {
-    auto& textBuffer = _pConApi->GetTextBuffer();
+    auto& textBuffer = _api.GetTextBuffer();
     auto& cursor = textBuffer.GetCursor();
     const auto width = textBuffer.GetLineWidth(cursor.GetPosition().Y);
     auto column = cursor.GetPosition().X;
@@ -1586,7 +1543,7 @@ bool AdaptDispatch::ForwardTab(const VTInt numTabs)
 // - True.
 bool AdaptDispatch::BackwardsTab(const VTInt numTabs)
 {
-    auto& textBuffer = _pConApi->GetTextBuffer();
+    auto& textBuffer = _api.GetTextBuffer();
     auto& cursor = textBuffer.GetCursor();
     const auto width = textBuffer.GetLineWidth(cursor.GetPosition().Y);
     auto column = cursor.GetPosition().X;
@@ -1638,7 +1595,7 @@ bool AdaptDispatch::TabClear(const DispatchTypes::TabClearType clearType)
 // - <none>
 void AdaptDispatch::_ClearSingleTabStop()
 {
-    const auto& textBuffer = _pConApi->GetTextBuffer();
+    const auto& textBuffer = _api.GetTextBuffer();
     const auto width = textBuffer.GetSize().Dimensions().X;
     const auto column = textBuffer.GetCursor().GetPosition().X;
 
@@ -1716,18 +1673,18 @@ bool AdaptDispatch::DesignateCodingSystem(const VTID codingSystem)
     // This will be used to restore the code page in response to a reset.
     if (!_initialCodePage.has_value())
     {
-        _initialCodePage = _pConApi->GetConsoleOutputCP();
+        _initialCodePage = _api.GetConsoleOutputCP();
     }
 
     switch (codingSystem)
     {
     case DispatchTypes::CodingSystem::ISO2022:
-        _pConApi->SetConsoleOutputCP(28591);
+        _api.SetConsoleOutputCP(28591);
         AcceptC1Controls(true);
         _termOutput.EnableGrTranslation(true);
         return true;
     case DispatchTypes::CodingSystem::UTF8:
-        _pConApi->SetConsoleOutputCP(CP_UTF8);
+        _api.SetConsoleOutputCP(CP_UTF8);
         AcceptC1Controls(false);
         _termOutput.EnableGrTranslation(false);
         return true;
@@ -1857,7 +1814,7 @@ bool AdaptDispatch::SoftReset()
     if (_initialCodePage.has_value())
     {
         // Restore initial code page if previously changed by a DOCS sequence.
-        _pConApi->SetConsoleOutputCP(_initialCodePage.value());
+        _api.SetConsoleOutputCP(_initialCodePage.value());
     }
     // Disable parsing of C1 control codes.
     AcceptC1Controls(false);
@@ -1870,7 +1827,7 @@ bool AdaptDispatch::SoftReset()
     _savedCursorState.at(0) = {}; // Main buffer
     _savedCursorState.at(1) = {}; // Alt buffer
 
-    return !_pConApi->IsConsolePty();
+    return !_api.IsConsolePty();
 }
 
 //Routine Description:
@@ -1900,7 +1857,7 @@ bool AdaptDispatch::HardReset()
     // If in the alt buffer, switch back to main before doing anything else.
     if (_usingAltBuffer)
     {
-        _pConApi->UseMainScreenBuffer();
+        _api.UseMainScreenBuffer();
         _usingAltBuffer = false;
     }
 
@@ -1933,7 +1890,7 @@ bool AdaptDispatch::HardReset()
     // make the state machine propagate this RIS sequence to the connected
     // terminal application. We've reset our state, but the connected terminal
     // might need to do more.
-    return !_pConApi->IsConsolePty();
+    return !_api.IsConsolePty();
 }
 
 // Routine Description:
@@ -1946,8 +1903,8 @@ bool AdaptDispatch::HardReset()
 // - True.
 bool AdaptDispatch::ScreenAlignmentPattern()
 {
-    const auto viewport = _pConApi->GetViewport();
-    auto& textBuffer = _pConApi->GetTextBuffer();
+    const auto viewport = _api.GetViewport();
+    auto& textBuffer = _api.GetTextBuffer();
     const auto bufferWidth = textBuffer.GetSize().Dimensions().X;
 
     // Fill the screen with the letter E using the default attributes.
@@ -1957,7 +1914,7 @@ bool AdaptDispatch::ScreenAlignmentPattern()
     // Reset the meta/extended attributes (but leave the colors unchanged).
     auto attr = textBuffer.GetCurrentAttributes();
     attr.SetStandardErase();
-    _pConApi->SetTextAttributes(attr);
+    _api.SetTextAttributes(attr);
     // Reset the origin mode to absolute.
     SetOriginMode(false);
     // Clear the scrolling margins.
@@ -1982,10 +1939,10 @@ bool AdaptDispatch::ScreenAlignmentPattern()
 // - <none>
 void AdaptDispatch::_EraseScrollback()
 {
-    const auto viewport = _pConApi->GetViewport();
+    const auto viewport = _api.GetViewport();
     const auto top = gsl::narrow_cast<short>(viewport.top);
     const auto height = gsl::narrow_cast<short>(viewport.bottom - viewport.top);
-    auto& textBuffer = _pConApi->GetTextBuffer();
+    auto& textBuffer = _api.GetTextBuffer();
     const auto bufferSize = textBuffer.GetSize().Dimensions();
     auto& cursor = textBuffer.GetCursor();
     const auto row = cursor.GetPosition().Y;
@@ -1997,7 +1954,7 @@ void AdaptDispatch::_EraseScrollback()
     // Also reset the line rendition for all of the cleared rows.
     textBuffer.ResetLineRenditionRange(height, bufferSize.Y);
     // Move the viewport
-    _pConApi->SetViewportPosition({ viewport.left, 0 });
+    _api.SetViewportPosition({ viewport.left, 0 });
     // Move the cursor to the same relative location.
     cursor.SetYPosition(row - top);
     cursor.SetHasMoved(true);
@@ -2017,9 +1974,9 @@ void AdaptDispatch::_EraseScrollback()
 // - <none>
 void AdaptDispatch::_EraseAll()
 {
-    const auto viewport = _pConApi->GetViewport();
+    const auto viewport = _api.GetViewport();
     const auto viewportHeight = gsl::narrow_cast<short>(viewport.bottom - viewport.top);
-    auto& textBuffer = _pConApi->GetTextBuffer();
+    auto& textBuffer = _api.GetTextBuffer();
     const auto bufferSize = textBuffer.GetSize();
 
     // Stash away the current position of the cursor within the viewport.
@@ -2028,9 +1985,12 @@ void AdaptDispatch::_EraseAll()
     auto& cursor = textBuffer.GetCursor();
     const auto row = cursor.GetPosition().Y - viewport.top;
 
-    // Calculate new viewport position
-    short newViewportTop = textBuffer.GetLastNonSpaceCharacter().Y + 1;
-    const short newViewportBottom = newViewportTop + viewportHeight;
+    // Calculate new viewport position. Typically we want to move one line below
+    // the last non-space row, but if the last non-space character is the very
+    // start of the buffer, then we shouldn't move down at all.
+    const til::point lastChar{ textBuffer.GetLastNonSpaceCharacter() };
+    auto newViewportTop = lastChar == til::point{} ? 0 : lastChar.Y + 1;
+    const auto newViewportBottom = newViewportTop + viewportHeight;
     const auto delta = newViewportBottom - (bufferSize.Height());
     for (auto i = 0; i < delta; i++)
     {
@@ -2038,7 +1998,7 @@ void AdaptDispatch::_EraseAll()
         newViewportTop--;
     }
     // Move the viewport
-    _pConApi->SetViewportPosition({ viewport.left, newViewportTop });
+    _api.SetViewportPosition({ viewport.left, newViewportTop });
     // Restore the relative cursor position
     cursor.SetYPosition(row + newViewportTop);
     cursor.SetHasMoved(true);
@@ -2154,9 +2114,16 @@ bool AdaptDispatch::EnableAlternateScroll(const bool enabled)
 // - enabled - true to enable, false to disable.
 // Return value:
 // True if handled successfully. False otherwise.
-bool AdaptDispatch::EnableXtermBracketedPasteMode(const bool /*enabled*/) noexcept
+bool AdaptDispatch::EnableXtermBracketedPasteMode(const bool enabled)
 {
-    return NoOp();
+    // Return false to forward the operation to the hosting terminal,
+    // since ConPTY can't handle this itself.
+    if (_api.IsConsolePty())
+    {
+        return false;
+    }
+    _api.EnableXtermBracketedPasteMode(enabled);
+    return true;
 }
 
 //Routine Description:
@@ -2175,7 +2142,7 @@ bool AdaptDispatch::SetCursorStyle(const DispatchTypes::CursorStyle cursorStyle)
     {
     case DispatchTypes::CursorStyle::UserDefault:
         fEnableBlinking = true;
-        actualType = _pConApi->GetUserDefaultCursorStyle();
+        actualType = _api.GetUserDefaultCursorStyle();
         break;
     case DispatchTypes::CursorStyle::BlinkingBlock:
         fEnableBlinking = true;
@@ -2209,14 +2176,14 @@ bool AdaptDispatch::SetCursorStyle(const DispatchTypes::CursorStyle cursorStyle)
         return false;
     }
 
-    auto& cursor = _pConApi->GetTextBuffer().GetCursor();
+    auto& cursor = _api.GetTextBuffer().GetCursor();
     cursor.SetType(actualType);
     cursor.SetBlinkingAllowed(fEnableBlinking);
     cursor.SetIsOn(true);
 
     // If we're a conpty, always return false, so that this cursor state will be
     // sent to the connected terminal
-    return !_pConApi->IsConsolePty();
+    return !_api.IsConsolePty();
 }
 
 // Method Description:
@@ -2237,9 +2204,16 @@ bool AdaptDispatch::SetCursorColor(const COLORREF cursorColor)
 // - content - The content to copy to clipboard. Must be null terminated.
 // Return Value:
 // - True if handled successfully. False otherwise.
-bool AdaptDispatch::SetClipboard(const std::wstring_view /*content*/) noexcept
+bool AdaptDispatch::SetClipboard(const std::wstring_view content)
 {
-    return false;
+    // Return false to forward the operation to the hosting terminal,
+    // since ConPTY can't handle this itself.
+    if (_api.IsConsolePty())
+    {
+        return false;
+    }
+    _api.CopyToClipboard(content);
+    return true;
 }
 
 // Method Description:
@@ -2257,14 +2231,19 @@ bool AdaptDispatch::SetColorTableEntry(const size_t tableIndex, const DWORD dwCo
     //      value to the terminal. Still handle the sequence so apps that use
     //      the API or VT to query the values of the color table still read the
     //      correct color.
-    if (_pConApi->IsConsolePty())
+    if (_api.IsConsolePty())
     {
         return false;
     }
 
+    // If we're updating the background color, we need to let the renderer
+    // know, since it may want to repaint the window background to match.
+    const auto backgroundIndex = _renderSettings.GetColorAliasIndex(ColorAlias::DefaultBackground);
+    const auto backgroundChanged = (tableIndex == backgroundIndex);
+
     // Update the screen colors if we're not a pty
     // No need to force a redraw in pty mode.
-    _renderer.TriggerRedrawAll();
+    _renderer.TriggerRedrawAll(backgroundChanged);
     return true;
 }
 
@@ -2314,16 +2293,16 @@ bool AdaptDispatch::WindowManipulation(const DispatchTypes::WindowManipulationTy
     switch (function)
     {
     case DispatchTypes::WindowManipulationType::DeIconifyWindow:
-        _pConApi->ShowWindow(true);
+        _api.ShowWindow(true);
         return true;
     case DispatchTypes::WindowManipulationType::IconifyWindow:
-        _pConApi->ShowWindow(false);
+        _api.ShowWindow(false);
         return true;
     case DispatchTypes::WindowManipulationType::RefreshWindow:
-        _pConApi->GetTextBuffer().TriggerRedrawAll();
+        _api.GetTextBuffer().TriggerRedrawAll();
         return true;
     case DispatchTypes::WindowManipulationType::ResizeWindowInCharacters:
-        _pConApi->ResizeWindow(parameter2.value_or(0), parameter1.value_or(0));
+        _api.ResizeWindow(parameter2.value_or(0), parameter1.value_or(0));
         return true;
     default:
         return false;
@@ -2338,7 +2317,7 @@ bool AdaptDispatch::WindowManipulation(const DispatchTypes::WindowManipulationTy
 // - true
 bool AdaptDispatch::AddHyperlink(const std::wstring_view uri, const std::wstring_view params)
 {
-    auto& textBuffer = _pConApi->GetTextBuffer();
+    auto& textBuffer = _api.GetTextBuffer();
     auto attr = textBuffer.GetCurrentAttributes();
     const auto id = textBuffer.GetHyperlinkId(uri, params);
     attr.SetHyperlinkId(id);
@@ -2353,7 +2332,7 @@ bool AdaptDispatch::AddHyperlink(const std::wstring_view uri, const std::wstring
 // - true
 bool AdaptDispatch::EndHyperlink()
 {
-    auto& textBuffer = _pConApi->GetTextBuffer();
+    auto& textBuffer = _api.GetTextBuffer();
     auto attr = textBuffer.GetCurrentAttributes();
     attr.SetHyperlinkId(0);
     textBuffer.SetCurrentAttributes(attr);
@@ -2361,12 +2340,93 @@ bool AdaptDispatch::EndHyperlink()
 }
 
 // Method Description:
-// - Ascribes to the ITermDispatch interface
-// - Not actually used in conhost
+// - Performs a ConEmu action
+//   Currently, the only actions we support are setting the taskbar state/progress
+//   and setting the working directory.
+// Arguments:
+// - string - contains the parameters that define which action we do
 // Return Value:
-// - false (so that the command gets flushed to terminal)
-bool AdaptDispatch::DoConEmuAction(const std::wstring_view /*string*/) noexcept
+// - True if handled successfully. False otherwise.
+bool AdaptDispatch::DoConEmuAction(const std::wstring_view string)
 {
+    // Return false to forward the operation to the hosting terminal,
+    // since ConPTY can't handle this itself.
+    if (_api.IsConsolePty())
+    {
+        return false;
+    }
+
+    constexpr size_t TaskbarMaxState{ 4 };
+    constexpr size_t TaskbarMaxProgress{ 100 };
+
+    unsigned int state = 0;
+    unsigned int progress = 0;
+
+    const auto parts = Utils::SplitString(string, L';');
+    unsigned int subParam = 0;
+
+    if (parts.size() < 1 || !Utils::StringToUint(til::at(parts, 0), subParam))
+    {
+        return false;
+    }
+
+    // 4 is SetProgressBar, which sets the taskbar state/progress.
+    if (subParam == 4)
+    {
+        if (parts.size() >= 2)
+        {
+            // A state parameter is defined, parse it out
+            const auto stateSuccess = Utils::StringToUint(til::at(parts, 1), state);
+            if (!stateSuccess && !til::at(parts, 1).empty())
+            {
+                return false;
+            }
+            if (parts.size() >= 3)
+            {
+                // A progress parameter is also defined, parse it out
+                const auto progressSuccess = Utils::StringToUint(til::at(parts, 2), progress);
+                if (!progressSuccess && !til::at(parts, 2).empty())
+                {
+                    return false;
+                }
+            }
+        }
+
+        if (state > TaskbarMaxState)
+        {
+            // state is out of bounds, return false
+            return false;
+        }
+        if (progress > TaskbarMaxProgress)
+        {
+            // progress is greater than the maximum allowed value, clamp it to the max
+            progress = TaskbarMaxProgress;
+        }
+        _api.SetTaskbarProgress(static_cast<DispatchTypes::TaskbarState>(state), progress);
+        return true;
+    }
+    // 9 is SetWorkingDirectory, which informs the terminal about the current working directory.
+    else if (subParam == 9)
+    {
+        if (parts.size() >= 2)
+        {
+            const auto path = til::at(parts, 1);
+            // The path should be surrounded with '"' according to the documentation of ConEmu.
+            // An example: 9;"D:/"
+            if (path.at(0) == L'"' && path.at(path.size() - 1) == L'"' && path.size() >= 3)
+            {
+                _api.SetWorkingDirectory(path.substr(1, path.size() - 2));
+            }
+            else
+            {
+                // If we fail to find the surrounding quotation marks, we'll give the path a try anyway.
+                // ConEmu also does this.
+                _api.SetWorkingDirectory(path);
+            }
+            return true;
+        }
+    }
+
     return false;
 }
 
@@ -2397,7 +2457,7 @@ ITermDispatch::StringHandler AdaptDispatch::DownloadDRCS(const VTInt fontNumber,
     // If we're a conpty, we're just going to ignore the operation for now.
     // There's no point in trying to pass it through without also being able
     // to pass through the character set designations.
-    if (_pConApi->IsConsolePty())
+    if (_api.IsConsolePty())
     {
         return nullptr;
     }
@@ -2482,7 +2542,7 @@ ITermDispatch::StringHandler AdaptDispatch::RequestSetting()
                 _ReportDECSTBMSetting();
                 break;
             default:
-                _WriteResponse(L"\033P0$r\033\\");
+                _api.ReturnResponse(L"\033P0$r\033\\");
                 break;
             }
             return false;
@@ -2513,7 +2573,7 @@ void AdaptDispatch::_ReportSGRSetting() const
     fmt::basic_memory_buffer<wchar_t, 64> response;
     response.append(L"\033P1$r0"sv);
 
-    const auto attr = _pConApi->GetTextBuffer().GetCurrentAttributes();
+    const auto attr = _api.GetTextBuffer().GetCurrentAttributes();
     // For each boolean attribute that is set, we add the appropriate
     // parameter value to the response string.
     const auto addAttribute = [&](const auto& parameter, const auto enabled) {
@@ -2560,7 +2620,7 @@ void AdaptDispatch::_ReportSGRSetting() const
 
     // The 'm' indicates this is an SGR response, and ST ends the sequence.
     response.append(L"m\033\\"sv);
-    _WriteResponse({ response.data(), response.size() });
+    _api.ReturnResponse({ response.data(), response.size() });
 }
 
 // Method Description:
@@ -2577,12 +2637,12 @@ void AdaptDispatch::_ReportDECSTBMSetting()
     fmt::basic_memory_buffer<wchar_t, 64> response;
     response.append(L"\033P1$r"sv);
 
-    const auto viewport = _pConApi->GetViewport();
+    const auto viewport = _api.GetViewport();
     const auto [marginTop, marginBottom] = _GetVerticalMargins(viewport, false);
     // VT origin is at 1,1 so we need to add 1 to these margins.
     fmt::format_to(std::back_inserter(response), FMT_COMPILE(L"{};{}"), marginTop + 1, marginBottom + 1);
 
     // The 'r' indicates this is an DECSTBM response, and ST ends the sequence.
     response.append(L"r\033\\"sv);
-    _WriteResponse({ response.data(), response.size() });
+    _api.ReturnResponse({ response.data(), response.size() });
 }
diff --git a/src/terminal/adapter/adaptDispatch.hpp b/src/terminal/adapter/adaptDispatch.hpp
index 3cf677b1947..722645dc1a5 100644
--- a/src/terminal/adapter/adaptDispatch.hpp
+++ b/src/terminal/adapter/adaptDispatch.hpp
@@ -15,7 +15,7 @@ Author(s):
 #pragma once
 
 #include "termDispatch.hpp"
-#include "conGetSet.hpp"
+#include "ITerminalApi.hpp"
 #include "FontBuffer.hpp"
 #include "terminalOutput.hpp"
 #include "../input/terminalInput.hpp"
@@ -29,7 +29,7 @@ namespace Microsoft::Console::VirtualTerminal
         using RenderSettings = Microsoft::Console::Render::RenderSettings;
 
     public:
-        AdaptDispatch(std::unique_ptr<ConGetSet> pConApi, Renderer& renderer, RenderSettings& renderSettings, TerminalInput& terminalInput);
+        AdaptDispatch(ITerminalApi& api, Renderer& renderer, RenderSettings& renderSettings, TerminalInput& terminalInput);
 
         void Print(const wchar_t wchPrintable) override;
         void PrintString(const std::wstring_view string) override;
@@ -109,11 +109,11 @@ namespace Microsoft::Console::VirtualTerminal
         bool EnableAnyEventMouseMode(const bool enabled) override; // ?1003
         bool EnableFocusEventMode(const bool enabled) override; // ?1004
         bool EnableAlternateScroll(const bool enabled) override; // ?1007
-        bool EnableXtermBracketedPasteMode(const bool enabled) noexcept override; // ?2004
+        bool EnableXtermBracketedPasteMode(const bool enabled) override; // ?2004
         bool SetCursorStyle(const DispatchTypes::CursorStyle cursorStyle) override; // DECSCUSR
         bool SetCursorColor(const COLORREF cursorColor) override;
 
-        bool SetClipboard(const std::wstring_view content) noexcept override; // OSCSetClipboard
+        bool SetClipboard(const std::wstring_view content) override; // OSCSetClipboard
 
         bool SetColorTableEntry(const size_t tableIndex,
                                 const DWORD color) override; // OSCColorTable
@@ -127,7 +127,7 @@ namespace Microsoft::Console::VirtualTerminal
         bool AddHyperlink(const std::wstring_view uri, const std::wstring_view params) override;
         bool EndHyperlink() override;
 
-        bool DoConEmuAction(const std::wstring_view string) noexcept override;
+        bool DoConEmuAction(const std::wstring_view string) override;
 
         StringHandler DownloadDRCS(const VTInt fontNumber,
                                    const VTParameter startChar,
@@ -184,7 +184,6 @@ namespace Microsoft::Console::VirtualTerminal
         void _OperatingStatus() const;
         void _CursorPositionReport();
 
-        void _WriteResponse(const std::wstring_view reply) const;
         bool _GetParserMode(const StateMachine::Mode mode) const;
         void _SetParserMode(const StateMachine::Mode mode, const bool enable);
         bool _SetInputMode(const TerminalInput::Mode mode, const bool enable);
@@ -202,7 +201,7 @@ namespace Microsoft::Console::VirtualTerminal
         std::vector<bool> _tabStopColumns;
         bool _initDefaultTabStops = true;
 
-        std::unique_ptr<ConGetSet> _pConApi;
+        ITerminalApi& _api;
         Renderer& _renderer;
         RenderSettings& _renderSettings;
         TerminalInput& _terminalInput;
diff --git a/src/terminal/adapter/adaptDispatchGraphics.cpp b/src/terminal/adapter/adaptDispatchGraphics.cpp
index 8caac1d6194..12485f9227a 100644
--- a/src/terminal/adapter/adaptDispatchGraphics.cpp
+++ b/src/terminal/adapter/adaptDispatchGraphics.cpp
@@ -4,7 +4,6 @@
 #include <precomp.h>
 
 #include "adaptDispatch.hpp"
-#include "conGetSet.hpp"
 #include "../../types/inc/utils.hpp"
 
 #define ENABLE_INTSAFE_SIGNED_FUNCTIONS
@@ -75,7 +74,7 @@ size_t AdaptDispatch::_SetRgbColorsHelper(const VTParameters options,
 // - True.
 bool AdaptDispatch::SetGraphicsRendition(const VTParameters options)
 {
-    auto attr = _pConApi->GetTextBuffer().GetCurrentAttributes();
+    auto attr = _api.GetTextBuffer().GetCurrentAttributes();
 
     // Run through the graphics options and apply them
     for (size_t i = 0; i < options.size(); i++)
@@ -255,7 +254,7 @@ bool AdaptDispatch::SetGraphicsRendition(const VTParameters options)
             break;
         }
     }
-    _pConApi->SetTextAttributes(attr);
+    _api.SetTextAttributes(attr);
 
     return true;
 }
@@ -270,7 +269,7 @@ bool AdaptDispatch::SetGraphicsRendition(const VTParameters options)
 // - True.
 bool AdaptDispatch::PushGraphicsRendition(const VTParameters options)
 {
-    const auto currentAttributes = _pConApi->GetTextBuffer().GetCurrentAttributes();
+    const auto currentAttributes = _api.GetTextBuffer().GetCurrentAttributes();
     _sgrStack.Push(currentAttributes, options);
     return true;
 }
@@ -284,7 +283,7 @@ bool AdaptDispatch::PushGraphicsRendition(const VTParameters options)
 // - True.
 bool AdaptDispatch::PopGraphicsRendition()
 {
-    const auto currentAttributes = _pConApi->GetTextBuffer().GetCurrentAttributes();
-    _pConApi->SetTextAttributes(_sgrStack.Pop(currentAttributes));
+    const auto currentAttributes = _api.GetTextBuffer().GetCurrentAttributes();
+    _api.SetTextAttributes(_sgrStack.Pop(currentAttributes));
     return true;
 }
diff --git a/src/terminal/adapter/lib/adapter.vcxproj b/src/terminal/adapter/lib/adapter.vcxproj
index 0a6b1205790..63953f218a9 100644
--- a/src/terminal/adapter/lib/adapter.vcxproj
+++ b/src/terminal/adapter/lib/adapter.vcxproj
@@ -28,7 +28,7 @@
     <ClInclude Include="..\DispatchTypes.hpp" />
     <ClInclude Include="..\FontBuffer.hpp" />
     <ClInclude Include="..\InteractDispatch.hpp" />
-    <ClInclude Include="..\conGetSet.hpp" />
+    <ClInclude Include="..\ITerminalApi.hpp" />
     <ClInclude Include="..\precomp.h" />
     <ClInclude Include="..\telemetry.hpp" />
     <ClInclude Include="..\terminalOutput.hpp" />
diff --git a/src/terminal/adapter/lib/adapter.vcxproj.filters b/src/terminal/adapter/lib/adapter.vcxproj.filters
index 1f333e76af3..10a5aa55ff7 100644
--- a/src/terminal/adapter/lib/adapter.vcxproj.filters
+++ b/src/terminal/adapter/lib/adapter.vcxproj.filters
@@ -44,7 +44,7 @@
     <ClInclude Include="..\adaptDispatch.hpp">
       <Filter>Header Files</Filter>
     </ClInclude>
-    <ClInclude Include="..\conGetSet.hpp">
+    <ClInclude Include="..\ITerminalApi.hpp">
       <Filter>Header Files</Filter>
     </ClInclude>
     <ClInclude Include="..\precomp.h">
diff --git a/src/terminal/adapter/ut_adapter/adapterTest.cpp b/src/terminal/adapter/ut_adapter/adapterTest.cpp
index 29b27f10dbf..ae1a926d54e 100644
--- a/src/terminal/adapter/ut_adapter/adapterTest.cpp
+++ b/src/terminal/adapter/ut_adapter/adapterTest.cpp
@@ -57,13 +57,29 @@ enum class AbsolutePosition : Microsoft::Console::VirtualTerminal::VTInt
 
 using namespace Microsoft::Console::VirtualTerminal;
 
-class TestGetSet final : public ConGetSet
+class TestGetSet final : public ITerminalApi
 {
 public:
     void PrintString(const std::wstring_view /*string*/) override
     {
     }
 
+    void ReturnResponse(const std::wstring_view response) override
+    {
+        Log::Comment(L"ReturnResponse MOCK called...");
+
+        THROW_HR_IF(E_FAIL, !_returnResponseResult);
+
+        if (_retainResponse)
+        {
+            _response += response;
+        }
+        else
+        {
+            _response = response;
+        }
+    }
+
     StateMachine& GetStateMachine() override
     {
         return *_stateMachine;
@@ -103,27 +119,6 @@ class TestGetSet final : public ConGetSet
         _textBuffer->SetCurrentAttributes(attrs);
     }
 
-    void WriteInput(std::deque<std::unique_ptr<IInputEvent>>& events, size_t& eventsWritten) override
-    {
-        Log::Comment(L"WriteInput MOCK called...");
-
-        THROW_HR_IF(E_FAIL, !_writeInputResult);
-
-        // move all the input events we were given into local storage so we can test against them
-        Log::Comment(NoThrowString().Format(L"Moving %zu input events into local storage...", events.size()));
-
-        if (_retainInput)
-        {
-            std::move(events.begin(), events.end(), std::back_inserter(_events));
-        }
-        else
-        {
-            _events.clear();
-            _events.swap(events);
-        }
-        eventsWritten = _events.size();
-    }
-
     void SetScrollingRegion(const til::inclusive_rect& scrollMargins) override
     {
         Log::Comment(L"SetScrollingRegion MOCK called...");
@@ -206,6 +201,26 @@ class TestGetSet final : public ConGetSet
         return _expectedOutputCP;
     }
 
+    void EnableXtermBracketedPasteMode(const bool /*enabled*/)
+    {
+        Log::Comment(L"EnableXtermBracketedPasteMode MOCK called...");
+    }
+
+    void CopyToClipboard(const std::wstring_view /*content*/)
+    {
+        Log::Comment(L"CopyToClipboard MOCK called...");
+    }
+
+    void SetTaskbarProgress(const DispatchTypes::TaskbarState /*state*/, const size_t /*progress*/)
+    {
+        Log::Comment(L"SetTaskbarProgress MOCK called...");
+    }
+
+    void SetWorkingDirectory(const std::wstring_view /*uri*/)
+    {
+        Log::Comment(L"SetWorkingDirectory MOCK called...");
+    }
+
     bool IsConsolePty() const override
     {
         Log::Comment(L"IsConsolePty MOCK called...");
@@ -217,11 +232,6 @@ class TestGetSet final : public ConGetSet
         Log::Comment(L"NotifyAccessibilityChange MOCK called...");
     }
 
-    void ReparentWindow(const uint64_t /*handle*/)
-    {
-        Log::Comment(L"ReparentWindow MOCK called...");
-    }
-
     void PrepData()
     {
         PrepData(CursorDirection::UP); // if called like this, the cursor direction doesn't matter.
@@ -252,7 +262,7 @@ class TestGetSet final : public ConGetSet
 
         // APIs succeed by default
         _setTextAttributesResult = TRUE;
-        _writeInputResult = TRUE;
+        _returnResponseResult = TRUE;
 
         _textBuffer = std::make_unique<TextBuffer>(COORD{ 100, 600 }, TextAttribute{}, 0, false, _renderer);
 
@@ -269,8 +279,8 @@ class TestGetSet final : public ConGetSet
         _textBuffer->SetCurrentAttributes(TextAttribute{ FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED });
         _expectedAttribute = _textBuffer->GetCurrentAttributes();
 
-        _events.clear();
-        _retainInput = false;
+        _response.clear();
+        _retainResponse = false;
     }
 
     void PrepCursor(CursorX xact, CursorY yact)
@@ -323,28 +333,7 @@ class TestGetSet final : public ConGetSet
 
     void ValidateInputEvent(_In_ PCWSTR pwszExpectedResponse)
     {
-        const auto cchResponse = wcslen(pwszExpectedResponse);
-        const auto eventCount = _events.size();
-
-        VERIFY_ARE_EQUAL(cchResponse * 2, eventCount, L"We should receive TWO input records for every character in the expected string. Key down and key up.");
-
-        for (size_t iInput = 0; iInput < eventCount; iInput++)
-        {
-            const auto wch = pwszExpectedResponse[iInput / 2]; // the same portion of the string will be used twice. 0/2 = 0. 1/2 = 0. 2/2 = 1. 3/2 = 1. and so on.
-
-            VERIFY_ARE_EQUAL(InputEventType::KeyEvent, _events[iInput]->EventType());
-
-            const auto keyEvent = static_cast<const KeyEvent* const>(_events[iInput].get());
-
-            // every even key is down. every odd key is up. DOWN = 0, UP = 1. DOWN = 2, UP = 3. and so on.
-            VERIFY_ARE_EQUAL((bool)!(iInput % 2), keyEvent->IsKeyDown());
-            VERIFY_ARE_EQUAL(0u, keyEvent->GetActiveModifierKeys());
-            Log::Comment(NoThrowString().Format(L"Comparing '%c' with '%c'...", wch, keyEvent->GetCharData()));
-            VERIFY_ARE_EQUAL(wch, keyEvent->GetCharData());
-            VERIFY_ARE_EQUAL(1u, keyEvent->GetRepeatCount());
-            VERIFY_ARE_EQUAL(0u, keyEvent->GetVirtualKeyCode());
-            VERIFY_ARE_EQUAL(0u, keyEvent->GetVirtualScanCode());
-        }
+        VERIFY_ARE_EQUAL(pwszExpectedResponse, _response);
     }
 
     void _SetMarginsHelper(til::inclusive_rect* rect, til::CoordType top, til::CoordType bottom)
@@ -366,15 +355,15 @@ class TestGetSet final : public ConGetSet
     static const WORD s_wDefaultAttribute = 0;
     static const WORD s_defaultFill = FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED; // dark gray on black.
 
-    std::deque<std::unique_ptr<IInputEvent>> _events;
-    bool _retainInput{ false };
+    std::wstring _response;
+    bool _retainResponse{ false };
 
     auto EnableInputRetentionInScope()
     {
-        auto oldRetainValue{ _retainInput };
-        _retainInput = true;
+        auto oldRetainValue{ _retainResponse };
+        _retainResponse = true;
         return wil::scope_exit([oldRetainValue, this] {
-            _retainInput = oldRetainValue;
+            _retainResponse = oldRetainValue;
         });
     }
 
@@ -392,7 +381,7 @@ class TestGetSet final : public ConGetSet
     bool _isPty = false;
 
     bool _setTextAttributesResult = false;
-    bool _writeInputResult = false;
+    bool _returnResponseResult = false;
 
     bool _setScrollingRegionResult = false;
     bool _getLineFeedModeResult = false;
@@ -422,12 +411,11 @@ class AdapterTest
         fSuccess = api.get() != nullptr;
         if (fSuccess)
         {
-            // give AdaptDispatch ownership of _testGetSet
-            _testGetSet = api.get(); // keep a copy for us but don't manage its lifetime anymore.
+            _testGetSet = std::move(api);
             _terminalInput = TerminalInput{ nullptr };
             auto& renderer = _testGetSet->_renderer;
             auto& renderSettings = renderer._renderSettings;
-            auto adapter = std::make_unique<AdaptDispatch>(std::move(api), renderer, renderSettings, _terminalInput);
+            auto adapter = std::make_unique<AdaptDispatch>(*_testGetSet, renderer, renderSettings, _terminalInput);
 
             fSuccess = adapter.get() != nullptr;
             if (fSuccess)
@@ -1448,9 +1436,9 @@ class AdapterTest
         auto pwszExpectedResponse = L"\x1b[?1;0c";
         _testGetSet->ValidateInputEvent(pwszExpectedResponse);
 
-        Log::Comment(L"Test 2: Verify failure when WriteInput doesn't work.");
+        Log::Comment(L"Test 2: Verify failure when ReturnResponse doesn't work.");
         _testGetSet->PrepData();
-        _testGetSet->_writeInputResult = FALSE;
+        _testGetSet->_returnResponseResult = FALSE;
 
         VERIFY_THROWS(_pDispatch->DeviceAttributes(), std::exception);
     }
@@ -1466,9 +1454,9 @@ class AdapterTest
         auto pwszExpectedResponse = L"\x1b[>0;10;1c";
         _testGetSet->ValidateInputEvent(pwszExpectedResponse);
 
-        Log::Comment(L"Test 2: Verify failure when WriteInput doesn't work.");
+        Log::Comment(L"Test 2: Verify failure when ReturnResponse doesn't work.");
         _testGetSet->PrepData();
-        _testGetSet->_writeInputResult = FALSE;
+        _testGetSet->_returnResponseResult = FALSE;
 
         VERIFY_THROWS(_pDispatch->SecondaryDeviceAttributes(), std::exception);
     }
@@ -1484,9 +1472,9 @@ class AdapterTest
         auto pwszExpectedResponse = L"\x1bP!|00000000\x1b\\";
         _testGetSet->ValidateInputEvent(pwszExpectedResponse);
 
-        Log::Comment(L"Test 2: Verify failure when WriteInput doesn't work.");
+        Log::Comment(L"Test 2: Verify failure when ReturnResponse doesn't work.");
         _testGetSet->PrepData();
-        _testGetSet->_writeInputResult = FALSE;
+        _testGetSet->_returnResponseResult = FALSE;
 
         VERIFY_THROWS(_pDispatch->TertiaryDeviceAttributes(), std::exception);
     }
@@ -1509,9 +1497,9 @@ class AdapterTest
         _testGetSet->PrepData();
         VERIFY_IS_FALSE(_pDispatch->RequestTerminalParameters((DispatchTypes::ReportingPermission)2));
 
-        Log::Comment(L"Test 4: Verify failure when WriteInput doesn't work.");
+        Log::Comment(L"Test 4: Verify failure when ReturnResponse doesn't work.");
         _testGetSet->PrepData();
-        _testGetSet->_writeInputResult = FALSE;
+        _testGetSet->_returnResponseResult = FALSE;
         VERIFY_THROWS(_pDispatch->RequestTerminalParameters(DispatchTypes::ReportingPermission::Unsolicited), std::exception);
     }
 
@@ -2256,7 +2244,7 @@ class AdapterTest
 
 private:
     TerminalInput _terminalInput{ nullptr };
-    TestGetSet* _testGetSet; // non-ownership pointer
+    std::unique_ptr<TestGetSet> _testGetSet;
     AdaptDispatch* _pDispatch; // non-ownership pointer
     std::unique_ptr<StateMachine> _stateMachine;
 };
diff --git a/src/terminal/parser/OutputStateMachineEngine.cpp b/src/terminal/parser/OutputStateMachineEngine.cpp
index e1d11693c25..864aa8555b5 100644
--- a/src/terminal/parser/OutputStateMachineEngine.cpp
+++ b/src/terminal/parser/OutputStateMachineEngine.cpp
@@ -267,19 +267,19 @@ bool OutputStateMachineEngine::ActionEscDispatch(const VTID id)
         TermTelemetry::Instance().Log(TermTelemetry::Codes::DECAC1);
         break;
     case EscActionCodes::DECDHL_DoubleHeightLineTop:
-        _dispatch->SetLineRendition(LineRendition::DoubleHeightTop);
+        success = _dispatch->SetLineRendition(LineRendition::DoubleHeightTop);
         TermTelemetry::Instance().Log(TermTelemetry::Codes::DECDHL);
         break;
     case EscActionCodes::DECDHL_DoubleHeightLineBottom:
-        _dispatch->SetLineRendition(LineRendition::DoubleHeightBottom);
+        success = _dispatch->SetLineRendition(LineRendition::DoubleHeightBottom);
         TermTelemetry::Instance().Log(TermTelemetry::Codes::DECDHL);
         break;
     case EscActionCodes::DECSWL_SingleWidthLine:
-        _dispatch->SetLineRendition(LineRendition::SingleWidth);
+        success = _dispatch->SetLineRendition(LineRendition::SingleWidth);
         TermTelemetry::Instance().Log(TermTelemetry::Codes::DECSWL);
         break;
     case EscActionCodes::DECDWL_DoubleWidthLine:
-        _dispatch->SetLineRendition(LineRendition::DoubleWidth);
+        success = _dispatch->SetLineRendition(LineRendition::DoubleWidth);
         TermTelemetry::Instance().Log(TermTelemetry::Codes::DECDWL);
         break;
     case EscActionCodes::DECALN_ScreenAlignmentPattern:
diff --git a/src/types/IBaseData.h b/src/types/IBaseData.h
index d8ba21d8711..676994cab57 100644
--- a/src/types/IBaseData.h
+++ b/src/types/IBaseData.h
@@ -36,8 +36,8 @@ namespace Microsoft::Console::Types
     public:
         virtual Microsoft::Console::Types::Viewport GetViewport() noexcept = 0;
         virtual COORD GetTextBufferEndPosition() const noexcept = 0;
-        virtual const TextBuffer& GetTextBuffer() noexcept = 0;
-        virtual const FontInfo& GetFontInfo() noexcept = 0;
+        virtual const TextBuffer& GetTextBuffer() const noexcept = 0;
+        virtual const FontInfo& GetFontInfo() const noexcept = 0;
 
         virtual std::vector<Microsoft::Console::Types::Viewport> GetSelectionRects() noexcept = 0;
 


Test patch: