Index: /trunk/src/VBox/Frontends/VirtualBox/Makefile.kmk
===================================================================
--- /trunk/src/VBox/Frontends/VirtualBox/Makefile.kmk	(revision 70486)
+++ /trunk/src/VBox/Frontends/VirtualBox/Makefile.kmk	(revision 70487)
@@ -335,4 +335,5 @@
 	src/hostnetwork/UIHostNetworkDetailsWidget.h \
 	src/hostnetwork/UIHostNetworkManager.h \
+	src/logviewer/UIVMLogViewerBookmarksPanel.h \
 	src/logviewer/UIVMLogViewerDialog.h \
 	src/logviewer/UIVMLogViewerFilterPanel.h \
@@ -651,4 +652,5 @@
 	src/hostnetwork/UIHostNetworkManager.cpp \
 	src/hostnetwork/UIHostNetworkUtils.cpp \
+	src/logviewer/UIVMLogViewerBookmarksPanel.cpp \
 	src/logviewer/UIVMLogViewerDialog.cpp \
 	src/logviewer/UIVMLogViewerFilterPanel.cpp \
Index: /trunk/src/VBox/Frontends/VirtualBox/src/logviewer/UIVMLogViewerBookmarksPanel.cpp
===================================================================
--- /trunk/src/VBox/Frontends/VirtualBox/src/logviewer/UIVMLogViewerBookmarksPanel.cpp	(revision 70487)
+++ /trunk/src/VBox/Frontends/VirtualBox/src/logviewer/UIVMLogViewerBookmarksPanel.cpp	(revision 70487)
@@ -0,0 +1,167 @@
+/* $Id$ */
+/** @file
+ * VBox Qt GUI - UIVMLogViewer class implementation.
+ */
+
+/*
+ * Copyright (C) 2010-2017 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ */
+
+#ifdef VBOX_WITH_PRECOMPILED_HEADERS
+# include <precomp.h>
+#else  /* !VBOX_WITH_PRECOMPILED_HEADERS */
+
+/* Qt includes: */
+# include <QComboBox>
+# include <QHBoxLayout>
+# if defined(RT_OS_SOLARIS)
+#  include <QFontDatabase>
+# endif
+# include <QLabel>
+# include <QLineEdit>
+# include <QPlainTextEdit>
+# include <QPushButton>
+# include <QTextCursor>
+# include <QToolButton>
+# include <QScrollArea>
+
+/* GUI includes: */
+# include "UIIconPool.h"
+# include "UISpecialControls.h"
+# include "UIVMLogViewerBookmarksPanel.h"
+# include "UIVMLogViewerWidget.h"
+# ifdef VBOX_WS_MAC
+#  include "VBoxUtils-darwin.h"
+# endif
+#endif /* !VBOX_WITH_PRECOMPILED_HEADERS */
+
+
+UIVMLogViewerBookmarksPanel::UIVMLogViewerBookmarksPanel(QWidget *pParent, UIVMLogViewerWidget *pViewer)
+    : QIWithRetranslateUI<QWidget>(pParent)
+    , m_iMaxBookmarkTextLength(60)
+    , m_pViewer(pViewer)
+    , m_pMainLayout(0)
+    , m_pCloseButton(0)
+    , m_pBookmarksComboBox(0)
+{
+    prepare();
+}
+
+void UIVMLogViewerBookmarksPanel::update()
+{
+    if(!m_pBookmarksComboBox)
+        return;
+    const QVector<QPair<int, QString> > *bookmarkVector = m_pViewer->currentBookmarkVector();
+    if(!bookmarkVector)
+        return;
+
+    m_pBookmarksComboBox->clear();
+    QStringList bList;
+    for(int i = 0; i < bookmarkVector->size(); ++i)
+    {
+        QString strItem = QString("BookMark %1 at Line %2: %3").arg(QString::number(i)).
+            arg(QString::number(bookmarkVector->at(i).first)).arg(bookmarkVector->at(i).second);
+
+        if(strItem.length() > m_iMaxBookmarkTextLength)
+        {
+            strItem.resize(m_iMaxBookmarkTextLength);
+            strItem.replace(m_iMaxBookmarkTextLength, 3, QString("..."));
+        }
+        bList << strItem;
+    }
+    m_pBookmarksComboBox->addItems(bList);
+}
+
+void UIVMLogViewerBookmarksPanel::setBookmarkIndex(int index)
+{
+    if (!m_pBookmarksComboBox)
+        return;
+    if (index >= m_pBookmarksComboBox->count())
+        return;
+    m_pBookmarksComboBox->setCurrentIndex(index);
+}
+
+void UIVMLogViewerBookmarksPanel::prepare()
+{
+    prepareWidgets();
+    prepareConnections();
+    retranslateUi();
+}
+
+void UIVMLogViewerBookmarksPanel::prepareWidgets()
+{
+    m_pMainLayout = new QHBoxLayout(this);
+    AssertPtrReturnVoid(m_pMainLayout);
+    m_pMainLayout->setContentsMargins(0, 0, 0, 0);
+    m_pMainLayout->setSpacing(4);
+
+    m_pCloseButton = new UIMiniCancelButton(this);
+    AssertPtrReturnVoid(m_pCloseButton);
+    m_pMainLayout->addWidget(m_pCloseButton, 0, Qt::AlignLeft);
+
+    m_pBookmarksComboBox = new QComboBox(this);
+    QFontMetrics fontMetrics = m_pBookmarksComboBox->fontMetrics();
+    AssertPtrReturnVoid(m_pBookmarksComboBox);
+    m_pBookmarksComboBox->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Maximum);
+    m_pBookmarksComboBox->setMaximumWidth(fontMetrics.width('a') * (m_iMaxBookmarkTextLength + 2));
+    printf("max max %d\n", fontMetrics.width('a') * (m_iMaxBookmarkTextLength + 2));
+    m_pMainLayout->addWidget(m_pBookmarksComboBox, 2, Qt::AlignLeft);
+
+}
+
+void UIVMLogViewerBookmarksPanel::prepareConnections()
+{
+    connect(m_pCloseButton, &UIMiniCancelButton::clicked, this, &UIVMLogViewerBookmarksPanel::hide);
+
+}
+
+
+void UIVMLogViewerBookmarksPanel::retranslateUi()
+{
+    m_pCloseButton->setToolTip(UIVMLogViewerWidget::tr("Close the search panel."));
+}
+
+bool UIVMLogViewerBookmarksPanel::eventFilter(QObject *pObject, QEvent *pEvent)
+{
+    /* Depending on event-type: */
+    switch (pEvent->type())
+    {
+        /* Process key press only: */
+    case QEvent::KeyPress:
+        {
+            break;
+        }
+    default:
+        break;
+    }
+    /* Call to base-class: */
+    return QWidget::eventFilter(pObject, pEvent);
+}
+
+/** Handles the Qt show @a pEvent. */
+void UIVMLogViewerBookmarksPanel::showEvent(QShowEvent *pEvent)
+{
+    /* Call to base-class: */
+    QWidget::showEvent(pEvent);
+}
+
+/** Handles the Qt hide @a pEvent. */
+void UIVMLogViewerBookmarksPanel::hideEvent(QHideEvent *pEvent)
+{
+    /* Get focused widget: */
+    QWidget *pFocus = QApplication::focusWidget();
+    /* If focus-widget is valid and child-widget of search-panel,
+     * focus next child-widget in line: */
+    if (pFocus && pFocus->parent() == this)
+        focusNextPrevChild(true);
+    /* Call to base-class: */
+    QWidget::hideEvent(pEvent);
+}
Index: /trunk/src/VBox/Frontends/VirtualBox/src/logviewer/UIVMLogViewerBookmarksPanel.h
===================================================================
--- /trunk/src/VBox/Frontends/VirtualBox/src/logviewer/UIVMLogViewerBookmarksPanel.h	(revision 70487)
+++ /trunk/src/VBox/Frontends/VirtualBox/src/logviewer/UIVMLogViewerBookmarksPanel.h	(revision 70487)
@@ -0,0 +1,94 @@
+/* $Id$ */
+/** @file
+ * VBox Qt GUI - UIVMLogViewer class declaration.
+ */
+
+/*
+ * Copyright (C) 2010-2017 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ */
+
+#ifndef ___UIVMLogViewerBookmarksPanel_h___
+#define ___UIVMLogViewerBookmarksPanel_h___
+
+/* Qt includes: */
+#include <QWidget>
+
+/* GUI includes: */
+#include "QIWithRetranslateUI.h"
+
+/* Forward declarations: */
+class QComboBox;
+class QHBoxLayout;
+class QLabel;
+class QLineEdit;
+class QPushButton;
+class UIVMFilterLineEdit;
+class UIMiniCancelButton;
+class UIVMLogViewerWidget;
+
+
+/** QWidget extension
+  * providing GUI for bookmark management. Show a list of bookmarks currently set
+  for displayed log page. It has controls to navigate and clear bookmarks. */
+class UIVMLogViewerBookmarksPanel : public QIWithRetranslateUI<QWidget>
+{
+    Q_OBJECT;
+
+signals:
+
+public:
+
+    UIVMLogViewerBookmarksPanel(QWidget *pParent, UIVMLogViewerWidget *pViewer);
+
+    /* Adds a single bookmark to an existing list of bookmarks. Possibly called
+       by UIVMLogViewerWidget when user adds a bookmark thru context menu etc. */
+    void addBookmark(const QPair<int, QString> &newBookmark);
+    /* Clear the bookmark list and show this list instead. Probably done after
+       user switches to another log page tab etc. */
+    void setBookmarksList(const QVector<QPair<int, QString> > &bookmarkList);
+    void update();
+    /* @a index is the index of the curent bookmark. */
+    void setBookmarkIndex(int index);
+
+public slots:
+
+
+private slots:
+
+
+private:
+
+    void prepare();
+    void prepareWidgets();
+    void prepareConnections();
+
+    /** Handles the translation event. */
+    void retranslateUi();
+
+    /** Handles Qt @a pEvent, used for keyboard processing. */
+    bool eventFilter(QObject *pObject, QEvent *pEvent);
+    /** Handles the Qt show @a pEvent. */
+    void showEvent(QShowEvent *pEvent);
+    /** Handles the Qt hide @a pEvent. */
+    void hideEvent(QHideEvent *pEvent);
+
+    const int m_iMaxBookmarkTextLength;
+    /** Holds the reference to VM Log-Viewer this panel belongs to. */
+    UIVMLogViewerWidget *m_pViewer;
+    /** Holds the instance of main-layout we create. */
+    QHBoxLayout         *m_pMainLayout;
+    /** Holds the instance of close-button we create. */
+    UIMiniCancelButton  *m_pCloseButton;
+    QComboBox           *m_pBookmarksComboBox;
+
+};
+
+#endif /* !___UIVMLogViewerBookmarksPanel_h___ */
Index: /trunk/src/VBox/Frontends/VirtualBox/src/logviewer/UIVMLogViewerFilterPanel.cpp
===================================================================
--- /trunk/src/VBox/Frontends/VirtualBox/src/logviewer/UIVMLogViewerFilterPanel.cpp	(revision 70486)
+++ /trunk/src/VBox/Frontends/VirtualBox/src/logviewer/UIVMLogViewerFilterPanel.cpp	(revision 70487)
@@ -204,17 +204,17 @@
     QPlainTextEdit *pCurrentPage = m_pViewer->currentLogPage();
     AssertReturnVoid(pCurrentPage);
