diff -r -u -X .ignore gnugo-copy/engine/board.c gnugo/engine/board.c
--- gnugo-copy/engine/board.c	2006-12-30 20:59:01.109375000 +0100
+++ gnugo/engine/board.c	2007-01-02 19:48:48.906250000 +0100
@@ -2,7 +2,7 @@
  * This is GNU Go, a Go program. Contact gnugo@gnu.org, or see       *
  * http://www.gnu.org/software/gnugo/ for more information.          *
  *                                                                   *
- * Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2005 and 2006       *
+ * Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006 and 2007 *
  * by the Free Software Foundation.                                  *
  *                                                                   *
  * This program is free software; you can redistribute it and/or     *
@@ -1778,7 +1778,7 @@
   liberties = string[str_nr].liberties;
   to_copy = maxlib > liberties ? liberties : maxlib;
 
-  if (liberties <= MAX_LIBERTIES || maxlib <= MAX_LIBERTIES) {
+  if (to_copy <= MAX_LIBERTIES) {
     /* The easy case, it suffices to copy liberty locations from the
      * incrementally updated list.
      */
diff -r -u -X .ignore gnugo-copy/engine/unconditional.c gnugo/engine/unconditional.c
--- gnugo-copy/engine/unconditional.c	2006-12-30 21:48:42.703125000 +0100
+++ gnugo/engine/unconditional.c	2007-01-02 19:53:46.187500000 +0100
@@ -2,7 +2,7 @@
  * This is GNU Go, a Go program. Contact gnugo@gnu.org, or see       *
  * http://www.gnu.org/software/gnugo/ for more information.          *
  *                                                                   *
- * Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2005 and 2006       *
+ * Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006 and 2007 *
  * by the Free Software Foundation.                                  *
  *                                                                   *
  * This program is free software; you can redistribute it and/or     *
@@ -41,7 +41,7 @@
 {
   int other = OTHER_COLOR(color);
   int something_captured = 1; /* To get into the first turn of the loop. */
-  int string_found = 0;
+  int invincible_found = 0;
   int moves_played = 0;
   int save_moves;
   int libs[MAXLIBS];
@@ -53,26 +53,20 @@
     /* Nothing captured so far in this turn of the loop. */
     something_captured = 0;
 
-    /* Is there something left to try to capture? */
-    string_found = 0;
+    /* If we found any invincible string in this turn of the loop. */
+    invincible_found = 0;
     
     /* Visit all friendly strings on the board. */
     for (pos = BOARDMIN; pos < BOARDMAX; pos++) {
-      if (board[pos] != color || find_origin(pos) != pos)
+      if (board[pos] != color || find_origin(pos) != pos
+	  || exceptions[pos])
 	continue;
 
-      if (exceptions && exceptions[pos])
-	continue;
-
-      string_found = 1;
-      
       /* Try to capture the string at pos. */
       liberties = findlib(pos, MAXLIBS, libs);
       save_moves = moves_played;
-      for (k = 0; k < liberties; k++) {
-	if (trymove(libs[k], other, "unconditional_life", pos))
-	  moves_played++;
-      }
+      for (k = 0; k < liberties; k++)
+	moves_played += trymove(libs[k], other, "unconditional_life", pos);
       
       /* Successful if already captured or a single liberty remains.
        * Otherwise we must rewind and take back the last batch of moves.
@@ -96,16 +90,19 @@
 	moves_played++;
 	something_captured = 1;
       }
-      else
+      else {
+	invincible_found = 1;
+
 	while (moves_played > save_moves) {
 	  popgo();
 	  moves_played--;
 	}
+      }
     }
   }
 
   if (none_invincible)
-    *none_invincible = !string_found;
+    *none_invincible = !invincible_found;
   
   return moves_played;
 }
@@ -148,15 +145,28 @@
  * 4. Play an opponent stone anywhere it can get one empty
  *    neighbor. (I.e. reduce two space eyes to one space eyes.)
  *
- * Remaining opponent strings in atari and remaining liberties of the
- * unconditionally alive strings constitute the unconditional
- * territory.
+ * Remaining opponent strings in atari (and its only liberty) and
+ * remaining liberties of the unconditionally alive strings constitute
+ * the unconditional territory.
  *
  * Opponent strings from the initial position placed on
  * unconditional territory are unconditionally dead.
  *
  * - - - - - - -
  *
+ * Step 2 is done, because of such position (we have to extend a stone
+ * in atari before reducing an eyespace):
+ *
+ * OOXOO
+ * OX.XO
+ * OX.XO
+ * OXXXO
+ * OX.XO
+ * OXXXO
+ * OOOOO
+ *
+ * - - - - - - -
+ *
  * The deficiency with this algorithm is that a certain class of sekis
  * are considered as dead, e.g. this position:
  *
@@ -183,7 +193,7 @@
  * 1. Run algorithm 1.
  * 2. Return to the original position.
  * 3. Capture all capturable O strings which according to algorithm 1
- *    do not belong to unconditional territory.
+ *    do belong to unconditional territory.
  * 4. Play opponent stones on all liberties of the unconditionally
  *    alive strings except where illegal. (That the move order may
  *    determine exactly which liberties can be played legally is not
@@ -197,9 +207,9 @@
  * 9. Play an opponent stone anywhere it can get one empty
  *    neighbor. (I.e. reduce two space eyes to one space eyes.)
  *
- * Remaining opponent strings in atari and remaining liberties of the
- * unconditionally alive strings constitute the unconditional
- * territory.
+ * Remaining opponent strings in atari (and its only liberty) and
+ * remaining liberties of the unconditionally alive strings constitute
+ * the unconditional territory.
  *
  * Opponent strings from the initial position placed on
  * unconditional territory are unconditionally dead.
@@ -263,8 +273,8 @@
  * .OXXXOO
  * .OOOOO.
  *
- * belong to different strings for the dead groups and to the same
- * string for the seki groups.
+ * which belong to different strings for the dead groups and to the
+ * same string for the seki groups.
  *
  * The trick to avoid misclassifying areas where the opponent can form
  * a seki group but not an invincible group as unconditional territory
@@ -296,9 +306,9 @@
  * 10. Play an opponent stone anywhere it can get one empty
  *    neighbor. (I.e. reduce two space eyes to one space eyes.)
  *
- * Remaining opponent strings in atari and remaining liberties of the
- * unconditionally alive strings constitute the unconditional
- * territory.
+ * Remaining opponent strings in atari (and its only liberty) and
+ * remaining liberties of the unconditionally alive strings constitute
+ * the unconditional territory.
  *
  * Opponent strings from the initial position placed on
  * unconditional territory are unconditionally dead.
@@ -313,7 +323,6 @@
 void
 unconditional_life(int unconditional_territory[BOARDMAX], int color)
 {
-  int found_one;
   int other = OTHER_COLOR(color);
   int libs[MAXLIBS];
   int liberties;
@@ -335,6 +344,7 @@
     int isolated = 1;
     int stones[2];
     int pos2;
+    int checked_stone;
     
     if (board[pos] != color
 	|| find_origin(pos) != pos
@@ -343,8 +353,9 @@
     
     findstones(pos, 2, stones);
     for (k = 0; k < 2 && isolated; k++) {
+      checked_stone = stones[k];
       for (r = 0; r < 8; r++) {
-	pos2 = stones[k] + delta[r];
+	pos2 = checked_stone + delta[r];
 	if (!ON_BOARD(pos2)
 	    || (board[pos2] == color
 		&& !same_string(pos, pos2)))
@@ -384,35 +395,30 @@
    *    alive strings except where illegal.
    */
   for (pos = BOARDMIN; pos < BOARDMAX; pos++) {
-    if (board[pos] != color || potential_sekis[pos] || find_origin(pos) != pos)
+    if (board[pos] != color || find_origin(pos) != pos || potential_sekis[pos])
       continue;
       
     /* Play as many liberties as we can. */
     liberties = findlib(pos, MAXLIBS, libs);
     for (k = 0; k < liberties; k++) {
-      if (trymove(libs[k], other, "unconditional_life", pos))
-	moves_played++;
+      moves_played += trymove(libs[k], other, "unconditional_life", pos);
     }
   }
 
   /* 2. Recursively extend opponent strings in atari, except where this
    *    would be suicide.
    */
-  found_one = 1;
-  while (found_one) {
-    /* Nothing found so far in this turn of the loop. */
-    found_one = 0;
-
-    for (pos = BOARDMIN; pos < BOARDMAX; pos++) {
-      if (board[pos] != other || countlib(pos) > 1)
-	continue;
+  for (pos = BOARDMIN; pos < BOARDMAX; pos++) {
+    if (board[pos] != other)
+      continue;
 	
-      /* Try to extend the string at (m, n). */
+    /* Try to extend the string. */
+    while (countlib(pos) == 1) {
       findlib(pos, 1, libs);
-      if (trymove(libs[0], other, "unconditional_life", pos)) {
+      if (trymove(libs[0], other, "unconditional_life", pos))
 	moves_played++;
-	found_one = 1;
-      }
+      else
+	break;
     }
   }
 
@@ -422,6 +428,8 @@
 	|| board[pos] == EMPTY
 	|| find_origin(pos) != pos)
       continue;
+
+    /* Try different rotations. */
     for (r = 0; r < 4; r++) {
       int up = delta[r];
       int right = delta[(r + 1) % 4];
@@ -432,15 +440,15 @@
 	continue;
       for (k = 0; k < 2; k++) {
 	if (k == 1)
-	  right = -right;
+	  right = -right; /* Try a mirror reflection. */
 	if (board[pos + right] != EMPTY || board[pos + up - right] != EMPTY)
 	  continue;
-	if (board[pos - right] == EMPTY
-	    && trymove(pos - right, other, "unconditional_life", pos))
-	  locally_played_moves++;
-	if (board[pos + up + right] == EMPTY
-	    && trymove(pos + up + right, other, "unconditional_life", pos))
-	  locally_played_moves++;
+	if (board[pos - right] == EMPTY)
+	  locally_played_moves += trymove(pos - right, other,
+					  "unconditional_life", pos);
+	if (board[pos + up + right] == EMPTY)
+	  locally_played_moves += trymove(pos + up + right, other,
+					  "unconditional_life", pos);
 	if (board[pos - right] == other && board[pos + up + right] == other
 	    && same_string(pos - right, pos + up + right)) {
 	  /* This is a critical seki. Extend the string with one stone
@@ -450,8 +458,7 @@
 	    popgo();
 	    locally_played_moves--;
 	  }
-	  trymove(pos - up, color, "unconditional_life", pos);
-	  moves_played++;
+	  moves_played += trymove(pos - up, color, "unconditional_life", pos);
 	  break;
 	}
 	else {
@@ -472,13 +479,16 @@
       continue;
     /* Play as many liberties as we can. */
     liberties = findlib(pos, MAXLIBS, libs);
-    for (k = 0; k < liberties; k++) {
-      if (trymove(libs[k], other, "unconditional_life", pos))
-	moves_played++;
-    }
+    for (k = 0; k < liberties; k++)
+      moves_played += trymove(libs[k], other, "unconditional_life", pos);
   }
     
-
+  /* All opponent strings liberties are now inside opponent territory
+     (due to step 4.). If any string has 3 or more liberties, it is alive
+     (2 eyes can be made). If a string has 1 liberty it must be in atari, so
+     is dead (because we tried to extend strings in atari in step 5.). We
+     only have to check strings, which have 2 liberties. This operations
+     are made instead 9. and 10. step of the algorithm. */
   for (pos = BOARDMIN; pos < BOARDMAX; pos++) {
     int apos;
     int bpos;
@@ -493,11 +503,12 @@
       continue;
     
     /* Only two liberties and these are adjacent. Play one. We want
-     * to maximize the number of open liberties. In this particular
-     * situation we can count this with approxlib for the opposite
-     * color. If the number of open liberties is the same, we
-     * maximize the total number of obtained liberties.
-     * Two relevant positions:
+     * to maximize the number of neighboring liberties (to split an
+     * eyespace). In this particular situation we can count this with
+     * approxlib for the opposite color. If the number of neighboring
+     * liberties is the same, we maximize the total number of obtained
+     * liberties. Two relevant positions (we want to make 2 eyes for
+     * these O groups):
      *
      * |XXX. 
      * |OOXX    |XXXXXXX
@@ -510,14 +521,10 @@
     alib  = approxlib(apos, other, 4, NULL);
     blib  = approxlib(bpos, other, 4, NULL);
     
-    if (aopen > bopen || (aopen == bopen && alib >= blib)) {
-      trymove(apos, other, "unconditional_life", pos);
-      moves_played++;
-    }
-    else {
-      trymove(bpos, other, "unconditional_life", pos);
-      moves_played++;
-    }
+    if (aopen > bopen || (aopen == bopen && alib >= blib))
+      moves_played += trymove(apos, other, "unconditional_life", pos);
+    else
+      moves_played += trymove(bpos, other, "unconditional_life", pos);
   }
   
   /* Identify unconditionally alive stones and unconditional territory. */
@@ -532,8 +539,10 @@
     }
     else if (board[pos] == other && countlib(pos) == 1) {
       unconditional_territory[pos] = 2;
-      findlib(pos, 1, libs);
-      unconditional_territory[libs[0]] = 2;
+      if (find_origin(pos) == pos) {
+        findlib(pos, 1, libs);
+        unconditional_territory[libs[0]] = 2;
+      }
     }
   }
   
diff -r -u -X .ignore gnugo-copy/engine/worm.c gnugo/engine/worm.c
--- gnugo-copy/engine/worm.c	2006-12-31 17:20:32.093750000 +0100
+++ gnugo/engine/worm.c	2007-01-02 20:02:58.859375000 +0100
@@ -2,7 +2,7 @@
  * This is GNU Go, a Go program. Contact gnugo@gnu.org, or see       *
  * http://www.gnu.org/software/gnugo/ for more information.          *
  *                                                                   *
- * Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2005 and 2006       *
+ * Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006 and 2007 *
  * by the Free Software Foundation.                                  *
  *                                                                   *
  * This program is free software; you can redistribute it and/or     *
@@ -712,6 +712,7 @@
   
   for (color = WHITE; color <= BLACK; color++) {
     unconditional_life(unconditional_territory, color);
+    gg_assert(stackp == 0);
 
     for (pos = BOARDMIN; pos < BOARDMAX; pos++) {
       if (!ON_BOARD(pos) || !unconditional_territory[pos])
@@ -732,7 +733,6 @@
 	worm[pos].unconditional_status = DEAD;
     }
   }
-  gg_assert(stackp == 0);
 }
 
 /*

