diff --git a/changes b/changes
index 22903b8d49d936b3e950f544e8df832e3f52ec09..12dbb33d3348695c9bd2005c91547763bd789a46 100644
--- a/changes
+++ b/changes
@@ -1,4 +1,5 @@
 1.5.2 alpha3
+     - extended grand staff, beaming notes on every staff separately
      - score supports bowing symbols, read them from XML
      - improved level creator
 
diff --git a/src/libs/core/score/tbeamobject.cpp b/src/libs/core/score/tbeamobject.cpp
index 59b059398e6499b426f3095e86af978842722a24..db5644db3ce64ab47f96f7b013dab12ffc8127f2 100644
--- a/src/libs/core/score/tbeamobject.cpp
+++ b/src/libs/core/score/tbeamobject.cpp
@@ -118,7 +118,8 @@ void TbeamObject::prepareBeam() {
   bool stemsUpPossible = true;
   qreal hiNote = 99.0, loNote = 0.0;
   for (TnotePair* np : qAsConst(m_notes)) {
-    stemDirStrength += np->item()->notePosY() - (m_measure->staff()->upperLine() + 4.0);
+    stemDirStrength += np->item()->notePosY() - (m_measure->staff()->upperLine()
+              + (m_measure->score()->isPianoStaff() && np->item()->notePosY() > m_measure->staff()->upperLine() + 13.0 ? 26.0 : 4.0));
     if (np->item()->notePosY() < MIN_STEM_HEIGHT)
       stemsUpPossible = false;
     hiNote = qMin(hiNote, np->item()->notePosY());
@@ -129,8 +130,15 @@ void TbeamObject::prepareBeam() {
   if (stemDirStrength < 0)
     allStemsDown = true; // stems down are always possible
   qreal stemTop = allStemsDown ? loNote + minStemHeight : hiNote - minStemHeight;
-  if ((allStemsDown && stemTop < m_measure->staff()->upperLine() + 4.0) || (!allStemsDown && stemTop > m_measure->staff()->upperLine() + 4.0))
-    stemTop = m_measure->staff()->upperLine() + 4.0; // keep beam on staff middle line
+  if (m_measure->score()->isPianoStaff() && !first()->note()->onUpperStaff()) { // when note lays on the lower staff
+      qreal lowerMidLine = m_measure->staff()->upperLine() + 26.0;
+      if ((allStemsDown && stemTop < lowerMidLine) || (!allStemsDown && stemTop > lowerMidLine))
+        stemTop = lowerMidLine; // keep beam on the lower staff middle line
+  } else {
+      qreal upperMidLine = m_measure->staff()->upperLine() + 4.0;
+      if ((allStemsDown && stemTop < upperMidLine) || (!allStemsDown && stemTop > upperMidLine))
+        stemTop = upperMidLine; // keep beam on staff middle line
+  }
   for (TnotePair* np : qAsConst(m_notes)) {
     np->note()->rtm.setStemDown(allStemsDown);
     np->addChange(TnotePair::e_stemDirChanged);
diff --git a/src/libs/core/score/tmeasureobject.cpp b/src/libs/core/score/tmeasureobject.cpp
index 5268d0406b2b3d6da30b89f218a4be75b976c0e8..0b3ad18af3d8de81f486ae6b02a2cf8b7bbe2b30 100644
--- a/src/libs/core/score/tmeasureobject.cpp
+++ b/src/libs/core/score/tmeasureobject.cpp
@@ -243,7 +243,9 @@ int TmeasureObject::beamGroup(int segmentId) {
     auto prevSeg = m_notes[segId - 1];
     if (!noteSeg->note()->isRest() && !prevSeg->note()->isRest() // not a rest
       && noteSeg->note()->rhythm() > Trhythm::Quarter // sixteenth or eighth
-      && prevSeg->note()->rhythm() > Trhythm::Quarter)
+      && prevSeg->note()->rhythm() > Trhythm::Quarter
+      && (!m_score->isPianoStaff() || noteSeg->note()->onUpperStaff() == prevSeg->note()->onUpperStaff())
+    )
     {
         if (prevSeg->note()->rtm.beam() == Trhythm::e_noBeam) // start beam group
           prevSeg->setBeam(new TbeamObject(prevSeg, this));
diff --git a/src/libs/core/score/tnoteitem.cpp b/src/libs/core/score/tnoteitem.cpp
index 4f4418f112635cf6dc6b618454406731efd2cc75..17625a58bf2ce3bb029fd330bc8ee1fc85ba1844 100644
--- a/src/libs/core/score/tnoteitem.cpp
+++ b/src/libs/core/score/tnoteitem.cpp
@@ -210,7 +210,8 @@ void TnoteItem::setNote(const Tnote& n) {
   bool updateHead = n.rhythm() != m_note->rhythm() || n.isRest() != m_note->isRest() || n.hasDot() != m_note->hasDot();
   bool fixBeam = n.isRest() != m_note->isRest();
   bool updateStem = updateHead || fixBeam || ((n.rtm.beam() != Trhythm::e_noBeam) != (m_note->rtm.beam() != Trhythm::e_noBeam))
-        || (n.rtm.stemDown() != m_note->rtm.stemDown() || m_stem->height() != m_stemHeight);
+        || (n.rtm.stemDown() != m_note->rtm.stemDown() || m_stem->height() != m_stemHeight) 
+        || n.onUpperStaff() != m_note->onUpperStaff();
   bool updateTie = n.rtm.tie() != m_note->rtm.tie();
 
   *m_note = n;
@@ -234,7 +235,7 @@ void TnoteItem::setNote(const Tnote& n) {
   else {
     if (m_note->isValid()) {
         m_notePosY = staff()->score()->clefOffset().total() + staff()->upperLine() - (n.octave() * 7 + (n.note() - 1));
-        if (staff()->score()->isPianoStaff()) {
+        if (staff()->isPianoStaff()) {
           if (m_note->onUpperStaff()) {
               if (m_notePosY > staff()->upperLine() + 13.0)
                 m_notePosY += 10.0;
@@ -326,7 +327,7 @@ void TnoteItem::setHeight(qreal hh) {
       m_upLines[l]->setY(2 * (l + 1) - 0.1);
       m_loLines[l]->setY(staff()->upperLine() + 10.0 + 2 * l - 0.1);
     }
-    if (staff()->score()->isPianoStaff()) {
+    if (staff()->isPianoStaff()) {
       if (m_underLoLines.isEmpty()) {
         m_staff->score()->component()->setData("import QtQuick 2.9; Rectangle {}", QUrl());
         for (int l = 0; l < 2; ++l) {
@@ -783,8 +784,10 @@ void TnoteItem::updateTieScale() {
 void TnoteItem::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(STEM_HEIGHT, qAbs(m_notePosY - (staff()->upperLine() + 4.0))));
+          m_note->rtm.setStemDown(m_notePosY < staff()->upperLine() + 4.0
+                                  || (staff()->isPianoStaff() && m_notePosY > staff()->upperLine() + 13.0 && m_notePosY < staff()->upperLine() + 26.0));
+          m_stem->setHeight(qMax(STEM_HEIGHT, qAbs(m_notePosY
+                            - (staff()->upperLine() + (staff()->isPianoStaff() && m_notePosY > staff()->upperLine() + 13.0 ? 26.0 : 4.0)))));
           QString flagText = getFlagText();
           m_flag->setProperty("text", flagText);
           if (!flagText.isEmpty())
@@ -834,11 +837,11 @@ void TnoteItem::updateNamePos() {
  */
 void TnoteItem::checkAddLinesVisibility() {
   bool v = m_head->isVisible() && !m_note->isRest();
-  bool betweenStaves = staff()->score()->isPianoStaff() &&  m_notePosY >= staff()->upperLine() + 10.0 && m_notePosY < staff()->upperLine() + 21.0;
+  bool betweenStaves = staff()->isPianoStaff() &&  m_notePosY >= staff()->upperLine() + 10.0 && m_notePosY < staff()->upperLine() + 21.0;
   for (int i = 0; i < 7; ++i) {
     m_upLines[i]->setVisible(v && m_notePosY > 0.0 && i >= qFloor((m_notePosY - 1.0) / 2.0));
     qreal upp1 = staff()->upperLine() + 10.0 + i * 2;
-    if (staff()->score()->isPianoStaff()) {
+    if (staff()->isPianoStaff()) {
         if (m_notePosY < staff()->upperLine() + 14.0)
           m_loLines[i]->setVisible(v && betweenStaves && m_notePosY >= upp1 && m_notePosY < staff()->upperLine() + 14.0);
         else
diff --git a/src/libs/core/score/tstaffitem.cpp b/src/libs/core/score/tstaffitem.cpp
index 85199dce0e233425853a6d8a3321f3b84ead77f7..251ff02196c927a9a0b73898761f4141a88961b2 100644
--- a/src/libs/core/score/tstaffitem.cpp
+++ b/src/libs/core/score/tstaffitem.cpp
@@ -101,6 +101,11 @@ void TstaffItem::setNotesIndent(qreal ni) {
 }
 
 
+bool TstaffItem::isPianoStaff() const {
+  return m_scoreObj->isPianoStaff();
+}
+
+
 char TstaffItem::debug() {
   QTextStream o(stdout);
   o << "\033[01;34m[" << number() + 1 << " STAFF]\033[01;00m";
diff --git a/src/libs/core/score/tstaffitem.h b/src/libs/core/score/tstaffitem.h
index b1a95a1688393086ec18d7fff0e79496dcc7294e..ddb33854d08d432077a5786e1964d84270cdff40 100644
--- a/src/libs/core/score/tstaffitem.h
+++ b/src/libs/core/score/tstaffitem.h
@@ -122,6 +122,8 @@ public:
 
   qreal gapsSum() const { return m_gapsSum; }
 
+  bool isPianoStaff() const;
+
       /**
        * Prints to std out debug info about this staff: [nr STAFF] in color
        */