-    const QString& strInputText = m_pViewer->currentLog();
+    const QString* strInputText = m_pViewer->currentLog();
     m_iUnfilteredLineCount = 0;
     m_iFilteredLineCount = 0;
-    if (strInputText.isNull())
+    if (!strInputText || strInputText->isNull())
         return;
     QTextDocument *document = pCurrentPage->document();
     if (!document)
         return;
-    QStringList stringLines = strInputText.split("\n");
+    QStringList stringLines = strInputText->split("\n");
     m_iUnfilteredLineCount = stringLines.size();
     if (m_filterTermList.empty())
     {
-        document->setPlainText(strInputText);
+        document->setPlainText(*strInputText);
         emit sigFilterApplied();
         m_iFilteredLineCount = document->lineCount();
Index: /trunk/src/VBox/Frontends/VirtualBox/src/logviewer/UIVMLogViewerWidget.cpp
===================================================================
--- /trunk/src/VBox/Frontends/VirtualBox/src/logviewer/UIVMLogViewerWidget.cpp	(revision 70486)
+++ /trunk/src/VBox/Frontends/VirtualBox/src/logviewer/UIVMLogViewerWidget.cpp	(revision 70487)
@@ -30,4 +30,5 @@
 # include <QPlainTextEdit>
 # include <QScrollBar>
+# include <QTextBlock>
 
 /* GUI includes: */
@@ -38,4 +39,5 @@
 # include "UIMessageCenter.h"
 # include "UIVMLogViewerWidget.h"
+# include "UIVMLogViewerBookmarksPanel.h"
 # include "UIVMLogViewerFilterPanel.h"
 # include "UIVMLogViewerSearchPanel.h"
@@ -48,4 +50,5 @@
 
 #endif /* !VBOX_WITH_PRECOMPILED_HEADERS */
+
 
 /** We use a modified scrollbar style for our QPlainTextEdits to get the
@@ -116,4 +119,67 @@
 };
 
+/* Sub-class QPlainTextEdit for some addtional context menu items: */
+class UIVMLogViewerTextEdit : public QPlainTextEdit
+{
+    Q_OBJECT;
+
+signals:
+
+    void sigContextMenuBookmarkAction(LogBookmark bookmark);
+
+public:
+    UIVMLogViewerTextEdit(QWidget* parent = 0, const QString& logFileName = QString())
+        :QPlainTextEdit(parent),
+         m_logFileName(logFileName)
+    {
+        //setStyleSheet("background-color: rgba(240, 240, 240, 75%) ");
+    }
+
+    const QString& logFileName() const
+    {
+        return m_logFileName;
+    }
+
+protected:
+
+    void contextMenuEvent(QContextMenuEvent *pEvent)
+    {
+        QMenu *menu = createStandardContextMenu();
+        QAction *pAction = menu->addAction(tr("Bookmark"));
+        QTextBlock block = cursorForPosition(pEvent->pos()).block();
+        m_iContextMenuBookmark.first = block.firstLineNumber();
+        m_iContextMenuBookmark.second = block.text();
+
+        if(pAction)
+            connect(pAction, &QAction::triggered, this, &UIVMLogViewerTextEdit::sltBookmark);
+
+        menu->exec(pEvent->globalPos());
+
+        if(pAction)
+            disconnect(pAction, &QAction::triggered, this, &UIVMLogViewerTextEdit::sltBookmark);
+
+        delete menu;
+    }
+
+    virtual void mousePressEvent(QMouseEvent *pEvent)
+    {
+        QPlainTextEdit::mousePressEvent(pEvent);
+    }
+
+private slots:
+    /// remove
+    void sltBookmark()
+    {
+        emit sigContextMenuBookmarkAction(m_iContextMenuBookmark);
+    }
+
+private:
+
+    /* Line number and text at the context menu position */
+    LogBookmark m_iContextMenuBookmark;
+    /* Name of the log file this text edit created to show. */
+    QString m_logFileName;
+};
+
 UIVMLogViewerWidget::UIVMLogViewerWidget(EmbedTo enmEmbedding, QWidget *pParent /* = 0 */, const CMachine &machine /* = CMachine() */)
     : QIWithRetranslateUI<QWidget>(pParent)
@@ -122,4 +188,7 @@
     , m_pViewerContainer(0)
     , m_iCurrentTabIndex(-1)
+    , m_pSearchPanel(0)
+    , m_pFilterPanel(0)
+    , m_pBookmarksPanel(0)
     , m_pMainLayout(0)
     , m_enmEmbedding(enmEmbedding)
@@ -129,4 +198,5 @@
     , m_pActionRefresh(0)
     , m_pActionSave(0)
+    , m_pActionBookmark(0)
     , m_pMenu(0)
 {
@@ -166,6 +236,8 @@
 }
 
-void UIVMLogViewerWidget::sltFind()
-{
+void UIVMLogViewerWidget::sltShowHideSearchPanel()
+{
+    if(!m_pSearchPanel)
+        return;
     /* Show/hide search-panel: */
     m_pSearchPanel->isHidden() ? m_pSearchPanel->show() : m_pSearchPanel->hide();
@@ -178,6 +250,4 @@
     disconnect(m_pViewerContainer, &QITabWidget::currentChanged, this, &UIVMLogViewerWidget::sltTabIndexChange);
 
-    /* Clearing old data if any: */
-    m_book.clear();
     m_logMap.clear();
     m_pViewerContainer->setEnabled(true);
@@ -226,5 +296,6 @@
 
     /* Apply the filter settings: */
-    m_pFilterPanel->applyFilter();
+    if(m_pFilterPanel)
+        m_pFilterPanel->applyFilter();
 
     /* Setup this connection after refresh to avoid initial signals during page creation: */
@@ -238,4 +309,5 @@
     m_pActionFilter->setEnabled(!noLogsToShow);
     m_pActionSave->setEnabled(!noLogsToShow);
+    m_pActionBookmark->setEnabled(!noLogsToShow);
     m_pViewerContainer->setEnabled(!noLogsToShow);
     m_pViewerContainer->show();
@@ -248,6 +320,9 @@
     if (m_comMachine.isNull())
         return;
+    UIVMLogViewerTextEdit *logPage = qobject_cast<UIVMLogViewerTextEdit*>(currentLogPage());
+    if(!logPage)
+        return;
     /* Prepare "save as" dialog: */
-    const QFileInfo fileInfo(m_book.at(m_pViewerContainer->currentIndex()).first);
+    const QFileInfo fileInfo(logPage->logFileName());
     /* Prepare default filename: */
     const QDateTime dtInfo = fileInfo.lastModified();
@@ -274,6 +349,8 @@
 }
 
-void UIVMLogViewerWidget::sltFilter()
-{
+void UIVMLogViewerWidget::sltShowHideFilterPanel()
+{
+    if(!m_pFilterPanel)
+        return;
     /* Show/hide filter-panel: */
     m_pFilterPanel->isHidden() ? m_pFilterPanel->show() : m_pFilterPanel->hide();
@@ -305,10 +382,44 @@
 }
 
-void UIVMLogViewerWidget::
-sltFilterApplied()
+void UIVMLogViewerWidget::sltFilterApplied()
 {
     /* Reapply the search to get highlighting etc. correctly */
     if (m_pSearchPanel && m_pSearchPanel->isVisible())
         m_pSearchPanel->refresh();
+}
+
+void UIVMLogViewerWidget::sltShowHideBookmarkPanel()
+{
+    if(!m_pBookmarksPanel)
+        return;
+    m_pBookmarksPanel->isHidden() ? m_pBookmarksPanel->show() : m_pBookmarksPanel->hide();
+}
+
+void UIVMLogViewerWidget::sltCreateBookmarkAtCurrent()
+{
+    if(!currentLogPage())
+        return;
+    QWidget* viewport = currentLogPage()->viewport();
+    if (!viewport)
+        return;
+    QPoint point(0.5 * viewport->width(), 0.5 * viewport->height());
+    QTextBlock block = currentLogPage()->cursorForPosition(point).block();
+    LogBookmark bookmark;
+    bookmark.first = block.firstLineNumber();
+    bookmark.second = block.text();
+    sltCreateBookmarkAtLine(bookmark);
+}
+
+void UIVMLogViewerWidget::sltCreateBookmarkAtLine(LogBookmark bookmark)
+{
+    QVector<LogBookmark> *pBookmarkVector = currentBookmarkVector();
+    if(!pBookmarkVector)
+        return;
+    pBookmarkVector->push_back(bookmark);
+    if(m_pBookmarksPanel)
+    {
+        m_pBookmarksPanel->update();
+        m_pBookmarksPanel->setBookmarkIndex(pBookmarkVector->size() - 1);
+    }
 }
 
@@ -384,4 +495,12 @@
                 this, &UIVMLogViewerWidget::sltFilterApplied);
     }
+
+    m_pBookmarksPanel = new UIVMLogViewerBookmarksPanel(this, this);
+    AssertPtrReturnVoid(m_pBookmarksPanel);
+    {
+        installEventFilter(m_pBookmarksPanel);
+        m_pBookmarksPanel->hide();
+        m_pMainLayout->insertWidget(4, m_pBookmarksPanel);
+    }
 }
 
