diff --git a/src/plugins/bineditor/bineditor.cpp b/src/plugins/bineditor/bineditor.cpp
index cc82aac138a54198213a33aa3e8d18254b0d148b..4046ab6a076641b75f3fbc36cf63d5112b5893ba 100644
--- a/src/plugins/bineditor/bineditor.cpp
+++ b/src/plugins/bineditor/bineditor.cpp
@@ -37,8 +37,10 @@
 #include <QtCore/QTemporaryFile>
 
 #include <QtGui/QApplication>
+#include <QtGui/QAction>
 #include <QtGui/QClipboard>
 #include <QtGui/QFontMetrics>
+#include <QtGui/QMenu>
 #include <QtGui/QPainter>
 #include <QtGui/QScrollBar>
 #include <QtGui/QWheelEvent>
@@ -93,6 +95,7 @@ BinEditor::BinEditor(QWidget *parent)
     m_lowNibble = false;
     m_cursorVisible = false;
     m_caseSensitiveSearch = false;
+    m_canRequestNewWindow = false;
     setFocusPolicy(Qt::WheelFocus);
 }
 
@@ -178,7 +181,8 @@ bool BinEditor::requestDataAt(int pos, bool synchronous) const
         if (!m_lazyRequests.contains(block)) {
             m_lazyRequests.insert(block);
             emit const_cast<BinEditor*>(this)->
-                lazyDataRequested(m_baseAddr / m_blockSize + block, synchronous);
+                lazyDataRequested(editorInterface(), m_baseAddr / m_blockSize + block,
+                                  synchronous);
             if (!m_lazyRequests.contains(block))
                 return true; // synchronous data source
         }
@@ -1119,12 +1123,16 @@ void BinEditor::zoomOut(int range)
     zoomIn(-range);
 }
 
