@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 State unpack(PackedElement packed) {
   assert packed.getLongsCount() == 1;
   long firstPacked = packed.getFirst();
   TopSpinState tss = new TopSpinState();
   // Start from end and go to start
   for (int i = this.tokensNumber - 1; i >= 0; --i) {
     // Each time, extract a single token
     int t = (int) firstPacked & 0xF;
     // Initialize this token
     tss.tokens[i] = t;
     // Update the word so that the next tile can be now extracted
     firstPacked >>= 4;
   }
   double[] hd = this._computeHD(tss);
   tss.h = hd[0];
   tss.d = hd[1];
   return tss;
 }