@@ -393,5 +512,6 @@
     {
         m_pActionFind->setShortcut(QKeySequence("Ctrl+F"));
-        connect(m_pActionFind, &QAction::triggered, this, &UIVMLogViewerWidget::sltFind);
+        m_pActionFind->setCheckable(true);
+        connect(m_pActionFind, &QAction::triggered, this, &UIVMLogViewerWidget::sltShowHideSearchPanel);
     }
 
@@ -401,5 +521,6 @@
     {
         m_pActionFilter->setShortcut(QKeySequence("Ctrl+T"));
-        connect(m_pActionFilter, &QAction::triggered, this, &UIVMLogViewerWidget::sltFilter);
+        m_pActionFilter->setCheckable(true);
+        connect(m_pActionFilter, &QAction::triggered, this, &UIVMLogViewerWidget::sltShowHideFilterPanel);
     }
 
@@ -419,8 +540,18 @@
            already assigned to another action in the selector UI: */
         if (m_enmEmbedding == EmbedTo_Dialog)
-        {
             m_pActionSave->setShortcut(QKeySequence("Ctrl+S"));
-            connect(m_pActionSave, &QAction::triggered, this, &UIVMLogViewerWidget::sltSave);
-        }
+        connect(m_pActionSave, &QAction::triggered, this, &UIVMLogViewerWidget::sltSave);
+     }
+
+    /* Create and configure 'Bookmark' action: */
+    m_pActionBookmark = new QAction(this);
+    AssertPtrReturnVoid(m_pActionBookmark);
+    {
+        /* tie Ctrl+D to save only if we show this in a dialog since Ctrl+D is
+           already assigned to another action in the selector UI: */
+        if (m_enmEmbedding == EmbedTo_Dialog)
+            m_pActionBookmark->setShortcut(QKeySequence("Ctrl+D"));
+        m_pActionBookmark->setCheckable(true);
+        connect(m_pActionBookmark, &QAction::triggered, this, &UIVMLogViewerWidget::sltShowHideBookmarkPanel);
     }
 
