@Override
 public State unpack(PackedElement packed) {
   PancakeState state = new PancakeState(this.numCakes);
   int index = this.numCakes - 1;
   for (int i = packed.getLongsCount() - 1; i >= 0; --i) {
     long current = packed.getLong(i);
     int maxIterationIndex = this.packedCakesInSingleLong;
     // In case of first iteration (starting from the end, maybe only part of the full coverage of
     // pancakes is
     // included inside the packed long - let's calculate this count
     if (i == packed.getLongsCount() - 1) {
       // E.g. if (numCakes=20; packedCakesInSingleLong=12 => maxIterationIndex=8)
       //      if (numCakes=15; packedCakesInSingleLong=15 => maxIterationIndex=0)
       //      if (numCakes=10; packedCakesInSingleLong=10 => maxIterationIndex=0)
       int specificMaxIterationIndex = this.numCakes % this.packedCakesInSingleLong;
       if (specificMaxIterationIndex > 0) {
         maxIterationIndex = specificMaxIterationIndex;
       }
     }
     for (int j = 0; j < maxIterationIndex && index >= 0; ++j) {
       int p = (int) (current & (int) this.maskForSinglePancake);
       current >>= this.bitsForSinglePancake;
       state.cakes[index--] = p;
     }
   }
   state.h = this._countGaps(state.cakes, this.costFunction);
   state.d = this._countGaps(state.cakes, COST_FUNCTION.UNIT);
   state.dNoGaps = this._countGaps(state.cakes, COST_FUNCTION.UNIT, false);
   return state;
 }
 @Override
 public PancakeState initialState() {
   PancakeState s = new PancakeState(this.numCakes);
   System.arraycopy(this.init, 0, s.cakes, 0, numCakes);
   s.h = this._countGaps(s.cakes, this.costFunction);
   s.d = this._countGaps(s.cakes, COST_FUNCTION.UNIT);
   if (this.k == 0) {
     s.dNoGaps = s.d;
   } else {
     // Calc d without k
     s.dNoGaps = this._countGaps(s.cakes, COST_FUNCTION.UNIT, false);
   }
   return s;
 }
 @Override
 public State applyOperator(State state, Operator op) {
   PancakeState pancakeState = (PancakeState) copy(state);
   int pancakeOperator = ((PancakeOperator) op).value;
   // Flip the top of the stack
   pancakeState.flipTopStackPortion(pancakeOperator);
   pancakeState.h = this._countGaps(pancakeState.cakes, this.costFunction);
   pancakeState.d = this._countGaps(pancakeState.cakes, COST_FUNCTION.UNIT);
   if (this.k == 0) {
     pancakeState.dNoGaps = pancakeState.d;
   } else {
     // Calc d without k
     pancakeState.dNoGaps = this._countGaps(pancakeState.cakes, COST_FUNCTION.UNIT, false);
   }
   return pancakeState;
 }