ChainStateImpl implements IChainState { @Override public void rollback(final Object modId) throws ChainModificationException { try { Modification rbMod = modifications.get(modId); Modification prevMod = null; LinkedHashMap<Object, Modification> newModifications = new LinkedHashMap<>(); if (null == rbMod) { throw new ChainModificationException("Invalid modification id."); } Iterator<Map.Entry<Object, Modification>> modIter = modifications.entrySet().iterator(); while (modIter.hasNext()) { Map.Entry<Object, Modification> modEntry = modIter.next(); if (modEntry.getValue() == rbMod) { break; } prevMod = modEntry.getValue(); newModifications.put(modEntry.getKey(), modEntry.getValue()); } while (modIter.hasNext()) { Map.Entry<Object, Modification> modEntry = modIter.next(); prevMod = new Modification( modEntry.getValue().getDescription(), applyModification(prevMod.getResult(), modEntry.getValue().getDescription()) ); newModifications.put(modEntry.getKey(), prevMod); } current = prevMod.getResult(); modifications = newModifications; } catch (ResolutionException | ReadValueException | InvalidArgumentException e) { throw new ChainModificationException(e); } } ChainStateImpl(final IReceiverChain initial); @Override Object update(final IObject modification); @Override void rollback(final Object modId); @Override IReceiverChain getCurrent();  }
@Test(expected = ChainModificationException.class) public void Should_throwWhenTryingToRollbackNonExistModification() throws Exception { new ChainStateImpl(chainMocks[0]).rollback(new Object()); }