-void BinEditor::copy()
+void BinEditor::copy(bool raw)
 {
     const int selStart = selectionStart();
     const int selEnd = selectionEnd();
     if (selStart < selEnd) {
         const QByteArray &data = dataMid(selStart, selEnd - selStart);
+        if (raw) {
+            QApplication::clipboard()->setText(data);
+            return;
+        }
         QString hexString;
         const char * const hex = "0123456789abcdef";
         for (int i = 0; i < data.size(); ++i) {
@@ -1217,3 +1225,81 @@ void BinEditor::redo()
     if (!m_redoStack.size())
         emit redoAvailable(false);
 }
+
+void BinEditor::contextMenuEvent(QContextMenuEvent *event)
+{
+    const int selStart = selectionStart();
+    const int byteCount = selectionEnd() - selStart;
+    if (byteCount == 0)
+        return;
+
+    QMenu contextMenu;
+    QAction copyAsciiAction(tr("Copy Selection as ASCII Characters"), this);
+    QAction copyHexAction(tr("Copy Selection as Hex Values"), this);
+    QMenu jumpBeMenu;
+    QMenu jumpLeMenu;
+    QAction jumpToBeAddressHere(tr("In This Window"), this);
+    QAction jumpToBeAddressNewWindow(tr("In New Window"), this);
+    QAction jumpToLeAddressHere(tr("In This Window"), this);
+    QAction jumpToLeAddressNewWindow(tr("In New Window"), this);
+    contextMenu.addAction(&copyAsciiAction);
+    contextMenu.addAction(&copyHexAction);
+    contextMenu.addMenu(&jumpBeMenu);
+
+    quint64 beAddress = 0;
+    quint64 leAddress = 0;
+    if (byteCount <= 8) {
+        const QByteArray &data = dataMid(selStart, byteCount);
+        for (int pos = 0; pos < byteCount; ++pos) {
+            const quint64 val = static_cast<quint64>(data.at(pos)) & 0xff;
+            beAddress += val << (pos * 8);
+            leAddress += val << ((byteCount - pos - 1) * 8);
+        }
+
+        setupJumpToMenuAction(&jumpBeMenu, &jumpToBeAddressHere,
+                              &jumpToBeAddressNewWindow, beAddress);
+
+        // If the menu entries would be identical, show only one of them.
+        if (beAddress != leAddress) {
+            setupJumpToMenuAction(&jumpLeMenu, &jumpToLeAddressHere,
+                              &jumpToLeAddressNewWindow, leAddress);
+            contextMenu.addMenu(&jumpLeMenu);
+        }
+    } else {
+        jumpBeMenu.setTitle(tr("Jump to Address"));
+        jumpBeMenu.setEnabled(false);
+    }
+
+    QAction *action = contextMenu.exec(event->globalPos());
+    if (action == &copyAsciiAction)
+        copy(true);
+    else if (action == &copyHexAction)
+        copy(false);
+    else if (action == &jumpToBeAddressHere)
+        setCursorPosition(beAddress - m_baseAddr);
+    else if (action == &jumpToLeAddressHere)
+        setCursorPosition(leAddress - m_baseAddr);
+    else if (action == &jumpToBeAddressNewWindow)
+        emit newWindowRequested(beAddress);
+    else if (action == &jumpToLeAddressNewWindow)
+        emit newWindowRequested(leAddress);
+}
+
+void BinEditor::setupJumpToMenuAction(QMenu *menu, QAction *actionHere,
+                                      QAction *actionNew, quint64 addr)
+{
+    menu->setTitle(tr("Jump to Address 0x%1").arg(QString::number(addr, 16)));
+    menu->addAction(actionHere);
+    if (addr < m_baseAddr || addr >= m_baseAddr + m_size)
+        actionHere->setEnabled(false);
+    if (!m_canRequestNewWindow)
+        actionNew->setEnabled(false);
+    menu->addAction(actionNew);
+    if (!actionHere->isEnabled() && !actionNew->isEnabled())
+        menu->setEnabled(false);
+}
+
+void BinEditor::setNewWindowRequestAllowed()
+{
+    m_canRequestNewWindow = true;
+}
diff --git a/src/plugins/bineditor/bineditor.h b/src/plugins/bineditor/bineditor.h
index bc62df085f37c05d5869aa681998774dd1fe136c..105ce4c42a24c3db86a26e229dc804a77f8cba5c 100644
--- a/src/plugins/bineditor/bineditor.h
+++ b/src/plugins/bineditor/bineditor.h
@@ -40,6 +40,8 @@
 #include <QtGui/QTextDocument>
 #include <QtGui/QTextFormat>
 
+QT_FORWARD_DECLARE_CLASS(QMenu)
+
 namespace Core {
 class IEditor;
 }
@@ -69,6 +71,7 @@ public:
     Q_INVOKABLE void setLazyData(quint64 startAddr, int range, int blockSize = 4096);
     inline int lazyDataBlockSize() const { return m_blockSize; }
     Q_INVOKABLE void addLazyData(quint64 block, const QByteArray &data);
+    Q_INVOKABLE void setNewWindowRequestAllowed();
     bool save(const QString &oldFileName, const QString &newFileName);
 
     void zoomIn(int range = 1);
@@ -116,7 +119,7 @@ public:
 public Q_SLOTS:
     void setFontSettings(const TextEditor::FontSettings &fs);
     void highlightSearchResults(const QByteArray &pattern, QTextDocument::FindFlags findFlags = 0);
-    void copy();
+    void copy(bool raw = false);
 
 Q_SIGNALS:
     void modificationChanged(bool modified);
@@ -125,7 +128,8 @@ Q_SIGNALS:
     void copyAvailable(bool);
     void cursorPositionChanged(int position);
 
-    void lazyDataRequested(quint64 block, bool synchronous);
+    void lazyDataRequested(Core::IEditor *editor, quint64 block, bool synchronous);
+    void newWindowRequested(quint64 address);
 
 protected:
     void scrollContentsBy(int dx, int dy);
@@ -140,6 +144,7 @@ protected:
     void focusInEvent(QFocusEvent *);
     void focusOutEvent(QFocusEvent *);
     void timerEvent(QTimerEvent *);
+    void contextMenuEvent(QContextMenuEvent *event);
 
 private:
     bool m_inLazyMode;
@@ -203,6 +208,9 @@ private:
     int findPattern(const QByteArray &data, const QByteArray &dataHex, int from, int offset, int *match);
     void drawItems(QPainter *painter, int x, int y, const QString &itemString);
 
+    void setupJumpToMenuAction(QMenu *menu, QAction *actionHere, QAction *actionNew,
+                               quint64 addr);
+
     struct BinEditorEditCommand {
         int position;
         uchar character;
@@ -214,6 +222,7 @@ private:
     Core::IEditor *m_ieditor;
     QString m_addressString;
     int m_addressBytes;
+    bool m_canRequestNewWindow;
 };
 
 } // namespace BINEditor
diff --git a/src/plugins/bineditor/bineditorplugin.cpp b/src/plugins/bineditor/bineditorplugin.cpp
index 4faeccf10aa6b9503fc166abf8fbeb8fe6ea880a..fe7f3f489a92b7d31c0b7f17586f6f0deaa127de 100644
--- a/src/plugins/bineditor/bineditorplugin.cpp
+++ b/src/plugins/bineditor/bineditorplugin.cpp
@@ -174,7 +174,8 @@ public:
         m_mimeType(QLatin1String(BINEditor::Constants::C_BINEDITOR_MIMETYPE))
     {
         m_editor = parent;
-        connect(m_editor, SIGNAL(lazyDataRequested(quint64, bool)), this, SLOT(provideData(quint64)));
+        connect(m_editor, SIGNAL(lazyDataRequested(Core::IEditor *, quint64, bool)),
+            this, SLOT(provideData(Core::IEditor *, quint64)));
     }
     ~BinEditorFile() {}
 
@@ -211,7 +212,7 @@ public:
     }
 
 private slots:
-    void provideData(quint64 block) {
+    void provideData(Core::IEditor *, quint64 block) {
         QFile file(m_fileName);
         if (file.open(QIODevice::ReadOnly)) {
             int blockSize = m_editor->lazyDataBlockSize();
diff --git a/src/plugins/debugger/cdb/cdbdebugengine.cpp b/src/plugins/debugger/cdb/cdbdebugengine.cpp
index 2231a5c259c0845d399400920c2cd4bdd3e84441..5869de1660e0da67a57915bab540954b370ec613 100644
--- a/src/plugins/debugger/cdb/cdbdebugengine.cpp
+++ b/src/plugins/debugger/cdb/cdbdebugengine.cpp
@@ -1135,7 +1135,7 @@ void CdbDebugEngine::fetchDisassembler(DisassemblerViewAgent *agent)
     }
 }
 
-void CdbDebugEngine::fetchMemory(MemoryViewAgent *agent, quint64 addr, quint64 length)
+void CdbDebugEngine::fetchMemory(MemoryViewAgent *agent, QObject *token, quint64 addr, quint64 length)
 {
     if (!m_d->m_hDebuggeeProcess && !length)
         return;
@@ -1149,7 +1149,7 @@ void CdbDebugEngine::fetchMemory(MemoryViewAgent *agent, quint64 addr, quint64 l
     }
     if (received < length)
         data.truncate(received);
-    agent->addLazyData(addr, data);
+    agent->addLazyData(token, addr, data);
 }
 
 void CdbDebugEngine::reloadModules()
diff --git a/src/plugins/debugger/cdb/cdbdebugengine.h b/src/plugins/debugger/cdb/cdbdebugengine.h
index 9265ce757f2ae205915e3880bf9cd5402d1c3898..d6f6bebb0198ffd8f17996c66c5a4d3a8379b5c6 100644
--- a/src/plugins/debugger/cdb/cdbdebugengine.h
+++ b/src/plugins/debugger/cdb/cdbdebugengine.h
@@ -90,7 +90,7 @@ public:
     virtual void attemptBreakpointSynchronization();
 
     virtual void fetchDisassembler(DisassemblerViewAgent *agent);
-    virtual void fetchMemory(MemoryViewAgent *, quint64 addr, quint64 length);
+    virtual void fetchMemory(MemoryViewAgent *, QObject *, quint64 addr, quint64 length);
 
     virtual void reloadModules();
     virtual void loadSymbols(const QString &moduleName);
diff --git a/src/plugins/debugger/debuggeragents.cpp b/src/plugins/debugger/debuggeragents.cpp
index 7874c204dd347b0734629b033f838325ebce2817..49559ea2a084ea5df01df15c06225688f652e60f 100644
--- a/src/plugins/debugger/debuggeragents.cpp
+++ b/src/plugins/debugger/debuggeragents.cpp
@@ -72,35 +72,41 @@ namespace Internal {
 MemoryViewAgent::MemoryViewAgent(DebuggerManager *manager, quint64 addr)
     : QObject(manager), m_engine(manager->currentEngine()), m_manager(manager)
 {
-    init(addr);
+    createBinEditor(addr);
 }
 
 MemoryViewAgent::MemoryViewAgent(DebuggerManager *manager, const QString &addr)
     : QObject(manager), m_engine(manager->currentEngine()), m_manager(manager)
 {
     bool ok = true;
-    init(addr.toULongLong(&ok, 0));
+    createBinEditor(addr.toULongLong(&ok, 0));
     //qDebug() <<  " ADDRESS: " << addr <<  addr.toUInt(&ok, 0);
 }
 
 MemoryViewAgent::~MemoryViewAgent()
 {
-    if (m_editor)
-        m_editor->deleteLater();
+    foreach (QPointer<Core::IEditor> editor, m_editors) {
+        if (editor)
+            editor->deleteLater();
+    }
 }
 
-void MemoryViewAgent::init(quint64 addr)
+void MemoryViewAgent::createBinEditor(quint64 addr)
 {
     Core::EditorManager *editorManager = Core::EditorManager::instance();
     QString titlePattern = tr("Memory $");
-    m_editor = editorManager->openEditorWithContents(
+    Core::IEditor *editor = editorManager->openEditorWithContents(
         Core::Constants::K_DEFAULT_BINARY_EDITOR_ID,
         &titlePattern);
-    if (m_editor) {
-        connect(m_editor->widget(), SIGNAL(lazyDataRequested(quint64,bool)),
-            this, SLOT(fetchLazyData(quint64,bool)));
-        editorManager->activateEditor(m_editor);
-        QMetaObject::invokeMethod(m_editor->widget(), "setLazyData",
+    if (editor) {
+        connect(editor->widget(), SIGNAL(lazyDataRequested(Core::IEditor *, quint64,bool)),
+            this, SLOT(fetchLazyData(Core::IEditor *, quint64,bool)));
+        connect(editor->widget(), SIGNAL(newWindowRequested(quint64)),
+            this, SLOT(createBinEditor(quint64)));
+        m_editors << editor;
+        editorManager->activateEditor(editor);
+        QMetaObject::invokeMethod(editor->widget(), "setNewWindowRequestAllowed");
+        QMetaObject::invokeMethod(editor->widget(), "setLazyData",
             Q_ARG(quint64, addr), Q_ARG(int, 1024 * 1024), Q_ARG(int, BinBlockSize));
     } else {
         m_manager->showMessageBox(QMessageBox::Warning,
@@ -111,18 +117,22 @@ void MemoryViewAgent::init(quint64 addr)
     }
 }
 
-void MemoryViewAgent::fetchLazyData(quint64 block, bool sync)
+void MemoryViewAgent::fetchLazyData(Core::IEditor *editor, quint64 block, bool sync)
 {
     Q_UNUSED(sync); // FIXME: needed support for incremental searching
     if (m_engine)
-        m_engine->fetchMemory(this, BinBlockSize * block, BinBlockSize);
+        m_engine->fetchMemory(this, editor, BinBlockSize * block, BinBlockSize);
 }
 
-void MemoryViewAgent::addLazyData(quint64 addr, const QByteArray &ba)
+void MemoryViewAgent::addLazyData(QObject *editorToken, quint64 addr,
+                                  const QByteArray &ba)
 {
-    if (m_editor && m_editor->widget())
-        QMetaObject::invokeMethod(m_editor->widget(), "addLazyData",
+    Core::IEditor *editor = qobject_cast<Core::IEditor *>(editorToken);
+    if (editor && editor->widget()) {
+        Core::EditorManager::instance()->activateEditor(editor);
+        QMetaObject::invokeMethod(editor->widget(), "addLazyData",
             Q_ARG(quint64, addr / BinBlockSize), Q_ARG(QByteArray, ba));
+    }
 }
 
 
diff --git a/src/plugins/debugger/debuggeragents.h b/src/plugins/debugger/debuggeragents.h
index 63d3e7ba238f29083efcca36f6e21bdcbf5c5dd3..d34f4702203536cc0bd33cfde153d6c319167e1d 100644
--- a/src/plugins/debugger/debuggeragents.h
+++ b/src/plugins/debugger/debuggeragents.h
@@ -37,6 +37,7 @@
 
 #include <QtCore/QObject>
 #include <QtCore/QDebug>
+#include <QtCore/QList>
 #include <QtCore/QPointer>
 #include <QtGui/QAction>
 
@@ -61,15 +62,15 @@ public:
 
 public slots:
     // Called from Engine
-    void addLazyData(quint64 addr, const QByteArray &data);
+    void addLazyData(QObject *editorToken, quint64 addr, const QByteArray &data);
     // Called from Editor
-    void fetchLazyData(quint64 block, bool sync);
+    void fetchLazyData(Core::IEditor *, quint64 block, bool sync);
 
 private:
-    void init(quint64 startaddr);
+    Q_SLOT void createBinEditor(quint64 startAddr);
 
     QPointer<IDebuggerEngine> m_engine;
-    QPointer<Core::IEditor> m_editor;
+    QList<QPointer<Core::IEditor> > m_editors;
     QPointer<DebuggerManager> m_manager;
 };
 
diff --git a/src/plugins/debugger/gdb/gdbengine.cpp b/src/plugins/debugger/gdb/gdbengine.cpp
index 14f8b65a058c448c0ea4c1b3432fc8858fe34c7b..a169b9df4a08320d6f448224d90810e27959ad37 100644
--- a/src/plugins/debugger/gdb/gdbengine.cpp
+++ b/src/plugins/debugger/gdb/gdbengine.cpp
@@ -3542,21 +3542,23 @@ void GdbEngine::handleWatchPoint(const GdbResponse &response)
 
 struct MemoryAgentCookie
 {
-    MemoryAgentCookie() : agent(0), address(0) {}
-    MemoryAgentCookie(MemoryViewAgent *agent_, quint64 address_)
-        : agent(agent_), address(address_)
+    MemoryAgentCookie() : agent(0), token(0), address(0) {}
+    MemoryAgentCookie(MemoryViewAgent *agent_, QObject *token_, quint64 address_)
+        : agent(agent_), token(token_), address(address_)
     {}
     QPointer<MemoryViewAgent> agent;
+    QPointer<QObject> token;
     quint64 address;
 };
 
-void GdbEngine::fetchMemory(MemoryViewAgent *agent, quint64 addr, quint64 length)
+void GdbEngine::fetchMemory(MemoryViewAgent *agent, QObject *token, quint64 addr,
+                            quint64 length)
 {
     //qDebug() << "GDB MEMORY FETCH" << agent << addr << length;
     postCommand("-data-read-memory " + QByteArray::number(addr) + " x 1 1 "
             + QByteArray::number(length),
         NeedsStop, CB(handleFetchMemory),
-        QVariant::fromValue(MemoryAgentCookie(agent, addr)));
+        QVariant::fromValue(MemoryAgentCookie(agent, token, addr)));
 }
 
 void GdbEngine::handleFetchMemory(const GdbResponse &response)
@@ -3581,7 +3583,7 @@ void GdbEngine::handleFetchMemory(const GdbResponse &response)
         QTC_ASSERT(ok, return);
         ba.append(c);
     }
-    ac.agent->addLazyData(ac.address, ba);
+    ac.agent->addLazyData(ac.token, ac.address, ba);
 }
 
 
diff --git a/src/plugins/debugger/gdb/gdbengine.h b/src/plugins/debugger/gdb/gdbengine.h
index 479a6d64b3e25b3ef9aefb8b54c39bb8a06c00a0..46234eeff7acb2c11daf9d09d6a34a0b28cc3944 100644
--- a/src/plugins/debugger/gdb/gdbengine.h
+++ b/src/plugins/debugger/gdb/gdbengine.h
@@ -428,7 +428,8 @@ private: ////////// View & Data Stuff //////////
 
     virtual void assignValueInDebugger(const QString &expr, const QString &value);
 
-    virtual void fetchMemory(MemoryViewAgent *agent, quint64 addr, quint64 length);
+    virtual void fetchMemory(MemoryViewAgent *agent, QObject *token,
+        quint64 addr, quint64 length);
     void handleFetchMemory(const GdbResponse &response);
 
     virtual void watchPoint(const QPoint &);
diff --git a/src/plugins/debugger/idebuggerengine.h b/src/plugins/debugger/idebuggerengine.h
index 6409ae5cb9569f2c7feec39fabe0be93fd768d3e..7756c6ee37f28a09609ab2637acce13eabf26f6f 100644
--- a/src/plugins/debugger/idebuggerengine.h
+++ b/src/plugins/debugger/idebuggerengine.h
@@ -112,7 +112,7 @@ public:
     virtual void reloadFullStack() = 0;
 
     virtual void watchPoint(const QPoint &) {}
-    virtual void fetchMemory(MemoryViewAgent *, quint64 addr, quint64 length)
+    virtual void fetchMemory(MemoryViewAgent *, QObject *, quint64 addr, quint64 length)
         { Q_UNUSED(addr); Q_UNUSED(length); }
     virtual void fetchDisassembler(DisassemblerViewAgent *) {}
     virtual void setRegisterValue(int regnr, const QString &value)