@@ -451,5 +582,7 @@
                                                        QString(":/%1_save_disabled_24px.png").arg(strPrefix)));
 
-
+    if (m_pActionBookmark)
+        m_pActionBookmark->setIcon(UIIconPool::iconSet(QString(":/%1_bookmark_24px.png").arg(strPrefix),
+                                                       QString(":/%1_bookmark_disabled_24px.png").arg(strPrefix)));
 }
 
@@ -476,4 +609,7 @@
         if (m_pActionSave)
             m_pToolBar->addAction(m_pActionSave);
+
+        if (m_pActionBookmark)
+            m_pToolBar->addAction(m_pActionBookmark);
 
 #ifdef VBOX_WS_MAC
@@ -505,4 +641,7 @@
         if (m_pActionSave)
             m_pMenu->addAction(m_pActionSave);
+        if (m_pActionBookmark)
+            m_pMenu->addAction(m_pActionBookmark);
+
     }
 }
@@ -545,4 +684,11 @@
         m_pActionSave->setToolTip(tr("Save the log"));
         m_pActionSave->setStatusTip(tr("Save the log"));
+    }
+
+    if (m_pActionBookmark)
+    {
+        m_pActionBookmark->setText(tr("&Bookmark..."));
+        m_pActionBookmark->setToolTip(tr("Bookmark the line"));
+        m_pActionBookmark->setStatusTip(tr("Bookmark the line"));
     }
 
