diff --git a/src/plugins/autotoolsprojectmanager/autotoolsproject.cpp b/src/plugins/autotoolsprojectmanager/autotoolsproject.cpp
index e8b36cbf87fb354bdf864c50c7374d1a39e8859e..a4a733d0cd23092be01f7d67ce2d79d485ec14ad 100644
--- a/src/plugins/autotoolsprojectmanager/autotoolsproject.cpp
+++ b/src/plugins/autotoolsprojectmanager/autotoolsproject.cpp
@@ -68,11 +68,11 @@ using namespace AutotoolsProjectManager::Internal;
 using namespace ProjectExplorer;
 
 AutotoolsProject::AutotoolsProject(const Utils::FileName &fileName) :
+    Project(Constants::MAKEFILE_MIMETYPE, fileName),
     m_fileWatcher(new Utils::FileSystemWatcher(this)),
     m_cppCodeModelUpdater(new CppTools::CppProjectUpdater(this))
 {
     setId(Constants::AUTOTOOLS_PROJECT_ID);
-    setDocument(new ProjectExplorer::ProjectDocument(Constants::MAKEFILE_MIMETYPE, fileName));
     setProjectContext(Core::Context(Constants::PROJECT_CONTEXT));
     setProjectLanguages(Core::Context(ProjectExplorer::Constants::CXX_LANGUAGE_ID));
 }
diff --git a/src/plugins/cmakeprojectmanager/cmakeproject.cpp b/src/plugins/cmakeprojectmanager/cmakeproject.cpp
index f850ee0af05ee0e67d13e63adb82e6653ec5a0d5..4bf0f0dcdc5c4124e7ffc8c1079939901dd5662d 100644
--- a/src/plugins/cmakeprojectmanager/cmakeproject.cpp
+++ b/src/plugins/cmakeprojectmanager/cmakeproject.cpp
@@ -73,12 +73,10 @@ using namespace Internal;
 /*!
   \class CMakeProject
 */
