//------------------------------------------------------------------------------
// Copyright (c) 2005, 2007 IBM Corporation and others.
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// which accompanies this distribution, and is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// Contributors:
// IBM Corporation - initial implementation
//------------------------------------------------------------------------------
package org.eclipse.epf.publishing.ui.preferences;

import org.eclipse.epf.library.LibraryService;
import org.eclipse.epf.library.LibraryServiceUtil;
import org.eclipse.epf.library.ui.preferences.LibraryUIPreferences;
import org.eclipse.epf.publishing.services.PublishOptions;
import org.eclipse.epf.publishing.ui.PublishingUIPlugin;
import org.eclipse.epf.uma.MethodConfiguration;
import org.eclipse.jface.preference.IPreferenceStore;

/**
 * Manages the Publishing UI preferences.
 * 
 * @author Kelvin Low
 * @author Jinhua Xi
 * @since 1.0 fix for https://bugs.eclipse.org/bugs/show_bug.cgi?id=156630
 */
public class PublishingUIPreferences {

	private static final String PUBLISH_ENTIRE_CONFIG = "publishEntireConfig"; //$NON-NLS-1$

	private static final String TITLE = PublishOptions.TITLE;

	private static final String BANNER_IMAGE = PublishOptions.BANNER_IMAGE;

	private static final String ABOUT_HTML = PublishOptions.ABOUT_HTML;

	private static final String FEEDBACK_URL = PublishOptions.FEEDBACK_URL;

	private static final String INCLUDE_GLOSSARY = PublishOptions.INCLUDE_GLOSSARY;

	private static final String INCLUDE_INDEX = PublishOptions.INCLUDE_INDEX;

	private static final String CHECK_EXTERNAL_LINKS = PublishOptions.CHECK_EXTERNAL_LINKS;

	private static final String CONVERT_BROKEN_LINKS = PublishOptions.CONVERT_BROKEN_LINKS;

	private static final String LIGHT_WEIGHT_TREE = PublishOptions.LIGHT_WEIGHT_TREE;

	private static final String EXTRA_DESCRIPTOR_INFO = PublishOptions.EXTRA_DESCRIPTOR_INFO;

	private static final String PUBLISH_UNOPEN_ACTIVITY_DD = LibraryUIPreferences.PUBLISH_UNOPEN_ACTIVITY_DD;

	private static final String PUBLISH_AD_FOR_ACTIVITY_EXTENSION = LibraryUIPreferences.PUBLISH_AD_FOR_ACTIVITY_EXTENSION;

	private static final String PUBLISH_PATH = PublishOptions.PUBLISH_PATH;

	private static final String PUBLISH_STATIC_WEB_SITE = "publishStaticWebSite"; //$NON-NLS-1$

	private static final String INCLUDE_SERVLET_SEARCH = "includeServletSearch"; //$NON-NLS-1$

	private static final String WEBAPP_NAME = PublishOptions.WEBAPP_NAME;

	private static final String INCLUDE_SEARCH = "includeSearch"; //$NON-NLS-1$

	private static final String INITIALIZED = "initialized"; //$NON-NLS-1$	

	// The plug-in specific preference store.
	private static IPreferenceStore prefStore = PublishingUIPlugin.getDefault()
			.getPreferenceStore();

	private static String defaultTitle = null;

	private static String defaultBannerImage = null;

	private static String defaultAboutHTML = null;

	private static String defaultFeedbackURL = null;

	private static String defaultPublishPath = null;

	static {
		// Initialize the default preference values.
		prefStore.setDefault(PUBLISH_ENTIRE_CONFIG, true);

		prefStore.setDefault(TITLE, getDefaultTitle());
		prefStore.setDefault(BANNER_IMAGE, getDefaultBannerImage());
		prefStore.setDefault(ABOUT_HTML, getDefaultAboutHTML());
		prefStore.setDefault(FEEDBACK_URL, getDefaultFeedbackURL());
		prefStore.setDefault(INCLUDE_GLOSSARY, true);
		prefStore.setDefault(INCLUDE_INDEX, true);
		prefStore.setDefault(CHECK_EXTERNAL_LINKS, true);
		prefStore.setDefault(CONVERT_BROKEN_LINKS, true);
		prefStore.setDefault(PUBLISH_UNOPEN_ACTIVITY_DD, true);
		prefStore.setDefault(PUBLISH_AD_FOR_ACTIVITY_EXTENSION, true);
		prefStore.setDefault(LIGHT_WEIGHT_TREE, true);
		prefStore.setDefault(EXTRA_DESCRIPTOR_INFO,
				getDefaultExtraDescriptorInfo());

		prefStore.setDefault(PUBLISH_PATH, getDefaultPublishPath());
		prefStore.setDefault(PUBLISH_STATIC_WEB_SITE, true);
		prefStore.setDefault(INCLUDE_SERVLET_SEARCH, true);
		prefStore.setDefault(WEBAPP_NAME, ""); //$NON-NLS-1$			
		prefStore.setDefault(INCLUDE_SEARCH, true);
	}

