/****************************************************************************
**
** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** This file is part of the QtDeclarative module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
** 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.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU General
** Public License version 3.0 as published by the Free Software Foundation
** and appearing in the file LICENSE.GPL included in the packaging of this
** file. Please review the following information to ensure the GNU General
** Public License version 3.0 requirements will be met:
** http://www.gnu.org/copyleft/gpl.html.
**
** Other Usage
** Alternatively, this file may be used in accordance with the terms and
** conditions contained in a signed written agreement between you and Nokia.
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include "qdeclarativeimport_p.h"

#include <QtCore/qdebug.h>
#include <QtCore/qdir.h>
#include <QtCore/qfileinfo.h>
#include <QtCore/qpluginloader.h>
#include <QtCore/qlibraryinfo.h>
#include <QtDeclarative/qdeclarativeextensioninterface.h>
#include <private/qdeclarativeglobal_p.h>
#include <private/qdeclarativetypenamecache_p.h>
#include <private/qdeclarativeengine_p.h>

#ifdef Q_OS_SYMBIAN
#include "private/qcore_symbian_p.h"
#endif

QT_BEGIN_NAMESPACE

DEFINE_BOOL_CONFIG_OPTION(qmlImportTrace, QML_IMPORT_TRACE)
DEFINE_BOOL_CONFIG_OPTION(qmlCheckTypes, QML_CHECK_TYPES)

static bool greaterThan(const QString &s1, const QString &s2)
{
    return s1 > s2;
}

typedef QMap<QString, QString> StringStringMap;
Q_GLOBAL_STATIC(StringStringMap, qmlEnginePluginsWithRegisteredTypes); // stores the uri

class QDeclarativeImportedNamespace 
{
public:
    QStringList uris;
    QStringList urls;
    QList<int> majversions;
    QList<int> minversions;
    QList<bool> isLibrary;
    QList<QDeclarativeDirComponents> qmlDirComponents;


    bool find_helper(int i, const QByteArray& type, int *vmajor, int *vminor,
                                 QDeclarativeType** type_return, QUrl* url_return,
                                 QUrl *base = 0, bool *typeRecursionDetected = 0);
    bool find(const QByteArray& type, int *vmajor, int *vminor, QDeclarativeType** type_return,
              QUrl* url_return, QUrl *base = 0, QString *errorString = 0);
};

class QDeclarativeImportsPrivate {
public:
    QDeclarativeImportsPrivate();
    ~QDeclarativeImportsPrivate();

    bool importExtension(const QString &absoluteFilePath, const QString &uri, 
                         QDeclarativeImportDatabase *database, QDeclarativeDirComponents* components, 
                         QString *errorString);

    QString resolvedUri(const QString &dir_arg, QDeclarativeImportDatabase *database);
    bool add(const QDeclarativeDirComponents &qmldircomponentsnetwork, 
             const QString& uri_arg, const QString& prefix, 
             int vmaj, int vmin, QDeclarativeScriptParser::Import::Type importType, 
             QDeclarativeImportDatabase *database, QString *errorString);
    bool find(const QByteArray& type, int *vmajor, int *vminor, 
              QDeclarativeType** type_return, QUrl* url_return, QString *errorString);

    QDeclarativeImportedNamespace *findNamespace(const QString& type);

    QUrl base;
    int ref;

    QSet<QString> qmlDirFilesForWhichPluginsHaveBeenLoaded;
    QDeclarativeImportedNamespace unqualifiedset;
    QHash<QString,QDeclarativeImportedNamespace* > set;
};

/*!
\class QDeclarativeImports
\brief The QDeclarativeImports class encapsulates one QML document's import statements.
\internal
*/
QDeclarativeImports::QDeclarativeImports(const QDeclarativeImports &copy) 
: d(copy.d)
{
    ++d->ref;
}

QDeclarativeImports &
QDeclarativeImports::operator =(const QDeclarativeImports &copy)
{
    ++copy.d->ref;
    if (--d->ref == 0)
        delete d;
    d = copy.d;
    return *this;
}

QDeclarativeImports::QDeclarativeImports() 
: d(new QDeclarativeImportsPrivate)
{
}

QDeclarativeImports::~QDeclarativeImports()
{
    if (--d->ref == 0)
        delete d;
}

/*!
  Sets the base URL to be used for all relative file imports added.
*/
void QDeclarativeImports::setBaseUrl(const QUrl& url)
{
    d->base = url;
}

/*!
  Returns the base URL to be used for all relative file imports added.
*/
QUrl QDeclarativeImports::baseUrl() const
{
    return d->base;
}

