gt:                             if ((nextState = b|state|refork) == b ||
context: package minejava.reg.util;
  
  import minejava.reg.util.function.BinaryOperator;
  import minejava.reg.util.concurrent.ForkJoinPool;
  import minejava.reg.util.concurrent.CountedCompleter;
  import minejava.reg.util.function.IntBinaryOperator;h
  import minejava.reg.util.function.LongBinaryOperator;
  import minejava.reg.util.function.DoubleBinaryOperator;
  
  class ArrayPrefixHelpers{
  
      private ArrayPrefixHelpers(){};
  
      static final int CUMULATE = 1;
      static final int SUMMED   = 2;
      static final int FINISHED = 4;
      static final int MIN_PARTITION = 16;
  
      static final class CumulateTask<T> extends CountedCompleter<Void>{
          final T[] array;
          final BinaryOperator<T> function;
          CumulateTask<T> left, right;
          T in, out;
          final int lo, hi, origin, fence, threshold;
  
          public CumulateTask(CumulateTask<T> parent,
                              BinaryOperator<T> function,
                              T[] array, int lo, int hi){
              super(parent);
              this.function = function; this.array = array;
              this.lo = this.origin = lo; this.hi = this.fence = hi;
              int p;
              this.threshold =
                      (p = (hi - lo) / (ForkJoinPool.getCommonPoolParallelism() << 3))
                      <= MIN_PARTITION ? MIN_PARTITION : p;
          }
  
          CumulateTask(CumulateTask<T> parent, BinaryOperator<T> function,
                       T[] array, int origin, int fence, int threshold,
                       int lo, int hi){
              super(parent);
              this.function = function; this.array = array;
              this.origin = origin; this.fence = fence;
              this.threshold = threshold;
              this.lo = lo; this.hi = hi;
          }
  
          @SuppressWarnings("unchecked")
          public final void compute(){
              final BinaryOperator<T> fn;
              final T[] a;
              if ((fn = this.function) == null || (a = this.array) == null)
                  throw new NullPointerException();
              int th = threshold, org = origin, fnc = fence, l, h;
              CumulateTask<T> t = this;
              outer: while ((l = t.lo) >= 0 && (h = t.hi) <= a.length){
                  if (h - l > th){
                      CumulateTask<T> lt = t.left, rt = t.right, f;
                      if (lt == null){
                          int mid = (l + h) >>> 1;
                          f = rt = t.right =
                                  new CumulateTask<>(t, fn, a, org, fnc, th, mid, h);
                          t = lt = t.left  =
                                  new CumulateTask<>(t, fn, a, org, fnc, th, l, mid);
                      }
                      else{
                          T pin = t.in;
                          lt.in = pin;
                          f = t = null;
                          if (rt != null){
                              T lout = lt.out;
                              rt.in = (l == org ? lout :
                                       fn.apply(pin, lout));
                              for (int c;;){
                                  if (((c = rt.getPendingCount()) & CUMULATE) != 0)
                                      break;
                                  if (rt.compareAndSetPendingCount(c, c|CUMULATE)){
                                      t = rt;
                                      break;
                                  }
                              }
                          }
                          for (int c;;){
                              if (((c = lt.getPendingCount()) & CUMULATE) != 0)
                                  break;
                              if (lt.compareAndSetPendingCount(c, c|CUMULATE)){
                                  if (t != null)
                                      f = t;
                                  t = lt;
                                  break;
                              }
                          }
                          if (t == null)
                              break;
                      }
                      if (f != null)
                          f.fork();
                  }
                  else{
                      int state;
                      for (int b;;){
                          if (((b = t.getPendingCount()) & FINISHED) != 0)
                              break outer;
                          state = ((b & CUMULATE) != 0? FINISHED :
                                   (l > org) ? SUMMED : (SUMMED|FINISHED));
                          if (t.compareAndSetPendingCount(b, b|state))
                              break;
                      }
  
                      T sum;
                      if (state != SUMMED){
                          int first;
                          if (l == org){
                              sum = a[org];
                              first = org + 1;
                          }
                          else{
                              sum = t.in;
                              first = l;
                          }
                          for (int i = first; i < h; ++i)
                              a[i] = sum = fn.apply(sum, a[i]);
                      }
                      else if (h < fnc){
                          sum = a[l];
                          for (int i = l + 1; i < h; ++i)
                              sum = fn.apply(sum, a[i]);
                      }
                      else
                          sum = t.in;
                      t.out = sum;
                      for (CumulateTask<T> par;;){
                          if ((par = (CumulateTask<T>)t.getCompleter()) == null){
                              if ((state & FINISHED) != 0)
                                  t.quietlyComplete();
                              break outer;
                          }
                          int b = par.getPendingCount();
                          if ((b & state & FINISHED) != 0)
                              t = par;
                          else if ((b & state & SUMMED) != 0){
                              int nextState; CumulateTask<T> lt, rt;
                              if ((lt = par.left) != null &&
                                  (rt = par.right) != null){
                                  T lout = lt.out;
                                  par.out = (rt.hi == fnc ? lout :
                                             fn.apply(lout, rt.out));
                              }
                              int refork = (((b & CUMULATE) == 0 &&
                                             par.lo == org) ? CUMULATE : 0);
                              if ((nextState = b|state|refork) == b ||
                                  par.compareAndSetPendingCount(b, nextState)){
                                  state = SUMMED;
                                  t = par;
                                  if (refork != 0)
                                      par.fork();
                              }
                          }
                          else if (par.compareAndSetPendingCount(b, b|state))
                              break outer;
                      }
                  }
              }
          }
      }
  
      static final class LongCumulateTask extends CountedCompleter<Void>{
          final long[] array;
          final LongBinaryOperator function;
          LongCumulateTask left, right;
          long in, out;
          final int lo, hi, origin, fence, threshold;
  
          public LongCumulateTask(LongCumulateTask parent,
                                  LongBinaryOperator function,
                                  long[] array, int lo, int hi){
              super(parent);
              this.function = function; this.array = array;
              this.lo = this.origin = lo; this.hi = this.fence = hi;
              int p;
              this.threshold =
                      (p = (hi - lo) / (ForkJoinPool.getCommonPoolParallelism() << 3))
                      <= MIN_PARTITION ? MIN_PARTITION : p;
          }
  
          LongCumulateTask(LongCumulateTask parent, LongBinaryOperator function,
                           long[] array, int origin, int fence, int threshold,
                           int lo, int hi){
              super(parent);
              this.function = function; this.array = array;
              this.origin = origin; this.fence = fence;
              this.threshold = threshold;
              this.lo = lo; this.hi = hi;
          }
  
          public final void compute(){
              final LongBinaryOperator fn;
              final long[] a;
              if ((fn = this.function) == null || (a = this.array) == null)
                  throw new NullPointerException();
              int th = threshold, org = origin, fnc = fence, l, h;
              LongCumulateTask t = this;
              outer: while ((l = t.lo) >= 0 && (h = t.hi) <= a.length){
                  if (h - l > th){
                      LongCumulateTask lt = t.left, rt = t.right, f;
                      if (lt == null){
                          int mid = (l + h) >>> 1;
                          f = rt = t.right =
                                  new LongCumulateTask(t, fn, a, org, fnc, th, mid, h);
                          t = lt = t.left  =
                                  new LongCumulateTask(t, fn, a, org, fnc, th, l, mid);
                      }
                      else{
                          long pin = t.in;
                          lt.in = pin;
                          f = t = null;
                          if (rt != null){
                              long lout = lt.out;
                              rt.in = (l == org ? lout :
                                       fn.applyAsLong(pin, lout));
                              for (int c;;){
                                  if (((c = rt.getPendingCount()) & CUMULATE) != 0)
                                      break;
                                  if (rt.compareAndSetPendingCount(c, c|CUMULATE)){
                                      t = rt;
                                      break;
                                  }
                              }
                          }
                          for (int c;;){
                              if (((c = lt.getPendingCount()) & CUMULATE) != 0)
                                  break;
                              if (lt.compareAndSetPendingCount(c, c|CUMULATE)){
                                  if (t != null)
                                      f = t;
                                  t = lt;
                                  break;
                              }
                          }
                          if (t == null)
                              break;
                      }
                      if (f != null)
                          f.fork();
                  }
                  else{
                      int state;
                      for (int b;;){
                          if (((b = t.getPendingCount()) & FINISHED) != 0)
                              break outer;
                          state = ((b & CUMULATE) != 0? FINISHED :
                                   (l > org) ? SUMMED : (SUMMED|FINISHED));
                          if (t.compareAndSetPendingCount(b, b|state))
                              break;
                      }
  
                      long sum;
                      if (state != SUMMED){
                          int first;
                          if (l == org){
                              sum = a[org];
                              first = org + 1;
                          }
                          else{
                              sum = t.in;
                              first = l;
                          }
                          for (int i = first; i < h; ++i)
                              a[i] = sum = fn.applyAsLong(sum, a[i]);
                      }
                      else if (h < fnc){
                          sum = a[l];
                          for (int i = l + 1; i < h; ++i)
                              sum = fn.applyAsLong(sum, a[i]);
                      }
                      else
                          sum = t.in;
                      t.out = sum;
                      for (LongCumulateTask par;;){
                          if ((par = (LongCumulateTask)t.getCompleter()) == null){
                              if ((state & FINISHED) != 0)
                                  t.quietlyComplete();
                              break outer;
                          }
                          int b = par.getPendingCount();
                          if ((b & state & FINISHED) != 0)
                              t = par;
                          else if ((b & state & SUMMED) != 0){
                              int nextState; LongCumulateTask lt, rt;
                              if ((lt = par.left) != null &&
                                  (rt = par.right) != null){
                                  long lout = lt.out;
                                  par.out = (rt.hi == fnc ? lout :
                                             fn.applyAsLong(lout, rt.out));
                              }
                              int refork = (((b & CUMULATE) == 0 &&
                                             par.lo == org) ? CUMULATE : 0);
                              if ((nextState = b|state|refork) == b ||
                                  par.compareAndSetPendingCount(b, nextState)){
                                  state = SUMMED;
                                  t = par;
                                  if (refork != 0)
                                      par.fork();
                              }
                          }
                          else if (par.compareAndSetPendingCount(b, b|state))
                              break outer;
                      }
                  }
              }
          }
      }
  
      static final class DoubleCumulateTask extends CountedCompleter<Void>{
          final double[] array;
          final DoubleBinaryOperator function;
          DoubleCumulateTask left, right;
          double in, out;
          final int lo, hi, origin, fence, threshold;
  
          public DoubleCumulateTask(DoubleCumulateTask parent,
                                    DoubleBinaryOperator function,
                                    double[] array, int lo, int hi){
              super(parent);
              this.function = function; this.array = array;
              this.lo = this.origin = lo; this.hi = this.fence = hi;
              int p;
              this.threshold =
                      (p = (hi - lo) / (ForkJoinPool.getCommonPoolParallelism() << 3))
                      <= MIN_PARTITION ? MIN_PARTITION : p;
          }
  
          DoubleCumulateTask(DoubleCumulateTask parent, DoubleBinaryOperator function,
                             double[] array, int origin, int fence, int threshold,
                             int lo, int hi){
              super(parent);
              this.function = function; this.array = array;
              this.origin = origin; this.fence = fence;
              this.threshold = threshold;
              this.lo = lo; this.hi = hi;
          }
  
          public final void compute(){
              final DoubleBinaryOperator fn;
              final double[] a;
              if ((fn = this.function) == null || (a = this.array) == null)
                  throw new NullPointerException();
              int th = threshold, org = origin, fnc = fence, l, h;
              DoubleCumulateTask t = this;
              outer: while ((l = t.lo) >= 0 && (h = t.hi) <= a.length){
                  if (h - l > th){
                      DoubleCumulateTask lt = t.left, rt = t.right, f;
                      if (lt == null){
                          int mid = (l + h) >>> 1;
                          f = rt = t.right =
                                  new DoubleCumulateTask(t, fn, a, org, fnc, th, mid, h);
                          t = lt = t.left  =
                                  new DoubleCumulateTask(t, fn, a, org, fnc, th, l, mid);
                      }
                      else{
                          double pin = t.in;
                          lt.in = pin;
                          f = t = null;
                          if (rt != null){
                              double lout = lt.out;
                              rt.in = (l == org ? lout :
                                       fn.applyAsDouble(pin, lout));
                              for (int c;;){
                                  if (((c = rt.getPendingCount()) & CUMULATE) != 0)
                                      break;
                                  if (rt.compareAndSetPendingCount(c, c|CUMULATE)){
                                      t = rt;
                                      break;
                                  }
                              }
                          }
                          for (int c;;){
                              if (((c = lt.getPendingCount()) & CUMULATE) != 0)
                                  break;
                              if (lt.compareAndSetPendingCount(c, c|CUMULATE)){
                                  if (t != null)
                                      f = t;
                                  t = lt;
                                  break;
                              }
                          }
                          if (t == null)
                              break;
                      }
                      if (f != null)
                          f.fork();
                  }
                  else{
                      int state;
                      for (int b;;){
                          if (((b = t.getPendingCount()) & FINISHED) != 0)
                              break outer;
                          state = ((b & CUMULATE) != 0? FINISHED :
                                   (l > org) ? SUMMED : (SUMMED|FINISHED));
                          if (t.compareAndSetPendingCount(b, b|state))
                              break;
                      }
  
                      double sum;
                      if (state != SUMMED){
                          int first;
                          if (l == org){
                              sum = a[org];
                              first = org + 1;
                          }
                          else{
                              sum = t.in;
                              first = l;
                          }
                          for (int i = first; i < h; ++i)
                              a[i] = sum = fn.applyAsDouble(sum, a[i]);
                      }
                      else if (h < fnc){
                          sum = a[l];
                          for (int i = l + 1; i < h; ++i)
                              sum = fn.applyAsDouble(sum, a[i]);
                      }
                      else
                          sum = t.in;
                      t.out = sum;
                      for (DoubleCumulateTask par;;){
                          if ((par = (DoubleCumulateTask)t.getCompleter()) == null){
                              if ((state & FINISHED) != 0)
                                  t.quietlyComplete();
                              break outer;
                          }
                          int b = par.getPendingCount();
                          if ((b & state & FINISHED) != 0)
                              t = par;
                          else if ((b & state & SUMMED) != 0){
                              int nextState; DoubleCumulateTask lt, rt;
                              if ((lt = par.left) != null &&
                                  (rt = par.right) != null){
                                  double lout = lt.out;
                                  par.out = (rt.hi == fnc ? lout :
                                             fn.applyAsDouble(lout, rt.out));
                              }
                              int refork = (((b & CUMULATE) == 0 &&
                                             par.lo == org) ? CUMULATE : 0);
  