void UISettingsSerializer::run()
{
    /* Initialize COM for other thread: */
    COMBase::InitializeCOM(false);

    /* Mark all the pages initially as NOT processed: */
    foreach (UISettingsPage *pPage, m_pages.values())
        pPage->setProcessed(false);

    /* Iterate over the all left settings pages: */
    UISettingsPageMap pages(m_pages);
    while (!pages.empty())
    {
        /* Get required page pointer, protect map by mutex while getting pointer: */
        UISettingsPage *pPage = m_iIdOfHighPriorityPage != -1 && pages.contains(m_iIdOfHighPriorityPage) ?
                                pages.value(m_iIdOfHighPriorityPage) : *pages.begin();
        /* Reset request of high priority: */
        if (m_iIdOfHighPriorityPage != -1)
            m_iIdOfHighPriorityPage = -1;
        /* Process this page if its enabled: */
        connect(pPage, SIGNAL(sigOperationProgressChange(ulong, QString, ulong, ulong)),
                this, SIGNAL(sigOperationProgressChange(ulong, QString, ulong, ulong)));
        connect(pPage, SIGNAL(sigOperationProgressError(QString)),
                this, SIGNAL(sigOperationProgressError(QString)));
        if (pPage->isEnabled())
        {
            if (m_enmDirection == Load)
                pPage->loadToCacheFrom(m_data);
            if (m_enmDirection == Save)
                pPage->saveFromCacheTo(m_data);
        }
        /* Remember what page was processed: */
        disconnect(pPage, SIGNAL(sigOperationProgressChange(ulong, QString, ulong, ulong)),
                   this, SIGNAL(sigOperationProgressChange(ulong, QString, ulong, ulong)));
        disconnect(pPage, SIGNAL(sigOperationProgressError(QString)),
                   this, SIGNAL(sigOperationProgressError(QString)));
        pPage->setProcessed(true);
        /* Remove processed page from our map: */
        pages.remove(pPage->id());
        /* Notify listeners about page was processed: */
        emit sigNotifyAboutPageProcessed(pPage->id());
        /* If serializer saves settings => wake up GUI thread: */
        if (m_enmDirection == Save)
            m_condition.wakeAll();
        /* Break further processing if page had failed: */
        if (pPage->failed())
            break;
    }
    /* Notify listeners about all pages were processed: */
    emit sigNotifyAboutPagesProcessed();
    /* If serializer saves settings => wake up GUI thread: */
    if (m_enmDirection == Save)
        m_condition.wakeAll();

    /* Deinitialize COM for other thread: */
    COMBase::CleanupCOM();
}
    /* Settings serializer constructor: */
    UISettingsSerializer(QObject *pParent, const QVariant &data, UISettingsSerializeDirection direction)
        : QThread(pParent)
        , m_direction(direction)
        , m_data(data)
        , m_fSavingComplete(m_direction == UISettingsSerializeDirection_Load)
        , m_fAllowToDestroySerializer(m_direction == UISettingsSerializeDirection_Load)
        , m_iIdOfHighPriorityPage(-1)
    {
        /* Set instance: */
        m_pInstance = this;

        /* Connecting this signals: */
        connect(this, SIGNAL(sigNotifyAboutPageProcessed(int)), this, SLOT(sltHandleProcessedPage(int)), Qt::QueuedConnection);
        connect(this, SIGNAL(sigNotifyAboutPagesProcessed()), this, SLOT(sltHandleProcessedPages()), Qt::QueuedConnection);
        connect(this, SIGNAL(finished()), this, SLOT(sltDestroySerializer()), Qt::QueuedConnection);
        /* Connecting parent signals: */
        connect(this, SIGNAL(sigNotifyAboutProcessStarted()), parent(), SLOT(sltHandleProcessStarted()), Qt::QueuedConnection);
        connect(this, SIGNAL(sigNotifyAboutPageProcessed(int)), parent(), SLOT(sltHandlePageProcessed()), Qt::QueuedConnection);
    }
UISettingsSerializer::UISettingsSerializer(QObject *pParent, SerializationDirection enmDirection,
                                           const QVariant &data, const UISettingsPageList &pages)
    : QThread(pParent)
    , m_enmDirection(enmDirection)
    , m_data(data)
    , m_fSavingComplete(m_enmDirection == Load)
    , m_iIdOfHighPriorityPage(-1)
{
    /* Copy the page(s) from incoming list to our map: */
    foreach (UISettingsPage *pPage, pages)
        m_pages.insert(pPage->id(), pPage);

    /* Handling internal signals, they are also redirected in their handlers: */
    connect(this, SIGNAL(sigNotifyAboutPageProcessed(int)), this, SLOT(sltHandleProcessedPage(int)), Qt::QueuedConnection);
    connect(this, SIGNAL(sigNotifyAboutPagesProcessed()), this, SLOT(sltHandleProcessedPages()), Qt::QueuedConnection);

    /* Redirecting unhandled internal signals: */
    connect(this, SIGNAL(finished()), this, SIGNAL(sigNotifyAboutProcessFinished()), Qt::QueuedConnection);
}