static QDeclarativeTypeNameCache *
cacheForNamespace(QDeclarativeEngine *engine, const QDeclarativeImportedNamespace &set, 
                  QDeclarativeTypeNameCache *cache)
{
    if (!cache)
        cache = new QDeclarativeTypeNameCache(engine);

    QList<QDeclarativeType *> types = QDeclarativeMetaType::qmlTypes();

    for (int ii = 0; ii < set.uris.count(); ++ii) {
        QByteArray base = set.uris.at(ii).toUtf8() + '/';
        int major = set.majversions.at(ii);
        int minor = set.minversions.at(ii);

        foreach (QDeclarativeType *type, types) {
            if (type->qmlTypeName().startsWith(base) &&
                type->qmlTypeName().lastIndexOf('/') == (base.length() - 1) &&
                type->availableInVersion(major,minor))
            {
                QString name = QString::fromUtf8(type->qmlTypeName().mid(base.length()));

                cache->add(name, type);
            }
        }
    }

    return cache;
}

void QDeclarativeImports::populateCache(QDeclarativeTypeNameCache *cache, QDeclarativeEngine *engine) const
{
    const QDeclarativeImportedNamespace &set = d->unqualifiedset;

    for (QHash<QString,QDeclarativeImportedNamespace* >::ConstIterator iter = d->set.begin();
         iter != d->set.end(); ++iter) {

        QDeclarativeTypeNameCache::Data *d = cache->data(iter.key());
        if (d) {
            if (!d->typeNamespace)
                cacheForNamespace(engine, *(*iter), d->typeNamespace);
        } else {
            QDeclarativeTypeNameCache *nc = cacheForNamespace(engine, *(*iter), 0);
            cache->add(iter.key(), nc);
            nc->release();
        }
    }

    cacheForNamespace(engine, set, cache);
}

/*!
  \internal

  The given (namespace qualified) \a type is resolved to either
  \list
  \o a QDeclarativeImportedNamespace stored at \a ns_return,
  \o a QDeclarativeType stored at \a type_return, or
  \o a component located at \a url_return.
  \endlist

  If any return pointer is 0, the corresponding search is not done.

  \sa addImport()
*/
bool QDeclarativeImports::resolveType(const QByteArray& type, 
                                      QDeclarativeType** type_return, QUrl* url_return, int *vmaj, int *vmin,
                                      QDeclarativeImportedNamespace** ns_return, QString *errorString) const
{
    QDeclarativeImportedNamespace* ns = d->findNamespace(QString::fromUtf8(type));
    if (ns) {
        if (ns_return)
            *ns_return = ns;
        return true;
    }
    if (type_return || url_return) {
        if (d->find(type,vmaj,vmin,type_return,url_return, errorString)) {
            if (qmlImportTrace()) {
                if (type_return && *type_return && url_return && !url_return->isEmpty())
                    qDebug().nospace() << "QDeclarativeImports(" << qPrintable(baseUrl().toString()) << ")" << "::resolveType: " 
                                       << type << " => " << (*type_return)->typeName() << " " << *url_return;
                if (type_return && *type_return)
                    qDebug().nospace() << "QDeclarativeImports(" << qPrintable(baseUrl().toString()) << ")" << "::resolveType: " 
                                       << type << " => " << (*type_return)->typeName();
                if (url_return && !url_return->isEmpty())
                    qDebug().nospace() << "QDeclarativeImports(" << qPrintable(baseUrl().toString()) << ")" << "::resolveType: " 
                                       << type << " => " << *url_return;
            }
            return true;
        }
    }
    return false;
}

/*!
  \internal

  Searching \e only in the namespace \a ns (previously returned in a call to
  resolveType(), \a type is found and returned to either
  a QDeclarativeType stored at \a type_return, or
  a component located at \a url_return.

  If either return pointer is 0, the corresponding search is not done.
*/
bool QDeclarativeImports::resolveType(QDeclarativeImportedNamespace* ns, const QByteArray& type, 
                                      QDeclarativeType** type_return, QUrl* url_return, 
                                      int *vmaj, int *vmin) const
{
    return ns->find(type,vmaj,vmin,type_return,url_return);
}

