diff -N -r -u -X .ignore gnugo-copy/engine/owl.c gnugo/engine/owl.c
--- gnugo-copy/engine/owl.c	2007-01-22 23:48:10.703125000 +0100
+++ gnugo/engine/owl.c	2007-01-22 22:01:30.234375000 +0100
@@ -670,6 +670,7 @@
   struct eyevalue probable_eyes_a;
   struct eyevalue probable_eyes_b;
   struct eyevalue dummy_eyes;
+  int I_have_more_eyes;
   
   SETUP_TRACE_INFO2("do_owl_analyze_semeai", apos, bpos);
 
@@ -804,6 +805,7 @@
   if (!owl_phase) {
     set_eyevalue(&probable_eyes_a, 0, 0, 0, 0);
     set_eyevalue(&probable_eyes_b, 0, 0, 0, 0);
+    I_have_more_eyes = 0;
   }
   else {
     /* First the vital moves. These include moves to attack or
@@ -893,13 +895,60 @@
 				     shape_defensive_moves, 1, owla))
 	  break;
     }
+    else
+      shape_defensive_moves[0].pos = 0;
+
     owl_shapes(&shape_offensive_patterns, shape_offensive_moves, color, owlb, 
 	       &owl_attackpat_db);
     for (k = 0; k < MAX_MOVES-1; k++)
       if (!get_next_move_from_list(&shape_offensive_patterns, color,
 	                           shape_offensive_moves, 1, owla))
 	break;
-    
+
+    /* Filter out moves, which fills our eye (and not split it). */
+    if (eyemax_a == 1) {
+      int n;
+      struct owl_move_data *checked_moves;
+
+      for (n = 1; n <= 5; n++) {
+	switch (n) {
+	case 1:
+	  checked_moves = moves;
+	  break;
+	case 2:
+	  checked_moves = vital_defensive_moves;
+	  break;
+	case 3:
+	  checked_moves = vital_offensive_moves;
+	  break;
+	case 4:
+	  checked_moves = shape_defensive_moves;
+	  break;
+	case 5:
+	  checked_moves = shape_offensive_moves;
+	  break;
+	}
+
+	for (k = 0; k < MAX_MOVES; k++) {
+	  if (checked_moves[k].pos <= 0)
+	    break;
+	  else {
+	    struct eye_data *eye = &owla->my_eye[checked_moves[k].pos];
+
+	    /* If esize==1 this eye must not be a real eye (at least one
+	     * worm is capturable, otherwise this move would not be
+	     * proposed).
+	     */
+	    if (eye->color == color && eye->msize == 0 && eye->neighbors <= 1
+		&& eye->esize != 1
+		&& owla->half_eye[checked_moves[k].pos].type != HALF_EYE
+		&& !has_neighbor(checked_moves[k].pos, OTHER_COLOR(color)))
+	      checked_moves[k].value = 0;
+	  }
+	}
+      }
+    }
+
     /* Now we review the moves already considered, while collecting
      * them into a single list. 
      */
@@ -954,6 +1003,21 @@
       include_semeai_worms_in_eyespace = 0;
     }
 
+    if (eyemin_a == eyemax_a)
+      /* We have stable number of eyes, so we can try to reduce
+       * opponent eyes. */
+      I_have_more_eyes = (eyemin_a > min_eyes(&probable_eyes_b));
+    else {
+      if (min_eyes(&probable_eyes_a) == max_eyes(&probable_eyes_a))
+        /* If we can't increase our number of eyes, we try to reduce
+	 * opponent eyes. */
+        I_have_more_eyes = (max_eyes(&probable_eyes_a) > min_eyes(&probable_eyes_b));
+      else
+        /* If we can increase our number of eyes, we do it and let
+	 * opponent to increase his. */
+        I_have_more_eyes = (max_eyes(&probable_eyes_a) > max_eyes(&probable_eyes_b));
+    }
+
     if (get_level() < 8) {
       /* If no owl moves were found on two consecutive moves,
        * turn off the owl phase.
@@ -977,13 +1041,15 @@
   
   /* Now we look for a move to fill a liberty. This is only
    * interesting if the opponent doesn't already have two eyes.
+   * If we have more eyes, always check for a backfilling move.
    */
   if (!you_look_alive
-      && !safe_outside_liberty_found && moves[0].value < 110) {
+      && !safe_outside_liberty_found
+      && (moves[0].value < 110 || I_have_more_eyes)) {
     int pos;
     for (pos = BOARDMIN; pos < BOARDMAX; pos++) {
       if (!ON_BOARD(pos))
-	continue;
+        continue;
       
       if (board[pos] == EMPTY && !mw[pos]) {
 	if (liberty_of_goal(pos, owlb)) {
@@ -995,8 +1061,8 @@
 	      break;
 	    }
 	    else if (backfill_outside_liberty.pos == NO_MOVE)
-	      backfill_outside_liberty.pos = find_semeai_backfilling_move(bpos,
-									  pos);
+	      backfill_outside_liberty.pos =
+	        find_semeai_backfilling_move(bpos, pos);
 	  }
 	  else {
 	    /* common liberty */
@@ -1005,8 +1071,8 @@
 	      common_liberty.pos = pos;
 	    }
 	    else if (backfill_common_liberty.pos == NO_MOVE)
-	      backfill_common_liberty.pos = find_semeai_backfilling_move(bpos,
-									 pos);
+	      backfill_common_liberty.pos =
+	        find_semeai_backfilling_move(bpos, pos);
 	  }
 	}
       }
