// l + r
 private R connectEmpty() {
   synchronized (root) {
     Connector<T, R> l = left, r = right;
     if (l == null) {
       return pushRight(none(), none());
     }
     left = right = null;
     l.rhs = null;
     T laright = l.right;
     l.right = none();
     if (l.acc == NONE) {
       if (r == null) l.drain();
       else {
         if (l.lhs != null) {
           l.lhs.right = r;
           r.lhs = l.lhs;
         }
       }
       return none();
     }
     if (r == null) {
       return l.drainLeft();
     }
     r.lhs = null;
     if (r.acc == NONE) {
       if (r.rhs != null) {
         r.rhs.left = l;
         l.rhs = r.rhs;
         l.right = laright;
       }
       return none();
     }
     T raleft = r.left;
     r.left = none();
     if (mergeable.test(laright, raleft)) {
       R acc = combiner.apply(l.acc, r.acc);
       if (l.left == NONE && r.right == NONE) {
         l.drain();
         r.drain();
         return acc;
       }
       l.acc = acc;
       l.right = r.right;
       if (r.rhs != null) {
         r.rhs.left = l;
         l.rhs = r.rhs;
       }
       return none();
     }
     if (l.left == NONE) {
       if (r.right == NONE) right = new Connector<>(this, r.drain(), null);
       return l.drain();
     }
     return r.drainRight();
   }
 }
 // l + <first|acc|?>
 private R pushLeft(T first, R acc) {
   synchronized (root) {
     Connector<T, R> l = left;
     if (l == null) return acc;
     left = null;
     l.rhs = null;
     T laright = l.right;
     l.right = none();
     if (l.acc == NONE) {
       l.acc = acc;
       l.left = first;
       return none();
     }
     if (this.mergeable.test(laright, first)) {
       l.acc = this.combiner.apply(l.acc, acc);
       return l.drainLeft();
     }
     if (l.left == NONE) {
       left = new Connector<>(null, acc, this);
       return l.drain();
     }
   }
   return acc;
 }