diff --git a/src/plugins/coreplugin/coreconstants.h b/src/plugins/coreplugin/coreconstants.h
index 1bdc864a0743fecbc15846c154cff43cbde5f2c2..db0b96591faf314d8aa7bdbe3c0b9e181e0e8430 100644
--- a/src/plugins/coreplugin/coreconstants.h
+++ b/src/plugins/coreplugin/coreconstants.h
@@ -109,7 +109,7 @@ const char SPLIT_SIDE_BY_SIDE[]    = "QtCreator.SplitSideBySide";
 const char SPLIT_NEW_WINDOW[]      = "QtCreator.SplitNewWindow";
 const char REMOVE_CURRENT_SPLIT[]  = "QtCreator.RemoveCurrentSplit";
 const char REMOVE_ALL_SPLITS[]     = "QtCreator.RemoveAllSplits";
-const char GOTO_OTHER_SPLIT[]      = "QtCreator.GotoOtherSplit";
+const char GOTO_NEXT_SPLIT[]      = "QtCreator.GotoOtherSplit";
 const char CLOSE[]                 = "QtCreator.Close";
 const char CLOSE_ALTERNATIVE[]     = "QtCreator.Close_Alternative"; // temporary, see QTCREATORBUG-72
 const char CLOSEALL[]              = "QtCreator.CloseAll";
diff --git a/src/plugins/coreplugin/editormanager/editormanager.cpp b/src/plugins/coreplugin/editormanager/editormanager.cpp
index 88762f1f29853a3aeeee779375b94cd573db4387..b31a5d131b55d90bcce454d3203170e12e6df42e 100644
--- a/src/plugins/coreplugin/editormanager/editormanager.cpp
+++ b/src/plugins/coreplugin/editormanager/editormanager.cpp
@@ -196,7 +196,7 @@ struct EditorManagerPrivate
     QAction *m_splitNewWindowAction;
     QAction *m_removeCurrentSplitAction;
     QAction *m_removeAllSplitsAction;
-    QAction *m_gotoOtherSplitAction;
+    QAction *m_gotoNextSplitAction;
 
     QAction *m_saveCurrentEditorContextAction;
     QAction *m_saveAsCurrentEditorContextAction;
@@ -399,11 +399,11 @@ EditorManager::EditorManager(QWidget *parent) :
     mwindow->addAction(cmd, Constants::G_WINDOW_SPLIT);
     connect(d->m_removeAllSplitsAction, SIGNAL(triggered()), this, SLOT(removeAllSplits()));
 
-    d->m_gotoOtherSplitAction = new QAction(tr("Go to Next Split"), this);
-    cmd = ActionManager::registerAction(d->m_gotoOtherSplitAction, Constants::GOTO_OTHER_SPLIT, editManagerContext);
+    d->m_gotoNextSplitAction = new QAction(tr("Go to Next Split"), this);
+    cmd = ActionManager::registerAction(d->m_gotoNextSplitAction, Constants::GOTO_NEXT_SPLIT, editManagerContext);
     cmd->setDefaultKeySequence(QKeySequence(UseMacShortcuts ? tr("Meta+E,o") : tr("Ctrl+E,o")));
     mwindow->addAction(cmd, Constants::G_WINDOW_SPLIT);
-    connect(d->m_gotoOtherSplitAction, SIGNAL(triggered()), this, SLOT(gotoOtherSplit()));
+    connect(d->m_gotoNextSplitAction, SIGNAL(triggered()), this, SLOT(gotoNextSplit()));
 
     ActionContainer *medit = ActionManager::actionContainer(Constants::M_EDIT);
     ActionContainer *advancedMenu = ActionManager::createMenu(Constants::M_EDIT_ADVANCED);
@@ -604,13 +604,20 @@ EditorView *EditorManager::viewForEditor(IEditor *editor)
     return 0;
 }
 
