/** For sword module lists set scope of verses. Scope will not be set if \list is empty. */
        void setScope(sword::ListKey list)
		{
			_hasScope = list.Count() > 0;
			_scopeMap.clear();

            if(!_module)
                return;

            if(_module->type() == CSwordModuleInfo::Lexicon)
            {
                CSwordLexiconModuleInfo *mi = qobject_cast<CSwordLexiconModuleInfo*>(_module);

                for(int i = 0; i < list.Count(); ++i)
                {
                    CSwordLDKey k(list.GetElement(i), mi);
                    _scopeMap.append(mi->entries().indexOf(k.key()));
                }
            }
            else
            {
                for(int i = 0; i < list.Count(); ++i)
                    _scopeMap.append(list.GetElement(i)->getIndex());
            }

            Q_ASSERT(!_scopeMap.contains(-1));
        }
StrongsResultList::StrongsResultList(const CSwordModuleInfo *module,
                                     const sword::ListKey & result,
                                     const QString &strongsNumber)
{
    using namespace Rendering;

    int count = result.getCount();
    if (!count)
        return;

    CTextRendering::KeyTreeItem::Settings settings;
    BtConstModuleList modules;
    modules.append(module);
    clear();

    // for whatever reason the text "Parsing...translations." does not appear.
    // this is not critical but the text is necessary to get the dialog box
    // to be wide enough.
    QProgressDialog progress(QObject::tr("Parsing Strong's Numbers"), 0, 0, count);
    //0, "progressDialog", tr("Parsing Strong's Numbers"), tr("Parsing Strong's numbers for translations."), true);
    //progress->setAllowCancel(false);
    //progress->setMinimumDuration(0);
    progress.show();
    progress.raise();

    qApp->processEvents(QEventLoop::AllEvents, 1); //1 ms only

    for (int index = 0; index < count; index++) {
        progress.setValue(index);
        qApp->processEvents(QEventLoop::AllEvents, 1); //1 ms only

        QString key = QString::fromUtf8(result.getElement(index)->getText());
        QString text = CDisplayRendering().renderSingleKey(key, modules, settings);
        for (int sIndex = 0;;) {
            continueloop:
            QString rText = getStrongsNumberText(text, sIndex, strongsNumber);
            if (rText.isEmpty()) break;

            for (iterator it = begin(); it != end(); ++it) {
                if ((*it).keyText() == rText) {
                    (*it).addKeyName(key);
                    goto continueloop; // break, then continue
                }
            }
            append(StrongsResult(rText, key));
        }
    }
}
/** Setups the list with the given module. */
void BtSearchInterface::setupReferenceModel(const CSwordModuleInfo *m,
                                            const sword::ListKey & results)
{
    QHash<int, QByteArray> roleNames;
    roleNames[TextRole] =  "text";
    roleNames[ValueRole] = "value";
    m_referencesModel.setRoleNames(roleNames);

    m_referencesModel.clear();
    if (!m)
        return;
    const int count = results.getCount();
    if (!count)
        return;

    for (int index = 0; index < count; index++) {
        QString reference = QString::fromUtf8(results.getElement(index)->getText());
        QStandardItem* item = new QStandardItem();
        item->setData(reference, TextRole);
        item->setData(reference, ValueRole);
        m_referencesModel.appendRow(item);
    }
    referencesModelChanged();
}
bool CSwordModuleInfo::searchIndexed(const QString& searchedText, sword::ListKey& scope) {
    char utfBuffer[BT_MAX_LUCENE_FIELD_LENGTH  + 1];
    wchar_t wcharBuffer[BT_MAX_LUCENE_FIELD_LENGTH + 1];

    // work around Swords thread insafety for Bibles and Commentaries
    boost::scoped_ptr < CSwordKey > key(CSwordKey::createInstance(this));
    sword::SWKey* s = dynamic_cast < sword::SWKey * >(key.get());
    QList<sword::VerseKey*> list;

    if (s) {
        m_module->SetKey(*s);
    }

    m_searchResult.ClearList();

    try {
        // do not use any stop words
        const TCHAR* stop_words[]  = { NULL };
        lucene::analysis::standard::StandardAnalyzer analyzer( stop_words );
        lucene::search::IndexSearcher searcher(getModuleStandardIndexLocation().toAscii().constData());
        lucene_utf8towcs(wcharBuffer, searchedText.toUtf8().constData(), BT_MAX_LUCENE_FIELD_LENGTH);
        boost::scoped_ptr<lucene::search::Query> q( lucene::queryParser::QueryParser::parse((const TCHAR*)wcharBuffer, (const TCHAR*)_T("content"), &analyzer) );

        boost::scoped_ptr<lucene::search::Hits> h( searcher.search(q.get(), lucene::search::Sort::INDEXORDER) );

        const bool useScope = (scope.Count() > 0);
//		const bool isVerseModule = (type() == CSwordModuleInfo::Bible) || (type() == CSwordModuleInfo::Commentary);

        lucene::document::Document* doc = 0;
        boost::scoped_ptr<sword::SWKey> swKey( module()->CreateKey() );


        for (int i = 0; i < h->length(); ++i) {
            doc = &h->doc(i);
            lucene_wcstoutf8(utfBuffer, (const wchar_t*)doc->get((const TCHAR*)_T("key")), BT_MAX_LUCENE_FIELD_LENGTH);

            swKey->setText(utfBuffer);

            // limit results based on scope
            //if (searchOptions & CSwordModuleSearch::useScope && scope.Count() > 0){
            if (useScope) {
                for (int j = 0; j < scope.Count(); j++) {
                    sword::VerseKey* vkey = dynamic_cast<sword::VerseKey*>(scope.getElement(j));
                    if (vkey->LowerBound().compare(*swKey) <= 0 && vkey->UpperBound().compare(*swKey) >= 0) {
                        m_searchResult.add(*swKey);
                    }
                }
            }
            else { // no scope, give me all buffers
                m_searchResult.add(*swKey);
            }
        }
    }
    catch (...) {
        qWarning("CLucene exception occurred");
        util::showWarning(0, QCoreApplication::tr("Search aborted"), QCoreApplication::tr("An internal error occurred while executing your search."));
        return false;
    }

    qDeleteAll(list);
    list.clear();

    return (m_searchResult.Count() > 0);
}