bool QDeclarativeImportedNamespace::find_helper(int i, const QByteArray& type, int *vmajor, int *vminor,
                                 QDeclarativeType** type_return, QUrl* url_return,
                                 QUrl *base, bool *typeRecursionDetected)
{
    int vmaj = majversions.at(i);
    int vmin = minversions.at(i);

    QByteArray qt = uris.at(i).toUtf8();
    qt += '/';
    qt += type;

    QDeclarativeType *t = QDeclarativeMetaType::qmlType(qt,vmaj,vmin);
    if (t) {
        if (vmajor) *vmajor = vmaj;
        if (vminor) *vminor = vmin;
        if (type_return)
            *type_return = t;
        return true;
    }

    QUrl url = QUrl(urls.at(i) + QLatin1Char('/') + QString::fromUtf8(type) + QLatin1String(".qml"));
    QDeclarativeDirComponents qmldircomponents = qmlDirComponents.at(i);

    bool typeWasDeclaredInQmldir = false;
    if (!qmldircomponents.isEmpty()) {
        const QString typeName = QString::fromUtf8(type);
        foreach (const QDeclarativeDirParser::Component &c, qmldircomponents) {
            if (c.typeName == typeName) {
                typeWasDeclaredInQmldir = true;

                // importing version -1 means import ALL versions
                if ((vmaj == -1) || (c.majorVersion < vmaj || (c.majorVersion == vmaj && vmin >= c.minorVersion))) {
                    QUrl candidate = url.resolved(QUrl(c.fileName));
                    if (c.internal && base) {
                        if (base->resolved(QUrl(c.fileName)) != candidate)
                            continue; // failed attempt to access an internal type
                    }
                    if (base && *base == candidate) {
                        if (typeRecursionDetected)
                            *typeRecursionDetected = true;
                        continue; // no recursion
                    }
                    if (url_return)
                        *url_return = candidate;
                    return true;
                }
            }
        }
    }

    if (!typeWasDeclaredInQmldir  && !isLibrary.at(i)) {
        // XXX search non-files too! (eg. zip files, see QT-524)
        QFileInfo f(QDeclarativeEnginePrivate::urlToLocalFileOrQrc(url));
        if (f.exists()) {
            if (base && *base == url) { // no recursion
                if (typeRecursionDetected)
                    *typeRecursionDetected = true;
            } else {
                if (url_return)
                    *url_return = url;
                return true;
            }
        }
    }
    return false;
}

QDeclarativeImportsPrivate::QDeclarativeImportsPrivate() 
: ref(1)
{
}

QDeclarativeImportsPrivate::~QDeclarativeImportsPrivate()
{
    foreach (QDeclarativeImportedNamespace* s, set.values())
        delete s;
}

bool QDeclarativeImportsPrivate::importExtension(const QString &absoluteFilePath, const QString &uri, 
                                                 QDeclarativeImportDatabase *database, 
                                                 QDeclarativeDirComponents* components, QString *errorString) 
{
    QFile file(absoluteFilePath);
    QString filecontent;
    if (!QDeclarative_isFileCaseCorrect(absoluteFilePath)) {
        if (errorString)
            *errorString = QDeclarativeImportDatabase::tr("cannot load module \"%1\": File name case mismatch for \"%2\"").arg(uri).arg(absoluteFilePath);
        return false;
    } else if (file.open(QFile::ReadOnly)) {
        filecontent = QString::fromUtf8(file.readAll());
        if (qmlImportTrace())
            qDebug().nospace() << "QDeclarativeImports(" << qPrintable(base.toString()) << "::importExtension: "
                               << "loaded " << absoluteFilePath;
    } else {
        if (errorString)
            *errorString = QDeclarativeImportDatabase::tr("module \"%1\" definition \"%2\" not readable").arg(uri).arg(absoluteFilePath);
        return false;
    }
    QDir dir = QFileInfo(file).dir();

    QDeclarativeDirParser qmldirParser;
    qmldirParser.setSource(filecontent);
    qmldirParser.parse();

    if (! qmlDirFilesForWhichPluginsHaveBeenLoaded.contains(absoluteFilePath)) {
        qmlDirFilesForWhichPluginsHaveBeenLoaded.insert(absoluteFilePath);


        foreach (const QDeclarativeDirParser::Plugin &plugin, qmldirParser.plugins()) {

            QString resolvedFilePath = database->resolvePlugin(dir, plugin.path, plugin.name);
#if defined(QT_LIBINFIX) && defined(Q_OS_SYMBIAN)
            if (resolvedFilePath.isEmpty()) {
                // In case of libinfixed build, attempt to load libinfixed version, too.
                QString infixedPluginName = plugin.name + QLatin1String(QT_LIBINFIX);
                resolvedFilePath = database->resolvePlugin(dir, plugin.path, infixedPluginName);
            }
#endif
            if (!resolvedFilePath.isEmpty()) {
                if (!database->importPlugin(resolvedFilePath, uri, errorString)) {
                    if (errorString)
                        *errorString = QDeclarativeImportDatabase::tr("plugin cannot be loaded for module \"%1\": %2").arg(uri).arg(*errorString);
                    return false;
                }
            } else {
                if (errorString)
                    *errorString = QDeclarativeImportDatabase::tr("module \"%1\" plugin \"%2\" not found").arg(uri).arg(plugin.name);
                return false;
            }
        }
    }

    if (components)
        *components = qmldirParser.components();

    return true;
}

