### Question:
MergeController extends AbstractMantleController implements Consumer<DataGroupInfo> { public void performMerge() { ThreadUtilities.runCpu(this::performMergeBackground); } MergeController(Toolbox toolbox, MergePrefs mergePreferences, Runnable saveCallback); synchronized MergeModel getModel(); void performMerge(); @Override void accept(DataGroupInfo group); synchronized void setModel(MergeModel model); void removeMerge(MergeModel model);  }### Answer:
@Test public void testPerformMerge() throws InterruptedException { EasyMockSupport support = new EasyMockSupport(); myRootGroup = null; CountDownLatch latch = new CountDownLatch(1); List<DataTypeInfo> layers = createDataTypes(support); DataElementLookupUtils lookup = createLookupUtils(support, layers); DataGroupController groupController = createGroupController(support); DataTypeController typeController = createTypeController(support, latch); MantleToolbox mantle = createMantleMerge(support, lookup, groupController, typeController); ColumnMappingController mapper = createMapperMerge(support); Toolbox toolbox = createToolboxMerge(support, mantle, mapper); support.replayAll(); MergeModel model = new MergeModel(layers); model.getNewLayerName().set(ourMergeLayerName); MergeController controller = new MergeController(toolbox, null, null); controller.setModel(model); controller.performMerge(); assertTrue(latch.await(1, TimeUnit.SECONDS)); assertEquals(ourExpectedRootGroup, myRootGroup.getDisplayName()); assertTrue(myRootGroup.isRootNode()); assertEquals(ourExpectedRootGroup, myRootGroup.getId()); assertEquals(ourExpectedRootGroup, myRootGroup.getProviderType()); assertEquals(ourMergeLayerName, myAddedType.getDisplayName()); assertEquals(ourExpectedRootGroup, myAddedType.getSourcePrefix()); assertEquals(ourMergeLayerName, myAddedType.getTypeKey()); assertEquals(ourMergeLayerName, myAddedType.getTypeName()); assertFalse(myAddedType.providerFiltersMetaData()); assertFalse(myAddedType.isFilterable()); assertTrue(myAddedType.isVisible()); List<String> expectedKeyNames = New.list(ourColumn1, ourColumn2, ourDefinedColumn, ourColumn4, ourColumn5); assertEquals(expectedKeyNames.size(), myAddedType.getMetaDataInfo().getKeyNames().size()); assertTrue(myAddedType.getMetaDataInfo().getKeyNames().containsAll(expectedKeyNames)); assertTrue(myAddedType.getParent().activationProperty().isActive()); assertTrue(myAddedType.getParent() instanceof DefaultDeletableDataGroupInfo); MapDataElement twitter = (MapDataElement)myProvider.next(); MapDataElement embers = (MapDataElement)myProvider.next(); assertFalse(myProvider.hasNext()); assertEquals(TimeSpan.get(1000), twitter.getTimeSpan()); assertEquals(new SimpleMapPointGeometrySupport(LatLonAlt.createFromDegrees(10, 11)), twitter.getMapGeometrySupport()); assertEquals(10d, ((Double)twitter.getMetaData().getValue(ourColumn1)).doubleValue(), 0d); assertEquals(11d, ((Double)twitter.getMetaData().getValue(ourColumn2)).doubleValue(), 0d); assertEquals("testuser", twitter.getMetaData().getValue(ourDefinedColumn).toString()); assertEquals("your mom", twitter.getMetaData().getValue(ourColumn4).toString()); assertNull(twitter.getMetaData().getValue(ourColumn5)); assertEquals(TimeSpan.get(2000), embers.getTimeSpan()); assertEquals(new SimpleMapPointGeometrySupport(LatLonAlt.createFromDegrees(12, 13)), embers.getMapGeometrySupport()); assertEquals(12d, ((Double)embers.getMetaData().getValue(ourColumn1)).doubleValue(), 0d); assertEquals(13d, ((Double)embers.getMetaData().getValue(ourColumn2)).doubleValue(), 0d); assertEquals("anotheruser", embers.getMetaData().getValue(ourDefinedColumn).toString()); assertNull(embers.getMetaData().getValue(ourColumn4)); assertEquals("hello there", embers.getMetaData().getValue(ourColumn5)); Thread.sleep(100); assertTrue(myTa.isComplete()); assertEquals("Merging selected layers to mergeLayer", myTa.getLabelValue()); controller.close(); assertNull(myRootGroup); assertNull(myAddedType); support.verifyAll(); }