diff --git a/org.eclipse.help.base/src/org/eclipse/help/internal/base/MissingContentManager.java b/org.eclipse.help.base/src/org/eclipse/help/internal/base/MissingContentManager.java
index ff79d28..b371139 100644
--- a/org.eclipse.help.base/src/org/eclipse/help/internal/base/MissingContentManager.java
+++ b/org.eclipse.help.base/src/org/eclipse/help/internal/base/MissingContentManager.java
@@ -1,225 +1,225 @@
-/*******************************************************************************
- * Copyright (c) 2011, 2015 IBM Corporation and others.
+/*******************************************************************************
+ * Copyright (c) 2011, 2015 IBM Corporation and others.
  *
- * This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License 2.0
- * which accompanies this distribution, and is available at
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
  * https://www.eclipse.org/legal/epl-2.0/
  *
- * SPDX-License-Identifier: EPL-2.0
- *
- * Contributors:
- *     IBM Corporation - initial API and implementation
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
  *******************************************************************************/
-
-package org.eclipse.help.internal.base;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Set;
-import java.util.StringTokenizer;
-
-import org.eclipse.core.runtime.IConfigurationElement;
-import org.eclipse.core.runtime.IExtensionRegistry;
-import org.eclipse.core.runtime.Platform;
-import org.eclipse.core.runtime.preferences.IEclipsePreferences;
-import org.eclipse.core.runtime.preferences.IScopeContext;
-import org.eclipse.core.runtime.preferences.InstanceScope;
-import org.eclipse.help.internal.HelpPlugin;
-import org.osgi.service.prefs.BackingStoreException;
-
-/**
- * Handles unresolved toc place holders as well as situations where remote help
- * is unavailable
- */
-
-public class MissingContentManager {
-
-	private static final String HELP_PROTOCOL = "help:"; //$NON-NLS-1$
-	private static final String EXTENSION_POINT_ID_TOC = HelpPlugin.PLUGIN_ID + ".toc"; //$NON-NLS-1$
-	private static final String ELEMENT_NAME_PLACEHOLDER = "placeholder"; //$NON-NLS-1$
-	private static final String ATTRIBUTE_NAME_PLUGIN = "plugin"; //$NON-NLS-1$
-	private static final String ATTRIBUTE_NAME_PLACEHOLDER_PAGE = "placeholderPage"; //$NON-NLS-1$
-	public static final String  IGNORE_MISSING_PLACEHOLDER_PREFERENCE = "ignorePlaceholders"; //$NON-NLS-1$
-
-	// Hrefs which are processed by org.eclipse.help.internal.webapp.StatusProducer
-	public static final String REMOTE_STATUS_HREF = "NetworkHelpStatus.html"; //$NON-NLS-1$
-	public static final String REMOTE_STATUS_HELP_VIEW_HREF = "NetworkHelpStatusHV.html"; //$NON-NLS-1$
-	public static final String MISSING_TOPIC_HREF = "MissingTopicStatus.html"; //$NON-NLS-1$
-	public static final String MISSING_TOPIC_PATH = "missingTopic/"; //$NON-NLS-1$
-	public static final String MISSING_BOOKS_HREF = "MissingBooks.html"; //$NON-NLS-1$
-	public static final String MISSING_BOOKS_HELP_VIEW_HREF = "MissingBooksHV.html"; //$NON-NLS-1$
-
-	/*
-	 * A place holder defines a page to be shown when a documentation page
-	 * which matches the specified path not installed
-	 */
-	public static class Placeholder implements Comparable<Placeholder> {
-		public String path;
-		public String bundle;
-		public String placeholderPage;
-
-		public Placeholder(String path, String bundle, String placeholderPage) {
-			this.path = path;
-			this.bundle = bundle;
-			this.placeholderPage = placeholderPage;
-		}
-
-		@Override
-		public int compareTo(Placeholder o) {
-			return o.path.compareTo(path);
-		}
-	}
-
-	private static MissingContentManager instance;
-	private List<Placeholder> placeholders;
-    private Set<String> bundlesToIgnore; // A set of bundles the user does not want to see reference to
-
-	public static MissingContentManager getInstance() {
-		if ( instance == null ) {
-			instance = new MissingContentManager();
-		}
-		return instance;
-	}
-
-	/*
-	 * Read the extension registry
-	 */
-	private MissingContentManager() {
-        IExtensionRegistry registry = Platform.getExtensionRegistry();
-		placeholders = new ArrayList<>();
-		bundlesToIgnore = new HashSet<>();
-        if ( BaseHelpSystem.getMode() == BaseHelpSystem.MODE_INFOCENTER ) {
-        	return; // Placeholders are not shown for infocenters
-        }
-        // Read the placeholders from the extension registry
-		IConfigurationElement[] elements = registry
-				.getConfigurationElementsFor(EXTENSION_POINT_ID_TOC);
-		for (int i = 0; i < elements.length; ++i) {
-			IConfigurationElement elem = elements[i];
-			String pluginId = elem.getContributor().getName();
-			if (elem.getName().equals(ELEMENT_NAME_PLACEHOLDER)) {
-				try {
-					String plugin = elem.getAttribute(ATTRIBUTE_NAME_PLUGIN);
-					String path = HELP_PROTOCOL  + plugin + '/';
-					String placeholder = elem
-							.getAttribute(ATTRIBUTE_NAME_PLACEHOLDER_PAGE);
-					placeholders.add(new Placeholder(path, plugin, placeholder));
-				} catch (Exception e) {
-					// log and skip
-					String msg = "Exception reading " + ELEMENT_NAME_PLACEHOLDER + " extension in bundle" + pluginId; //$NON-NLS-1$ //$NON-NLS-2$
-					HelpPlugin.logError(msg, e);
-				}
-			}
-		}
-		Collections.sort(placeholders);
-		// Read the preferences to find any ignored placeholders
-		String ignoredBundles = Platform.getPreferencesService().getString(HelpBasePlugin.PLUGIN_ID, IGNORE_MISSING_PLACEHOLDER_PREFERENCE, "", null); //$NON-NLS-1$
-		if (ignoredBundles.length() > 0) {
-			StringTokenizer tokenizer = new StringTokenizer(ignoredBundles, " ,"); //$NON-NLS-1$
-			while (tokenizer.hasMoreTokens()) {
-				bundlesToIgnore.add(tokenizer.nextToken());
-			}
-		}
-	}
-
-	/**
-     * Called when a page cannot be found
-	 * @param path the path of the page that could not be loaded
-	 * @return a place holder page if defined, otherwise an error page
-	 */
-	public String getPageNotFoundPage(String path, boolean showPlaceholderPage) {
-		for (Iterator<Placeholder> iter = placeholders.iterator(); iter.hasNext(); ) {
-			Placeholder placeholder = iter.next();
-			if (path.startsWith(placeholder.path) && Platform.getBundle(placeholder.bundle) == null) {
-				if ( showPlaceholderPage) {
-				    return placeholder.placeholderPage;
-				} else {
-				    return "/org.eclipse.help.webapp/" + MISSING_TOPIC_PATH + path.substring(HELP_PROTOCOL.length()); //$NON-NLS-1$
-				}
-			}
-		}
-		return Platform.getPreferencesService().getString(HelpBasePlugin.PLUGIN_ID, "page_not_found", null, null); //$NON-NLS-1$
-	}
-
-	/**
-	 *
-	 * @return true if there is an unresolved place holder and this is not an infocenter
-	 */
-	public boolean isUnresolvedPlaceholders() {
-		if (BaseHelpSystem.getMode()==BaseHelpSystem.MODE_INFOCENTER) {
-			return false;
-		}
-		Placeholder[] unresolvedPlaceHolders = getUnresolvedPlaceholders();
-		return unresolvedPlaceHolders.length > 0;
-	}
-
-	/**
-	 * If any help is missing returns an appropriate page
-	 * @return null if no help is unavailable or an appropriate page if
-	 *  the plug-in that corresponds to a place holder is not available.
-	 *  The returned page will be in the format /plug-in/path.
-	 */
-	public String getHelpMissingPage(boolean isHelpView) {
-		Placeholder[] unresolvedPlaceHolders = getUnresolvedPlaceholders();
-		if (unresolvedPlaceHolders.length == 0) {
-		    	return null;
-		} else {
-			    String suffix = isHelpView ? MISSING_BOOKS_HELP_VIEW_HREF : MISSING_BOOKS_HREF;
-		    	return "/org.eclipse.help.webapp" + '/'+ suffix; //$NON-NLS-1$
-		}
-	}
-
-	/**
-	 * Get the page to be shown when some remote help is known to be unavailable
-	 */
-	public String getRemoteHelpUnavailablePage(boolean isHelpView) {
-		if ( BaseHelpSystem.getMode()!=BaseHelpSystem.MODE_INFOCENTER ) {
-		    String suffix = isHelpView ? REMOTE_STATUS_HELP_VIEW_HREF : REMOTE_STATUS_HREF;
-			return "/org.eclipse.help.webapp/" + suffix; //$NON-NLS-1$
-		}
-		return null;
-	}
-
-	public Placeholder[] getUnresolvedPlaceholders() {
-		List<Placeholder> unresolved;
-		unresolved = new ArrayList<>();
-		for (Iterator<Placeholder> iter = placeholders.iterator(); iter.hasNext(); ) {
-			Placeholder ph = iter.next();
-			String bundle = ph.bundle;
-			if (bundle != null && !bundlesToIgnore.contains(bundle) ) {
-			    if (Platform.getBundle(bundle) == null ) {
-			    	unresolved.add(ph);
-			    }
-			}
-		}
-		return unresolved.toArray(new Placeholder[unresolved.size()]);
-	}
-
-	// Modifies the preferences to ignore any bundles that are currently unresolved placeholders
-	public void ignoreAllMissingPlaceholders() {
-		Placeholder[] unresolved = getUnresolvedPlaceholders();
-		String ignoredBundles = Platform.getPreferencesService().getString(HelpBasePlugin.PLUGIN_ID, IGNORE_MISSING_PLACEHOLDER_PREFERENCE, "", null); //$NON-NLS-1$
-		for ( int i = 0; i < unresolved.length; i++) {
-			String bundle = unresolved[i].bundle;
-			bundlesToIgnore.add(bundle);
-			if (ignoredBundles.length() > 0) {
-				ignoredBundles = ignoredBundles + ',';
-			}
-			ignoredBundles = ignoredBundles + bundle;
-
-		}
-		IScopeContext instanceScope = InstanceScope.INSTANCE;
-		IEclipsePreferences prefs = instanceScope.getNode(HelpBasePlugin.PLUGIN_ID);
-		prefs.put(IGNORE_MISSING_PLACEHOLDER_PREFERENCE, ignoredBundles);
-		try {
-			prefs.flush();
-		} catch (BackingStoreException e) {
-			HelpBasePlugin.logError("Cannot save preferences", e); //$NON-NLS-1$
-		}
-	}
-
-}
+
+package org.eclipse.help.internal.base;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+import java.util.StringTokenizer;
+
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.core.runtime.IExtensionRegistry;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.core.runtime.preferences.IEclipsePreferences;
+import org.eclipse.core.runtime.preferences.IScopeContext;
+import org.eclipse.core.runtime.preferences.InstanceScope;
+import org.eclipse.help.internal.HelpPlugin;
+import org.osgi.service.prefs.BackingStoreException;
+
+/**
+ * Handles unresolved toc place holders as well as situations where remote help
+ * is unavailable
+ */
+
+public class MissingContentManager {
+
+	private static final String HELP_PROTOCOL = "help:"; //$NON-NLS-1$
+	private static final String EXTENSION_POINT_ID_TOC = HelpPlugin.PLUGIN_ID + ".toc"; //$NON-NLS-1$
+	private static final String ELEMENT_NAME_PLACEHOLDER = "placeholder"; //$NON-NLS-1$
+	private static final String ATTRIBUTE_NAME_PLUGIN = "plugin"; //$NON-NLS-1$
+	private static final String ATTRIBUTE_NAME_PLACEHOLDER_PAGE = "placeholderPage"; //$NON-NLS-1$
+	public static final String  IGNORE_MISSING_PLACEHOLDER_PREFERENCE = "ignorePlaceholders"; //$NON-NLS-1$
+
+	// Hrefs which are processed by org.eclipse.help.internal.webapp.StatusProducer
+	public static final String REMOTE_STATUS_HREF = "NetworkHelpStatus.html"; //$NON-NLS-1$
+	public static final String REMOTE_STATUS_HELP_VIEW_HREF = "NetworkHelpStatusHV.html"; //$NON-NLS-1$
+	public static final String MISSING_TOPIC_HREF = "MissingTopicStatus.html"; //$NON-NLS-1$
+	public static final String MISSING_TOPIC_PATH = "missingTopic/"; //$NON-NLS-1$
+	public static final String MISSING_BOOKS_HREF = "MissingBooks.html"; //$NON-NLS-1$
+	public static final String MISSING_BOOKS_HELP_VIEW_HREF = "MissingBooksHV.html"; //$NON-NLS-1$
+
+	/*
+	 * A place holder defines a page to be shown when a documentation page
+	 * which matches the specified path not installed
+	 */
+	public static class Placeholder implements Comparable<Placeholder> {
+		public String path;
+		public String bundle;
+		public String placeholderPage;
+
+		public Placeholder(String path, String bundle, String placeholderPage) {
+			this.path = path;
+			this.bundle = bundle;
+			this.placeholderPage = placeholderPage;
+		}
+
+		@Override
+		public int compareTo(Placeholder o) {
+			return o.path.compareTo(path);
+		}
+	}
+
+	private static MissingContentManager instance;
+	private List<Placeholder> placeholders;
+    private Set<String> bundlesToIgnore; // A set of bundles the user does not want to see reference to
+
+	public static MissingContentManager getInstance() {
+		if ( instance == null ) {
+			instance = new MissingContentManager();
+		}
+		return instance;
+	}
+
+	/*
+	 * Read the extension registry
+	 */
+	private MissingContentManager() {
+        IExtensionRegistry registry = Platform.getExtensionRegistry();
+		placeholders = new ArrayList<>();
+		bundlesToIgnore = new HashSet<>();
+        if ( BaseHelpSystem.getMode() == BaseHelpSystem.MODE_INFOCENTER ) {
+        	return; // Placeholders are not shown for infocenters
+        }
+        // Read the placeholders from the extension registry
+		IConfigurationElement[] elements = registry
+				.getConfigurationElementsFor(EXTENSION_POINT_ID_TOC);
+		for (int i = 0; i < elements.length; ++i) {
+			IConfigurationElement elem = elements[i];
+			String pluginId = elem.getContributor().getName();
+			if (elem.getName().equals(ELEMENT_NAME_PLACEHOLDER)) {
+				try {
+					String plugin = elem.getAttribute(ATTRIBUTE_NAME_PLUGIN);
+					String path = HELP_PROTOCOL  + plugin + '/';
+					String placeholder = elem
+							.getAttribute(ATTRIBUTE_NAME_PLACEHOLDER_PAGE);
+					placeholders.add(new Placeholder(path, plugin, placeholder));
+				} catch (Exception e) {
+					// log and skip
+					String msg = "Exception reading " + ELEMENT_NAME_PLACEHOLDER + " extension in bundle" + pluginId; //$NON-NLS-1$ //$NON-NLS-2$
+					HelpPlugin.logError(msg, e);
+				}
+			}
+		}
+		Collections.sort(placeholders);
+		// Read the preferences to find any ignored placeholders
+		String ignoredBundles = Platform.getPreferencesService().getString(HelpBasePlugin.PLUGIN_ID, IGNORE_MISSING_PLACEHOLDER_PREFERENCE, "", null); //$NON-NLS-1$
+		if (ignoredBundles.length() > 0) {
+			StringTokenizer tokenizer = new StringTokenizer(ignoredBundles, " ,"); //$NON-NLS-1$
+			while (tokenizer.hasMoreTokens()) {
+				bundlesToIgnore.add(tokenizer.nextToken());
+			}
+		}
+	}
+
+	/**
+     * Called when a page cannot be found
+	 * @param path the path of the page that could not be loaded
+	 * @return a place holder page if defined, otherwise an error page
+	 */
+	public String getPageNotFoundPage(String path, boolean showPlaceholderPage) {
+		for (Iterator<Placeholder> iter = placeholders.iterator(); iter.hasNext(); ) {
+			Placeholder placeholder = iter.next();
+			if (path.startsWith(placeholder.path) && Platform.getBundle(placeholder.bundle) == null) {
+				if ( showPlaceholderPage) {
+				    return placeholder.placeholderPage;
+				} else {
+				    return "/org.eclipse.help.webapp/" + MISSING_TOPIC_PATH + path.substring(HELP_PROTOCOL.length()); //$NON-NLS-1$
+				}
+			}
+		}
+		return Platform.getPreferencesService().getString(HelpBasePlugin.PLUGIN_ID, "page_not_found", null, null); //$NON-NLS-1$
+	}
+
+	/**
+	 *
+	 * @return true if there is an unresolved place holder and this is not an infocenter
+	 */
+	public boolean isUnresolvedPlaceholders() {
+		if (BaseHelpSystem.getMode()==BaseHelpSystem.MODE_INFOCENTER) {
+			return false;
+		}
+		Placeholder[] unresolvedPlaceHolders = getUnresolvedPlaceholders();
+		return unresolvedPlaceHolders.length > 0;
+	}
+
+	/**
+	 * If any help is missing returns an appropriate page
+	 * @return null if no help is unavailable or an appropriate page if
+	 *  the plug-in that corresponds to a place holder is not available.
+	 *  The returned page will be in the format /plug-in/path.
+	 */
+	public String getHelpMissingPage(boolean isHelpView) {
+		Placeholder[] unresolvedPlaceHolders = getUnresolvedPlaceholders();
+		if (unresolvedPlaceHolders.length == 0) {
+		    	return null;
+		} else {
+			    String suffix = isHelpView ? MISSING_BOOKS_HELP_VIEW_HREF : MISSING_BOOKS_HREF;
+		    	return "/org.eclipse.help.webapp" + '/'+ suffix; //$NON-NLS-1$
+		}
+	}
+
+	/**
+	 * Get the page to be shown when some remote help is known to be unavailable
+	 */
+	public String getRemoteHelpUnavailablePage(boolean isHelpView) {
+		if ( BaseHelpSystem.getMode()!=BaseHelpSystem.MODE_INFOCENTER ) {
+		    String suffix = isHelpView ? REMOTE_STATUS_HELP_VIEW_HREF : REMOTE_STATUS_HREF;
+			return "/org.eclipse.help.webapp/" + suffix; //$NON-NLS-1$
+		}
+		return null;
+	}
+
+	public Placeholder[] getUnresolvedPlaceholders() {
+		List<Placeholder> unresolved;
+		unresolved = new ArrayList<>();
+		for (Iterator<Placeholder> iter = placeholders.iterator(); iter.hasNext(); ) {
+			Placeholder ph = iter.next();
+			String bundle = ph.bundle;
+			if (bundle != null && !bundlesToIgnore.contains(bundle) ) {
+			    if (Platform.getBundle(bundle) == null ) {
+			    	unresolved.add(ph);
+			    }
+			}
+		}
+		return unresolved.toArray(new Placeholder[unresolved.size()]);
+	}
+
+	// Modifies the preferences to ignore any bundles that are currently unresolved placeholders
+	public void ignoreAllMissingPlaceholders() {
+		Placeholder[] unresolved = getUnresolvedPlaceholders();
+		String ignoredBundles = Platform.getPreferencesService().getString(HelpBasePlugin.PLUGIN_ID, IGNORE_MISSING_PLACEHOLDER_PREFERENCE, "", null); //$NON-NLS-1$
+		for ( int i = 0; i < unresolved.length; i++) {
+			String bundle = unresolved[i].bundle;
+			bundlesToIgnore.add(bundle);
+			if (ignoredBundles.length() > 0) {
+				ignoredBundles = ignoredBundles + ',';
+			}
+			ignoredBundles = ignoredBundles + bundle;
+
+		}
+		IScopeContext instanceScope = InstanceScope.INSTANCE;
+		IEclipsePreferences prefs = instanceScope.getNode(HelpBasePlugin.PLUGIN_ID);
+		prefs.put(IGNORE_MISSING_PLACEHOLDER_PREFERENCE, ignoredBundles);
+		try {
+			prefs.flush();
+		} catch (BackingStoreException e) {
+			HelpBasePlugin.logError("Cannot save preferences", e); //$NON-NLS-1$
+		}
+	}
+
+}
diff --git a/org.eclipse.help.base/src/org/eclipse/help/internal/search/AnalyzerFactory.java b/org.eclipse.help.base/src/org/eclipse/help/internal/search/AnalyzerFactory.java
index 8ba94a1..adae6bd 100644
--- a/org.eclipse.help.base/src/org/eclipse/help/internal/search/AnalyzerFactory.java
+++ b/org.eclipse.help.base/src/org/eclipse/help/internal/search/AnalyzerFactory.java
@@ -1,70 +1,70 @@
-/*******************************************************************************
- * Copyright (c) 2012, 2016 IBM Corporation and others.
+/*******************************************************************************
+ * Copyright (c) 2012, 2016 IBM Corporation and others.
  *
- * This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License 2.0
- * which accompanies this distribution, and is available at
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
  * https://www.eclipse.org/legal/epl-2.0/
  *
- * SPDX-License-Identifier: EPL-2.0
- *
- * Contributors:
- *     IBM Corporation - initial API and implementation
- *     Sopot Cela - Bug 466829
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     Sopot Cela - Bug 466829
  *******************************************************************************/
