diff --git a/src/libs/qmljsdebugclient/qmlprofilereventlist.cpp b/src/libs/qmljsdebugclient/qmlprofilereventlist.cpp
index 51531af8211e40c7d0d403ba9aa283b586d59788..0bca4e029aeab614ad3ca45c642512e89d0b2b2e 100644
--- a/src/libs/qmljsdebugclient/qmlprofilereventlist.cpp
+++ b/src/libs/qmljsdebugclient/qmlprofilereventlist.cpp
@@ -71,6 +71,7 @@ QmlEventData::QmlEventData()
     timePerCall = 0;
     percentOfTime = 0;
     medianTime = 0;
+    isBindingLoop = false;
 }
 
 QmlEventData::~QmlEventData()
@@ -99,6 +100,7 @@ QmlEventData &QmlEventData::operator=(const QmlEventData &ref)
     percentOfTime = ref.percentOfTime;
     medianTime = ref.medianTime;
     eventId = ref.eventId;
+    isBindingLoop = ref.isBindingLoop;
 
     qDeleteAll(parentHash.values());
     parentHash.clear();
@@ -182,6 +184,8 @@ struct QmlEventStartTimeData {
     // animation-related data
     int frameRate;
     int animationCount;
+
+    int bindingLoopHead;
 };
 
 struct QmlEventTypeCount {
@@ -790,6 +794,9 @@ void QmlProfilerEventList::compileStatistics(qint64 startTime, qint64 endTime)
             iter.key()->medianTime = iter.value().at(iter.value().count()/2);
         }
     }
+
+    // find binding loops
+    findBindingLoops(startTime, endTime);
 }
 
 void QmlProfilerEventList::prepareForDisplay()
@@ -1063,6 +1070,59 @@ void QmlProfilerEventList::finishedRewritingDetails()
     emit reloadDetailLabels();
 }
 
+void QmlProfilerEventList::findBindingLoops(qint64 startTime, qint64 endTime)
+{
+    // first clear existing data
+    foreach (QmlEventData *event, d->m_eventDescriptions.values()) {
+        event->isBindingLoop = false;
+        foreach (QmlEventSub *parentEvent, event->parentHash.values())
+            parentEvent->inLoopPath = false;
+        foreach (QmlEventSub *childEvent, event->childrenHash.values())
+            childEvent->inLoopPath = false;
+    }
+
+    QList <QmlEventData *> stackRefs;
+    QList <QmlEventStartTimeData *> stack;
+    int fromIndex = findFirstIndex(startTime);
+    int toIndex = findLastIndex(endTime);
+
+    for (int i = 0; i < d->m_startTimeSortedList.count(); i++) {
+        QmlEventData *currentEvent = d->m_startTimeSortedList[i].description;
+        QmlEventStartTimeData *inTimeEvent = &d->m_startTimeSortedList[i];
+        inTimeEvent->bindingLoopHead = -1;
+
+        // managing call stack
+        for (int j = stack.count() - 1; j >= 0; j--) {
+            if (stack[j]->startTime + stack[j]->length < inTimeEvent->startTime) {
+                stack.removeAt(j);
+                stackRefs.removeAt(j);
+            }
+        }
+
+        bool loopDetected = stackRefs.contains(currentEvent);
+        stack << inTimeEvent;
+        stackRefs << currentEvent;
+
+        if (loopDetected) {
+            if (i >= fromIndex && i <= toIndex) {
+                // for the statistics
+                currentEvent->isBindingLoop = true;
+                for (int j = stackRefs.indexOf(currentEvent); j < stackRefs.count()-1; j++) {
+                    QmlEventSub *nextEventSub = stackRefs[j]->childrenHash.value(stackRefs[j+1]->eventHashStr);
+                    nextEventSub->inLoopPath = true;
+                    QmlEventSub *prevEventSub = stackRefs[j+1]->parentHash.value(stackRefs[j]->eventHashStr);
+                    prevEventSub->inLoopPath = true;
+                }
+            }
+
+            // use crossed references to find index in starttimesortedlist
+            QmlEventStartTimeData *head = stack[stackRefs.indexOf(currentEvent)];
+            inTimeEvent->bindingLoopHead = d->m_endTimeSortedList[head->endTimeIndex].startTimeIndex;
+            d->m_startTimeSortedList[inTimeEvent->bindingLoopHead].bindingLoopHead = i;
+        }
+    }
+}
+
 // get list of events between A and B:
 // find fist event with endtime after A -> aa
 // find last event with starttime before B -> bb
