diff --git a/src/libs/core/CMakeLists.txt b/src/libs/core/CMakeLists.txt
index b496a3d4abfbc31e4183f46e9405a993d4aba845..bcac2a104290186ea56e8cbc036f485d3386e68e 100644
--- a/src/libs/core/CMakeLists.txt
+++ b/src/libs/core/CMakeLists.txt
@@ -36,6 +36,7 @@ set(LIB_NOOTKACORE_SRC
   score/tmeasureobject.cpp
   score/tnoteobject.cpp
   score/tnotepair.cpp
+  score/tbeamobject.cpp
 
   instruments/tguitarbg.cpp
 
diff --git a/src/libs/core/score/tbeamobject.cpp b/src/libs/core/score/tbeamobject.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..428430f9a391ac74114e719a5b8d99d71abd5934
--- /dev/null
+++ b/src/libs/core/score/tbeamobject.cpp
@@ -0,0 +1,196 @@
+/***************************************************************************
+ *   Copyright (C) 2016 by Tomasz Bojczuk                                  *
+ *   seelook@gmail.com                                                     *
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 3 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   This program is distributed in the hope that it will be useful,       *
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
+ *   GNU General Public License for more details.                          *
+ *                                                                         *
+ *  You should have received a copy of the GNU General Public License      *
+ *  along with this program.  If not, see <http://www.gnu.org/licenses/>.  *
+ ***************************************************************************/
+
+#include "tbeamobject.h"
+#include "tscoreobject.h"
+#include "tstaffobject.h"
+#include "tmeasureobject.h"
+#include "tnoteobject.h"
+#include "tnotepair.h"
+#include <music/tnote.h>
+
+#include <qmath.h>
+#include <QtGui/qguiapplication.h>
+#include <QtGui/qpalette.h>
+#include <QtGui/qpainter.h>
+
+#include <QtCore/qdebug.h>
+#include "checktime.h"
+
+
+/**
+ * Simple structure to describe second beam line (sixteenth)
+ * which can be chunked when there are rests or eights in the group
+ */
+class T16beam {
+public:
+  T16beam(int firstStemNr = 0) : startStem(firstStemNr) {}
+  int startStem = -1; /**< Undefined by default (-1) */
+  int endStem = -1; /**< When remains undefined (-1) - beam is partial */
+
+      /** @p TRUE when beam is not connected to another stem */
+  bool isHalf() { return endStem == -1; }
+};
+
+
+#define MIN_STEM_HEIGHT (4.0) // minimal stem height (distance of note head to staff boundary)
+#define BEAM_THICK (0.8) // thickness of a beam
+#define HALF_THICK (0.4) // half of beam thickness
+
+
+
+TbeamObject::TbeamObject(TnotePair* sn, TmeasureObject* m) :
+  QQuickPaintedItem(m->staff()->staffItem()),
+  m_measure(m)
+{
+  addNote(sn);
+  setParent(m_measure->score());
+}
+
+
+TbeamObject::~TbeamObject()
+{
+  qDebug() << "     [BEAM] deleted of id" << first()->index();
+  for (TnotePair* note : m_notes) {
+    note->note()->rtm.setBeam(Trhythm::e_noBeam); // restore beams
+  }
+}
+
+
+void TbeamObject::addNote(TnotePair* np) {
+  if (np->beam() == nullptr)
+    np->setBeam(this);
+  else
+    qDebug() << "     [BEAM] note" << np->index() << "has already a beam";
+
+  if (m_notes.count() > 1)
+    m_notes.last()->note()->rtm.setBeam(Trhythm::e_beamCont); // no need to be updated
+  if (m_notes.isEmpty())
+    np->note()->rtm.setBeam(Trhythm::e_beamStart);
+  else
+    np->note()->rtm.setBeam(Trhythm::e_beamEnd);
+  if (np->item()) // mark it changed only when object exists, otherwise its note will be updated during creation
+    np->addChange(TnotePair::e_beamChanged);
+  m_notes << np;
+
+  if (np->note()->rhythm() == Trhythm::Sixteenth) {
+    Tnote* beforeLastNote = m_notes.count() > 1 ? m_notes[m_notes.count() - 2]->note() : nullptr;
+    if (m_16beams.isEmpty() || (beforeLastNote && beforeLastNote->rhythm() != Trhythm::Sixteenth)) {
+        // is first in beam or previous note was not a sixteenth
+        m_16beams << T16beam(m_notes.count() - 1); // then create new beam segment
+    } else if (!m_16beams.isEmpty() && (beforeLastNote && beforeLastNote->rhythm() == Trhythm::Sixteenth)) {
+        // there is 16 beam and previous note and this notes are 16th
+        m_16beams.last().endStem = m_notes.count() - 1; // then set end stem for it
+    }
+  }
+}
+
+
+/**
+ * With @p stemDirStrength (strength of stem direction) we trying to determine preferred common direction of stems in the group.
+ * More far from middle of the staff (18) note is placed - stronger its direction has to be preserved
+ * to keep beaming more natural and looking good
+ *
+ * @p stemsUpPossible keep true when there is enough space between note head and staff border for whole stem
+ * if not stems go down.
+ * @p stemTop it top stem position of all notes. It is set to middle of the staff if necessary (to look well)
+ */
+void TbeamObject::prepareBeam() {
+  int stemDirStrength = 0;
+  bool stemsUpPossible = true;
+  qreal hiNote = 99.0, loNote = 0.0;
+  for (TnotePair* np : m_notes) {
+    stemDirStrength += np->item()->notePosY() - 18;
+    if (np->item()->notePosY() < MIN_STEM_HEIGHT)
+      stemsUpPossible = false;
+    hiNote = qMin(hiNote, np->item()->notePosY());
+    loNote = qMax(loNote, np->item()->notePosY());
+  }
+  bool allStemsDown = !stemsUpPossible;
+  qreal minStemHeight = MIN_STEM_HEIGHT + (m_16beams.empty() ? 0.0 : 1.0);
+  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
+  for (TnotePair* np : m_notes) {
+    np->note()->rtm.setStemDown(allStemsDown);
+    np->addChange(TnotePair::e_stemDirChanged);
+    np->item()->setStemHeight(qAbs(np->item()->notePosY() - stemTop));
+    np->approve();
+  }
+}
+
+
+/**
+ * Poligons are painted, single for 8ths and possible a few for 16ths.
+ * Paiter canvas orientation depends on are stems up or down,
+ * for stems-up, top beam is 8ths and bottom are 16ths,
+ * for stems-down the opposite.
+ */
+void TbeamObject::paint(QPainter* painter) {
+CHECKTIME (
+  if (count() > 1) {
+    qreal s = first()->note()->rtm.stemDown() ? -1.0 : 1.0;
+    qreal t = first()->note()->rtm.stemDown() ? height() : 0.0;
+    painter->setPen(Qt::NoPen);
+    painter->setBrush(qApp->palette().text().color());
+    QPolygonF topBeam;
+    topBeam << QPointF(0.0, t) << QPointF(0.0, t + s * BEAM_THICK) << QPointF(width(), t + s * BEAM_THICK) << QPointF(width(), t) << QPointF(0.0, t);
+    painter->drawPolygon(topBeam);
+    for (int b = 0; b < m_16beams.count(); ++b) {
+      T16beam& b16 = m_16beams[b];
+      qreal startX = m_notes[b16.startStem]->item()->stemTop().x() - x();
+      // 16th beam of fist stem is right-sided (2.0) others are left-sided (-2.0)
+      qreal endX = (b16.isHalf() ? startX + BEAM_THICK * (b16.startStem == 0 ? 2.0 : -2.0) : m_notes[b16.endStem]->item()->stemTop().x() - x()) + 0.3;
+      QPolygonF polyB;
+      polyB << QPointF(startX, t + s * 1.5 * BEAM_THICK) << QPointF(startX, t + s * 2.5 * BEAM_THICK) << QPointF(endX, t + s * 2.5 * BEAM_THICK)
+            << QPointF(endX, t + s * 1.5 * BEAM_THICK) << QPointF(startX, t + s * 1.5 * BEAM_THICK);
+      painter->drawPolygon(polyB);
+    }
+  }
+)
+}
+
+
+//#################################################################################################
+//###################              PROTECTED           ############################################
+//#################################################################################################
+
+/**
+ * According to first and last notes in the beam, this method sets item geometry.
+ * @p setTextureSize() is called to make texture big enough and avoid pixelization
+ */
+void TbeamObject::drawBeam() {
+  auto p1 = first()->item()->stemTop();
+  auto p2 = last()->item()->stemTop();
+  setWidth(qAbs(p2.x() - p1.x()) + 0.3);
+  setHeight(qAbs(p1.y() - p2.y()) + BEAM_THICK * 2.5);
+  setX(p1.x());
+  setY(qMin(p1.y(), p2.y()) - (first()->note()->rtm.stemDown() ? 2.0 * BEAM_THICK : HALF_THICK));
+  setTextureSize(QSize(qCeil(width() * m_measure->staff()->scale()), qCeil(height() * m_measure->staff()->scale())));
+  /** @p update should be call here to invoke @p paint()
+   * but it is invoked by Qt itself whenever width, height, x or y change */
+}
+
+
+void TbeamObject::changeStaff(TstaffObject* st) {
+  setParentItem(st->staffItem());
+}
+
+
diff --git a/src/libs/core/score/tbeamobject.h b/src/libs/core/score/tbeamobject.h
new file mode 100644
index 0000000000000000000000000000000000000000..165f8ae53c6b32f2c58ad611710ba7275b7fb046
--- /dev/null
+++ b/src/libs/core/score/tbeamobject.h
@@ -0,0 +1,98 @@
+/***************************************************************************
+ *   Copyright (C) 2016-2017 by Tomasz Bojczuk                             *
+ *   seelook@gmail.com                                                     *
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 3 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   This program is distributed in the hope that it will be useful,       *
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
+ *   GNU General Public License for more details.                          *
+ *                                                                         *
+ *  You should have received a copy of the GNU General Public License      *
+ *  along with this program.  If not, see <http://www.gnu.org/licenses/>.  *
+ ***************************************************************************/
+
+#ifndef TBEAMOBJECT_H
+#define TBEAMOBJECT_H
+
+
+#include <nootkacoreglobal.h>
+#include <QtQuick/qquickpainteditem.h>
+
+
+class TstaffObject;
+class TmeasureObject;
+class TnoteObject;
+class TnotePair;
+class T16beam;
+
+
+/**
+ * This class manages displaying beams of rhythmic group.
+ * It paints either eight beam line and 16th beam line(s)
+ * By @p addNote() a beam flag of @p TnotePair is set.
+ * It that moment @p TnotePair::objeject() can be empty.
+ * After note objects initialization @p prepareBeam() is called
+ * where common stem direction of rhythm group is set and stems length.
+ * When @p TnoteObject::setX() is called (note and its stem changes position)
+ * @p drawBeam() is invoked to refresh beam size and call @p update()
+ * to repaint the beam if necessary.
+ */
+class NOOTKACORE_EXPORT TbeamObject : public QQuickPaintedItem
+{
+
+  Q_OBJECT
+
+  friend class TstaffObject;
+  friend class TmeasureObject;
+  friend class TnoteObject;
+
+public:
+  explicit TbeamObject(TnotePair* sn, TmeasureObject* m);
+  virtual ~TbeamObject();
+
+      /** Adds @p TnotePair to beam group
+       * and according to adding order sets appropriate beam flag.
+       * It changes stem direction of note(s) when necessary.
+       * It does not perform painting yet
+       */
+  void addNote(TnotePair* np);
+
+      /**
+       * Returns note @p id in beam group
+       */
+  TnotePair* note(int id) { return m_notes[id]; }
+
+  TnotePair* first() { return m_notes.first(); }
+  TnotePair* last() { return m_notes.last(); }
+
+      /**
+       * Number of notes in the beam group
+       */
+  int count() { return m_notes.count(); }
+
+
+  void paint(QPainter* painter) override;
+
+protected:
+  void prepareBeam();
+  void drawBeam();
+
+      /**
+       * Because beams are parented with staff it is important
+       * to change their staff when measure is shifted between staves
+       */
+  void changeStaff(TstaffObject* st);
+
+
+private:
+  TmeasureObject                   *m_measure;
+  QList<TnotePair*>                 m_notes;
+  QList<T16beam>                    m_16beams; /**< list of lines of sixteenths */
+};
+
+#endif // TBEAMOBJECT_H
diff --git a/src/libs/core/score/tmeasureobject.cpp b/src/libs/core/score/tmeasureobject.cpp
index 56cc7aee10bf0d3d23e1f5725f30cf264c5b937e..ca96dea153335b1d0eee6e612ae984bd054c3973 100644
--- a/src/libs/core/score/tmeasureobject.cpp
+++ b/src/libs/core/score/tmeasureobject.cpp
@@ -21,6 +21,7 @@
 #include "tstaffobject.h"
 #include "tnoteobject.h"
 #include "tnotepair.h"
+#include "tbeamobject.h"
 #include "music/tmeter.h"
 #include "music/tnote.h"
 
@@ -58,7 +59,7 @@ void TmeasureObject::setStaff(TstaffObject* st) {
   if (m_staff != st) {
     m_staff = st;
     for (TnotePair* np : m_notes)
-      np->object()->setStaff(m_staff);
+      np->item()->setStaff(m_staff);
   }
 }
 
@@ -69,16 +70,25 @@ void TmeasureObject::appendNewNotes(int segmentId, int count) {
   for (int n = segmentId; n < segmentId + count; ++n)
     m_notes.append(m_score->noteSegment(n));
   updateRhythmicGroups();
-  // resolve beaming
+  int grWithBeam = beamGroup(segmentId);
   for (int n = segmentId; n < segmentId + count; ++n) {
     auto np = m_score->noteSegment(n);
-    auto noteObject = new TnoteObject(m_staff);
-    noteObject->setIndex(np->index());
+    auto noteObject = new TnoteObject(m_staff, np);
     noteObject->setMeasure(this);
     np->setNoteObject(noteObject);
     checkAccidentals();
     noteObject->setNote(*np->note());
   }
+  if (grWithBeam > -1) {
+    auto firstInGrId = m_score->noteSegment(firstNoteId() + m_firstInGr[grWithBeam])->index();
+    while (firstInGrId < m_score->notesCount()) {
+      auto ns = m_score->noteSegment(firstInGrId);
+      if (ns->beam()) {
+        ns->beam()->prepareBeam();
+        break;
+      }
+    }
+  }
   refresh();
   m_staff->refresh();
   checkBarLine();
@@ -102,19 +112,19 @@ void TmeasureObject::insertNote(int id, TnotePair* np) {
 
 void TmeasureObject::keySignatureChanged() {
   for (int n = 0; n < m_notes.size(); ++n) {
-    m_notes[n]->object()->keySignatureChanged();
+    m_notes[n]->item()->keySignatureChanged();
   }
   refresh();
 }
 
 
 int TmeasureObject::firstNoteId() const {
-  return m_notes.count() ? m_notes.first()->object()->index() : 0;
+  return m_notes.count() ? m_notes.first()->index() : 0;
 }
 
 
 int TmeasureObject::lastNoteId() const {
-  return m_notes.count() ? m_notes.last()->object()->index() : 0;
+  return m_notes.count() ? m_notes.last()->index() : 0;
 }
 
 
@@ -158,7 +168,7 @@ void TmeasureObject::updateRhythmicGroups() {
 
 void TmeasureObject::checkBarLine() {
   if (m_free == 0) {
-    auto lastNote = last()->object();
+    auto lastNote = last()->item();
     if (!m_barLine) {
       QQmlEngine engine;
       QQmlComponent comp(&engine, this);
@@ -168,7 +178,7 @@ void TmeasureObject::checkBarLine() {
       m_barLine->setProperty("color", lastNote->color());
       m_barLine->setY(m_staff->upperLine());
     }
-    qreal xOff = lastNote == m_staff->lastMeasure()->last()->object() ? 0.2 : 0.0; // fit line at the staff end
+    qreal xOff = lastNote == m_staff->lastMeasure()->last()->item() ? 0.2 : 0.0; // fit line at the staff end
     m_barLine->setX(lastNote->rightX() - lastNote->x() + xOff);
   }
 }
@@ -178,7 +188,7 @@ void TmeasureObject::refresh() {
   m_gapsSum = 0.0;
   m_allNotesWidth = 0.0;
   for (int n = 0; n < m_notes.size(); ++n) {
-    auto noteObj = note(n)->object();
+    auto noteObj = note(n)->item();
     m_gapsSum += noteObj->rhythmFactor();
     m_allNotesWidth += noteObj->width();
   }
@@ -195,6 +205,29 @@ void TmeasureObject::checkAccidentals() {
 }
 
 
+int TmeasureObject::beamGroup(int segmentId) {
+  int currGr = m_score->noteSegment(segmentId)->rhythmGroup();
+  int segId = m_firstInGr[currGr] + 1;
+  int grWithBeam = -1;
+  while (segId < m_notes.count() && m_notes[segId]->rhythmGroup() == currGr) {
+    auto noteSeg = m_notes[segId];
+    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)
+    {
+        if (prevSeg->note()->rtm.beam() == Trhythm::e_noBeam) // start beam group
+          prevSeg->setBeam(new TbeamObject(prevSeg, this));
+        auto beam = prevSeg->beam();
+        if (noteSeg->beam() == nullptr)
+          beam->addNote(noteSeg);
+        grWithBeam = currGr;
+    }
+    segId++;
+  }
+  return grWithBeam;
+}
+
 //#################################################################################################
 //###################              PRIVATE             ############################################
 //#################################################################################################
diff --git a/src/libs/core/score/tmeasureobject.h b/src/libs/core/score/tmeasureobject.h
index acf0b6819946caebc1b07b862c4650759576a261..7ed22818791ac6c93fc3fee22b623df1de99ce68 100644
--- a/src/libs/core/score/tmeasureobject.h
+++ b/src/libs/core/score/tmeasureobject.h
@@ -29,6 +29,7 @@ class TscoreObject;
 class TstaffObject;
 class TnoteObject;
 class TnotePair;
+class TbeamObject;
 
 
 /**
@@ -122,6 +123,13 @@ protected:
 
   qint8 accidState(int noteNr) { return m_accidsState[noteNr]; }
 
+      /**
+       * Checks notes rhythms of group @p segmentId belongs to
+       * for 8ths and 16ths and crates beams (@p TbeamObject) if they occurs
+       * It can be called before @p TnoteObject will be created
+       */
+  int beamGroup(int segmentId);
+
 private:
   void clearAccidState();