-SplitterOrView *EditorManager::findRoot(EditorView *view)
+SplitterOrView *EditorManager::findRoot(const EditorView *view, int *rootIndex)
 {
     SplitterOrView *current = view->parentSplitterOrView();
-    while (current && !m_instance->d->m_root.contains(current)) {
+    while (current) {
+        int index = m_instance->d->m_root.indexOf(current);
+        if (index >= 0) {
+            if (rootIndex)
+                *rootIndex = index;
+            return current;
+        }
         current = current->findParentSplitter();
     }
-    return current;
+    QTC_CHECK(false); // we should never have views without a root
+    return 0;
 }
 
 QList<IEditor *> EditorManager::editorsForFileName(const QString &filename) const
@@ -1151,6 +1158,18 @@ void EditorManager::activateEditorForIndex(Internal::EditorView *view, const QMo
         d->m_editorModel->removeEditor(index);
 }
 
+void EditorManager::activateView(EditorView *view)
+{
+    QTC_ASSERT(view, return);
+    if (IEditor *editor = view->currentEditor()) {
+        setCurrentEditor(editor, true);
+        editor->widget()->setFocus();
+        ICore::raiseWindow(editor->widget());
+    } else {
+        setCurrentView(view);
+    }
+}
+
 Core::IEditor *EditorManager::placeEditor(Core::Internal::EditorView *view, Core::IEditor *editor)
 {
     Q_ASSERT(view && editor);
@@ -1398,11 +1417,8 @@ IEditor *EditorManager::openEditor(const QString &fileName, const Id &editorId,
                                   fileName, editorId, flags, newEditor);
 }
 
-IEditor *EditorManager::openEditorInNextSplit(const QString &fileName, const Id &editorId, OpenEditorFlags flags, bool *newEditor)
+IEditor *EditorManager::openEditorInOtherSplit(const QString &fileName, const Id &editorId, OpenEditorFlags flags, bool *newEditor)
 {
-    if (!m_instance->hasSplitter())
-        m_instance->splitSideBySide();
-
     m_instance->gotoOtherSplit();
     return m_instance->openEditor(m_instance->currentEditorView(),
                                   fileName, editorId, flags, newEditor);
@@ -1973,7 +1989,7 @@ void EditorManager::updateActions()
     bool hasSplitter = parentSplitter && parentSplitter->isSplitter();
     d->m_removeCurrentSplitAction->setEnabled(hasSplitter);
     d->m_removeAllSplitsAction->setEnabled(hasSplitter);
-    d->m_gotoOtherSplitAction->setEnabled(hasSplitter);
+    d->m_gotoNextSplitAction->setEnabled(hasSplitter || d->m_root.size() > 1);
 }
 
 void EditorManager::setCloseSplitEnabled(SplitterOrView *splitterOrView, bool enable)
@@ -2010,7 +2026,8 @@ QList<IEditor*> EditorManager::visibleEditors() const
                     if (view->currentEditor())
                         editors.append(view->currentEditor());
                     view = view->findNextView();
-                } while (view && view != firstView);
+                    QTC_ASSERT(view != firstView, break); // we start with firstView and shouldn't have cycles
+                } while (view);
             }
         } else {
             if (root->editor())
@@ -2375,26 +2392,77 @@ void EditorManager::removeAllSplits()
     root->unsplitAll();
 }
 