-CMakeProject::CMakeProject(const FileName &fileName)
-    : m_cppCodeModelUpdater(new CppTools::CppProjectUpdater(this))
+CMakeProject::CMakeProject(const FileName &fileName) : Project(Constants::CMAKEMIMETYPE, fileName),
+    m_cppCodeModelUpdater(new CppTools::CppProjectUpdater(this))
 {
     setId(CMakeProjectManager::Constants::CMAKEPROJECT_ID);
-    setDocument(new ProjectDocument(CMakeProjectManager::Constants::CMAKEMIMETYPE, fileName));
-
     setProjectContext(Core::Context(CMakeProjectManager::Constants::PROJECTCONTEXT));
     setProjectLanguages(Core::Context(ProjectExplorer::Constants::CXX_LANGUAGE_ID));
 
diff --git a/src/plugins/cpptools/modelmanagertesthelper.cpp b/src/plugins/cpptools/modelmanagertesthelper.cpp
index f347cd81af4948fc678c937ecd19d16a49ea6d01..9eebbee15d3c856f9221d69ec1339d9d16691303 100644
--- a/src/plugins/cpptools/modelmanagertesthelper.cpp
+++ b/src/plugins/cpptools/modelmanagertesthelper.cpp
@@ -36,7 +36,9 @@
 using namespace CppTools::Internal;
 using namespace CppTools::Tests;
 
-TestProject::TestProject(const QString &name, QObject *parent) : m_name (name)
+TestProject::TestProject(const QString &name, QObject *parent) :
+    ProjectExplorer::Project("x-binary/foo", Utils::FileName()),
+    m_name(name)
 {
     setParent(parent);
     setId(Core::Id::fromString(name));
diff --git a/src/plugins/genericprojectmanager/genericproject.cpp b/src/plugins/genericprojectmanager/genericproject.cpp
index b991793e761d66cb8808f1f4730375855b215d4a..6dae648a5f92846a2d756412affca6cbc644fb3a 100644
--- a/src/plugins/genericprojectmanager/genericproject.cpp
+++ b/src/plugins/genericprojectmanager/genericproject.cpp
@@ -65,12 +65,11 @@ namespace Internal {
 //
 ////////////////////////////////////////////////////////////////////////////////////
 
-GenericProject::GenericProject(const Utils::FileName &fileName)
-    : m_cppCodeModelUpdater(new CppTools::CppProjectUpdater(this))
+GenericProject::GenericProject(const Utils::FileName &fileName) :
+    Project(Constants::GENERICMIMETYPE, fileName, [this]() { refresh(Everything); }),
+    m_cppCodeModelUpdater(new CppTools::CppProjectUpdater(this))
 {
     setId(Constants::GENERICPROJECT_ID);
-    setDocument(new ProjectDocument(Constants::GENERICMIMETYPE, fileName,
-                                    [this]() { refresh(Everything); }));
     setProjectContext(Context(GenericProjectManager::Constants::PROJECTCONTEXT));
     setProjectLanguages(Context(ProjectExplorer::Constants::CXX_LANGUAGE_ID));
 
diff --git a/src/plugins/nim/project/nimproject.cpp b/src/plugins/nim/project/nimproject.cpp
index 483edfc7be24453d7743e466c6a6203860c3e3d4..39c8ac3e80fccfdb59c3403ad7a8381431cbcfa5 100644
--- a/src/plugins/nim/project/nimproject.cpp
+++ b/src/plugins/nim/project/nimproject.cpp
@@ -54,10 +54,9 @@ namespace Nim {
 
 const int MIN_TIME_BETWEEN_PROJECT_SCANS = 4500;
 
-NimProject::NimProject(const FileName &fileName)
+NimProject::NimProject(const FileName &fileName) : Project(Constants::C_NIM_MIMETYPE, fileName)
 {
     setId(Constants::C_NIMPROJECT_ID);
-    setDocument(new ProjectDocument(Constants::C_NIM_MIMETYPE, fileName));
 
     m_projectScanTimer.setSingleShot(true);
     connect(&m_projectScanTimer, &QTimer::timeout, this, &NimProject::collectProjectFiles);
diff --git a/src/plugins/projectexplorer/project.cpp b/src/plugins/projectexplorer/project.cpp
index 38be84ad804e652c29c6fd2dc6175561e2c533f2..214dedc3320dbc97cd1e066af9aa381227fb5cd7 100644
--- a/src/plugins/projectexplorer/project.cpp
+++ b/src/plugins/projectexplorer/project.cpp
@@ -126,7 +126,9 @@ bool ProjectDocument::reload(QString *errorString, Core::IDocument::ReloadFlag f
 class ProjectPrivate
 {
 public:
-    ProjectPrivate(Project *owner) : m_containerNode(owner) {}
+    ProjectPrivate(Project *owner, Core::IDocument *document) :
+        m_document(document), m_containerNode(owner)
+    { }
     ~ProjectPrivate();
 
     Core::Id m_id;
@@ -158,7 +160,9 @@ ProjectPrivate::~ProjectPrivate()
     delete m_accessor;
 }
 
-Project::Project() : d(new ProjectPrivate(this))
+Project::Project(const QString &mimeType, const Utils::FileName &fileName,
+                 const ProjectDocument::ProjectCallback &callback) :
+    d(new ProjectPrivate(this, new ProjectDocument(mimeType, fileName, callback)))
 {
     d->m_macroExpander.setDisplayName(tr("Project"));
     d->m_macroExpander.registerVariable("Project:Name", tr("Project Name"),
@@ -453,13 +457,6 @@ void Project::setId(Core::Id id)
     d->m_id = id;
 }
 
-void Project::setDocument(Core::IDocument *doc)
-{
-    QTC_ASSERT(doc, return);
-    QTC_ASSERT(!d->m_document, return);
-    d->m_document = doc;
-}
-
 void Project::setRootProjectNode(ProjectNode *root)
 {
     if (d->m_rootProjectNode == root)
diff --git a/src/plugins/projectexplorer/project.h b/src/plugins/projectexplorer/project.h
index a54828e54dced4dc3c010577a6bc08801d3f3e28..343643b281371d176dabddd6ff5f995ff3f8662a 100644
--- a/src/plugins/projectexplorer/project.h
+++ b/src/plugins/projectexplorer/project.h
@@ -88,7 +88,8 @@ public:
         EnabledRole
     };
 
-    Project();
+    Project(const QString &mimeType, const Utils::FileName &fileName,
+            const ProjectDocument::ProjectCallback &callback = {});
     ~Project() override;
 
     virtual QString displayName() const = 0;
@@ -193,7 +194,6 @@ protected:
     void setPreferredKitPredicate(const Kit::Predicate &predicate);
 
     void setId(Core::Id id);
-    void setDocument(Core::IDocument *doc); // takes ownership!
     void setRootProjectNode(ProjectNode *root); // takes ownership!
     void setProjectContext(Core::Context context);
     void setProjectLanguages(Core::Context language);
diff --git a/src/plugins/pythoneditor/pythoneditorplugin.cpp b/src/plugins/pythoneditor/pythoneditorplugin.cpp
index 7dbe7953fff591faa827948193c5ec3b98030bf6..1e97696fb3fb529f27b739078090fd39dd20f6f8 100644
--- a/src/plugins/pythoneditor/pythoneditorplugin.cpp
+++ b/src/plugins/pythoneditor/pythoneditorplugin.cpp
@@ -375,11 +375,10 @@ private:
     }
 };
 
-PythonProject::PythonProject(const FileName &fileName)
+PythonProject::PythonProject(const FileName &fileName) :
+    Project(Constants::C_PY_MIMETYPE, fileName, [this]() { refresh(); })
 {
     setId(PythonProjectId);
-    setDocument(new ProjectDocument(Constants::C_PY_MIMETYPE, fileName, [this]() { refresh(); }));
-
     setProjectContext(Context(PythonProjectContext));
     setProjectLanguages(Context(ProjectExplorer::Constants::CXX_LANGUAGE_ID));
 }
diff --git a/src/plugins/qbsprojectmanager/qbsproject.cpp b/src/plugins/qbsprojectmanager/qbsproject.cpp
index 145d78b71b03e782af14b2e51104b60507d61f28..5e1abd4c3a1817d1e211990f5aabec84f80ebc3f 100644
--- a/src/plugins/qbsprojectmanager/qbsproject.cpp
+++ b/src/plugins/qbsprojectmanager/qbsproject.cpp
@@ -116,6 +116,7 @@ private:
 // --------------------------------------------------------------------
 
 QbsProject::QbsProject(const FileName &fileName) :
+    Project(Constants::MIME_TYPE, fileName, [this]() { delayParsing(); }),
     m_qbsProjectParser(0),
     m_qbsUpdateFutureInterface(0),
     m_parsingScheduled(false),
@@ -127,7 +128,6 @@ QbsProject::QbsProject(const FileName &fileName) :
     m_parsingDelay.setInterval(1000); // delay parsing by 1s.
 
     setId(Constants::PROJECT_ID);
-    setDocument(new ProjectDocument(Constants::MIME_TYPE, fileName, [this]() { delayParsing(); }));
 
     setProjectContext(Context(Constants::PROJECT_ID));
     setProjectLanguages(Context(ProjectExplorer::Constants::CXX_LANGUAGE_ID));
diff --git a/src/plugins/qmakeprojectmanager/qmakeproject.cpp b/src/plugins/qmakeprojectmanager/qmakeproject.cpp
index 3ca2d9ea8a3f284be41a557f6d2c7ac0e97809ce..2aff80e3f1abb338af5a139fbe8333a4af4b2b0a 100644
--- a/src/plugins/qmakeprojectmanager/qmakeproject.cpp
+++ b/src/plugins/qmakeprojectmanager/qmakeproject.cpp
@@ -158,12 +158,12 @@ static QList<QmakeProject *> s_projects;
   */
 
 QmakeProject::QmakeProject(const FileName &fileName) :
+    Project(QmakeProjectManager::Constants::PROFILE_MIMETYPE, fileName),
     m_qmakeVfs(new QMakeVfs),
     m_cppCodeModelUpdater(new CppTools::CppProjectUpdater(this))
 {
     s_projects.append(this);
     setId(Constants::QMAKEPROJECT_ID);
-    setDocument(new ProjectDocument(QmakeProjectManager::Constants::PROFILE_MIMETYPE, fileName));
     setProjectContext(Core::Context(QmakeProjectManager::Constants::PROJECT_ID));
     setProjectLanguages(Core::Context(ProjectExplorer::Constants::CXX_LANGUAGE_ID));
     setRequiredKitPredicate(QtSupport::QtKitInformation::qtVersionPredicate());
diff --git a/src/plugins/qmlprojectmanager/qmlproject.cpp b/src/plugins/qmlprojectmanager/qmlproject.cpp
index 096fca8a2f2d7892215195ca08067f2f1fd40016..601f153582f7f530ccab2ace132ae2efc1dcfb85 100644
--- a/src/plugins/qmlprojectmanager/qmlproject.cpp
+++ b/src/plugins/qmlprojectmanager/qmlproject.cpp
@@ -55,12 +55,10 @@ using namespace ProjectExplorer;
 namespace QmlProjectManager {
 
 QmlProject::QmlProject(const Utils::FileName &fileName) :
+    Project(QString::fromLatin1(Constants::QMLPROJECT_MIMETYPE), fileName, [this]() { refreshProjectFile(); }),
     m_defaultImport(UnknownImport)
 {
     setId("QmlProjectManager.QmlProject");
-    setDocument(new ProjectDocument(QString::fromLatin1(Constants::QMLPROJECT_MIMETYPE), fileName,
-                                    [this]() { refreshProjectFile(); }));
-
     setProjectContext(Context(QmlProjectManager::Constants::PROJECTCONTEXT));
     setProjectLanguages(Context(ProjectExplorer::Constants::QMLJS_LANGUAGE_ID));
 }