@@ -1093,6 +1159,9 @@
     if (mpos == NO_MOVE)
       break;
 
+    if (moves[k].value == 0)
+      continue;
+
     /* Do not try too many moves. */
     if (tested_moves > 2
 	|| (stackp > semeai_branch_depth2 && tested_moves > 1)
@@ -1281,8 +1350,52 @@
   gg_assert(this_resulta != NULL && this_resultb != NULL);
   *this_resulta = 0;
   *this_resultb = 0;
-  if (!komaster_trymove(move, color, move_name, apos, &ko_move, ko_allowed))
+
+  if (!komaster_trymove(move, color, move_name, apos, &ko_move, ko_allowed)) {
+    /* Move was not allowed because of komaster. We want to check, if this
+     * situation is double ko and when it is, we won semeai.
+     */
+    int libs[MAX_LIBERTIES];
+    int n;
+    int nlib;
+    int sworm;
+    int worm_color;
+
+    for (sworm = 0; sworm < s_worms; sworm++) {
+      worm_color = board[semeai_worms[sworm]];
+      if (worm_color == color && *this_resulta == 0) {
+	/* We only check up to MAX_LIBERTIES, due to performance reasons. When we
+	 * have more liberties we have some outside liberties to fill and these
+	 * moves will be tried later (and double ko situation will be found).
+	 */
+	nlib = findlib(semeai_worms[sworm], MAX_LIBERTIES, libs);
+	if (nlib > MAX_LIBERTIES)
+	  return 0;
+
+	for (n = 0; n < nlib; n++)
+	  if (is_ko(libs[n], OTHER_COLOR(color), NULL)) {
+	    /* Our dragon has double ko, but we have to check if opponent dragon
+	     * doesn't have outside liberties or double ko.
+	     */
+	    *this_resulta = WIN;
+	    *this_resultb = WIN;
+	  }
+      }
+      else if (worm_color == OTHER_COLOR(color)) {
+	nlib = findlib(semeai_worms[sworm], 2, libs);
+	if (nlib > 2)
+	  /* In double ko situation the opponent can have only
+	   * a single eye and a ko outside liberty to be sure that we
+	   * will always win double ko. */
+	  return 0;
+      }
+    }
+
+    if (*this_resulta == WIN)
+      return 1;
+
     return 0;
+  }
   
   semeai_add_sgf_comment(move_value, owl_phase);
   TRACE("Trying %C %1m. Current stack: ", color, move);
@@ -1451,6 +1564,9 @@
     if (move == NO_MOVE)
       break;
 
+    if (owl_moves[k].value == 0)
+      continue;
+
     /* Does the move fill a liberty in the semeai? */
     if (liberty_of_goal(move, owlb)
 	&& safe_move(move, color)) {
diff -N -r -u -X .ignore gnugo-copy/patterns/conn.db gnugo/patterns/conn.db
--- gnugo-copy/patterns/conn.db	2006-01-23 19:15:50.000000000 +0100
+++ gnugo/patterns/conn.db	2007-01-19 11:44:56.869875000 +0100
@@ -611,7 +611,7 @@
 Bc
 dA
 
-;(attack(A) || attack(B)) && !oplay_disconnect(c,d)
+;lib(c)<=1 || lib(d)<=1 || xplay_defend_both(A,B) ? 0 : (amalgamate(c,d), 0)
 
 
 Pattern CC506
