public Character next() {
   if (left.hasNext()) {
     return left.next();
   } else if (right.hasNext()) {
     return right.next();
   }
   throw new NoSuchElementException();
 }
 public boolean hasNext() {
   while (next == null) {
     if (leftChar == null) {
       if (left.hasNext()) {
         leftChar = left.next();
       } else {
         break;
       }
     }
     if (right.hasNext()) {
       Character c = right.next();
       if (c == leftChar) {
         next = c;
       }
     } else {
       right.reset();
       leftChar = null;
     }
   }
   return next != null;
 }
 @Override
 protected void visit(RENode.CharacterClass expr) throws RuntimeException {
   expr.getExpr().accept(this);
   for (int i = expr.getMin(); i > 0; i--) {
     if (solver.hasNext()) {
       char c = solver.next();
       current.resolvingExpression.append(c);
       current.buffer.append(c);
       solver.reset();
     } else {
       throw new UnsupportedOperationException("wtf?");
     }
   }
 }