diff --git a/src/libs/core/music/trhythm.h b/src/libs/core/music/trhythm.h
index 84de937d862aaf81892508320498af237ae6cde9..d2436f0c8560b6b40b357a0a58b67cd8af8c859b 100644
--- a/src/libs/core/music/trhythm.h
+++ b/src/libs/core/music/trhythm.h
@@ -88,6 +88,7 @@ public:
   enum Ebeam : quint8 {
     e_noBeam = 0, e_beamStart = 16, e_beamCont = 32, e_beamEnd = 48
   };
+  Q_ENUM(Ebeam)
 
   enum Etie : quint8 {
     e_noTie = 0, e_tieStart = 64, e_tieCont = 128, e_tieEnd = 192
diff --git a/src/libs/core/score/tnoteobject.cpp b/src/libs/core/score/tnoteobject.cpp
index c800600bb15ac4ccb80b3c94cb6d733d83c75958..041b0d0636e235ff6141f51b6342d919f6fd8a59 100644
--- a/src/libs/core/score/tnoteobject.cpp
+++ b/src/libs/core/score/tnoteobject.cpp
@@ -20,6 +20,7 @@
 #include "tscoreobject.h"
 #include "tstaffobject.h"
 #include "tmeasureobject.h"
+#include "tbeamobject.h"
 #include "tnotepair.h"
 #include "music/tnote.h"
 
@@ -60,10 +61,10 @@ const qreal rtmGapArray[5][3] = {
 
 
 
-TnoteObject::TnoteObject(TstaffObject* staffObj) :
+TnoteObject::TnoteObject(TstaffObject* staffObj, TnotePair* wrapper) :
   QQuickItem(staffObj->staffItem()),
   m_staff(staffObj),
-  m_index(-1),
+  m_wrapper(wrapper),
   m_stemHeight(6.0)
 {
   setParent(m_staff->score()); // to avoid deleting with parent staff
@@ -115,10 +116,17 @@ TnoteObject::~TnoteObject() {
 }
 
 
+int TnoteObject::index() const {
+  return m_wrapper->index();
+}
+
+
 void TnoteObject::setStaff(TstaffObject* staffObj) {
   if (staffObj != m_staff) {
     m_staff = staffObj;
     setParentItem(m_staff->staffItem());
+    if (m_wrapper->beam() && m_wrapper->beam()->last()->item() == this)
+      m_wrapper->beam()->changeStaff(m_staff);
   } else
       qDebug() << debug() << "has staff set already";
 }
@@ -129,6 +137,11 @@ void TnoteObject::setMeasure(TmeasureObject* m) {
 }
 
 
+void TnoteObject::setStemHeight(qreal sh) {
+  m_stem->setHeight(sh);
+}
+
+
 void TnoteObject::setColor(const QColor& c) {
   m_head->setProperty("color", c);
   m_alter->setProperty("color", c);
@@ -159,7 +172,8 @@ void TnoteObject::setColor(const QColor& c) {
  */
 void TnoteObject::setNote(const Tnote& n) {
   bool updateHead = n.rhythm() != m_note->rhythm() || n.isRest() != m_note->isRest() || n.hasDot() != m_note->hasDot();
-  bool updateStem = updateHead || (n.rtm.beam() != Trhythm::e_noBeam) != (m_note->rtm.beam() != Trhythm::e_noBeam);
+  bool updateStem = updateHead || ((n.rtm.beam() != Trhythm::e_noBeam) != (m_note->rtm.beam() != Trhythm::e_noBeam))
+                    || (n.rtm.stemDown() != m_note->rtm.stemDown());
   bool updateTie = n.rtm.tie() != m_note->rtm.tie();
 
   *m_note = n;
@@ -186,22 +200,8 @@ void TnoteObject::setNote(const Tnote& n) {
     updateStem = true;
   }
 
-  if (updateStem) {
-    if (m_notePosY && !m_note->isRest() && m_note->rhythm() > Trhythm::Whole ) {
-        if (m_note->rtm.beam() == Trhythm::e_noBeam) {
-            m_note->rtm.setStemDown(m_notePosY < staff()->upperLine() + 4.0);
-            m_stem->setHeight(qMax(6.0, qAbs(m_notePosY - (staff()->upperLine() + 4.0))));
-            QString flag = getFlagText();
-            m_flag->setProperty("text", flag);
-            if (!flag.isEmpty())
-              m_flag->setY((m_note->rtm.stemDown() ? m_stem->height() : 0.0) - 15.0);
-        }
-        m_stem->setX(m_head->x() + (m_note->rtm.stemDown() ? 0.0 : 2.0));
-        m_stem->setY(m_notePosY + (m_note->rtm.stemDown() ? 0.0 : - m_stem->height()));
-        m_stem->setVisible(true);
-    } else
-        m_stem->setVisible(false);
-  }
+  if (updateStem)
+    checkStem();
 
   updateAlter();
   updateWidth();
@@ -221,6 +221,8 @@ void TnoteObject::setNote(const Tnote& n) {
 void TnoteObject::setX(qreal xx) {
   updateTieScale();
   QQuickItem::setX(xx + (m_accidText.isEmpty() ? 0.0 : m_alter->width()));
+  if (m_wrapper->beam() && m_wrapper->beam()->last()->item() == this)
+    m_wrapper->beam()->last()->beam()->drawBeam();
 }
 
 
@@ -262,7 +264,12 @@ void TnoteObject::checkTie() {
 
 
 qreal TnoteObject::tieWidth() {
-  return staff()->gapFactor() * rhythmFactor() + (this == m_measure->last()->object() ? 1.5 : 0.0) + (m_note->rtm.stemDown() ? 0.0 : m_flag->width() - 0.2);
+  return staff()->gapFactor() * rhythmFactor() + (this == m_measure->last()->item() ? 1.5 : 0.0) + (m_note->rtm.stemDown() ? 0.0 : m_flag->width() - 0.2);
+}
+
+
+QPointF TnoteObject::stemTop() {
+  return mapToItem(parentItem(), QPointF(m_stem->x(), m_stem->y() + (m_note->rtm.stemDown() ? m_stem->height() : 0.0)));
 }
 
 //#################################################################################################
@@ -289,7 +296,7 @@ QString TnoteObject::getAccidText() {
     }
   }
   int id = index() - 1; // check the previous notes for accidentals
-  while (id >= 0 && m_staff->score()->noteSegment(id)->object()->measure() == measure()) {
+  while (id >= 0 && m_staff->score()->noteSegment(id)->item()->measure() == measure()) {
     if (m_staff->score()->noteSegment(id)->note()->note == m_note->note) {
       char prevAlter = m_staff->score()->noteSegment(id)->note()->alter;
       if (prevAlter != 0 && m_note->alter == 0) {
@@ -401,3 +408,24 @@ void TnoteObject::updateTieScale() {
     m_tie->setProperty("stemDown", m_note->rtm.stemDown());
   }
 }
+
+
+void TnoteObject::checkStem() {
+  if (m_notePosY && !m_note->isRest() && m_note->rhythm() > Trhythm::Whole ) {
+      if (m_note->rtm.beam() == Trhythm::e_noBeam) {
+          m_note->rtm.setStemDown(m_notePosY < staff()->upperLine() + 4.0);
+          m_stem->setHeight(qMax(6.0, qAbs(m_notePosY - (staff()->upperLine() + 4.0))));
+          QString flag = getFlagText();
+          m_flag->setProperty("text", flag);
+          if (!flag.isEmpty())
+            m_flag->setY((m_note->rtm.stemDown() ? m_stem->height() : 0.0) - 15.0);
+      } else {
+          if (m_flag->width() > 0.0)
+            m_flag->setProperty("text", QString());
+      }
+      m_stem->setX(m_head->x() + (m_note->rtm.stemDown() ? 0.0 : 2.0));
+      m_stem->setY(m_notePosY + (m_note->rtm.stemDown() ? 0.0 : - m_stem->height()));
+      m_stem->setVisible(true);
+  } else
+      m_stem->setVisible(false);
+}
diff --git a/src/libs/core/score/tnoteobject.h b/src/libs/core/score/tnoteobject.h
index d4c92b7d0b9f8a008a8d2e92a6a9dc8700285c27..11de61a7b5665f22ce0c6aeeb859f628bf413f0a 100644
--- a/src/libs/core/score/tnoteobject.h
+++ b/src/libs/core/score/tnoteobject.h
@@ -26,6 +26,7 @@
 
 class TstaffObject;
 class TmeasureObject;
+class TnotePair;
 class Tnote;
 
 
@@ -44,9 +45,10 @@ class NOOTKACORE_EXPORT TnoteObject : public QQuickItem
   friend class TscoreObject;
   friend class TstaffObject;
   friend class TmeasureObject;
+  friend class TbeamObject;
 
 public:
-  explicit TnoteObject(TstaffObject* staffObj = nullptr);
+  explicit TnoteObject(TstaffObject* staffObj = nullptr, TnotePair* wrapper = nullptr);
   ~TnoteObject();
 
   TstaffObject* staff() const { return m_staff; }
@@ -64,8 +66,7 @@ public:
       /**
        * Note number in the staff
        */
-  int index() const { return m_index; }
-  void setIndex(int id) { m_index = id; }
+  int index() const;
 
   qreal stemHeight() const { return m_stemHeight; }
   void setStemHeight(qreal sh);
@@ -75,7 +76,8 @@ public:
   void setColor(const QColor& c);
 
       /**
-       * Overrides standard @p setX() method to shift note segment about accidental symbol width (if it is set)
+       * Overrides standard @p setX() method to shift note segment about accidental symbol width (if it is set).
+       * It also updates tie (if any) and beam (for the last note in a beam group)
        */
   void setX(qreal xx);
 
@@ -89,6 +91,11 @@ public:
        */
   qreal rhythmFactor();
 
+      /**
+       * Returns position of the top of this note stem in staff coordinates
+       */
+  QPointF stemTop();
+
       /**
        * Prints to std out debug info about this note: [NOTE number] in color
        */
@@ -124,9 +131,9 @@ protected:
 private:
 
   TstaffObject                *m_staff;
+  TnotePair                   *m_wrapper;
   TmeasureObject              *m_measure;
   Tnote                       *m_note;
-  int                          m_index;
   qreal                        m_notePosY;
   qreal                        m_x;
   QQuickItem                  *m_head, *m_alter, *m_stem, *m_flag, *m_bg;
@@ -141,6 +148,7 @@ private:
   void updateWidth();
   void updateNoteHead();
   void updateTieScale();
+  void checkStem();
 };
 
 #endif // TNOTEOBJECT_H