code: @Override
      public boolean isTabu(Move<? super SubsetSolution> move, SubsetSolution currentSolution) {
          // check move type
          if(move instanceof SubsetMove){
              // cast
              SubsetMove sMove = (SubsetMove) move;
              // check if any involved ID is tabu
              return containsTabuID(sMove.getAddedIDs()) || containsTabuID(sMove.getDeletedIDs());
          } else {
              // wrong move type
              throw new IncompatibleTabuMemoryException("ID based subset tabu memory can only be used in combination with "
                                                      + "neighbourhoods that generate moves of type SubsetMove. Received: "
                                                      + move.getClass().getSimpleName());
          }
      }
docs: A move is considered tabu if any involved ID (added or deleted) is currently contained in the tabu memory.
  If not, the move is allowed. It is required that the given move is of type {@link SubsetMove}, else an
  {@link IncompatibleTabuMemoryException} will be thrown. Note that the argument <code>currentSolution</code>
  is not used here, because the move itself contains all necessary information, and may be <code>null</code>.
  
  @param move subset move to be applied to the current solution (required to be of type {@link SubsetMove})
  @param currentSolution current solution (not used here, allowed to be <code>null</code>)
  @return <code>true</code> if the current memory contains any ID which is added or deleted by the given move
  @throws IncompatibleTabuMemoryException if the given move is not of type {@link SubsetMove}