@@ -1689,10 +1749,16 @@ QString QmlProfilerEventList::getDetails(int index) const
     return d->m_startTimeSortedList[index].description->details;
 }
 
-int QmlProfilerEventList::getEventId(int index) const {
+int QmlProfilerEventList::getEventId(int index) const
+{
     return d->m_startTimeSortedList[index].description->eventId;
 }
 
+int QmlProfilerEventList::getBindingLoopDest(int index) const
+{
+    return d->m_startTimeSortedList[index].bindingLoopHead;
+}
+
 int QmlProfilerEventList::getFramerate(int index) const
 {
     return d->m_startTimeSortedList[index].frameRate;
diff --git a/src/libs/qmljsdebugclient/qmlprofilereventlist.h b/src/libs/qmljsdebugclient/qmlprofilereventlist.h
index b8eef3a2bc86bafc2487e2dcd063a8388dc26707..b5b9660354e3660c6a4bb121a88722923b2dc163 100644
--- a/src/libs/qmljsdebugclient/qmlprofilereventlist.h
+++ b/src/libs/qmljsdebugclient/qmlprofilereventlist.h
@@ -65,16 +65,18 @@ struct QMLJSDEBUGCLIENT_EXPORT QmlEventData
     double percentOfTime;
     qint64 medianTime;
     int eventId;
+    bool isBindingLoop;
 
     QmlEventData &operator=(const QmlEventData &ref);
 };
 
 struct QMLJSDEBUGCLIENT_EXPORT QmlEventSub {
-    QmlEventSub(QmlEventData *from) : reference(from), duration(0), calls(0) {}
-    QmlEventSub(QmlEventSub *from) : reference(from->reference), duration(from->duration), calls(from->calls) {}
+    QmlEventSub(QmlEventData *from) : reference(from), duration(0), calls(0), inLoopPath(false) {}
+    QmlEventSub(QmlEventSub *from) : reference(from->reference), duration(from->duration), calls(from->calls), inLoopPath(from->inLoopPath) {}
     QmlEventData *reference;
     qint64 duration;
     qint64 calls;
+    bool inLoopPath;
 };
 
 struct QMLJSDEBUGCLIENT_EXPORT QV8EventData
@@ -142,11 +144,13 @@ public:
     Q_INVOKABLE int getColumn(int index) const;
     Q_INVOKABLE QString getDetails(int index) const;
     Q_INVOKABLE int getEventId(int index) const;
+    Q_INVOKABLE int getBindingLoopDest(int index) const;
     Q_INVOKABLE int getFramerate(int index) const;
     Q_INVOKABLE int getAnimationCount(int index) const;
     Q_INVOKABLE int getMaximumAnimationCount() const;
     Q_INVOKABLE int getMinimumAnimationCount() const;
 
+
     // per-type data
     Q_INVOKABLE int uniqueEventsOfType(int type) const;
     Q_INVOKABLE int maxNestingForType(int type) const;
@@ -206,6 +210,8 @@ private:
     void prepareForDisplay();
     void linkEndsToStarts();
     void reloadDetails();
+    void findBindingLoops(qint64 startTime, qint64 endTime);
+    bool checkBindingLoop(QmlEventData *from, QmlEventData *current, QList<QmlEventData *>visited);
 
 private:
     class QmlProfilerEventListPrivate;
diff --git a/src/plugins/qmlprofiler/qml/MainView.qml b/src/plugins/qmlprofiler/qml/MainView.qml
index bf0fd6f6f6cf34b08e64ab566bd319dfd55283a1..557d8279e6b3dd8f429dec80e873cbada5b15b12 100644
--- a/src/plugins/qmlprofiler/qml/MainView.qml
+++ b/src/plugins/qmlprofiler/qml/MainView.qml
@@ -269,6 +269,7 @@ Rectangle {
         rangeDetails.file = "";
         rangeDetails.line = -1;
         rangeDetails.column = 0;
+        rangeDetails.isBindingLoop = false;
     }
 
     function selectNextWithId( eventId )
@@ -424,6 +425,7 @@ Rectangle {
                     rangeDetails.line = qmlEventList.getLine(selectedItem);
                     rangeDetails.column = qmlEventList.getColumn(selectedItem);
                     rangeDetails.type = root.names[qmlEventList.getType(selectedItem)];
+                    rangeDetails.isBindingLoop = qmlEventList.getBindingLoopDest(selectedItem)!==-1;
 
                     rangeDetails.visible = true;
 
diff --git a/src/plugins/qmlprofiler/qml/Overview.js b/src/plugins/qmlprofiler/qml/Overview.js
index 7aeeabd971d41e24458c57903210fe4d24aa63ed..4fe625a7fd10e7cc5e7346ae2b5e208358051386 100644
--- a/src/plugins/qmlprofiler/qml/Overview.js
+++ b/src/plugins/qmlprofiler/qml/Overview.js
@@ -95,6 +95,21 @@ function drawData(canvas, ctxt, region)
             highest[ty] = xx+eventWidth;
         }
     }