	/**
	 * Gets the publish entire configuration preference value.
	 * 
	 * @param configId
	 *            a method configuration GUID
	 * @return <code>true</code> if the preference is set
	 */
	public static boolean getPublishEntireConfig(String configId) {
		if (getConfigPrefInitialized(configId)) {
			return prefStore.getBoolean(getConfigPrefPrefix(configId)
					+ PUBLISH_ENTIRE_CONFIG);
		} else {
			return prefStore.getBoolean(PUBLISH_ENTIRE_CONFIG);
		}
	}

	/**
	 * Sets the publish entire configurationpreference value.
	 * 
	 * @param configId
	 *            a method configuration GUID
	 * @param value
	 *            the preference value
	 */
	public static void setPublishEntireConfig(String configId, boolean value) {
		prefStore.setValue(getConfigPrefPrefix(configId)
				+ PUBLISH_ENTIRE_CONFIG, value);
	}

	/**
	 * Gets the default title for a published website.
	 * 
	 * @return the default title for a published website
	 */
	public static String getDefaultTitle() {
		if (defaultTitle == null) {
			String url = PublishingUIPlugin.getDefault().getString("title"); //$NON-NLS-1$
			if (url == null || url.length() == 0 || url.startsWith("[")) { //$NON-NLS-1$
				url = ""; //$NON-NLS-1$
			}
			defaultTitle = url;
		}
		return defaultTitle;
	}

	/**
	 * Gets the web site title preference value.
	 * 
	 * @param configId
	 *            a method configuration GUID
	 * @return the web site title
	 */
	public static String getTitle(String configId) {
		if (getConfigPrefInitialized(configId)) {
			return prefStore.getString(getConfigPrefPrefix(configId) + TITLE);
		} else {
			return prefStore.getString(TITLE);
		}
	}

	/**
	 * Sets the web site title preference value.
	 * 
	 * @param configId
	 *            a method configuration GUID
	 * @param title
	 *            the web site title
	 */
	public static void setTitle(String configId, String title) {
		prefStore.setValue(getConfigPrefPrefix(configId) + TITLE, title);
	}

	/**
	 * Gets the default banner image for a published website.
	 * 
	 * @return the default banner image for a published website
	 */
	public static String getDefaultBannerImage() {
		if (defaultBannerImage == null) {
			String image = PublishingUIPlugin.getDefault().getString(
					"bannerImage"); //$NON-NLS-1$
			if (image == null || image.length() == 0 || image.startsWith("[")) { //$NON-NLS-1$
				image = ""; //$NON-NLS-1$
			}
			defaultBannerImage = image;
		}
		return defaultBannerImage;
	}

	/**
	 * Gets the banner image preference value.
	 * 
	 * @param configId
	 *            a method configuration GUID
	 * @return the banner image
	 */
	public static String getBannerImage(String configId) {
		if (getConfigPrefInitialized(configId)) {
			return prefStore.getString(getConfigPrefPrefix(configId)
					+ BANNER_IMAGE);
		} else {
			return prefStore.getString(BANNER_IMAGE);
		}
	}

	/**
	 * Sets the banner image preference value.
	 * 
	 * @param configId
	 *            a method configuration GUID
	 * @param image
	 *            the banner image URL
	 */
	public static void setBannerImage(String configId, String image) {
		prefStore.setValue(getConfigPrefPrefix(configId) + BANNER_IMAGE,
				image);
	}

	/**
	 * Gets the default about HTML for a published website.
	 * 
	 * @return the default about HTML for a published website
	 */
	public static String getDefaultAboutHTML() {
		if (defaultAboutHTML == null) {
			String file = PublishingUIPlugin.getDefault()
					.getString("aboutHTML"); //$NON-NLS-1$
			if (file == null || file.length() == 0 || file.startsWith("[")) { //$NON-NLS-1$
				file = ""; //$NON-NLS-1$
			}
			defaultAboutHTML = file;
		}
		return defaultAboutHTML;
	}

