diff --git a/Sources/VLModel.cpp b/Sources/VLModel.cpp
index 74d1803..31da39f 100644
--- a/Sources/VLModel.cpp
+++ b/Sources/VLModel.cpp
@@ -811,12 +811,18 @@ VLSong::VLSong(bool initialize)
 		fMeasures[i].fChords.push_back(rchord);
 		fMeasures[i].fMelody.push_back(rest);
 	}
+
+	fGoToCoda	= -1;
+	fCoda		= -1;
 }
 
 void VLSong::swap(VLSong & other)
 {
 	fProperties.swap(other.fProperties);
 	fMeasures.swap(other.fMeasures);
+	fRepeats.swap(other.fRepeats);
+	std::swap(fGoToCoda, other.fGoToCoda);
+	std::swap(fCoda, other.fCoda);
 }
 
 //
@@ -1009,6 +1015,27 @@ static void TransposePinned(int8_t & pitch, int semi)
 		pitch 		  = octave+pitchInOctave;
 }
 
+bool VLSong::IsNonEmpty() const
+{
+	for (size_t measure=0; measure<fMeasures.size(); ++measure) {
+		VLNoteList::const_iterator i = fMeasures[measure].fMelody.begin();
+		VLNoteList::const_iterator e = fMeasures[measure].fMelody.end();
+		
+		for (; i!=e; ++i) 
+			if (i->fPitch != VLNote::kNoPitch)
+				return true;
+	}
+	for (size_t measure=0; measure<fMeasures.size(); ++measure) {
+		VLChordList::const_iterator i = fMeasures[measure].fChords.begin();
+		VLChordList::const_iterator e = fMeasures[measure].fChords.end();
+
+		for (; i!=e; ++i) 
+			if (i->fPitch != VLNote::kNoPitch)
+				return true;
+	}
+	return false;
+}
+
 void VLSong::Transpose(int semi)
 {
 	for (int pass=0; pass<2 && semi;) {
@@ -1109,6 +1136,9 @@ void VLSong::LilypondNotes(std::string & notes) const
 			indent = "";
 		}
 		notes += indent;
+		if (fCoda == measure)
+			notes += "\\break \\mark \\markup { \\musicglyph #\"scripts.coda\" }\n"
+				+ indent;
 		VLFraction prevDur(0);
 		bool triplet = false;
 		for (; i!=e; ++i) {
@@ -1131,7 +1161,12 @@ void VLSong::LilypondNotes(std::string & notes) const
 		while ((trip = notes.find("} ~ \\times 2/3 { ")) != std::string::npos)
 			notes.replace(trip, 17, "~ ", 2);
 
-		notes += '|';
+		if (fGoToCoda == measure+1)
+			notes += "\n"
+				+ indent 
+				+ "\\mark \\markup { \\musicglyph #\"scripts.coda\" } |";
+		else
+			notes += '|';
 		if (!(measure % 4)) {
 			char measNo[8];
 			sprintf(measNo, " %% %d", measure+1);
@@ -1672,6 +1707,12 @@ void VLSong::iterator::AdjustStatus()
 			return;
 		} 
 	}
+	if (fSong.fCoda > 0 && fMeasure==fSong.fGoToCoda)
+		if (fStatus.size() && fStatus.back().fVolta == fStatus.back().fTimes-1) {
+			fMeasure = fSong.fCoda;
+			
+			return;
+		}
 	if (fMeasure == fSong.CountMeasures())
 		while (fStatus.size())
 			if (++fStatus.back().fVolta < fStatus.back().fTimes) {
diff --git a/Sources/VLModel.h b/Sources/VLModel.h
index c11b7f9..a9833b1 100644
--- a/Sources/VLModel.h
+++ b/Sources/VLModel.h
@@ -268,6 +268,8 @@ struct VLSong {
 	std::vector<VLProperties>	fProperties;
 	std::vector<VLMeasure>		fMeasures;
 	std::vector<VLRepeat>		fRepeats;
+	int8_t						fGoToCoda;
+	int8_t						fCoda;
 
 	//
 	// Iterate over measures in performance order
@@ -324,6 +326,7 @@ struct VLSong {
 	bool DoesEndRepeat(size_t measure, int * times = 0) const;
 	bool DoesBeginEnding(size_t measure, bool * repeat = 0, size_t * volta = 0) const;
 	bool DoesEndEnding(size_t measure, bool * repeat = 0, size_t * volta = 0) const;
+	bool IsNonEmpty() const;
 	void Transpose(int semitones);
 
 	bool FindWord(size_t stanza, size_t & measure, VLFraction & at);