void CLexiconReadWindow::initActions() {
    qDebug() << "CLexiconReadWindow::initActions";

    BtActionCollection* ac = actionCollection();
    CReadWindow::initActions();
    CLexiconReadWindow::insertKeyboardActions(ac);

    m_actions.backInHistory = dynamic_cast<BtToolBarPopupAction*>(
                                  ac->action(CResMgr::displaywindows::general::backInHistory::actionName) );
    Q_ASSERT(m_actions.backInHistory);
    addAction(m_actions.backInHistory);

    m_actions.forwardInHistory = dynamic_cast<BtToolBarPopupAction*>(
                                     ac->action(CResMgr::displaywindows::general::forwardInHistory::actionName) );
    Q_ASSERT(m_actions.forwardInHistory);
    addAction(m_actions.forwardInHistory);

    QAction* qaction;

    qaction = ac->action("nextEntry");
    QObject::connect(qaction, SIGNAL(triggered()), this, SLOT( nextEntry() ) );
    addAction(qaction);

    qaction = ac->action("previousEntry");
    QObject::connect(qaction, SIGNAL(triggered()), this, SLOT( previousEntry() ) );
    addAction(qaction);

    m_actions.selectAll = ac->action("selectAll");
    Q_ASSERT(m_actions.selectAll);

    m_actions.findText = ac->action("findText");
    Q_ASSERT(m_actions.findText);

    m_actions.findStrongs = ac->action(CResMgr::displaywindows::general::findStrongs::actionName);
    QObject::connect(m_actions.findStrongs, SIGNAL(triggered()), this, SLOT(openSearchStrongsDialog()) );
    addAction(m_actions.findStrongs);

    m_actions.copy.reference = ac->action("copyReferenceOnly");
    QObject::connect(m_actions.copy.reference, SIGNAL(triggered()), displayWidget()->connectionsProxy(), SLOT(copyAnchorOnly()) );
    addAction(m_actions.copy.reference);

    m_actions.copy.entry = ac->action("copyEntryWithText");
    QObject::connect(m_actions.copy.entry, SIGNAL(triggered()), displayWidget()->connectionsProxy(), SLOT(copyAll()) );
    addAction(m_actions.copy.entry);

    Q_ASSERT(ac->action("copySelectedText"));
    m_actions.copy.selectedText = ac->action("copySelectedText");

    m_actions.save.entryAsPlain = new QAction(tr("Entry as plain text"), ac );
    QObject::connect(m_actions.save.entryAsPlain, SIGNAL(triggered()), this, SLOT(saveAsPlain()) );
    addAction(m_actions.save.entryAsPlain);

    m_actions.save.entryAsHTML = ac->action("saveHtml");
    QObject::connect(m_actions.save.entryAsHTML, SIGNAL(triggered()), this, SLOT(saveAsHTML()));
    addAction(m_actions.save.entryAsHTML);

    m_actions.print.reference = ac->action("printReferenceOnly");
    QObject::connect(m_actions.print.reference, SIGNAL(triggered()), this, SLOT(printAnchorWithText()));
    addAction(m_actions.print.reference);

    m_actions.print.entry = ac->action("printEntryWithText");
    QObject::connect(m_actions.print.entry, SIGNAL(triggered()), this, SLOT(printAll()));
    addAction(m_actions.print.entry);

    // init with the user defined settings
    qDebug() << "call CBTConfig::setupAccelSettings(CBTConfig::lexiconWindow, ac); and end CLexiconReadWindow::initActions";
    CBTConfig::setupAccelSettings(CBTConfig::lexiconWindow, ac);
}
	void withoutReplacementImpl(withoutReplacementArgs& args)
	{
		boost::numeric::ublas::matrix<double>& matrix = args.matrix;
		int n = args.n;
		int seed = args.seed;
		double alpha = args.alpha;
		if(matrix.size1() != matrix.size2())
		{
			throw std::runtime_error("Matrix must be square");
		}
		if(n < 1)
		{
			throw std::runtime_error("Input n must be at least 1");
		}
		int dimension = matrix.size1();
		boost::mt19937 randomSource;
		randomSource.seed(seed);
		std::vector<double> columnSums(dimension,0);
		for(int row = 0; row < dimension; row++)
		{
			for(int column = 0; column < dimension; column++)
			{
				columnSums[column] += std::fabs(matrix(row, column));
			}
		}
		
		std::vector<double> currentColumnSums(dimension), newCurrentColumnSums;
		std::vector<int> availableColumns(dimension), newAvailableColumns;
		std::vector<int> availableRows(dimension), newAvailableRows;
		std::vector<int> previousEntry(1), newPreviousEntry;
		std::vector<bool> usedRows(dimension), newUsedRows;
		std::vector<mpfr_class> weights(1, 1), newWeights;
		//Get out the choices at the start. 
		std::vector<possibility> possibilities;
		for(int i = 0; i < dimension; i++)
		{
			for(int j = 0; j < dimension; j++)
			{
				possibility nextPos;
				nextPos.parent = 0;
				nextPos.previousEntry = i;
				nextPos.newEntry = j;
				possibilities.push_back(nextPos);
			}
		}
		//These choices are all derived from a single particle at the start
		std::copy(columnSums.begin(), columnSums.end(), currentColumnSums.begin());
		for(int i = 0; i < dimension; i++)
		{
			availableColumns[i] = i;
			availableRows[i] = i;
		}
		std::fill(usedRows.begin(), usedRows.end(), false);

		sampling::sampfordFromParetoNaiveArgs samplingArgs;
		samplingArgs.n = n;

		samplingArgs.weights.resize(dimension*dimension);
		for(int i = 0; i < (int)possibilities.size(); i++)
		{
			possibility& pos = possibilities[i];
			if(pos.previousEntry == pos.newEntry)
			{
				samplingArgs.weights[i] = alpha * std::fabs(matrix(pos.previousEntry, pos.newEntry)) / (dimension*(dimension - 1));
			}
			else 
			{
				samplingArgs.weights[i] = std::fabs(matrix(pos.previousEntry, pos.newEntry)) / dimension;
			}
		}

		int currentSamples = 1;
		for(int permutationCounter = 0; permutationCounter < dimension; permutationCounter++)
		{
			//Draw sample
			if((int)possibilities.size() <= n)
			{
				newCurrentColumnSums.resize(possibilities.size()*dimension);
				newAvailableColumns.resize(possibilities.size()*(dimension - permutationCounter-1));
				newAvailableRows.resize(possibilities.size()*(dimension - permutationCounter-1));
				newUsedRows.resize(possibilities.size()*dimension);
				newPreviousEntry.resize(possibilities.size());
				int newAvailableColumnsIndex = 0;
				int newAvailableRowsIndex = 0;
				for(int i = 0; i < (int)possibilities.size(); i++)
				{
					possibility& pos = possibilities[i];
					std::copy(currentColumnSums.begin() + pos.parent * dimension, currentColumnSums.begin() + (pos.parent + 1) * dimension, newCurrentColumnSums.begin() + dimension * i);
					newCurrentColumnSums[dimension*i + pos.newEntry] -= std::fabs(matrix(pos.previousEntry, pos.newEntry));
					std::copy(usedRows.begin() + pos.parent*dimension, usedRows.begin() + (pos.parent + 1) * dimension, newUsedRows.begin() + dimension*i);
					newUsedRows[dimension*i + pos.previousEntry] = true;
					for(int j = 0; j < dimension - permutationCounter; j++)
					{
						if(availableColumns[j + pos.parent*(dimension - permutationCounter)] != pos.newEntry)
						{
							newAvailableColumns.at(newAvailableColumnsIndex) = availableColumns.at(j + pos.parent*(dimension - permutationCounter));
							newAvailableColumnsIndex++;
						}
						if(availableRows[j + pos.parent*(dimension - permutationCounter)] != pos.previousEntry)
						{
							newAvailableRows.at(newAvailableRowsIndex) = availableRows.at(j + pos.parent*(dimension - permutationCounter));
							newAvailableRowsIndex++;
						}
					}
					if(newUsedRows[i*dimension + pos.newEntry])
					{
						newPreviousEntry[i] = -1;
					}
					else
					{
						newPreviousEntry[i] = pos.newEntry;
					}
				}
				newWeights.swap(samplingArgs.weights);
				currentSamples = possibilities.size();
			}
			else
			{
				sampfordFromParetoNaive(samplingArgs, randomSource);
				newCurrentColumnSums.resize(n*dimension);
				newAvailableColumns.resize(n*(dimension - permutationCounter-1));
				newAvailableRows.resize(n*(dimension - permutationCounter-1));
				newUsedRows.resize(n*dimension);
				newWeights.resize(n);
				newPreviousEntry.resize(n);
				int newAvailableColumnsIndex = 0;
				int newAvailableRowsIndex = 0;
				for(int i = 0; i < n; i++)
				{
					possibility& pos = possibilities[samplingArgs.indices[i]];
					std::copy(currentColumnSums.begin() + pos.parent * dimension, currentColumnSums.begin() + (pos.parent + 1) * dimension, newCurrentColumnSums.begin() + dimension * i);
					newCurrentColumnSums[dimension*i + pos.newEntry] -= std::fabs(matrix(pos.previousEntry, pos.newEntry));
					std::copy(usedRows.begin() + pos.parent*dimension, usedRows.begin() + (pos.parent + 1) * dimension, newUsedRows.begin() + dimension*i);
					newUsedRows[dimension*i + pos.previousEntry] = true;
					for(int j = 0; j < dimension - permutationCounter; j++)
					{
						if(availableColumns[j + pos.parent*(dimension - permutationCounter)] != pos.newEntry)
						{
							newAvailableColumns.at(newAvailableColumnsIndex) = availableColumns.at(j + pos.parent*(dimension - permutationCounter));
							newAvailableColumnsIndex++;
						}
						if(availableRows[j + pos.parent*(dimension - permutationCounter)] != pos.previousEntry)
						{
							newAvailableRows.at(newAvailableRowsIndex) = availableRows.at(j + pos.parent*(dimension - permutationCounter));
							newAvailableRowsIndex++;
						}
					}
					if(newUsedRows[i*dimension + pos.newEntry])
					{
						newPreviousEntry[i] = -1;
					}
					else
					{
						newPreviousEntry[i] = pos.newEntry;
					}
					newWeights[i] = samplingArgs.weights[samplingArgs.indices[i]] / samplingArgs.rescaledWeights[samplingArgs.indices[i]];
				}
				currentSamples = n;
			}
			previousEntry.swap(newPreviousEntry);
			currentColumnSums.swap(newCurrentColumnSums);
			availableColumns.swap(newAvailableColumns);
			availableRows.swap(newAvailableRows);
			usedRows.swap(newUsedRows);
			weights.swap(newWeights);

			//If we're not at the end, get out the list of possibilities and also weights
			if(permutationCounter != dimension - 1)
			{
				possibilities.clear();
				samplingArgs.weights.clear();
				for(int i = 0; i < currentSamples; i++)
				{
					if(previousEntry[i] == -1)
					{
						for(int j = 0; j < dimension - permutationCounter - 1; j++)
						{
							for(int k = 0; k < dimension - permutationCounter - 1; k++)
							{
								possibility pos;
								pos.parent = i;
								pos.previousEntry = availableRows[(dimension - permutationCounter - 1) * i + j];
								pos.newEntry = availableColumns[(dimension - permutationCounter - 1) * i + k];
								possibilities.push_back(pos);
								if(j == k || usedRows[pos.newEntry + dimension * i])
								{
									if(dimension - 2 != permutationCounter)
									{
										samplingArgs.weights.push_back(weights[i] * alpha * std::fabs(matrix(pos.previousEntry, pos.newEntry))/ (dimension - permutationCounter - 2));
									}
									else
									{
										samplingArgs.weights.push_back(weights[i] * alpha * std::fabs(matrix(pos.previousEntry, pos.newEntry)));
									}
								}
								else
								{
									samplingArgs.weights.push_back(weights[i] * std::fabs(matrix(pos.previousEntry, pos.newEntry)));
								}
							}
						}

					}
					else
					{
						for(int j = 0; j < dimension - permutationCounter - 1; j++)
						{
							possibility pos;
							pos.parent = i;
							pos.previousEntry = previousEntry[i];
							pos.newEntry = availableColumns[(dimension - permutationCounter - 1) * i + j];
							possibilities.push_back(pos);
							if(j == previousEntry[i] || usedRows[pos.newEntry + dimension * i])
							{
								if(dimension - 2 != permutationCounter)
								{
									samplingArgs.weights.push_back(weights[i] * alpha * std::fabs(matrix(pos.previousEntry, pos.newEntry)) / (dimension - permutationCounter - 2));
								}
								else
								{
									samplingArgs.weights.push_back(weights[i] * alpha * std::fabs(matrix(pos.previousEntry, pos.newEntry)));
								}
							}
							else
							{
								samplingArgs.weights.push_back(weights[i] * std::fabs(matrix(pos.previousEntry, pos.newEntry)));
							}
						}
					}
				}
			}
		}
		args.estimate = 0;
		for(int i = 0; i < (int)weights.size(); i++)
		{
			args.estimate += weights[i];
		}
	}
