CleanUp: [Preferences] Add nullable annotations to
SettingsChangeNotifier

Change-Id: If6850ac662c408dbffe7bccd05bddd77c6aee1fe
diff --git a/ecommons/org.eclipse.statet.ecommons.coremisc/src/org/eclipse/statet/ecommons/preferences/SettingsChangeNotifier.java b/ecommons/org.eclipse.statet.ecommons.coremisc/src/org/eclipse/statet/ecommons/preferences/SettingsChangeNotifier.java
index 9c3ee2f..0fa1c5b 100644
--- a/ecommons/org.eclipse.statet.ecommons.coremisc/src/org/eclipse/statet/ecommons/preferences/SettingsChangeNotifier.java
+++ b/ecommons/org.eclipse.statet.ecommons.coremisc/src/org/eclipse/statet/ecommons/preferences/SettingsChangeNotifier.java
@@ -14,7 +14,6 @@
 
 package org.eclipse.statet.ecommons.preferences;
 
-import java.util.Arrays;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Map;
@@ -22,16 +21,23 @@
 
 import org.eclipse.core.runtime.IProgressMonitor;
 import org.eclipse.core.runtime.IStatus;
-import org.eclipse.core.runtime.ListenerList;
 import org.eclipse.core.runtime.Status;
 import org.eclipse.core.runtime.jobs.ISchedulingRule;
 import org.eclipse.core.runtime.jobs.Job;
 
+import org.eclipse.statet.jcommons.collections.CopyOnWriteIdentityListSet;
+import org.eclipse.statet.jcommons.collections.ImCollection;
+import org.eclipse.statet.jcommons.collections.ImCollections;
+import org.eclipse.statet.jcommons.collections.ImList;
 import org.eclipse.statet.jcommons.lang.Disposable;
+import org.eclipse.statet.jcommons.lang.NonNull;
+import org.eclipse.statet.jcommons.lang.NonNullByDefault;
+import org.eclipse.statet.jcommons.lang.Nullable;
 
 import org.eclipse.statet.internal.ecommons.preferences.Messages;
 
 
