### Question:
ChainContainer implements Cloneable { public ChainContainer getBeforeTheForkChain(ChainContainer chainContainer) { Chain newChain = new Chain(); newChain.setId(chainContainer.getChain().getId()); newChain.initData(chain.getStartBlockHeader(), new CopyOnWriteArrayList<>(chain.getAllBlockHeaderList()), new CopyOnWriteArrayList<>(chain.getAllBlockList())); if (chain.getAgentList() != null) { List<Agent> agentList = new ArrayList<>(); for (Agent agent : chain.getAgentList()) { try { agentList.add(agent.clone()); } catch (CloneNotSupportedException e) { Log.error(e); } } newChain.setAgentList(agentList); } if (chain.getDepositList() != null) { List<Deposit> depositList = new ArrayList<>(); for (Deposit deposit : chain.getDepositList()) { try { depositList.add(deposit.clone()); } catch (CloneNotSupportedException e) { Log.error(e); } } newChain.setDepositList(depositList); } if (chain.getYellowPunishList() != null) { newChain.setYellowPunishList(new ArrayList<>(chain.getYellowPunishList())); } if (chain.getRedPunishList() != null) { newChain.setRedPunishList(new ArrayList<>(chain.getRedPunishList())); } ChainContainer newChainContainer = new ChainContainer(newChain); BlockHeader pointBlockHeader = chainContainer.getChain().getStartBlockHeader(); List<Block> blockList = newChain.getAllBlockList(); for (int i = blockList.size() - 1; i >= 0; i--) { Block block = blockList.get(i); if (pointBlockHeader.getPreHash().equals(block.getHeader().getHash())) { break; } newChainContainer.rollback(block); } newChainContainer.initRound(); return newChainContainer; } ChainContainer(Chain chain); boolean addBlock(Block block); Result verifyBlock(Block block); Result verifyBlock(Block block, boolean isDownload, boolean isNeedCheckCoinBaseTx); boolean verifyCoinBaseTx(Block block, MeetingRound currentRound, MeetingMember member); boolean verifyPunishTx(Block block, MeetingRound currentRound, MeetingMember member); Result verifyAndAddBlock(Block block, boolean isDownload, boolean isNeedCheckCoinBaseTx); boolean rollback(Block block); ChainContainer getBeforeTheForkChain(ChainContainer chainContainer); ChainContainer getAfterTheForkChain(ChainContainer chainContainer); MeetingRound getCurrentRound(); MeetingRound getOrResetCurrentRound(); MeetingRound getOrResetCurrentRound(boolean isRealTime); MeetingRound initRound(); void clearRound(int count); Block getBestBlock(); Chain getChain(); void setChain(Chain chain); @Override boolean equals(Object obj); RoundManager getRoundManager();  }### Answer:
@Test public void testGetBeforeTheForkChain() { Block forkBlock = null; for (int i = 0; i < 20; i++) { Block bestBlock = chainContainer.getBestBlock(); Block newBlock = newBlock(bestBlock); Result success = chainContainer.verifyAndAddBlock(newBlock, false, true); assertTrue(success.isSuccess()); bestBlock = chainContainer.getBestBlock(); assertEquals(bestBlock.getHeader().getHeight(), 1L + i); if (i == 10) { forkBlock = bestBlock; } } Chain chain = new Chain(); chain.addBlock(forkBlock); Block newBlock = newBlock(forkBlock); chain.addBlock(newBlock); ChainContainer otherChainContainer = new ChainContainer(chain); ChainContainer newForkChainContainer = chainContainer.getBeforeTheForkChain(otherChainContainer); assertEquals(newForkChainContainer.getBestBlock().getHeader().getHeight(), 10L); }