-package org.eclipse.help.internal.search;
-
-import org.apache.lucene.analysis.Analyzer;
-import org.apache.lucene.analysis.br.BrazilianAnalyzer;
-import org.apache.lucene.analysis.cjk.CJKAnalyzer;
-import org.apache.lucene.analysis.cz.CzechAnalyzer;
-import org.apache.lucene.analysis.de.GermanAnalyzer;
-import org.apache.lucene.analysis.el.GreekAnalyzer;
-import org.apache.lucene.analysis.fr.FrenchAnalyzer;
-import org.apache.lucene.analysis.nl.DutchAnalyzer;
-import org.apache.lucene.analysis.ru.RussianAnalyzer;
-import org.eclipse.core.runtime.CoreException;
-import org.eclipse.core.runtime.IConfigurationElement;
-import org.eclipse.core.runtime.IExecutableExtension;
-
-/**
- * A factory responsible for instantiating a lucene {@link Analyzer}.
- */
-public class AnalyzerFactory implements IExecutableExtension{
-	private String locale = null;
-	public Analyzer create() {
-		if (locale == null)
-			return null;
-		if ("pt".equals(locale)) //$NON-NLS-1$
-			return new BrazilianAnalyzer();
-		if ("ja".equals(locale)) //$NON-NLS-1$
-			return new CJKAnalyzer();
-		if ("ko".equals(locale)) //$NON-NLS-1$
-			return new CJKAnalyzer();
-		if ("pt".equals(locale)) //$NON-NLS-1$
-			return new BrazilianAnalyzer();
-		if ("cs".equals(locale)) //$NON-NLS-1$
-			return new CzechAnalyzer();
-		if ("de".equals(locale)) //$NON-NLS-1$
-			return new GermanAnalyzer();
-		if ("el".equals(locale)) //$NON-NLS-1$
-			return new GreekAnalyzer();
-		if ("fr".equals(locale)) //$NON-NLS-1$
-			return new FrenchAnalyzer();
-		if ("nl".equals(locale)) //$NON-NLS-1$
-			return new DutchAnalyzer();
-		if ("ru".equals(locale)) //$NON-NLS-1$
-			return new RussianAnalyzer();
-		//unknown language
-		return null;
-
-	}
-
-	@Override
-	public void setInitializationData(IConfigurationElement config, String propertyName, Object data)
-			throws CoreException {
-		if (data instanceof String)
-			locale = (String)data;
-	}
-
-}
+package org.eclipse.help.internal.search;
+
+import org.apache.lucene.analysis.Analyzer;
+import org.apache.lucene.analysis.br.BrazilianAnalyzer;
+import org.apache.lucene.analysis.cjk.CJKAnalyzer;
+import org.apache.lucene.analysis.cz.CzechAnalyzer;
+import org.apache.lucene.analysis.de.GermanAnalyzer;
+import org.apache.lucene.analysis.el.GreekAnalyzer;
+import org.apache.lucene.analysis.fr.FrenchAnalyzer;
+import org.apache.lucene.analysis.nl.DutchAnalyzer;
+import org.apache.lucene.analysis.ru.RussianAnalyzer;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.core.runtime.IExecutableExtension;
+
+/**
+ * A factory responsible for instantiating a lucene {@link Analyzer}.
+ */
+public class AnalyzerFactory implements IExecutableExtension{
+	private String locale = null;
+	public Analyzer create() {
+		if (locale == null)
+			return null;
+		if ("pt".equals(locale)) //$NON-NLS-1$
+			return new BrazilianAnalyzer();
+		if ("ja".equals(locale)) //$NON-NLS-1$
+			return new CJKAnalyzer();
+		if ("ko".equals(locale)) //$NON-NLS-1$
+			return new CJKAnalyzer();
+		if ("pt".equals(locale)) //$NON-NLS-1$
+			return new BrazilianAnalyzer();
+		if ("cs".equals(locale)) //$NON-NLS-1$
+			return new CzechAnalyzer();
+		if ("de".equals(locale)) //$NON-NLS-1$
+			return new GermanAnalyzer();
+		if ("el".equals(locale)) //$NON-NLS-1$
+			return new GreekAnalyzer();
+		if ("fr".equals(locale)) //$NON-NLS-1$
+			return new FrenchAnalyzer();
+		if ("nl".equals(locale)) //$NON-NLS-1$
+			return new DutchAnalyzer();
+		if ("ru".equals(locale)) //$NON-NLS-1$
+			return new RussianAnalyzer();
+		//unknown language
+		return null;
+
+	}
+
+	@Override
+	public void setInitializationData(IConfigurationElement config, String propertyName, Object data)
+			throws CoreException {
+		if (data instanceof String)
+			locale = (String)data;
+	}
+
+}
diff --git a/org.eclipse.help.ui/src/org/eclipse/help/ui/internal/preferences/IC.java b/org.eclipse.help.ui/src/org/eclipse/help/ui/internal/preferences/IC.java
index e652945..106c647 100644
--- a/org.eclipse.help.ui/src/org/eclipse/help/ui/internal/preferences/IC.java
+++ b/org.eclipse.help.ui/src/org/eclipse/help/ui/internal/preferences/IC.java
@@ -1,168 +1,168 @@
-/*******************************************************************************
- * Copyright (c) 2011 IBM Corporation and others.
+/*******************************************************************************
+ * Copyright (c) 2011 IBM Corporation and others.
  *
- * This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License 2.0
- * which accompanies this distribution, and is available at
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
  * https://www.eclipse.org/legal/epl-2.0/
  *
- * SPDX-License-Identifier: EPL-2.0
- *
- * Contributors:
- *     IBM Corporation - initial API and implementation
- *******************************************************************************/
-
-package org.eclipse.help.ui.internal.preferences;
-
-import java.net.InetAddress;
-import java.net.MalformedURLException;
-import java.net.URL;
-import java.net.UnknownHostException;
-
-/**
- * Information Center (IC) - stores URL info.
- *
- * @author chaustin
- *
- */
-public class IC {
-
-	private String name;
-	private boolean enabled;
-	private String protocol;
-	private String host;
-	private String path;
-	private int port = -1;
-
-
-	public IC(String name,String href,boolean enabled) throws MalformedURLException
-	{
-		this.name = name;
-		this.enabled = enabled;
-		setHref(href);
-	}
-
-	public void setHref(String href) throws MalformedURLException
-	{
-		if (href.startsWith(":")) //$NON-NLS-1$
-			href = "http"+href; //$NON-NLS-1$
-
-		setHref(new URL(href));
-	}
-
-	public void setHref(URL url)
-	{
-		this.protocol = url.getProtocol();
-		this.host = url.getHost();
-		this.path = url.getPath();
-		this.port = url.getPort();
-		if (port==-1)
-		{
-			if (protocol.equals("http")) //$NON-NLS-1$
-				port = 80;
-			else if (protocol.equals("https")) //$NON-NLS-1$
-				port = 443;
-		}
-	}
-
-	public String getHref()
-	{
-		String portString = ":"+port; //$NON-NLS-1$
-		if (port==80 && protocol.equals("http")) //$NON-NLS-1$
-			portString = ""; //$NON-NLS-1$
-		else if (port==443 && protocol.equals("https")) //$NON-NLS-1$
-			portString = ""; //$NON-NLS-1$
-
-		return protocol+"://"+host+portString+path; //$NON-NLS-1$
-	}
-
-
-	public String getName()
-	{
-		return name;
-	}
-
-
-	public boolean isEnabled()
-	{
-		return enabled;
-	}
-	public String getProtocol() {
-		return protocol;
-	}
-
-	public void setProtocol(String protocol) {
-		this.protocol = protocol;
-	}
-
-	public String getHost() {
-		return host;
-	}
-
-	public void setHost(String host) {
-		this.host = host;
-	}
-
-	public String getPath() {
-		return path;
-	}
-
-	public void setPath(String path) {
-		this.path = path;
-	}
-
-	public int getPort() {
-		return port;
-	}
-
-	public void setPort(int port) {
-		this.port = port;
-	}
-
-	public void setName(String name) {
-		this.name = name;
-	}
-
-	public void setEnabled(boolean enabled) {
-		this.enabled = enabled;
-	}
-
-	@Override
-	public String toString()
-	{
-		return name+" ("+getHref()+")"; //$NON-NLS-1$ //$NON-NLS-2$
-	}
-
-	/**
-	 * Tests to see if 2 ICs are equal.  The state (enabled or disabled) is ignored
-	 * during this operation.
-	 *
-	 */
-	@Override
-	public boolean equals(Object o)
-	{
-		if (!(o instanceof IC))
-			return false;
-
-		IC candidate = (IC)o;
-
-		if (getName().equals(candidate.getName())
-				&& getPath().equals(candidate.getPath())
-				&& getPort()==candidate.getPort()
-				&& getProtocol().equals(candidate.getProtocol()))
-		{
-			try {
-				InetAddress host1 = InetAddress.getByName(getHost());
-				InetAddress host2 = InetAddress.getByName(candidate.getHost());
-
-				if (host1.getHostAddress().equals(host2.getHostAddress()))
-					return true;
-			} catch (UnknownHostException e) {
-				if (getHost().equals(candidate.getHost()))
-					return true;
-			}
-		}
-
-		return false;
-	}
-}
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.help.ui.internal.preferences;
+
+import java.net.InetAddress;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.net.UnknownHostException;
+
+/**
+ * Information Center (IC) - stores URL info.
+ *
+ * @author chaustin
+ *
+ */
+public class IC {
+
+	private String name;
+	private boolean enabled;
+	private String protocol;
+	private String host;
+	private String path;
+	private int port = -1;
+
+
+	public IC(String name,String href,boolean enabled) throws MalformedURLException
+	{
+		this.name = name;
+		this.enabled = enabled;
+		setHref(href);
+	}
+
+	public void setHref(String href) throws MalformedURLException
+	{
+		if (href.startsWith(":")) //$NON-NLS-1$
+			href = "http"+href; //$NON-NLS-1$
+
+		setHref(new URL(href));
+	}
+
+	public void setHref(URL url)
+	{
+		this.protocol = url.getProtocol();
+		this.host = url.getHost();
+		this.path = url.getPath();
+		this.port = url.getPort();
+		if (port==-1)
+		{
+			if (protocol.equals("http")) //$NON-NLS-1$
+				port = 80;
+			else if (protocol.equals("https")) //$NON-NLS-1$
+				port = 443;
+		}
+	}
+
+	public String getHref()
+	{
+		String portString = ":"+port; //$NON-NLS-1$
+		if (port==80 && protocol.equals("http")) //$NON-NLS-1$
+			portString = ""; //$NON-NLS-1$
+		else if (port==443 && protocol.equals("https")) //$NON-NLS-1$
+			portString = ""; //$NON-NLS-1$
+
+		return protocol+"://"+host+portString+path; //$NON-NLS-1$
+	}
+
+
+	public String getName()
+	{
+		return name;
+	}
+
+
+	public boolean isEnabled()
+	{
+		return enabled;
+	}
+	public String getProtocol() {
+		return protocol;
+	}
+
+	public void setProtocol(String protocol) {
+		this.protocol = protocol;
+	}
+
+	public String getHost() {
+		return host;
+	}
+
+	public void setHost(String host) {
+		this.host = host;
+	}
+
+	public String getPath() {
+		return path;
+	}
+
+	public void setPath(String path) {
+		this.path = path;
+	}
+
+	public int getPort() {
+		return port;
+	}
+
+	public void setPort(int port) {
+		this.port = port;
+	}
+
+	public void setName(String name) {
+		this.name = name;
+	}
+
+	public void setEnabled(boolean enabled) {
+		this.enabled = enabled;
+	}
+
+	@Override
+	public String toString()
+	{
+		return name+" ("+getHref()+")"; //$NON-NLS-1$ //$NON-NLS-2$
+	}
+
+	/**
+	 * Tests to see if 2 ICs are equal.  The state (enabled or disabled) is ignored
+	 * during this operation.
+	 *
+	 */
+	@Override
+	public boolean equals(Object o)
+	{
+		if (!(o instanceof IC))
+			return false;
+
+		IC candidate = (IC)o;
+
+		if (getName().equals(candidate.getName())
+				&& getPath().equals(candidate.getPath())
+				&& getPort()==candidate.getPort()
+				&& getProtocol().equals(candidate.getProtocol()))
+		{
+			try {
+				InetAddress host1 = InetAddress.getByName(getHost());
+				InetAddress host2 = InetAddress.getByName(candidate.getHost());
+
+				if (host1.getHostAddress().equals(host2.getHostAddress()))
+					return true;
+			} catch (UnknownHostException e) {
+				if (getHost().equals(candidate.getHost()))
+					return true;
+			}
+		}
+
+		return false;
+	}
+}
diff --git a/org.eclipse.help.ui/src/org/eclipse/help/ui/internal/preferences/ICButtons.java b/org.eclipse.help.ui/src/org/eclipse/help/ui/internal/preferences/ICButtons.java
index 350a126..da9d204 100644
--- a/org.eclipse.help.ui/src/org/eclipse/help/ui/internal/preferences/ICButtons.java
+++ b/org.eclipse.help.ui/src/org/eclipse/help/ui/internal/preferences/ICButtons.java
@@ -1,285 +1,285 @@
-/*******************************************************************************
- * Copyright (c) 2011, 2016 IBM Corporation and others.
+/*******************************************************************************
+ * Copyright (c) 2011, 2016 IBM Corporation and others.
  *
- * This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License 2.0
- * which accompanies this distribution, and is available at
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
  * https://www.eclipse.org/legal/epl-2.0/
  *
- * SPDX-License-Identifier: EPL-2.0
- *
- * Contributors:
- *     IBM Corporation - initial API and implementation
- *******************************************************************************/
-
-package org.eclipse.help.ui.internal.preferences;
-
-
-import java.util.List;
-
-import org.eclipse.help.ui.internal.Messages;
-import org.eclipse.jface.dialogs.MessageDialog;
-import org.eclipse.jface.viewers.IStructuredSelection;
-import org.eclipse.jface.window.Window;
-import org.eclipse.osgi.util.NLS;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.events.SelectionEvent;
-import org.eclipse.swt.events.SelectionListener;
-import org.eclipse.swt.layout.GridData;
-import org.eclipse.swt.layout.GridLayout;
-import org.eclipse.swt.widgets.Button;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Table;
-
-public class ICButtons implements SelectionListener{
-
-	private HelpContentPreferencePage page;
-
-	private Button addIC;
-	private Button editIC;
-	private Button removeIC;
-	private Button moveUp;
-	private Button moveDown;
-	private Button testIC;
-	private Button enableIC;
-
-	private boolean enabled = true;
-
-	public ICButtons(Composite parent,HelpContentPreferencePage page)
-	{
-		this.page = page;
-
-		Composite container = new Composite(parent, SWT.NONE);
-		GridLayout layout = new GridLayout();
-		layout.marginHeight = 0;
-		layout.marginWidth = 0;
-		container.setLayout(layout);
-		container.setLayoutData(new GridData(GridData.FILL_VERTICAL));
-		container.setFont(parent.getFont());
-
-		addIC = createPushButton(container, Messages.HelpContentBlock_addICTitle);
-		editIC = createPushButton(container, Messages.HelpContentBlock_editICTitle);
-		removeIC = createPushButton(container, Messages.HelpContentBlock_removeICTitle);
-		testIC = createPushButton(container, Messages.HelpContentBlock_testConnectionTitle);
-
-		String enableTitle = Messages.HelpContentBlock_3.length() > Messages.HelpContentBlock_4.length() ?
-				Messages.HelpContentBlock_3 : Messages.HelpContentBlock_4;
-		enableIC = createPushButton(container, enableTitle);
-		moveUp = createPushButton(container, Messages.HelpContentBlock_upTitle);
-		moveDown = createPushButton(container, Messages.HelpContentBlock_downTitle);
-
-		page.getTable().getTable().addSelectionListener(this);
-
-
-		updateButtonStates();
-	}
-
-	public void setEnabled(boolean enabled)
-	{
-		this.enabled  = enabled;
-		updateButtonStates();
-	}
-
-	public Button createPushButton(Composite parent, String buttonText) {
-		Button button = new Button(parent, SWT.PUSH);
-		button.setFont(parent.getFont());
-		button.setText(buttonText);
-		button.addSelectionListener(this);
-		page.setButtonLayoutData(button);
-		return button;
-	}
-
-	@Override
-	public void widgetSelected(SelectionEvent e) {
-		if (e.getSource() instanceof Button)
-		{
-			if (e.getSource()==addIC)
-				addIC();
-			else if (e.getSource()==editIC)
-				editIC();
-			else if (e.getSource()==removeIC)
-				removeIC();
-			else if (e.getSource()==testIC)
-				testIC();
-			else if (e.getSource()==enableIC)
-				enableIC();
-			else if (e.getSource()==moveUp)
-				move(-1);
-			else if (e.getSource()==moveDown)
-				move(1);
-		}
-		else if (e.getSource() instanceof Table)
-			updateButtonStates();
-	}
-
-	@Override
-	public void widgetDefaultSelected(SelectionEvent e) {
-		if (e.getSource() instanceof Table)
-			editIC();
-	}
-
-	public void addIC()
-	{
-		ICDialog dialog = new ICDialog(page.getShell());
-		if (dialog.open() == Window.OK) {
-			page.getTable().addIC(dialog.getIC());
-			updateButtonStates();
-		}
-	}
-
-	public void editIC()
-	{
-		IStructuredSelection selection = (IStructuredSelection)page.getTable().getSelection();
-		IC ic = (IC)selection.getFirstElement();
-		if (ic==null)
-			return;
-
-		ICDialog dialog = new ICDialog(page.getShell(),ic);
-
-		if (dialog.open() == Window.OK) {
-			page.getTable().editIC(dialog.getIC());
-			updateButtonStates();
-		}
-	}
-
-	public void removeIC()
-	{
-		IStructuredSelection selection = (IStructuredSelection)page.getTable().getSelection();
-		List<IC> ics = selection.toList();
-		String remove = ""; //$NON-NLS-1$
-
-		for (int i=0;i<ics.size();i++)
-		{
-			remove+="\n"+ics.get(i); //$NON-NLS-1$
-		}
-
-		boolean shouldRemove =
-	          MessageDialog.openQuestion(
-	        	page.getShell(),
-	            NLS.bind(Messages.HelpContentBlock_rmvTitle ,""), //$NON-NLS-1$
-	            NLS.bind(Messages.HelpContentBlock_rmvLabel ,remove));
-
-		if (shouldRemove)
-		{
-			for (int i=0;i<ics.size();i++)
-				page.getTable().removeIC(ics.get(i));
-			updateButtonStates();
-		}
-	}
-
-	public void testIC()
-	{
-		IStructuredSelection selection = (IStructuredSelection)page.getTable().getSelection();
-		IC ic = (IC)selection.getFirstElement();
-		if (ic==null)
-			return;
-
-		ICDialog dialog = new ICDialog(page.getShell(),ic,true);
-
-		if (dialog.open() == Window.OK) {
-			page.getTable().editIC(dialog.getIC());
-			updateButtonStates();
-		}
-
-
-/*		boolean connected = TestConnectionUtility.testConnection(ic.getHost(),
-					ic.getPort()+"", ic.getPath(),ic.getProtocol());
-		TestICDialog dialog = new TestICDialog(page.getShell(),ic);
-		dialog.setConnectionStatus(connected);
-		dialog.open();
-*/
-	}
-
-	public void enableIC()
-	{
-		int indexes[] = page.getTable().getTable().getSelectionIndices();
-		IStructuredSelection selection = (IStructuredSelection)page.getTable().getSelection();
-		List<IC> ics = selection.toList();
-
-		boolean enable = enableIC.getText().equals(Messages.HelpContentBlock_4);
-
-		for (int i=0;i<ics.size();i++)
-		{
-			ics.get(i).setEnabled(enable);
-			page.getTable().getTableViewer().replace(ics.get(i), indexes[i]);
-		}
-		page.getTable().refresh();
-
-		updateButtonStates();
-	}
-
-	public void move(int offset)
-	{
-		int index = page.getTable().getTable().getSelectionIndices()[0];
-
-		List<IC> ics = page.getTable().getICs();
-		IC x = ics.get(index);
-		IC y = ics.get(index + offset);
-
-		ics.set(index+offset,x);
-		ics.set(index,y);
-
-
-		page.getTable().getTableViewer().getContentProvider().inputChanged(
-				page.getTable().getTableViewer(), null, ics);
-
-		page.getTable().getTableViewer().replace(x,index+offset);
-		page.getTable().getTableViewer().replace(y,index);
-		page.getTable().refresh();
-
-		page.getTable().getTable().deselectAll();
-		page.getTable().getTable().select(index+offset);
-		updateButtonStates();
-
-	}
-
-	public void updateButtonStates()
-	{
-		if (!enabled)
-		{
-			editIC.setEnabled(false);
-			testIC.setEnabled(false);
-			moveUp.setEnabled(false);
-			moveDown.setEnabled(false);
-			enableIC.setEnabled(false);
-			addIC.setEnabled(false);
-			removeIC.setEnabled(false);
-			return;
-		}
-
-		addIC.setEnabled(true);
-
-		IC firstIC = (IC)(((IStructuredSelection)page.getTable().getSelection()).getFirstElement());
-		if (firstIC!=null)
-		{
-			int index = page.getTable().getTable().getSelectionIndices()[0];
-			enableIC.setText(firstIC.isEnabled() ? Messages.HelpContentBlock_3 : Messages.HelpContentBlock_4);
-
-			if (page.getTable().getTable().getSelectionIndices().length==1)
-			{
-				editIC.setEnabled(true);
-				testIC.setEnabled(true);
-				moveUp.setEnabled(index!=0);
-				moveDown.setEnabled(index!=page.getTable().getICs().size()-1);
-			}
-			else
-			{
-				editIC.setEnabled(false);
-				testIC.setEnabled(false);
-				moveUp.setEnabled(false);
-				moveDown.setEnabled(false);
-			}
-			removeIC.setEnabled(true);
-			enableIC.setEnabled(true);
-		}
-		else
-		{
-			editIC.setEnabled(false);
-			testIC.setEnabled(false);
-			moveUp.setEnabled(false);
-			moveDown.setEnabled(false);
-			removeIC.setEnabled(false);
-			enableIC.setEnabled(false);
-		}
-	}
-}
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.help.ui.internal.preferences;
+
+
+import java.util.List;
+
+import org.eclipse.help.ui.internal.Messages;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.window.Window;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Table;
+
+public class ICButtons implements SelectionListener{
+
+	private HelpContentPreferencePage page;
+
+	private Button addIC;
+	private Button editIC;
+	private Button removeIC;
+	private Button moveUp;
+	private Button moveDown;
+	private Button testIC;
+	private Button enableIC;
+
+	private boolean enabled = true;
+
+	public ICButtons(Composite parent,HelpContentPreferencePage page)
+	{
+		this.page = page;
+
+		Composite container = new Composite(parent, SWT.NONE);
+		GridLayout layout = new GridLayout();
+		layout.marginHeight = 0;
+		layout.marginWidth = 0;
+		container.setLayout(layout);
+		container.setLayoutData(new GridData(GridData.FILL_VERTICAL));
+		container.setFont(parent.getFont());
+
+		addIC = createPushButton(container, Messages.HelpContentBlock_addICTitle);
+		editIC = createPushButton(container, Messages.HelpContentBlock_editICTitle);
+		removeIC = createPushButton(container, Messages.HelpContentBlock_removeICTitle);
+		testIC = createPushButton(container, Messages.HelpContentBlock_testConnectionTitle);
+
+		String enableTitle = Messages.HelpContentBlock_3.length() > Messages.HelpContentBlock_4.length() ?
+				Messages.HelpContentBlock_3 : Messages.HelpContentBlock_4;
+		enableIC = createPushButton(container, enableTitle);
+		moveUp = createPushButton(container, Messages.HelpContentBlock_upTitle);
+		moveDown = createPushButton(container, Messages.HelpContentBlock_downTitle);
+
+		page.getTable().getTable().addSelectionListener(this);
+
+
+		updateButtonStates();
+	}
+
+	public void setEnabled(boolean enabled)
+	{
+		this.enabled  = enabled;
+		updateButtonStates();
+	}
+
+	public Button createPushButton(Composite parent, String buttonText) {
+		Button button = new Button(parent, SWT.PUSH);
+		button.setFont(parent.getFont());
+		button.setText(buttonText);
+		button.addSelectionListener(this);
+		page.setButtonLayoutData(button);
+		return button;
+	}
+
+	@Override
+	public void widgetSelected(SelectionEvent e) {
+		if (e.getSource() instanceof Button)
+		{
+			if (e.getSource()==addIC)
+				addIC();
+			else if (e.getSource()==editIC)
+				editIC();
+			else if (e.getSource()==removeIC)
+				removeIC();
+			else if (e.getSource()==testIC)
+				testIC();
+			else if (e.getSource()==enableIC)
+				enableIC();
+			else if (e.getSource()==moveUp)
+				move(-1);
+			else if (e.getSource()==moveDown)
+				move(1);
+		}
+		else if (e.getSource() instanceof Table)
+			updateButtonStates();
+	}
+
+	@Override
+	public void widgetDefaultSelected(SelectionEvent e) {
+		if (e.getSource() instanceof Table)
+			editIC();
+	}
+
+	public void addIC()
+	{
+		ICDialog dialog = new ICDialog(page.getShell());
+		if (dialog.open() == Window.OK) {
+			page.getTable().addIC(dialog.getIC());
+			updateButtonStates();
+		}
+	}
+
+	public void editIC()
+	{
+		IStructuredSelection selection = (IStructuredSelection)page.getTable().getSelection();
+		IC ic = (IC)selection.getFirstElement();
+		if (ic==null)
+			return;
+
+		ICDialog dialog = new ICDialog(page.getShell(),ic);
+
+		if (dialog.open() == Window.OK) {
+			page.getTable().editIC(dialog.getIC());
+			updateButtonStates();
+		}
+	}
+
+	public void removeIC()
+	{
+		IStructuredSelection selection = (IStructuredSelection)page.getTable().getSelection();
+		List<IC> ics = selection.toList();
+		String remove = ""; //$NON-NLS-1$
+
+		for (int i=0;i<ics.size();i++)
+		{
+			remove+="\n"+ics.get(i); //$NON-NLS-1$
+		}
+
+		boolean shouldRemove =
+	          MessageDialog.openQuestion(
+	        	page.getShell(),
+	            NLS.bind(Messages.HelpContentBlock_rmvTitle ,""), //$NON-NLS-1$
+	            NLS.bind(Messages.HelpContentBlock_rmvLabel ,remove));
+
+		if (shouldRemove)
+		{
+			for (int i=0;i<ics.size();i++)
+				page.getTable().removeIC(ics.get(i));
+			updateButtonStates();
+		}
+	}
+
+	public void testIC()
+	{
+		IStructuredSelection selection = (IStructuredSelection)page.getTable().getSelection();
+		IC ic = (IC)selection.getFirstElement();
+		if (ic==null)
+			return;
+
+		ICDialog dialog = new ICDialog(page.getShell(),ic,true);
+
+		if (dialog.open() == Window.OK) {
+			page.getTable().editIC(dialog.getIC());
+			updateButtonStates();
+		}
+
+
+/*		boolean connected = TestConnectionUtility.testConnection(ic.getHost(),
+					ic.getPort()+"", ic.getPath(),ic.getProtocol());
+		TestICDialog dialog = new TestICDialog(page.getShell(),ic);
+		dialog.setConnectionStatus(connected);
+		dialog.open();
+*/
+	}
+
+	public void enableIC()
+	{
+		int indexes[] = page.getTable().getTable().getSelectionIndices();
+		IStructuredSelection selection = (IStructuredSelection)page.getTable().getSelection();
+		List<IC> ics = selection.toList();
+
+		boolean enable = enableIC.getText().equals(Messages.HelpContentBlock_4);
+
+		for (int i=0;i<ics.size();i++)
+		{
+			ics.get(i).setEnabled(enable);
+			page.getTable().getTableViewer().replace(ics.get(i), indexes[i]);
+		}
+		page.getTable().refresh();
+
+		updateButtonStates();
+	}
+
+	public void move(int offset)
+	{
+		int index = page.getTable().getTable().getSelectionIndices()[0];
+
+		List<IC> ics = page.getTable().getICs();
+		IC x = ics.get(index);
+		IC y = ics.get(index + offset);
+
+		ics.set(index+offset,x);
+		ics.set(index,y);
+
+
+		page.getTable().getTableViewer().getContentProvider().inputChanged(
+				page.getTable().getTableViewer(), null, ics);
+
+		page.getTable().getTableViewer().replace(x,index+offset);
+		page.getTable().getTableViewer().replace(y,index);
+		page.getTable().refresh();
+
+		page.getTable().getTable().deselectAll();
+		page.getTable().getTable().select(index+offset);
+		updateButtonStates();
+
+	}
+
+	public void updateButtonStates()
+	{
+		if (!enabled)
+		{
+			editIC.setEnabled(false);
+			testIC.setEnabled(false);
+			moveUp.setEnabled(false);
+			moveDown.setEnabled(false);
+			enableIC.setEnabled(false);
+			addIC.setEnabled(false);
+			removeIC.setEnabled(false);
+			return;
+		}
+
+		addIC.setEnabled(true);
+
+		IC firstIC = (IC)(((IStructuredSelection)page.getTable().getSelection()).getFirstElement());
+		if (firstIC!=null)
+		{
+			int index = page.getTable().getTable().getSelectionIndices()[0];
+			enableIC.setText(firstIC.isEnabled() ? Messages.HelpContentBlock_3 : Messages.HelpContentBlock_4);
+
+			if (page.getTable().getTable().getSelectionIndices().length==1)
+			{
+				editIC.setEnabled(true);
+				testIC.setEnabled(true);
+				moveUp.setEnabled(index!=0);
+				moveDown.setEnabled(index!=page.getTable().getICs().size()-1);
+			}
+			else
+			{
+				editIC.setEnabled(false);
+				testIC.setEnabled(false);
+				moveUp.setEnabled(false);
+				moveDown.setEnabled(false);
+			}
+			removeIC.setEnabled(true);
+			enableIC.setEnabled(true);
+		}
+		else
+		{
+			editIC.setEnabled(false);
+			testIC.setEnabled(false);
+			moveUp.setEnabled(false);
+			moveDown.setEnabled(false);
+			removeIC.setEnabled(false);
+			enableIC.setEnabled(false);
+		}
+	}
+}
diff --git a/org.eclipse.help.ui/src/org/eclipse/help/ui/internal/preferences/ICDialog.java b/org.eclipse.help.ui/src/org/eclipse/help/ui/internal/preferences/ICDialog.java
index 6ae3428..1734424 100644
--- a/org.eclipse.help.ui/src/org/eclipse/help/ui/internal/preferences/ICDialog.java
+++ b/org.eclipse.help.ui/src/org/eclipse/help/ui/internal/preferences/ICDialog.java
@@ -1,265 +1,265 @@
-/*******************************************************************************
- * Copyright (c) 2011, 2016 IBM Corporation and others.
+/*******************************************************************************
+ * Copyright (c) 2011, 2016 IBM Corporation and others.
  *
- * This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License 2.0
- * which accompanies this distribution, and is available at
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
  * https://www.eclipse.org/legal/epl-2.0/
  *
- * SPDX-License-Identifier: EPL-2.0
- *
- * Contributors:
- *     IBM Corporation - initial API and implementation
- *     Lars Vogel <Lars.Vogel@gmail.com> - Bug 431683
- *******************************************************************************/
-
-package org.eclipse.help.ui.internal.preferences;
-
-import java.net.MalformedURLException;
-import java.net.URL;
-
-import org.eclipse.core.runtime.IStatus;
-import org.eclipse.core.runtime.Status;
-import org.eclipse.help.internal.base.util.TestConnectionUtility;
-import org.eclipse.help.ui.internal.Messages;
-import org.eclipse.jface.dialogs.Dialog;
-import org.eclipse.jface.dialogs.IDialogConstants;
-import org.eclipse.jface.dialogs.StatusDialog;
-import org.eclipse.osgi.util.NLS;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.events.SelectionEvent;
-import org.eclipse.swt.events.SelectionListener;
-import org.eclipse.swt.graphics.Point;
-import org.eclipse.swt.layout.GridData;
-import org.eclipse.swt.layout.GridLayout;
-import org.eclipse.swt.widgets.Button;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Control;
-import org.eclipse.swt.widgets.Event;
-import org.eclipse.swt.widgets.Label;
-import org.eclipse.swt.widgets.Listener;
-import org.eclipse.swt.widgets.Shell;
-import org.eclipse.swt.widgets.Text;
-import org.eclipse.ui.PlatformUI;
-
-
-public class ICDialog extends StatusDialog implements Listener, SelectionListener {
-
-	private IC ic = null;
-
-	private Text nameText;
-	private Text hrefText;
-
-	private Button testButton;
-
-	private boolean testConnect = false;
-
-	public ICDialog(Shell parentShell) {
-		this(parentShell,null,false);
-	}
-	public ICDialog(Shell parentShell, IC initialIC) {
-		this(parentShell,initialIC,false);
-	}
-	public ICDialog(Shell parentShell, IC initialIC,boolean testConnect) {
-		super(parentShell);
-		this.ic = initialIC;
-		this.testConnect  = testConnect;
-	}
-
-	@Override
-	protected Control createDialogArea(Composite parent) {
-		PlatformUI.getWorkbench().getHelpSystem().setHelp(parent,
-				"org.eclipse.help.ui.prefPageHelpContent"); //$NON-NLS-1$
-
-		Composite top = (Composite) super.createDialogArea(parent);
-		top.setSize(top.computeSize(SWT.DEFAULT, SWT.DEFAULT));
-
-		Composite topGroup = new Composite(top, SWT.NONE);
-		GridLayout layout = new GridLayout();
-		layout.numColumns = 2;
-		layout.marginHeight = 2;
-		layout.marginWidth = 2;
-		layout.makeColumnsEqualWidth = false;
-		topGroup.setLayout(layout);
-		topGroup.setFont(top.getFont());
-		topGroup.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_FILL | GridData.GRAB_HORIZONTAL));
-
-		Label label = new Label(topGroup, SWT.NONE);
-		label.setText(Messages.AddICDialog_4);
-
-		nameText = new Text(topGroup, SWT.BORDER);
-		nameText.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
-		if (nameText.getOrientation() == SWT.RIGHT_TO_LEFT)
-			nameText.setOrientation(SWT.LEFT_TO_RIGHT);
-		nameText.addListener(SWT.Modify, this);
-
-		label = new Label(topGroup, SWT.NONE);
-		label.setText(Messages.InfoCenterPage_url);
-
-		hrefText = new Text(topGroup, SWT.BORDER);
-		hrefText.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
-		if (hrefText.getOrientation() == SWT.RIGHT_TO_LEFT)
-			hrefText.setOrientation(SWT.LEFT_TO_RIGHT);
-		hrefText.addListener(SWT.Modify, this);
-
-
-		if (ic!=null)
-		{
-			nameText.setText(ic.getName());
-			hrefText.setText(ic.getHref());
-			this.getShell().setText(NLS.bind(Messages.EditICDialog_7, ic.getName()));
-		}
-		else
-			this.getShell().setText(Messages.AddICDialog_2);
-
-
-		Dialog.applyDialogFont(top);
-		return top;
-
-	}
-
-	@Override
-	protected void createButtonsForButtonBar(Composite parent) {
-
-		testButton = this.createButton(
-				parent,
-				IDialogConstants.CLIENT_ID,
-				Messages.HelpContentBlock_testConnectionTitle,
-				true);
-		testButton.addSelectionListener(this);
-		super.createButtonsForButtonBar(parent);
-
-
-		//Initialize validity
-		updateValidity();
-
-		if (testConnect)
-			testConnection();
-	}
-
-
-	@Override
-	public void initializeBounds() {
-		Point size = getInitialSize();
-		Point location = getInitialLocation(size);
-		this.getShell().setBounds(location.x, location.y,
-				size.x + 180, size.y);
-	}
-
-	@Override
-	public void okPressed() {
-		try {
-			String href = formalizeHref(hrefText.getText());
-
-			ic = new IC(nameText.getText(),href,true);
-		} catch (MalformedURLException e) {}  // This should never happen since we test in updateValidity
-		this.setReturnCode(OK);
-		this.close();
-	}
-
-	public String formalizeHref(String href)
-	{
-		if (href.endsWith("/index.jsp")) //$NON-NLS-1$
-			href = href.substring(0,href.lastIndexOf("/index.jsp")); //$NON-NLS-1$
-		else if (href.endsWith("/site/site.xml")) //$NON-NLS-1$
-			href = href.substring(0,href.lastIndexOf("/site/site.xml")); //$NON-NLS-1$
-
-		return href;
-	}
-
-	/*
-	 * Checks for errors in the user input and shows/clears the error message
-	 * as appropriate.
-	 */
-	private void updateValidity() {
-
-		IStatus status = Status.OK_STATUS;
-
-		if (nameText!=null && nameText.getText().equals(""))  //$NON-NLS-1$
-			status = new Status(IStatus.ERROR,"org.eclipse.help.ui",Messages.InfoCenterPage_invalidURL); //$NON-NLS-1$
-		else if (hrefText!=null)
-		{
-			try {
-				String href = hrefText.getText();
-				new URL(href);
-
-				if (!href.matches(".*\\://.+/.+")) //$NON-NLS-1$
-					status = new Status(IStatus.ERROR,"org.eclipse.help.ui",Messages.InfoCenterPage_invalidURL); //$NON-NLS-1$
-
-			} catch (MalformedURLException e) {
-				status = new Status(IStatus.ERROR,"org.eclipse.help.ui",Messages.InfoCenterPage_invalidURL); //$NON-NLS-1$
-			}
-		}
-
-//		if (testButton!=null)
-//			testButton.setEnabled(status.isOK());
-
-		this.updateStatus(status);
-	}
-
-	private boolean areFieldsValid()
-	{
-		if (nameText!=null && nameText.getText().equals(""))  //$NON-NLS-1$
-			return false;
-		else if (hrefText!=null)
-		{
-			try {
-				String href = hrefText.getText();
-				new URL(href);
-
-				if (!href.matches(".*\\://.+/.+")) //$NON-NLS-1$
-					return false;
-
-			} catch (MalformedURLException e) {
-				return false;
-			}
-		}
-		return true;
-	}
-
-	private void testConnection()
-	{
-		IC testIC;
-		IStatus status;
-		try {
-			testIC = new IC(nameText.getText(),formalizeHref(hrefText.getText()),true);
-			boolean connected = TestConnectionUtility.testConnection(testIC.getHost(),
-						testIC.getPort()+"", testIC.getPath(),testIC.getProtocol()); //$NON-NLS-1$
-
-
-			if(connected)
-				status = new Status(IStatus.INFO,"org.eclipse.help.ui",Messages.TestConnectionDialog_12); //$NON-NLS-1$
-			else
-				status = new Status(IStatus.WARNING,"org.eclipse.help.ui",Messages.TestConnectionDialog_13); //$NON-NLS-1$
-
-		} catch (MalformedURLException e) {
-
-			status = new Status(IStatus.WARNING,"org.eclipse.help.ui",Messages.TestConnectionDialog_13); //$NON-NLS-1$
-		}
-
-
-		updateStatus(status);
-		this.getButton(IDialogConstants.OK_ID).setEnabled(areFieldsValid());
-		this.getButton(IDialogConstants.CANCEL_ID).setEnabled(true);
-	}
-
-	public IC getIC()
-	{
-		return ic;
-	}
-
-	@Override
-	public void handleEvent(Event event) {
-		  updateValidity();
-	}
-
-	@Override
-	public void widgetSelected(SelectionEvent e) {
-		if (e.getSource() instanceof Button)
-			testConnection();
-	}
-
-	@Override
-	public void widgetDefaultSelected(SelectionEvent e) {}
-
-}
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     Lars Vogel <Lars.Vogel@gmail.com> - Bug 431683
+ *******************************************************************************/
+
+package org.eclipse.help.ui.internal.preferences;
+
+import java.net.MalformedURLException;
+import java.net.URL;
+
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.help.internal.base.util.TestConnectionUtility;
+import org.eclipse.help.ui.internal.Messages;
+import org.eclipse.jface.dialogs.Dialog;
+import org.eclipse.jface.dialogs.IDialogConstants;
+import org.eclipse.jface.dialogs.StatusDialog;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Event;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Listener;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.widgets.Text;
+import org.eclipse.ui.PlatformUI;
+
+
+public class ICDialog extends StatusDialog implements Listener, SelectionListener {
+
+	private IC ic = null;
+
+	private Text nameText;
+	private Text hrefText;
+
+	private Button testButton;
+
+	private boolean testConnect = false;
+
+	public ICDialog(Shell parentShell) {
+		this(parentShell,null,false);
+	}
+	public ICDialog(Shell parentShell, IC initialIC) {
+		this(parentShell,initialIC,false);
+	}
+	public ICDialog(Shell parentShell, IC initialIC,boolean testConnect) {
+		super(parentShell);
+		this.ic = initialIC;
+		this.testConnect  = testConnect;
+	}
+
+	@Override
+	protected Control createDialogArea(Composite parent) {
+		PlatformUI.getWorkbench().getHelpSystem().setHelp(parent,
+				"org.eclipse.help.ui.prefPageHelpContent"); //$NON-NLS-1$
+
+		Composite top = (Composite) super.createDialogArea(parent);
+		top.setSize(top.computeSize(SWT.DEFAULT, SWT.DEFAULT));
+
+		Composite topGroup = new Composite(top, SWT.NONE);
+		GridLayout layout = new GridLayout();
+		layout.numColumns = 2;
+		layout.marginHeight = 2;
+		layout.marginWidth = 2;
+		layout.makeColumnsEqualWidth = false;
+		topGroup.setLayout(layout);
+		topGroup.setFont(top.getFont());
+		topGroup.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_FILL | GridData.GRAB_HORIZONTAL));
+
+		Label label = new Label(topGroup, SWT.NONE);
+		label.setText(Messages.AddICDialog_4);
+
+		nameText = new Text(topGroup, SWT.BORDER);
+		nameText.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
+		if (nameText.getOrientation() == SWT.RIGHT_TO_LEFT)
+			nameText.setOrientation(SWT.LEFT_TO_RIGHT);
+		nameText.addListener(SWT.Modify, this);
+
+		label = new Label(topGroup, SWT.NONE);
+		label.setText(Messages.InfoCenterPage_url);
+
+		hrefText = new Text(topGroup, SWT.BORDER);
+		hrefText.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
+		if (hrefText.getOrientation() == SWT.RIGHT_TO_LEFT)
+			hrefText.setOrientation(SWT.LEFT_TO_RIGHT);
+		hrefText.addListener(SWT.Modify, this);
+
+
+		if (ic!=null)
+		{
+			nameText.setText(ic.getName());
+			hrefText.setText(ic.getHref());
+			this.getShell().setText(NLS.bind(Messages.EditICDialog_7, ic.getName()));
+		}
+		else
+			this.getShell().setText(Messages.AddICDialog_2);
+
+
+		Dialog.applyDialogFont(top);
+		return top;
+
+	}
+
+	@Override
+	protected void createButtonsForButtonBar(Composite parent) {
+
+		testButton = this.createButton(
+				parent,
+				IDialogConstants.CLIENT_ID,
+				Messages.HelpContentBlock_testConnectionTitle,
+				true);
+		testButton.addSelectionListener(this);
+		super.createButtonsForButtonBar(parent);
+
+
+		//Initialize validity
+		updateValidity();
+
+		if (testConnect)
+			testConnection();
+	}
+
+
+	@Override
+	public void initializeBounds() {
+		Point size = getInitialSize();
+		Point location = getInitialLocation(size);
+		this.getShell().setBounds(location.x, location.y,
+				size.x + 180, size.y);
+	}
+
+	@Override
+	public void okPressed() {
+		try {
+			String href = formalizeHref(hrefText.getText());
+
+			ic = new IC(nameText.getText(),href,true);
+		} catch (MalformedURLException e) {}  // This should never happen since we test in updateValidity
+		this.setReturnCode(OK);
+		this.close();
+	}
+
+	public String formalizeHref(String href)
+	{
+		if (href.endsWith("/index.jsp")) //$NON-NLS-1$
+			href = href.substring(0,href.lastIndexOf("/index.jsp")); //$NON-NLS-1$
+		else if (href.endsWith("/site/site.xml")) //$NON-NLS-1$
+			href = href.substring(0,href.lastIndexOf("/site/site.xml")); //$NON-NLS-1$
+
+		return href;
+	}
+
+	/*
+	 * Checks for errors in the user input and shows/clears the error message
+	 * as appropriate.
+	 */
+	private void updateValidity() {
+
+		IStatus status = Status.OK_STATUS;
+
+		if (nameText!=null && nameText.getText().equals(""))  //$NON-NLS-1$
+			status = new Status(IStatus.ERROR,"org.eclipse.help.ui",Messages.InfoCenterPage_invalidURL); //$NON-NLS-1$
+		else if (hrefText!=null)
+		{
+			try {
+				String href = hrefText.getText();
+				new URL(href);
+
+				if (!href.matches(".*\\://.+/.+")) //$NON-NLS-1$
+					status = new Status(IStatus.ERROR,"org.eclipse.help.ui",Messages.InfoCenterPage_invalidURL); //$NON-NLS-1$
+
+			} catch (MalformedURLException e) {
+				status = new Status(IStatus.ERROR,"org.eclipse.help.ui",Messages.InfoCenterPage_invalidURL); //$NON-NLS-1$
+			}
+		}
+
+//		if (testButton!=null)
+//			testButton.setEnabled(status.isOK());
+
+		this.updateStatus(status);
+	}
+
+	private boolean areFieldsValid()
+	{
+		if (nameText!=null && nameText.getText().equals(""))  //$NON-NLS-1$
+			return false;
+		else if (hrefText!=null)
+		{
+			try {
+				String href = hrefText.getText();
+				new URL(href);
+
+				if (!href.matches(".*\\://.+/.+")) //$NON-NLS-1$
+					return false;
+
+			} catch (MalformedURLException e) {
+				return false;
+			}
+		}
+		return true;
+	}
+
+	private void testConnection()
+	{
+		IC testIC;
+		IStatus status;
+		try {
+			testIC = new IC(nameText.getText(),formalizeHref(hrefText.getText()),true);
+			boolean connected = TestConnectionUtility.testConnection(testIC.getHost(),
+						testIC.getPort()+"", testIC.getPath(),testIC.getProtocol()); //$NON-NLS-1$
+
+
+			if(connected)
+				status = new Status(IStatus.INFO,"org.eclipse.help.ui",Messages.TestConnectionDialog_12); //$NON-NLS-1$
+			else
+				status = new Status(IStatus.WARNING,"org.eclipse.help.ui",Messages.TestConnectionDialog_13); //$NON-NLS-1$
+
+		} catch (MalformedURLException e) {
+
+			status = new Status(IStatus.WARNING,"org.eclipse.help.ui",Messages.TestConnectionDialog_13); //$NON-NLS-1$
+		}
+
+
+		updateStatus(status);
+		this.getButton(IDialogConstants.OK_ID).setEnabled(areFieldsValid());
+		this.getButton(IDialogConstants.CANCEL_ID).setEnabled(true);
+	}
+
+	public IC getIC()
+	{
+		return ic;
+	}
+
+	@Override
+	public void handleEvent(Event event) {
+		  updateValidity();
+	}
+
+	@Override
+	public void widgetSelected(SelectionEvent e) {
+		if (e.getSource() instanceof Button)
+			testConnection();
+	}
+
+	@Override
+	public void widgetDefaultSelected(SelectionEvent e) {}
+
+}
diff --git a/org.eclipse.help.ui/src/org/eclipse/help/ui/internal/preferences/ICPreferences.java b/org.eclipse.help.ui/src/org/eclipse/help/ui/internal/preferences/ICPreferences.java
index c537f73..287e20e 100644
--- a/org.eclipse.help.ui/src/org/eclipse/help/ui/internal/preferences/ICPreferences.java
+++ b/org.eclipse.help.ui/src/org/eclipse/help/ui/internal/preferences/ICPreferences.java
@@ -1,207 +1,207 @@
-/*******************************************************************************
- * Copyright (c) 2011, 2016 IBM Corporation and others.
+/*******************************************************************************
+ * Copyright (c) 2011, 2016 IBM Corporation and others.
  *
- * This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License 2.0
- * which accompanies this distribution, and is available at
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
  * https://www.eclipse.org/legal/epl-2.0/
  *
- * SPDX-License-Identifier: EPL-2.0
- *
- * Contributors:
- *     IBM Corporation - initial API and implementation
- *******************************************************************************/
-
-package org.eclipse.help.ui.internal.preferences;
-
-import java.net.MalformedURLException;
-import java.util.ArrayList;
-import java.util.List;
-
-import org.eclipse.core.runtime.preferences.DefaultScope;
-import org.eclipse.core.runtime.preferences.IEclipsePreferences;
-import org.eclipse.core.runtime.preferences.InstanceScope;
-import org.eclipse.help.internal.HelpPlugin;
-import org.eclipse.help.internal.base.IHelpBaseConstants;
-import org.eclipse.help.ui.internal.HelpUIPlugin;
-import org.osgi.service.prefs.BackingStoreException;
-
-
-public class ICPreferences {
-
-	public final static String DELIMITER = ","; //$NON-NLS-1$
-
-
-	public static void setICs(List<IC> ics)
-	{
-		String name = "", host = "", path = "", protocol="", port = "", enabled = ""; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$
-
-		for (int i=0;i<ics.size();i++)
-		{
-			name += ics.get(i).getName() + DELIMITER;
-			protocol += ics.get(i).getProtocol() + DELIMITER;
-			host += ics.get(i).getHost() + DELIMITER;
-			port += ics.get(i).getPort() + DELIMITER;
-			path += ics.get(i).getPath() + DELIMITER;
-			enabled += ics.get(i).isEnabled() + DELIMITER;
-		}
-
-		// Remove trailing commas
-		if(ics.size()!=0)
-		{
-			name = name.substring(0,name.length()-1);
-			protocol = protocol.substring(0,protocol.length()-1);
-			host = host.substring(0,host.length()-1);
-			port = port.substring(0,port.length()-1);
-			path = path.substring(0,path.length()-1);
-			enabled = enabled.substring(0,enabled.length()-1);
-		}
-
-		set("org.eclipse.help.base",IHelpBaseConstants.P_KEY_REMOTE_HELP_NAME, name); //$NON-NLS-1$
-		set("org.eclipse.help.base",IHelpBaseConstants.P_KEY_REMOTE_HELP_HOST, host); //$NON-NLS-1$
-		set("org.eclipse.help.base",IHelpBaseConstants.P_KEY_REMOTE_HELP_PATH, path); //$NON-NLS-1$
-		set("org.eclipse.help.base",IHelpBaseConstants.P_KEY_REMOTE_HELP_PROTOCOL, protocol); //$NON-NLS-1$
-		set("org.eclipse.help.base",IHelpBaseConstants.P_KEY_REMOTE_HELP_PORT, port); //$NON-NLS-1$
-		set("org.eclipse.help.base",IHelpBaseConstants.P_KEY_REMOTE_HELP_ICEnabled, enabled); //$NON-NLS-1$
-
-		HelpPlugin.getTocManager().clearCache();
-	}
-
-	public static List<IC> getICs()
-	{
-		return prefsToICs(
-				ICPreferences.get("org.eclipse.help.base",IHelpBaseConstants.P_KEY_REMOTE_HELP_NAME).split(DELIMITER), //$NON-NLS-1$
-				ICPreferences.get("org.eclipse.help.base",IHelpBaseConstants.P_KEY_REMOTE_HELP_PROTOCOL).split(DELIMITER), //$NON-NLS-1$
-				ICPreferences.get("org.eclipse.help.base",IHelpBaseConstants.P_KEY_REMOTE_HELP_HOST).split(DELIMITER), //$NON-NLS-1$
-				ICPreferences.get("org.eclipse.help.base",IHelpBaseConstants.P_KEY_REMOTE_HELP_PORT).split(DELIMITER), //$NON-NLS-1$
-				ICPreferences.get("org.eclipse.help.base",IHelpBaseConstants.P_KEY_REMOTE_HELP_PATH).split(DELIMITER), //$NON-NLS-1$
-				ICPreferences.get("org.eclipse.help.base",IHelpBaseConstants.P_KEY_REMOTE_HELP_ICEnabled).split(DELIMITER)); //$NON-NLS-1$
-	}
-
-	public static List<IC> prefsToICs(String names[],String protocols[],String hosts[],String ports[],String paths[],String states[])
-	{
-		List<IC> ics = new ArrayList<>();
-
-		for (int i=0;i<names.length;i++)
-		{
-			if (!names[i].equals("")) //$NON-NLS-1$
-			{
-				try {
-					IC ic = new IC(
-						names[i],
-						(protocols.length>i ? protocols[i] : "http") + "://" + //$NON-NLS-1$ //$NON-NLS-2$
-						hosts[i]+":"+ //$NON-NLS-1$
-						ports[i]+
-						paths[i],
-						"true".equalsIgnoreCase(states[i])); //$NON-NLS-1$
-					ics.add(ic);
-				} catch (MalformedURLException e) {
-					HelpUIPlugin.logError(e.getMessage(), e);
-				}
-			}
-		}
-		return ics;
-	}
-
-
-
-	public static List<IC> getDefaultICs()
-	{
-		return prefsToICs(
-				getDefault("org.eclipse.help.base",IHelpBaseConstants.P_KEY_REMOTE_HELP_NAME).split(DELIMITER), //$NON-NLS-1$
-				getDefault("org.eclipse.help.base",IHelpBaseConstants.P_KEY_REMOTE_HELP_PROTOCOL).split(DELIMITER), //$NON-NLS-1$
-				getDefault("org.eclipse.help.base",IHelpBaseConstants.P_KEY_REMOTE_HELP_HOST).split(DELIMITER), //$NON-NLS-1$
-				getDefault("org.eclipse.help.base",IHelpBaseConstants.P_KEY_REMOTE_HELP_PORT).split(DELIMITER), //$NON-NLS-1$
-				getDefault("org.eclipse.help.base",IHelpBaseConstants.P_KEY_REMOTE_HELP_PATH).split(DELIMITER), //$NON-NLS-1$
-				getDefault("org.eclipse.help.base",IHelpBaseConstants.P_KEY_REMOTE_HELP_ICEnabled).split(DELIMITER)); //$NON-NLS-1$
-	}
-
-
-	/**
-	 * Returns a default preference for the given name
-	 *
-	 * @param plugin - Name of the plugin containing this preference
-	 * @param name - Name of the preference to retrieve
-	 * @return value, or empty string if no preference found
-	 */
-	public static String getDefault(String plugin,String name)
-	{
-		return getDefaultNode(plugin).get(name, ""); //$NON-NLS-1$
-	}
-
-	public static void setRemoteHelp(boolean enabled)
-	{
-		set("org.eclipse.help.base",IHelpBaseConstants.P_KEY_REMOTE_HELP_ON,enabled+""); //$NON-NLS-1$ //$NON-NLS-2$
-		HelpPlugin.getTocManager().clearCache();
-	}
-
-	public static void setRemoteHelpPreferred(boolean remotePreferred)
-	{
-		set("org.eclipse.help.base",IHelpBaseConstants.P_KEY_REMOTE_HELP_PREFERRED,remotePreferred+""); //$NON-NLS-1$ //$NON-NLS-2$
-		HelpPlugin.getTocManager().clearCache();
-	}
-
-	/**
-	 * Sets a preference
-	 *
-	 * @param plugin - Name of the plugin containing this preference
-	 * @param name - Name of the preference
-	 * @param value - Value to set
-	 */
-	public static void set(String plugin,String name,String value)
-	{
-		set(getNode(plugin),name,value);
-	}
-
-	/**
-	 * Set a preference in the given node.
-	 *
-	 * @param node
-	 * @param name
-	 * @param value
-	 */
-	public static void set(IEclipsePreferences node,String name,String value)
-	{
-		node.put(name, value);
-		try {
-			node.flush();
-		} catch (BackingStoreException e) {} //Nothing we can do, move on
-	}
-
-	/**
-	 * Returns the preference found for the given name
-	 *
-	 * @param plugin - Name of the plugin containing this preference
-	 * @param name - Name of the preference to retrieve
-	 * @return value, or empty string if no preference found
-	 */
-	public static String get(String plugin,String name)
-	{
-		return getNode(plugin).get(name, ""); //$NON-NLS-1$
-	}
-
-	/**
-	 * Get the IEclipsePreferences node for the given plugin
-	 *
-	 * @param plugin
-	 * @return
-	 */
-	public static IEclipsePreferences getNode(String plugin)
-	{
-		IEclipsePreferences p = InstanceScope.INSTANCE.getNode(plugin);
-		return p;
-	}
-
-
-	/**
-	 * Get the default IEclipsePreferences node for the given plugin
-	 *
-	 * @param plugin
-	 * @return
-	 */
-	public static IEclipsePreferences getDefaultNode(String plugin)
-	{
-		IEclipsePreferences p = DefaultScope.INSTANCE.getNode(plugin);
-		return p;
-	}
-}
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.help.ui.internal.preferences;
+
+import java.net.MalformedURLException;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.core.runtime.preferences.DefaultScope;
+import org.eclipse.core.runtime.preferences.IEclipsePreferences;
+import org.eclipse.core.runtime.preferences.InstanceScope;
+import org.eclipse.help.internal.HelpPlugin;
+import org.eclipse.help.internal.base.IHelpBaseConstants;
+import org.eclipse.help.ui.internal.HelpUIPlugin;
+import org.osgi.service.prefs.BackingStoreException;
+
+
+public class ICPreferences {
+
+	public final static String DELIMITER = ","; //$NON-NLS-1$
+
+
+	public static void setICs(List<IC> ics)
+	{
+		String name = "", host = "", path = "", protocol="", port = "", enabled = ""; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$
+
+		for (int i=0;i<ics.size();i++)
+		{
+			name += ics.get(i).getName() + DELIMITER;
+			protocol += ics.get(i).getProtocol() + DELIMITER;
+			host += ics.get(i).getHost() + DELIMITER;
+			port += ics.get(i).getPort() + DELIMITER;
+			path += ics.get(i).getPath() + DELIMITER;
+			enabled += ics.get(i).isEnabled() + DELIMITER;
+		}
+
+		// Remove trailing commas
+		if(ics.size()!=0)
+		{
+			name = name.substring(0,name.length()-1);
+			protocol = protocol.substring(0,protocol.length()-1);
+			host = host.substring(0,host.length()-1);
+			port = port.substring(0,port.length()-1);
+			path = path.substring(0,path.length()-1);
+			enabled = enabled.substring(0,enabled.length()-1);
+		}
+
+		set("org.eclipse.help.base",IHelpBaseConstants.P_KEY_REMOTE_HELP_NAME, name); //$NON-NLS-1$
+		set("org.eclipse.help.base",IHelpBaseConstants.P_KEY_REMOTE_HELP_HOST, host); //$NON-NLS-1$
+		set("org.eclipse.help.base",IHelpBaseConstants.P_KEY_REMOTE_HELP_PATH, path); //$NON-NLS-1$
+		set("org.eclipse.help.base",IHelpBaseConstants.P_KEY_REMOTE_HELP_PROTOCOL, protocol); //$NON-NLS-1$
+		set("org.eclipse.help.base",IHelpBaseConstants.P_KEY_REMOTE_HELP_PORT, port); //$NON-NLS-1$
+		set("org.eclipse.help.base",IHelpBaseConstants.P_KEY_REMOTE_HELP_ICEnabled, enabled); //$NON-NLS-1$
+
+		HelpPlugin.getTocManager().clearCache();
+	}
+
+	public static List<IC> getICs()
+	{
+		return prefsToICs(
+				ICPreferences.get("org.eclipse.help.base",IHelpBaseConstants.P_KEY_REMOTE_HELP_NAME).split(DELIMITER), //$NON-NLS-1$
+				ICPreferences.get("org.eclipse.help.base",IHelpBaseConstants.P_KEY_REMOTE_HELP_PROTOCOL).split(DELIMITER), //$NON-NLS-1$
+				ICPreferences.get("org.eclipse.help.base",IHelpBaseConstants.P_KEY_REMOTE_HELP_HOST).split(DELIMITER), //$NON-NLS-1$
+				ICPreferences.get("org.eclipse.help.base",IHelpBaseConstants.P_KEY_REMOTE_HELP_PORT).split(DELIMITER), //$NON-NLS-1$
+				ICPreferences.get("org.eclipse.help.base",IHelpBaseConstants.P_KEY_REMOTE_HELP_PATH).split(DELIMITER), //$NON-NLS-1$
+				ICPreferences.get("org.eclipse.help.base",IHelpBaseConstants.P_KEY_REMOTE_HELP_ICEnabled).split(DELIMITER)); //$NON-NLS-1$
+	}
+
+	public static List<IC> prefsToICs(String names[],String protocols[],String hosts[],String ports[],String paths[],String states[])
+	{
+		List<IC> ics = new ArrayList<>();
+
+		for (int i=0;i<names.length;i++)
+		{
+			if (!names[i].equals("")) //$NON-NLS-1$
+			{
+				try {
+					IC ic = new IC(
+						names[i],
+						(protocols.length>i ? protocols[i] : "http") + "://" + //$NON-NLS-1$ //$NON-NLS-2$
+						hosts[i]+":"+ //$NON-NLS-1$
+						ports[i]+
+						paths[i],
+						"true".equalsIgnoreCase(states[i])); //$NON-NLS-1$
+					ics.add(ic);
+				} catch (MalformedURLException e) {
+					HelpUIPlugin.logError(e.getMessage(), e);
+				}
+			}
+		}
+		return ics;
+	}
+
+
+
+	public static List<IC> getDefaultICs()
+	{
+		return prefsToICs(
+				getDefault("org.eclipse.help.base",IHelpBaseConstants.P_KEY_REMOTE_HELP_NAME).split(DELIMITER), //$NON-NLS-1$
+				getDefault("org.eclipse.help.base",IHelpBaseConstants.P_KEY_REMOTE_HELP_PROTOCOL).split(DELIMITER), //$NON-NLS-1$
+				getDefault("org.eclipse.help.base",IHelpBaseConstants.P_KEY_REMOTE_HELP_HOST).split(DELIMITER), //$NON-NLS-1$
+				getDefault("org.eclipse.help.base",IHelpBaseConstants.P_KEY_REMOTE_HELP_PORT).split(DELIMITER), //$NON-NLS-1$
+				getDefault("org.eclipse.help.base",IHelpBaseConstants.P_KEY_REMOTE_HELP_PATH).split(DELIMITER), //$NON-NLS-1$
+				getDefault("org.eclipse.help.base",IHelpBaseConstants.P_KEY_REMOTE_HELP_ICEnabled).split(DELIMITER)); //$NON-NLS-1$
+	}
+
+
+	/**
+	 * Returns a default preference for the given name
+	 *
+	 * @param plugin - Name of the plugin containing this preference
+	 * @param name - Name of the preference to retrieve
+	 * @return value, or empty string if no preference found
+	 */
+	public static String getDefault(String plugin,String name)
+	{
+		return getDefaultNode(plugin).get(name, ""); //$NON-NLS-1$
+	}
+
+	public static void setRemoteHelp(boolean enabled)
+	{
+		set("org.eclipse.help.base",IHelpBaseConstants.P_KEY_REMOTE_HELP_ON,enabled+""); //$NON-NLS-1$ //$NON-NLS-2$
+		HelpPlugin.getTocManager().clearCache();
+	}
+
+	public static void setRemoteHelpPreferred(boolean remotePreferred)
+	{
+		set("org.eclipse.help.base",IHelpBaseConstants.P_KEY_REMOTE_HELP_PREFERRED,remotePreferred+""); //$NON-NLS-1$ //$NON-NLS-2$
+		HelpPlugin.getTocManager().clearCache();
+	}
+
+	/**
+	 * Sets a preference
+	 *
+	 * @param plugin - Name of the plugin containing this preference
+	 * @param name - Name of the preference
+	 * @param value - Value to set
+	 */
+	public static void set(String plugin,String name,String value)
+	{
+		set(getNode(plugin),name,value);
+	}
+
+	/**
+	 * Set a preference in the given node.
+	 *
+	 * @param node
+	 * @param name
+	 * @param value
+	 */
+	public static void set(IEclipsePreferences node,String name,String value)
+	{
+		node.put(name, value);
+		try {
+			node.flush();
+		} catch (BackingStoreException e) {} //Nothing we can do, move on
+	}
+
+	/**
+	 * Returns the preference found for the given name
+	 *
+	 * @param plugin - Name of the plugin containing this preference
+	 * @param name - Name of the preference to retrieve
+	 * @return value, or empty string if no preference found
+	 */
+	public static String get(String plugin,String name)
+	{
+		return getNode(plugin).get(name, ""); //$NON-NLS-1$
+	}
+
+	/**
+	 * Get the IEclipsePreferences node for the given plugin
+	 *
+	 * @param plugin
+	 * @return
+	 */
+	public static IEclipsePreferences getNode(String plugin)
+	{
+		IEclipsePreferences p = InstanceScope.INSTANCE.getNode(plugin);
+		return p;
+	}
+
+
+	/**
+	 * Get the default IEclipsePreferences node for the given plugin
+	 *
+	 * @param plugin
+	 * @return
+	 */
+	public static IEclipsePreferences getDefaultNode(String plugin)
+	{
+		IEclipsePreferences p = DefaultScope.INSTANCE.getNode(plugin);
+		return p;
+	}
+}
diff --git a/org.eclipse.help.ui/src/org/eclipse/help/ui/internal/preferences/ICTable.java b/org.eclipse.help.ui/src/org/eclipse/help/ui/internal/preferences/ICTable.java
index da56b8f..1a548fb 100644
--- a/org.eclipse.help.ui/src/org/eclipse/help/ui/internal/preferences/ICTable.java
+++ b/org.eclipse.help.ui/src/org/eclipse/help/ui/internal/preferences/ICTable.java
@@ -1,293 +1,293 @@
-/*******************************************************************************
- * Copyright (c) 2011, 2016 IBM Corporation and others.
+/*******************************************************************************
+ * Copyright (c) 2011, 2016 IBM Corporation and others.
  *
- * This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License 2.0
- * which accompanies this distribution, and is available at
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
  * https://www.eclipse.org/legal/epl-2.0/
  *
- * SPDX-License-Identifier: EPL-2.0
- *
- * Contributors:
- *     IBM Corporation - initial API and implementation
- *******************************************************************************/
-
-package org.eclipse.help.ui.internal.preferences;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-
-import org.eclipse.help.ui.internal.Messages;
-import org.eclipse.jface.dialogs.IDialogConstants;
-import org.eclipse.jface.viewers.ColumnLayoutData;
-import org.eclipse.jface.viewers.ColumnWeightData;
-import org.eclipse.jface.viewers.ISelection;
-import org.eclipse.jface.viewers.IStructuredContentProvider;
-import org.eclipse.jface.viewers.ITableLabelProvider;
-import org.eclipse.jface.viewers.LabelProvider;
-import org.eclipse.jface.viewers.TableLayout;
-import org.eclipse.jface.viewers.TableViewer;
-import org.eclipse.jface.viewers.Viewer;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.graphics.Image;
-import org.eclipse.swt.layout.GridData;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Control;
-import org.eclipse.swt.widgets.Table;
-import org.eclipse.swt.widgets.TableColumn;
-
-public class ICTable {
-
-	private Table table;
-	private TableViewer viewer;
-
-	private final String NAME_COLUMN = Messages.RemoteICViewer_Name;
-	private final String LOCATION_COLUMN = Messages.RemoteICViewer_URL;
-	private final String STATUS_COLUMN = Messages.RemoteICViewer_Enabled;
-
-	// Set column names
-	private String[] columnNames = new String[] {NAME_COLUMN,
-			LOCATION_COLUMN, STATUS_COLUMN};
-
-
-	public ICTable(Composite parent) {
-
-		// Create the table
-		table = createTable(parent);
-		// Create and setup the TableViewer
-		viewer = createTableViewer();
-
-		loadPreferences();
-	}
-
-	/**
-	 * Release resources
-	 */
-	public void dispose() {
-		// Tell the label provider to release its resources
-		viewer.getLabelProvider().dispose();
-	}
-
-	/**
-	 * Create the Table
-	 */
-	private Table createTable(Composite parent) {
-		int style = SWT.MULTI | SWT.BORDER | SWT.H_SCROLL | SWT.V_SCROLL | SWT.FULL_SELECTION;
-
-		TableLayout tableLayout = new TableLayout();
-		Table table = new Table(parent, style);
-		table.setLayout(tableLayout);
-		table.setHeaderVisible(true);
-		table.setLinesVisible(true);
-		table.setFont(parent.getFont());
-
-		GridData gridData = new GridData(GridData.FILL_BOTH);
-		gridData.grabExcessVerticalSpace = true;
-		gridData.grabExcessHorizontalSpace = true;
-		gridData.verticalAlignment = GridData.FILL;
-		gridData.horizontalAlignment = GridData.FILL;
-		gridData.widthHint = IDialogConstants.ENTRY_FIELD_WIDTH;
-		gridData.heightHint =  table.getItemHeight();
-		gridData.horizontalSpan = 1;
-		table.setLayoutData(gridData);
-
-
-
-		ColumnLayoutData[] fTableColumnLayouts= {
-		        new ColumnWeightData(85),
-		        new ColumnWeightData(165),
-		        new ColumnWeightData(60)
-		};
-
-		TableColumn column;
-
-		tableLayout.addColumnData(fTableColumnLayouts[0]);
-	    column = new TableColumn(table, SWT.NONE, 0);
-	    column.setResizable(fTableColumnLayouts[0].resizable);
-	    column.setText(NAME_COLUMN);
-
-	    tableLayout.addColumnData(fTableColumnLayouts[1]);
-	    column = new TableColumn(table, SWT.NONE, 1);
-	    column.setResizable(fTableColumnLayouts[1].resizable);
-	    column.setText(LOCATION_COLUMN);
-
-	    tableLayout.addColumnData(fTableColumnLayouts[2]);
-	    column = new TableColumn(table, SWT.NONE, 2);
-	    column.setResizable(fTableColumnLayouts[2].resizable);
-	    column.setText(STATUS_COLUMN);
-
-	    return table;
-	}
-
-	/**
-	 * Create the TableViewer
-	 */
-	private TableViewer createTableViewer() {
-
-		TableViewer viewer = new TableViewer(table);
-		viewer.setUseHashlookup(true);
-		viewer.setColumnProperties(columnNames);
-		viewer.setContentProvider(new ICContentProvider());
-		viewer.setLabelProvider(new ICLabelProvider());
-		return viewer;
-	}
-
-	/**
-	 * Proxy for the the RemoteICList which provides content
-	 * for the Table. This class implements IRemoteHelpListViewer interface an
-	 * registers itself with RemoteICList
-	 */
-	class ICContentProvider implements IStructuredContentProvider
-	{
-		private List<IC> content = new ArrayList<>();
-
-		@Override
-		public void dispose() {
-			content = null;
-		}
-
-		@Override
-		@SuppressWarnings("unchecked")
-		public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
-			content = (List<IC>)newInput;
-		}
-
-		@Override
-		public IC[] getElements(Object inputElement) {
-			return content.toArray(new IC[content.size()]);
-		}
-
-	}
-
-	public class ICLabelProvider extends LabelProvider implements ITableLabelProvider {
-
-		@Override
-		public Image getColumnImage(Object element, int columnIndex) {
-			return null;
-		}
-
-		@Override
-		public String getColumnText(Object element, int columnIndex) {
-			switch (columnIndex) {
-			case 0:
-				return ((IC)element).getName();
-			case 1:
-				return ((IC)element).getHref();
-			case 2:
-				return ((IC)element).isEnabled() ? Messages.RemoteICLabelProvider_4 : Messages.RemoteICLabelProvider_5;
-			default:
-				return null;
-			}
-		}
-
-	}
-
-
-
-
-	/**
-	 * @param rics the ordered remote InfoCenters
-	 */
-	public void update(List<IC> ics) {
-		viewer.getContentProvider().inputChanged(viewer, null, ics);
-		refresh();
-	}
-
-	/**
-	 * Make sure the table viewer shows the latest copy of the ordered InfoCenters
-	 */
-	public void refresh() {
-		viewer.refresh(getICs());
-	}
-
-	/**
-	 * Return the column names in a collection
-	 *
-	 * @return List containing column names
-	 */
-	public List<String> getColumnNames() {
-		return Arrays.asList(columnNames);
-	}
-
-	/**
-	 * @return currently selected item
-	 */
-	public ISelection getSelection() {
-		return viewer.getSelection();
-	}
-
-	/**
-	 * Return the RemoteICList
-	 */
-	public List<IC> getICs() {
-		ICContentProvider p = (ICContentProvider)viewer.getContentProvider();
-		IC objs[] = p.getElements(null);
-		List<IC> content = new ArrayList<>();
-		for (int o=0;o<objs.length;o++)
-			content.add(objs[o]);
-		return content;
-	}
-
-	public void setICs(List<IC> ics)
-	{
-		List<IC> oldICs = getICs();
-		for (int o=0;o<oldICs.size();o++)
-			removeIC(oldICs.get(o));
-
-		for (int i=0;i<ics.size();i++)
-			addIC(ics.get(i));
-	}
-
-	public TableViewer getTableViewer()
-	{
-		return viewer;
-	}
-	/**
-	 * Return the parent composite
-	 */
-	public Control getControl() {
-		return table.getParent();
-	}
-
-	public Table getTable() {
-		return table;
-	}
-
-	public void addIC(IC ic)
-	{
-		List<IC> content = getICs();
-		content.add(ic);
-		getTableViewer().getContentProvider().inputChanged(
-				getTableViewer(), null, content);
-		getTableViewer().add(ic);
-		refresh();
-	}
-
-	public void editIC(IC ic)
-	{
-		List<IC> content = getICs();
-		content.set(getTable().getSelectionIndex(), ic);
-		getTableViewer().replace(ic,getTable().getSelectionIndex());
-		getTableViewer().getContentProvider().inputChanged(
-				getTableViewer(), null, content);
-		refresh();
-	}
-
-	public void removeIC(IC ic)
-	{
-		List<IC> content = getICs();
-		content.remove(ic);
-		getTableViewer().getContentProvider().inputChanged(getTableViewer(), null, content);
-		getTableViewer().remove(ic);
-		refresh();
-	}
-
-	private void loadPreferences()
-	{
-		List<IC> ics = ICPreferences.getICs();
-		for (int i=0;i<ics.size();i++)
-			addIC(ics.get(i));
-	}
-
-}
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.help.ui.internal.preferences;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import org.eclipse.help.ui.internal.Messages;
+import org.eclipse.jface.dialogs.IDialogConstants;
+import org.eclipse.jface.viewers.ColumnLayoutData;
+import org.eclipse.jface.viewers.ColumnWeightData;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.IStructuredContentProvider;
+import org.eclipse.jface.viewers.ITableLabelProvider;
+import org.eclipse.jface.viewers.LabelProvider;
+import org.eclipse.jface.viewers.TableLayout;
+import org.eclipse.jface.viewers.TableViewer;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Table;
+import org.eclipse.swt.widgets.TableColumn;
+
+public class ICTable {
+
+	private Table table;
+	private TableViewer viewer;
+
+	private final String NAME_COLUMN = Messages.RemoteICViewer_Name;
+	private final String LOCATION_COLUMN = Messages.RemoteICViewer_URL;
+	private final String STATUS_COLUMN = Messages.RemoteICViewer_Enabled;
+
+	// Set column names
+	private String[] columnNames = new String[] {NAME_COLUMN,
+			LOCATION_COLUMN, STATUS_COLUMN};
+
+
+	public ICTable(Composite parent) {
+
+		// Create the table
+		table = createTable(parent);
+		// Create and setup the TableViewer
+		viewer = createTableViewer();
+
+		loadPreferences();
+	}
+
+	/**
+	 * Release resources
+	 */
+	public void dispose() {
+		// Tell the label provider to release its resources
+		viewer.getLabelProvider().dispose();
+	}
+
+	/**
+	 * Create the Table
+	 */
+	private Table createTable(Composite parent) {
+		int style = SWT.MULTI | SWT.BORDER | SWT.H_SCROLL | SWT.V_SCROLL | SWT.FULL_SELECTION;
+
+		TableLayout tableLayout = new TableLayout();
+		Table table = new Table(parent, style);
+		table.setLayout(tableLayout);
+		table.setHeaderVisible(true);
+		table.setLinesVisible(true);
+		table.setFont(parent.getFont());
+
+		GridData gridData = new GridData(GridData.FILL_BOTH);
+		gridData.grabExcessVerticalSpace = true;
+		gridData.grabExcessHorizontalSpace = true;
+		gridData.verticalAlignment = GridData.FILL;
+		gridData.horizontalAlignment = GridData.FILL;
+		gridData.widthHint = IDialogConstants.ENTRY_FIELD_WIDTH;
+		gridData.heightHint =  table.getItemHeight();
+		gridData.horizontalSpan = 1;
+		table.setLayoutData(gridData);
+
+
+
+		ColumnLayoutData[] fTableColumnLayouts= {
+		        new ColumnWeightData(85),
+		        new ColumnWeightData(165),
+		        new ColumnWeightData(60)
+		};
+
+		TableColumn column;
+
+		tableLayout.addColumnData(fTableColumnLayouts[0]);
+	    column = new TableColumn(table, SWT.NONE, 0);
+	    column.setResizable(fTableColumnLayouts[0].resizable);
+	    column.setText(NAME_COLUMN);
+
+	    tableLayout.addColumnData(fTableColumnLayouts[1]);
+	    column = new TableColumn(table, SWT.NONE, 1);
+	    column.setResizable(fTableColumnLayouts[1].resizable);
+	    column.setText(LOCATION_COLUMN);
+
+	    tableLayout.addColumnData(fTableColumnLayouts[2]);
+	    column = new TableColumn(table, SWT.NONE, 2);
+	    column.setResizable(fTableColumnLayouts[2].resizable);
+	    column.setText(STATUS_COLUMN);
+
+	    return table;
+	}
+
+	/**
+	 * Create the TableViewer
+	 */
+	private TableViewer createTableViewer() {
+
+		TableViewer viewer = new TableViewer(table);
+		viewer.setUseHashlookup(true);
+		viewer.setColumnProperties(columnNames);
+		viewer.setContentProvider(new ICContentProvider());
+		viewer.setLabelProvider(new ICLabelProvider());
+		return viewer;
+	}
+
+	/**
+	 * Proxy for the the RemoteICList which provides content
+	 * for the Table. This class implements IRemoteHelpListViewer interface an
+	 * registers itself with RemoteICList
+	 */
+	class ICContentProvider implements IStructuredContentProvider
+	{
+		private List<IC> content = new ArrayList<>();
+
+		@Override
+		public void dispose() {
+			content = null;
+		}
+
+		@Override
+		@SuppressWarnings("unchecked")
+		public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
+			content = (List<IC>)newInput;
+		}
+
+		@Override
+		public IC[] getElements(Object inputElement) {
+			return content.toArray(new IC[content.size()]);
+		}
+
+	}
+
+	public class ICLabelProvider extends LabelProvider implements ITableLabelProvider {
+
+		@Override
+		public Image getColumnImage(Object element, int columnIndex) {
+			return null;
+		}
+
+		@Override
+		public String getColumnText(Object element, int columnIndex) {
+			switch (columnIndex) {
+			case 0:
+				return ((IC)element).getName();
+			case 1:
+				return ((IC)element).getHref();
+			case 2:
+				return ((IC)element).isEnabled() ? Messages.RemoteICLabelProvider_4 : Messages.RemoteICLabelProvider_5;
+			default:
+				return null;
+			}
+		}
+
+	}
+
+
+
+
+	/**
+	 * @param rics the ordered remote InfoCenters
+	 */
+	public void update(List<IC> ics) {
+		viewer.getContentProvider().inputChanged(viewer, null, ics);
+		refresh();
+	}
+
+	/**
+	 * Make sure the table viewer shows the latest copy of the ordered InfoCenters
+	 */
+	public void refresh() {
+		viewer.refresh(getICs());
+	}
+
+	/**
+	 * Return the column names in a collection
+	 *
+	 * @return List containing column names
+	 */
+	public List<String> getColumnNames() {
+		return Arrays.asList(columnNames);
+	}
+
+	/**
+	 * @return currently selected item
+	 */
+	public ISelection getSelection() {
+		return viewer.getSelection();
+	}
+
+	/**
+	 * Return the RemoteICList
+	 */
+	public List<IC> getICs() {
+		ICContentProvider p = (ICContentProvider)viewer.getContentProvider();
+		IC objs[] = p.getElements(null);
+		List<IC> content = new ArrayList<>();
+		for (int o=0;o<objs.length;o++)
+			content.add(objs[o]);
+		return content;
+	}
+
+	public void setICs(List<IC> ics)
+	{
+		List<IC> oldICs = getICs();
+		for (int o=0;o<oldICs.size();o++)
+			removeIC(oldICs.get(o));
+
+		for (int i=0;i<ics.size();i++)
+			addIC(ics.get(i));
+	}
+
+	public TableViewer getTableViewer()
+	{
+		return viewer;
+	}
+	/**
+	 * Return the parent composite
+	 */
+	public Control getControl() {
+		return table.getParent();
+	}
+
+	public Table getTable() {
+		return table;
+	}
+
+	public void addIC(IC ic)
+	{
+		List<IC> content = getICs();
+		content.add(ic);
+		getTableViewer().getContentProvider().inputChanged(
+				getTableViewer(), null, content);
+		getTableViewer().add(ic);
+		refresh();
+	}
+
+	public void editIC(IC ic)
+	{
+		List<IC> content = getICs();
+		content.set(getTable().getSelectionIndex(), ic);
+		getTableViewer().replace(ic,getTable().getSelectionIndex());
+		getTableViewer().getContentProvider().inputChanged(
+				getTableViewer(), null, content);
+		refresh();
+	}
+
+	public void removeIC(IC ic)
+	{
+		List<IC> content = getICs();
+		content.remove(ic);
+		getTableViewer().getContentProvider().inputChanged(getTableViewer(), null, content);
+		getTableViewer().remove(ic);
+		refresh();
+	}
+
+	private void loadPreferences()
+	{
+		List<IC> ics = ICPreferences.getICs();
+		for (int i=0;i<ics.size();i++)
+			addIC(ics.get(i));
+	}
+
+}
diff --git a/org.eclipse.help.ui/src/org/eclipse/help/ui/internal/views/IgnoreMissingPlaceholderHandler.java b/org.eclipse.help.ui/src/org/eclipse/help/ui/internal/views/IgnoreMissingPlaceholderHandler.java
index 8c8e046..02940fd 100644
--- a/org.eclipse.help.ui/src/org/eclipse/help/ui/internal/views/IgnoreMissingPlaceholderHandler.java
+++ b/org.eclipse.help.ui/src/org/eclipse/help/ui/internal/views/IgnoreMissingPlaceholderHandler.java
@@ -1,31 +1,31 @@
-/*******************************************************************************
- * Copyright (c) 2011, 2016 IBM Corporation and others.
+/*******************************************************************************
+ * Copyright (c) 2011, 2016 IBM Corporation and others.
  *
- * This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License 2.0
- * which accompanies this distribution, and is available at
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
  * https://www.eclipse.org/legal/epl-2.0/
  *
- * SPDX-License-Identifier: EPL-2.0
- *
- * Contributors:
- *     IBM Corporation - initial API and implementation
- *******************************************************************************/
-
-package org.eclipse.help.ui.internal.views;
-
-import org.eclipse.core.commands.AbstractHandler;
-import org.eclipse.core.commands.ExecutionEvent;
-import org.eclipse.core.commands.ExecutionException;
-import org.eclipse.help.internal.base.MissingContentManager;
-
-
-public class IgnoreMissingPlaceholderHandler extends AbstractHandler {
-
-	@Override
-	public Object execute(ExecutionEvent event) throws ExecutionException {
-		MissingContentManager.getInstance().ignoreAllMissingPlaceholders();
-		return null;
-	}
-
-}
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.help.ui.internal.views;
+
+import org.eclipse.core.commands.AbstractHandler;
+import org.eclipse.core.commands.ExecutionEvent;
+import org.eclipse.core.commands.ExecutionException;
+import org.eclipse.help.internal.base.MissingContentManager;
+
+
+public class IgnoreMissingPlaceholderHandler extends AbstractHandler {
+
+	@Override
+	public Object execute(ExecutionEvent event) throws ExecutionException {
+		MissingContentManager.getInstance().ignoreAllMissingPlaceholders();
+		return null;
+	}
+
+}
