--- /dev/null
+package org.opendaylight.yangtools.concepts;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Set;
+
+public final class CompositeObjectRegistration<T> extends AbstractObjectRegistration<T> {
+
+ private final Set<Registration<? super T>> registrations;
+
+ public CompositeObjectRegistration(T instance, Collection<? extends Registration<? super T>> registrations) {
+ super(instance);
+ if (registrations == null) {
+ throw new IllegalArgumentException();
+ }
+ this.registrations = Collections.unmodifiableSet(new HashSet<>(registrations));
+ }
+
+ @Override
+ protected void removeRegistration() {
+ for (Registration<? super T> registration : registrations) {
+ try {
+ registration.close();
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+ }
+
+ public static <T> CompositeObjectRegistrationBuilder<T> builderFor(T instance) {
+ return new CompositeObjectRegistrationBuilder<>(instance);
+ }
+
+ public static final class CompositeObjectRegistrationBuilder<T> implements //
+ Builder<CompositeObjectRegistration<T>> {
+
+ private final T instance;
+ private final Set<Registration<? super T>> registrations;
+
+ public CompositeObjectRegistrationBuilder(T instance) {
+ this.instance = instance;
+ registrations = new HashSet<>();
+ }
+
+ public CompositeObjectRegistrationBuilder<T> add(Registration<? super T> registration) {
+ if (registration.getInstance() != instance) {
+ throw new IllegalArgumentException("Instance must be same.");
+ }
+ registrations.add(registration);
+ return this;
+ }
+
+ public CompositeObjectRegistrationBuilder<T> remove(Registration<? super T> registration) {
+ if (registration.getInstance() != instance) {
+ throw new IllegalArgumentException("Instance must be same.");
+ }
+ registrations.remove(registration);
+ return this;
+ }
+
+ @Override
+ public CompositeObjectRegistration<T> toInstance() {
+ return new CompositeObjectRegistration<>(instance, registrations);
+ }
+ }
+}
--- /dev/null
+package org.opendaylight.yangtools.concepts.util;
+
+import java.util.Collections;
+import java.util.EventListener;
+import java.util.HashSet;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+
+import javax.swing.text.html.HTMLDocument.Iterator;
+
+import org.opendaylight.yangtools.concepts.AbstractObjectRegistration;
+import org.opendaylight.yangtools.concepts.ListenerRegistration;
+
+public class ListenerRegistry<T extends EventListener> implements Iterable<ListenerRegistration<T>> {
+
+ final Set<ListenerRegistration<T>> listeners;
+ final Set<ListenerRegistration<T>> unmodifiableView;
+
+ public ListenerRegistry() {
+ listeners = new HashSet<>();
+ unmodifiableView = Collections.unmodifiableSet(listeners);
+ }
+
+ public Iterable<ListenerRegistration<T>> getListeners() {
+ return unmodifiableView;
+ }
+
+ public ListenerRegistration<T> register(T listener) {
+ if (listener == null) {
+ throw new IllegalArgumentException("Listener should not be null.");
+ }
+ ListenerRegistrationImpl<T> ret = new ListenerRegistrationImpl<T>(listener);
+ listeners.add(ret);
+ return ret;
+ }
+
+ @Override
+ public java.util.Iterator<ListenerRegistration<T>> iterator() {
+ return listeners.iterator();
+ }
+
+ @SuppressWarnings("rawtypes")
+ private void remove(ListenerRegistrationImpl registration) {
+ listeners.remove(registration);
+ }
+
+ private class ListenerRegistrationImpl<P extends EventListener> //
+ extends AbstractObjectRegistration<P> //
+ implements ListenerRegistration<P> {
+
+ public ListenerRegistrationImpl(P instance) {
+ super(instance);
+ }
+
+ @Override
+ protected void removeRegistration() {
+ ListenerRegistry.this.remove(this);
+ }
+ }
+}