+@NonNullByDefault
 public class SettingsChangeNotifier implements ISchedulingRule, Disposable {
 	
 	
@@ -58,78 +64,83 @@
 	
 	private class NotifyJob extends Job {
 		
-		private final String fSource;
-		private final Set<String> fChangedGroupIds= new HashSet<>();
+		private final String source;
+		private final Set<String> changedGroupIds= new HashSet<>();
 		
 		public NotifyJob(final String source) {
 			super(Messages.SettingsChangeNotifier_Job_title);
 			setPriority(Job.SHORT);
 			setRule(SettingsChangeNotifier.this);
-			fSource = source;
+			this.source= source;
 		}
 		
-		public void addGroups(final String[] groupIds) {
-			fChangedGroupIds.addAll(Arrays.asList(groupIds));
+		public void addGroups(final ImCollection<String> groupIds) {
+			this.changedGroupIds.addAll(groupIds);
 		}
 		
 		@Override
 		protected IStatus run(final IProgressMonitor monitor) {
-			Object[] managers;
-			Object[] listeners;
+			ImList<ManageListener> managers;
+			ImList<ChangeListener> listeners;
 			synchronized (SettingsChangeNotifier.this) {
-				managers = fManagers.getListeners();
-				listeners = fListeners.getListeners();
-				fPendingJobs.remove(fSource);
+				managers= SettingsChangeNotifier.this.managers.toList();
+				listeners= SettingsChangeNotifier.this.listeners.toList();
+				SettingsChangeNotifier.this.pendingJobs.remove(this.source);
 			}
-			monitor.beginTask(Messages.SettingsChangeNotifier_Task_name, managers.length*5+listeners.length*5);
+			monitor.beginTask(Messages.SettingsChangeNotifier_Task_name, managers.size() * 5 + listeners.size() * 5);
 			for (final Object obj : managers) {
-				((ManageListener) obj).beforeSettingsChangeNotification(fChangedGroupIds);
+				((ManageListener) obj).beforeSettingsChangeNotification(this.changedGroupIds);
 				monitor.worked(3);
 			}
 			for (final Object obj : listeners) {
-				((ChangeListener) obj).settingsChanged(fChangedGroupIds);
+				((ChangeListener) obj).settingsChanged(this.changedGroupIds);
 				monitor.worked(5);
 			}
 			for (final Object obj : managers) {
-				((ManageListener) obj).afterSettingsChangeNotification(fChangedGroupIds);
+				((ManageListener) obj).afterSettingsChangeNotification(this.changedGroupIds);
 				monitor.worked(2);
 			}
 			return Status.OK_STATUS;
 		}
 	}
 	
-	private final ListenerList fManagers = new ListenerList();
-	private final ListenerList fListeners = new ListenerList();
-	private final Map<String, NotifyJob> fPendingJobs= new HashMap<>();
+	private volatile boolean isDisposed;
 	
-	private volatile boolean fIsDisposed;
+	private final CopyOnWriteIdentityListSet<ManageListener> managers= new CopyOnWriteIdentityListSet<>();
+	private final CopyOnWriteIdentityListSet<ChangeListener> listeners= new CopyOnWriteIdentityListSet<>();
+	private final Map<String, NotifyJob> pendingJobs= new HashMap<>();
 	
 	
 	public SettingsChangeNotifier() {
-		fIsDisposed = false;
+		this.isDisposed= false;
 	}
 	
 	
-	public Job getNotifyJob(String source, final String[] groupIds) {
-		if (fIsDisposed) {
+	public @Nullable Job getNotifyJob(@Nullable String source, final ImCollection<String> groupIds) {
+		if (this.isDisposed) {
 			return null;
 		}
 		if (source == null) {
-			source = "direct"; //$NON-NLS-1$
+			source= "direct"; //$NON-NLS-1$
 		}
 		synchronized (SettingsChangeNotifier.this) {
-			NotifyJob job = fPendingJobs.get(source);
+			NotifyJob job= this.pendingJobs.get(source);
 			if (job != null) {
 				job.addGroups(groupIds);
 				return null;
 			}
-			job = new NotifyJob(source);
-			fPendingJobs.put(source, job);
+			job= new NotifyJob(source);
+			this.pendingJobs.put(source, job);
 			job.addGroups(groupIds);
 			return job;
 		}
 	}
 	
+	@Deprecated
+	public @Nullable Job getNotifyJob(@Nullable final String source, final @NonNull String[] groupIds) {
+		return getNotifyJob(source, ImCollections.newList(groupIds));
+	}
+	
 	@Override
 	public boolean contains(final ISchedulingRule rule) {
 		return (rule == this);
@@ -140,34 +151,34 @@
 	}
 	
 	public void addChangeListener(final ChangeListener listener) {
-		if (!fIsDisposed) {
-			fListeners.add(listener);
+		if (!this.isDisposed) {
+			this.listeners.add(listener);
 		}
 	}
 	
 	public void removeChangeListener(final ChangeListener listener) {
-		if (!fIsDisposed) {
-			fListeners.remove(listener);
+		if (!this.isDisposed) {
+			this.listeners.remove(listener);
 		}
 	}
 	
 	public void addManageListener(final ManageListener listener) {
-		if (!fIsDisposed) {
-			fManagers.add(listener);
+		if (!this.isDisposed) {
+			this.managers.add(listener);
 		}
 	}
 	
 	public void removeManageListener(final ManageListener listener) {
-		if (!fIsDisposed) {
-			fManagers.remove(listener);
+		if (!this.isDisposed) {
+			this.managers.remove(listener);
 		}
 	}
 	
 	@Override
 	public void dispose() {
-		fIsDisposed = true;
-		fManagers.clear();
-		fListeners.clear();
+		this.isDisposed= true;
+		this.managers.clear();
+		this.listeners.clear();
 	}
 	
 }
diff --git a/ecommons/org.eclipse.statet.ecommons.uimisc/src/org/eclipse/statet/ecommons/preferences/ui/ConfigurationBlock.java b/ecommons/org.eclipse.statet.ecommons.uimisc/src/org/eclipse/statet/ecommons/preferences/ui/ConfigurationBlock.java
index 071731a..d548c5b 100644
--- a/ecommons/org.eclipse.statet.ecommons.uimisc/src/org/eclipse/statet/ecommons/preferences/ui/ConfigurationBlock.java
+++ b/ecommons/org.eclipse.statet.ecommons.uimisc/src/org/eclipse/statet/ecommons/preferences/ui/ConfigurationBlock.java
@@ -32,6 +32,8 @@
 import org.eclipse.ui.preferences.IWorkbenchPreferenceContainer;
 import org.eclipse.ui.statushandlers.StatusManager;
 
+import org.eclipse.statet.jcommons.collections.ImCollection;
+import org.eclipse.statet.jcommons.collections.ImCollections;
 import org.eclipse.statet.jcommons.lang.NonNullByDefault;
 import org.eclipse.statet.jcommons.lang.Nullable;
 
@@ -51,7 +53,8 @@
 		return gd;
 	}
 	
-	public static void scheduleChangeNotification(final IWorkbenchPreferenceContainer container, final String[] groupIds, final boolean directly) {
+	public static void scheduleChangeNotification(final IWorkbenchPreferenceContainer container,
+			final @Nullable ImCollection<String> groupIds, final boolean directly) {
 		if (groupIds != null) {
 			final String source= (directly) ? null : container.toString();
 			final Job job= PreferencesUtil.getSettingsChangeNotifier().getNotifyJob(source, groupIds);
@@ -175,7 +178,7 @@
 	}
 	
 	protected void scheduleChangeNotification(final Set<String> groupIds, final boolean directly) {
-		scheduleChangeNotification(this.container, groupIds.toArray(new String[groupIds.size()]), directly);
+		scheduleChangeNotification(this.container, ImCollections.toList(groupIds), directly);
 	}
 	
 	protected void logSaveError(final BackingStoreException e) {