+/*!
+ * Moves focus to the next split, cycling through windows.
+ */
+void EditorManager::gotoNextSplit()
+{
+    EditorView *view = currentEditorView();
+    if (!view)
+        return;
+    EditorView *nextView = view->findNextView();
+    if (!nextView) {
+        // we are in the "last" view in this root
+        int rootIndex = -1;
+        SplitterOrView *root = findRoot(view, &rootIndex);
+        QTC_ASSERT(root, return);
+        QTC_ASSERT(rootIndex >= 0 && rootIndex < d->m_root.size(), return);
+        // find next root. this might be the same root if there's only one.
+        int nextRootIndex = rootIndex + 1;
+        if (nextRootIndex >= d->m_root.size())
+            nextRootIndex = 0;
+        nextView = d->m_root.at(nextRootIndex)->findFirstView();
+        QTC_CHECK(nextView);
+    }
+
+    if (nextView)
+        activateView(nextView);
+}
+
+/*!
+ * Moves focus to "other" split, possibly creating a split if necessary.
+ * If there's no split and no other window, a side-by-side split is created.
+ * If the current window is split, focus is moved to the next split within this window, cycling.
+ * If the current window is not split, focus is moved to the next window.
+ */
 void EditorManager::gotoOtherSplit()
 {
     EditorView *view = currentEditorView();
     if (!view)
         return;
-    SplitterOrView *root = findRoot(view);
-    QTC_ASSERT(root, return);
-    if (!root->isSplitter())
-        splitSideBySide();
-
-    view = view->findNextView();
-    if (view) {
-        if (IEditor *editor = view->currentEditor()) {
-            setCurrentEditor(editor, true);
-            editor->widget()->setFocus();
-            ICore::raiseWindow(editor->widget());
+    EditorView *nextView = view->findNextView();
+    if (!nextView) {
+        // we are in the "last" view in this root
+        int rootIndex = -1;
+        SplitterOrView *root = findRoot(view, &rootIndex);
+        QTC_ASSERT(root, return);
+        QTC_ASSERT(rootIndex >= 0 && rootIndex < d->m_root.size(), return);
+        // stay in same window if it is split
+        if (root->isSplitter()) {
+            nextView = root->findFirstView();
+            QTC_CHECK(nextView != view);
         } else {
-            setCurrentView(view);
+            // find next root. this might be the same root if there's only one.
+            int nextRootIndex = rootIndex + 1;
+            if (nextRootIndex >= d->m_root.size())
+                nextRootIndex = 0;
+            nextView = d->m_root.at(nextRootIndex)->findFirstView();
+            QTC_CHECK(nextView);
+            // if we had only one root with only one view, we end up at the startpoint
+            // in that case we need to split
+            if (nextView == view) {
+                QTC_CHECK(!root->isSplitter());
+                splitSideBySide(); // that deletes 'view'
+                view = root->findFirstView();
+                nextView = view->findNextView();
+                QTC_CHECK(nextView != view);
+                QTC_CHECK(nextView);
+            }
         }
     }
+
+    if (nextView)
+        activateView(nextView);
 }
 
 qint64 EditorManager::maxTextFileSize()
diff --git a/src/plugins/coreplugin/editormanager/editormanager.h b/src/plugins/coreplugin/editormanager/editormanager.h
index 1dabf2f3685ade99819e5d85e3f34ba5e7da18eb..74297304602485be44657a36495a6faf3a7bb90c 100644
--- a/src/plugins/coreplugin/editormanager/editormanager.h
+++ b/src/plugins/coreplugin/editormanager/editormanager.h
@@ -117,7 +117,7 @@ public:
     static QString splitLineNumber(QString *fileName);
     static IEditor *openEditor(const QString &fileName, const Id &editorId = Id(),
         OpenEditorFlags flags = 0, bool *newEditor = 0);
-    static IEditor *openEditorInNextSplit(const QString &fileName, const Id &editorId = Id(),
+    static IEditor *openEditorInOtherSplit(const QString &fileName, const Id &editorId = Id(),
         OpenEditorFlags flags = 0, bool *newEditor = 0);
     static IEditor *openEditorWithContents(const Id &editorId,
         QString *titlePattern = 0, const QString &contents = QString());
@@ -234,6 +234,8 @@ private slots:
     void rootDestroyed(QObject *root);
     void setCurrentEditorFromContextChange();
 
+    void gotoNextSplit();
+
 public slots:
     void goBackInNavigationHistory();
     void goForwardInNavigationHistory();
@@ -257,6 +259,7 @@ private:
     IEditor *duplicateEditor(IEditor *editor);
     IEditor *activateEditor(Internal::EditorView *view, IEditor *editor, OpenEditorFlags flags = 0);
     void activateEditorForIndex(Internal::EditorView *view, const QModelIndex &index, OpenEditorFlags = 0);
+    void activateView(Internal::EditorView *view);
     IEditor *openEditor(Internal::EditorView *view, const QString &fileName,
         const Id &id = Id(), OpenEditorFlags flags = 0, bool *newEditor = 0);
 
@@ -264,7 +267,7 @@ private:
     void setCurrentView(Internal::EditorView *view);
     Internal::EditorView *currentEditorView() const;
     static Internal::EditorView *viewForEditor(IEditor *editor);
-    static Internal::SplitterOrView *findRoot(Internal::EditorView *view);
+    static Internal::SplitterOrView *findRoot(const Internal::EditorView *view, int *rootIndex = 0);
 
     void closeEditor(IEditor *editor);
     void closeDuplicate(IEditor *editor);
diff --git a/src/plugins/coreplugin/editormanager/editorview.cpp b/src/plugins/coreplugin/editormanager/editorview.cpp
index 87e4ecee5aa486f642576ab86d5a601daa20fc82..30cbb9c0233dfb163835f0e76f4b550e4e66a182 100644
--- a/src/plugins/coreplugin/editormanager/editorview.cpp
+++ b/src/plugins/coreplugin/editormanager/editorview.cpp
@@ -144,8 +144,8 @@ EditorView *EditorView::findNextView()
         current = parent;
         parent = current->findParentSplitter();
     }
-    // current has no parent, so just take the very first view
-    return current->findFirstView();
+    // current has no parent, so we are at the top and there is no "next" view
+    return 0;
 }
 
 void EditorView::closeView()
diff --git a/src/plugins/cppeditor/cppeditor.cpp b/src/plugins/cppeditor/cppeditor.cpp
index dd42d6cb7f28b75985caeb633263c8059e32d373..00e6a932378714e8a094aae5f977c094ec51559b 100644
--- a/src/plugins/cppeditor/cppeditor.cpp
+++ b/src/plugins/cppeditor/cppeditor.cpp
@@ -1994,8 +1994,6 @@ bool CPPEditorWidget::openCppEditorAt(const Link &link, bool inNextSplit)
 
     Core::EditorManager *editorManager = Core::EditorManager::instance();
     if (inNextSplit) {
-        if (!editorManager->hasSplitter())
-            editorManager->splitSideBySide();
         editorManager->gotoOtherSplit();
     } else if (baseTextDocument()->fileName() == link.targetFileName) {
         editorManager->addCurrentPositionToNavigationHistory();
diff --git a/src/plugins/cpptools/cpptoolsplugin.cpp b/src/plugins/cpptools/cpptoolsplugin.cpp
index 7f70a37640c9cfb21620743049bfeba69d9c3fe5..66e8a6896607ad9a629b6215d92de77eab3a23f2 100644
--- a/src/plugins/cpptools/cpptoolsplugin.cpp
+++ b/src/plugins/cpptools/cpptoolsplugin.cpp
@@ -164,7 +164,7 @@ void CppToolsPlugin::switchHeaderSourceInNextSplit()
     QString otherFile = correspondingHeaderOrSource(
                 Core::EditorManager::currentEditor()->document()->fileName());
     if (!otherFile.isEmpty())
-        Core::EditorManager::openEditorInNextSplit(otherFile);
+        Core::EditorManager::openEditorInOtherSplit(otherFile);
 }
 
 static QStringList findFilesInProject(const QString &name,
diff --git a/src/plugins/fakevim/fakevimplugin.cpp b/src/plugins/fakevim/fakevimplugin.cpp
index 235696eda64dec69e58683f8706855bd3b99b94d..3d9c30356a8e0eb58a95fa42d395ec79b3422aae 100644
--- a/src/plugins/fakevim/fakevimplugin.cpp
+++ b/src/plugins/fakevim/fakevimplugin.cpp
@@ -1324,7 +1324,7 @@ void FakeVimPluginPrivate::windowCommand(const QString &map, int count)
     else if (key == _("S") || key == _("<C-S>"))
         triggerAction(Core::Constants::SPLIT);
     else if (key == _("W") || key == _("<C-W>"))
-        triggerAction(Core::Constants::GOTO_OTHER_SPLIT);
+        triggerAction(Core::Constants::GOTO_NEXT_SPLIT);
     else if (key.contains(_("RIGHT")) || key == _("L") || key == _("<S-L>"))
         moveSomewhere(&moveRightWeight, key == _("<S-L>") ? -1 : count);
     else if (key.contains(_("LEFT"))  || key == _("H") || key == _("<S-H>"))
diff --git a/src/plugins/texteditor/basetexteditor.cpp b/src/plugins/texteditor/basetexteditor.cpp
index 2b3f5eef3abc420fb741ac12170c7f45130a5ea2..3984a4ca9b7477954cd1218cad95f80467ee47b3 100644
--- a/src/plugins/texteditor/basetexteditor.cpp
+++ b/src/plugins/texteditor/basetexteditor.cpp
@@ -4910,8 +4910,6 @@ bool BaseTextEditorWidget::openLink(const Link &link, bool inNextSplit)
 
     Core::EditorManager *editorManager = Core::EditorManager::instance();
     if (inNextSplit) {
-        if (!editorManager->hasSplitter())
-            editorManager->splitSideBySide();
         editorManager->gotoOtherSplit();
     } else if (baseTextDocument()->fileName() == link.targetFileName) {
         editorManager->addCurrentPositionToNavigationHistory();