@@ -616,4 +762,11 @@
 }
 
+const QString* UIVMLogViewerWidget::currentLog()
+{
+    if(!currentLogPage())
+        return 0;
+    return &(m_logMap[currentLogPage()]);
+}
+
 QPlainTextEdit* UIVMLogViewerWidget::currentLogPage() const
 {
@@ -630,4 +783,29 @@
     return 0;
 }
+
+const QVector<LogBookmark>* UIVMLogViewerWidget::currentBookmarkVector() const
+{
+    UIVMLogViewerTextEdit *logPage = qobject_cast<UIVMLogViewerTextEdit*>(currentLogPage());
+    if(!logPage)
+        return 0;
+    QString logFileName = logPage->logFileName();
+    if(logFileName.isEmpty())
+        return 0;
+
+    return &(m_bookmarkMap[logFileName]);
+}
+
+QVector<LogBookmark>* UIVMLogViewerWidget::currentBookmarkVector()
+{
+    UIVMLogViewerTextEdit *logPage = qobject_cast<UIVMLogViewerTextEdit*>(currentLogPage());
+    if(!logPage)
+        return 0;
+    QString logFileName = logPage->logFileName();
+    if(logFileName.isEmpty())
+        return 0;
+
+    return &(m_bookmarkMap[logFileName]);
+}
+
 
 QPlainTextEdit* UIVMLogViewerWidget::logPage(int pIndex) const