QString QDeclarativeImportsPrivate::resolvedUri(const QString &dir_arg, QDeclarativeImportDatabase *database)
{
    QString dir = dir_arg;
    if (dir.endsWith(QLatin1Char('/')) || dir.endsWith(QLatin1Char('\\')))
        dir.chop(1);

    QStringList paths = database->fileImportPath;
    qSort(paths.begin(), paths.end(), greaterThan); // Ensure subdirs preceed their parents.

    QString stableRelativePath = dir;
    foreach(const QString &path, paths) {
        if (dir.startsWith(path)) {
            stableRelativePath = dir.mid(path.length()+1);
            break;
        }
    }

    stableRelativePath.replace(QLatin1Char('\\'), QLatin1Char('/'));

    // remove optional versioning in dot notation from uri
    int lastSlash = stableRelativePath.lastIndexOf(QLatin1Char('/'));
    if (lastSlash >= 0) {
        int versionDot = stableRelativePath.indexOf(QLatin1Char('.'), lastSlash);
        if (versionDot >= 0)
            stableRelativePath = stableRelativePath.left(versionDot);
    }

    stableRelativePath.replace(QLatin1Char('/'), QLatin1Char('.'));
    return stableRelativePath;
}

bool QDeclarativeImportsPrivate::add(const QDeclarativeDirComponents &qmldircomponentsnetwork, 
                                     const QString& uri_arg, const QString& prefix, int vmaj, int vmin, 
                                     QDeclarativeScriptParser::Import::Type importType, 
                                     QDeclarativeImportDatabase *database, QString *errorString)
{
    QDeclarativeDirComponents qmldircomponents = qmldircomponentsnetwork;
    QString uri = uri_arg;
    QDeclarativeImportedNamespace *s;
    if (prefix.isEmpty()) {
        s = &unqualifiedset;
    } else {
        s = set.value(prefix);
        if (!s)
            set.insert(prefix,(s=new QDeclarativeImportedNamespace));
    }

    QString url = uri;
    bool versionFound = false;
    if (importType == QDeclarativeScriptParser::Import::Library) {
        url.replace(QLatin1Char('.'), QLatin1Char('/'));
        bool found = false;
        QString dir;


        // step 1: search for extension with fully encoded version number
        if (vmaj >= 0 && vmin >= 0) {
            foreach (const QString &p, database->fileImportPath) {
                dir = p+QLatin1Char('/')+url;

                QFileInfo fi(dir+QString(QLatin1String(".%1.%2")).arg(vmaj).arg(vmin)+QLatin1String("/qmldir"));
                const QString absoluteFilePath = fi.absoluteFilePath();

                if (fi.isFile()) {
                    found = true;

                    url = QUrl::fromLocalFile(fi.absolutePath()).toString();
                    uri = resolvedUri(dir, database);
                    if (!importExtension(absoluteFilePath, uri, database, &qmldircomponents, errorString))
                        return false;
                    break;
                }
            }
        }
        // step 2: search for extension with encoded version major
        if (vmaj >= 0 && vmin >= 0) {
            foreach (const QString &p, database->fileImportPath) {
                dir = p+QLatin1Char('/')+url;

                QFileInfo fi(dir+QString(QLatin1String(".%1")).arg(vmaj)+QLatin1String("/qmldir"));
                const QString absoluteFilePath = fi.absoluteFilePath();

                if (fi.isFile()) {
                    found = true;

                    url = QUrl::fromLocalFile(fi.absolutePath()).toString();
                    uri = resolvedUri(dir, database);
                    if (!importExtension(absoluteFilePath, uri, database, &qmldircomponents, errorString))
                        return false;
                    break;
                }
            }
        }
        if (!found) {
            // step 3: search for extension without version number

            foreach (const QString &p, database->fileImportPath) {
                dir = p+QLatin1Char('/')+url;

                QFileInfo fi(dir+QLatin1String("/qmldir"));
                const QString absoluteFilePath = fi.absoluteFilePath();

                if (fi.isFile()) {
                    found = true;

                    url = QUrl::fromLocalFile(fi.absolutePath()).toString();
                    uri = resolvedUri(dir, database);
                    if (!importExtension(absoluteFilePath, uri, database, &qmldircomponents, errorString))
                        return false;
                    break;
                }
            }
        }

        if (QDeclarativeMetaType::isModule(uri.toUtf8(), vmaj, vmin))
            versionFound = true;

        if (!versionFound && qmldircomponents.isEmpty()) {
            if (errorString) {
                bool anyversion = QDeclarativeMetaType::isModule(uri.toUtf8(), -1, -1);
                if (anyversion)
                    *errorString = QDeclarativeImportDatabase::tr("module \"%1\" version %2.%3 is not installed").arg(uri_arg).arg(vmaj).arg(vmin);
                else
                    *errorString = QDeclarativeImportDatabase::tr("module \"%1\" is not installed").arg(uri_arg);
            }
            return false;
        }
    } else {

        if (importType == QDeclarativeScriptParser::Import::File && qmldircomponents.isEmpty()) {
            QUrl importUrl = base.resolved(QUrl(uri + QLatin1String("/qmldir")));
            QString localFileOrQrc = QDeclarativeEnginePrivate::urlToLocalFileOrQrc(importUrl);
            if (!localFileOrQrc.isEmpty()) {
                QString dir = QDeclarativeEnginePrivate::urlToLocalFileOrQrc(base.resolved(QUrl(uri)));
                QFileInfo dirinfo(dir);
                if (dir.isEmpty() || !dirinfo.exists() || !dirinfo.isDir()) {
                    if (errorString)
                        *errorString = QDeclarativeImportDatabase::tr("\"%1\": no such directory").arg(uri_arg);
                    return false; // local import dirs must exist
                }
                uri = resolvedUri(QDeclarativeEnginePrivate::urlToLocalFileOrQrc(base.resolved(QUrl(uri))), database);
                if (uri.endsWith(QLatin1Char('/')))
                    uri.chop(1);
                if (QFile::exists(localFileOrQrc)) {
                    if (!importExtension(localFileOrQrc,uri,database,&qmldircomponents,errorString))
                        return false;
                }
            } else {
                if (prefix.isEmpty()) {
                    // directory must at least exist for valid import
                    QString localFileOrQrc = QDeclarativeEnginePrivate::urlToLocalFileOrQrc(base.resolved(QUrl(uri)));
                    QFileInfo dirinfo(localFileOrQrc);
                    if (localFileOrQrc.isEmpty() || !dirinfo.exists() || !dirinfo.isDir()) {
                        if (errorString) {
                            if (localFileOrQrc.isEmpty())
                                *errorString = QDeclarativeImportDatabase::tr("import \"%1\" has no qmldir and no namespace").arg(uri);
                            else
                                *errorString = QDeclarativeImportDatabase::tr("\"%1\": no such directory").arg(uri);
                        }
                        return false;
                    }
                }
            }
        }

        url = base.resolved(QUrl(url)).toString();
        if (url.endsWith(QLatin1Char('/')))
            url.chop(1);
    }

    if (!versionFound && vmaj > -1 && vmin > -1 && !qmldircomponents.isEmpty()) {
        QList<QDeclarativeDirParser::Component>::ConstIterator it = qmldircomponents.begin();
        int lowest_maj = INT_MAX;
        int lowest_min = INT_MAX;
        int highest_maj = INT_MIN;
        int highest_min = INT_MIN;
        for (; it != qmldircomponents.end(); ++it) {
            if (it->majorVersion > highest_maj || (it->majorVersion == highest_maj && it->minorVersion > highest_min)) {
                highest_maj = it->majorVersion;
                highest_min = it->minorVersion;
            }
            if (it->majorVersion < lowest_maj || (it->majorVersion == lowest_maj && it->minorVersion < lowest_min)) {
                lowest_maj = it->majorVersion;
                lowest_min = it->minorVersion;
            }
        }
        if (lowest_maj > vmaj || (lowest_maj == vmaj && lowest_min > vmin)
            || highest_maj < vmaj || (highest_maj == vmaj && highest_min < vmin))
        {
            *errorString = QDeclarativeImportDatabase::tr("module \"%1\" version %2.%3 is not installed").arg(uri_arg).arg(vmaj).arg(vmin);
            return false;
        }
    }

    s->uris.prepend(uri);
    s->urls.prepend(url);
    s->majversions.prepend(vmaj);
    s->minversions.prepend(vmin);
    s->isLibrary.prepend(importType == QDeclarativeScriptParser::Import::Library);
    s->qmlDirComponents.prepend(qmldircomponents);
    return true;
}

