From: Han-Wen Nienhuys <hanwen@xs4all.nl>
Date: Wed, 19 Jul 2000 17:01:09 +0000 (+0200)
Subject: release: 1.3.74
X-Git-Tag: release/1.3.74
X-Git-Url: https://git.donarmstrong.com/?a=commitdiff_plain;h=9c8bcb9a2a1fedb5459e593b18a8c550318e6800;p=lilypond.git

release: 1.3.74

======
* Removed \interscoreline after the last line, prevents some
empty pages. (patch by Mats Bengtsson)

* Smobified Music, junked associated identifiers. Use Scheme list to
store Music_sequence.  Removed const declarations from
Music_iterators.  Added a mutable and immutable property list to
Music.  Use music property for all Scheme values in Music.  Created
and fixed a load of Garbage Collection bugs.

* Changed number font to allow automatic .mf creation.

* Output place of definition as \special{src:LOCATION}. See FAQ for
explanation how to use.

* Schemified Local_key_item and fixed minor bug with accidentals.

* new Japanese .po file.

* Bugfix for broken tie direction

* Bugfix for bar at beginning of line break

1.3
---

diff --git a/AUTHORS.txt b/AUTHORS.txt
index b0453ea529..7ec65fe642 100644
--- a/AUTHORS.txt
+++ b/AUTHORS.txt
@@ -60,8 +60,8 @@ list is alphabetically ordered.
 
    * Stephen Peters <portnoy@ai.mit.edu>,     pdfTeX support
 
-   * Glen Prideaux <glenprideaux@iname.com>,     minor bug fix to
-     script used to generate doc++ documentation
+   * Glen Prideaux <glenprideaux@iname.com>,     minor bug fixes,
+     lyric-phrasing.
 
    * Roy R. Rankin <Roy.Rankin@alcatel.com.au>,     major extension,
      fixes to abc2ly, lilypond bug fixes
diff --git a/CHANGES b/CHANGES
index d6504f1579..0e730c4cdf 100644
--- a/CHANGES
+++ b/CHANGES
@@ -1,4 +1,19 @@
+* Small bugfix: also do a deep copy on  submusices
 
+* Fixed:  \autochange doesn't crash anymore.
+
+* Cleanup, documentation and enforcement of smob interfaces in
+LilyPond.  We distinguish between SIMPLE_SMOBS and SMOBS (objects that
+have self_scm_)
+
+* Glen Prideaux lyric phrasing engraver. See
+input/test/lyric-phrasing.ly
+
+
+
+
+1.3.73
+======
 * Removed \interscoreline after the last line, prevents some
 empty pages. (patch by Mats Bengtsson)
 
diff --git a/Documentation/faq.texi b/Documentation/faq.texi
index ae735e482b..725efa3fa6 100644
--- a/Documentation/faq.texi
+++ b/Documentation/faq.texi
@@ -401,7 +401,8 @@ Upgrade/downgrade to 4.17.
 As of 1.3.73, lilypond provides support for the xdvi @code{src:}
 special. This can be used with Xdvik (22.16 or better) and xdvi (22.28
 or better) to go to the place in the input that corresponds to a symbol
-in the output.
+in the output: click on the note, and your editor jumps to the place
+where it was defined
 
 lilypond:
 
@@ -446,8 +447,14 @@ Xdvi
 
 @uref{Xdvi,ftp://ftp.math.berkeley.edu/pub/Software/TeX/xdvi.tar.gz} has
 better support for src specials. Apply @uref{this patch,
-http://www.cs.uu.nl/~hanwen/software/xdvi-src}. When viewing,
-control-mousebutton 1 will take you to the correct line/column. 
+http://www.cs.uu.nl/~hanwen/software/xdvi-src}. Before starting, set the
+environment variable @code{XEDITOR} to @code{"emacsclient --no-wait +%d
+%s"}.  When viewing, control-mousebutton 1 will take you to the correct
+line/column. Control-mousebutton 2 will show all clickable boxes.
+
+dvips:
+
+dvips will complain about the specials, but the complaints are harmless.
 
 
 @subsubsection I use dvilj4, and there are lots of warning messages for the printing
diff --git a/Documentation/topdocs/AUTHORS.texi b/Documentation/topdocs/AUTHORS.texi
index 9c0ce77848..8ef54580a1 100644
--- a/Documentation/topdocs/AUTHORS.texi
+++ b/Documentation/topdocs/AUTHORS.texi
@@ -63,7 +63,7 @@ list is alphabetically ordered.
 @item @email{portnoy@@ai.mit.edu,Stephen Peters},
     pdfTeX support
 @item @email{glenprideaux@@iname.com, Glen Prideaux},
-    minor bug fix to script used to generate doc++ documentation
+    minor bug fixes, lyric-phrasing.
 @item @email{Roy.Rankin@@alcatel.com.au, Roy R. Rankin},
     major extension, fixes to abc2ly, lilypond bug fixes
 @item @email{daboys@@austin.rr.com, Jeffrey B. Reed},
diff --git a/VERSION b/VERSION
index a0d0b48def..26c0f60758 100644
--- a/VERSION
+++ b/VERSION
@@ -1,7 +1,7 @@
 PACKAGE_NAME=LilyPond
 MAJOR_VERSION=1
 MINOR_VERSION=3
-PATCH_LEVEL=73
+PATCH_LEVEL=74
 MY_PATCH_LEVEL=
 
 # use the above to send patches: MY_PATCH_LEVEL is always empty for a
diff --git a/input/test/lyric-phrasing.ly b/input/test/lyric-phrasing.ly
new file mode 100644
index 0000000000..2edfa2dbeb
--- /dev/null
+++ b/input/test/lyric-phrasing.ly
@@ -0,0 +1,48 @@
+\header{
+filename =	 "twinkle-pop.ly";
+%title =	 "Ah, vous dirais-je, maman ";
+description =	 "twinkle twinkle in pop-song-settings";
+composer =	 "traditional";
+enteredby =	 "HWN, chords by Johan Vromans";
+copyright =	 "public domain";
+}
+
+\version "1.3.59";
+
+m =\notes  \relative c'' {
+	\property Staff.automaticMelismata = ##t
+	\autoBeamOff
+	g4  r8 \times 2/3 { g'8( f )e } r8 \grace { [d16 c b] } e4
+	\emptyText
+	d8.^"melisma" 	\melisma c16
+	\melismaEnd
+	b c d e }
+
+textI =  \lyrics  { la4 __ la -- la  I, la dargh la dargh.  }
+textII =  \lyrics  { dar -- dargh __ dargh dargh; dargh la dargh loo.  }
+textIII =  \lyrics  { la -- da __ doo dah; dargh la dargh loo.  }
+
+\score {
+
+    \notes < \context Staff = SA \context Voice = VA { s1 }
+      \context LyricVoice = "VA-1" { s1 }
+      \context LyricVoice = "VA-2" { s1 }
+      
+      \addlyrics
+	  \context Staff = SA \m
+	  < \context LyricVoice = "VA-1" \textI
+	    \context LyricVoice = "VA-2" \textII
+	    \context LyricVoice = "VA-3" \textIII
+	  >
+	  
+    >
+
+  \paper {
+    \translator {
+      \ScoreContext
+      \consists "Lyric_phrasing_engraver";
+      automaticPhrasing = ##t;
+    }
+  }
+
+}
\ No newline at end of file
diff --git a/input/trip.ly b/input/trip.ly
index 2e0f75403b..750a0f6eb7 100644
--- a/input/trip.ly
+++ b/input/trip.ly
@@ -11,7 +11,7 @@ basic faults in lily, this file will not run correctly.
 
 TODO:
 
-* repeats.
+* autochange.
 
 * tremolo
 
diff --git a/lily/afm.cc b/lily/afm.cc
index 9f1f8045f5..c86c1faafc 100644
--- a/lily/afm.cc
+++ b/lily/afm.cc
@@ -24,7 +24,16 @@ Adobe_font_metric::Adobe_font_metric (AFM_Font_info * fi)
       name_to_metric_dict_[c->name] = i;
     }
 }
-  
+
+
+SCM
+Adobe_font_metric::make_afm (AFM_Font_info *fi)
+{
+  Adobe_font_metric * fm = new Adobe_font_metric (fi);
+
+  return fm->smobbed_self();    
+}
+
 
 AFM_CharMetricInfo const *
 Adobe_font_metric::find_ascii_metric (int a , bool warn) const
@@ -74,7 +83,7 @@ Adobe_font_metric::get_char (int code, bool warn) const
     return Box (Interval (0,0),Interval(0,0));
 }
 
-Adobe_font_metric*
+SCM
 read_afm_file (String nm)
 {
   FILE *f = fopen (nm.ch_C() , "r");
@@ -89,7 +98,7 @@ read_afm_file (String nm)
     }
   fclose (f);
 
-  return new Adobe_font_metric (fi);
+  return Adobe_font_metric::make_afm (fi);
 }
 
   
diff --git a/lily/align-interface.cc b/lily/align-interface.cc
index 51ac50d509..4527bbf41b 100644
--- a/lily/align-interface.cc
+++ b/lily/align-interface.cc
@@ -138,7 +138,7 @@ Align_interface::get_count (Score_element*me,Score_element*s)
   int c =0;
   while (gh_pair_p (e))
     {
-      if (gh_car (e) == s->self_scm_)
+      if (gh_car (e) == s->self_scm ())
 	break;
       c++;
       e = gh_cdr (e);
diff --git a/lily/all-font-metrics.cc b/lily/all-font-metrics.cc
index 9cff0e2b28..10f0ef3476 100644
--- a/lily/all-font-metrics.cc
+++ b/lily/all-font-metrics.cc
@@ -14,7 +14,10 @@
 #include "afm.hh"
 #include "tfm.hh"
 #include "lily-guile.hh"
-#include "tfm-reader.hh"
+#include "scm-hash.hh"
+
+
+
 
 extern "C" {
 #include <kpathsea/kpathsea.h>
@@ -24,14 +27,25 @@ const char * default_font_sz_ = "cmr10";
 
 All_font_metrics::All_font_metrics (String path)
 {
+  afm_p_dict_ = new Scheme_hash_table;
+  tfm_p_dict_ = new Scheme_hash_table;
+  scaled_p_dict_ = new Scheme_hash_table;
+  
   search_path_.parse_path (path);
 }
 
+All_font_metrics::~All_font_metrics ()
+{
+  scm_unprotect_object (afm_p_dict_->self_scm ());
+  scm_unprotect_object (tfm_p_dict_->self_scm ());
+  scm_unprotect_object (scaled_p_dict_->self_scm ());
+}
+
 Adobe_font_metric *
 All_font_metrics::find_afm (String name)
 {
   SCM sname = ly_symbol2scm (name.ch_C ());
-  if (!afm_p_dict_.elem_b (sname))
+  if (!afm_p_dict_->elem_b (sname))
     {
       String path;
       if (path.empty_b ())
@@ -48,36 +62,35 @@ All_font_metrics::find_afm (String name)
       
       if (verbose_global_b)
 	progress_indication ("[" + path);
-      Adobe_font_metric * afm_p = read_afm_file (path);
+      SCM  afm = read_afm_file (path);
 
-      afm_p->name_ = ly_symbol2scm (name.ch_C ());
+      unsmob_metrics (afm)->name_ = sname;
 
       if (verbose_global_b)
 	progress_indication ("]");
 
-      afm_p_dict_.set (sname,afm_p->self_scm_);
+       afm_p_dict_->set (sname,afm);
     }
   
-  return dynamic_cast<Adobe_font_metric*> (unsmob_metrics (afm_p_dict_.get (sname)));
+  return dynamic_cast<Adobe_font_metric*> (unsmob_metrics (afm_p_dict_->get (sname)));
 }
 
 Scaled_font_metric * 
 All_font_metrics::find_scaled (String nm, int m)
 {
-  Scaled_font_metric * s=0;
   String index =  nm + "@" + to_str (m);
   SCM sname = ly_symbol2scm (index.ch_C ());
 
   Font_metric *fm =0;
-  if (!scaled_p_dict_.elem_b (sname))
+  if (!scaled_p_dict_->elem_b (sname))
     {
       Font_metric *f = find_font (nm);
-      s = new Scaled_font_metric (f, m);
-      scaled_p_dict_.set (sname, s->self_scm_);
-      fm =  s;
+      SCM s =  Scaled_font_metric::make_scaled_font_metric (f, m);
+      scaled_p_dict_->set (sname, s);
+      fm =  unsmob_metrics (s);
     }
   else
-    fm = unsmob_metrics (scaled_p_dict_.get (sname));
+    fm = unsmob_metrics (scaled_p_dict_->get (sname));
 
   return dynamic_cast<Scaled_font_metric*> (fm);
 }
@@ -86,7 +99,7 @@ Tex_font_metric *
 All_font_metrics::find_tfm (String name)
 {
   SCM sname = ly_symbol2scm (name.ch_C ());  
-  if (!tfm_p_dict_.elem_b (sname))
+  if (!tfm_p_dict_->elem_b (sname))
     {
       String path;
       
@@ -102,17 +115,17 @@ All_font_metrics::find_tfm (String name)
 
       if (verbose_global_b)
 	progress_indication ("[" + path);
-      Tex_font_metric	* tfm_p = Tex_font_metric_reader::read_file (path);
-      tfm_p->name_ = ly_symbol2scm (name.ch_C( ));
-
+      SCM tfm = Tex_font_metric::make_tfm (path);
       if (verbose_global_b)
 	progress_indication ("]");
 
-      tfm_p_dict_.set (sname, tfm_p->self_scm_);
+      Font_metric *fm = unsmob_metrics (tfm);
+      fm->name_ = sname;
+      tfm_p_dict_->set (sname, tfm);
     }
     
   return
-    dynamic_cast<Tex_font_metric*> (unsmob_metrics (tfm_p_dict_.get(sname)));
+    dynamic_cast<Tex_font_metric*> (unsmob_metrics (tfm_p_dict_->get(sname)));
 }
 
 
@@ -158,9 +171,9 @@ All_font_metrics::font_descriptions () const
 {
   SCM l[] = {0,0,0};
 
-  l[0] = afm_p_dict_.to_alist ();
-  l[1] = tfm_p_dict_.to_alist ();
-  l[2] = scaled_p_dict_.to_alist ();  
+  l[0] = afm_p_dict_->to_alist ();
+  l[1] = tfm_p_dict_->to_alist ();
+  l[2] = scaled_p_dict_->to_alist ();  
 
   SCM list = SCM_EOL;
   for (int i=0; i < 3; i++)
diff --git a/lily/auto-change-iterator.cc b/lily/auto-change-iterator.cc
index ef0edb3cbd..2c9de1f717 100644
--- a/lily/auto-change-iterator.cc
+++ b/lily/auto-change-iterator.cc
@@ -65,18 +65,20 @@ Auto_change_iterator::change_to (Music_iterator *it, String to_type,
     ; //    error (_ ("none of these in my family"));
 
 }
-
+Pitch_interrogate_req* spanish_inquisition; // nobody expects it
 void
 Auto_change_iterator::do_process_and_next (Moment m)
 {
   Music_wrapper_iterator::do_process_and_next (m);
-  Pitch_interrogate_req spanish_inquisition; // nobody expects it
 
-  Music_iterator *it = try_music (&spanish_inquisition);
+  if (!spanish_inquisition)
+    spanish_inquisition = new Pitch_interrogate_req;
+
+  Music_iterator *it = try_music (spanish_inquisition);
 
-  if (it && spanish_inquisition.pitch_arr_.size ())
+  if (it && spanish_inquisition->pitch_arr_.size ())
     {
-      Musical_pitch p = spanish_inquisition.pitch_arr_[0];
+      Musical_pitch p = spanish_inquisition->pitch_arr_[0];
       Direction s = Direction (sign(p.steps ()));
       if (s != where_dir_)
 	{
@@ -87,6 +89,8 @@ Auto_change_iterator::do_process_and_next (Moment m)
 	  change_to (it, auto_mus->what_str_, to_id);	  
 	}
     }
+
+  spanish_inquisition->pitch_arr_.clear ();
 }
 
 Auto_change_iterator::Auto_change_iterator( )
diff --git a/lily/bar-number-engraver.cc b/lily/bar-number-engraver.cc
index facf059ace..34a0cb2eae 100644
--- a/lily/bar-number-engraver.cc
+++ b/lily/bar-number-engraver.cc
@@ -70,7 +70,7 @@ Bar_number_engraver::acknowledge_element (Score_element_info inf)
   Score_element * s = inf.elem_l_;
   if (Staff_symbol::has_interface (s))
     {
-      staffs_ = gh_cons (inf.elem_l_->self_scm_, staffs_);
+      staffs_ = gh_cons (inf.elem_l_->self_scm (), staffs_);
     }
   else if (text_p_
 	   && dynamic_cast<Item*> (s)
diff --git a/lily/bar.cc b/lily/bar.cc
index bb91147180..cb956edf23 100644
--- a/lily/bar.cc
+++ b/lily/bar.cc
@@ -32,7 +32,7 @@ Bar::brew_molecule (SCM smob)
   if (gh_string_p (s) && gh_procedure_p (barsiz_proc))
     {
       String str  =ly_scm2string (s);
-      SCM siz = gh_call1 (barsiz_proc, me->self_scm_);
+      SCM siz = gh_call1 (barsiz_proc, me->self_scm ());
       return compound_barline (me, str, gh_scm2double (siz)).create_scheme ();
     }
   return SCM_EOL;
diff --git a/lily/beam.cc b/lily/beam.cc
index 1356abe333..25fe6e9019 100644
--- a/lily/beam.cc
+++ b/lily/beam.cc
@@ -45,7 +45,7 @@ Beam::add_stem (Score_element*me, Score_element*s)
   s->add_dependency (me);
 
   assert (!Stem::beam_l (s));
-  s->set_elt_property ("beam", me->self_scm_);
+  s->set_elt_property ("beam", me->self_scm ());
 
   add_bound_item (dynamic_cast<Spanner*> (me), dynamic_cast<Item*> (s));
 }
diff --git a/lily/break-align-engraver.cc b/lily/break-align-engraver.cc
index 3ca38f7db7..b48f31b25a 100644
--- a/lily/break-align-engraver.cc
+++ b/lily/break-align-engraver.cc
@@ -111,10 +111,10 @@ Break_align_engraver::acknowledge_element (Score_element_info inf)
 	  */
 	  edge->set_extent_callback (Score_element::point_dimension_callback,X_AXIS);
 	  
-	  align_l_->set_elt_property ("group-center-element", edge->self_scm_);
+	  align_l_->set_elt_property ("group-center-element", edge->self_scm ());
 
 	  announce_element (edge, 0);
-	  column_alist_ = scm_assoc_set_x (column_alist_, edge_sym, edge->self_scm_);
+	  column_alist_ = scm_assoc_set_x (column_alist_, edge_sym, edge->self_scm ());
 	}
 
       SCM s = scm_assoc (align_name, column_alist_);
@@ -136,7 +136,7 @@ Break_align_engraver::acknowledge_element (Score_element_info inf)
 	  group->set_elt_property ("break-align-symbol", align_name);
 	  group->set_parent (align_l_, Y_AXIS);
 	  announce_element (group, 0);
-	  column_alist_ = scm_assoc_set_x (column_alist_, align_name, group->self_scm_);
+	  column_alist_ = scm_assoc_set_x (column_alist_, align_name, group->self_scm ());
 	}
       Axis_group_interface::add_element (group, item_l);
     }
