diff --git a/src/plugins/plugins.pro b/src/plugins/plugins.pro
index 388a8c53bc70c3a06a870faff221d78c0961630b..ad25fcd0c4e2083ab7185a188e5723ee04fe6967 100644
--- a/src/plugins/plugins.pro
+++ b/src/plugins/plugins.pro
@@ -31,6 +31,7 @@ SUBDIRS   = plugin_coreplugin \
             plugin_designer \
             plugin_resourceeditor \
 	    plugin_genericprojectmanager \
+	    plugin_qmlprojectmanager \
             debugger/dumper.pro
 
 plugin_coreplugin.subdir = coreplugin
@@ -162,3 +163,8 @@ plugin_genericprojectmanager.depends += plugin_projectexplorer
 plugin_genericprojectmanager.depends += plugin_cpptools
 plugin_genericprojectmanager.depends += plugin_cppeditor
 plugin_genericprojectmanager.depends += plugin_help
+
+plugin_qmlprojectmanager.subdir = qmlprojectmanager
+plugin_qmlprojectmanager.depends = plugin_texteditor
+plugin_qmlprojectmanager.depends += plugin_projectexplorer
+plugin_qmlprojectmanager.depends += plugin_help
diff --git a/src/plugins/qmlprojectmanager/QmlProject.mimetypes.xml b/src/plugins/qmlprojectmanager/QmlProject.mimetypes.xml
new file mode 100644
index 0000000000000000000000000000000000000000..9132ca54a667fe26385275be6fa495feff113be7
--- /dev/null
+++ b/src/plugins/qmlprojectmanager/QmlProject.mimetypes.xml
@@ -0,0 +1,16 @@
+<?xml version="1.0"?>
+
+<mime-info xmlns='http://www.freedesktop.org/standards/shared-mime-info'>
+  <mime-type type="text/x-qml-project">
+    <sub-class-of type="text/plain"/>
+    <comment>Qml Project file</comment>
+    <glob pattern="*.qmlproject"/>
+  </mime-type>
+
+  <mime-type type="application/vnd.nokia.qt.qml.files">
+    <sub-class-of type="text/plain"/>
+    <comment>Qml Project Files</comment>
+    <glob pattern="*.files"/>
+  </mime-type>
+
+</mime-info>
diff --git a/src/plugins/qmlprojectmanager/QmlProjectManager.pluginspec b/src/plugins/qmlprojectmanager/QmlProjectManager.pluginspec
new file mode 100644
index 0000000000000000000000000000000000000000..7fc7c9efffdc34ed0e88e21221de5970cc26c12c
--- /dev/null
+++ b/src/plugins/qmlprojectmanager/QmlProjectManager.pluginspec
@@ -0,0 +1,28 @@
+<plugin name="QmlProjectManager" version="1.1.80" compatVersion="1.1.80">
+    <vendor>Nokia Corporation</vendor>
+    <copyright>(C) 2008-2009 Nokia Corporation</copyright>
+    <license>
+Commercial Usage
+
+Licensees holding valid Qt Commercial licenses may use this plugin in
+accordance with the Qt Commercial License Agreement provided with the
+Software or, alternatively, in accordance with the terms contained in
+a written agreement between you and Nokia.
+
+GNU Lesser General Public License Usage
+
+Alternatively, this plugin may be used under the terms of the GNU Lesser
+General Public License version 2.1 as published by the Free Software
+Foundation.  Please review the following information to
+ensure the GNU Lesser General Public License version 2.1 requirements
+will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.</license>
+    <description>Qml support</description>
+    <url>http://www.qtsoftware.com</url>
+    <dependencyList>
+        <dependency name="TextEditor" version="1.1.80"/>
+        <dependency name="ProjectExplorer" version="1.1.80"/>
+        <dependency name="CppTools" version="1.1.80"/>
+        <dependency name="CppEditor" version="1.1.80"/>
+        <dependency name="Help" version="1.1.80"/>
+    </dependencyList>
+</plugin>
diff --git a/src/plugins/qmlprojectmanager/qmlproject.cpp b/src/plugins/qmlprojectmanager/qmlproject.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..9595e539e5d14bc675a5bc40bbb2493920d0b5dc
--- /dev/null
+++ b/src/plugins/qmlprojectmanager/qmlproject.cpp
@@ -0,0 +1,385 @@
+/**************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact:  Qt Software Information (qt-info@nokia.com)
+**
+** Commercial Usage
+**
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Nokia.
+**
+** GNU Lesser General Public License Usage
+**
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file.  Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+**
+**************************************************************************/
+
+#include "qmlproject.h"
+#include "qmlprojectconstants.h"
+
+#include <projectexplorer/toolchain.h>
+#include <projectexplorer/projectexplorerconstants.h>
+#include <extensionsystem/pluginmanager.h>
+#include <utils/pathchooser.h>
+#include <utils/qtcassert.h>
+#include <coreplugin/icore.h>
+
+#include <QtCore/QtDebug>
+#include <QtCore/QDir>
+#include <QtCore/QSettings>
+#include <QtCore/QProcess>
+#include <QtCore/QCoreApplication>
+
+#include <QtGui/QFormLayout>
+#include <QtGui/QMainWindow>
+#include <QtGui/QComboBox>
+#include <QtGui/QStringListModel>
+#include <QtGui/QListWidget>
+#include <QtGui/QPushButton>
+
+using namespace QmlProjectManager;
+using namespace QmlProjectManager::Internal;
+
+namespace {
+
+/**
+ * An editable string list model. New strings can be added by editing the entry
+ * called "<new>", displayed at the end.
+ */
+class ListModel: public QStringListModel
+{
+public:
+    ListModel(QObject *parent)
+        : QStringListModel(parent) {}
+
+    virtual ~ListModel() {}
+
+    virtual int rowCount(const QModelIndex &parent) const
+    { return 1 + QStringListModel::rowCount(parent); }
+
+    virtual Qt::ItemFlags flags(const QModelIndex &index) const
+    { return QStringListModel::flags(index) | Qt::ItemIsEditable | Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled; }
+
+    virtual QModelIndex index(int row, int column, const QModelIndex &parent) const
+    {
+        if (row == stringList().size())
+            return createIndex(row, column);
+
+        return QStringListModel::index(row, column, parent);
+    }
+
+    virtual QVariant data(const QModelIndex &index, int role) const
+    {
+        if (role == Qt::DisplayRole || role == Qt::EditRole) {
+            if (index.row() == stringList().size())
+                return QCoreApplication::translate("QmlProject", "<new>");
+        }
+
+        return QStringListModel::data(index, role);
+    }
+
+    virtual bool setData(const QModelIndex &index, const QVariant &value, int role)
+    {
+        if (role == Qt::EditRole && index.row() == stringList().size())
+            insertRow(index.row(), QModelIndex());
+
+        return QStringListModel::setData(index, value, role);
+    }
+};
+
+} // end of anonymous namespace
+
+////////////////////////////////////////////////////////////////////////////////////
+// QmlProject
+////////////////////////////////////////////////////////////////////////////////////
+
+QmlProject::QmlProject(Manager *manager, const QString &fileName)
+    : m_manager(manager),
+      m_fileName(fileName)
+{
+    QFileInfo fileInfo(m_fileName);
+    QDir dir = fileInfo.dir();
+
+    m_projectName      = fileInfo.completeBaseName();
+    m_filesFileName    = QFileInfo(dir, m_projectName + QLatin1String(".files")).absoluteFilePath();
+
+    m_file = new QmlProjectFile(this, fileName);
+    m_rootNode = new QmlProjectNode(this, m_file);
+
+    m_manager->registerProject(this);
+}
+
+QmlProject::~QmlProject()
+{
+    m_manager->unregisterProject(this);
+
+    delete m_rootNode;
+}
+
+QString QmlProject::filesFileName() const
+{ return m_filesFileName; }
+
+static QStringList readLines(const QString &absoluteFileName)
+{
+    QStringList lines;
+
+    QFile file(absoluteFileName);
+    if (file.open(QFile::ReadOnly)) {
+        QTextStream stream(&file);
+
+        forever {
+            QString line = stream.readLine();
+            if (line.isNull())
+                break;
+
+            line = line.trimmed();
+            if (line.isEmpty())
+                continue;
+
+            lines.append(line);
+        }
+    }
+
+    return lines;
+}
+
+
+void QmlProject::parseProject(RefreshOptions options)
+{
+    if (options & Files) {
+        m_files = convertToAbsoluteFiles(readLines(filesFileName()));
+        m_files.removeDuplicates();
+    }
+
+    if (options & Configuration) {
+        // update configuration
+    }
+
+    if (options & Files)
+        emit fileListChanged();
+}
+
+void QmlProject::refresh(RefreshOptions options)
+{
+    QSet<QString> oldFileList;
+    if (!(options & Configuration))
+        oldFileList = m_files.toSet();
+
+    parseProject(options);
+
+    if (options & Files)
+        m_rootNode->refresh();
+}
+
+QStringList QmlProject::convertToAbsoluteFiles(const QStringList &paths) const
+{
+    const QDir projectDir(QFileInfo(m_fileName).dir());
+    QStringList absolutePaths;
+    foreach (const QString &file, paths) {
+        QFileInfo fileInfo(projectDir, file);
+        absolutePaths.append(fileInfo.absoluteFilePath());
+    }
+    absolutePaths.removeDuplicates();
+    return absolutePaths;
+}
+
+QStringList QmlProject::files() const
+{ return m_files; }
+
+QString QmlProject::buildParser(const QString &) const
+{
+    return QString();
+}
+
+QString QmlProject::name() const
+{
+    return m_projectName;
+}
+
+Core::IFile *QmlProject::file() const
+{
+    return m_file;
+}
+
+ProjectExplorer::IProjectManager *QmlProject::projectManager() const
+{
+    return m_manager;
+}
+
+QList<ProjectExplorer::Project *> QmlProject::dependsOn()
+{
+    return QList<Project *>();
+}
+
+bool QmlProject::isApplication() const
+{
+    return true;
+}
+
+ProjectExplorer::Environment QmlProject::environment(const QString &) const
+{
+    return ProjectExplorer::Environment::systemEnvironment();
+}
+
+QString QmlProject::buildDirectory(const QString &buildConfiguration) const
+{
+    QString buildDirectory = value(buildConfiguration, "buildDirectory").toString();
+
+    if (buildDirectory.isEmpty()) {
+        QFileInfo fileInfo(m_fileName);
+
+        buildDirectory = fileInfo.absolutePath();
+    }
+
+    return buildDirectory;
+}
+
+ProjectExplorer::BuildStepConfigWidget *QmlProject::createConfigWidget()
+{
+    return new QmlBuildSettingsWidget(this);
+}
+
+QList<ProjectExplorer::BuildStepConfigWidget*> QmlProject::subConfigWidgets()
+{
+    return QList<ProjectExplorer::BuildStepConfigWidget*>();
+}
+
+ void QmlProject::newBuildConfiguration(const QString &)
+ {
+ }
+
+QmlProjectNode *QmlProject::rootProjectNode() const
+{
+    return m_rootNode;
+}
+
+QStringList QmlProject::files(FilesMode) const
+{
+    return m_files;
+}
+
+QStringList QmlProject::targets() const
+{
+    QStringList targets;
+    return targets;
+}
+
+QmlMakeStep *QmlProject::makeStep() const
+{
+    return 0;
+}
+
+void QmlProject::restoreSettingsImpl(ProjectExplorer::PersistentSettingsReader &reader)
+{
+    Project::restoreSettingsImpl(reader);
+
+    refresh(Everything);
+}
+
+void QmlProject::saveSettingsImpl(ProjectExplorer::PersistentSettingsWriter &writer)
+{
+    Project::saveSettingsImpl(writer);
+}
+
+////////////////////////////////////////////////////////////////////////////////////
+// QmlBuildSettingsWidget
+////////////////////////////////////////////////////////////////////////////////////
+
+QmlBuildSettingsWidget::QmlBuildSettingsWidget(QmlProject *project)
+    : m_project(project)
+{
+    QFormLayout *fl = new QFormLayout(this);
+
+    // build directory
+    m_pathChooser = new Core::Utils::PathChooser(this);
+    m_pathChooser->setEnabled(true);
+    fl->addRow(tr("Build directory:"), m_pathChooser);
+    connect(m_pathChooser, SIGNAL(changed()), this, SLOT(buildDirectoryChanged()));
+}
+
+QmlBuildSettingsWidget::~QmlBuildSettingsWidget()
+{ }
+
+QString QmlBuildSettingsWidget::displayName() const
+{ return tr("Qml Manager"); }
+
+void QmlBuildSettingsWidget::init(const QString &buildConfiguration)
+{
+    m_buildConfiguration = buildConfiguration;
+    m_pathChooser->setPath(m_project->buildDirectory(buildConfiguration));
+}
+
+void QmlBuildSettingsWidget::buildDirectoryChanged()
+{
+    m_project->setValue(m_buildConfiguration, "buildDirectory", m_pathChooser->path());
+}
+
+////////////////////////////////////////////////////////////////////////////////////
+// QmlProjectFile
+////////////////////////////////////////////////////////////////////////////////////
+
+QmlProjectFile::QmlProjectFile(QmlProject *parent, QString fileName)
+    : Core::IFile(parent),
+      m_project(parent),
+      m_fileName(fileName)
+{ }
+
+QmlProjectFile::~QmlProjectFile()
+{ }
+
+bool QmlProjectFile::save(const QString &)
+{
+    return false;
+}
+
+QString QmlProjectFile::fileName() const
+{
+    return m_fileName;
+}
+
+QString QmlProjectFile::defaultPath() const
+{
+    return QString();
+}
+
+QString QmlProjectFile::suggestedFileName() const
+{
+    return QString();
+}
+
+QString QmlProjectFile::mimeType() const
+{
+    return Constants::QMLMIMETYPE;
+}
+
+bool QmlProjectFile::isModified() const
+{
+    return false;
+}
+
+bool QmlProjectFile::isReadOnly() const
+{
+    return true;
+}
+
+bool QmlProjectFile::isSaveAsAllowed() const
+{
+    return false;
+}
+
+void QmlProjectFile::modified(ReloadBehavior *)
+{
+}
diff --git a/src/plugins/qmlprojectmanager/qmlproject.h b/src/plugins/qmlprojectmanager/qmlproject.h
new file mode 100644
index 0000000000000000000000000000000000000000..7429a68c055c08b05868ff4f184d223bef28d0e8
--- /dev/null
+++ b/src/plugins/qmlprojectmanager/qmlproject.h
@@ -0,0 +1,169 @@
+/**************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact:  Qt Software Information (qt-info@nokia.com)
+**
+** Commercial Usage
+**
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Nokia.
+**
+** GNU Lesser General Public License Usage
+**
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file.  Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+**
+**************************************************************************/
+
+#ifndef QMLPROJECT_H
+#define QMLPROJECT_H
+
+#include "qmlprojectmanager.h"
+#include "qmlprojectnodes.h"
+
+#include <projectexplorer/project.h>
+#include <projectexplorer/projectnodes.h>
+#include <projectexplorer/buildstep.h>
+#include <coreplugin/ifile.h>
+
+QT_BEGIN_NAMESPACE
+class QPushButton;
+class QStringListModel;
+QT_END_NAMESPACE
+
+namespace Core {
+namespace Utils {
+class PathChooser;
+}
+}
+
+namespace QmlProjectManager {
+namespace Internal {
+
+class QmlMakeStep;
+class QmlProjectFile;
+
+class QmlProject : public ProjectExplorer::Project
+{
+    Q_OBJECT
+
+public:
+    QmlProject(Manager *manager, const QString &filename);
+    virtual ~QmlProject();
+
+    QString filesFileName() const;
+
+    virtual QString name() const;
+    virtual Core::IFile *file() const;
+    virtual ProjectExplorer::IProjectManager *projectManager() const;
+
+    virtual QList<ProjectExplorer::Project *> dependsOn();
+
+    virtual bool isApplication() const;
+
+    virtual ProjectExplorer::Environment environment(const QString &buildConfiguration) const;
+    virtual QString buildDirectory(const QString &buildConfiguration) const;
+
+    virtual ProjectExplorer::BuildStepConfigWidget *createConfigWidget();
+    virtual QList<ProjectExplorer::BuildStepConfigWidget*> subConfigWidgets();
+
+    virtual void newBuildConfiguration(const QString &buildConfiguration);
+    virtual QmlProjectNode *rootProjectNode() const;
+    virtual QStringList files(FilesMode fileMode) const;
+
+    QStringList targets() const;
+    QmlMakeStep *makeStep() const;
+    QString buildParser(const QString &buildConfiguration) const;
+
+    enum RefreshOptions {
+        Files         = 0x01,
+        Configuration = 0x02,
+        Everything    = Files | Configuration
+    };
+
+    void refresh(RefreshOptions options);
+
+    QStringList files() const;
+
+protected:
+    virtual void saveSettingsImpl(ProjectExplorer::PersistentSettingsWriter &writer);
+    virtual void restoreSettingsImpl(ProjectExplorer::PersistentSettingsReader &reader);
+
+private:
+    void parseProject(RefreshOptions options);
+    QStringList convertToAbsoluteFiles(const QStringList &paths) const;
+
+    Manager *m_manager;
+    QString m_fileName;
+    QString m_filesFileName;
+    QmlProjectFile *m_file;
+    QString m_projectName;
+
+    QStringList m_files;
+
+    QmlProjectNode *m_rootNode;
+};
+
+class QmlProjectFile : public Core::IFile
+{
+    Q_OBJECT
+
+public:
+    QmlProjectFile(QmlProject *parent, QString fileName);
+    virtual ~QmlProjectFile();
+
+    virtual bool save(const QString &fileName = QString());
+    virtual QString fileName() const;
+
+    virtual QString defaultPath() const;
+    virtual QString suggestedFileName() const;
+    virtual QString mimeType() const;
+
+    virtual bool isModified() const;
+    virtual bool isReadOnly() const;
+    virtual bool isSaveAsAllowed() const;
+
+    virtual void modified(ReloadBehavior *behavior);
+
+private:
+    QmlProject *m_project;
+    QString m_fileName;
+};
+
+class QmlBuildSettingsWidget : public ProjectExplorer::BuildStepConfigWidget
+{
+    Q_OBJECT
+
+public:
+    QmlBuildSettingsWidget(QmlProject *project);
+    virtual ~QmlBuildSettingsWidget();
+
+    virtual QString displayName() const;
+
+    virtual void init(const QString &buildConfiguration);
+
+private Q_SLOTS:
+    void buildDirectoryChanged();
+
+private:
+    QmlProject *m_project;
+    Core::Utils::PathChooser *m_pathChooser;
+    QString m_buildConfiguration;
+};
+
+} // namespace Internal
+} // namespace QmlProjectManager
+
+#endif // QMLPROJECT_H
diff --git a/src/plugins/qmlprojectmanager/qmlproject.qrc b/src/plugins/qmlprojectmanager/qmlproject.qrc
new file mode 100644
index 0000000000000000000000000000000000000000..3a446209bf7f05378d263be9d5a49000db00dc9e
--- /dev/null
+++ b/src/plugins/qmlprojectmanager/qmlproject.qrc
@@ -0,0 +1,5 @@
+<RCC>
+    <qresource prefix="/qmlproject" >
+        <file>QmlProject.mimetypes.xml</file>
+    </qresource>
+</RCC>
diff --git a/src/plugins/qmlprojectmanager/qmlprojectconstants.h b/src/plugins/qmlprojectmanager/qmlprojectconstants.h
new file mode 100644
index 0000000000000000000000000000000000000000..55b548daba3e64e9164d7985b24152bae0b6724a
--- /dev/null
+++ b/src/plugins/qmlprojectmanager/qmlprojectconstants.h
@@ -0,0 +1,58 @@
+/**************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact:  Qt Software Information (qt-info@nokia.com)
+**
+** Commercial Usage
+**
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Nokia.
+**
+** GNU Lesser General Public License Usage
+**
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file.  Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+**
+**************************************************************************/
+
+#ifndef QMLPROJECTCONSTANTS_H
+#define QMLPROJECTCONSTANTS_H
+
+namespace QmlProjectManager {
+namespace Constants {
+
+const char *const PROJECTCONTEXT     = "QmlProject.ProjectContext";
+const char *const QMLMIMETYPE    = "text/x-qml-project"; // ### FIXME
+const char *const MAKESTEP           = "QmlProjectManager.MakeStep";
+
+// contexts
+const char *const C_FILESEDITOR      = ".files Editor";
+
+// kinds
+const char *const PROJECT_KIND       = "Qml";
+
+const char *const FILES_EDITOR       = ".files Editor";
+const char *const FILES_MIMETYPE     = "application/vnd.nokia.qt.qml.files";
+
+const char *const INCLUDES_EDITOR    = ".includes Editor";
+const char *const INCLUDES_MIMETYPE  = "application/vnd.nokia.qt.qml.includes";
+
+const char *const CONFIG_EDITOR      = ".includes Editor";
+const char *const CONFIG_MIMETYPE    = "application/vnd.nokia.qt.qml.config";
+
+} // namespace Constants
+} // namespace QmlProjectManager
+
+#endif // QMLPROJECTCONSTANTS_H
diff --git a/src/plugins/qmlprojectmanager/qmlprojectfileseditor.cpp b/src/plugins/qmlprojectmanager/qmlprojectfileseditor.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..afd40d81e1875720923e6c5e6385ac0540b81173
--- /dev/null
+++ b/src/plugins/qmlprojectmanager/qmlprojectfileseditor.cpp
@@ -0,0 +1,189 @@
+/**************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact:  Qt Software Information (qt-info@nokia.com)
+**
+** Commercial Usage
+**
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Nokia.
+**
+** GNU Lesser General Public License Usage
+**
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file.  Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+**
+**************************************************************************/
+
+#include "qmlprojectfileseditor.h"
+#include "qmlprojectmanager.h"
+#include "qmlprojectconstants.h"
+
+#include <coreplugin/uniqueidmanager.h>
+#include <coreplugin/editormanager/editormanager.h>
+#include <texteditor/fontsettings.h>
+#include <texteditor/texteditoractionhandler.h>
+#include <texteditor/texteditorsettings.h>
+
+using namespace QmlProjectManager;
+using namespace QmlProjectManager::Internal;
+
+
+////////////////////////////////////////////////////////////////////////////////////////
+// ProjectFilesFactory
+////////////////////////////////////////////////////////////////////////////////////////
+
+ProjectFilesFactory::ProjectFilesFactory(Manager *manager,
+                                         TextEditor::TextEditorActionHandler *handler)
+    : Core::IEditorFactory(manager),
+      m_manager(manager),
+      m_actionHandler(handler)
+{
+    m_mimeTypes.append(QLatin1String(Constants::FILES_MIMETYPE));
+    m_mimeTypes.append(QLatin1String(Constants::INCLUDES_MIMETYPE));
+    m_mimeTypes.append(QLatin1String(Constants::CONFIG_MIMETYPE));
+}
+
+ProjectFilesFactory::~ProjectFilesFactory()
+{
+}
+
+Manager *ProjectFilesFactory::manager() const
+{
+    return m_manager;
+}
+
+Core::IEditor *ProjectFilesFactory::createEditor(QWidget *parent)
+{
+    ProjectFilesEditor *ed = new ProjectFilesEditor(parent, this, m_actionHandler);
+    TextEditor::TextEditorSettings::instance()->initializeEditor(ed);
+    return ed->editableInterface();
+}
+
+QStringList ProjectFilesFactory::mimeTypes() const
+{
+    return m_mimeTypes;
+}
+
+QString ProjectFilesFactory::kind() const
+{
+    return QLatin1String(Constants::FILES_EDITOR);
+}
+
+Core::IFile *ProjectFilesFactory::open(const QString &fileName)
+{
+    Core::EditorManager *editorManager = Core::EditorManager::instance();
+
+    if (Core::IEditor *editor = editorManager->openEditor(fileName, kind()))
+        return editor->file();
+
+    return 0;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////
+// ProjectFilesEditable
+////////////////////////////////////////////////////////////////////////////////////////
+
+ProjectFilesEditable::ProjectFilesEditable(ProjectFilesEditor *editor)
+    : TextEditor::BaseTextEditorEditable(editor)
+{
+    Core::UniqueIDManager *uidm = Core::UniqueIDManager::instance();
+    m_context << uidm->uniqueIdentifier(Constants::C_FILESEDITOR);
+}
+
+ProjectFilesEditable::~ProjectFilesEditable()
+{ }
+
+QList<int> ProjectFilesEditable::context() const
+{
+    return m_context;
+}
+
+const char *ProjectFilesEditable::kind() const
+{
+    return Constants::FILES_EDITOR;
+}
+
+bool ProjectFilesEditable::duplicateSupported() const
+{
+    return true;
+}
+
+Core::IEditor *ProjectFilesEditable::duplicate(QWidget *parent)
+{
+    ProjectFilesEditor *parentEditor = qobject_cast<ProjectFilesEditor *>(editor());
+    ProjectFilesEditor *editor = new ProjectFilesEditor(parent,
+                                                        parentEditor->factory(),
+                                                        parentEditor->actionHandler());
+    TextEditor::TextEditorSettings::instance()->initializeEditor(editor);
+    return editor->editableInterface();
+}
+
+////////////////////////////////////////////////////////////////////////////////////////
+// ProjectFilesEditor
+////////////////////////////////////////////////////////////////////////////////////////
+
+ProjectFilesEditor::ProjectFilesEditor(QWidget *parent, ProjectFilesFactory *factory,
+                                       TextEditor::TextEditorActionHandler *handler)
+    : TextEditor::BaseTextEditor(parent),
+      m_factory(factory),
+      m_actionHandler(handler)
+{
+    Manager *manager = factory->manager();
+    ProjectFilesDocument *doc = new ProjectFilesDocument(manager);
+    setBaseTextDocument(doc);
+
+    handler->setupActions(this);
+}
+
+ProjectFilesEditor::~ProjectFilesEditor()
+{ }
+
+ProjectFilesFactory *ProjectFilesEditor::factory() const
+{
+    return m_factory;
+}
+
+TextEditor::TextEditorActionHandler *ProjectFilesEditor::actionHandler() const
+{
+    return m_actionHandler;
+}
+
+TextEditor::BaseTextEditorEditable *ProjectFilesEditor::createEditableInterface()
+{
+    return new ProjectFilesEditable(this);
+}
+
+////////////////////////////////////////////////////////////////////////////////////////
+// ProjectFilesDocument
+////////////////////////////////////////////////////////////////////////////////////////
+
+ProjectFilesDocument::ProjectFilesDocument(Manager *manager)
+    : m_manager(manager)
+{
+    setMimeType(QLatin1String(Constants::FILES_MIMETYPE));
+}
+
+ProjectFilesDocument::~ProjectFilesDocument()
+{ }
+
+bool ProjectFilesDocument::save(const QString &name)
+{
+    if (! BaseTextDocument::save(name))
+        return false;
+
+    m_manager->notifyChanged(name);
+    return true;
+}
diff --git a/src/plugins/qmlprojectmanager/qmlprojectfileseditor.h b/src/plugins/qmlprojectmanager/qmlprojectfileseditor.h
new file mode 100644
index 0000000000000000000000000000000000000000..4b189a379b37a1661159e756e7d48de35d8f46a5
--- /dev/null
+++ b/src/plugins/qmlprojectmanager/qmlprojectfileseditor.h
@@ -0,0 +1,123 @@
+/**************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact:  Qt Software Information (qt-info@nokia.com)
+**
+** Commercial Usage
+**
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Nokia.
+**
+** GNU Lesser General Public License Usage
+**
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file.  Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+**
+**************************************************************************/
+
+#ifndef QMLPROJECTFILESEDITOR_H
+#define QMLPROJECTFILESEDITOR_H
+
+#include <texteditor/basetexteditor.h>
+#include <texteditor/basetextdocument.h>
+
+#include <coreplugin/editormanager/ieditorfactory.h>
+
+namespace QmlProjectManager {
+namespace Internal {
+
+class Manager;
+class ProjectFilesEditable;
+class ProjectFilesEditor;
+class ProjectFilesDocument;
+class ProjectFilesFactory;
+
+class ProjectFilesFactory: public Core::IEditorFactory
+{
+    Q_OBJECT
+
+public:
+    ProjectFilesFactory(Manager *manager, TextEditor::TextEditorActionHandler *handler);
+    virtual ~ProjectFilesFactory();
+    
+    Manager *manager() const;
+
+    virtual Core::IEditor *createEditor(QWidget *parent);
+
+    virtual QStringList mimeTypes() const;
+    virtual QString kind() const;
+    virtual Core::IFile *open(const QString &fileName);
+
+private:
+    Manager *m_manager;
+    TextEditor::TextEditorActionHandler *m_actionHandler;
+    QStringList m_mimeTypes;
+};
+
+class ProjectFilesEditable: public TextEditor::BaseTextEditorEditable
+{
+    Q_OBJECT
+
+public:
+    ProjectFilesEditable(ProjectFilesEditor *editor);
+    virtual ~ProjectFilesEditable();
+
+    virtual QList<int> context() const;
+    virtual const char *kind() const;
+
+    virtual bool duplicateSupported() const;
+    virtual Core::IEditor *duplicate(QWidget *parent);
+
+private:
+    QList<int> m_context;
+};
+
+class ProjectFilesEditor: public TextEditor::BaseTextEditor
+{
+    Q_OBJECT
+
+public:
+    ProjectFilesEditor(QWidget *parent, ProjectFilesFactory *factory,
+                       TextEditor::TextEditorActionHandler *handler);
+    virtual ~ProjectFilesEditor();
+
+    ProjectFilesFactory *factory() const;
+    TextEditor::TextEditorActionHandler *actionHandler() const;
+
+    virtual TextEditor::BaseTextEditorEditable *createEditableInterface();
+
+private:
+    ProjectFilesFactory *m_factory;
+    TextEditor::TextEditorActionHandler *m_actionHandler;
+};
+
+class ProjectFilesDocument: public TextEditor::BaseTextDocument
+{
+    Q_OBJECT
+
+public:
+    ProjectFilesDocument(Manager *manager);
+    virtual ~ProjectFilesDocument();
+
+    virtual bool save(const QString &name);
+
+private:
+    Manager *m_manager;
+};
+
+} // end of namespace Internal
+} // end of namespace QmlProjectManager
+
+#endif // QMLPROJECTFILESEDITOR_H
diff --git a/src/plugins/qmlprojectmanager/qmlprojectmanager.cpp b/src/plugins/qmlprojectmanager/qmlprojectmanager.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..02facd1dc5c9dfd275b75bf949064ceda8ebbb06
--- /dev/null
+++ b/src/plugins/qmlprojectmanager/qmlprojectmanager.cpp
@@ -0,0 +1,86 @@
+/**************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact:  Qt Software Information (qt-info@nokia.com)
+**
+** Commercial Usage
+**
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Nokia.
+**
+** GNU Lesser General Public License Usage
+**
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file.  Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+**
+**************************************************************************/
+
+#include "qmlprojectmanager.h"
+#include "qmlprojectconstants.h"
+#include "qmlproject.h"
+
+#include <coreplugin/icore.h>
+#include <coreplugin/uniqueidmanager.h>
+#include <projectexplorer/projectexplorerconstants.h>
+
+#include <QtDebug>
+
+using namespace QmlProjectManager::Internal;
+
+Manager::Manager()
+{
+    Core::UniqueIDManager *uidm = Core::UniqueIDManager::instance();
+    m_projectContext  = uidm->uniqueIdentifier(QmlProjectManager::Constants::PROJECTCONTEXT);
+    m_projectLanguage = uidm->uniqueIdentifier(ProjectExplorer::Constants::LANG_CXX);
+}
+
+Manager::~Manager()
+{ }
+
+int Manager::projectContext() const
+{ return m_projectContext; }
+
+int Manager::projectLanguage() const
+{ return m_projectLanguage; }
+
+QString Manager::mimeType() const
+{ return QLatin1String(Constants::QMLMIMETYPE); }
+
+ProjectExplorer::Project *Manager::openProject(const QString &fileName)
+{
+    QFileInfo fileInfo(fileName);
+
+    if (fileInfo.isFile()) {
+        QmlProject *project = new QmlProject(this, fileName);
+        return project;
+    }
+
+    return 0;
+}
+
+void Manager::registerProject(QmlProject *project)
+{ m_projects.append(project); }
+
+void Manager::unregisterProject(QmlProject *project)
+{ m_projects.removeAll(project); }
+
+void Manager::notifyChanged(const QString &fileName)
+{
+    foreach (QmlProject *project, m_projects) {
+        if (fileName == project->filesFileName()) {
+            project->refresh(QmlProject::Files);
+        }
+    }
+}
diff --git a/src/plugins/qmlprojectmanager/qmlprojectmanager.h b/src/plugins/qmlprojectmanager/qmlprojectmanager.h
new file mode 100644
index 0000000000000000000000000000000000000000..66a4271b0a5ed3f974834ce220b511ca8e02b6a1
--- /dev/null
+++ b/src/plugins/qmlprojectmanager/qmlprojectmanager.h
@@ -0,0 +1,68 @@
+/**************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact:  Qt Software Information (qt-info@nokia.com)
+**
+** Commercial Usage
+**
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Nokia.
+**
+** GNU Lesser General Public License Usage
+**
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file.  Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+**
+**************************************************************************/
+
+#ifndef QMLPROJECTMANAGER_H
+#define QMLPROJECTMANAGER_H
+
+#include <projectexplorer/iprojectmanager.h>
+
+namespace QmlProjectManager {
+namespace Internal {
+
+class QmlProject;
+
+class Manager: public ProjectExplorer::IProjectManager
+{
+    Q_OBJECT
+
+public:
+    Manager();
+    virtual ~Manager();
+
+    virtual int projectContext() const;
+    virtual int projectLanguage() const;
+
+    virtual QString mimeType() const;
+    virtual ProjectExplorer::Project *openProject(const QString &fileName);
+
+    void notifyChanged(const QString &fileName);
+
+    void registerProject(QmlProject *project);
+    void unregisterProject(QmlProject *project);
+
+private:
+    int m_projectContext;
+    int m_projectLanguage;
+    QList<QmlProject *> m_projects;
+};
+
+} // namespace Internal
+} // namespace QmlProjectManager
+
+#endif // QMLPROJECTMANAGER_H
diff --git a/src/plugins/qmlprojectmanager/qmlprojectmanager.pro b/src/plugins/qmlprojectmanager/qmlprojectmanager.pro
new file mode 100644
index 0000000000000000000000000000000000000000..f9804420a759dc6fb4b99c4c20958cb21a5c958f
--- /dev/null
+++ b/src/plugins/qmlprojectmanager/qmlprojectmanager.pro
@@ -0,0 +1,20 @@
+TEMPLATE = lib
+TARGET = QmlProjectManager
+include(../../qworkbenchplugin.pri)
+include(qmlprojectmanager_dependencies.pri)
+HEADERS = qmlproject.h \
+    qmlprojectplugin.h \
+    qmlprojectmanager.h \
+    qmlprojectconstants.h \
+    qmlprojectnodes.h \
+    qmlprojectwizard.h \
+    qmlprojectfileseditor.h
+SOURCES = qmlproject.cpp \
+    qmlprojectplugin.cpp \
+    qmlprojectmanager.cpp \
+    qmlprojectnodes.cpp \
+    qmlprojectwizard.cpp \
+    qmlprojectfileseditor.cpp
+RESOURCES += qmlproject.qrc
+
+OTHER_FILES += QmlProjectManager.pluginspec
diff --git a/src/plugins/qmlprojectmanager/qmlprojectmanager_dependencies.pri b/src/plugins/qmlprojectmanager/qmlprojectmanager_dependencies.pri
new file mode 100644
index 0000000000000000000000000000000000000000..191c4a96e9b40bd8f24770605b6bbf118f2695c4
--- /dev/null
+++ b/src/plugins/qmlprojectmanager/qmlprojectmanager_dependencies.pri
@@ -0,0 +1,2 @@
+include(../../plugins/projectexplorer/projectexplorer.pri)
+include(../../plugins/texteditor/texteditor.pri)
diff --git a/src/plugins/qmlprojectmanager/qmlprojectnodes.cpp b/src/plugins/qmlprojectmanager/qmlprojectnodes.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..1943276502654bb8f480000e54ac09bd6bc4b3c4
--- /dev/null
+++ b/src/plugins/qmlprojectmanager/qmlprojectnodes.cpp
@@ -0,0 +1,196 @@
+/**************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact:  Qt Software Information (qt-info@nokia.com)
+**
+** Commercial Usage
+**
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Nokia.
+**
+** GNU Lesser General Public License Usage
+**
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file.  Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+**
+**************************************************************************/
+
+#include "qmlprojectnodes.h"
+#include "qmlproject.h"
+
+#include <coreplugin/ifile.h>
+#include <projectexplorer/projectexplorer.h>
+
+#include <QFileInfo>
+
+using namespace QmlProjectManager;
+using namespace QmlProjectManager::Internal;
+
+QmlProjectNode::QmlProjectNode(QmlProject *project, Core::IFile *projectFile)
+    : ProjectExplorer::ProjectNode(QFileInfo(projectFile->fileName()).absolutePath()),
+      m_project(project),
+      m_projectFile(projectFile)
+{
+    setFolderName(QFileInfo(projectFile->fileName()).completeBaseName());
+}
+
+QmlProjectNode::~QmlProjectNode()
+{ }
+
+Core::IFile *QmlProjectNode::projectFile() const
+{ return m_projectFile; }
+
+QString QmlProjectNode::projectFilePath() const
+{ return m_projectFile->fileName(); }
+
+void QmlProjectNode::refresh()
+{
+    using namespace ProjectExplorer;
+
+    // remove the existing nodes.
+    removeFileNodes(fileNodes(), this);
+    removeFolderNodes(subFolderNodes(), this);
+
+    //ProjectExplorerPlugin::instance()->setCurrentNode(0); // ### remove me
+
+    FileNode *projectFilesNode = new FileNode(m_project->filesFileName(),
+                                              ProjectFileType,
+                                              /* generated = */ false);
+
+    QStringList files = m_project->files();
+    files.removeAll(m_project->filesFileName());
+
+    addFileNodes(QList<FileNode *>()
+                 << projectFilesNode,
+                 this);
+
+    QStringList filePaths;
+    QHash<QString, QStringList> filesInPath;
+
+    foreach (const QString &absoluteFileName, files) {
+        QFileInfo fileInfo(absoluteFileName);
+        const QString absoluteFilePath = fileInfo.path();
+
+        if (! absoluteFilePath.startsWith(path()))
+            continue; // `file' is not part of the project.
+
+        const QString relativeFilePath = absoluteFilePath.mid(path().length() + 1);
+
+        if (! filePaths.contains(relativeFilePath))
+            filePaths.append(relativeFilePath);
+
+        filesInPath[relativeFilePath].append(absoluteFileName);
+    }
+
+    foreach (const QString &filePath, filePaths) {
+        FolderNode *folder = findOrCreateFolderByName(filePath);
+
+        QList<FileNode *> fileNodes;
+        foreach (const QString &file, filesInPath.value(filePath)) {
+            FileType fileType = SourceType; // ### FIXME
+            FileNode *fileNode = new FileNode(file, fileType, /*generated = */ false);
+            fileNodes.append(fileNode);
+        }
+
+        addFileNodes(fileNodes, folder);
+    }
+
+    m_folderByName.clear();
+}
+
+ProjectExplorer::FolderNode *QmlProjectNode::findOrCreateFolderByName(const QStringList &components, int end)
+{
+    if (! end)
+        return 0;
+
+    QString folderName;
+    for (int i = 0; i < end; ++i) {
+        folderName.append(components.at(i));
+        folderName += QLatin1Char('/'); // ### FIXME
+    }
+
+    const QString component = components.at(end - 1);
+
+    if (component.isEmpty())
+        return this;
+
+    else if (FolderNode *folder = m_folderByName.value(folderName))
+        return folder;
+
+    FolderNode *folder = new FolderNode(component);
+    m_folderByName.insert(folderName, folder);
+
+    FolderNode *parent = findOrCreateFolderByName(components, end - 1);
+    if (! parent)
+        parent = this;
+    addFolderNodes(QList<FolderNode*>() << folder, parent);
+
+    return folder;
+}
+
+ProjectExplorer::FolderNode *QmlProjectNode::findOrCreateFolderByName(const QString &filePath)
+{
+    QStringList components = filePath.split(QLatin1Char('/'));
+    return findOrCreateFolderByName(components, components.length());
+}
+
+bool QmlProjectNode::hasTargets() const
+{
+    return true;
+}
+
+QList<ProjectExplorer::ProjectNode::ProjectAction> QmlProjectNode::supportedActions() const
+{
+    return QList<ProjectAction>();
+}
+
+bool QmlProjectNode::addSubProjects(const QStringList &proFilePaths)
+{
+    Q_UNUSED(proFilePaths);
+    return false;
+}
+
+bool QmlProjectNode::removeSubProjects(const QStringList &proFilePaths)
+{
+    Q_UNUSED(proFilePaths);
+    return false;
+}
+
+bool QmlProjectNode::addFiles(const ProjectExplorer::FileType fileType,
+                                  const QStringList &filePaths, QStringList *notAdded)
+{
+    Q_UNUSED(fileType);
+    Q_UNUSED(filePaths);
+    Q_UNUSED(notAdded);
+    return false;
+}
+
+bool QmlProjectNode::removeFiles(const ProjectExplorer::FileType fileType,
+                                     const QStringList &filePaths, QStringList *notRemoved)
+{
+    Q_UNUSED(fileType);
+    Q_UNUSED(filePaths);
+    Q_UNUSED(notRemoved);
+    return false;
+}
+
+bool QmlProjectNode::renameFile(const ProjectExplorer::FileType fileType,
+                                    const QString &filePath, const QString &newFilePath)
+{
+    Q_UNUSED(fileType);
+    Q_UNUSED(filePath);
+    Q_UNUSED(newFilePath);
+    return false;
+}
diff --git a/src/plugins/qmlprojectmanager/qmlprojectnodes.h b/src/plugins/qmlprojectmanager/qmlprojectnodes.h
new file mode 100644
index 0000000000000000000000000000000000000000..c5f3851cc75a4c905e606eec13a0faaec9191f11
--- /dev/null
+++ b/src/plugins/qmlprojectmanager/qmlprojectnodes.h
@@ -0,0 +1,91 @@
+/**************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact:  Qt Software Information (qt-info@nokia.com)
+**
+** Commercial Usage
+**
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Nokia.
+**
+** GNU Lesser General Public License Usage
+**
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file.  Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+**
+**************************************************************************/
+
+#ifndef QMLPROJECTNODE_H
+#define QMLPROJECTNODE_H
+
+#include <projectexplorer/projectnodes.h>
+
+#include <QStringList>
+#include <QHash>
+
+namespace Core {
+class IFile;
+}
+
+namespace QmlProjectManager {
+namespace Internal {
+
+class QmlProject;
+
+class QmlProjectNode : public ProjectExplorer::ProjectNode
+{
+public:
+    QmlProjectNode(QmlProject *project, Core::IFile *projectFile);
+    virtual ~QmlProjectNode();
+
+    Core::IFile *projectFile() const;
+    QString projectFilePath() const;
+
+    virtual bool hasTargets() const;
+
+    virtual QList<ProjectExplorer::ProjectNode::ProjectAction> supportedActions() const;
+
+    virtual bool addSubProjects(const QStringList &proFilePaths);
+    virtual bool removeSubProjects(const QStringList &proFilePaths);
+
+    virtual bool addFiles(const ProjectExplorer::FileType fileType,
+                          const QStringList &filePaths,
+                          QStringList *notAdded = 0);
+
+    virtual bool removeFiles(const ProjectExplorer::FileType fileType,
+                             const QStringList &filePaths,
+                             QStringList *notRemoved = 0);
+
+    virtual bool renameFile(const ProjectExplorer::FileType fileType,
+                             const QString &filePath,
+                             const QString &newFilePath);
+
+
+    void refresh();
+
+private:
+    FolderNode *findOrCreateFolderByName(const QString &filePath);
+    FolderNode *findOrCreateFolderByName(const QStringList &components, int end);
+
+private:
+    QmlProject *m_project;
+    Core::IFile *m_projectFile;
+    QHash<QString, FolderNode *> m_folderByName;
+};
+
+} // namespace Internal
+} // namespace QmlProjectManager
+
+#endif // QMLPROJECTNODE_H
diff --git a/src/plugins/qmlprojectmanager/qmlprojectplugin.cpp b/src/plugins/qmlprojectmanager/qmlprojectplugin.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..1f4b0cbc001f8f77f7b036e264384bcfa6334b53
--- /dev/null
+++ b/src/plugins/qmlprojectmanager/qmlprojectplugin.cpp
@@ -0,0 +1,86 @@
+/**************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact:  Qt Software Information (qt-info@nokia.com)
+**
+** Commercial Usage
+**
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Nokia.
+**
+** GNU Lesser General Public License Usage
+**
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file.  Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+**
+**************************************************************************/
+
+#include "qmlprojectplugin.h"
+#include "qmlprojectmanager.h"
+#include "qmlprojectwizard.h"
+#include "qmlprojectconstants.h"
+#include "qmlprojectfileseditor.h"
+
+#include <coreplugin/icore.h>
+#include <coreplugin/mimedatabase.h>
+
+#include <texteditor/texteditoractionhandler.h>
+
+#include <QtCore/QtPlugin>
+#include <QtCore/QDebug>
+
+using namespace QmlProjectManager;
+using namespace QmlProjectManager::Internal;
+
+QmlProjectPlugin::QmlProjectPlugin()
+    : m_projectFilesEditorFactory(0)
+{ }
+
+QmlProjectPlugin::~QmlProjectPlugin()
+{
+    removeObject(m_projectFilesEditorFactory);
+    delete m_projectFilesEditorFactory;
+}
+
+bool QmlProjectPlugin::initialize(const QStringList &, QString *errorMessage)
+{
+    using namespace Core;
+
+    ICore *core = ICore::instance();
+    Core::MimeDatabase *mimeDB = core->mimeDatabase();
+
+    const QLatin1String mimetypesXml(":qmlproject/QmlProject.mimetypes.xml");
+
+    if (! mimeDB->addMimeTypes(mimetypesXml, errorMessage))
+        return false;
+
+    Manager *manager = new Manager;
+
+    TextEditor::TextEditorActionHandler *actionHandler =
+            new TextEditor::TextEditorActionHandler(Constants::C_FILESEDITOR);
+
+    m_projectFilesEditorFactory = new ProjectFilesFactory(manager, actionHandler);
+    addObject(m_projectFilesEditorFactory);
+
+    addAutoReleasedObject(manager);
+    addAutoReleasedObject(new QmlProjectWizard);
+
+    return true;
+}
+
+void QmlProjectPlugin::extensionsInitialized()
+{ }
+
+Q_EXPORT_PLUGIN(QmlProjectPlugin)
diff --git a/src/plugins/qmlprojectmanager/qmlprojectplugin.h b/src/plugins/qmlprojectmanager/qmlprojectplugin.h
new file mode 100644
index 0000000000000000000000000000000000000000..8590bf53c52644905eb24def8537d8ba2d5d37f3
--- /dev/null
+++ b/src/plugins/qmlprojectmanager/qmlprojectplugin.h
@@ -0,0 +1,60 @@
+/**************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact:  Qt Software Information (qt-info@nokia.com)
+**
+** Commercial Usage
+**
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Nokia.
+**
+** GNU Lesser General Public License Usage
+**
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file.  Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+**
+**************************************************************************/
+
+#ifndef QMLPROJECTPLUGIN_H
+#define QMLPROJECTPLUGIN_H
+
+#include <extensionsystem/iplugin.h>
+
+#include <QtCore/QObject>
+
+namespace QmlProjectManager {
+namespace Internal {
+
+class ProjectFilesFactory;
+
+class QmlProjectPlugin: public ExtensionSystem::IPlugin
+{
+    Q_OBJECT
+
+public:
+    QmlProjectPlugin();
+    ~QmlProjectPlugin();
+
+    virtual bool initialize(const QStringList &arguments, QString *errorString);
+    virtual void extensionsInitialized();
+
+private:
+    ProjectFilesFactory *m_projectFilesEditorFactory;
+};
+
+} // namespace Internal
+} // namespace QmlProject
+
+#endif // QMLPROJECTPLUGIN_H
diff --git a/src/plugins/qmlprojectmanager/qmlprojectwizard.cpp b/src/plugins/qmlprojectmanager/qmlprojectwizard.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..68736377fc381ea97d45aed4de9f15935dbd109c
--- /dev/null
+++ b/src/plugins/qmlprojectmanager/qmlprojectwizard.cpp
@@ -0,0 +1,355 @@
+/**************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact:  Qt Software Information (qt-info@nokia.com)
+**
+** Commercial Usage
+**
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Nokia.
+**
+** GNU Lesser General Public License Usage
+**
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file.  Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+**
+**************************************************************************/
+
+#include "qmlprojectwizard.h"
+
+#include <coreplugin/icore.h>
+#include <coreplugin/mimedatabase.h>
+#include <projectexplorer/projectexplorer.h>
+
+#include <utils/filenamevalidatinglineedit.h>
+#include <utils/filewizardpage.h>
+#include <utils/pathchooser.h>
+
+#include <QtCore/QDir>
+#include <QtCore/QtDebug>
+
+#include <QtGui/QDirModel>
+#include <QtGui/QFormLayout>
+#include <QtGui/QListView>
+#include <QtGui/QTreeView>
+
+using namespace QmlProjectManager::Internal;
+using namespace Core::Utils;
+
+namespace {
+
+class DirModel : public QDirModel
+{
+public:
+    DirModel(QObject *parent)
+        : QDirModel(parent)
+    { setFilter(QDir::Dirs | QDir::NoDotAndDotDot); }
+
+    virtual ~DirModel()
+    { }
+
+public:
+    virtual int columnCount(const QModelIndex &) const
+    { return 1; }
+
+    virtual Qt::ItemFlags flags(const QModelIndex &index) const
+    { return QDirModel::flags(index) | Qt::ItemIsUserCheckable; }
+
+    virtual QVariant data(const QModelIndex &index, int role) const
+    {
+        if (index.column() == 0 && role == Qt::CheckStateRole) {
+            if (m_selectedPaths.contains(index))
+                return Qt::Checked;
+
+            return Qt::Unchecked;
+        }
+
+        return QDirModel::data(index, role);
+    }
+
+    virtual bool setData(const QModelIndex &index, const QVariant &value, int role)
+    {
+        if (index.column() == 0 && role == Qt::CheckStateRole) {
+            if (value.toBool())
+                m_selectedPaths.insert(index);
+            else
+                m_selectedPaths.remove(index);
+
+            return true;
+        }
+
+        return QDirModel::setData(index, value, role);
+    }
+
+    void clearSelectedPaths()
+    { m_selectedPaths.clear(); }
+
+    QSet<QString> selectedPaths() const
+    {
+        QSet<QString> paths;
+
+        foreach (const QModelIndex &index, m_selectedPaths)
+            paths.insert(filePath(index));
+
+        return paths;
+    }
+
+private:
+    QSet<QModelIndex> m_selectedPaths;
+};
+
+} // end of anonymous namespace
+
+
+//////////////////////////////////////////////////////////////////////////////
+// QmlProjectWizardDialog
+//////////////////////////////////////////////////////////////////////////////
+
+
+QmlProjectWizardDialog::QmlProjectWizardDialog(QWidget *parent)
+    : QWizard(parent)
+{
+    setWindowTitle(tr("Import of QML Project"));
+
+    // first page
+    m_firstPage = new FileWizardPage;
+    m_firstPage->setTitle(tr("Qml Project"));
+    m_firstPage->setNameLabel(tr("Project name:"));
+    m_firstPage->setPathLabel(tr("Location:"));
+
+    addPage(m_firstPage);
+
+#if 0
+    // second page
+    QWizardPage *secondPage = new QWizardPage;
+    secondPage->setTitle(tr("Second Page Title"));
+
+    QFormLayout *secondPageLayout = new QFormLayout(secondPage);
+
+    m_dirView = new QTreeView;
+    m_dirModel = new DirModel(this);
+    m_dirView->setModel(_dirModel);
+
+    Core::ICore *core = Core::ICore::instance();
+    Core::MimeDatabase *mimeDatabase = core->mimeDatabase();
+
+    const QStringList suffixes = mimeDatabase->suffixes();
+
+    QStringList nameFilters;
+    foreach (const QString &suffix, suffixes) {
+        QString nameFilter;
+        nameFilter.append(QLatin1String("*."));
+        nameFilter.append(suffix);
+        nameFilters.append(nameFilter);
+    }
+
+    m_filesView = new QListView;
+    m_filesModel = new QDirModel(this);
+    m_filesModel->setNameFilters(nameFilters);
+    m_filesModel->setFilter(QDir::Files);
+
+    connect(_dirView->selectionModel(), SIGNAL(currentChanged(QModelIndex,QModelIndex)),
+            this, SLOT(updateFilesView(QModelIndex,QModelIndex)));
+
+    secondPageLayout->addRow(_dirView);
+    secondPageLayout->addRow(_filesView);
+
+    m_secondPageId = addPage(secondPage);
+#endif
+}
+
+QmlProjectWizardDialog::~QmlProjectWizardDialog()
+{ }
+
+QString QmlProjectWizardDialog::path() const
+{
+    return m_firstPage->path();
+}
+
+void QmlProjectWizardDialog::setPath(const QString &path)
+{
+    m_firstPage->setPath(path);
+}
+
+QString QmlProjectWizardDialog::projectName() const
+{
+    return m_firstPage->name();
+}
+
+void QmlProjectWizardDialog::updateFilesView(const QModelIndex &current,
+                                                 const QModelIndex &)
+{
+    if (! current.isValid())
+        m_filesView->setModel(0);
+
+    else {
+        const QString selectedPath = m_dirModel->filePath(current);
+
+        if (! m_filesView->model())
+            m_filesView->setModel(m_filesModel);
+
+        m_filesView->setRootIndex(m_filesModel->index(selectedPath));
+    }
+}
+
+void QmlProjectWizardDialog::initializePage(int id)
+{
+    Q_UNUSED(id)
+#if 0
+    if (id == m_secondPageId) {
+        using namespace Core::Utils;
+
+        const QString projectPath = m_pathChooser->path();
+
+        QDirModel *dirModel = qobject_cast<QDirModel *>(_dirView->model());
+        m_dirView->setRootIndex(dirModel->index(projectPath));
+    }
+#endif
+}
+
+bool QmlProjectWizardDialog::validateCurrentPage()
+{
+    using namespace Core::Utils;
+
+#if 0
+    if (currentId() == m_secondPageId) {
+        return true;
+    }
+#endif
+
+    return QWizard::validateCurrentPage();
+}
+
+QmlProjectWizard::QmlProjectWizard()
+    : Core::BaseFileWizard(parameters())
+{ }
+
+QmlProjectWizard::~QmlProjectWizard()
+{ }
+
+Core::BaseFileWizardParameters QmlProjectWizard::parameters()
+{
+    static Core::BaseFileWizardParameters parameters(ProjectWizard);
+    parameters.setIcon(QIcon(":/wizards/images/console.png"));
+    parameters.setName(tr("Import of QML Project"));
+    parameters.setDescription(tr("Creates a QML project."));
+    parameters.setCategory(QLatin1String("Projects"));
+    parameters.setTrCategory(tr("Projects"));
+    return parameters;
+}
+
+QWizard *QmlProjectWizard::createWizardDialog(QWidget *parent,
+                                                  const QString &defaultPath,
+                                                  const WizardPageList &extensionPages) const
+{
+    QmlProjectWizardDialog *wizard = new QmlProjectWizardDialog(parent);
+    setupWizard(wizard);
+
+    wizard->setPath(defaultPath);
+
+    foreach (QWizardPage *p, extensionPages)
+        wizard->addPage(p);
+
+    return wizard;
+}
+
+void QmlProjectWizard::getFileList(const QDir &dir, const QString &projectRoot,
+                                       const QStringList &suffixes,
+                                       QStringList *files, QStringList *paths) const
+{
+    const QFileInfoList fileInfoList = dir.entryInfoList(QDir::Files |
+                                                         QDir::Dirs |
+                                                         QDir::NoDotAndDotDot |
+                                                         QDir::NoSymLinks);
+
+    foreach (const QFileInfo &fileInfo, fileInfoList) {
+        QString filePath = fileInfo.absoluteFilePath();
+        filePath = filePath.mid(projectRoot.length() + 1);
+
+        if (fileInfo.isDir() && isValidDir(fileInfo)) {
+            getFileList(QDir(fileInfo.absoluteFilePath()), projectRoot,
+                        suffixes, files, paths);
+
+            if (! paths->contains(filePath))
+                paths->append(filePath);
+        }
+
+        else if (suffixes.contains(fileInfo.suffix()))
+            files->append(filePath);
+    }
+}
+
+bool QmlProjectWizard::isValidDir(const QFileInfo &fileInfo) const
+{
+    const QString fileName = fileInfo.fileName();
+    const QString suffix = fileInfo.suffix();
+
+    if (fileName.startsWith(QLatin1Char('.')))
+        return false;
+
+    else if (fileName == QLatin1String("CVS"))
+        return false;    
+
+    // ### user include/exclude
+
+    return true;
+}
+
+Core::GeneratedFiles QmlProjectWizard::generateFiles(const QWizard *w,
+						     QString *errorMessage) const
+{
+    Q_UNUSED(errorMessage)
+
+    const QmlProjectWizardDialog *wizard = qobject_cast<const QmlProjectWizardDialog *>(w);
+    const QString projectPath = wizard->path();
+    const QDir dir(projectPath);
+    const QString projectName = wizard->projectName();
+    const QString creatorFileName = QFileInfo(dir, projectName + QLatin1String(".qmlproject")).absoluteFilePath();
+    const QString filesFileName = QFileInfo(dir, projectName + QLatin1String(".files")).absoluteFilePath();
+    const QString includesFileName = QFileInfo(dir, projectName + QLatin1String(".includes")).absoluteFilePath();
+    const QString configFileName = QFileInfo(dir, projectName + QLatin1String(".config")).absoluteFilePath();
+
+    Core::ICore *core = Core::ICore::instance();
+    Core::MimeDatabase *mimeDatabase = core->mimeDatabase();
+
+    const QStringList suffixes = mimeDatabase->suffixes();
+
+    QStringList sources, paths;
+    getFileList(dir, projectPath, suffixes, &sources, &paths);
+
+    Core::GeneratedFile generatedCreatorFile(creatorFileName);
+    generatedCreatorFile.setContents(QLatin1String("[General]\n"));
+
+    Core::GeneratedFile generatedFilesFile(filesFileName);
+    generatedFilesFile.setContents(sources.join(QLatin1String("\n")));
+
+    Core::GeneratedFiles files;
+    files.append(generatedFilesFile);
+    files.append(generatedCreatorFile);
+
+    return files;
+}
+
+bool QmlProjectWizard::postGenerateFiles(const Core::GeneratedFiles &l, QString *errorMessage)
+{
+    // Post-Generate: Open the project
+    const QString proFileName = l.back().path();
+    if (!ProjectExplorer::ProjectExplorerPlugin::instance()->openProject(proFileName)) {
+        *errorMessage = tr("The project %1 could not be opened.").arg(proFileName);
+        return false;
+    }
+    return true;
+}
+
diff --git a/src/plugins/qmlprojectmanager/qmlprojectwizard.h b/src/plugins/qmlprojectmanager/qmlprojectwizard.h
new file mode 100644
index 0000000000000000000000000000000000000000..a49cc5d4cb0682c73bdc58d31b7d9bedb778e89b
--- /dev/null
+++ b/src/plugins/qmlprojectmanager/qmlprojectwizard.h
@@ -0,0 +1,122 @@
+/**************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact:  Qt Software Information (qt-info@nokia.com)
+**
+** Commercial Usage
+**
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Nokia.
+**
+** GNU Lesser General Public License Usage
+**
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file.  Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+**
+**************************************************************************/
+
+#ifndef QMLPROJECTWIZARD_H
+#define QMLPROJECTWIZARD_H
+
+#include <coreplugin/basefilewizard.h>
+
+#include <QtGui/QWizard>
+
+QT_BEGIN_NAMESPACE
+class QDir;
+class QDirModel;
+class QFileInfo;
+class QListView;
+class QModelIndex;
+class QStringList;
+class QTreeView;
+QT_END_NAMESPACE
+
+namespace Core {
+namespace Utils {
+
+class FileWizardPage;
+
+} // namespace Utils
+} // namespace Core
+
+namespace QmlProjectManager {
+namespace Internal {
+
+class QmlProjectWizardDialog : public QWizard
+{
+    Q_OBJECT
+
+public:
+    QmlProjectWizardDialog(QWidget *parent = 0);
+    virtual ~QmlProjectWizardDialog();
+
+    QString path() const;
+    void setPath(const QString &path);
+
+    QString projectName() const;
+
+private Q_SLOTS:
+    void updateFilesView(const QModelIndex &current,
+                         const QModelIndex &previous);
+
+protected:
+    virtual void initializePage(int id);
+    virtual bool validateCurrentPage();
+
+private:
+    int m_secondPageId;
+
+    Core::Utils::FileWizardPage *m_firstPage;
+
+    QTreeView *m_dirView;
+    QDirModel *m_dirModel;
+
+    QListView *m_filesView;
+    QDirModel *m_filesModel;
+};
+
+class QmlProjectWizard : public Core::BaseFileWizard
+{
+    Q_OBJECT
+
+public:
+    QmlProjectWizard();
+    virtual ~QmlProjectWizard();
+
+    static Core::BaseFileWizardParameters parameters();
+
+protected:
+    virtual QWizard *createWizardDialog(QWidget *parent,
+                                        const QString &defaultPath,
+                                        const WizardPageList &extensionPages) const;
+
+    virtual Core::GeneratedFiles generateFiles(const QWizard *w,
+                                               QString *errorMessage) const;
+
+    virtual bool postGenerateFiles(const Core::GeneratedFiles &l, QString *errorMessage);
+
+    bool isValidDir(const QFileInfo &fileInfo) const;
+
+    void getFileList(const QDir &dir, const QString &projectRoot,
+                     const QStringList &suffixes,
+                     QStringList *files,
+                     QStringList *paths) const;
+};
+
+} // end of namespace Internal
+} // end of namespace QmlProjectManager
+
+#endif // QMLPROJECTWIZARD_H