+
+    // binding loops
+    ctxt.strokeStyle = "orange";
+    ctxt.lineWidth = 2;
+    var radius = 1;
+    for (var ii = 0; ii < qmlEventList.count(); ++ii) {
+        if (qmlEventList.getBindingLoopDest(ii) >= 0) {
+            var xcenter = Math.round(qmlEventList.getStartTime(ii) +
+                                     qmlEventList.getDuration(ii) -
+                                     qmlEventList.traceStartTime()) * spacing;
+            var ycenter = Math.round(bump + qmlEventList.getType(ii) * blockHeight + blockHeight/2);
+            ctxt.arc(xcenter, ycenter, radius, 0, 2*Math.PI, true);
+            ctxt.stroke();
+        }
+    }
 }
 
 function drawTimeBar(canvas, ctxt, region)
diff --git a/src/plugins/qmlprofiler/qml/RangeDetails.qml b/src/plugins/qmlprofiler/qml/RangeDetails.qml
index 7013affe08ee3161cdaf033adf3665c190ba77c4..324c0903b0b9825ef188d1850ed105d9536c48de 100644
--- a/src/plugins/qmlprofiler/qml/RangeDetails.qml
+++ b/src/plugins/qmlprofiler/qml/RangeDetails.qml
@@ -42,6 +42,7 @@ Item {
     property string file
     property int line
     property int column
+    property bool isBindingLoop
 
     property bool locked: view.selectionLocked
 
@@ -153,6 +154,11 @@ Item {
                     return (file.length !== 0) ? (file + ":" + rangeDetails.line) : "";
                 }
             }
+            Detail {
+                visible: isBindingLoop
+                opacity: content.length != 0 ? 1 : 0
+                label: qsTr("Binding loop detected")
+            }
         }
     }
 
