diff -up lineage/lineage.module lineage-new/lineage.module
--- lineage/lineage.module	2009-10-25 10:10:58.000000000 -0500
+++ lineage-new/lineage.module	2009-10-25 10:04:04.000000000 -0500
@@ -160,8 +160,30 @@ function lineage_update_all($vid=false) 
   return $count;
 }
 
-function lineage_update_term($term) {
+function lineage_update_term($term,$all=false) {
   if (is_array($term)) $term = (object) $term;
+
+  // If we are in the middle of updating all lineages, skip this.
+  if (!$all) {
+    // Select lineage for a different term in this vocab arbitrarily.
+    $r = db_query("
+         SELECT tl.`lineage`, td.tid, td.name, td.weight, td.vid, th.parent 
+         FROM {term_data} td
+         LEFT JOIN {term_lineage} tl ON tl.tid=td.tid 
+         LEFT JOIN {term_hierarchy} th ON td.tid = th.tid 
+         WHERE td.vid='%d' AND td.tid<>'%d' LIMIT 1;",$term->vid,$term->tid); 
+
+    $other_term = db_fetch_object($r);
+
+    // If the lineage string doesn't match what we think it should be, 
+    // an update is required.
+    if ($other_term->lineage != lineage_string($other_term)) {
+      $count = lineage_update_all($term->vid);
+      return $count;
+    }
+  }
+
+  // Else, just update this term.
   $base = _lineage_get_parent_lineage($term->parent);
   return count(lineage_update_term_r($term, $base));
 }
@@ -179,7 +201,7 @@ function lineage_update_term_r($term, $b
   $tids[$term->tid] = true;
 
   // Update all the children.
-  $result = db_query("SELECT td.tid, td.name, td.weight FROM {term_hierarchy} th LEFT JOIN {term_data} td ON td.tid = th.tid WHERE th.parent = '%d'", $term->tid);
+  $result = db_query("SELECT td.tid, td.name, td.weight, td.vid FROM {term_hierarchy} th LEFT JOIN {term_data} td ON td.tid = th.tid WHERE th.parent = '%d'", $term->tid);
   while ($child = db_fetch_object($result)) {
     // loop protection, just in case.
     if (!isset($tids[$child->tid])) {
@@ -194,13 +216,14 @@ function lineage_delete_term($tid) {
 }
 
 function lineage_string($term) {
-  // add 10 to the weight cause negative numbers don't sort the same
-  // in strong form as they do numerically.
-  return sprintf("%02d", $term->weight + 10) . $term->name . "\n";
+  // Ensure positive weights with enough digits so that all sort properly.
+  $w = _lineage_weights($term->vid);
+  return sprintf("%0".$w['digits']."d", $term->weight + $w['offset']) 
+    . "-" . $term->name . "\n";
 }
 
 function _lineage_get_parent_lineage($tid) {
-  $result = db_query("SELECT td.tid, td.name, td.weight, th.parent FROM {term_hierarchy} th LEFT JOIN {term_data} td ON td.tid = th.tid WHERE td.tid = '%d'", $tid);
+  $result = db_query("SELECT td.tid, td.name, td.weight, td.vid, th.parent FROM {term_hierarchy} th LEFT JOIN {term_data} td ON td.tid = th.tid WHERE td.tid = '%d'", $tid);
 
   if ($term = db_fetch_object($result)) {
     $ret = _lineage_get_parent_lineage($term->parent);
@@ -223,3 +246,30 @@ function lineage_views_api() {
   );
 }
 
+
+/**
+ * Determine how many digits to use in weights.
+ * @param vid the vocabulary.
+ * @return array of min weight, max weight, offset to use, and # digits.
+ */
+function _lineage_weights($vid) {
+  // Keep static array with weight info to prevent unneeded queries.
+  static $weights = array();
+
+  if (!isset($weights[$vid])) {
+    $min_r = db_query("SELECT MIN(`weight`) FROM {term_data} WHERE `vid` = '%d'",$vid);
+    $weights[$vid]['min'] = db_result($min_r);
+    $weights[$vid]['offset'] = 
+      ($weights[$vid]['min'] < 0) ? abs($weights[$vid]['min']) : 0;
+    
+    $max_r = db_query("SELECT MAX(`weight`) FROM {term_data} WHERE `vid` = '%d'",$vid);
+    $weights[$vid]['max'] = db_result($max_r);
+    $weights[$vid]['digits'] = 
+      floor(log($weights[$vid]['max']+$weights[$vid]['offset']+1));
+    if ($weights[$vid]['digits'] == 0) {
+      $weights[$vid]['digits']++;
+    }
+  }
+
+  return $weights[$vid];
+}
\ No newline at end of file
diff -up lineage/lineage_handler_field.inc lineage-new/lineage_handler_field.inc
--- lineage/lineage_handler_field.inc	2008-09-05 02:15:48.000000000 -0500
+++ lineage-new/lineage_handler_field.inc	2009-10-25 10:05:24.000000000 -0500
@@ -10,7 +10,7 @@ class lineage_handler_field extends view
     if ($content == '') return '';
 
     // split lineage string into pieces, i.e. hierarchial path (getting rid of weight numbers, too)
-    $path = split("\n[0-9]+", "\n".$content);
+    $path = preg_split("(\n[0-9]+-)", "\n".$content);
     $s = '';
     // compose the path in readable form
     foreach ($path as $a) {
