public void constructCache(DefaultSolverScope solverScope) {
   long childSize = childMoveSelector.getSize();
   if (childSize > (long) Integer.MAX_VALUE) {
     throw new IllegalStateException(
         "The selector ("
             + this
             + ") has a childMoveSelector ("
             + childMoveSelector
             + ") with childSize ("
             + childSize
             + ") which is higher than Integer.MAX_VALUE.");
   }
   cachedMoveList = new ArrayList<Move>((int) childSize);
   CollectionUtils.addAll(cachedMoveList, childMoveSelector.iterator());
   logger.trace(
       "    Created cachedMoveList with size ({}) in moveSelector({}).",
       cachedMoveList.size(),
       this);
 }
 public AbstractCachingMoveSelector(MoveSelector childMoveSelector, SelectionCacheType cacheType) {
   this.childMoveSelector = childMoveSelector;
   this.cacheType = cacheType;
   if (childMoveSelector.isNeverEnding()) {
     throw new IllegalStateException(
         "The selector ("
             + this
             + ") has a childMoveSelector ("
             + childMoveSelector
             + ") with neverEnding ("
             + childMoveSelector.isNeverEnding()
             + ").");
   }
   solverPhaseLifecycleSupport.addEventListener(childMoveSelector);
   if (cacheType.isNotCached()) {
     throw new IllegalArgumentException(
         "The selector (" + this + ") does not support the cacheType (" + cacheType + ").");
   }
   solverPhaseLifecycleSupport.addEventListener(
       new SelectionCacheLifecycleBridge(cacheType, this));
 }
  public void runCacheType(SelectorCacheType cacheType, int timesCalled) {
    CachingMoveSelector moveSelector = new CachingMoveSelector(cacheType);
    MoveSelector childMoveSelector = mock(MoveSelector.class);
    final List<Move> moveList =
        Arrays.<Move>asList(new DummyMove("a1"), new DummyMove("a2"), new DummyMove("a3"));
    when(childMoveSelector.iterator())
        .thenAnswer(
            new Answer<Object>() {
              public Object answer(InvocationOnMock invocation) throws Throwable {
                return moveList.iterator();
              }
            });
    when(childMoveSelector.isContinuous()).thenReturn(false);
    when(childMoveSelector.isNeverEnding()).thenReturn(false);
    when(childMoveSelector.getSize()).thenReturn((long) moveList.size());
    when(childMoveSelector.getRandomProbabilityWeight()).thenReturn(7L);
    moveSelector.setChildMoveSelector(childMoveSelector);
    verify(childMoveSelector, times(1)).isNeverEnding();

    DefaultSolverScope solverScope = mock(DefaultSolverScope.class);
    moveSelector.solvingStarted(solverScope);

    AbstractSolverPhaseScope phaseScopeA = mock(AbstractSolverPhaseScope.class);
    when(phaseScopeA.getSolverScope()).thenReturn(solverScope);
    moveSelector.phaseStarted(phaseScopeA);

    AbstractStepScope stepScopeA1 = mock(AbstractStepScope.class);
    when(stepScopeA1.getSolverPhaseScope()).thenReturn(phaseScopeA);
    moveSelector.stepStarted(stepScopeA1);
    runAsserts(moveSelector);
    moveSelector.stepEnded(stepScopeA1);

    AbstractStepScope stepScopeA2 = mock(AbstractStepScope.class);
    when(stepScopeA2.getSolverPhaseScope()).thenReturn(phaseScopeA);
    moveSelector.stepStarted(stepScopeA2);
    runAsserts(moveSelector);
    moveSelector.stepEnded(stepScopeA2);

    moveSelector.phaseEnded(phaseScopeA);

    AbstractSolverPhaseScope phaseScopeB = mock(AbstractSolverPhaseScope.class);
    when(phaseScopeB.getSolverScope()).thenReturn(solverScope);
    moveSelector.phaseStarted(phaseScopeB);

    AbstractStepScope stepScopeB1 = mock(AbstractStepScope.class);
    when(stepScopeB1.getSolverPhaseScope()).thenReturn(phaseScopeB);
    moveSelector.stepStarted(stepScopeB1);
    runAsserts(moveSelector);
    moveSelector.stepEnded(stepScopeB1);

    AbstractStepScope stepScopeB2 = mock(AbstractStepScope.class);
    when(stepScopeB2.getSolverPhaseScope()).thenReturn(phaseScopeB);
    moveSelector.stepStarted(stepScopeB2);
    runAsserts(moveSelector);
    moveSelector.stepEnded(stepScopeB2);

    AbstractStepScope stepScopeB3 = mock(AbstractStepScope.class);
    when(stepScopeB3.getSolverPhaseScope()).thenReturn(phaseScopeB);
    moveSelector.stepStarted(stepScopeB3);
    runAsserts(moveSelector);
    moveSelector.stepEnded(stepScopeB3);

    moveSelector.phaseEnded(phaseScopeB);

    moveSelector.solvingEnded(solverScope);

    verify(childMoveSelector, times(timesCalled)).iterator();
    verify(childMoveSelector, times(timesCalled)).getSize();
    verify(childMoveSelector, times(timesCalled)).getRandomProbabilityWeight();
  }