	/**
	 * Gets the about HTML preference value.
	 * 
	 * @param configId
	 *            a method configuration GUID
	 * @return the about HTML file path
	 */
	public static String getAboutHTML(String configId) {
		if (getConfigPrefInitialized(configId)) {
			return prefStore.getString(getConfigPrefPrefix(configId)
					+ ABOUT_HTML);
		} else {
			return prefStore.getString(ABOUT_HTML);
		}
	}

	/**
	 * Sets the about HTML preference value.
	 * 
	 * @param configId
	 *            a method configuration GUID
	 * @param path
	 *            the about HTML file path
	 */
	public static void setAboutHTML(String configId, String path) {
		prefStore.setValue(getConfigPrefPrefix(configId) + ABOUT_HTML, path);
	}

	/**
	 * Gets the default feedback URL for a published website.
	 * 
	 * @return the default feedback URL for a published website
	 */
	public static String getDefaultFeedbackURL() {
		if (defaultFeedbackURL == null) {
			defaultFeedbackURL = "http://www.published_website.com/feedback"; //$NON-NLS-1$
		}
		return defaultFeedbackURL;
	}

	/**
	 * Gets the feedback URL preference value.
	 * 
	 * @return the feedback URL
	 */
	public static String getFeedbackURL() {
		return prefStore.getString(FEEDBACK_URL);
	}

	/**
	 * Sets the feedback URL preference value.
	 * 
	 * @param url
	 *            the feedback URL
	 */
	public static void setFeedbackURL(String url) {
		prefStore.setValue(FEEDBACK_URL, url);
	}

	/**
	 * Gets the feedback URL preference value.
	 * 
	 * @param configId
	 *            a method configuration GUID
	 * @return the feedback URL
	 */
	public static String getFeedbackURL(String configId) {
		if (getConfigPrefInitialized(configId)) {
			return prefStore.getString(getConfigPrefPrefix(configId)
					+ FEEDBACK_URL);
		} else {
			return prefStore.getString(FEEDBACK_URL);
		}
	}

	/**
	 * Sets the feedback URL preference value.
	 * 
	 * @param configId
	 *            a method configuration GUID
	 * @param url
	 *            the feedback URL
	 */
	public static void setFeedbackURL(String configId, String url) {
		prefStore.setValue(getConfigPrefPrefix(configId) + FEEDBACK_URL, url);
	}

	/**
	 * Gets the include glossary preference value.
	 * 
	 * @param configId
	 *            a method configuration GUID
	 * @return <code>true</code> if the preference is set
	 */
	public static boolean getIncludeGlossary(String configId) {
		if (getConfigPrefInitialized(configId)) {
			return prefStore.getBoolean(getConfigPrefPrefix(configId)
					+ INCLUDE_GLOSSARY);
		} else {
			return prefStore.getBoolean(INCLUDE_GLOSSARY);
		}
	}

	/**
	 * Sets the include glossary preference value.
	 * 
	 * @param configId
	 *            a method configuration GUID
	 * @param value
	 *            the preference value
	 */
	public static void setIncludeGlossary(String configId, boolean value) {
		prefStore.setValue(getConfigPrefPrefix(configId) + INCLUDE_GLOSSARY,
				value);
	}

	/**
	 * Gets the include index preference value.
	 * 
	 * @param configId
	 *            a method configuration GUID
	 * @return <code>true</code> if the preference is set
	 */
	public static boolean getIncludeIndex(String configId) {
		if (getConfigPrefInitialized(configId)) {
			return prefStore.getBoolean(getConfigPrefPrefix(configId)
					+ INCLUDE_INDEX);
		} else {
			return prefStore.getBoolean(INCLUDE_INDEX);
		}
	}

	/**
	 * Sets the include index preference value.
	 * 
	 * @param configId
	 *            a method configuration GUID
	 * @param value
	 *            the preference value
	 */
	public static void setIncludeIndex(String configId, boolean value) {
		prefStore.setValue(getConfigPrefPrefix(configId) + INCLUDE_INDEX,
				value);
	}

	/**
	 * Gets the check external links preference value.
	 * 
	 * @param configId
	 *            a method configuration GUID
	 * @return <code>true</code> if the preference is set
	 */
	public static boolean getCheckExternalLinks(String configId) {
		if (getConfigPrefInitialized(configId)) {
			return prefStore.getBoolean(getConfigPrefPrefix(configId)
					+ CHECK_EXTERNAL_LINKS);
		} else {
			return prefStore.getBoolean(CHECK_EXTERNAL_LINKS);
		}
	}

