// 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();
   }
 }
 // <?|acc|last> + r
 private R pushRight(R acc, T last) {
   cur = none();
   if (right == null) return acc;
   synchronized (root) {
     Connector<T, R> r = right;
     if (r == null) return acc;
     right = null;
     r.lhs = null;
     T raleft = r.left;
     r.left = none();
     if (r.acc == NONE) {
       if (acc == NONE) {
         r.drain();
       } else {
         r.acc = acc;
         r.right = last;
       }
       return none();
     }
     if (acc == NONE) {
       return r.drainRight();
     }
     if (mergeable.test(last, raleft)) {
       r.acc = combiner.apply(acc, r.acc);
       return r.drainRight();
     }
     if (r.right == NONE) right = new Connector<>(this, r.drain(), null);
     return acc;
   }
 }
 private CollapseSpliterator(
     CollapseSpliterator<T, R> root,
     Spliterator<T> source,
     Connector<T, R> left,
     Connector<T, R> right) {
   this.source = source;
   this.root = root;
   this.mergeable = root.mergeable;
   this.mapper = root.mapper;
   this.accumulator = root.accumulator;
   this.combiner = root.combiner;
   this.left = left;
   this.right = right;
   if (left != null) left.rhs = this;
   right.lhs = this;
 }