@@ -671,5 +849,5 @@
             {
                 /* Create a log viewer page and append the read text to it: */
-                QPlainTextEdit *pLogViewer = createLogPage(QFileInfo(strFileName).fileName());
+                QPlainTextEdit *pLogViewer = createLogPage(strFileName);
                 pLogViewer->setPlainText(strText);
                 /* Move the cursor position to end: */
@@ -677,6 +855,4 @@
                 cursor.movePosition(QTextCursor::End, QTextCursor::MoveAnchor);
                 pLogViewer->setTextCursor(cursor);
-                /* Add the actual file name and the QPlainTextEdit containing the content to a list: */
-                m_book << qMakePair(strFileName, pLogViewer);
                 /* Add the log-text to the map: */
                 m_logMap[pLogViewer] = strText;
@@ -688,5 +864,5 @@
 }
 
-QPlainTextEdit* UIVMLogViewerWidget::createLogPage(const QString &strName)
+QPlainTextEdit* UIVMLogViewerWidget::createLogPage(const QString &strFileName)
 {
     /* Create page-container: */
@@ -698,5 +874,7 @@
         AssertPtrReturn(pPageLayout, 0);
         /* Create Log-Viewer: */
-        QPlainTextEdit *pLogViewer = new QPlainTextEdit(pPageContainer);
+        UIVMLogViewerTextEdit *pLogViewer = new UIVMLogViewerTextEdit(pPageContainer, strFileName);
+        connect(pLogViewer, &UIVMLogViewerTextEdit::sigContextMenuBookmarkAction,
+                this, &UIVMLogViewerWidget::sltCreateBookmarkAtLine);
 
         AssertPtrReturn(pLogViewer, 0);
@@ -722,12 +900,7 @@
         }
         /* Add page-container to viewer-container: */