diff --git a/lily/collision.cc b/lily/collision.cc
index 8d1f6d1232..c0bec3356d 100644
--- a/lily/collision.cc
+++ b/lily/collision.cc
@@ -32,7 +32,7 @@ Collision::force_shift_callback (Score_element * c, Axis a)
    */
   if (!unsmob_element (me->get_elt_property ("done")))
     {
-      me->set_elt_property ("done", me->self_scm_);
+      me->set_elt_property ("done", me->self_scm ());
       do_shifts (me);
     }
   
@@ -195,7 +195,7 @@ Collision::automatic_shift (Score_element *me)
   do
     {
       for (int i=0; i < clash_groups[d].size (); i++)
-	tups = gh_cons (gh_cons (clash_groups[d][i]->self_scm_, gh_double2scm (offsets[d][i])),
+	tups = gh_cons (gh_cons (clash_groups[d][i]->self_scm (), gh_double2scm (offsets[d][i])),
 				 tups);
     }
   while (flip (&d) != UP);
@@ -216,7 +216,7 @@ Collision::forced_shift (Score_element *me)
       SCM force =  se->remove_elt_property ("force-hshift");
       if (gh_number_p (force))
 	{
-	  tups = gh_cons (gh_cons (se->self_scm_, force),
+	  tups = gh_cons (gh_cons (se->self_scm (), force),
 			  tups);
 	}
     }
diff --git a/lily/dynamic-engraver.cc b/lily/dynamic-engraver.cc
index c57c533265..cfd5eae9a2 100644
--- a/lily/dynamic-engraver.cc
+++ b/lily/dynamic-engraver.cc
@@ -256,10 +256,10 @@ Dynamic_engraver::do_process_music ()
 	  if (text_p_)
 	    {
 	      index_set_cell (cresc_p_->get_elt_property ("dynamic-drul"),
-			      LEFT, text_p_->self_scm_);
+			      LEFT, text_p_->self_scm ());
 	      if (finished_cresc_p_)
 		index_set_cell (finished_cresc_p_->get_elt_property ("dynamic-drul"),
-				RIGHT, text_p_->self_scm_);
+				RIGHT, text_p_->self_scm ());
 	    }
 
 	  Axis_group_interface::add_element (line_spanner_, cresc_p_);
diff --git a/lily/font-metric.cc b/lily/font-metric.cc
index 4443aa6399..467f0f84cf 100644
--- a/lily/font-metric.cc
+++ b/lily/font-metric.cc
@@ -67,14 +67,11 @@ Scaled_font_metric::text_dimension (String t) const
 
 Font_metric::~Font_metric ()
 {
-  unsmobify_self ();
 }
 
 Font_metric::Font_metric ()
 {
-  self_scm_ = SCM_EOL;
   name_ = SCM_EOL;
-  smobify_self ();
 }
 
 Font_metric::Font_metric (Font_metric const &)
@@ -94,6 +91,15 @@ Scaled_font_metric::Scaled_font_metric (Font_metric* m, int s)
   orig_l_ = m;
 }
 
+SCM
+Scaled_font_metric::make_scaled_font_metric (Font_metric*m, int s)
+{
+  Scaled_font_metric *sfm = new Scaled_font_metric (m,s);
+  sfm->name_ = m->name_;
+  
+  return sfm->smobbed_self ();
+}
+
 SCM
 Font_metric::description () const
 {
@@ -110,15 +116,11 @@ Scaled_font_metric::description () const
 }
 
 
-void
-Font_metric::do_smobify_self ()
-{
-}
 
 SCM
 Font_metric::mark_smob (SCM s)
 {
-  Font_metric * m = SMOB_TO_TYPE(Font_metric, s);
+  Font_metric * m = (Font_metric*) SCM_CELL_WORD_1(s);
   return m->name_;
 }
 
@@ -134,5 +136,5 @@ Font_metric::print_smob (SCM s, SCM port, scm_print_state * )
 
 
 IMPLEMENT_UNSMOB (Font_metric, metrics);
-IMPLEMENT_SMOBS (Font_metric);
-
+IMPLEMENT_SIMPLE_SMOBS (Font_metric);
+IMPLEMENT_DEFAULT_EQUAL_P(Font_metric);
diff --git a/lily/grace-position-performer.cc b/lily/grace-position-performer.cc
index c1c4ae8896..0259587934 100644
--- a/lily/grace-position-performer.cc
+++ b/lily/grace-position-performer.cc
@@ -62,8 +62,8 @@ Grace_position_performer::process_acknowledged ()
 	  
 	  Rational grace_fraction_rat (1, 2);
 	  SCM prop = get_property ("graceFraction");
-	  if (SMOB_IS_TYPE_B(Moment, prop))
-	    grace_fraction_rat = *SMOB_TO_TYPE (Moment,prop);
+	  if (unsmob_moment (prop))
+	    grace_fraction_rat = *unsmob_moment (prop);
 
 	  delay_mom = shortest_mom * grace_fraction_rat;
 	  for (int i=0; i < notes_.size (); i++)
diff --git a/lily/identifier.cc b/lily/identifier.cc
index 41b5e049f9..d3d0e7221b 100644
--- a/lily/identifier.cc
+++ b/lily/identifier.cc
@@ -22,18 +22,19 @@
 
 IMPLEMENT_UNSMOB(Identifier, identifier);
 IMPLEMENT_SMOBS(Identifier);
+IMPLEMENT_DEFAULT_EQUAL_P(Identifier);
 
 Identifier::Identifier (int code)
 {
-  self_scm_ = SCM_EOL;
   token_code_i_ = code;
   accessed_b_ = 0;
+  smobify_self ();
 }
 
 Identifier::Identifier (Identifier const&s)
   : Input (s)
 {
-  self_scm_ = SCM_EOL;
+  smobify_self ();  
   token_code_i_ = s.token_code_i_;
   accessed_b_ = s.accessed_b_;
 }
@@ -173,8 +174,3 @@ Identifier::mark_smob (SCM s)
 
 
 
-void
-Identifier::do_smobify_self ()
-{
-  
-}
diff --git a/lily/include/afm.hh b/lily/include/afm.hh
index a0dfa15f42..d761dc093c 100644
--- a/lily/include/afm.hh
+++ b/lily/include/afm.hh
@@ -18,22 +18,27 @@
 #include "font-metric.hh"
 #include "parse-afm.hh"
 