	/**
	 * Sets the check external links preference value.
	 * 
	 * @param configId
	 *            a method configuration GUID
	 * @param value
	 *            the preference value
	 */
	public static void setCheckExternalLinks(String configId, boolean value) {
		prefStore.setValue(getConfigPrefPrefix(configId)
				+ CHECK_EXTERNAL_LINKS, value);
	}

	/**
	 * Gets the convert broken links preference value.
	 * 
	 * @param configId
	 *            a method configuration GUID
	 * @return <code>true</code> if the preference is set
	 */
	public static boolean getConvertBrokenLinks(String configId) {
		if (getConfigPrefInitialized(configId)) {
			return prefStore.getBoolean(getConfigPrefPrefix(configId)
					+ CONVERT_BROKEN_LINKS);
		} else {
			return prefStore.getBoolean(CONVERT_BROKEN_LINKS);
		}
	}

	/**
	 * Sets the convert broken links preference value.
	 * 
	 * @param configId
	 *            a method configuration GUID
	 * @param value
	 *            the preference value
	 */
	public static void setConvertBrokenLinks(String configId, boolean value) {
		prefStore.setValue(getConfigPrefPrefix(configId)
				+ CONVERT_BROKEN_LINKS, value);
	}

	/**
	 * Gets the publish unopen activity detail diagrams preference value.
	 * 
	 * @param configId
	 *            a method configuration GUID
	 * @return <code>true</code> if the preference is set
	 */
	public static boolean getPublishUnopenActivitydd(String configId) {
		if (getConfigPrefInitialized(configId)) {
			return prefStore.getBoolean(getConfigPrefPrefix(configId)
					+ PUBLISH_UNOPEN_ACTIVITY_DD);
		} else {
			return prefStore.getBoolean(PUBLISH_UNOPEN_ACTIVITY_DD);
		}
	}

	/**
	 * Sets the publish unopen activity detail diagrams preference value.
	 * 
	 * @param configId
	 *            a method configuration GUID
	 * @param value
	 *            the preference value
	 */
	public static void setPublishUnopenActivitydd(String configId,
			boolean value) {
		prefStore.setValue(getConfigPrefPrefix(configId)
				+ PUBLISH_UNOPEN_ACTIVITY_DD, value);
	}

	/**
	 * Gets the publish activiy diagrams for base activities with unmodified
	 * extension preference value.
	 * 
	 * @param configId
	 *            a method configuration GUID
	 * @return <code>true</code> if the preference is set
	 */
	public static boolean getPublishADForActivityExtension(String configId) {
		if (getConfigPrefInitialized(configId)) {
			return prefStore.getBoolean(getConfigPrefPrefix(configId)
					+ PUBLISH_AD_FOR_ACTIVITY_EXTENSION);
		} else {
			return prefStore.getBoolean(PUBLISH_AD_FOR_ACTIVITY_EXTENSION);
		}
	}

	/**
	 * Sets the publish activiy diagrams for base activities with unmodified
	 * extension preference value.
	 * 
	 * @param configId
	 *            a method configuration GUID
	 * @param value
	 *            the preference value
	 */
	public static void setPublishADForActivityExtension(String configId,
			boolean value) {
		prefStore.setValue(getConfigPrefPrefix(configId)
				+ PUBLISH_AD_FOR_ACTIVITY_EXTENSION, value);
	}

	/**
	 * Gets the light weight tree preference value.
	 * 
	 * @param configId
	 *            a method configuration GUID
	 * @return <code>true</code> if the preference is set
	 */
	public static boolean getLightWeightTree(String configId) {
		if (getConfigPrefInitialized(configId)) {
			return prefStore.getBoolean(getConfigPrefPrefix(configId)
					+ LIGHT_WEIGHT_TREE);
		} else {
			return prefStore.getBoolean(LIGHT_WEIGHT_TREE);
		}
	}

	/**
	 * Sets the light weight tree preference value.
	 * 
	 * @param configId
	 *            a method configuration GUID
	 * @param value
	 *            the preference value
	 */
	public static void setLightWeightTree(String configId, boolean value) {
		prefStore.setValue(getConfigPrefPrefix(configId) + LIGHT_WEIGHT_TREE,
				value);
	}