diff --git a/src/plugins/qmlprofiler/qmlprofilereventview.cpp b/src/plugins/qmlprofiler/qmlprofilereventview.cpp
index f89a966f9b81276c1760399b1e108b7243e6b1bf..57eb3d4fa24ace07cea86511f0358633b17db43d 100644
--- a/src/plugins/qmlprofiler/qmlprofilereventview.cpp
+++ b/src/plugins/qmlprofiler/qmlprofilereventview.cpp
@@ -54,6 +54,16 @@ using namespace QmlJsDebugClient;
 namespace QmlProfiler {
 namespace Internal {
 
+struct Colors {
+    Colors () {
+        this->bindingLoopBackground = QColor("orange").lighter();
+    }
+
+    QColor bindingLoopBackground;
+};
+
+Q_GLOBAL_STATIC(Colors, colors)
+
 ////////////////////////////////////////////////////////////////////////////////////
 
 class EventsViewItem : public QStandardItem
@@ -531,6 +541,11 @@ void QmlProfilerEventsMainView::QmlProfilerEventsMainViewPrivate::buildModelFrom
             newRow.at(0)->setData(QVariant(binding->location.line),LineRole);
             newRow.at(0)->setData(QVariant(binding->location.column),ColumnRole);
             newRow.at(0)->setData(QVariant(binding->eventId),EventIdRole);
+            if (binding->isBindingLoop)
+                foreach (QStandardItem *item, newRow) {
+                    item->setBackground(colors()->bindingLoopBackground);
+                    item->setToolTip(tr("Binding loop detected"));
+                }
 
             // append
             parentItem->appendRow(newRow);
@@ -877,6 +892,11 @@ void QmlProfilerEventsParentsAndChildrenView::rebuildTree(void *eventList)
             newRow.at(0)->setData(QVariant(event->reference->eventId), EventIdRole);
             newRow.at(2)->setData(QVariant(event->duration));
             newRow.at(3)->setData(QVariant(event->calls));
+            if (event->inLoopPath)
+                foreach (QStandardItem *item, newRow) {
+                    item->setBackground(colors()->bindingLoopBackground);
+                    item->setToolTip(tr("Part of binding loop"));
+                }
         } else {
             QV8EventSub *event = v8List->at(index);
             newRow << new EventsViewItem(event->reference->displayName);
diff --git a/src/plugins/qmlprofiler/timelineview.cpp b/src/plugins/qmlprofiler/timelineview.cpp
index aa971f166fcefc79a56ec66acc79a57c8c9c3a6c..3fd0d4c07d3ec780c689b649b8d633c4c3091a81 100644
--- a/src/plugins/qmlprofiler/timelineview.cpp
+++ b/src/plugins/qmlprofiler/timelineview.cpp
@@ -107,9 +107,10 @@ void TimelineView::paint(QPainter *p, const QStyleOptionGraphicsItem *, QWidget
 
     int firstIndex = m_eventList->findFirstIndex(m_startTime);
     int lastIndex = m_eventList->findLastIndex(m_endTime);
-    drawItemsToPainter(p, firstIndex, lastIndex);
 
-    drawSelectionBoxes(p);
+    drawItemsToPainter(p, firstIndex, lastIndex);
+    drawSelectionBoxes(p, firstIndex, lastIndex);
+    drawBindingLoopMarkers(p, firstIndex, lastIndex);
 
     m_lastStartTime = m_startTime;
     m_lastEndTime = m_endTime;
@@ -166,13 +167,11 @@ void TimelineView::drawItemsToPainter(QPainter *p, int fromIndex, int toIndex)
     }
 }
 
-void TimelineView::drawSelectionBoxes(QPainter *p)
+void TimelineView::drawSelectionBoxes(QPainter *p, int fromIndex, int toIndex)
 {
     if (m_selectedItem == -1)
         return;
 
-    int fromIndex = m_eventList->findFirstIndex(m_startTime);
-    int toIndex = m_eventList->findLastIndex(m_endTime);
     int id = m_eventList->getEventId(m_selectedItem);
 
     p->setBrush(Qt::transparent);
@@ -216,6 +215,74 @@ void TimelineView::drawSelectionBoxes(QPainter *p)
     }
 }
 