bool QDeclarativeImportsPrivate::find(const QByteArray& type, int *vmajor, int *vminor, QDeclarativeType** type_return,
                                      QUrl* url_return, QString *errorString)
{
    QDeclarativeImportedNamespace *s = 0;
    int slash = type.indexOf('/');
    if (slash >= 0) {
        QString namespaceName = QString::fromUtf8(type.left(slash));
        s = set.value(namespaceName);
        if (!s) {
            if (errorString)
                *errorString = QDeclarativeImportDatabase::tr("- %1 is not a namespace").arg(namespaceName);
            return false;
        }
        int nslash = type.indexOf('/',slash+1);
        if (nslash > 0) {
            if (errorString)
                *errorString = QDeclarativeImportDatabase::tr("- nested namespaces not allowed");
            return false;
        }
    } else {
        s = &unqualifiedset;
    }
    QByteArray unqualifiedtype = slash < 0 ? type : type.mid(slash+1); // common-case opt (QString::mid works fine, but slower)
    if (s) {
        if (s->find(unqualifiedtype,vmajor,vminor,type_return,url_return, &base, errorString))
            return true;
        if (s->urls.count() == 1 && !s->isLibrary[0] && url_return && s != &unqualifiedset) {
            // qualified, and only 1 url
            *url_return = QUrl(s->urls[0]+QLatin1Char('/')).resolved(QUrl(QString::fromUtf8(unqualifiedtype) + QLatin1String(".qml")));
            return true;
        }
    }

    return false;
}