	/**
	 * Gets the default extra descriptor info preference value.
	 * 
	 * @return <code>true</code> if the preference is set
	 */
	public static boolean getDefaultExtraDescriptorInfo() {
		return true;
	}

	/**
	 * Gets the extra descriptor info preference value.
	 * 
	 * @return the preference value
	 */
	public static boolean getExtraDescriptorInfo() {
		return prefStore.getBoolean(EXTRA_DESCRIPTOR_INFO);
	}

	/**
	 * Sets the default extra descriptor info preference value.
	 * 
	 * @param value
	 *            the preference value
	 */
	public static void setExtraDescriptorInfo(boolean value) {
		prefStore.setValue(EXTRA_DESCRIPTOR_INFO, value);
	}

	/**
	 * Gets the extra descriptor info preference value.
	 * 
	 * @param configId
	 *            a method configuration GUID
	 * @return <code>true</code> if the preference is set
	 */
	public static boolean getExtraDescriptorInfo(String configId) {
		if (getConfigPrefInitialized(configId)) {
			return prefStore.getBoolean(getConfigPrefPrefix(configId)
					+ EXTRA_DESCRIPTOR_INFO);
		} else {
			return prefStore.getBoolean(EXTRA_DESCRIPTOR_INFO);
		}
	}

	/**
	 * Sets the extra descriptor info preference value.
	 * 
	 * @param configId
	 *            a method configuration GUID
	 * @param value
	 *            the preference value
	 */
	public static void setExtraDescriptorInfo(String configId, boolean value) {
		prefStore.setValue(getConfigPrefPrefix(configId)
				+ EXTRA_DESCRIPTOR_INFO, value);
	}

	/**
	 * Gets the default path for a published web site.
	 * 
	 * @return the default path for a published web site.
	 */
	public static String getDefaultPublishPath() {
		if (defaultPublishPath == null) {
			String userHome = System
					.getProperty("user.home").replace('\\', '/'); //$NON-NLS-1$
			String path = PublishingUIPlugin.getDefault().getString(
					"publishPath"); //$NON-NLS-1$
			if (path == null || path.length() == 0 || path.startsWith("[")) { //$NON-NLS-1$
				path = userHome + "/publish"; //$NON-NLS-1$
			} else if (path.startsWith("<user.home>")) { //$NON-NLS-1$
				path = userHome + path.substring(11);
			}
			if (System.getProperty("file.separator").equals("\\")) { //$NON-NLS-1$ //$NON-NLS-2$
				path = path.replace('/', '\\');
			}

			int idx = -1;
			if ((idx = path.indexOf("<app.name>")) >= 0) { //$NON-NLS-1$
				String appNameProper = LibraryUIPreferences
						.getApplicationShortName();
				path = path.substring(0, idx) + appNameProper
						+ path.substring(idx + 10);
			}

			defaultPublishPath = path;
		}
		return defaultPublishPath;
	}

	/**
	 * Gets the publish path preference value.
	 * 
	 * @return the publish path
	 */
	public static String getPublishPath() {
		return prefStore.getString(PUBLISH_PATH);
	}

	/**
	 * Sets the publish path preference value.
	 * 
	 * @param path
	 *            the publish path
	 */
	public static void setPublishPath(String path) {
		prefStore.setValue(PUBLISH_PATH, path);
	}

	/**
	 * Gets the publish path preference value.
	 * 
	 * @param configId
	 *            a method configuration GUID
	 * @return the publish path
	 */
	public static String getPublishPath(String configId) {
		if (getConfigPrefInitialized(configId)) {
			return prefStore.getString(getConfigPrefPrefix(configId)
					+ PUBLISH_PATH);
		} else {
			return prefStore.getString(PUBLISH_PATH);
		}
	}

	/**
	 * Sets the publish path preference value.
	 * 
	 * @param configId
	 *            a method configuration GUID
	 * @param path
	 *            the publish path
	 */
	public static void setPublishPath(String configId, String path) {
		prefStore
				.setValue(getConfigPrefPrefix(configId) + PUBLISH_PATH, path);
	}

	/**
	 * Gets the publish static web site preference value.
	 * 
	 * @param configId
	 *            a method configuration GUID
	 * @return <code>true</code> if the preference is set
	 */
	public static boolean getPublishStaticWebSite(String configId) {
		if (getConfigPrefInitialized(configId)) {
			return prefStore.getBoolean(getConfigPrefPrefix(configId)
					+ PUBLISH_STATIC_WEB_SITE);
		} else {
			return prefStore.getBoolean(PUBLISH_STATIC_WEB_SITE);
		}
	}

