### Question:
ProgressListenerChain implements ProgressListener { @Override public void progressChanged(final ProgressEvent progressEvent) { ProgressEvent filteredEvent = progressEvent; if (progressEventFilter != null) { filteredEvent = progressEventFilter.filter(progressEvent); if (filteredEvent == null) return; } for (ProgressListener listener : listeners) { try { listener.progressChanged(filteredEvent); } catch (RuntimeException e) { log.warn("Couldn't update progress listener", e); } } } ProgressListenerChain(ProgressListener... listeners);  ProgressListenerChain(ProgressEventFilter progressEventFilter,
            ProgressListener... listeners); synchronized void addProgressListener(ProgressListener listener); synchronized void removeProgressListener(ProgressListener listener); @Override void progressChanged(final ProgressEvent progressEvent);  }### Answer:
@Test public void testProgressListenerChainNoFilters() { final ConcurrentHashMap<ProgressListener, ProgressEvent> listenerMap = new ConcurrentHashMap<ProgressListener, ProgressEvent>(); ProgressListener listener1 = new ProgressListener() { @Override public void progressChanged(ProgressEvent progressEvent) { if (listenerMap.get(this) != null) { fail("recieved unexpected event"); } else { listenerMap.put(this, progressEvent); } } }; ProgressListener listener2 = new ProgressListener() { @Override public void progressChanged(ProgressEvent progressEvent) { if (listenerMap.get(this) != null) { fail("recieved unexpected event"); } else { listenerMap.put(this, progressEvent); } } }; ProgressListenerChain chain = new ProgressListenerChain(listener1, listener2); ProgressEvent event = new ProgressEvent(0); chain.progressChanged(event); assertSame(listenerMap.get(listener1), event); assertSame(listenerMap.get(listener2), event); }
@Test public void testProgressListenerChainWithFilters() { final ConcurrentHashMap<ProgressListener, ProgressEvent> listenerMap = new ConcurrentHashMap<ProgressListener, ProgressEvent>(); ProgressListener listener1 = new ProgressListener() { @Override public void progressChanged(ProgressEvent progressEvent) { if (listenerMap.get(this) != null) { fail("recieved unexpected event"); } else { listenerMap.put(this, progressEvent); } } }; ProgressListener listener2 = new ProgressListener() { @Override public void progressChanged(ProgressEvent progressEvent) { if (listenerMap.get(this) != null) { fail("recieved unexpected event"); } else { listenerMap.put(this, progressEvent); } } }; ProgressListenerChain chain = new ProgressListenerChain( new ProgressListenerChain.ProgressEventFilter() { @Override public ProgressEvent filter(ProgressEvent progressEvent) { progressEvent.setBytesTransferred(100); return progressEvent; } }, listener1, listener2); ProgressEvent event = new ProgressEvent(0); chain.progressChanged(event); assertSame(listenerMap.get(listener1), event); assertSame(listenerMap.get(listener2), event); assertEquals(listenerMap.get(listener1).getBytesTransferred(), 100); assertEquals(listenerMap.get(listener2).getBytesTransferred(), 100); }