QDeclarativeImportedNamespace *QDeclarativeImportsPrivate::findNamespace(const QString& type)
{
    return set.value(type);
}

bool QDeclarativeImportedNamespace::find(const QByteArray& type, int *vmajor, int *vminor, QDeclarativeType** type_return,
          QUrl* url_return, QUrl *base, QString *errorString)
{
    bool typeRecursionDetected = false;
    for (int i=0; i<urls.count(); ++i) {
        if (find_helper(i, type, vmajor, vminor, type_return, url_return, base, &typeRecursionDetected)) {
            if (qmlCheckTypes()) {
                // check for type clashes
                for (int j = i+1; j<urls.count(); ++j) {
                    if (find_helper(j, type, vmajor, vminor, 0, 0, base)) {
                        if (errorString) {
                            QString u1 = urls.at(i);
                            QString u2 = urls.at(j);
                            if (base) {
                                QString b = base->toString();
                                int slash = b.lastIndexOf(QLatin1Char('/'));
                                if (slash >= 0) {
                                    b = b.left(slash+1);
                                    QString l = b.left(slash);
                                    if (u1.startsWith(b))
                                        u1 = u1.mid(b.count());
                                    else if (u1 == l)
                                        u1 = QDeclarativeImportDatabase::tr("local directory");
                                    if (u2.startsWith(b))
                                        u2 = u2.mid(b.count());
                                    else if (u2 == l)
                                        u2 = QDeclarativeImportDatabase::tr("local directory");
                                }
                            }

                            if (u1 != u2)
                                *errorString
                                        = QDeclarativeImportDatabase::tr("is ambiguous. Found in %1 and in %2")
                                .arg(u1).arg(u2);
                            else
                                *errorString
                                        = QDeclarativeImportDatabase::tr("is ambiguous. Found in %1 in version %2.%3 and %4.%5")
                                          .arg(u1)
                                          .arg(majversions.at(i)).arg(minversions.at(i))
                                          .arg(majversions.at(j)).arg(minversions.at(j));
                        }
                        return false;
                    }
                }
            }
            return true;
        }
    }
    if (errorString) {
        if (typeRecursionDetected)
            *errorString = QDeclarativeImportDatabase::tr("is instantiated recursively");
        else
            *errorString = QDeclarativeImportDatabase::tr("is not a type");
    }
    return false;
}

/*!
\class QDeclarativeImportDatabase
\brief The QDeclarativeImportDatabase class manages the QML imports for a QDeclarativeEngine.
\internal
*/
QDeclarativeImportDatabase::QDeclarativeImportDatabase(QDeclarativeEngine *e)
: engine(e)
{
    filePluginPath << QLatin1String(".");

    // Search order is applicationDirPath(), $QML_IMPORT_PATH, QLibraryInfo::ImportsPath

    QString installImportsPath =  QLibraryInfo::location(QLibraryInfo::ImportsPath);

#if defined(Q_OS_SYMBIAN)
    // Append imports path for all available drives in Symbian
    if (installImportsPath.at(1) != QChar(QLatin1Char(':'))) {
        QString tempPath = installImportsPath;
        if (tempPath.at(tempPath.length() - 1) != QDir::separator()) {
            tempPath += QDir::separator();
        }
        RFs& fs = qt_s60GetRFs();
        TPtrC tempPathPtr(reinterpret_cast<const TText*> (tempPath.constData()));
        TFindFile finder(fs);
        TInt err = finder.FindByDir(tempPathPtr, tempPathPtr);
        while (err == KErrNone) {
            QString foundDir(reinterpret_cast<const QChar *>(finder.File().Ptr()),
                             finder.File().Length());
            foundDir = QDir(foundDir).canonicalPath();
            addImportPath(foundDir);
            err = finder.Find();
        }
    } else {
        addImportPath(installImportsPath);
    }
#else
    addImportPath(installImportsPath);
#endif
    // env import paths
    QByteArray envImportPath = qgetenv("QML_IMPORT_PATH");
    if (!envImportPath.isEmpty()) {
#if defined(Q_OS_WIN) || defined(Q_OS_SYMBIAN)
        QLatin1Char pathSep(';');
#else
        QLatin1Char pathSep(':');
#endif
        QStringList paths = QString::fromLatin1(envImportPath).split(pathSep, QString::SkipEmptyParts);
        for (int ii = paths.count() - 1; ii >= 0; --ii)
            addImportPath(paths.at(ii));
    }

    addImportPath(QCoreApplication::applicationDirPath());
}

QDeclarativeImportDatabase::~QDeclarativeImportDatabase()
{
}