	/**
	 * Sets the publish static web site preference value.
	 * 
	 * @param configId
	 *            a method configuration GUID
	 * @param value
	 *            the preference value
	 */
	public static void setPublishStaticWebSite(String configId, boolean value) {
		prefStore.setValue(getConfigPrefPrefix(configId)
				+ PUBLISH_STATIC_WEB_SITE, value);
	}

	/**
	 * Gets the include applet search preference value.
	 * 
	 * @param configId
	 *            a method configuration GUID
	 * @return <code>true</code> if the preference is set
	 */
	public static boolean getIncludeServletSearch(String configId) {
		if (getConfigPrefInitialized(configId)) {
			return prefStore.getBoolean(getConfigPrefPrefix(configId)
					+ INCLUDE_SERVLET_SEARCH);
		} else {
			return prefStore.getBoolean(INCLUDE_SERVLET_SEARCH);
		}
	}

	/**
	 * Sets the include servlet search preference value..
	 * 
	 * @param configId
	 *            a method configuration GUID
	 * @param value
	 *            the preference value
	 */
	public static void setIncludeServletSearch(String configId, boolean value) {
		prefStore.setValue(getConfigPrefPrefix(configId)
				+ INCLUDE_SERVLET_SEARCH, value);
	}

	/**
	 * Gets the include search preference value.
	 * 
	 * @param configId
	 *            a method configuration GUID
	 * @return <code>true</code> if the preference is set
	 */
	public static boolean getIncludeSearch(String configId) {
		if (getConfigPrefInitialized(configId)) {
			return prefStore.getBoolean(getConfigPrefPrefix(configId)
					+ INCLUDE_SEARCH);
		} else {
			return prefStore.getBoolean(INCLUDE_SEARCH);
		}
	}

	/**
	 * Sets the include search preference value.
	 * 
	 * @param configId
	 *            a method configuration GUID
	 * @param value
	 *            the preference value
	 */
	public static void setIncludeSearch(String configId, boolean value) {
		prefStore.setValue(getConfigPrefPrefix(configId) + INCLUDE_SEARCH,
				value);
	}

	/**
	 * Gets the web application name preference value.
	 * 
	 * @param configId
	 *            a method configuration GUID
	 * @return the preference value
	 */
	public static String getWebAppName(String configId) {
		if (getConfigPrefInitialized(configId)) {
			return prefStore.getString(getConfigPrefPrefix(configId)
					+ WEBAPP_NAME);
		} else {
			return prefStore.getString(WEBAPP_NAME);
		}
	}

	/**
	 * Sets the web application name preference value.
	 * 
	 * @param configId
	 *            a method configuration GUID
	 * @param name
	 *            the web application name
	 */
	public static void setWebAppName(String configId, String name) {
		prefStore.setValue(getConfigPrefPrefix(configId) + WEBAPP_NAME, name);
	}

	/**
	 * Gets the method configuration specific preference prefix.
	 * 
	 * @param configId
	 *            the name of a method configuration
	 * @return a preference prefix assigned to the configuration
	 */
	public static String getConfigPrefPrefix(String configId) {
		try {
			MethodConfiguration config = LibraryServiceUtil
					.getMethodConfiguration(LibraryService.getInstance()
							.getCurrentMethodLibrary(), configId);
			return config.getGuid() + "."; //$NON-NLS-1$
		} catch (Exception e) {
			return "";
		}
	}

	/**
	 * Gets the configuration specific preferences initialized preference value.
	 * 
	 * @param configId
	 *            a method configuration GUID
	 * @return the preference value
	 */
	public static boolean getConfigPrefInitialized(String configId) {
		return prefStore.getBoolean(getConfigPrefPrefix(configId)
				+ INITIALIZED);
	}

	/**
	 * Sets the configuration specific preferences initialized preference value.
	 * 
	 * @param configId
	 *            a method configuration GUID
	 * @param value
	 *            the preference value
	 */
	public static void setConfigPrefInitialized(String configId, boolean value) {
		prefStore
				.setValue(getConfigPrefPrefix(configId) + INITIALIZED, value);
	}

	/**
	 * Saves all the preferences.
	 */
	public static void saveAllPreferences() {
		PublishingUIPlugin.getDefault().savePluginPreferences();
	}
}
