Tree merge(Tree a, Tree b) 
  {
    // Compute location for first cycle
    Tree   min = a;
    double mindist = distance(a);
    Tree   tmp = a;
    for (a = a.next; a != tmp; a = a.next) {
      double test = distance(a);
      if (test < mindist) {
	mindist = test;
	min = a;
      }
    }

    Tree next = min.next;
    Tree prev = min.prev;
    double mintonext = min.distance(next);
    double mintoprev = min.distance(prev);
    double ttonext   = distance(next);
    double ttoprev   = distance(prev);

    Tree p1, n1;
    double tton1, ttop1;
    if ((ttoprev - mintoprev) < (ttonext - mintonext)) {
      // would insert between min and prev
      p1 = prev;
      n1 = min;
      tton1 = mindist;
      ttop1 = ttoprev;
    } else { 
      // would insert between min and next
      p1 = min;
      n1 = next;
      ttop1 = mindist;
      tton1 = ttonext;
    }
 
    // Compute location for second cycle
    min = b;
    mindist = distance(b);
    tmp = b;
    for (b = b.next; b != tmp; b = b.next) {
      double test = distance(b);
      if (test < mindist) {
	mindist = test;
	min = b;
      }
    }

    next = min.next;
    prev = min.prev;
    mintonext = min.distance(next);
    mintoprev = min.distance(prev);
    ttonext = this.distance(next);
    ttoprev = this.distance(prev);
    
    Tree p2, n2;
    double tton2, ttop2;
    if ((ttoprev - mintoprev) < (ttonext - mintonext)) {
      // would insert between min and prev
      p2 = prev;
      n2 = min;
      tton2 = mindist;
      ttop2 = ttoprev;
    } else { 
      // would insert between min andn ext 
      p2 = min;
      n2 = next;
      ttop2 = mindist;
      tton2 = ttonext;
    }

    // Now we have 4 choices to complete:
    // 1:t,p1 t,p2 n1,n2
    // 2:t,p1 t,n2 n1,p2
    // 3:t,n1 t,p2 p1,n2
    // 4:t,n1 t,n2 p1,p2 
    double n1ton2 = n1.distance(n2);
    double n1top2 = n1.distance(p2);
    double p1ton2 = p1.distance(n2);
    double p1top2 = p1.distance(p2);

    mindist = ttop1 + ttop2 + n1ton2; 
    int choice = 1;

    double test = ttop1 + tton2 + n1top2;
    if (test < mindist) {
      choice = 2;
      mindist = test;
    }

    test = tton1 + ttop2 + p1ton2;
    if (test < mindist) {
      choice = 3;
      mindist = test;
    }
  
    test = tton1 + tton2 + p1top2;
    if (test < mindist) 
      choice = 4;

    switch (choice) {
    case 1:
      // 1:p1,this this,p2 n2,n1 -- reverse 2!
      n2.reverse();
      p1.next = this;
      this.prev = p1;
      this.next = p2;
      p2.prev = this;
      n2.next = n1;
      n1.prev = n2;
      break;
    case 2:
      // 2:p1,this this,n2 p2,n1 -- OK
      p1.next = this;
      this.prev = p1;
      this.next = n2;
      n2.prev = this;
      p2.next = n1;
      n1.prev = p2;
      break;
    case 3:
      // 3:p2,this this,n1 p1,n2 -- OK
      p2.next = this;
      this.prev = p2;
      this.next = n1;
      n1.prev = this;
      p1.next = n2;
      n2.prev = p1;
      break;
    case 4:
      // 4:n1,this this,n2 p2,p1 -- reverse 1!
      n1.reverse();
      n1.next = this;
      this.prev = n1;
      this.next = n2;
      n2.prev = this;
      p2.next = p1;
      p1.prev = p2;
      break;
    }
    return this;
  }