/*!
  \internal

  Adds information to \a imports such that subsequent calls to resolveType()
  will resolve types qualified by \a prefix by considering types found at the given \a uri.

  The uri is either a directory (if importType is FileImport), or a URI resolved using paths
  added via addImportPath() (if importType is LibraryImport).

  The \a prefix may be empty, in which case the import location is considered for
  unqualified types.

  The base URL must already have been set with Import::setBaseUrl().
*/
bool QDeclarativeImports::addImport(QDeclarativeImportDatabase *importDb, 
                                    const QString& uri, const QString& prefix, int vmaj, int vmin, 
                                    QDeclarativeScriptParser::Import::Type importType, 
                                    const QDeclarativeDirComponents &qmldircomponentsnetwork, 
                                    QString *errorString) 
{
    if (qmlImportTrace())
        qDebug().nospace() << "QDeclarativeImports(" << qPrintable(baseUrl().toString()) << ")" << "::addImport: " 
                           << uri << " " << vmaj << '.' << vmin << " " 
                           << (importType==QDeclarativeScriptParser::Import::Library? "Library" : "File") 
                           << " as " << prefix;

    return d->add(qmldircomponentsnetwork, uri, prefix, vmaj, vmin, importType, importDb, errorString);
}

/*!
  \internal

  Returns the result of the merge of \a baseName with \a path, \a suffixes, and \a prefix.
  The \a prefix must contain the dot.

  \a qmldirPath is the location of the qmldir file.
 */
QString QDeclarativeImportDatabase::resolvePlugin(const QDir &qmldirPath, const QString &qmldirPluginPath, 
                                                  const QString &baseName, const QStringList &suffixes,
                                                  const QString &prefix)
{
    QStringList searchPaths = filePluginPath;
    bool qmldirPluginPathIsRelative = QDir::isRelativePath(qmldirPluginPath);
    if (!qmldirPluginPathIsRelative)
        searchPaths.prepend(qmldirPluginPath);

    foreach (const QString &pluginPath, searchPaths) {

        QString resolvedPath;

        if (pluginPath == QLatin1String(".")) {
            if (qmldirPluginPathIsRelative)
                resolvedPath = qmldirPath.absoluteFilePath(qmldirPluginPath);
            else
                resolvedPath = qmldirPath.absolutePath();
        } else {
            resolvedPath = pluginPath;
        }

        // hack for resources, should probably go away
        if (resolvedPath.startsWith(QLatin1Char(':')))
            resolvedPath = QCoreApplication::applicationDirPath();

        QDir dir(resolvedPath);
        foreach (const QString &suffix, suffixes) {
            QString pluginFileName = prefix;

            pluginFileName += baseName;
            pluginFileName += suffix;

            QFileInfo fileInfo(dir, pluginFileName);

            if (fileInfo.exists())
                return fileInfo.absoluteFilePath();
        }
    }

    if (qmlImportTrace())
        qDebug() << "QDeclarativeImportDatabase::resolvePlugin: Could not resolve plugin" << baseName 
                 << "in" << qmldirPath.absolutePath();

    return QString();
}

/*!
  \internal

  Returns the result of the merge of \a baseName with \a dir and the platform suffix.

  \table
  \header \i Platform \i Valid suffixes
  \row \i Windows     \i \c .dll
  \row \i Unix/Linux  \i \c .so
  \row \i AIX  \i \c .a
  \row \i HP-UX       \i \c .sl, \c .so (HP-UXi)
  \row \i Mac OS X    \i \c .dylib, \c .bundle, \c .so
  \row \i Symbian     \i \c .dll
  \endtable

  Version number on unix are ignored.
*/
QString QDeclarativeImportDatabase::resolvePlugin(const QDir &qmldirPath, const QString &qmldirPluginPath, 
                                                  const QString &baseName)
{
#if defined(Q_OS_WIN32) || defined(Q_OS_WINCE)
    return resolvePlugin(qmldirPath, qmldirPluginPath, baseName,
                         QStringList()
# ifdef QT_DEBUG
                         << QLatin1String("d.dll") // try a qmake-style debug build first
# endif
                         << QLatin1String(".dll"));
#elif defined(Q_OS_SYMBIAN)
    return resolvePlugin(qmldirPath, qmldirPluginPath, baseName,
                         QStringList()
                         << QLatin1String(".dll")
                         << QLatin1String(".qtplugin"));
#else

# if defined(Q_OS_DARWIN)

    return resolvePlugin(qmldirPath, qmldirPluginPath, baseName,
                         QStringList()
# ifdef QT_DEBUG
                         << QLatin1String("_debug.dylib") // try a qmake-style debug build first
                         << QLatin1String(".dylib")
# else
                         << QLatin1String(".dylib")
                         << QLatin1String("_debug.dylib") // try a qmake-style debug build after
# endif
                         << QLatin1String(".so")
                         << QLatin1String(".bundle"),
                         QLatin1String("lib"));
# else  // Generic Unix
    QStringList validSuffixList;

#  if defined(Q_OS_HPUX)
/*
    See "HP-UX Linker and Libraries User's Guide", section "Link-time Differences between PA-RISC and IPF":
    "In PA-RISC (PA-32 and PA-64) shared libraries are suffixed with .sl. In IPF (32-bit and 64-bit),
    the shared libraries are suffixed with .so. For compatibility, the IPF linker also supports the .sl suffix."
 */
    validSuffixList << QLatin1String(".sl");
#   if defined __ia64
    validSuffixList << QLatin1String(".so");
#   endif
#  elif defined(Q_OS_AIX)
    validSuffixList << QLatin1String(".a") << QLatin1String(".so");
#  elif defined(Q_OS_UNIX)
    validSuffixList << QLatin1String(".so");
#  endif

    // Examples of valid library names:
    //  libfoo.so

    return resolvePlugin(qmldirPath, qmldirPluginPath, baseName, validSuffixList, QLatin1String("lib"));
# endif

#endif
}