-        m_pViewerContainer->addTab(pPageContainer, strName);
+        m_pViewerContainer->addTab(pPageContainer, QFileInfo(strFileName).fileName());
         return pLogViewer;
     }
-}
-
-const QString& UIVMLogViewerWidget::currentLog()
-{
-    return m_logMap[currentLogPage()];
 }
 
Index: /trunk/src/VBox/Frontends/VirtualBox/src/logviewer/UIVMLogViewerWidget.h
===================================================================
--- /trunk/src/VBox/Frontends/VirtualBox/src/logviewer/UIVMLogViewerWidget.h	(revision 70486)
+++ /trunk/src/VBox/Frontends/VirtualBox/src/logviewer/UIVMLogViewerWidget.h	(revision 70487)
@@ -37,11 +37,16 @@
 class QVBoxLayout;
 class UIToolBar;
+class UIVMLogViewerBookmarksPanel;
 class UIVMLogViewerFilterPanel;
 class UIVMLogViewerSearchPanel;
 
 /* Type definitions: */
-typedef QPair<QString, QPlainTextEdit*> LogPage;
-typedef QList<LogPage> LogBook;
+/** value is the content of the log file */
 typedef QMap<QPlainTextEdit*, QString> VMLogMap;
+/** first is line number, second is block text */
+typedef QPair<int, QString> LogBookmark;
+/** key is log file name, value is a vector of bookmarks. */
+typedef QMap<QString, QVector<LogBookmark> > BookmarkMap;
+
 
 /** QIMainWindow extension
@@ -78,20 +83,23 @@
 private slots:
 
-    /** Handles search action triggering. */
-    void sltFind();
     /** Handles refresh action triggering. */
     void sltRefresh();
     /** Handles save action triggering. */
     void sltSave();
