Explorar o código

Merge branch 'feature/OSMD-6_Porting' into feature/VexFlowIntegration

Andrea Condoluci %!s(int64=9) %!d(string=hai) anos
pai
achega
a3b715d6ac

+ 1 - 1
src/MusicalScore/Graphical/AbstractGraphicalInstruction.ts

@@ -1,7 +1,7 @@
 import {GraphicalStaffEntry} from "./GraphicalStaffEntry";
 import {GraphicalObject} from "./GraphicalObject";
 
-export class AbstractGraphicalInstruction extends GraphicalObject {
+export abstract class AbstractGraphicalInstruction extends GraphicalObject {
     protected parent: GraphicalStaffEntry;
     constructor(parent: GraphicalStaffEntry) {
         super();

+ 9 - 0
src/MusicalScore/Graphical/GraphicalComment.ts

@@ -0,0 +1,9 @@
+import {GraphicalLabel} from "./GraphicalLabel";
+export class GraphicalComment {
+    constructor(label: GraphicalLabel, settingsLabel: GraphicalLabel) {
+        this.label = label;
+        this.settings = settingsLabel;
+    }
+    public label: GraphicalLabel;
+    public settings: GraphicalLabel;
+}

+ 14 - 0
src/MusicalScore/Graphical/GraphicalMarkedArea.ts

@@ -0,0 +1,14 @@
+import {GraphicalLabel} from "./GraphicalLabel";
+import {GraphicalRectangle} from "./GraphicalRectangle";
+export class GraphicalMarkedArea {
+    constructor(systemRectangle: GraphicalRectangle, labelRectangle: GraphicalRectangle = null, label: GraphicalLabel = null, settingsLabel: GraphicalLabel = null) {
+        this.systemRectangle = systemRectangle;
+        this.labelRectangle = labelRectangle;
+        this.label = label;
+        this.settings = settingsLabel;
+    }
+    public systemRectangle: GraphicalRectangle;
+    public labelRectangle: GraphicalRectangle;
+    public label: GraphicalLabel;
+    public settings: GraphicalLabel;
+}

+ 15 - 0
src/MusicalScore/Graphical/GraphicalRectangle.ts

@@ -0,0 +1,15 @@
+import {OutlineAndFillStyleEnum} from "./DrawingEnums";
+import {BoundingBox} from "./BoundingBox";
+import {PointF2D} from "../../Common/DataObjects/PointF2D";
+import {GraphicalObject} from "./GraphicalObject";
+export class GraphicalRectangle extends GraphicalObject {
+    constructor(upperLeftPoint: PointF2D, lowerRightPoint: PointF2D, parent: BoundingBox, style: OutlineAndFillStyleEnum) {
+        super();
+        this.boundingBox = new BoundingBox(parent);
+        this.boundingBox.RelativePosition = upperLeftPoint;
+        this.boundingBox.BorderRight = lowerRightPoint.x - upperLeftPoint.x;
+        this.boundingBox.BorderBottom = lowerRightPoint.y - upperLeftPoint.y;
+        this.style = style;
+    }
+    public style: OutlineAndFillStyleEnum;
+}

+ 1 - 1
src/MusicalScore/Graphical/GraphicalStaffEntry.ts

@@ -17,7 +17,7 @@ import {AbstractGraphicalInstruction} from "./AbstractGraphicalInstruction";
 import {GraphicalStaffEntryLink} from "./GraphicalStaffEntryLink";
 import {CollectionUtil} from "../../Util/collectionUtil";
 
-export class GraphicalStaffEntry extends GraphicalObject {
+export abstract class GraphicalStaffEntry extends GraphicalObject {
     constructor(parentMeasure: StaffMeasure, sourceStaffEntry: SourceStaffEntry = undefined, staffEntryParent: GraphicalStaffEntry = undefined) {
         super();
         this.parentMeasure = parentMeasure;

+ 1 - 1
src/MusicalScore/Graphical/MusicSheetCalculator.ts

@@ -905,7 +905,7 @@ export abstract class MusicSheetCalculator {
             for (let idx: number = 0, len: number = sourceMeasure.FirstInstructionsStaffEntries[staffIndex].Instructions.length; idx < len; ++idx) {
                 let instruction: AbstractNotationInstruction = sourceMeasure.FirstInstructionsStaffEntries[staffIndex].Instructions[idx];
                 if (instruction instanceof KeyInstruction) {
-                    let key: KeyInstruction = new KeyInstruction(<KeyInstruction>instruction);
+                    let key: KeyInstruction = KeyInstruction.copy(instruction);
                     if (this.graphicalMusicSheet.ParentMusicSheet.Transpose !== 0 &&
                         measure.ParentStaff.ParentInstrument.MidiInstrumentId !== MidiInstrument.Percussion &&
                         MusicSheetCalculator.transposeCalculator !== undefined) {

+ 24 - 2
src/MusicalScore/Graphical/MusicSystem.ts

@@ -15,8 +15,10 @@ import {GraphicalStaffEntry} from "./GraphicalStaffEntry";
 import {SystemLinesEnum} from "./SystemLinesEnum";
 import Dictionary from "typescript-collections/dist/lib/Dictionary";
 import {CollectionUtil} from "../../Util/collectionUtil";
+import {GraphicalComment} from "./GraphicalComment";
+import {GraphicalMarkedArea} from "./GraphicalMarkedArea";
 
-export class MusicSystem extends GraphicalObject {
+export abstract class MusicSystem extends GraphicalObject {
     public needsToBeRedrawn: boolean = true;
     protected parent: GraphicalMusicPage;
     protected id: number;
@@ -26,7 +28,11 @@ export class MusicSystem extends GraphicalObject {
     protected measureNumberLabels: GraphicalLabel[] = [];
     protected maxLabelLength: number;
     protected objectsToRedraw: [Object[], Object][] = [];
-
+    protected instrumentBrackets: GraphicalObject[] = [];
+    protected groupBrackets: GraphicalObject[] = [];
+    protected graphicalMarkedAreas: GraphicalMarkedArea[] = [];
+    protected graphicalComments: GraphicalComment[] = [];
+    protected
     constructor(parent: GraphicalMusicPage, id: number) {
         super();
         this.parent = parent;
@@ -63,6 +69,22 @@ export class MusicSystem extends GraphicalObject {
         return this.objectsToRedraw;
     }
 
+    public get InstrumentBrackets(): GraphicalObject[] {
+        return this.instrumentBrackets;
+    }
+
+    public get GroupBrackets(): GraphicalObject[] {
+        return this.groupBrackets;
+    }
+
+    public get GraphicalMarkedAreas(): GraphicalMarkedArea[] {
+        return this.graphicalMarkedAreas;
+    }
+
+    public get GraphicalComments(): GraphicalComment[] {
+        return this.graphicalComments;
+    }
+
     public get Id(): number {
         return this.id;
     }

+ 2 - 3
src/MusicalScore/Graphical/MusicSystemBuilder.ts

@@ -316,9 +316,8 @@ export class MusicSystemBuilder {
                 let staffIndex: number = this.visibleStaffIndices[i];
                 let graphicalMeasure: StaffMeasure = this.graphicalMusicSheet.getGraphicalMeasureFromSourceMeasureAndIndex(firstSourceMeasure, staffIndex);
                 this.activeClefs[i] = <ClefInstruction>firstSourceMeasure.FirstInstructionsStaffEntries[staffIndex].Instructions[0];
-                let keyInstruction: KeyInstruction = new KeyInstruction(
-                    <KeyInstruction>firstSourceMeasure.FirstInstructionsStaffEntries[staffIndex].Instructions[1]
-                );
+                let keyInstruction: KeyInstruction = KeyInstruction.copy(
+                    <KeyInstruction>firstSourceMeasure.FirstInstructionsStaffEntries[staffIndex].Instructions[1]);
                 keyInstruction = this.transposeKeyInstruction(keyInstruction, graphicalMeasure);
                 this.activeKeys[i] = keyInstruction;
                 this.activeRhythm[i] = <RhythmInstruction>firstSourceMeasure.FirstInstructionsStaffEntries[staffIndex].Instructions[2];

+ 1 - 1
src/MusicalScore/Graphical/StaffLine.ts

@@ -9,7 +9,7 @@ import {MusicSystem} from "./MusicSystem";
 import {StaffLineActivitySymbol} from "./StaffLineActivitySymbol";
 import {PointF2D} from "../../Common/DataObjects/PointF2D";
 
-export class StaffLine extends GraphicalObject {
+export abstract class StaffLine extends GraphicalObject {
     protected measures: StaffMeasure[] = [];
     protected staffLines: GraphicalLine[] = new Array(5);
     protected parentMusicSystem: MusicSystem;

+ 1 - 1
src/MusicalScore/Graphical/StaffMeasure.ts

@@ -15,7 +15,7 @@ import {SystemLinesEnum} from "./SystemLinesEnum";
 import {BoundingBox} from "./BoundingBox";
 import {PointF2D} from "../../Common/DataObjects/PointF2D";
 
-export class StaffMeasure extends GraphicalObject {
+export abstract class StaffMeasure extends GraphicalObject {
     protected firstInstructionStaffEntry: GraphicalStaffEntry;
     protected lastInstructionStaffEntry: GraphicalStaffEntry;
 

+ 1 - 1
src/MusicalScore/MusicSource/PartListEntry.ts

@@ -2,7 +2,7 @@ import {MusicSheet} from "../MusicSheet";
 import {Fraction} from "../../Common/DataObjects/fraction";
 import {SourceMeasure} from "../VoiceData/SourceMeasure";
 
-export class PartListEntry {
+export abstract class PartListEntry {
     constructor(musicSheet: MusicSheet) {
         this.musicSheet = musicSheet;
     }

+ 908 - 888
src/MusicalScore/ScoreIO/InstrumentReader.ts

@@ -46,948 +46,968 @@ import {MidiInstrument} from "../VoiceData/Instructions/ClefInstruction";
 type repetitionInstructionReader = any;
 
 export class InstrumentReader {
-  constructor(repetitionInstructionReader: repetitionInstructionReader, xmlMeasureList: IXmlElement[], instrument: Instrument) {
-    // (*) this.repetitionInstructionReader = repetitionInstructionReader;
-    this.xmlMeasureList = xmlMeasureList;
-    this.musicSheet = instrument.GetMusicSheet;
-    this.instrument = instrument;
-    this.activeClefs = new Array(instrument.Staves.length);
-    this.activeClefsHaveBeenInitialized = new Array(instrument.Staves.length);
-    for (let i: number = 0; i < instrument.Staves.length; i++) {
-      this.activeClefsHaveBeenInitialized[i] = false;
+    constructor(repetitionInstructionReader: repetitionInstructionReader, xmlMeasureList: IXmlElement[], instrument: Instrument) {
+        // (*) this.repetitionInstructionReader = repetitionInstructionReader;
+        this.xmlMeasureList = xmlMeasureList;
+        this.musicSheet = instrument.GetMusicSheet;
+        this.instrument = instrument;
+        this.activeClefs = new Array(instrument.Staves.length);
+        this.activeClefsHaveBeenInitialized = new Array(instrument.Staves.length);
+        for (let i: number = 0; i < instrument.Staves.length; i++) {
+            this.activeClefsHaveBeenInitialized[i] = false;
+        }
+        // FIXME createExpressionGenerators(instrument.Staves.length);
+        // (*) this.slurReader = MusicSymbolModuleFactory.createSlurReader(this.musicSheet);
     }
-    // FIXME createExpressionGenerators(instrument.Staves.length);
-    // (*) this.slurReader = MusicSymbolModuleFactory.createSlurReader(this.musicSheet);
-  }
-  // (*) private repetitionInstructionReader: RepetitionInstructionReader;
-  private xmlMeasureList: IXmlElement[];
-  private musicSheet: MusicSheet;
-  private slurReader: any; // (*) SlurReader;
-  private instrument: Instrument;
-  private voiceGeneratorsDict: { [n: number]: VoiceGenerator; } = {};
-  private staffMainVoiceGeneratorDict: { [staffId: number]: VoiceGenerator } = {};
-  private inSourceMeasureInstrumentIndex: number;
-  private divisions: number = 0;
-  private currentMeasure: SourceMeasure;
-  private previousMeasure: SourceMeasure;
-  private currentXmlMeasureIndex: number = 0;
-  private currentStaff: Staff;
-  private currentStaffEntry: SourceStaffEntry;
-  private activeClefs: ClefInstruction[];
-  private activeKey: KeyInstruction;
-  private activeRhythm: RhythmInstruction;
-  private activeClefsHaveBeenInitialized: boolean[];
-  private activeKeyHasBeenInitialized: boolean = false;
-  private abstractInstructions: [number, AbstractNotationInstruction][] = [];
-  private openChordSymbolContainer: ChordSymbolContainer;
-  // (*) private expressionReaders: ExpressionReader[];
-  private currentVoiceGenerator: VoiceGenerator;
-  //private openSlurDict: { [n: number]: Slur; } = {};
-  private maxTieNoteFraction: Fraction;
-
-  public get ActiveKey(): KeyInstruction {
-    return this.activeKey;
-  }
-  public get MaxTieNoteFraction(): Fraction {
-    return this.maxTieNoteFraction;
-  }
-  public get ActiveRhythm(): RhythmInstruction {
-    return this.activeRhythm;
-  }
-  public set ActiveRhythm(value: RhythmInstruction) {
-    this.activeRhythm = value;
-  }
-  public readNextXmlMeasure(currentMeasure: SourceMeasure, measureStartAbsoluteTimestamp: Fraction, guitarPro: boolean): boolean {
-    if (this.currentXmlMeasureIndex >= this.xmlMeasureList.length) {
-      return false;
+
+    // (*) private repetitionInstructionReader: RepetitionInstructionReader;
+    private xmlMeasureList: IXmlElement[];
+    private musicSheet: MusicSheet;
+    private slurReader: any; // (*) SlurReader;
+    private instrument: Instrument;
+    private voiceGeneratorsDict: { [n: number]: VoiceGenerator; } = {};
+    private staffMainVoiceGeneratorDict: { [staffId: number]: VoiceGenerator } = {};
+    private inSourceMeasureInstrumentIndex: number;
+    private divisions: number = 0;
+    private currentMeasure: SourceMeasure;
+    private previousMeasure: SourceMeasure;
+    private currentXmlMeasureIndex: number = 0;
+    private currentStaff: Staff;
+    private currentStaffEntry: SourceStaffEntry;
+    private activeClefs: ClefInstruction[];
+    private activeKey: KeyInstruction;
+    private activeRhythm: RhythmInstruction;
+    private activeClefsHaveBeenInitialized: boolean[];
+    private activeKeyHasBeenInitialized: boolean = false;
+    private abstractInstructions: [number, AbstractNotationInstruction][] = [];
+    private openChordSymbolContainer: ChordSymbolContainer;
+    // (*) private expressionReaders: ExpressionReader[];
+    private currentVoiceGenerator: VoiceGenerator;
+    //private openSlurDict: { [n: number]: Slur; } = {};
+    private maxTieNoteFraction: Fraction;
+
+    public get ActiveKey(): KeyInstruction {
+        return this.activeKey;
     }
-    this.currentMeasure = currentMeasure;
-    this.inSourceMeasureInstrumentIndex = this.musicSheet.getGlobalStaffIndexOfFirstStaff(this.instrument);
-    // (*) if (this.repetitionInstructionReader !== undefined) {
-    //  this.repetitionInstructionReader.prepareReadingMeasure(currentMeasure, this.currentXmlMeasureIndex);
-    //}
-    let currentFraction: Fraction = new Fraction(0, 1);
-    let previousFraction: Fraction = new Fraction(0, 1);
-    let divisionsException: boolean = false;
-    this.maxTieNoteFraction = new Fraction(0, 1);
-    let lastNoteWasGrace: boolean = false;
-    try {
-      let xmlMeasureListArr: IXmlElement[] = this.xmlMeasureList[this.currentXmlMeasureIndex].elements();
-      for (let xmlNode of xmlMeasureListArr) {
-        if (xmlNode.name === "note") {
-          if (xmlNode.hasAttributes && xmlNode.attribute("print-object") && xmlNode.attribute("print-spacing")) {
-            continue;
-          }
-          let noteStaff: number = 1;
-          if (this.instrument.Staves.length > 1) {
-            if (xmlNode.element("staff") !== undefined) {
-              noteStaff = parseInt(xmlNode.element("staff").value, 10);
-              if (isNaN(noteStaff)) {
-                Logging.debug("InstrumentReader.readNextXmlMeasure.get staff number");
-                noteStaff = 1;
-              }
+
+    public get MaxTieNoteFraction(): Fraction {
+        return this.maxTieNoteFraction;
+    }
+
+    public get ActiveRhythm(): RhythmInstruction {
+        return this.activeRhythm;
+    }
+
+    public set ActiveRhythm(value: RhythmInstruction) {
+        this.activeRhythm = value;
+    }
+
+    public readNextXmlMeasure(currentMeasure: SourceMeasure, measureStartAbsoluteTimestamp: Fraction, guitarPro: boolean): boolean {
+        if (this.currentXmlMeasureIndex >= this.xmlMeasureList.length) {
+            return false;
+        }
+        this.currentMeasure = currentMeasure;
+        this.inSourceMeasureInstrumentIndex = this.musicSheet.getGlobalStaffIndexOfFirstStaff(this.instrument);
+        // (*) if (this.repetitionInstructionReader !== undefined) {
+        //  this.repetitionInstructionReader.prepareReadingMeasure(currentMeasure, this.currentXmlMeasureIndex);
+        //}
+        let currentFraction: Fraction = new Fraction(0, 1);
+        let previousFraction: Fraction = new Fraction(0, 1);
+        let divisionsException: boolean = false;
+        this.maxTieNoteFraction = new Fraction(0, 1);
+        let lastNoteWasGrace: boolean = false;
+        try {
+            let xmlMeasureListArr: IXmlElement[] = this.xmlMeasureList[this.currentXmlMeasureIndex].elements();
+            for (let xmlNode of xmlMeasureListArr) {
+                if (xmlNode.name === "note") {
+                    if (xmlNode.hasAttributes && xmlNode.attribute("print-object") && xmlNode.attribute("print-spacing")) {
+                        continue;
+                    }
+                    let noteStaff: number = 1;
+                    if (this.instrument.Staves.length > 1) {
+                        if (xmlNode.element("staff") !== undefined) {
+                            noteStaff = parseInt(xmlNode.element("staff").value, 10);
+                            if (isNaN(noteStaff)) {
+                                Logging.debug("InstrumentReader.readNextXmlMeasure.get staff number");
+                                noteStaff = 1;
+                            }
+                        }
+                    }
+
+                    this.currentStaff = this.instrument.Staves[noteStaff - 1];
+                    let isChord: boolean = xmlNode.element("chord") !== undefined;
+                    if (xmlNode.element("voice") !== undefined) {
+                        let noteVoice: number = parseInt(xmlNode.element("voice").value, 10);
+                        this.currentVoiceGenerator = this.getOrCreateVoiceGenerator(noteVoice, noteStaff - 1);
+                    } else {
+                        if (!isChord || this.currentVoiceGenerator === undefined) {
+                            this.currentVoiceGenerator = this.getOrCreateVoiceGenerator(1, noteStaff - 1);
+                        }
+                    }
+                    let noteDivisions: number = 0;
+                    let noteDuration: Fraction = new Fraction(0, 1);
+                    let isTuplet: boolean = false;
+                    if (xmlNode.element("duration") !== undefined) {
+                        noteDivisions = parseInt(xmlNode.element("duration").value, 10);
+                        if (!isNaN(noteDivisions)) {
+                            noteDuration = new Fraction(noteDivisions, 4 * this.divisions);
+                            if (noteDivisions === 0) {
+                                noteDuration = this.getNoteDurationFromTypeNode(xmlNode);
+                            }
+                            if (xmlNode.element("time-modification") !== undefined) {
+                                noteDuration = this.getNoteDurationForTuplet(xmlNode);
+                                isTuplet = true;
+                            }
+                        } else {
+                            let errorMsg: string = ITextTranslation.translateText("ReaderErrorMessages/NoteDurationError", "Invalid Note Duration.");
+                            this.musicSheet.SheetErrors.pushMeasureError(errorMsg);
+                            Logging.debug("InstrumentReader.readNextXmlMeasure", errorMsg);
+                            continue;
+                        }
+                    }
+
+                    let restNote: boolean = xmlNode.element("rest") !== undefined;
+                    //Logging.log("New note found!", noteDivisions, noteDuration.toString(), restNote);
+                    let isGraceNote: boolean = xmlNode.element("grace") !== undefined || noteDivisions === 0 || isChord && lastNoteWasGrace;
+                    let musicTimestamp: Fraction = currentFraction.clone();
+                    if (isChord) {
+                        musicTimestamp = previousFraction.clone();
+                    }
+                    this.currentStaffEntry = this.currentMeasure.findOrCreateStaffEntry(
+                        musicTimestamp,
+                        this.inSourceMeasureInstrumentIndex + noteStaff - 1,
+                        this.currentStaff
+                    ).staffEntry;
+                    //Logging.log("currentStaffEntry", this.currentStaffEntry, this.currentMeasure.VerticalSourceStaffEntryContainers.length);
+
+                    if (!this.currentVoiceGenerator.hasVoiceEntry() || (!isChord && !isGraceNote && !lastNoteWasGrace) || (!lastNoteWasGrace && isGraceNote)) {
+                        this.currentVoiceGenerator.createVoiceEntry(musicTimestamp, this.currentStaffEntry, !restNote);
+                    }
+                    if (!isGraceNote && !isChord) {
+                        previousFraction = currentFraction.clone();
+                        currentFraction.Add(noteDuration);
+                    }
+                    if (
+                        isChord &&
+                        this.currentStaffEntry !== undefined &&
+                        this.currentStaffEntry.ParentStaff !== this.currentStaff
+                    ) {
+                        this.currentStaffEntry = this.currentVoiceGenerator.checkForStaffEntryLink(
+                            this.inSourceMeasureInstrumentIndex + noteStaff - 1, this.currentStaff, this.currentStaffEntry, this.currentMeasure
+                        );
+                    }
+                    let beginOfMeasure: boolean = (
+                        this.currentStaffEntry !== undefined &&
+                        this.currentStaffEntry.Timestamp !== undefined &&
+                        this.currentStaffEntry.Timestamp.Equals(new Fraction(0, 1)) && !this.currentStaffEntry.hasNotes()
+                    );
+                    this.saveAbstractInstructionList(this.instrument.Staves.length, beginOfMeasure);
+                    if (this.openChordSymbolContainer !== undefined) {
+                        this.currentStaffEntry.ChordContainer = this.openChordSymbolContainer;
+                        this.openChordSymbolContainer = undefined;
+                    }
+                    if (this.activeRhythm !== undefined) {
+                        // (*) this.musicSheet.SheetPlaybackSetting.Rhythm = this.activeRhythm.Rhythm;
+                    }
+                    if (isTuplet) {
+                        this.currentVoiceGenerator.read(
+                            xmlNode, noteDuration.Numerator,
+                            noteDuration.Denominator, restNote, isGraceNote,
+                            this.currentStaffEntry, this.currentMeasure,
+                            measureStartAbsoluteTimestamp,
+                            this.maxTieNoteFraction, isChord, guitarPro
+                        );
+                    } else {
+                        this.currentVoiceGenerator.read(
+                            xmlNode, noteDivisions, 4 * this.divisions,
+                            restNote, isGraceNote, this.currentStaffEntry,
+                            this.currentMeasure, measureStartAbsoluteTimestamp,
+                            this.maxTieNoteFraction, isChord, guitarPro
+                        );
+                    }
+                    let notationsNode: IXmlElement = xmlNode.element("notations");
+                    if (notationsNode !== undefined && notationsNode.element("dynamics") !== undefined) {
+                        // (*) let expressionReader: ExpressionReader = this.expressionReaders[this.readExpressionStaffNumber(xmlNode) - 1];
+                        //if (expressionReader !== undefined) {
+                        //  expressionReader.readExpressionParameters(
+                        //    xmlNode, this.instrument, this.divisions, currentFraction, previousFraction, this.currentMeasure.MeasureNumber, false
+                        //  );
+                        //  expressionReader.read(
+                        //    xmlNode, this.currentMeasure, previousFraction
+                        //  );
+                        //}
+                    }
+                    lastNoteWasGrace = isGraceNote;
+                } else if (xmlNode.name === "attributes") {
+                    let divisionsNode: IXmlElement = xmlNode.element("divisions");
+                    if (divisionsNode !== undefined) {
+                        this.divisions = parseInt(divisionsNode.value, 10);
+                        if (isNaN(this.divisions)) {
+                            let errorMsg: string = ITextTranslation.translateText("ReaderErrorMessages/DivisionError", "Invalid divisions value at Instrument: ");
+                            Logging.debug("InstrumentReader.readNextXmlMeasure", errorMsg);
+                            this.divisions = this.readDivisionsFromNotes();
+                            if (this.divisions > 0) {
+                                this.musicSheet.SheetErrors.push(errorMsg + this.instrument.Name);
+                            } else {
+                                divisionsException = true;
+                                throw new MusicSheetReadingException(errorMsg + this.instrument.Name);
+                            }
+                        }
+
+                    }
+                    if (
+                        xmlNode.element("divisions") === undefined &&
+                        this.divisions === 0 &&
+                        this.currentXmlMeasureIndex === 0
+                    ) {
+                        let errorMsg: string = ITextTranslation.translateText("ReaderErrorMessages/DivisionError", "Invalid divisions value at Instrument: ");
+                        this.divisions = this.readDivisionsFromNotes();
+                        if (this.divisions > 0) {
+                            this.musicSheet.SheetErrors.push(errorMsg + this.instrument.Name);
+                        } else {
+                            divisionsException = true;
+                            throw new MusicSheetReadingException(errorMsg + this.instrument.Name);
+                        }
+                    }
+                    this.addAbstractInstruction(xmlNode, guitarPro);
+                    if (currentFraction.Equals(new Fraction(0, 1)) && this.isAttributesNodeAtBeginOfMeasure(this.xmlMeasureList[this.currentXmlMeasureIndex], xmlNode)) {
+                        this.saveAbstractInstructionList(this.instrument.Staves.length, true);
+                    }
+                    if (this.isAttributesNodeAtEndOfMeasure(this.xmlMeasureList[this.currentXmlMeasureIndex], xmlNode)) {
+                        this.saveClefInstructionAtEndOfMeasure();
+                    }
+                } else if (xmlNode.name === "forward") {
+                    let forFraction: number = parseInt(xmlNode.element("duration").value, 10);
+                    currentFraction.Add(new Fraction(forFraction, 4 * this.divisions));
+                } else if (xmlNode.name === "backup") {
+                    let backFraction: number = parseInt(xmlNode.element("duration").value, 10);
+                    currentFraction.Sub(new Fraction(backFraction, 4 * this.divisions));
+                    if (currentFraction.Numerator < 0) {
+                        currentFraction = new Fraction(0, 1);
+                    }
+                    previousFraction.Sub(new Fraction(backFraction, 4 * this.divisions));
+                    if (previousFraction.Numerator < 0) {
+                        previousFraction = new Fraction(0, 1);
+                    }
+                } else if (xmlNode.name === "direction") {
+                    // unused let directionTypeNode: IXmlElement = xmlNode.element("direction-type");
+                    // (*) MetronomeReader.readMetronomeInstructions(xmlNode, this.musicSheet, this.currentXmlMeasureIndex);
+                    let relativePositionInMeasure: number = Math.min(1, currentFraction.RealValue);
+                    if (this.activeRhythm !== undefined && this.activeRhythm.Rhythm !== undefined) {
+                        relativePositionInMeasure /= this.activeRhythm.Rhythm.RealValue;
+                    }
+                    // unused: let handeled: boolean = false;
+                    // (*) if (this.repetitionInstructionReader !== undefined) {
+                    //  handeled = this.repetitionInstructionReader.handleRepetitionInstructionsFromWordsOrSymbols(directionTypeNode, relativePositionInMeasure);
+                    //}
+                    //if (!handeled) {
+                    //  let expressionReader: ExpressionReader = this.expressionReaders[0];
+                    //  let staffIndex: number = this.readExpressionStaffNumber(xmlNode) - 1;
+                    //  if (staffIndex < this.expressionReaders.length) {
+                    //    expressionReader = this.expressionReaders[staffIndex];
+                    //  }
+                    //  if (expressionReader !== undefined) {
+                    //    if (directionTypeNode.element("octave-shift") !== undefined) {
+                    //      expressionReader.readExpressionParameters(
+                    //        xmlNode, this.instrument, this.divisions, currentFraction, previousFraction, this.currentMeasure.MeasureNumber, true
+                    //      );
+                    //      expressionReader.addOctaveShift(xmlNode, this.currentMeasure, previousFraction.clone());
+                    //    }
+                    //    expressionReader.readExpressionParameters(
+                    //      xmlNode, this.instrument, this.divisions, currentFraction, previousFraction, this.currentMeasure.MeasureNumber, false
+                    //    );
+                    //    expressionReader.read(xmlNode, this.currentMeasure, currentFraction);
+                    //  }
+                    //}
+                } else if (xmlNode.name === "barline") {
+                    // (*)
+                    //if (this.repetitionInstructionReader !== undefined) {
+                    //  let measureEndsSystem: boolean = false;
+                    //  this.repetitionInstructionReader.handleLineRepetitionInstructions(xmlNode, measureEndsSystem);
+                    //  if (measureEndsSystem) {
+                    //    this.currentMeasure.BreakSystemAfter = true;
+                    //    this.currentMeasure.endsPiece = true;
+                    //  }
+                    //}
+                } else if (xmlNode.name === "sound") {
+                    // (*) MetronomeReader.readTempoInstruction(xmlNode, this.musicSheet, this.currentXmlMeasureIndex);
+                } else if (xmlNode.name === "harmony") {
+                    // (*) this.openChordSymbolContainer = ChordSymbolReader.readChordSymbol(xmlNode, this.musicSheet, this.activeKey);
+                }
             }
-          }
-
-          this.currentStaff = this.instrument.Staves[noteStaff - 1];
-          let isChord: boolean = xmlNode.element("chord") !== undefined;
-          if (xmlNode.element("voice") !== undefined) {
-            let noteVoice: number = parseInt(xmlNode.element("voice").value, 10);
-            this.currentVoiceGenerator = this.getOrCreateVoiceGenerator(noteVoice, noteStaff - 1);
-          } else {
-            if (!isChord || this.currentVoiceGenerator === undefined) {
-              this.currentVoiceGenerator = this.getOrCreateVoiceGenerator(1, noteStaff - 1);
+            for (let j in this.voiceGeneratorsDict) {
+                if (this.voiceGeneratorsDict.hasOwnProperty(j)) {
+                    let voiceGenerator: VoiceGenerator = this.voiceGeneratorsDict[j];
+                    voiceGenerator.checkForOpenBeam();
+                    voiceGenerator.checkForOpenGraceNotes();
+                }
             }
-          }
-          let noteDivisions: number = 0;
-          let noteDuration: Fraction = new Fraction(0, 1);
-          let isTuplet: boolean = false;
-          if (xmlNode.element("duration") !== undefined) {
-            noteDivisions = parseInt(xmlNode.element("duration").value, 10);
-            if (!isNaN(noteDivisions)) {
-              noteDuration = new Fraction(noteDivisions, 4 * this.divisions);
-              if (noteDivisions === 0) {
-                noteDuration = this.getNoteDurationFromTypeNode(xmlNode);
-              }
-              if (xmlNode.element("time-modification") !== undefined) {
-                noteDuration = this.getNoteDurationForTuplet(xmlNode);
-                isTuplet = true;
-              }
-            } else {
-              let errorMsg: string = ITextTranslation.translateText("ReaderErrorMessages/NoteDurationError", "Invalid Note Duration.");
-              this.musicSheet.SheetErrors.pushMeasureError(errorMsg);
-              Logging.debug("InstrumentReader.readNextXmlMeasure", errorMsg);
-              continue;
+            if (this.currentXmlMeasureIndex === this.xmlMeasureList.length - 1) {
+                for (let i: number = 0; i < this.instrument.Staves.length; i++) {
+                    if (!this.activeClefsHaveBeenInitialized[i]) {
+                        this.createDefaultClefInstruction(this.musicSheet.getGlobalStaffIndexOfFirstStaff(this.instrument) + i);
+                    }
+                }
+                if (!this.activeKeyHasBeenInitialized) {
+                    this.createDefaultKeyInstruction();
+                }
+                // (*)
+                //for (let i: number = 0; i < this.expressionReaders.length; i++) {
+                //  let reader: ExpressionReader = this.expressionReaders[i];
+                //  if (reader !== undefined) {
+                //    reader.checkForOpenExpressions(this.currentMeasure, currentFraction);
+                //  }
+                //}
             }
-          }
-
-          let restNote: boolean = xmlNode.element("rest") !== undefined;
-          //Logging.log("New note found!", noteDivisions, noteDuration.toString(), restNote);
-          let isGraceNote: boolean = xmlNode.element("grace") !== undefined || noteDivisions === 0 || isChord && lastNoteWasGrace;
-          let musicTimestamp: Fraction = currentFraction.clone();
-          if (isChord) {
-            musicTimestamp = previousFraction.clone();
-          }
-          this.currentStaffEntry = this.currentMeasure.findOrCreateStaffEntry(
-            musicTimestamp,
-            this.inSourceMeasureInstrumentIndex + noteStaff - 1,
-            this.currentStaff
-          ).staffEntry;
-          //Logging.log("currentStaffEntry", this.currentStaffEntry, this.currentMeasure.VerticalSourceStaffEntryContainers.length);
-
-          if (!this.currentVoiceGenerator.hasVoiceEntry() || (!isChord && !isGraceNote && !lastNoteWasGrace) || (!lastNoteWasGrace && isGraceNote)) {
-            this.currentVoiceGenerator.createVoiceEntry(musicTimestamp, this.currentStaffEntry, !restNote);
-          }
-          if (!isGraceNote && !isChord) {
-            previousFraction = currentFraction.clone();
-            currentFraction.Add(noteDuration);
-          }
-          if (
-            isChord &&
-            this.currentStaffEntry !== undefined &&
-            this.currentStaffEntry.ParentStaff !== this.currentStaff
-          ) {
-            this.currentStaffEntry = this.currentVoiceGenerator.checkForStaffEntryLink(
-              this.inSourceMeasureInstrumentIndex + noteStaff - 1, this.currentStaff, this.currentStaffEntry, this.currentMeasure
-            );
-          }
-          let beginOfMeasure: boolean = (
-            this.currentStaffEntry !== undefined &&
-            this.currentStaffEntry.Timestamp !== undefined &&
-            this.currentStaffEntry.Timestamp.Equals(new Fraction(0, 1)) &&
-            !this.currentStaffEntry.hasNotes()
-          );
-          this.saveAbstractInstructionList(this.instrument.Staves.length, beginOfMeasure);
-          if (this.openChordSymbolContainer !== undefined) {
-            this.currentStaffEntry.ChordContainer = this.openChordSymbolContainer;
-            this.openChordSymbolContainer = undefined;
-          }
-          if (this.activeRhythm !== undefined) {
-            // (*) this.musicSheet.SheetPlaybackSetting.Rhythm = this.activeRhythm.Rhythm;
-          }
-          if (isTuplet) {
-            this.currentVoiceGenerator.read(
-              xmlNode, noteDuration.Numerator,
-              noteDuration.Denominator, restNote, isGraceNote,
-              this.currentStaffEntry, this.currentMeasure,
-              measureStartAbsoluteTimestamp,
-              this.maxTieNoteFraction, isChord, guitarPro
-            );
-          } else {
-            this.currentVoiceGenerator.read(
-            xmlNode, noteDivisions, 4 * this.divisions,
-            restNote, isGraceNote, this.currentStaffEntry,
-            this.currentMeasure, measureStartAbsoluteTimestamp,
-            this.maxTieNoteFraction, isChord, guitarPro
-            );
-          }
-          let notationsNode: IXmlElement = xmlNode.element("notations");
-          if (notationsNode !== undefined && notationsNode.element("dynamics") !== undefined) {
-            // (*) let expressionReader: ExpressionReader = this.expressionReaders[this.readExpressionStaffNumber(xmlNode) - 1];
-            //if (expressionReader !== undefined) {
-            //  expressionReader.readExpressionParameters(
-            //    xmlNode, this.instrument, this.divisions, currentFraction, previousFraction, this.currentMeasure.MeasureNumber, false
-            //  );
-            //  expressionReader.read(
-            //    xmlNode, this.currentMeasure, previousFraction
-            //  );
-            //}
-          }
-          lastNoteWasGrace = isGraceNote;
-        } else if (xmlNode.name === "attributes") {
-          let divisionsNode: IXmlElement = xmlNode.element("divisions");
-          if (divisionsNode !== undefined) {
-            this.divisions = parseInt(divisionsNode.value, 10);
-            if (isNaN(this.divisions)) {
-              let errorMsg: string = ITextTranslation.translateText("ReaderErrorMessages/DivisionError", "Invalid divisions value at Instrument: ");
-              Logging.debug("InstrumentReader.readNextXmlMeasure", errorMsg);
-              this.divisions = this.readDivisionsFromNotes();
-              if (this.divisions > 0) {
-                this.musicSheet.SheetErrors.push(errorMsg + this.instrument.Name);
-              } else {
-                divisionsException = true;
-                throw new MusicSheetReadingException(errorMsg + this.instrument.Name);
-              }
+        } catch (e) {
+            if (divisionsException) {
+                throw new MusicSheetReadingException(e.Message);
             }
+            let errorMsg: string = ITextTranslation.translateText("ReaderErrorMessages/MeasureError", "Error while reading Measure.");
+            this.musicSheet.SheetErrors.pushMeasureError(errorMsg);
+            Logging.debug("InstrumentReader.readNextXmlMeasure", errorMsg, e);
+        }
 
-          }
-          if (
-            xmlNode.element("divisions") === undefined &&
-            this.divisions === 0 &&
-            this.currentXmlMeasureIndex === 0
-          ) {
-            let errorMsg: string = ITextTranslation.translateText("ReaderErrorMessages/DivisionError", "Invalid divisions value at Instrument: ");
-            this.divisions = this.readDivisionsFromNotes();
-            if (this.divisions > 0) {
-              this.musicSheet.SheetErrors.push(errorMsg + this.instrument.Name);
-            } else {
-              divisionsException = true;
-              throw new MusicSheetReadingException(errorMsg + this.instrument.Name);
+        this.previousMeasure = this.currentMeasure;
+        this.currentXmlMeasureIndex += 1;
+        return true;
+    }
+
+    public doCalculationsAfterDurationHasBeenSet(): void {
+        for (let j in this.voiceGeneratorsDict) {
+            if (this.voiceGeneratorsDict.hasOwnProperty(j)) {
+                this.voiceGeneratorsDict[j].checkOpenTies();
             }
-          }
-          this.addAbstractInstruction(xmlNode, guitarPro);
-          if (currentFraction.Equals(new Fraction(0, 1)) && this.isAttributesNodeAtBeginOfMeasure(this.xmlMeasureList[this.currentXmlMeasureIndex], xmlNode)) {
-            this.saveAbstractInstructionList(this.instrument.Staves.length, true);
-          }
-          if (this.isAttributesNodeAtEndOfMeasure(this.xmlMeasureList[this.currentXmlMeasureIndex], xmlNode)) {
-            this.saveClefInstructionAtEndOfMeasure();
-          }
-        } else if (xmlNode.name === "forward") {
-          let forFraction: number = parseInt(xmlNode.element("duration").value, 10);
-          currentFraction.Add(new Fraction(forFraction, 4 * this.divisions));
-        } else if (xmlNode.name === "backup") {
-          let backFraction: number = parseInt(xmlNode.element("duration").value, 10);
-          currentFraction.Sub(new Fraction(backFraction, 4 * this.divisions));
-          if (currentFraction.Numerator < 0) {
-            currentFraction = new Fraction(0, 1);
-          }
-          previousFraction.Sub(new Fraction(backFraction, 4 * this.divisions));
-          if (previousFraction.Numerator < 0) {
-            previousFraction = new Fraction(0, 1);
-          }
-        } else if (xmlNode.name === "direction") {
-          // unused let directionTypeNode: IXmlElement = xmlNode.element("direction-type");
-          // (*) MetronomeReader.readMetronomeInstructions(xmlNode, this.musicSheet, this.currentXmlMeasureIndex);
-          let relativePositionInMeasure: number = Math.min(1, currentFraction.RealValue);
-          if (this.activeRhythm !== undefined && this.activeRhythm.Rhythm !== undefined) {
-            relativePositionInMeasure /= this.activeRhythm.Rhythm.RealValue;
-          }
-          // unused: let handeled: boolean = false;
-          // (*) if (this.repetitionInstructionReader !== undefined) {
-          //  handeled = this.repetitionInstructionReader.handleRepetitionInstructionsFromWordsOrSymbols(directionTypeNode, relativePositionInMeasure);
-          //}
-          //if (!handeled) {
-          //  let expressionReader: ExpressionReader = this.expressionReaders[0];
-          //  let staffIndex: number = this.readExpressionStaffNumber(xmlNode) - 1;
-          //  if (staffIndex < this.expressionReaders.length) {
-          //    expressionReader = this.expressionReaders[staffIndex];
-          //  }
-          //  if (expressionReader !== undefined) {
-          //    if (directionTypeNode.element("octave-shift") !== undefined) {
-          //      expressionReader.readExpressionParameters(
-          //        xmlNode, this.instrument, this.divisions, currentFraction, previousFraction, this.currentMeasure.MeasureNumber, true
-          //      );
-          //      expressionReader.addOctaveShift(xmlNode, this.currentMeasure, previousFraction.clone());
-          //    }
-          //    expressionReader.readExpressionParameters(
-          //      xmlNode, this.instrument, this.divisions, currentFraction, previousFraction, this.currentMeasure.MeasureNumber, false
-          //    );
-          //    expressionReader.read(xmlNode, this.currentMeasure, currentFraction);
-          //  }
-          //}
-        } else if (xmlNode.name === "barline") {
-          // (*)
-          //if (this.repetitionInstructionReader !== undefined) {
-          //  let measureEndsSystem: boolean = false;
-          //  this.repetitionInstructionReader.handleLineRepetitionInstructions(xmlNode, measureEndsSystem);
-          //  if (measureEndsSystem) {
-          //    this.currentMeasure.BreakSystemAfter = true;
-          //    this.currentMeasure.endsPiece = true;
-          //  }
-          //}
-        } else if (xmlNode.name === "sound") {
-          // (*) MetronomeReader.readTempoInstruction(xmlNode, this.musicSheet, this.currentXmlMeasureIndex);
-        } else if (xmlNode.name === "harmony") {
-          // (*) this.openChordSymbolContainer = ChordSymbolReader.readChordSymbol(xmlNode, this.musicSheet, this.activeKey);
-        }
-      }
-      for (let j in this.voiceGeneratorsDict) {
-        if (this.voiceGeneratorsDict.hasOwnProperty(j)) {
-          let voiceGenerator: VoiceGenerator = this.voiceGeneratorsDict[j];
-          voiceGenerator.checkForOpenBeam();
-          voiceGenerator.checkForOpenGraceNotes();
-        }
-      }
-      if (this.currentXmlMeasureIndex === this.xmlMeasureList.length - 1) {
-        for (let i: number = 0; i < this.instrument.Staves.length; i++) {
-          if (!this.activeClefsHaveBeenInitialized[i]) {
-            this.createDefaultClefInstruction(this.musicSheet.getGlobalStaffIndexOfFirstStaff(this.instrument) + i);
-        }}
-        if (!this.activeKeyHasBeenInitialized) {
-          this.createDefaultKeyInstruction();
         }
-        // (*)
-        //for (let i: number = 0; i < this.expressionReaders.length; i++) {
-        //  let reader: ExpressionReader = this.expressionReaders[i];
-        //  if (reader !== undefined) {
-        //    reader.checkForOpenExpressions(this.currentMeasure, currentFraction);
-        //  }
-        //}
-      }
-    } catch (e) {
-      if (divisionsException) {
-        throw new MusicSheetReadingException(e.Message);
-      }
-      let errorMsg: string = ITextTranslation.translateText("ReaderErrorMessages/MeasureError", "Error while reading Measure.");
-      this.musicSheet.SheetErrors.pushMeasureError(errorMsg);
-      Logging.debug("InstrumentReader.readNextXmlMeasure", errorMsg, e);
     }
 
-    this.previousMeasure = this.currentMeasure;
-    this.currentXmlMeasureIndex += 1;
-    return true;
-  }
-  public doCalculationsAfterDurationHasBeenSet(): void {
-    for (let j in this.voiceGeneratorsDict) {
-      if (this.voiceGeneratorsDict.hasOwnProperty(j)) {
-        this.voiceGeneratorsDict[j].checkOpenTies();
-      }
-    }
-  }
-  private getOrCreateVoiceGenerator(voiceId: number, staffId: number): VoiceGenerator {
-    let staff: Staff = this.instrument.Staves[staffId];
-    let voiceGenerator: VoiceGenerator = this.voiceGeneratorsDict[voiceId];
-    if (voiceGenerator !== undefined) {
-      if (staff.Voices.indexOf(voiceGenerator.GetVoice) === -1) {
-        staff.Voices.push(voiceGenerator.GetVoice);
-      }
-    } else {
-      let mainVoiceGenerator: VoiceGenerator = this.staffMainVoiceGeneratorDict[staffId];
-      if (mainVoiceGenerator !== undefined) {
-        voiceGenerator = new VoiceGenerator(this.instrument, voiceId, this.slurReader, mainVoiceGenerator.GetVoice);
-        staff.Voices.push(voiceGenerator.GetVoice);
-        this.voiceGeneratorsDict[voiceId] = voiceGenerator;
-      } else {
-        voiceGenerator = new VoiceGenerator(this.instrument, voiceId, this.slurReader);
-        staff.Voices.push(voiceGenerator.GetVoice);
-        this.voiceGeneratorsDict[voiceId] = voiceGenerator;
-        this.staffMainVoiceGeneratorDict[staffId] = voiceGenerator;
-      }
+    private getOrCreateVoiceGenerator(voiceId: number, staffId: number): VoiceGenerator {
+        let staff: Staff = this.instrument.Staves[staffId];
+        let voiceGenerator: VoiceGenerator = this.voiceGeneratorsDict[voiceId];
+        if (voiceGenerator !== undefined) {
+            if (staff.Voices.indexOf(voiceGenerator.GetVoice) === -1) {
+                staff.Voices.push(voiceGenerator.GetVoice);
+            }
+        } else {
+            let mainVoiceGenerator: VoiceGenerator = this.staffMainVoiceGeneratorDict[staffId];
+            if (mainVoiceGenerator !== undefined) {
+                voiceGenerator = new VoiceGenerator(this.instrument, voiceId, this.slurReader, mainVoiceGenerator.GetVoice);
+                staff.Voices.push(voiceGenerator.GetVoice);
+                this.voiceGeneratorsDict[voiceId] = voiceGenerator;
+            } else {
+                voiceGenerator = new VoiceGenerator(this.instrument, voiceId, this.slurReader);
+                staff.Voices.push(voiceGenerator.GetVoice);
+                this.voiceGeneratorsDict[voiceId] = voiceGenerator;
+                this.staffMainVoiceGeneratorDict[staffId] = voiceGenerator;
+            }
+        }
+        return voiceGenerator;
     }
-    return voiceGenerator;
-  }
 
 
-  //private createExpressionGenerators(numberOfStaves: number): void {
-  //  // (*)
-  //  //this.expressionReaders = new Array(numberOfStaves);
-  //  //for (let i: number = 0; i < numberOfStaves; i++) {
-  //  //  this.expressionReaders[i] = MusicSymbolModuleFactory.createExpressionGenerator(this.musicSheet, this.instrument, i + 1);
-  //  //}
-  //}
+    //private createExpressionGenerators(numberOfStaves: number): void {
+    //  // (*)
+    //  //this.expressionReaders = new Array(numberOfStaves);
+    //  //for (let i: number = 0; i < numberOfStaves; i++) {
+    //  //  this.expressionReaders[i] = MusicSymbolModuleFactory.createExpressionGenerator(this.musicSheet, this.instrument, i + 1);
+    //  //}
+    //}
 
 
-  private createDefaultClefInstruction(staffIndex: number): void {
-    let first: SourceMeasure;
-    if (this.musicSheet.SourceMeasures.length > 0) {
-      first = this.musicSheet.SourceMeasures[0];
-    } else {
-      first = this.currentMeasure;
-    }
-    let clefInstruction: ClefInstruction = new ClefInstruction(ClefEnum.G, 0, 2);
-    let firstStaffEntry: SourceStaffEntry;
-    if (first.FirstInstructionsStaffEntries[staffIndex] === undefined) {
-      firstStaffEntry = new SourceStaffEntry(undefined, undefined);
-      first.FirstInstructionsStaffEntries[staffIndex] = firstStaffEntry;
-    } else {
-      firstStaffEntry = first.FirstInstructionsStaffEntries[staffIndex];
-      firstStaffEntry.removeFirstInstructionOfTypeClefInstruction();
-    }
-    clefInstruction.Parent = firstStaffEntry;
-    firstStaffEntry.Instructions.splice(0, 0, clefInstruction);
-  }
-
-  private createDefaultKeyInstruction(): void {
-    let first: SourceMeasure;
-    if (this.musicSheet.SourceMeasures.length > 0) {
-      first = this.musicSheet.SourceMeasures[0];
-    } else {
-      first = this.currentMeasure;
-    }
-    let keyInstruction: KeyInstruction = new KeyInstruction(undefined, 0, KeyEnum.major);
-    for (let j: number = this.inSourceMeasureInstrumentIndex; j < this.inSourceMeasureInstrumentIndex + this.instrument.Staves.length; j++) {
-      if (first.FirstInstructionsStaffEntries[j] === undefined) {
-        let firstStaffEntry: SourceStaffEntry = new SourceStaffEntry(undefined, undefined);
-        first.FirstInstructionsStaffEntries[j] = firstStaffEntry;
-        keyInstruction.Parent = firstStaffEntry;
-        firstStaffEntry.Instructions.push(keyInstruction);
-      } else {
-        let firstStaffEntry: SourceStaffEntry = first.FirstInstructionsStaffEntries[j];
-        keyInstruction.Parent = firstStaffEntry;
-        firstStaffEntry.removeFirstInstructionOfTypeKeyInstruction();
-        if (firstStaffEntry.Instructions[0] instanceof ClefInstruction) {
-          firstStaffEntry.Instructions.splice(1, 0, keyInstruction);
+    private createDefaultClefInstruction(staffIndex: number): void {
+        let first: SourceMeasure;
+        if (this.musicSheet.SourceMeasures.length > 0) {
+            first = this.musicSheet.SourceMeasures[0];
         } else {
-          firstStaffEntry.Instructions.splice(0, 0, keyInstruction);
+            first = this.currentMeasure;
         }
-      }
-    }
-  }
-  private isAttributesNodeAtBeginOfMeasure(parentNode: IXmlElement, attributesNode: IXmlElement): boolean {
-    let children: IXmlElement[] = parentNode.elements();
-    let attributesNodeIndex: number = children.indexOf(attributesNode); // FIXME | 0
-    if (attributesNodeIndex > 0 && children[attributesNodeIndex - 1].name === "backup") {
-      return true;
-    }
-    let firstNoteNodeIndex: number = -1;
-    for (let i: number = 0; i < children.length; i++) {
-      if (children[i].name === "note") {
-        firstNoteNodeIndex = i;
-        break;
-      }
-    }
-    return (attributesNodeIndex < firstNoteNodeIndex && firstNoteNodeIndex > 0) || (firstNoteNodeIndex < 0);
-  }
-  private isAttributesNodeAtEndOfMeasure(parentNode: IXmlElement, attributesNode: IXmlElement): boolean {
-    let childs: IXmlElement[] = parentNode.elements().slice();
-    let attributesNodeIndex: number = 0;
-    for (let i: number = 0; i < childs.length; i++) {
-      if (childs[i] === attributesNode) {
-        attributesNodeIndex = i;
-        break;
-      }
-    }
-    let nextNoteNodeIndex: number = 0;
-    for (let i: number = attributesNodeIndex; i < childs.length; i++) {
-      if (childs[i].name === "note") {
-        nextNoteNodeIndex = i;
-        break;
-      }
-    }
-    return attributesNodeIndex > nextNoteNodeIndex;
-  }
-  private getNoteDurationFromTypeNode(xmlNode: IXmlElement): Fraction {
-    if (xmlNode.element("type") !== undefined) {
-      let typeNode: IXmlElement = xmlNode.element("type");
-      if (typeNode !== undefined) {
-        let type: string = typeNode.value;
-        return this.currentVoiceGenerator.getNoteDurationFromType(type);
-      }
-    }
-    return new Fraction(0, 4 * this.divisions);
-  }
-  private addAbstractInstruction(node: IXmlElement, guitarPro: boolean): void {
-    if (node.element("divisions") !== undefined) {
-      if (node.elements().length === 1) { return; }
-    }
-    let transposeNode: IXmlElement = node.element("transpose");
-    if (transposeNode !== undefined) {
-      let chromaticNode: IXmlElement = transposeNode.element("chromatic");
-      if (chromaticNode !== undefined) {
-        this.instrument.PlaybackTranspose = parseInt(chromaticNode.value, 10);
-      }
+        let clefInstruction: ClefInstruction = new ClefInstruction(ClefEnum.G, 0, 2);
+        let firstStaffEntry: SourceStaffEntry;
+        if (first.FirstInstructionsStaffEntries[staffIndex] === undefined) {
+            firstStaffEntry = new SourceStaffEntry(undefined, undefined);
+            first.FirstInstructionsStaffEntries[staffIndex] = firstStaffEntry;
+        } else {
+            firstStaffEntry = first.FirstInstructionsStaffEntries[staffIndex];
+            firstStaffEntry.removeFirstInstructionOfTypeClefInstruction();
+        }
+        clefInstruction.Parent = firstStaffEntry;
+        firstStaffEntry.Instructions.splice(0, 0, clefInstruction);
     }
-    let clefList: IXmlElement[] = node.elements("clef");
-    let errorMsg: string;
-    if (clefList.length > 0) {
-      for (let idx: number = 0, len: number = clefList.length; idx < len; ++idx) {
-        let nodeList: IXmlElement = clefList[idx];
-        let clefEnum: ClefEnum = ClefEnum.G;
-        let line: number = 2;
-        let staffNumber: number = 1;
-        let clefOctaveOffset: number = 0;
-        let lineNode: IXmlElement = nodeList.element("line");
-        if (lineNode !== undefined) {
-          try {
-            line = parseInt(lineNode.value, 10);
-          } catch (ex) {
-            errorMsg = ITextTranslation.translateText(
-                "ReaderErrorMessages/ClefLineError",
-                "Invalid clef line given -> using default clef line."
-            );
-            this.musicSheet.SheetErrors.pushMeasureError(errorMsg);
-            line = 2;
-            Logging.debug("InstrumentReader.addAbstractInstruction", errorMsg, ex);
-          }
 
+    private createDefaultKeyInstruction(): void {
+        let first: SourceMeasure;
+        if (this.musicSheet.SourceMeasures.length > 0) {
+            first = this.musicSheet.SourceMeasures[0];
+        } else {
+            first = this.currentMeasure;
         }
-        let signNode: IXmlElement = nodeList.element("sign");
-        if (signNode !== undefined) {
-          try {
-            clefEnum = ClefEnum[signNode.value];
-            if (!ClefInstruction.isSupportedClef(clefEnum)) {
-              if (clefEnum === ClefEnum.TAB && guitarPro) {
-                clefOctaveOffset = -1;
-              }
-              errorMsg = ITextTranslation.translateText(
-                  "ReaderErrorMessages/ClefError",
-                  "Unsupported clef found -> using default clef."
-              );
-              this.musicSheet.SheetErrors.pushMeasureError(errorMsg);
-              clefEnum = ClefEnum.G;
-              line = 2;
+        let keyInstruction: KeyInstruction = new KeyInstruction(undefined, 0, KeyEnum.major);
+        for (let j: number = this.inSourceMeasureInstrumentIndex; j < this.inSourceMeasureInstrumentIndex + this.instrument.Staves.length; j++) {
+            if (first.FirstInstructionsStaffEntries[j] === undefined) {
+                let firstStaffEntry: SourceStaffEntry = new SourceStaffEntry(undefined, undefined);
+                first.FirstInstructionsStaffEntries[j] = firstStaffEntry;
+                keyInstruction.Parent = firstStaffEntry;
+                firstStaffEntry.Instructions.push(keyInstruction);
+            } else {
+                let firstStaffEntry: SourceStaffEntry = first.FirstInstructionsStaffEntries[j];
+                keyInstruction.Parent = firstStaffEntry;
+                firstStaffEntry.removeFirstInstructionOfTypeKeyInstruction();
+                if (firstStaffEntry.Instructions[0] instanceof ClefInstruction) {
+                    firstStaffEntry.Instructions.splice(1, 0, keyInstruction);
+                } else {
+                    firstStaffEntry.Instructions.splice(0, 0, keyInstruction);
+                }
             }
-          } catch (e) {
-            errorMsg = ITextTranslation.translateText(
-                "ReaderErrorMessages/ClefError",
-                "Invalid clef found -> using default clef."
-            );
-            this.musicSheet.SheetErrors.pushMeasureError(errorMsg);
-            clefEnum = ClefEnum.G;
-            line = 2;
-            Logging.debug("InstrumentReader.addAbstractInstruction", errorMsg, e);
-          }
-
         }
-        let clefOctaveNode: IXmlElement = nodeList.element("clef-octave-change");
-        if (clefOctaveNode !== undefined) {
-          try {
-            clefOctaveOffset = parseInt(clefOctaveNode.value, 10);
-          } catch (e) {
-            errorMsg = ITextTranslation.translateText(
-                "ReaderErrorMessages/ClefOctaveError",
-                "Invalid clef octave found -> using default clef octave."
-            );
-            this.musicSheet.SheetErrors.pushMeasureError(errorMsg);
-            clefOctaveOffset = 0;
-          }
+    }
 
+    private isAttributesNodeAtBeginOfMeasure(parentNode: IXmlElement, attributesNode: IXmlElement): boolean {
+        let children: IXmlElement[] = parentNode.elements();
+        let attributesNodeIndex: number = children.indexOf(attributesNode); // FIXME | 0
+        if (attributesNodeIndex > 0 && children[attributesNodeIndex - 1].name === "backup") {
+            return true;
         }
-        if (nodeList.hasAttributes && nodeList.attributes()[0].name === "number") {
-          try {
-            staffNumber = parseInt(nodeList.attributes()[0].value, 10);
-          } catch (err) {
-            errorMsg = ITextTranslation.translateText(
-                "ReaderErrorMessages/ClefError",
-                "Invalid clef found -> using default clef."
-            );
-            this.musicSheet.SheetErrors.pushMeasureError(errorMsg);
-            staffNumber = 1;
-          }
+        let firstNoteNodeIndex: number = -1;
+        for (let i: number = 0; i < children.length; i++) {
+            if (children[i].name === "note") {
+                firstNoteNodeIndex = i;
+                break;
+            }
         }
+        return (attributesNodeIndex < firstNoteNodeIndex && firstNoteNodeIndex > 0) || (firstNoteNodeIndex < 0);
+    }
 
-        let clefInstruction: ClefInstruction = new ClefInstruction(clefEnum, clefOctaveOffset, line);
-        this.abstractInstructions.push([staffNumber, clefInstruction]);
-      }
+    private isAttributesNodeAtEndOfMeasure(parentNode: IXmlElement, attributesNode: IXmlElement): boolean {
+        let childs: IXmlElement[] = parentNode.elements().slice();
+        let attributesNodeIndex: number = 0;
+        for (let i: number = 0; i < childs.length; i++) {
+            if (childs[i] === attributesNode) {
+                attributesNodeIndex = i;
+                break;
+            }
+        }
+        let nextNoteNodeIndex: number = 0;
+        for (let i: number = attributesNodeIndex; i < childs.length; i++) {
+            if (childs[i].name === "note") {
+                nextNoteNodeIndex = i;
+                break;
+            }
+        }
+        return attributesNodeIndex > nextNoteNodeIndex;
     }
-    if (node.element("key") !== undefined && this.instrument.MidiInstrumentId !== MidiInstrument.Percussion) {
-      let key: number = 0;
-      let keyNode: IXmlElement = node.element("key").element("fifths");
-      if (keyNode !== undefined) {
-        try {
-          key = parseInt(keyNode.value, 10);
-        } catch (ex) {
-          errorMsg = ITextTranslation.translateText(
-              "ReaderErrorMessages/KeyError",
-              "Invalid key found -> set to default."
-          );
-          this.musicSheet.SheetErrors.pushMeasureError(errorMsg);
-          key = 0;
-          Logging.debug("InstrumentReader.addAbstractInstruction", errorMsg, ex);
+
+    private getNoteDurationFromTypeNode(xmlNode: IXmlElement): Fraction {
+        if (xmlNode.element("type") !== undefined) {
+            let typeNode: IXmlElement = xmlNode.element("type");
+            if (typeNode !== undefined) {
+                let type: string = typeNode.value;
+                return this.currentVoiceGenerator.getNoteDurationFromType(type);
+            }
         }
+        return new Fraction(0, 4 * this.divisions);
+    }
 
-      }
-      let keyEnum: KeyEnum = KeyEnum.none;
-      let modeNode: IXmlElement = node.element("key");
-      if (modeNode !== undefined) { modeNode = modeNode.element("mode"); }
-      if (modeNode !== undefined) {
-        try {
-          keyEnum = KeyEnum[modeNode.value];
-        } catch (ex) {
-          errorMsg = ITextTranslation.translateText(
-              "ReaderErrorMessages/KeyError",
-              "Invalid key found -> set to default."
-          );
-          this.musicSheet.SheetErrors.pushMeasureError(errorMsg);
-          keyEnum = KeyEnum.major;
-          Logging.debug("InstrumentReader.addAbstractInstruction", errorMsg, ex);
+    private addAbstractInstruction(node: IXmlElement, guitarPro: boolean): void {
+        if (node.element("divisions") !== undefined) {
+            if (node.elements().length === 1) {
+                return;
+            }
         }
+        let transposeNode: IXmlElement = node.element("transpose");
+        if (transposeNode !== undefined) {
+            let chromaticNode: IXmlElement = transposeNode.element("chromatic");
+            if (chromaticNode !== undefined) {
+                this.instrument.PlaybackTranspose = parseInt(chromaticNode.value, 10);
+            }
+        }
+        let clefList: IXmlElement[] = node.elements("clef");
+        let errorMsg: string;
+        if (clefList.length > 0) {
+            for (let idx: number = 0, len: number = clefList.length; idx < len; ++idx) {
+                let nodeList: IXmlElement = clefList[idx];
+                let clefEnum: ClefEnum = ClefEnum.G;
+                let line: number = 2;
+                let staffNumber: number = 1;
+                let clefOctaveOffset: number = 0;
+                let lineNode: IXmlElement = nodeList.element("line");
+                if (lineNode !== undefined) {
+                    try {
+                        line = parseInt(lineNode.value, 10);
+                    } catch (ex) {
+                        errorMsg = ITextTranslation.translateText(
+                            "ReaderErrorMessages/ClefLineError",
+                            "Invalid clef line given -> using default clef line."
+                        );
+                        this.musicSheet.SheetErrors.pushMeasureError(errorMsg);
+                        line = 2;
+                        Logging.debug("InstrumentReader.addAbstractInstruction", errorMsg, ex);
+                    }
 
-      }
-      let keyInstruction: KeyInstruction = new KeyInstruction(undefined, key, keyEnum);
-      this.abstractInstructions.push([1, keyInstruction]);
-    }
-    if (node.element("time") !== undefined) {
-      let symbolEnum: RhythmSymbolEnum = RhythmSymbolEnum.NONE;
-      let timeNode: IXmlElement = node.element("time");
-      if (timeNode !== undefined && timeNode.hasAttributes) {
-        let firstAttr: IXmlAttribute = timeNode.firstAttribute;
-        if (firstAttr.name === "symbol") {
-          if (firstAttr.value === "common") {
-            symbolEnum = RhythmSymbolEnum.COMMON;
-          } else if (firstAttr.value === "cut") {
-            symbolEnum = RhythmSymbolEnum.CUT;
-          }
+                }
+                let signNode: IXmlElement = nodeList.element("sign");
+                if (signNode !== undefined) {
+                    try {
+                        clefEnum = ClefEnum[signNode.value];
+                        if (!ClefInstruction.isSupportedClef(clefEnum)) {
+                            if (clefEnum === ClefEnum.TAB && guitarPro) {
+                                clefOctaveOffset = -1;
+                            }
+                            errorMsg = ITextTranslation.translateText(
+                                "ReaderErrorMessages/ClefError",
+                                "Unsupported clef found -> using default clef."
+                            );
+                            this.musicSheet.SheetErrors.pushMeasureError(errorMsg);
+                            clefEnum = ClefEnum.G;
+                            line = 2;
+                        }
+                    } catch (e) {
+                        errorMsg = ITextTranslation.translateText(
+                            "ReaderErrorMessages/ClefError",
+                            "Invalid clef found -> using default clef."
+                        );
+                        this.musicSheet.SheetErrors.pushMeasureError(errorMsg);
+                        clefEnum = ClefEnum.G;
+                        line = 2;
+                        Logging.debug("InstrumentReader.addAbstractInstruction", errorMsg, e);
+                    }
+
+                }
+                let clefOctaveNode: IXmlElement = nodeList.element("clef-octave-change");
+                if (clefOctaveNode !== undefined) {
+                    try {
+                        clefOctaveOffset = parseInt(clefOctaveNode.value, 10);
+                    } catch (e) {
+                        errorMsg = ITextTranslation.translateText(
+                            "ReaderErrorMessages/ClefOctaveError",
+                            "Invalid clef octave found -> using default clef octave."
+                        );
+                        this.musicSheet.SheetErrors.pushMeasureError(errorMsg);
+                        clefOctaveOffset = 0;
+                    }
+
+                }
+                if (nodeList.hasAttributes && nodeList.attributes()[0].name === "number") {
+                    try {
+                        staffNumber = parseInt(nodeList.attributes()[0].value, 10);
+                    } catch (err) {
+                        errorMsg = ITextTranslation.translateText(
+                            "ReaderErrorMessages/ClefError",
+                            "Invalid clef found -> using default clef."
+                        );
+                        this.musicSheet.SheetErrors.pushMeasureError(errorMsg);
+                        staffNumber = 1;
+                    }
+                }
+
+                let clefInstruction: ClefInstruction = new ClefInstruction(clefEnum, clefOctaveOffset, line);
+                this.abstractInstructions.push([staffNumber, clefInstruction]);
+            }
         }
-      }
-      let num: number = 0;
-      let denom: number = 0;
-      let senzaMisura: boolean = (timeNode !== undefined && timeNode.element("senza-misura") !== undefined);
-      let timeList: IXmlElement[] = node.elements("time");
-      let beatsList: IXmlElement[] = [];
-      let typeList: IXmlElement[] = [];
-      for (let idx: number = 0, len: number = timeList.length; idx < len; ++idx) {
-        let xmlNode: IXmlElement = timeList[idx];
-        beatsList.push.apply(beatsList, xmlNode.elements("beats"));
-        typeList.push.apply(typeList, xmlNode.elements("beat-type"));
-      }
-      if (!senzaMisura) {
-        try {
-          if (beatsList !== undefined && beatsList.length > 0 && typeList !== undefined && beatsList.length === typeList.length) {
-            let length: number = beatsList.length;
-            let fractions: Fraction[] = new Array(length);
-            let maxDenom: number = 0;
-            for (let i: number = 0; i < length; i++) {
-              let s: string = beatsList[i].value;
-              let n: number = 0;
-              let d: number = 0;
-              if (s.indexOf("+") !== -1) {
-                let numbers: string[] = s.split("+");
-                for (let idx: number = 0, len: number = numbers.length; idx < len; ++idx) {
-                  n += parseInt(numbers[idx], 10);
+        if (node.element("key") !== undefined && this.instrument.MidiInstrumentId !== MidiInstrument.Percussion) {
+            let key: number = 0;
+            let keyNode: IXmlElement = node.element("key").element("fifths");
+            if (keyNode !== undefined) {
+                try {
+                    key = parseInt(keyNode.value, 10);
+                } catch (ex) {
+                    errorMsg = ITextTranslation.translateText(
+                        "ReaderErrorMessages/KeyError",
+                        "Invalid key found -> set to default."
+                    );
+                    this.musicSheet.SheetErrors.pushMeasureError(errorMsg);
+                    key = 0;
+                    Logging.debug("InstrumentReader.addAbstractInstruction", errorMsg, ex);
                 }
-              } else {
-                n = parseInt(s, 10);
-              }
-              d = parseInt(typeList[i].value, 10);
-              maxDenom = Math.max(maxDenom, d);
-              fractions[i] = new Fraction(n, d, false);
+
             }
-            for (let i: number = 0; i < length; i++) {
-              if (fractions[i].Denominator === maxDenom) {
-                num += fractions[i].Numerator;
-              } else {
-                num += (maxDenom / fractions[i].Denominator) * fractions[i].Numerator;
-              }
+            let keyEnum: KeyEnum = KeyEnum.none;
+            let modeNode: IXmlElement = node.element("key");
+            if (modeNode !== undefined) {
+                modeNode = modeNode.element("mode");
             }
-            denom = maxDenom;
-          } else {
-            num = parseInt(node.element("time").element("beats").value, 10);
-            denom = parseInt(node.element("time").element("beat-type").value, 10);
-          }
-        } catch (ex) {
-          errorMsg = ITextTranslation.translateText("ReaderErrorMessages/RhythmError", "Invalid rhythm found -> set to default.");
-          this.musicSheet.SheetErrors.pushMeasureError(errorMsg);
-          num = 4;
-          denom = 4;
-          Logging.debug("InstrumentReader.addAbstractInstruction", errorMsg, ex);
+            if (modeNode !== undefined) {
+                try {
+                    keyEnum = KeyEnum[modeNode.value];
+                } catch (ex) {
+                    errorMsg = ITextTranslation.translateText(
+                        "ReaderErrorMessages/KeyError",
+                        "Invalid key found -> set to default."
+                    );
+                    this.musicSheet.SheetErrors.pushMeasureError(errorMsg);
+                    keyEnum = KeyEnum.major;
+                    Logging.debug("InstrumentReader.addAbstractInstruction", errorMsg, ex);
+                }
+
+            }
+            let keyInstruction: KeyInstruction = new KeyInstruction(undefined, key, keyEnum);
+            this.abstractInstructions.push([1, keyInstruction]);
         }
+        if (node.element("time") !== undefined) {
+            let symbolEnum: RhythmSymbolEnum = RhythmSymbolEnum.NONE;
+            let timeNode: IXmlElement = node.element("time");
+            if (timeNode !== undefined && timeNode.hasAttributes) {
+                let firstAttr: IXmlAttribute = timeNode.firstAttribute;
+                if (firstAttr.name === "symbol") {
+                    if (firstAttr.value === "common") {
+                        symbolEnum = RhythmSymbolEnum.COMMON;
+                    } else if (firstAttr.value === "cut") {
+                        symbolEnum = RhythmSymbolEnum.CUT;
+                    }
+                }
+            }
+            let num: number = 0;
+            let denom: number = 0;
+            let senzaMisura: boolean = (timeNode !== undefined && timeNode.element("senza-misura") !== undefined);
+            let timeList: IXmlElement[] = node.elements("time");
+            let beatsList: IXmlElement[] = [];
+            let typeList: IXmlElement[] = [];
+            for (let idx: number = 0, len: number = timeList.length; idx < len; ++idx) {
+                let xmlNode: IXmlElement = timeList[idx];
+                beatsList.push.apply(beatsList, xmlNode.elements("beats"));
+                typeList.push.apply(typeList, xmlNode.elements("beat-type"));
+            }
+            if (!senzaMisura) {
+                try {
+                    if (beatsList !== undefined && beatsList.length > 0 && typeList !== undefined && beatsList.length === typeList.length) {
+                        let length: number = beatsList.length;
+                        let fractions: Fraction[] = new Array(length);
+                        let maxDenom: number = 0;
+                        for (let i: number = 0; i < length; i++) {
+                            let s: string = beatsList[i].value;
+                            let n: number = 0;
+                            let d: number = 0;
+                            if (s.indexOf("+") !== -1) {
+                                let numbers: string[] = s.split("+");
+                                for (let idx: number = 0, len: number = numbers.length; idx < len; ++idx) {
+                                    n += parseInt(numbers[idx], 10);
+                                }
+                            } else {
+                                n = parseInt(s, 10);
+                            }
+                            d = parseInt(typeList[i].value, 10);
+                            maxDenom = Math.max(maxDenom, d);
+                            fractions[i] = new Fraction(n, d, false);
+                        }
+                        for (let i: number = 0; i < length; i++) {
+                            if (fractions[i].Denominator === maxDenom) {
+                                num += fractions[i].Numerator;
+                            } else {
+                                num += (maxDenom / fractions[i].Denominator) * fractions[i].Numerator;
+                            }
+                        }
+                        denom = maxDenom;
+                    } else {
+                        num = parseInt(node.element("time").element("beats").value, 10);
+                        denom = parseInt(node.element("time").element("beat-type").value, 10);
+                    }
+                } catch (ex) {
+                    errorMsg = ITextTranslation.translateText("ReaderErrorMessages/RhythmError", "Invalid rhythm found -> set to default.");
+                    this.musicSheet.SheetErrors.pushMeasureError(errorMsg);
+                    num = 4;
+                    denom = 4;
+                    Logging.debug("InstrumentReader.addAbstractInstruction", errorMsg, ex);
+                }
 
-        if ((num === 4 && denom === 4) || (num === 2 && denom === 2)) {
-          symbolEnum = RhythmSymbolEnum.NONE;
+                if ((num === 4 && denom === 4) || (num === 2 && denom === 2)) {
+                    symbolEnum = RhythmSymbolEnum.NONE;
+                }
+                this.abstractInstructions.push([1, new RhythmInstruction(
+                    new Fraction(num, denom, false), num, denom, symbolEnum
+                )]);
+            } else {
+                this.abstractInstructions.push([1, new RhythmInstruction(new Fraction(4, 4, false), 4, 4, RhythmSymbolEnum.NONE)]);
+            }
         }
-        this.abstractInstructions.push([1, new RhythmInstruction(
-            new Fraction(num, denom, false), num, denom, symbolEnum
-        )]);
-      } else {
-        this.abstractInstructions.push([1, new RhythmInstruction(new Fraction(4, 4, false), 4, 4, RhythmSymbolEnum.NONE)]);
-      }
     }
-  }
-
-  private saveAbstractInstructionList(numberOfStaves: number, beginOfMeasure: boolean): void {
-    for (let i: number = this.abstractInstructions.length - 1; i >= 0; i--) {
-      let pair: [number, AbstractNotationInstruction] = this.abstractInstructions[i];
-      let key: number = pair[0];
-      let value: AbstractNotationInstruction = pair[1];
-      if (value instanceof ClefInstruction) {
-        let clefInstruction: ClefInstruction = <ClefInstruction>value;
-        if (this.currentXmlMeasureIndex === 0 || (key <= this.activeClefs.length && clefInstruction !== this.activeClefs[key - 1])) {
-          if (!beginOfMeasure && this.currentStaffEntry !== undefined && !this.currentStaffEntry.hasNotes() && key - 1
-          === this.instrument.Staves.indexOf(this.currentStaffEntry.ParentStaff)) {
-            let newClefInstruction: ClefInstruction = clefInstruction;
-            newClefInstruction.Parent = this.currentStaffEntry;
-            this.currentStaffEntry.removeFirstInstructionOfType<ClefInstruction>();
-            this.currentStaffEntry.Instructions.push(newClefInstruction);
-            this.activeClefs[key - 1] = clefInstruction;
-            this.abstractInstructions.splice(i, 1);
-          } else if (beginOfMeasure) {
-            let firstStaffEntry: SourceStaffEntry;
-            if (this.currentMeasure !== undefined) {
-              let newClefInstruction: ClefInstruction = clefInstruction;
-              if (this.currentXmlMeasureIndex === 0) {
-                if (this.currentMeasure.FirstInstructionsStaffEntries[this.inSourceMeasureInstrumentIndex + key - 1] === undefined) {
-                  firstStaffEntry = new SourceStaffEntry(undefined, undefined);
-                  this.currentMeasure.FirstInstructionsStaffEntries[this.inSourceMeasureInstrumentIndex + key - 1] = firstStaffEntry;
-                  newClefInstruction.Parent = firstStaffEntry;
-                  firstStaffEntry.Instructions.push(newClefInstruction);
-                  this.activeClefsHaveBeenInitialized[key - 1] = true;
-                } else if (this.currentMeasure.FirstInstructionsStaffEntries[this.inSourceMeasureInstrumentIndex + key - 1]
-                !==
-                undefined && !(this.currentMeasure.FirstInstructionsStaffEntries[this.inSourceMeasureInstrumentIndex + key - 1].Instructions[0]
-                 instanceof ClefInstruction)) {
-                  firstStaffEntry = this.currentMeasure.FirstInstructionsStaffEntries[this.inSourceMeasureInstrumentIndex + key - 1];
-                  newClefInstruction.Parent = firstStaffEntry;
-                  firstStaffEntry.removeFirstInstructionOfType<ClefInstruction>();
-                  firstStaffEntry.Instructions.splice(0, 0, newClefInstruction);
-                  this.activeClefsHaveBeenInitialized[key - 1] = true;
-                } else {
-                  let lastStaffEntry: SourceStaffEntry = new SourceStaffEntry(undefined, undefined);
-                  this.currentMeasure.LastInstructionsStaffEntries[this.inSourceMeasureInstrumentIndex + key - 1] = lastStaffEntry;
-                  newClefInstruction.Parent = lastStaffEntry;
-                  lastStaffEntry.Instructions.push(newClefInstruction);
+
+    private saveAbstractInstructionList(numberOfStaves: number, beginOfMeasure: boolean): void {
+        for (let i: number = this.abstractInstructions.length - 1; i >= 0; i--) {
+            let pair: [number, AbstractNotationInstruction] = this.abstractInstructions[i];
+            let key: number = pair[0];
+            let value: AbstractNotationInstruction = pair[1];
+            if (value instanceof ClefInstruction) {
+                let clefInstruction: ClefInstruction = <ClefInstruction>value;
+                if (this.currentXmlMeasureIndex === 0 || (key <= this.activeClefs.length && clefInstruction !== this.activeClefs[key - 1])) {
+                    if (!beginOfMeasure && this.currentStaffEntry !== undefined && !this.currentStaffEntry.hasNotes() && key - 1
+                        === this.instrument.Staves.indexOf(this.currentStaffEntry.ParentStaff)) {
+                        let newClefInstruction: ClefInstruction = clefInstruction;
+                        newClefInstruction.Parent = this.currentStaffEntry;
+                        this.currentStaffEntry.removeFirstInstructionOfType<ClefInstruction>();
+                        this.currentStaffEntry.Instructions.push(newClefInstruction);
+                        this.activeClefs[key - 1] = clefInstruction;
+                        this.abstractInstructions.splice(i, 1);
+                    } else if (beginOfMeasure) {
+                        let firstStaffEntry: SourceStaffEntry;
+                        if (this.currentMeasure !== undefined) {
+                            let newClefInstruction: ClefInstruction = clefInstruction;
+                            if (this.currentXmlMeasureIndex === 0) {
+                                if (this.currentMeasure.FirstInstructionsStaffEntries[this.inSourceMeasureInstrumentIndex + key - 1] === undefined) {
+                                    firstStaffEntry = new SourceStaffEntry(undefined, undefined);
+                                    this.currentMeasure.FirstInstructionsStaffEntries[this.inSourceMeasureInstrumentIndex + key - 1] = firstStaffEntry;
+                                    newClefInstruction.Parent = firstStaffEntry;
+                                    firstStaffEntry.Instructions.push(newClefInstruction);
+                                    this.activeClefsHaveBeenInitialized[key - 1] = true;
+                                } else if (this.currentMeasure.FirstInstructionsStaffEntries[this.inSourceMeasureInstrumentIndex + key - 1]
+                                    !==
+                                    undefined && !(this.currentMeasure.FirstInstructionsStaffEntries[this.inSourceMeasureInstrumentIndex + key - 1].Instructions[0] instanceof ClefInstruction)) {
+                                    firstStaffEntry = this.currentMeasure.FirstInstructionsStaffEntries[this.inSourceMeasureInstrumentIndex + key - 1];
+                                    newClefInstruction.Parent = firstStaffEntry;
+                                    firstStaffEntry.removeFirstInstructionOfType<ClefInstruction>();
+                                    firstStaffEntry.Instructions.splice(0, 0, newClefInstruction);
+                                    this.activeClefsHaveBeenInitialized[key - 1] = true;
+                                } else {
+                                    let lastStaffEntry: SourceStaffEntry = new SourceStaffEntry(undefined, undefined);
+                                    this.currentMeasure.LastInstructionsStaffEntries[this.inSourceMeasureInstrumentIndex + key - 1] = lastStaffEntry;
+                                    newClefInstruction.Parent = lastStaffEntry;
+                                    lastStaffEntry.Instructions.push(newClefInstruction);
+                                }
+                            } else if (!this.activeClefsHaveBeenInitialized[key - 1]) {
+                                let first: SourceMeasure = this.musicSheet.SourceMeasures[0];
+                                if (first.FirstInstructionsStaffEntries[this.inSourceMeasureInstrumentIndex + key - 1] === undefined) {
+                                    firstStaffEntry = new SourceStaffEntry(undefined, undefined);
+                                } else {
+                                    firstStaffEntry = first.FirstInstructionsStaffEntries[this.inSourceMeasureInstrumentIndex + key - 1];
+                                    firstStaffEntry.removeFirstInstructionOfType<ClefInstruction>();
+                                }
+                                newClefInstruction.Parent = firstStaffEntry;
+                                firstStaffEntry.Instructions.splice(0, 0, newClefInstruction);
+                                this.activeClefsHaveBeenInitialized[key - 1] = true;
+                            } else {
+                                let lastStaffEntry: SourceStaffEntry = new SourceStaffEntry(undefined, undefined);
+                                this.previousMeasure.LastInstructionsStaffEntries[this.inSourceMeasureInstrumentIndex + key - 1] = lastStaffEntry;
+                                newClefInstruction.Parent = lastStaffEntry;
+                                lastStaffEntry.Instructions.push(newClefInstruction);
+                            }
+                            this.activeClefs[key - 1] = clefInstruction;
+                            this.abstractInstructions.splice(i, 1);
+                        }
+                    }
                 }
-              } else if (!this.activeClefsHaveBeenInitialized[key - 1]) {
-                let first: SourceMeasure = this.musicSheet.SourceMeasures[0];
-                if (first.FirstInstructionsStaffEntries[this.inSourceMeasureInstrumentIndex + key - 1] === undefined) {
-                  firstStaffEntry = new SourceStaffEntry(undefined, undefined);
-                } else {
-                  firstStaffEntry = first.FirstInstructionsStaffEntries[this.inSourceMeasureInstrumentIndex + key - 1];
-                  firstStaffEntry.removeFirstInstructionOfType<ClefInstruction>();
+                if (key <= this.activeClefs.length && clefInstruction === this.activeClefs[key - 1]) {
+                    this.abstractInstructions.splice(i, 1);
                 }
-                newClefInstruction.Parent = firstStaffEntry;
-                firstStaffEntry.Instructions.splice(0, 0, newClefInstruction);
-                this.activeClefsHaveBeenInitialized[key - 1] = true;
-              } else {
-                let lastStaffEntry: SourceStaffEntry = new SourceStaffEntry(undefined, undefined);
-                this.previousMeasure.LastInstructionsStaffEntries[this.inSourceMeasureInstrumentIndex + key - 1] = lastStaffEntry;
-                newClefInstruction.Parent = lastStaffEntry;
-                lastStaffEntry.Instructions.push(newClefInstruction);
-              }
-              this.activeClefs[key - 1] = clefInstruction;
-              this.abstractInstructions.splice(i, 1);
             }
-          }
-        } else { //if (key <= this.activeClefs.length && clefInstruction === this.activeClefs[key - 1]) {
-          this.abstractInstructions.splice(i, 1);
-        }
-      }
-      if (value instanceof KeyInstruction) {
-        let keyInstruction: KeyInstruction = <KeyInstruction>value;
-        if (this.activeKey === undefined || this.activeKey.Key !== keyInstruction.Key) {
-          this.activeKey = keyInstruction;
-          this.abstractInstructions.splice(i, 1);
-          let sourceMeasure: SourceMeasure;
-          if (!this.activeKeyHasBeenInitialized) {
-            this.activeKeyHasBeenInitialized = true;
-            if (this.currentXmlMeasureIndex > 0) {
-              sourceMeasure = this.musicSheet.SourceMeasures[0];
-            } else {
-              sourceMeasure = this.currentMeasure;
+            if (value instanceof KeyInstruction) {
+                let keyInstruction: KeyInstruction = <KeyInstruction>value;
+                if (this.activeKey === undefined || this.activeKey.Key !== keyInstruction.Key) {
+                    this.activeKey = keyInstruction;
+                    this.abstractInstructions.splice(i, 1);
+                    let sourceMeasure: SourceMeasure;
+                    if (!this.activeKeyHasBeenInitialized) {
+                        this.activeKeyHasBeenInitialized = true;
+                        if (this.currentXmlMeasureIndex > 0) {
+                            sourceMeasure = this.musicSheet.SourceMeasures[0];
+                        } else {
+                            sourceMeasure = this.currentMeasure;
+                        }
+                    } else {
+                        sourceMeasure = this.currentMeasure;
+                    }
+                    if (sourceMeasure !== undefined) {
+                        for (let j: number = this.inSourceMeasureInstrumentIndex; j < this.inSourceMeasureInstrumentIndex + numberOfStaves; j++) {
+                            let newKeyInstruction: KeyInstruction = keyInstruction;
+                            if (sourceMeasure.FirstInstructionsStaffEntries[j] === undefined) {
+                                let firstStaffEntry: SourceStaffEntry = new SourceStaffEntry(undefined, undefined);
+                                sourceMeasure.FirstInstructionsStaffEntries[j] = firstStaffEntry;
+                                newKeyInstruction.Parent = firstStaffEntry;
+                                firstStaffEntry.Instructions.push(newKeyInstruction);
+                            } else {
+                                let firstStaffEntry: SourceStaffEntry = sourceMeasure.FirstInstructionsStaffEntries[j];
+                                newKeyInstruction.Parent = firstStaffEntry;
+                                firstStaffEntry.removeFirstInstructionOfTypeKeyInstruction();
+                                if (firstStaffEntry.Instructions.length === 0) {
+                                    firstStaffEntry.Instructions.push(newKeyInstruction);
+                                } else {
+                                    if (firstStaffEntry.Instructions[0] instanceof ClefInstruction) {
+                                        firstStaffEntry.Instructions.splice(1, 0, newKeyInstruction);
+                                    } else {
+                                        firstStaffEntry.Instructions.splice(0, 0, newKeyInstruction);
+                                    }
+                                }
+                            }
+                        }
+                    }
+                }
+                if (this.activeKey !== undefined && this.activeKey === keyInstruction) {
+                    this.abstractInstructions.splice(i, 1);
+                }
             }
-          } else {
-            sourceMeasure = this.currentMeasure;
-          }
-          if (sourceMeasure !== undefined) {
-            for (let j: number = this.inSourceMeasureInstrumentIndex; j < this.inSourceMeasureInstrumentIndex + numberOfStaves; j++) {
-              let newKeyInstruction: KeyInstruction = keyInstruction;
-              if (sourceMeasure.FirstInstructionsStaffEntries[j] === undefined) {
-                let firstStaffEntry: SourceStaffEntry = new SourceStaffEntry(undefined, undefined);
-                sourceMeasure.FirstInstructionsStaffEntries[j] = firstStaffEntry;
-                newKeyInstruction.Parent = firstStaffEntry;
-                firstStaffEntry.Instructions.push(newKeyInstruction);
-              } else {
-                let firstStaffEntry: SourceStaffEntry = sourceMeasure.FirstInstructionsStaffEntries[j];
-                newKeyInstruction.Parent = firstStaffEntry;
-                firstStaffEntry.removeFirstInstructionOfTypeKeyInstruction();
-                if (firstStaffEntry.Instructions.length === 0) {
-                  firstStaffEntry.Instructions.push(newKeyInstruction);
-                } else {
-                  if (firstStaffEntry.Instructions[0] instanceof ClefInstruction) {
-                    firstStaffEntry.Instructions.splice(1, 0, newKeyInstruction);
-                  } else {
-                    firstStaffEntry.Instructions.splice(0, 0, newKeyInstruction);
-                  }
+            if (value instanceof RhythmInstruction) {
+                let rhythmInstruction: RhythmInstruction = <RhythmInstruction>value;
+                if (this.activeRhythm === undefined || this.activeRhythm !== rhythmInstruction) {
+                    this.activeRhythm = rhythmInstruction;
+                    this.abstractInstructions.splice(i, 1);
+                    if (this.currentMeasure !== undefined) {
+                        for (let j: number = this.inSourceMeasureInstrumentIndex; j < this.inSourceMeasureInstrumentIndex + numberOfStaves; j++) {
+                            let newRhythmInstruction: RhythmInstruction = rhythmInstruction;
+                            let firstStaffEntry: SourceStaffEntry;
+                            if (this.currentMeasure.FirstInstructionsStaffEntries[j] === undefined) {
+                                firstStaffEntry = new SourceStaffEntry(undefined, undefined);
+                                this.currentMeasure.FirstInstructionsStaffEntries[j] = firstStaffEntry;
+                            } else {
+                                firstStaffEntry = this.currentMeasure.FirstInstructionsStaffEntries[j];
+                                firstStaffEntry.removeFirstInstructionOfType<RhythmInstruction>();
+                            }
+                            newRhythmInstruction.Parent = firstStaffEntry;
+                            firstStaffEntry.Instructions.push(newRhythmInstruction);
+                        }
+                    }
+                }
+                if (this.activeRhythm !== undefined && this.activeRhythm === rhythmInstruction) {
+                    this.abstractInstructions.splice(i, 1);
                 }
-              }
             }
-          }
-        } else {
-          this.abstractInstructions.splice(i, 1);
         }
-      }
-      if (value instanceof RhythmInstruction) {
-        let rhythmInstruction: RhythmInstruction = <RhythmInstruction>value;
-        if (this.activeRhythm === undefined || this.activeRhythm !== rhythmInstruction) {
-          this.activeRhythm = rhythmInstruction;
-          this.abstractInstructions.splice(i, 1);
-          if (this.currentMeasure !== undefined) {
-            for (let j: number = this.inSourceMeasureInstrumentIndex; j < this.inSourceMeasureInstrumentIndex + numberOfStaves; j++) {
-              let newRhythmInstruction: RhythmInstruction = rhythmInstruction;
-              let firstStaffEntry: SourceStaffEntry;
-              if (this.currentMeasure.FirstInstructionsStaffEntries[j] === undefined) {
-                firstStaffEntry = new SourceStaffEntry(undefined, undefined);
-                this.currentMeasure.FirstInstructionsStaffEntries[j] = firstStaffEntry;
-              } else {
-                firstStaffEntry = this.currentMeasure.FirstInstructionsStaffEntries[j];
-                firstStaffEntry.removeFirstInstructionOfType<RhythmInstruction>();
-              }
-              newRhythmInstruction.Parent = firstStaffEntry;
-              firstStaffEntry.Instructions.push(newRhythmInstruction);
+    }
+
+    private saveClefInstructionAtEndOfMeasure(): void {
+        for (let i: number = this.abstractInstructions.length - 1; i >= 0; i--) {
+            let key: number = this.abstractInstructions[i][0];
+            let value: AbstractNotationInstruction = this.abstractInstructions[i][1];
+            if (value instanceof ClefInstruction) {
+                let clefInstruction: ClefInstruction = <ClefInstruction>value;
+                if (
+                    (this.activeClefs[key - 1] === undefined) ||
+                    (clefInstruction.ClefType !== this.activeClefs[key - 1].ClefType || (
+                        clefInstruction.ClefType === this.activeClefs[key - 1].ClefType &&
+                        clefInstruction.Line !== this.activeClefs[key - 1].Line
+                    ))) {
+                    let lastStaffEntry: SourceStaffEntry = new SourceStaffEntry(undefined, undefined);
+                    this.currentMeasure.LastInstructionsStaffEntries[this.inSourceMeasureInstrumentIndex + key - 1] = lastStaffEntry;
+                    let newClefInstruction: ClefInstruction = clefInstruction;
+                    newClefInstruction.Parent = lastStaffEntry;
+                    lastStaffEntry.Instructions.push(newClefInstruction);
+                    this.activeClefs[key - 1] = clefInstruction;
+                    this.abstractInstructions.splice(i, 1);
+                }
             }
-          }
-        } else {
-          this.abstractInstructions.splice(i, 1);
         }
-      }
-    }
-  }
-
-  private saveClefInstructionAtEndOfMeasure(): void {
-    for (let i: number = this.abstractInstructions.length - 1; i >= 0; i--) {
-      let key: number = this.abstractInstructions[i][0];
-      let value: AbstractNotationInstruction = this.abstractInstructions[i][1];
-      if (value instanceof ClefInstruction) {
-          let clefInstruction: ClefInstruction = <ClefInstruction>value;
-          if (
-            (this.activeClefs[key - 1] === undefined) ||
-            (clefInstruction.ClefType !== this.activeClefs[key - 1].ClefType || (
-              clefInstruction.ClefType === this.activeClefs[key - 1].ClefType &&
-              clefInstruction.Line !== this.activeClefs[key - 1].Line
-            ))) {
-            let lastStaffEntry: SourceStaffEntry = new SourceStaffEntry(undefined, undefined);
-            this.currentMeasure.LastInstructionsStaffEntries[this.inSourceMeasureInstrumentIndex + key - 1] = lastStaffEntry;
-            let newClefInstruction: ClefInstruction = clefInstruction;
-            newClefInstruction.Parent = lastStaffEntry;
-            lastStaffEntry.Instructions.push(newClefInstruction);
-            this.activeClefs[key - 1] = clefInstruction;
-            this.abstractInstructions.splice(i, 1);
-          }
-      }
     }
-  }
-  private getNoteDurationForTuplet(xmlNode: IXmlElement): Fraction {
-    let duration: Fraction = new Fraction(0, 1);
-    let typeDuration: Fraction = this.getNoteDurationFromTypeNode(xmlNode);
-    if (xmlNode.element("time-modification") !== undefined) {
-      let time: IXmlElement = xmlNode.element("time-modification");
-      if (time !== undefined) {
-        if (time.element("actual-notes") !== undefined && time.element("normal-notes") !== undefined) {
-          let actualNotes: IXmlElement = time.element("actual-notes");
-          let normalNotes: IXmlElement = time.element("normal-notes");
-          if (actualNotes !== undefined && normalNotes !== undefined) {
-            let actual: number = parseInt(actualNotes.value, 10);
-            let normal: number = parseInt(normalNotes.value, 10);
-            duration = new Fraction(normal * typeDuration.Numerator, actual * typeDuration.Denominator);
-          }
+
+    private getNoteDurationForTuplet(xmlNode: IXmlElement): Fraction {
+        let duration: Fraction = new Fraction(0, 1);
+        let typeDuration: Fraction = this.getNoteDurationFromTypeNode(xmlNode);
+        if (xmlNode.element("time-modification") !== undefined) {
+            let time: IXmlElement = xmlNode.element("time-modification");
+            if (time !== undefined) {
+                if (time.element("actual-notes") !== undefined && time.element("normal-notes") !== undefined) {
+                    let actualNotes: IXmlElement = time.element("actual-notes");
+                    let normalNotes: IXmlElement = time.element("normal-notes");
+                    if (actualNotes !== undefined && normalNotes !== undefined) {
+                        let actual: number = parseInt(actualNotes.value, 10);
+                        let normal: number = parseInt(normalNotes.value, 10);
+                        duration = new Fraction(normal * typeDuration.Numerator, actual * typeDuration.Denominator);
+                    }
+                }
+            }
         }
-      }
+        return duration;
     }
-    return duration;
-  }
-  //private readExpressionStaffNumber(xmlNode: IXmlElement): number {
-  //  let directionStaffNumber: number = 1;
-  //  if (xmlNode.element("staff") !== undefined) {
-  //    let staffNode: IXmlElement = xmlNode.element("staff");
-  //    if (staffNode !== undefined) {
-  //      try {
-  //        directionStaffNumber = parseInt(staffNode.value, 10);
-  //      } catch (ex) {
-  //        let errorMsg: string = ITextTranslation.translateText(
-  //          "ReaderErrorMessages/ExpressionStaffError", "Invalid Expression staff number -> set to default."
-  //        );
-  //        this.musicSheet.SheetErrors.pushTemp(errorMsg);
-  //        directionStaffNumber = 1;
-  //        logging.debug("InstrumentReader.readExpressionStaffNumber", errorMsg, ex);
-  //      }
-  //
-  //    }
-  //  }
-  //  return directionStaffNumber;
-  //}
-  private readDivisionsFromNotes(): number {
-    let divisionsFromNote: number = 0;
-    let xmlMeasureIndex: number = this.currentXmlMeasureIndex;
-    let read: boolean = false;
-    while (!read) {
-      let xmlMeasureListArr: IXmlElement[] = this.xmlMeasureList[xmlMeasureIndex].elements();
-      for (let idx: number = 0, len: number = xmlMeasureListArr.length; idx < len; ++idx) {
-        let xmlNode: IXmlElement = xmlMeasureListArr[idx];
-        if (xmlNode.name === "note" && xmlNode.element("time-modification") === undefined) {
-          if (xmlNode.element("duration") !== undefined && xmlNode.element("type") !== undefined) {
-            let durationNode: IXmlElement = xmlNode.element("duration");
-            let typeNode: IXmlElement = xmlNode.element("type");
-            if (durationNode !== undefined && typeNode !== undefined) {
-              let type: string = typeNode.value;
-              let noteDuration: number = 0;
-              try {
-                noteDuration = parseInt(durationNode.value, 10);
-              } catch (ex) {
-                Logging.debug("InstrumentReader.readDivisionsFromNotes", ex);
-                continue;
-              }
-
-              switch (type) {
-                case "1024th":
-                    divisionsFromNote = (noteDuration / 4) * 1024;
-                    break;
-                case "512th":
-                    divisionsFromNote = (noteDuration / 4) * 512;
-                    break;
-                case "256th":
-                    divisionsFromNote = (noteDuration / 4) * 256;
-                    break;
-                case "128th":
-                    divisionsFromNote = (noteDuration / 4) * 128;
-                    break;
-                case "64th":
-                    divisionsFromNote = (noteDuration / 4) * 64;
-                    break;
-                case "32nd":
-                    divisionsFromNote = (noteDuration / 4) * 32;
-                    break;
-                case "16th":
-                    divisionsFromNote = (noteDuration / 4) * 16;
-                    break;
-                case "eighth":
-                    divisionsFromNote = (noteDuration / 4) * 8;
-                    break;
-                case "quarter":
-                    divisionsFromNote = (noteDuration / 4) * 4;
-                    break;
-                case "half":
-                    divisionsFromNote = (noteDuration / 4) * 2;
-                    break;
-                case "whole":
-                    divisionsFromNote = (noteDuration / 4);
-                    break;
-                case "breve":
-                    divisionsFromNote = (noteDuration / 4) / 2;
-                    break;
-                case "long":
-                    divisionsFromNote = (noteDuration / 4) / 4;
-                    break;
-                case "maxima":
-                    divisionsFromNote = (noteDuration / 4) / 8;
+
+    //private readExpressionStaffNumber(xmlNode: IXmlElement): number {
+    //  let directionStaffNumber: number = 1;
+    //  if (xmlNode.element("staff") !== undefined) {
+    //    let staffNode: IXmlElement = xmlNode.element("staff");
+    //    if (staffNode !== undefined) {
+    //      try {
+    //        directionStaffNumber = parseInt(staffNode.value, 10);
+    //      } catch (ex) {
+    //        let errorMsg: string = ITextTranslation.translateText(
+    //          "ReaderErrorMessages/ExpressionStaffError", "Invalid Expression staff number -> set to default."
+    //        );
+    //        this.musicSheet.SheetErrors.pushTemp(errorMsg);
+    //        directionStaffNumber = 1;
+    //        logging.debug("InstrumentReader.readExpressionStaffNumber", errorMsg, ex);
+    //      }
+    //
+    //    }
+    //  }
+    //  return directionStaffNumber;
+    //}
+    private readDivisionsFromNotes(): number {
+        let divisionsFromNote: number = 0;
+        let xmlMeasureIndex: number = this.currentXmlMeasureIndex;
+        let read: boolean = false;
+        while (!read) {
+            let xmlMeasureListArr: IXmlElement[] = this.xmlMeasureList[xmlMeasureIndex].elements();
+            for (let idx: number = 0, len: number = xmlMeasureListArr.length; idx < len; ++idx) {
+                let xmlNode: IXmlElement = xmlMeasureListArr[idx];
+                if (xmlNode.name === "note" && xmlNode.element("time-modification") === undefined) {
+                    if (xmlNode.element("duration") !== undefined && xmlNode.element("type") !== undefined) {
+                        let durationNode: IXmlElement = xmlNode.element("duration");
+                        let typeNode: IXmlElement = xmlNode.element("type");
+                        if (durationNode !== undefined && typeNode !== undefined) {
+                            let type: string = typeNode.value;
+                            let noteDuration: number = 0;
+                            try {
+                                noteDuration = parseInt(durationNode.value, 10);
+                            } catch (ex) {
+                                Logging.debug("InstrumentReader.readDivisionsFromNotes", ex);
+                                continue;
+                            }
+
+                            switch (type) {
+                                case "1024th":
+                                    divisionsFromNote = (noteDuration / 4) * 1024;
+                                    break;
+                                case "512th":
+                                    divisionsFromNote = (noteDuration / 4) * 512;
+                                    break;
+                                case "256th":
+                                    divisionsFromNote = (noteDuration / 4) * 256;
+                                    break;
+                                case "128th":
+                                    divisionsFromNote = (noteDuration / 4) * 128;
+                                    break;
+                                case "64th":
+                                    divisionsFromNote = (noteDuration / 4) * 64;
+                                    break;
+                                case "32nd":
+                                    divisionsFromNote = (noteDuration / 4) * 32;
+                                    break;
+                                case "16th":
+                                    divisionsFromNote = (noteDuration / 4) * 16;
+                                    break;
+                                case "eighth":
+                                    divisionsFromNote = (noteDuration / 4) * 8;
+                                    break;
+                                case "quarter":
+                                    divisionsFromNote = (noteDuration / 4) * 4;
+                                    break;
+                                case "half":
+                                    divisionsFromNote = (noteDuration / 4) * 2;
+                                    break;
+                                case "whole":
+                                    divisionsFromNote = (noteDuration / 4);
+                                    break;
+                                case "breve":
+                                    divisionsFromNote = (noteDuration / 4) / 2;
+                                    break;
+                                case "long":
+                                    divisionsFromNote = (noteDuration / 4) / 4;
+                                    break;
+                                case "maxima":
+                                    divisionsFromNote = (noteDuration / 4) / 8;
+                                    break;
+                                default:
+                                    break;
+                            }
+                        }
+                    }
+                }
+                if (divisionsFromNote > 0) {
+                    read = true;
                     break;
-                default: break;
-              }
+                }
+            }
+            if (divisionsFromNote === 0) {
+                xmlMeasureIndex++;
+                if (xmlMeasureIndex === this.xmlMeasureList.length) {
+                    let errorMsg: string = ITextTranslation.translateText("ReaderErrorMEssages/DivisionsError", "Invalid divisions value at Instrument: ");
+                    throw new MusicSheetReadingException(errorMsg + this.instrument.Name);
+                }
             }
-          }
-        }
-        if (divisionsFromNote > 0) {
-          read = true;
-          break;
-        }
-      }
-      if (divisionsFromNote === 0) {
-        xmlMeasureIndex++;
-        if (xmlMeasureIndex === this.xmlMeasureList.length) {
-          let errorMsg: string = ITextTranslation.translateText("ReaderErrorMEssages/DivisionsError", "Invalid divisions value at Instrument: ");
-          throw new MusicSheetReadingException(errorMsg + this.instrument.Name);
         }
-      }
+        return divisionsFromNote;
     }
-    return divisionsFromNote;
-  }
 }

+ 759 - 727
src/MusicalScore/ScoreIO/MusicSheetReader.ts

@@ -23,777 +23,809 @@ type RepetitionCalculator = any;
 
 export class MusicSheetReader /*implements IMusicSheetReader*/ {
 
-  //constructor(afterSheetReadingModules: IAfterSheetReadingModule[]) {
-  //  if (afterSheetReadingModules === undefined) {
-  //    this.afterSheetReadingModules = [];
-  //  } else {
-  //    this.afterSheetReadingModules = afterSheetReadingModules;
-  //  }
-  //  this.repetitionInstructionReader = MusicSymbolModuleFactory.createRepetitionInstructionReader();
-  //  this.repetitionCalculator = MusicSymbolModuleFactory.createRepetitionCalculator();
-  //}
-
-  private repetitionInstructionReader: RepetitionInstructionReader;
-  private repetitionCalculator: RepetitionCalculator;
-  // private afterSheetReadingModules: IAfterSheetReadingModule[];
-  private musicSheet: MusicSheet;
-  private completeNumberOfStaves: number = 0;
-  private currentMeasure: SourceMeasure;
-  private previousMeasure: SourceMeasure;
-  private currentFraction: Fraction;
-
-  public get CompleteNumberOfStaves(): number {
-    return this.completeNumberOfStaves;
-  }
-  private static doCalculationsAfterDurationHasBeenSet(instrumentReaders: InstrumentReader[]): void {
-    for (let instrumentReader of instrumentReaders) {
-      instrumentReader.doCalculationsAfterDurationHasBeenSet();
-    }
-  }
+    //constructor(afterSheetReadingModules: IAfterSheetReadingModule[]) {
+    //  if (afterSheetReadingModules === undefined) {
+    //    this.afterSheetReadingModules = [];
+    //  } else {
+    //    this.afterSheetReadingModules = afterSheetReadingModules;
+    //  }
+    //  this.repetitionInstructionReader = MusicSymbolModuleFactory.createRepetitionInstructionReader();
+    //  this.repetitionCalculator = MusicSymbolModuleFactory.createRepetitionCalculator();
+    //}
 
-  public createMusicSheet(root: IXmlElement, path: string): MusicSheet {
-    try {
-      return this._createMusicSheet(root, path);
-    } catch (e) {
-      Logging.log("MusicSheetReader.CreateMusicSheet", e);
-    }
-  }
+    private repetitionInstructionReader: RepetitionInstructionReader;
+    private repetitionCalculator: RepetitionCalculator;
+    // private afterSheetReadingModules: IAfterSheetReadingModule[];
+    private musicSheet: MusicSheet;
+    private completeNumberOfStaves: number = 0;
+    private currentMeasure: SourceMeasure;
+    private previousMeasure: SourceMeasure;
+    private currentFraction: Fraction;
 
-  private _removeFromArray(list: any[], elem: any): void {
-    let i: number = list.indexOf(elem);
-    if (i !== -1) {
-      list.splice(i, 1);
-    }
-  }
-  // Trim from a string also newlines
-  private trimString(str: string): string {
-    return str.replace(/^\s+|\s+$/g, "");
-  }
-
-  private _lastElement<T>(list: T[]): T {
-    return list[list.length - 1];
-  }
-
-  //public SetPhonicScoreInterface(phonicScoreInterface: IPhonicScoreInterface): void {
-  //  this.phonicScoreInterface = phonicScoreInterface;
-  //}
-  //public ReadMusicSheetParameters(sheetObject: MusicSheetParameterObject, root: IXmlElement, path: string): MusicSheetParameterObject {
-  //  this.musicSheet = new MusicSheet();
-  //  if (root !== undefined) {
-  //    this.pushSheetLabels(root, path);
-  //    if (this.musicSheet.Title !== undefined) {
-  //      sheetObject.Title = this.musicSheet.Title.text;
-  //    }
-  //    if (this.musicSheet.Composer !== undefined) {
-  //      sheetObject.Composer = this.musicSheet.Composer.text;
-  //    }
-  //    if (this.musicSheet.Lyricist !== undefined) {
-  //      sheetObject.Lyricist = this.musicSheet.Lyricist.text;
-  //    }
-  //    let partlistNode: IXmlElement = root.element("part-list");
-  //    let partList: IXmlElement[] = partlistNode.elements();
-  //    this.createInstrumentGroups(partList);
-  //    for (let idx: number = 0, len: number = this.musicSheet.Instruments.length; idx < len; ++idx) {
-  //      let instr: Instrument = this.musicSheet.Instruments[idx];
-  //      sheetObject.InstrumentList.push(__init(new MusicSheetParameterObject.LibrarySheetInstrument(), { name: instr.name }));
-  //    }
-  //  }
-  //  return sheetObject;
-  //}
-
-  private _createMusicSheet(root: IXmlElement, path: string): MusicSheet {
-    let instrumentReaders: InstrumentReader[] = [];
-    let sourceMeasureCounter: number = 0;
-    this.musicSheet = new MusicSheet();
-    this.musicSheet.Path = path;
-    if (root === undefined) {
-      throw new MusicSheetReadingException("Undefined root element");
-    }
-    this.pushSheetLabels(root, path);
-    let partlistNode: IXmlElement = root.element("part-list");
-    if (partlistNode === undefined) {
-      throw new MusicSheetReadingException("Undefined partListNode");
+    public get CompleteNumberOfStaves(): number {
+        return this.completeNumberOfStaves;
     }
 
-    let partInst: IXmlElement[] = root.elements("part");
-    console.log(partInst.length + " parts");
-    let partList: IXmlElement[] = partlistNode.elements();
-    //Logging.debug("Starting initializeReading");
-    this.initializeReading(partList, partInst, instrumentReaders);
-    //Logging.debug("Done initializeReading");
-    let couldReadMeasure: boolean = true;
-    this.currentFraction = new Fraction(0, 1);
-    let guitarPro: boolean = false;
-    let encoding: IXmlElement = root.element("identification");
-    if (encoding !== undefined) {
-      encoding = encoding.element("encoding");
-    }
-    if (encoding !== undefined) {
-      encoding = encoding.element("software");
-    }
-    if (encoding !== undefined && encoding.value === "Guitar Pro 5") {
-      guitarPro = true;
+    private static doCalculationsAfterDurationHasBeenSet(instrumentReaders: InstrumentReader[]): void {
+        for (let instrumentReader of instrumentReaders) {
+            instrumentReader.doCalculationsAfterDurationHasBeenSet();
+        }
     }
 
-    while (couldReadMeasure) {
-      if (this.currentMeasure !== undefined && this.currentMeasure.endsPiece) {
-        sourceMeasureCounter = 0;
-      }
-      this.currentMeasure = new SourceMeasure(this.completeNumberOfStaves);
-      for (let instrumentReader of instrumentReaders) {
+    public createMusicSheet(root: IXmlElement, path: string): MusicSheet {
         try {
-          couldReadMeasure = couldReadMeasure && instrumentReader.readNextXmlMeasure(this.currentMeasure, this.currentFraction, guitarPro);
+            return this._createMusicSheet(root, path);
         } catch (e) {
-          let errorMsg: string = ITextTranslation.translateText("ReaderErrorMessages/InstrumentError", "Error while reading instruments.");
-          throw new MusicSheetReadingException(errorMsg, e);
-        }
-
-      }
-      if (couldReadMeasure) {
-        //Logging.debug("couldReadMeasure: 1");
-        this.musicSheet.addMeasure(this.currentMeasure);
-        //Logging.debug("couldReadMeasure: 2");
-        this.checkIfRhythmInstructionsAreSetAndEqual(instrumentReaders);
-        //Logging.debug("couldReadMeasure: 3");
-        this.checkSourceMeasureForundefinedEntries();
-        //Logging.debug("couldReadMeasure: 4");
-        this.setSourceMeasureDuration(instrumentReaders, sourceMeasureCounter);
-        //Logging.debug("couldReadMeasure: 5");
-        MusicSheetReader.doCalculationsAfterDurationHasBeenSet(instrumentReaders);
-        //Logging.debug("couldReadMeasure: 6");
-        this.currentMeasure.AbsoluteTimestamp = this.currentFraction.clone();
-        this.musicSheet.SheetErrors.finalizeMeasure(this.currentMeasure.MeasureNumber);
-        this.currentFraction.Add(this.currentMeasure.Duration);
-        this.previousMeasure = this.currentMeasure;
-        //Logging.debug("couldReadMeasure: 7");
-      }
+            Logging.log("MusicSheetReader.CreateMusicSheet", e);
+        }
     }
 
-    if (this.repetitionInstructionReader !== undefined) {
-      this.repetitionInstructionReader.removeRedundantInstructions();
-      if (this.repetitionCalculator !== undefined) {
-        this.repetitionCalculator.calculateRepetitions(this.musicSheet, this.repetitionInstructionReader.RepetitionInstructions);
-      }
+    private _removeFromArray(list: any[], elem: any): void {
+        let i: number = list.indexOf(elem);
+        if (i !== -1) {
+            list.splice(i, 1);
+        }
     }
-    this.musicSheet.checkForInstrumentWithNoVoice();
-    this.musicSheet.fillStaffList();
-    //this.musicSheet.DefaultStartTempoInBpm = this.musicSheet.SheetPlaybackSetting.BeatsPerMinute;
-    //for (let idx: number = 0, len: number = this.afterSheetReadingModules.length; idx < len; ++idx) {
-    //  let afterSheetReadingModule: IAfterSheetReadingModule = this.afterSheetReadingModules[idx];
-    //  afterSheetReadingModule.calculate(this.musicSheet);
-    //}
 
-    return this.musicSheet;
-  }
-
-  private initializeReading(
-    partList: IXmlElement[], partInst: IXmlElement[], instrumentReaders: InstrumentReader[]
-  ): void {
-    let instrumentDict: { [_: string]: Instrument; } = this.createInstrumentGroups(partList);
-    this.completeNumberOfStaves = this.getCompleteNumberOfStavesFromXml(partInst);
-    if (partInst.length !== 0) {
-      // (*) this.repetitionInstructionReader.MusicSheet = this.musicSheet;
-      this.currentFraction = new Fraction(0, 1);
-      this.currentMeasure = undefined;
-      this.previousMeasure = undefined;
+    // Trim from a string also newlines
+    private trimString(str: string): string {
+        return str.replace(/^\s+|\s+$/g, "");
     }
-    let counter: number = 0;
-    for (let node of partInst) {
-      let idNode: IXmlAttribute = node.attribute("id");
-      if (idNode) {
-        let currentInstrument: Instrument = instrumentDict[idNode.value];
-        let xmlMeasureList: IXmlElement[] = node.elements("measure");
-        let instrumentNumberOfStaves: number = 1;
-        try {
-          instrumentNumberOfStaves = this.getInstrumentNumberOfStavesFromXml(node);
-        } catch (err) {
-          let errorMsg: string = ITextTranslation.translateText(
-              "ReaderErrorMessages/InstrumentStavesNumberError",
-              "Invalid number of staves at instrument: "
-          );
-          this.musicSheet.SheetErrors.push(errorMsg + currentInstrument.Name);
-          continue;
-        }
-
-        currentInstrument.createStaves(instrumentNumberOfStaves);
-        instrumentReaders.push(new InstrumentReader(this.repetitionInstructionReader, xmlMeasureList, currentInstrument));
+
+    private _lastElement<T>(list: T[]): T {
+        return list[list.length - 1];
+    }
+
+    //public SetPhonicScoreInterface(phonicScoreInterface: IPhonicScoreInterface): void {
+    //  this.phonicScoreInterface = phonicScoreInterface;
+    //}
+    //public ReadMusicSheetParameters(sheetObject: MusicSheetParameterObject, root: IXmlElement, path: string): MusicSheetParameterObject {
+    //  this.musicSheet = new MusicSheet();
+    //  if (root !== undefined) {
+    //    this.pushSheetLabels(root, path);
+    //    if (this.musicSheet.Title !== undefined) {
+    //      sheetObject.Title = this.musicSheet.Title.text;
+    //    }
+    //    if (this.musicSheet.Composer !== undefined) {
+    //      sheetObject.Composer = this.musicSheet.Composer.text;
+    //    }
+    //    if (this.musicSheet.Lyricist !== undefined) {
+    //      sheetObject.Lyricist = this.musicSheet.Lyricist.text;
+    //    }
+    //    let partlistNode: IXmlElement = root.element("part-list");
+    //    let partList: IXmlElement[] = partlistNode.elements();
+    //    this.createInstrumentGroups(partList);
+    //    for (let idx: number = 0, len: number = this.musicSheet.Instruments.length; idx < len; ++idx) {
+    //      let instr: Instrument = this.musicSheet.Instruments[idx];
+    //      sheetObject.InstrumentList.push(__init(new MusicSheetParameterObject.LibrarySheetInstrument(), { name: instr.name }));
+    //    }
+    //  }
+    //  return sheetObject;
+    //}
+
+    private _createMusicSheet(root: IXmlElement, path: string): MusicSheet {
+        let instrumentReaders: InstrumentReader[] = [];
+        let sourceMeasureCounter: number = 0;
+        this.musicSheet = new MusicSheet();
+        this.musicSheet.Path = path;
+        if (root === undefined) {
+            throw new MusicSheetReadingException("Undefined root element");
+        }
+        this.pushSheetLabels(root, path);
+        let partlistNode: IXmlElement = root.element("part-list");
+        if (partlistNode === undefined) {
+            throw new MusicSheetReadingException("Undefined partListNode");
+        }
+
+        let partInst: IXmlElement[] = root.elements("part");
+        console.log(partInst.length + " parts");
+        let partList: IXmlElement[] = partlistNode.elements();
+        //Logging.debug("Starting initializeReading");
+        this.initializeReading(partList, partInst, instrumentReaders);
+        //Logging.debug("Done initializeReading");
+        let couldReadMeasure: boolean = true;
+        this.currentFraction = new Fraction(0, 1);
+        let guitarPro: boolean = false;
+        let encoding: IXmlElement = root.element("identification");
+        if (encoding !== undefined) {
+            encoding = encoding.element("encoding");
+        }
+        if (encoding !== undefined) {
+            encoding = encoding.element("software");
+        }
+        if (encoding !== undefined && encoding.value === "Guitar Pro 5") {
+            guitarPro = true;
+        }
+
+        while (couldReadMeasure) {
+            if (this.currentMeasure !== undefined && this.currentMeasure.endsPiece) {
+                sourceMeasureCounter = 0;
+            }
+            this.currentMeasure = new SourceMeasure(this.completeNumberOfStaves);
+            for (let instrumentReader of instrumentReaders) {
+                try {
+                    couldReadMeasure = couldReadMeasure && instrumentReader.readNextXmlMeasure(this.currentMeasure, this.currentFraction, guitarPro);
+                } catch (e) {
+                    let errorMsg: string = ITextTranslation.translateText("ReaderErrorMessages/InstrumentError", "Error while reading instruments.");
+                    throw new MusicSheetReadingException(errorMsg, e);
+                }
+
+            }
+            if (couldReadMeasure) {
+                //Logging.debug("couldReadMeasure: 1");
+                this.musicSheet.addMeasure(this.currentMeasure);
+                //Logging.debug("couldReadMeasure: 2");
+                this.checkIfRhythmInstructionsAreSetAndEqual(instrumentReaders);
+                //Logging.debug("couldReadMeasure: 3");
+                this.checkSourceMeasureForundefinedEntries();
+                //Logging.debug("couldReadMeasure: 4");
+                this.setSourceMeasureDuration(instrumentReaders, sourceMeasureCounter);
+                //Logging.debug("couldReadMeasure: 5");
+                MusicSheetReader.doCalculationsAfterDurationHasBeenSet(instrumentReaders);
+                //Logging.debug("couldReadMeasure: 6");
+                this.currentMeasure.AbsoluteTimestamp = this.currentFraction.clone();
+                this.musicSheet.SheetErrors.finalizeMeasure(this.currentMeasure.MeasureNumber);
+                this.currentFraction.Add(this.currentMeasure.Duration);
+                this.previousMeasure = this.currentMeasure;
+                //Logging.debug("couldReadMeasure: 7");
+            }
+        }
+
         if (this.repetitionInstructionReader !== undefined) {
-          this.repetitionInstructionReader.XmlMeasureList[counter] = xmlMeasureList;
+            this.repetitionInstructionReader.removeRedundantInstructions();
+            if (this.repetitionCalculator !== undefined) {
+                this.repetitionCalculator.calculateRepetitions(this.musicSheet, this.repetitionInstructionReader.RepetitionInstructions);
+            }
         }
-        counter++;
-      }
+        this.musicSheet.checkForInstrumentWithNoVoice();
+        this.musicSheet.fillStaffList();
+        //this.musicSheet.DefaultStartTempoInBpm = this.musicSheet.SheetPlaybackSetting.BeatsPerMinute;
+        //for (let idx: number = 0, len: number = this.afterSheetReadingModules.length; idx < len; ++idx) {
+        //  let afterSheetReadingModule: IAfterSheetReadingModule = this.afterSheetReadingModules[idx];
+        //  afterSheetReadingModule.calculate(this.musicSheet);
+        //}
+
+        return this.musicSheet;
     }
-  }
-  private checkIfRhythmInstructionsAreSetAndEqual(instrumentReaders: InstrumentReader[]): void {
-    let rhythmInstructions: RhythmInstruction[] = [];
-    for (let i: number = 0; i < this.completeNumberOfStaves; i++) {
-      if (this.currentMeasure.FirstInstructionsStaffEntries[i] !== undefined) {
-        let last: AbstractNotationInstruction = this.currentMeasure.FirstInstructionsStaffEntries[i].Instructions[
-          this.currentMeasure.FirstInstructionsStaffEntries[i].Instructions.length - 1
-        ];
-        if (last instanceof RhythmInstruction) {
-          rhythmInstructions.push(<RhythmInstruction>last);
-        }
-      }
+
+    private initializeReading(partList: IXmlElement[], partInst: IXmlElement[], instrumentReaders: InstrumentReader[]): void {
+        let instrumentDict: { [_: string]: Instrument; } = this.createInstrumentGroups(partList);
+        this.completeNumberOfStaves = this.getCompleteNumberOfStavesFromXml(partInst);
+        if (partInst.length !== 0) {
+            // (*) this.repetitionInstructionReader.MusicSheet = this.musicSheet;
+            this.currentFraction = new Fraction(0, 1);
+            this.currentMeasure = undefined;
+            this.previousMeasure = undefined;
+        }
+        let counter: number = 0;
+        for (let node of partInst) {
+            let idNode: IXmlAttribute = node.attribute("id");
+            if (idNode) {
+                let currentInstrument: Instrument = instrumentDict[idNode.value];
+                let xmlMeasureList: IXmlElement[] = node.elements("measure");
+                let instrumentNumberOfStaves: number = 1;
+                try {
+                    instrumentNumberOfStaves = this.getInstrumentNumberOfStavesFromXml(node);
+                } catch (err) {
+                    let errorMsg: string = ITextTranslation.translateText(
+                        "ReaderErrorMessages/InstrumentStavesNumberError",
+                        "Invalid number of staves at instrument: "
+                    );
+                    this.musicSheet.SheetErrors.push(errorMsg + currentInstrument.Name);
+                    continue;
+                }
+
+                currentInstrument.createStaves(instrumentNumberOfStaves);
+                instrumentReaders.push(new InstrumentReader(this.repetitionInstructionReader, xmlMeasureList, currentInstrument));
+                if (this.repetitionInstructionReader !== undefined) {
+                    this.repetitionInstructionReader.XmlMeasureList[counter] = xmlMeasureList;
+                }
+                counter++;
+            }
+        }
     }
-    let maxRhythmValue: number = 0.0;
-    let index: number = -1;
-    for (let idx: number = 0, len: number = rhythmInstructions.length; idx < len; ++idx) {
-      let rhythmInstruction: RhythmInstruction = rhythmInstructions[idx];
-      if (rhythmInstruction.Rhythm.RealValue > maxRhythmValue) {
-        if (this.areRhythmInstructionsMixed(rhythmInstructions) && rhythmInstruction.SymbolEnum !== RhythmSymbolEnum.NONE) { continue; }
-        maxRhythmValue = rhythmInstruction.Rhythm.RealValue;
-        index = rhythmInstructions.indexOf(rhythmInstruction);
-      }
+
+    private checkIfRhythmInstructionsAreSetAndEqual(instrumentReaders: InstrumentReader[]): void {
+        let rhythmInstructions: RhythmInstruction[] = [];
+        for (let i: number = 0; i < this.completeNumberOfStaves; i++) {
+            if (this.currentMeasure.FirstInstructionsStaffEntries[i] !== undefined) {
+                let last: AbstractNotationInstruction = this.currentMeasure.FirstInstructionsStaffEntries[i].Instructions[
+                this.currentMeasure.FirstInstructionsStaffEntries[i].Instructions.length - 1
+                    ];
+                if (last instanceof RhythmInstruction) {
+                    rhythmInstructions.push(<RhythmInstruction>last);
+                }
+            }
+        }
+        let maxRhythmValue: number = 0.0;
+        let index: number = -1;
+        for (let idx: number = 0, len: number = rhythmInstructions.length; idx < len; ++idx) {
+            let rhythmInstruction: RhythmInstruction = rhythmInstructions[idx];
+            if (rhythmInstruction.Rhythm.RealValue > maxRhythmValue) {
+                if (this.areRhythmInstructionsMixed(rhythmInstructions) && rhythmInstruction.SymbolEnum !== RhythmSymbolEnum.NONE) {
+                    continue;
+                }
+                maxRhythmValue = rhythmInstruction.Rhythm.RealValue;
+                index = rhythmInstructions.indexOf(rhythmInstruction);
+            }
+        }
+        if (rhythmInstructions.length > 0 && rhythmInstructions.length < this.completeNumberOfStaves) {
+            let rhythmInstruction: RhythmInstruction = rhythmInstructions[index].clone();
+            for (let i: number = 0; i < this.completeNumberOfStaves; i++) {
+                if (
+                    this.currentMeasure.FirstInstructionsStaffEntries[i] !== undefined && !(this._lastElement(this.currentMeasure.FirstInstructionsStaffEntries[i].Instructions) instanceof RhythmInstruction)
+                ) {
+                    this.currentMeasure.FirstInstructionsStaffEntries[i].removeAllInstructionsOfTypeRhythmInstruction();
+                    this.currentMeasure.FirstInstructionsStaffEntries[i].Instructions.push(rhythmInstruction.clone());
+                }
+                if (this.currentMeasure.FirstInstructionsStaffEntries[i] === undefined) {
+                    this.currentMeasure.FirstInstructionsStaffEntries[i] = new SourceStaffEntry(undefined, undefined);
+                    this.currentMeasure.FirstInstructionsStaffEntries[i].Instructions.push(rhythmInstruction.clone());
+                }
+            }
+            for (let idx: number = 0, len: number = instrumentReaders.length; idx < len; ++idx) {
+                let instrumentReader: InstrumentReader = instrumentReaders[idx];
+                instrumentReader.ActiveRhythm = rhythmInstruction;
+            }
+        }
+        if (rhythmInstructions.length === 0 && this.currentMeasure === this.musicSheet.SourceMeasures[0]) {
+            let rhythmInstruction: RhythmInstruction = new RhythmInstruction(new Fraction(4, 4, false), 4, 4, RhythmSymbolEnum.NONE);
+            for (let i: number = 0; i < this.completeNumberOfStaves; i++) {
+                if (this.currentMeasure.FirstInstructionsStaffEntries[i] === undefined) {
+                    this.currentMeasure.FirstInstructionsStaffEntries[i] = new SourceStaffEntry(undefined, undefined);
+                } else {
+                    this.currentMeasure.FirstInstructionsStaffEntries[i].removeAllInstructionsOfTypeRhythmInstruction();
+                }
+                this.currentMeasure.FirstInstructionsStaffEntries[i].Instructions.push(rhythmInstruction);
+            }
+            for (let idx: number = 0, len: number = instrumentReaders.length; idx < len; ++idx) {
+                let instrumentReader: InstrumentReader = instrumentReaders[idx];
+                instrumentReader.ActiveRhythm = rhythmInstruction;
+            }
+        }
+        for (let idx: number = 0, len: number = rhythmInstructions.length; idx < len; ++idx) {
+            let rhythmInstruction: RhythmInstruction = rhythmInstructions[idx];
+            if (rhythmInstruction.Rhythm.RealValue < maxRhythmValue) {
+                if (this._lastElement(
+                        this.currentMeasure.FirstInstructionsStaffEntries[rhythmInstructions.indexOf(rhythmInstruction)].Instructions
+                    ) instanceof RhythmInstruction) {
+                    // TODO Test correctness
+                    let instrs: AbstractNotationInstruction[] =
+                        this.currentMeasure.FirstInstructionsStaffEntries[rhythmInstructions.indexOf(rhythmInstruction)].Instructions;
+                    instrs[instrs.length - 1] = rhythmInstructions[index].clone();
+                }
+            }
+            if (
+                Math.abs(rhythmInstruction.Rhythm.RealValue - maxRhythmValue) < 0.000001 &&
+                rhythmInstruction.SymbolEnum !== RhythmSymbolEnum.NONE &&
+                this.areRhythmInstructionsMixed(rhythmInstructions)
+            ) {
+                rhythmInstruction.SymbolEnum = RhythmSymbolEnum.NONE;
+            }
+        }
     }
-    if (rhythmInstructions.length > 0 && rhythmInstructions.length < this.completeNumberOfStaves) {
-      let rhythmInstruction: RhythmInstruction = rhythmInstructions[index].clone();
-      for (let i: number = 0; i < this.completeNumberOfStaves; i++) {
-        if (
-          this.currentMeasure.FirstInstructionsStaffEntries[i] !== undefined &&
-          !(this._lastElement(this.currentMeasure.FirstInstructionsStaffEntries[i].Instructions) instanceof RhythmInstruction)
-        ) {
-          this.currentMeasure.FirstInstructionsStaffEntries[i].removeAllInstructionsOfTypeRhythmInstruction();
-          this.currentMeasure.FirstInstructionsStaffEntries[i].Instructions.push(rhythmInstruction.clone());
-        }
-        if (this.currentMeasure.FirstInstructionsStaffEntries[i] === undefined) {
-          this.currentMeasure.FirstInstructionsStaffEntries[i] = new SourceStaffEntry(undefined, undefined);
-          this.currentMeasure.FirstInstructionsStaffEntries[i].Instructions.push(rhythmInstruction.clone());
-        }
-      }
-      for (let idx: number = 0, len: number = instrumentReaders.length; idx < len; ++idx) {
-        let instrumentReader: InstrumentReader = instrumentReaders[idx];
-        instrumentReader.ActiveRhythm = rhythmInstruction;
-      }
+
+    private areRhythmInstructionsMixed(rhythmInstructions: RhythmInstruction[]): boolean {
+        for (let i: number = 1; i < rhythmInstructions.length; i++) {
+            if (
+                Math.abs(rhythmInstructions[i].Rhythm.RealValue - rhythmInstructions[0].Rhythm.RealValue) < 0.000001 &&
+                rhythmInstructions[i].SymbolEnum !== rhythmInstructions[0].SymbolEnum
+            ) {
+                return true;
+            }
+        }
+        return false;
     }
-    if (rhythmInstructions.length === 0 && this.currentMeasure === this.musicSheet.SourceMeasures[0]) {
-      let rhythmInstruction: RhythmInstruction = new RhythmInstruction(new Fraction(4, 4, false), 4, 4, RhythmSymbolEnum.NONE);
-      for (let i: number = 0; i < this.completeNumberOfStaves; i++) {
-        if (this.currentMeasure.FirstInstructionsStaffEntries[i] === undefined) {
-          this.currentMeasure.FirstInstructionsStaffEntries[i] = new SourceStaffEntry(undefined, undefined);
+
+    private setSourceMeasureDuration(instrumentReaders: InstrumentReader[], sourceMeasureCounter: number): void {
+        let activeRhythm: Fraction = new Fraction(0, 1);
+        let instrumentsMaxTieNoteFractions: Fraction[] = [];
+        for (let idx: number = 0, len: number = instrumentReaders.length; idx < len; ++idx) {
+            let instrumentReader: InstrumentReader = instrumentReaders[idx];
+            instrumentsMaxTieNoteFractions.push(instrumentReader.MaxTieNoteFraction);
+            let activeRythmMeasure: Fraction = instrumentReader.ActiveRhythm.Rhythm;
+            if (activeRhythm < activeRythmMeasure) {
+                activeRhythm = new Fraction(activeRythmMeasure.Numerator, activeRythmMeasure.Denominator, false);
+            }
+        }
+        let instrumentsDurations: Fraction[] = this.currentMeasure.calculateInstrumentsDuration(this.musicSheet, instrumentsMaxTieNoteFractions);
+        let maxInstrumentDuration: Fraction = new Fraction(0, 1);
+        for (let idx: number = 0, len: number = instrumentsDurations.length; idx < len; ++idx) {
+            let instrumentsDuration: Fraction = instrumentsDurations[idx];
+            if (maxInstrumentDuration < instrumentsDuration) {
+                maxInstrumentDuration = instrumentsDuration;
+            }
+        }
+        if (Fraction.Equal(maxInstrumentDuration, activeRhythm)) {
+            this.checkFractionsForEquivalence(maxInstrumentDuration, activeRhythm);
         } else {
-          this.currentMeasure.FirstInstructionsStaffEntries[i].removeAllInstructionsOfTypeRhythmInstruction();
-        }
-        this.currentMeasure.FirstInstructionsStaffEntries[i].Instructions.push(rhythmInstruction);
-      }
-      for (let idx: number = 0, len: number = instrumentReaders.length; idx < len; ++idx) {
-        let instrumentReader: InstrumentReader = instrumentReaders[idx];
-        instrumentReader.ActiveRhythm = rhythmInstruction;
-      }
-    }
-    for (let idx: number = 0, len: number = rhythmInstructions.length; idx < len; ++idx) {
-      let rhythmInstruction: RhythmInstruction = rhythmInstructions[idx];
-      if (rhythmInstruction.Rhythm.RealValue < maxRhythmValue) {
-        if (this._lastElement(
-                this.currentMeasure.FirstInstructionsStaffEntries[rhythmInstructions.indexOf(rhythmInstruction)].Instructions
-            ) instanceof RhythmInstruction) {
-          // TODO Test correctness
-          let instrs: AbstractNotationInstruction[] =
-              this.currentMeasure.FirstInstructionsStaffEntries[rhythmInstructions.indexOf(rhythmInstruction)].Instructions;
-          instrs[instrs.length - 1] = rhythmInstructions[index].clone();
-        }
-      }
-      if (
-        Math.abs(rhythmInstruction.Rhythm.RealValue - maxRhythmValue) < 0.000001 &&
-        rhythmInstruction.SymbolEnum !== RhythmSymbolEnum.NONE &&
-        this.areRhythmInstructionsMixed(rhythmInstructions)
-      ) {
-        rhythmInstruction.SymbolEnum = RhythmSymbolEnum.NONE;
-      }
-    }
-  }
-  private areRhythmInstructionsMixed(rhythmInstructions: RhythmInstruction[]): boolean {
-    for (let i: number = 1; i < rhythmInstructions.length; i++) {
-      if (
-        Math.abs(rhythmInstructions[i].Rhythm.RealValue - rhythmInstructions[0].Rhythm.RealValue) < 0.000001 &&
-      rhythmInstructions[i].SymbolEnum !== rhythmInstructions[0].SymbolEnum
-      ) { return true; }
-    }
-    return false;
-  }
-  private setSourceMeasureDuration(
-    instrumentReaders: InstrumentReader[], sourceMeasureCounter: number
-  ): void {
-    let activeRhythm: Fraction = new Fraction(0, 1);
-    let instrumentsMaxTieNoteFractions: Fraction[] = [];
-    for (let idx: number = 0, len: number = instrumentReaders.length; idx < len; ++idx) {
-      let instrumentReader: InstrumentReader = instrumentReaders[idx];
-      instrumentsMaxTieNoteFractions.push(instrumentReader.MaxTieNoteFraction);
-      let activeRythmMeasure: Fraction = instrumentReader.ActiveRhythm.Rhythm;
-      if (activeRhythm < activeRythmMeasure) {
-        activeRhythm = new Fraction(activeRythmMeasure.Numerator, activeRythmMeasure.Denominator, false);
-      }
-    }
-    let instrumentsDurations: Fraction[] = this.currentMeasure.calculateInstrumentsDuration(this.musicSheet, instrumentsMaxTieNoteFractions);
-    let maxInstrumentDuration: Fraction = new Fraction(0, 1);
-    for (let idx: number = 0, len: number = instrumentsDurations.length; idx < len; ++idx) {
-      let instrumentsDuration: Fraction = instrumentsDurations[idx];
-      if (maxInstrumentDuration < instrumentsDuration) {
-        maxInstrumentDuration = instrumentsDuration;
-      }
-    }
-    if (Fraction.Equal(maxInstrumentDuration, activeRhythm)) {
-      this.checkFractionsForEquivalence(maxInstrumentDuration, activeRhythm);
-    } else {
-      if (maxInstrumentDuration < activeRhythm) {
-        maxInstrumentDuration = this.currentMeasure.reverseCheck(this.musicSheet, maxInstrumentDuration);
-        this.checkFractionsForEquivalence(maxInstrumentDuration, activeRhythm);
-      }
-    }
-    this.currentMeasure.ImplicitMeasure = this.checkIfMeasureIsImplicit(maxInstrumentDuration, activeRhythm);
-    if (!this.currentMeasure.ImplicitMeasure) {
-      sourceMeasureCounter++;
-    }
-    this.currentMeasure.Duration = maxInstrumentDuration;
-    this.currentMeasure.MeasureNumber = sourceMeasureCounter;
-    for (let i: number = 0; i < instrumentsDurations.length; i++) {
-      let instrumentsDuration: Fraction = instrumentsDurations[i];
-      if (
-        (this.currentMeasure.ImplicitMeasure && instrumentsDuration !== maxInstrumentDuration) ||
-        instrumentsDuration !== activeRhythm && // FIXME
-        !this.allInstrumentsHaveSameDuration(instrumentsDurations, maxInstrumentDuration)
-      ) {
-        let firstStaffIndexOfInstrument: number = this.musicSheet.getGlobalStaffIndexOfFirstStaff(this.musicSheet.Instruments[i]);
-        for (let staffIndex: number = 0; staffIndex < this.musicSheet.Instruments[i].Staves.length; staffIndex++) {
-          if (!this.staffMeasureIsEmpty(firstStaffIndexOfInstrument + staffIndex)) {
-            this.currentMeasure.setErrorInStaffMeasure(firstStaffIndexOfInstrument + staffIndex, true);
-            let errorMsg: string = ITextTranslation.translateText("ReaderErrorMessages/MissingNotesError", "Given Notes don't correspond to measure duration.");
-            this.musicSheet.SheetErrors.pushMeasureError(errorMsg);
-          }
-        }
-      }
-    }
-  }
-  private checkFractionsForEquivalence(maxInstrumentDuration: Fraction, activeRhythm: Fraction): void {
-    if (activeRhythm.Denominator > maxInstrumentDuration.Denominator) {
-      let factor: number = activeRhythm.Denominator / maxInstrumentDuration.Denominator;
-      maxInstrumentDuration.multiplyWithFactor(factor);
-    }
-  }
-  private checkIfMeasureIsImplicit(maxInstrumentDuration: Fraction, activeRhythm: Fraction): boolean {
-    if (this.previousMeasure === undefined && maxInstrumentDuration < activeRhythm) { return true; }
-    if (this.previousMeasure !== undefined) {
-      return Fraction.plus(this.previousMeasure.Duration, maxInstrumentDuration).CompareTo(activeRhythm) === 0;
-    }
-    return false;
-  }
-  private allInstrumentsHaveSameDuration(
-    instrumentsDurations: Fraction[], maxInstrumentDuration: Fraction
-  ): boolean {
-    let counter: number = 0;
-    for (let idx: number = 0, len: number = instrumentsDurations.length; idx < len; ++idx) {
-      let instrumentsDuration: Fraction = instrumentsDurations[idx];
-      if (instrumentsDuration === maxInstrumentDuration) { counter++; }
-    }
-    return (counter === instrumentsDurations.length && maxInstrumentDuration !== new Fraction(0, 1));
-  }
-  private staffMeasureIsEmpty(index: number): boolean {
-    let counter: number = 0;
-    for (let i: number = 0; i < this.currentMeasure.VerticalSourceStaffEntryContainers.length; i++) {
-      if (this.currentMeasure.VerticalSourceStaffEntryContainers[i].StaffEntries[index] === undefined) { counter++; }
-    }
-    return (counter === this.currentMeasure.VerticalSourceStaffEntryContainers.length);
-  }
-  private checkSourceMeasureForundefinedEntries(): void {
-    for (let i: number = this.currentMeasure.VerticalSourceStaffEntryContainers.length - 1; i >= 0; i--) {
-      for (let j: number = this.currentMeasure.VerticalSourceStaffEntryContainers[i].StaffEntries.length - 1; j >= 0; j--) {
-        let sourceStaffEntry: SourceStaffEntry = this.currentMeasure.VerticalSourceStaffEntryContainers[i].StaffEntries[j];
-        if (sourceStaffEntry !== undefined) {
-          for (let k: number = sourceStaffEntry.VoiceEntries.length - 1; k >= 0; k--) {
-            let voiceEntry: VoiceEntry = sourceStaffEntry.VoiceEntries[k];
-            if (voiceEntry.Notes.length === 0) {
-              this._removeFromArray(voiceEntry.ParentVoice.VoiceEntries, voiceEntry);
-              this._removeFromArray(sourceStaffEntry.VoiceEntries, voiceEntry);
-            }
-          }
-        }
-        if (sourceStaffEntry !== undefined && sourceStaffEntry.VoiceEntries.length === 0) {
-          this.currentMeasure.VerticalSourceStaffEntryContainers[i].StaffEntries[j] = undefined;
-        }
-      }
-    }
-    for (let i: number = this.currentMeasure.VerticalSourceStaffEntryContainers.length - 1; i >= 0; i--) {
-      let counter: number = 0;
-      for (let idx: number = 0, len: number = this.currentMeasure.VerticalSourceStaffEntryContainers[i].StaffEntries.length; idx < len; ++idx) {
-        let sourceStaffEntry: SourceStaffEntry = this.currentMeasure.VerticalSourceStaffEntryContainers[i].StaffEntries[idx];
-        if (sourceStaffEntry === undefined) { counter++; }
-      }
-      if (counter === this.currentMeasure.VerticalSourceStaffEntryContainers[i].StaffEntries.length) {
-        this._removeFromArray(this.currentMeasure.VerticalSourceStaffEntryContainers, this.currentMeasure.VerticalSourceStaffEntryContainers[i]);
-      }
+            if (maxInstrumentDuration < activeRhythm) {
+                maxInstrumentDuration = this.currentMeasure.reverseCheck(this.musicSheet, maxInstrumentDuration);
+                this.checkFractionsForEquivalence(maxInstrumentDuration, activeRhythm);
+            }
+        }
+        this.currentMeasure.ImplicitMeasure = this.checkIfMeasureIsImplicit(maxInstrumentDuration, activeRhythm);
+        if (!this.currentMeasure.ImplicitMeasure) {
+            sourceMeasureCounter++;
+        }
+        this.currentMeasure.Duration = maxInstrumentDuration;
+        this.currentMeasure.MeasureNumber = sourceMeasureCounter;
+        for (let i: number = 0; i < instrumentsDurations.length; i++) {
+            let instrumentsDuration: Fraction = instrumentsDurations[i];
+            if (
+                (this.currentMeasure.ImplicitMeasure && instrumentsDuration !== maxInstrumentDuration) ||
+                instrumentsDuration !== activeRhythm && // FIXME
+                !this.allInstrumentsHaveSameDuration(instrumentsDurations, maxInstrumentDuration)
+            ) {
+                let firstStaffIndexOfInstrument: number = this.musicSheet.getGlobalStaffIndexOfFirstStaff(this.musicSheet.Instruments[i]);
+                for (let staffIndex: number = 0; staffIndex < this.musicSheet.Instruments[i].Staves.length; staffIndex++) {
+                    if (!this.staffMeasureIsEmpty(firstStaffIndexOfInstrument + staffIndex)) {
+                        this.currentMeasure.setErrorInStaffMeasure(firstStaffIndexOfInstrument + staffIndex, true);
+                        let errorMsg: string = ITextTranslation.translateText("ReaderErrorMessages/MissingNotesError", "Given Notes don't correspond to measure duration.");
+                        this.musicSheet.SheetErrors.pushMeasureError(errorMsg);
+                    }
+                }
+            }
+        }
     }
-  }
-  private pushSheetLabels(root: IXmlElement, filePath: string): void {
-    this.readComposer(root);
-    this.readTitle(root);
-    if (this.musicSheet.Title === undefined || this.musicSheet.Composer === undefined) {
-      this.readTitleAndComposerFromCredits(root);
+
+    private checkFractionsForEquivalence(maxInstrumentDuration: Fraction, activeRhythm: Fraction): void {
+        if (activeRhythm.Denominator > maxInstrumentDuration.Denominator) {
+            let factor: number = activeRhythm.Denominator / maxInstrumentDuration.Denominator;
+            maxInstrumentDuration.multiplyWithFactor(factor);
+        }
     }
-    if (this.musicSheet.Title === undefined) {
-      try {
-        let barI: number = Math.max(
-          0, filePath.lastIndexOf("/"), filePath.lastIndexOf("\\")
-        );
-        let filename: string = filePath.substr(barI);
-        let filenameSplits: string[] = filename.split(".", 1);
-        this.musicSheet.Title = new Label(filenameSplits[0]);
-      } catch (ex) {
-        Logging.log("MusicSheetReader.pushSheetLabels: ", ex);
-      }
 
+    private checkIfMeasureIsImplicit(maxInstrumentDuration: Fraction, activeRhythm: Fraction): boolean {
+        if (this.previousMeasure === undefined && maxInstrumentDuration < activeRhythm) {
+            return true;
+        }
+        if (this.previousMeasure !== undefined) {
+            return Fraction.plus(this.previousMeasure.Duration, maxInstrumentDuration).CompareTo(activeRhythm) === 0;
+        }
+        return false;
     }
-  }
-  // Checks whether _elem_ has an attribute with value _val_.
-  private presentAttrsWithValue(elem: IXmlElement, val: string): boolean {
-    for (let attr of elem.attributes()) {
-      if (attr.value === val) { return true; }
+
+    private allInstrumentsHaveSameDuration(instrumentsDurations: Fraction[], maxInstrumentDuration: Fraction): boolean {
+        let counter: number = 0;
+        for (let idx: number = 0, len: number = instrumentsDurations.length; idx < len; ++idx) {
+            let instrumentsDuration: Fraction = instrumentsDurations[idx];
+            if (instrumentsDuration === maxInstrumentDuration) {
+                counter++;
+            }
+        }
+        return (counter === instrumentsDurations.length && maxInstrumentDuration !== new Fraction(0, 1));
     }
-    return false;
-  }
-
-  private readComposer(root: IXmlElement): void {
-    let identificationNode: IXmlElement = root.element("identification");
-    if (identificationNode !== undefined) {
-      let creators: IXmlElement[] = identificationNode.elements("creator");
-      for (let idx: number = 0, len: number = creators.length; idx < len; ++idx) {
-        let creator: IXmlElement = creators[idx];
-        if (creator.hasAttributes) {
-          if (this.presentAttrsWithValue(creator, "composer")) {
-            this.musicSheet.Composer = new Label(this.trimString(creator.value));
-            continue;
-          }
-          if (this.presentAttrsWithValue(creator, "lyricist") || this.presentAttrsWithValue(creator, "poet")) {
-            this.musicSheet.Lyricist = new Label(this.trimString(creator.value));
-          }
-        }
-      }
+
+    private staffMeasureIsEmpty(index: number): boolean {
+        let counter: number = 0;
+        for (let i: number = 0; i < this.currentMeasure.VerticalSourceStaffEntryContainers.length; i++) {
+            if (this.currentMeasure.VerticalSourceStaffEntryContainers[i].StaffEntries[index] === undefined) {
+                counter++;
+            }
+        }
+        return (counter === this.currentMeasure.VerticalSourceStaffEntryContainers.length);
     }
-  }
-
-  private readTitleAndComposerFromCredits(root: IXmlElement): void {
-    let systemYCoordinates: number = this.computeSystemYCoordinates(root);
-    if (systemYCoordinates === 0) { return; }
-    let largestTitleCreditSize: number = 1;
-    let finalTitle: string = undefined;
-    let largestCreditYInfo: number = 0;
-    let finalSubtitle: string = undefined;
-    let possibleTitle: string = undefined;
-    let creditElements: IXmlElement[] = root.elements("credit");
-    for (let idx: number = 0, len: number = creditElements.length; idx < len; ++idx) {
-      let credit: IXmlElement = creditElements[idx];
-      if (!credit.attribute("page")) { return; }
-      if (credit.attribute("page").value === "1") {
-        let creditChild: IXmlElement = undefined;
-        if (credit !== undefined) {
-          creditChild = credit.element("credit-words");
-          if (!creditChild.attribute("justify")) {
-            break;
-          }
-          let creditJustify: string = creditChild.attribute("justify").value;
-          let creditY: string = creditChild.attribute("default-y").value;
-          let creditYInfo: number = parseFloat(creditY);
-          if (creditYInfo > systemYCoordinates) {
-            if (this.musicSheet.Title === undefined) {
-              let creditSize: string = creditChild.attribute("font-size").value;
-              let titleCreditSizeInt: number = parseFloat(creditSize);
-              if (largestTitleCreditSize < titleCreditSizeInt) {
-                largestTitleCreditSize = titleCreditSizeInt;
-                finalTitle = creditChild.value;
-              }
-            }
-            if (this.musicSheet.Subtitle === undefined) {
-              if (creditJustify !== "right" && creditJustify !== "left") {
-                if (largestCreditYInfo < creditYInfo) {
-                  largestCreditYInfo = creditYInfo;
-                  if (possibleTitle) {
-                    finalSubtitle = possibleTitle;
-                    possibleTitle = creditChild.value;
-                  } else {
-                    possibleTitle = creditChild.value;
-                  }
+
+    private checkSourceMeasureForundefinedEntries(): void {
+        for (let i: number = this.currentMeasure.VerticalSourceStaffEntryContainers.length - 1; i >= 0; i--) {
+            for (let j: number = this.currentMeasure.VerticalSourceStaffEntryContainers[i].StaffEntries.length - 1; j >= 0; j--) {
+                let sourceStaffEntry: SourceStaffEntry = this.currentMeasure.VerticalSourceStaffEntryContainers[i].StaffEntries[j];
+                if (sourceStaffEntry !== undefined) {
+                    for (let k: number = sourceStaffEntry.VoiceEntries.length - 1; k >= 0; k--) {
+                        let voiceEntry: VoiceEntry = sourceStaffEntry.VoiceEntries[k];
+                        if (voiceEntry.Notes.length === 0) {
+                            this._removeFromArray(voiceEntry.ParentVoice.VoiceEntries, voiceEntry);
+                            this._removeFromArray(sourceStaffEntry.VoiceEntries, voiceEntry);
+                        }
+                    }
                 }
-              }
-            }
-            if (!(this.musicSheet.Composer !== undefined && this.musicSheet.Lyricist !== undefined)) {
-              switch (creditJustify) {
-                case "right":
-                  this.musicSheet.Composer = new Label(this.trimString(creditChild.value));
-                  break;
-                case "left":
-                  this.musicSheet.Lyricist = new Label(this.trimString(creditChild.value));
-                  break;
-                default: break;
-              }
-            }
-          }
-        }
-      }
-    }
-    if (this.musicSheet.Title === undefined && finalTitle) {
-      this.musicSheet.Title = new Label(this.trimString(finalTitle));
-    }
-    if (this.musicSheet.Subtitle === undefined && finalSubtitle) {
-      this.musicSheet.Subtitle = new Label(this.trimString(finalSubtitle));
+                if (sourceStaffEntry !== undefined && sourceStaffEntry.VoiceEntries.length === 0) {
+                    this.currentMeasure.VerticalSourceStaffEntryContainers[i].StaffEntries[j] = undefined;
+                }
+            }
+        }
+        for (let i: number = this.currentMeasure.VerticalSourceStaffEntryContainers.length - 1; i >= 0; i--) {
+            let counter: number = 0;
+            for (let idx: number = 0, len: number = this.currentMeasure.VerticalSourceStaffEntryContainers[i].StaffEntries.length; idx < len; ++idx) {
+                let sourceStaffEntry: SourceStaffEntry = this.currentMeasure.VerticalSourceStaffEntryContainers[i].StaffEntries[idx];
+                if (sourceStaffEntry === undefined) {
+                    counter++;
+                }
+            }
+            if (counter === this.currentMeasure.VerticalSourceStaffEntryContainers[i].StaffEntries.length) {
+                this._removeFromArray(this.currentMeasure.VerticalSourceStaffEntryContainers, this.currentMeasure.VerticalSourceStaffEntryContainers[i]);
+            }
+        }
     }
-  }
 
-  private computeSystemYCoordinates(root: IXmlElement): number {
-    if (root.element("defaults") === undefined) {
-      return 0;
-    }
-    let paperHeight: number = 0;
-    let topSystemDistance: number = 0;
-    let defi: string = root.element("defaults").element("page-layout").element("page-height").value;
-    paperHeight = parseFloat(defi);
-    let found: boolean = false;
-    let parts: IXmlElement[] = root.elements("part");
-    for (let idx: number = 0, len: number = parts.length; idx < len; ++idx) {
-      let measures: IXmlElement[] = parts[idx].elements("measure");
-      for (let idx2: number = 0, len2: number = measures.length; idx2 < len2; ++idx2) {
-        let measure: IXmlElement = measures[idx2];
-        if (measure.element("print") !== undefined) {
-          let systemLayouts: IXmlElement[] = measure.element("print").elements("system-layout");
-          for (let idx3: number = 0, len3: number = systemLayouts.length; idx3 < len3; ++idx3) {
-            let syslab: IXmlElement = systemLayouts[idx3];
-            if (syslab.element("top-system-distance") !== undefined) {
-              let topSystemDistanceString: string = syslab.element("top-system-distance").value;
-              topSystemDistance = parseFloat(topSystemDistanceString);
-              found = true;
-              break;
-            }
-          }
-          break;
-        }
-      }
-      if (found) { break; }
-    }
-    if (root.element("defaults").element("system-layout") !== undefined) {
-      let syslay: IXmlElement = root.element("defaults").element("system-layout");
-      if (syslay.element("top-system-distance") !== undefined) {
-        let topSystemDistanceString: string = root.element("defaults").element("system-layout").element("top-system-distance").value;
-        topSystemDistance = parseFloat(topSystemDistanceString);
-      }
-    }
-    if (topSystemDistance === 0) { return 0; }
-    return paperHeight - topSystemDistance;
-  }
-  private readTitle(root: IXmlElement): void {
-    let titleNode: IXmlElement = root.element("work");
-    let titleNodeChild: IXmlElement = undefined;
-    if (titleNode !== undefined) {
-      titleNodeChild = titleNode.element("work-title");
-      if (titleNodeChild !== undefined && titleNodeChild.value) {
-        this.musicSheet.Title = new Label(this.trimString(titleNodeChild.value));
-      }
-    }
-    let movementNode: IXmlElement = root.element("movement-title");
-    let finalSubTitle: string = "";
-    if (movementNode !== undefined) {
-      if (this.musicSheet.Title === undefined) {
-        this.musicSheet.Title = new Label(this.trimString(movementNode.value));
-      } else {
-        finalSubTitle = this.trimString(movementNode.value);
-      }
+    private pushSheetLabels(root: IXmlElement, filePath: string): void {
+        this.readComposer(root);
+        this.readTitle(root);
+        if (this.musicSheet.Title === undefined || this.musicSheet.Composer === undefined) {
+            this.readTitleAndComposerFromCredits(root);
+        }
+        if (this.musicSheet.Title === undefined) {
+            try {
+                let barI: number = Math.max(
+                    0, filePath.lastIndexOf("/"), filePath.lastIndexOf("\\")
+                );
+                let filename: string = filePath.substr(barI);
+                let filenameSplits: string[] = filename.split(".", 1);
+                this.musicSheet.Title = new Label(filenameSplits[0]);
+            } catch (ex) {
+                Logging.log("MusicSheetReader.pushSheetLabels: ", ex);
+            }
+
+        }
     }
-    if (titleNode !== undefined) {
-      let subtitleNodeChild: IXmlElement = titleNode.element("work-number");
-      if (subtitleNodeChild !== undefined) {
-        let workNumber: string = subtitleNodeChild.value;
-        if (workNumber) {
-          if (finalSubTitle) {
-            finalSubTitle = workNumber;
-          } else {
-            finalSubTitle = finalSubTitle + ", " + workNumber;
-          }
-        }
-      }
+
+    // Checks whether _elem_ has an attribute with value _val_.
+    private presentAttrsWithValue(elem: IXmlElement, val: string): boolean {
+        for (let attr of elem.attributes()) {
+            if (attr.value === val) {
+                return true;
+            }
+        }
+        return false;
     }
-    if (finalSubTitle
-    ) {
-      this.musicSheet.Subtitle = new Label(finalSubTitle);
+
+    private readComposer(root: IXmlElement): void {
+        let identificationNode: IXmlElement = root.element("identification");
+        if (identificationNode !== undefined) {
+            let creators: IXmlElement[] = identificationNode.elements("creator");
+            for (let idx: number = 0, len: number = creators.length; idx < len; ++idx) {
+                let creator: IXmlElement = creators[idx];
+                if (creator.hasAttributes) {
+                    if (this.presentAttrsWithValue(creator, "composer")) {
+                        this.musicSheet.Composer = new Label(this.trimString(creator.value));
+                        continue;
+                    }
+                    if (this.presentAttrsWithValue(creator, "lyricist") || this.presentAttrsWithValue(creator, "poet")) {
+                        this.musicSheet.Lyricist = new Label(this.trimString(creator.value));
+                    }
+                }
+            }
+        }
     }
-  }
-  private createInstrumentGroups(entryList: IXmlElement[]): { [_: string]: Instrument; } {
-    let instrumentId: number = 0;
-    let instrumentDict: { [_: string]: Instrument; } = {};
-    let currentGroup: InstrumentalGroup;
-    try {
-      let entryArray: IXmlElement[] = entryList;
-      for (let idx: number = 0, len: number = entryArray.length; idx < len; ++idx) {
-        let node: IXmlElement = entryArray[idx];
-        if (node.name === "score-part") {
-          let instrIdString: string = node.attribute("id").value;
-          let instrument: Instrument = new Instrument(instrumentId, instrIdString, this.musicSheet, currentGroup);
-          instrumentId++;
-          let partElements: IXmlElement[] = node.elements();
-          for (let idx2: number = 0, len2: number = partElements.length; idx2 < len2; ++idx2) {
-            let partElement: IXmlElement = partElements[idx2];
-            try {
-              if (partElement.name === "part-name") {
-                instrument.Name = partElement.value;
-              } else if (partElement.name === "score-instrument") {
-                let subInstrument: SubInstrument = new SubInstrument(instrument);
-                subInstrument.idString = partElement.firstAttribute.value;
-                instrument.SubInstruments.push(subInstrument);
-                let subElement: IXmlElement = partElement.element("instrument-name");
-                if (subElement !== undefined) {
-                  subInstrument.name = subElement.value;
-                  subInstrument.setMidiInstrument(subElement.value);
+
+    private readTitleAndComposerFromCredits(root: IXmlElement): void {
+        let systemYCoordinates: number = this.computeSystemYCoordinates(root);
+        if (systemYCoordinates === 0) {
+            return;
+        }
+        let largestTitleCreditSize: number = 1;
+        let finalTitle: string = undefined;
+        let largestCreditYInfo: number = 0;
+        let finalSubtitle: string = undefined;
+        let possibleTitle: string = undefined;
+        let creditElements: IXmlElement[] = root.elements("credit");
+        for (let idx: number = 0, len: number = creditElements.length; idx < len; ++idx) {
+            let credit: IXmlElement = creditElements[idx];
+            if (!credit.attribute("page")) {
+                return;
+            }
+            if (credit.attribute("page").value === "1") {
+                let creditChild: IXmlElement = undefined;
+                if (credit !== undefined) {
+                    creditChild = credit.element("credit-words");
+                    if (!creditChild.attribute("justify")) {
+                        break;
+                    }
+                    let creditJustify: string = creditChild.attribute("justify").value;
+                    let creditY: string = creditChild.attribute("default-y").value;
+                    let creditYInfo: number = parseFloat(creditY);
+                    if (creditYInfo > systemYCoordinates) {
+                        if (this.musicSheet.Title === undefined) {
+                            let creditSize: string = creditChild.attribute("font-size").value;
+                            let titleCreditSizeInt: number = parseFloat(creditSize);
+                            if (largestTitleCreditSize < titleCreditSizeInt) {
+                                largestTitleCreditSize = titleCreditSizeInt;
+                                finalTitle = creditChild.value;
+                            }
+                        }
+                        if (this.musicSheet.Subtitle === undefined) {
+                            if (creditJustify !== "right" && creditJustify !== "left") {
+                                if (largestCreditYInfo < creditYInfo) {
+                                    largestCreditYInfo = creditYInfo;
+                                    if (possibleTitle) {
+                                        finalSubtitle = possibleTitle;
+                                        possibleTitle = creditChild.value;
+                                    } else {
+                                        possibleTitle = creditChild.value;
+                                    }
+                                }
+                            }
+                        }
+                        if (!(this.musicSheet.Composer !== undefined && this.musicSheet.Lyricist !== undefined)) {
+                            switch (creditJustify) {
+                                case "right":
+                                    this.musicSheet.Composer = new Label(this.trimString(creditChild.value));
+                                    break;
+                                case "left":
+                                    this.musicSheet.Lyricist = new Label(this.trimString(creditChild.value));
+                                    break;
+                                default:
+                                    break;
+                            }
+                        }
+                    }
                 }
-              } else if (partElement.name === "midi-instrument") {
-                let subInstrument: SubInstrument = instrument.getSubInstrument(partElement.firstAttribute.value);
-                for (let idx3: number = 0, len3: number = instrument.SubInstruments.length; idx3 < len3; ++idx3) {
-                  let subInstr: SubInstrument = instrument.SubInstruments[idx3];
-                  if (subInstr.idString === partElement.value) {
-                    subInstrument = subInstr;
+            }
+        }
+        if (this.musicSheet.Title === undefined && finalTitle) {
+            this.musicSheet.Title = new Label(this.trimString(finalTitle));
+        }
+        if (this.musicSheet.Subtitle === undefined && finalSubtitle) {
+            this.musicSheet.Subtitle = new Label(this.trimString(finalSubtitle));
+        }
+    }
+
+    private computeSystemYCoordinates(root: IXmlElement): number {
+        if (root.element("defaults") === undefined) {
+            return 0;
+        }
+        let paperHeight: number = 0;
+        let topSystemDistance: number = 0;
+        let defi: string = root.element("defaults").element("page-layout").element("page-height").value;
+        paperHeight = parseFloat(defi);
+        let found: boolean = false;
+        let parts: IXmlElement[] = root.elements("part");
+        for (let idx: number = 0, len: number = parts.length; idx < len; ++idx) {
+            let measures: IXmlElement[] = parts[idx].elements("measure");
+            for (let idx2: number = 0, len2: number = measures.length; idx2 < len2; ++idx2) {
+                let measure: IXmlElement = measures[idx2];
+                if (measure.element("print") !== undefined) {
+                    let systemLayouts: IXmlElement[] = measure.element("print").elements("system-layout");
+                    for (let idx3: number = 0, len3: number = systemLayouts.length; idx3 < len3; ++idx3) {
+                        let syslab: IXmlElement = systemLayouts[idx3];
+                        if (syslab.element("top-system-distance") !== undefined) {
+                            let topSystemDistanceString: string = syslab.element("top-system-distance").value;
+                            topSystemDistance = parseFloat(topSystemDistanceString);
+                            found = true;
+                            break;
+                        }
+                    }
                     break;
-                  }
                 }
-                let instrumentElements: IXmlElement[] = partElement.elements();
-                for (let idx3: number = 0, len3: number = instrumentElements.length; idx3 < len3; ++idx3) {
-                  let instrumentElement: IXmlElement = instrumentElements[idx3];
-                  try {
-                    if (instrumentElement.name === "midi-channel") {
-                      if (parseInt(instrumentElement.value, 10) === 10) {
-                        instrument.MidiInstrumentId = MidiInstrument.Percussion;
-                      }
-                    } else if (instrumentElement.name === "midi-program") {
-                      if (instrument.SubInstruments.length > 0 && instrument.MidiInstrumentId !== MidiInstrument.Percussion) {
-                        subInstrument.midiInstrumentID = <MidiInstrument>Math.max(0, parseInt(instrumentElement.value, 10) - 1);
-                      }
-                    } else if (instrumentElement.name === "midi-unpitched") {
-                      subInstrument.fixedKey = Math.max(0, parseInt(instrumentElement.value, 10));
-                    } else if (instrumentElement.name === "volume") {
-                      try {
-                        let result: number = <number>parseFloat(instrumentElement.value);
-                        subInstrument.volume = result / 127.0;
-                      } catch (ex) {
-                        Logging.debug("ExpressionReader.readExpressionParameters", "read volume", ex);
-                      }
-
-                    } else if (instrumentElement.name === "pan") {
-                      try {
-                        let result: number = <number>parseFloat(instrumentElement.value);
-                        subInstrument.pan = result / 64.0;
-                      } catch (ex) {
-                        Logging.debug("ExpressionReader.readExpressionParameters", "read pan", ex);
-                      }
+            }
+            if (found) {
+                break;
+            }
+        }
+        if (root.element("defaults").element("system-layout") !== undefined) {
+            let syslay: IXmlElement = root.element("defaults").element("system-layout");
+            if (syslay.element("top-system-distance") !== undefined) {
+                let topSystemDistanceString: string = root.element("defaults").element("system-layout").element("top-system-distance").value;
+                topSystemDistance = parseFloat(topSystemDistanceString);
+            }
+        }
+        if (topSystemDistance === 0) {
+            return 0;
+        }
+        return paperHeight - topSystemDistance;
+    }
 
+    private readTitle(root: IXmlElement): void {
+        let titleNode: IXmlElement = root.element("work");
+        let titleNodeChild: IXmlElement = undefined;
+        if (titleNode !== undefined) {
+            titleNodeChild = titleNode.element("work-title");
+            if (titleNodeChild !== undefined && titleNodeChild.value) {
+                this.musicSheet.Title = new Label(this.trimString(titleNodeChild.value));
+            }
+        }
+        let movementNode: IXmlElement = root.element("movement-title");
+        let finalSubTitle: string = "";
+        if (movementNode !== undefined) {
+            if (this.musicSheet.Title === undefined) {
+                this.musicSheet.Title = new Label(this.trimString(movementNode.value));
+            } else {
+                finalSubTitle = this.trimString(movementNode.value);
+            }
+        }
+        if (titleNode !== undefined) {
+            let subtitleNodeChild: IXmlElement = titleNode.element("work-number");
+            if (subtitleNodeChild !== undefined) {
+                let workNumber: string = subtitleNodeChild.value;
+                if (workNumber) {
+                    if (finalSubTitle) {
+                        finalSubTitle = workNumber;
+                    } else {
+                        finalSubTitle = finalSubTitle + ", " + workNumber;
                     }
-                  } catch (ex) {
-                    Logging.log("MusicSheetReader.createInstrumentGroups midi settings: ", ex);
-                  }
-
                 }
-              }
-            } catch (ex) {
-              Logging.log("MusicSheetReader.createInstrumentGroups: ", ex);
-            }
-
-          }
-          if (instrument.SubInstruments.length === 0) {
-            let subInstrument: SubInstrument = new SubInstrument(instrument);
-            instrument.SubInstruments.push(subInstrument);
-          }
-          instrumentDict[instrIdString] = instrument;
-          if (currentGroup !== undefined) {
-            currentGroup.InstrumentalGroups.push(instrument);
-            this.musicSheet.Instruments.push(instrument);
-          } else {
-            this.musicSheet.InstrumentalGroups.push(instrument);
-            this.musicSheet.Instruments.push(instrument);
-          }
-        } else {
-          if ((node.name === "part-group") && (node.attribute("type").value === "start")) {
-            let iG: InstrumentalGroup = new InstrumentalGroup("group", this.musicSheet, currentGroup);
-            if (currentGroup !== undefined) {
-              currentGroup.InstrumentalGroups.push(iG);
-            } else {
-              this.musicSheet.InstrumentalGroups.push(iG);
-            }
-            currentGroup = iG;
-          } else {
-            if ((node.name === "part-group") && (node.attribute("type").value === "stop")) {
-              if (currentGroup !== undefined) {
-                if (currentGroup.InstrumentalGroups.length === 1) {
-                  let instr: InstrumentalGroup = currentGroup.InstrumentalGroups[0];
-                  if (currentGroup.Parent !== undefined) {
-                    currentGroup.Parent.InstrumentalGroups.push(instr);
-                    this._removeFromArray(currentGroup.Parent.InstrumentalGroups, currentGroup);
-                  } else {
-                    this.musicSheet.InstrumentalGroups.push(instr);
-                    this._removeFromArray(this.musicSheet.InstrumentalGroups, currentGroup);
-                  }
+            }
+        }
+        if (finalSubTitle
+        ) {
+            this.musicSheet.Subtitle = new Label(finalSubTitle);
+        }
+    }
+
+    private createInstrumentGroups(entryList: IXmlElement[]): { [_: string]: Instrument; } {
+        let instrumentId: number = 0;
+        let instrumentDict: { [_: string]: Instrument; } = {};
+        let currentGroup: InstrumentalGroup;
+        try {
+            let entryArray: IXmlElement[] = entryList;
+            for (let idx: number = 0, len: number = entryArray.length; idx < len; ++idx) {
+                let node: IXmlElement = entryArray[idx];
+                if (node.name === "score-part") {
+                    let instrIdString: string = node.attribute("id").value;
+                    let instrument: Instrument = new Instrument(instrumentId, instrIdString, this.musicSheet, currentGroup);
+                    instrumentId++;
+                    let partElements: IXmlElement[] = node.elements();
+                    for (let idx2: number = 0, len2: number = partElements.length; idx2 < len2; ++idx2) {
+                        let partElement: IXmlElement = partElements[idx2];
+                        try {
+                            if (partElement.name === "part-name") {
+                                instrument.Name = partElement.value;
+                            } else if (partElement.name === "score-instrument") {
+                                let subInstrument: SubInstrument = new SubInstrument(instrument);
+                                subInstrument.idString = partElement.firstAttribute.value;
+                                instrument.SubInstruments.push(subInstrument);
+                                let subElement: IXmlElement = partElement.element("instrument-name");
+                                if (subElement !== undefined) {
+                                    subInstrument.name = subElement.value;
+                                    subInstrument.setMidiInstrument(subElement.value);
+                                }
+                            } else if (partElement.name === "midi-instrument") {
+                                let subInstrument: SubInstrument = instrument.getSubInstrument(partElement.firstAttribute.value);
+                                for (let idx3: number = 0, len3: number = instrument.SubInstruments.length; idx3 < len3; ++idx3) {
+                                    let subInstr: SubInstrument = instrument.SubInstruments[idx3];
+                                    if (subInstr.idString === partElement.value) {
+                                        subInstrument = subInstr;
+                                        break;
+                                    }
+                                }
+                                let instrumentElements: IXmlElement[] = partElement.elements();
+                                for (let idx3: number = 0, len3: number = instrumentElements.length; idx3 < len3; ++idx3) {
+                                    let instrumentElement: IXmlElement = instrumentElements[idx3];
+                                    try {
+                                        if (instrumentElement.name === "midi-channel") {
+                                            if (parseInt(instrumentElement.value, 10) === 10) {
+                                                instrument.MidiInstrumentId = MidiInstrument.Percussion;
+                                            }
+                                        } else if (instrumentElement.name === "midi-program") {
+                                            if (instrument.SubInstruments.length > 0 && instrument.MidiInstrumentId !== MidiInstrument.Percussion) {
+                                                subInstrument.midiInstrumentID = <MidiInstrument>Math.max(0, parseInt(instrumentElement.value, 10) - 1);
+                                            }
+                                        } else if (instrumentElement.name === "midi-unpitched") {
+                                            subInstrument.fixedKey = Math.max(0, parseInt(instrumentElement.value, 10));
+                                        } else if (instrumentElement.name === "volume") {
+                                            try {
+                                                let result: number = <number>parseFloat(instrumentElement.value);
+                                                subInstrument.volume = result / 127.0;
+                                            } catch (ex) {
+                                                Logging.debug("ExpressionReader.readExpressionParameters", "read volume", ex);
+                                            }
+
+                                        } else if (instrumentElement.name === "pan") {
+                                            try {
+                                                let result: number = <number>parseFloat(instrumentElement.value);
+                                                subInstrument.pan = result / 64.0;
+                                            } catch (ex) {
+                                                Logging.debug("ExpressionReader.readExpressionParameters", "read pan", ex);
+                                            }
+
+                                        }
+                                    } catch (ex) {
+                                        Logging.log("MusicSheetReader.createInstrumentGroups midi settings: ", ex);
+                                    }
+
+                                }
+                            }
+                        } catch (ex) {
+                            Logging.log("MusicSheetReader.createInstrumentGroups: ", ex);
+                        }
+
+                    }
+                    if (instrument.SubInstruments.length === 0) {
+                        let subInstrument: SubInstrument = new SubInstrument(instrument);
+                        instrument.SubInstruments.push(subInstrument);
+                    }
+                    instrumentDict[instrIdString] = instrument;
+                    if (currentGroup !== undefined) {
+                        currentGroup.InstrumentalGroups.push(instrument);
+                        this.musicSheet.Instruments.push(instrument);
+                    } else {
+                        this.musicSheet.InstrumentalGroups.push(instrument);
+                        this.musicSheet.Instruments.push(instrument);
+                    }
+                } else {
+                    if ((node.name === "part-group") && (node.attribute("type").value === "start")) {
+                        let iG: InstrumentalGroup = new InstrumentalGroup("group", this.musicSheet, currentGroup);
+                        if (currentGroup !== undefined) {
+                            currentGroup.InstrumentalGroups.push(iG);
+                        } else {
+                            this.musicSheet.InstrumentalGroups.push(iG);
+                        }
+                        currentGroup = iG;
+                    } else {
+                        if ((node.name === "part-group") && (node.attribute("type").value === "stop")) {
+                            if (currentGroup !== undefined) {
+                                if (currentGroup.InstrumentalGroups.length === 1) {
+                                    let instr: InstrumentalGroup = currentGroup.InstrumentalGroups[0];
+                                    if (currentGroup.Parent !== undefined) {
+                                        currentGroup.Parent.InstrumentalGroups.push(instr);
+                                        this._removeFromArray(currentGroup.Parent.InstrumentalGroups, currentGroup);
+                                    } else {
+                                        this.musicSheet.InstrumentalGroups.push(instr);
+                                        this._removeFromArray(this.musicSheet.InstrumentalGroups, currentGroup);
+                                    }
+                                }
+                                currentGroup = currentGroup.Parent;
+                            }
+                        }
+                    }
                 }
-                currentGroup = currentGroup.Parent;
-              }
             }
-          }
+        } catch (e) {
+            let errorMsg: string = ITextTranslation.translateText(
+                "ReaderErrorMessages/InstrumentError", "Error while reading Instruments"
+            );
+            throw new MusicSheetReadingException(errorMsg, e);
+        }
+
+        for (let idx: number = 0, len: number = this.musicSheet.Instruments.length; idx < len; ++idx) {
+            let instrument: Instrument = this.musicSheet.Instruments[idx];
+            if (!instrument.Name) {
+                instrument.Name = "Instr. " + instrument.IdString;
+            }
         }
-      }
-    } catch (e) {
-      let errorMsg: string = ITextTranslation.translateText(
-        "ReaderErrorMessages/InstrumentError", "Error while reading Instruments"
-      );
-      throw new MusicSheetReadingException(errorMsg, e);
+        return instrumentDict;
     }
 
-    for (let idx: number = 0, len: number = this.musicSheet.Instruments.length; idx < len; ++idx) {
-      let instrument: Instrument = this.musicSheet.Instruments[idx];
-      if (!instrument.Name) {
-        instrument.Name = "Instr. " + instrument.IdString;
-      }
+    private getCompleteNumberOfStavesFromXml(partInst: IXmlElement[]): number {
+        let num: number = 0;
+        for (let partNode of partInst) {
+            let xmlMeasureList: IXmlElement[] = partNode.elements("measure");
+            if (xmlMeasureList.length > 0) {
+                let xmlMeasure: IXmlElement = xmlMeasureList[0];
+                if (xmlMeasure !== undefined) {
+                    let stavesNode: IXmlElement = xmlMeasure.element("attributes");
+                    if (stavesNode !== undefined) {
+                        stavesNode = stavesNode.element("staves");
+                    }
+                    if (stavesNode === undefined) {
+                        num++;
+                    } else {
+                        num += parseInt(stavesNode.value, 10);
+                    }
+                }
+            }
+        }
+        if (isNaN(num) || num <= 0) {
+            let errorMsg: string = ITextTranslation.translateText(
+                "ReaderErrorMessages/StaffError", "Invalid number of staves."
+            );
+            throw new MusicSheetReadingException(errorMsg);
+        }
+        return num;
     }
-    return instrumentDict;
-  }
-  private getCompleteNumberOfStavesFromXml(partInst: IXmlElement[]): number {
-    let num: number = 0;
-    for (let partNode of partInst) {
-      let xmlMeasureList: IXmlElement[] = partNode.elements("measure");
-      if (xmlMeasureList.length > 0) {
-        let xmlMeasure: IXmlElement = xmlMeasureList[0];
+
+    private getInstrumentNumberOfStavesFromXml(partNode: IXmlElement): number {
+        let num: number = 0;
+        let xmlMeasure: IXmlElement = partNode.element("measure");
         if (xmlMeasure !== undefined) {
-          let stavesNode: IXmlElement = xmlMeasure.element("attributes");
-          if (stavesNode !== undefined) {
-            stavesNode = stavesNode.element("staves");
-          }
-          if (stavesNode === undefined) {
-            num++;
-          } else {
-            num += parseInt(stavesNode.value, 10);
-          }
-        }
-      }
-    }
-    if (isNaN(num) || num <= 0) {
-      let errorMsg: string = ITextTranslation.translateText(
-        "ReaderErrorMessages/StaffError", "Invalid number of staves."
-      );
-      throw new MusicSheetReadingException(errorMsg);
-    }
-    return num;
-  }
-  private getInstrumentNumberOfStavesFromXml(partNode: IXmlElement): number {
-    let num: number = 0;
-    let xmlMeasure: IXmlElement = partNode.element("measure");
-    if (xmlMeasure !== undefined) {
-      let attributes: IXmlElement = xmlMeasure.element("attributes");
-      let staves: IXmlElement = undefined;
-      if (attributes !== undefined) {
-        staves = attributes.element("staves");
-      }
-      if (attributes === undefined || staves === undefined) {
-        num = 1;
-      } else {
-        num = parseInt(staves.value, 10);
-      }
-    }
-    if (isNaN(num) || num <= 0) {
-      let errorMsg: string = ITextTranslation.translateText(
-        "ReaderErrorMessages/StaffError", "Invalid number of Staves."
-      );
-      throw new MusicSheetReadingException(errorMsg);
+            let attributes: IXmlElement = xmlMeasure.element("attributes");
+            let staves: IXmlElement = undefined;
+            if (attributes !== undefined) {
+                staves = attributes.element("staves");
+            }
+            if (attributes === undefined || staves === undefined) {
+                num = 1;
+            } else {
+                num = parseInt(staves.value, 10);
+            }
+        }
+        if (isNaN(num) || num <= 0) {
+            let errorMsg: string = ITextTranslation.translateText(
+                "ReaderErrorMessages/StaffError", "Invalid number of Staves."
+            );
+            throw new MusicSheetReadingException(errorMsg);
+        }
+        return num;
     }
-    return num;
-  }
 }

+ 1 - 1
src/MusicalScore/VoiceData/Expressions/abstractTempoExpression.ts

@@ -1,7 +1,7 @@
 import {PlacementEnum} from "./abstractExpression";
 import {MultiTempoExpression} from "./multiTempoExpression";
 
-export class AbstractTempoExpression {
+export abstract class AbstractTempoExpression {
     constructor(label: string, placement: PlacementEnum, staffNumber: number, parentMultiTempoExpression: MultiTempoExpression) {
         this.label = label;
         this.placement = placement;

+ 1 - 1
src/MusicalScore/VoiceData/Instructions/AbstractNotationInstruction.ts

@@ -1,6 +1,6 @@
 import {SourceStaffEntry} from "../SourceStaffEntry";
 
-export class AbstractNotationInstruction {
+export abstract class AbstractNotationInstruction {
     constructor(parent: SourceStaffEntry) {
         this.parent = parent;
     }

+ 270 - 252
src/MusicalScore/VoiceData/Instructions/ClefInstruction.ts

@@ -5,272 +5,290 @@ import {AccidentalEnum} from "../../../Common/DataObjects/pitch";
 import {ArgumentOutOfRangeException} from "../../Exceptions";
 
 export class ClefInstruction extends AbstractNotationInstruction {
-  constructor(clefType: ClefEnum = ClefEnum.G, octaveOffset: number = 0, line: number = 2) {
-    super(undefined); // FIXME? Missing SourceStaffEntry!
-    this.line = line;
-    this.clefType = clefType;
-    this.octaveOffset = octaveOffset;
-    this.calcParameters();
-  }
-  private clefType: ClefEnum = ClefEnum.G;
-  private line: number = 2;
-  private octaveOffset: number = 0;
-  private clefPitch: Pitch;
-  private referenceCyPosition: number;
+    constructor(clefType: ClefEnum = ClefEnum.G, octaveOffset: number = 0, line: number = 2) {
+        super(undefined); // FIXME? Missing SourceStaffEntry!
+        this.line = line;
+        this.clefType = clefType;
+        this.octaveOffset = octaveOffset;
+        this.calcParameters();
+    }
+
+    private clefType: ClefEnum = ClefEnum.G;
+    private line: number = 2;
+    private octaveOffset: number = 0;
+    private clefPitch: Pitch;
+    private referenceCyPosition: number;
+
+    public static getDefaultClefFromMidiInstrument(instrument: MidiInstrument): ClefInstruction {
+        switch (instrument) {
+            case MidiInstrument.Acoustic_Grand_Piano:
+                return new ClefInstruction(ClefEnum.F, 0, 4);
+            case MidiInstrument.Electric_Bass_finger:
+                return new ClefInstruction(ClefEnum.F, 0, 4);
+            case MidiInstrument.Electric_Bass_pick:
+                return new ClefInstruction(ClefEnum.F, 0, 4);
+            case MidiInstrument.Fretless_Bass:
+                return new ClefInstruction(ClefEnum.F, 0, 4);
+            case MidiInstrument.Slap_Bass_1:
+                return new ClefInstruction(ClefEnum.F, 0, 4);
+            case MidiInstrument.Slap_Bass_2:
+                return new ClefInstruction(ClefEnum.F, 0, 4);
+            case MidiInstrument.Synth_Bass_1:
+                return new ClefInstruction(ClefEnum.F, 0, 4);
+            case MidiInstrument.Synth_Bass_2:
+                return new ClefInstruction(ClefEnum.F, 0, 4);
+            case MidiInstrument.Contrabass:
+                return new ClefInstruction(ClefEnum.F, 0, 4);
+            default:
+                return new ClefInstruction(ClefEnum.G, 0, 2);
+        }
+    }
+
+    public static getAllPossibleClefs(): ClefInstruction[] {
+        let clefList: ClefInstruction[] = [];
+        for (let i: number = 0; i <= 2; i++) {
+            let clefInstructionG: ClefInstruction = new ClefInstruction(ClefEnum.G, i, 2);
+            clefList.push(clefInstructionG);
+        }
+        for (let j: number = -2; j <= 0; j++) {
+            let clefInstructionF: ClefInstruction = new ClefInstruction(ClefEnum.F, j, 4);
+            clefList.push(clefInstructionF);
+        }
+        return clefList;
+    }
+
+    public static isSupportedClef(clef: ClefEnum): boolean {
+        switch (clef) {
+            case ClefEnum.G:
+            case ClefEnum.F:
+            case ClefEnum.C:
+            case ClefEnum.percussion:
+                return true;
+            default:
+                return false;
+        }
+    }
 
-  public static getDefaultClefFromMidiInstrument(instrument: MidiInstrument): ClefInstruction {
-    switch (instrument) {
-      case MidiInstrument.Acoustic_Grand_Piano:
-        return new ClefInstruction(ClefEnum.F, 0, 4);
-      case MidiInstrument.Electric_Bass_finger:
-        return new ClefInstruction(ClefEnum.F, 0, 4);
-      case MidiInstrument.Electric_Bass_pick:
-        return new ClefInstruction(ClefEnum.F, 0, 4);
-      case MidiInstrument.Fretless_Bass:
-        return new ClefInstruction(ClefEnum.F, 0, 4);
-      case MidiInstrument.Slap_Bass_1:
-        return new ClefInstruction(ClefEnum.F, 0, 4);
-      case MidiInstrument.Slap_Bass_2:
-        return new ClefInstruction(ClefEnum.F, 0, 4);
-      case MidiInstrument.Synth_Bass_1:
-        return new ClefInstruction(ClefEnum.F, 0, 4);
-      case MidiInstrument.Synth_Bass_2:
-        return new ClefInstruction(ClefEnum.F, 0, 4);
-      case MidiInstrument.Contrabass:
-        return new ClefInstruction(ClefEnum.F, 0, 4);
-      default:
-        return new ClefInstruction(ClefEnum.G, 0, 2);
+    public get ClefType(): ClefEnum {
+        return this.clefType;
     }
-  }
-  public static getAllPossibleClefs(): ClefInstruction[] {
-    let clefList: ClefInstruction[] = [];
-    for (let i: number = 0; i <= 2; i++) {
-      let clefInstructionG: ClefInstruction = new ClefInstruction(ClefEnum.G, i, 2);
-      clefList.push(clefInstructionG);
+
+    public set ClefType(value: ClefEnum) {
+        this.clefType = value;
     }
-    for (let j: number = -2; j <= 0; j++) {
-      let clefInstructionF: ClefInstruction = new ClefInstruction(ClefEnum.F, j, 4);
-      clefList.push(clefInstructionF);
+
+    public get Line(): number {
+        return this.line;
     }
-    return clefList;
-  }
-  public static isSupportedClef(clef: ClefEnum): boolean {
-    switch (clef) {
-      case ClefEnum.G:
-      case ClefEnum.F:
-      case ClefEnum.C:
-      case ClefEnum.percussion:
-        return true;
-      default:
-        return false;
+
+    public set Line(value: number) {
+        this.line = value;
     }
-  }
 
-  public get ClefType(): ClefEnum {
-    return this.clefType;
-  }
-  public set ClefType(value: ClefEnum) {
-    this.clefType = value;
-  }
-  public get Line(): number {
-    return this.line;
-  }
-  public set Line(value: number) {
-    this.line = value;
-  }
-  public get OctaveOffset(): number {
-    return this.octaveOffset;
-  }
-  public set OctaveOffset(value: number) {
-    this.octaveOffset = value;
-  }
-  public get ClefPitch(): Pitch {
-    return this.clefPitch;
-  }
-  public set ClefPitch(value: Pitch) {
-    this.clefPitch = value;
-  }
-  public get ReferenceCyPosition(): number {
-    return this.referenceCyPosition;
-  }
-  public set ReferenceCyPosition(value: number) {
-    this.referenceCyPosition = value;
-  }
-  public Equals(other: ClefInstruction): boolean {
-    if (this === other) { return true; }
-    if (this === undefined || other === undefined) { return false; }
-    return (this.ClefPitch === other.ClefPitch && this.Line === other.Line);
-  }
+    public get OctaveOffset(): number {
+        return this.octaveOffset;
+    }
+
+    public set OctaveOffset(value: number) {
+        this.octaveOffset = value;
+    }
 
-  public NotEqual(clef2: ClefInstruction): boolean {
-    return ! this.Equals(clef2);
-  }
+    public get ClefPitch(): Pitch {
+        return this.clefPitch;
+    }
+
+    public set ClefPitch(value: Pitch) {
+        this.clefPitch = value;
+    }
+
+    public get ReferenceCyPosition(): number {
+        return this.referenceCyPosition;
+    }
+
+    public set ReferenceCyPosition(value: number) {
+        this.referenceCyPosition = value;
+    }
+
+    public Equals(other: ClefInstruction): boolean {
+        if (this === other) {
+            return true;
+        }
+        if (this === undefined || other === undefined) {
+            return false;
+        }
+        return (this.ClefPitch === other.ClefPitch && this.Line === other.Line);
+    }
+
+    public NotEqual(clef2: ClefInstruction): boolean {
+        return !this.Equals(clef2);
+    }
+
+    public ToString(): string {
+        return "ClefType: " + this.clefType;
+    }
 
-  public ToString(): string {
-    return "ClefType: " + this.clefType;
-  }
-  private calcParameters(): void {
-    switch (this.clefType) {
-      case ClefEnum.G:
-        this.clefPitch = new Pitch(NoteEnum.G, 1 + this.octaveOffset, AccidentalEnum.NONE);
-        this.referenceCyPosition = (5 - this.line) + 2;
-        break;
-      case ClefEnum.F:
-        this.clefPitch = new Pitch(NoteEnum.F, 0 + this.octaveOffset, AccidentalEnum.NONE);
-        this.referenceCyPosition = (5 - this.line) + 1.5;
-        break;
-      case ClefEnum.C:
-        this.clefPitch = new Pitch(NoteEnum.C, 1 + this.octaveOffset, AccidentalEnum.NONE);
-        this.referenceCyPosition = (5 - this.line);
-        break;
-      case ClefEnum.percussion:
-        this.clefPitch = new Pitch(NoteEnum.C, 2, AccidentalEnum.NONE);
-        this.referenceCyPosition = 2;
-        break;
-      default:
-        throw new ArgumentOutOfRangeException("clefType");
+    private calcParameters(): void {
+        switch (this.clefType) {
+            case ClefEnum.G:
+                this.clefPitch = new Pitch(NoteEnum.G, 1 + this.octaveOffset, AccidentalEnum.NONE);
+                this.referenceCyPosition = (5 - this.line) + 2;
+                break;
+            case ClefEnum.F:
+                this.clefPitch = new Pitch(NoteEnum.F, 0 + this.octaveOffset, AccidentalEnum.NONE);
+                this.referenceCyPosition = (5 - this.line) + 1.5;
+                break;
+            case ClefEnum.C:
+                this.clefPitch = new Pitch(NoteEnum.C, 1 + this.octaveOffset, AccidentalEnum.NONE);
+                this.referenceCyPosition = (5 - this.line);
+                break;
+            case ClefEnum.percussion:
+                this.clefPitch = new Pitch(NoteEnum.C, 2, AccidentalEnum.NONE);
+                this.referenceCyPosition = 2;
+                break;
+            default:
+                throw new ArgumentOutOfRangeException("clefType");
+        }
     }
-  }
 }
 
 export enum ClefEnum {
-  G = 0,
-  F = 1,
-  C = 2,
-  percussion = 3,
-  TAB = 4
+    G = 0,
+    F = 1,
+    C = 2,
+    percussion = 3,
+    TAB = 4
 }
 
 
 export enum MidiInstrument {
-  None = -1,
-  Acoustic_Grand_Piano,
-  Bright_Acoustic_Piano,
-  Electric_Grand_Piano,
-  Honky_tonk_Piano,
-  Electric_Piano_1,
-  Electric_Piano_2,
-  Harpsichord,
-  Clavinet,
-  Celesta,
-  Glockenspiel,
-  Music_Box,
-  Vibraphone,
-  Marimba,
-  Xylophone,
-  Tubular_Bells,
-  Dulcimer,
-  Drawbar_Organ,
-  Percussive_Organ,
-  Rock_Organ,
-  Church_Organ,
-  Reed_Organ,
-  Accordion,
-  Harmonica,
-  Tango_Accordion,
-  Acoustic_Guitar_nylon,
-  Acoustic_Guitar_steel,
-  Electric_Guitar_jazz,
-  Electric_Guitar_clean,
-  Electric_Guitar_muted,
-  Overdriven_Guitar,
-  Distortion_Guitar,
-  Guitar_harmonics,
-  Acoustic_Bass,
-  Electric_Bass_finger,
-  Electric_Bass_pick,
-  Fretless_Bass,
-  Slap_Bass_1,
-  Slap_Bass_2,
-  Synth_Bass_1,
-  Synth_Bass_2,
-  Violin,
-  Viola,
-  Cello,
-  Contrabass,
-  Tremolo_Strings,
-  Pizzicato_Strings,
-  Orchestral_Harp,
-  Timpani,
-  String_Ensemble_1,
-  String_Ensemble_2,
-  Synth_Strings_1,
-  Synth_Strings_2,
-  Choir_Aahs,
-  Voice_Oohs,
-  Synth_Voice,
-  Orchestra_Hit,
-  Trumpet,
-  Trombone,
-  Tuba,
-  Muted_Trumpet,
-  French_Horn,
-  Brass_Section,
-  Synth_Brass_1,
-  Synth_Brass_2,
-  Soprano_Sax,
-  Alto_Sax,
-  Tenor_Sax,
-  Baritone_Sax,
-  Oboe,
-  English_Horn,
-  Bassoon,
-  Clarinet,
-  Piccolo,
-  Flute,
-  Recorder,
-  Pan_Flute,
-  Blown_Bottle,
-  Shakuhachi,
-  Whistle,
-  Ocarina,
-  Lead_1_square,
-  Lead_2_sawtooth,
-  Lead_3_calliope,
-  Lead_4_chiff,
-  Lead_5_charang,
-  Lead_6_voice,
-  Lead_7_fifths,
-  Lead_8_bass_lead,
-  Pad_1_new_age,
-  Pad_2_warm,
-  Pad_3_polysynth,
-  Pad_4_choir,
-  Pad_5_bowed,
-  Pad_6_metallic,
-  Pad_7_halo,
-  Pad_8_sweep,
-  FX_1_rain,
-  FX_2_soundtrack,
-  FX_3_crystal,
-  FX_4_atmosphere,
-  FX_5_brightness,
-  FX_6_goblins,
-  FX_7_echoes,
-  FX_8_scifi,
-  Sitar,
-  Banjo,
-  Shamisen,
-  Koto,
-  Kalimba,
-  Bag_pipe,
-  Fiddle,
-  Shanai,
-  Tinkle_Bell,
-  Agogo,
-  Steel_Drums,
-  Woodblock,
-  Taiko_Drum,
-  Melodic_Tom,
-  Synth_Drum,
-  Reverse_Cymbal,
-  Guitar_Fret_Noise,
-  Breath_Noise,
-  Seashore,
-  Bird_Tweet,
-  Telephone_Ring,
-  Helicopter,
-  Applause,
-  Gunshot,
-  Percussion = 128
+    None = -1,
+    Acoustic_Grand_Piano,
+    Bright_Acoustic_Piano,
+    Electric_Grand_Piano,
+    Honky_tonk_Piano,
+    Electric_Piano_1,
+    Electric_Piano_2,
+    Harpsichord,
+    Clavinet,
+    Celesta,
+    Glockenspiel,
+    Music_Box,
+    Vibraphone,
+    Marimba,
+    Xylophone,
+    Tubular_Bells,
+    Dulcimer,
+    Drawbar_Organ,
+    Percussive_Organ,
+    Rock_Organ,
+    Church_Organ,
+    Reed_Organ,
+    Accordion,
+    Harmonica,
+    Tango_Accordion,
+    Acoustic_Guitar_nylon,
+    Acoustic_Guitar_steel,
+    Electric_Guitar_jazz,
+    Electric_Guitar_clean,
+    Electric_Guitar_muted,
+    Overdriven_Guitar,
+    Distortion_Guitar,
+    Guitar_harmonics,
+    Acoustic_Bass,
+    Electric_Bass_finger,
+    Electric_Bass_pick,
+    Fretless_Bass,
+    Slap_Bass_1,
+    Slap_Bass_2,
+    Synth_Bass_1,
+    Synth_Bass_2,
+    Violin,
+    Viola,
+    Cello,
+    Contrabass,
+    Tremolo_Strings,
+    Pizzicato_Strings,
+    Orchestral_Harp,
+    Timpani,
+    String_Ensemble_1,
+    String_Ensemble_2,
+    Synth_Strings_1,
+    Synth_Strings_2,
+    Choir_Aahs,
+    Voice_Oohs,
+    Synth_Voice,
+    Orchestra_Hit,
+    Trumpet,
+    Trombone,
+    Tuba,
+    Muted_Trumpet,
+    French_Horn,
+    Brass_Section,
+    Synth_Brass_1,
+    Synth_Brass_2,
+    Soprano_Sax,
+    Alto_Sax,
+    Tenor_Sax,
+    Baritone_Sax,
+    Oboe,
+    English_Horn,
+    Bassoon,
+    Clarinet,
+    Piccolo,
+    Flute,
+    Recorder,
+    Pan_Flute,
+    Blown_Bottle,
+    Shakuhachi,
+    Whistle,
+    Ocarina,
+    Lead_1_square,
+    Lead_2_sawtooth,
+    Lead_3_calliope,
+    Lead_4_chiff,
+    Lead_5_charang,
+    Lead_6_voice,
+    Lead_7_fifths,
+    Lead_8_bass_lead,
+    Pad_1_new_age,
+    Pad_2_warm,
+    Pad_3_polysynth,
+    Pad_4_choir,
+    Pad_5_bowed,
+    Pad_6_metallic,
+    Pad_7_halo,
+    Pad_8_sweep,
+    FX_1_rain,
+    FX_2_soundtrack,
+    FX_3_crystal,
+    FX_4_atmosphere,
+    FX_5_brightness,
+    FX_6_goblins,
+    FX_7_echoes,
+    FX_8_scifi,
+    Sitar,
+    Banjo,
+    Shamisen,
+    Koto,
+    Kalimba,
+    Bag_pipe,
+    Fiddle,
+    Shanai,
+    Tinkle_Bell,
+    Agogo,
+    Steel_Drums,
+    Woodblock,
+    Taiko_Drum,
+    Melodic_Tom,
+    Synth_Drum,
+    Reverse_Cymbal,
+    Guitar_Fret_Noise,
+    Breath_Noise,
+    Seashore,
+    Bird_Tweet,
+    Telephone_Ring,
+    Helicopter,
+    Applause,
+    Gunshot,
+    Percussion = 128
 }

+ 94 - 102
src/MusicalScore/VoiceData/Instructions/KeyInstruction.ts

@@ -6,126 +6,118 @@ import {Pitch} from "../../../Common/DataObjects/pitch";
 
 
 export class KeyInstruction extends AbstractNotationInstruction {
-  constructor(first: SourceStaffEntry|KeyInstruction, key?: number, mode?: KeyEnum) {
-    // FIXME Andrea: check this constructor
-    if (first === undefined) {
-      super(undefined);
-      this.Key = key;
-      this.mode = mode;
+    constructor(sourceStaffEntry: SourceStaffEntry = undefined, key: number = 0, mode: KeyEnum = KeyEnum.major) {
+        super(sourceStaffEntry);
+        this.Key = key;
+        this.mode = mode;
     }
-    if (first instanceof SourceStaffEntry) {
-      let parent: SourceStaffEntry = <SourceStaffEntry> first;
-      super(parent);
-      this.Key = key;
-      this.mode = mode;
-    }
-    if (first instanceof KeyInstruction) {
-      let keyInstruction: KeyInstruction = <KeyInstruction> first;
-      //super(undefined);
-      //this(keyInstruction.parent, keyInstruction.keyType, keyInstruction.mode);
-      if (keyInstruction.parent instanceof SourceStaffEntry) {
-        super(keyInstruction.parent);
-      } else {
-        super(undefined);
-      }
-      this.keyType = keyInstruction.keyType;
-      this.mode = keyInstruction.mode;
+
+    private static sharpPositionList: NoteEnum[] = [NoteEnum.F, NoteEnum.C, NoteEnum.G, NoteEnum.D, NoteEnum.A, NoteEnum.E, NoteEnum.B];
+    private static flatPositionList: NoteEnum[] = [NoteEnum.B, NoteEnum.E, NoteEnum.A, NoteEnum.D, NoteEnum.G, NoteEnum.C, NoteEnum.F];
+
+    private keyType: number;
+    private mode: KeyEnum;
+
+    public static copy(keyInstruction: KeyInstruction): KeyInstruction {
+        let newKeyInstruction: KeyInstruction = new KeyInstruction(keyInstruction.parent, keyInstruction.Key, keyInstruction.Mode);
+        return newKeyInstruction;
     }
 
-  }
+    public static getNoteEnumList(instruction: KeyInstruction): NoteEnum[] {
+        let enums: NoteEnum[] = [];
+        if (instruction.keyType > 0) {
+            for (let i: number = 0; i < instruction.keyType; i++) {
+                enums.push(KeyInstruction.sharpPositionList[i]);
+            }
+        }
+        if (instruction.keyType < 0) {
+            for (let i: number = 0; i < Math.abs(instruction.keyType); i++) {
+                enums.push(KeyInstruction.flatPositionList[i]);
+            }
+        }
+        return enums;
+    }
 
-  private static sharpPositionList: NoteEnum[] = [NoteEnum.F, NoteEnum.C, NoteEnum.G, NoteEnum.D, NoteEnum.A, NoteEnum.E, NoteEnum.B];
-  private static flatPositionList: NoteEnum[] = [NoteEnum.B, NoteEnum.E, NoteEnum.A, NoteEnum.D, NoteEnum.G, NoteEnum.C, NoteEnum.F];
+    public static getAllPossibleMajorKeyInstructions(): KeyInstruction[] {
+        let keyInstructionList: KeyInstruction[] = [];
+        for (let keyType: number = -7; keyType < 7; keyType++) {
+            let currentKeyInstruction: KeyInstruction = new KeyInstruction(undefined, keyType, KeyEnum.major);
+            keyInstructionList.push(currentKeyInstruction);
+        }
+        return keyInstructionList;
+    }
 
-  private keyType: number;
-  private mode: KeyEnum;
+    public get Key(): number {
+        return this.keyType;
+    }
 
-  public static getNoteEnumList(instruction: KeyInstruction): NoteEnum[] {
-    let enums: NoteEnum[] = [];
-    if (instruction.keyType > 0) {
-      for (let i: number = 0; i < instruction.keyType; i++) {
-        enums.push(KeyInstruction.sharpPositionList[i]);
-      }
+    public set Key(value: number) {
+        this.keyType = value;
     }
-    if (instruction.keyType < 0) {
-      for (let i: number = 0; i < Math.abs(instruction.keyType); i++) {
-        enums.push(KeyInstruction.flatPositionList[i]);
-      }
+
+    public get Mode(): KeyEnum {
+        return this.mode;
     }
-    return enums;
-  }
-
-  public static getAllPossibleMajorKeyInstructions(): KeyInstruction[] {
-    let keyInstructionList: KeyInstruction[] = [];
-    for (let keyType: number = -7; keyType < 7; keyType++) {
-      let currentKeyInstruction: KeyInstruction = new KeyInstruction(undefined, keyType, KeyEnum.major);
-      keyInstructionList.push(currentKeyInstruction);
+
+    public set Mode(value: KeyEnum) {
+        this.mode = value;
     }
-    return keyInstructionList;
-  }
-  public get Key(): number {
-    return this.keyType;
-  }
-  public set Key(value: number) {
-    this.keyType = value;
-  }
-  public get Mode(): KeyEnum {
-    return this.mode;
-  }
-  public set Mode(value: KeyEnum) {
-    this.mode = value;
-  }
-  public getFundamentalNotesOfAccidentals(): NoteEnum[] {
-    let noteList: NoteEnum[] = [];
-    if (this.keyType > 0) {
-      for (let i: number = 0; i < this.keyType; i++) {
-        noteList.push(KeyInstruction.sharpPositionList[i]);
-      }
-    } else if (this.keyType < 0) {
-      for (let i: number = 0; i < -this.keyType; i++) {
-        noteList.push(KeyInstruction.flatPositionList[i]);
-      }
+
+    public getFundamentalNotesOfAccidentals(): NoteEnum[] {
+        let noteList: NoteEnum[] = [];
+        if (this.keyType > 0) {
+            for (let i: number = 0; i < this.keyType; i++) {
+                noteList.push(KeyInstruction.sharpPositionList[i]);
+            }
+        } else if (this.keyType < 0) {
+            for (let i: number = 0; i < -this.keyType; i++) {
+                noteList.push(KeyInstruction.flatPositionList[i]);
+            }
+        }
+        return noteList;
     }
-    return noteList;
-  }
-  public getAlterationForPitch(pitch: Pitch): AccidentalEnum {
-    if (this.keyType > 0 && KeyInstruction.sharpPositionList.indexOf(pitch.FundamentalNote) <= this.keyType) {
-      return AccidentalEnum.SHARP;
-    } else if (this.keyType < 0 && KeyInstruction.flatPositionList.indexOf(pitch.FundamentalNote) <= Math.abs(this.keyType)) {
-      return AccidentalEnum.FLAT;
+
+    public getAlterationForPitch(pitch: Pitch): AccidentalEnum {
+        if (this.keyType > 0 && KeyInstruction.sharpPositionList.indexOf(pitch.FundamentalNote) <= this.keyType) {
+            return AccidentalEnum.SHARP;
+        } else if (this.keyType < 0 && KeyInstruction.flatPositionList.indexOf(pitch.FundamentalNote) <= Math.abs(this.keyType)) {
+            return AccidentalEnum.FLAT;
+        }
+        return AccidentalEnum.NONE;
     }
-    return AccidentalEnum.NONE;
-  }
-  public ToString(): string {
-    return "Key: " + this.keyType + "" + this.mode;
-  }
-  public OperatorEquals(key2: KeyInstruction): boolean {
-    let key1: KeyInstruction = this;
-    if (key1 === key2) {
-      return true;
+
+    public ToString(): string {
+        return "Key: " + this.keyType + "" + this.mode;
     }
-    if ((key1 === undefined) || (key2 === undefined)) {
-      return false;
+
+    public OperatorEquals(key2: KeyInstruction): boolean {
+        let key1: KeyInstruction = this;
+        if (key1 === key2) {
+            return true;
+        }
+        if ((key1 === undefined) || (key2 === undefined)) {
+            return false;
+        }
+        return (key1.Key === key2.Key && key1.Mode === key2.Mode);
     }
-    return (key1.Key === key2.Key && key1.Mode === key2.Mode);
-  }
 
-  public OperatorNotEqual(key2: KeyInstruction): boolean {
-    return !(this.OperatorEquals(key2));
-  }
+    public OperatorNotEqual(key2: KeyInstruction): boolean {
+        return !(this.OperatorEquals(key2));
+    }
 }
 
 export class NoteEnumToHalfToneLink {
-  constructor(note: NoteEnum, halftone: number) {
-    this.note = note;
-    this.halfTone = halftone;
-  }
-  public note: NoteEnum;
-  public halfTone: number;
+    constructor(note: NoteEnum, halftone: number) {
+        this.note = note;
+        this.halfTone = halftone;
+    }
+
+    public note: NoteEnum;
+    public halfTone: number;
 }
 
 export enum KeyEnum {
-  major = 0,
-  minor = 1,
-  none = 2,
+    major = 0,
+    minor = 1,
+    none = 2,
 }

+ 139 - 120
src/MusicalScore/VoiceData/Instructions/RepetitionInstruction.ts

@@ -1,141 +1,160 @@
 import {Repetition} from "../../MusicSource/Repetition";
 
 export class RepetitionInstructionComparer /*implements IComparer<RepetitionInstruction>*/ {
-  public static Compare(x: RepetitionInstruction, y: RepetitionInstruction): number {
-    if (x.parentRepetition !== undefined && y.parentRepetition !== undefined) {
-      if (x.alignment === AlignmentType.End && y.alignment === AlignmentType.End) {
-        if (x.parentRepetition.StartIndex < y.parentRepetition.StartIndex) { return 1; }
-        if (x.parentRepetition.StartIndex > y.parentRepetition.StartIndex) { return -1; }
-      }
-      if (x.alignment === AlignmentType.Begin && y.alignment === AlignmentType.Begin) {
-        if (x.parentRepetition.EndIndex < y.parentRepetition.EndIndex) { return 1; }
-        if (x.parentRepetition.EndIndex > y.parentRepetition.EndIndex) { return -1; }
-      }
+    public static Compare(x: RepetitionInstruction, y: RepetitionInstruction): number {
+        if (x.parentRepetition !== undefined && y.parentRepetition !== undefined) {
+            if (x.alignment === AlignmentType.End && y.alignment === AlignmentType.End) {
+                if (x.parentRepetition.StartIndex < y.parentRepetition.StartIndex) {
+                    return 1;
+                }
+                if (x.parentRepetition.StartIndex > y.parentRepetition.StartIndex) {
+                    return -1;
+                }
+            }
+            if (x.alignment === AlignmentType.Begin && y.alignment === AlignmentType.Begin) {
+                if (x.parentRepetition.EndIndex < y.parentRepetition.EndIndex) {
+                    return 1;
+                }
+                if (x.parentRepetition.EndIndex > y.parentRepetition.EndIndex) {
+                    return -1;
+                }
+            }
+        }
+        return 0;
     }
-    return 0;
-  }
 }
 
 export class RepetitionInstruction /*implements IComparable*/ {
-  /* FIXME: Check constructor calling from other classes
-  constructor(measureIndex: number, type: RepetitionInstructionEnum) {
-    this(measureIndex, [], type, AlignmentType.End, undefined);
-    if (type === RepetitionInstructionEnum.StartLine || type === RepetitionInstructionEnum.Segno || type === RepetitionInstructionEnum.Coda) {
-      this.alignment = AlignmentType.Begin;
-    }
-  }
-  constructor(measureIndex: number, type: RepetitionInstructionEnum, alignment: AlignmentType, parentRepetition: Repetition) {
-    this(measureIndex, [], type, alignment, parentRepetition);
+    /* FIXME: Check constructor calling from other classes
+     constructor(measureIndex: number, type: RepetitionInstructionEnum) {
+     this(measureIndex, [], type, AlignmentType.End, undefined);
+     if (type === RepetitionInstructionEnum.StartLine || type === RepetitionInstructionEnum.Segno || type === RepetitionInstructionEnum.Coda) {
+     this.alignment = AlignmentType.Begin;
+     }
+     }
+     constructor(measureIndex: number, type: RepetitionInstructionEnum, alignment: AlignmentType, parentRepetition: Repetition) {
+     this(measureIndex, [], type, alignment, parentRepetition);
 
-  }
-  constructor(measureIndex: number, endingIndex: number, type: RepetitionInstructionEnum, alignment: AlignmentType, parentRepetition: Repetition) {
-    this(measureIndex, [endingIndex], type, alignment, parentRepetition);
+     }
+     constructor(measureIndex: number, endingIndex: number, type: RepetitionInstructionEnum, alignment: AlignmentType, parentRepetition: Repetition) {
+     this(measureIndex, [endingIndex], type, alignment, parentRepetition);
 
-  }
-  */
-  constructor(measureIndex: number, endingIndices: number[], type: RepetitionInstructionEnum, alignment: AlignmentType, parentRepetition: Repetition) {
-    this.measureIndex = measureIndex;
-    this.endingIndices = endingIndices.slice();
-    this.type = type;
-    this.alignment = alignment;
-    this.parentRepetition = parentRepetition;
-  }
+     }
+     */
+    constructor(measureIndex: number, endingIndices: number[], type: RepetitionInstructionEnum, alignment: AlignmentType, parentRepetition: Repetition) {
+        this.measureIndex = measureIndex;
+        this.endingIndices = endingIndices.slice();
+        this.type = type;
+        this.alignment = alignment;
+        this.parentRepetition = parentRepetition;
+    }
 
-  public measureIndex: number;
-  public endingIndices: number[];
-  public type: RepetitionInstructionEnum;
-  public alignment: AlignmentType;
-  public parentRepetition: Repetition;
+    public measureIndex: number;
+    public endingIndices: number[];
+    public type: RepetitionInstructionEnum;
+    public alignment: AlignmentType;
+    public parentRepetition: Repetition;
 
-  public CompareTo(obj: Object): number {
-    let other: RepetitionInstruction = <RepetitionInstruction>obj;
-    if (this.measureIndex > other.measureIndex) {
-      return 1;
-    } else if (this.measureIndex < other.measureIndex) {
-      return -1;
-    }
-    if (this.alignment === AlignmentType.Begin) {
-      if (other.alignment === AlignmentType.End) { return -1; }
-      switch (this.type) {
-        case RepetitionInstructionEnum.Ending:
-          return 1;
-        case RepetitionInstructionEnum.StartLine:
-          if (other.type === RepetitionInstructionEnum.Ending) {
-            return -1;
-          }
-          return 1;
-        case RepetitionInstructionEnum.Coda:
-        case RepetitionInstructionEnum.Segno:
-          if (other.type === RepetitionInstructionEnum.Coda) {
+    public CompareTo(obj: Object): number {
+        let other: RepetitionInstruction = <RepetitionInstruction>obj;
+        if (this.measureIndex > other.measureIndex) {
             return 1;
-          }
-          return -1;
-        default:
-      }
-    } else {
-      if (other.alignment === AlignmentType.Begin) { return 1; }
-      switch (this.type) {
-        case RepetitionInstructionEnum.Ending:
-          return -1;
-        case RepetitionInstructionEnum.Fine:
-        case RepetitionInstructionEnum.ToCoda:
-          if (other.type === RepetitionInstructionEnum.Ending) { return 1; }
-          return -1;
-        case RepetitionInstructionEnum.ForwardJump:
-          switch (other.type) {
-            case RepetitionInstructionEnum.Ending:
-            case RepetitionInstructionEnum.Fine:
-            case RepetitionInstructionEnum.ToCoda:
-              return 1;
-            default:
-          }
-          return -1;
-        case RepetitionInstructionEnum.DalSegnoAlFine:
-        case RepetitionInstructionEnum.DaCapoAlFine:
-        case RepetitionInstructionEnum.DalSegnoAlCoda:
-        case RepetitionInstructionEnum.DaCapoAlCoda:
-        case RepetitionInstructionEnum.DaCapo:
-        case RepetitionInstructionEnum.DalSegno:
-        case RepetitionInstructionEnum.BackJumpLine:
-          return 1;
-        default:
-      }
+        } else if (this.measureIndex < other.measureIndex) {
+            return -1;
+        }
+        if (this.alignment === AlignmentType.Begin) {
+            if (other.alignment === AlignmentType.End) {
+                return -1;
+            }
+            switch (this.type) {
+                case RepetitionInstructionEnum.Ending:
+                    return 1;
+                case RepetitionInstructionEnum.StartLine:
+                    if (other.type === RepetitionInstructionEnum.Ending) {
+                        return -1;
+                    }
+                    return 1;
+                case RepetitionInstructionEnum.Coda:
+                case RepetitionInstructionEnum.Segno:
+                    if (other.type === RepetitionInstructionEnum.Coda) {
+                        return 1;
+                    }
+                    return -1;
+                default:
+            }
+        } else {
+            if (other.alignment === AlignmentType.Begin) {
+                return 1;
+            }
+            switch (this.type) {
+                case RepetitionInstructionEnum.Ending:
+                    return -1;
+                case RepetitionInstructionEnum.Fine:
+                case RepetitionInstructionEnum.ToCoda:
+                    if (other.type === RepetitionInstructionEnum.Ending) {
+                        return 1;
+                    }
+                    return -1;
+                case RepetitionInstructionEnum.ForwardJump:
+                    switch (other.type) {
+                        case RepetitionInstructionEnum.Ending:
+                        case RepetitionInstructionEnum.Fine:
+                        case RepetitionInstructionEnum.ToCoda:
+                            return 1;
+                        default:
+                    }
+                    return -1;
+                case RepetitionInstructionEnum.DalSegnoAlFine:
+                case RepetitionInstructionEnum.DaCapoAlFine:
+                case RepetitionInstructionEnum.DalSegnoAlCoda:
+                case RepetitionInstructionEnum.DaCapoAlCoda:
+                case RepetitionInstructionEnum.DaCapo:
+                case RepetitionInstructionEnum.DalSegno:
+                case RepetitionInstructionEnum.BackJumpLine:
+                    return 1;
+                default:
+            }
+        }
+        return 0;
     }
-    return 0;
-  }
-  public equals(other: RepetitionInstruction): boolean {
-    if (
-      this.measureIndex !== other.measureIndex
-      || this.type !== other.type
-      || this.alignment !== other.alignment
-      || this.endingIndices.length !== other.endingIndices.length
-    ) { return false; }
-    for (let i: number = 0; i < this.endingIndices.length; i++) {
-      if (this.endingIndices[i] !== other.endingIndices[i]) { return false; }
+
+    public equals(other: RepetitionInstruction): boolean {
+        if (
+            this.measureIndex !== other.measureIndex
+            || this.type !== other.type
+            || this.alignment !== other.alignment
+            || this.endingIndices.length !== other.endingIndices.length
+        ) {
+            return false;
+        }
+        for (let i: number = 0; i < this.endingIndices.length; i++) {
+            if (this.endingIndices[i] !== other.endingIndices[i]) {
+                return false;
+            }
+        }
+        return true;
     }
-    return true;
-  }
 }
 
 export enum RepetitionInstructionEnum {
-  StartLine,
-  ForwardJump,
-  BackJumpLine,
-  Ending,
-  DaCapo,
-  DalSegno,
-  Fine,
-  ToCoda,
-  DalSegnoAlFine,
-  DaCapoAlFine,
-  DalSegnoAlCoda,
-  DaCapoAlCoda,
-  Coda,
-  Segno,
-  None,
+    StartLine,
+    ForwardJump,
+    BackJumpLine,
+    Ending,
+    DaCapo,
+    DalSegno,
+    Fine,
+    ToCoda,
+    DalSegnoAlFine,
+    DaCapoAlFine,
+    DalSegnoAlCoda,
+    DaCapoAlCoda,
+    Coda,
+    Segno,
+    None,
 }
 
 export enum AlignmentType {
-  Begin,
-  End,
+    Begin,
+    End,
 }

+ 6 - 0
src/MusicalScore/VoiceData/Instructions/RhythmInstruction.ts

@@ -9,6 +9,7 @@ export class RhythmInstruction extends AbstractNotationInstruction {
         this.denominator = denominator;
         this.symbolEnum = rhythmSymbolEnum;
     }
+
     private numerator: number;
     private denominator: number;
     private rhythm: Fraction;
@@ -17,18 +18,23 @@ export class RhythmInstruction extends AbstractNotationInstruction {
     public get Rhythm(): Fraction {
         return this.rhythm;
     }
+
     public set Rhythm(value: Fraction) {
         this.rhythm = value;
     }
+
     public get SymbolEnum(): RhythmSymbolEnum {
         return this.symbolEnum;
     }
+
     public set SymbolEnum(value: RhythmSymbolEnum) {
         this.symbolEnum = value;
     }
+
     public clone(): RhythmInstruction {
         return new RhythmInstruction(this.rhythm.clone(), this.numerator, this.denominator, this.symbolEnum);
     }
+
     public OperatorEquals(rhythm2: RhythmInstruction): boolean {
         let rhythm1: RhythmInstruction = this;
         if (rhythm1 === rhythm2) {