/*!
    \internal
*/
QStringList QDeclarativeImportDatabase::pluginPathList() const
{
    return filePluginPath;
}

/*!
    \internal
*/
void QDeclarativeImportDatabase::setPluginPathList(const QStringList &paths)
{
    filePluginPath = paths;
}

/*!
    \internal
*/
void QDeclarativeImportDatabase::addPluginPath(const QString& path)
{
    if (qmlImportTrace())
        qDebug().nospace() << "QDeclarativeImportDatabase::addPluginPath: " << path;

    QUrl url = QUrl(path);
    if (url.isRelative() || url.scheme() == QLatin1String("file")
            || (url.scheme().length() == 1 && QFile::exists(path)) ) {  // windows path
        QDir dir = QDir(path);
        filePluginPath.prepend(dir.canonicalPath());
    } else {
        filePluginPath.prepend(path);
    }
}

/*!
    \internal
*/
void QDeclarativeImportDatabase::addImportPath(const QString& path)
{
    if (qmlImportTrace())
        qDebug().nospace() << "QDeclarativeImportDatabase::addImportPath: " << path;

    if (path.isEmpty())
        return;

    QUrl url = QUrl(path);
    QString cPath;

    if (url.isRelative() || url.scheme() == QLatin1String("file")
            || (url.scheme().length() == 1 && QFile::exists(path)) ) {  // windows path
        QDir dir = QDir(path);
        cPath = dir.canonicalPath();
    } else {
        cPath = path;
        cPath.replace(QLatin1Char('\\'), QLatin1Char('/'));
    }

    if (!cPath.isEmpty()
        && !fileImportPath.contains(cPath))
        fileImportPath.prepend(cPath);
}

/*!
    \internal
*/
QStringList QDeclarativeImportDatabase::importPathList() const
{
    return fileImportPath;
}

/*!
    \internal
*/
void QDeclarativeImportDatabase::setImportPathList(const QStringList &paths)
{
    fileImportPath = paths;
}

/*!
    \internal
*/
bool QDeclarativeImportDatabase::importPlugin(const QString &filePath, const QString &uri, QString *errorString)
{
    if (qmlImportTrace())
        qDebug().nospace() << "QDeclarativeImportDatabase::importPlugin: " << uri << " from " << filePath;

    QFileInfo fileInfo(filePath);
    const QString absoluteFilePath = fileInfo.absoluteFilePath();

    bool engineInitialized = initializedPlugins.contains(absoluteFilePath);
    bool typesRegistered = qmlEnginePluginsWithRegisteredTypes()->contains(absoluteFilePath);

    if (typesRegistered) {
        Q_ASSERT_X(qmlEnginePluginsWithRegisteredTypes()->value(absoluteFilePath) == uri,
                   "QDeclarativeImportDatabase::importExtension",
                   "Internal error: Plugin imported previously with different uri");
    }

    if (!engineInitialized || !typesRegistered) {
        if (!QDeclarative_isFileCaseCorrect(absoluteFilePath)) {
            if (errorString) 
                *errorString = tr("File name case mismatch for \"%2\"").arg(absoluteFilePath);
            return false;
        }
        QPluginLoader loader(absoluteFilePath);

        if (!loader.load()) {
            if (errorString)
                *errorString = loader.errorString();
            return false;
        }

        if (QDeclarativeExtensionInterface *iface = qobject_cast<QDeclarativeExtensionInterface *>(loader.instance())) {

            const QByteArray bytes = uri.toUtf8();
            const char *moduleId = bytes.constData();
            if (!typesRegistered) {

                // ### this code should probably be protected with a mutex.
                qmlEnginePluginsWithRegisteredTypes()->insert(absoluteFilePath, uri);
                iface->registerTypes(moduleId);
            }
            if (!engineInitialized) {
                // things on the engine (eg. adding new global objects) have to be done for every engine.

                // protect against double initialization
                initializedPlugins.insert(absoluteFilePath);
                iface->initializeEngine(engine, moduleId);
            }
        } else {
            if (errorString)
                *errorString = loader.errorString();
            return false;
        }
    }

    return true;
}


QT_END_NAMESPACE
