diff --git a/src/libs/languageutils/componentversion.cpp b/src/libs/languageutils/componentversion.cpp
index 7811bb438cada43312f4ccde587aa91a5cb873e3..4368d5f94f8fd5b0b3d26944fcf885b08bc02e8e 100644
--- a/src/libs/languageutils/componentversion.cpp
+++ b/src/libs/languageutils/componentversion.cpp
@@ -34,9 +34,12 @@
 
 #include <QtCore/QString>
 
+#include <limits>
+
 using namespace LanguageUtils;
 
 const int ComponentVersion::NoVersion = -1;
+const int ComponentVersion::MaxVersion = std::numeric_limits<int>::max();
 
 ComponentVersion::ComponentVersion()
     : _major(NoVersion), _minor(NoVersion)
diff --git a/src/libs/languageutils/componentversion.h b/src/libs/languageutils/componentversion.h
index 5f8e413fb66a60dc7785c4d641efd66dfbedd0a9..baa8d4e1878ca068974272346f49a17c26ff95fa 100644
--- a/src/libs/languageutils/componentversion.h
+++ b/src/libs/languageutils/componentversion.h
@@ -44,6 +44,7 @@ class LANGUAGEUTILS_EXPORT ComponentVersion
 
 public:
     static const int NoVersion;
+    static const int MaxVersion;
 
     ComponentVersion();
     ComponentVersion(int major, int minor);
diff --git a/src/libs/qmljs/qmljsdocument.cpp b/src/libs/qmljs/qmljsdocument.cpp
index 467c522c74c42c579e8f67e95f3275c63631ba50..2cfeb1d6ee0521bbfb91d15103dce20fd6b96089 100644
--- a/src/libs/qmljs/qmljsdocument.cpp
+++ b/src/libs/qmljs/qmljsdocument.cpp
@@ -357,14 +357,14 @@ void Document::extractPragmas(QString *source)
     }
 }
 
-LibraryInfo::LibraryInfo()
-    : _valid(false)
+LibraryInfo::LibraryInfo(Status status)
+    : _status(status)
     , _dumpStatus(DumpNotStartedOrRunning)
 {
 }
 
 LibraryInfo::LibraryInfo(const QmlDirParser &parser)
-    : _valid(true)
+    : _status(Found)
     , _components(parser.components())
     , _plugins(parser.plugins())
     , _dumpStatus(DumpNotStartedOrRunning)
diff --git a/src/libs/qmljs/qmljsdocument.h b/src/libs/qmljs/qmljsdocument.h
index 2c1a516cac9ff312074d4189e9ed373e823db62f..b1aaadaa32f62c63944e9129f0be23011d388f42 100644
--- a/src/libs/qmljs/qmljsdocument.h
+++ b/src/libs/qmljs/qmljsdocument.h
@@ -127,8 +127,14 @@ public:
         DumpError
     };
 
+    enum Status {
+        NotScanned,
+        NotFound,
+        Found
+    };
+
 private:
-    bool _valid;
+    Status _status;
     QList<QmlDirParser::Component> _components;
     QList<QmlDirParser::Plugin> _plugins;
     typedef QList<LanguageUtils::FakeMetaObject::ConstPtr> FakeMetaObjectList;
@@ -138,8 +144,8 @@ private:
     QString _dumpError;
 
 public:
-    LibraryInfo();
-    LibraryInfo(const QmlDirParser &parser);
+    explicit LibraryInfo(Status status = NotScanned);
+    explicit LibraryInfo(const QmlDirParser &parser);
     ~LibraryInfo();
 
     QList<QmlDirParser::Component> components() const
@@ -155,7 +161,10 @@ public:
     { _metaObjects = objects; }
 
     bool isValid() const
-    { return _valid; }
+    { return _status == Found; }
+
+    bool wasScanned() const
+    { return _status != NotScanned; }
 
     DumpStatus dumpStatus() const
     { return _dumpStatus; }
diff --git a/src/libs/qmljs/qmljslink.cpp b/src/libs/qmljs/qmljslink.cpp
index 8f20b447d22488268af525341c366f18d760e85f..c9c1bb8e92628079a8475f039c3d03f396bd2e74 100644
--- a/src/libs/qmljs/qmljslink.cpp
+++ b/src/libs/qmljs/qmljslink.cpp
@@ -43,8 +43,6 @@
 #include <QtCore/QDir>
 #include <QtCore/QDebug>
 