void CLexiconReadWindow::initActions()
{
	qDebug("CLexiconReadWindow::initActions");

	KActionCollection* ac = actionCollection();
	CLexiconReadWindow::insertKeyboardActions(ac);
	CReadWindow::initActions();

	
	m_actions.backInHistory = dynamic_cast<KToolBarPopupAction*>(
		ac->action(CResMgr::displaywindows::general::backInHistory::actionName) );
	Q_ASSERT(m_actions.backInHistory);

	m_actions.forwardInHistory = dynamic_cast<KToolBarPopupAction*>(
		 ac->action(CResMgr::displaywindows::general::forwardInHistory::actionName) );
	Q_ASSERT(m_actions.forwardInHistory);


	KAction* kaction;

	kaction = new KAction(tr("Next entry"), ac );
	kaction->setShortcut( CResMgr::displaywindows::lexiconWindow::nextEntry::accel);
	QObject::connect(kaction, SIGNAL(triggered()), this, SLOT( nextEntry() ) );
	ac->addAction("nextEntry", kaction);

	kaction = new KAction(tr("Previous entry"), ac );
	kaction->setShortcut( CResMgr::displaywindows::lexiconWindow::previousEntry::accel);
	QObject::connect(kaction, SIGNAL(triggered()), this, SLOT( previousEntry() ) );
	ac->addAction("previousEntry", kaction);


	m_actions.selectAll = qobject_cast<KAction*>(ac->action("selectAll"));
	//TODO: Q_ASSERT(m_actions.selectAll);

	m_actions.findText = qobject_cast<KAction*>(ac->action("findText"));
	//TODO: Q_ASSERT(m_actions.findText);
	

	m_actions.findStrongs = new KAction(
		KIcon(CResMgr::displaywindows::general::findStrongs::icon),
		tr("Strong's Search"),
		ac
		);
	m_actions.findStrongs->setShortcut(CResMgr::displaywindows::general::findStrongs::accel);
	QObject::connect(m_actions.findStrongs, SIGNAL(triggered()), this, SLOT(openSearchStrongsDialog()) );
	ac->addAction(CResMgr::displaywindows::general::findStrongs::actionName, m_actions.findStrongs);

	m_actions.copy.reference = new KAction(tr("Reference only"), ac );
	QObject::connect(m_actions.copy.reference, SIGNAL(triggered()), displayWidget()->connectionsProxy(), SLOT(copyAnchorOnly()) );
	ac->addAction("copyReferenceOnly", m_actions.copy.reference);

	m_actions.copy.entry = new KAction(tr("Entry with text"), ac );
	QObject::connect(m_actions.copy.entry, SIGNAL(triggered()), displayWidget()->connectionsProxy(), SLOT(copyAll()) );
	ac->addAction("copyEntryWithText", m_actions.copy.entry);

	Q_ASSERT(ac->action("copySelectedText"));
	m_actions.copy.selectedText = qobject_cast<KAction*>(ac->action("copySelectedText"));
	
	m_actions.save.entryAsPlain = new KAction(tr("Entry as plain text"), ac );
	QObject::connect(m_actions.save.entryAsPlain, SIGNAL(triggered()), this, SLOT(saveAsPlain()) );
	ac->addAction("saveEntryAsPlain", m_actions.save.entryAsPlain);

	m_actions.save.entryAsHTML = new KAction(tr("Entry as HTML"), ac );
	QObject::connect(m_actions.save.entryAsHTML, SIGNAL(triggered()), this, SLOT(saveAsHTML()));
	ac->addAction("saveEntryAsHTML", m_actions.save.entryAsHTML);

	m_actions.print.reference = new KAction(tr("Reference only"), ac);
	QObject::connect(m_actions.print.reference, SIGNAL(triggered()), this, SLOT(printAnchorWithText()));
	ac->addAction("printReferenceOnly", m_actions.print.reference);

	m_actions.print.entry = new KAction(tr("Entry with text"), ac);
	QObject::connect(m_actions.print.entry, SIGNAL(triggered()), this, SLOT(printAll()));
	ac->addAction("printEntryWithText", m_actions.print.entry);

	// init with the user defined settings
	qDebug("call CBTConfig::setupAccelSettings(CBTConfig::lexiconWindow, ac); and end CLexiconReadWindow::initActions");
	CBTConfig::setupAccelSettings(CBTConfig::lexiconWindow, ac);
};