+void TimelineView::drawBindingLoopMarkers(QPainter *p, int fromIndex, int toIndex)
+{
+    int destindex;
+    int xfrom, xto, eventType;
+    int yfrom, yto;
+    int radius = DefaultRowHeight / 3;
+    QPen shadowPen = QPen(QColor("grey"),2);
+    QPen markerPen = QPen(QColor("orange"),2);
+    QBrush shadowBrush = QBrush(QColor("grey"));
+    QBrush markerBrush = QBrush(QColor("orange"));
+
+    p->save();
+    for (int i = fromIndex; i <= toIndex; i++) {
+        destindex = m_eventList->getBindingLoopDest(i);
+        if (destindex >= 0) {
+            // from
+            xfrom = (m_eventList->getStartTime(i) + m_eventList->getDuration(i)/2 -
+                     m_startTime) * m_spacing;
+            eventType = m_eventList->getType(i);
+            if (m_rowsExpanded[eventType])
+                yfrom = m_rowStarts[eventType] + DefaultRowHeight*
+                        (m_eventList->eventPosInType(i) + 1);
+            else
+                yfrom = m_rowStarts[eventType] + DefaultRowHeight*m_eventList->getNestingLevel(i);
+
+            yfrom += DefaultRowHeight / 2;
+
+            // to
+            xto = (m_eventList->getStartTime(destindex) + m_eventList->getDuration(destindex)/2 -
+                   m_startTime) * m_spacing;
+            eventType = m_eventList->getType(destindex);
+            if (m_rowsExpanded[eventType])
+                yto = m_rowStarts[eventType] + DefaultRowHeight*
+                        (m_eventList->eventPosInType(destindex) + 1);
+            else
+                yto = m_rowStarts[eventType] + DefaultRowHeight *
+                        m_eventList->getNestingLevel(destindex);
+
+            yto += DefaultRowHeight / 2;
+
+            // radius
+            int eventWidth = m_eventList->getDuration(i) * m_spacing;
+            radius = 5;
+            if (radius * 2 > eventWidth)
+                radius = eventWidth / 2;
+            if (radius < 2)
+                radius = 2;
+
+            // shadow
+            int shadowoffset = 2;
+            p->setPen(shadowPen);
+            p->setBrush(shadowBrush);
+            p->drawEllipse(QPoint(xfrom, yfrom + shadowoffset), radius, radius);
+            p->drawEllipse(QPoint(xto, yto + shadowoffset), radius, radius);
+            p->drawLine(QPoint(xfrom, yfrom + shadowoffset), QPoint(xto, yto + shadowoffset));
+
+
+            // marker
+            p->setPen(markerPen);
+            p->setBrush(markerBrush);
+            p->drawEllipse(QPoint(xfrom, yfrom), radius, radius);
+            p->drawEllipse(QPoint(xto, yto), radius, radius);
+            p->drawLine(QPoint(xfrom, yfrom), QPoint(xto, yto));
+        }
+    }
+    p->restore();
+}
+
 void TimelineView::mousePressEvent(QGraphicsSceneMouseEvent *event)
 {
     // special case: if there is a drag area below me, don't accept the
diff --git a/src/plugins/qmlprofiler/timelineview.h b/src/plugins/qmlprofiler/timelineview.h
index 9b04b6dc5bb72482d101c2fba5d0e47e6825f4af..dcb3bbfc3feccfd3b4fba91b5802e0d853a51103 100644
--- a/src/plugins/qmlprofiler/timelineview.h
+++ b/src/plugins/qmlprofiler/timelineview.h
@@ -182,7 +182,8 @@ protected:
 private:
     QColor colorForItem(int itemIndex);
     void drawItemsToPainter(QPainter *p, int fromIndex, int toIndex);
-    void drawSelectionBoxes(QPainter *p);
+    void drawSelectionBoxes(QPainter *p, int fromIndex, int toIndex);
+    void drawBindingLoopMarkers(QPainter *p, int fromIndex, int toIndex);
 
     void manageClicked();
     void manageHovered(int x, int y);