-#include <limits>
-
 using namespace LanguageUtils;
 using namespace QmlJS;
 using namespace QmlJS::Interpreter;
@@ -276,18 +274,37 @@ ObjectValue *Link::importNonFile(Document::Ptr doc, const ImportInfo &importInfo
 
     bool importFound = false;
 
-    // check the filesystem
     const QString &packagePath = importInfo.name();
+    // check the filesystem with full version
     foreach (const QString &importPath, d->importPaths) {
-        QString libraryPath = importPath;
-        libraryPath += QDir::separator();
-        libraryPath += packagePath;
+        QString libraryPath = QString("%1/%2.%3").arg(importPath, packagePath, version.toString());
 
         if (importLibrary(doc, import, libraryPath, importInfo, importPath)) {
             importFound = true;
             break;
         }
     }
+    if (!importFound) {
+        // check the filesystem with major version
+        foreach (const QString &importPath, d->importPaths) {
+            QString libraryPath = QString("%1/%2.%3").arg(importPath, packagePath,
+                                                          QString::number(version.majorVersion()));
+            if (importLibrary(doc, import, libraryPath, importInfo, importPath)) {
+                importFound = true;
+                break;
+            }
+        }
+    }
+    if (!importFound) {
+        // check the filesystem with no version
+        foreach (const QString &importPath, d->importPaths) {
+            QString libraryPath = QString("%1/%2").arg(importPath, packagePath);
+            if (importLibrary(doc, import, libraryPath, importInfo, importPath)) {
+                importFound = true;
+                break;
+            }
+        }
+    }
 
     // if there are cpp-based types for this package, use them too
     if (engine()->cppQmlTypes().hasPackage(packageName)) {
@@ -406,8 +423,7 @@ void Link::loadQmldirComponents(Interpreter::ObjectValue *import, ComponentVersi
 
     // if the version isn't valid, import the latest
     if (!version.isValid()) {
-        const int maxVersion = std::numeric_limits<int>::max();
-        version = ComponentVersion(maxVersion, maxVersion);
+        version = ComponentVersion(ComponentVersion::MaxVersion, ComponentVersion::MaxVersion);
     }
 
 
diff --git a/src/plugins/qmljstools/qmljsmodelmanager.cpp b/src/plugins/qmljstools/qmljsmodelmanager.cpp
index 08f943e055444de4ab26e48e9e1167493967b87a..5cb426e2c2e98f7ee1867fbcab36ddc926abbbbf 100644
--- a/src/plugins/qmljstools/qmljsmodelmanager.cpp
+++ b/src/plugins/qmljstools/qmljsmodelmanager.cpp
@@ -285,7 +285,9 @@ void ModelManager::updateLibraryInfo(const QString &path, const LibraryInfo &inf
         QMutexLocker locker(&m_mutex);
         _snapshot.insertLibraryInfo(path, info);
     }
-    emit libraryInfoUpdated(path, info);
+    // only emit if we got new useful information
+    if (info.isValid())
+        emit libraryInfoUpdated(path, info);
 }
 
 static QStringList qmlFilesInDirectory(const QString &path)
@@ -356,15 +358,22 @@ static bool findNewQmlLibraryInPath(const QString &path,
                                     QSet<QString> *newLibraries)
 {
     // if we know there is a library, done
-    if (snapshot.libraryInfo(path).isValid())
+    const LibraryInfo &existingInfo = snapshot.libraryInfo(path);
+    if (existingInfo.isValid())
         return true;
     if (newLibraries->contains(path))
         return true;
+    // if we looked at the path before, done
+    if (existingInfo.wasScanned())
+        return false;
 
     const QDir dir(path);
     QFile qmldirFile(dir.filePath(QLatin1String("qmldir")));
-    if (!qmldirFile.exists())
+    if (!qmldirFile.exists()) {
+        LibraryInfo libraryInfo(LibraryInfo::NotFound);
+        modelManager->updateLibraryInfo(path, libraryInfo);
         return false;
+    }
 
 #ifdef Q_OS_WIN
     // QTCREATORBUG-3402 - be case sensitive even here?
@@ -380,8 +389,7 @@ static bool findNewQmlLibraryInPath(const QString &path,
 
     const QString libraryPath = QFileInfo(qmldirFile).absolutePath();
     newLibraries->insert(libraryPath);
-    modelManager->updateLibraryInfo(libraryPath,
-                                    LibraryInfo(qmldirParser));
+    modelManager->updateLibraryInfo(libraryPath, LibraryInfo(qmldirParser));
 
     // scan the qml files in the library
     foreach (const QmlDirParser::Component &component, qmldirParser.components()) {
@@ -398,30 +406,62 @@ static bool findNewQmlLibraryInPath(const QString &path,
     return true;
 }
 
+static void findNewQmlLibrary(
+    const QString &path,
+    const LanguageUtils::ComponentVersion &version,
+    const Snapshot &snapshot,
+    ModelManager *modelManager,
+    QStringList *importedFiles,
+    QSet<QString> *scannedPaths,
+    QSet<QString> *newLibraries)
+{
+    QString libraryPath = QString("%1.%2.%3").arg(
+                path,
+                QString::number(version.majorVersion()),
+                QString::number(version.minorVersion()));
+    findNewQmlLibraryInPath(
+                libraryPath, snapshot, modelManager,
+                importedFiles, scannedPaths, newLibraries);
+
+    libraryPath = QString("%1.%2").arg(
+                path,
+                QString::number(version.majorVersion()));
+    findNewQmlLibraryInPath(
+                libraryPath, snapshot, modelManager,
+                importedFiles, scannedPaths, newLibraries);
+
+    findNewQmlLibraryInPath(
+                path, snapshot, modelManager,
+                importedFiles, scannedPaths, newLibraries);
+}
+
 static void findNewLibraryImports(const Document::Ptr &doc, const Snapshot &snapshot,
                            ModelManager *modelManager,
                            QStringList *importedFiles, QSet<QString> *scannedPaths, QSet<QString> *newLibraries)
 {
-    // scan library imports
+    // scan current dir
+    findNewQmlLibraryInPath(doc->path(), snapshot, modelManager,
+                            importedFiles, scannedPaths, newLibraries);
+
+    // scan dir and lib imports
     const QStringList importPaths = modelManager->importPaths();
     foreach (const Interpreter::ImportInfo &import, doc->bind()->imports()) {
+        if (import.type() == Interpreter::ImportInfo::DirectoryImport) {
+            const QString targetPath = import.name();
+            findNewQmlLibraryInPath(targetPath, snapshot, modelManager,
+                                    importedFiles, scannedPaths, newLibraries);
+        }
+
         if (import.type() == Interpreter::ImportInfo::LibraryImport) {
+            if (!import.version().isValid())
+                continue;
             foreach (const QString &importPath, importPaths) {
                 const QString targetPath = QDir(importPath).filePath(import.name());
-
-                if (findNewQmlLibraryInPath(targetPath, snapshot, modelManager,
-                                            importedFiles, scannedPaths, newLibraries))
-                    break;
+                findNewQmlLibrary(targetPath, import.version(), snapshot, modelManager,
+                                  importedFiles, scannedPaths, newLibraries);
             }
-        } else if (import.type() == Interpreter::ImportInfo::DirectoryImport) {
-            const QString targetPath = import.name();
-            findNewQmlLibraryInPath(targetPath, snapshot, modelManager,
-                                    importedFiles, scannedPaths, newLibraries);
         }
     }
-
-    findNewQmlLibraryInPath(doc->path(), snapshot, modelManager,
-                            importedFiles, scannedPaths, newLibraries);
 }
 
 static bool suffixMatches(const QString &fileName, const Core::MimeType &mimeType)
@@ -451,8 +491,6 @@ void ModelManager::parse(QFutureInterface<void> &future,
     int progressRange = files.size();
     future.setProgressRange(0, progressRange);
 
-    Snapshot snapshot = modelManager->_snapshot;
-
     // paths we have scanned for files and added to the files list
     QSet<QString> scannedPaths;
     // libraries we've found while scanning imports
@@ -499,6 +537,10 @@ void ModelManager::parse(QFutureInterface<void> &future,
         doc->setSource(contents);
         doc->parse();
 
+        // update snapshot. requires synchronization, but significantly reduces amount of file
+        // system queries for library imports because queries are cached in libraryInfo
+        const Snapshot snapshot = modelManager->snapshot();
+
         // get list of referenced files not yet in snapshot or in directories already scanned
         QStringList importedFiles;
         findNewImplicitImports(doc, snapshot, &importedFiles, &scannedPaths);