diff --git a/src/plugins/android/androidanalyzesupport.cpp b/src/plugins/android/androidanalyzesupport.cpp
index 352a5f16bd442b9f9e5fc3dfd7264074a4427ee1..820e9ab00de01b1ad88b77352793b7db69a80dc7 100644
--- a/src/plugins/android/androidanalyzesupport.cpp
+++ b/src/plugins/android/androidanalyzesupport.cpp
@@ -39,7 +39,7 @@
 #include <QDir>
 #include <QTcpServer>
 
-using namespace Analyzer;
+using namespace Debugger;
 using namespace ProjectExplorer;
 
 namespace Android {
@@ -48,7 +48,7 @@ namespace Internal {
 RunControl *AndroidAnalyzeSupport::createAnalyzeRunControl(AndroidRunConfiguration *runConfig,
                                                            Core::Id runMode)
 {
-    AnalyzerRunControl *runControl = AnalyzerManager::createRunControl(runConfig, runMode);
+    AnalyzerRunControl *runControl = Debugger::createAnalyzerRunControl(runConfig, runMode);
     QTC_ASSERT(runControl, return 0);
     AnalyzerConnection connection;
     if (runMode == ProjectExplorer::Constants::QML_PROFILER_RUN_MODE) {
diff --git a/src/plugins/android/androidanalyzesupport.h b/src/plugins/android/androidanalyzesupport.h
index ba4416a2d4409142af63a2087596f8db1f108247..e272688a271aacc622498ce13be715239c5f3950 100644
--- a/src/plugins/android/androidanalyzesupport.h
+++ b/src/plugins/android/androidanalyzesupport.h
@@ -29,7 +29,7 @@
 #include "androidrunconfiguration.h"
 #include <qmldebug/qmloutputparser.h>
 
-namespace Analyzer { class AnalyzerRunControl; }
+namespace Debugger { class AnalyzerRunControl; }
 namespace ProjectExplorer { class RunControl; }
 
 namespace Android {
@@ -43,7 +43,7 @@ class AndroidAnalyzeSupport : public QObject
 
 public:
     AndroidAnalyzeSupport(AndroidRunConfiguration *runConfig,
-        Analyzer::AnalyzerRunControl *runControl);
+        Debugger::AnalyzerRunControl *runControl);
 
     static ProjectExplorer::RunControl *createAnalyzeRunControl(AndroidRunConfiguration *runConfig,
                                                                 Core::Id runMode);
diff --git a/src/plugins/baremetal/baremetalruncontrolfactory.cpp b/src/plugins/baremetal/baremetalruncontrolfactory.cpp
index 0221fab3ad44782e070dc6950f6d389b2f897ca4..b9b49286db3a22da677c80f2e6a3bac83cfa8c56 100644
--- a/src/plugins/baremetal/baremetalruncontrolfactory.cpp
+++ b/src/plugins/baremetal/baremetalruncontrolfactory.cpp
@@ -50,7 +50,6 @@
 
 #include <QApplication>
 
-using namespace Analyzer;
 using namespace Debugger;
 using namespace ProjectExplorer;
 
diff --git a/src/plugins/clangstaticanalyzer/clangstaticanalyzerdiagnostic.h b/src/plugins/clangstaticanalyzer/clangstaticanalyzerdiagnostic.h
index ecb5e8e94e48a3bd3cfec7daa04c8f0d724e0b23..708b5137f59bdfe1d5967b326a3f6c5f81dc1c01 100644
--- a/src/plugins/clangstaticanalyzer/clangstaticanalyzerdiagnostic.h
+++ b/src/plugins/clangstaticanalyzer/clangstaticanalyzerdiagnostic.h
@@ -44,8 +44,8 @@ public:
 
     QString message;
     QString extendedMessage;
-    Analyzer::DiagnosticLocation location;
-    QList<Analyzer::DiagnosticLocation> ranges;
+    Debugger::DiagnosticLocation location;
+    QList<Debugger::DiagnosticLocation> ranges;
     int depth;
 };
 
@@ -59,7 +59,7 @@ public:
     QString type;
     QString issueContextKind;
     QString issueContext;
-    Analyzer::DiagnosticLocation location;
+    Debugger::DiagnosticLocation location;
     QList<ExplainingStep> explainingSteps;
 };
 
diff --git a/src/plugins/clangstaticanalyzer/clangstaticanalyzerdiagnosticmodel.cpp b/src/plugins/clangstaticanalyzer/clangstaticanalyzerdiagnosticmodel.cpp
index fa0625891a3197b46fe5b5e69cc10cc5cc188fdb..49b904a812c6a9e99b704ea45ed8050aaa22559e 100644
--- a/src/plugins/clangstaticanalyzer/clangstaticanalyzerdiagnosticmodel.cpp
+++ b/src/plugins/clangstaticanalyzer/clangstaticanalyzerdiagnosticmodel.cpp
@@ -168,7 +168,7 @@ static QString createExplainingStepToolTipString(const ExplainingStep &step)
     return html;
 }
 
-static QString createLocationString(const Analyzer::DiagnosticLocation &location)
+static QString createLocationString(const Debugger::DiagnosticLocation &location)
 {
     const QString filePath = location.filePath;
     const QString lineNumber = QString::number(location.line);
@@ -224,10 +224,10 @@ DiagnosticItem::DiagnosticItem(const Diagnostic &diag) : m_diagnostic(diag)
         appendChild(new ExplainingStepItem(s));
 }
 
-QVariant locationData(int role, const Analyzer::DiagnosticLocation &location)
+QVariant locationData(int role, const Debugger::DiagnosticLocation &location)
 {
     switch (role) {
-    case Analyzer::DetailedErrorView::LocationRole:
+    case Debugger::DetailedErrorView::LocationRole:
         return QVariant::fromValue(location);
     case Qt::ToolTipRole:
         return location.filePath.isEmpty() ? QVariant() : QVariant(location.filePath);
@@ -238,12 +238,12 @@ QVariant locationData(int role, const Analyzer::DiagnosticLocation &location)
 
 QVariant DiagnosticItem::data(int column, int role) const
 {
-    if (column == Analyzer::DetailedErrorView::LocationColumn)
+    if (column == Debugger::DetailedErrorView::LocationColumn)
         return locationData(role, m_diagnostic.location);
 
     // DiagnosticColumn
     switch (role) {
-    case Analyzer::DetailedErrorView::FullTextRole:
+    case Debugger::DetailedErrorView::FullTextRole:
         return fullText(m_diagnostic);
     case ClangStaticAnalyzerDiagnosticModel::DiagnosticRole:
         return QVariant::fromValue(m_diagnostic);
@@ -262,12 +262,12 @@ ExplainingStepItem::ExplainingStepItem(const ExplainingStep &step) : m_step(step
 
 QVariant ExplainingStepItem::data(int column, int role) const
 {
-    if (column == Analyzer::DetailedErrorView::LocationColumn)
+    if (column == Debugger::DetailedErrorView::LocationColumn)
         return locationData(role, m_step.location);
 
     // DiagnosticColumn
     switch (role) {
-    case Analyzer::DetailedErrorView::FullTextRole:
+    case Debugger::DetailedErrorView::FullTextRole:
         return fullText(static_cast<DiagnosticItem *>(parent())->diagnostic());
     case ClangStaticAnalyzerDiagnosticModel::DiagnosticRole:
         return QVariant::fromValue(static_cast<DiagnosticItem *>(parent())->diagnostic());
diff --git a/src/plugins/clangstaticanalyzer/clangstaticanalyzerdiagnosticmodel.h b/src/plugins/clangstaticanalyzer/clangstaticanalyzerdiagnosticmodel.h
index 437e83ce4029ce9e4ff696303cd6629e55932663..e8a30f34efe681b5ff889dafeb2b4f0d81a76352 100644
--- a/src/plugins/clangstaticanalyzer/clangstaticanalyzerdiagnosticmodel.h
+++ b/src/plugins/clangstaticanalyzer/clangstaticanalyzerdiagnosticmodel.h
@@ -52,7 +52,7 @@ public:
     QList<Diagnostic> diagnostics() const;
 
     enum ItemRole {
-        DiagnosticRole = Analyzer::DetailedErrorView::FullTextRole + 1
+        DiagnosticRole = Debugger::DetailedErrorView::FullTextRole + 1
     };
 };
 
diff --git a/src/plugins/clangstaticanalyzer/clangstaticanalyzerdiagnosticview.cpp b/src/plugins/clangstaticanalyzer/clangstaticanalyzerdiagnosticview.cpp
index 69fb87a3bb5f2f68b8653da3b56d336fabfe8cbe..fdd3a7aef592263e15552b7b76c403f979962505 100644
--- a/src/plugins/clangstaticanalyzer/clangstaticanalyzerdiagnosticview.cpp
+++ b/src/plugins/clangstaticanalyzer/clangstaticanalyzerdiagnosticview.cpp
@@ -36,13 +36,13 @@
 #include <QAction>
 #include <QDebug>
 
-using namespace Analyzer;
+using namespace Debugger;
 
 namespace ClangStaticAnalyzer {
 namespace Internal {
 
 ClangStaticAnalyzerDiagnosticView::ClangStaticAnalyzerDiagnosticView(QWidget *parent)
-    : Analyzer::DetailedErrorView(parent)
+    : Debugger::DetailedErrorView(parent)
 {
     m_suppressAction = new QAction(tr("Suppress this diagnostic"), this);
     connect(m_suppressAction, &QAction::triggered, [this](bool) { suppressCurrentDiagnostic(); });
diff --git a/src/plugins/clangstaticanalyzer/clangstaticanalyzerdiagnosticview.h b/src/plugins/clangstaticanalyzer/clangstaticanalyzerdiagnosticview.h
index 0d5016fd7c48f3f5c0257064666f34ab0c1df7aa..55ba24642cfba34818ba6db0e8f8e07268a7abdc 100644
--- a/src/plugins/clangstaticanalyzer/clangstaticanalyzerdiagnosticview.h
+++ b/src/plugins/clangstaticanalyzer/clangstaticanalyzerdiagnosticview.h
@@ -31,7 +31,7 @@
 namespace ClangStaticAnalyzer {
 namespace Internal {
 
-class ClangStaticAnalyzerDiagnosticView : public Analyzer::DetailedErrorView
+class ClangStaticAnalyzerDiagnosticView : public Debugger::DetailedErrorView
 {
     Q_OBJECT
 
diff --git a/src/plugins/clangstaticanalyzer/clangstaticanalyzerlogfilereader.cpp b/src/plugins/clangstaticanalyzer/clangstaticanalyzerlogfilereader.cpp
index dd0727864fc0a3814cf334e9898c334f080aafd5..f66ce2a545b6a0886cff199134050882f7b9abc0 100644
--- a/src/plugins/clangstaticanalyzer/clangstaticanalyzerlogfilereader.cpp
+++ b/src/plugins/clangstaticanalyzer/clangstaticanalyzerlogfilereader.cpp
@@ -55,8 +55,8 @@ private:
     void readDiagnosticsDict();
     QList<ExplainingStep> readPathArray();
     ExplainingStep readPathDict();
-    Analyzer::DiagnosticLocation readLocationDict(bool elementIsRead = false);
-    QList<Analyzer::DiagnosticLocation> readRangesArray();
+    Debugger::DiagnosticLocation readLocationDict(bool elementIsRead = false);
+    QList<Debugger::DiagnosticLocation> readRangesArray();
 
     QString readString();
     QStringList readStringArray();
@@ -284,9 +284,9 @@ ExplainingStep ClangStaticAnalyzerLogFileReader::readPathDict()
     return explainingStep;
 }
 
-Analyzer::DiagnosticLocation ClangStaticAnalyzerLogFileReader::readLocationDict(bool elementIsRead)
+Debugger::DiagnosticLocation ClangStaticAnalyzerLogFileReader::readLocationDict(bool elementIsRead)
 {
-    Analyzer::DiagnosticLocation location;
+    Debugger::DiagnosticLocation location;
     if (elementIsRead) {
         QTC_ASSERT(m_xml.isStartElement() && m_xml.name() == QLatin1String("dict"),
                    return location);
@@ -317,14 +317,14 @@ Analyzer::DiagnosticLocation ClangStaticAnalyzerLogFileReader::readLocationDict(
 
     if (lineOk && columnOk && fileIndexOk) {
         QTC_ASSERT(fileIndex < m_referencedFiles.size(), return location);
-        location = Analyzer::DiagnosticLocation(m_referencedFiles.at(fileIndex), line, column);
+        location = Debugger::DiagnosticLocation(m_referencedFiles.at(fileIndex), line, column);
     }
     return location;
 }
 
-QList<Analyzer::DiagnosticLocation> ClangStaticAnalyzerLogFileReader::readRangesArray()
+QList<Debugger::DiagnosticLocation> ClangStaticAnalyzerLogFileReader::readRangesArray()
 {
-    QList<Analyzer::DiagnosticLocation> result;
+    QList<Debugger::DiagnosticLocation> result;
 
     // It's an array of arrays...
     QTC_ASSERT(m_xml.readNextStartElement() && m_xml.name() == QLatin1String("array"),
diff --git a/src/plugins/clangstaticanalyzer/clangstaticanalyzerplugin.cpp b/src/plugins/clangstaticanalyzer/clangstaticanalyzerplugin.cpp
index 28146c0acdd4afba7dd9d10a68a3bcc59c305358..0ab5c15e0000f62920453b66c5f7c25ce1f01f94 100644
--- a/src/plugins/clangstaticanalyzer/clangstaticanalyzerplugin.cpp
+++ b/src/plugins/clangstaticanalyzer/clangstaticanalyzerplugin.cpp
@@ -53,7 +53,7 @@
 
 #include <QtPlugin>
 
-using namespace Analyzer;
+using namespace Debugger;
 
 namespace ClangStaticAnalyzer {
 namespace Internal {
@@ -122,36 +122,10 @@ bool ClangStaticAnalyzerPlugin::initialize(const QStringList &arguments, QString
     panelFactory->setSimpleCreateWidgetFunction<ProjectSettingsWidget>(QIcon());
     ProjectExplorer::ProjectPanelFactory::registerFactory(panelFactory);
 
-    auto tool = m_analyzerTool = new ClangStaticAnalyzerTool(this);
+    m_analyzerTool = new ClangStaticAnalyzerTool(this);
     addAutoReleasedObject(new ClangStaticAnalyzerRunControlFactory(m_analyzerTool));
     addAutoReleasedObject(new ClangStaticAnalyzerOptionsPage);
 
-    AnalyzerManager::registerToolbar(ClangStaticAnalyzerPerspectiveId, tool->createWidgets());
-
-    auto runControlCreator = [tool](ProjectExplorer::RunConfiguration *runConfiguration,
-                                    Core::Id runMode) {
-        return tool->createRunControl(runConfiguration, runMode);
-    };
-
-    const QString toolTip = tr("Clang Static Analyzer uses the analyzer from the clang project "
-                               "to find bugs.");
-
-    AnalyzerManager::registerPerspective(ClangStaticAnalyzerPerspectiveId, {
-        { ClangStaticAnalyzerDockId, Core::Id(), Perspective::SplitVertical }
-    });
-
-    ActionDescription desc;
-    desc.setText(tr("Clang Static Analyzer"));
-    desc.setToolTip(toolTip);
-    desc.setRunMode(Constants::CLANGSTATICANALYZER_RUN_MODE);
-    desc.setPerspectiveId(ClangStaticAnalyzerPerspectiveId);
-    desc.setRunControlCreator(runControlCreator);
-    desc.setCustomToolStarter([tool](ProjectExplorer::RunConfiguration *rc) {
-        tool->startTool(rc);
-    });
-    desc.setMenuGroup(Analyzer::Constants::G_ANALYZER_TOOLS);
-    AnalyzerManager::registerAction(ClangStaticAnalyzerActionId, desc);
-
     return true;
 }
 
diff --git a/src/plugins/clangstaticanalyzer/clangstaticanalyzerruncontrol.cpp b/src/plugins/clangstaticanalyzer/clangstaticanalyzerruncontrol.cpp
index 5d4c1e3194d70b72d75a5a55a21d1085d4e94398..b8bc63d267b5f192fa6bd6e453e40908747e8dcb 100644
--- a/src/plugins/clangstaticanalyzer/clangstaticanalyzerruncontrol.cpp
+++ b/src/plugins/clangstaticanalyzer/clangstaticanalyzerruncontrol.cpp
@@ -304,12 +304,12 @@ static Core::Id toolchainType(ProjectExplorer::RunConfiguration *runConfiguratio
     return ToolChainKitInformation::toolChain(runConfiguration->target()->kit())->typeId();
 }
 
-bool ClangStaticAnalyzerRunControl::startEngine()
+void ClangStaticAnalyzerRunControl::start()
 {
     m_success = false;
     emit starting();
 
-    QTC_ASSERT(m_projectInfo.isValid(), emit finished(); return false);
+    QTC_ASSERT(m_projectInfo.isValid(), emit finished(); return);
     const Utils::FileName projectFile = m_projectInfo.project()->projectFilePath();
     appendMessage(tr("Running Clang Static Analyzer on %1").arg(projectFile.toUserOutput())
                   + QLatin1Char('\n'), Utils::NormalMessageFormat);
@@ -324,7 +324,7 @@ bool ClangStaticAnalyzerRunControl::startEngine()
         appendMessage(errorMessage + QLatin1Char('\n'), Utils::ErrorMessageFormat);
         AnalyzerUtils::logToIssuesPane(Task::Error, errorMessage);
         emit finished();
-        return false;
+        return;
     }
     m_clangExecutable = executable;
 
@@ -337,7 +337,7 @@ bool ClangStaticAnalyzerRunControl::startEngine()
         appendMessage(errorMessage + QLatin1Char('\n'), Utils::ErrorMessageFormat);
         AnalyzerUtils::logToIssuesPane(Task::Error, errorMessage);
         emit finished();
-        return false;
+        return;
     }
     m_clangLogFileDir = temporaryDir.path();
 
@@ -364,19 +364,22 @@ bool ClangStaticAnalyzerRunControl::startEngine()
     qCDebug(LOG) << "Environment:" << m_environment;
     m_runners.clear();
     const int parallelRuns = ClangStaticAnalyzerSettings::instance()->simultaneousProcesses();
-    QTC_ASSERT(parallelRuns >= 1, emit finished(); return false);
+    QTC_ASSERT(parallelRuns >= 1, emit finished(); return);
     m_success = true;
+    m_running = true;
 
     if (m_unitsToProcess.isEmpty()) {
         finalize();
-        return false;
+        return;
     }
+
+    emit started();
+
     while (m_runners.size() < parallelRuns && !m_unitsToProcess.isEmpty())
         analyzeNextFile();
-    return true;
 }
 
-void ClangStaticAnalyzerRunControl::stopEngine()
+RunControl::StopResult ClangStaticAnalyzerRunControl::stop()
 {
     QSetIterator<ClangStaticAnalyzerRunner *> i(m_runners);
     while (i.hasNext()) {
@@ -389,7 +392,14 @@ void ClangStaticAnalyzerRunControl::stopEngine()
     appendMessage(tr("Clang Static Analyzer stopped by user.") + QLatin1Char('\n'),
                   Utils::NormalMessageFormat);
     m_progress.reportFinished();
+    m_running = false;
     emit finished();
+    return RunControl::StoppedSynchronously;
+}
+
+bool ClangStaticAnalyzerRunControl::isRunning() const
+{
+    return m_running;
 }
 
 void ClangStaticAnalyzerRunControl::analyzeNextFile()
@@ -479,7 +489,6 @@ void ClangStaticAnalyzerRunControl::handleFinished()
 
 void ClangStaticAnalyzerRunControl::onProgressCanceled()
 {
-    Analyzer::AnalyzerManager::stopTool();
     m_progress.reportCanceled();
     m_progress.reportFinished();
 }
diff --git a/src/plugins/clangstaticanalyzer/clangstaticanalyzerruncontrol.h b/src/plugins/clangstaticanalyzer/clangstaticanalyzerruncontrol.h
index 84ad1ae9fcec41e007eb653b03b28d2d13ed10d6..0293f4d3b19037521130dcd1135f9e2b32b1377b 100644
--- a/src/plugins/clangstaticanalyzer/clangstaticanalyzerruncontrol.h
+++ b/src/plugins/clangstaticanalyzer/clangstaticanalyzerruncontrol.h
@@ -48,7 +48,7 @@ struct AnalyzeUnit {
 };
 typedef QList<AnalyzeUnit> AnalyzeUnits;
 
-class ClangStaticAnalyzerRunControl : public Analyzer::AnalyzerRunControl
+class ClangStaticAnalyzerRunControl : public Debugger::AnalyzerRunControl
 {
     Q_OBJECT
 
@@ -57,8 +57,9 @@ public:
                                   Core::Id runMode,
                                   const CppTools::ProjectInfo &projectInfo);
 
-    bool startEngine() override;
-    void stopEngine() override;
+    void start() override;
+    StopResult stop() override;
+    bool isRunning() const override;
 
     bool success() const { return m_success; } // For testing.
 
@@ -93,6 +94,7 @@ private:
     int m_filesAnalyzed;
     int m_filesNotAnalyzed;
     bool m_success;
+    bool m_running = false;
 };
 
 } // namespace Internal
diff --git a/src/plugins/clangstaticanalyzer/clangstaticanalyzerruncontrolfactory.cpp b/src/plugins/clangstaticanalyzer/clangstaticanalyzerruncontrolfactory.cpp
index a179e2fa1fe3a561c2438cb869913a4af9b382d9..017a87cefdd5b97f5a046c1837fc2c6486fd3599 100644
--- a/src/plugins/clangstaticanalyzer/clangstaticanalyzerruncontrolfactory.cpp
+++ b/src/plugins/clangstaticanalyzer/clangstaticanalyzerruncontrolfactory.cpp
@@ -47,7 +47,7 @@
 
 #include <utils/qtcassert.h>
 
-using namespace Analyzer;
+using namespace Debugger;
 using namespace ProjectExplorer;
 
 namespace ClangStaticAnalyzer {
@@ -115,7 +115,7 @@ RunControl *ClangStaticAnalyzerRunControlFactory::create(RunConfiguration *runCo
         return 0;
     }
 
-    return AnalyzerManager::createRunControl(runConfiguration, runMode);
+    return Debugger::createAnalyzerRunControl(runConfiguration, runMode);
 }
 
 } // namespace Internal
diff --git a/src/plugins/clangstaticanalyzer/clangstaticanalyzertool.cpp b/src/plugins/clangstaticanalyzer/clangstaticanalyzertool.cpp
index 93a18a1d3ffcbdf64c2cd73cc2a47155280c3656..1f5d443c6ba65bfa7b8552422c47ae7bdd8b3de3 100644
--- a/src/plugins/clangstaticanalyzer/clangstaticanalyzertool.cpp
+++ b/src/plugins/clangstaticanalyzer/clangstaticanalyzertool.cpp
@@ -53,8 +53,9 @@
 #include <QSortFilterProxyModel>
 #include <QToolButton>
 
-using namespace Analyzer;
+using namespace Debugger;
 using namespace ProjectExplorer;
+using namespace Utils;
 
 namespace ClangStaticAnalyzer {
 namespace Internal {
@@ -69,14 +70,6 @@ ClangStaticAnalyzerTool::ClangStaticAnalyzerTool(QObject *parent)
     , m_running(false)
 {
     setObjectName(QLatin1String("ClangStaticAnalyzerTool"));
-}
-
-QWidget *ClangStaticAnalyzerTool::createWidgets()
-{
-    QTC_ASSERT(!m_diagnosticView, return 0);
-    QTC_ASSERT(!m_diagnosticModel, return 0);
-    QTC_ASSERT(!m_goBack, return 0);
-    QTC_ASSERT(!m_goNext, return 0);
 
     //
     // Diagnostic View
@@ -104,27 +97,19 @@ QWidget *ClangStaticAnalyzerTool::createWidgets()
                 this, &ClangStaticAnalyzerTool::handleStateUpdate);
     }
 
-    AnalyzerManager::registerDockWidget(ClangStaticAnalyzerDockId, m_diagnosticView);
-
     //
     // Toolbar widget
     //
-    QHBoxLayout *layout = new QHBoxLayout;
-    layout->setMargin(0);
-    layout->setSpacing(0);
 
-    QAction *action = 0;
-    QToolButton *button = 0;
+    m_startAction = Debugger::createStartAction();
+    m_stopAction = Debugger::createStopAction();
 
     // Go to previous diagnostic
-    action = new QAction(this);
+    auto action = new QAction(this);
     action->setDisabled(true);
     action->setIcon(Core::Icons::PREV.icon());
     action->setToolTip(tr("Go to previous bug."));
     connect(action, &QAction::triggered, m_diagnosticView, &DetailedErrorView::goBack);
-    button = new QToolButton;
-    button->setDefaultAction(action);
-    layout->addWidget(button);
     m_goBack = action;
 
     // Go to next diagnostic
@@ -133,17 +118,41 @@ QWidget *ClangStaticAnalyzerTool::createWidgets()
     action->setIcon(Core::Icons::NEXT.icon());
     action->setToolTip(tr("Go to next bug."));
     connect(action, &QAction::triggered, m_diagnosticView, &DetailedErrorView::goNext);
-    button = new QToolButton;
-    button->setDefaultAction(action);
-    layout->addWidget(button);
     m_goNext = action;
 
-    layout->addStretch();
-
-    QWidget *toolbarWidget = new QWidget;
-    toolbarWidget->setObjectName(QLatin1String("ClangStaticAnalyzerToolBarWidget"));
-    toolbarWidget->setLayout(layout);
-    return toolbarWidget;
+    const QString toolTip = tr("Clang Static Analyzer uses the analyzer from the clang project "
+                               "to find bugs.");
+
+    Debugger::registerPerspective(ClangStaticAnalyzerPerspectiveId, {
+        tr("Clang Static Analyzer"),
+        {{ ClangStaticAnalyzerDockId, m_diagnosticView, {}, Perspective::SplitVertical }}
+    });
+
+    ActionDescription desc;
+    desc.setText(tr("Clang Static Analyzer"));
+    desc.setToolTip(toolTip);
+    desc.setRunMode(Constants::CLANGSTATICANALYZER_RUN_MODE);
+    desc.setPerspectiveId(ClangStaticAnalyzerPerspectiveId);
+    desc.setRunControlCreator([this](RunConfiguration *runConfiguration, Core::Id runMode) {
+        return createRunControl(runConfiguration, runMode);
+    });
+    desc.setCustomToolStarter([this](RunConfiguration *runConfiguration) {
+        startTool(runConfiguration);
+    });
+    desc.setMenuGroup(Debugger::Constants::G_ANALYZER_TOOLS);
+    Debugger::registerAction(ClangStaticAnalyzerActionId, desc, m_startAction);
+
+    ToolbarDescription toolbar;
+    toolbar.addAction(m_startAction);
+    toolbar.addAction(m_stopAction);
+    toolbar.addAction(m_goBack);
+    toolbar.addAction(m_goNext);
+    Debugger::registerToolbar(ClangStaticAnalyzerPerspectiveId, toolbar);
+
+    updateRunActions();
+
+    connect(ProjectExplorerPlugin::instance(), &ProjectExplorerPlugin::updateRunActions,
+            this, &ClangStaticAnalyzerTool::updateRunActions);
 }
 
 AnalyzerRunControl *ClangStaticAnalyzerTool::createRunControl(RunConfiguration *runConfiguration,
@@ -171,6 +180,11 @@ AnalyzerRunControl *ClangStaticAnalyzerTool::createRunControl(RunConfiguration *
             this, &ClangStaticAnalyzerTool::onNewDiagnosticsAvailable);
     connect(runControl, &ClangStaticAnalyzerRunControl::finished,
             this, &ClangStaticAnalyzerTool::onEngineFinished);
+
+    connect(m_stopAction, &QAction::triggered, runControl, [runControl] { runControl->stop(); });
+
+    m_toolBusy = true;
+    updateRunActions();
     return runControl;
 }
 
@@ -208,8 +222,6 @@ static bool dontStartAfterHintForDebugMode(Project *project)
 
 void ClangStaticAnalyzerTool::startTool(ProjectExplorer::RunConfiguration *runConfiguration)
 {
-    AnalyzerManager::showMode();
-
     Project *project = SessionManager::startupProject();
     QTC_ASSERT(project, emit finished(false); return);
 
@@ -261,8 +273,28 @@ void ClangStaticAnalyzerTool::onEngineFinished()
     m_running = false;
     handleStateUpdate();
     emit finished(static_cast<ClangStaticAnalyzerRunControl *>(sender())->success());
+    m_toolBusy = false;
+    updateRunActions();
 }
 
+void ClangStaticAnalyzerTool::updateRunActions()
+{
+    if (m_toolBusy) {
+        m_startAction->setEnabled(false);
+        m_startAction->setToolTip(tr("A Clang analysis is still in progress."));
+        m_stopAction->setEnabled(true);
+    } else {
+        const bool projectUsable = SessionManager::startupProject() != 0;
+        m_startAction->setToolTip(tr("Start Qml Profiler."));
+        if (projectUsable) {
+            m_startAction->setEnabled(true);
+            m_stopAction->setEnabled(false);
+        } else {
+            m_startAction->setEnabled(false);
+            m_stopAction->setEnabled(false);
+        }
+    }
+}
 void ClangStaticAnalyzerTool::setBusyCursor(bool busy)
 {
     QTC_ASSERT(m_diagnosticView, return);
@@ -291,7 +323,7 @@ void ClangStaticAnalyzerTool::handleStateUpdate()
         message += tr("%n issues found (%1 suppressed).", 0, issuesFound)
                 .arg(issuesFound - issuesVisible);
     }
-    AnalyzerManager::showPermanentStatusMessage(message);
+    Debugger::showPermanentStatusMessage(message);
 }
 
 } // namespace Internal
diff --git a/src/plugins/clangstaticanalyzer/clangstaticanalyzertool.h b/src/plugins/clangstaticanalyzer/clangstaticanalyzertool.h
index 37f5f3e75c4cbe7cd304d6a8564b4914ade8bd26..08580b395373dff4ed0726fbe461a6f3282920b7 100644
--- a/src/plugins/clangstaticanalyzer/clangstaticanalyzertool.h
+++ b/src/plugins/clangstaticanalyzer/clangstaticanalyzertool.h
@@ -56,8 +56,7 @@ public:
     bool isRunning() const { return m_running; }
     QList<Diagnostic> diagnostics() const;
 
-    QWidget *createWidgets();
-    Analyzer::AnalyzerRunControl *createRunControl(ProjectExplorer::RunConfiguration *runConfiguration,
+    Debugger::AnalyzerRunControl *createRunControl(ProjectExplorer::RunConfiguration *runConfiguration,
                                                    Core::Id runMode);
     void startTool(ProjectExplorer::RunConfiguration *rc);
 
@@ -71,6 +70,7 @@ private:
 
     void setBusyCursor(bool busy);
     void handleStateUpdate();
+    void updateRunActions();
 
 private:
     CppTools::ProjectInfo m_projectInfoBeforeBuild;
@@ -79,9 +79,12 @@ private:
     ClangStaticAnalyzerDiagnosticFilterModel *m_diagnosticFilterModel;
     ClangStaticAnalyzerDiagnosticView *m_diagnosticView;
 
+    QAction *m_startAction = 0;
+    QAction *m_stopAction = 0;
     QAction *m_goBack;
     QAction *m_goNext;
     bool m_running;
+    bool m_toolBusy = false;
 };
 
 } // namespace Internal
diff --git a/src/plugins/clangstaticanalyzer/clangstaticanalyzerunittests.cpp b/src/plugins/clangstaticanalyzer/clangstaticanalyzerunittests.cpp
index 76a063a260d54433fc1fcc105cc2efa57e9ee280..ba8814cbfa3050020e0d7bb28238e6ae7942fc5f 100644
--- a/src/plugins/clangstaticanalyzer/clangstaticanalyzerunittests.cpp
+++ b/src/plugins/clangstaticanalyzer/clangstaticanalyzerunittests.cpp
@@ -44,7 +44,7 @@
 #include <QTimer>
 #include <QtTest>
 
-using namespace Analyzer;
+using namespace Debugger;
 using namespace ProjectExplorer;
 using namespace Utils;
 
@@ -89,7 +89,7 @@ void ClangStaticAnalyzerUnitTests::testProject()
     CppTools::Tests::ProjectOpenerAndCloser projectManager;
     const CppTools::ProjectInfo projectInfo = projectManager.open(projectFilePath, true);
     QVERIFY(projectInfo.isValid());
-    AnalyzerManager::selectAction(ClangStaticAnalyzerPerspectiveId, /* alsoRunIt = */ true);
+    Debugger::runAction(ClangStaticAnalyzerActionId);
     QSignalSpy waiter(m_analyzerTool, SIGNAL(finished(bool)));
     QVERIFY(waiter.wait(30000));
     const QList<QVariant> arguments = waiter.takeFirst();
diff --git a/src/plugins/clangstaticanalyzer/clangstaticanalyzerutils.cpp b/src/plugins/clangstaticanalyzer/clangstaticanalyzerutils.cpp
index 1c7af5176bac1a9d797aac7b46951e75cbe3ee7d..d800af2588d35d89470dac5dda5c967dfc278ef8 100644
--- a/src/plugins/clangstaticanalyzer/clangstaticanalyzerutils.cpp
+++ b/src/plugins/clangstaticanalyzer/clangstaticanalyzerutils.cpp
@@ -77,7 +77,7 @@ QString clangExecutable(const QString &fileNameOrPath, bool *isValid)
     return executable;
 }
 
-QString createFullLocationString(const Analyzer::DiagnosticLocation &location)
+QString createFullLocationString(const Debugger::DiagnosticLocation &location)
 {
     const QString filePath = location.filePath;
     const QString lineNumber = QString::number(location.line);
diff --git a/src/plugins/clangstaticanalyzer/clangstaticanalyzerutils.h b/src/plugins/clangstaticanalyzer/clangstaticanalyzerutils.h
index 63f6f6517f96ae8e0c9ba752de0c3a6e5b637554..1531d050c6d7ca290c4d502f2d66d2eebd773928 100644
--- a/src/plugins/clangstaticanalyzer/clangstaticanalyzerutils.h
+++ b/src/plugins/clangstaticanalyzer/clangstaticanalyzerutils.h
@@ -34,7 +34,7 @@ QT_BEGIN_NAMESPACE
 class QString;
 QT_END_NAMESPACE
 
-namespace Analyzer { class DiagnosticLocation; }
+namespace Debugger { class DiagnosticLocation; }
 
 namespace ClangStaticAnalyzer {
 namespace Internal {
@@ -44,7 +44,7 @@ bool isClangExecutableUsable(const QString &filePath, QString *errorMessage = 0)
 QString clangExecutable(const QString &fileNameOrPath, bool *isValid);
 QString clangExecutableFromSettings(Core::Id toolchainType, bool *isValid);
 
-QString createFullLocationString(const Analyzer::DiagnosticLocation &location);
+QString createFullLocationString(const Debugger::DiagnosticLocation &location);
 
 } // namespace Internal
 } // namespace ClangStaticAnalyzer
diff --git a/src/plugins/debugger/analyzer/analyzer.pri b/src/plugins/debugger/analyzer/analyzer.pri
index 40da12eb3d669894c99dc261c1cf1944133d1fa9..2ae4afc59873551c96b8c2105dc1f93cfd6d655e 100644
--- a/src/plugins/debugger/analyzer/analyzer.pri
+++ b/src/plugins/debugger/analyzer/analyzer.pri
@@ -5,7 +5,6 @@ QT += network
 
 SOURCES += \
     $$PWD/analyzerruncontrol.cpp \
-    $$PWD/analyzermanager.cpp \
     $$PWD/analyzerrunconfigwidget.cpp \
     $$PWD/analyzerutils.cpp \
     $$PWD/detailederrorview.cpp \
@@ -13,7 +12,6 @@ SOURCES += \
     $$PWD/startremotedialog.cpp
 
 HEADERS += \
-    $$PWD/analyzerbase_global.h \
     $$PWD/analyzerconstants.h \
     $$PWD/analyzerruncontrol.h \
     $$PWD/analyzermanager.h \
diff --git a/src/plugins/debugger/analyzer/analyzerbase_global.h b/src/plugins/debugger/analyzer/analyzerbase_global.h
deleted file mode 100644
index 4d47f89a6d428b003ab0c25492830c4b27fc23e9..0000000000000000000000000000000000000000
--- a/src/plugins/debugger/analyzer/analyzerbase_global.h
+++ /dev/null
@@ -1,34 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Author: Nicolas Arnaud-Cormos, KDAB (nicolas.arnaud-cormos@kdab.com)
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt Creator.
-**
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-****************************************************************************/
-
-#ifndef ANALYZERBASE_GLOBAL_H
-#define ANALYZERBASE_GLOBAL_H
-
-#include "../debugger_global.h"
-
-#define ANALYZER_EXPORT DEBUGGER_EXPORT
-
-#endif // ANALYZERBASE_GLOBAL_H
diff --git a/src/plugins/debugger/analyzer/analyzerconstants.h b/src/plugins/debugger/analyzer/analyzerconstants.h
index 8f6da351e85883150d1d692fe1ba2448dac85532..c2554f42c26dbc56661687b19aa1b72860161ccb 100644
--- a/src/plugins/debugger/analyzer/analyzerconstants.h
+++ b/src/plugins/debugger/analyzer/analyzerconstants.h
@@ -29,16 +29,9 @@
 
 #include <QtGlobal>
 
-namespace Analyzer {
+namespace Debugger {
 namespace Constants {
 
-// Mode and its priority.
-const char MODE_ANALYZE[] = "Mode.Analyze";
-const int  P_MODE_ANALYZE = 76;
-
-// Context.
-const char C_ANALYZEMODE[] = "Analyzer.AnalyzeMode";
-
 // Menu.
 const char M_DEBUG_ANALYZER[] = "Analyzer.Menu.StartAnalyzer";
 const char M_DEBUG_ANALYZER_QML_OPTIONS[] = "Analyzer.Menu.QMLOptions";
@@ -51,6 +44,6 @@ const char G_ANALYZER_OPTIONS[] = "Menu.Group.Analyzer.Options";
 const char ANALYZERTASK_ID[] = "Analyzer.TaskId";
 
 } // namespace Constants
-} // namespace Analyzer
+} // namespace Debugger
 
 #endif // ANALYZERCONSTANTS_H
diff --git a/src/plugins/debugger/analyzer/analyzericons.h b/src/plugins/debugger/analyzer/analyzericons.h
index fa8d6a8bef7802fae4fcb3423a73fb96ba6220b6..f9f4a69056bca91e005d1b117b113898c2706fdb 100644
--- a/src/plugins/debugger/analyzer/analyzericons.h
+++ b/src/plugins/debugger/analyzer/analyzericons.h
@@ -28,7 +28,7 @@
 
 #include <utils/icon.h>
 
-namespace Analyzer {
+namespace Debugger {
 namespace Icons {
 
 const Utils::Icon ANALYZER_CONTROL_START({
@@ -42,6 +42,6 @@ const Utils::Icon MODE_ANALYZE_FLAT_ACTIVE({
         {QLatin1String(":/images/mode_analyze_mask.png"), Utils::Theme::IconsModeAnalyzeActiveColor}});
 
 } // namespace Icons
-} // namespace Analyzer
+} // namespace Debugger
 
 #endif // ANALYZERICONS_H
diff --git a/src/plugins/debugger/analyzer/analyzermanager.cpp b/src/plugins/debugger/analyzer/analyzermanager.cpp
deleted file mode 100644
index 15ab6253cd6a422246a2ffac4ffb45435fab774f..0000000000000000000000000000000000000000
--- a/src/plugins/debugger/analyzer/analyzermanager.cpp
+++ /dev/null
@@ -1,738 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Author: Andreas Hartmetz, KDAB (andreas.hartmetz@kdab.com)
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt Creator.
-**
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-****************************************************************************/
-
-#include "analyzermanager.h"
-
-#include "analyzericons.h"
-#include "analyzerstartparameters.h"
-#include "analyzerruncontrol.h"
-#include "../debuggerplugin.h"
-
-#include "../debuggermainwindow.h"
-
-#include <coreplugin/actionmanager/actioncontainer.h>
-#include <coreplugin/actionmanager/actionmanager.h>
-#include <coreplugin/actionmanager/command.h>
-#include <coreplugin/coreicons.h>
-#include <coreplugin/editormanager/editormanager.h>
-#include <coreplugin/findplaceholder.h>
-#include <coreplugin/icore.h>
-#include <coreplugin/imode.h>
-#include <coreplugin/modemanager.h>
-#include <coreplugin/modemanager.h>
-#include <coreplugin/navigationwidget.h>
-#include <coreplugin/outputpane.h>
-#include <coreplugin/rightpane.h>
-
-#include <projectexplorer/buildconfiguration.h>
-#include <projectexplorer/project.h>
-#include <projectexplorer/projectexplorer.h>
-#include <projectexplorer/projectexplorericons.h>
-#include <projectexplorer/session.h>
-#include <projectexplorer/target.h>
-#include <projectexplorer/taskhub.h>
-
-#include <utils/algorithm.h>
-#include <utils/fancymainwindow.h>
-#include <utils/styledbar.h>
-#include <utils/qtcassert.h>
-#include <utils/checkablemessagebox.h>
-#include <utils/statuslabel.h>
-
-#include <QAction>
-#include <QComboBox>
-#include <QDebug>
-#include <QDialog>
-#include <QDialogButtonBox>
-#include <QDockWidget>
-#include <QHBoxLayout>
-#include <QMenu>
-#include <QPointer>
-#include <QPushButton>
-#include <QStackedWidget>
-#include <QSettings>
-#include <QToolButton>
-#include <QVBoxLayout>
-#include <QVariant>
-
-using namespace Core;
-using namespace Utils;
-using namespace Core::Constants;
-using namespace Analyzer::Constants;
-using namespace ProjectExplorer;
-using namespace Debugger;
-using namespace Debugger::Internal;
-
-namespace Analyzer {
-
-bool ActionDescription::isRunnable(QString *reason) const
-{
-    if (m_customToolStarter) // Something special. Pretend we can always run it.
-        return true;
-
-    return ProjectExplorerPlugin::canRun(SessionManager::startupProject(), m_runMode, reason);
-}
-
-static bool buildTypeAccepted(QFlags<ToolMode> toolMode, BuildConfiguration::BuildType buildType)
-{
-    if (buildType == BuildConfiguration::Unknown)
-        return true;
-    if (buildType == BuildConfiguration::Debug && (toolMode & DebugMode))
-        return true;
-    if (buildType == BuildConfiguration::Release && (toolMode & ReleaseMode))
-        return true;
-    if (buildType == BuildConfiguration::Profile && (toolMode & ProfileMode))
-        return true;
-    return false;
-}
-
-void ActionDescription::startTool() const
-{
-    // Make sure mode is shown.
-    AnalyzerManager::showMode();
-
-    TaskHub::clearTasks(Constants::ANALYZERTASK_ID);
-    AnalyzerManager::showPermanentStatusMessage(QString());
-
-    if (m_toolPreparer && !m_toolPreparer())
-        return;
-
-    // ### not sure if we're supposed to check if the RunConFiguration isEnabled
-    Project *pro = SessionManager::startupProject();
-    RunConfiguration *rc = 0;
-    BuildConfiguration::BuildType buildType = BuildConfiguration::Unknown;
-    if (pro) {
-        if (const Target *target = pro->activeTarget()) {
-            // Build configuration is 0 for QML projects.
-            if (const BuildConfiguration *buildConfig = target->activeBuildConfiguration())
-                buildType = buildConfig->buildType();
-            rc = target->activeRunConfiguration();
-        }
-    }
-
-    // Custom start.
-    if (m_customToolStarter) {
-        if (rc) {
-            m_customToolStarter(rc);
-        } else {
-            QMessageBox *errorDialog = new QMessageBox(ICore::mainWindow());
-            errorDialog->setIcon(QMessageBox::Warning);
-            errorDialog->setWindowTitle(m_text);
-            errorDialog->setText(tr("Cannot start %1 without a project. Please open the project "
-                                    "and try again.").arg(m_text));
-            errorDialog->setStandardButtons(QMessageBox::Ok);
-            errorDialog->setDefaultButton(QMessageBox::Ok);
-            errorDialog->show();
-        }
-        return;
-    }
-
-    // Check the project for whether the build config is in the correct mode
-    // if not, notify the user and urge him to use the correct mode.
-    if (!buildTypeAccepted(m_toolMode, buildType)) {
-        QString currentMode;
-        switch (buildType) {
-            case BuildConfiguration::Debug:
-                currentMode = AnalyzerManager::tr("Debug");
-                break;
-            case BuildConfiguration::Profile:
-                currentMode = AnalyzerManager::tr("Profile");
-                break;
-            case BuildConfiguration::Release:
-                currentMode = AnalyzerManager::tr("Release");
-                break;
-            default:
-                QTC_CHECK(false);
-        }
-
-        QString toolModeString;
-        switch (m_toolMode) {
-            case DebugMode:
-                toolModeString = AnalyzerManager::tr("in Debug mode");
-                break;
-            case ProfileMode:
-                toolModeString = AnalyzerManager::tr("in Profile mode");
-                break;
-            case ReleaseMode:
-                toolModeString = AnalyzerManager::tr("in Release mode");
-                break;
-            case SymbolsMode:
-                toolModeString = AnalyzerManager::tr("with debug symbols (Debug or Profile mode)");
-                break;
-            case OptimizedMode:
-                toolModeString = AnalyzerManager::tr("on optimized code (Profile or Release mode)");
-                break;
-            default:
-                QTC_CHECK(false);
-        }
-        const QString toolName = m_text; // The action text is always the name of the tool
-        const QString title = AnalyzerManager::tr("Run %1 in %2 Mode?").arg(toolName).arg(currentMode);
-        const QString message = AnalyzerManager::tr("<html><head/><body><p>You are trying "
-            "to run the tool \"%1\" on an application in %2 mode. "
-            "The tool is designed to be used %3.</p><p>"
-            "Run-time characteristics differ significantly between "
-            "optimized and non-optimized binaries. Analytical "
-            "findings for one mode may or may not be relevant for "
-            "the other.</p><p>"
-            "Running tools that need debug symbols on binaries that "
-            "don't provide any may lead to missing function names "
-            "or otherwise insufficient output.</p><p>"
-            "Do you want to continue and run the tool in %2 mode?</p></body></html>")
-                .arg(toolName).arg(currentMode).arg(toolModeString);
-        if (Utils::CheckableMessageBox::doNotAskAgainQuestion(ICore::mainWindow(),
-                title, message, ICore::settings(), QLatin1String("AnalyzerCorrectModeWarning"))
-                    != QDialogButtonBox::Yes)
-            return;
-    }
-
-    ProjectExplorerPlugin::runStartupProject(m_runMode);
-}
-
-namespace Internal {
-
-const char LAST_ACTIVE_ACTION[] = "Analyzer.Plugin.LastActiveTool";
-
-////////////////////////////////////////////////////////////////////
-//
-// AnalyzerMode
-//
-////////////////////////////////////////////////////////////////////
-
-class AnalyzerMode : public IMode
-{
-public:
-    AnalyzerMode(QObject *parent = 0)
-        : IMode(parent)
-    {
-        setContext(Context(C_ANALYZEMODE, C_NAVIGATION_PANE));
-        setDisplayName(AnalyzerManager::tr("Analyze"));
-        setIcon(Utils::Icon::modeIcon(Icons::MODE_ANALYZE_CLASSIC,
-                                      Icons::MODE_ANALYZE_FLAT, Icons::MODE_ANALYZE_FLAT_ACTIVE));
-        setPriority(P_MODE_ANALYZE);
-        setId(MODE_ANALYZE);
-    }
-
-    ~AnalyzerMode()
-    {
-        delete m_widget;
-        m_widget = 0;
-    }
-};
-
-} // namespace Internal
-
-////////////////////////////////////////////////////////////////////
-//
-// AnalyzerManagerPrivate
-//
-////////////////////////////////////////////////////////////////////
-
-class AnalyzerManagerPrivate : public QObject
-{
-    Q_DECLARE_TR_FUNCTIONS(Analyzer::AnalyzerManager)
-
-public:
-    AnalyzerManagerPrivate(AnalyzerManager *qq);
-
-    /**
-     * After calling this, a proper instance of IMode is initialized
-     * It is delayed since an analyzer mode makes no sense without analyzer tools
-     *
-     * \note Call this before adding a tool to the manager
-     */
-    void delayedInit();
-
-    void setupActions();
-    void createModeMainWindow();
-    bool showPromptDialog(const QString &title, const QString &text,
-        const QString &stopButtonText, const QString &cancelButtonText) const;
-
-    void registerAction(Core::Id actionId, const ActionDescription &desc);
-    void selectSavedTool();
-    void selectAction(Id actionId);
-    void handleToolStarted();
-    void handleToolFinished();
-    void modeChanged(IMode *mode);
-    void resetLayout();
-    void updateRunActions();
-
-public:
-    AnalyzerManager *q;
-    Internal::AnalyzerMode *m_mode = 0;
-    bool m_isRunning = false;
-    Core::Id m_currentActionId;
-    QHash<Id, QAction *> m_actions;
-    QHash<Id, ActionDescription> m_descriptions;
-    QAction *m_startAction = 0;
-    QAction *m_stopAction = 0;
-    ActionContainer *m_menu = 0;
-    MainWindowBase *m_mainWindow;
-};
-
-AnalyzerManagerPrivate::AnalyzerManagerPrivate(AnalyzerManager *qq):
-    q(qq), m_mainWindow(new MainWindowBase)
-{
-    QComboBox *toolBox = m_mainWindow->toolBox();
-    toolBox->setObjectName(QLatin1String("AnalyzerManagerToolBox"));
-    toolBox->insertSeparator(0);
-    connect(toolBox, static_cast<void (QComboBox::*)(int)>(&QComboBox::activated), this, [this, toolBox](int item) {
-        selectAction(Id::fromSetting(toolBox->itemData(item)));
-    });
-
-    setupActions();
-
-    ProjectExplorerPlugin *pe = ProjectExplorerPlugin::instance();
-    connect(pe, &ProjectExplorerPlugin::updateRunActions, this, &AnalyzerManagerPrivate::updateRunActions);
-}
-
-void AnalyzerManagerPrivate::setupActions()
-{
-    Command *command = 0;
-
-    // Menus
-    m_menu = ActionManager::createMenu(M_DEBUG_ANALYZER);
-    m_menu->menu()->setTitle(tr("&Analyze"));
-    m_menu->menu()->setEnabled(true);
-
-    m_menu->appendGroup(G_ANALYZER_CONTROL);
-    m_menu->appendGroup(G_ANALYZER_TOOLS);
-    m_menu->appendGroup(G_ANALYZER_REMOTE_TOOLS);
-    m_menu->appendGroup(G_ANALYZER_OPTIONS);
-
-    ActionContainer *menubar = ActionManager::actionContainer(MENU_BAR);
-    ActionContainer *mtools = ActionManager::actionContainer(M_TOOLS);
-    menubar->addMenu(mtools, m_menu);
-
-    m_startAction = new QAction(tr("Start"), m_menu);
-    m_startAction->setIcon(Analyzer::Icons::ANALYZER_CONTROL_START.icon());
-    ActionManager::registerAction(m_startAction, "Analyzer.Start");
-    connect(m_startAction, &QAction::triggered, this, [this] {
-        QTC_ASSERT(m_descriptions.contains(m_currentActionId), return);
-        m_descriptions.value(m_currentActionId).startTool();
-    });
-
-    m_stopAction = new QAction(tr("Stop"), m_menu);
-    m_stopAction->setEnabled(false);
-    m_stopAction->setIcon(ProjectExplorer::Icons::STOP_SMALL.icon());
-    command = ActionManager::registerAction(m_stopAction, "Analyzer.Stop");
-    m_menu->addAction(command, G_ANALYZER_CONTROL);
-
-    m_menu->addSeparator(G_ANALYZER_TOOLS);
-    m_menu->addSeparator(G_ANALYZER_REMOTE_TOOLS);
-    m_menu->addSeparator(G_ANALYZER_OPTIONS);
-}
-
-void AnalyzerManagerPrivate::delayedInit()
-{
-    if (m_mode)
-        return;
-
-    m_mode = new Internal::AnalyzerMode(q);
-    createModeMainWindow();
-
-    connect(ModeManager::instance(), &ModeManager::currentModeChanged,
-            this, &AnalyzerManagerPrivate::modeChanged);
-
-    // Right-side window with editor, output etc.
-    auto mainWindowSplitter = new MiniSplitter;
-    mainWindowSplitter->addWidget(m_mainWindow);
-    mainWindowSplitter->addWidget(new OutputPanePlaceHolder(m_mode, mainWindowSplitter));
-    mainWindowSplitter->setStretchFactor(0, 10);
-    mainWindowSplitter->setStretchFactor(1, 0);
-    mainWindowSplitter->setOrientation(Qt::Vertical);
-
-    // Navigation + right-side window.
-    auto splitter = new MiniSplitter;
-    splitter->addWidget(new NavigationWidgetPlaceHolder(m_mode));
-    splitter->addWidget(mainWindowSplitter);
-    splitter->setStretchFactor(0, 0);
-    splitter->setStretchFactor(1, 1);
-
-    auto modeContextObject = new IContext(this);
-    modeContextObject->setContext(Context(C_EDITORMANAGER));
-    modeContextObject->setWidget(splitter);
-    ICore::addContextObject(modeContextObject);
-    m_mode->setWidget(splitter);
-
-    Debugger::Internal::DebuggerPlugin::instance()->addAutoReleasedObject(m_mode);
-
-    // Populate Windows->Views menu with standard actions.
-    Context analyzerContext(C_ANALYZEMODE);
-    ActionContainer *viewsMenu = ActionManager::actionContainer(M_WINDOW_VIEWS);
-    Command *cmd = ActionManager::registerAction(m_mainWindow->menuSeparator1(),
-        "Analyzer.Views.Separator1", analyzerContext);
-    cmd->setAttribute(Command::CA_Hide);
-    viewsMenu->addAction(cmd, G_DEFAULT_THREE);
-    cmd = ActionManager::registerAction(m_mainWindow->autoHideTitleBarsAction(),
-        "Analyzer.Views.AutoHideTitleBars", analyzerContext);
-    cmd->setAttribute(Command::CA_Hide);
-    viewsMenu->addAction(cmd, G_DEFAULT_THREE);
-    cmd = ActionManager::registerAction(m_mainWindow->menuSeparator2(),
-        "Analyzer.Views.Separator2", analyzerContext);
-    cmd->setAttribute(Command::CA_Hide);
-    viewsMenu->addAction(cmd, G_DEFAULT_THREE);
-    cmd = ActionManager::registerAction(m_mainWindow->resetLayoutAction(),
-        "Analyzer.Views.ResetSimple", analyzerContext);
-    cmd->setAttribute(Command::CA_Hide);
-    viewsMenu->addAction(cmd, G_DEFAULT_THREE);
-}
-
-static QToolButton *toolButton(QAction *action)
-{
-    auto button = new QToolButton;
-    button->setDefaultAction(action);
-    return button;
-}
-
-void AnalyzerManagerPrivate::createModeMainWindow()
-{
-    m_mainWindow->setObjectName(QLatin1String("AnalyzerManagerMainWindow"));
-    m_mainWindow->setLastSettingsName(QLatin1String(Internal::LAST_ACTIVE_ACTION));
-
-    auto editorHolderLayout = new QVBoxLayout;
-    editorHolderLayout->setMargin(0);
-    editorHolderLayout->setSpacing(0);
-
-    auto editorAndFindWidget = new QWidget;
-    editorAndFindWidget->setLayout(editorHolderLayout);
-    editorHolderLayout->addWidget(new EditorManagerPlaceHolder(m_mode));
-    editorHolderLayout->addWidget(new FindToolBarPlaceHolder(editorAndFindWidget));
-
-    auto documentAndRightPane = new MiniSplitter;
-    documentAndRightPane->addWidget(editorAndFindWidget);
-    documentAndRightPane->addWidget(new RightPanePlaceHolder(m_mode));
-    documentAndRightPane->setStretchFactor(0, 1);
-    documentAndRightPane->setStretchFactor(1, 0);
-
-    auto analyzeToolBar = new StyledBar;
-    analyzeToolBar->setProperty("topBorder", true);
-
-    auto analyzeToolBarLayout = new QHBoxLayout(analyzeToolBar);
-    analyzeToolBarLayout->setMargin(0);
-    analyzeToolBarLayout->setSpacing(0);
-    analyzeToolBarLayout->addWidget(toolButton(m_startAction));
-    analyzeToolBarLayout->addWidget(toolButton(m_stopAction));
-    analyzeToolBarLayout->addWidget(new StyledSeparator);
-    analyzeToolBarLayout->addWidget(m_mainWindow->toolBox());
-    analyzeToolBarLayout->addWidget(m_mainWindow->controlsStack());
-    analyzeToolBarLayout->addWidget(m_mainWindow->statusLabel());
-    analyzeToolBarLayout->addStretch();
-
-    auto dock = new QDockWidget(tr("Analyzer Toolbar"));
-    dock->setObjectName(QLatin1String("Analyzer Toolbar"));
-    dock->setWidget(analyzeToolBar);
-    dock->setFeatures(QDockWidget::NoDockWidgetFeatures);
-    dock->setProperty("managed_dockwidget", QLatin1String("true"));
-    dock->setAllowedAreas(Qt::BottomDockWidgetArea);
-    // hide title bar
-    dock->setTitleBarWidget(new QWidget(dock));
-    m_mainWindow->addDockWidget(Qt::BottomDockWidgetArea, dock);
-    m_mainWindow->setToolBarDockWidget(dock);
-
-    auto centralWidget = new QWidget;
-    m_mainWindow->setCentralWidget(centralWidget);
-
-    auto centralLayout = new QVBoxLayout(centralWidget);
-    centralWidget->setLayout(centralLayout);
-    centralLayout->setMargin(0);
-    centralLayout->setSpacing(0);
-    centralLayout->addWidget(documentAndRightPane);
-    centralLayout->setStretch(0, 1);
-    centralLayout->setStretch(1, 0);
-}
-
-bool AnalyzerManagerPrivate::showPromptDialog(const QString &title, const QString &text,
-    const QString &stopButtonText, const QString &cancelButtonText) const
-{
-    CheckableMessageBox messageBox(ICore::mainWindow());
-    messageBox.setWindowTitle(title);
-    messageBox.setText(text);
-    messageBox.setStandardButtons(QDialogButtonBox::Yes|QDialogButtonBox::Cancel);
-    if (!stopButtonText.isEmpty())
-        messageBox.button(QDialogButtonBox::Yes)->setText(stopButtonText);
-    if (!cancelButtonText.isEmpty())
-        messageBox.button(QDialogButtonBox::Cancel)->setText(cancelButtonText);
-    messageBox.setDefaultButton(QDialogButtonBox::Yes);
-    messageBox.setCheckBoxVisible(false);
-    messageBox.exec();
-    return messageBox.clickedStandardButton() == QDialogButtonBox::Yes;
-}
-
-void AnalyzerManagerPrivate::modeChanged(IMode *mode)
-{
-    if (mode && mode == m_mode) {
-        m_mainWindow->setDockActionsVisible(true);
-        static bool firstTime = !m_currentActionId.isValid();
-        if (firstTime)
-            selectSavedTool();
-        firstTime = false;
-        updateRunActions();
-    } else {
-        m_mainWindow->setDockActionsVisible(false);
-    }
-}
-
-void AnalyzerManagerPrivate::selectSavedTool()
-{
-    const QSettings *settings = ICore::settings();
-
-    if (settings->contains(QLatin1String(Internal::LAST_ACTIVE_ACTION))) {
-        const Id lastAction = Id::fromSetting(settings->value(QLatin1String(Internal::LAST_ACTIVE_ACTION)));
-        selectAction(lastAction);
-    }
-    // fallback to first available tool
-    if (!m_descriptions.isEmpty())
-        selectAction(m_descriptions.begin().key());
-}
-
-void AnalyzerManagerPrivate::selectAction(Id actionId)
-{
-    QTC_ASSERT(m_descriptions.contains(actionId), return);
-    if (m_currentActionId == actionId)
-        return;
-
-    // Now change the tool.
-    m_currentActionId = actionId;
-    ActionDescription desc = m_descriptions.value(actionId);
-
-    m_mainWindow->restorePerspective(desc.perspectiveId());
-
-    const int toolboxIndex = m_mainWindow->toolBox()->findText(desc.text());
-    QTC_ASSERT(toolboxIndex >= 0, return);
-    m_mainWindow->toolBox()->setCurrentIndex(toolboxIndex);
-
-    updateRunActions();
-}
-
-void AnalyzerManagerPrivate::registerAction(Id actionId, const ActionDescription &desc)
-{
-    delayedInit(); // Make sure that there is a valid IMode instance.
-
-    auto action = new QAction(this);
-    action->setText(desc.text());
-    action->setToolTip(desc.toolTip());
-    m_actions.insert(actionId, action);
-    m_descriptions.insert(actionId, desc);
-
-    int index = -1;
-    if (desc.menuGroup() == Constants::G_ANALYZER_REMOTE_TOOLS) {
-        index = m_mainWindow->toolBox()->count();
-    } else if (desc.menuGroup() == Constants::G_ANALYZER_TOOLS) {
-        for (int i = m_mainWindow->toolBox()->count(); --i >= 0; )
-            if (m_mainWindow->toolBox()->itemText(i).isEmpty())
-                index = i;
-    }
-
-    if (index >= 0)
-        m_mainWindow->toolBox()->insertItem(index, desc.text(), actionId.toSetting());
-
-    Id menuGroup = desc.menuGroup();
-    if (menuGroup.isValid()) {
-        Command *command = ActionManager::registerAction(action, actionId);
-        m_menu->addAction(command, menuGroup);
-    }
-
-    connect(action, &QAction::triggered, this, [this, desc, actionId] {
-        selectAction(actionId);
-        desc.startTool();
-    });
-}
-
-void AnalyzerManagerPrivate::handleToolStarted()
-{
-    m_isRunning = true; // FIXME: Make less global.
-    updateRunActions();
-}
-
-void AnalyzerManagerPrivate::handleToolFinished()
-{
-    m_isRunning = false;
-    updateRunActions();
-}
-
-void AnalyzerManagerPrivate::updateRunActions()
-{
-    QString disabledReason;
-    bool enabled = false;
-    if (m_isRunning)
-        disabledReason = tr("An analysis is still in progress.");
-    else if (m_currentActionId.isValid())
-        enabled = m_descriptions.value(m_currentActionId).isRunnable(&disabledReason);
-    else
-        disabledReason = tr("No analyzer tool selected.");
-
-    m_startAction->setEnabled(enabled);
-    m_startAction->setToolTip(disabledReason);
-    m_mainWindow->toolBox()->setEnabled(!m_isRunning);
-    m_stopAction->setEnabled(m_isRunning);
-
-    for (auto it = m_actions.begin(), end = m_actions.end(); it != end; ++it)
-        it.value()->setEnabled(!m_isRunning && m_descriptions.value(it.key()).isRunnable());
-}
-
-////////////////////////////////////////////////////////////////////
-//
-// AnalyzerManager
-//
-////////////////////////////////////////////////////////////////////
-
-static AnalyzerManagerPrivate *d = 0;
-
-AnalyzerManager::AnalyzerManager(QObject *parent)
-  : QObject(parent)
-{
-    QTC_CHECK(d == 0);
-    d = new AnalyzerManagerPrivate(this);
-}
-
-AnalyzerManager::~AnalyzerManager()
-{
-    QTC_CHECK(d);
-    delete d;
-    d = 0;
-}
-
-void AnalyzerManager::shutdown()
-{
-    d->m_mainWindow->saveCurrentPerspective();
-}
-
-void AnalyzerManager::registerAction(Id actionId, const ActionDescription &desc)
-{
-    d->registerAction(actionId, desc);
-}
-
-void AnalyzerManager::registerDockWidget(Id dockId, QWidget *widget)
-{
-    QTC_ASSERT(!widget->objectName().isEmpty(), return);
-    QDockWidget *dockWidget = d->m_mainWindow->registerDockWidget(dockId, widget);
-
-    QAction *toggleViewAction = dockWidget->toggleViewAction();
-    toggleViewAction->setText(dockWidget->windowTitle());
-
-    Command *cmd = ActionManager::registerAction(toggleViewAction,
-        Id("Analyzer.").withSuffix(dockWidget->objectName()));
-    cmd->setAttribute(Command::CA_Hide);
-
-    ActionContainer *viewsMenu = ActionManager::actionContainer(Id(M_WINDOW_VIEWS));
-    viewsMenu->addAction(cmd);
-}
-
-void AnalyzerManager::registerToolbar(Id toolbarId, QWidget *widget)
-{
-    d->m_mainWindow->registerToolbar(toolbarId, widget);
-}
-
-Perspective::Operation::Operation(Id dockId, Id existing, Perspective::OperationType operationType,
-                                  bool visibleByDefault, Qt::DockWidgetArea area)
-    : dockId(dockId), existing(existing), operationType(operationType),
-      visibleByDefault(visibleByDefault), area(area)
-{}
-
-Perspective::Perspective(std::initializer_list<Perspective::Operation> operations)
-    : m_operations(operations)
-{
-    for (const Operation &operation : operations)
-        m_docks.append(operation.dockId);
-}
-
-void Perspective::addOperation(const Operation &operation)
-{
-    m_docks.append(operation.dockId);
-    m_operations.append(operation);
-}
-
-void AnalyzerManager::registerPerspective(Id perspectiveId, const Perspective &perspective)
-{
-    d->m_mainWindow->registerPerspective(perspectiveId, perspective);
-}
-
-void AnalyzerManager::selectAction(Id actionId, bool alsoRunIt)
-{
-    d->selectAction(actionId);
-    if (alsoRunIt)
-        d->m_descriptions.value(actionId).startTool();
-}
-
-void AnalyzerManager::enableMainWindow(bool on)
-{
-    d->m_mainWindow->setEnabled(on);
-}
-
-void AnalyzerManager::showStatusMessage(const QString &message, int timeoutMS)
-{
-    d->m_mainWindow->showStatusMessage(message, timeoutMS);
-}
-
-void AnalyzerManager::showPermanentStatusMessage(const QString &message)
-{
-    d->m_mainWindow->showStatusMessage(message, -1);
-}
-
-void AnalyzerManager::showMode()
-{
-    if (d->m_mode)
-        ModeManager::activateMode(d->m_mode->id());
-}
-
-void AnalyzerManager::stopTool()
-{
-    stopAction()->trigger();
-}
-
-QAction *AnalyzerManager::stopAction()
-{
-    return d->m_stopAction;
-}
-
-void AnalyzerManager::handleToolStarted()
-{
-    d->handleToolStarted();
-}
-
-void AnalyzerManager::handleToolFinished()
-{
-    d->handleToolFinished();
-}
-
-AnalyzerRunControl *AnalyzerManager::createRunControl(RunConfiguration *runConfiguration, Id runMode)
-{
-    foreach (const ActionDescription &action, d->m_descriptions) {
-        if (action.runMode() == runMode)
-            return action.runControlCreator()(runConfiguration, runMode);
-    }
-    return 0;
-}
-
-bool operator==(const AnalyzerConnection &c1, const AnalyzerConnection &c2)
-{
-    return c1.connParams == c2.connParams
-        && c1.analyzerHost == c2.analyzerHost
-        && c1.analyzerSocket == c2.analyzerSocket
-        && c1.analyzerPort == c2.analyzerPort;
-}
-
-} // namespace Analyzer
diff --git a/src/plugins/debugger/analyzer/analyzermanager.h b/src/plugins/debugger/analyzer/analyzermanager.h
index d4bfd35ab53eaa1cd5c8bfe412f61b8f9923a23b..70209ea291497880aa39cb105657a4a94dcc6d5c 100644
--- a/src/plugins/debugger/analyzer/analyzermanager.h
+++ b/src/plugins/debugger/analyzer/analyzermanager.h
@@ -27,7 +27,6 @@
 #ifndef ANALYZERMANAGER_H
 #define ANALYZERMANAGER_H
 
-#include "analyzerbase_global.h"
 #include "analyzerconstants.h"
 
 #include "../debuggermainwindow.h"
@@ -48,7 +47,7 @@ QT_END_NAMESPACE
 
 namespace ProjectExplorer { class RunConfiguration; }
 
-namespace Analyzer {
+namespace Debugger {
 
 class AnalyzerRunControl;
 
@@ -75,9 +74,9 @@ Q_DECLARE_FLAGS(ToolModes, ToolMode)
  *
 */
 
-class ANALYZER_EXPORT ActionDescription
+class DEBUGGER_EXPORT ActionDescription
 {
-    Q_DECLARE_TR_FUNCTIONS(Analyzer::AnalyzerAction)
+    Q_DECLARE_TR_FUNCTIONS(Debugger::AnalyzerAction)
 
 public:
     ActionDescription() {}
@@ -85,8 +84,8 @@ public:
     Core::Id menuGroup() const { return m_menuGroup; }
     void setMenuGroup(Core::Id menuGroup) { m_menuGroup = menuGroup; }
 
-    Core::Id perspectiveId() const { return m_perspective; }
-    void setPerspectiveId(Core::Id id) { m_perspective = id; }
+    QByteArray perspectiveId() const { return m_perspectiveId; }
+    void setPerspectiveId(const QByteArray &id) { m_perspectiveId = id; }
     void setToolMode(QFlags<ToolMode> mode) { m_toolMode = mode; }
 
     Core::Id runMode() const { return m_runMode; }
@@ -120,7 +119,7 @@ private:
     QString m_text;
     QString m_toolTip;
     Core::Id m_menuGroup;
-    Core::Id m_perspective;
+    QByteArray m_perspectiveId;
     QFlags<ToolMode> m_toolMode = AnyMode;
     Core::Id m_runMode;
     RunControlCreator m_runControlCreator;
@@ -128,41 +127,28 @@ private:
     ToolPreparer m_toolPreparer;
 };
 
-// FIXME: Merge with AnalyzerPlugin.
-class ANALYZER_EXPORT AnalyzerManager : public QObject
-{
-    Q_OBJECT
-
-public:
-    explicit AnalyzerManager(QObject *parent);
-    ~AnalyzerManager();
+// FIXME: Merge with something sensible.
 
-    static void shutdown();
+// Register a tool for a given start mode.
+DEBUGGER_EXPORT void registerAction(Core::Id actionId, const ActionDescription &desc, QAction *startAction = 0);
+DEBUGGER_EXPORT void registerPerspective(const QByteArray &perspectiveId, const Utils::Perspective &perspective);
+DEBUGGER_EXPORT void registerToolbar(const QByteArray &perspectiveId, const Utils::ToolbarDescription &desc);
 
-    // Register a tool for a given start mode.
-    static void registerAction(Core::Id actionId, const ActionDescription &desc);
-    static void registerPerspective(Core::Id perspectiveId, const Perspective &perspective);
-    static void registerDockWidget(Core::Id dockId, QWidget *widget);
-    static void registerToolbar(Core::Id toolbarId, QWidget *widget);
+DEBUGGER_EXPORT void enableMainWindow(bool on);
 
-    static void enableMainWindow(bool on);
+DEBUGGER_EXPORT void selectPerspective(const QByteArray &perspectiveId);
+DEBUGGER_EXPORT void runAction(Core::Id actionId);
 
-    static void showMode();
-    static void selectAction(Core::Id actionId, bool alsoRunIt = false);
-    static void stopTool();
+// Convenience functions.
+DEBUGGER_EXPORT void showStatusMessage(const QString &message, int timeoutMS = 10000);
+DEBUGGER_EXPORT void showPermanentStatusMessage(const QString &message);
 
-    // Convenience functions.
-    static void showStatusMessage(const QString &message, int timeoutMS = 10000);
-    static void showPermanentStatusMessage(const QString &message);
+DEBUGGER_EXPORT QAction *createStartAction();
+DEBUGGER_EXPORT QAction *createStopAction();
 
-    static void handleToolStarted();
-    static void handleToolFinished();
-    static QAction *stopAction();
-
-    static AnalyzerRunControl *createRunControl(
-        ProjectExplorer::RunConfiguration *runConfiguration, Core::Id runMode);
-};
+DEBUGGER_EXPORT AnalyzerRunControl *createAnalyzerRunControl(
+    ProjectExplorer::RunConfiguration *runConfiguration, Core::Id runMode);
 
-} // namespace Analyzer
+} // namespace Debugger
 
 #endif // ANALYZERMANAGER_H
diff --git a/src/plugins/debugger/analyzer/analyzerrunconfigwidget.cpp b/src/plugins/debugger/analyzer/analyzerrunconfigwidget.cpp
index 9504ebce9fb234c91f10a28eb607caac4d5341b6..94e0314d5ab75f76091043817b1c238267e96d66 100644
--- a/src/plugins/debugger/analyzer/analyzerrunconfigwidget.cpp
+++ b/src/plugins/debugger/analyzer/analyzerrunconfigwidget.cpp
@@ -36,7 +36,7 @@
 #include <QComboBox>
 #include <QPushButton>
 
-namespace Analyzer {
+namespace Debugger {
 
 AnalyzerRunConfigWidget::AnalyzerRunConfigWidget(ProjectExplorer::IRunConfigurationAspect *aspect)
 {
@@ -105,4 +105,4 @@ void AnalyzerRunConfigWidget::restoreGlobal()
     m_aspect->resetProjectToGlobalSettings();
 }
 
-} // namespace Analyzer
+} // namespace Debugger
diff --git a/src/plugins/debugger/analyzer/analyzerrunconfigwidget.h b/src/plugins/debugger/analyzer/analyzerrunconfigwidget.h
index aa18b74156dd7a5d6e011f914b21ff06166029a2..ad4ba8cc2d33d54d486bfee00af63a9dccfb821d 100644
--- a/src/plugins/debugger/analyzer/analyzerrunconfigwidget.h
+++ b/src/plugins/debugger/analyzer/analyzerrunconfigwidget.h
@@ -27,7 +27,7 @@
 #ifndef ANALYZERRUNCONFIGWIDGET_H
 #define ANALYZERRUNCONFIGWIDGET_H
 
-#include "analyzerbase_global.h"
+#include <debugger/debugger_global.h>
 
 #include <projectexplorer/runconfiguration.h>
 
@@ -38,9 +38,9 @@ QT_END_NAMESPACE
 
 namespace Utils { class DetailsWidget; }
 
-namespace Analyzer {
+namespace Debugger {
 
-class ANALYZER_EXPORT AnalyzerRunConfigWidget : public ProjectExplorer::RunConfigWidget
+class DEBUGGER_EXPORT AnalyzerRunConfigWidget : public ProjectExplorer::RunConfigWidget
 {
     Q_OBJECT
 
@@ -62,6 +62,6 @@ private:
     Utils::DetailsWidget *m_details;
 };
 
-} // namespace Analyzer
+} // namespace Debugger
 
 #endif // ANALYZERRUNCONFIGWIDGET_H
diff --git a/src/plugins/debugger/analyzer/analyzerruncontrol.cpp b/src/plugins/debugger/analyzer/analyzerruncontrol.cpp
index 9d4957e54f2f87f2c744ca4c148bcee002db8b33..18e74abe185faa6e5778a974ac995c604a1fc0d8 100644
--- a/src/plugins/debugger/analyzer/analyzerruncontrol.cpp
+++ b/src/plugins/debugger/analyzer/analyzerruncontrol.cpp
@@ -37,60 +37,12 @@
 
 using namespace ProjectExplorer;
 
-//////////////////////////////////////////////////////////////////////////
-//
-// AnalyzerRunControl
-//
-//////////////////////////////////////////////////////////////////////////
-
-namespace Analyzer {
+namespace Debugger {
 
 AnalyzerRunControl::AnalyzerRunControl(RunConfiguration *runConfiguration, Core::Id runMode)
     : RunControl(runConfiguration, runMode)
 {
     setIcon(Icons::ANALYZER_CONTROL_START);
-
-    connect(this, &AnalyzerRunControl::finished,
-            this, &AnalyzerRunControl::runControlFinished);
-    connect(AnalyzerManager::stopAction(), &QAction::triggered,
-            this, &AnalyzerRunControl::stopIt);
-}
-
-void AnalyzerRunControl::stopIt()
-{
-    if (stop() == RunControl::StoppedSynchronously)
-        AnalyzerManager::handleToolFinished();
-}
-
-void AnalyzerRunControl::runControlFinished()
-{
-    m_isRunning = false;
-    AnalyzerManager::handleToolFinished();
-}
-
-void AnalyzerRunControl::start()
-{
-    AnalyzerManager::handleToolStarted();
-
-    if (startEngine()) {
-        m_isRunning = true;
-        emit started();
-    }
-}
-
-RunControl::StopResult AnalyzerRunControl::stop()
-{
-    if (!m_isRunning)
-        return StoppedSynchronously;
-
-    stopEngine();
-    m_isRunning = false;
-    return AsynchronousStop;
-}
-
-bool AnalyzerRunControl::isRunning() const
-{
-    return m_isRunning;
 }
 
-} // namespace Analyzer
+} // namespace Debugger
diff --git a/src/plugins/debugger/analyzer/analyzerruncontrol.h b/src/plugins/debugger/analyzer/analyzerruncontrol.h
index d13adc98b76826389e2cf9414d32a18fece183d7..a919a7f36388c0a3faf5e0fc87b59f2b6bedbb10 100644
--- a/src/plugins/debugger/analyzer/analyzerruncontrol.h
+++ b/src/plugins/debugger/analyzer/analyzerruncontrol.h
@@ -27,31 +27,26 @@
 #ifndef ANALYZERRUNCONTROL_H
 #define ANALYZERRUNCONTROL_H
 
-#include "analyzerbase_global.h"
+#include <debugger/debugger_global.h>
 
 #include <projectexplorer/runconfiguration.h>
 
 #include <utils/outputformat.h>
 
-namespace Analyzer {
+namespace Debugger {
 
 /**
  * An AnalyzerRunControl instance handles the launch of an analyzation tool.
  *
  * It gets created for each launch and deleted when the launch is stopped or ended.
  */
-class ANALYZER_EXPORT AnalyzerRunControl : public ProjectExplorer::RunControl
+class DEBUGGER_EXPORT AnalyzerRunControl : public ProjectExplorer::RunControl
 {
     Q_OBJECT
 
 public:
     AnalyzerRunControl(ProjectExplorer::RunConfiguration *runConfiguration, Core::Id runMode);
 
-    /// Start analyzation process.
-    virtual bool startEngine() = 0;
-    /// Trigger async stop of the analyzation process.
-    virtual void stopEngine() = 0;
-
     /// Controller actions.
     virtual bool canPause() const { return false; }
     virtual void pause() {}
@@ -60,28 +55,16 @@ public:
     virtual void notifyRemoteSetupDone(quint16) {}
     virtual void notifyRemoteFinished() {}
 
-    // ProjectExplorer::RunControl
-    void start() override;
-    StopResult stop() override;
-    bool isRunning() const override;
+signals:
+    void starting();
 
 public slots:
     virtual void logApplicationMessage(const QString &, Utils::OutputFormat) { }
 
-private slots:
-    void stopIt();
-    void runControlFinished();
-
-signals:
-    /// Must be emitted when the engine is starting.
-    void starting();
-
 private:
     bool supportsReRunning() const override { return false; }
-
-protected:
-    bool m_isRunning;
 };
-} // namespace Analyzer
+
+} // namespace Debugger
 
 #endif // ANALYZERRUNCONTROL_H
diff --git a/src/plugins/debugger/analyzer/analyzerstartparameters.h b/src/plugins/debugger/analyzer/analyzerstartparameters.h
index 1b4a3a6bdff41ed3fbf94ec7b8320fa11984d15a..73226c0e33e609dec37b183030f7235680ac685a 100644
--- a/src/plugins/debugger/analyzer/analyzerstartparameters.h
+++ b/src/plugins/debugger/analyzer/analyzerstartparameters.h
@@ -26,16 +26,16 @@
 #ifndef ANALYZERSTARTPARAMETERS_H
 #define ANALYZERSTARTPARAMETERS_H
 
-#include "analyzerbase_global.h"
+#include <debugger/debugger_global.h>
 
 #include <projectexplorer/runnables.h>
 #include <ssh/sshconnection.h>
 
 #include <QMetaType>
 
-namespace Analyzer {
+namespace Debugger {
 
-class ANALYZER_EXPORT AnalyzerConnection
+class DEBUGGER_EXPORT AnalyzerConnection
 {
 public:
     QSsh::SshConnectionParameters connParams;
@@ -44,8 +44,8 @@ public:
     quint16 analyzerPort = 0;
 };
 
-ANALYZER_EXPORT bool operator==(const AnalyzerConnection &c1, const AnalyzerConnection &c2);
+DEBUGGER_EXPORT bool operator==(const AnalyzerConnection &c1, const AnalyzerConnection &c2);
 
-} // namespace Analyzer
+} // namespace Debugger
 
 #endif // ANALYZERSTARTPARAMETERS_H
diff --git a/src/plugins/debugger/analyzer/analyzerutils.cpp b/src/plugins/debugger/analyzer/analyzerutils.cpp
index cafafa1f114059ef0389248e8dc8ae84ceae54d7..c38e54bb4546efba2c0d2951e1f69bc0b0222a2b 100644
--- a/src/plugins/debugger/analyzer/analyzerutils.cpp
+++ b/src/plugins/debugger/analyzer/analyzerutils.cpp
@@ -39,7 +39,7 @@
 
 #include <QTextCursor>
 
-using namespace Analyzer;
+using namespace Debugger;
 using namespace Core;
 using namespace ProjectExplorer;
 
@@ -92,7 +92,7 @@ CPlusPlus::Symbol *AnalyzerUtils::findSymbolUnderCursor()
 
 void AnalyzerUtils::logToIssuesPane(Task::TaskType type, const QString &message)
 {
-    TaskHub::addTask(type, message, Analyzer::Constants::ANALYZERTASK_ID);
+    TaskHub::addTask(type, message, Debugger::Constants::ANALYZERTASK_ID);
     if (type == Task::Error)
         TaskHub::requestPopup();
 }
diff --git a/src/plugins/debugger/analyzer/analyzerutils.h b/src/plugins/debugger/analyzer/analyzerutils.h
index e173c58d1e5d04313816c2f1586a697ca33ebef1..65f3de5f304c077f4315e3d4d22f1c8144739b86 100644
--- a/src/plugins/debugger/analyzer/analyzerutils.h
+++ b/src/plugins/debugger/analyzer/analyzerutils.h
@@ -26,7 +26,7 @@
 #ifndef ANALYZERUTILS_H
 #define ANALYZERUTILS_H
 
-#include "analyzerbase_global.h"
+#include <debugger/debugger_global.h>
 
 #include <projectexplorer/task.h>
 
@@ -34,8 +34,8 @@ namespace CPlusPlus { class Symbol; }
 
 namespace AnalyzerUtils
 {
-    ANALYZER_EXPORT CPlusPlus::Symbol *findSymbolUnderCursor();
-    ANALYZER_EXPORT void logToIssuesPane(ProjectExplorer::Task::TaskType type,
+    DEBUGGER_EXPORT CPlusPlus::Symbol *findSymbolUnderCursor();
+    DEBUGGER_EXPORT void logToIssuesPane(ProjectExplorer::Task::TaskType type,
                                          const QString &message);
 }
 
diff --git a/src/plugins/debugger/analyzer/detailederrorview.cpp b/src/plugins/debugger/analyzer/detailederrorview.cpp
index c539102c4f1120944e54523ede50b246fec7dec5..7a47e40857605c59d21d7f6771cae24f98eeb949 100644
--- a/src/plugins/debugger/analyzer/detailederrorview.cpp
+++ b/src/plugins/debugger/analyzer/detailederrorview.cpp
@@ -44,7 +44,7 @@
 #include <QSharedPointer>
 #include <QTextDocument>
 
-namespace Analyzer {
+namespace Debugger {
 namespace Internal {
 
 class DetailedErrorDelegate : public QStyledItemDelegate
@@ -138,8 +138,7 @@ DetailedErrorView::DetailedErrorView(QWidget *parent) :
     });
     connect(this, &QAbstractItemView::clicked, [](const QModelIndex &index) {
         if (index.column() == LocationColumn) {
-            const auto loc = index.model()
-                    ->data(index, Analyzer::DetailedErrorView::LocationRole)
+            const auto loc = index.model()->data(index, DetailedErrorView::LocationRole)
                     .value<DiagnosticLocation>();
             if (loc.isValid())
                 Core::EditorManager::openEditorAt(loc.filePath, loc.line, loc.column - 1);
@@ -212,6 +211,6 @@ void DetailedErrorView::setCurrentRow(int row)
     scrollTo(index);
 }
 
-} // namespace Analyzer
+} // namespace Debugger
 
 #include "detailederrorview.moc"
diff --git a/src/plugins/debugger/analyzer/detailederrorview.h b/src/plugins/debugger/analyzer/detailederrorview.h
index 485e082e08e9aedc1c151ceffa660c42d00c3ecd..ab141ad57ecfb3bcc0cc4f1756a25b248ce08399 100644
--- a/src/plugins/debugger/analyzer/detailederrorview.h
+++ b/src/plugins/debugger/analyzer/detailederrorview.h
@@ -26,14 +26,14 @@
 #ifndef DETAILEDERRORVIEW_H
 #define DETAILEDERRORVIEW_H
 
-#include "analyzerbase_global.h"
+#include <debugger/debugger_global.h>
 
 #include <QTreeView>
 #include <QStyledItemDelegate>
 
-namespace Analyzer {
+namespace Debugger {
 
-class ANALYZER_EXPORT DetailedErrorView : public QTreeView
+class DEBUGGER_EXPORT DetailedErrorView : public QTreeView
 {
     Q_OBJECT
 
@@ -67,6 +67,6 @@ private:
     QAction * const m_copyAction;
 };
 
-} // namespace Analyzer
+} // namespace Debugger
 
 #endif // DETAILEDERRORVIEW_H
diff --git a/src/plugins/debugger/analyzer/diagnosticlocation.cpp b/src/plugins/debugger/analyzer/diagnosticlocation.cpp
index 7fa15f83c8412b15ba683f3b6cd302719693ad0c..e5f6c8ee4957908b9c176be5aca7d0ef34305d28 100644
--- a/src/plugins/debugger/analyzer/diagnosticlocation.cpp
+++ b/src/plugins/debugger/analyzer/diagnosticlocation.cpp
@@ -25,7 +25,7 @@
 
 #include "diagnosticlocation.h"
 
-namespace Analyzer {
+namespace Debugger {
 
 DiagnosticLocation::DiagnosticLocation() : line(0), column(0)
 {
@@ -56,5 +56,5 @@ QDebug operator<<(QDebug dbg, const DiagnosticLocation &location)
     return dbg.space();
 }
 
-} // namespace Analyzer
+} // namespace Debugger
 
diff --git a/src/plugins/debugger/analyzer/diagnosticlocation.h b/src/plugins/debugger/analyzer/diagnosticlocation.h
index 497698413dd22a2ca6c85836905169ccdca8b67b..61fdbe2298875460078f6225b3b58da986269a2f 100644
--- a/src/plugins/debugger/analyzer/diagnosticlocation.h
+++ b/src/plugins/debugger/analyzer/diagnosticlocation.h
@@ -26,15 +26,15 @@
 #ifndef ANALYZERDIAGNOSTIC_H
 #define ANALYZERDIAGNOSTIC_H
 
-#include "analyzerbase_global.h"
+#include <debugger/debugger_global.h>
 
 #include <QDebug>
 #include <QMetaType>
 #include <QString>
 
-namespace Analyzer {
+namespace Debugger {
 
-class ANALYZER_EXPORT DiagnosticLocation
+class DEBUGGER_EXPORT DiagnosticLocation
 {
 public:
     DiagnosticLocation();
@@ -49,12 +49,12 @@ public:
     int column;
 };
 
-ANALYZER_EXPORT bool operator==(const DiagnosticLocation &first, const DiagnosticLocation &second);
-ANALYZER_EXPORT QDebug operator<<(QDebug dbg, const DiagnosticLocation &location);
+DEBUGGER_EXPORT bool operator==(const DiagnosticLocation &first, const DiagnosticLocation &second);
+DEBUGGER_EXPORT QDebug operator<<(QDebug dbg, const DiagnosticLocation &location);
 
-} // namespace Analyzer
+} // namespace Debugger
 
-Q_DECLARE_METATYPE(Analyzer::DiagnosticLocation)
+Q_DECLARE_METATYPE(Debugger::DiagnosticLocation)
 
 #endif // Include guard.
 
diff --git a/src/plugins/debugger/analyzer/startremotedialog.cpp b/src/plugins/debugger/analyzer/startremotedialog.cpp
index 79c37c390ff39f52ea3f1353cb799d0ad1f788f5..8616ab2f782f33c7169c63d1e3a7c18dc345c09b 100644
--- a/src/plugins/debugger/analyzer/startremotedialog.cpp
+++ b/src/plugins/debugger/analyzer/startremotedialog.cpp
@@ -41,7 +41,7 @@
 using namespace ProjectExplorer;
 using namespace Utils;
 
-namespace Analyzer {
+namespace Debugger {
 namespace Internal {
 
 class StartRemoteDialogPrivate
@@ -146,4 +146,4 @@ StandardRunnable StartRemoteDialog::runnable() const
     return r;
 }
 
-} // namespace Analyzer
+} // namespace Debugger
diff --git a/src/plugins/debugger/analyzer/startremotedialog.h b/src/plugins/debugger/analyzer/startremotedialog.h
index f6694d08efcbdabf0b39723282ffa84c308e6a9f..ff559a51bf0112fe2a0e0d5b86b9593eb34427a7 100644
--- a/src/plugins/debugger/analyzer/startremotedialog.h
+++ b/src/plugins/debugger/analyzer/startremotedialog.h
@@ -26,7 +26,7 @@
 #ifndef STARTREMOTEDIALOG_H
 #define STARTREMOTEDIALOG_H
 
-#include "analyzerbase_global.h"
+#include <debugger/debugger_global.h>
 
 #include <QDialog>
 
@@ -34,29 +34,28 @@ namespace QSsh { class SshConnectionParameters; }
 
 namespace ProjectExplorer { class StandardRunnable; }
 
-namespace Analyzer {
+namespace Debugger {
 
 namespace Internal { class StartRemoteDialogPrivate; }
 
-class ANALYZER_EXPORT StartRemoteDialog : public QDialog
+class DEBUGGER_EXPORT StartRemoteDialog : public QDialog
 {
     Q_OBJECT
 
 public:
     explicit StartRemoteDialog(QWidget *parent = 0);
-    ~StartRemoteDialog();
+    ~StartRemoteDialog() override;
 
     QSsh::SshConnectionParameters sshParams() const;
     ProjectExplorer::StandardRunnable runnable() const;
 
-private slots:
+private:
     void validate();
-    virtual void accept();
+    void accept() override;
 
-private:
     Internal::StartRemoteDialogPrivate *d;
 };
 
-} // namespace Analyzer
+} // namespace Debugger
 
 #endif // STARTREMOTEDIALOG_H
diff --git a/src/plugins/debugger/cdb/cdbengine.cpp b/src/plugins/debugger/cdb/cdbengine.cpp
index f9317178bb1569ee6462ec3fd8ab61db9a07e6b4..c323cf6cb71ccc5b46edffb82166f87c48a9b73f 100644
--- a/src/plugins/debugger/cdb/cdbengine.cpp
+++ b/src/plugins/debugger/cdb/cdbengine.cpp
@@ -32,6 +32,7 @@
 #include <debugger/breakhandler.h>
 #include <debugger/debuggeractions.h>
 #include <debugger/debuggercore.h>
+#include <debugger/debuggerinternalconstants.h>
 #include <debugger/debuggerprotocol.h>
 #include <debugger/debuggermainwindow.h>
 #include <debugger/debuggerstartparameters.h>
diff --git a/src/plugins/debugger/debugger.qbs b/src/plugins/debugger/debugger.qbs
index 9a927632f1f5e3ef2727a1e0d34c0946c112a8b9..df08a58de4d27a470cc97fa41cb4500d8b28ed65 100644
--- a/src/plugins/debugger/debugger.qbs
+++ b/src/plugins/debugger/debugger.qbs
@@ -234,10 +234,8 @@ QtcPlugin {
 
         files: [
             "analyzer/analyzerbase.qrc",
-            "analyzer/analyzerbase_global.h",
             "analyzer/analyzerconstants.h",
             "analyzer/analyzericons.h",
-            "analyzer/analyzermanager.cpp",
             "analyzer/analyzermanager.h",
             "analyzer/analyzerrunconfigwidget.cpp",
             "analyzer/analyzerrunconfigwidget.h",
diff --git a/src/plugins/debugger/debuggerconstants.h b/src/plugins/debugger/debuggerconstants.h
index b5966c352096ff99b9543a56251aa2230d7a0a78..5964860883edca80544122b828cfecdfff09718b 100644
--- a/src/plugins/debugger/debuggerconstants.h
+++ b/src/plugins/debugger/debuggerconstants.h
@@ -39,6 +39,9 @@ const char C_DEBUGMODE[]            = "Debugger.DebugMode";
 const char C_CPPDEBUGGER[]          = "Gdb Debugger";
 const char C_QMLDEBUGGER[]          = "Qml/JavaScript Debugger";
 
+const char CppPerspectiveId[]       = "Debugger.Perspective.Cpp";
+const char QmlPerspectiveId[]       = "Debugger.Perspective.Qml";
+
 // Menu Groups
 const char G_GENERAL[]              = "Debugger.Group.General";
 const char G_SPECIAL[]              = "Debugger.Group.Special";
diff --git a/src/plugins/debugger/debuggercore.h b/src/plugins/debugger/debuggercore.h
index 7431f4cab5803dace14ecc4af221a2325e069c9b..023278d4271bcaa65f59decb58876340d4baf354 100644
--- a/src/plugins/debugger/debuggercore.h
+++ b/src/plugins/debugger/debuggercore.h
@@ -74,7 +74,6 @@ bool isReverseDebugging();
 void runControlStarted(DebuggerEngine *engine);
 void runControlFinished(DebuggerEngine *engine);
 void displayDebugger(DebuggerEngine *engine, bool updateEngine);
-DebuggerLanguages activeLanguages();
 void synchronizeBreakpoints();
 
 QWidget *mainWindow();
diff --git a/src/plugins/debugger/debuggerinternalconstants.h b/src/plugins/debugger/debuggerinternalconstants.h
index 89afc314f66c85fe85eeb141efe4efc179ab77e7..3b9f65977ce320bd30a9742ae4db7ca96a1c8a92 100644
--- a/src/plugins/debugger/debuggerinternalconstants.h
+++ b/src/plugins/debugger/debuggerinternalconstants.h
@@ -29,6 +29,21 @@
 #include <QtGlobal>
 
 namespace Debugger {
+namespace Internal {
+
+// DebuggerMainWindow dock widget names
+const char DOCKWIDGET_BREAK[]         = "Debugger.Docks.Break";
+const char DOCKWIDGET_MODULES[]       = "Debugger.Docks.Modules";
+const char DOCKWIDGET_REGISTER[]      = "Debugger.Docks.Register";
+const char DOCKWIDGET_OUTPUT[]        = "Debugger.Docks.Output";
+const char DOCKWIDGET_SNAPSHOTS[]     = "Debugger.Docks.Snapshots";
+const char DOCKWIDGET_STACK[]         = "Debugger.Docks.Stack";
+const char DOCKWIDGET_SOURCE_FILES[]  = "Debugger.Docks.SourceFiles";
+const char DOCKWIDGET_THREADS[]       = "Debugger.Docks.Threads";
+const char DOCKWIDGET_WATCHERS[]      = "Debugger.Docks.LocalsAndWatchers";
+
+} // namespace Internal
+
 namespace Constants {
 
 const char DEBUGGER_COMMON_SETTINGS_ID[]   = "A.Debugger.General";
diff --git a/src/plugins/debugger/debuggermainwindow.cpp b/src/plugins/debugger/debuggermainwindow.cpp
index dbcfe449ae8c2cee234d6e03dc70d765265f77fd..b0970d70c8bba77a4a1a6f67d7cd52bd15088d7a 100644
--- a/src/plugins/debugger/debuggermainwindow.cpp
+++ b/src/plugins/debugger/debuggermainwindow.cpp
@@ -24,37 +24,65 @@
 ****************************************************************************/
 
 #include "debuggermainwindow.h"
+#include "debuggerconstants.h"
+#include "debuggerinternalconstants.h"
+#include "analyzer/analyzericons.h"
 
+#include <coreplugin/actionmanager/actioncontainer.h>
+#include <coreplugin/actionmanager/actionmanager.h>
+#include <coreplugin/actionmanager/command.h>
+#include <coreplugin/coreconstants.h>
 #include <coreplugin/icore.h>
 
+#include <projectexplorer/projectexplorericons.h>
+
+#include <utils/styledbar.h>
 #include <utils/qtcassert.h>
 
+#include <QAction>
 #include <QComboBox>
 #include <QDockWidget>
+#include <QHBoxLayout>
+#include <QMenu>
 #include <QStackedWidget>
+#include <QToolButton>
 
-using namespace Analyzer;
+using namespace Debugger;
 using namespace Core;
-using namespace Utils;
 
-namespace Debugger {
-namespace Internal {
+namespace Utils {
+
+const char LAST_PERSPECTIVE_KEY[]   = "LastPerspective";
 
-MainWindowBase::MainWindowBase()
+DebuggerMainWindow::DebuggerMainWindow()
 {
     m_controlsStackWidget = new QStackedWidget;
     m_statusLabel = new Utils::StatusLabel;
-    m_toolBox = new QComboBox;
+
+    m_perspectiveChooser = new QComboBox;
+    m_perspectiveChooser->setObjectName(QLatin1String("PerspectiveChooser"));
+    connect(m_perspectiveChooser, static_cast<void (QComboBox::*)(int)>(&QComboBox::activated),
+            this, [this](int item) { restorePerspective(m_perspectiveChooser->itemData(item).toByteArray()); });
 
     setDockNestingEnabled(true);
     setDockActionsVisible(false);
     setDocumentMode(true);
 
     connect(this, &FancyMainWindow::resetLayout,
-            this, &MainWindowBase::resetCurrentPerspective);
+            this, &DebuggerMainWindow::resetCurrentPerspective);
+
+    auto dock = new QDockWidget(tr("Toolbar"));
+    dock->setObjectName(QLatin1String("Toolbar"));
+    dock->setFeatures(QDockWidget::NoDockWidgetFeatures);
+    dock->setAllowedAreas(Qt::BottomDockWidgetArea);
+    dock->setTitleBarWidget(new QWidget(dock)); // hide title bar
+    dock->setProperty("managed_dockwidget", QLatin1String("true"));
+
+    addDockWidget(Qt::BottomDockWidgetArea, dock);
+    setToolBarDockWidget(dock);
 }
 
-MainWindowBase::~MainWindowBase()
+DebuggerMainWindow::~DebuggerMainWindow()
 {
     // as we have to setParent(0) on dock widget that are not selected,
     // we keep track of all and make sure we don't leak any
@@ -64,64 +92,155 @@ MainWindowBase::~MainWindowBase()
     }
 }
 
-void MainWindowBase::registerPerspective(Id perspectiveId, const Perspective &perspective)
+void DebuggerMainWindow::registerPerspective(const QByteArray &perspectiveId, const Perspective &perspective)
 {
     m_perspectiveForPerspectiveId.insert(perspectiveId, perspective);
+    m_perspectiveChooser->addItem(perspective.name(), perspectiveId);
 }
 
-void MainWindowBase::registerToolbar(Id perspectiveId, QWidget *widget)
+void DebuggerMainWindow::registerToolbar(const QByteArray &perspectiveId, QWidget *widget)
 {
     m_toolbarForPerspectiveId.insert(perspectiveId, widget);
     m_controlsStackWidget->addWidget(widget);
 }
 
-void MainWindowBase::showStatusMessage(const QString &message, int timeoutMS)
+void DebuggerMainWindow::showStatusMessage(const QString &message, int timeoutMS)
 {
     m_statusLabel->showStatusMessage(message, timeoutMS);
 }
 
-void MainWindowBase::resetCurrentPerspective()
+QDockWidget *DebuggerMainWindow::dockWidget(const QByteArray &dockId) const
+{
+   return m_dockForDockId.value(dockId);
+}
+
+void DebuggerMainWindow::resetCurrentPerspective()
 {
     loadPerspectiveHelper(m_currentPerspectiveId, false);
 }
 
-void MainWindowBase::restorePerspective(Id perspectiveId)
+void DebuggerMainWindow::restorePerspective(const QByteArray &perspectiveId)
 {
     loadPerspectiveHelper(perspectiveId, true);
+
+    int index = m_perspectiveChooser->findData(perspectiveId);
+    if (index == -1)
+        index = m_perspectiveChooser->findData(m_currentPerspectiveId);
+    if (index != -1)
+        m_perspectiveChooser->setCurrentIndex(index);
 }
 
-void MainWindowBase::loadPerspectiveHelper(Id perspectiveId, bool fromStoredSettings)
+void DebuggerMainWindow::finalizeSetup()
 {
-    QTC_ASSERT(perspectiveId.isValid(), return);
+    auto viewButton = new QToolButton;
+    viewButton->setText(tr("Views"));
+
+    auto toolbar = new Utils::StyledBar;
+    toolbar->setProperty("topBorder", true);
+    auto hbox = new QHBoxLayout(toolbar);
+    hbox->setMargin(0);
+    hbox->setSpacing(0);
+    hbox->addWidget(m_perspectiveChooser);
+    hbox->addWidget(m_controlsStackWidget);
+    hbox->addWidget(m_statusLabel);
+    hbox->addWidget(new Utils::StyledSeparator);
+    hbox->addStretch();
+    hbox->addWidget(viewButton);
+
+    connect(viewButton, &QAbstractButton::clicked, [this, viewButton] {
+        QMenu menu;
+        addDockActionsToMenu(&menu);
+        menu.exec(viewButton->mapToGlobal(QPoint()));
+    });
+
+    toolBarDockWidget()->setWidget(toolbar);
 
+    Context debugcontext(Debugger::Constants::C_DEBUGMODE);
+
+    ActionContainer *viewsMenu = ActionManager::actionContainer(Core::Constants::M_WINDOW_VIEWS);
+    Command *cmd = ActionManager::registerAction(menuSeparator1(),
+        "Debugger.Views.Separator1", debugcontext);
+    cmd->setAttribute(Command::CA_Hide);
+    viewsMenu->addAction(cmd, Core::Constants::G_DEFAULT_THREE);
+    cmd = ActionManager::registerAction(autoHideTitleBarsAction(),
+        "Debugger.Views.AutoHideTitleBars", debugcontext);
+    cmd->setAttribute(Command::CA_Hide);
+    viewsMenu->addAction(cmd, Core::Constants::G_DEFAULT_THREE);
+    cmd = ActionManager::registerAction(menuSeparator2(),
+        "Debugger.Views.Separator2", debugcontext);
+    cmd->setAttribute(Command::CA_Hide);
+    viewsMenu->addAction(cmd, Core::Constants::G_DEFAULT_THREE);
+    cmd = ActionManager::registerAction(resetLayoutAction(),
+        "Debugger.Views.ResetSimple", debugcontext);
+    cmd->setAttribute(Command::CA_Hide);
+    viewsMenu->addAction(cmd, Core::Constants::G_DEFAULT_THREE);
+
+    addDockActionsToMenu(viewsMenu->menu());
+}
+
+void DebuggerMainWindow::loadPerspectiveHelper(const QByteArray &perspectiveId, bool fromStoredSettings)
+{
     // Clean up old perspective.
-    closeCurrentPerspective();
+    if (!m_currentPerspectiveId.isEmpty()) {
+        saveCurrentPerspective();
+        foreach (QDockWidget *dockWidget, m_dockForDockId) {
+            QTC_ASSERT(dockWidget, continue);
+            removeDockWidget(dockWidget);
+            dockWidget->hide();
+            // Prevent saveState storing the data of the wrong children.
+            dockWidget->setParent(0);
+        }
+
+        ICore::removeAdditionalContext(Context(Id::fromName(m_currentPerspectiveId)));
+    }
 
     m_currentPerspectiveId = perspectiveId;
 
-    QTC_ASSERT(m_perspectiveForPerspectiveId.contains(perspectiveId), return);
-    const auto operations = m_perspectiveForPerspectiveId.value(perspectiveId).operations();
+    if (m_currentPerspectiveId.isEmpty()) {
+        const QSettings *settings = ICore::settings();
+        m_currentPerspectiveId = settings->value(QLatin1String(LAST_PERSPECTIVE_KEY)).toByteArray();
+        if (m_currentPerspectiveId.isEmpty())
+            m_currentPerspectiveId = Debugger::Constants::CppPerspectiveId;
+    }
+
+    ICore::addAdditionalContext(Context(Id::fromName(m_currentPerspectiveId)));
+
+    QTC_ASSERT(m_perspectiveForPerspectiveId.contains(m_currentPerspectiveId), return);
+    const auto operations = m_perspectiveForPerspectiveId.value(m_currentPerspectiveId).operations();
     for (const Perspective::Operation &operation : operations) {
         QDockWidget *dock = m_dockForDockId.value(operation.dockId);
-        QTC_ASSERT(dock, continue);
+        if (!dock) {
+            QTC_CHECK(!operation.widget->objectName().isEmpty());
+            dock = registerDockWidget(operation.dockId, operation.widget);
+
+            QAction *toggleViewAction = dock->toggleViewAction();
+            toggleViewAction->setText(dock->windowTitle());
+
+            Command *cmd = ActionManager::registerAction(toggleViewAction,
+                Id("Dock.").withSuffix(dock->objectName()),
+                Context(Id::fromName(m_currentPerspectiveId)));
+            cmd->setAttribute(Command::CA_Hide);
+
+            ActionManager::actionContainer(Core::Constants::M_WINDOW_VIEWS)->addAction(cmd);
+        }
         if (operation.operationType == Perspective::Raise) {
             dock->raise();
             continue;
         }
         addDockWidget(operation.area, dock);
-        QDockWidget *existing = m_dockForDockId.value(operation.existing);
-        if (!existing && operation.area == Qt::BottomDockWidgetArea)
-            existing = toolBarDockWidget();
-        if (existing) {
+        QDockWidget *anchor = m_dockForDockId.value(operation.anchorDockId);
+        if (!anchor && operation.area == Qt::BottomDockWidgetArea)
+            anchor = toolBarDockWidget();
+        if (anchor) {
             switch (operation.operationType) {
             case Perspective::AddToTab:
-                tabifyDockWidget(existing, dock);
+                tabifyDockWidget(anchor, dock);
                 break;
             case Perspective::SplitHorizontal:
-                splitDockWidget(existing, dock, Qt::Horizontal);
+                splitDockWidget(anchor, dock, Qt::Horizontal);
                 break;
             case Perspective::SplitVertical:
-                splitDockWidget(existing, dock, Qt::Vertical);
+                splitDockWidget(anchor, dock, Qt::Vertical);
                 break;
             default:
                 break;
@@ -135,66 +254,84 @@ void MainWindowBase::loadPerspectiveHelper(Id perspectiveId, bool fromStoredSett
 
     if (fromStoredSettings) {
         QSettings *settings = ICore::settings();
-        settings->beginGroup(perspectiveId.toString());
+        settings->beginGroup(QString::fromLatin1(m_currentPerspectiveId));
         if (settings->value(QLatin1String("ToolSettingsSaved"), false).toBool())
             restoreSettings(settings);
         settings->endGroup();
     }
 
-    QTC_CHECK(m_toolbarForPerspectiveId.contains(perspectiveId));
-    m_controlsStackWidget->setCurrentWidget(m_toolbarForPerspectiveId.value(perspectiveId));
-}
-
-void MainWindowBase::closeCurrentPerspective()
-{
-    if (!m_currentPerspectiveId.isValid())
-        return;
-
-    saveCurrentPerspective();
-    foreach (QDockWidget *dockWidget, m_dockForDockId) {
-        QTC_ASSERT(dockWidget, continue);
-        removeDockWidget(dockWidget);
-        dockWidget->hide();
-        // Prevent saveState storing the data of the wrong children.
-        dockWidget->setParent(0);
-    }
+    QTC_CHECK(m_toolbarForPerspectiveId.contains(m_currentPerspectiveId));
+    m_controlsStackWidget->setCurrentWidget(m_toolbarForPerspectiveId.value(m_currentPerspectiveId));
+    m_statusLabel->clear();
 }
 
-void MainWindowBase::saveCurrentPerspective()
+void DebuggerMainWindow::saveCurrentPerspective()
 {
-    if (!m_currentPerspectiveId.isValid())
+    if (m_currentPerspectiveId.isEmpty())
         return;
     QSettings *settings = ICore::settings();
-    settings->beginGroup(m_currentPerspectiveId.toString());
+    settings->beginGroup(QString::fromLatin1(m_currentPerspectiveId));
     saveSettings(settings);
     settings->setValue(QLatin1String("ToolSettingsSaved"), true);
     settings->endGroup();
-    settings->setValue(m_lastSettingsName, m_currentPerspectiveId.toString());
+    settings->setValue(QLatin1String(LAST_PERSPECTIVE_KEY), m_currentPerspectiveId);
 }
 
-QDockWidget *MainWindowBase::registerDockWidget(Id dockId, QWidget *widget)
+QDockWidget *DebuggerMainWindow::registerDockWidget(const QByteArray &dockId, QWidget *widget)
 {
     QTC_ASSERT(!widget->objectName().isEmpty(), return 0);
     QDockWidget *dockWidget = addDockForWidget(widget);
-    m_dockWidgets.append(MainWindowBase::DockPtr(dockWidget));
+    dockWidget->setParent(0);
+    m_dockWidgets.append(DebuggerMainWindow::DockPtr(dockWidget));
     m_dockForDockId[dockId] = dockWidget;
     return dockWidget;
 }
 
-Core::Id MainWindowBase::currentPerspectiveId() const
+QString Perspective::name() const
 {
-    return m_currentPerspectiveId;
+    return m_name;
 }
 
-QString MainWindowBase::lastSettingsName() const
+void Perspective::setName(const QString &name)
+{
+    m_name = name;
+}
+
+QList<QWidget *> ToolbarDescription::widgets() const
+{
+    return m_widgets;
+}
+
+void ToolbarDescription::addAction(QAction *action)
+{
+    auto button = new QToolButton;
+    button->setDefaultAction(action);
+    m_widgets.append(button);
+}
+
+void ToolbarDescription::addWidget(QWidget *widget)
+{
+    m_widgets.append(widget);
+}
+
+Perspective::Operation::Operation(const QByteArray &dockId, QWidget *widget, const QByteArray &anchorDockId,
+                                  Perspective::OperationType splitType, bool visibleByDefault,
+                                  Qt::DockWidgetArea area)
+    : dockId(dockId), widget(widget), anchorDockId(anchorDockId),
+      operationType(splitType), visibleByDefault(visibleByDefault), area(area)
+{}
+
+Perspective::Perspective(const QString &name, const QVector<Operation> &splits)
+    : m_name(name), m_operations(splits)
 {
-    return m_lastSettingsName;
+    for (const Operation &split : splits)
+        m_docks.append(split.dockId);
 }
 
-void MainWindowBase::setLastSettingsName(const QString &lastSettingsName)
+void Perspective::addOperation(const Operation &operation)
 {
-    m_lastSettingsName = lastSettingsName;
+    m_docks.append(operation.dockId);
+    m_operations.append(operation);
 }
 
-} // Internal
-} // Debugger
+} // Utils
diff --git a/src/plugins/debugger/debuggermainwindow.h b/src/plugins/debugger/debuggermainwindow.h
index 3f12344c84af0f9df892b7254a0cb7ef38c10e0b..b1aeb1633970778bb32fea0f9689c3317ade85d3 100644
--- a/src/plugins/debugger/debuggermainwindow.h
+++ b/src/plugins/debugger/debuggermainwindow.h
@@ -27,9 +27,6 @@
 #define DEBUGGERMAINWINDOW_H
 
 #include "debugger_global.h"
-#include "analyzer/analyzerbase_global.h"
-
-#include <coreplugin/id.h>
 
 #include <utils/fancymainwindow.h>
 #include <utils/statuslabel.h>
@@ -38,113 +35,108 @@
 #include <QSet>
 
 #include <functional>
-#include <initializer_list>
 
 QT_BEGIN_NAMESPACE
 class QComboBox;
 class QStackedWidget;
 QT_END_NAMESPACE
 
-namespace Analyzer {
+namespace Utils {
 
-class ANALYZER_EXPORT Perspective
+class DEBUGGER_EXPORT Perspective
 {
 public:
     enum OperationType { SplitVertical, SplitHorizontal, AddToTab, Raise };
 
-    class ANALYZER_EXPORT Operation
+    class DEBUGGER_EXPORT Operation
     {
     public:
         Operation() = default;
-        Operation(Core::Id dockId, Core::Id existing, OperationType operationType,
-              bool visibleByDefault = true,
-              Qt::DockWidgetArea area = Qt::BottomDockWidgetArea);
-
-        Core::Id dockId;
-        Core::Id existing;
+        Operation(const QByteArray &dockId, QWidget *widget,
+                  const QByteArray &anchorDockId,
+                  OperationType operationType,
+                  bool visibleByDefault = true,
+                  Qt::DockWidgetArea area = Qt::BottomDockWidgetArea);
+
+        QByteArray dockId;
+        QWidget *widget = 0;
+        QByteArray anchorDockId;
         OperationType operationType;
         bool visibleByDefault;
         Qt::DockWidgetArea area;
     };
 
     Perspective() = default;
-    Perspective(std::initializer_list<Operation> operations);
+    Perspective(const QString &name, const QVector<Operation> &operations);
 
     void addOperation(const Operation &operation);
 
     QVector<Operation> operations() const { return m_operations; }
-    QVector<Core::Id> docks() const { return m_docks; }
+    QVector<QByteArray> docks() const { return m_docks; }
+
+    QString name() const;
+    void setName(const QString &name);
 
 private:
-    QVector<Core::Id> m_docks;
+    QString m_name;
+    QVector<QByteArray> m_docks;
     QVector<Operation> m_operations;
 };
 
-} // Analyzer
+class DEBUGGER_EXPORT ToolbarDescription
+{
+public:
+    ToolbarDescription() = default;
+    ToolbarDescription(const QList<QWidget *> &widgets) : m_widgets(widgets) {}
 
-namespace Debugger {
-namespace Internal {
+    QList<QWidget *> widgets() const;
 
-// DebuggerMainWindow dock widget names
-const char DOCKWIDGET_BREAK[]         = "Debugger.Docks.Break";
-const char DOCKWIDGET_MODULES[]       = "Debugger.Docks.Modules";
-const char DOCKWIDGET_REGISTER[]      = "Debugger.Docks.Register";
-const char DOCKWIDGET_OUTPUT[]        = "Debugger.Docks.Output";
-const char DOCKWIDGET_SNAPSHOTS[]     = "Debugger.Docks.Snapshots";
-const char DOCKWIDGET_STACK[]         = "Debugger.Docks.Stack";
-const char DOCKWIDGET_SOURCE_FILES[]  = "Debugger.Docks.SourceFiles";
-const char DOCKWIDGET_THREADS[]       = "Debugger.Docks.Threads";
-const char DOCKWIDGET_WATCHERS[]      = "Debugger.Docks.LocalsAndWatchers";
+    void addAction(QAction *action);
+    void addWidget(QWidget *widget);
 
-const char CppPerspectiveId[]         = "Debugger.Perspective.Cpp";
-const char QmlPerspectiveId[]         = "Debugger.Perspective.Qml";
+private:
+    QList<QWidget *> m_widgets;
+};
 
-class MainWindowBase : public Utils::FancyMainWindow
+class DebuggerMainWindow : public FancyMainWindow
 {
     Q_OBJECT
 
 public:
-    MainWindowBase();
-    ~MainWindowBase() override;
-
-    QComboBox *toolBox() const { return m_toolBox; }
-    QStackedWidget *controlsStack() const { return m_controlsStackWidget; }
-    Utils::StatusLabel *statusLabel() const { return m_statusLabel; }
+    DebuggerMainWindow();
+    ~DebuggerMainWindow() override;
 
-    void registerPerspective(Core::Id perspectiveId, const Analyzer::Perspective &perspective);
-    void registerToolbar(Core::Id perspectiveId, QWidget *widget);
-    QDockWidget *registerDockWidget(Core::Id dockId, QWidget *widget);
+    void registerPerspective(const QByteArray &perspectiveId, const Perspective &perspective);
+    void registerToolbar(const QByteArray &perspectiveId, QWidget *widget);
 
     void saveCurrentPerspective();
-    void closeCurrentPerspective();
     void resetCurrentPerspective();
-    void restorePerspective(Core::Id perspectiveId);
-
-    void showStatusMessage(const QString &message, int timeoutMS);
+    void restorePerspective(const QByteArray &perspectiveId);
 
-    QString lastSettingsName() const;
-    void setLastSettingsName(const QString &lastSettingsName);
+    void finalizeSetup();
 
-    Core::Id currentPerspectiveId() const;
+    void showStatusMessage(const QString &message, int timeoutMS);
+    QDockWidget *dockWidget(const QByteArray &dockId) const;
+    QByteArray currentPerspective() const { return m_currentPerspectiveId; }
 
 private:
-    void loadPerspectiveHelper(Core::Id perspectiveId, bool fromStoredSettings = true);
+    QDockWidget *registerDockWidget(const QByteArray &dockId, QWidget *widget);
+    void loadPerspectiveHelper(const QByteArray &perspectiveId, bool fromStoredSettings = true);
 
-    Core::Id m_currentPerspectiveId;
-    QString m_lastSettingsName;
-    QComboBox *m_toolBox;
+    QByteArray m_currentPerspectiveId;
+    QComboBox *m_perspectiveChooser;
     QStackedWidget *m_controlsStackWidget;
     Utils::StatusLabel *m_statusLabel;
-    QHash<Core::Id, QDockWidget *> m_dockForDockId;
-    QHash<Core::Id, QWidget *> m_toolbarForPerspectiveId;
-    QHash<Core::Id, Analyzer::Perspective> m_perspectiveForPerspectiveId;
+
+    QHash<QByteArray, QDockWidget *> m_dockForDockId;
+    QHash<QByteArray, QWidget *> m_toolbarForPerspectiveId;
+    QHash<QByteArray, Perspective> m_perspectiveForPerspectiveId;
 
     // list of dock widgets to prevent memory leak
     typedef QPointer<QDockWidget> DockPtr;
     QList<DockPtr> m_dockWidgets;
 };
 
-} // namespace Internal
-} // namespace Debugger
+} // Utils
 
 #endif // DEBUGGERMAINWINDOW_H
diff --git a/src/plugins/debugger/debuggerplugin.cpp b/src/plugins/debugger/debuggerplugin.cpp
index 78d24374b1ddc4ba7ed84cabd7330f3cb331bef0..090c2eff3e7b53af08e193c813e0ab4dc19b8d8d 100644
--- a/src/plugins/debugger/debuggerplugin.cpp
+++ b/src/plugins/debugger/debuggerplugin.cpp
@@ -71,7 +71,10 @@
 #include "gdb/startgdbserverdialog.h"
 
 #include "analyzer/analyzerconstants.h"
+#include "analyzer/analyzericons.h"
 #include "analyzer/analyzermanager.h"
+#include "analyzer/analyzerruncontrol.h"
+#include "analyzer/analyzerstartparameters.h"
 
 #include <coreplugin/actionmanager/actioncontainer.h>
 #include <coreplugin/actionmanager/actionmanager.h>
@@ -87,6 +90,7 @@
 #include <coreplugin/messagebox.h>
 #include <coreplugin/messagemanager.h>
 #include <coreplugin/modemanager.h>
+#include <coreplugin/modemanager.h>
 #include <coreplugin/navigationwidget.h>
 #include <coreplugin/outputpane.h>
 #include <coreplugin/rightpane.h>
@@ -96,21 +100,21 @@
 
 #include <extensionsystem/invoker.h>
 
+#include <projectexplorer/buildconfiguration.h>
 #include <projectexplorer/buildmanager.h>
-#include <projectexplorer/taskhub.h>
-#include <projectexplorer/toolchain.h>
-#include <projectexplorer/devicesupport/deviceprocesslist.h>
 #include <projectexplorer/devicesupport/deviceprocessesdialog.h>
+#include <projectexplorer/devicesupport/deviceprocesslist.h>
+#include <projectexplorer/project.h>
 #include <projectexplorer/projectexplorer.h>
 #include <projectexplorer/projectexplorericons.h>
-#include <projectexplorer/projecttree.h>
 #include <projectexplorer/projectexplorersettings.h>
-#include <projectexplorer/project.h>
+#include <projectexplorer/projecttree.h>
 #include <projectexplorer/runconfiguration.h>
 #include <projectexplorer/runnables.h>
 #include <projectexplorer/session.h>
-#include <projectexplorer/taskhub.h>
 #include <projectexplorer/target.h>
+#include <projectexplorer/taskhub.h>
+#include <projectexplorer/toolchain.h>
 
 #include <texteditor/texteditor.h>
 #include <texteditor/textdocument.h>
@@ -120,6 +124,7 @@
 #include <utils/algorithm.h>
 #include <utils/appmainwindow.h>
 #include <utils/basetreeview.h>
+#include <utils/checkablemessagebox.h>
 #include <utils/fancymainwindow.h>
 #include <utils/hostosinfo.h>
 #include <utils/mimetypes/mimedatabase.h>
@@ -128,7 +133,6 @@
 #include <utils/savedaction.h>
 #include <utils/statuslabel.h>
 #include <utils/styledbar.h>
-#include <utils/styledbar.h>
 #include <utils/winutils.h>
 
 #include <QAction>
@@ -136,21 +140,33 @@
 #include <QCheckBox>
 #include <QComboBox>
 #include <QDebug>
+#include <QDialog>
+#include <QDialogButtonBox>
 #include <QDockWidget>
 #include <QFileDialog>
 #include <QHBoxLayout>
 #include <QHeaderView>
 #include <QInputDialog>
 #include <QMenu>
-#include <QMenu>
 #include <QMessageBox>
+#include <QPointer>
+#include <QPushButton>
+#include <QSettings>
 #include <QStackedWidget>
 #include <QTextBlock>
 #include <QToolButton>
 #include <QTreeWidget>
 #include <QVBoxLayout>
+#include <QVariant>
 #include <QtPlugin>
 
+using namespace Core;
+using namespace Utils;
+using namespace Core::Constants;
+using namespace ProjectExplorer;
+using namespace Debugger;
+using namespace Debugger::Internal;
+
 #ifdef WITH_TESTS
 #include <QTest>
 #include <QSignalSpy>
@@ -405,13 +421,9 @@ using namespace ProjectExplorer;
 using namespace TextEditor;
 using namespace Utils;
 
-using namespace Analyzer;
-//using namespace Analyzer::Internal;
-
 namespace CC = Core::Constants;
 namespace PE = ProjectExplorer::Constants;
 
-
 namespace Debugger {
 namespace Internal {
 
@@ -425,36 +437,15 @@ struct TestCallBack
     QVariant cookie;
 };
 
-
-} // namespace Internal
-} // namespace Debugger
-
-Q_DECLARE_METATYPE(Debugger::Internal::TestCallBack)
-
-namespace Debugger {
-namespace Internal {
-
 void addCdbOptionPages(QList<IOptionsPage*> *opts);
 void addGdbOptionPages(QList<IOptionsPage*> *opts);
 QObject *createDebuggerRunControlFactory(QObject *parent);
 
-static QToolButton *toolButton(QAction *action)
-{
-    QToolButton *button = new QToolButton;
-    button->setDefaultAction(action);
-    return button;
-}
-
 static void setProxyAction(ProxyAction *proxy, Id id)
 {
     proxy->setAction(ActionManager::command(id)->action());
 }
 
-static QToolButton *toolButton(Id id)
-{
-    return toolButton(ActionManager::command(id)->action());
-}
-
 ///////////////////////////////////////////////////////////////////////
 //
 // DummyEngine
@@ -465,17 +456,17 @@ class DummyEngine : public DebuggerEngine
 {
 public:
     DummyEngine() : DebuggerEngine(DebuggerRunParameters()) {}
-    ~DummyEngine() {}
-
-    void setupEngine() {}
-    void setupInferior() {}
-    void runEngine() {}
-    void shutdownEngine() {}
-    void shutdownInferior() {}
-    bool hasCapability(unsigned cap) const;
-    bool acceptsBreakpoint(Breakpoint) const { return false; }
-    bool acceptsDebuggerCommands() const { return false; }
-    void selectThread(ThreadId) {}
+    ~DummyEngine() override {}
+
+    void setupEngine() override {}
+    void setupInferior() override {}
+    void runEngine() override {}
+    void shutdownEngine() override {}
+    void shutdownInferior() override {}
+    bool hasCapability(unsigned cap) const override;
+    bool acceptsBreakpoint(Breakpoint) const override { return false; }
+    bool acceptsDebuggerCommands() const override { return false; }
+    void selectThread(ThreadId) override {}
 };
 
 bool DummyEngine::hasCapability(unsigned cap) const
@@ -516,13 +507,15 @@ public:
         setDisplayName(DebuggerPlugin::tr("Debug"));
         setIcon(Utils::Icon::modeIcon(Icons::MODE_DEBUGGER_CLASSIC,
                                       Icons::MODE_DEBUGGER_FLAT, Icons::MODE_DEBUGGER_FLAT_ACTIVE));
+//        setIcon(Utils::Icon::modeIcon(Icons::MODE_ANALYZE_CLASSIC,
+//                                      Icons::MODE_ANALYZE_FLAT, Icons::MODE_ANALYZE_FLAT_ACTIVE));
         setPriority(85);
         setId(MODE_DEBUG);
     }
 
     ~DebugMode()
     {
-        delete m_widget;
+//        delete m_widget;
     }
 };
 
@@ -716,7 +709,6 @@ public:
     void toggleBreakpointHelper();
     void toggleBreakpoint(const ContextData &location, const QString &tracePointMessage = QString());
     void onModeChanged(IMode *mode);
-    void onCoreAboutToOpen();
     void updateDebugWithoutDeployMenu();
 
     void startAndDebugApplication();
@@ -778,7 +770,7 @@ public:
 
 #endif
 
-public slots:
+public:
     void updateDebugActions();
 
     void handleExecDetach()
@@ -962,45 +954,35 @@ public slots:
     bool parseArguments(const QStringList &args, QString *errorMessage);
     void parseCommandLineArguments();
 
-public:
-    // Active languages to be debugged.
-    DebuggerLanguages activeDebugLanguages() const;
+    // Ex-Analyzer
+    bool showPromptDialog(const QString &title, const QString &text,
+        const QString &stopButtonText, const QString &cancelButtonText) const;
+
+    void registerAction(Core::Id actionId, const ActionDescription &desc, QAction *startAction);
+    void selectPerspective(const QByteArray &perspectiveId);
 
     // Called when all dependent plugins have loaded.
     void initialize();
 
-    void onModeChangedHelper(Core::IMode *mode);
-
-    // Dockwidgets are registered to the main window.
-    QDockWidget *createDockWidget(Id dockId, QWidget *widget);
-    QWidget *createContents(Core::IMode *mode);
-
-    void readWindowSettings();
-    void writeWindowSettings() const;
-
-    void createViewsMenuItems();
-
-    QWidget *mainWindow() const { return m_mainWindow; }
-
     void updateUiForProject(ProjectExplorer::Project *project);
     void updateUiForTarget(ProjectExplorer::Target *target);
     void updateUiForRunConfiguration(ProjectExplorer::RunConfiguration *rc);
     void updateActiveLanguages();
 
 public:
-    MainWindowBase *m_mainWindow = 0;
+    DebuggerMainWindow *m_mainWindow = 0;
+
+    QHash<Id, QAction *> m_actions;
+    QHash<Id, ActionDescription> m_descriptions;
+    ActionContainer *m_menu = 0;
 
 //    DockWidgetEventFilter m_resizeEventFilter;
 
     QHash<DebuggerLanguage, Core::Context> m_contextsForLanguage;
 
-    bool m_inDebugMode = false;
-
-    Core::ActionContainer *m_viewsMenu = 0;
-
-    ProjectExplorer::Project *m_previousProject = 0;
-    ProjectExplorer::Target *m_previousTarget = 0;
-    ProjectExplorer::RunConfiguration *m_previousRunConfiguration = 0;
+    Project *m_previousProject = 0;
+    Target *m_previousTarget = 0;
+    QPointer<RunConfiguration> m_previousRunConfiguration;
 
     Id m_previousMode;
     QVector<QPair<DebuggerRunParameters, Kit *>> m_scheduledStarts;
@@ -1037,15 +1019,11 @@ public:
     QAction *m_frameUpAction = 0;
     QAction *m_frameDownAction = 0;
     QAction *m_resetAction = 0;
+    QAction *m_operateByInstructionAction = 0;
 
     QToolButton *m_reverseToolButton = 0;
 
-    QIcon m_startIcon;
-    QIcon m_exitIcon;
-    QIcon m_continueIcon;
-    QIcon m_interruptIcon;
     QIcon m_locationMarkIcon;
-    QIcon m_resetIcon;
 
     QComboBox *m_threadBox = 0;
 
@@ -1091,6 +1069,8 @@ public:
     CommonOptionsPage *m_commonOptionsPage = 0;
     DummyEngine *m_dummyEngine = 0;
     const QSharedPointer<GlobalDebuggerOptions> m_globalDebuggerOptions;
+
+    DebugMode *m_debugMode = 0;
 };
 
 DebuggerPluginPrivate::DebuggerPluginPrivate(DebuggerPlugin *plugin)
@@ -1112,10 +1092,6 @@ DebuggerPluginPrivate::DebuggerPluginPrivate(DebuggerPlugin *plugin)
 
 DebuggerPluginPrivate::~DebuggerPluginPrivate()
 {
-// Mainwindow will be deleted by debug mode.
-//    delete m_mainWindow;
-//    m_mainWindow = 0;
-
     delete m_debuggerSettings;
     m_debuggerSettings = 0;
 
@@ -1124,6 +1100,11 @@ DebuggerPluginPrivate::~DebuggerPluginPrivate()
 
     delete m_breakHandler;
     m_breakHandler = 0;
+
+//    delete m_debugMode;
+//    m_debugMode = 0;
+    delete m_mainWindow;
+    m_mainWindow = 0;
 }
 
 DebuggerEngine *DebuggerPluginPrivate::dummyEngine()
@@ -1270,10 +1251,37 @@ bool DebuggerPluginPrivate::initialize(const QStringList &arguments,
         connect(KitManager::instance(), &KitManager::kitsLoaded,
                 this, &DebuggerPluginPrivate::parseCommandLineArguments);
 
-    m_mainWindow = new MainWindowBase;
-    m_mainWindow->setObjectName(QLatin1String("DebuggerMainWindow"));
+    m_mainWindow = new DebuggerMainWindow;
+
+    // Menus
+    m_menu = ActionManager::createMenu(M_DEBUG_ANALYZER);
+    m_menu->menu()->setTitle(tr("&Analyze"));
+    m_menu->menu()->setEnabled(true);
+
+    m_menu->appendGroup(G_ANALYZER_CONTROL);
+    m_menu->appendGroup(G_ANALYZER_TOOLS);
+    m_menu->appendGroup(G_ANALYZER_REMOTE_TOOLS);
+    m_menu->appendGroup(G_ANALYZER_OPTIONS);
+
+    ActionContainer *menubar = ActionManager::actionContainer(MENU_BAR);
+    ActionContainer *mtools = ActionManager::actionContainer(M_TOOLS);
+    menubar->addMenu(mtools, m_menu);
+
+    m_menu->addSeparator(G_ANALYZER_TOOLS);
+    m_menu->addSeparator(G_ANALYZER_REMOTE_TOOLS);
+    m_menu->addSeparator(G_ANALYZER_OPTIONS);
+
+    // Populate Windows->Views menu with standard actions.
+    Context debugcontext(Constants::C_DEBUGMODE);
+
+    auto openMemoryEditorAction = new QAction(this);
+    openMemoryEditorAction->setText(DebuggerPluginPrivate::tr("Memory..."));
+    connect(openMemoryEditorAction, &QAction::triggered,
+            this, &Internal::openMemoryEditor);
 
-    createViewsMenuItems();
+    Command *cmd = ActionManager::registerAction(openMemoryEditorAction,
+        "Debugger.Views.OpenMemoryEditor", debugcontext);
+    cmd->setAttribute(Command::CA_Hide);
 
     m_plugin->addAutoReleasedObject(debuggerConsole());
 
@@ -1282,1741 +1290,1722 @@ bool DebuggerPluginPrivate::initialize(const QStringList &arguments,
     TaskHub::addCategory(TASK_CATEGORY_DEBUGGER_RUNTIME,
                          tr("Debugger Runtime"));
 
-    return true;
-}
-
-void setConfigValue(const QByteArray &name, const QVariant &value)
-{
-    ICore::settings()->setValue(_("DebugMode/" + name), value);
-}
+    const QKeySequence debugKey = QKeySequence(UseMacShortcuts ? tr("Ctrl+Y") : tr("F5"));
 
-QVariant configValue(const QByteArray &name)
-{
-    return ICore::settings()->value(_("DebugMode/" + name));
-}
+    QSettings *settings = ICore::settings();
 
-void DebuggerPluginPrivate::onCurrentProjectChanged(Project *project)
-{
-    RunConfiguration *activeRc = 0;
-    if (project) {
-        Target *target = project->activeTarget();
-        if (target)
-            activeRc = target->activeRunConfiguration();
-        if (!activeRc)
-            return;
-    }
-    for (int i = 0, n = m_snapshotHandler->size(); i != n; ++i) {
-        // Run controls might be deleted during exit.
-        if (DebuggerEngine *engine = m_snapshotHandler->at(i)) {
-            DebuggerRunControl *runControl = engine->runControl();
-            RunConfiguration *rc = runControl->runConfiguration();
-            if (rc == activeRc) {
-                m_snapshotHandler->setCurrentIndex(i);
-                updateState(engine);
-                return;
-            }
-        }
-    }
+    m_debuggerSettings = new DebuggerSettings;
+    m_debuggerSettings->readSettings();
 
-    // If we have a running debugger, don't touch it.
-    if (m_snapshotHandler->size())
-        return;
+    connect(ICore::instance(), &ICore::coreAboutToClose, this, &DebuggerPluginPrivate::coreShutdown);
 
-    // No corresponding debugger found. So we are ready to start one.
-    m_interruptAction->setEnabled(false);
-    m_continueAction->setEnabled(false);
-    m_exitAction->setEnabled(false);
-    QString whyNot;
-    const bool canRun = ProjectExplorerPlugin::canRun(project, ProjectExplorer::Constants::DEBUG_RUN_MODE, &whyNot);
-    m_startAction->setEnabled(canRun);
-    m_startAction->setToolTip(whyNot);
-    m_debugWithoutDeployAction->setEnabled(canRun);
-    setProxyAction(m_visibleStartAction, Id(Constants::DEBUG));
-}
+    const Context cppDebuggercontext(C_CPPDEBUGGER);
+    const Context cppeditorcontext(CppEditor::Constants::CPPEDITOR_ID);
 
-void DebuggerPluginPrivate::startAndDebugApplication()
-{
-    DebuggerRunParameters rp;
-    Kit *kit;
-    if (StartApplicationDialog::run(ICore::dialogParent(), &rp, &kit))
-        createAndScheduleRun(rp, kit);
-}
+    const QIcon continueSideBarIcon = Icon::sideBarIcon(Icons::CONTINUE, Icons::CONTINUE_FLAT);
+    const QIcon interruptSideBarIcon = Icon::sideBarIcon(Icons::INTERRUPT, Icons::INTERRUPT_FLAT);
+    m_locationMarkIcon = Icons::LOCATION.icon();
 
-void DebuggerPluginPrivate::attachCore()
-{
-    AttachCoreDialog dlg(ICore::dialogParent());
+    m_busy = false;
 
-    const QString lastExternalKit = configValue("LastExternalKit").toString();
-    if (!lastExternalKit.isEmpty())
-        dlg.setKitId(Id::fromString(lastExternalKit));
-    dlg.setLocalExecutableFile(configValue("LastExternalExecutableFile").toString());
-    dlg.setLocalCoreFile(configValue("LastLocalCoreFile").toString());
-    dlg.setRemoteCoreFile(configValue("LastRemoteCoreFile").toString());
-    dlg.setOverrideStartScript(configValue("LastExternalStartScript").toString());
-    dlg.setForceLocalCoreFile(configValue("LastForceLocalCoreFile").toBool());
+    m_logWindow = new LogWindow;
+    m_logWindow->setObjectName(QLatin1String(DOCKWIDGET_OUTPUT));
 
-    if (dlg.exec() != QDialog::Accepted)
-        return;
+    m_breakHandler = new BreakHandler;
+    m_breakView = new BreakTreeView;
+    m_breakView->setSettings(settings, "Debugger.BreakWindow");
+    m_breakView->setModel(m_breakHandler->model());
+    m_breakWindow = addSearch(m_breakView, tr("Breakpoints"), DOCKWIDGET_BREAK);
 
-    setConfigValue("LastExternalExecutableFile", dlg.localExecutableFile());
-    setConfigValue("LastLocalCoreFile", dlg.localCoreFile());
-    setConfigValue("LastRemoteCoreFile", dlg.remoteCoreFile());
-    setConfigValue("LastExternalKit", dlg.kit()->id().toSetting());
-    setConfigValue("LastExternalStartScript", dlg.overrideStartScript());
-    setConfigValue("LastForceLocalCoreFile", dlg.forcesLocalCoreFile());
+    m_modulesView = new ModulesTreeView;
+    m_modulesView->setSettings(settings, "Debugger.ModulesView");
+    m_modulesWindow = addSearch(m_modulesView, tr("Modules"), DOCKWIDGET_MODULES);
 
-    QString display = dlg.useLocalCoreFile() ? dlg.localCoreFile() : dlg.remoteCoreFile();
-    DebuggerRunParameters rp;
-    rp.masterEngineType = DebuggerKitInformation::engineType(dlg.kit());
-    rp.inferior.executable = dlg.localExecutableFile();
-    rp.coreFile = dlg.localCoreFile();
-    rp.displayName = tr("Core file \"%1\"").arg(display);
-    rp.startMode = AttachCore;
-    rp.closeMode = DetachAtClose;
-    rp.overrideStartScript = dlg.overrideStartScript();
-    createAndScheduleRun(rp, dlg.kit());
-}
+    m_registerView = new RegisterTreeView;
+    m_registerView->setSettings(settings, "Debugger.RegisterView");
+    m_registerWindow = addSearch(m_registerView, tr("Registers"), DOCKWIDGET_REGISTER);
 
-void DebuggerPluginPrivate::startRemoteCdbSession()
-{
-    const QByteArray connectionKey = "CdbRemoteConnection";
-    DebuggerRunParameters rp;
-    Kit *kit = findUniversalCdbKit();
-    QTC_ASSERT(kit, return);
-    rp.startMode = AttachToRemoteServer;
-    rp.closeMode = KillAtClose;
-    StartRemoteCdbDialog dlg(ICore::dialogParent());
-    QString previousConnection = configValue(connectionKey).toString();
-    if (previousConnection.isEmpty())
-        previousConnection = QLatin1String("localhost:1234");
-    dlg.setConnection(previousConnection);
-    if (dlg.exec() != QDialog::Accepted)
-        return;
-    rp.remoteChannel = dlg.connection();
-    setConfigValue(connectionKey, rp.remoteChannel);
-    createAndScheduleRun(rp, kit);
-}
+    m_stackView = new StackTreeView;
+    m_stackView->setSettings(settings, "Debugger.StackView");
+    m_stackWindow = addSearch(m_stackView, tr("Stack"), DOCKWIDGET_STACK);
 
-void DebuggerPluginPrivate::attachToRemoteServer()
-{
-    DebuggerRunParameters rp;
-    Kit *kit;
-    rp.startMode = AttachToRemoteServer;
-    if (StartApplicationDialog::run(ICore::dialogParent(), &rp, &kit)) {
-        rp.closeMode = KillAtClose;
-        createAndScheduleRun(rp, kit);
-    }
-}
+    m_sourceFilesView = new SourceFilesTreeView;
+    m_sourceFilesView->setSettings(settings, "Debugger.SourceFilesView");
+    m_sourceFilesWindow = addSearch(m_sourceFilesView, tr("Source Files"), DOCKWIDGET_SOURCE_FILES);
 
-void DebuggerPluginPrivate::startRemoteServerAndAttachToProcess()
-{
-    auto kitChooser = new DebuggerKitChooser(DebuggerKitChooser::AnyDebugging);
-    auto dlg = new DeviceProcessesDialog(kitChooser, ICore::dialogParent());
-    dlg->addAcceptButton(DeviceProcessesDialog::tr("&Attach to Process"));
-    dlg->showAllDevices();
-    if (dlg->exec() == QDialog::Rejected) {
-        delete dlg;
-        return;
-    }
+    m_threadsView = new ThreadsTreeView;
+    m_threadsView->setSettings(settings, "Debugger.ThreadsView");
+    m_threadsWindow = addSearch(m_threadsView, tr("Threads"), DOCKWIDGET_THREADS);
 
-    dlg->setAttribute(Qt::WA_DeleteOnClose);
-    Kit *kit = kitChooser->currentKit();
-    QTC_ASSERT(kit, return);
-    IDevice::ConstPtr device = DeviceKitInformation::device(kit);
-    QTC_ASSERT(device, return);
+    m_returnView = new WatchTreeView(ReturnType); // No settings.
+    m_returnWindow = addSearch(m_returnView, tr("Locals and Expressions"), "CppDebugReturn");
 
-    GdbServerStarter *starter = new GdbServerStarter(dlg, true);
-    starter->run();
-}
+    m_localsView = new WatchTreeView(LocalsType);
+    m_localsView->setSettings(settings, "Debugger.LocalsView");
+    m_localsWindow = addSearch(m_localsView, tr("Locals and Expressions"), "CppDebugLocals");
 
-void DebuggerPluginPrivate::attachToRunningApplication()
-{
-    auto kitChooser = new DebuggerKitChooser(DebuggerKitChooser::LocalDebugging);
+    m_watchersView = new WatchTreeView(WatchersType); // No settings.
+    m_watchersWindow = addSearch(m_watchersView, tr("Locals and Expressions"), "CppDebugWatchers");
 
-    auto dlg = new DeviceProcessesDialog(kitChooser, ICore::dialogParent());
-    dlg->addAcceptButton(DeviceProcessesDialog::tr("&Attach to Process"));
-    dlg->showAllDevices();
-    if (dlg->exec() == QDialog::Rejected) {
-        delete dlg;
-        return;
-    }
+    m_inspectorView = new WatchTreeView(InspectType);
+    m_inspectorView->setSettings(settings, "Debugger.LocalsView"); // sic! same as locals view.
+    m_inspectorWindow = addSearch(m_inspectorView, tr("Locals and Expressions"), "Inspector");
 
-    dlg->setAttribute(Qt::WA_DeleteOnClose);
-    Kit *kit = kitChooser->currentKit();
-    QTC_ASSERT(kit, return);
-    IDevice::ConstPtr device = DeviceKitInformation::device(kit);
-    QTC_ASSERT(device, return);
+    // Snapshot
+    m_snapshotHandler = new SnapshotHandler;
+    m_snapshotView = new SnapshotTreeView(m_snapshotHandler);
+    m_snapshotView->setSettings(settings, "Debugger.SnapshotView");
+    m_snapshotView->setModel(m_snapshotHandler->model());
+    m_snapshotWindow = addSearch(m_snapshotView, tr("Snapshots"), DOCKWIDGET_SNAPSHOTS);
 
-    if (device->type() == PE::DESKTOP_DEVICE_TYPE) {
-        attachToRunningProcess(kit, dlg->currentProcess(), false);
-    } else {
-        GdbServerStarter *starter = new GdbServerStarter(dlg, true);
-        starter->run();
-    }
-}
+    // Watchers
+    connect(m_localsView->header(), &QHeaderView::sectionResized,
+        this, &DebuggerPluginPrivate::updateWatchersHeader, Qt::QueuedConnection);
 
-void DebuggerPluginPrivate::attachToUnstartedApplicationDialog()
-{
-    auto dlg = new UnstartedAppWatcherDialog(ICore::dialogParent());
+    auto act = m_continueAction = new QAction(tr("Continue"), this);
+    act->setIcon(Icon::combinedIcon({Core::Icons::DEBUG_CONTINUE_SMALL.icon(), continueSideBarIcon}));
+    connect(act, &QAction::triggered, this, &DebuggerPluginPrivate::handleExecContinue);
 
-    connect(dlg, &QDialog::finished, dlg, &QObject::deleteLater);
-    connect(dlg, &UnstartedAppWatcherDialog::processFound, this, [this, dlg] {
-        DebuggerRunControl *rc = attachToRunningProcess(dlg->currentKit(),
-                                                        dlg->currentProcess(),
-                                                        dlg->continueOnAttach());
-        if (!rc)
-            return;
+    act = m_exitAction = new QAction(tr("Stop Debugger"), this);
+    act->setIcon(Core::Icons::DEBUG_EXIT_SMALL.icon());
+    connect(act, &QAction::triggered, this, &DebuggerPluginPrivate::handleExecExit);
 
-        if (dlg->hideOnAttach())
-            connect(rc, &RunControl::finished, dlg, &UnstartedAppWatcherDialog::startWatching);
-    });
+    auto interruptIcon = Icon::combinedIcon({Core::Icons::DEBUG_INTERRUPT_SMALL.icon(), interruptSideBarIcon});
+    act = m_interruptAction = new QAction(tr("Interrupt"), this);
+    act->setIcon(interruptIcon);
+    connect(act, &QAction::triggered, this, &DebuggerPluginPrivate::handleExecInterrupt);
 
-    dlg->show();
-}
+    // A "disabled pause" seems to be a good choice.
+    act = m_undisturbableAction = new QAction(tr("Debugger is Busy"), this);
+    act->setIcon(interruptIcon);
+    act->setEnabled(false);
 
-DebuggerRunControl *DebuggerPluginPrivate::attachToRunningProcess(Kit *kit,
-    DeviceProcessItem process, bool contAfterAttach)
-{
-    QTC_ASSERT(kit, return 0);
-    IDevice::ConstPtr device = DeviceKitInformation::device(kit);
-    QTC_ASSERT(device, return 0);
-    if (process.pid == 0) {
-        AsynchronousMessageBox::warning(tr("Warning"), tr("Cannot attach to process with PID 0"));
-        return 0;
-    }
+    act = m_abortAction = new QAction(tr("Abort Debugging"), this);
+    act->setToolTip(tr("Aborts debugging and "
+        "resets the debugger to the initial state."));
+    connect(act, &QAction::triggered, this, &DebuggerPluginPrivate::handleAbort);
 
-    bool isWindows = false;
-    if (const ToolChain *tc = ToolChainKitInformation::toolChain(kit))
-        isWindows = tc->targetAbi().os() == Abi::WindowsOS;
-    if (isWindows && isWinProcessBeingDebugged(process.pid)) {
-        AsynchronousMessageBox::warning(tr("Process Already Under Debugger Control"),
-                             tr("The process %1 is already under the control of a debugger.\n"
-                                "Qt Creator cannot attach to it.").arg(process.pid));
-        return 0;
-    }
+    act = m_resetAction = new QAction(tr("Restart Debugging"),this);
+    act->setToolTip(tr("Restart the debugging session."));
+    act->setIcon(Icons::RESTART.icon());
+    connect(act, &QAction::triggered, this, &DebuggerPluginPrivate::handleReset);
 
-    if (device->type() != PE::DESKTOP_DEVICE_TYPE) {
-        AsynchronousMessageBox::warning(tr("Not a Desktop Device Type"),
-                             tr("It is only possible to attach to a locally running process."));
-        return 0;
-    }
+    act = m_nextAction = new QAction(tr("Step Over"), this);
+    act->setIcon(Icons::STEP_OVER.icon());
+    connect(act, &QAction::triggered, this, &DebuggerPluginPrivate::handleExecNext);
 
-    DebuggerRunParameters rp;
-    rp.attachPID = process.pid;
-    rp.displayName = tr("Process %1").arg(process.pid);
-    rp.inferior.executable = process.exe;
-    rp.startMode = AttachExternal;
-    rp.closeMode = DetachAtClose;
-    rp.continueAfterAttach = contAfterAttach;
-    return createAndScheduleRun(rp, kit);
-}
+    act = m_stepAction = new QAction(tr("Step Into"), this);
+    act->setIcon(Icons::STEP_INTO.icon());
+    connect(act, &QAction::triggered, this, &DebuggerPluginPrivate::handleExecStep);
 
-void DebuggerPlugin::attachExternalApplication(RunControl *rc)
-{
-    DebuggerRunParameters rp;
-    rp.attachPID = rc->applicationProcessHandle().pid();
-    rp.displayName = tr("Process %1").arg(rp.attachPID);
-    rp.startMode = AttachExternal;
-    rp.closeMode = DetachAtClose;
-    rp.toolChainAbi = rc->abi();
-    Kit *kit = 0;
-    if (const RunConfiguration *runConfiguration = rc->runConfiguration())
-        if (const Target *target = runConfiguration->target())
-            kit = target->kit();
-    createAndScheduleRun(rp, kit);
-}
+    act = m_stepOutAction = new QAction(tr("Step Out"), this);
+    act->setIcon(Icons::STEP_OUT.icon());
+    connect(act, &QAction::triggered, this, &DebuggerPluginPrivate::handleExecStepOut);
 
-void DebuggerPluginPrivate::attachToQmlPort()
-{
-    DebuggerRunParameters rp;
-    AttachToQmlPortDialog dlg(ICore::mainWindow());
+    act = m_runToLineAction = new QAction(tr("Run to Line"), this);
+    connect(act, &QAction::triggered, this, &DebuggerPluginPrivate::handleExecRunToLine);
 
-    const QVariant qmlServerPort = configValue("LastQmlServerPort");
-    if (qmlServerPort.isValid())
-        dlg.setPort(qmlServerPort.toInt());
-    else
-        dlg.setPort(rp.qmlServerPort);
+    act = m_runToSelectedFunctionAction = new QAction(tr("Run to Selected Function"), this);
+    connect(act, &QAction::triggered, this, &DebuggerPluginPrivate::handleExecRunToSelectedFunction);
 
-    const Id kitId = Id::fromSetting(configValue("LastProfile"));
-    if (kitId.isValid())
-        dlg.setKitId(kitId);
+    act = m_returnFromFunctionAction =
+        new QAction(tr("Immediately Return From Inner Function"), this);
+    connect(act, &QAction::triggered, this, &DebuggerPluginPrivate::handleExecReturn);
 
-    if (dlg.exec() != QDialog::Accepted)
-        return;
+    act = m_jumpToLineAction = new QAction(tr("Jump to Line"), this);
+    connect(act, &QAction::triggered, this, &DebuggerPluginPrivate::handleExecJumpToLine);
 
-    Kit *kit = dlg.kit();
-    QTC_ASSERT(kit, return);
-    setConfigValue("LastQmlServerPort", dlg.port());
-    setConfigValue("LastProfile", kit->id().toSetting());
+    m_breakAction = new QAction(tr("Toggle Breakpoint"), this);
 
-    IDevice::ConstPtr device = DeviceKitInformation::device(kit);
-    if (device) {
-        rp.connParams = device->sshParameters();
-        rp.qmlServerAddress = device->qmlProfilerHost();
-    }
-    rp.qmlServerPort = dlg.port();
-    rp.startMode = AttachToRemoteProcess;
-    rp.closeMode = KillAtClose;
-    rp.languages = QmlLanguage;
-    rp.masterEngineType = QmlEngineType;
+    act = m_watchAction1 = new QAction(tr("Add Expression Evaluator"), this);
+    connect(act, &QAction::triggered, this, &DebuggerPluginPrivate::handleAddToWatchWindow);
 
-    //
-    // get files from all the projects in the session
-    //
-    QList<Project *> projects = SessionManager::projects();
-    if (Project *startupProject = SessionManager::startupProject()) {
-        // startup project first
-        projects.removeOne(startupProject);
-        projects.insert(0, startupProject);
-    }
-    QStringList sourceFiles;
-    foreach (Project *project, projects)
-        sourceFiles << project->files(Project::SourceFiles);
+    act = m_watchAction2 = new QAction(tr("Add Expression Evaluator"), this);
+    connect(act, &QAction::triggered, this, &DebuggerPluginPrivate::handleAddToWatchWindow);
 
-    rp.projectSourceDirectory =
-            !projects.isEmpty() ? projects.first()->projectDirectory().toString() : QString();
-    rp.projectSourceFiles = sourceFiles;
-    createAndScheduleRun(rp, kit);
-}
+    //act = m_snapshotAction = new QAction(tr("Create Snapshot"), this);
+    //act->setProperty(Role, RequestCreateSnapshotRole);
+    //act->setIcon(Icons::SNAPSHOT.icon());
 
-void DebuggerPluginPrivate::enableReverseDebuggingTriggered(const QVariant &value)
-{
-    QTC_ASSERT(m_reverseToolButton, return);
-    m_reverseToolButton->setVisible(value.toBool());
-    m_reverseDirectionAction->setChecked(false);
-    m_reverseDirectionAction->setEnabled(value.toBool());
-}
+    act = m_reverseDirectionAction = new QAction(tr("Reverse Direction"), this);
+    act->setCheckable(true);
+    act->setChecked(false);
+    act->setCheckable(false);
+    act->setIcon(Icons::REVERSE_MODE.icon());
+    act->setIconVisibleInMenu(false);
 
-void DebuggerPluginPrivate::runScheduled()
-{
-    for (int i = 0, n = m_scheduledStarts.size(); i != n; ++i)
-        createAndScheduleRun(m_scheduledStarts.at(i).first, m_scheduledStarts.at(i).second);
-}
+    act = m_frameDownAction = new QAction(tr("Move to Called Frame"), this);
+    connect(act, &QAction::triggered, this, &DebuggerPluginPrivate::handleFrameDown);
 
-void DebuggerPluginPrivate::editorOpened(IEditor *editor)
-{
-    if (auto widget = qobject_cast<TextEditorWidget *>(editor->widget())) {
-        connect(widget, &TextEditorWidget::markRequested,
-                this, &DebuggerPluginPrivate::requestMark);
+    act = m_frameUpAction = new QAction(tr("Move to Calling Frame"), this);
+    connect(act, &QAction::triggered, this, &DebuggerPluginPrivate::handleFrameUp);
 
-        connect(widget, &TextEditorWidget::markContextMenuRequested,
-                this, &DebuggerPluginPrivate::requestContextMenu);
-    }
-}
+    act = m_operateByInstructionAction = action(OperateByInstruction);
+    connect(act, &QAction::triggered,
+            this, &DebuggerPluginPrivate::handleOperateByInstructionTriggered);
 
-void DebuggerPluginPrivate::updateBreakMenuItem(IEditor *editor)
-{
-    BaseTextEditor *textEditor = qobject_cast<BaseTextEditor *>(editor);
-    m_breakAction->setEnabled(textEditor != 0);
-}
+    ActionContainer *debugMenu = ActionManager::actionContainer(PE::M_DEBUG);
 
-void DebuggerPluginPrivate::requestContextMenu(TextEditorWidget *widget,
-    int lineNumber, QMenu *menu)
-{
-    Breakpoint bp;
-    TextDocument *document = widget->textDocument();
+    m_localsAndExpressionsWindow = new LocalsAndExpressionsWindow(
+                m_localsWindow, m_inspectorWindow, m_returnWindow, m_watchersWindow);
+    m_localsAndExpressionsWindow->setObjectName(QLatin1String(DOCKWIDGET_WATCHERS));
+    m_localsAndExpressionsWindow->setWindowTitle(m_localsWindow->windowTitle());
 
-    ContextData args = getLocationContext(document, lineNumber);
-    if (args.type == LocationByAddress) {
-        BreakpointResponse needle;
-        needle.type = BreakpointByAddress;
-        needle.address = args.address;
-        needle.lineNumber = -1;
-        bp = breakHandler()->findSimilarBreakpoint(needle);
-    } else if (args.type == LocationByFile) {
-        bp = breakHandler()->findBreakpointByFileAndLine(args.fileName, lineNumber);
-        if (!bp)
-            bp = breakHandler()->findBreakpointByFileAndLine(args.fileName, lineNumber, false);
-    }
+    m_plugin->addAutoReleasedObject(createDebuggerRunControlFactory(m_plugin));
 
-    if (bp) {
-        QString id = bp.id().toString();
+    // The main "Start Debugging" action.
+    act = m_startAction = new QAction(this);
+    const QIcon sideBarIcon =
+            Icon::sideBarIcon(ProjectExplorer::Icons::DEBUG_START, ProjectExplorer::Icons::DEBUG_START_FLAT);
+    const QIcon debuggerIcon = Icon::combinedIcon({Core::Icons::DEBUG_START_SMALL.icon(), sideBarIcon});
+    act->setIcon(debuggerIcon);
+    act->setText(tr("Start Debugging"));
+    connect(act, &QAction::triggered, [] { ProjectExplorerPlugin::runStartupProject(ProjectExplorer::Constants::DEBUG_RUN_MODE); });
 
-        // Remove existing breakpoint.
-        auto act = menu->addAction(tr("Remove Breakpoint %1").arg(id));
-        connect(act, &QAction::triggered, [bp] { bp.removeBreakpoint(); });
+    act = m_debugWithoutDeployAction = new QAction(this);
+    act->setText(tr("Start Debugging Without Deployment"));
+    connect(act, &QAction::triggered, [] { ProjectExplorerPlugin::runStartupProject(ProjectExplorer::Constants::DEBUG_RUN_MODE, true); });
 
-        // Enable/disable existing breakpoint.
-        if (bp.isEnabled()) {
-            act = menu->addAction(tr("Disable Breakpoint %1").arg(id));
-            connect(act, &QAction::triggered, [bp] { bp.setEnabled(false); });
-        } else {
-            act = menu->addAction(tr("Enable Breakpoint %1").arg(id));
-            connect(act, &QAction::triggered, [bp] { bp.setEnabled(true); });
-        }
+    act = m_startAndDebugApplicationAction = new QAction(this);
+    act->setText(tr("Start and Debug External Application..."));
+    connect(act, &QAction::triggered, this, &DebuggerPluginPrivate::startAndDebugApplication);
 
-        // Edit existing breakpoint.
-        act = menu->addAction(tr("Edit Breakpoint %1...").arg(id));
-        connect(act, &QAction::triggered, [bp] {
-            BreakTreeView::editBreakpoint(bp, ICore::dialogParent());
-        });
+    act = m_attachToCoreAction = new QAction(this);
+    act->setText(tr("Load Core File..."));
+    connect(act, &QAction::triggered, this, &DebuggerPluginPrivate::attachCore);
 
-    } else {
-        // Handle non-existing breakpoint.
-        const QString text = args.address
-            ? tr("Set Breakpoint at 0x%1").arg(args.address, 0, 16)
-            : tr("Set Breakpoint at Line %1").arg(lineNumber);
-        auto act = menu->addAction(text);
-        act->setEnabled(args.isValid());
-        connect(act, &QAction::triggered, [this, args] {
-            breakpointSetMarginActionTriggered(false, args);
-        });
-
-        // Message trace point
-        const QString tracePointText = args.address
-            ? tr("Set Message Tracepoint at 0x%1...").arg(args.address, 0, 16)
-            : tr("Set Message Tracepoint at Line %1...").arg(lineNumber);
-        act = menu->addAction(tracePointText);
-        act->setEnabled(args.isValid());
-        connect(act, &QAction::triggered, [this, args] {
-            breakpointSetMarginActionTriggered(true, args);
-        });
-    }
+    act = m_attachToRemoteServerAction = new QAction(this);
+    act->setText(tr("Attach to Running Debug Server..."));
+    connect(act, &QAction::triggered, this, &DebuggerPluginPrivate::attachToRemoteServer);
 
-    // Run to, jump to line below in stopped state.
-    if (currentEngine()->state() == InferiorStopOk && args.isValid()) {
-        menu->addSeparator();
-        if (currentEngine()->hasCapability(RunToLineCapability)) {
-            auto act = menu->addAction(args.address
-                ? DebuggerEngine::tr("Run to Address 0x%1").arg(args.address, 0, 16)
-                : DebuggerEngine::tr("Run to Line %1").arg(args.lineNumber));
-            connect(act, &QAction::triggered, [this, args] {
-                currentEngine()->executeRunToLine(args);
-            });
-        }
-        if (currentEngine()->hasCapability(JumpToLineCapability)) {
-            auto act = menu->addAction(args.address
-                ? DebuggerEngine::tr("Jump to Address 0x%1").arg(args.address, 0, 16)
-                : DebuggerEngine::tr("Jump to Line %1").arg(args.lineNumber));
-            connect(act, &QAction::triggered, [this, args] {
-                currentEngine()->executeJumpToLine(args);
-            });
-        }
-        // Disassemble current function in stopped state.
-        if (currentEngine()->hasCapability(DisassemblerCapability)) {
-            StackFrame frame;
-            frame.function = cppFunctionAt(args.fileName, lineNumber, 1);
-            frame.line = 42; // trick gdb into mixed mode.
-            if (!frame.function.isEmpty()) {
-                const QString text = tr("Disassemble Function \"%1\"")
-                    .arg(frame.function);
-                auto act = new QAction(text, menu);
-                connect(act, &QAction::triggered, [this, frame] {
-                    currentEngine()->openDisassemblerView(Location(frame));
-                });
-                menu->addAction(act);
-            }
-        }
-    }
-}
+    act = m_startRemoteServerAction = new QAction(this);
+    act->setText(tr("Start Debug Server Attached to Process..."));
+    connect(act, &QAction::triggered, this, &DebuggerPluginPrivate::startRemoteServerAndAttachToProcess);
 
-void DebuggerPluginPrivate::toggleBreakpoint(const ContextData &location, const QString &tracePointMessage)
-{
-    QTC_ASSERT(location.isValid(), return);
-    BreakHandler *handler = m_breakHandler;
-    Breakpoint bp;
-    if (location.type == LocationByFile) {
-        bp = handler->findBreakpointByFileAndLine(location.fileName, location.lineNumber, true);
-        if (!bp)
-            bp = handler->findBreakpointByFileAndLine(location.fileName, location.lineNumber, false);
-    } else if (location.type == LocationByAddress) {
-        bp = handler->findBreakpointByAddress(location.address);
-    }
+    act = m_attachToRunningApplication = new QAction(this);
+    act->setText(tr("Attach to Running Application..."));
+    connect(act, &QAction::triggered, this, &DebuggerPluginPrivate::attachToRunningApplication);
 
-    if (bp) {
-        bp.removeBreakpoint();
-    } else {
-        BreakpointParameters data;
-        if (location.type == LocationByFile) {
-            data.type = BreakpointByFileAndLine;
-            if (boolSetting(BreakpointsFullPathByDefault))
-                data.pathUsage = BreakpointUseFullPath;
-            data.tracepoint = !tracePointMessage.isEmpty();
-            data.message = tracePointMessage;
-            data.fileName = location.fileName;
-            data.lineNumber = location.lineNumber;
-        } else if (location.type == LocationByAddress) {
-            data.type = BreakpointByAddress;
-            data.tracepoint = !tracePointMessage.isEmpty();
-            data.message = tracePointMessage;
-            data.address = location.address;
-        }
-        handler->appendBreakpoint(data);
-    }
-}
+    act = m_attachToUnstartedApplication = new QAction(this);
+    act->setText(tr("Attach to Unstarted Application..."));
+    connect(act, &QAction::triggered, this, &DebuggerPluginPrivate::attachToUnstartedApplicationDialog);
 
-void DebuggerPluginPrivate::toggleBreakpointHelper()
-{
-    BaseTextEditor *textEditor = BaseTextEditor::currentTextEditor();
-    QTC_ASSERT(textEditor, return);
-    const int lineNumber = textEditor->currentLine();
-    ContextData location = getLocationContext(textEditor->textDocument(), lineNumber);
-    if (location.isValid())
-        toggleBreakpoint(location);
-}
+    act = m_attachToQmlPortAction = new QAction(this);
+    act->setText(tr("Attach to QML Port..."));
+    connect(act, &QAction::triggered, this, &DebuggerPluginPrivate::attachToQmlPort);
 
-void DebuggerPluginPrivate::requestMark(TextEditorWidget *widget, int lineNumber,
-                                        TextMarkRequestKind kind)
-{
-    if (kind == BreakpointRequest) {
-        ContextData location = getLocationContext(widget->textDocument(), lineNumber);
-        if (location.isValid())
-            toggleBreakpoint(location);
+    if (HostOsInfo::isWindowsHost()) {
+        m_startRemoteCdbAction = new QAction(tr("Attach to Remote CDB Session..."), this);
+        connect(m_startRemoteCdbAction, &QAction::triggered,
+                this, &DebuggerPluginPrivate::startRemoteCdbSession);
     }
-}
 
-// If updateEngine is set, the engine will update its threads/modules and so forth.
-void DebuggerPluginPrivate::displayDebugger(DebuggerEngine *engine, bool updateEngine)
-{
-    QTC_ASSERT(engine, return);
-    disconnectEngine();
-    connectEngine(engine);
-    if (updateEngine)
-        engine->updateAll();
-    engine->updateViews();
-}
+    act = m_detachAction = new QAction(this);
+    act->setText(tr("Detach Debugger"));
+    connect(act, &QAction::triggered, this, &DebuggerPluginPrivate::handleExecDetach);
 
-void DebuggerPluginPrivate::connectEngine(DebuggerEngine *engine)
-{
-    if (!engine)
-        engine = dummyEngine();
+    // "Start Debugging" sub-menu
+    // groups:
+    //   G_DEFAULT_ONE
+    //   G_START_LOCAL
+    //   G_START_REMOTE
+    //   G_START_QML
 
-    if (m_currentEngine == engine)
-        return;
+    ActionContainer *mstart = ActionManager::actionContainer(PE::M_DEBUG_STARTDEBUGGING);
 
-    if (m_currentEngine)
-        m_currentEngine->resetLocation();
-    m_currentEngine = engine;
+    cmd = ActionManager::registerAction(m_startAction, Constants::DEBUG);
+    cmd->setDescription(tr("Start Debugging"));
+    cmd->setDefaultKeySequence(debugKey);
+    cmd->setAttribute(Command::CA_UpdateText);
+    mstart->addAction(cmd, CC::G_DEFAULT_ONE);
+    m_visibleStartAction = new ProxyAction(this);
+    m_visibleStartAction->initialize(cmd->action());
+    m_visibleStartAction->setAttribute(ProxyAction::UpdateText);
+    m_visibleStartAction->setAttribute(ProxyAction::UpdateIcon);
+    m_visibleStartAction->setAction(cmd->action());
 
-    m_localsView->setModel(engine->watchModel());
-    m_modulesView->setModel(engine->modulesModel());
-    m_registerView->setModel(engine->registerModel());
-    m_returnView->setModel(engine->watchModel());
-    m_sourceFilesView->setModel(engine->sourceFilesModel());
-    m_stackView->setModel(engine->stackModel());
-    m_threadsView->setModel(engine->threadsModel());
-    m_watchersView->setModel(engine->watchModel());
-    m_inspectorView->setModel(engine->watchModel());
+    ModeManager::addAction(m_visibleStartAction, Constants::P_ACTION_DEBUG);
 
-    engine->watchHandler()->resetWatchers();
-    m_localsView->hideProgressIndicator();
-}
+    cmd = ActionManager::registerAction(m_debugWithoutDeployAction,
+        "Debugger.DebugWithoutDeploy");
+    cmd->setAttribute(Command::CA_Hide);
+    mstart->addAction(cmd, CC::G_DEFAULT_ONE);
 
-static void changeFontSize(QWidget *widget, qreal size)
-{
-    QFont font = widget->font();
-    font.setPointSizeF(size);
-    widget->setFont(font);
-}
+    cmd = ActionManager::registerAction(m_attachToRunningApplication,
+         "Debugger.AttachToRemoteProcess");
+    cmd->setDescription(tr("Attach to Running Application"));
+    mstart->addAction(cmd, G_GENERAL);
 
-void DebuggerPluginPrivate::fontSettingsChanged
-    (const FontSettings &settings)
-{
-    if (!boolSetting(FontSizeFollowsEditor))
-        return;
-    qreal size = settings.fontZoom() * settings.fontSize() / 100.;
-    changeFontSize(m_breakWindow, size);
-    changeFontSize(m_logWindow, size);
-    changeFontSize(m_localsWindow, size);
-    changeFontSize(m_modulesWindow, size);
-    //changeFontSize(m_consoleWindow, size);
-    changeFontSize(m_registerWindow, size);
-    changeFontSize(m_returnWindow, size);
-    changeFontSize(m_sourceFilesWindow, size);
-    changeFontSize(m_stackWindow, size);
-    changeFontSize(m_threadsWindow, size);
-    changeFontSize(m_watchersWindow, size);
-    changeFontSize(m_inspectorWindow, size);
-}
+    cmd = ActionManager::registerAction(m_attachToUnstartedApplication,
+          "Debugger.AttachToUnstartedProcess");
+    cmd->setDescription(tr("Attach to Unstarted Application"));
+    mstart->addAction(cmd, G_GENERAL);
 
-void DebuggerPluginPrivate::cleanupViews()
-{
-    m_reverseDirectionAction->setChecked(false);
-    m_reverseDirectionAction->setEnabled(false);
+    cmd = ActionManager::registerAction(m_startAndDebugApplicationAction,
+        "Debugger.StartAndDebugApplication");
+    cmd->setAttribute(Command::CA_Hide);
+    mstart->addAction(cmd, G_GENERAL);
 
-    const bool closeSource = boolSetting(CloseSourceBuffersOnExit);
-    const bool closeMemory = boolSetting(CloseMemoryBuffersOnExit);
+    cmd = ActionManager::registerAction(m_attachToCoreAction,
+        "Debugger.AttachCore");
+    cmd->setAttribute(Command::CA_Hide);
+    mstart->addAction(cmd, Constants::G_GENERAL);
 
-    QList<IDocument *> toClose;
-    foreach (IDocument *document, DocumentModel::openedDocuments()) {
-        const bool isMemory = document->property(Constants::OPENED_WITH_DISASSEMBLY).toBool();
-        if (document->property(Constants::OPENED_BY_DEBUGGER).toBool()) {
-            bool keepIt = true;
-            if (document->isModified())
-                keepIt = true;
-            else if (document->filePath().toString().contains(_("qeventdispatcher")))
-                keepIt = false;
-            else if (isMemory)
-                keepIt = !closeMemory;
-            else
-                keepIt = !closeSource;
+    cmd = ActionManager::registerAction(m_attachToRemoteServerAction,
+        "Debugger.AttachToRemoteServer");
+    cmd->setAttribute(Command::CA_Hide);
+    mstart->addAction(cmd, Constants::G_SPECIAL);
 
-            if (keepIt)
-                document->setProperty(Constants::OPENED_BY_DEBUGGER, false);
-            else
-                toClose.append(document);
-        }
+    cmd = ActionManager::registerAction(m_startRemoteServerAction,
+         "Debugger.StartRemoteServer");
+    cmd->setDescription(tr("Start Gdbserver"));
+    mstart->addAction(cmd, Constants::G_SPECIAL);
+
+    if (m_startRemoteCdbAction) {
+        cmd = ActionManager::registerAction(m_startRemoteCdbAction,
+             "Debugger.AttachRemoteCdb");
+        cmd->setAttribute(Command::CA_Hide);
+        mstart->addAction(cmd, Constants::G_SPECIAL);
     }
-    EditorManager::closeDocuments(toClose);
-}
 
-void DebuggerPluginPrivate::setBusyCursor(bool busy)
-{
-    //STATE_DEBUG("BUSY FROM: " << m_busy << " TO: " << busy);
-    if (busy == m_busy)
-        return;
-    m_busy = busy;
-    QCursor cursor(busy ? Qt::BusyCursor : Qt::ArrowCursor);
-    m_breakWindow->setCursor(cursor);
-    //m_consoleWindow->setCursor(cursor);
-    m_localsWindow->setCursor(cursor);
-    m_modulesWindow->setCursor(cursor);
-    m_logWindow->setCursor(cursor);
-    m_registerWindow->setCursor(cursor);
-    m_returnWindow->setCursor(cursor);
-    m_sourceFilesWindow->setCursor(cursor);
-    m_stackWindow->setCursor(cursor);
-    m_threadsWindow->setCursor(cursor);
-    m_watchersWindow->setCursor(cursor);
-    m_snapshotWindow->setCursor(cursor);
-}
+    mstart->addSeparator(Context(CC::C_GLOBAL), Constants::G_START_QML);
 
-void DebuggerPluginPrivate::setInitialState()
-{
-    m_watchersWindow->setVisible(false);
-    m_returnWindow->setVisible(false);
-    setBusyCursor(false);
-    m_reverseDirectionAction->setChecked(false);
-    m_reverseDirectionAction->setEnabled(false);
-    m_toolTipManager.closeAllToolTips();
+    cmd = ActionManager::registerAction(m_attachToQmlPortAction, "Debugger.AttachToQmlPort");
+    cmd->setAttribute(Command::CA_Hide);
+    mstart->addAction(cmd, Constants::G_START_QML);
 
-    m_startAndDebugApplicationAction->setEnabled(true);
-    m_attachToQmlPortAction->setEnabled(true);
-    m_attachToCoreAction->setEnabled(true);
-    m_attachToRemoteServerAction->setEnabled(true);
-    m_attachToRunningApplication->setEnabled(true);
-    m_attachToUnstartedApplication->setEnabled(true);
-    m_detachAction->setEnabled(false);
+    cmd = ActionManager::registerAction(m_detachAction, "Debugger.Detach");
+    cmd->setAttribute(Command::CA_Hide);
+    debugMenu->addAction(cmd, CC::G_DEFAULT_ONE);
 
-    m_watchAction1->setEnabled(true);
-    m_watchAction2->setEnabled(true);
-    m_breakAction->setEnabled(false);
-    //m_snapshotAction->setEnabled(false);
-    action(OperateByInstruction)->setEnabled(false);
+    cmd = ActionManager::registerAction(m_interruptAction, Constants::INTERRUPT);
+    cmd->setDescription(tr("Interrupt Debugger"));
+    debugMenu->addAction(cmd, CC::G_DEFAULT_ONE);
 
-    m_exitAction->setEnabled(false);
-    m_abortAction->setEnabled(false);
-    m_resetAction->setEnabled(false);
+    cmd = ActionManager::registerAction(m_continueAction, Constants::CONTINUE);
+    cmd->setDefaultKeySequence(debugKey);
+    debugMenu->addAction(cmd, CC::G_DEFAULT_ONE);
 
-    m_interruptAction->setEnabled(false);
-    m_continueAction->setEnabled(false);
+    cmd = ActionManager::registerAction(m_exitAction, Constants::STOP);
+    debugMenu->addAction(cmd, CC::G_DEFAULT_ONE);
+    m_hiddenStopAction = new ProxyAction(this);
+    m_hiddenStopAction->initialize(cmd->action());
+    m_hiddenStopAction->setAttribute(ProxyAction::UpdateText);
+    m_hiddenStopAction->setAttribute(ProxyAction::UpdateIcon);
 
-    m_stepAction->setEnabled(true);
-    m_stepOutAction->setEnabled(false);
-    m_runToLineAction->setEnabled(false);
-    m_runToSelectedFunctionAction->setEnabled(true);
-    m_returnFromFunctionAction->setEnabled(false);
-    m_jumpToLineAction->setEnabled(false);
-    m_nextAction->setEnabled(true);
+    cmd = ActionManager::registerAction(m_hiddenStopAction, Constants::HIDDEN_STOP);
+    cmd->setDefaultKeySequence(QKeySequence(UseMacShortcuts ? tr("Shift+Ctrl+Y") : tr("Shift+F5")));
 
-    action(AutoDerefPointers)->setEnabled(true);
-    action(ExpandStack)->setEnabled(false);
-}
+    cmd = ActionManager::registerAction(m_abortAction, Constants::ABORT);
+    cmd->setDescription(tr("Reset Debugger"));
+    debugMenu->addAction(cmd, CC::G_DEFAULT_ONE);
 
-void DebuggerPluginPrivate::updateState(DebuggerEngine *engine)
-{
-    QTC_ASSERT(engine, return);
-    QTC_ASSERT(m_watchersView->model(), return);
-    QTC_ASSERT(m_returnView->model(), return);
-    QTC_ASSERT(!engine->isSlaveEngine(), return);
+    cmd = ActionManager::registerAction(m_resetAction, Constants::RESET);
+    cmd->setDescription(tr("Restart Debugging"));
+    debugMenu->addAction(cmd, CC::G_DEFAULT_ONE);
 
-    m_threadBox->setCurrentIndex(engine->threadsHandler()->currentThreadIndex());
+    debugMenu->addSeparator();
 
-    const DebuggerState state = engine->state();
-    //showMessage(QString::fromLatin1("PLUGIN SET STATE: ")
-    //    + DebuggerEngine::stateName(state), LogStatus);
-    //qDebug() << "PLUGIN SET STATE: " << state;
+    cmd = ActionManager::registerAction(m_nextAction, Constants::NEXT);
+    cmd->setDefaultKeySequence(QKeySequence(UseMacShortcuts ? tr("Ctrl+Shift+O") : tr("F10")));
+    cmd->setAttribute(Command::CA_Hide);
+    cmd->setAttribute(Command::CA_UpdateText);
+    debugMenu->addAction(cmd);
 
-    static DebuggerState previousState = DebuggerNotReady;
-    if (state == previousState)
-        return;
+    cmd = ActionManager::registerAction(m_stepAction, Constants::STEP);
+    cmd->setDefaultKeySequence(QKeySequence(UseMacShortcuts ? tr("Ctrl+Shift+I") : tr("F11")));
+    cmd->setAttribute(Command::CA_Hide);
+    cmd->setAttribute(Command::CA_UpdateText);
+    debugMenu->addAction(cmd);
 
-    bool actionsEnabled = DebuggerEngine::debuggerActionsEnabled(state);
+    cmd = ActionManager::registerAction(m_stepOutAction,
+        Constants::STEPOUT, cppDebuggercontext);
+    cmd->setDefaultKeySequence(QKeySequence(UseMacShortcuts ? tr("Ctrl+Shift+T") : tr("Shift+F11")));
+    cmd->setAttribute(Command::CA_Hide);
+    debugMenu->addAction(cmd);
 
-    if (state == DebuggerNotReady) {
-        QTC_ASSERT(false, /* We use the Core's m_debugAction here */);
-        // F5 starts debugging. It is "startable".
-        m_interruptAction->setEnabled(false);
-        m_continueAction->setEnabled(false);
-        m_exitAction->setEnabled(false);
-        m_startAction->setEnabled(true);
-        m_debugWithoutDeployAction->setEnabled(true);
-        setProxyAction(m_visibleStartAction, Id(Constants::DEBUG));
-        m_hiddenStopAction->setAction(m_undisturbableAction);
-    } else if (state == InferiorStopOk) {
-        // F5 continues, Shift-F5 kills. It is "continuable".
-        m_interruptAction->setEnabled(false);
-        m_continueAction->setEnabled(true);
-        m_exitAction->setEnabled(true);
-        m_startAction->setEnabled(false);
-        m_debugWithoutDeployAction->setEnabled(false);
-        setProxyAction(m_visibleStartAction, Id(Constants::CONTINUE));
-        m_hiddenStopAction->setAction(m_exitAction);
-        m_localsAndExpressionsWindow->setShowLocals(true);
-    } else if (state == InferiorRunOk) {
-        // Shift-F5 interrupts. It is also "interruptible".
-        m_interruptAction->setEnabled(true);
-        m_continueAction->setEnabled(false);
-        m_exitAction->setEnabled(true);
-        m_startAction->setEnabled(false);
-        m_debugWithoutDeployAction->setEnabled(false);
-        setProxyAction(m_visibleStartAction, Id(Constants::INTERRUPT));
-        m_hiddenStopAction->setAction(m_interruptAction);
-        m_localsAndExpressionsWindow->setShowLocals(false);
-        activateDebugMode();
-    } else if (state == DebuggerFinished) {
-        Project *project = SessionManager::startupProject();
-        const bool canRun = ProjectExplorerPlugin::canRun(project, ProjectExplorer::Constants::DEBUG_RUN_MODE);
-        // We don't want to do anything anymore.
-        m_interruptAction->setEnabled(false);
-        m_continueAction->setEnabled(false);
-        m_exitAction->setEnabled(false);
-        m_startAction->setEnabled(canRun);
-        m_debugWithoutDeployAction->setEnabled(canRun);
-        setProxyAction(m_visibleStartAction, Id(Constants::DEBUG));
-        m_hiddenStopAction->setAction(m_undisturbableAction);
-        m_codeModelSnapshot = CPlusPlus::Snapshot();
-        setBusyCursor(false);
-        cleanupViews();
-    } else if (state == InferiorUnrunnable) {
-        // We don't want to do anything anymore.
-        m_interruptAction->setEnabled(false);
-        m_continueAction->setEnabled(false);
-        m_exitAction->setEnabled(true);
-        m_startAction->setEnabled(false);
-        m_debugWithoutDeployAction->setEnabled(false);
-        m_visibleStartAction->setAction(m_undisturbableAction);
-        m_hiddenStopAction->setAction(m_exitAction);
-        // show locals in core dumps
-        m_localsAndExpressionsWindow->setShowLocals(true);
-        activateDebugMode();
-    } else {
-        // Everything else is "undisturbable".
-        m_interruptAction->setEnabled(false);
-        m_continueAction->setEnabled(false);
-        m_exitAction->setEnabled(false);
-        m_startAction->setEnabled(false);
-        m_debugWithoutDeployAction->setEnabled(false);
-        m_visibleStartAction->setAction(m_undisturbableAction);
-        m_hiddenStopAction->setAction(m_undisturbableAction);
-    }
+    cmd = ActionManager::registerAction(m_runToLineAction,
+        "Debugger.RunToLine", cppDebuggercontext);
+    cmd->setDefaultKeySequence(QKeySequence(UseMacShortcuts ? tr("Shift+F8") : tr("Ctrl+F10")));
+    cmd->setAttribute(Command::CA_Hide);
+    debugMenu->addAction(cmd);
 
-    m_startAndDebugApplicationAction->setEnabled(true);
-    m_attachToQmlPortAction->setEnabled(true);
-    m_attachToCoreAction->setEnabled(true);
-    m_attachToRemoteServerAction->setEnabled(true);
-    m_attachToRunningApplication->setEnabled(true);
-    m_attachToUnstartedApplication->setEnabled(true);
+    cmd = ActionManager::registerAction(m_runToSelectedFunctionAction,
+        "Debugger.RunToSelectedFunction", cppDebuggercontext);
+    cmd->setDefaultKeySequence(QKeySequence(tr("Ctrl+F6")));
+    cmd->setAttribute(Command::CA_Hide);
+    // Don't add to menu by default as keeping its enabled state
+    // and text up-to-date is a lot of hassle.
+    // debugMenu->addAction(cmd);
 
-    m_threadBox->setEnabled(state == InferiorStopOk || state == InferiorUnrunnable);
+    cmd = ActionManager::registerAction(m_jumpToLineAction,
+        "Debugger.JumpToLine", cppDebuggercontext);
+    cmd->setAttribute(Command::CA_Hide);
+    debugMenu->addAction(cmd);
 
-    const bool isCore = engine->runParameters().startMode == AttachCore;
-    const bool stopped = state == InferiorStopOk;
-    const bool detachable = stopped && !isCore;
-    m_detachAction->setEnabled(detachable);
+    cmd = ActionManager::registerAction(m_returnFromFunctionAction,
+        "Debugger.ReturnFromFunction", cppDebuggercontext);
+    cmd->setAttribute(Command::CA_Hide);
+    debugMenu->addAction(cmd);
 
-    if (stopped)
-        QApplication::alert(mainWindow(), 3000);
+    if (isReverseDebuggingEnabled()) {
+        cmd = ActionManager::registerAction(m_reverseDirectionAction,
+                                            Constants::REVERSE, cppDebuggercontext);
+        cmd->setDefaultKeySequence(QKeySequence(UseMacShortcuts ? QString() : tr("F12")));
+        cmd->setAttribute(Command::CA_Hide);
+        debugMenu->addAction(cmd);
+    }
 
-    const bool canReverse = engine->hasCapability(ReverseSteppingCapability)
-                && boolSetting(EnableReverseDebugging);
-    m_reverseDirectionAction->setEnabled(canReverse);
+    debugMenu->addSeparator();
 
-    m_watchAction1->setEnabled(true);
-    m_watchAction2->setEnabled(true);
-    m_breakAction->setEnabled(true);
+    //cmd = ActionManager::registerAction(m_snapshotAction,
+    //    "Debugger.Snapshot", cppDebuggercontext);
+    //cmd->setDefaultKeySequence(QKeySequence(tr("Ctrl+D,Ctrl+S")));
+    //cmd->setAttribute(Command::CA_Hide);
+    //debugMenu->addAction(cmd);
 
-    const bool canOperateByInstruction = engine->hasCapability(OperateByInstructionCapability)
-            && (stopped || isCore);
-    action(OperateByInstruction)->setEnabled(canOperateByInstruction);
+    ActionManager::registerAction(m_frameDownAction,
+        "Debugger.FrameDown", cppDebuggercontext);
+    ActionManager::registerAction(m_frameUpAction,
+        "Debugger.FrameUp", cppDebuggercontext);
 
-    m_abortAction->setEnabled(state != DebuggerNotReady
-                                      && state != DebuggerFinished);
-    m_resetAction->setEnabled((stopped || state == DebuggerNotReady)
-                              && engine->hasCapability(ResetInferiorCapability));
+    cmd = ActionManager::registerAction(m_operateByInstructionAction,
+        Constants::OPERATE_BY_INSTRUCTION, cppDebuggercontext);
+    cmd->setAttribute(Command::CA_Hide);
+    debugMenu->addAction(cmd);
 
-    m_stepAction->setEnabled(stopped || state == DebuggerNotReady);
-    m_nextAction->setEnabled(stopped || state == DebuggerNotReady);
-    m_stepAction->setToolTip(QString());
-    m_nextAction->setToolTip(QString());
+    cmd = ActionManager::registerAction(m_breakAction, "Debugger.ToggleBreak");
+    cmd->setDefaultKeySequence(QKeySequence(UseMacShortcuts ? tr("F8") : tr("F9")));
+    debugMenu->addAction(cmd);
+    connect(m_breakAction, &QAction::triggered,
+        this, &DebuggerPluginPrivate::toggleBreakpointHelper);
 
-    m_stepOutAction->setEnabled(stopped);
-    m_runToLineAction->setEnabled(stopped && engine->hasCapability(RunToLineCapability));
-    m_runToSelectedFunctionAction->setEnabled(stopped);
-    m_returnFromFunctionAction->
-        setEnabled(stopped && engine->hasCapability(ReturnFromFunctionCapability));
+    debugMenu->addSeparator();
 
-    const bool canJump = stopped && engine->hasCapability(JumpToLineCapability);
-    m_jumpToLineAction->setEnabled(canJump);
+    // currently broken
+//    auto qmlUpdateOnSaveDummyAction = new QAction(tr("Apply Changes on Save"), this);
+//    qmlUpdateOnSaveDummyAction->setCheckable(true);
+//    qmlUpdateOnSaveDummyAction->setIcon(Icons::APPLY_ON_SAVE.icon());
+//    qmlUpdateOnSaveDummyAction->setEnabled(false);
+//    cmd = ActionManager::registerAction(qmlUpdateOnSaveDummyAction, Constants::QML_UPDATE_ON_SAVE);
+//    debugMenu->addAction(cmd);
 
-    const bool canDeref = actionsEnabled && engine->hasCapability(AutoDerefPointersCapability);
-    action(AutoDerefPointers)->setEnabled(canDeref);
-    action(AutoDerefPointers)->setEnabled(true);
-    action(ExpandStack)->setEnabled(actionsEnabled);
+    auto qmlShowAppOnTopDummyAction = new QAction(tr("Show Application on Top"), this);
+    qmlShowAppOnTopDummyAction->setCheckable(true);
+    qmlShowAppOnTopDummyAction->setIcon(Icons::APP_ON_TOP.icon());
+    qmlShowAppOnTopDummyAction->setEnabled(false);
+    cmd = ActionManager::registerAction(qmlShowAppOnTopDummyAction, Constants::QML_SHOW_APP_ON_TOP);
+    debugMenu->addAction(cmd);
 
-    const bool notbusy = state == InferiorStopOk
-        || state == DebuggerNotReady
-        || state == DebuggerFinished
-        || state == InferiorUnrunnable;
-    setBusyCursor(!notbusy);
-}
+    auto qmlSelectDummyAction = new QAction(tr("Select"), this);
+    qmlSelectDummyAction->setCheckable(true);
+    qmlSelectDummyAction->setIcon(Icons::SELECT.icon());
+    qmlSelectDummyAction->setEnabled(false);
+    cmd = ActionManager::registerAction(qmlSelectDummyAction, Constants::QML_SELECTTOOL);
+    debugMenu->addAction(cmd);
 
-void DebuggerPluginPrivate::updateDebugActions()
-{
-    //if we're currently debugging the actions are controlled by engine
-    if (m_currentEngine->state() != DebuggerNotReady)
-        return;
+    auto qmlZoomDummyAction = new QAction(tr("Zoom"), this);
+    qmlZoomDummyAction->setCheckable(true);
+    qmlZoomDummyAction->setIcon(Core::Icons::ZOOM.icon());
+    qmlZoomDummyAction->setEnabled(false);
+    cmd = ActionManager::registerAction(qmlZoomDummyAction, Constants::QML_ZOOMTOOL);
+    debugMenu->addAction(cmd);
 
-    Project *project = SessionManager::startupProject();
-    QString whyNot;
-    const bool canRun = ProjectExplorerPlugin::canRun(project, ProjectExplorer::Constants::DEBUG_RUN_MODE, &whyNot);
-    m_startAction->setEnabled(canRun);
-    m_startAction->setToolTip(whyNot);
-    m_debugWithoutDeployAction->setEnabled(canRun);
+    debugMenu->addSeparator();
 
-    // Step into/next: Start and break at 'main' unless a debugger is running.
-    if (m_snapshotHandler->currentIndex() < 0) {
-        QString toolTip;
-        const bool canRunAndBreakMain
-                = ProjectExplorerPlugin::canRun(project, ProjectExplorer::Constants::DEBUG_RUN_MODE_WITH_BREAK_ON_MAIN, &toolTip);
-        m_stepAction->setEnabled(canRunAndBreakMain);
-        m_nextAction->setEnabled(canRunAndBreakMain);
-        if (canRunAndBreakMain) {
-            QTC_ASSERT(project, return ; );
-            toolTip = tr("Start \"%1\" and break at function \"main()\"")
-                      .arg(project->displayName());
-        }
-        m_stepAction->setToolTip(toolTip);
-        m_nextAction->setToolTip(toolTip);
-    }
-}
+    // Don't add '1' to the string as it shows up in the shortcut dialog.
+    cmd = ActionManager::registerAction(m_watchAction1,
+        "Debugger.AddToWatch", cppeditorcontext);
+    //cmd->setDefaultKeySequence(QKeySequence(tr("Ctrl+D,Ctrl+W")));
+    debugMenu->addAction(cmd);
 
-void DebuggerPluginPrivate::onCoreAboutToOpen()
-{
-    onModeChangedHelper(ModeManager::currentMode());
-}
+    // If the CppEditor plugin is there, we want to add something to
+    // the editor context menu.
+    if (ActionContainer *editorContextMenu =
+            ActionManager::actionContainer(CppEditor::Constants::M_CONTEXT)) {
+        cmd = editorContextMenu->addSeparator(cppDebuggercontext);
+        cmd->setAttribute(Command::CA_Hide);
 
-void DebuggerPluginPrivate::onModeChanged(IMode *mode)
-{
-     // FIXME: This one gets always called, even if switching between modes
-     //        different then the debugger mode. E.g. Welcome and Help mode and
-     //        also on shutdown.
+        cmd = ActionManager::registerAction(m_watchAction2,
+            "Debugger.AddToWatch2", cppDebuggercontext);
+        cmd->action()->setEnabled(true);
+        editorContextMenu->addAction(cmd);
+        cmd->setAttribute(Command::CA_Hide);
+        cmd->setAttribute(Command::CA_NonConfigurable);
+        // Debugger.AddToWatch is enough.
+    }
 
-    onModeChangedHelper(mode);
+    QList<IOptionsPage *> engineOptionPages;
+    addGdbOptionPages(&engineOptionPages);
+    addCdbOptionPages(&engineOptionPages);
 
-    if (mode->id() != Constants::MODE_DEBUG) {
-        m_toolTipManager.leavingDebugMode();
-        return;
-    }
+    foreach (IOptionsPage *op, engineOptionPages)
+        m_plugin->addAutoReleasedObject(op);
+    m_plugin->addAutoReleasedObject(new LocalsAndExpressionsOptionsPage);
+    m_plugin->addAutoReleasedObject(new DebuggerOptionsPage);
 
-    if (IEditor *editor = EditorManager::currentEditor())
-        editor->widget()->setFocus();
+    connect(ModeManager::instance(), &ModeManager::currentModeChanged,
+        this, &DebuggerPluginPrivate::onModeChanged);
+    connect(ProjectExplorerPlugin::instance(), &ProjectExplorerPlugin::settingsChanged,
+        this, &DebuggerPluginPrivate::updateDebugWithoutDeployMenu);
 
-    m_toolTipManager.debugModeEntered();
-}
+    // Debug mode setup
+    m_debugMode = new DebugMode;
 
-void DebuggerPluginPrivate::onModeChangedHelper(IMode *mode)
-{
-    m_inDebugMode = (mode && mode->id() == Constants::MODE_DEBUG);
-    m_mainWindow->setDockActionsVisible(m_inDebugMode);
+    connect(SessionManager::instance(), &SessionManager::startupProjectChanged,
+            this, &DebuggerPluginPrivate::updateUiForProject);
 
-    // Hide all the debugger windows if mode is different.
-    if (m_inDebugMode) {
-//        readWindowSettings();
-        updateActiveLanguages();
-    } else {
-        // Hide dock widgets manually in case they are floating.
-        foreach (QDockWidget *dockWidget, m_mainWindow->dockWidgets()) {
-            if (dockWidget->isFloating())
-                dockWidget->hide();
-        }
-    }
-}
+    auto editorHolderLayout = new QVBoxLayout;
+    editorHolderLayout->setMargin(0);
+    editorHolderLayout->setSpacing(0);
 
-void DebuggerPluginPrivate::updateDebugWithoutDeployMenu()
-{
-    const bool state = ProjectExplorerPlugin::projectExplorerSettings().deployBeforeRun;
-    m_debugWithoutDeployAction->setVisible(state);
-}
+    auto editorAndFindWidget = new QWidget;
+    editorAndFindWidget->setLayout(editorHolderLayout);
+    auto editorManagerPlaceHolder = new EditorManagerPlaceHolder(m_debugMode);
+    editorHolderLayout->addWidget(editorManagerPlaceHolder);
+    editorHolderLayout->addWidget(new FindToolBarPlaceHolder(editorAndFindWidget));
 
-void DebuggerPluginPrivate::dumpLog()
-{
-    QString fileName = QFileDialog::getSaveFileName(ICore::mainWindow(),
-        tr("Save Debugger Log"), QDir::tempPath());
-    if (fileName.isEmpty())
-        return;
-    FileSaver saver(fileName);
-    if (!saver.hasError()) {
-        QTextStream ts(saver.file());
-        ts << m_logWindow->inputContents();
-        ts << "\n\n=======================================\n\n";
-        ts << m_logWindow->combinedContents();
-        saver.setResult(&ts);
-    }
-    saver.finalize(ICore::mainWindow());
-}
+    auto documentAndRightPane = new MiniSplitter;
+    documentAndRightPane->addWidget(editorAndFindWidget);
+    documentAndRightPane->addWidget(new RightPanePlaceHolder(m_debugMode));
+    documentAndRightPane->setStretchFactor(0, 1);
+    documentAndRightPane->setStretchFactor(1, 0);
 
-/*! Activates the previous mode when the current mode is the debug mode. */
-void DebuggerPluginPrivate::activatePreviousMode()
-{
-    if (ModeManager::currentMode() == ModeManager::mode(MODE_DEBUG)
-            && m_previousMode.isValid()) {
-        // If stopping the application also makes Qt Creator active (as the
-        // "previously active application"), doing the switch synchronously
-        // leads to funny effects with floating dock widgets
-        const Core::Id mode = m_previousMode;
-        QTimer::singleShot(0, this, [mode]() { ModeManager::activateMode(mode); });
-        m_previousMode = Id();
-    }
-}
+    auto centralWidget = new QWidget;
+    m_mainWindow->setCentralWidget(centralWidget);
 
-void DebuggerPluginPrivate::activateDebugMode()
-{
-    m_reverseDirectionAction->setChecked(false);
-    m_reverseDirectionAction->setEnabled(false);
-    m_previousMode = ModeManager::currentMode()->id();
-    ModeManager::activateMode(MODE_DEBUG);
-}
+    m_mainWindow->finalizeSetup();
 
-void DebuggerPluginPrivate::sessionLoaded()
-{
-    m_breakHandler->loadSessionData();
-    dummyEngine()->watchHandler()->loadSessionData();
-    DebuggerToolTipManager::loadSessionData();
-}
+    auto centralLayout = new QVBoxLayout(centralWidget);
+    centralWidget->setLayout(centralLayout);
+    centralLayout->setMargin(0);
+    centralLayout->setSpacing(0);
+    centralLayout->addWidget(documentAndRightPane);
+    centralLayout->setStretch(0, 1);
+    centralLayout->setStretch(1, 0);
 
-void DebuggerPluginPrivate::aboutToUnloadSession()
-{
-    m_toolTipManager.sessionAboutToChange();
-}
+    // Right-side window with editor, output etc.
+    auto mainWindowSplitter = new MiniSplitter;
+    mainWindowSplitter->addWidget(m_mainWindow);
+    mainWindowSplitter->addWidget(new OutputPanePlaceHolder(m_debugMode, mainWindowSplitter));
+    auto outputPane = new OutputPanePlaceHolder(m_debugMode, mainWindowSplitter);
+    outputPane->setObjectName(QLatin1String("DebuggerOutputPanePlaceHolder"));
+    mainWindowSplitter->addWidget(outputPane);
+    mainWindowSplitter->setStretchFactor(0, 10);
+    mainWindowSplitter->setStretchFactor(1, 0);
+    mainWindowSplitter->setOrientation(Qt::Vertical);
 
-void DebuggerPluginPrivate::aboutToSaveSession()
-{
-    dummyEngine()->watchHandler()->saveSessionData();
-    m_breakHandler->saveSessionData();
-    DebuggerToolTipManager::saveSessionData();
-}
+    // Navigation and right-side window.
+    auto splitter = new MiniSplitter;
+    splitter->setFocusProxy(editorManagerPlaceHolder);
+    splitter->addWidget(new NavigationWidgetPlaceHolder(m_debugMode));
+    splitter->addWidget(mainWindowSplitter);
+    splitter->setStretchFactor(0, 0);
+    splitter->setStretchFactor(1, 1);
+    splitter->setObjectName(QLatin1String("DebugModeWidget"));
 
-void DebuggerPluginPrivate::showStatusMessage(const QString &msg0, int timeout)
-{
-    showMessage(msg0, LogStatus);
-    QString msg = msg0;
-    msg.replace(QChar::LineFeed, QLatin1String("; "));
-    m_mainWindow->showStatusMessage(msg, timeout);
-}
+    IContext *modeContextObject = new IContext(this);
+    modeContextObject->setContext(Context(CC::C_EDITORMANAGER));
+    modeContextObject->setWidget(splitter);
+    ICore::addContextObject(modeContextObject);
+    m_debugMode->setWidget(splitter);
 
-void DebuggerPluginPrivate::coreShutdown()
-{
-    m_shuttingDown = true;
-}
+    m_plugin->addAutoReleasedObject(m_debugMode);
 
-const CPlusPlus::Snapshot &cppCodeModelSnapshot()
-{
-    if (dd->m_codeModelSnapshot.isEmpty() && action(UseCodeModel)->isChecked())
-        dd->m_codeModelSnapshot = CppTools::CppModelManager::instance()->snapshot();
-    return dd->m_codeModelSnapshot;
-}
 
-void setSessionValue(const QByteArray &key, const QVariant &value)
-{
-    SessionManager::setValue(QString::fromUtf8(key), value);
-}
+    //
+    //  Connections
+    //
 
-QVariant sessionValue(const QByteArray &key)
-{
-    return SessionManager::value(QString::fromUtf8(key));
-}
+    // Core
+    connect(ICore::instance(), &ICore::saveSettingsRequested,
+            this, &DebuggerPluginPrivate::writeSettings);
 
-QTreeView *inspectorView()
-{
-    return dd->m_inspectorView;
-}
+    // TextEditor
+    connect(TextEditorSettings::instance(), &TextEditorSettings::fontSettingsChanged,
+            this, &DebuggerPluginPrivate::fontSettingsChanged);
 
-void DebuggerPluginPrivate::showMessage(const QString &msg, int channel, int timeout)
-{
-    //qDebug() << "PLUGIN OUTPUT: " << channel << msg;
-    //ConsoleWindow *cw = m_consoleWindow;
-    QTC_ASSERT(m_logWindow, return);
-    switch (channel) {
-        case StatusBar:
-            // This will append to m_logWindow's output pane, too.
-            showStatusMessage(msg, timeout);
-            break;
-        case LogMiscInput:
-            m_logWindow->showInput(LogMisc, msg);
-            m_logWindow->showOutput(LogMisc, msg);
-            break;
-        case LogInput:
-            m_logWindow->showInput(LogInput, msg);
-            m_logWindow->showOutput(LogInput, msg);
-            break;
-        case LogError:
-            m_logWindow->showInput(LogError, QLatin1String("ERROR: ") + msg);
-            m_logWindow->showOutput(LogError, QLatin1String("ERROR: ") + msg);
-            break;
-        default:
-            m_logWindow->showOutput(channel, msg);
-            break;
-    }
-}
+    // ProjectExplorer
+    connect(SessionManager::instance(), &SessionManager::sessionLoaded,
+            this, &DebuggerPluginPrivate::sessionLoaded);
+    connect(SessionManager::instance(), &SessionManager::aboutToSaveSession,
+            this, &DebuggerPluginPrivate::aboutToSaveSession);
+    connect(SessionManager::instance(), &SessionManager::aboutToUnloadSession,
+            this, &DebuggerPluginPrivate::aboutToUnloadSession);
+    connect(ProjectExplorerPlugin::instance(), &ProjectExplorerPlugin::updateRunActions,
+            this, &DebuggerPluginPrivate::updateDebugActions);
 
-static void createNewDock(QWidget *widget)
-{
-    dd->createDockWidget(Core::Id::fromString(widget->objectName()), widget);
-    QDockWidget *dockWidget = qobject_cast<QDockWidget *>(widget->parentWidget());
-    dockWidget->setWindowTitle(widget->windowTitle());
-    dockWidget->setFeatures(QDockWidget::DockWidgetClosable);
-    dockWidget->show();
-}
+    // EditorManager
+    connect(EditorManager::instance(), &EditorManager::editorOpened,
+            this, &DebuggerPluginPrivate::editorOpened);
+    connect(EditorManager::instance(), &EditorManager::currentEditorChanged,
+            this, &DebuggerPluginPrivate::updateBreakMenuItem);
 
-static QString formatStartParameters(DebuggerRunParameters &sp)
-{
-    QString rc;
-    QTextStream str(&rc);
-    str << "Start parameters: '" << sp.displayName << "' mode: " << sp.startMode
-        << "\nABI: " << sp.toolChainAbi.toString() << '\n';
-    str << "Languages: ";
-    if (sp.languages == AnyLanguage)
-        str << "any";
-    if (sp.languages & CppLanguage)
-        str << "c++ ";
-    if (sp.languages & QmlLanguage)
-        str << "qml";
-    str << '\n';
-    if (!sp.inferior.executable.isEmpty()) {
-        str << "Executable: " << QDir::toNativeSeparators(sp.inferior.executable)
-            << ' ' << sp.inferior.commandLineArguments;
-        if (sp.useTerminal)
-            str << " [terminal]";
-        str << '\n';
-        if (!sp.inferior.workingDirectory.isEmpty())
-            str << "Directory: " << QDir::toNativeSeparators(sp.inferior.workingDirectory)
-                << '\n';
-    }
-    QString cmd = sp.debuggerCommand;
-    if (!cmd.isEmpty())
-        str << "Debugger: " << QDir::toNativeSeparators(cmd) << '\n';
-    if (!sp.coreFile.isEmpty())
-        str << "Core: " << QDir::toNativeSeparators(sp.coreFile) << '\n';
-    if (sp.attachPID > 0)
-        str << "PID: " << sp.attachPID << ' ' << sp.crashParameter << '\n';
-    if (!sp.projectSourceDirectory.isEmpty()) {
-        str << "Project: " << QDir::toNativeSeparators(sp.projectSourceDirectory);
-        str << "Addtional Search Directories:"
-            << sp.additionalSearchDirectories.join(QLatin1Char(' ')) << '\n';
-    }
-    if (!sp.qmlServerAddress.isEmpty())
-        str << "QML server: " << sp.qmlServerAddress << ':'
-            << sp.qmlServerPort << '\n';
-    if (!sp.remoteChannel.isEmpty())
-        str << "Remote: " << sp.remoteChannel << '\n';
-    str << "Sysroot: " << sp.sysRoot << '\n';
-    str << "Debug Source Location: " << sp.debugSourceLocation.join(QLatin1Char(':')) << '\n';
-    return rc;
-}
+    // Application interaction
+    connect(action(SettingsDialog), &QAction::triggered,
+            [] { ICore::showOptionsDialog(DEBUGGER_COMMON_SETTINGS_ID); });
 
-void DebuggerPluginPrivate::runControlStarted(DebuggerEngine *engine)
-{
-    activateDebugMode();
-    const QString message = tr("Starting debugger \"%1\" for ABI \"%2\"...")
-            .arg(engine->objectName())
-            .arg(engine->runParameters().toolChainAbi.toString());
-    showStatusMessage(message);
-    showMessage(formatStartParameters(engine->runParameters()), LogDebug);
-    showMessage(m_debuggerSettings->dump(), LogDebug);
-    m_snapshotHandler->appendSnapshot(engine);
-    connectEngine(engine);
-}
+    // Toolbar
+    ToolbarDescription toolbar;
+    toolbar.addAction(m_visibleStartAction);
+    toolbar.addAction(m_exitAction);
+    toolbar.addAction(m_nextAction);
+    toolbar.addAction(m_stepAction);
+    toolbar.addAction(m_stepOutAction);
+    toolbar.addAction(m_resetAction);
+    toolbar.addAction(m_operateByInstructionAction);
 
-void DebuggerPluginPrivate::runControlFinished(DebuggerEngine *engine)
-{
-    showStatusMessage(tr("Debugger finished."));
-    m_snapshotHandler->removeSnapshot(engine);
-    if (m_snapshotHandler->size() == 0) {
-        // Last engine quits.
-        disconnectEngine();
-        if (boolSetting(SwitchModeOnExit))
-            activatePreviousMode();
-    } else {
-        // Connect to some existing engine.
-        m_snapshotHandler->activateSnapshot(0);
+    if (isReverseDebuggingEnabled()) {
+        m_reverseToolButton = new QToolButton;
+        m_reverseToolButton->setDefaultAction(m_reverseDirectionAction);
+        toolbar.addWidget(m_reverseToolButton);
     }
-    action(OperateByInstruction)->setValue(QVariant(false));
-    m_logWindow->clearUndoRedoStacks();
-}
 
-void DebuggerPluginPrivate::remoteCommand(const QStringList &options)
-{
-    if (options.isEmpty())
-        return;
+    toolbar.addWidget(new StyledSeparator);
+    toolbar.addWidget(new QLabel(tr("Threads:")));
 
-    QString errorMessage;
+    m_threadBox = new QComboBox;
+    m_threadBox->setSizeAdjustPolicy(QComboBox::AdjustToContents);
+    connect(m_threadBox, static_cast<void(QComboBox::*)(int)>(&QComboBox::activated),
+            this, &DebuggerPluginPrivate::selectThread);
 
-    if (!parseArguments(options, &errorMessage)) {
-        qWarning("%s", qPrintable(errorMessage));
-        return;
-    }
-    runScheduled();
-}
+    toolbar.addWidget(m_threadBox);
+//    toolbar.addSpacerItem(new QSpacerItem(4, 0));
+
+//    ToolbarDescription qmlToolbar
+//    qmlToolbar.addAction(qmlUpdateOnSaveDummyAction);
+//    qmlToolbar.addAction(qmlShowAppOnTopDummyAction);
+//    qmlToolbar.addWidget(new StyledSeparator);
+//    qmlToolbar.addAction(qmlSelectDummyAction);
+//    qmlToolbar.addAction(qmlZoomDummyAction);
+//    qmlToolbar.addWidget(new StyledSeparator);
+
+    Perspective basePerspective({}, {
+        { DOCKWIDGET_STACK, m_stackWindow, {}, Perspective::SplitVertical },
+        { DOCKWIDGET_BREAK, m_breakWindow, DOCKWIDGET_STACK, Perspective::SplitHorizontal },
+        { DOCKWIDGET_THREADS, m_threadsWindow, DOCKWIDGET_BREAK, Perspective::AddToTab, false },
+        { DOCKWIDGET_MODULES, m_modulesWindow, DOCKWIDGET_THREADS, Perspective::AddToTab, false },
+        { DOCKWIDGET_SOURCE_FILES, m_sourceFilesWindow, DOCKWIDGET_MODULES, Perspective::AddToTab, false },
+        { DOCKWIDGET_SNAPSHOTS, m_snapshotWindow, DOCKWIDGET_SOURCE_FILES, Perspective::AddToTab, false },
+        { DOCKWIDGET_WATCHERS, m_localsAndExpressionsWindow, {}, Perspective::AddToTab, true,
+          Qt::RightDockWidgetArea },
+        { DOCKWIDGET_OUTPUT, m_logWindow, {}, Perspective::AddToTab, false, Qt::TopDockWidgetArea },
+        { DOCKWIDGET_BREAK, 0, {}, Perspective::Raise }
+    });
 
-QMessageBox *showMessageBox(int icon, const QString &title,
-    const QString &text, int buttons)
-{
-    QMessageBox *mb = new QMessageBox(QMessageBox::Icon(icon),
-        title, text, QMessageBox::StandardButtons(buttons),
-        ICore::mainWindow());
-    mb->setAttribute(Qt::WA_DeleteOnClose);
-    mb->setTextInteractionFlags(Qt::TextSelectableByMouse);
-    mb->show();
-    return mb;
+    Perspective cppPerspective = basePerspective;
+    cppPerspective.setName(tr("Debugger"));
+    cppPerspective.addOperation({ DOCKWIDGET_REGISTER, m_registerWindow, DOCKWIDGET_SNAPSHOTS,
+                                  Perspective::AddToTab, false });
+
+    Debugger::registerToolbar(CppPerspectiveId, toolbar);
+    Debugger::registerPerspective(CppPerspectiveId, cppPerspective);
+
+//    Perspective qmlPerspective = basePerspective;
+//    qmlPerspective.setName(tr("QML Debugger"));
+//    qmlPerspective.addOperation({ DOCKWIDGET_REGISTER, DOCKWIDGET_SNAPSHOTS,
+//                                  Perspective::AddToTab, false });
+//
+//    Debugger::registerToolbar(QmlPerspectiveId, toolbarContainer);
+//    Debugger::registerPerspective(QmlPerspectiveId, qmlPerspective);
+
+    connect(action(EnableReverseDebugging), &SavedAction::valueChanged,
+            this, &DebuggerPluginPrivate::enableReverseDebuggingTriggered);
+
+    setInitialState();
+    connectEngine(0);
+
+    connect(SessionManager::instance(), &SessionManager::startupProjectChanged,
+        this, &DebuggerPluginPrivate::onCurrentProjectChanged);
+
+    m_commonOptionsPage = new CommonOptionsPage(m_globalDebuggerOptions);
+    m_plugin->addAutoReleasedObject(m_commonOptionsPage);
+
+    m_globalDebuggerOptions->fromSettings();
+    m_watchersWindow->setVisible(false);
+    m_returnWindow->setVisible(false);
+
+    return true;
 }
 
-bool isReverseDebuggingEnabled()
+void setConfigValue(const QByteArray &name, const QVariant &value)
 {
-    static bool enabled = qEnvironmentVariableIsSet("QTC_DEBUGGER_ENABLE_REVERSE");
-    return enabled;
+    ICore::settings()->setValue(_("DebugMode/" + name), value);
 }
 
-bool isReverseDebugging()
+QVariant configValue(const QByteArray &name)
 {
-    return isReverseDebuggingEnabled() && dd->m_reverseDirectionAction->isChecked();
+    return ICore::settings()->value(_("DebugMode/" + name));
 }
 
-void DebuggerPluginPrivate::extensionsInitialized()
+void DebuggerPluginPrivate::onCurrentProjectChanged(Project *project)
 {
-    const QKeySequence debugKey = QKeySequence(UseMacShortcuts ? tr("Ctrl+Y") : tr("F5"));
+    RunConfiguration *activeRc = 0;
+    if (project) {
+        Target *target = project->activeTarget();
+        if (target)
+            activeRc = target->activeRunConfiguration();
+        if (!activeRc)
+            return;
+    }
+    for (int i = 0, n = m_snapshotHandler->size(); i != n; ++i) {
+        // Run controls might be deleted during exit.
+        if (DebuggerEngine *engine = m_snapshotHandler->at(i)) {
+            DebuggerRunControl *runControl = engine->runControl();
+            RunConfiguration *rc = runControl->runConfiguration();
+            if (rc == activeRc) {
+                m_snapshotHandler->setCurrentIndex(i);
+                updateState(engine);
+                return;
+            }
+        }
+    }
 
-    QSettings *settings = ICore::settings();
+    // If we have a running debugger, don't touch it.
+    if (m_snapshotHandler->size())
+        return;
 
-    m_debuggerSettings = new DebuggerSettings;
-    m_debuggerSettings->readSettings();
+    // No corresponding debugger found. So we are ready to start one.
+    m_interruptAction->setEnabled(false);
+    m_continueAction->setEnabled(false);
+    m_exitAction->setEnabled(false);
+    QString whyNot;
+    const bool canRun = ProjectExplorerPlugin::canRun(project, ProjectExplorer::Constants::DEBUG_RUN_MODE, &whyNot);
+    m_startAction->setEnabled(canRun);
+    m_startAction->setToolTip(whyNot);
+    m_debugWithoutDeployAction->setEnabled(canRun);
+    setProxyAction(m_visibleStartAction, Id(Constants::DEBUG));
+}
 
-    connect(ICore::instance(), &ICore::coreAboutToClose, this, &DebuggerPluginPrivate::coreShutdown);
+void DebuggerPluginPrivate::startAndDebugApplication()
+{
+    DebuggerRunParameters rp;
+    Kit *kit;
+    if (StartApplicationDialog::run(ICore::dialogParent(), &rp, &kit))
+        createAndScheduleRun(rp, kit);
+}
 
-    const Context cppDebuggercontext(C_CPPDEBUGGER);
-    const Context cppeditorcontext(CppEditor::Constants::CPPEDITOR_ID);
+void DebuggerPluginPrivate::attachCore()
+{
+    AttachCoreDialog dlg(ICore::dialogParent());
 
-    m_startIcon = Core::Icons::DEBUG_START_SMALL.icon();
-    m_exitIcon = Core::Icons::DEBUG_EXIT_SMALL.icon();
-    const QIcon continueSideBarIcon =
-            Icon::sideBarIcon(Icons::CONTINUE, Icons::CONTINUE_FLAT);
-    m_continueIcon = Icon::combinedIcon({Core::Icons::DEBUG_CONTINUE_SMALL.icon(), continueSideBarIcon});
-    const QIcon interruptSideBarIcon =
-            Icon::sideBarIcon(Icons::INTERRUPT, Icons::INTERRUPT_FLAT);
-    m_interruptIcon = Icon::combinedIcon({Core::Icons::DEBUG_INTERRUPT_SMALL.icon(), interruptSideBarIcon});
-    m_locationMarkIcon = Icons::LOCATION.icon();
-    m_resetIcon = Icons::RESTART.icon();
+    const QString lastExternalKit = configValue("LastExternalKit").toString();
+    if (!lastExternalKit.isEmpty())
+        dlg.setKitId(Id::fromString(lastExternalKit));
+    dlg.setLocalExecutableFile(configValue("LastExternalExecutableFile").toString());
+    dlg.setLocalCoreFile(configValue("LastLocalCoreFile").toString());
+    dlg.setRemoteCoreFile(configValue("LastRemoteCoreFile").toString());
+    dlg.setOverrideStartScript(configValue("LastExternalStartScript").toString());
+    dlg.setForceLocalCoreFile(configValue("LastForceLocalCoreFile").toBool());
 
-    m_busy = false;
+    if (dlg.exec() != QDialog::Accepted)
+        return;
 
-    m_logWindow = new LogWindow;
-    m_logWindow->setObjectName(QLatin1String(DOCKWIDGET_OUTPUT));
+    setConfigValue("LastExternalExecutableFile", dlg.localExecutableFile());
+    setConfigValue("LastLocalCoreFile", dlg.localCoreFile());
+    setConfigValue("LastRemoteCoreFile", dlg.remoteCoreFile());
+    setConfigValue("LastExternalKit", dlg.kit()->id().toSetting());
+    setConfigValue("LastExternalStartScript", dlg.overrideStartScript());
+    setConfigValue("LastForceLocalCoreFile", dlg.forcesLocalCoreFile());
 
-    m_breakHandler = new BreakHandler;
-    m_breakView = new BreakTreeView;
-    m_breakView->setSettings(settings, "Debugger.BreakWindow");
-    m_breakView->setModel(m_breakHandler->model());
-    m_breakWindow = addSearch(m_breakView, tr("Breakpoints"), DOCKWIDGET_BREAK);
+    QString display = dlg.useLocalCoreFile() ? dlg.localCoreFile() : dlg.remoteCoreFile();
+    DebuggerRunParameters rp;
+    rp.masterEngineType = DebuggerKitInformation::engineType(dlg.kit());
+    rp.inferior.executable = dlg.localExecutableFile();
+    rp.coreFile = dlg.localCoreFile();
+    rp.displayName = tr("Core file \"%1\"").arg(display);
+    rp.startMode = AttachCore;
+    rp.closeMode = DetachAtClose;
+    rp.overrideStartScript = dlg.overrideStartScript();
+    createAndScheduleRun(rp, dlg.kit());
+}
 
-    m_modulesView = new ModulesTreeView;
-    m_modulesView->setSettings(settings, "Debugger.ModulesView");
-    m_modulesWindow = addSearch(m_modulesView, tr("Modules"), DOCKWIDGET_MODULES);
-
-    m_registerView = new RegisterTreeView;
-    m_registerView->setSettings(settings, "Debugger.RegisterView");
-    m_registerWindow = addSearch(m_registerView, tr("Registers"), DOCKWIDGET_REGISTER);
-
-    m_stackView = new StackTreeView;
-    m_stackView->setSettings(settings, "Debugger.StackView");
-    m_stackWindow = addSearch(m_stackView, tr("Stack"), DOCKWIDGET_STACK);
+void DebuggerPluginPrivate::startRemoteCdbSession()
+{
+    const QByteArray connectionKey = "CdbRemoteConnection";
+    DebuggerRunParameters rp;
+    Kit *kit = findUniversalCdbKit();
+    QTC_ASSERT(kit, return);
+    rp.startMode = AttachToRemoteServer;
+    rp.closeMode = KillAtClose;
+    StartRemoteCdbDialog dlg(ICore::dialogParent());
+    QString previousConnection = configValue(connectionKey).toString();
+    if (previousConnection.isEmpty())
+        previousConnection = QLatin1String("localhost:1234");
+    dlg.setConnection(previousConnection);
+    if (dlg.exec() != QDialog::Accepted)
+        return;
+    rp.remoteChannel = dlg.connection();
+    setConfigValue(connectionKey, rp.remoteChannel);
+    createAndScheduleRun(rp, kit);
+}
 
-    m_sourceFilesView = new SourceFilesTreeView;
-    m_sourceFilesView->setSettings(settings, "Debugger.SourceFilesView");
-    m_sourceFilesWindow = addSearch(m_sourceFilesView, tr("Source Files"), DOCKWIDGET_SOURCE_FILES);
+void DebuggerPluginPrivate::attachToRemoteServer()
+{
+    DebuggerRunParameters rp;
+    Kit *kit;
+    rp.startMode = AttachToRemoteServer;
+    if (StartApplicationDialog::run(ICore::dialogParent(), &rp, &kit)) {
+        rp.closeMode = KillAtClose;
+        createAndScheduleRun(rp, kit);
+    }
+}
 
-    m_threadsView = new ThreadsTreeView;
-    m_threadsView->setSettings(settings, "Debugger.ThreadsView");
-    m_threadsWindow = addSearch(m_threadsView, tr("Threads"), DOCKWIDGET_THREADS);
+void DebuggerPluginPrivate::startRemoteServerAndAttachToProcess()
+{
+    auto kitChooser = new DebuggerKitChooser(DebuggerKitChooser::AnyDebugging);
+    auto dlg = new DeviceProcessesDialog(kitChooser, ICore::dialogParent());
+    dlg->addAcceptButton(DeviceProcessesDialog::tr("&Attach to Process"));
+    dlg->showAllDevices();
+    if (dlg->exec() == QDialog::Rejected) {
+        delete dlg;
+        return;
+    }
 
-    m_returnView = new WatchTreeView(ReturnType); // No settings.
-    m_returnWindow = addSearch(m_returnView, tr("Locals and Expressions"), "CppDebugReturn");
+    dlg->setAttribute(Qt::WA_DeleteOnClose);
+    Kit *kit = kitChooser->currentKit();
+    QTC_ASSERT(kit, return);
+    IDevice::ConstPtr device = DeviceKitInformation::device(kit);
+    QTC_ASSERT(device, return);
 
-    m_localsView = new WatchTreeView(LocalsType);
-    m_localsView->setSettings(settings, "Debugger.LocalsView");
-    m_localsWindow = addSearch(m_localsView, tr("Locals and Expressions"), "CppDebugLocals");
+    GdbServerStarter *starter = new GdbServerStarter(dlg, true);
+    starter->run();
+}
 
-    m_watchersView = new WatchTreeView(WatchersType); // No settings.
-    m_watchersWindow = addSearch(m_watchersView, tr("Locals and Expressions"), "CppDebugWatchers");
+void DebuggerPluginPrivate::attachToRunningApplication()
+{
+    auto kitChooser = new DebuggerKitChooser(DebuggerKitChooser::LocalDebugging);
 
-    m_inspectorView = new WatchTreeView(InspectType);
-    m_inspectorView->setSettings(settings, "Debugger.LocalsView"); // sic! same as locals view.
-    m_inspectorWindow = addSearch(m_inspectorView, tr("Locals and Expressions"), "Inspector");
+    auto dlg = new DeviceProcessesDialog(kitChooser, ICore::dialogParent());
+    dlg->addAcceptButton(DeviceProcessesDialog::tr("&Attach to Process"));
+    dlg->showAllDevices();
+    if (dlg->exec() == QDialog::Rejected) {
+        delete dlg;
+        return;
+    }
 
-    // Snapshot
-    m_snapshotHandler = new SnapshotHandler;
-    m_snapshotView = new SnapshotTreeView(m_snapshotHandler);
-    m_snapshotView->setSettings(settings, "Debugger.SnapshotView");
-    m_snapshotView->setModel(m_snapshotHandler->model());
-    m_snapshotWindow = addSearch(m_snapshotView, tr("Snapshots"), DOCKWIDGET_SNAPSHOTS);
+    dlg->setAttribute(Qt::WA_DeleteOnClose);
+    Kit *kit = kitChooser->currentKit();
+    QTC_ASSERT(kit, return);
+    IDevice::ConstPtr device = DeviceKitInformation::device(kit);
+    QTC_ASSERT(device, return);
 
-    // Watchers
-    connect(m_localsView->header(), &QHeaderView::sectionResized,
-        this, &DebuggerPluginPrivate::updateWatchersHeader, Qt::QueuedConnection);
+    if (device->type() == PE::DESKTOP_DEVICE_TYPE) {
+        attachToRunningProcess(kit, dlg->currentProcess(), false);
+    } else {
+        GdbServerStarter *starter = new GdbServerStarter(dlg, true);
+        starter->run();
+    }
+}
 
-    QAction *act = 0;
+void DebuggerPluginPrivate::attachToUnstartedApplicationDialog()
+{
+    auto dlg = new UnstartedAppWatcherDialog(ICore::dialogParent());
 
-    act = m_continueAction = new QAction(tr("Continue"), this);
-    act->setIcon(m_continueIcon);
-    connect(act, &QAction::triggered, this, &DebuggerPluginPrivate::handleExecContinue);
+    connect(dlg, &QDialog::finished, dlg, &QObject::deleteLater);
+    connect(dlg, &UnstartedAppWatcherDialog::processFound, this, [this, dlg] {
+        DebuggerRunControl *rc = attachToRunningProcess(dlg->currentKit(),
+                                                        dlg->currentProcess(),
+                                                        dlg->continueOnAttach());
+        if (!rc)
+            return;
 
-    act = m_exitAction = new QAction(tr("Stop Debugger"), this);
-    act->setIcon(m_exitIcon);
-    connect(act, &QAction::triggered, this, &DebuggerPluginPrivate::handleExecExit);
+        if (dlg->hideOnAttach())
+            connect(rc, &RunControl::finished, dlg, &UnstartedAppWatcherDialog::startWatching);
+    });
 
-    act = m_interruptAction = new QAction(tr("Interrupt"), this);
-    act->setIcon(m_interruptIcon);
-    connect(act, &QAction::triggered, this, &DebuggerPluginPrivate::handleExecInterrupt);
+    dlg->show();
+}
 
-    // A "disabled pause" seems to be a good choice.
-    act = m_undisturbableAction = new QAction(tr("Debugger is Busy"), this);
-    act->setIcon(m_interruptIcon);
-    act->setEnabled(false);
+DebuggerRunControl *DebuggerPluginPrivate::attachToRunningProcess(Kit *kit,
+    DeviceProcessItem process, bool contAfterAttach)
+{
+    QTC_ASSERT(kit, return 0);
+    IDevice::ConstPtr device = DeviceKitInformation::device(kit);
+    QTC_ASSERT(device, return 0);
+    if (process.pid == 0) {
+        AsynchronousMessageBox::warning(tr("Warning"), tr("Cannot attach to process with PID 0"));
+        return 0;
+    }
 
-    act = m_abortAction = new QAction(tr("Abort Debugging"), this);
-    act->setToolTip(tr("Aborts debugging and "
-        "resets the debugger to the initial state."));
-    connect(act, &QAction::triggered, this, &DebuggerPluginPrivate::handleAbort);
+    bool isWindows = false;
+    if (const ToolChain *tc = ToolChainKitInformation::toolChain(kit))
+        isWindows = tc->targetAbi().os() == Abi::WindowsOS;
+    if (isWindows && isWinProcessBeingDebugged(process.pid)) {
+        AsynchronousMessageBox::warning(tr("Process Already Under Debugger Control"),
+                             tr("The process %1 is already under the control of a debugger.\n"
+                                "Qt Creator cannot attach to it.").arg(process.pid));
+        return 0;
+    }
 
-    act = m_resetAction = new QAction(tr("Restart Debugging"),this);
-    act->setToolTip(tr("Restart the debugging session."));
-    act->setIcon(m_resetIcon);
-    connect(act, &QAction::triggered, this, &DebuggerPluginPrivate::handleReset);
+    if (device->type() != PE::DESKTOP_DEVICE_TYPE) {
+        AsynchronousMessageBox::warning(tr("Not a Desktop Device Type"),
+                             tr("It is only possible to attach to a locally running process."));
+        return 0;
+    }
 
-    act = m_nextAction = new QAction(tr("Step Over"), this);
-    act->setIcon(Icons::STEP_OVER.icon());
-    connect(act, &QAction::triggered, this, &DebuggerPluginPrivate::handleExecNext);
+    DebuggerRunParameters rp;
+    rp.attachPID = process.pid;
+    rp.displayName = tr("Process %1").arg(process.pid);
+    rp.inferior.executable = process.exe;
+    rp.startMode = AttachExternal;
+    rp.closeMode = DetachAtClose;
+    rp.continueAfterAttach = contAfterAttach;
+    return createAndScheduleRun(rp, kit);
+}
 
-    act = m_stepAction = new QAction(tr("Step Into"), this);
-    act->setIcon(Icons::STEP_INTO.icon());
-    connect(act, &QAction::triggered, this, &DebuggerPluginPrivate::handleExecStep);
+void DebuggerPlugin::attachExternalApplication(RunControl *rc)
+{
+    DebuggerRunParameters rp;
+    rp.attachPID = rc->applicationProcessHandle().pid();
+    rp.displayName = tr("Process %1").arg(rp.attachPID);
+    rp.startMode = AttachExternal;
+    rp.closeMode = DetachAtClose;
+    rp.toolChainAbi = rc->abi();
+    Kit *kit = 0;
+    if (const RunConfiguration *runConfiguration = rc->runConfiguration())
+        if (const Target *target = runConfiguration->target())
+            kit = target->kit();
+    createAndScheduleRun(rp, kit);
+}
 
-    act = m_stepOutAction = new QAction(tr("Step Out"), this);
-    act->setIcon(Icons::STEP_OUT.icon());
-    connect(act, &QAction::triggered, this, &DebuggerPluginPrivate::handleExecStepOut);
+void DebuggerPluginPrivate::attachToQmlPort()
+{
+    DebuggerRunParameters rp;
+    AttachToQmlPortDialog dlg(ICore::mainWindow());
 
-    act = m_runToLineAction = new QAction(tr("Run to Line"), this);
-    connect(act, &QAction::triggered, this, &DebuggerPluginPrivate::handleExecRunToLine);
+    const QVariant qmlServerPort = configValue("LastQmlServerPort");
+    if (qmlServerPort.isValid())
+        dlg.setPort(qmlServerPort.toInt());
+    else
+        dlg.setPort(rp.qmlServerPort);
 
-    act = m_runToSelectedFunctionAction =
-        new QAction(tr("Run to Selected Function"), this);
-    connect(act, &QAction::triggered, this, &DebuggerPluginPrivate::handleExecRunToSelectedFunction);
+    const Id kitId = Id::fromSetting(configValue("LastProfile"));
+    if (kitId.isValid())
+        dlg.setKitId(kitId);
 
-    act = m_returnFromFunctionAction =
-        new QAction(tr("Immediately Return From Inner Function"), this);
-    connect(act, &QAction::triggered, this, &DebuggerPluginPrivate::handleExecReturn);
+    if (dlg.exec() != QDialog::Accepted)
+        return;
 
-    act = m_jumpToLineAction = new QAction(tr("Jump to Line"), this);
-    connect(act, &QAction::triggered, this, &DebuggerPluginPrivate::handleExecJumpToLine);
+    Kit *kit = dlg.kit();
+    QTC_ASSERT(kit, return);
+    setConfigValue("LastQmlServerPort", dlg.port());
+    setConfigValue("LastProfile", kit->id().toSetting());
 
-    m_breakAction = new QAction(tr("Toggle Breakpoint"), this);
+    IDevice::ConstPtr device = DeviceKitInformation::device(kit);
+    if (device) {
+        rp.connParams = device->sshParameters();
+        rp.qmlServerAddress = device->qmlProfilerHost();
+    }
+    rp.qmlServerPort = dlg.port();
+    rp.startMode = AttachToRemoteProcess;
+    rp.closeMode = KillAtClose;
+    rp.languages = QmlLanguage;
+    rp.masterEngineType = QmlEngineType;
 
-    act = m_watchAction1 = new QAction(tr("Add Expression Evaluator"), this);
-    connect(act, &QAction::triggered, this, &DebuggerPluginPrivate::handleAddToWatchWindow);
+    //
+    // get files from all the projects in the session
+    //
+    QList<Project *> projects = SessionManager::projects();
+    if (Project *startupProject = SessionManager::startupProject()) {
+        // startup project first
+        projects.removeOne(startupProject);
+        projects.insert(0, startupProject);
+    }
+    QStringList sourceFiles;
+    foreach (Project *project, projects)
+        sourceFiles << project->files(Project::SourceFiles);
 
-    act = m_watchAction2 = new QAction(tr("Add Expression Evaluator"), this);
-    connect(act, &QAction::triggered, this, &DebuggerPluginPrivate::handleAddToWatchWindow);
+    rp.projectSourceDirectory =
+            !projects.isEmpty() ? projects.first()->projectDirectory().toString() : QString();
+    rp.projectSourceFiles = sourceFiles;
+    createAndScheduleRun(rp, kit);
+}
 
-    //m_snapshotAction = new QAction(tr("Create Snapshot"), this);
-    //m_snapshotAction->setProperty(Role, RequestCreateSnapshotRole);
-    //m_snapshotAction->setIcon(Icons::SNAPSHOT.icon());
+void DebuggerPluginPrivate::enableReverseDebuggingTriggered(const QVariant &value)
+{
+    QTC_ASSERT(m_reverseToolButton, return);
+    m_reverseToolButton->setVisible(value.toBool());
+    m_reverseDirectionAction->setChecked(false);
+    m_reverseDirectionAction->setEnabled(value.toBool());
+}
 
-    act = m_reverseDirectionAction = new QAction(tr("Reverse Direction"), this);
-    act->setCheckable(true);
-    act->setChecked(false);
-    act->setCheckable(false);
-    act->setIcon(Icons::REVERSE_MODE.icon());
-    act->setIconVisibleInMenu(false);
+void DebuggerPluginPrivate::runScheduled()
+{
+    for (int i = 0, n = m_scheduledStarts.size(); i != n; ++i)
+        createAndScheduleRun(m_scheduledStarts.at(i).first, m_scheduledStarts.at(i).second);
+}
 
-    act = m_frameDownAction = new QAction(tr("Move to Called Frame"), this);
-    connect(act, &QAction::triggered, this, &DebuggerPluginPrivate::handleFrameDown);
+void DebuggerPluginPrivate::editorOpened(IEditor *editor)
+{
+    if (auto widget = qobject_cast<TextEditorWidget *>(editor->widget())) {
+        connect(widget, &TextEditorWidget::markRequested,
+                this, &DebuggerPluginPrivate::requestMark);
 
-    act = m_frameUpAction = new QAction(tr("Move to Calling Frame"), this);
-    connect(act, &QAction::triggered, this, &DebuggerPluginPrivate::handleFrameUp);
+        connect(widget, &TextEditorWidget::markContextMenuRequested,
+                this, &DebuggerPluginPrivate::requestContextMenu);
+    }
+}
 
-    connect(action(OperateByInstruction), &QAction::triggered,
-            this, &DebuggerPluginPrivate::handleOperateByInstructionTriggered);
+void DebuggerPluginPrivate::updateBreakMenuItem(IEditor *editor)
+{
+    BaseTextEditor *textEditor = qobject_cast<BaseTextEditor *>(editor);
+    m_breakAction->setEnabled(textEditor != 0);
+}
 
-    ActionContainer *debugMenu = ActionManager::actionContainer(PE::M_DEBUG);
+void DebuggerPluginPrivate::requestContextMenu(TextEditorWidget *widget,
+    int lineNumber, QMenu *menu)
+{
+    Breakpoint bp;
+    TextDocument *document = widget->textDocument();
 
-    // Dock widgets
-    QDockWidget *dock = 0;
-    dock = createDockWidget(DOCKWIDGET_MODULES, m_modulesWindow);
-    connect(dock->toggleViewAction(), &QAction::toggled,
-        this, &DebuggerPluginPrivate::modulesDockToggled, Qt::QueuedConnection);
+    ContextData args = getLocationContext(document, lineNumber);
+    if (args.type == LocationByAddress) {
+        BreakpointResponse needle;
+        needle.type = BreakpointByAddress;
+        needle.address = args.address;
+        needle.lineNumber = -1;
+        bp = breakHandler()->findSimilarBreakpoint(needle);
+    } else if (args.type == LocationByFile) {
+        bp = breakHandler()->findBreakpointByFileAndLine(args.fileName, lineNumber);
+        if (!bp)
+            bp = breakHandler()->findBreakpointByFileAndLine(args.fileName, lineNumber, false);
+    }
 
-    dock = createDockWidget(DOCKWIDGET_REGISTER, m_registerWindow);
-    connect(dock->toggleViewAction(), &QAction::toggled,
-        this, &DebuggerPluginPrivate::registerDockToggled, Qt::QueuedConnection);
+    if (bp) {
+        QString id = bp.id().toString();
 
-    dock = createDockWidget(DOCKWIDGET_SOURCE_FILES, m_sourceFilesWindow);
-    connect(dock->toggleViewAction(), &QAction::toggled,
-        this, &DebuggerPluginPrivate::sourceFilesDockToggled, Qt::QueuedConnection);
+        // Remove existing breakpoint.
+        auto act = menu->addAction(tr("Remove Breakpoint %1").arg(id));
+        connect(act, &QAction::triggered, [bp] { bp.removeBreakpoint(); });
 
-    createDockWidget(DOCKWIDGET_OUTPUT, m_logWindow);
-    createDockWidget(DOCKWIDGET_BREAK, m_breakWindow);
-    createDockWidget(DOCKWIDGET_SNAPSHOTS, m_snapshotWindow);
-    createDockWidget(DOCKWIDGET_STACK, m_stackWindow);
-    createDockWidget(DOCKWIDGET_THREADS, m_threadsWindow);
+        // Enable/disable existing breakpoint.
+        if (bp.isEnabled()) {
+            act = menu->addAction(tr("Disable Breakpoint %1").arg(id));
+            connect(act, &QAction::triggered, [bp] { bp.setEnabled(false); });
+        } else {
+            act = menu->addAction(tr("Enable Breakpoint %1").arg(id));
+            connect(act, &QAction::triggered, [bp] { bp.setEnabled(true); });
+        }
 
-    m_localsAndExpressionsWindow = new LocalsAndExpressionsWindow(
-                m_localsWindow, m_inspectorWindow, m_returnWindow,
-                m_watchersWindow);
-    m_localsAndExpressionsWindow->setObjectName(QLatin1String(DOCKWIDGET_WATCHERS));
-    m_localsAndExpressionsWindow->setWindowTitle(m_localsWindow->windowTitle());
+        // Edit existing breakpoint.
+        act = menu->addAction(tr("Edit Breakpoint %1...").arg(id));
+        connect(act, &QAction::triggered, [bp] {
+            BreakTreeView::editBreakpoint(bp, ICore::dialogParent());
+        });
 
-    dock = createDockWidget(DOCKWIDGET_WATCHERS, m_localsAndExpressionsWindow);
+    } else {
+        // Handle non-existing breakpoint.
+        const QString text = args.address
+            ? tr("Set Breakpoint at 0x%1").arg(args.address, 0, 16)
+            : tr("Set Breakpoint at Line %1").arg(lineNumber);
+        auto act = menu->addAction(text);
+        act->setEnabled(args.isValid());
+        connect(act, &QAction::triggered, [this, args] {
+            breakpointSetMarginActionTriggered(false, args);
+        });
 
-    m_mainWindow->addDockActionsToMenu(m_viewsMenu->menu());
+        // Message trace point
+        const QString tracePointText = args.address
+            ? tr("Set Message Tracepoint at 0x%1...").arg(args.address, 0, 16)
+            : tr("Set Message Tracepoint at Line %1...").arg(lineNumber);
+        act = menu->addAction(tracePointText);
+        act->setEnabled(args.isValid());
+        connect(act, &QAction::triggered, [this, args] {
+            breakpointSetMarginActionTriggered(true, args);
+        });
+    }
 
-    m_plugin->addAutoReleasedObject(createDebuggerRunControlFactory(m_plugin));
+    // Run to, jump to line below in stopped state.
+    if (currentEngine()->state() == InferiorStopOk && args.isValid()) {
+        menu->addSeparator();
+        if (currentEngine()->hasCapability(RunToLineCapability)) {
+            auto act = menu->addAction(args.address
+                ? DebuggerEngine::tr("Run to Address 0x%1").arg(args.address, 0, 16)
+                : DebuggerEngine::tr("Run to Line %1").arg(args.lineNumber));
+            connect(act, &QAction::triggered, [this, args] {
+                currentEngine()->executeRunToLine(args);
+            });
+        }
+        if (currentEngine()->hasCapability(JumpToLineCapability)) {
+            auto act = menu->addAction(args.address
+                ? DebuggerEngine::tr("Jump to Address 0x%1").arg(args.address, 0, 16)
+                : DebuggerEngine::tr("Jump to Line %1").arg(args.lineNumber));
+            connect(act, &QAction::triggered, [this, args] {
+                currentEngine()->executeJumpToLine(args);
+            });
+        }
+        // Disassemble current function in stopped state.
+        if (currentEngine()->hasCapability(DisassemblerCapability)) {
+            StackFrame frame;
+            frame.function = cppFunctionAt(args.fileName, lineNumber, 1);
+            frame.line = 42; // trick gdb into mixed mode.
+            if (!frame.function.isEmpty()) {
+                const QString text = tr("Disassemble Function \"%1\"")
+                    .arg(frame.function);
+                auto act = new QAction(text, menu);
+                connect(act, &QAction::triggered, [this, frame] {
+                    currentEngine()->openDisassemblerView(Location(frame));
+                });
+                menu->addAction(act);
+            }
+        }
+    }
+}
 
-    // The main "Start Debugging" action.
-    act = m_startAction = new QAction(this);
-    const QIcon sideBarIcon =
-            Icon::sideBarIcon(ProjectExplorer::Icons::DEBUG_START, ProjectExplorer::Icons::DEBUG_START_FLAT);
-    const QIcon debuggerIcon = Icon::combinedIcon({Core::Icons::DEBUG_START_SMALL.icon(), sideBarIcon});
-    act->setIcon(debuggerIcon);
-    act->setText(tr("Start Debugging"));
-    connect(act, &QAction::triggered, [] { ProjectExplorerPlugin::runStartupProject(ProjectExplorer::Constants::DEBUG_RUN_MODE); });
+void DebuggerPluginPrivate::toggleBreakpoint(const ContextData &location, const QString &tracePointMessage)
+{
+    QTC_ASSERT(location.isValid(), return);
+    BreakHandler *handler = m_breakHandler;
+    Breakpoint bp;
+    if (location.type == LocationByFile) {
+        bp = handler->findBreakpointByFileAndLine(location.fileName, location.lineNumber, true);
+        if (!bp)
+            bp = handler->findBreakpointByFileAndLine(location.fileName, location.lineNumber, false);
+    } else if (location.type == LocationByAddress) {
+        bp = handler->findBreakpointByAddress(location.address);
+    }
 
-    act = m_debugWithoutDeployAction = new QAction(this);
-    act->setText(tr("Start Debugging Without Deployment"));
-    connect(act, &QAction::triggered, [] { ProjectExplorerPlugin::runStartupProject(ProjectExplorer::Constants::DEBUG_RUN_MODE, true); });
+    if (bp) {
+        bp.removeBreakpoint();
+    } else {
+        BreakpointParameters data;
+        if (location.type == LocationByFile) {
+            data.type = BreakpointByFileAndLine;
+            if (boolSetting(BreakpointsFullPathByDefault))
+                data.pathUsage = BreakpointUseFullPath;
+            data.tracepoint = !tracePointMessage.isEmpty();
+            data.message = tracePointMessage;
+            data.fileName = location.fileName;
+            data.lineNumber = location.lineNumber;
+        } else if (location.type == LocationByAddress) {
+            data.type = BreakpointByAddress;
+            data.tracepoint = !tracePointMessage.isEmpty();
+            data.message = tracePointMessage;
+            data.address = location.address;
+        }
+        handler->appendBreakpoint(data);
+    }
+}
 
-    act = m_startAndDebugApplicationAction = new QAction(this);
-    act->setText(tr("Start and Debug External Application..."));
-    connect(act, &QAction::triggered, this, &DebuggerPluginPrivate::startAndDebugApplication);
+void DebuggerPluginPrivate::toggleBreakpointHelper()
+{
+    BaseTextEditor *textEditor = BaseTextEditor::currentTextEditor();
+    QTC_ASSERT(textEditor, return);
+    const int lineNumber = textEditor->currentLine();
+    ContextData location = getLocationContext(textEditor->textDocument(), lineNumber);
+    if (location.isValid())
+        toggleBreakpoint(location);
+}
 
-    act = m_attachToCoreAction = new QAction(this);
-    act->setText(tr("Load Core File..."));
-    connect(act, &QAction::triggered, this, &DebuggerPluginPrivate::attachCore);
+void DebuggerPluginPrivate::requestMark(TextEditorWidget *widget, int lineNumber,
+                                        TextMarkRequestKind kind)
+{
+    if (kind == BreakpointRequest) {
+        ContextData location = getLocationContext(widget->textDocument(), lineNumber);
+        if (location.isValid())
+            toggleBreakpoint(location);
+    }
+}
 
-    act = m_attachToRemoteServerAction = new QAction(this);
-    act->setText(tr("Attach to Running Debug Server..."));
-    connect(act, &QAction::triggered, this, &DebuggerPluginPrivate::attachToRemoteServer);
+// If updateEngine is set, the engine will update its threads/modules and so forth.
+void DebuggerPluginPrivate::displayDebugger(DebuggerEngine *engine, bool updateEngine)
+{
+    QTC_ASSERT(engine, return);
+    disconnectEngine();
+    connectEngine(engine);
+    if (updateEngine)
+        engine->updateAll();
+    engine->updateViews();
+}
 
-    act = m_startRemoteServerAction = new QAction(this);
-    act->setText(tr("Start Debug Server Attached to Process..."));
-    connect(act, &QAction::triggered, this, &DebuggerPluginPrivate::startRemoteServerAndAttachToProcess);
+void DebuggerPluginPrivate::connectEngine(DebuggerEngine *engine)
+{
+    if (!engine)
+        engine = dummyEngine();
 
-    act = m_attachToRunningApplication = new QAction(this);
-    act->setText(tr("Attach to Running Application..."));
-    connect(act, &QAction::triggered, this, &DebuggerPluginPrivate::attachToRunningApplication);
+    if (m_currentEngine == engine)
+        return;
 
-    act = m_attachToUnstartedApplication = new QAction(this);
-    act->setText(tr("Attach to Unstarted Application..."));
-    connect(act, &QAction::triggered, this, &DebuggerPluginPrivate::attachToUnstartedApplicationDialog);
+    if (m_currentEngine)
+        m_currentEngine->resetLocation();
+    m_currentEngine = engine;
 
-    act = m_attachToQmlPortAction = new QAction(this);
-    act->setText(tr("Attach to QML Port..."));
-    connect(act, &QAction::triggered, this, &DebuggerPluginPrivate::attachToQmlPort);
+    m_localsView->setModel(engine->watchModel());
+    m_modulesView->setModel(engine->modulesModel());
+    m_registerView->setModel(engine->registerModel());
+    m_returnView->setModel(engine->watchModel());
+    m_sourceFilesView->setModel(engine->sourceFilesModel());
+    m_stackView->setModel(engine->stackModel());
+    m_threadsView->setModel(engine->threadsModel());
+    m_watchersView->setModel(engine->watchModel());
+    m_inspectorView->setModel(engine->watchModel());
 
-    if (HostOsInfo::isWindowsHost()) {
-        m_startRemoteCdbAction = new QAction(tr("Attach to Remote CDB Session..."), this);
-        connect(m_startRemoteCdbAction, &QAction::triggered,
-                this, &DebuggerPluginPrivate::startRemoteCdbSession);
-    }
+    engine->watchHandler()->resetWatchers();
+    m_localsView->hideProgressIndicator();
+}
 
-    act = m_detachAction = new QAction(this);
-    act->setText(tr("Detach Debugger"));
-    connect(act, &QAction::triggered, this, &DebuggerPluginPrivate::handleExecDetach);
+static void changeFontSize(QWidget *widget, qreal size)
+{
+    QFont font = widget->font();
+    font.setPointSizeF(size);
+    widget->setFont(font);
+}
 
-    // "Start Debugging" sub-menu
-    // groups:
-    //   G_DEFAULT_ONE
-    //   G_START_LOCAL
-    //   G_START_REMOTE
-    //   G_START_QML
-
-    Command *cmd = 0;
-    ActionContainer *mstart = ActionManager::actionContainer(PE::M_DEBUG_STARTDEBUGGING);
-
-    cmd = ActionManager::registerAction(m_startAction, Constants::DEBUG);
-    cmd->setDescription(tr("Start Debugging"));
-    cmd->setDefaultKeySequence(debugKey);
-    cmd->setAttribute(Command::CA_UpdateText);
-    mstart->addAction(cmd, CC::G_DEFAULT_ONE);
-    m_visibleStartAction = new ProxyAction(this);
-    m_visibleStartAction->initialize(cmd->action());
-    m_visibleStartAction->setAttribute(ProxyAction::UpdateText);
-    m_visibleStartAction->setAttribute(ProxyAction::UpdateIcon);
-    m_visibleStartAction->setAction(cmd->action());
-
-    ModeManager::addAction(m_visibleStartAction, Constants::P_ACTION_DEBUG);
+void DebuggerPluginPrivate::fontSettingsChanged(const FontSettings &settings)
+{
+    if (!boolSetting(FontSizeFollowsEditor))
+        return;
+    qreal size = settings.fontZoom() * settings.fontSize() / 100.;
+    changeFontSize(m_breakWindow, size);
+    changeFontSize(m_logWindow, size);
+    changeFontSize(m_localsWindow, size);
+    changeFontSize(m_modulesWindow, size);
+    //changeFontSize(m_consoleWindow, size);
+    changeFontSize(m_registerWindow, size);
+    changeFontSize(m_returnWindow, size);
+    changeFontSize(m_sourceFilesWindow, size);
+    changeFontSize(m_stackWindow, size);
+    changeFontSize(m_threadsWindow, size);
+    changeFontSize(m_watchersWindow, size);
+    changeFontSize(m_inspectorWindow, size);
+}
 
-    cmd = ActionManager::registerAction(m_debugWithoutDeployAction,
-        "Debugger.DebugWithoutDeploy");
-    cmd->setAttribute(Command::CA_Hide);
-    mstart->addAction(cmd, CC::G_DEFAULT_ONE);
+void DebuggerPluginPrivate::cleanupViews()
+{
+    m_reverseDirectionAction->setChecked(false);
+    m_reverseDirectionAction->setEnabled(false);
 
-    cmd = ActionManager::registerAction(m_attachToRunningApplication,
-         "Debugger.AttachToRemoteProcess");
-    cmd->setDescription(tr("Attach to Running Application"));
-    mstart->addAction(cmd, G_GENERAL);
+    const bool closeSource = boolSetting(CloseSourceBuffersOnExit);
+    const bool closeMemory = boolSetting(CloseMemoryBuffersOnExit);
 
-    cmd = ActionManager::registerAction(m_attachToUnstartedApplication,
-          "Debugger.AttachToUnstartedProcess");
-    cmd->setDescription(tr("Attach to Unstarted Application"));
-    mstart->addAction(cmd, G_GENERAL);
+    QList<IDocument *> toClose;
+    foreach (IDocument *document, DocumentModel::openedDocuments()) {
+        const bool isMemory = document->property(Constants::OPENED_WITH_DISASSEMBLY).toBool();
+        if (document->property(Constants::OPENED_BY_DEBUGGER).toBool()) {
+            bool keepIt = true;
+            if (document->isModified())
+                keepIt = true;
+            else if (document->filePath().toString().contains(_("qeventdispatcher")))
+                keepIt = false;
+            else if (isMemory)
+                keepIt = !closeMemory;
+            else
+                keepIt = !closeSource;
 
-    cmd = ActionManager::registerAction(m_startAndDebugApplicationAction,
-        "Debugger.StartAndDebugApplication");
-    cmd->setAttribute(Command::CA_Hide);
-    mstart->addAction(cmd, G_GENERAL);
+            if (keepIt)
+                document->setProperty(Constants::OPENED_BY_DEBUGGER, false);
+            else
+                toClose.append(document);
+        }
+    }
+    EditorManager::closeDocuments(toClose);
+}
 
-    cmd = ActionManager::registerAction(m_attachToCoreAction,
-        "Debugger.AttachCore");
-    cmd->setAttribute(Command::CA_Hide);
-    mstart->addAction(cmd, Constants::G_GENERAL);
+void DebuggerPluginPrivate::setBusyCursor(bool busy)
+{
+    //STATE_DEBUG("BUSY FROM: " << m_busy << " TO: " << busy);
+    if (busy == m_busy)
+        return;
+    m_busy = busy;
+    QCursor cursor(busy ? Qt::BusyCursor : Qt::ArrowCursor);
+    m_breakWindow->setCursor(cursor);
+    //m_consoleWindow->setCursor(cursor);
+    m_localsWindow->setCursor(cursor);
+    m_modulesWindow->setCursor(cursor);
+    m_logWindow->setCursor(cursor);
+    m_registerWindow->setCursor(cursor);
+    m_returnWindow->setCursor(cursor);
+    m_sourceFilesWindow->setCursor(cursor);
+    m_stackWindow->setCursor(cursor);
+    m_threadsWindow->setCursor(cursor);
+    m_watchersWindow->setCursor(cursor);
+    m_snapshotWindow->setCursor(cursor);
+}
 
-    cmd = ActionManager::registerAction(m_attachToRemoteServerAction,
-        "Debugger.AttachToRemoteServer");
-    cmd->setAttribute(Command::CA_Hide);
-    mstart->addAction(cmd, Constants::G_SPECIAL);
+void DebuggerPluginPrivate::setInitialState()
+{
+    m_watchersWindow->setVisible(false);
+    m_returnWindow->setVisible(false);
+    setBusyCursor(false);
+    m_reverseDirectionAction->setChecked(false);
+    m_reverseDirectionAction->setEnabled(false);
+    m_toolTipManager.closeAllToolTips();
 
-    cmd = ActionManager::registerAction(m_startRemoteServerAction,
-         "Debugger.StartRemoteServer");
-    cmd->setDescription(tr("Start Gdbserver"));
-    mstart->addAction(cmd, Constants::G_SPECIAL);
+    m_startAndDebugApplicationAction->setEnabled(true);
+    m_attachToQmlPortAction->setEnabled(true);
+    m_attachToCoreAction->setEnabled(true);
+    m_attachToRemoteServerAction->setEnabled(true);
+    m_attachToRunningApplication->setEnabled(true);
+    m_attachToUnstartedApplication->setEnabled(true);
+    m_detachAction->setEnabled(false);
 
-    if (m_startRemoteCdbAction) {
-        cmd = ActionManager::registerAction(m_startRemoteCdbAction,
-             "Debugger.AttachRemoteCdb");
-        cmd->setAttribute(Command::CA_Hide);
-        mstart->addAction(cmd, Constants::G_SPECIAL);
-    }
+    m_watchAction1->setEnabled(true);
+    m_watchAction2->setEnabled(true);
+    m_breakAction->setEnabled(false);
+    //m_snapshotAction->setEnabled(false);
+    m_operateByInstructionAction->setEnabled(false);
 
-    mstart->addSeparator(Context(CC::C_GLOBAL), Constants::G_START_QML);
+    m_exitAction->setEnabled(false);
+    m_abortAction->setEnabled(false);
+    m_resetAction->setEnabled(false);
 
-    cmd = ActionManager::registerAction(m_attachToQmlPortAction, "Debugger.AttachToQmlPort");
-    cmd->setAttribute(Command::CA_Hide);
-    mstart->addAction(cmd, Constants::G_START_QML);
+    m_interruptAction->setEnabled(false);
+    m_continueAction->setEnabled(false);
 
-    cmd = ActionManager::registerAction(m_detachAction, "Debugger.Detach");
-    cmd->setAttribute(Command::CA_Hide);
-    debugMenu->addAction(cmd, CC::G_DEFAULT_ONE);
+    m_stepAction->setEnabled(true);
+    m_stepOutAction->setEnabled(false);
+    m_runToLineAction->setEnabled(false);
+    m_runToSelectedFunctionAction->setEnabled(true);
+    m_returnFromFunctionAction->setEnabled(false);
+    m_jumpToLineAction->setEnabled(false);
+    m_nextAction->setEnabled(true);
 
-    cmd = ActionManager::registerAction(m_interruptAction, Constants::INTERRUPT);
-    cmd->setDescription(tr("Interrupt Debugger"));
-    debugMenu->addAction(cmd, CC::G_DEFAULT_ONE);
+    action(AutoDerefPointers)->setEnabled(true);
+    action(ExpandStack)->setEnabled(false);
+}
 
-    cmd = ActionManager::registerAction(m_continueAction, Constants::CONTINUE);
-    cmd->setDefaultKeySequence(debugKey);
-    debugMenu->addAction(cmd, CC::G_DEFAULT_ONE);
+void DebuggerPluginPrivate::updateState(DebuggerEngine *engine)
+{
+    QTC_ASSERT(engine, return);
+    QTC_ASSERT(m_watchersView->model(), return);
+    QTC_ASSERT(m_returnView->model(), return);
+    QTC_ASSERT(!engine->isSlaveEngine(), return);
 
-    cmd = ActionManager::registerAction(m_exitAction, Constants::STOP);
-    debugMenu->addAction(cmd, CC::G_DEFAULT_ONE);
-    m_hiddenStopAction = new ProxyAction(this);
-    m_hiddenStopAction->initialize(cmd->action());
-    m_hiddenStopAction->setAttribute(ProxyAction::UpdateText);
-    m_hiddenStopAction->setAttribute(ProxyAction::UpdateIcon);
+    m_threadBox->setCurrentIndex(engine->threadsHandler()->currentThreadIndex());
 
-    cmd = ActionManager::registerAction(m_hiddenStopAction, Constants::HIDDEN_STOP);
-    cmd->setDefaultKeySequence(QKeySequence(UseMacShortcuts ? tr("Shift+Ctrl+Y") : tr("Shift+F5")));
+    const DebuggerState state = engine->state();
+    //showMessage(QString::fromLatin1("PLUGIN SET STATE: ")
+    //    + DebuggerEngine::stateName(state), LogStatus);
+    //qDebug() << "PLUGIN SET STATE: " << state;
 
-    cmd = ActionManager::registerAction(m_abortAction, Constants::ABORT);
-    cmd->setDescription(tr("Reset Debugger"));
-    debugMenu->addAction(cmd, CC::G_DEFAULT_ONE);
+    static DebuggerState previousState = DebuggerNotReady;
+    if (state == previousState)
+        return;
 
-    cmd = ActionManager::registerAction(m_resetAction, Constants::RESET);
-    cmd->setDescription(tr("Restart Debugging"));
-    debugMenu->addAction(cmd, CC::G_DEFAULT_ONE);
+    bool actionsEnabled = DebuggerEngine::debuggerActionsEnabled(state);
 
-    debugMenu->addSeparator();
+    if (state == DebuggerNotReady) {
+        QTC_ASSERT(false, /* We use the Core's m_debugAction here */);
+        // F5 starts debugging. It is "startable".
+        m_interruptAction->setEnabled(false);
+        m_continueAction->setEnabled(false);
+        m_exitAction->setEnabled(false);
+        m_startAction->setEnabled(true);
+        m_debugWithoutDeployAction->setEnabled(true);
+        setProxyAction(m_visibleStartAction, Id(Constants::DEBUG));
+        m_hiddenStopAction->setAction(m_undisturbableAction);
+    } else if (state == InferiorStopOk) {
+        // F5 continues, Shift-F5 kills. It is "continuable".
+        m_interruptAction->setEnabled(false);
+        m_continueAction->setEnabled(true);
+        m_exitAction->setEnabled(true);
+        m_startAction->setEnabled(false);
+        m_debugWithoutDeployAction->setEnabled(false);
+        setProxyAction(m_visibleStartAction, Id(Constants::CONTINUE));
+        m_hiddenStopAction->setAction(m_exitAction);
+        m_localsAndExpressionsWindow->setShowLocals(true);
+    } else if (state == InferiorRunOk) {
+        // Shift-F5 interrupts. It is also "interruptible".
+        m_interruptAction->setEnabled(true);
+        m_continueAction->setEnabled(false);
+        m_exitAction->setEnabled(true);
+        m_startAction->setEnabled(false);
+        m_debugWithoutDeployAction->setEnabled(false);
+        setProxyAction(m_visibleStartAction, Id(Constants::INTERRUPT));
+        m_hiddenStopAction->setAction(m_interruptAction);
+        m_localsAndExpressionsWindow->setShowLocals(false);
+        activateDebugMode();
+    } else if (state == DebuggerFinished) {
+        Project *project = SessionManager::startupProject();
+        const bool canRun = ProjectExplorerPlugin::canRun(project, ProjectExplorer::Constants::DEBUG_RUN_MODE);
+        // We don't want to do anything anymore.
+        m_interruptAction->setEnabled(false);
+        m_continueAction->setEnabled(false);
+        m_exitAction->setEnabled(false);
+        m_startAction->setEnabled(canRun);
+        m_debugWithoutDeployAction->setEnabled(canRun);
+        setProxyAction(m_visibleStartAction, Id(Constants::DEBUG));
+        m_hiddenStopAction->setAction(m_undisturbableAction);
+        m_codeModelSnapshot = CPlusPlus::Snapshot();
+        setBusyCursor(false);
+        cleanupViews();
+    } else if (state == InferiorUnrunnable) {
+        // We don't want to do anything anymore.
+        m_interruptAction->setEnabled(false);
+        m_continueAction->setEnabled(false);
+        m_exitAction->setEnabled(true);
+        m_startAction->setEnabled(false);
+        m_debugWithoutDeployAction->setEnabled(false);
+        m_visibleStartAction->setAction(m_undisturbableAction);
+        m_hiddenStopAction->setAction(m_exitAction);
+        // show locals in core dumps
+        m_localsAndExpressionsWindow->setShowLocals(true);
+        activateDebugMode();
+    } else {
+        // Everything else is "undisturbable".
+        m_interruptAction->setEnabled(false);
+        m_continueAction->setEnabled(false);
+        m_exitAction->setEnabled(false);
+        m_startAction->setEnabled(false);
+        m_debugWithoutDeployAction->setEnabled(false);
+        m_visibleStartAction->setAction(m_undisturbableAction);
+        m_hiddenStopAction->setAction(m_undisturbableAction);
+    }
 
-    cmd = ActionManager::registerAction(m_nextAction, Constants::NEXT);
-    cmd->setDefaultKeySequence(QKeySequence(UseMacShortcuts ? tr("Ctrl+Shift+O") : tr("F10")));
-    cmd->setAttribute(Command::CA_Hide);
-    cmd->setAttribute(Command::CA_UpdateText);
-    debugMenu->addAction(cmd);
+    m_startAndDebugApplicationAction->setEnabled(true);
+    m_attachToQmlPortAction->setEnabled(true);
+    m_attachToCoreAction->setEnabled(true);
+    m_attachToRemoteServerAction->setEnabled(true);
+    m_attachToRunningApplication->setEnabled(true);
+    m_attachToUnstartedApplication->setEnabled(true);
 
-    cmd = ActionManager::registerAction(m_stepAction, Constants::STEP);
-    cmd->setDefaultKeySequence(QKeySequence(UseMacShortcuts ? tr("Ctrl+Shift+I") : tr("F11")));
-    cmd->setAttribute(Command::CA_Hide);
-    cmd->setAttribute(Command::CA_UpdateText);
-    debugMenu->addAction(cmd);
+    m_threadBox->setEnabled(state == InferiorStopOk || state == InferiorUnrunnable);
 
-    cmd = ActionManager::registerAction(m_stepOutAction,
-        Constants::STEPOUT, cppDebuggercontext);
-    cmd->setDefaultKeySequence(QKeySequence(UseMacShortcuts ? tr("Ctrl+Shift+T") : tr("Shift+F11")));
-    cmd->setAttribute(Command::CA_Hide);
-    debugMenu->addAction(cmd);
+    const bool isCore = engine->runParameters().startMode == AttachCore;
+    const bool stopped = state == InferiorStopOk;
+    const bool detachable = stopped && !isCore;
+    m_detachAction->setEnabled(detachable);
 
-    cmd = ActionManager::registerAction(m_runToLineAction,
-        "Debugger.RunToLine", cppDebuggercontext);
-    cmd->setDefaultKeySequence(QKeySequence(UseMacShortcuts ? tr("Shift+F8") : tr("Ctrl+F10")));
-    cmd->setAttribute(Command::CA_Hide);
-    debugMenu->addAction(cmd);
+    if (stopped)
+        QApplication::alert(mainWindow(), 3000);
 
-    cmd = ActionManager::registerAction(m_runToSelectedFunctionAction,
-        "Debugger.RunToSelectedFunction", cppDebuggercontext);
-    cmd->setDefaultKeySequence(QKeySequence(tr("Ctrl+F6")));
-    cmd->setAttribute(Command::CA_Hide);
-    // Don't add to menu by default as keeping its enabled state
-    // and text up-to-date is a lot of hassle.
-    // debugMenu->addAction(cmd);
+    const bool canReverse = engine->hasCapability(ReverseSteppingCapability)
+                && boolSetting(EnableReverseDebugging);
+    m_reverseDirectionAction->setEnabled(canReverse);
 
-    cmd = ActionManager::registerAction(m_jumpToLineAction,
-        "Debugger.JumpToLine", cppDebuggercontext);
-    cmd->setAttribute(Command::CA_Hide);
-    debugMenu->addAction(cmd);
+    m_watchAction1->setEnabled(true);
+    m_watchAction2->setEnabled(true);
+    m_breakAction->setEnabled(true);
 
-    cmd = ActionManager::registerAction(m_returnFromFunctionAction,
-        "Debugger.ReturnFromFunction", cppDebuggercontext);
-    cmd->setAttribute(Command::CA_Hide);
-    debugMenu->addAction(cmd);
+    const bool canOperateByInstruction = engine->hasCapability(OperateByInstructionCapability)
+            && (stopped || isCore);
+    m_operateByInstructionAction->setEnabled(canOperateByInstruction);
 
-    if (isReverseDebuggingEnabled()) {
-        cmd = ActionManager::registerAction(m_reverseDirectionAction,
-                                            Constants::REVERSE, cppDebuggercontext);
-        cmd->setDefaultKeySequence(QKeySequence(UseMacShortcuts ? QString() : tr("F12")));
-        cmd->setAttribute(Command::CA_Hide);
-        debugMenu->addAction(cmd);
-    }
+    m_abortAction->setEnabled(state != DebuggerNotReady
+                                      && state != DebuggerFinished);
+    m_resetAction->setEnabled((stopped || state == DebuggerNotReady)
+                              && engine->hasCapability(ResetInferiorCapability));
 
-    debugMenu->addSeparator();
+    m_stepAction->setEnabled(stopped || state == DebuggerNotReady);
+    m_nextAction->setEnabled(stopped || state == DebuggerNotReady);
+    m_stepAction->setToolTip(QString());
+    m_nextAction->setToolTip(QString());
 
-    //cmd = ActionManager::registerAction(m_snapshotAction,
-    //    "Debugger.Snapshot", cppDebuggercontext);
-    //cmd->setDefaultKeySequence(QKeySequence(tr("Ctrl+D,Ctrl+S")));
-    //cmd->setAttribute(Command::CA_Hide);
-    //debugMenu->addAction(cmd);
+    m_stepOutAction->setEnabled(stopped);
+    m_runToLineAction->setEnabled(stopped && engine->hasCapability(RunToLineCapability));
+    m_runToSelectedFunctionAction->setEnabled(stopped);
+    m_returnFromFunctionAction->
+        setEnabled(stopped && engine->hasCapability(ReturnFromFunctionCapability));
 
-    ActionManager::registerAction(m_frameDownAction,
-        "Debugger.FrameDown", cppDebuggercontext);
-    ActionManager::registerAction(m_frameUpAction,
-        "Debugger.FrameUp", cppDebuggercontext);
+    const bool canJump = stopped && engine->hasCapability(JumpToLineCapability);
+    m_jumpToLineAction->setEnabled(canJump);
 
-    cmd = ActionManager::registerAction(action(OperateByInstruction),
-        Constants::OPERATE_BY_INSTRUCTION, cppDebuggercontext);
-    cmd->setAttribute(Command::CA_Hide);
-    debugMenu->addAction(cmd);
+    const bool canDeref = actionsEnabled && engine->hasCapability(AutoDerefPointersCapability);
+    action(AutoDerefPointers)->setEnabled(canDeref);
+    action(AutoDerefPointers)->setEnabled(true);
+    action(ExpandStack)->setEnabled(actionsEnabled);
 
-    cmd = ActionManager::registerAction(m_breakAction, "Debugger.ToggleBreak");
-    cmd->setDefaultKeySequence(QKeySequence(UseMacShortcuts ? tr("F8") : tr("F9")));
-    debugMenu->addAction(cmd);
-    connect(m_breakAction, &QAction::triggered,
-        this, &DebuggerPluginPrivate::toggleBreakpointHelper);
+    const bool notbusy = state == InferiorStopOk
+        || state == DebuggerNotReady
+        || state == DebuggerFinished
+        || state == InferiorUnrunnable;
+    setBusyCursor(!notbusy);
+}
 
-    debugMenu->addSeparator();
+void DebuggerPluginPrivate::updateDebugActions()
+{
+    //if we're currently debugging the actions are controlled by engine
+    if (m_currentEngine->state() != DebuggerNotReady)
+        return;
 
-    // currently broken
-//    QAction *qmlUpdateOnSaveDummyAction = new QAction(tr("Apply Changes on Save"), this);
-//    qmlUpdateOnSaveDummyAction->setCheckable(true);
-//    qmlUpdateOnSaveDummyAction->setIcon(Icons::APPLY_ON_SAVE.icon());
-//    qmlUpdateOnSaveDummyAction->setEnabled(false);
-//    cmd = ActionManager::registerAction(qmlUpdateOnSaveDummyAction, Constants::QML_UPDATE_ON_SAVE);
-//    debugMenu->addAction(cmd);
+    Project *project = SessionManager::startupProject();
+    QString whyNot;
+    const bool canRun = ProjectExplorerPlugin::canRun(project, ProjectExplorer::Constants::DEBUG_RUN_MODE, &whyNot);
+    m_startAction->setEnabled(canRun);
+    m_startAction->setToolTip(whyNot);
+    m_debugWithoutDeployAction->setEnabled(canRun);
 
-    QAction *qmlShowAppOnTopDummyAction = new QAction(tr("Show Application on Top"), this);
-    qmlShowAppOnTopDummyAction->setCheckable(true);
-    qmlShowAppOnTopDummyAction->setIcon(Icons::APP_ON_TOP.icon());
-    qmlShowAppOnTopDummyAction->setEnabled(false);
-    cmd = ActionManager::registerAction(qmlShowAppOnTopDummyAction, Constants::QML_SHOW_APP_ON_TOP);
-    debugMenu->addAction(cmd);
+    // Step into/next: Start and break at 'main' unless a debugger is running.
+    if (m_snapshotHandler->currentIndex() < 0) {
+        QString toolTip;
+        const bool canRunAndBreakMain
+                = ProjectExplorerPlugin::canRun(project, ProjectExplorer::Constants::DEBUG_RUN_MODE_WITH_BREAK_ON_MAIN, &toolTip);
+        m_stepAction->setEnabled(canRunAndBreakMain);
+        m_nextAction->setEnabled(canRunAndBreakMain);
+        if (canRunAndBreakMain) {
+            QTC_ASSERT(project, return ; );
+            toolTip = tr("Start \"%1\" and break at function \"main()\"")
+                      .arg(project->displayName());
+        }
+        m_stepAction->setToolTip(toolTip);
+        m_nextAction->setToolTip(toolTip);
+    }
+}
 
-    QAction *qmlSelectDummyAction = new QAction(tr("Select"), this);
-    qmlSelectDummyAction->setCheckable(true);
-    qmlSelectDummyAction->setIcon(Icons::SELECT.icon());
-    qmlSelectDummyAction->setEnabled(false);
-    cmd = ActionManager::registerAction(qmlSelectDummyAction, Constants::QML_SELECTTOOL);
-    debugMenu->addAction(cmd);
+void DebuggerPluginPrivate::updateDebugWithoutDeployMenu()
+{
+    const bool state = ProjectExplorerPlugin::projectExplorerSettings().deployBeforeRun;
+    m_debugWithoutDeployAction->setVisible(state);
+}
 
-    QAction *qmlZoomDummyAction = new QAction(tr("Zoom"), this);
-    qmlZoomDummyAction->setCheckable(true);
-    qmlZoomDummyAction->setIcon(Core::Icons::ZOOM.icon());
-    qmlZoomDummyAction->setEnabled(false);
-    cmd = ActionManager::registerAction(qmlZoomDummyAction, Constants::QML_ZOOMTOOL);
-    debugMenu->addAction(cmd);
+void DebuggerPluginPrivate::dumpLog()
+{
+    QString fileName = QFileDialog::getSaveFileName(ICore::mainWindow(),
+        tr("Save Debugger Log"), QDir::tempPath());
+    if (fileName.isEmpty())
+        return;
+    FileSaver saver(fileName);
+    if (!saver.hasError()) {
+        QTextStream ts(saver.file());
+        ts << m_logWindow->inputContents();
+        ts << "\n\n=======================================\n\n";
+        ts << m_logWindow->combinedContents();
+        saver.setResult(&ts);
+    }
+    saver.finalize(ICore::mainWindow());
+}
 
-    debugMenu->addSeparator();
+/*! Activates the previous mode when the current mode is the debug mode. */
+void DebuggerPluginPrivate::activatePreviousMode()
+{
+    if (ModeManager::currentMode() == ModeManager::mode(MODE_DEBUG)
+            && m_previousMode.isValid()) {
+        // If stopping the application also makes Qt Creator active (as the
+        // "previously active application"), doing the switch synchronously
+        // leads to funny effects with floating dock widgets
+        const Core::Id mode = m_previousMode;
+        QTimer::singleShot(0, this, [mode]() { ModeManager::activateMode(mode); });
+        m_previousMode = Id();
+    }
+}
 
-    // Don't add '1' to the string as it shows up in the shortcut dialog.
-    cmd = ActionManager::registerAction(m_watchAction1,
-        "Debugger.AddToWatch", cppeditorcontext);
-    //cmd->setDefaultKeySequence(QKeySequence(tr("Ctrl+D,Ctrl+W")));
-    debugMenu->addAction(cmd);
+void DebuggerPluginPrivate::activateDebugMode()
+{
+    m_reverseDirectionAction->setChecked(false);
+    m_reverseDirectionAction->setEnabled(false);
+    m_previousMode = ModeManager::currentMode()->id();
+    ModeManager::activateMode(MODE_DEBUG);
+}
 
-    // If the CppEditor plugin is there, we want to add something to
-    // the editor context menu.
-    if (ActionContainer *editorContextMenu =
-            ActionManager::actionContainer(CppEditor::Constants::M_CONTEXT)) {
-        cmd = editorContextMenu->addSeparator(cppDebuggercontext);
-        cmd->setAttribute(Command::CA_Hide);
+void DebuggerPluginPrivate::sessionLoaded()
+{
+    m_breakHandler->loadSessionData();
+    dummyEngine()->watchHandler()->loadSessionData();
+    DebuggerToolTipManager::loadSessionData();
+}
 
-        cmd = ActionManager::registerAction(m_watchAction2,
-            "Debugger.AddToWatch2", cppDebuggercontext);
-        cmd->action()->setEnabled(true);
-        editorContextMenu->addAction(cmd);
-        cmd->setAttribute(Command::CA_Hide);
-        cmd->setAttribute(Command::CA_NonConfigurable);
-        // Debugger.AddToWatch is enough.
-    }
+void DebuggerPluginPrivate::aboutToUnloadSession()
+{
+    m_toolTipManager.sessionAboutToChange();
+}
 
-    QList<IOptionsPage *> engineOptionPages;
-    addGdbOptionPages(&engineOptionPages);
-    addCdbOptionPages(&engineOptionPages);
+void DebuggerPluginPrivate::aboutToSaveSession()
+{
+    dummyEngine()->watchHandler()->saveSessionData();
+    m_breakHandler->saveSessionData();
+    DebuggerToolTipManager::saveSessionData();
+}
 
-    foreach (IOptionsPage *op, engineOptionPages)
-        m_plugin->addAutoReleasedObject(op);
-    m_plugin->addAutoReleasedObject(new LocalsAndExpressionsOptionsPage);
-    m_plugin->addAutoReleasedObject(new DebuggerOptionsPage);
+void DebuggerPluginPrivate::showStatusMessage(const QString &msg0, int timeout)
+{
+    showMessage(msg0, LogStatus);
+    QString msg = msg0;
+    msg.replace(QChar::LineFeed, QLatin1String("; "));
+    m_mainWindow->showStatusMessage(msg, timeout);
+}
 
-    connect(ModeManager::instance(), &ModeManager::currentModeChanged,
-        this, &DebuggerPluginPrivate::onModeChanged);
-    connect(ICore::instance(), &ICore::coreAboutToOpen,
-        this, &DebuggerPluginPrivate::onCoreAboutToOpen);
-    connect(ProjectExplorerPlugin::instance(), &ProjectExplorerPlugin::settingsChanged,
-        this, &DebuggerPluginPrivate::updateDebugWithoutDeployMenu);
+void DebuggerPluginPrivate::coreShutdown()
+{
+    m_shuttingDown = true;
+}
 
-    // Debug mode setup
-    DebugMode *debugMode = new DebugMode;
-    QWidget *widget = createContents(debugMode);
-    IContext *modeContextObject = new IContext(this);
-    modeContextObject->setContext(Context(CC::C_EDITORMANAGER));
-    modeContextObject->setWidget(widget);
-    ICore::addContextObject(modeContextObject);
-    debugMode->setWidget(widget);
+const CPlusPlus::Snapshot &cppCodeModelSnapshot()
+{
+    if (dd->m_codeModelSnapshot.isEmpty() && action(UseCodeModel)->isChecked())
+        dd->m_codeModelSnapshot = CppTools::CppModelManager::instance()->snapshot();
+    return dd->m_codeModelSnapshot;
+}
 
-    m_plugin->addAutoReleasedObject(debugMode);
+void setSessionValue(const QByteArray &key, const QVariant &value)
+{
+    SessionManager::setValue(QString::fromUtf8(key), value);
+}
 
-    //
-    //  Connections
-    //
+QVariant sessionValue(const QByteArray &key)
+{
+    return SessionManager::value(QString::fromUtf8(key));
+}
 
-    // Core
-    connect(ICore::instance(), &ICore::saveSettingsRequested,
-            this, &DebuggerPluginPrivate::writeSettings);
+QTreeView *inspectorView()
+{
+    return dd->m_inspectorView;
+}
 
-    // TextEditor
-    connect(TextEditorSettings::instance(), &TextEditorSettings::fontSettingsChanged,
-            this, &DebuggerPluginPrivate::fontSettingsChanged);
+void DebuggerPluginPrivate::showMessage(const QString &msg, int channel, int timeout)
+{
+    //qDebug() << "PLUGIN OUTPUT: " << channel << msg;
+    QTC_ASSERT(m_logWindow, return);
+    switch (channel) {
+        case StatusBar:
+            // This will append to m_logWindow's output pane, too.
+            showStatusMessage(msg, timeout);
+            break;
+        case LogMiscInput:
+            m_logWindow->showInput(LogMisc, msg);
+            m_logWindow->showOutput(LogMisc, msg);
+            break;
+        case LogInput:
+            m_logWindow->showInput(LogInput, msg);
+            m_logWindow->showOutput(LogInput, msg);
+            break;
+        case LogError:
+            m_logWindow->showInput(LogError, QLatin1String("ERROR: ") + msg);
+            m_logWindow->showOutput(LogError, QLatin1String("ERROR: ") + msg);
+            break;
+        default:
+            m_logWindow->showOutput(channel, msg);
+            break;
+    }
+}
 
-    // ProjectExplorer
-    connect(SessionManager::instance(), &SessionManager::sessionLoaded,
-            this, &DebuggerPluginPrivate::sessionLoaded);
-    connect(SessionManager::instance(), &SessionManager::aboutToSaveSession,
-            this, &DebuggerPluginPrivate::aboutToSaveSession);
-    connect(SessionManager::instance(), &SessionManager::aboutToUnloadSession,
-            this, &DebuggerPluginPrivate::aboutToUnloadSession);
-    connect(ProjectExplorerPlugin::instance(), &ProjectExplorerPlugin::updateRunActions,
-            this, &DebuggerPluginPrivate::updateDebugActions);
+static void createNewDock(QWidget *widget)
+{
+//    m_mainWindow->registerDockWidget(dockId, widget);
 
-    // EditorManager
-    connect(EditorManager::instance(), &EditorManager::editorOpened,
-            this, &DebuggerPluginPrivate::editorOpened);
-    connect(EditorManager::instance(), &EditorManager::currentEditorChanged,
-            this, &DebuggerPluginPrivate::updateBreakMenuItem);
+//    QDockWidget *dockWidget = qobject_cast<QDockWidget *>(widget->parentWidget());
+//    //dockWidget->installEventFilter(&m_resizeEventFilter);
 
-    // Application interaction
-    connect(action(SettingsDialog), &QAction::triggered,
-            [] { ICore::showOptionsDialog(DEBUGGER_COMMON_SETTINGS_ID); });
+//    QAction *toggleViewAction = dockWidget->toggleViewAction();
+//    Command *cmd = ActionManager::registerAction(toggleViewAction,
+//             Id("Debugger.").withSuffix(widget->objectName()));
+//    cmd->setAttribute(Command::CA_Hide);
+//    dd->createDockWidget(Core::Id::fromString(widget->objectName()), widget);
+//    QDockWidget *dockWidget = qobject_cast<QDockWidget *>(widget->parentWidget());
+//    QDockWidget *dockWidget = Debugger::registerDockWidget(Id::fromString(widget->objectName()), widget);
+    QDockWidget *dockWidget = new QDockWidget;
+    dockWidget->setWidget(widget);
 
-    // Toolbar
-    QWidget *toolbarContainer = new QWidget(mainWindow());
+    dockWidget->setWindowTitle(widget->windowTitle());
+    dockWidget->setFeatures(QDockWidget::DockWidgetClosable);
+    dockWidget->show();
+}
+
+static QString formatStartParameters(DebuggerRunParameters &sp)
+{
+    QString rc;
+    QTextStream str(&rc);
+    str << "Start parameters: '" << sp.displayName << "' mode: " << sp.startMode
+        << "\nABI: " << sp.toolChainAbi.toString() << '\n';
+    str << "Languages: ";
+    if (sp.languages == AnyLanguage)
+        str << "any";
+    if (sp.languages & CppLanguage)
+        str << "c++ ";
+    if (sp.languages & QmlLanguage)
+        str << "qml";
+    str << '\n';
+    if (!sp.inferior.executable.isEmpty()) {
+        str << "Executable: " << QDir::toNativeSeparators(sp.inferior.executable)
+            << ' ' << sp.inferior.commandLineArguments;
+        if (sp.useTerminal)
+            str << " [terminal]";
+        str << '\n';
+        if (!sp.inferior.workingDirectory.isEmpty())
+            str << "Directory: " << QDir::toNativeSeparators(sp.inferior.workingDirectory)
+                << '\n';
+    }
+    QString cmd = sp.debuggerCommand;
+    if (!cmd.isEmpty())
+        str << "Debugger: " << QDir::toNativeSeparators(cmd) << '\n';
+    if (!sp.coreFile.isEmpty())
+        str << "Core: " << QDir::toNativeSeparators(sp.coreFile) << '\n';
+    if (sp.attachPID > 0)
+        str << "PID: " << sp.attachPID << ' ' << sp.crashParameter << '\n';
+    if (!sp.projectSourceDirectory.isEmpty()) {
+        str << "Project: " << QDir::toNativeSeparators(sp.projectSourceDirectory);
+        str << "Addtional Search Directories:"
+            << sp.additionalSearchDirectories.join(QLatin1Char(' ')) << '\n';
+    }
+    if (!sp.qmlServerAddress.isEmpty())
+        str << "QML server: " << sp.qmlServerAddress << ':'
+            << sp.qmlServerPort << '\n';
+    if (!sp.remoteChannel.isEmpty())
+        str << "Remote: " << sp.remoteChannel << '\n';
+    str << "Sysroot: " << sp.sysRoot << '\n';
+    str << "Debug Source Location: " << sp.debugSourceLocation.join(QLatin1Char(':')) << '\n';
+    return rc;
+}
 
-    QHBoxLayout *hbox = new QHBoxLayout(toolbarContainer);
-    hbox->setMargin(0);
-    hbox->setSpacing(0);
-    hbox->addWidget(toolButton(m_visibleStartAction));
-    hbox->addWidget(toolButton(Constants::STOP));
-    hbox->addWidget(toolButton(Constants::NEXT));
-    hbox->addWidget(toolButton(Constants::STEP));
-    hbox->addWidget(toolButton(Constants::STEPOUT));
-    hbox->addWidget(toolButton(Constants::RESET));
-    hbox->addWidget(toolButton(Constants::OPERATE_BY_INSTRUCTION));
+void DebuggerPluginPrivate::runControlStarted(DebuggerEngine *engine)
+{
+    activateDebugMode();
+    const QString message = tr("Starting debugger \"%1\" for ABI \"%2\"...")
+            .arg(engine->objectName())
+            .arg(engine->runParameters().toolChainAbi.toString());
+    showStatusMessage(message);
+    showMessage(formatStartParameters(engine->runParameters()), LogDebug);
+    showMessage(m_debuggerSettings->dump(), LogDebug);
+    m_snapshotHandler->appendSnapshot(engine);
+    connectEngine(engine);
+}
 
-    if (isReverseDebuggingEnabled()) {
-        m_reverseToolButton = toolButton(Constants::REVERSE);
-        hbox->addWidget(m_reverseToolButton);
+void DebuggerPluginPrivate::runControlFinished(DebuggerEngine *engine)
+{
+    showStatusMessage(tr("Debugger finished."));
+    m_snapshotHandler->removeSnapshot(engine);
+    if (m_snapshotHandler->size() == 0) {
+        // Last engine quits.
+        disconnectEngine();
+        if (boolSetting(SwitchModeOnExit))
+            activatePreviousMode();
+    } else {
+        // Connect to some existing engine.
+        m_snapshotHandler->activateSnapshot(0);
     }
+    m_operateByInstructionAction->setChecked(false);
+    m_logWindow->clearUndoRedoStacks();
+}
 
-    hbox->addWidget(new StyledSeparator);
-    hbox->addWidget(new QLabel(tr("Threads:")));
-
-    m_threadBox = new QComboBox;
-    m_threadBox->setSizeAdjustPolicy(QComboBox::AdjustToContents);
-    connect(m_threadBox, static_cast<void(QComboBox::*)(int)>(&QComboBox::activated),
-            this, &DebuggerPluginPrivate::selectThread);
-
-    hbox->addWidget(m_threadBox);
-    hbox->addSpacerItem(new QSpacerItem(4, 0));
-
-    QWidget *qmlToolbar = new QWidget(mainWindow());
-    hbox = new QHBoxLayout(qmlToolbar);
-    hbox->setMargin(0);
-    hbox->setSpacing(0);
-    // currently broken
-    //hbox->addWidget(toolButton(Constants::QML_UPDATE_ON_SAVE));
-    hbox->addWidget(toolButton(Constants::QML_SHOW_APP_ON_TOP));
-    hbox->addWidget(new StyledSeparator);
-    hbox->addWidget(toolButton(Constants::QML_SELECTTOOL));
-    hbox->addWidget(toolButton(Constants::QML_ZOOMTOOL));
-    hbox->addWidget(new StyledSeparator);
-
-    m_mainWindow->registerToolbar(CppPerspectiveId, toolbarContainer);
-    m_mainWindow->registerPerspective(CppPerspectiveId, {
-        { DOCKWIDGET_STACK, Core::Id(), Perspective::SplitVertical },
-        { DOCKWIDGET_BREAK, DOCKWIDGET_STACK, Perspective::SplitHorizontal },
-        { DOCKWIDGET_MODULES, DOCKWIDGET_BREAK, Perspective::AddToTab },
-        { DOCKWIDGET_SOURCE_FILES, DOCKWIDGET_MODULES, Perspective::AddToTab },
-        { DOCKWIDGET_WATCHERS, Core::Id(), Perspective::AddToTab,
-                               true, Qt::RightDockWidgetArea },
-        { DOCKWIDGET_REGISTER, DOCKWIDGET_WATCHERS, Perspective::AddToTab,
-                               true, Qt::RightDockWidgetArea },
-        { DOCKWIDGET_OUTPUT, Core::Id(), Perspective::AddToTab,
-                               false, Qt::TopDockWidgetArea }
-    });
-
-    m_mainWindow->registerToolbar(QmlPerspectiveId, toolbarContainer);
-    m_mainWindow->registerPerspective(QmlPerspectiveId, {
-        { DOCKWIDGET_STACK, Core::Id(), Perspective::SplitVertical },
-        { DOCKWIDGET_BREAK, DOCKWIDGET_STACK, Perspective::SplitHorizontal },
-        { DOCKWIDGET_MODULES, DOCKWIDGET_BREAK, Perspective::AddToTab },
-        { DOCKWIDGET_SOURCE_FILES, DOCKWIDGET_MODULES, Perspective::AddToTab },
-        { DOCKWIDGET_WATCHERS, Core::Id(), Perspective::AddToTab,
-                               true, Qt::RightDockWidgetArea },
-        { DOCKWIDGET_OUTPUT, Core::Id(), Perspective::AddToTab,
-                               false, Qt::TopDockWidgetArea }
-    });
+void DebuggerPluginPrivate::remoteCommand(const QStringList &options)
+{
+    if (options.isEmpty())
+        return;
 
-    connect(action(EnableReverseDebugging), &SavedAction::valueChanged,
-            this, &DebuggerPluginPrivate::enableReverseDebuggingTriggered);
+    QString errorMessage;
 
-    setInitialState();
-    connectEngine(0);
+    if (!parseArguments(options, &errorMessage)) {
+        qWarning("%s", qPrintable(errorMessage));
+        return;
+    }
+    runScheduled();
+}
 
-    connect(SessionManager::instance(), &SessionManager::startupProjectChanged,
-        this, &DebuggerPluginPrivate::onCurrentProjectChanged);
+QMessageBox *showMessageBox(int icon, const QString &title,
+    const QString &text, int buttons)
+{
+    QMessageBox *mb = new QMessageBox(QMessageBox::Icon(icon),
+        title, text, QMessageBox::StandardButtons(buttons),
+        ICore::mainWindow());
+    mb->setAttribute(Qt::WA_DeleteOnClose);
+    mb->setTextInteractionFlags(Qt::TextSelectableByMouse);
+    mb->show();
+    return mb;
+}
 
-    m_commonOptionsPage = new CommonOptionsPage(m_globalDebuggerOptions);
-    m_plugin->addAutoReleasedObject(m_commonOptionsPage);
+bool isReverseDebuggingEnabled()
+{
+    static bool enabled = qEnvironmentVariableIsSet("QTC_DEBUGGER_ENABLE_REVERSE");
+    return enabled;
+}
 
-    m_globalDebuggerOptions->fromSettings();
-    m_watchersWindow->setVisible(false);
-    m_returnWindow->setVisible(false);
+bool isReverseDebugging()
+{
+    return isReverseDebuggingEnabled() && dd->m_reverseDirectionAction->isChecked();
+}
 
-    // time gdb -i mi -ex 'b debuggerplugin.cpp:800' -ex r -ex q bin/qtcreator.bin
+void DebuggerPluginPrivate::extensionsInitialized()
+{
 }
 
 DebuggerEngine *currentEngine()
@@ -3174,11 +3163,6 @@ void displayDebugger(DebuggerEngine *engine, bool updateEngine)
     dd->displayDebugger(engine, updateEngine);
 }
 
-DebuggerLanguages activeLanguages()
-{
-    return dd->activeDebugLanguages();
-}
-
 void synchronizeBreakpoints()
 {
     dd->synchronizeBreakpoints();
@@ -3186,7 +3170,7 @@ void synchronizeBreakpoints()
 
 QWidget *mainWindow()
 {
-    return dd->mainWindow();
+    return dd->m_mainWindow;
 }
 
 bool isDockVisible(const QString &objectName)
@@ -3215,8 +3199,6 @@ QSharedPointer<Internal::GlobalDebuggerOptions> globalDebuggerOptions()
     return dd->m_globalDebuggerOptions;
 }
 
-} // namespace Internal
-
 ///////////////////////////////////////////////////////////////////////
 //
 // DebuggerPlugin
@@ -3272,12 +3254,9 @@ bool DebuggerPlugin::initialize(const QStringList &arguments, QString *errorMess
 
     KitManager::registerKitInformation(new DebuggerKitInformation);
 
-    // Ex-Analyzer stuff
-    (void) new AnalyzerManager(this);
-
     // Task integration.
     //: Category under which Analyzer tasks are listed in Issues view
-    ProjectExplorer::TaskHub::addCategory(Analyzer::Constants::ANALYZERTASK_ID, tr("Analyzer"));
+    ProjectExplorer::TaskHub::addCategory(Debugger::Constants::ANALYZERTASK_ID, tr("Debugger"));
 
     return dd->initialize(arguments, errorMessage);
 }
@@ -3286,7 +3265,7 @@ IPlugin::ShutdownFlag DebuggerPlugin::aboutToShutdown()
 {
     removeObject(this);
     dd->aboutToShutdown();
-    AnalyzerManager::shutdown();
+    dd->m_mainWindow->saveCurrentPerspective();
     return SynchronousShutdown;
 }
 
@@ -3317,7 +3296,8 @@ void DebuggerPluginPrivate::updateUiForProject(Project *project)
         return;
     }
     connect(project, &Project::activeTargetChanged,
-            this, &DebuggerPluginPrivate::updateUiForTarget);
+            this, &DebuggerPluginPrivate::updateUiForTarget,
+            Qt::QueuedConnection);
     updateUiForTarget(project->activeTarget());
 }
 
@@ -3336,178 +3316,340 @@ void DebuggerPluginPrivate::updateUiForTarget(Target *target)
     }
 
     connect(target, &Target::activeRunConfigurationChanged,
-            this, &DebuggerPluginPrivate::updateUiForRunConfiguration);
+            this, &DebuggerPluginPrivate::updateUiForRunConfiguration,
+            Qt::QueuedConnection);
     updateUiForRunConfiguration(target->activeRunConfiguration());
 }
 
 // updates default debug language settings per run config.
 void DebuggerPluginPrivate::updateUiForRunConfiguration(RunConfiguration *rc)
 {
-    if (m_previousRunConfiguration)
-        disconnect(m_previousRunConfiguration, &RunConfiguration::requestRunActionsUpdate,
-                   this, &DebuggerPluginPrivate::updateActiveLanguages);
-    m_previousRunConfiguration = rc;
+//    if (m_previousRunConfiguration)
+//        disconnect(m_previousRunConfiguration, &RunConfiguration::requestRunActionsUpdate,
+//                   this, &DebuggerPluginPrivate::updateActiveLanguages);
+//    m_previousRunConfiguration = rc;
+    Q_UNUSED(rc); // FIXME
     updateActiveLanguages();
-    if (m_previousRunConfiguration)
-        connect(m_previousRunConfiguration, &RunConfiguration::requestRunActionsUpdate,
-                this, &DebuggerPluginPrivate::updateActiveLanguages);
+//    if (m_previousRunConfiguration)
+//        connect(m_previousRunConfiguration, &RunConfiguration::requestRunActionsUpdate,
+//                this, &DebuggerPluginPrivate::updateActiveLanguages,
+//                Qt::QueuedConnection);
 }
 
 void DebuggerPluginPrivate::updateActiveLanguages()
 {
-    if (!(activeDebugLanguages() & QmlLanguage))
-        m_mainWindow->restorePerspective(CppPerspectiveId);
-    else
-        m_mainWindow->restorePerspective(QmlPerspectiveId);
+//    DebuggerLanguages languages = dd->m_currentEngine->runParameters().languages;
+//    Id perspective = (languages & QmlLanguage) && !(languages & CppLanguage)
+//            ? QmlPerspectiveId : CppPerspectiveId;
+//    m_mainWindow->restorePerspective(perspective);
 }
 
-DebuggerLanguages DebuggerPluginPrivate::activeDebugLanguages() const
+//bool DockWidgetEventFilter::eventFilter(QObject *obj, QEvent *event)
+//{
+//    switch (event->type()) {
+//    case QEvent::Resize:
+//    case QEvent::ZOrderChange:
+//        dd->updateDockWidgetSettings();
+//        break;
+//    default:
+//        break;
+//    }
+//    return QObject::eventFilter(obj, event);
+//}
+
+bool DebuggerPluginPrivate::showPromptDialog(const QString &title, const QString &text,
+    const QString &stopButtonText, const QString &cancelButtonText) const
 {
-    return dd->m_currentEngine->runParameters().languages;
+    CheckableMessageBox messageBox(ICore::mainWindow());
+    messageBox.setWindowTitle(title);
+    messageBox.setText(text);
+    messageBox.setStandardButtons(QDialogButtonBox::Yes|QDialogButtonBox::Cancel);
+    if (!stopButtonText.isEmpty())
+        messageBox.button(QDialogButtonBox::Yes)->setText(stopButtonText);
+    if (!cancelButtonText.isEmpty())
+        messageBox.button(QDialogButtonBox::Cancel)->setText(cancelButtonText);
+    messageBox.setDefaultButton(QDialogButtonBox::Yes);
+    messageBox.setCheckBoxVisible(false);
+    messageBox.exec();
+    return messageBox.clickedStandardButton() == QDialogButtonBox::Yes;
 }
 
-void DebuggerPluginPrivate::createViewsMenuItems()
+void DebuggerPluginPrivate::onModeChanged(IMode *mode)
 {
-    Context debugcontext(Constants::C_DEBUGMODE);
-    m_viewsMenu = ActionManager::actionContainer(Id(Core::Constants::M_WINDOW_VIEWS));
-    QTC_ASSERT(m_viewsMenu, return);
+    // FIXME: This one gets always called, even if switching between modes
+    //        different then the debugger mode. E.g. Welcome and Help mode and
+    //        also on shutdown.
 
-    auto openMemoryEditorAction = new QAction(this);
-    openMemoryEditorAction->setText(DebuggerPluginPrivate::tr("Memory..."));
-    connect(openMemoryEditorAction, &QAction::triggered,
-            this, &Internal::openMemoryEditor);
+    if (mode && mode->id() == MODE_DEBUG) {
+        if (IEditor *editor = EditorManager::currentEditor())
+            editor->widget()->setFocus();
 
-    // Add menu items
-    Command *cmd = 0;
-    cmd = ActionManager::registerAction(openMemoryEditorAction,
-        "Debugger.Views.OpenMemoryEditor", debugcontext);
-    cmd->setAttribute(Command::CA_Hide);
-    m_viewsMenu->addAction(cmd, Core::Constants::G_DEFAULT_THREE);
-    cmd = ActionManager::registerAction(m_mainWindow->menuSeparator1(),
-        "Debugger.Views.Separator1", debugcontext);
-    cmd->setAttribute(Command::CA_Hide);
-    m_viewsMenu->addAction(cmd, Core::Constants::G_DEFAULT_THREE);
-    cmd = ActionManager::registerAction(m_mainWindow->menuSeparator2(),
-        "Debugger.Views.Separator2", debugcontext);
-    cmd->setAttribute(Command::CA_Hide);
-    m_viewsMenu->addAction(cmd, Core::Constants::G_DEFAULT_THREE);
+        m_toolTipManager.debugModeEntered();
+        m_mainWindow->setDockActionsVisible(true);
+        m_mainWindow->restorePerspective({});
+
+//        static bool firstTime = true;
+//        if (firstTime) {
+
+//            // Dock widgets
+//            connect(m_mainWindow->dockWidget(DOCKWIDGET_MODULES)->toggleViewAction(), &QAction::toggled,
+//                    this, &DebuggerPluginPrivate::modulesDockToggled, Qt::QueuedConnection);
+//            connect(m_mainWindow->dockWidget(DOCKWIDGET_OUTPUT)->toggleViewAction(), &QAction::toggled,
+//                    this, &DebuggerPluginPrivate::registerDockToggled, Qt::QueuedConnection);
+//            connect(m_mainWindow->dockWidget(DOCKWIDGET_SOURCE_FILES)->toggleViewAction(), &QAction::toggled,
+//                    this, &DebuggerPluginPrivate::sourceFilesDockToggled, Qt::QueuedConnection);
+
+//            firstTime = false;
+//        }
+        updateActiveLanguages();
+    } else {
+        m_toolTipManager.leavingDebugMode();
+        m_mainWindow->setDockActionsVisible(false);
+
+        // Hide dock widgets manually in case they are floating.
+        foreach (QDockWidget *dockWidget, m_mainWindow->dockWidgets()) {
+            if (dockWidget->isFloating())
+                dockWidget->hide();
+        }
+    }
 }
 
-/*!
-    Keep track of dock widgets so they can be shown/hidden for different languages
-*/
-QDockWidget *DebuggerPluginPrivate::createDockWidget(Core::Id dockId, QWidget *widget)
+void DebuggerPluginPrivate::selectPerspective(const QByteArray &perspectiveId)
+{
+    m_mainWindow->restorePerspective(perspectiveId);
+}
+
+void DebuggerPluginPrivate::registerAction(Id actionId, const ActionDescription &desc, QAction *startAction)
 {
-    m_mainWindow->registerDockWidget(dockId, widget);
+    auto action = new QAction(this);
+    action->setText(desc.text());
+    action->setToolTip(desc.toolTip());
+    m_actions.insert(actionId, action);
+    m_descriptions.insert(actionId, desc);
 
-    QDockWidget *dockWidget = qobject_cast<QDockWidget *>(widget->parentWidget());
+    Id menuGroup = desc.menuGroup();
+    if (menuGroup.isValid()) {
+        Command *command = ActionManager::registerAction(action, actionId);
+        m_menu->addAction(command, menuGroup);
+    }
 
-    QAction *toggleViewAction = dockWidget->toggleViewAction();
-    Command *cmd = ActionManager::registerAction(toggleViewAction,
-             Id("Debugger.").withSuffix(widget->objectName()));
-    cmd->setAttribute(Command::CA_Hide);
+    connect(action, &QAction::triggered, this, [this, desc] { desc.startTool(); });
 
-    //dockWidget->installEventFilter(&m_resizeEventFilter);
-    return dockWidget;
+    if (startAction) {
+        QObject::connect(startAction, &QAction::triggered, action, &QAction::triggered);
+
+        QObject::connect(startAction, &QAction::changed, action, [action, startAction] {
+            action->setEnabled(startAction->isEnabled());
+        });
+    }
 }
 
-QWidget *DebuggerPluginPrivate::createContents(IMode *mode)
+} // namespace Internal
+
+bool ActionDescription::isRunnable(QString *reason) const
 {
-    connect(SessionManager::instance(), &SessionManager::startupProjectChanged,
-            this, &DebuggerPluginPrivate::updateUiForProject);
+    if (m_customToolStarter) // Something special. Pretend we can always run it.
+        return true;
 
-    auto editorHolderLayout = new QVBoxLayout;
-    editorHolderLayout->setMargin(0);
-    editorHolderLayout->setSpacing(0);
+    return ProjectExplorerPlugin::canRun(SessionManager::startupProject(), m_runMode, reason);
+}
 
-    auto editorAndFindWidget = new QWidget;
-    editorAndFindWidget->setLayout(editorHolderLayout);
-    auto editorManagerPlaceHolder = new EditorManagerPlaceHolder(mode);
-    editorHolderLayout->addWidget(editorManagerPlaceHolder);
-    editorHolderLayout->addWidget(new FindToolBarPlaceHolder(editorAndFindWidget));
+static bool buildTypeAccepted(QFlags<ToolMode> toolMode, BuildConfiguration::BuildType buildType)
+{
+    if (buildType == BuildConfiguration::Unknown)
+        return true;
+    if (buildType == BuildConfiguration::Debug && (toolMode & DebugMode))
+        return true;
+    if (buildType == BuildConfiguration::Release && (toolMode & ReleaseMode))
+        return true;
+    if (buildType == BuildConfiguration::Profile && (toolMode & ProfileMode))
+        return true;
+    return false;
+}
 
-    auto documentAndRightPane = new MiniSplitter;
-    documentAndRightPane->addWidget(editorAndFindWidget);
-    documentAndRightPane->addWidget(new RightPanePlaceHolder(mode));
-    documentAndRightPane->setStretchFactor(0, 1);
-    documentAndRightPane->setStretchFactor(1, 0);
+void ActionDescription::startTool() const
+{
+    TaskHub::clearTasks(Constants::ANALYZERTASK_ID);
+    Debugger::selectPerspective(m_perspectiveId);
 
-    auto viewButton = new QToolButton();
-    viewButton->setText(tr("Views"));
-
-    auto debugToolBar = new Utils::StyledBar;
-    debugToolBar->setProperty("topBorder", true);
-    auto debugToolBarLayout = new QHBoxLayout(debugToolBar);
-    debugToolBarLayout->setMargin(0);
-    debugToolBarLayout->setSpacing(0);
-//    debugToolBarLayout->addWidget(m_mainWindow->toolBox());
-    debugToolBarLayout->addWidget(m_mainWindow->controlsStack());
-    debugToolBarLayout->addWidget(m_mainWindow->statusLabel());
-    debugToolBarLayout->addWidget(new Utils::StyledSeparator);
-    debugToolBarLayout->addStretch();
-    debugToolBarLayout->addWidget(viewButton);
-
-    connect(viewButton, &QAbstractButton::clicked, [this, viewButton] {
-        QMenu menu;
-        m_mainWindow->addDockActionsToMenu(&menu);
-        menu.exec(viewButton->mapToGlobal(QPoint()));
-    });
+    if (m_toolPreparer && !m_toolPreparer())
+        return;
 
-    auto dock = new QDockWidget(DebuggerPluginPrivate::tr("Debugger Toolbar"));
-    dock->setObjectName(QLatin1String("Debugger Toolbar"));
-    dock->setWidget(debugToolBar);
-    dock->setFeatures(QDockWidget::NoDockWidgetFeatures);
-    dock->setAllowedAreas(Qt::BottomDockWidgetArea);
-    dock->setTitleBarWidget(new QWidget(dock));
-    dock->setProperty("managed_dockwidget", QLatin1String("true"));
-    m_mainWindow->addDockWidget(Qt::BottomDockWidgetArea, dock);
-    m_mainWindow->setToolBarDockWidget(dock);
+    // ### not sure if we're supposed to check if the RunConFiguration isEnabled
+    Project *pro = SessionManager::startupProject();
+    RunConfiguration *rc = 0;
+    BuildConfiguration::BuildType buildType = BuildConfiguration::Unknown;
+    if (pro) {
+        if (const Target *target = pro->activeTarget()) {
+            // Build configuration is 0 for QML projects.
+            if (const BuildConfiguration *buildConfig = target->activeBuildConfiguration())
+                buildType = buildConfig->buildType();
+            rc = target->activeRunConfiguration();
+        }
+    }
 
-    auto centralWidget = new QWidget;
-    m_mainWindow->setCentralWidget(centralWidget);
+    // Custom start.
+    if (m_customToolStarter) {
+        if (rc) {
+            m_customToolStarter(rc);
+        } else {
+            QMessageBox *errorDialog = new QMessageBox(ICore::mainWindow());
+            errorDialog->setIcon(QMessageBox::Warning);
+            errorDialog->setWindowTitle(m_text);
+            errorDialog->setText(tr("Cannot start %1 without a project. Please open the project "
+                                    "and try again.").arg(m_text));
+            errorDialog->setStandardButtons(QMessageBox::Ok);
+            errorDialog->setDefaultButton(QMessageBox::Ok);
+            errorDialog->show();
+        }
+        return;
+    }
 
-    auto centralLayout = new QVBoxLayout(centralWidget);
-    centralWidget->setLayout(centralLayout);
-    centralLayout->setMargin(0);
-    centralLayout->setSpacing(0);
-    centralLayout->addWidget(documentAndRightPane);
-    centralLayout->setStretch(0, 1);
-    centralLayout->setStretch(1, 0);
+    // Check the project for whether the build config is in the correct mode
+    // if not, notify the user and urge him to use the correct mode.
+    if (!buildTypeAccepted(m_toolMode, buildType)) {
+        QString currentMode;
+        switch (buildType) {
+            case BuildConfiguration::Debug:
+                currentMode = tr("Debug");
+                break;
+            case BuildConfiguration::Profile:
+                currentMode = tr("Profile");
+                break;
+            case BuildConfiguration::Release:
+                currentMode = tr("Release");
+                break;
+            default:
+                QTC_CHECK(false);
+        }
 
-    // Right-side window with editor, output etc.
-    auto mainWindowSplitter = new MiniSplitter;
-    mainWindowSplitter->addWidget(m_mainWindow);
-    auto outputPane = new OutputPanePlaceHolder(mode, mainWindowSplitter);
-    outputPane->setObjectName(QLatin1String("DebuggerOutputPanePlaceHolder"));
-    mainWindowSplitter->addWidget(outputPane);
-    mainWindowSplitter->setStretchFactor(0, 10);
-    mainWindowSplitter->setStretchFactor(1, 0);
-    mainWindowSplitter->setOrientation(Qt::Vertical);
+        QString toolModeString;
+        switch (m_toolMode) {
+            case DebugMode:
+                toolModeString = tr("in Debug mode");
+                break;
+            case ProfileMode:
+                toolModeString = tr("in Profile mode");
+                break;
+            case ReleaseMode:
+                toolModeString = tr("in Release mode");
+                break;
+            case SymbolsMode:
+                toolModeString = tr("with debug symbols (Debug or Profile mode)");
+                break;
+            case OptimizedMode:
+                toolModeString = tr("on optimized code (Profile or Release mode)");
+                break;
+            default:
+                QTC_CHECK(false);
+        }
+        const QString toolName = m_text; // The action text is always the name of the tool
+        const QString title = tr("Run %1 in %2 Mode?").arg(toolName).arg(currentMode);
+        const QString message = tr("<html><head/><body><p>You are trying "
+            "to run the tool \"%1\" on an application in %2 mode. "
+            "The tool is designed to be used %3.</p><p>"
+            "Run-time characteristics differ significantly between "
+            "optimized and non-optimized binaries. Analytical "
+            "findings for one mode may or may not be relevant for "
+            "the other.</p><p>"
+            "Running tools that need debug symbols on binaries that "
+            "don't provide any may lead to missing function names "
+            "or otherwise insufficient output.</p><p>"
+            "Do you want to continue and run the tool in %2 mode?</p></body></html>")
+                .arg(toolName).arg(currentMode).arg(toolModeString);
+        if (Utils::CheckableMessageBox::doNotAskAgainQuestion(ICore::mainWindow(),
+                title, message, ICore::settings(), QLatin1String("AnalyzerCorrectModeWarning"))
+                    != QDialogButtonBox::Yes)
+            return;
+    }
 
-    // Navigation and right-side window.
-    auto splitter = new MiniSplitter;
-    splitter->setFocusProxy(editorManagerPlaceHolder);
-    splitter->addWidget(new NavigationWidgetPlaceHolder(mode));
-    splitter->addWidget(mainWindowSplitter);
-    splitter->setStretchFactor(0, 0);
-    splitter->setStretchFactor(1, 1);
-    splitter->setObjectName(QLatin1String("DebugModeWidget"));
-    return splitter;
+    ProjectExplorerPlugin::runStartupProject(m_runMode);
 }
 
-//bool DockWidgetEventFilter::eventFilter(QObject *obj, QEvent *event)
-//{
-//    switch (event->type()) {
-//    case QEvent::Resize:
-//    case QEvent::ZOrderChange:
-//        dd->updateDockWidgetSettings();
-//        break;
-//    default:
-//        break;
-//    }
-//    return QObject::eventFilter(obj, event);
-//}
+void registerAction(Id actionId, const ActionDescription &desc, QAction *startAction)
+{
+    dd->registerAction(actionId, desc, startAction);
+}
+
+void registerToolbar(const QByteArray &perspectiveId, const ToolbarDescription &desc)
+{
+    auto toolbar = new QWidget;
+    toolbar->setObjectName(QString::fromLatin1(perspectiveId + ".Toolbar"));
+    auto hbox = new QHBoxLayout(toolbar);
+    hbox->setMargin(0);
+    hbox->setSpacing(0);
+    for (QWidget *widget : desc.widgets())
+        hbox->addWidget(widget);
+    hbox->addStretch();
+    toolbar->setLayout(hbox);
+
+    dd->m_mainWindow->registerToolbar(perspectiveId, toolbar);
+}
 
+QAction *createStartAction()
+{
+    auto action = new QAction(DebuggerMainWindow::tr("Start"), 0);
+    action->setIcon(Debugger::Icons::ANALYZER_CONTROL_START.icon());
+    action->setEnabled(true);
+    return action;
+}
+
+QAction *createStopAction()
+{
+    auto action = new QAction(DebuggerMainWindow::tr("Stop"), 0);
+    action->setIcon(ProjectExplorer::Icons::STOP_SMALL.icon());
+    action->setEnabled(true);
+    return action;
+}
+
+void registerPerspective(const QByteArray &perspectiveId, const Perspective &perspective)
+{
+    dd->m_mainWindow->registerPerspective(perspectiveId, perspective);
+}
+
+void selectPerspective(const QByteArray &perspectiveId)
+{
+    ModeManager::activateMode(MODE_DEBUG);
+    dd->selectPerspective(perspectiveId);
+}
+
+void runAction(Id actionId)
+{
+    ActionDescription desc = dd->m_descriptions.value(actionId);
+    desc.startTool();
+}
+
+void enableMainWindow(bool on)
+{
+    dd->m_mainWindow->setEnabled(on);
+}
+
+void showStatusMessage(const QString &message, int timeoutMS)
+{
+    dd->m_mainWindow->showStatusMessage(message, timeoutMS);
+}
+
+void showPermanentStatusMessage(const QString &message)
+{
+    dd->m_mainWindow->showStatusMessage(message, -1);
+}
+
+AnalyzerRunControl *createAnalyzerRunControl(RunConfiguration *runConfiguration, Id runMode)
+{
+    foreach (const ActionDescription &action, dd->m_descriptions) {
+        if (action.runMode() == runMode)
+            return action.runControlCreator()(runConfiguration, runMode);
+    }
+    return 0;
+}
+
+bool operator==(const AnalyzerConnection &c1, const AnalyzerConnection &c2)
+{
+    return c1.connParams == c2.connParams
+        && c1.analyzerHost == c2.analyzerHost
+        && c1.analyzerSocket == c2.analyzerSocket
+        && c1.analyzerPort == c2.analyzerPort;
+}
 
 #ifdef WITH_TESTS
 void DebuggerPluginPrivate::testLoadProject(const QString &proFile, const TestCallBack &cb)
diff --git a/src/plugins/debugger/debuggerruncontrol.cpp b/src/plugins/debugger/debuggerruncontrol.cpp
index 8edb6b40778f0d173593db375cead3e1fbbe5336..f676fbfe9bc970538919fe856d660429c448011c 100644
--- a/src/plugins/debugger/debuggerruncontrol.cpp
+++ b/src/plugins/debugger/debuggerruncontrol.cpp
@@ -25,6 +25,7 @@
 
 #include "debuggerruncontrol.h"
 
+#include "analyzer/analyzermanager.h"
 #include "debuggeractions.h"
 #include "debuggercore.h"
 #include "debuggerengine.h"
@@ -140,6 +141,7 @@ QString DebuggerRunControl::displayName() const
 
 void DebuggerRunControl::start()
 {
+    Debugger::selectPerspective(Debugger::Constants::CppPerspectiveId);
     TaskHub::clearTasks(Debugger::Constants::TASK_CATEGORY_DEBUGGER_DEBUGINFO);
     TaskHub::clearTasks(Debugger::Constants::TASK_CATEGORY_DEBUGGER_RUNTIME);
 
diff --git a/src/plugins/ios/iosanalyzesupport.cpp b/src/plugins/ios/iosanalyzesupport.cpp
index dc40be7f79db3648d352b39d629a454ecd9e7833..c9e7020af3590831db9d4a957278af8f64fa94c5 100644
--- a/src/plugins/ios/iosanalyzesupport.cpp
+++ b/src/plugins/ios/iosanalyzesupport.cpp
@@ -56,7 +56,7 @@
 #include <io.h>
 #endif
 
-using namespace Analyzer;
+using namespace Debugger;
 using namespace ProjectExplorer;
 
 namespace Ios {
diff --git a/src/plugins/ios/iosanalyzesupport.h b/src/plugins/ios/iosanalyzesupport.h
index 76c4da284d8546050be4cb74db755eb89bd7fa69..2b18c5f6936e5ba8b58f75d39523cb70dd69269f 100644
--- a/src/plugins/ios/iosanalyzesupport.h
+++ b/src/plugins/ios/iosanalyzesupport.h
@@ -33,7 +33,7 @@
 #include <QProcess>
 #include <QObject>
 
-namespace Analyzer { class AnalyzerRunControl; }
+namespace Debugger { class AnalyzerRunControl; }
 
 namespace Ios {
 namespace Internal {
@@ -47,7 +47,7 @@ class IosAnalyzeSupport : public QObject
 
 public:
     IosAnalyzeSupport(IosRunConfiguration *runConfig,
-                      Analyzer::AnalyzerRunControl *runControl, bool cppDebug, bool qmlDebug);
+                      Debugger::AnalyzerRunControl *runControl, bool cppDebug, bool qmlDebug);
     ~IosAnalyzeSupport();
 
 private:
@@ -59,7 +59,7 @@ private:
     void handleRemoteOutput(const QString &output);
     void handleRemoteErrorOutput(const QString &output);
 
-    Analyzer::AnalyzerRunControl *m_runControl;
+    Debugger::AnalyzerRunControl *m_runControl;
     IosRunner * const m_runner;
     QmlDebug::QmlOutputParser m_outputParser;
     int m_qmlPort;
diff --git a/src/plugins/ios/iosrunfactories.cpp b/src/plugins/ios/iosrunfactories.cpp
index bd5a0dbf5637fd1dd751b80bfd3c75aedca2200a..a8262b4abdd143cee757acab026394903700865f 100644
--- a/src/plugins/ios/iosrunfactories.cpp
+++ b/src/plugins/ios/iosrunfactories.cpp
@@ -48,7 +48,7 @@
 #include <qtsupport/qtsupportconstants.h>
 #include <coreplugin/id.h>
 
-using namespace Analyzer;
+using namespace Debugger;
 using namespace ProjectExplorer;
 using namespace QmakeProjectManager;
 
@@ -190,7 +190,7 @@ RunControl *IosRunControlFactory::create(RunConfiguration *runConfig,
     if (mode == ProjectExplorer::Constants::NORMAL_RUN_MODE)
         res = new Ios::Internal::IosRunControl(rc);
     else if (mode == ProjectExplorer::Constants::QML_PROFILER_RUN_MODE) {
-        AnalyzerRunControl *runControl = AnalyzerManager::createRunControl(runConfig, mode);
+        AnalyzerRunControl *runControl = Debugger::createAnalyzerRunControl(runConfig, mode);
         QTC_ASSERT(runControl, return 0);
         IDevice::ConstPtr device = DeviceKitInformation::device(target->kit());
         if (device.isNull())
diff --git a/src/plugins/qmlprofiler/localqmlprofilerrunner.cpp b/src/plugins/qmlprofiler/localqmlprofilerrunner.cpp
index 7492ce0ff1564be81cd9d5649db7b0a5e82b48b1..b79aa79e927484ed07c0b4587022b769de2ea67f 100644
--- a/src/plugins/qmlprofiler/localqmlprofilerrunner.cpp
+++ b/src/plugins/qmlprofiler/localqmlprofilerrunner.cpp
@@ -74,7 +74,7 @@ LocalQmlProfilerRunner::LocalQmlProfilerRunner(const Configuration &configuratio
             engine, &QmlProfilerRunControl::notifyRemoteFinished);
     connect(this, &LocalQmlProfilerRunner::appendMessage,
             engine, &QmlProfilerRunControl::logApplicationMessage);
-    connect(engine, &Analyzer::AnalyzerRunControl::starting,
+    connect(engine, &Debugger::AnalyzerRunControl::starting,
             this, &LocalQmlProfilerRunner::start);
     connect(engine, &RunControl::finished,
             this, &LocalQmlProfilerRunner::stop);
diff --git a/src/plugins/qmlprofiler/qmlprofilerplugin.cpp b/src/plugins/qmlprofiler/qmlprofilerplugin.cpp
index 4cad320dbf9edcbed7b5461ddc7fb390458a2809..be64b14a26ee4d781b4bae4f4c84a441a9101539 100644
--- a/src/plugins/qmlprofiler/qmlprofilerplugin.cpp
+++ b/src/plugins/qmlprofiler/qmlprofilerplugin.cpp
@@ -34,8 +34,6 @@
 
 #include <QtPlugin>
 
-using namespace Analyzer;
-
 namespace QmlProfiler {
 namespace Internal {
 
diff --git a/src/plugins/qmlprofiler/qmlprofilerrunconfigurationaspect.cpp b/src/plugins/qmlprofiler/qmlprofilerrunconfigurationaspect.cpp
index 27260698fe2d5d58bff33055ba9cedfda9e36c80..1522acba0d0ba03a48c6c66ac890ed23c750a413 100644
--- a/src/plugins/qmlprofiler/qmlprofilerrunconfigurationaspect.cpp
+++ b/src/plugins/qmlprofiler/qmlprofilerrunconfigurationaspect.cpp
@@ -53,7 +53,7 @@ ProjectExplorer::IRunConfigurationAspect *QmlProfilerRunConfigurationAspect::cre
 
 ProjectExplorer::RunConfigWidget *QmlProfilerRunConfigurationAspect::createConfigurationWidget()
 {
-    return new Analyzer::AnalyzerRunConfigWidget(this);
+    return new Debugger::AnalyzerRunConfigWidget(this);
 }
 
 } // Internal
diff --git a/src/plugins/qmlprofiler/qmlprofilerruncontrol.cpp b/src/plugins/qmlprofiler/qmlprofilerruncontrol.cpp
index 4626072e9673305b9beff60a7c4542b1947ec889..48ca56a213e624e1b88cea509cf100a3b7823049 100644
--- a/src/plugins/qmlprofiler/qmlprofilerruncontrol.cpp
+++ b/src/plugins/qmlprofiler/qmlprofilerruncontrol.cpp
@@ -51,7 +51,7 @@
 #include <QMessageBox>
 #include <QPushButton>
 
-using namespace Analyzer;
+using namespace Debugger;
 using namespace Core;
 using namespace ProjectExplorer;
 
@@ -102,16 +102,16 @@ QmlProfilerRunControl::QmlProfilerRunControl(RunConfiguration *runConfiguration,
 QmlProfilerRunControl::~QmlProfilerRunControl()
 {
     if (d->m_profilerState)
-        stopEngine();
+        stop();
     delete d;
 }
 
-bool QmlProfilerRunControl::startEngine()
+void QmlProfilerRunControl::start()
 {
     d->m_tool->finalizeRunControl(this);
-    QTC_ASSERT(d->m_profilerState, return false);
+    QTC_ASSERT(d->m_profilerState, finished(); return);
 
-    QTC_ASSERT(connection().is<AnalyzerConnection>(), return false);
+    QTC_ASSERT(connection().is<AnalyzerConnection>(), finished(); return);
     auto conn = connection().as<AnalyzerConnection>();
 
     if (conn.analyzerPort != 0)
@@ -120,13 +120,14 @@ bool QmlProfilerRunControl::startEngine()
         d->m_noDebugOutputTimer.start();
 
     d->m_profilerState->setCurrentState(QmlProfilerStateManager::AppRunning);
+    d->m_running = true;
     emit starting();
-    return true;
 }
 
-void QmlProfilerRunControl::stopEngine()
+RunControl::StopResult QmlProfilerRunControl::stop()
 {
-    QTC_ASSERT(d->m_profilerState, return);
+    d->m_running = false;
+    QTC_ASSERT(d->m_profilerState, return RunControl::StoppedSynchronously);
 
     switch (d->m_profilerState->currentState()) {
     case QmlProfilerStateManager::AppRunning:
@@ -147,6 +148,13 @@ void QmlProfilerRunControl::stopEngine()
     }
         break;
     }
+
+    return RunControl::StoppedSynchronously;
+}
+
+bool QmlProfilerRunControl::isRunning() const
+{
+    return d->m_running;
 }
 
 void QmlProfilerRunControl::notifyRemoteFinished()
@@ -156,7 +164,6 @@ void QmlProfilerRunControl::notifyRemoteFinished()
     switch (d->m_profilerState->currentState()) {
     case QmlProfilerStateManager::AppRunning:
         d->m_profilerState->setCurrentState(QmlProfilerStateManager::AppDying);
-        AnalyzerManager::stopTool();
         emit finished();
         break;
     case QmlProfilerStateManager::Idle:
@@ -215,7 +222,6 @@ void QmlProfilerRunControl::wrongSetupMessageBox(const QString &errorMessage)
     // KILL
     d->m_profilerState->setCurrentState(QmlProfilerStateManager::AppDying);
     d->m_noDebugOutputTimer.stop();
-    AnalyzerManager::stopTool();
     emit finished();
 }
 
@@ -270,12 +276,4 @@ void QmlProfilerRunControl::profilerStateChanged()
     }
 }
 
-RunControl::StopResult QmlProfilerRunControl::stop()
-{
-    StopResult result = Analyzer::AnalyzerRunControl::stop();
-    if (d->m_profilerState->currentState() != QmlProfilerStateManager::Idle)
-        m_isRunning = true;
-    return result;
-}
-
 } // namespace QmlProfiler
diff --git a/src/plugins/qmlprofiler/qmlprofilerruncontrol.h b/src/plugins/qmlprofiler/qmlprofilerruncontrol.h
index a7d42d7c34bed92a60986e015a8479fd4481dad7..a44e6c710a1e78b21fea38220a9647cecf0f5753 100644
--- a/src/plugins/qmlprofiler/qmlprofilerruncontrol.h
+++ b/src/plugins/qmlprofiler/qmlprofilerruncontrol.h
@@ -35,7 +35,7 @@ namespace QmlProfiler {
 
 namespace Internal { class QmlProfilerTool; }
 
-class QmlProfilerRunControl : public Analyzer::AnalyzerRunControl
+class QmlProfilerRunControl : public Debugger::AnalyzerRunControl
 {
     Q_OBJECT
 
@@ -47,25 +47,22 @@ public:
     void registerProfilerStateManager( QmlProfilerStateManager *profilerState );
 
     void notifyRemoteSetupDone(quint16 port) override;
+    void start() override;
     StopResult stop() override;
-
-signals:
-    void processRunning(quint16 port);
-
-public slots:
-    bool startEngine() override;
-    void stopEngine() override;
+    bool isRunning() const override;
     void cancelProcess();
     void notifyRemoteFinished() override;
     void logApplicationMessage(const QString &msg, Utils::OutputFormat format) override;
 
-private slots:
+signals:
+    void processRunning(quint16 port);
+
+private:
     void wrongSetupMessageBox(const QString &errorMessage);
     void wrongSetupMessageBoxFinished(int);
     void processIsRunning(quint16 port);
     void profilerStateChanged();
 
-private:
     class QmlProfilerRunControlPrivate;
     QmlProfilerRunControlPrivate *d;
 };
diff --git a/src/plugins/qmlprofiler/qmlprofilerruncontrolfactory.cpp b/src/plugins/qmlprofiler/qmlprofilerruncontrolfactory.cpp
index b6252f64b1864c1576a07df1c778fa5251fa4bf7..5803d2395760ce085471d2325e3880bae0882a46 100644
--- a/src/plugins/qmlprofiler/qmlprofilerruncontrolfactory.cpp
+++ b/src/plugins/qmlprofiler/qmlprofilerruncontrolfactory.cpp
@@ -45,7 +45,7 @@
 
 #include <utils/qtcassert.h>
 
-using namespace Analyzer;
+using namespace Debugger;
 using namespace ProjectExplorer;
 
 namespace QmlProfiler {
@@ -94,7 +94,7 @@ RunControl *QmlProfilerRunControlFactory::create(RunConfiguration *runConfigurat
     }
 
     auto runControl = qobject_cast<QmlProfilerRunControl *>
-             (AnalyzerManager::createRunControl(runConfiguration, mode));
+             (Debugger::createAnalyzerRunControl(runConfiguration, mode));
     QTC_ASSERT(runControl, return 0);
 
     runControl->setRunnable(runnable);
diff --git a/src/plugins/qmlprofiler/qmlprofilertool.cpp b/src/plugins/qmlprofiler/qmlprofilertool.cpp
index ed862ce019088bfed738c7c9caa09412cf2b5651..6cc38a234823a9e5baa4bf547958ae2f0b9528b4 100644
--- a/src/plugins/qmlprofiler/qmlprofilertool.cpp
+++ b/src/plugins/qmlprofiler/qmlprofilertool.cpp
@@ -82,8 +82,8 @@
 
 using namespace Core;
 using namespace Core::Constants;
-using namespace Analyzer;
-using namespace Analyzer::Constants;
+using namespace Debugger;
+using namespace Debugger::Constants;
 using namespace QmlProfiler::Constants;
 using namespace QmlDebug;
 using namespace ProjectExplorer;
@@ -103,6 +103,8 @@ public:
     QToolButton *m_recordButton = 0;
     QMenu *m_recordFeaturesMenu = 0;
 
+    QAction *m_startAction = 0;
+    QAction *m_stopAction = 0;
     QToolButton *m_clearButton = 0;
 
     // elapsed time display
@@ -120,6 +122,8 @@ public:
     // save and load actions
     QAction *m_saveQmlTrace = 0;
     QAction *m_loadQmlTrace = 0;
+
+    bool m_toolBusy = false;
 };
 
 QmlProfilerTool::QmlProfilerTool(QObject *parent)
@@ -176,8 +180,6 @@ QmlProfilerTool::QmlProfilerTool(QObject *parent)
 
     d->m_recordingTimer.setInterval(100);
     connect(&d->m_recordingTimer, &QTimer::timeout, this, &QmlProfilerTool::updateTimeDisplay);
-
-
     d->m_viewContainer = new QmlProfilerViewManager(this,
                                                     d->m_profilerModelManager,
                                                     d->m_profilerState);
@@ -187,14 +189,7 @@ QmlProfilerTool::QmlProfilerTool(QObject *parent)
     //
     // Toolbar
     //
-    QWidget *toolbarWidget = new QWidget;
-    toolbarWidget->setObjectName(QLatin1String("QmlProfilerToolBarWidget"));
-
-    QHBoxLayout *layout = new QHBoxLayout;
-    layout->setMargin(0);
-    layout->setSpacing(0);
-
-    d->m_recordButton = new QToolButton(toolbarWidget);
+    d->m_recordButton = new QToolButton;
     d->m_recordButton->setCheckable(true);
 
     connect(d->m_recordButton,&QAbstractButton::clicked,
@@ -207,9 +202,8 @@ QmlProfilerTool::QmlProfilerTool(QObject *parent)
             this, &QmlProfilerTool::toggleRequestedFeature);
 
     setRecording(d->m_profilerState->clientRecording());
-    layout->addWidget(d->m_recordButton);
 
-    d->m_clearButton = new QToolButton(toolbarWidget);
+    d->m_clearButton = new QToolButton;
     d->m_clearButton->setIcon(Icons::CLEAN_PANE.icon());
     d->m_clearButton->setToolTip(tr("Discard data"));
 
@@ -218,12 +212,9 @@ QmlProfilerTool::QmlProfilerTool(QObject *parent)
             clearData();
     });
 
-    layout->addWidget(d->m_clearButton);
-
     d->m_searchButton = new QToolButton;
     d->m_searchButton->setIcon(Icons::ZOOM.icon());
     d->m_searchButton->setToolTip(tr("Search timeline event notes."));
-    layout->addWidget(d->m_searchButton);
 
     connect(d->m_searchButton, &QToolButton::clicked, this, &QmlProfilerTool::showTimeLineSearch);
 
@@ -236,7 +227,6 @@ QmlProfilerTool::QmlProfilerTool(QObject *parent)
     d->m_displayFeaturesButton->setMenu(d->m_displayFeaturesMenu);
     connect(d->m_displayFeaturesMenu, &QMenu::triggered,
             this, &QmlProfilerTool::toggleVisibleFeature);
-    layout->addWidget(d->m_displayFeaturesButton);
 
     d->m_timeLabel = new QLabel();
     QPalette palette;
@@ -244,11 +234,7 @@ QmlProfilerTool::QmlProfilerTool(QObject *parent)
     d->m_timeLabel->setPalette(palette);
     d->m_timeLabel->setIndent(10);
     updateTimeDisplay();
-    layout->addWidget(d->m_timeLabel);
 
-    layout->addStretch();
-
-    toolbarWidget->setLayout(layout);
     setAvailableFeatures(d->m_profilerModelManager->availableFeatures());
     setRecordedFeatures(0);
 
@@ -263,6 +249,9 @@ QmlProfilerTool::QmlProfilerTool(QObject *parent)
     QString description = tr("The QML Profiler can be used to find performance "
                              "bottlenecks in applications using QML.");
 
+    d->m_startAction = Debugger::createStartAction();
+    d->m_stopAction = Debugger::createStopAction();
+
     ActionDescription desc;
     desc.setText(tr("QML Profiler"));
     desc.setToolTip(description);
@@ -270,8 +259,8 @@ QmlProfilerTool::QmlProfilerTool(QObject *parent)
     desc.setRunControlCreator(runControlCreator);
     desc.setToolPreparer([this] { return prepareTool(); });
     desc.setRunMode(ProjectExplorer::Constants::QML_PROFILER_RUN_MODE);
-    desc.setMenuGroup(Analyzer::Constants::G_ANALYZER_TOOLS);
-    AnalyzerManager::registerAction(Constants::QmlProfilerLocalActionId, desc);
+    desc.setMenuGroup(Debugger::Constants::G_ANALYZER_TOOLS);
+    Debugger::registerAction(Constants::QmlProfilerLocalActionId, desc, d->m_startAction);
 
     desc.setText(tr("QML Profiler (External)"));
     desc.setToolTip(description);
@@ -280,10 +269,21 @@ QmlProfilerTool::QmlProfilerTool(QObject *parent)
     desc.setCustomToolStarter([this](RunConfiguration *rc) { startRemoteTool(rc); });
     desc.setToolPreparer([this] { return prepareTool(); });
     desc.setRunMode(ProjectExplorer::Constants::QML_PROFILER_RUN_MODE);
-    desc.setMenuGroup(Analyzer::Constants::G_ANALYZER_REMOTE_TOOLS);
-    AnalyzerManager::registerAction(Constants::QmlProfilerRemoteActionId, desc);
+    desc.setMenuGroup(Debugger::Constants::G_ANALYZER_REMOTE_TOOLS);
+    Debugger::registerAction(Constants::QmlProfilerRemoteActionId, desc);
+
+    Utils::ToolbarDescription toolbar;
+    toolbar.addAction(d->m_startAction);
+    toolbar.addAction(d->m_stopAction);
+    toolbar.addWidget(d->m_recordButton);
+    toolbar.addWidget(d->m_clearButton);
+    toolbar.addWidget(d->m_searchButton);
+    toolbar.addWidget(d->m_displayFeaturesButton);
+    toolbar.addWidget(d->m_timeLabel);
+    Debugger::registerToolbar(Constants::QmlProfilerPerspectiveId, toolbar);
 
-    AnalyzerManager::registerToolbar(Constants::QmlProfilerPerspectiveId, toolbarWidget);
+    connect(ProjectExplorerPlugin::instance(), &ProjectExplorerPlugin::updateRunActions,
+            this, &QmlProfilerTool::updateRunActions);
 }
 
 QmlProfilerTool::~QmlProfilerTool()
@@ -291,6 +291,25 @@ QmlProfilerTool::~QmlProfilerTool()
     delete d;
 }
 
+void QmlProfilerTool::updateRunActions()
+{
+    if (d->m_toolBusy) {
+        d->m_startAction->setEnabled(false);
+        d->m_startAction->setToolTip(tr("A Qml Profiler analysis is still in progress."));
+        d->m_stopAction->setEnabled(true);
+    } else {
+        const bool projectUsable = SessionManager::startupProject() != 0;
+        d->m_startAction->setToolTip(tr("Start Qml Profiler."));
+        if (projectUsable) {
+            d->m_startAction->setEnabled(true);
+            d->m_stopAction->setEnabled(false);
+        } else {
+            d->m_startAction->setEnabled(false);
+            d->m_stopAction->setEnabled(false);
+        }
+    }
+}
+
 static QString sysroot(RunConfiguration *runConfig)
 {
     QTC_ASSERT(runConfig, return QString());
@@ -302,6 +321,7 @@ static QString sysroot(RunConfiguration *runConfig)
 
 AnalyzerRunControl *QmlProfilerTool::createRunControl(RunConfiguration *runConfiguration)
 {
+    d->m_toolBusy = true;
     if (runConfiguration) {
         QmlProfilerRunConfigurationAspect *aspect = static_cast<QmlProfilerRunConfigurationAspect *>(
                     runConfiguration->extraAspect(Constants::SETTINGS));
@@ -314,7 +334,16 @@ AnalyzerRunControl *QmlProfilerTool::createRunControl(RunConfiguration *runConfi
         }
     }
 
-    return new QmlProfilerRunControl(runConfiguration, this);
+    auto runControl = new QmlProfilerRunControl(runConfiguration, this);
+    connect(runControl, &RunControl::finished, [this, runControl] {
+        d->m_toolBusy = false;
+        updateRunActions();
+    });
+
+    connect(d->m_stopAction, &QAction::triggered, runControl, [runControl] { runControl->stop(); });
+
+    updateRunActions();
+    return runControl;
 }
 
 void QmlProfilerTool::finalizeRunControl(QmlProfilerRunControl *runControl)
@@ -503,8 +532,6 @@ bool QmlProfilerTool::prepareTool()
 
 void QmlProfilerTool::startRemoteTool(ProjectExplorer::RunConfiguration *rc)
 {
-    AnalyzerManager::showMode();
-
     Id kitId;
     quint16 port;
     Kit *kit = 0;
@@ -596,7 +623,7 @@ void QmlProfilerTool::showSaveDialog()
         if (!filename.endsWith(QLatin1String(TraceFileExtension)))
             filename += QLatin1String(TraceFileExtension);
         saveLastTraceFile(filename);
-        AnalyzerManager::enableMainWindow(false);
+        Debugger::enableMainWindow(false);
         d->m_profilerModelManager->save(filename);
     }
 }
@@ -606,10 +633,7 @@ void QmlProfilerTool::showLoadDialog()
     if (!checkForUnsavedNotes())
         return;
 
-    if (ModeManager::currentMode()->id() != MODE_ANALYZE)
-        AnalyzerManager::showMode();
-
-    AnalyzerManager::selectAction(QmlProfilerRemoteActionId);
+    Debugger::selectPerspective(QmlProfilerPerspectiveId);
 
     QString filename = QFileDialog::getOpenFileName(
                 ICore::mainWindow(), tr("Load QML Trace"),
@@ -618,7 +642,7 @@ void QmlProfilerTool::showLoadDialog()
 
     if (!filename.isEmpty()) {
         saveLastTraceFile(filename);
-        AnalyzerManager::enableMainWindow(false);
+        Debugger::enableMainWindow(false);
         connect(d->m_profilerModelManager, &QmlProfilerModelManager::recordedFeaturesChanged,
                 this, &QmlProfilerTool::setRecordedFeatures);
         d->m_profilerModelManager->load(filename);
@@ -629,7 +653,7 @@ void QmlProfilerTool::onLoadSaveFinished()
 {
     disconnect(d->m_profilerModelManager, &QmlProfilerModelManager::recordedFeaturesChanged,
                this, &QmlProfilerTool::setRecordedFeatures);
-    AnalyzerManager::enableMainWindow(true);
+    Debugger::enableMainWindow(true);
 }
 
 /*!
diff --git a/src/plugins/qmlprofiler/qmlprofilertool.h b/src/plugins/qmlprofiler/qmlprofilertool.h
index 23f740e2d31f40464f2918c9296f920ab28c5344..34c7e21505147a4316a30661412243c1d8c116de 100644
--- a/src/plugins/qmlprofiler/qmlprofilertool.h
+++ b/src/plugins/qmlprofiler/qmlprofilertool.h
@@ -51,7 +51,7 @@ public:
     explicit QmlProfilerTool(QObject *parent);
     ~QmlProfilerTool();
 
-    Analyzer::AnalyzerRunControl *createRunControl(ProjectExplorer::RunConfiguration *runConfiguration = 0);
+    Debugger::AnalyzerRunControl *createRunControl(ProjectExplorer::RunConfiguration *runConfiguration = 0);
     void finalizeRunControl(QmlProfilerRunControl *runControl);
 
     bool prepareTool();
@@ -96,6 +96,7 @@ private slots:
     void toggleVisibleFeature(QAction *action);
 
 private:
+    void updateRunActions();
     void clearDisplay();
     void populateFileFinder(QString projectDirectory = QString(), QString activeSysroot = QString());
     template<QmlDebug::ProfileFeature feature>
diff --git a/src/plugins/qmlprofiler/qmlprofilerviewmanager.cpp b/src/plugins/qmlprofiler/qmlprofilerviewmanager.cpp
index 9655734d9d23edb1b88a7f968526833be9375a1a..1c4a67e5b93574b15a7a66001ac2456eef13548d 100644
--- a/src/plugins/qmlprofiler/qmlprofilerviewmanager.cpp
+++ b/src/plugins/qmlprofiler/qmlprofilerviewmanager.cpp
@@ -40,7 +40,8 @@
 
 #include <QDockWidget>
 
-using namespace Analyzer;
+using namespace Debugger;
+using namespace Utils;
 
 namespace QmlProfiler {
 namespace Internal {
@@ -80,7 +81,7 @@ void QmlProfilerViewManager::createViews()
     QTC_ASSERT(d->profilerModelManager, return);
     QTC_ASSERT(d->profilerState, return);
 
-    //Utils::FancyMainWindow *mw = AnalyzerManager::mainWindow();
+    //Utils::FancyMainWindow *mw = Debugger::mainWindow();
 
     d->traceView = new QmlProfilerTraceView(0, this, d->profilerModelManager);
     d->traceView->setWindowTitle(tr("Timeline"));
@@ -90,12 +91,12 @@ void QmlProfilerViewManager::createViews()
             this, &QmlProfilerViewManager::typeSelected);
     connect(this, &QmlProfilerViewManager::typeSelected,
             d->traceView, &QmlProfilerTraceView::selectByTypeId);
-    AnalyzerManager::registerDockWidget(Constants::QmlProfilerTimelineDockId, d->traceView);
 
     new QmlProfilerStateWidget(d->profilerState, d->profilerModelManager, d->traceView);
 
-    Perspective perspective;
-    perspective.addOperation({Constants::QmlProfilerTimelineDockId, Core::Id(),
+    Utils::Perspective perspective;
+    perspective.setName(tr("QML Profiler"));
+    perspective.addOperation({Constants::QmlProfilerTimelineDockId, d->traceView, {},
                               Perspective::SplitVertical});
 
     d->eventsViews << new QmlProfilerStatisticsView(0, d->profilerModelManager);
@@ -118,19 +119,17 @@ void QmlProfilerViewManager::createViews()
                 this, &QmlProfilerViewManager::gotoSourceLocation);
         connect(view, &QmlProfilerEventsView::showFullRange,
                 this, [this](){restrictEventsToRange(-1, -1);});
-        Core::Id dockId = Core::Id::fromString(view->objectName());
-        AnalyzerManager::registerDockWidget(dockId, view);
-        perspective.addOperation({dockId, Constants::QmlProfilerTimelineDockId, Perspective::AddToTab});
+        QByteArray dockId = view->objectName().toLatin1();
+        perspective.addOperation({dockId, view, Constants::QmlProfilerTimelineDockId, Perspective::AddToTab});
         new QmlProfilerStateWidget(d->profilerState, d->profilerModelManager, view);
 
-        if (!settings->contains(view->parent()->objectName())) // parent() is QDockWidget.
-            settings->remove(QString());
+//        if (!settings->contains(view->parent()->objectName())) // parent() is QDockWidget.
+//            settings->remove(QString());
     }
-    AnalyzerManager::registerPerspective(Constants::QmlProfilerPerspectiveId, perspective);
+    perspective.addOperation({Constants::QmlProfilerTimelineDockId, 0, {}, Perspective::Raise});
+    Debugger::registerPerspective(Constants::QmlProfilerPerspectiveId, perspective);
 
     settings->endGroup();
-    QTC_ASSERT(qobject_cast<QDockWidget *>(d->traceView->parentWidget()), return);
-    d->traceView->parentWidget()->raise();
 }
 
 bool QmlProfilerViewManager::hasValidSelection() const
diff --git a/src/plugins/qnx/qnxanalyzesupport.cpp b/src/plugins/qnx/qnxanalyzesupport.cpp
index e25dcd58550d57d44a06d60db78ab3359a0cc1e7..289d7d1756ac2ea8e33b1ca0961533924d0250e4 100644
--- a/src/plugins/qnx/qnxanalyzesupport.cpp
+++ b/src/plugins/qnx/qnxanalyzesupport.cpp
@@ -45,7 +45,7 @@ namespace Qnx {
 namespace Internal {
 
 QnxAnalyzeSupport::QnxAnalyzeSupport(QnxRunConfiguration *runConfig,
-                                     Analyzer::AnalyzerRunControl *runControl)
+                                     Debugger::AnalyzerRunControl *runControl)
     : QnxAbstractRunSupport(runConfig, runControl)
     , m_runnable(runConfig->runnable().as<StandardRunnable>())
     , m_runControl(runControl)
@@ -65,7 +65,7 @@ QnxAnalyzeSupport::QnxAnalyzeSupport(QnxRunConfiguration *runConfig,
     connect(runner, &DeviceApplicationRunner::remoteStderr,
             this, &QnxAnalyzeSupport::handleRemoteOutput);
 
-    connect(m_runControl, &Analyzer::AnalyzerRunControl::starting,
+    connect(m_runControl, &Debugger::AnalyzerRunControl::starting,
             this, &QnxAnalyzeSupport::handleAdapterSetupRequested);
     connect(&m_outputParser, &QmlDebug::QmlOutputParser::waitingForConnectionOnPort,
             this, &QnxAnalyzeSupport::remoteIsRunning);
diff --git a/src/plugins/qnx/qnxanalyzesupport.h b/src/plugins/qnx/qnxanalyzesupport.h
index 6dbb23c09964abf199a283f4e06494fca01f908b..d1361fff3a82646bdb1b3e9f9413cf618f307a7b 100644
--- a/src/plugins/qnx/qnxanalyzesupport.h
+++ b/src/plugins/qnx/qnxanalyzesupport.h
@@ -32,7 +32,7 @@
 #include <utils/outputformat.h>
 #include <qmldebug/qmloutputparser.h>
 
-namespace Analyzer { class AnalyzerRunControl; }
+namespace Debugger { class AnalyzerRunControl; }
 
 namespace Qnx {
 namespace Internal {
@@ -44,7 +44,7 @@ class QnxAnalyzeSupport : public QnxAbstractRunSupport
 {
     Q_OBJECT
 public:
-    QnxAnalyzeSupport(QnxRunConfiguration *runConfig, Analyzer::AnalyzerRunControl *engine);
+    QnxAnalyzeSupport(QnxRunConfiguration *runConfig, Debugger::AnalyzerRunControl *engine);
 
 public slots:
     void handleProfilingFinished();
@@ -66,7 +66,7 @@ private:
     void startExecution();
 
     ProjectExplorer::StandardRunnable m_runnable;
-    Analyzer::AnalyzerRunControl *m_runControl;
+    Debugger::AnalyzerRunControl *m_runControl;
     QmlDebug::QmlOutputParser m_outputParser;
     int m_qmlPort;
 
diff --git a/src/plugins/qnx/qnxruncontrolfactory.cpp b/src/plugins/qnx/qnxruncontrolfactory.cpp
index cf38795e862a4b0bc95c65f2eda21e4cc81ddeb1..0b95af65b1ebfd202ff75b988c11c63538d2b80b 100644
--- a/src/plugins/qnx/qnxruncontrolfactory.cpp
+++ b/src/plugins/qnx/qnxruncontrolfactory.cpp
@@ -48,7 +48,6 @@
 #include <qtsupport/qtkitinformation.h>
 #include <utils/portlist.h>
 
-using namespace Analyzer;
 using namespace Debugger;
 using namespace ProjectExplorer;
 using namespace Qnx;
@@ -142,7 +141,7 @@ RunControl *QnxRunControlFactory::create(RunConfiguration *runConfig, Core::Id m
         const IDevice::ConstPtr device = DeviceKitInformation::device(kit);
         if (device.isNull())
             return 0;
-        AnalyzerRunControl *runControl = AnalyzerManager::createRunControl(runConfig, mode);
+        AnalyzerRunControl *runControl = Debugger::createAnalyzerRunControl(runConfig, mode);
         QTC_ASSERT(runControl, return 0);
         runControl->setRunnable(runConfig->runnable());
         AnalyzerConnection connection;
diff --git a/src/plugins/remotelinux/remotelinuxanalyzesupport.cpp b/src/plugins/remotelinux/remotelinuxanalyzesupport.cpp
index 0e88bea8736944bb9fe275d3b302a142d4cb3b6e..e63baf8949cedb89afd3240fdedc9bdeab10815a 100644
--- a/src/plugins/remotelinux/remotelinuxanalyzesupport.cpp
+++ b/src/plugins/remotelinux/remotelinuxanalyzesupport.cpp
@@ -45,7 +45,7 @@
 #include <QPointer>
 
 using namespace QSsh;
-using namespace Analyzer;
+using namespace Debugger;
 using namespace ProjectExplorer;
 using namespace Utils;
 
diff --git a/src/plugins/remotelinux/remotelinuxanalyzesupport.h b/src/plugins/remotelinux/remotelinuxanalyzesupport.h
index 9f69296a16d46f95bfa0f88d5ac7dd755d621d57..de083d38bce35709f0307ae46b551d32fcf120e0 100644
--- a/src/plugins/remotelinux/remotelinuxanalyzesupport.h
+++ b/src/plugins/remotelinux/remotelinuxanalyzesupport.h
@@ -33,7 +33,7 @@
 
 #include <utils/outputformat.h>
 
-namespace Analyzer { class AnalyzerRunControl; }
+namespace Debugger { class AnalyzerRunControl; }
 
 namespace RemoteLinux {
 
@@ -44,7 +44,7 @@ class REMOTELINUX_EXPORT RemoteLinuxAnalyzeSupport : public AbstractRemoteLinuxR
     Q_OBJECT
 public:
     RemoteLinuxAnalyzeSupport(ProjectExplorer::RunConfiguration *runConfig,
-            Analyzer::AnalyzerRunControl *engine, Core::Id runMode);
+            Debugger::AnalyzerRunControl *engine, Core::Id runMode);
     ~RemoteLinuxAnalyzeSupport();
 
 protected:
diff --git a/src/plugins/remotelinux/remotelinuxruncontrolfactory.cpp b/src/plugins/remotelinux/remotelinuxruncontrolfactory.cpp
index 42158d461784f4fddeb7dcf4400edff854b118c7..3439c977b4b1714f98c79ae817129138726899a7 100644
--- a/src/plugins/remotelinux/remotelinuxruncontrolfactory.cpp
+++ b/src/plugins/remotelinux/remotelinuxruncontrolfactory.cpp
@@ -48,7 +48,6 @@
 #include <utils/portlist.h>
 #include <utils/qtcassert.h>
 
-using namespace Analyzer;
 using namespace Debugger;
 using namespace ProjectExplorer;
 
@@ -139,7 +138,7 @@ RunControl *RemoteLinuxRunControlFactory::create(RunConfiguration *runConfig, Co
     }
 
     if (mode == ProjectExplorer::Constants::QML_PROFILER_RUN_MODE) {
-        auto runControl = AnalyzerManager::createRunControl(runConfig, mode);
+        auto runControl = Debugger::createAnalyzerRunControl(runConfig, mode);
         AnalyzerConnection connection;
         connection.connParams =
             DeviceKitInformation::device(runConfig->target()->kit())->sshParameters();
diff --git a/src/plugins/valgrind/callgrindengine.cpp b/src/plugins/valgrind/callgrindengine.cpp
index b3a9a183c0b792b900c4390f995e2172fb1a4702..cc7e41ac0dbf99c00ef003dbb8913458942d2e3b 100644
--- a/src/plugins/valgrind/callgrindengine.cpp
+++ b/src/plugins/valgrind/callgrindengine.cpp
@@ -35,7 +35,7 @@
 
 #include <utils/qtcassert.h>
 
-using namespace Analyzer;
+using namespace Debugger;
 using namespace Valgrind;
 using namespace Valgrind::Internal;
 
@@ -48,7 +48,7 @@ CallgrindRunControl::CallgrindRunControl(ProjectExplorer::RunConfiguration *runC
     connect(m_runner.parser(), &Callgrind::Parser::parserDataReady,
             this, &CallgrindRunControl::slotFinished);
     connect(&m_runner, &Callgrind::CallgrindRunner::statusMessage,
-            this, &AnalyzerManager::showPermanentStatusMessage);
+            this, &Debugger::showPermanentStatusMessage);
 }
 
 QStringList CallgrindRunControl::toolArguments() const
@@ -89,10 +89,10 @@ ValgrindRunner * CallgrindRunControl::runner()
     return &m_runner;
 }
 
-bool CallgrindRunControl::startEngine()
+void CallgrindRunControl::start()
 {
     appendMessage(tr("Profiling %1").arg(executable()) + QLatin1Char('\n'), Utils::NormalMessageFormat);
-    return ValgrindRunControl::startEngine();
+    return ValgrindRunControl::start();
 }
 
 void CallgrindRunControl::dump()
diff --git a/src/plugins/valgrind/callgrindengine.h b/src/plugins/valgrind/callgrindengine.h
index 87da36fd146ba0d635b05d828e4b84fba0e142e5..19e91a95b41db3a1a13c62279a5ceda7759d3104 100644
--- a/src/plugins/valgrind/callgrindengine.h
+++ b/src/plugins/valgrind/callgrindengine.h
@@ -41,7 +41,7 @@ class CallgrindRunControl : public ValgrindRunControl
 public:
     CallgrindRunControl(ProjectExplorer::RunConfiguration *runConfiguration);
 
-    bool startEngine() override;
+    void start() override;
 
     Valgrind::Callgrind::ParseData *takeParserData();
 
diff --git a/src/plugins/valgrind/callgrindtool.cpp b/src/plugins/valgrind/callgrindtool.cpp
index 9a625113113a22438f8ae471163e83ca3858e8a0..ec67a51b8bec6c18873541ca0e681921799c7827 100644
--- a/src/plugins/valgrind/callgrindtool.cpp
+++ b/src/plugins/valgrind/callgrindtool.cpp
@@ -43,6 +43,7 @@
 #include <valgrind/valgrindplugin.h>
 #include <valgrind/valgrindsettings.h>
 
+#include <debugger/debuggerconstants.h>
 #include <debugger/analyzer/analyzerconstants.h>
 #include <debugger/analyzer/analyzericons.h>
 #include <debugger/analyzer/analyzermanager.h>
@@ -90,11 +91,12 @@
 #include <QToolBar>
 #include <QToolButton>
 
-using namespace Analyzer;
+using namespace Debugger;
 using namespace Core;
 using namespace Valgrind::Callgrind;
 using namespace TextEditor;
 using namespace ProjectExplorer;
+using namespace Utils;
 
 namespace Valgrind {
 namespace Internal {
@@ -108,7 +110,6 @@ public:
     ~CallgrindTool();
 
     ValgrindRunControl *createRunControl(RunConfiguration *runConfiguration);
-    void createWidgets();
 
     void setParseData(ParseData *data);
     CostDelegate::CostFormat costFormat() const;
@@ -164,6 +165,7 @@ public:
 
     void editorOpened(IEditor *);
     void requestContextMenu(TextEditorWidget *widget, int line, QMenu *menu);
+    void updateRunActions();
 
 public:
     DataModel m_dataModel;
@@ -200,15 +202,17 @@ public:
 
     QVector<CallgrindTextMark *> m_textMarks;
 
+    QAction *m_startAction = 0;
+    QAction *m_stopAction = 0;
     QAction *m_loadExternalLogFile;
     QAction *m_dumpAction = 0;
     QAction *m_resetAction = 0;
     QAction *m_pauseAction = 0;
 
     QString m_toggleCollectFunction;
+    bool m_toolBusy = false;
 };
 
-
 CallgrindTool::CallgrindTool(QObject *parent)
     : QObject(parent)
 {
@@ -231,6 +235,9 @@ CallgrindTool::CallgrindTool(QObject *parent)
     connect(EditorManager::instance(), &EditorManager::editorOpened,
             this, &CallgrindTool::editorOpened);
 
+    m_startAction = Debugger::createStartAction();
+    m_stopAction = Debugger::createStopAction();
+
     ActionDescription desc;
     desc.setToolTip(tr("Valgrind Function Profile uses the "
         "Callgrind tool to record function calls when a program runs."));
@@ -243,13 +250,13 @@ CallgrindTool::CallgrindTool(QObject *parent)
         });
         desc.setToolMode(OptimizedMode);
         desc.setRunMode(CALLGRIND_RUN_MODE);
-        desc.setMenuGroup(Analyzer::Constants::G_ANALYZER_TOOLS);
-        AnalyzerManager::registerAction(CallgrindLocalActionId, desc);
+        desc.setMenuGroup(Debugger::Constants::G_ANALYZER_TOOLS);
+        Debugger::registerAction(CallgrindLocalActionId, desc, m_startAction);
     }
 
     desc.setText(tr("Valgrind Function Profiler (External Application)"));
     desc.setPerspectiveId(CallgrindPerspectiveId);
-    desc.setCustomToolStarter([this](ProjectExplorer::RunConfiguration *runConfig) {
+    desc.setCustomToolStarter([this](RunConfiguration *runConfig) {
         StartRemoteDialog dlg;
         if (dlg.exec() != QDialog::Accepted)
             return;
@@ -263,17 +270,17 @@ CallgrindTool::CallgrindTool(QObject *parent)
         rc->setDisplayName(runnable.executable);
         ProjectExplorerPlugin::startRunControl(rc, CALLGRIND_RUN_MODE);
     });
-    desc.setMenuGroup(Analyzer::Constants::G_ANALYZER_REMOTE_TOOLS);
-    AnalyzerManager::registerAction(CallgrindRemoteActionId, desc);
+    desc.setMenuGroup(Debugger::Constants::G_ANALYZER_REMOTE_TOOLS);
+    Debugger::registerAction(CallgrindRemoteActionId, desc);
 
     // If there is a CppEditor context menu add our own context menu actions.
     if (ActionContainer *editorContextMenu =
             ActionManager::actionContainer(CppEditor::Constants::M_CONTEXT)) {
-        Context analyzerContext = Context(Analyzer::Constants::C_ANALYZEMODE);
+        Context analyzerContext = Context(Debugger::Constants::C_DEBUGMODE);
         editorContextMenu->addSeparator(analyzerContext);
 
         auto action = new QAction(tr("Profile Costs of This Function and Its Callees"), this);
-        action->setIcon(Analyzer::Icons::ANALYZER_CONTROL_START.icon());
+        action->setIcon(Debugger::Icons::ANALYZER_CONTROL_START.icon());
         connect(action, &QAction::triggered, this,
                 &CallgrindTool::handleShowCostsOfFunction);
         Command *cmd = ActionManager::registerAction(action, "Analyzer.Callgrind.ShowCostsOfFunction",
@@ -283,7 +290,214 @@ CallgrindTool::CallgrindTool(QObject *parent)
         cmd->setAttribute(Command::CA_NonConfigurable);
     }
 
-    createWidgets();
+    QSettings *coreSettings = ICore::settings();
+
+    //
+    // DockWidgets
+    //
+    m_visualization = new Visualisation;
+    m_visualization->setFrameStyle(QFrame::NoFrame);
+    m_visualization->setObjectName(QLatin1String("Valgrind.CallgrindTool.Visualisation"));
+    m_visualization->setWindowTitle(tr("Visualization"));
+    m_visualization->setModel(&m_dataModel);
+    connect(m_visualization, &Visualisation::functionActivated,
+            this, &CallgrindTool::visualisationFunctionSelected);
+
+    m_callersView = new CostView;
+    m_callersView->setObjectName(QLatin1String("Valgrind.CallgrindTool.CallersView"));
+    m_callersView->setWindowTitle(tr("Callers"));
+    m_callersView->setSettings(coreSettings, "Valgrind.CallgrindTool.CallersView");
+    m_callersView->sortByColumn(CallModel::CostColumn);
+    m_callersView->setFrameStyle(QFrame::NoFrame);
+    // enable sorting
+    m_callersProxy.setSourceModel(&m_callersModel);
+    m_callersView->setModel(&m_callersProxy);
+    m_callersView->hideColumn(CallModel::CalleeColumn);
+    connect(m_callersView, &QAbstractItemView::activated,
+            this, &CallgrindTool::callerFunctionSelected);
+
+    m_calleesView = new CostView;
+    m_calleesView->setObjectName(QLatin1String("Valgrind.CallgrindTool.CalleesView"));
+    m_calleesView->setWindowTitle(tr("Callees"));
+    m_calleesView->setSettings(coreSettings, "Valgrind.CallgrindTool.CalleesView");
+    m_calleesView->sortByColumn(CallModel::CostColumn);
+    m_calleesView->setFrameStyle(QFrame::NoFrame);
+    // enable sorting
+    m_calleesProxy.setSourceModel(&m_calleesModel);
+    m_calleesView->setModel(&m_calleesProxy);
+    m_calleesView->hideColumn(CallModel::CallerColumn);
+    connect(m_calleesView, &QAbstractItemView::activated,
+            this, &CallgrindTool::calleeFunctionSelected);
+
+    m_flatView = new CostView;
+    m_flatView->setObjectName(QLatin1String("Valgrind.CallgrindTool.FlatView"));
+    m_flatView->setWindowTitle(tr("Functions"));
+    m_flatView->setSettings(coreSettings, "Valgrind.CallgrindTool.FlatView");
+    m_flatView->sortByColumn(DataModel::SelfCostColumn);
+    m_flatView->setFrameStyle(QFrame::NoFrame);
+    m_flatView->setAttribute(Qt::WA_MacShowFocusRect, false);
+    m_flatView->setModel(&m_proxyModel);
+    connect(m_flatView, &QAbstractItemView::activated,
+            this, &CallgrindTool::dataFunctionSelected);
+
+    updateCostFormat();
+
+    //
+    // Control Widget
+    //
+
+    // load external log file
+    auto action = m_loadExternalLogFile = new QAction(this);
+    action->setIcon(Core::Icons::OPENFILE.icon());
+    action->setToolTip(tr("Load External Log File"));
+    connect(action, &QAction::triggered, this, &CallgrindTool::loadExternalLogFile);
+
+    // dump action
+    m_dumpAction = action = new QAction(this);
+    action->setDisabled(true);
+    action->setIcon(Core::Icons::REDO.icon());
+    //action->setText(tr("Dump"));
+    action->setToolTip(tr("Request the dumping of profile information. This will update the Callgrind visualization."));
+    connect(action, &QAction::triggered, this, &CallgrindTool::slotRequestDump);
+
+    // reset action
+    m_resetAction = action = new QAction(this);
+    action->setDisabled(true);
+    action->setIcon(Core::Icons::RELOAD.icon());
+    //action->setText(tr("Reset"));
+    action->setToolTip(tr("Reset all event counters."));
+    connect(action, &QAction::triggered, this, &CallgrindTool::resetRequested);
+
+    // pause action
+    m_pauseAction = action = new QAction(this);
+    action->setCheckable(true);
+    action->setIcon(ProjectExplorer::Icons::INTERRUPT_SMALL.icon());
+    //action->setText(tr("Ignore"));
+    action->setToolTip(tr("Pause event logging. No events are counted which will speed up program execution during profiling."));
+    connect(action, &QAction::toggled, this, &CallgrindTool::pauseToggled);
+
+    // navigation
+    // go back
+    m_goBack = action = new QAction(this);
+    action->setDisabled(true);
+    action->setIcon(Core::Icons::PREV.icon());
+    action->setToolTip(tr("Go back one step in history. This will select the previously selected item."));
+    connect(action, &QAction::triggered, &m_stackBrowser, &StackBrowser::goBack);
+
+    // go forward
+    m_goNext = action = new QAction(this);
+    action->setDisabled(true);
+    action->setIcon(Core::Icons::NEXT.icon());
+    action->setToolTip(tr("Go forward one step in history."));
+    connect(action, &QAction::triggered, &m_stackBrowser, &StackBrowser::goNext);
+
+    // event selection
+    m_eventCombo = new QComboBox;
+    m_eventCombo->setToolTip(tr("Selects which events from the profiling data are shown and visualized."));
+    connect(m_eventCombo, static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged),
+            this, &CallgrindTool::setCostEvent);
+    updateEventCombo();
+
+    ToolbarDescription toolbar;
+    toolbar.addAction(m_startAction);
+    toolbar.addAction(m_stopAction);
+    toolbar.addAction(m_loadExternalLogFile);
+    toolbar.addAction(m_dumpAction);
+    toolbar.addAction(m_resetAction);
+    toolbar.addAction(m_pauseAction);
+    toolbar.addAction(m_goBack);
+    toolbar.addAction(m_goNext);
+    toolbar.addWidget(new Utils::StyledSeparator);
+    toolbar.addWidget(m_eventCombo);
+
+    // Cost formatting
+    {
+    auto menu = new QMenu;
+    auto group = new QActionGroup(this);
+
+    // Show costs as absolute numbers
+    m_costAbsolute = new QAction(tr("Absolute Costs"), this);
+    m_costAbsolute->setToolTip(tr("Show costs as absolute numbers."));
+    m_costAbsolute->setCheckable(true);
+    m_costAbsolute->setChecked(true);
+    connect(m_costAbsolute, &QAction::toggled, this, &CallgrindTool::updateCostFormat);
+    group->addAction(m_costAbsolute);
+    menu->addAction(m_costAbsolute);
+
+    // Show costs in percentages
+    m_costRelative = new QAction(tr("Relative Costs"), this);
+    m_costRelative->setToolTip(tr("Show costs relative to total inclusive cost."));
+    m_costRelative->setCheckable(true);
+    connect(m_costRelative, &QAction::toggled, this, &CallgrindTool::updateCostFormat);
+    group->addAction(m_costRelative);
+    menu->addAction(m_costRelative);
+
+    // Show costs relative to parent
+    m_costRelativeToParent = new QAction(tr("Relative Costs to Parent"), this);
+    m_costRelativeToParent->setToolTip(tr("Show costs relative to parent functions inclusive cost."));
+    m_costRelativeToParent->setCheckable(true);
+    connect(m_costRelativeToParent, &QAction::toggled, this, &CallgrindTool::updateCostFormat);
+    group->addAction(m_costRelativeToParent);
+    menu->addAction(m_costRelativeToParent);
+
+    auto button = new QToolButton;
+    button->setMenu(menu);
+    button->setPopupMode(QToolButton::InstantPopup);
+    button->setText(QLatin1String("$"));
+    button->setToolTip(tr("Cost Format"));
+    toolbar.addWidget(button);
+    }
+
+    ValgrindGlobalSettings *settings = ValgrindPlugin::globalSettings();
+
+    // Cycle detection
+    //action = new QAction(QLatin1String("Cycle Detection"), this); ///FIXME: icon
+    action = m_cycleDetection = new QAction(QLatin1String("O"), this); ///FIXME: icon
+    action->setToolTip(tr("Enable cycle detection to properly handle recursive or circular function calls."));
+    action->setCheckable(true);
+    connect(action, &QAction::toggled, &m_dataModel, &DataModel::enableCycleDetection);
+    connect(action, &QAction::toggled, settings, &ValgrindGlobalSettings::setDetectCycles);
+
+    // Shorter template signature
+    action = m_shortenTemplates = new QAction(QLatin1String("<>"), this);
+    action->setToolTip(tr("This removes template parameter lists when displaying function names."));
+    action->setCheckable(true);
+    connect(action, &QAction::toggled, &m_dataModel, &DataModel::setShortenTemplates);
+    connect(action, &QAction::toggled, settings, &ValgrindGlobalSettings::setShortenTemplates);
+
+    // Filtering
+    action = m_filterProjectCosts = new QAction(tr("Show Project Costs Only"), this);
+    action->setIcon(Core::Icons::FILTER.icon());
+    action->setToolTip(tr("Show only profiling info that originated from this project source."));
+    action->setCheckable(true);
+    connect(action, &QAction::toggled, this, &CallgrindTool::handleFilterProjectCosts);
+
+    // Filter
+    ///FIXME: find workaround for https://bugreports.qt.io/browse/QTCREATORBUG-3247
+    m_searchFilter = new QLineEdit;
+    m_searchFilter->setPlaceholderText(tr("Filter..."));
+    connect(m_searchFilter, &QLineEdit::textChanged,
+            &m_updateTimer, static_cast<void(QTimer::*)()>(&QTimer::start));
+
+    setCostFormat(settings->costFormat());
+    enableCycleDetection(settings->detectCycles());
+
+    toolbar.addAction(m_cycleDetection);
+    toolbar.addAction(m_shortenTemplates);
+    toolbar.addAction(m_filterProjectCosts);
+    toolbar.addWidget(m_searchFilter);
+    Debugger::registerToolbar(CallgrindPerspectiveId, toolbar);
+
+    Debugger::registerPerspective(CallgrindPerspectiveId, { tr("Callgrind"), {
+        { CallgrindFlatDockId, m_flatView, {}, Perspective::SplitVertical },
+        { CallgrindCalleesDockId, m_calleesView, {}, Perspective::SplitVertical },
+        { CallgrindCallersDockId, m_callersView, CallgrindCalleesDockId, Perspective::SplitHorizontal },
+        { CallgrindVisualizationDockId, m_visualization, {}, Perspective::SplitVertical,
+          false, Qt::RightDockWidgetArea }
+    }});
+
+    connect(ProjectExplorerPlugin::instance(), &ProjectExplorerPlugin::updateRunActions,
+            this, &CallgrindTool::updateRunActions);
 }
 
 CallgrindTool::~CallgrindTool()
@@ -521,34 +735,28 @@ void CallgrindTool::updateEventCombo()
         m_eventCombo->addItem(ParseData::prettyStringForEvent(event));
 }
 
-static QToolButton *createToolButton(QAction *action)
-{
-    QToolButton *button = new QToolButton;
-    button->setDefaultAction(action);
-    //button->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
-    return button;
-}
-
 ValgrindRunControl *CallgrindTool::createRunControl(RunConfiguration *runConfiguration)
 {
-    auto rc = new CallgrindRunControl(runConfiguration);
+    auto runControl = new CallgrindRunControl(runConfiguration);
+
+    connect(runControl, &CallgrindRunControl::parserDataReady, this, &CallgrindTool::takeParserDataFromRunControl);
+    connect(runControl, &AnalyzerRunControl::starting, this, &CallgrindTool::engineStarting);
+    connect(runControl, &RunControl::finished, this, &CallgrindTool::engineFinished);
 
-    connect(rc, &CallgrindRunControl::parserDataReady, this, &CallgrindTool::takeParserDataFromRunControl);
-    connect(rc, &AnalyzerRunControl::starting, this, &CallgrindTool::engineStarting);
-    connect(rc, &RunControl::finished, this, &CallgrindTool::engineFinished);
+    connect(this, &CallgrindTool::dumpRequested, runControl, &CallgrindRunControl::dump);
+    connect(this, &CallgrindTool::resetRequested, runControl, &CallgrindRunControl::reset);
+    connect(this, &CallgrindTool::pauseToggled, runControl, &CallgrindRunControl::setPaused);
 
-    connect(this, &CallgrindTool::dumpRequested, rc, &CallgrindRunControl::dump);
-    connect(this, &CallgrindTool::resetRequested, rc, &CallgrindRunControl::reset);
-    connect(this, &CallgrindTool::pauseToggled, rc, &CallgrindRunControl::setPaused);
+    connect(m_stopAction, &QAction::triggered, runControl, [runControl] { runControl->stop(); });
 
     // initialize run control
-    rc->setPaused(m_pauseAction->isChecked());
+    runControl->setPaused(m_pauseAction->isChecked());
 
     // we may want to toggle collect for one function only in this run
-    rc->setToggleCollectFunction(m_toggleCollectFunction);
+    runControl->setToggleCollectFunction(m_toggleCollectFunction);
     m_toggleCollectFunction.clear();
 
-    QTC_ASSERT(m_visualization, return rc);
+    QTC_ASSERT(m_visualization, return runControl);
 
     // apply project settings
     if (runConfiguration) {
@@ -560,241 +768,32 @@ ValgrindRunControl *CallgrindTool::createRunControl(RunConfiguration *runConfigu
             }
         }
     }
-    return rc;
-}
-
-void CallgrindTool::createWidgets()
-{
-    QTC_ASSERT(!m_visualization, return);
 
-    QSettings *coreSettings = ICore::settings();
-
-    //
-    // DockWidgets
-    //
-    m_visualization = new Visualisation;
-    m_visualization->setFrameStyle(QFrame::NoFrame);
-    m_visualization->setObjectName(QLatin1String("Valgrind.CallgrindTool.Visualisation"));
-    m_visualization->setWindowTitle(tr("Visualization"));
-    m_visualization->setModel(&m_dataModel);
-    connect(m_visualization, &Visualisation::functionActivated,
-            this, &CallgrindTool::visualisationFunctionSelected);
-
-    m_callersView = new CostView;
-    m_callersView->setObjectName(QLatin1String("Valgrind.CallgrindTool.CallersView"));
-    m_callersView->setWindowTitle(tr("Callers"));
-    m_callersView->setSettings(coreSettings, "Valgrind.CallgrindTool.CallersView");
-    m_callersView->sortByColumn(CallModel::CostColumn);
-    m_callersView->setFrameStyle(QFrame::NoFrame);
-    // enable sorting
-    m_callersProxy.setSourceModel(&m_callersModel);
-    m_callersView->setModel(&m_callersProxy);
-    m_callersView->hideColumn(CallModel::CalleeColumn);
-    connect(m_callersView, &QAbstractItemView::activated,
-            this, &CallgrindTool::callerFunctionSelected);
-
-    m_calleesView = new CostView;
-    m_calleesView->setObjectName(QLatin1String("Valgrind.CallgrindTool.CalleesView"));
-    m_calleesView->setWindowTitle(tr("Callees"));
-    m_calleesView->setSettings(coreSettings, "Valgrind.CallgrindTool.CalleesView");
-    m_calleesView->sortByColumn(CallModel::CostColumn);
-    m_calleesView->setFrameStyle(QFrame::NoFrame);
-    // enable sorting
-    m_calleesProxy.setSourceModel(&m_calleesModel);
-    m_calleesView->setModel(&m_calleesProxy);
-    m_calleesView->hideColumn(CallModel::CallerColumn);
-    connect(m_calleesView, &QAbstractItemView::activated,
-            this, &CallgrindTool::calleeFunctionSelected);
-
-    m_flatView = new CostView;
-    m_flatView->setObjectName(QLatin1String("Valgrind.CallgrindTool.FlatView"));
-    m_flatView->setWindowTitle(tr("Functions"));
-    m_flatView->setSettings(coreSettings, "Valgrind.CallgrindTool.FlatView");
-    m_flatView->sortByColumn(DataModel::SelfCostColumn);
-    m_flatView->setFrameStyle(QFrame::NoFrame);
-    m_flatView->setAttribute(Qt::WA_MacShowFocusRect, false);
-    m_flatView->setModel(&m_proxyModel);
-    connect(m_flatView, &QAbstractItemView::activated,
-            this, &CallgrindTool::dataFunctionSelected);
-
-    updateCostFormat();
-
-    //
-    // Control Widget
-    //
-    auto layout = new QHBoxLayout;
-    layout->setMargin(0);
-    layout->setSpacing(0);
-
-    auto widget = new QWidget;
-    widget->setLayout(layout);
-
-    // load external log file
-    auto action = new QAction(this);
-    action->setIcon(Core::Icons::OPENFILE.icon());
-    action->setToolTip(tr("Load External Log File"));
-    connect(action, &QAction::triggered, this, &CallgrindTool::loadExternalLogFile);
-    layout->addWidget(createToolButton(action));
-    m_loadExternalLogFile = action;
-
-    // dump action
-    action = new QAction(this);
-    action->setDisabled(true);
-    action->setIcon(Core::Icons::REDO.icon());
-    //action->setText(tr("Dump"));
-    action->setToolTip(tr("Request the dumping of profile information. This will update the Callgrind visualization."));
-    connect(action, &QAction::triggered, this, &CallgrindTool::slotRequestDump);
-    layout->addWidget(createToolButton(action));
-    m_dumpAction = action;
-
-    // reset action
-    action = new QAction(this);
-    action->setDisabled(true);
-    action->setIcon(Core::Icons::RELOAD.icon());
-    //action->setText(tr("Reset"));
-    action->setToolTip(tr("Reset all event counters."));
-    connect(action, &QAction::triggered, this, &CallgrindTool::resetRequested);
-    layout->addWidget(createToolButton(action));
-    m_resetAction = action;
-
-    // pause action
-    action = new QAction(this);
-    action->setCheckable(true);
-    action->setIcon(ProjectExplorer::Icons::INTERRUPT_SMALL.icon());
-    //action->setText(tr("Ignore"));
-    action->setToolTip(tr("Pause event logging. No events are counted which will speed up program execution during profiling."));
-    connect(action, &QAction::toggled, this, &CallgrindTool::pauseToggled);
-    layout->addWidget(createToolButton(action));
-    m_pauseAction = action;
-
-    // navigation
-    // go back
-    action = new QAction(this);
-    action->setDisabled(true);
-    action->setIcon(Core::Icons::PREV.icon());
-    action->setToolTip(tr("Go back one step in history. This will select the previously selected item."));
-    connect(action, &QAction::triggered, &m_stackBrowser, &StackBrowser::goBack);
-    layout->addWidget(createToolButton(action));
-    m_goBack = action;
+    m_toolBusy = true;
+    updateRunActions();
 
-    // go forward
-    action = new QAction(this);
-    action->setDisabled(true);
-    action->setIcon(Core::Icons::NEXT.icon());
-    action->setToolTip(tr("Go forward one step in history."));
-    connect(action, &QAction::triggered, &m_stackBrowser, &StackBrowser::goNext);
-    layout->addWidget(createToolButton(action));
-    m_goNext = action;
-
-    layout->addWidget(new Utils::StyledSeparator);
-
-    // event selection
-    m_eventCombo = new QComboBox;
-    m_eventCombo->setToolTip(tr("Selects which events from the profiling data are shown and visualized."));
-    connect(m_eventCombo, static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged),
-            this, &CallgrindTool::setCostEvent);
-    updateEventCombo();
-    layout->addWidget(m_eventCombo);
-
-    // Cost formatting
-    {
-    auto menu = new QMenu(layout->parentWidget());
-    auto group = new QActionGroup(this);
-
-    // Show costs as absolute numbers
-    m_costAbsolute = new QAction(tr("Absolute Costs"), this);
-    m_costAbsolute->setToolTip(tr("Show costs as absolute numbers."));
-    m_costAbsolute->setCheckable(true);
-    m_costAbsolute->setChecked(true);
-    connect(m_costAbsolute, &QAction::toggled, this, &CallgrindTool::updateCostFormat);
-    group->addAction(m_costAbsolute);
-    menu->addAction(m_costAbsolute);
-
-    // Show costs in percentages
-    m_costRelative = new QAction(tr("Relative Costs"), this);
-    m_costRelative->setToolTip(tr("Show costs relative to total inclusive cost."));
-    m_costRelative->setCheckable(true);
-    connect(m_costRelative, &QAction::toggled, this, &CallgrindTool::updateCostFormat);
-    group->addAction(m_costRelative);
-    menu->addAction(m_costRelative);
-
-    // Show costs relative to parent
-    m_costRelativeToParent = new QAction(tr("Relative Costs to Parent"), this);
-    m_costRelativeToParent->setToolTip(tr("Show costs relative to parent functions inclusive cost."));
-    m_costRelativeToParent->setCheckable(true);
-    connect(m_costRelativeToParent, &QAction::toggled, this, &CallgrindTool::updateCostFormat);
-    group->addAction(m_costRelativeToParent);
-    menu->addAction(m_costRelativeToParent);
+    return runControl;
+}
 
-    auto button = new QToolButton;
-    button->setMenu(menu);
-    button->setPopupMode(QToolButton::InstantPopup);
-    button->setText(QLatin1String("$"));
-    button->setToolTip(tr("Cost Format"));
-    layout->addWidget(button);
+void CallgrindTool::updateRunActions()
+{
+    if (m_toolBusy) {
+        m_startAction->setEnabled(false);
+        m_startAction->setToolTip(tr("A Valgrind Callgrind analysis is still in progress."));
+        m_stopAction->setEnabled(true);
+    } else {
+        const bool projectUsable = SessionManager::startupProject() != 0;
+        if (projectUsable) {
+            m_startAction->setEnabled(true);
+            m_startAction->setToolTip(tr("Start a Valgrind Callgrind analysis."));
+            m_stopAction->setEnabled(false);
+        } else {
+            m_startAction->setEnabled(false);
+            m_startAction->setToolTip(tr("Start a Valgrind Callgrind analysis."));
+            m_stopAction->setEnabled(false);
+        }
     }
-
-    ValgrindGlobalSettings *settings = ValgrindPlugin::globalSettings();
-
-    // Cycle detection
-    //action = new QAction(QLatin1String("Cycle Detection"), this); ///FIXME: icon
-    action = new QAction(QLatin1String("O"), this); ///FIXME: icon
-    action->setToolTip(tr("Enable cycle detection to properly handle recursive or circular function calls."));
-    action->setCheckable(true);
-    connect(action, &QAction::toggled, &m_dataModel, &DataModel::enableCycleDetection);
-    connect(action, &QAction::toggled, settings, &ValgrindGlobalSettings::setDetectCycles);
-    layout->addWidget(createToolButton(action));
-    m_cycleDetection = action;
-
-    // Shorter template signature
-    action = new QAction(QLatin1String("<>"), this);
-    action->setToolTip(tr("This removes template parameter lists when displaying function names."));
-    action->setCheckable(true);
-    connect(action, &QAction::toggled, &m_dataModel, &DataModel::setShortenTemplates);
-    connect(action, &QAction::toggled, settings, &ValgrindGlobalSettings::setShortenTemplates);
-    layout->addWidget(createToolButton(action));
-    m_shortenTemplates = action;
-
-    // Filtering
-    action = new QAction(tr("Show Project Costs Only"), this);
-    action->setIcon(Core::Icons::FILTER.icon());
-    action->setToolTip(tr("Show only profiling info that originated from this project source."));
-    action->setCheckable(true);
-    connect(action, &QAction::toggled, this, &CallgrindTool::handleFilterProjectCosts);
-    layout->addWidget(createToolButton(action));
-    m_filterProjectCosts = action;
-
-    // Filter
-    ///FIXME: find workaround for https://bugreports.qt.io/browse/QTCREATORBUG-3247
-    auto filter = new QLineEdit;
-    filter->setPlaceholderText(tr("Filter..."));
-    connect(filter, &QLineEdit::textChanged,
-            &m_updateTimer, static_cast<void(QTimer::*)()>(&QTimer::start));
-    layout->addWidget(filter);
-    m_searchFilter = filter;
-
-    setCostFormat(settings->costFormat());
-    enableCycleDetection(settings->detectCycles());
-
-    layout->addWidget(new Utils::StyledSeparator);
-    layout->addStretch();
-
-    AnalyzerManager::registerDockWidget(CallgrindCallersDockId, m_callersView);
-    AnalyzerManager::registerDockWidget(CallgrindFlatDockId, m_flatView);
-    AnalyzerManager::registerDockWidget(CallgrindCalleesDockId, m_calleesView);
-    AnalyzerManager::registerDockWidget(CallgrindVisualizationDockId, m_visualization);
-
-    AnalyzerManager::registerPerspective(CallgrindPerspectiveId, {
-        { CallgrindFlatDockId, Id(), Perspective::SplitVertical },
-        { CallgrindCalleesDockId, Id(), Perspective::SplitVertical },
-        { CallgrindCallersDockId, CallgrindCalleesDockId, Perspective::SplitHorizontal },
-        { CallgrindVisualizationDockId, Id(), Perspective::SplitVertical,
-          false, Qt::RightDockWidgetArea }
-    });
-
-    AnalyzerManager::registerToolbar(CallgrindPerspectiveId, widget);
 }
-
 void CallgrindTool::clearTextMarks()
 {
     qDeleteAll(m_textMarks);
@@ -813,6 +812,9 @@ void CallgrindTool::engineStarting()
 
 void CallgrindTool::engineFinished()
 {
+    m_toolBusy = false;
+    updateRunActions();
+
     // Enable/disable actions
     m_resetAction->setEnabled(false);
     m_dumpAction->setEnabled(false);
@@ -822,7 +824,7 @@ void CallgrindTool::engineFinished()
     if (data)
         showParserResults(data);
     else
-        AnalyzerManager::showPermanentStatusMessage(tr("Profiling aborted."));
+        Debugger::showPermanentStatusMessage(tr("Profiling aborted."));
 
     setBusyCursor(false);
 }
@@ -841,7 +843,7 @@ void CallgrindTool::showParserResults(const ParseData *data)
     } else {
         msg = tr("Parsing failed.");
     }
-    AnalyzerManager::showPermanentStatusMessage(msg);
+    Debugger::showPermanentStatusMessage(msg);
 }
 
 void CallgrindTool::editorOpened(IEditor *editor)
@@ -878,8 +880,7 @@ void CallgrindTool::handleShowCostsOfFunction()
     const QString qualifiedFunctionName = view.prettyName(CPlusPlus::LookupContext::fullyQualifiedName(symbol));
 
     m_toggleCollectFunction = qualifiedFunctionName + QLatin1String("()");
-
-    AnalyzerManager::selectAction(CallgrindLocalActionId, /* alsoRunIt = */ true);
+    m_startAction->trigger();
 }
 
 void CallgrindTool::slotRequestDump()
@@ -906,7 +907,7 @@ void CallgrindTool::loadExternalLogFile()
         return;
     }
 
-    AnalyzerManager::showPermanentStatusMessage(tr("Parsing Profile Data..."));
+    Debugger::showPermanentStatusMessage(tr("Parsing Profile Data..."));
     QCoreApplication::processEvents();
 
     Parser parser;
diff --git a/src/plugins/valgrind/memcheckengine.cpp b/src/plugins/valgrind/memcheckengine.cpp
index a40ffe9db2a8eb6834c68180e9461ff69fa7de2a..6d4a212c89174add378886afac1d5919b270a11a 100644
--- a/src/plugins/valgrind/memcheckengine.cpp
+++ b/src/plugins/valgrind/memcheckengine.cpp
@@ -44,7 +44,7 @@
 
 #include <utils/qtcassert.h>
 
-using namespace Analyzer;
+using namespace Debugger;
 using namespace ProjectExplorer;
 using namespace Valgrind::XmlProtocol;
 
@@ -72,20 +72,20 @@ ValgrindRunner *MemcheckRunControl::runner()
     return &m_runner;
 }
 
-bool MemcheckRunControl::startEngine()
+void MemcheckRunControl::start()
 {
     m_runner.setParser(&m_parser);
 
     appendMessage(tr("Analyzing memory of %1").arg(executable()) + QLatin1Char('\n'),
                         Utils::NormalMessageFormat);
-    return ValgrindRunControl::startEngine();
+    ValgrindRunControl::start();
 }
 
-void MemcheckRunControl::stopEngine()
+RunControl::StopResult MemcheckRunControl::stop()
 {
     disconnect(&m_parser, &ThreadedParser::internalError,
                this, &MemcheckRunControl::internalParserError);
-    ValgrindRunControl::stopEngine();
+    return ValgrindRunControl::stop();
 }
 
 QStringList MemcheckRunControl::toolArguments() const
diff --git a/src/plugins/valgrind/memcheckengine.h b/src/plugins/valgrind/memcheckengine.h
index a1ac1f8373dedd8227033bc5e733e494515da826..b619aa96694efea6a3d2ef1207fb4247d53c6ecd 100644
--- a/src/plugins/valgrind/memcheckengine.h
+++ b/src/plugins/valgrind/memcheckengine.h
@@ -43,8 +43,8 @@ public:
     MemcheckRunControl(ProjectExplorer::RunConfiguration *runConfiguration,
                        Core::Id runMode);
 
-    bool startEngine() override;
-    void stopEngine() override;
+    void start() override;
+    StopResult stop() override;
 
     QStringList suppressionFiles() const;
 
diff --git a/src/plugins/valgrind/memcheckerrorview.cpp b/src/plugins/valgrind/memcheckerrorview.cpp
index b3627965daa00e62e8ad9ca94a137509fb4b35e6..a15d7731337f9f574d7dc6dabf663bae0ec2c247 100644
--- a/src/plugins/valgrind/memcheckerrorview.cpp
+++ b/src/plugins/valgrind/memcheckerrorview.cpp
@@ -50,7 +50,7 @@ namespace Valgrind {
 namespace Internal {
 
 MemcheckErrorView::MemcheckErrorView(QWidget *parent)
-    : Analyzer::DetailedErrorView(parent),
+    : Debugger::DetailedErrorView(parent),
       m_settings(0)
 {
     m_suppressAction = new QAction(this);
diff --git a/src/plugins/valgrind/memcheckerrorview.h b/src/plugins/valgrind/memcheckerrorview.h
index 38f92fcf46f65b29b7c6f01d209ddf0de99ef392..205c7238415ffe2f2c9d3ae77e15e709e9f3fc85 100644
--- a/src/plugins/valgrind/memcheckerrorview.h
+++ b/src/plugins/valgrind/memcheckerrorview.h
@@ -36,7 +36,7 @@ namespace Internal {
 
 class ValgrindBaseSettings;
 
-class MemcheckErrorView : public Analyzer::DetailedErrorView
+class MemcheckErrorView : public Debugger::DetailedErrorView
 {
     Q_OBJECT
 
diff --git a/src/plugins/valgrind/memchecktool.cpp b/src/plugins/valgrind/memchecktool.cpp
index 43f15739c8a6aa866bc941ac9e4738663b376101..07431252ebc2129d015ff6ce83614f0f6b5064ac 100644
--- a/src/plugins/valgrind/memchecktool.cpp
+++ b/src/plugins/valgrind/memchecktool.cpp
@@ -85,14 +85,60 @@
 #include <QString>
 #include <QToolButton>
 
-using namespace Analyzer;
+using namespace Debugger;
 using namespace ProjectExplorer;
+using namespace Utils;
 using namespace Valgrind::XmlProtocol;
 
 namespace Valgrind {
 namespace Internal {
 
-class FrameFinder;
+class FrameFinder : public ErrorListModel::RelevantFrameFinder
+{
+public:
+    Frame findRelevant(const Error &error) const
+    {
+        const QVector<Stack> stacks = error.stacks();
+        if (stacks.isEmpty())
+            return Frame();
+        const Stack &stack = stacks[0];
+        const QVector<Frame> frames = stack.frames();
+        if (frames.isEmpty())
+            return Frame();
+
+        //find the first frame belonging to the project
+        if (!m_projectFiles.isEmpty()) {
+            foreach (const Frame &frame, frames) {
+                if (frame.directory().isEmpty() || frame.fileName().isEmpty())
+                    continue;
+
+                //filepaths can contain "..", clean them:
+                const QString f = QFileInfo(frame.filePath()).absoluteFilePath();
+                if (m_projectFiles.contains(f))
+                    return frame;
+            }
+        }
+
+        //if no frame belonging to the project was found, return the first one that is not malloc/new
+        foreach (const Frame &frame, frames) {
+            if (!frame.functionName().isEmpty() && frame.functionName() != QLatin1String("malloc")
+                && !frame.functionName().startsWith(QLatin1String("operator new(")))
+            {
+                return frame;
+            }
+        }
+
+        //else fallback to the first frame
+        return frames.first();
+    }
+    void setFiles(const QStringList &files)
+    {
+        m_projectFiles = files;
+    }
+private:
+    QStringList m_projectFiles;
+};
+
 
 class MemcheckErrorFilterProxyModel : public QSortFilterProxyModel
 {
@@ -203,12 +249,13 @@ class MemcheckTool : public QObject
 public:
     MemcheckTool(QObject *parent);
 
-    QWidget *createWidgets();
+    void createWidgets();
 
     MemcheckRunControl *createRunControl(ProjectExplorer::RunConfiguration *runConfiguration,
                                          Core::Id runMode);
 
 private:
+    void updateRunActions();
     void settingsDestroyed(QObject *settings);
     void maybeActiveRunConfigurationChanged();
 
@@ -240,10 +287,14 @@ private:
     QList<QAction *> m_errorFilterActions;
     QAction *m_filterProjectAction;
     QList<QAction *> m_suppressionActions;
+    QAction *m_startAction;
+    QAction *m_startWithGdbAction;
+    QAction *m_stopAction;
     QAction *m_suppressionSeparator;
     QAction *m_loadExternalLogFile;
     QAction *m_goBack;
     QAction *m_goNext;
+    bool m_toolBusy = false;
 };
 
 MemcheckTool::MemcheckTool(QObject *parent)
@@ -288,7 +339,79 @@ MemcheckTool::MemcheckTool(QObject *parent)
 
     using namespace std::placeholders;
 
-    AnalyzerManager::registerToolbar(MemcheckPerspectiveId, createWidgets());
+    QTC_ASSERT(!m_errorView, return);
+
+    m_errorView = new MemcheckErrorView;
+    m_errorView->setObjectName(QLatin1String("MemcheckErrorView"));
+    m_errorView->setFrameStyle(QFrame::NoFrame);
+    m_errorView->setAttribute(Qt::WA_MacShowFocusRect, false);
+    m_errorModel = new ErrorListModel(m_errorView);
+    m_frameFinder = new Internal::FrameFinder;
+    m_errorModel->setRelevantFrameFinder(QSharedPointer<Internal::FrameFinder>(m_frameFinder));
+    m_errorProxyModel = new MemcheckErrorFilterProxyModel(m_errorView);
+    m_errorProxyModel->setSourceModel(m_errorModel);
+    m_errorProxyModel->setDynamicSortFilter(true);
+    m_errorView->setModel(m_errorProxyModel);
+    m_errorView->setSelectionMode(QAbstractItemView::ExtendedSelection);
+    // make m_errorView->selectionModel()->selectedRows() return something
+    m_errorView->setSelectionBehavior(QAbstractItemView::SelectRows);
+    m_errorView->setVerticalScrollMode(QAbstractItemView::ScrollPerPixel);
+    m_errorView->setAutoScroll(false);
+    m_errorView->setObjectName(QLatin1String("Valgrind.MemcheckTool.ErrorView"));
+    m_errorView->setWindowTitle(tr("Memory Issues"));
+
+    Debugger::registerPerspective(MemcheckPerspectiveId, { tr("Memcheck"), {
+        { MemcheckErrorDockId, m_errorView, {}, Perspective::SplitVertical }
+    }});
+
+    connect(ProjectExplorerPlugin::instance(), &ProjectExplorerPlugin::updateRunActions,
+            this, &MemcheckTool::maybeActiveRunConfigurationChanged);
+
+    //
+    // The Control Widget.
+    //
+
+    m_startAction = Debugger::createStartAction();
+    m_startWithGdbAction = Debugger::createStartAction();
+    m_stopAction = Debugger::createStopAction();
+
+    // Load external XML log file
+    auto action = new QAction(this);
+    action->setIcon(Core::Icons::OPENFILE.icon());
+    action->setToolTip(tr("Load External XML Log File"));
+    connect(action, &QAction::triggered, this, &MemcheckTool::loadExternalXmlLogFile);
+    m_loadExternalLogFile = action;
+
+    // Go to previous leak.
+    action = new QAction(this);
+    action->setDisabled(true);
+    action->setIcon(Core::Icons::PREV.icon());
+    action->setToolTip(tr("Go to previous leak."));
+    connect(action, &QAction::triggered, m_errorView, &MemcheckErrorView::goBack);
+    m_goBack = action;
+
+    // Go to next leak.
+    action = new QAction(this);
+    action->setDisabled(true);
+    action->setIcon(Core::Icons::NEXT.icon());
+    action->setToolTip(tr("Go to next leak."));
+    connect(action, &QAction::triggered, m_errorView, &MemcheckErrorView::goNext);
+    m_goNext = action;
+
+    auto filterButton = new QToolButton;
+    filterButton->setIcon(Core::Icons::FILTER.icon());
+    filterButton->setText(tr("Error Filter"));
+    filterButton->setPopupMode(QToolButton::InstantPopup);
+    filterButton->setProperty("noArrow", true);
+
+    m_filterMenu = new QMenu(filterButton);
+    foreach (QAction *filterAction, m_errorFilterActions)
+        m_filterMenu->addAction(filterAction);
+    m_filterMenu->addSeparator();
+    m_filterMenu->addAction(m_filterProjectAction);
+    m_filterMenu->addAction(m_suppressionSeparator);
+    connect(m_filterMenu, &QMenu::triggered, this, &MemcheckTool::updateErrorFilter);
+    filterButton->setMenu(m_filterMenu);
 
     ActionDescription desc;
     desc.setToolTip(tr("Valgrind Analyze Memory uses the "
@@ -300,8 +423,8 @@ MemcheckTool::MemcheckTool(QObject *parent)
         desc.setRunControlCreator(std::bind(&MemcheckTool::createRunControl, this, _1, _2));
         desc.setToolMode(DebugMode);
         desc.setRunMode(MEMCHECK_RUN_MODE);
-        desc.setMenuGroup(Analyzer::Constants::G_ANALYZER_TOOLS);
-        AnalyzerManager::registerAction("Memcheck.Local", desc);
+        desc.setMenuGroup(Debugger::Constants::G_ANALYZER_TOOLS);
+        Debugger::registerAction("Memcheck.Local", desc, m_startAction);
 
         desc.setText(tr("Valgrind Memory Analyzer with GDB"));
         desc.setToolTip(tr("Valgrind Analyze Memory with GDB uses the "
@@ -311,8 +434,8 @@ MemcheckTool::MemcheckTool(QObject *parent)
         desc.setRunControlCreator(std::bind(&MemcheckTool::createRunControl, this, _1, _2));
         desc.setToolMode(DebugMode);
         desc.setRunMode(MEMCHECK_WITH_GDB_RUN_MODE);
-        desc.setMenuGroup(Analyzer::Constants::G_ANALYZER_TOOLS);
-        AnalyzerManager::registerAction("MemcheckWithGdb.Local", desc);
+        desc.setMenuGroup(Debugger::Constants::G_ANALYZER_TOOLS);
+        Debugger::registerAction("MemcheckWithGdb.Local", desc, m_startWithGdbAction);
     }
 
     desc.setText(tr("Valgrind Memory Analyzer (External Application)"));
@@ -331,8 +454,42 @@ MemcheckTool::MemcheckTool(QObject *parent)
         rc->setDisplayName(runnable.executable);
         ProjectExplorerPlugin::startRunControl(rc, MEMCHECK_RUN_MODE);
     });
-    desc.setMenuGroup(Analyzer::Constants::G_ANALYZER_REMOTE_TOOLS);
-    AnalyzerManager::registerAction("Memcheck.Remote", desc);
+    desc.setMenuGroup(Debugger::Constants::G_ANALYZER_REMOTE_TOOLS);
+    Debugger::registerAction("Memcheck.Remote", desc);
+
+    ToolbarDescription toolbar;
+    toolbar.addAction(m_startAction);
+    //toolbar.addAction(m_startWithGdbAction);
+    toolbar.addAction(m_stopAction);
+    toolbar.addAction(m_loadExternalLogFile);
+    toolbar.addAction(m_goBack);
+    toolbar.addAction(m_goNext);
+    toolbar.addWidget(filterButton);
+    Debugger::registerToolbar(MemcheckPerspectiveId, toolbar);
+}
+
+void MemcheckTool::updateRunActions()
+{
+    if (m_toolBusy) {
+        m_startAction->setEnabled(false);
+        m_startAction->setToolTip(tr("A Valgrind Memcheck analysis is still in progress."));
+        m_startWithGdbAction->setEnabled(false);
+        m_startWithGdbAction->setToolTip(tr("A Valgrind Memcheck analysis is still in progress."));
+        m_stopAction->setEnabled(true);
+    } else {
+        const bool projectUsable = SessionManager::startupProject() != 0;
+        m_startAction->setToolTip(tr("Start a Valgrind Memcheck analysis."));
+        m_startWithGdbAction->setToolTip(tr("Start a Valgrind Memcheck with GDB analysis."));
+        if (projectUsable) {
+            m_startAction->setEnabled(true);
+            m_startWithGdbAction->setEnabled(true);
+            m_stopAction->setEnabled(false);
+        } else {
+            m_startAction->setEnabled(false);
+            m_startWithGdbAction->setEnabled(false);
+            m_stopAction->setEnabled(false);
+        }
+    }
 }
 
 void MemcheckTool::settingsDestroyed(QObject *settings)
@@ -368,6 +525,8 @@ void MemcheckTool::updateFromSettings()
 
 void MemcheckTool::maybeActiveRunConfigurationChanged()
 {
+    updateRunActions();
+
     ValgrindBaseSettings *settings = 0;
     if (Project *project = SessionManager::startupProject())
         if (Target *target = project->activeTarget())
@@ -395,150 +554,6 @@ void MemcheckTool::maybeActiveRunConfigurationChanged()
     updateFromSettings();
 }
 
-class FrameFinder : public ErrorListModel::RelevantFrameFinder
-{
-public:
-    Frame findRelevant(const Error &error) const
-    {
-        const QVector<Stack> stacks = error.stacks();
-        if (stacks.isEmpty())
-            return Frame();
-        const Stack &stack = stacks[0];
-        const QVector<Frame> frames = stack.frames();
-        if (frames.isEmpty())
-            return Frame();
-
-        //find the first frame belonging to the project
-        if (!m_projectFiles.isEmpty()) {
-            foreach (const Frame &frame, frames) {
-                if (frame.directory().isEmpty() || frame.fileName().isEmpty())
-                    continue;
-
-                //filepaths can contain "..", clean them:
-                const QString f = QFileInfo(frame.filePath()).absoluteFilePath();
-                if (m_projectFiles.contains(f))
-                    return frame;
-            }
-        }
-
-        //if no frame belonging to the project was found, return the first one that is not malloc/new
-        foreach (const Frame &frame, frames) {
-            if (!frame.functionName().isEmpty() && frame.functionName() != QLatin1String("malloc")
-                && !frame.functionName().startsWith(QLatin1String("operator new(")))
-            {
-                return frame;
-            }
-        }
-
-        //else fallback to the first frame
-        return frames.first();
-    }
-    void setFiles(const QStringList &files)
-    {
-        m_projectFiles = files;
-    }
-private:
-    QStringList m_projectFiles;
-};
-
-
-QWidget *MemcheckTool::createWidgets()
-{
-    QTC_ASSERT(!m_errorView, return 0);
-
-    m_errorView = new MemcheckErrorView;
-    m_errorView->setObjectName(QLatin1String("MemcheckErrorView"));
-    m_errorView->setFrameStyle(QFrame::NoFrame);
-    m_errorView->setAttribute(Qt::WA_MacShowFocusRect, false);
-    m_errorModel = new ErrorListModel(m_errorView);
-    m_frameFinder = new Internal::FrameFinder;
-    m_errorModel->setRelevantFrameFinder(QSharedPointer<Internal::FrameFinder>(m_frameFinder));
-    m_errorProxyModel = new MemcheckErrorFilterProxyModel(m_errorView);
-    m_errorProxyModel->setSourceModel(m_errorModel);
-    m_errorProxyModel->setDynamicSortFilter(true);
-    m_errorView->setModel(m_errorProxyModel);
-    m_errorView->setSelectionMode(QAbstractItemView::ExtendedSelection);
-    // make m_errorView->selectionModel()->selectedRows() return something
-    m_errorView->setSelectionBehavior(QAbstractItemView::SelectRows);
-    m_errorView->setVerticalScrollMode(QAbstractItemView::ScrollPerPixel);
-    m_errorView->setAutoScroll(false);
-    m_errorView->setObjectName(QLatin1String("Valgrind.MemcheckTool.ErrorView"));
-    m_errorView->setWindowTitle(tr("Memory Issues"));
-
-    AnalyzerManager::registerDockWidget(MemcheckErrorDockId, m_errorView);
-
-    AnalyzerManager::registerPerspective(MemcheckPerspectiveId, {
-        { MemcheckErrorDockId, Core::Id(), Perspective::SplitVertical }
-    });
-
-    connect(ProjectExplorerPlugin::instance(), &ProjectExplorerPlugin::updateRunActions,
-            this, &MemcheckTool::maybeActiveRunConfigurationChanged);
-
-    //
-    // The Control Widget.
-    //
-    QAction *action = 0;
-    QHBoxLayout *layout = new QHBoxLayout;
-    QToolButton *button = 0;
-
-    layout->setMargin(0);
-    layout->setSpacing(0);
-
-    // Load external XML log file
-    action = new QAction(this);
-    action->setIcon(Core::Icons::OPENFILE.icon());
-    action->setToolTip(tr("Load External XML Log File"));
-    connect(action, &QAction::triggered, this, &MemcheckTool::loadExternalXmlLogFile);
-    button = new QToolButton;
-    button->setDefaultAction(action);
-    layout->addWidget(button);
-    m_loadExternalLogFile = action;
-
-    // Go to previous leak.
-    action = new QAction(this);
-    action->setDisabled(true);
-    action->setIcon(Core::Icons::PREV.icon());
-    action->setToolTip(tr("Go to previous leak."));
-    connect(action, &QAction::triggered, m_errorView, &MemcheckErrorView::goBack);
-    button = new QToolButton;
-    button->setDefaultAction(action);
-    layout->addWidget(button);
-    m_goBack = action;
-
-    // Go to next leak.
-    action = new QAction(this);
-    action->setDisabled(true);
-    action->setIcon(Core::Icons::NEXT.icon());
-    action->setToolTip(tr("Go to next leak."));
-    connect(action, &QAction::triggered, m_errorView, &MemcheckErrorView::goNext);
-    button = new QToolButton;
-    button->setDefaultAction(action);
-    layout->addWidget(button);
-    m_goNext = action;
-
-    QToolButton *filterButton = new QToolButton;
-    filterButton->setIcon(Core::Icons::FILTER.icon());
-    filterButton->setText(tr("Error Filter"));
-    filterButton->setPopupMode(QToolButton::InstantPopup);
-    filterButton->setProperty("noArrow", true);
-
-    m_filterMenu = new QMenu(filterButton);
-    foreach (QAction *filterAction, m_errorFilterActions)
-        m_filterMenu->addAction(filterAction);
-    m_filterMenu->addSeparator();
-    m_filterMenu->addAction(m_filterProjectAction);
-    m_filterMenu->addAction(m_suppressionSeparator);
-    connect(m_filterMenu, &QMenu::triggered, this, &MemcheckTool::updateErrorFilter);
-    filterButton->setMenu(m_filterMenu);
-    layout->addWidget(filterButton);
-
-    layout->addStretch();
-    QWidget *widget = new QWidget;
-    widget->setObjectName(QLatin1String("MemCheckToolBarWidget"));
-    widget->setLayout(layout);
-    return widget;
-}
-
 MemcheckRunControl *MemcheckTool::createRunControl(RunConfiguration *runConfiguration,
                                                    Core::Id runMode)
 {
@@ -555,6 +570,12 @@ MemcheckRunControl *MemcheckTool::createRunControl(RunConfiguration *runConfigur
     connect(runControl, &MemcheckRunControl::parserError, this, &MemcheckTool::parserError);
     connect(runControl, &MemcheckRunControl::internalParserError, this, &MemcheckTool::internalParserError);
     connect(runControl, &MemcheckRunControl::finished, this, &MemcheckTool::engineFinished);
+
+    connect(m_stopAction, &QAction::triggered, runControl, [runControl] { runControl->stop(); });
+
+    m_toolBusy = true;
+    updateRunActions();
+
     return runControl;
 }
 
@@ -673,18 +694,19 @@ int MemcheckTool::updateUiAfterFinishedHelper()
 
 void MemcheckTool::engineFinished()
 {
+    m_toolBusy = false;
+    updateRunActions();
+
     const int issuesFound = updateUiAfterFinishedHelper();
-    AnalyzerManager::showPermanentStatusMessage(issuesFound > 0
-        ? AnalyzerManager::tr("Memory Analyzer Tool finished, %n issues were found.", 0, issuesFound)
-        : AnalyzerManager::tr("Memory Analyzer Tool finished, no issues were found."));
+    Debugger::showPermanentStatusMessage(
+        tr("Memory Analyzer Tool finished, %n issues were found.", 0, issuesFound));
 }
 
 void MemcheckTool::loadingExternalXmlLogFileFinished()
 {
     const int issuesFound = updateUiAfterFinishedHelper();
-    AnalyzerManager::showPermanentStatusMessage(issuesFound > 0
-        ? AnalyzerManager::tr("Log file processed, %n issues were found.", 0, issuesFound)
-        : AnalyzerManager::tr("Log file processed, no issues were found."));
+    Debugger::showPermanentStatusMessage(
+        tr("Log file processed, %n issues were found.", 0, issuesFound));
 }
 
 void MemcheckTool::setBusyCursor(bool busy)
diff --git a/src/plugins/valgrind/valgrindengine.cpp b/src/plugins/valgrind/valgrindengine.cpp
index 12c2215c4075c3a81e2f8fe9c3cc1ba601a57c71..2f3825d2b597f31d7b79a22152a57a603efa0ade 100644
--- a/src/plugins/valgrind/valgrindengine.cpp
+++ b/src/plugins/valgrind/valgrindengine.cpp
@@ -43,7 +43,7 @@
 
 #define VALGRIND_DEBUG_OUTPUT 0
 
-using namespace Analyzer;
+using namespace Debugger;
 using namespace Core;
 using namespace Utils;
 using namespace ProjectExplorer;
@@ -65,10 +65,8 @@ ValgrindRunControl::ValgrindRunControl(RunConfiguration *runConfiguration, Core:
         m_settings = ValgrindPlugin::globalSettings();
 }
 
-bool ValgrindRunControl::startEngine()
+void ValgrindRunControl::start()
 {
-    emit starting();
-
     FutureProgress *fp = ProgressManager::addTimedTask(m_progress, progressTitle(), "valgrind", 100);
     fp->setKeepOnFinish(FutureProgress::HideOnFinish);
     connect(fp, &FutureProgress::canceled,
@@ -86,7 +84,6 @@ bool ValgrindRunControl::startEngine()
     ValgrindRunner *run = runner();
     run->setValgrindExecutable(m_settings->valgrindExecutable());
     run->setValgrindArguments(genericToolArguments() + toolArguments());
-    QTC_ASSERT(!device().isNull(), return false);
     run->setDevice(device());
     run->setDebuggee(runnable().as<StandardRunnable>());
 
@@ -99,15 +96,24 @@ bool ValgrindRunControl::startEngine()
 
     if (!run->start()) {
         m_progress.cancel();
-        return false;
+        emit finished();
+        return;
     }
-    return true;
+
+    m_isRunning = true;
+    emit started();
 }
 
-void ValgrindRunControl::stopEngine()
+RunControl::StopResult ValgrindRunControl::stop()
 {
     m_isStopping = true;
     runner()->stop();
+    return AsynchronousStop;
+}
+
+bool ValgrindRunControl::isRunning() const
+{
+    return m_isRunning;
 }
 
 QString ValgrindRunControl::executable() const
@@ -139,7 +145,6 @@ QStringList ValgrindRunControl::genericToolArguments() const
 
 void ValgrindRunControl::handleProgressCanceled()
 {
-    AnalyzerManager::stopTool();
     m_progress.reportCanceled();
     m_progress.reportFinished();
 }
@@ -151,6 +156,8 @@ void ValgrindRunControl::handleProgressFinished()
 
 void ValgrindRunControl::runnerFinished()
 {
+    m_isRunning = false;
+
     appendMessage(tr("Analyzing finished.") + QLatin1Char('\n'), NormalMessageFormat);
     emit finished();
 
diff --git a/src/plugins/valgrind/valgrindengine.h b/src/plugins/valgrind/valgrindengine.h
index 302f3a7bdb4699a6222a7f282e2571bbe697cb9b..fa9ffcc91aabdc8bc5b5b30aa9f89aa22582ff06 100644
--- a/src/plugins/valgrind/valgrindengine.h
+++ b/src/plugins/valgrind/valgrindengine.h
@@ -38,7 +38,7 @@
 namespace Valgrind {
 namespace Internal {
 
-class ValgrindRunControl : public Analyzer::AnalyzerRunControl
+class ValgrindRunControl : public Debugger::AnalyzerRunControl
 {
     Q_OBJECT
 
@@ -46,8 +46,9 @@ public:
     ValgrindRunControl(ProjectExplorer::RunConfiguration *runConfiguration,
                        Core::Id runMode);
 
-    bool startEngine() override;
-    void stopEngine() override;
+    void start() override;
+    StopResult stop() override;
+    bool isRunning() const override;
 
     QString executable() const;
 
@@ -70,6 +71,7 @@ private:
     QStringList genericToolArguments() const;
 
 private:
+    bool m_isRunning = false;
     bool m_isStopping = false;
 };
 
diff --git a/src/plugins/valgrind/valgrindruncontrolfactory.cpp b/src/plugins/valgrind/valgrindruncontrolfactory.cpp
index 2db334b5845d73bf6ffaa26e286ee0df0b189caf..f1338b1665587e95640d35181bb7ec616ef33de9 100644
--- a/src/plugins/valgrind/valgrindruncontrolfactory.cpp
+++ b/src/plugins/valgrind/valgrindruncontrolfactory.cpp
@@ -36,7 +36,7 @@
 
 #include <utils/qtcassert.h>
 
-using namespace Analyzer;
+using namespace Debugger;
 using namespace ProjectExplorer;
 
 namespace Valgrind {
@@ -56,7 +56,7 @@ bool ValgrindRunControlFactory::canRun(RunConfiguration *runConfiguration, Core:
 RunControl *ValgrindRunControlFactory::create(RunConfiguration *runConfiguration, Core::Id mode, QString *errorMessage)
 {
     Q_UNUSED(errorMessage);
-    return AnalyzerManager::createRunControl(runConfiguration, mode);
+    return Debugger::createAnalyzerRunControl(runConfiguration, mode);
 }
 
 class ValgrindRunConfigurationAspect : public IRunConfigurationAspect
diff --git a/src/plugins/valgrind/valgrindrunner.cpp b/src/plugins/valgrind/valgrindrunner.cpp
index 763e7110261baf0a4638f7bc202707abd9384754..420b5e88775e44cd2493ab0f71ce9586fec11152 100644
--- a/src/plugins/valgrind/valgrindrunner.cpp
+++ b/src/plugins/valgrind/valgrindrunner.cpp
@@ -188,8 +188,8 @@ QString ValgrindRunner::errorString() const
 
 void ValgrindRunner::stop()
 {
-    if (d->process)
-        d->process->close();
+    QTC_ASSERT(d->process, finished(); return);
+    d->process->close();
 }
 
 ValgrindProcess *ValgrindRunner::valgrindProcess() const
diff --git a/src/plugins/valgrind/xmlprotocol/errorlistmodel.cpp b/src/plugins/valgrind/xmlprotocol/errorlistmodel.cpp
index c625a58920a4930633de4b0e4ba6570ad6524889..915b0ab4e88f1a9e05e23fea56f1e5a2f101763c 100644
--- a/src/plugins/valgrind/xmlprotocol/errorlistmodel.cpp
+++ b/src/plugins/valgrind/xmlprotocol/errorlistmodel.cpp
@@ -191,8 +191,8 @@ ErrorItem::ErrorItem(const ErrorListModelPrivate *modelPrivate, const Error &err
 static QVariant location(const Frame &frame, int role)
 {
     switch (role) {
-    case Analyzer::DetailedErrorView::LocationRole:
-        return QVariant::fromValue(Analyzer::DiagnosticLocation(frame.filePath(), frame.line(), 0));
+    case Debugger::DetailedErrorView::LocationRole:
+        return QVariant::fromValue(Debugger::DiagnosticLocation(frame.filePath(), frame.line(), 0));
     case Qt::ToolTipRole:
         return frame.filePath().isEmpty() ? QVariant() : QVariant(frame.filePath());
     default:
@@ -202,14 +202,14 @@ static QVariant location(const Frame &frame, int role)
 
 QVariant ErrorItem::data(int column, int role) const
 {
-    if (column == Analyzer::DetailedErrorView::LocationColumn) {
+    if (column == Debugger::DetailedErrorView::LocationColumn) {
         const Frame frame = m_modelPrivate->findRelevantFrame(m_error);
         return location(frame, role);
     }
 
     // DiagnosticColumn
     switch (role) {
-    case Analyzer::DetailedErrorView::FullTextRole: {
+    case Debugger::DetailedErrorView::FullTextRole: {
         QString content;
         QTextStream stream(&content);
 
@@ -257,7 +257,7 @@ StackItem::StackItem(const Stack &stack) : m_stack(stack)
 QVariant StackItem::data(int column, int role) const
 {
     const ErrorItem * const errorItem = getErrorItem();
-    if (column == Analyzer::DetailedErrorView::LocationColumn)
+    if (column == Debugger::DetailedErrorView::LocationColumn)
         return location(errorItem->modelPrivate()->findRelevantFrame(errorItem->error()), role);
 
     // DiagnosticColumn
@@ -285,7 +285,7 @@ FrameItem::FrameItem(const Frame &frame) : m_frame(frame)
 
 QVariant FrameItem::data(int column, int role) const
 {
-    if (column == Analyzer::DetailedErrorView::LocationColumn)
+    if (column == Debugger::DetailedErrorView::LocationColumn)
         return location(m_frame, role);
 
     // DiagnosticColumn
diff --git a/src/plugins/valgrind/xmlprotocol/errorlistmodel.h b/src/plugins/valgrind/xmlprotocol/errorlistmodel.h
index 9db79252b3cfdc015001edde7260cee37b3552f4..ec7f5de61c67c8291c121fa6ef0d3c14e4119f50 100644
--- a/src/plugins/valgrind/xmlprotocol/errorlistmodel.h
+++ b/src/plugins/valgrind/xmlprotocol/errorlistmodel.h
@@ -45,7 +45,7 @@ class ErrorListModel : public Utils::TreeModel
 
 public:
     enum Role {
-        ErrorRole = Analyzer::DetailedErrorView::FullTextRole + 1,
+        ErrorRole = Debugger::DetailedErrorView::FullTextRole + 1,
     };
 
     class RelevantFrameFinder
diff --git a/tests/auto/clangstaticanalyzer/clangstaticanalyzerlogfilereader/tst_clangstaticanalyzerlogfilereader.cpp b/tests/auto/clangstaticanalyzer/clangstaticanalyzerlogfilereader/tst_clangstaticanalyzerlogfilereader.cpp
index e8050c514ed218ae4f325869a0af761b759cf638..076f576e82bf5c8cee71e0b8abe32a303f59cdff 100644
--- a/tests/auto/clangstaticanalyzer/clangstaticanalyzerlogfilereader/tst_clangstaticanalyzerlogfilereader.cpp
+++ b/tests/auto/clangstaticanalyzer/clangstaticanalyzerlogfilereader/tst_clangstaticanalyzerlogfilereader.cpp
@@ -31,7 +31,7 @@
 
 enum { debug = 0 };
 
-using namespace Analyzer;
+using namespace Debugger;
 using namespace ClangStaticAnalyzer::Internal;
 
 namespace {