-    /** Handles filter action triggering. */
-    void sltFilter();
+
+    void sltShowHideFilterPanel();
+    void sltShowHideSearchPanel();
+    void sltShowHideBookmarkPanel();
 
     /** Handles the search result highlight changes. */
     void sltSearchResultHighLigting();
-
     /** Handles the tab change of the logviewer. */
     void sltTabIndexChange(int tabIndex);
-
     void sltFilterApplied();
+    /* create a bookmark out of line number and block text. */
+    void sltCreateBookmarkAtLine(QPair<int, QString> bookmark);
+    /* Determines the (middle) line number of the visible text and calls sltCreateBookmarkAtLine. */
+    void sltCreateBookmarkAtCurrent();
+
 
 private:
@@ -129,6 +137,6 @@
     /** Returns the newly created log-page using @a strPage filename. */
     QPlainTextEdit* createLogPage(const QString &strPage);
-    /** Returns the content of current log-page. */
-    const QString& currentLog();
+    /** Returns the content of current log-file as it is read. */
+    const QString* currentLog();
 
     /** Attempts to read the logs through the API, returns true if there exists any logs, false otherwise. */
@@ -138,4 +146,8 @@
     void resetHighlighthing();
 
+    /** Returns the vector of bookmarks for the current log page */
+    QVector<LogBookmark>* currentBookmarkVector();
+    const QVector<LogBookmark>* currentBookmarkVector() const;
+
     /** Holds whether the dialog is polished. */
     bool m_fIsPolished;
@@ -152,13 +164,11 @@
     /** Holds the instance of search-panel. */
     UIVMLogViewerSearchPanel *m_pSearchPanel;
-
-    /** Holds the list of log-pages. */
-    LogBook m_book;
-
     /** Holds the instance of filter panel. */
     UIVMLogViewerFilterPanel *m_pFilterPanel;
-
-    /** Holds the list of log-content. */
-    VMLogMap m_logMap;
+    UIVMLogViewerBookmarksPanel *m_pBookmarksPanel;
+
+    /** Holds the list of log file content. */
+    VMLogMap             m_logMap;
+    mutable BookmarkMap  m_bookmarkMap;
 
     QVBoxLayout      *m_pMainLayout;
@@ -179,10 +189,14 @@
         /** Holds the Save action instance. */
         QAction   *m_pActionSave;
+        /** Holds the Bookmark action instance. */
+        QAction   *m_pActionBookmark;
+
         /** Holds the menu object instance. */
         QMenu     *m_pMenu;
     /** @} */
 
+    friend class UIVMLogViewerBookmarksPanel;
+    friend class UIVMLogViewerFilterPanel;
     friend class UIVMLogViewerSearchPanel;
-    friend class UIVMLogViewerFilterPanel;
 };
 
Index: /trunk/src/VBox/Frontends/VirtualBox/src/medium/UIMediumManager.cpp
===================================================================
--- /trunk/src/VBox/Frontends/VirtualBox/src/medium/UIMediumManager.cpp	(revision 70486)
+++ /trunk/src/VBox/Frontends/VirtualBox/src/medium/UIMediumManager.cpp	(revision 70487)
@@ -2468,3 +2468,2 @@
     return qobject_cast<UIMediumManagerWidget*>(QIManagerDialog::widget());
 }
-