-struct Adobe_font_metric : Font_metric {
+struct Adobe_font_metric : Font_metric
+{
   AFM_Font_info * font_inf_;
 
-  Array<int> ascii_to_metric_idx_;
-  Dictionary<int> name_to_metric_dict_;
-
   Box get_char (int, bool) const;
   AFM_CharMetricInfo const *find_char_metric (String name, bool warn=true) const;
   AFM_CharMetricInfo const *find_ascii_metric (int, bool warn=true) const;  
 
   String str () const;
-  Adobe_font_metric (AFM_Font_info*);
   ~Adobe_font_metric ();
+  static SCM make_afm (AFM_Font_info*);
+
+protected:
+  Array<int> ascii_to_metric_idx_;
+  Dictionary<int> name_to_metric_dict_;
+
+  Adobe_font_metric (AFM_Font_info*);
+
 };
 
-Adobe_font_metric * read_afm_file (String fn);
+SCM read_afm_file (String fn);
 Box afm_bbox_to_box (AFM_BBox bb);
   
 
diff --git a/lily/include/all-font-metrics.hh b/lily/include/all-font-metrics.hh
index b01ad19119..f705080d32 100644
--- a/lily/include/all-font-metrics.hh
+++ b/lily/include/all-font-metrics.hh
@@ -10,24 +10,22 @@
 #ifndef ALL_FONTS_HH
 #define ALL_FONTS_HH
 
-
 #include "file-path.hh"
 #include "lily-proto.hh"
 #include "font-metric.hh"
-#include "scm-hash.hh"
 
 /**
    Interface to all .afm files living in the filesystem.
  */
 class All_font_metrics
 {
-  Scheme_hash_table afm_p_dict_;
-  Scheme_hash_table tfm_p_dict_;
-  Scheme_hash_table scaled_p_dict_;
+  Scheme_hash_table *afm_p_dict_;
+  Scheme_hash_table *tfm_p_dict_;
+  Scheme_hash_table *scaled_p_dict_;
   
   File_path search_path_;
 public:
-  
+  ~All_font_metrics ();  
   Adobe_font_metric *find_afm (String name);
   Tex_font_metric *find_tfm (String);
   Font_metric *find_font (String name);  
diff --git a/lily/include/font-metric.hh b/lily/include/font-metric.hh
index 9db37fda4e..843fab6ffe 100644
--- a/lily/include/font-metric.hh
+++ b/lily/include/font-metric.hh
@@ -17,31 +17,34 @@
 
 struct Font_metric
 {
-  Font_metric ();
   SCM name_;
   virtual SCM description () const;
   virtual Box get_char (int ascii, bool warn) const;
   virtual ~Font_metric ();
   virtual Box text_dimension (String) const;
 
-  DECLARE_SMOBS;
+  DECLARE_SIMPLE_SMOBS(Font_metric,);
 private:
   Font_metric (Font_metric const&); // no copy.
+protected:
+  Font_metric ();
 };
 
 
 struct Scaled_font_metric : public Font_metric
 {
+  virtual SCM description () const;
+  virtual Box text_dimension (String) const;
+
+  static SCM make_scaled_font_metric (Font_metric*, int);
+protected:
   Font_metric *orig_l_;
   int magstep_i_;
   
-  Scaled_font_metric (Font_metric*, int);
-  virtual SCM description () const;
-  virtual Box text_dimension (String) const;
+  Scaled_font_metric (Font_metric*,int);
 };
 
 Font_metric * unsmob_metrics (SCM s);
 
-
 #endif /* FONT_METRIC_HH */
 
diff --git a/lily/include/identifier.hh b/lily/include/identifier.hh
index 750c49089a..02587ce978 100644
--- a/lily/include/identifier.hh
+++ b/lily/include/identifier.hh
@@ -33,14 +33,11 @@ virtual Class *  access_content_ ## Class (bool) const { error (#Class  + String
    */
 struct Identifier : public Input {
 
-  DECLARE_SMOBS;
   bool init_b_;
   bool accessed_b_;
   int token_code_i_;
   Identifier (Identifier const&);    
   Identifier (int code) ;
-  virtual ~Identifier() ;
-  
 
   void print() const;
   
@@ -52,6 +49,7 @@ struct Identifier : public Input {
   IDACCESSOR(Duration)
   VIRTUAL_COPY_CONS(Identifier);
 
+  DECLARE_SMOBS(Identifier, foo);
 protected:
   virtual void do_print () const;
   virtual String do_str () const;
diff --git a/lily/include/lily-proto.hh b/lily/include/lily-proto.hh
index b63843e6d1..d0de6ff36b 100644
--- a/lily/include/lily-proto.hh
+++ b/lily/include/lily-proto.hh
@@ -84,6 +84,7 @@ class Lyric_combine_music;
 class Lyric_combine_music_iterator;
 class Lyric_engraver;
 class Lyric_performer;
+class Lyric_phrasing_engraver;
 class Lyric_req;
 class Mark_req;
 class Melisma_playing_req;
diff --git a/lily/include/lookup.hh b/lily/include/lookup.hh
index d0f5e33f2c..88f48b2603 100644
--- a/lily/include/lookup.hh
+++ b/lily/include/lookup.hh
@@ -24,15 +24,11 @@
  */
 class Lookup
 {
-
-
   Lookup ();
   Lookup (Lookup const&);
-
-  friend class Brutus;		// kai su, teknon. (make GCC shut up.)
-  
+  DECLARE_SIMPLE_SMOBS(Lookup,);  
 public:
-  DECLARE_SMOBS;
+
   static SCM make_lookup ();
   String font_name_;
   Adobe_font_metric * afm_l_;
diff --git a/lily/include/ly-smobs.icc b/lily/include/ly-smobs.icc
index 8a8648e6a5..b17bd314f1 100644
--- a/lily/include/ly-smobs.icc
+++ b/lily/include/ly-smobs.icc
@@ -17,83 +17,83 @@
 CL *						\
 unsmob_ ## name ( SCM s)			\
 {						\
-  if (SMOB_IS_TYPE_B(CL, s))			\
-    return SMOB_TO_TYPE(CL, s);			\
-  else						\
-    return 0;					\
-}\
-SCM smobify (CL *cl)\
-{\
-  SCM s;								\
-									\
-  SCM_NEWCELL(s);							\
-  SCM_SETCAR(s,CL::smob_tag_);						\
-  SCM me_s = SCM_PACK(cl);							\
-  SCM_SETCDR (s, me_s); \
-return s;\
-}\
+return  CL::unsmob (s);				\
+}
 
 
-/*
-  should include equal_p ? 
- */
-#define IMPLEMENT_SMOBS(CL)\
-long CL::smob_tag_;\
-void									\
-CL::init_smobs ()							\
-{									\
-  smob_tag_ = scm_make_smob_type_mfpe ( \
-     #CL, 0, CL::mark_smob, CL::free_smob, CL::print_smob, 0);\
-}\
-									\
-									 \
-void									 \
-CL::unsmobify_self ()							 \
-{									 \
-  SCM s = self_scm_;							 \
-  scm_unprotect_object (s);						 \
-  									 \
-  SCM_SETCAR (self_scm_, SCM_EOL); \
-  SCM_SETCDR (self_scm_, SCM_EOL); \
-  self_scm_ = SCM_EOL;							 \
-\
-  scm_done_malloc ( - sizeof (CL));\
-}									 \
-\
-SCM									\
-CL::smobify_self ()							\
-{									\
-  if (self_scm_ != SCM_EOL)						\
-    return self_scm_;							\
-									\
-  /*									\
-    This is local. We don't assign to self_scm_ directly, to assure	\
-    that S isn't GC-ed from under us.					\
-   */									\
-  SCM s = smobify (this); \
-  self_scm_ = s;							\
-  scm_protect_object (s);						\
-									\
-  scm_done_malloc(sizeof(CL));\
-  do_smobify_self();							\
-  return s;					\
-}						\
-scm_sizet					\
-CL::free_smob (SCM ses)				\
+#ifndef SCM_CELL_TYPE
+#define SCM_CELL_TYPE(X) SCM_CAR(X)
+#endif
+
+#ifndef SCM_CELL_WORD_1
+#define SCM_CELL_WORD_1(X) SCM_CDR(X)
+#endif
+
+
+#define IMPLEMENT_SIMPLE_SMOBS(CL)				\
+long CL::smob_tag_;						\
+void								\
+CL::init_smobs ()						\
+{								\
+  smob_tag_ = scm_make_smob_type_mfpe (				\
+     #CL, 0, CL::mark_smob, CL::free_smob, CL::print_smob, 0);	\
+}								\
+SCM CL::smobbed_self () const					\
+{								\
+  SCM s;							\
+  s = gh_cons (SCM_PACK(CL::smob_tag_), SCM_PACK(this));	\
+  scm_done_malloc(sizeof(CL));					\
+								\
+  return s;							\
+}								\
+CL *								\
+CL::unsmob (SCM s)						\
+{								\
+  if (SCM_NIMP(s) && SCM_CELL_TYPE(s) == smob_tag_)		\
+    return (CL*) SCM_CELL_WORD_1(s);				\
+  else								\
+    return 0;							\
+}								\
+scm_sizet							\
+CL::free_smob (SCM ses)						\
+{								\
+  CL * s = (CL*) SCM_CDR(ses);					\
+   delete s;							\
+  return sizeof (CL);						\
+}								\
+ADD_SCM_INIT_FUNC(CL, CL::init_smobs)
+
+#define IMPLEMENT_SMOBS(CL)							\
+IMPLEMENT_SIMPLE_SMOBS(CL)							\
+SCM										\
+CL::smobify_self ()								\
+{										\
+  /*										\
+    This is local. We don't assign to self_scm_ directly, to assure		\
+    that S isn't GC-ed from under us.						\
+										\
+    We don't use smobbed_self () to ensure that mark_smob () doesn't have to	\
+    deal half-initialized objects: scm_done_malloc( ) might trigger GC.		\
+    the warning in smobs.hh is just to be doubleplus goodly sure		\
+   */										\
+  SCM s;										\
+  SCM_NEWCELL(s);								\
+  SCM_SETCAR(s,CL::smob_tag_);							\
+  SCM_SETCDR (s, SCM_PACK(this));						\
+  self_scm_ = s;								\
+ scm_done_malloc(sizeof(CL));							\
+  scm_protect_object (s);							\
+  return s;									\
+}
+
+#define IMPLEMENT_DEFAULT_EQUAL_P(CL)		\
+SCM						\
+CL::equal_p (SCM a , SCM b)			\
 {						\
-  CL * s = (CL*) SCM_CDR(ses);			\
-  /* someone else did the deed already; this might be an automatic var.*/ \
-  if (s->self_scm_ != ses)\
-     return 0; \
-\
- /* no need to call scm_unprotect_object, since this call \
-    implies that the object is not protected. */ \
-  SCM_SETCAR (ses, SCM_EOL); \
-  delete s;\
-  return sizeof (CL);\
-} \
-ADD_SCM_INIT_FUNC(CL, CL::init_smobs)\
+  return a == b ? SCM_BOOL_T : SCM_BOOL_F;	\
+}
 
 
 #endif /* LY_SMOBS_ICC */
 
+
diff --git a/lily/include/moment.hh b/lily/include/moment.hh
index 53afd01816..0bd535a6d5 100644
--- a/lily/include/moment.hh
+++ b/lily/include/moment.hh
@@ -17,18 +17,22 @@
    Rationals with glue for Guilification;
 
    FIXME: remove self_scm_ and then remove this class */
-struct Moment : public Rational
+class Moment : public Rational
 {
-  Moment () { self_scm_ = SCM_EOL; }
-  Moment (int m) : Rational (m) {self_scm_ = SCM_EOL; }
-  Moment (int m, int n) : Rational (m,n) {self_scm_ = SCM_EOL; }
-  Moment (Rational m) : Rational (m) {self_scm_ = SCM_EOL; }
-  ~Moment ();
-  
-  DECLARE_SMOBS;
+  DECLARE_SIMPLE_SMOBS(Moment,);
+public:
+  Moment () { }
+  Moment (int m) : Rational (m) { }
+  Moment (int m, int n) : Rational (m,n) { }
+  Moment (Rational m) : Rational (m) { }
+
+  /*
+    Deliver a copy of THIS as a smobified SCM
+   */
+  SCM make_scm () const; 
 };
 
-SCM smobify (Moment*);
+
 Moment * unsmob_moment (SCM);
 
 IMPLEMENT_ARITHMETIC_OPERATOR (Moment, / );
diff --git a/lily/include/music.hh b/lily/include/music.hh
index 2eee399d18..fc3d8ae05c 100644
--- a/lily/include/music.hh
+++ b/lily/include/music.hh
@@ -30,10 +30,6 @@
   */
 class Music {
 public:
-  DECLARE_SMOBS;
-  SCM immutable_property_alist_;
-  SCM mutable_property_alist_;
- 
   Input *origin () const; 
   void set_spot (Input);  
   
@@ -46,13 +42,11 @@ public:
   void set_mus_pointer (const char*, SCM val);
   SCM remove_mus_property (const char* nm);
 
-  virtual SCM do_derived_mark ();
   virtual Musical_pitch to_relative_octave (Musical_pitch);
 
   /// The duration of this piece of music
   virtual Moment length_mom () const;
 
-  virtual ~Music();
   void print() const;
   /// Transpose, with the interval central C to #p#
   virtual void transpose (Musical_pitch p);
@@ -64,6 +58,10 @@ public:
   Music();
 protected:
   virtual void do_print() const;
+  DECLARE_SMOBS(Music,);
+  SCM immutable_property_alist_;
+  SCM mutable_property_alist_;
+ 
 };
 
 
diff --git a/lily/include/paper-def.hh b/lily/include/paper-def.hh
index 8d4c326c75..94bf6dd94f 100644
--- a/lily/include/paper-def.hh
+++ b/lily/include/paper-def.hh
@@ -62,7 +62,7 @@ public:
   SCM get_scmvar (String id)const; 
   void reinit ();
   Paper_def ();
-  void set_lookup (int, Lookup*);
+  void set_lookup (int, SCM lookup_smob);
   Paper_def (Paper_def const&);
 
   /** The distance between beams of multiplicity_i
diff --git a/lily/include/request.hh b/lily/include/request.hh
index 0b8ec16d6a..35401d75d7 100644
--- a/lily/include/request.hh
+++ b/lily/include/request.hh
@@ -26,7 +26,6 @@
  */
 class Request : public Music {
 public:
-  virtual ~Request(){}
   VIRTUAL_COPY_CONS(Music);
   bool equal_b (Request const*) const;
 protected:
diff --git a/lily/include/scm-hash.hh b/lily/include/scm-hash.hh
index 7a903469c1..ae733e9df8 100644
--- a/lily/include/scm-hash.hh
+++ b/lily/include/scm-hash.hh
@@ -30,7 +30,7 @@ typedef map<SCM,SCM, SCM_less> Scm_stl_map;
 /**
    auto resizing hash table. This should come from GUILE.
 
-   ALWAYS USE THIS AS VIA A POINTER, i.e.
+   1. ALWAYS USE THIS AS VIA A POINTER, i.e.
 
    class Foo {
     Scheme_hash_table * tab;
@@ -41,6 +41,12 @@ typedef map<SCM,SCM, SCM_less> Scm_stl_map;
    class Foo {
     Scheme_hash_table tab;
    }
+
+
+   2. UPON DESTRUCTION, DO
+
+   scm_unprotect_object (tab->self_scm_);
+   
  */
 class Scheme_hash_table :  private Scm_stl_map
 {
@@ -57,9 +63,10 @@ public:
   Scheme_hash_table ();
   void operator = (Scheme_hash_table const &); 
   Scheme_hash_table (Scheme_hash_table const &);
-  virtual ~Scheme_hash_table ();
-  DECLARE_SMOBS;
+
   SCM to_alist () const;
+  DECLARE_SMOBS(Scheme_hash_table,foo);
+
 };
 
 #endif /* SCM_HASH_HH */
diff --git a/lily/include/score-element.hh b/lily/include/score-element.hh
index 7ce14c8cc1..85ff5e8774 100644
--- a/lily/include/score-element.hh
+++ b/lily/include/score-element.hh
@@ -141,11 +141,6 @@ public:
   static Interval molecule_extent (Score_element *,Axis);
 
 protected:
-  /**
-    Junk score element. This is protected because this is supposed to
-    be handled by GUILE gc.  */
-  virtual ~Score_element ();
-  
   ///executed directly after the item is added to the Paper_score
   virtual void do_add_processing ();
   static Interval dim_cache_callback (Dimension_cache const*);
@@ -163,7 +158,7 @@ public:
   virtual void handle_prebroken_dependencies ();
 
 
-  DECLARE_SMOBS;
+  DECLARE_SMOBS(Score_element,foo);
 
   void init ();
 
diff --git a/lily/include/smobs.hh b/lily/include/smobs.hh
index dff21977b1..edd1f2e60c 100644
--- a/lily/include/smobs.hh
+++ b/lily/include/smobs.hh
@@ -12,48 +12,120 @@
 
 #include "lily-guile.hh"
 
-/**
-   A smob is a C++ class with static member functions to glue it with
-   Scheme. Every instance carries SELF_SCM_, a pointer to the Scheme
-   smob of itself.  Upon destruction, SELF_SCM_ is set to SCM_EOL.
 
-   smob_free() checks if SELF_SCM_ equals its argument, so we can also
-   use a smobbified object on the stack: the destruction will happen
-   before GC hits the object.
+/*
 
-   This is discouraged, though, because it causes memory leaks, and has
-   weird semantics.
+   Each smobbed C-object may only be interfaced by a single, unique
+   smob cell. Therefore NEVER provide a public function that will
+   create a smobcell for an existing object pointer.
+
+   There are two ways to reach this goal:
+
+   simple smobs:
+
+   - Data structures that are encapsulated by GUILE. If constructed
+   through GUILE, you may only store them as protected SCMs, and may
+   not copy the pointer the object itself. Typical interface
+
+   struct Ssmob {
+   public:
+     SCM make_copy_scm () const {
+       Ssmob *sp = new Ssmob (*this);
+       return sp->smobbed_self ();
+     }
+   };
+
+   or
+
+   struct Ssmob {
+   public:
+     DECLARE_SIMPLE_SMOBS;
+     static SCM make_scm (void initdata) {
+       Ssmob * sp = new Ssmob (initdata);
+       return sp->smobbed_self();
+     }
+   private:
+     Ssmob (initdata);
+   }
+
+   Objets of type Ssmob may live on the stack, or on the heap, or as
+   part of other objects.  However, as soon as the object is smobbed,
+   by definition (by definition of the constructors, in this example),
+   lives on the heap as a separate object
    
+   - complex smobs: data structures whose identity is referenced and
+   stored both in C++ and in GUILE form. From going from C++ to GUILE,
+   you use smob_ptr->self_scm_
+
+   class Csmob {
+     DECLARE_SMOBS;
+     Csmob () { smobify_self(); }
+     Csmob (Csmob const & s) {
+       // don't copy self_scm_
+       smobify_self ();
+     }
+   };
+   
+   A complex smob is a C++ class with static member functions to glue
+   it with Scheme. Every instance carries SELF_SCM_, a pointer to the
+   unique Scheme smob cell of itself.
+
+   Upon creation, SELF_SCM_ is protected, so if you choose to store it
+   in C++ structures, you need to do
+
+   class Bla {
+   Csmob *ptr;
+   ~Bla () {  scm_unprotect_object (ptr->self_scm_); }
+   
+   };
+
+   If protection is done via GUILE, don't forget to unprotect AFTER putting
+   stuff into the GUILE datastructs
 
+
+   guile_data = gh_cons (ptr->self_scm_, guile_data);
+   ptr->self_scm_
+
+   Since GUILE takes care of the freeing the object, the destructor
+   is private.
+
+   DUMMY a thing to make sure compiles only work if this header
+   if this file is there.
+
+
+   WARNING:
+
+   smobify_self() might trigger a GC, so make sure that objects are  
+   sane when you do smobify_self().
 */
 
-#define DECLARE_SMOBS					\
-	SCM smobify_self ();					\
+#define DECLARE_SIMPLE_SMOBS(CL,dummy) \
+protected: \
+	friend class Non_existant_class ; \
+	SCM smobbed_self () const; \
+private:\
+	static long smob_tag_;					\
 	static SCM mark_smob (SCM);				\
 	static scm_sizet free_smob (SCM s);			\
 	static int print_smob (SCM s, SCM p, scm_print_state*);	\
-	static long smob_tag_;					\
+public: \
 	static SCM equal_p (SCM a, SCM b);\
+	static CL * unsmob (SCM);\
 	static void init_smobs();				\
-	void unsmobify_self ();\
-        void do_smobify_self();\
-	SCM self_scm_;
+private:
 
 
-#ifndef SCM_CELL_TYPE
-#define SCM_CELL_TYPE(X) SCM_CAR(X)
-#endif
-
-#ifndef SCM_CELL_WORD_1
-#define SCM_CELL_WORD_1(X) SCM_CDR(X)
-#endif	
+#define DECLARE_SMOBS(CL,dummy)					\
+	DECLARE_SIMPLE_SMOBS(CL,dammy) \
+protected:\
+	virtual ~CL();\
+private: \
+	SCM smobify_self ();					\
+	SCM self_scm_; \
+public: \
+	SCM self_scm () const { return self_scm_; } \
+private:
 
-/**
-   Check if S is of the specified C++ class.
- */
-#define SMOB_IS_TYPE_B(TYPE, S)  (SCM_NIMP(S) && SCM_CELL_TYPE(S) == TYPE::smob_tag_)
 
-/// Cast S.  No checks are done.
-#define SMOB_TO_TYPE(TYPE, S)  ((TYPE*) SCM_CELL_WORD_1(S))
 #endif /* SMOBS_HH */
 
diff --git a/lily/include/tfm-reader.hh b/lily/include/tfm-reader.hh
index 569a2d0614..53cb6d45ed 100644
--- a/lily/include/tfm-reader.hh
+++ b/lily/include/tfm-reader.hh
@@ -18,12 +18,7 @@
 
 class Tex_font_metric_reader
 {
-public:
-  static Tex_font_metric * read_file (String name);
-  
 private:
-  Tex_font_metric_reader (Tex_font_metric *, String name);
-
   Real get_U32_fix_f ();
   Real get_U32_fix_scaled_f ();
   String get_bcpl_str ();
@@ -34,8 +29,17 @@ private:
   Tex_font_char_metric read_char ();
   void read_lig_kern_program (Array<Tfm_ligature>* ligature_arr_p, Array <Tfm_kern>* kern_arr_p);
 
-  Tex_font_metric *tfm_l_;
+
   Binary_source_file input_;
+
+public:
+  Tex_font_metric_reader ( String name);
+
+  
+  Tfm_info info_;
+  Tfm_header header_;
+  Array<Tex_font_char_metric> char_metrics_;
+  Array<int> ascii_to_metric_idx_;
 };
 
 
diff --git a/lily/include/tfm.hh b/lily/include/tfm.hh
index 0481ad1b7e..098fbe3e91 100644
--- a/lily/include/tfm.hh
+++ b/lily/include/tfm.hh
@@ -148,14 +148,16 @@ struct Tex_font_char_metric
 class Tex_font_metric : public Font_metric
 {
 public:
-  Tex_font_metric ();
+  static  SCM make_tfm (String filename);
 
-  void clear (int n);
   Box get_char (int, bool) const;
   Tex_font_char_metric const *find_ascii (int ascii, bool warn=true) const;
 
   String str () const;
 
+private:
+  Tex_font_metric ();
+  
   Tfm_info info_;
   Tfm_header header_;
   Array<Tex_font_char_metric> char_metrics_;
diff --git a/lily/item.cc b/lily/item.cc
index d9531c6dfb..eac4533b4c 100644
--- a/lily/item.cc
+++ b/lily/item.cc
@@ -180,8 +180,8 @@ SCM
 Item::do_derived_mark ()
 {
   if (broken_to_drul_[LEFT])
-    scm_gc_mark (broken_to_drul_[LEFT]->self_scm_);
+    scm_gc_mark (broken_to_drul_[LEFT]->self_scm ());
   if (broken_to_drul_[RIGHT])
-    scm_gc_mark (broken_to_drul_[RIGHT]->self_scm_);
+    scm_gc_mark (broken_to_drul_[RIGHT]->self_scm ());
   return SCM_EOL;
 }
diff --git a/lily/line-of-score.cc b/lily/line-of-score.cc
index 3d104e9377..9af28cc404 100644
--- a/lily/line-of-score.cc
+++ b/lily/line-of-score.cc
@@ -52,7 +52,7 @@ Line_of_score::typeset_element (Score_element * elem_p)
 {
   elem_p->pscore_l_ = pscore_l_;
   Pointer_group_interface (this, "all-elements").add_element (elem_p);
-  scm_unprotect_object (elem_p->self_scm_);
+  scm_unprotect_object (elem_p->self_scm ());
 }
 
 void
@@ -235,7 +235,7 @@ Line_of_score::add_column (Paper_column*p)
 
 
 
-  me->set_elt_property ("columns",  gh_cons (p->self_scm_, cs));
+  me->set_elt_property ("columns",  gh_cons (p->self_scm (), cs));
 
   Axis_group_interface::add_element (me, p);
 }
@@ -272,7 +272,7 @@ Line_of_score::pre_processing ()
       Score_element * e = unsmob_element (gh_car (s));
       SCM proc = e->get_elt_property ("spacing-procedure");
       if (gh_procedure_p (proc))
-	gh_call1 (proc, e->self_scm_);
+	gh_call1 (proc, e->self_scm ());
     }
 }
 
@@ -364,13 +364,13 @@ Line_of_score::broken_col_range (Item const*l, Item const*r) const
   r = r->column_l ();
   SCM s = get_elt_property ("columns");
 
-  while (gh_pair_p (s) && gh_car (s) != r->self_scm_)
+  while (gh_pair_p (s) && gh_car (s) != r->self_scm ())
     s = gh_cdr  (s);
     
   if (gh_pair_p (s))
     s = gh_cdr (s);
   
-  while (gh_pair_p (s) && gh_car (s) != l->self_scm_)
+  while (gh_pair_p (s) && gh_car (s) != l->self_scm ())
     {
       Paper_column*c = dynamic_cast<Paper_column*> ( unsmob_element (gh_car (s)));
       if (Item::breakable_b (c) && !c->line_l_)
diff --git a/lily/lookup.cc b/lily/lookup.cc
index 4b7a9bdc53..a6c24eddd3 100644
--- a/lily/lookup.cc
+++ b/lily/lookup.cc
@@ -34,16 +34,12 @@
 Lookup::Lookup ()
 {
   afm_l_ = 0;  
-  self_scm_ = SCM_EOL;
-  smobify_self ();  
 }
 
 Lookup::Lookup (Lookup const& s)
 {
   font_name_ = s.font_name_;
-  self_scm_ = SCM_EOL;
   afm_l_ = 0;
-  smobify_self ();
 }
 
 SCM
@@ -59,28 +55,16 @@ Lookup::print_smob (SCM s, SCM p, scm_print_state*)
   return 1;
 }
 
-SCM
-Lookup::equal_p (SCM a , SCM b)
-{
-  return a == b ? SCM_BOOL_T : SCM_BOOL_F;
-}
-
-void
-Lookup::do_smobify_self ()
-{
-  
-}
 
 IMPLEMENT_UNSMOB(Lookup, lookup);
-IMPLEMENT_SMOBS(Lookup);
+IMPLEMENT_SIMPLE_SMOBS(Lookup);
+IMPLEMENT_DEFAULT_EQUAL_P(Lookup);
 
 SCM
 Lookup::make_lookup ()
 {
   Lookup * l = new Lookup;
-  SCM ls = l->self_scm_;
-  scm_unprotect_object (ls);
-  return ls;
+  return l->smobbed_self();
 }
 
 
diff --git a/lily/lyric-combine-music.cc b/lily/lyric-combine-music.cc
index d6e42d2cbc..0b1f86b332 100644
--- a/lily/lyric-combine-music.cc
+++ b/lily/lyric-combine-music.cc
@@ -12,8 +12,8 @@
 
 Lyric_combine_music::Lyric_combine_music (Music * m, Music * l)
 {
-  set_mus_property ("music", m->self_scm_);
-  set_mus_property ("lyrics", l->self_scm_);  
+  set_mus_property ("music", m->self_scm ());
+  set_mus_property ("lyrics", l->self_scm ());  
 }
 
 
diff --git a/lily/mark-engraver.cc b/lily/mark-engraver.cc
index 6b37780158..0f2df8fcdf 100644
--- a/lily/mark-engraver.cc
+++ b/lily/mark-engraver.cc
@@ -64,7 +64,7 @@ Mark_engraver::acknowledge_element (Score_element_info inf)
   Score_element * s = inf.elem_l_;
   if (Staff_symbol::has_interface (s))
     {
-      staffs_ = gh_cons (inf.elem_l_->self_scm_, staffs_);
+      staffs_ = gh_cons (inf.elem_l_->self_scm (), staffs_);
     }
   else if (text_p_ && Bar::has_interface (s))
     {
diff --git a/lily/midi-def.cc b/lily/midi-def.cc
index 1013399eac..f5cbd2a952 100644
--- a/lily/midi-def.cc
+++ b/lily/midi-def.cc
@@ -39,8 +39,8 @@ Midi_def::set_tempo (Moment one_beat_mom, int beats_per_minute_i)
 {
   Moment beats_per_second = Moment (beats_per_minute_i) / Moment (60);
 
-  Moment *m = new Moment (Moment(1)/Moment(beats_per_second * one_beat_mom));
-  scope_p_->set ("whole-in-seconds", smobify (m));
+  Moment m = Moment(1)/Moment(beats_per_second * one_beat_mom);
+  scope_p_->set ("whole-in-seconds", m.make_scm());
 }
 
 
diff --git a/lily/moment.cc b/lily/moment.cc
index 8495cdc470..a224da0a1c 100644
--- a/lily/moment.cc
+++ b/lily/moment.cc
@@ -12,6 +12,12 @@
 #include "moment.hh"
 #include "warn.hh"
 
+#include "ly-smobs.icc"
+
+IMPLEMENT_UNSMOB(Moment,moment);
+IMPLEMENT_SIMPLE_SMOBS(Moment);
+
+
 SCM
 Moment::mark_smob (SCM)
 {
@@ -19,11 +25,14 @@ Moment::mark_smob (SCM)
 }
 
 
-Moment::~Moment()
+SCM
+Moment::make_scm () const
 {
-  self_scm_ = SCM_EOL;
+  Moment * m = new Moment (*this);
+  return m->smobbed_self();
 }
 
+
 int
 Moment::print_smob (SCM s, SCM port, scm_print_state *)
 {
@@ -37,35 +46,23 @@ Moment::print_smob (SCM s, SCM port, scm_print_state *)
   return 1;
 }
 
-void
-Moment::do_smobify_self ()
-{
-}
-
 SCM
 make_rational (SCM n, SCM d)
 {
-  Moment *r;
-  SCM retval = SCM_EOL;
+  Moment m (1,1);
+
   if (SCM_INUMP (n) && SCM_INUMP(d))
     {
-      r= new Moment (gh_scm2int (n), gh_scm2int (d));
+      m =  Moment (gh_scm2int (n), gh_scm2int (d));
     }
   else
     {
-      ::error ("make-moment takes two integer arguments.");
-      r = new Moment (1,1);
+      ::error ("make-moment takes two integer arguments. Using 1/1");
     }
 
-  retval = r->smobify_self ();
-  scm_unprotect_object (r->self_scm_);
-  return retval ;  
+  return m.make_scm ();
 }
 
-#include "ly-smobs.icc"
-
-IMPLEMENT_UNSMOB(Moment,moment);
-IMPLEMENT_SMOBS(Moment);
 
 void
 init_moments ()
@@ -78,8 +75,9 @@ ADD_SCM_INIT_FUNC(moms,init_moments);
 SCM
 Moment::equal_p (SCM a, SCM b)
 {
-  Moment *m1 = SMOB_TO_TYPE(Moment, a);
-  Moment *m2 = SMOB_TO_TYPE(Moment, b);
+  Moment *m1 = unsmob_moment (a);
+  Moment *m2 = unsmob_moment (b);
       
   return (*m1 == *m2) ? SCM_BOOL_T : SCM_BOOL_F;
 }
+
diff --git a/lily/multi-measure-rest-engraver.cc b/lily/multi-measure-rest-engraver.cc
index d6a34e3268..c5d75d3a9f 100644
--- a/lily/multi-measure-rest-engraver.cc
+++ b/lily/multi-measure-rest-engraver.cc
@@ -155,7 +155,6 @@ Multi_measure_rest_engraver::do_post_move_processing ()
 {
   Moment now (now_mom ());
   
-  
   SCM smp = get_property ("measurePosition");
   Moment mp =  (unsmob_moment (smp)) ? *unsmob_moment (smp) : Moment (0);
   
diff --git a/lily/music-sequence.cc b/lily/music-sequence.cc
index aa3bc2eb35..32c386c323 100644
--- a/lily/music-sequence.cc
+++ b/lily/music-sequence.cc
@@ -47,7 +47,7 @@ void
 Music_sequence::append_music (Music *m)
 {
   set_mus_property ("list",
-		    gh_append2( music_list(), gh_cons (m->self_scm_, SCM_EOL)));
+		    gh_append2( music_list(), gh_cons (m->self_scm (), SCM_EOL)));
 }
 Music_sequence::Music_sequence(SCM h)
 {
diff --git a/lily/music-wrapper.cc b/lily/music-wrapper.cc
index 59d3c43441..641c83b91b 100644
--- a/lily/music-wrapper.cc
+++ b/lily/music-wrapper.cc
@@ -27,7 +27,7 @@ Music_wrapper::transpose (Musical_pitch p)
 
 Music_wrapper::Music_wrapper(Music*p)
 {
-  set_mus_property ("element", p->self_scm_);
+  set_mus_property ("element", p->self_scm ());
 }
 
 Moment
diff --git a/lily/music.cc b/lily/music.cc
index 536082211e..8ce821e012 100644
--- a/lily/music.cc
+++ b/lily/music.cc
@@ -18,11 +18,13 @@ ly_deep_mus_copy (SCM m)
 {
   if (unsmob_music (m))
     {
-      return unsmob_music (m)->clone ()->self_scm_;
+      SCM ss =  unsmob_music (m)->clone ()->self_scm ();
+      scm_unprotect_object (ss);
+      return ss;
     }
   else if (gh_pair_p (m))
     {
-      return gh_cons (ly_deep_copy (gh_car (m)), ly_deep_copy (gh_cdr (m)));
+      return gh_cons (ly_deep_mus_copy (gh_car (m)), ly_deep_mus_copy (gh_cdr (m)));
     }
   else
     return m;
@@ -31,7 +33,6 @@ ly_deep_mus_copy (SCM m)
 
 Music::Music (Music const &m)
 {
-  self_scm_ = SCM_EOL;
   immutable_property_alist_ = m.immutable_property_alist_;
   SCM c =ly_deep_mus_copy (m.mutable_property_alist_);
   mutable_property_alist_ = c;
@@ -44,7 +45,6 @@ Music::Music (Music const &m)
 
 Music::Music()
 {
-  self_scm_ = SCM_EOL;
   immutable_property_alist_ = SCM_EOL;
   mutable_property_alist_ = SCM_EOL;
   smobify_self ();
@@ -53,10 +53,10 @@ Music::Music()
 SCM
 Music::mark_smob (SCM m)
 {
-  Music * mus = SMOB_TO_TYPE (Music, m);
+  Music * mus = (Music *)SCM_CELL_WORD_1(m);
   scm_gc_mark (mus->immutable_property_alist_);
   scm_gc_mark (mus->mutable_property_alist_);
-  return mus->do_derived_mark ();
+  return SCM_EOL;
 }
 
 void    
@@ -99,6 +99,7 @@ Music::transpose (Musical_pitch )
 
 IMPLEMENT_UNSMOB(Music,music);
 IMPLEMENT_SMOBS(Music);
+IMPLEMENT_DEFAULT_EQUAL_P(Music);
 
 /****************************/
 
@@ -175,21 +176,13 @@ Music::origin () const
   return ip ? ip : & dummy_input_global; 
 }
 
-SCM
-Music::do_derived_mark ()
-{
-  return SCM_EOL;
-}
 
 void
 Music::print ()const
 {
 }
 
-void
-Music::do_smobify_self ()
-{
-}
+
 
 Music::~Music ()
 {
diff --git a/lily/my-lily-parser.cc b/lily/my-lily-parser.cc
index 3e4bbb602b..f77e59a4df 100644
--- a/lily/my-lily-parser.cc
+++ b/lily/my-lily-parser.cc
@@ -126,14 +126,14 @@ My_lily_parser::get_chord (Musical_pitch tonic,
     {
       Inversion_req* i = new Inversion_req;
       i->pitch_ = chord.inversion_pitch_;
-      l = gh_cons (i->self_scm_, l);
+      l = gh_cons (i->self_scm (), l);
     }
 
   if (chord.bass_b_)
     {
       Bass_req* b = new Bass_req;
       b->pitch_ = chord.bass_pitch_;
-      l = gh_cons (b->self_scm_, l);      
+      l = gh_cons (b->self_scm (), l);      
     }
 
   Array<Musical_pitch> pitch_arr = chord.to_pitch_arr ();
@@ -143,7 +143,7 @@ My_lily_parser::get_chord (Musical_pitch tonic,
       Note_req* n = new Note_req;
       n->pitch_ = p;
       n->duration_ = d;
-      l = gh_cons (n->self_scm_, l);
+      l = gh_cons (n->self_scm (), l);
     }
 
   Simultaneous_music*v = new Request_chord (l);
diff --git a/lily/note-column.cc b/lily/note-column.cc
index 473c014663..f9711fc954 100644
--- a/lily/note-column.cc
+++ b/lily/note-column.cc
@@ -86,7 +86,7 @@ Note_column::dir (Score_element*  me)
 void
 Note_column::set_stem (Score_element*me,Score_element * stem_l)
 {
-  me->set_elt_property ("stem", stem_l->self_scm_);
+  me->set_elt_property ("stem", stem_l->self_scm ());
   me->add_dependency (stem_l);
   Axis_group_interface::add_element (me, stem_l);
 }
@@ -96,7 +96,7 @@ Note_column::add_head (Score_element*me,Score_element *h)
 {
   if (Rest::has_interface (h))
     {
-      me->set_elt_property ("rest", h->self_scm_);
+      me->set_elt_property ("rest", h->self_scm ());
     }
   else if (Note_head::has_interface (h))
     {
diff --git a/lily/output-property-engraver.cc b/lily/output-property-engraver.cc
index 40036ec0af..b20f3d7ca2 100644
--- a/lily/output-property-engraver.cc
+++ b/lily/output-property-engraver.cc
@@ -48,7 +48,7 @@ Output_property_engraver::acknowledge_element (Score_element_info inf)
 	should typecheck pred. 
        */
       SCM result=gh_apply (pred,
-			   gh_list (inf.elem_l_->self_scm_, SCM_UNDEFINED));
+			   gh_list (inf.elem_l_->self_scm (), SCM_UNDEFINED));
       if (to_boolean (result))
 	{
 	  SCM sym = o->get_mus_property ("symbol");
diff --git a/lily/paper-def.cc b/lily/paper-def.cc
index d90d5b305b..698daf4585 100644
--- a/lily/paper-def.cc
+++ b/lily/paper-def.cc
@@ -87,9 +87,10 @@ Paper_def::line_dimensions_int (int n) const
 }
 
 void
-Paper_def::set_lookup (int i, Lookup*l)
+Paper_def::set_lookup (int i, SCM l)
 {
-  lookup_alist_ = scm_assq_set_x(lookup_alist_, gh_int2scm (i), l->self_scm_);
+  assert (unsmob_lookup (l));
+  lookup_alist_ = scm_assq_set_x(lookup_alist_, gh_int2scm (i), l);
 }
 
 
diff --git a/lily/paper-score.cc b/lily/paper-score.cc
index ec2c83f65f..9c13a867ea 100644
--- a/lily/paper-score.cc
+++ b/lily/paper-score.cc
@@ -38,11 +38,11 @@ Paper_score::typeset_line (Line_of_score *l)
     {
       line_l_ = l;		// ugh.
     }
-  main_smob_ = gh_cons (l->self_scm_, main_smob_);
+  main_smob_ = gh_cons (l->self_scm (), main_smob_);
   l->pscore_l_ = this;
 
   /*
-    We don't unprotect l->self_scm_, we haven't got any place else to
+    We don't unprotect l->self_scm (), we haven't got any place else to
     protect it from collection.  */
 
 }
diff --git a/lily/parser.yy b/lily/parser.yy
index 8ce72cb885..5c4632ac72 100644
--- a/lily/parser.yy
+++ b/lily/parser.yy
@@ -289,9 +289,9 @@ toplevel_expression:
 		Identifier * id = new
 			Music_output_def_identifier ($1, MUSIC_OUTPUT_DEF_IDENTIFIER);
 		if (dynamic_cast<Paper_def*> ($1))
-			THIS->lexer_p_->set_identifier ("$defaultpaper", smobify (id));
+			THIS->lexer_p_->set_identifier ("$defaultpaper", id->self_scm ());
 		else if (dynamic_cast<Midi_def*> ($1))
-			THIS->lexer_p_->set_identifier ("$defaultmidi", smobify (id));
+			THIS->lexer_p_->set_identifier ("$defaultmidi", id->self_scm ());
 	}
 	| embedded_scm {
 		// junk value
@@ -357,8 +357,17 @@ assignment:
 		THIS->remember_spot ();
 	}
 	/* cont */ '=' identifier_init  {
-	    THIS->lexer_p_->set_identifier (ly_scm2string ($1), $4);
+	        THIS->lexer_p_->set_identifier (ly_scm2string ($1), $4);
 
+/*
+ TODO: devise standard for protection in parser.
+		if (SCM_NIMP($4))
+			scm_unprotect_object ($4);
+
+  The parser stack lives on the C-stack, which means that
+all objects can be unprotected as soon as they're here.
+
+*/
 		Identifier * id =unsmob_identifier ($4);
 		Input spot = THIS->pop_spot ();
 		if (id) id->set_spot (spot);
@@ -369,24 +378,22 @@ assignment:
 
 identifier_init:
 	score_block {
-		$$ = smobify (new Score_identifier ($1, SCORE_IDENTIFIER));
+		$$ = (new Score_identifier ($1, SCORE_IDENTIFIER))->self_scm();
 	}
 	| output_def {
-		$$ = smobify (new Music_output_def_identifier ($1, MUSIC_OUTPUT_DEF_IDENTIFIER));
+		$$ = (new Music_output_def_identifier ($1, MUSIC_OUTPUT_DEF_IDENTIFIER))->self_scm();
 	}
 	| translator_spec_block {
-		$$ = smobify (new Translator_group_identifier ($1, TRANS_IDENTIFIER));
+		$$ = (new Translator_group_identifier ($1, TRANS_IDENTIFIER))->self_scm();
 	}
 	| Music  {
-		$$ = $1->self_scm_;
-		scm_unprotect_object ($$);
+		$$ = $1->self_scm ();
 	}
 	| post_request {
-		$$ = $1->self_scm_;
-		scm_unprotect_object ($$);
+		$$ = $1->self_scm ();
 	}
 	| explicit_duration {
-		$$ = smobify (new Duration_identifier ($1, DURATION_IDENTIFIER));
+		$$ = (new Duration_identifier ($1, DURATION_IDENTIFIER))->self_scm ();
 	}
 	| number_expression {
 		$$ = $1;
@@ -477,8 +484,8 @@ score_body:
 		$$ = new Score;
 
 		$$->set_spot (THIS->here_input ());
-		SCM m = $1->self_scm_;
-		scm_unprotect_object (m);
+		SCM m = $1->self_scm ();
+//		scm_unprotect_object (m);
 		$$->music_ = m;
 	}
 	| SCORE_IDENTIFIER {
@@ -554,9 +561,10 @@ music_output_def_body:
 		dynamic_cast<Midi_def*> ($$)->set_tempo ($2->dur_.length_mom (), $2->metronome_i_);
 	}
 	| music_output_def_body bare_int '=' FONT STRING		{ // ugh, what a syntax
-		Lookup * l =unsmob_lookup (Lookup::make_lookup());
+		SCM sl = Lookup::make_lookup();
+		Lookup * l =unsmob_lookup (sl);
 		l->font_name_ = ly_scm2string ($5);
-		dynamic_cast<Paper_def*> ($$)->set_lookup ($2, l);
+		dynamic_cast<Paper_def*> ($$)->set_lookup ($2, sl);
 	}
 	| music_output_def_body error {
 
@@ -577,8 +585,8 @@ Music_list: /* empty */ {
 	}
 	| Music_list Music {
 		SCM s = $$;
-		SCM c = gh_cons ($2->self_scm_, SCM_EOL);
-		scm_unprotect_object ($2->self_scm_); /* UGH */
+		SCM c = gh_cons ($2->self_scm (), SCM_EOL);
+//		scm_unprotect_object ($2->self_scm ()); /* UGH */
 
 	
 		if (gh_pair_p (gh_cdr (s)))
@@ -817,14 +825,15 @@ request_chord:
 
 command_element:
 	command_req {
-		$$ = new Request_chord (gh_cons ($1->self_scm_, SCM_EOL));
+		$$ = new Request_chord (gh_cons ($1->self_scm (), SCM_EOL));
 		$$-> set_spot (THIS->here_input ());
 		$1-> set_spot (THIS->here_input ());
 	}
 	| PARTIAL duration_length ';' 	{
 		Translation_property * p = new Translation_property;
 		p->set_mus_property ("symbol", ly_symbol2scm ( "measurePosition"));
-		p->set_mus_property ("value", (new Moment (-$2->length_mom ()))->smobify_self ());
+		Moment m = - $2->length_mom ();
+		p->set_mus_property ("value", m.make_scm());
 		delete $2; // ugh
 		Context_specced_music * sp = new Context_specced_music (p);
 		$$ =sp ;
@@ -1274,7 +1283,7 @@ simple_element:
 		n->forceacc_b_ = $2 % 2 || n->cautionary_b_;
 
 
-		Simultaneous_music*v = new Request_chord (gh_list (n->self_scm_, SCM_UNDEFINED));
+		Simultaneous_music*v = new Request_chord (gh_list (n->self_scm (), SCM_UNDEFINED));
 		v->set_spot ($1->spot ());
 		n->set_spot ($1->spot ());
 		$$ = v;
@@ -1291,14 +1300,14 @@ simple_element:
 		      skip_p->duration_ = *$2;
 
 		      skip_p->set_spot (THIS->here_input());
-			e = skip_p->self_scm_;
+			e = skip_p->self_scm ();
 		    }
 		  else
 		    {
 		      Rest_req * rest_req_p = new Rest_req;
 		      rest_req_p->duration_ = *$2;
 		      rest_req_p->set_spot (THIS->here_input());
-			e = rest_req_p->self_scm_;
+			e = rest_req_p->self_scm ();
 		    }
 		  Simultaneous_music* velt_p = new Request_chord (gh_list (e,SCM_UNDEFINED));
 		  velt_p->set_spot (THIS->here_input());
@@ -1317,11 +1326,11 @@ simple_element:
 		sp2-> span_dir_ = STOP;
 		sp1->span_type_str_ = sp2->span_type_str_ = "rest";
 
-		Request_chord * rqc1 = new Request_chord (gh_list (sp1->self_scm_, SCM_UNDEFINED));
-		Request_chord * rqc2 = new Request_chord (gh_list (sk->self_scm_, SCM_UNDEFINED));;
-		Request_chord * rqc3 = new Request_chord(gh_list (sp2->self_scm_, SCM_UNDEFINED));;
+		Request_chord * rqc1 = new Request_chord (gh_list (sp1->self_scm (), SCM_UNDEFINED));
+		Request_chord * rqc2 = new Request_chord (gh_list (sk->self_scm (), SCM_UNDEFINED));;
+		Request_chord * rqc3 = new Request_chord(gh_list (sp2->self_scm (), SCM_UNDEFINED));;
 
-		SCM ms = gh_list (rqc1->self_scm_, rqc2->self_scm_, rqc3->self_scm_, SCM_UNDEFINED);
+		SCM ms = gh_list (rqc1->self_scm (), rqc2->self_scm (), rqc3->self_scm (), SCM_UNDEFINED);
 
 		$$ = new Sequential_music (ms);
 	}
@@ -1332,7 +1341,7 @@ simple_element:
 		lreq_p ->text_str_ = ly_scm2string ($1);
 		lreq_p->duration_ = *$2;
 		lreq_p->set_spot (THIS->here_input());
-		Simultaneous_music* velt_p = new Request_chord (gh_list (lreq_p->self_scm_, SCM_UNDEFINED));
+		Simultaneous_music* velt_p = new Request_chord (gh_list (lreq_p->self_scm (), SCM_UNDEFINED));
 
 		delete  $2; // ugh
 		$$= velt_p;
diff --git a/lily/pointer-group-interface.cc b/lily/pointer-group-interface.cc
index cb9c413a9d..f1a6ae4011 100644
--- a/lily/pointer-group-interface.cc
+++ b/lily/pointer-group-interface.cc
@@ -34,7 +34,7 @@ void
 Pointer_group_interface::add_element (Score_element*p) 
 {
   elt_l_->set_elt_property (name_.ch_C(),
-			   gh_cons (p->self_scm_,
+			   gh_cons (p->self_scm (),
 				    elt_l_->get_elt_property (name_.ch_C())));
 }
 
diff --git a/lily/property-engraver.cc b/lily/property-engraver.cc
index 35d19d162a..c6e5430263 100644
--- a/lily/property-engraver.cc
+++ b/lily/property-engraver.cc
@@ -19,24 +19,47 @@ class Property_engraver : public Engraver
   /*
     UGH. Junk Dictionary
   */
-  Scheme_hash_table prop_dict_;	// junkme
+  Scheme_hash_table *prop_dict_;	// junkme
   void apply_properties (SCM, Score_element*);
 
 protected:
   virtual void acknowledge_element (Score_element_info ei);
   virtual void do_creation_processing ();
-
+  virtual void do_removal_processing ();
+public:
+  ~Property_engraver();
+  Property_engraver();
   VIRTUAL_COPY_CONS(Translator);
 };
 
+
+
+Property_engraver::Property_engraver()
+{
+  prop_dict_ = 0;
+}
+void
+Property_engraver::do_removal_processing()
+{
+  
+}
+
+Property_engraver::~Property_engraver ()
+{
+  if (prop_dict_)
+    scm_unprotect_object (prop_dict_->self_scm ());
+}
+
 void
 Property_engraver::do_creation_processing ()
 {
+  prop_dict_ = new Scheme_hash_table;
+
   SCM plist = get_property ("Generic_property_list");
   for (; gh_pair_p (plist); plist = gh_cdr (plist))
     {
       SCM elt_props = gh_car (plist);
-      prop_dict_.set (gh_car (elt_props), gh_cdr (elt_props));
+      prop_dict_->set (gh_car (elt_props), gh_cdr (elt_props));
     }
 }
 
@@ -47,13 +70,13 @@ Property_engraver::acknowledge_element (Score_element_info i)
   SCM props;
   for (; gh_pair_p (ifs); ifs = gh_cdr (ifs))
     {      
-      if (prop_dict_.try_retrieve (gh_car (ifs), &props))
+      if (prop_dict_->try_retrieve (gh_car (ifs), &props))
 	{
 	  apply_properties (props,i.elem_l_);
 	}
     }
 
-  if (prop_dict_.try_retrieve (ly_symbol2scm ("all"), &props))
+  if (prop_dict_->try_retrieve (ly_symbol2scm ("all"), &props))
     {
       apply_properties (props, i.elem_l_);
     }
diff --git a/lily/repeated-music.cc b/lily/repeated-music.cc
index f2e9b77daa..2e8e0e3d02 100644
--- a/lily/repeated-music.cc
+++ b/lily/repeated-music.cc
@@ -26,14 +26,14 @@ Repeated_music::alternatives ()const
 
 Repeated_music::Repeated_music(Music *beg, int times, Music_sequence * alts)
 {
-  set_mus_property ("body", beg->self_scm_);
+  set_mus_property ("body", beg->self_scm ());
   fold_b_ = false;
   repeats_i_ = times;
   volta_fold_b_ = true;
   if (alts)
     {
       alts->truncate (times);
-      set_mus_property ("alternatives", alts->self_scm_);
+      set_mus_property ("alternatives", alts->self_scm ());
     }
 }
 
diff --git a/lily/rest-collision.cc b/lily/rest-collision.cc
index 5427a20c6d..6429df3684 100644
--- a/lily/rest-collision.cc
+++ b/lily/rest-collision.cc
@@ -48,7 +48,7 @@ Rest_collision::add_column (Score_element*me,Score_element *p)
   gi.add_element (p);
 
   p->add_offset_callback (&Rest_collision::force_shift_callback, Y_AXIS);
-  p->set_elt_property ("rest-collision", me->self_scm_);
+  p->set_elt_property ("rest-collision", me->self_scm ());
 }
 
 static SCM
diff --git a/lily/rhythmic-head.cc b/lily/rhythmic-head.cc
index 63006674fc..cf18863152 100644
--- a/lily/rhythmic-head.cc
+++ b/lily/rhythmic-head.cc
@@ -51,7 +51,7 @@ Rhythmic_head::dot_count (Score_element*me)
 void
 Rhythmic_head::set_dots (Score_element*me,Item *dot_l)
 {
-  me->set_elt_property ("dot", dot_l->self_scm_);
+  me->set_elt_property ("dot", dot_l->self_scm ());
 }
 
 
diff --git a/lily/scm-hash.cc b/lily/scm-hash.cc
index 98c430b3eb..16c5974737 100644
--- a/lily/scm-hash.cc
+++ b/lily/scm-hash.cc
@@ -14,7 +14,13 @@
 
 Scheme_hash_table::Scheme_hash_table ()
 {
-  self_scm_ = SCM_EOL;
+  smobify_self ();
+}
+
+
+Scheme_hash_table::Scheme_hash_table (Scheme_hash_table const &src)
+  : Scm_stl_map (src)
+{
   smobify_self ();
 }
 
@@ -23,13 +29,10 @@ Scheme_hash_table::operator =(Scheme_hash_table const & src)
 {
   Scm_stl_map::operator = (src);
 	
-  // we do not copy the self_scm_ field!
+  // we do not copy the self_scm () field!
 }
 
-void
-Scheme_hash_table::do_smobify_self ()
-{
-}
+
 
 
 SCM
@@ -39,7 +42,7 @@ Scheme_hash_table::mark_smob (SCM s)
     can't typecheck naively, since GC bit lives in CAR of S
    */
   
-  Scheme_hash_table *me = SMOB_TO_TYPE(Scheme_hash_table,s);
+  Scheme_hash_table *me = (Scheme_hash_table*) SCM_CELL_WORD_1(s);
 
   for (Scm_stl_map::const_iterator i= me->begin (); i != me->end(); i++)
     {
@@ -49,22 +52,14 @@ Scheme_hash_table::mark_smob (SCM s)
   return SCM_EOL;
 }
 
-
-Scheme_hash_table::Scheme_hash_table (Scheme_hash_table const &src)
-  : Scm_stl_map (src)
-{
-  self_scm_ = SCM_EOL;
-  smobify_self ();
-}
-
 int
 Scheme_hash_table::print_smob (SCM s, SCM p, scm_print_state*)
 {
-  assert (SMOB_IS_TYPE_B (Scheme_hash_table, s));
+  assert (unsmob (s));
   char str[1000];
   sprintf (str, "#<Scheme_hash_table 0x%0x ", s);
   scm_puts (str, p);      
-  Scheme_hash_table *me = SMOB_TO_TYPE(Scheme_hash_table,s);
+  Scheme_hash_table *me = unsmob(s);
   for (Scm_stl_map::const_iterator i = me->begin (); i != me->end(); i++)
     {
       scm_display ((*i).first, p);
@@ -109,7 +104,6 @@ Scheme_hash_table::get (SCM k)const
 
 Scheme_hash_table::~Scheme_hash_table( )
 {
-  unsmobify_self ();
 }
 
 SCM
@@ -125,5 +119,6 @@ Scheme_hash_table::to_alist () const
 #include "ly-smobs.icc"
 IMPLEMENT_UNSMOB(Scheme_hash_table,scheme_hash);
 IMPLEMENT_SMOBS(Scheme_hash_table);
+IMPLEMENT_DEFAULT_EQUAL_P(Scheme_hash_table);
 
 
diff --git a/lily/scope.cc b/lily/scope.cc
index c04878f934..85837e5d09 100644
--- a/lily/scope.cc
+++ b/lily/scope.cc
@@ -14,12 +14,12 @@
 
 Scope::~Scope ()
 {
-  delete id_dict_;
+  scm_unprotect_object (id_dict_->self_scm ());
 }
 
 Scope::Scope (Scope const&s)
-  : id_dict_ (new Scheme_hash_table (*s.id_dict_))
 {
+  id_dict_ =new Scheme_hash_table (*s.id_dict_);
 }
 
 Scope::Scope ()
@@ -72,7 +72,7 @@ Scope::set (String s, SCM id)
 void
 Scope::set (String s, Identifier * id) 
 {
-  return id_dict_->set (ly_symbol2scm (s.ch_C()), smobify (id));
+  return id_dict_->set (ly_symbol2scm (s.ch_C()), id->self_scm ());
 }
 
 SCM
diff --git a/lily/score-element.cc b/lily/score-element.cc
index 451c1f40be..e1c218d1bf 100644
--- a/lily/score-element.cc
+++ b/lily/score-element.cc
@@ -49,7 +49,6 @@ Score_element::Score_element(SCM basicprops)
   pscore_l_=0;
   lookup_l_ =0;
   status_i_ = 0;
-  self_scm_ = SCM_EOL;
   original_l_ = 0;
   immutable_property_alist_ =  basicprops;
   mutable_property_alist_ = SCM_EOL;
@@ -65,7 +64,6 @@ Score_element::Score_element(SCM basicprops)
 Score_element::Score_element (Score_element const&s)
    : dim_cache_ (s.dim_cache_)
 {
-  self_scm_ = SCM_EOL;
   original_l_ =(Score_element*) &s;
   immutable_property_alist_ = s.immutable_property_alist_;
   mutable_property_alist_ = SCM_EOL;
@@ -236,7 +234,7 @@ Score_element::calculate_dependencies (int final, int busy, SCM funcname)
   String s = ly_symbol2string (funcname);
   SCM proc = get_elt_property (s.ch_C());
   if (gh_procedure_p (proc))
-    gh_call1 (proc, this->self_scm_);
+    gh_call1 (proc, this->self_scm ());
   
   status_i_= final;
 
@@ -249,7 +247,7 @@ Score_element::get_molecule ()  const
 
   SCM mol = SCM_EOL;
   if (gh_procedure_p (proc)) 
-    mol = gh_apply (proc, gh_list (this->self_scm_, SCM_UNDEFINED));
+    mol = gh_apply (proc, gh_list (this->self_scm (), SCM_UNDEFINED));
 
 
   SCM origin =get_elt_property ("origin");
@@ -345,7 +343,7 @@ Score_element::handle_broken_smobs (SCM src, SCM criterion)
 	  if (i && i->break_status_dir () != d)
 	    {
 	      Item *br = i->find_prebroken_piece (d);
-	      return  (br) ? br->self_scm_ : SCM_UNDEFINED;
+	      return  (br) ? br->self_scm () : SCM_UNDEFINED;
 	    }
 	}
       else
@@ -367,7 +365,7 @@ Score_element::handle_broken_smobs (SCM src, SCM criterion)
 	      || (sc->common_refpoint (line, X_AXIS)
 		  && sc->common_refpoint (line, Y_AXIS)))
 	    {
-	      return sc->self_scm_;
+	      return sc->self_scm ();
 	    }
 	  return SCM_UNDEFINED;
 	}
@@ -419,7 +417,7 @@ Score_element::handle_broken_dependencies()
 	  Line_of_score * l = sc->line_l ();
 	  sc->mutable_property_alist_ =
 	    handle_broken_smobs (mutable_property_alist_,
-				 l ? l->self_scm_ : SCM_UNDEFINED);
+				 l ? l->self_scm () : SCM_UNDEFINED);
 	}
     }
 
@@ -430,7 +428,7 @@ Score_element::handle_broken_dependencies()
     {
       mutable_property_alist_
 	= handle_broken_smobs (mutable_property_alist_,
-			       line ? line->self_scm_ : SCM_UNDEFINED);
+			       line ? line->self_scm () : SCM_UNDEFINED);
     }
   else if (dynamic_cast <Line_of_score*> (this))
     {
@@ -712,26 +710,22 @@ Score_element::fixup_refpoint (SCM smob)
 
 IMPLEMENT_UNSMOB(Score_element, element);
 IMPLEMENT_SMOBS(Score_element);
+IMPLEMENT_DEFAULT_EQUAL_P(Score_element);
 
 SCM
 Score_element::mark_smob (SCM ses)
 {
-  Score_element * s = SMOB_TO_TYPE (Score_element, ses);
-  if (s->self_scm_ != ses)
-    {
-      programming_error ("SMOB marking gone awry");
-      return SCM_EOL;
-    }
+  Score_element * s = (Score_element*) SCM_CELL_WORD_1(ses);
   scm_gc_mark (s->immutable_property_alist_);
   scm_gc_mark (s->mutable_property_alist_);
   
   if (s->parent_l (Y_AXIS))
-    scm_gc_mark (s->parent_l (Y_AXIS)->self_scm_);
+    scm_gc_mark (s->parent_l (Y_AXIS)->self_scm ());
   if (s->parent_l (X_AXIS))
-    scm_gc_mark (s->parent_l (X_AXIS)->self_scm_);
+    scm_gc_mark (s->parent_l (X_AXIS)->self_scm ());
 
   if (s->original_l_)
-    scm_gc_mark (s->original_l_->self_scm_);
+    scm_gc_mark (s->original_l_->self_scm ());
   return s->do_derived_mark ();
 }
 
@@ -756,17 +750,6 @@ Score_element::do_derived_mark ()
   return SCM_EOL;
 }
 
-void
-Score_element::do_smobify_self ()
-{
-}
-
-SCM
-Score_element::equal_p (SCM a, SCM b)
-{
-  return gh_cdr(a) == gh_cdr(b) ? SCM_BOOL_T : SCM_BOOL_F;
-}
-
 
 SCM
 ly_set_elt_property (SCM elt, SCM sym, SCM val)
@@ -822,7 +805,7 @@ Score_element::discretionary_processing()
 SCM
 spanner_get_bound (SCM slur, SCM dir)
 {
-  return dynamic_cast<Spanner*> (unsmob_element (slur))->get_bound (to_dir (dir))->self_scm_;
+  return dynamic_cast<Spanner*> (unsmob_element (slur))->get_bound (to_dir (dir))->self_scm ();
 }
 
 
diff --git a/lily/score-engraver.cc b/lily/score-engraver.cc
index c360b99649..80ad78157a 100644
--- a/lily/score-engraver.cc
+++ b/lily/score-engraver.cc
@@ -35,9 +35,8 @@ Score_engraver::prepare (Moment w)
   SCM props = get_property (ly_symbol2scm ("basicPaperColumnProperties"));
   set_columns (new Paper_column (props),  new Paper_column (props));
   
-  SCM when = smobify (new Moment (w));
-  command_column_l_->set_elt_property ("when", when);
-  musical_column_l_->set_elt_property ("when", when);
+  command_column_l_->set_elt_property ("when", w.make_scm());
+  musical_column_l_->set_elt_property ("when", w.make_scm());
   command_column_l_->set_elt_property ("breakable", SCM_BOOL_T);
   
   Score_element_info i1(command_column_l_, 0), i2 (musical_column_l_,0);
@@ -206,9 +205,9 @@ Score_engraver::set_columns (Paper_column *new_command_l,
     }
 
   if (new_musical_l)
-    set_property ("currentMusicalColumn", new_musical_l->self_scm_);
+    set_property ("currentMusicalColumn", new_musical_l->self_scm ());
   if (new_command_l)
-    set_property ("currentCommandColumn", new_command_l->self_scm_);  
+    set_property ("currentCommandColumn", new_command_l->self_scm ());  
 }
 
 Music_output*
diff --git a/lily/score.cc b/lily/score.cc
index 8a4e348d0d..75e397aab8 100644
--- a/lily/score.cc
+++ b/lily/score.cc
@@ -39,7 +39,7 @@ Score::Score (Score const &s)
   : Input (s)
 {
   Music * m =unsmob_music (s.music_);
-  music_ =  m?m->clone()->self_scm_ : SCM_EOL;
+  music_ =  m?m->clone()->self_scm () : SCM_EOL;
   for (int i=0; i < s.def_p_arr_.size (); i++)
     def_p_arr_.push(s.def_p_arr_[i]->clone());
   errorlevel_i_ = s.errorlevel_i_;
diff --git a/lily/script-engraver.cc b/lily/script-engraver.cc
index db95e855f4..3f47d8f714 100644
--- a/lily/script-engraver.cc
+++ b/lily/script-engraver.cc
@@ -128,7 +128,7 @@ Script_engraver::acknowledge_element (Score_element_info inf)
 	{
 	  Score_element*e = script_p_arr_[i];
 
-	  e->set_elt_property ("direction-source", inf.elem_l_->self_scm_);
+	  e->set_elt_property ("direction-source", inf.elem_l_->self_scm ());
 	  Side_position::add_support (e, inf.elem_l_);
 	}
     }
diff --git a/lily/separation-item.cc b/lily/separation-item.cc
index 7613471c7f..d740483ac8 100644
--- a/lily/separation-item.cc
+++ b/lily/separation-item.cc
@@ -38,9 +38,9 @@ Separation_item::my_width (Score_element *me)
   for (SCM s =  me->get_elt_property ("elements"); gh_pair_p (s); s = gh_cdr (s))
     {
       SCM elt = gh_car (s);
-      if (!SMOB_IS_TYPE_B(Score_element, elt))
+      if (!unsmob_element (elt))
 	continue;
-      
+
       Item *il = dynamic_cast<Item*> (unsmob_element (elt));
       if (pc != il->column_l ())
 	{
diff --git a/lily/slur.cc b/lily/slur.cc
index 19cabbc6c1..ccad52d81c 100644
--- a/lily/slur.cc
+++ b/lily/slur.cc
@@ -177,7 +177,7 @@ Slur::set_extremities (Score_element*me)
 	  for (SCM s = scm_eval (ly_symbol2scm ("slur-extremity-rules"));
 	       s != SCM_EOL; s = gh_cdr (s))
 	    {
-	      SCM r = gh_call2 (gh_caar (s), me->self_scm_,
+	      SCM r = gh_call2 (gh_caar (s), me->self_scm (),
 				 gh_int2scm ((int)dir));
 	      if (r != SCM_BOOL_F)
 		{
diff --git a/lily/spaceable-element.cc b/lily/spaceable-element.cc
index 6bc4c1893f..b11f984218 100644
--- a/lily/spaceable-element.cc
+++ b/lily/spaceable-element.cc
@@ -27,7 +27,7 @@ Spaceable_element::add_rod (Score_element *me , Score_element * p, Real d)
   for (SCM s = mins; gh_pair_p (s); s = gh_cdr (s))
     {
       SCM dist = gh_car (s);
-      if (gh_car (dist) == p->self_scm_)
+      if (gh_car (dist) == p->self_scm ())
 	{
 	  gh_set_cdr_x (dist, scm_max (gh_cdr (dist),
 				       newdist));
@@ -35,7 +35,7 @@ Spaceable_element::add_rod (Score_element *me , Score_element * p, Real d)
 	}
     }
 
-  mins = gh_cons (gh_cons (p->self_scm_, newdist), mins);
+  mins = gh_cons (gh_cons (p->self_scm (), newdist), mins);
   me->set_elt_property ("minimum-distances", mins);
 }
 
@@ -47,7 +47,7 @@ Spaceable_element::add_spring (Score_element*me, Score_element * p, Real d, Real
   for (SCM s = mins; gh_pair_p (s); s = gh_cdr (s))
     {
       SCM dist = gh_car (s);
-      if (gh_car (dist) == p->self_scm_)
+      if (gh_car (dist) == p->self_scm ())
 	{
 	  programming_error("already have that spring");
 	  return ;
@@ -55,7 +55,7 @@ Spaceable_element::add_spring (Score_element*me, Score_element * p, Real d, Real
     }
   SCM newstrength= gh_double2scm (strength);  
   
-  mins = gh_cons (gh_cons (p->self_scm_, gh_cons (newdist, newstrength)), mins);
+  mins = gh_cons (gh_cons (p->self_scm (), gh_cons (newdist, newstrength)), mins);
   me->set_elt_property ("ideal-distances", mins);
 }
 
diff --git a/lily/spacing-engraver.cc b/lily/spacing-engraver.cc
index de4be78cb2..7578fa0073 100644
--- a/lily/spacing-engraver.cc
+++ b/lily/spacing-engraver.cc
@@ -138,8 +138,8 @@ Spacing_engraver::do_pre_move_processing ()
   Paper_column * sc
     = dynamic_cast<Paper_column*> (unsmob_element (get_property ("currentMusicalColumn")));
 
-  SCM sh = smobify (new Moment (shortest_playing));
-  SCM st = smobify (new Moment (starter));
+  SCM sh = shortest_playing.make_scm( );
+  SCM st = starter.make_scm();
 
   sc->set_elt_property ("shortest-playing-duration", sh);  
   sc->set_elt_property ("shortest-starter-duration", st);
diff --git a/lily/spacing-spanner.cc b/lily/spacing-spanner.cc
index d83d58e725..5ad98d494e 100644
--- a/lily/spacing-spanner.cc
+++ b/lily/spacing-spanner.cc
@@ -54,7 +54,7 @@ Spacing_spanner::do_measure (Score_element*me, Link_array<Score_element> cols)
       if (dynamic_cast<Paper_column*> (cols[i])->musical_b ())
 	{
 	  SCM  st = cols[i]->get_elt_property ("shortest-starter-duration");
-	  Moment this_shortest = (*SMOB_TO_TYPE(Moment, st));
+	  Moment this_shortest = *unsmob_moment(st);
 	  shortest = shortest <? this_shortest;
 	  if (!mean_shortest.infty_b ())
 	    {
diff --git a/lily/spanner.cc b/lily/spanner.cc
index 5c8f4a1977..04387ef9f7 100644
--- a/lily/spanner.cc
+++ b/lily/spanner.cc
@@ -271,11 +271,11 @@ Spanner::do_derived_mark ()
   Direction d = LEFT;
   do
     if (spanned_drul_[d])
-      scm_gc_mark (spanned_drul_[d]->self_scm_);
+      scm_gc_mark (spanned_drul_[d]->self_scm ());
   while (flip (&d) != LEFT);
 
   for (int i= broken_into_l_arr_.size () ; i--;)
-    scm_gc_mark (broken_into_l_arr_[i]->self_scm_);
+    scm_gc_mark (broken_into_l_arr_[i]->self_scm ());
 
   return SCM_EOL;
 }
diff --git a/lily/staff-symbol-engraver.cc b/lily/staff-symbol-engraver.cc
index d5fb4860f2..410cbac927 100644
--- a/lily/staff-symbol-engraver.cc
+++ b/lily/staff-symbol-engraver.cc
@@ -70,7 +70,7 @@ Staff_symbol_engraver::do_removal_processing()
 void
 Staff_symbol_engraver::acknowledge_element (Score_element_info s)
 {
-  s.elem_l_->set_elt_property ("staff-symbol", span_p_->self_scm_);
+  s.elem_l_->set_elt_property ("staff-symbol", span_p_->self_scm ());
   s.elem_l_->add_dependency (span_p_); // UGH. UGH. UGH 
 }
 
diff --git a/lily/stem-tremolo.cc b/lily/stem-tremolo.cc
index fff6f5c056..fc0ed1023f 100644
--- a/lily/stem-tremolo.cc
+++ b/lily/stem-tremolo.cc
@@ -126,6 +126,6 @@ Stem_tremolo::brew_molecule (SCM smob)
 void
 Stem_tremolo::set_stem (Score_element*me,Score_element *s)
 {
-  me->set_elt_property ("stem", s->self_scm_);
+  me->set_elt_property ("stem", s->self_scm ());
 }
 
diff --git a/lily/stem.cc b/lily/stem.cc
index 9a0f2b4688..9332b6532d 100644
--- a/lily/stem.cc
+++ b/lily/stem.cc
@@ -200,7 +200,7 @@ Stem::extremal_heads (Score_element*me)
 void
 Stem::add_head (Score_element*me, Score_element *n)
 {
-  n->set_elt_property ("stem", me->self_scm_);
+  n->set_elt_property ("stem", me->self_scm ());
   n->add_dependency (me);
 
   if (Note_head::has_interface (n))
@@ -209,7 +209,7 @@ Stem::add_head (Score_element*me, Score_element *n)
     }
   else
     {
-      n->set_elt_property ("rest", n->self_scm_);
+      n->set_elt_property ("rest", n->self_scm ());
     }
 }
 
diff --git a/lily/tfm-reader.cc b/lily/tfm-reader.cc
index 7bc495b49b..f188e300c2 100644
--- a/lily/tfm-reader.cc
+++ b/lily/tfm-reader.cc
@@ -19,29 +19,19 @@
 static const Real fix_to_real (Fix f);
 
 
-Tex_font_metric_reader::Tex_font_metric_reader (Tex_font_metric* fp, String name)
+Tex_font_metric_reader::Tex_font_metric_reader (String name)
   : input_ (name)
 {
-  tfm_l_=fp;
-  tfm_l_->clear (TFM_SIZE);
+  
+  for (int i=0; i < TFM_SIZE; i++)
+    ascii_to_metric_idx_.push (-1);
+
   read_header ();
   read_params ();
   read_char_metrics ();
 
 }
 
-Tex_font_metric * 
-Tex_font_metric_reader::read_file (String name)
-{
-  Tex_font_metric * tfmp = new Tex_font_metric;
-  Tex_font_metric_reader tfm_reader (tfmp, name);
-
-  return tfmp;
-}
-
-
-
-
 static const Real
 fix_to_real (Fix f)
 {
@@ -62,7 +52,7 @@ Tex_font_metric_reader::get_U32_fix_f ()
 Real
 Tex_font_metric_reader::get_U32_fix_scaled_f ()
 {
-  return get_U32_fix_f () * tfm_l_->info_.design_size;
+  return get_U32_fix_f () * info_.design_size;
 }
 
 String
@@ -83,8 +73,8 @@ Tex_font_metric_reader::read_header ()
   (void) file_length;
   U16 header_length = input_.get_U16 ();
 
-  tfm_l_->info_.first_charcode = input_.get_U16 ();
-  tfm_l_->info_.last_charcode = input_.get_U16 ();
+  info_.first_charcode = input_.get_U16 ();
+  info_.last_charcode = input_.get_U16 ();
   U16 width_word_count = input_.get_U16 ();
   U16 height_word_count = input_.get_U16 ();
   U16 depth_word_count = input_.get_U16 ();
@@ -95,38 +85,38 @@ Tex_font_metric_reader::read_header ()
   U16 extensible_word_count = input_.get_U16 ();
   (void)extensible_word_count;
   
-  tfm_l_->header_.param_word_count = input_.get_U16 ();
-  tfm_l_->info_.parameter_count = tfm_l_->header_.param_word_count;
-
-  tfm_l_->header_.char_info_pos = (6 + header_length) * 4;
-  tfm_l_->header_.width_pos = tfm_l_->header_.char_info_pos
-                         + (tfm_l_->info_.last_charcode
-                            - tfm_l_->info_.first_charcode + 1) * 4;
-  tfm_l_->header_.height_pos = tfm_l_->header_.width_pos + width_word_count * 4;
-  tfm_l_->header_.depth_pos = tfm_l_->header_.height_pos + height_word_count * 4;
-  tfm_l_->header_.italic_correction_pos = tfm_l_->header_.depth_pos
+  header_.param_word_count = input_.get_U16 ();
+  info_.parameter_count = header_.param_word_count;
+
+  header_.char_info_pos = (6 + header_length) * 4;
+  header_.width_pos = header_.char_info_pos
+                         + (info_.last_charcode
+                            - info_.first_charcode + 1) * 4;
+  header_.height_pos = header_.width_pos + width_word_count * 4;
+  header_.depth_pos = header_.height_pos + height_word_count * 4;
+  header_.italic_correction_pos = header_.depth_pos
                                      + depth_word_count * 4;
-  tfm_l_->header_.lig_kern_pos = tfm_l_->header_.italic_correction_pos
+  header_.lig_kern_pos = header_.italic_correction_pos
     + italic_correction_word_count * 4;
-  tfm_l_->header_.kern_pos = tfm_l_->header_.lig_kern_pos + lig_kern_word_count * 4;
+  header_.kern_pos = header_.lig_kern_pos + lig_kern_word_count * 4;
   /* We don't care about the extensible table.  */
 
   if (header_length < 2)
     error (_f ("TFM header of `%s' has only %u word(s)",
 	       input_.name_str ().ch_C (), header_length));
 
-  tfm_l_->info_.checksum = input_.get_U32 ();
-  tfm_l_->info_.design_size = get_U32_fix_f ();
+  info_.checksum = input_.get_U32 ();
+  info_.design_size = get_U32_fix_f ();
 
   /* Although the coding scheme might be interesting to the caller, the
      font family and face byte probably aren't.  So we don't read them.  */
-  tfm_l_->info_.coding_scheme = header_length > 2
+  info_.coding_scheme = header_length > 2
     ? get_bcpl_str () : "unspecified";
 
   DEBUG_OUT << format_str ("TFM checksum = %u, design_size = %fpt, coding scheme = `%s'.\n",
-		      tfm_l_->info_.checksum,
-		      tfm_l_->info_.design_size,
-		      tfm_l_->info_.coding_scheme.ch_C ());
+		      info_.checksum,
+		      info_.design_size,
+		      info_.coding_scheme.ch_C ());
 }
 
 /* Although TFM files are only usable by TeX if they have at least seven
@@ -139,34 +129,34 @@ void
 Tex_font_metric_reader::read_params ()
 {
   /* If we have no font parameters at all, we're done.  */
-  if (tfm_l_->header_.param_word_count == 0)
+  if (header_.param_word_count == 0)
     return;
 
   //brrr
   /* Move to the beginning of the parameter table in the file.  */
-  input_.seek_ch_C (-4 * tfm_l_->header_.param_word_count);
+  input_.seek_ch_C (-4 * header_.param_word_count);
 
   /* It's unlikely but possible that this TFM file has more fontdimens
      than we can deal with.  */
-  if (tfm_l_->header_.param_word_count > TFM_MAX_FONTDIMENS)
+  if (header_.param_word_count > TFM_MAX_FONTDIMENS)
     {
       warning (_f ("%s: TFM file has %u parameters, which is more than the %u I can handle",
 		   input_.name_str ().ch_C (),
-		   tfm_l_->header_.param_word_count,
+		   header_.param_word_count,
 		   TFM_MAX_FONTDIMENS));
-      tfm_l_->header_.param_word_count = TFM_MAX_FONTDIMENS;
+      header_.param_word_count = TFM_MAX_FONTDIMENS;
     }
 
   /* The first parameter is different than all the rest, because it
      isn't scaled by the design size.  */
-  tfm_l_->info_.parameters[(TFM_SLANT_PARAMETER) - 1] = get_U32_fix_f ();
+  info_.parameters[(TFM_SLANT_PARAMETER) - 1] = get_U32_fix_f ();
 
-  for (Char_code i = 2; i <= tfm_l_->header_.param_word_count; i++)
-    tfm_l_->info_.parameters[i - 1] = get_U32_fix_scaled_f ();
+  for (Char_code i = 2; i <= header_.param_word_count; i++)
+    info_.parameters[i - 1] = get_U32_fix_scaled_f ();
 
 #ifdef PRINT
-  for (Char_code i = 1; i <= tfm_l_->header_.param_word_count; i++)
-    DEBUG_OUT << format_str ("TFM parameter %d: %.3f", i, tfm_l_->info_.parameters[i - 1]);
+  for (Char_code i = 1; i <= header_.param_word_count; i++)
+    DEBUG_OUT << format_str ("TFM parameter %d: %.3f", i, info_.parameters[i - 1]);
 #endif
 }
 
@@ -176,12 +166,12 @@ Tex_font_metric_reader::read_params ()
 void
 Tex_font_metric_reader::read_char_metrics ()
 {
-  for (int i = tfm_l_->info_.first_charcode; i <= tfm_l_->info_.last_charcode; i++)
+  for (int i = info_.first_charcode; i <= info_.last_charcode; i++)
     {
       Tex_font_char_metric tfm_char = read_char_metric (i);
       if (tfm_char.exists_b_)
-	tfm_l_->ascii_to_metric_idx_[tfm_char.code_] = tfm_l_->char_metrics_.size ();
-      tfm_l_->char_metrics_.push (tfm_char);
+	ascii_to_metric_idx_[tfm_char.code_] = char_metrics_.size ();
+      char_metrics_.push (tfm_char);
     }
 }
 
@@ -196,12 +186,12 @@ Tex_font_metric_reader::read_char_metric (Char_code code)
 
   /* If the character is outside the declared bounds in the file, don't
      try to read it. */
-  if (code < tfm_l_->info_.first_charcode || code > tfm_l_->info_.last_charcode)
+  if (code < info_.first_charcode || code > info_.last_charcode)
     return tfm_char;
   
   //brr
   /* Move to the appropriate place in the `char_info' array.  */
-  input_.seek_ch_C (tfm_l_->header_.char_info_pos + (code - tfm_l_->info_.first_charcode) * 4);
+  input_.seek_ch_C (header_.char_info_pos + (code - info_.first_charcode) * 4);
 
   /* Read the character.  */
   tfm_char = read_char ();
@@ -239,10 +229,10 @@ Tex_font_metric_reader::read_char ()
 #define GET_CHAR_DIMEN(d) \
    if (d##_index != 0) \
      { \
-       input_.seek_ch_C (tfm_l_->header_.##d##_pos + d##_index*4); \
+       input_.seek_ch_C (header_.##d##_pos + d##_index*4); \
        tfm_char.d##_fix_ = input_.get_U32 (); \
        tfm_char.d##_ = fix_to_real (tfm_char.d##_fix_) \
-                      * tfm_l_->info_.design_size; \
+                      * info_.design_size; \
      }
 
   GET_CHAR_DIMEN (width);
@@ -265,7 +255,7 @@ Tex_font_metric_reader::read_char ()
 
   if (tag == 1)
     {
-      input_.seek_ch_C (tfm_l_->header_.lig_kern_pos + remainder * 4);
+      input_.seek_ch_C (header_.lig_kern_pos + remainder * 4);
       read_lig_kern_program (&tfm_char.ligature_arr_, &tfm_char.kern_arr_);
     }
 
@@ -303,7 +293,7 @@ Tex_font_metric_reader::read_lig_kern_program (Array <Tfm_ligature>* ligature_ar
 	  kern_element.character = next_char;
 
 	  char const* old_pos = input_.pos_ch_C ();
-	  input_.seek_ch_C (tfm_l_->header_.kern_pos + remainder * 4);
+	  input_.seek_ch_C (header_.kern_pos + remainder * 4);
 	  kern_element.kern = get_U32_fix_scaled_f ();
 	  input_.set_pos (old_pos);
 
diff --git a/lily/tfm.cc b/lily/tfm.cc
index 982b357300..7b6f008527 100644
--- a/lily/tfm.cc
+++ b/lily/tfm.cc
@@ -57,6 +57,7 @@ Tex_font_metric::Tex_font_metric ()
 {
 }
 
+
 static Tex_font_char_metric dummy_static_char_metric;
 
 Tex_font_char_metric const *
@@ -89,11 +90,19 @@ Tex_font_metric::str () const
   return outstr;
 }
 
-void
-Tex_font_metric::clear (int n)
-{
-  for (int i=0; i < n; i++)
-    ascii_to_metric_idx_.push (-1);
-}
 
 
+
+SCM
+Tex_font_metric::make_tfm (String fn)
+{
+  Tex_font_metric	* tfm_p = new Tex_font_metric;
+  Tex_font_metric_reader reader (fn);
+
+  tfm_p->info_ = reader.info_;
+  tfm_p->header_ = reader.header_;
+  tfm_p->char_metrics_ = reader.char_metrics_;
+  tfm_p->ascii_to_metric_idx_ = reader.ascii_to_metric_idx_;
+  
+  return tfm_p->smobbed_self ();
+}
diff --git a/lily/tie-engraver.cc b/lily/tie-engraver.cc
index aa3180f7f6..68121fb2bb 100644
--- a/lily/tie-engraver.cc
+++ b/lily/tie-engraver.cc
@@ -156,8 +156,8 @@ Tie_engraver::process_acknowledged ()
 	    }
 	  else
 	    {
-	      head_list  = gh_cons (gh_cons (stopped_heads_[j].head_l_->self_scm_,
-					     now_heads_[i].head_l_->self_scm_),
+	      head_list  = gh_cons (gh_cons (stopped_heads_[j].head_l_->self_scm (),
+					     now_heads_[i].head_l_->self_scm ()),
 				    head_list);
 
 	      past_notes_pq_. insert (now_heads_[i]);
@@ -250,8 +250,8 @@ Tie_engraver::typeset_tie (Score_element *her)
       new_head_drul[d] = Tie::head(her,(Direction)-d);
   } while (flip(&d) != LEFT);
 
-  index_set_cell (her->get_elt_property ("heads"), LEFT, new_head_drul[LEFT]->self_scm_ );
-  index_set_cell (her->get_elt_property ("heads"), RIGHT, new_head_drul[RIGHT]->self_scm_ );
+  index_set_cell (her->get_elt_property ("heads"), LEFT, new_head_drul[LEFT]->self_scm () );
+  index_set_cell (her->get_elt_property ("heads"), RIGHT, new_head_drul[RIGHT]->self_scm () );
 
   typeset_element (her);
 }
diff --git a/lily/tie.cc b/lily/tie.cc
index 4eae4439cb..2b214131b1 100644
--- a/lily/tie.cc
+++ b/lily/tie.cc
@@ -38,7 +38,7 @@ void
 Tie::set_head (Score_element*me,Direction d, Item * head_l)
 {
   assert (!head (me,d));
-  index_set_cell (me->get_elt_property ("heads"), d, head_l->self_scm_);
+  index_set_cell (me->get_elt_property ("heads"), d, head_l->self_scm ());
   
   dynamic_cast<Spanner*> (me)->set_bound (d, head_l);
   me->add_dependency (head_l);
diff --git a/lily/timing-translator.cc b/lily/timing-translator.cc
index 762ac771ba..ab453e5a45 100644
--- a/lily/timing-translator.cc
+++ b/lily/timing-translator.cc
@@ -75,12 +75,11 @@ Timing_translator::do_process_music()
 	{
 	  if (measure_position ())
 	    {
+	      Moment nm; 
 	      tr_l ->origin ()->warning (_f ("barcheck failed at: %s", 
 				  measure_position ().str ()));
 	      // resync
-	      daddy_trans_l_->set_property("measurePosition",
-					   smobify (new Moment));
-
+	      daddy_trans_l_->set_property("measurePosition", nm.make_scm ());
 	    }
 	}
     }
@@ -122,11 +121,12 @@ ADD_THIS_TRANSLATOR(Timing_translator);
 void
 Timing_translator::do_creation_processing()
 {
+  Moment m;
   daddy_trans_l_->set_property ("timing" , SCM_BOOL_T);  
   daddy_trans_l_->set_property ("currentBarNumber" , gh_int2scm (1));
-  daddy_trans_l_->set_property ("measurePosition", smobify (new Moment));
-  daddy_trans_l_->set_property ("beatLength", smobify (new Moment (1,4)));
-  daddy_trans_l_->set_property ("measureLength", smobify (new Moment (1)));
+  daddy_trans_l_->set_property ("measurePosition", m.make_scm ());
+  daddy_trans_l_->set_property ("beatLength", Moment (1,4).make_scm ());
+  daddy_trans_l_->set_property ("measureLength",  Moment (1).make_scm());
 }
 
 Moment
@@ -145,8 +145,8 @@ Timing_translator::set_time_signature (int l, int o)
 {
   Moment one_beat = Moment (1)/Moment (o);
   Moment len = Moment (l) * one_beat;
-  daddy_trans_l_->set_property ("measureLength", smobify (new Moment (len)));
-  daddy_trans_l_->set_property ("beatLength", smobify (new Moment (one_beat)));
+  daddy_trans_l_->set_property ("measureLength", len.make_scm ());
+  daddy_trans_l_->set_property ("beatLength", one_beat.make_scm ());
 }
 
 Timing_translator::Timing_translator()
@@ -160,9 +160,9 @@ Timing_translator::measure_position () const
   SCM sm = get_property ("measurePosition");
   
   Moment m   =0;
-  if (SMOB_IS_TYPE_B (Moment, sm))
+  if (unsmob_moment (sm))
     {
-      m = *SMOB_TO_TYPE (Moment, sm);
+      m = *unsmob_moment(sm);
       while (m < Moment (0))
 	m += measure_length ();
     }
@@ -192,21 +192,19 @@ Timing_translator::do_post_move_processing()
   if (!dt)
     return;
 
-  Moment * measposp =0;
+  Moment measposp;
 
   SCM s = get_property ("measurePosition");
-  if (SMOB_IS_TYPE_B (Moment, s))
+  if (unsmob_moment (s))
     {
-      measposp = SMOB_TO_TYPE (Moment,s);
+      measposp = *unsmob_moment(s);
     }
   else
     {
-      measposp = new Moment;
-      daddy_trans_l_->set_property ("measurePosition", smobify (measposp));
+      daddy_trans_l_->set_property ("measurePosition", measposp.make_scm());
     }
   
-  *measposp += dt;
-  // don't need to set_property
+  measposp += dt;
   
   SCM barn = get_property ("currentBarNumber");
   int b = 0;
@@ -219,12 +217,13 @@ Timing_translator::do_post_move_processing()
   bool c= to_boolean (cad );
 
   Moment len = measure_length ();
-  while (c && *measposp >= len)
-      {
-	*measposp -= len;
-	b ++;
-      }
+  while (c && measposp >= len)
+    {
+      measposp -= len;
+      b ++;
+    }
 
   daddy_trans_l_->set_property ("currentBarNumber", gh_int2scm (b));
+  daddy_trans_l_->set_property ("measurePosition", measposp.make_scm());
 }
 
diff --git a/lily/translator-group.cc b/lily/translator-group.cc
index 4303d0cbf4..8d92fb8ac1 100644
--- a/lily/translator-group.cc
+++ b/lily/translator-group.cc
@@ -28,7 +28,7 @@ Translator_group::~Translator_group ()
 {
   assert (removable_b());
   trans_p_list_.junk ();
-  delete properties_dict_;
+  scm_unprotect_object (properties_dict_->self_scm ());
 }
 
 
@@ -358,7 +358,7 @@ Translator_group::do_print() const
   if (!flower_dstream)
     return ;
 
-  gh_display (properties_dict_->self_scm_);
+  gh_display (properties_dict_->self_scm ());
   if (status == ORPHAN)
     {
       DEBUG_OUT << "consists of: ";
diff --git a/ly/declarations.ly b/ly/declarations.ly
index ec640fb578..408a512e26 100644
--- a/ly/declarations.ly
+++ b/ly/declarations.ly
@@ -1,17 +1,29 @@
-
+#(gc)
   
 breve = \duration #'( -1 0)
 longa = \duration #'( -2 0 )
 maxima = \duration #'( -3 0 )
 
+#(gc)
+
 #(eval-string (ly-gulp-file "generic-property.scm"))
 
+#(gc)
+
 % urg, move to basic property?
 #(eval-string (ly-gulp-file "slur.scm"))
 
+#(gc)
+
 \include "nederlands.ly"		% dutch
+
+#(gc)
+
 \include "chord-modifiers.ly"
+#(gc)
+
 \include "script.ly"
+#(gc)
 
 
 % declarations for standard directions
diff --git a/ly/engraver.ly b/ly/engraver.ly
index b9bbb9fb10..d189cae32a 100644
--- a/ly/engraver.ly
+++ b/ly/engraver.ly
@@ -264,13 +264,15 @@ StaffGroupContext= \translator {
 LyricsVoiceContext= \translator{
 	\type "Engraver_group_engraver";
 	\consistsend "Axis_group_engraver";
-	LyricVoiceMinimumVerticalExtent = #(cons -2.5 2.5)
+	LyricVoiceMinimumVerticalExtent = #(cons -1.2 1.2)
 
 	\name LyricVoice ;
 	\consists "Separating_line_group_engraver";
 	\consists "Lyric_engraver";
 	\consists "Extender_engraver";
 	\consists "Hyphen_engraver";
+
+	phrasingPunctuation = #".,;:!?"
 };
 \translator{ \LyricsVoiceContext }
 
@@ -376,6 +378,10 @@ ScoreContext = \translator {
 	\consists "Spacing_engraver";
 
 	\consists "Vertical_align_engraver";
+
+	\consists "Lyric_phrasing_engraver";
+        automaticPhrasing = ##f;
+
 	\consists "Bar_number_engraver";
 	alignmentReference = \down;
 	defaultClef = #"treble"
@@ -536,7 +542,7 @@ ScoreContext = \translator {
 		(molecule-callback . ,Text_item::brew_molecule)
 		(self-alignment-X . 0)
 		(non-rhythmic . #t)
-		(interfaces .  (text-item-interface))
+		(interfaces .  (lyric-syllable-interface text-item-interface))
 	)
 	basicMarkProperties = #`(
 	  (molecule-callback . ,Text_item::brew_molecule)	
diff --git a/ly/init.ly b/ly/init.ly
index 41308ac2cf..b7d9ee49b5 100644
--- a/ly/init.ly
+++ b/ly/init.ly
@@ -1,5 +1,6 @@
 % Toplevel initialisation file. 
 
+
 \version "1.3.59";
 
 \include "declarations.ly";
diff --git a/make/out/lilypond.lsm b/make/out/lilypond.lsm
index e7e6b811eb..cae88b51f5 100644
--- a/make/out/lilypond.lsm
+++ b/make/out/lilypond.lsm
@@ -1,15 +1,15 @@
 Begin3
 Title: LilyPond
-Version: 1.3.73
-Entered-date: 17JUL00
+Version: 1.3.74
+Entered-date: 19JUL00
 Description: 
 Keywords: music notation typesetting midi fonts engraving
 Author: hanwen@cs.uu.nl (Han-Wen Nienhuys)
 	janneke@gnu.org (Jan Nieuwenhuizen)
 Maintained-by: hanwen@stack.nl (Han-Wen Nienhuys)
 Primary-site: sunsite.unc.edu /pub/Linux/apps/sound/convert
-	1000k lilypond-1.3.73.tar.gz 
+	1000k lilypond-1.3.74.tar.gz 
 Original-site: ftp.cs.uu.nl /pub/GNU/LilyPond/development/
-	1000k lilypond-1.3.73.tar.gz 
+	1000k lilypond-1.3.74.tar.gz 
 Copying-policy: GPL
 End
diff --git a/make/out/lilypond.spec b/make/out/lilypond.spec
index 37f6140aac..d7d2b3f088 100644
--- a/make/out/lilypond.spec
+++ b/make/out/lilypond.spec
@@ -1,9 +1,9 @@
 Name: lilypond
-Version: 1.3.73
+Version: 1.3.74
 Release: 1
 Copyright: GPL
 Group: Applications/Publishing
-Source0: ftp.cs.uu.nl:/pub/GNU/LilyPond/development/lilypond-1.3.73.tar.gz
+Source0: ftp.cs.uu.nl:/pub/GNU/LilyPond/development/lilypond-1.3.74.tar.gz
 Summary: A program for printing sheet music.
 URL: http://www.cs.uu.nl/~hanwen/lilypond
 # Icon: lilypond-icon.gif