//------------------------------------------------------------------------------
	// Copyright (c) 2005, 2006 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.authoring.ui.forms;

import java.io.File;
import java.io.IOException;
import java.net.URI;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.Iterator;
import java.util.List;

import org.eclipse.core.runtime.IStatus;
import org.eclipse.draw2d.ColorConstants;
import org.eclipse.emf.common.command.Command;
import org.eclipse.emf.common.notify.AdapterFactory;
import org.eclipse.emf.common.notify.Notification;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.edit.ui.provider.AdapterFactoryContentProvider;
import org.eclipse.emf.edit.ui.provider.AdapterFactoryLabelProvider;
import org.eclipse.epf.authoring.ui.AuthoringUIHelpContexts;
import org.eclipse.epf.authoring.ui.AuthoringUIImages;
import org.eclipse.epf.authoring.ui.AuthoringUIPlugin;
import org.eclipse.epf.authoring.ui.AuthoringUIResources;
import org.eclipse.epf.authoring.ui.AuthoringUIText;
import org.eclipse.epf.authoring.ui.dialogs.ItemsFilterDialog;
import org.eclipse.epf.authoring.ui.editors.EditorChooser;
import org.eclipse.epf.authoring.ui.editors.MethodElementEditor;
import org.eclipse.epf.authoring.ui.editors.MethodElementEditorInput;
import org.eclipse.epf.authoring.ui.filters.ContentFilter;
import org.eclipse.epf.authoring.ui.preferences.AuthoringUIPreferences;
import org.eclipse.epf.authoring.ui.providers.ColumnElement;
import org.eclipse.epf.authoring.ui.providers.DescriptionPageColumnProvider;
import org.eclipse.epf.authoring.ui.richtext.IMethodRichText;
import org.eclipse.epf.authoring.ui.richtext.IMethodRichTextEditor;
import org.eclipse.epf.authoring.ui.util.EditorsContextHelper;
import org.eclipse.epf.authoring.ui.util.UIHelper;
import org.eclipse.epf.authoring.ui.views.LibraryView;
import org.eclipse.epf.common.ui.util.MsgBox;
import org.eclipse.epf.common.utils.FileUtil;
import org.eclipse.epf.common.utils.NetUtil;
import org.eclipse.epf.common.utils.StrUtil;
import org.eclipse.epf.library.LibraryService;
import org.eclipse.epf.library.edit.IFilter;
import org.eclipse.epf.library.edit.LibraryEditResources;
import org.eclipse.epf.library.edit.TngAdapterFactory;
import org.eclipse.epf.library.edit.command.DeleteMethodElementCommand;
import org.eclipse.epf.library.edit.command.IActionManager;
import org.eclipse.epf.library.edit.itemsfilter.FilterConstants;
import org.eclipse.epf.library.edit.util.ExtensionManager;
import org.eclipse.epf.library.edit.util.TngUtil;
import org.eclipse.epf.library.edit.validation.DependencyChecker;
import org.eclipse.epf.library.edit.validation.IValidator;
import org.eclipse.epf.library.edit.validation.IValidatorFactory;
import org.eclipse.epf.library.ui.LibraryUIText;
import org.eclipse.epf.library.ui.LibraryUIUtil;
import org.eclipse.epf.library.ui.actions.MethodElementDeleteAction;
import org.eclipse.epf.library.ui.util.ConvertGuidanceType;
import org.eclipse.epf.library.util.LibraryUtil;
import org.eclipse.epf.library.util.ResourceHelper;
import org.eclipse.epf.richtext.RichTextListener;
import org.eclipse.epf.uma.Guidance;
import org.eclipse.epf.uma.MethodConfiguration;
import org.eclipse.epf.uma.MethodElement;
import org.eclipse.epf.uma.MethodElementProperty;
import org.eclipse.epf.uma.MethodPlugin;
import org.eclipse.epf.uma.SupportingMaterial;
import org.eclipse.epf.uma.UmaFactory;
import org.eclipse.epf.uma.UmaPackage;
import org.eclipse.epf.uma.VariabilityElement;
import org.eclipse.epf.uma.VariabilityType;
import org.eclipse.epf.uma.util.ContentDescriptionFactory;
import org.eclipse.epf.uma.util.UmaUtil;
import org.eclipse.jface.viewers.ComboViewer;
import org.eclipse.jface.viewers.ILabelProvider;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.IStructuredContentProvider;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.osgi.util.NLS;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.ControlEvent;
import org.eclipse.swt.events.ControlListener;
import org.eclipse.swt.events.FocusAdapter;
import org.eclipse.swt.events.FocusEvent;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
import org.eclipse.swt.events.PaintEvent;
import org.eclipse.swt.events.PaintListener;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.ImageData;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.layout.FormAttachment;
import org.eclipse.swt.layout.FormData;
import org.eclipse.swt.layout.FormLayout;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Canvas;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.FileDialog;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableItem;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IEditorSite;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.forms.IManagedForm;
import org.eclipse.ui.forms.editor.FormEditor;
import org.eclipse.ui.forms.events.HyperlinkAdapter;
import org.eclipse.ui.forms.events.HyperlinkEvent;
import org.eclipse.ui.forms.widgets.FormToolkit;
import org.eclipse.ui.forms.widgets.ImageHyperlink;
import org.eclipse.ui.forms.widgets.Section;
import org.eclipse.ui.forms.widgets.TableWrapData;
import org.eclipse.ui.forms.widgets.TableWrapLayout;

import com.ibm.icu.text.DateFormat;


/**
 * The base class for all Description pages in the Method editors.
 * 
 * @author Jeff Hardy
 * @author Kelvin Low
 * @author Shashidhar Kannoori
 * @author Shilpa Toraskar
 * @author Phong Nguyen Le
 * @since 1.0
 * fix for https://bugs.eclipse.org/bugs/show_bug.cgi?id=176382
 */
public abstract class DescriptionFormPage extends BaseFormPage implements IRefreshable {

	public static final int BUTTON_WIDTH = 150;
	
	protected static final String NOT_APPLICABLE_TEXT = AuthoringUIResources.notApplicable_text; 
	
	protected static final String CONTRIBUTES_TEXT = AuthoringUIResources.contributes_text; 
	
	private static final String LOCAL_CONTRIBUTES_TEXT = AuthoringUIResources.localContributes_text;  

	protected static final String EXTENDS_TEXT = AuthoringUIResources.extends_text; 

	protected static final String REPLACES_TEXT = AuthoringUIResources.replaces_text; 
	
	protected static final String LOCAL_REPLACES_TEXT = AuthoringUIResources.localReplaces_text; 
	
	protected static final String EXTENDS_REPLACES_TEXT = AuthoringUIResources.extendsReplaces_text;

	protected static final ILabelProvider labelProvider = new AdapterFactoryLabelProvider(
			TngUtil.umaItemProviderAdapterFactory);
	
	// Composites and sections.
	protected Section formSection;

	protected Composite sectionComposite;
	
	private Composite mainComposite;

	protected Composite expandedComposite;

	protected Section generalSection;

	protected Section variabilitySection;

	protected Composite generalComposite;

	protected Composite variabilityComposite;

	protected Section versionSection;

	protected Composite versionComposite;

	protected Section iconSection;

	protected Composite iconComposite;

	private Canvas pane1;

	private Canvas pane3;

	protected Section detailSection;

	protected Composite detailComposite;

	protected Section notationSection;

	protected Composite notationComposite;

	protected Section tailoringSection;

	protected Composite tailoringComposite;

	// Edit controls.
	protected Text ctrl_name;

	protected Text ctrl_presentation_name;
	
	protected Text ctrl_long_presentation_name;

	protected Label ctrl_type_label;

	protected Button ctrl_type_button;

	protected Text ctrl_brief_desc;

	protected IMethodRichText ctrl_full_desc;

	protected IMethodRichText ctrl_key;

	protected IMethodRichTextEditor ctrl_expanded;

	protected ComboViewer viewer_variability;

	protected Combo ctrl_variability;

	protected Label label_base;

	protected TableViewer base_viewer;

	protected Table ctrl_base;

	protected Button ctrl_base_button;

	private IMethodRichText activeControl;

	private Text ctrl_authors;

	protected Text ctrl_change_date;

	private Text ctrl_change_desc;

	private Text ctrl_version;

	protected Label label_copyright;

	protected TableViewer copyright_viewer;

	protected Table ctrl_copyright;

	private Button copyright_button;

	private Button copyright_button_deselect;

	protected ImageHyperlink expandDetailLink;

	protected Label expandDetailLabel;

	protected ImageHyperlink expandNotationLink;

	protected Label expandNotationLabel;

	protected ImageHyperlink expandTailoringLink;

	protected Label expandTailoringLabel;

	protected IMethodRichText ctrl_purpose;

	protected Text ctrl_external_id;

	private Image shapeImage;

	private Image nodeImage;

	protected Button ctrl_select_shapeIcon_button;

	protected Button ctrl_clear_shapeIcon_button;

	protected Button ctrl_select_nodeIcon_button;

	protected Button ctrl_clear_nodeIcon_button;
	
	protected Button ctrl_publish_categories_button;

	protected ImageHyperlink expandVersionLink;

	protected Label expandVersionLabel;

	protected ImageHyperlink expandLink;

	protected Label expandLabel;
	
	protected IStructuredContentProvider contentProviderVariability;

	protected IStructuredContentProvider contentProviderBase;
	
	private IColumnProvider columnProvider;
	
	private List<ISectionProvider> sectionProviders;
	
	private boolean autoGenName = false;
	
	protected ILabelProvider labelProviderVariability = new AdapterFactoryLabelProvider(
			TngAdapterFactory.INSTANCE
					.getNavigatorView_ComposedAdapterFactory()) {
		public String getText(Object object) {
			VariabilityType varObject = (VariabilityType) object;
			if (varObject == VariabilityType.NA)
				return NOT_APPLICABLE_TEXT;
			if (varObject == VariabilityType.CONTRIBUTES)
				return CONTRIBUTES_TEXT;
			if (varObject == VariabilityType.LOCAL_CONTRIBUTION)
				return LOCAL_CONTRIBUTES_TEXT;
			if (varObject == VariabilityType.EXTENDS)
				return EXTENDS_TEXT;
			if (varObject == VariabilityType.REPLACES)
				return REPLACES_TEXT;
			if (varObject == VariabilityType.LOCAL_REPLACEMENT)
				return LOCAL_REPLACES_TEXT;
			if (varObject == VariabilityType.EXTENDS_REPLACES)
				return EXTENDS_REPLACES_TEXT;
			
			return null;
		}
	};

	protected ILabelProvider labelProviderBase = new AdapterFactoryLabelProvider(
			TngAdapterFactory.INSTANCE
					.getNavigatorView_ComposedAdapterFactory()) {
		public String getColumnText(Object object, int columnIndex) {
			return TngUtil.getLabelWithPath(object);
		}
	};

	protected IActionManager actionMgr;

	protected IStructuredContentProvider copyrightContentProvider;

	private ILabelProvider copyrightLabelProviderBase = new AdapterFactoryLabelProvider(
			TngAdapterFactory.INSTANCE
					.getNavigatorView_ComposedAdapterFactory());

	protected ModifyListener modelModifyListener;

	protected ModifyListener contentModifyListener;
	
	
	protected FocusAdapter nameFocusListener = new FocusAdapter() {
		public void focusGained(FocusEvent e) {
			((MethodElementEditor) getEditor()).setCurrentFeatureEditor(e.widget,
					UmaPackage.eINSTANCE.getNamedElement_Name());
		}

		public void focusLost(FocusEvent e) {
			String oldContent = methodElement.getName() ;
			String name = ctrl_name.getText().trim();
			if (((MethodElementEditor) getEditor()).mustRestoreValue(
					e.widget, methodElement.getName())) {
				return;
			}
			if (name.equals(methodElement.getName()))
				return;
			
			// 178462
			String msg = null;
			if (oldContent.indexOf("&") < 0 && name.indexOf("&") > -1) { //$NON-NLS-1$ //$NON-NLS-2$
				msg = NLS.bind(
						LibraryEditResources.invalidElementNameError4_msg,
						name);
			} else {
				IValidator validator = getNameValidator();
				if(validator == null){
					validator = IValidatorFactory.INSTANCE
						.createNameValidator(
								methodElement,
								TngAdapterFactory.INSTANCE
										.getNavigatorView_ComposedAdapterFactory());
				}
				msg = validator.isValid(name);
			}
			if (msg == null && !name.equals(methodElement.getName())) {
				if(name.indexOf("&") > -1) { //$NON-NLS-1$
					msg = NLS.bind(
							LibraryEditResources.invalidElementNameError4_msg,
							name);
				}
			}
			if (msg == null) {
				name = StrUtil.makeValidFileName(ctrl_name.getText());
				ctrl_name.setText(name); //183084
				if (!name.equals(methodElement.getName())) {						
					if (!changeElementName(name)) {
						return;
					}
				}
			} else {
				//Fix missing "&" in error dialog
				if (msg.indexOf("&") >= 0) {//$NON-NLS-1$
					msg = msg.replace("&", "&&");//$NON-NLS-1$//$NON-NLS-2$
				}
				AuthoringUIPlugin
						.getDefault()
						.getMsgDialog()
						.displayError(
								AuthoringUIResources.renameError_title, 
								msg);
				ctrl_name.setText(methodElement.getName());
				ctrl_name.getDisplay().asyncExec(new Runnable() {
					public void run() {
						ctrl_name.setFocus();
						ctrl_name.selectAll();
					}
				});
			}
		}
	};

	protected boolean changeElementName(String name) {
		boolean success = actionMgr.doAction(
				IActionManager.SET, methodElement,
				UmaPackage.eINSTANCE.getNamedElement_Name(),
				name, -1);
		if (!success) {
			return false;
		}
		if(methodElement instanceof MethodConfiguration) {
			Resource resource = methodElement.eResource();
			if(resource != null) {
				((MethodElementEditor) getEditor()).addResourceToAdjustLocation(resource);
			}
		}
		if (ContentDescriptionFactory
				.hasPresentation(methodElement)) {
			Resource contentResource = contentElement
					.getPresentation().eResource();
			if (contentResource != null) {
				((MethodElementEditor) getEditor())
						.addResourceToAdjustLocation(contentResource);
			}
		}
		setFormTextWithVariableInfo();
		ctrl_name.setText(name);
		
		return true;
	}
	
	// Editing and display flags.
	protected boolean descExpandFlag = false;

	protected boolean generalSectionExpandFlag = false;

	protected boolean detailSectionExpandFlag = false;

	protected boolean notationSectionExpandFlag = false;

	protected boolean tailoringSectionExpandFlag = false;

	protected boolean versionSectionExpandFlag = false;

	protected boolean elementSectionExpandFlag = false;

	protected boolean iconSectionExpandFlag = false;

	protected boolean fullDescOn = true;

	protected boolean keyConsiderationOn = true;

	protected boolean briefDescOn = true;

	protected boolean elementTypeOn = false;

	protected boolean contentFieldOn = false;

	protected boolean versionSectionOn = true;

	protected boolean anyAttributeModified = false;

	protected boolean generalSectionOn = true;

	protected boolean notationSectionOn = false;

	protected boolean detailSectionOn = true;

	protected boolean tailoringSectionOn = false;

	protected boolean variabilitySectionOn = true;
	
	protected boolean slotSectionOn= false;

	protected boolean purposeOn = false;

	protected boolean externalIdOn = false;

	protected boolean iconSectionOn = false;
	
	protected boolean publishCategoryOn = false;
	
	protected boolean publishPracticeOn = false;
	
	protected boolean publishPracticeOnForUDT = false;
	
//	protected boolean publishDeliveableOn = false;
	
	protected boolean longPresentationNameOn = false;

	// Internal IDs for the sections.
	protected static final int GENERAL_SECTION_ID = 1;

	protected static final int DETAIL_SECTION_ID = 2;

	protected static final int VERSION_SECTION_ID = 3;

	protected static final int NOTATION_SECTION_ID = 4;

	protected static final int TAILORING_SECTION_ID = 5;

	private int warningCount = 1;

	private int SECTIONS = 0;

	private static int SHAPEICON_WIDTH_MAX = 32;

	private static int SHAPEICON_HEIGHT_MAX = 32;

	private static int NODEICON_WIDTH_MAX = 16;

	private static int NODEICON_HEIGHT_MAX = 16;

	protected IFilter filter;

	private boolean disposed;

	// To handle the i118n properly and avoid string concatenation.
	public String generalSectionDescription;
	public String detailSectionDescription;
	public String tailoringSectionDescription;
	public String notationSectionDescription;
	public String variabilitySectionDescription;
	public String iconSectionDescription;
	public String versionSectionDescription;

	private Label nodeIconPath;

	private Label shapeIconPath;
	
	private String[] imageTypes = new String[] { "*.gif;*.jpg;*.png;*.ico;*.bmp" }; //$NON-NLS-1$
	private String[] imageNames = new String[] { "Image (gif, jpeg, png, ico, bmp)" }; //$NON-NLS-1$

	/**
	 * Returns the Content filter associated with this page.
	 */
	protected IFilter getFilter() {
		return filter;
	}

	/**
	 * Returns the Content element associated with this page.
	 */
	protected Object getContentElement() {
		return null;
	}

	protected void initContentProviderBase() {
		contentProviderBase = new AdapterFactoryContentProvider(
				TngAdapterFactory.INSTANCE
						.getNavigatorView_ComposedAdapterFactory()) {
			public Object[] getElements(Object object) {
				ArrayList base_selected_list = new ArrayList();
				if (contentElement.getVariabilityBasedOnElement() != null)
					base_selected_list.add(contentElement
							.getVariabilityBasedOnElement());
				return base_selected_list.toArray();
			}

			public void notifyChanged(Notification notification) {
				switch (notification.getFeatureID(VariabilityElement.class)) {
				case UmaPackage.VARIABILITY_ELEMENT__VARIABILITY_BASED_ON_ELEMENT:
					super.notifyChanged(notification);
				}
			}
		};
		base_viewer.setContentProvider(contentProviderBase);
	}

	/**
	 * Creates a new instance.
	 * 
	 * @param editor
	 *            The parent form editor.
	 * @param id
	 *            The unique ID for the form page.
	 * @param title
	 *            The title for the form page.
	 */
	public DescriptionFormPage(FormEditor editor, String id, String title) {
		super(editor, id, title);
	}
	
	private class VariabilityTypeContentProvider extends AdapterFactoryContentProvider {

		private VariabilityType[] types;

		public VariabilityTypeContentProvider(AdapterFactory adapterFactory, VariabilityType[] types) {
			super(adapterFactory);
			this.types = types;
		}
		
		@Override
		public Object[] getElements(Object object) {
			return types;
		}
		
		@Override
		public void notifyChanged(Notification notification) {
			if (notification.getNotifier() == methodElement
					&& notification.getEventType() == Notification.SET
					&& notification.getFeature() == UmaPackage.Literals.VARIABILITY_ELEMENT__VARIABILITY_TYPE) {
				viewer.setSelection(new StructuredSelection(notification.getNewValue()));
			}
		}
	}

	/**
	 * @see org.eclipse.epf.authoring.ui.forms.BaseFormPage#init(org.eclipse.ui.IEditorSite, org.eclipse.ui.IEditorInput)
	 */
	public void init(IEditorSite site, IEditorInput input) {
		super.init(site, input);
		if (AuthoringUIPreferences.getEnableAutoNameGen()) {
			if (AuthoringUIPreferences.getEnableAutoNameGen()) {
				if (LibraryUtil.hasNameTrackPresentationNameMark(methodElement)) {
					setAutoGenName(true);
				}
			}
		}
				
		VariabilityType[] types;
//		if (methodElement instanceof ContentCategory) {
//			types = new VariabilityType[] {
//					VariabilityType.NA,
//					VariabilityType.CONTRIBUTES,
//					VariabilityType.REPLACES,
//					VariabilityType.EXTENDS_REPLACES
//			};
//		} else {
//			types = new VariabilityType[] {
//					VariabilityType.NA,
//					VariabilityType.CONTRIBUTES,
//					VariabilityType.EXTENDS,
//					VariabilityType.REPLACES,
//					VariabilityType.EXTENDS_REPLACES
//			};
//		}
		types = new VariabilityType[] {
				VariabilityType.NA,
				VariabilityType.CONTRIBUTES,
				VariabilityType.EXTENDS,
				VariabilityType.REPLACES,
				VariabilityType.EXTENDS_REPLACES
		};
		contentProviderVariability = new VariabilityTypeContentProvider(
				TngAdapterFactory.INSTANCE
						.getNavigatorView_ComposedAdapterFactory(), types);
	}

	/**
	 * @see org.eclipse.ui.forms.editor.createFormContent(IManagedForm)
	 */
	protected void createFormContent(IManagedForm managedForm) {
		super.createFormContent(managedForm);
		createEditorContent(toolkit);
		setContextHelp();
		setFormTextWithVariableInfo();
		loadData();
		addListeners();
	}
	
	private void setFormTextWithVariableInfo() {
		UIHelper.setFormText(form, methodElement);
	}

	/**
	 * @deprecated
	 * @see TngUtil#getLabel Code moved to TngUtil.getLabel(below more specific
	 *      method)returns label with variabilityInfo
	 *      <code>TngUtil.getLabel(VariabilityElement object, String alternativeLabel, boolean preferBase)</code>
	 * 
	 */
	public String getLabel(VariabilityElement object, String alternativeLabel,
			boolean preferBase) {
		String label = TngUtil.getLabel(object, alternativeLabel);
		if (preferBase && object.getVariabilityBasedOnElement() != null) {
			VariabilityType type = object.getVariabilityType();
			String variabilityTxt = null;
			if (type == VariabilityType.CONTRIBUTES) {
				variabilityTxt = AuthoringUIResources
						.contributes_to_text; 
			} else if (type == VariabilityType.LOCAL_CONTRIBUTION) {
				variabilityTxt = AuthoringUIResources
					.localContributes_text; 			
			} else if (type == VariabilityType.EXTENDS) {					
				variabilityTxt = AuthoringUIResources
						.extends_text;
			} else if (type == VariabilityType.REPLACES) {
				variabilityTxt = AuthoringUIResources
						.replaces_text; 
			} else if (type == VariabilityType.LOCAL_REPLACEMENT) {
				variabilityTxt = AuthoringUIResources
						.localReplaces_text; 
			} else if (type == VariabilityType.EXTENDS_REPLACES) {
				variabilityTxt = AuthoringUIResources
				.extendsReplaces_text; 
			}
			if (variabilityTxt != null) {
				StringBuffer strBuf = new StringBuffer(label)
						.append(" (").append(variabilityTxt).append(" '") //$NON-NLS-1$ //$NON-NLS-2$
						.append(
								TngUtil.getLabel(object
										.getVariabilityBasedOnElement(),
										alternativeLabel)).append("'"); //$NON-NLS-1$
				MethodPlugin basePlugin = UmaUtil.getMethodPlugin(object
						.getVariabilityBasedOnElement());
				if (basePlugin != null) {
					strBuf
							.append(" in '").append(basePlugin.getName()).append("')"); //$NON-NLS-1$ //$NON-NLS-2$
				}
				label = strBuf.toString();
			}
		}

		return label;
	}

	/**
	 * Creates the editor tab content
	 * 
	 * @param toolkit
	 *            The form toolkit.
	 */
	protected void createEditorContent(FormToolkit toolkit) {
		createFormComposites(toolkit);
		loadSectionDescription();
		
		// check for extension section if any
		loadSectionProviders();
		
		// Create the General section.
		if (generalSectionOn) {
			createGeneralSection(toolkit);
			toolkit.paintBordersFor(generalComposite);
			SECTIONS++;
		}

		for (int i = 0; i < sectionProviders.size(); i++) {
			try {
				Object provider  = sectionProviders.get(i);
				if (provider instanceof ISectionProvider) {
					((ISectionProvider) provider).createSection(
							(MethodElementEditor) getEditor(), toolkit,
							sectionComposite);
					SECTIONS++;
				}
			} catch (Exception e) {
				AuthoringUIPlugin.getDefault().getLogger().logError(e);
			}
		}
		
		// Create the Slot Section
		if (slotSectionOn) {
			createSlotSection(toolkit);
			SECTIONS++;
		}
		
		// Create the Detail section.
		if (detailSectionOn) {
			createDetailSection(toolkit);
			SECTIONS++;
		}

		// Create the Notation section.
		if (notationSectionOn) {
			createNotationSection(toolkit);
			SECTIONS++;
		}

		// Create the Tailoring Section.
		if (tailoringSectionOn) {
			createTailoringSection(toolkit);
			SECTIONS++;
		}

		// Create the Version section.
		if (versionSectionOn) {
			createVersionSection(toolkit);
			createVersionSectionContent();
			toolkit.paintBordersFor(versionComposite);
			SECTIONS++;
		}		
		
		if (variabilitySectionOn) {
			createVariabilitySection(toolkit);
			toolkit.paintBordersFor(variabilityComposite);
			SECTIONS++;
		}
		
		// Icon Section
		if (iconSectionOn) {
			createIconSection(toolkit);
			createIconSectionContent();
			SECTIONS++;
		}

		if (expandedComposite != null)
			toolkit.paintBordersFor(expandedComposite);
	}

	
	/** 
	 * Get all section providers
	 * @return
	 */
	private List<ISectionProvider> loadSectionProviders() {
		if (sectionProviders == null) {
			sectionProviders = ExtensionManager.getExtensions(AuthoringUIPlugin.getDefault().getId(), "descriptionPageSectionProvider", ISectionProvider.class); //$NON-NLS-1$	
		}
		return sectionProviders;
	}
	
	private void createFormComposites(FormToolkit toolkit) {
		// Create the main section (used for swapping display of
		// sectionComposite and expandedComposite).
		formSection = toolkit.createSection(form.getBody(), Section.NO_TITLE);
		{
			TableWrapData td = new TableWrapData(TableWrapData.FILL_GRAB);
			formSection.setLayoutData(td);
			formSection.setLayout(new TableWrapLayout());
		}

		// Create the composite for the sections.
		mainComposite = toolkit.createComposite(formSection, SWT.NONE);
		{
			TableWrapData td = new TableWrapData(TableWrapData.FILL_GRAB);
			mainComposite.setLayoutData(td);
			FormLayout layout = new FormLayout();
			layout.marginHeight = 0;
			layout.marginWidth = 0;
			mainComposite.setLayout( layout);
			formSection.setClient(mainComposite);
		}
		
	
		// check for extenstion point and add the page if there
		List<?> columnProviders = DescriptionPageColumnProvider.getInstance()
				.getColumnProviders();

		if (columnProviders == null || columnProviders.size() == 0) {
			createSectionComposite(mainComposite, 0, 100);
		} else {
			try {
				for (int i = 0; i < columnProviders.size(); i++) {
					ColumnElement column = (ColumnElement) columnProviders.get(i);
					Object providerClass = column.getContributorClass();
					int width = column.getWidth();
					String alignment = column.getAlignment();
					
					if (providerClass instanceof IColumnProvider) {
						columnProvider = (IColumnProvider) providerClass;
						
						if (alignment.equals("left")) {	//$NON-NLS-1$	
							createSectionComposite(mainComposite, width,
									100);

							Composite columnComposite = columnProvider
									.setColumn((MethodElementEditor) getEditor(), toolkit, mainComposite);
							{							
								FormData data = new FormData();
								data.top = new FormAttachment(0, 0);
								data.left = new FormAttachment(0, 5);
								data.bottom = new FormAttachment(100, -5);
								data.right = new FormAttachment(
										sectionComposite, 0);
								columnComposite.setLayoutData(data);
								GridLayout layout = new GridLayout();
								layout.marginHeight = 0;
								columnComposite.setLayout(layout);
							}						
						}
						if (alignment.equals("right")) { //$NON-NLS-1$	
							createSectionComposite(mainComposite, 0,
									100 - width);

							Composite columnComposite = columnProvider
									.setColumn((MethodElementEditor) getEditor(), toolkit, mainComposite);
							{	
								FormData data = new FormData();
								data.top = new FormAttachment(0, 0);
								data.left = new FormAttachment(
										sectionComposite, 5);
								data.bottom = new FormAttachment(100, -5);
								data.right = new FormAttachment(100, 0);
								columnComposite.setLayoutData(data);
								GridLayout layout = new GridLayout();
								layout.marginHeight = 0;
								columnComposite.setLayout(layout);
							}
						}
					}
				}
			} catch (Exception e) {
				AuthoringUIPlugin.getDefault().getLogger().logError(e);
			}
		}

		// Create the composite for the RichTextEditor.
		expandedComposite = toolkit.createComposite(formSection, SWT.NONE);
		{
			TableWrapData td = new TableWrapData(TableWrapData.FILL_GRAB);
			expandedComposite.setLayoutData(td);
			expandedComposite.setLayout(new GridLayout(2, false));
			expandedComposite.setVisible(false);
		}

		// Add the expand/collapse hyperlink image.
		expandLink = toolkit.createImageHyperlink(expandedComposite, SWT.NONE);
		expandLink.setImage(AuthoringUIImages.IMG_EXPANDED);
		expandLink.setToolTipText(AuthoringUIResources.closeRTE);
		expandLink.setUnderlined(false);
		expandLink.addHyperlinkListener(new HyperlinkAdapter() {
			public void linkActivated(HyperlinkEvent e) {
				toggle(e);
			}
		});

		// Add the expand/collapse hyperlink text.
		expandLabel = createDecoratedLabel(toolkit, expandedComposite, ""); //$NON-NLS-1$
	}

	/**
	 * Creates EPF Main section composite where all general, detail section resides
	 */
	private void createSectionComposite(Composite parent, int leftMargin,
			int rightMargin) {
		// Create the composite for the sections.
		sectionComposite = toolkit.createComposite(parent, SWT.NONE);
		{
			FormData data = new FormData();
			data.top = new FormAttachment(0, 0);
			data.left = new FormAttachment(leftMargin, 0);
			data.bottom = new FormAttachment(100, -5);
			data.right = new FormAttachment(rightMargin, -5);
			sectionComposite.setLayoutData(data);
			GridLayout layout = new GridLayout();
			layout.marginHeight = 0;
			sectionComposite.setLayout(layout);
		}
	}
	
	/**
	 * Creates the General section.
	 */
	protected void createGeneralSection(FormToolkit toolkit) {
		generalSection = createSection(toolkit, sectionComposite,
				AuthoringUIText.GENERAL_INFO_SECTION_NAME,
				getGeneralSectionDescription());
		generalComposite = createComposite(toolkit, generalSection);
		((GridLayout) generalComposite.getLayout()).numColumns = 4;
		createGeneralSectionContent();
	}

	/**
	 * Creates the General section content.
	 */
	protected void createGeneralSectionContent() {
		// Add the Name label and text control.
		ctrl_name = createTextEditWithLabel3(toolkit, generalComposite,
				AuthoringUIText.NAME_TEXT, SWT.DEFAULT, SWT.SINGLE);

		// Add the Presentation name label and text control.
		ctrl_presentation_name = createTextEditWithLabel3(toolkit,
				generalComposite, AuthoringUIText.PRESENTATION_NAME_TEXT,
				SWT.DEFAULT, SWT.SINGLE);
		
		// Add long  presentation name lable and text control
		
		if (longPresentationNameOn && AuthoringUIPreferences.getEnableUIFields()) {
			ctrl_long_presentation_name = createTextEditWithLabel3(toolkit,
					generalComposite, AuthoringUIText.LONG_PRESENTATION_NAME_TEXT,
					SWT.DEFAULT, SWT.SINGLE);
		}

		if (elementTypeOn) {
			createLabel(toolkit, generalComposite, AuthoringUIText.TYPE_TEXT, 2);
			ctrl_type_label = createLabel(toolkit, generalComposite, ""); //$NON-NLS-1$
			{
				GridData gridData = new GridData(GridData.BEGINNING);
				gridData.horizontalSpan = 1;
				ctrl_type_label.setBackground(Display.getCurrent()
						.getSystemColor(19));
				ctrl_type_label.setLayoutData(gridData);
			}
			if (methodElement instanceof Guidance) {
				ctrl_type_button = toolkit.createButton(generalComposite,
						AuthoringUIText.CHANGE_TYPE_BUTTON_TEXT, SWT.PUSH);
				{
					GridData gridData = new GridData(GridData.BEGINNING);
					gridData.horizontalSpan = 1;
					ctrl_type_button.setLayoutData(gridData);
				}
				if (ConvertGuidanceType
						.getValidNewGuidanceTypes((Guidance) methodElement) == null) {
					ctrl_type_button.setVisible(false);
				}
			}
		}

		if (externalIdOn && AuthoringUIPreferences.getEnableUIFields()) {
			ctrl_external_id = createTextEditWithLabel3(toolkit,
					generalComposite, AuthoringUIText.EXTERNAL_ID_TEXT,
					SWT.DEFAULT, SWT.SINGLE);
		}

		if (briefDescOn) {
			ctrl_brief_desc = createTextEditWithLabel3(toolkit,
					generalComposite, AuthoringUIText.BRIEF_DESCRIPTION_TEXT,
					40, SWT.MULTI | SWT.TRAVERSE_TAB_NEXT);
		}		

		String publishButtonText = AuthoringUIText.PUBLISH_CATEGORIES_TEXT;
		if (! publishCategoryOn) {
			publishCategoryOn = publishPracticeOn;
			if (publishPracticeOn) {
				publishButtonText = AuthoringUIText.PUBLISH_PRACTICES_TEXT;
				if (publishPracticeOnForUDT) {
					// TODO_translation: to avoid new translation, use the new string in English, otherwise use the old one
					// if (publishButtonText.startsWith("Publish back links to this practice from its contained elements"))	//$NON-NLS-1$
						publishButtonText = AuthoringUIText.PUBLISH_PRACTICES_FOR_UDT_TEXT;
				}
			}
		}
		
		if (publishCategoryOn) {
			ctrl_publish_categories_button = toolkit
			.createButton(
					generalComposite,
					publishButtonText, SWT.CHECK); 
			GridData data = new GridData();
			data.horizontalSpan = 3;
			ctrl_publish_categories_button.setLayoutData(data);
		}
	}

	/**
	 * Creates the Content Variability section.
	 */
	protected void createVariabilitySection(FormToolkit toolkit) {
		variabilitySection = createSection(toolkit, sectionComposite,
				AuthoringUIText.VARIABILITY_SECTION_NAME,
				getVariabilitySectionDescription());
		
		variabilityComposite = toolkit.createComposite(variabilitySection);
		{
			GridData gridData = new GridData(GridData.FILL_HORIZONTAL | GridData.BEGINNING | GridData.GRAB_HORIZONTAL);
			gridData.horizontalSpan = 1;
			gridData.heightHint = 24;
			gridData.widthHint = 300;
			variabilityComposite.setLayoutData(gridData);
		}
		variabilityComposite.setLayout(new GridLayout(5, false));
		variabilitySection.setClient(variabilityComposite);

		ctrl_variability = createComboWithLabel3(toolkit, variabilityComposite,
				AuthoringUIText.VARIABILITY_TYPE_TEXT);

		viewer_variability = new ComboViewer(ctrl_variability);
		{
			GridData gridData = new GridData(GridData.FILL_HORIZONTAL | GridData.BEGINNING | GridData.GRAB_HORIZONTAL);
			gridData.horizontalSpan = 2;
			gridData.heightHint = 24;
			gridData.widthHint = 300;
			viewer_variability.getCombo().setLayoutData(gridData);
		}
		viewer_variability.setContentProvider(contentProviderVariability);
		viewer_variability.setLabelProvider(labelProviderVariability);
		viewer_variability.setInput(methodElement);

		toolkit.createLabel(variabilityComposite, "", SWT.NONE); //$NON-NLS-1$

		//String baseElement = LibraryUIText.getUITextLower(methodElement);
		label_base = createLabel(toolkit, variabilityComposite,
				AuthoringUIText.BASE_ELEMENT_TEXT, 2);
		ctrl_base = createTable(toolkit, variabilityComposite, SWT.SINGLE
				| SWT.READ_ONLY, GridData.FILL_HORIZONTAL | GridData.BEGINNING, 5, 300, 1, 2);
		{
			GridData gridData = new GridData(GridData.FILL_HORIZONTAL | GridData.BEGINNING);
			gridData.horizontalSpan = 2;
			gridData.heightHint = 24;
			gridData.widthHint = 300;
			ctrl_base.setLayoutData(gridData);
		}

		base_viewer = new TableViewer(ctrl_base);
		initContentProviderBase();
		base_viewer.setLabelProvider(labelProviderBase);
		base_viewer.setInput(methodElement);

		Composite baseButtonPane = createComposite(toolkit, variabilityComposite, 
				GridData.HORIZONTAL_ALIGN_FILL | GridData.VERTICAL_ALIGN_BEGINNING, 1, 1, 1);
		{
			GridData gridData = new GridData(GridData.HORIZONTAL_ALIGN_FILL);
			baseButtonPane.setLayoutData(gridData);
		}
		ctrl_base_button = toolkit.createButton(baseButtonPane,
				AuthoringUIText.SELECT_BUTTON_TEXT, SWT.SIMPLE);
		{
			GridData gridData = new GridData(GridData.FILL_HORIZONTAL);
			gridData.widthHint = BUTTON_WIDTH;
			ctrl_base_button.setLayoutData(gridData);
		}

		// Set focus on the Name text control.
		Display display = form.getBody().getDisplay();
		if (!(display == null || display.isDisposed())) {
			display.asyncExec(new Runnable() {
				public void run() {
					if(ctrl_name.isDisposed()) return;
					
					if (isAutoGenName()) {
						ctrl_presentation_name.setFocus();
						if (methodUnit != null && methodUnit.getChangeDate() == null)
							ctrl_presentation_name.setSelection(0, ctrl_presentation_name.getText().length());
					} else {
						ctrl_name.setFocus();
						if (methodUnit != null && methodUnit.getChangeDate() == null)
							ctrl_name.setSelection(0, ctrl_name.getText().length());
					}
					
				}
			});
		}
	}

	protected void refresh(boolean editable) {
		ctrl_name.setEditable(editable);
		ctrl_presentation_name.setEditable(editable);
		if (longPresentationNameOn && AuthoringUIPreferences.getEnableUIFields()) {
			ctrl_long_presentation_name.setEditable(editable);
		}

		if (briefDescOn) {
			ctrl_brief_desc.setEditable(editable);
		}
		if (purposeOn) {
			ctrl_purpose.setEditable(editable);
		}
		if (fullDescOn) {
			ctrl_full_desc.setEditable(editable);
		}
		if (keyConsiderationOn) {
			ctrl_key.setEditable(editable);
		}
		if (externalIdOn && AuthoringUIPreferences.getEnableUIFields()) {
			ctrl_external_id.setEditable(editable);
		}
		if (elementTypeOn) {
			ctrl_type_button.setEnabled(editable);
		}
		if (variabilitySectionOn) {
			ctrl_variability.setEnabled(editable);
			ctrl_base_button.setEnabled(editable);
			if (((IStructuredSelection) viewer_variability.getSelection())
					.getFirstElement() == VariabilityType.NA) {
				ctrl_base_button.setEnabled(false);
			}
			
			if (((IStructuredSelection) viewer_variability.getSelection())
					.getFirstElement() == VariabilityType.CONTRIBUTES) {
				ctrl_presentation_name.setEditable(false);
				if (externalIdOn && AuthoringUIPreferences.getEnableUIFields()) {
					ctrl_external_id.setEditable(false);
				}
			}
		}
		if (versionSectionOn) {
			ctrl_change_date.setEditable(false);
			ctrl_change_desc.setEditable(editable);
			ctrl_authors.setEditable(editable);
			ctrl_version.setEditable(editable);
			copyright_button.setEnabled(editable);
			setCopyrightButtonDeselect();
		}
		if (iconSectionOn) {
			ctrl_select_shapeIcon_button.setEnabled(editable);
			ctrl_clear_shapeIcon_button.setEnabled(editable
					&& contentElement.getShapeicon() != null);
			ctrl_select_nodeIcon_button.setEnabled(editable);
			ctrl_clear_nodeIcon_button.setEnabled(editable
					&& contentElement.getNodeicon() != null);
		}
		if (ctrl_expanded != null) {
			ctrl_expanded.setEditable(editable);
		}
		
		if (publishCategoryOn) {
			ctrl_publish_categories_button.setEnabled(editable);
		}
		if (editable) {
			refreshForContributor();
		}
		if (columnProvider != null)
			columnProvider.refresh(editable);
		
		for (int i = 0; i < sectionProviders.size(); i++) {
			Object provider = sectionProviders.get(i);
			if (provider != null && provider instanceof ISectionProvider) {
				((ISectionProvider) provider).refresh(editable);
			}
		}
			
	}

	/**
	 * Create the Detail section.
	 */
	protected void createDetailSection(FormToolkit toolkit) {
		detailSection = createSection(toolkit, sectionComposite,
				AuthoringUIText.DETAIL_SECTION_NAME,
				getDetailSectionDescription());
		detailComposite = createComposite(toolkit, detailSection);
		createDetailSectionContent();
		toolkit.paintBordersFor(detailComposite);
	}

	/**
	 * Creates the Detail section content.
	 */
	protected void createDetailSectionContent() {
		if (purposeOn) {
			ctrl_purpose = createRichTextEditWithLinkForSection(toolkit,
					detailComposite, AuthoringUIText.PURPOSE_TEXT, 40, 400,
					DETAIL_SECTION_ID);
		}

		if (fullDescOn) {
			ctrl_full_desc = createRichTextEditWithLinkForSection(toolkit,
					detailComposite, AuthoringUIText.MAIN_DESCRIPTION_TEXT,
					100, 400, DETAIL_SECTION_ID);

		}

		if (keyConsiderationOn) {
			ctrl_key = createRichTextEditWithLinkForSection(toolkit,
					detailComposite, AuthoringUIText.KEY_CONSIDERATIONS_TEXT,
					40, 400, DETAIL_SECTION_ID);
		}
	}

	/**
	 * Creates the Notation section.
	 */
	protected void createNotationSection(FormToolkit toolkit) {
		notationSection = createSection(toolkit, sectionComposite,
				AuthoringUIText.NOTATION_SECTION_NAME,
				getNotationSectionDescription());
		notationComposite = createComposite(toolkit, notationSection);
		createNotationSectionContent();
		toolkit.paintBordersFor(notationComposite);
	}

	/**
	 * Creates the Notation section content.
	 */
	protected void createNotationSectionContent() {
	}

	/**
	 * Creates the Tailoring section.
	 */
	protected void createTailoringSection(FormToolkit toolkit) {
		tailoringSection = createSection(toolkit, sectionComposite,
				AuthoringUIText.TAILORING_SECTION_NAME,
				getTailoringSectionDescription());
		tailoringComposite = createComposite(toolkit, tailoringSection);
		createTailoringSectionContent();
		toolkit.paintBordersFor(tailoringComposite);

	}

	protected void createTailoringSectionContent() {
	}
	
	/**
	 * Creates the slot section.
	 */
	protected void createSlotSection(FormToolkit toolkit) {

	}

	/**
	 * Add listeners to monitor focus and modification changes in the edit
	 * controls.
	 */
	protected void addListeners() {
		final MethodElementEditor editor = (MethodElementEditor) getEditor();

		modelModifyListener = editor.createModifyListener(methodElement);
		contentModifyListener = editor.createModifyListener(methodUnit);
		actionMgr = editor.getActionManager();
		
		

		form.addControlListener(new ControlListener() {
			public void controlResized(ControlEvent e) {
				if (ctrl_expanded != null) {
					((GridData) ctrl_expanded.getLayoutData()).heightHint = getRichTextEditorHeight();
					((GridData) ctrl_expanded.getLayoutData()).widthHint = getRichTextEditorWidth();
				}
				formSection.layout(true, true);
			}

			public void controlMoved(ControlEvent e) {
			}
		});

		form.getParent().addListener(SWT.Activate, new Listener() {
			public void handleEvent(Event event) {
				if(disposed) {
					return;
				}
				
				refresh(!TngUtil.isLocked(methodElement));
				setFormTextWithVariableInfo();
				
				// do refresh variability and copyright viewer
				if(variabilitySectionOn)
					base_viewer.refresh();
				if(versionSectionOn)
					copyright_viewer.refresh();
			}
		});

		if (generalSectionOn) {
			addGeneralSectionListeners();
		}

		if (detailSectionOn) {
			addDetailSectionListeners();
		}

		if (versionSectionOn) {
			addVersionSectionListeners();
		}

		if (iconSectionOn) {
			addIconSectionListeners();
		}

		if (variabilitySectionOn) {
			viewer_variability
					.addSelectionChangedListener(new ISelectionChangedListener() {
						public void selectionChanged(SelectionChangedEvent event) {
							IStructuredSelection selection = (IStructuredSelection) viewer_variability
									.getSelection();
	
							if (contentElement.getVariabilityBasedOnElement() != null) {
								boolean status = editor
										.getActionManager()
										.doAction(
												IActionManager.SET,
												methodElement,
												UmaPackage.eINSTANCE
														.getVariabilityElement_VariabilityType(),
												(VariabilityType) selection
														.getFirstElement(), -1);
								
								if (!status) {
									return;
								}
								else {
									if (selection.getFirstElement() == VariabilityType.CONTRIBUTES)
										updatePNameForContributor(true);	
									else
										updatePNameForContributor(false);
								}
							}
							if (selection.getFirstElement() == VariabilityType.NA) {
								if (contentElement.getVariabilityBasedOnElement() != null) {
									boolean status = editor
											.getActionManager()
											.doAction(
													IActionManager.SET,
													methodElement,
													UmaPackage.eINSTANCE
															.getVariabilityElement_VariabilityBasedOnElement(),
													null, -1);
									if (!status) {
										return;
									}
								}
								ctrl_base_button.setEnabled(false);
								base_viewer.refresh();
							} else {
								List selectionBaseList = new ArrayList();
								VariabilityElement base = contentElement
										.getVariabilityBasedOnElement();
								selectionBaseList.add(base);
								ctrl_base_button.setEnabled(true);
								base_viewer.refresh();
							}
							setFormTextWithVariableInfo();
							
							for (int i = 0; i < sectionProviders.size(); i++) {
								Object provider = sectionProviders.get(i);
								if (provider != null && provider instanceof ISectionProvider) {
									((ISectionProvider) provider).refresh(false);
								}
							}
						}
					});
	
			ctrl_base_button.addSelectionListener(new SelectionAdapter() {
				public void widgetSelected(SelectionEvent e) {
					filter = getFilter();
					if (filter != null) {
						ItemsFilterDialog fd = new ItemsFilterDialog(PlatformUI
								.getWorkbench().getActiveWorkbenchWindow()
								.getShell(), filter, getContentElement(),
								LibraryUIText.getUIText(methodElement, true));
						fd.setViewerSelectionSingle(true);
						fd.setBlockOnOpen(true);
						fd.setTitle(LibraryUIText.getUIText(methodElement, true));
						fd.open();
						fd.getSelectedItems();
						if (fd.getSelectedItems().size() > 0) {
							IStatus istatus = DependencyChecker.checkCircularDependencyAfterFilterSelection(
									contentElement, (VariabilityElement) fd.getSelectedItems().get(0));
							if(!istatus.isOK()) {
								String title = AuthoringUIResources.variability_error_title;
								AuthoringUIPlugin.getDefault().getMsgDialog().displayError(title, istatus.getMessage());						
								return;
							}
							boolean status = editor
									.getActionManager()
									.doAction(
											IActionManager.SET,
											methodElement,
											UmaPackage.eINSTANCE
													.getVariabilityElement_VariabilityBasedOnElement(),
											(VariabilityElement) fd
													.getSelectedItems().get(0), -1);
							if (!status) {
								return;
							}
							status = editor
									.getActionManager()
									.doAction(
											IActionManager.SET,
											methodElement,
											UmaPackage.eINSTANCE
													.getVariabilityElement_VariabilityType(),
											(VariabilityType) ((IStructuredSelection) viewer_variability
													.getSelection())
													.getFirstElement(), -1);
							if (status) {
								if ((VariabilityType) ((IStructuredSelection) viewer_variability
										.getSelection()).getFirstElement() == VariabilityType.CONTRIBUTES)
									updatePNameForContributor(true);	
								else
									updatePNameForContributor(false);
							}
						}
					}
					setFormTextWithVariableInfo();
					
					for (int i = 0; i < sectionProviders.size(); i++) {
						Object provider = sectionProviders.get(i);
						if (provider != null && provider instanceof ISectionProvider) {
							((ISectionProvider) provider).refresh(false);
						}
					}
					if ((ctrl_base != null) && (!(ctrl_base.isDisposed())))
						ctrl_base.redraw();
					if ((base_viewer != null)
							&& (!(base_viewer.getControl().isDisposed())))
						base_viewer.refresh();
				}
			});
		}
	}

	private void updatePNameForContributor(boolean update) {
		// final MethodElementEditor editor = (MethodElementEditor) getEditor();

		final MethodElementEditor editor = (MethodElementEditor) getEditor();

		actionMgr = editor.getActionManager();
		if (contentElement.getVariabilityType() == VariabilityType.CONTRIBUTES) {
			// make presentation name empty
			actionMgr.doAction(IActionManager.SET, methodElement,
					UmaPackage.eINSTANCE.getMethodElement_PresentationName(),
					"", -1); //$NON-NLS-1$
			ctrl_presentation_name.setText(""); //$NON-NLS-1$

			// make external Id empty
			actionMgr.doAction(IActionManager.SET, contentElement
					.getPresentation(), UmaPackage.eINSTANCE
					.getContentDescription_ExternalId(), "", -1); //$NON-NLS-1$
			if (externalIdOn && AuthoringUIPreferences.getEnableUIFields()) {
				ctrl_external_id.setText(""); //$NON-NLS-1$
			}
		}
	
		refreshForContributor();
	}
	
	
	private void refreshForContributor() {
		boolean editable = true;
		ctrl_presentation_name.setEditable(editable);
		if (externalIdOn && AuthoringUIPreferences.getEnableUIFields()) {
			ctrl_external_id.setEditable(editable);
		}
		
		if (contentElement != null
				&& (contentElement.getVariabilityType() == VariabilityType.CONTRIBUTES)) {	
			if (contentElement.getPresentationName().equals("")) { //$NON-NLS-1$
				ctrl_presentation_name.setEditable(false);
			}
			if (externalIdOn && AuthoringUIPreferences.getEnableUIFields()) {
				if (contentElement.getPresentation().getExternalId().equals("")) { //$NON-NLS-1$
					ctrl_external_id.setEditable(false);
				}
			}
		}
	}
	
	protected ModifyListener newNameTackingPNameListener() {
		ModifyListener ret = new ModifyListener() {
			public void modifyText(ModifyEvent e) {
				if (isAutoGenName()) {
					String name = generateName(ctrl_presentation_name.getText());
					if (name.length() > 0) {
						ctrl_name.setText(name);
					}
				}
			}
		};
		
		return ret;
	}
	
	protected void addGeneralSectionListeners() {
		ctrl_name.addModifyListener(modelModifyListener);
		ctrl_name.addFocusListener(nameFocusListener);

		ctrl_presentation_name.addModifyListener(modelModifyListener);
		ctrl_presentation_name.addModifyListener(newNameTackingPNameListener());
		
		ctrl_presentation_name.addFocusListener(new FocusAdapter() {
			public void focusLost(FocusEvent e) {
				String oldContent = methodElement.getPresentationName();
				if (((MethodElementEditor) getEditor()).mustRestoreValue(
						e.widget, oldContent)) {
					return;
				}
				
				String newContent = StrUtil.getPlainText(ctrl_presentation_name
						.getText());				
				if (!newContent.equals(oldContent)) {
					boolean success = actionMgr.doAction(IActionManager.SET,
							methodElement, UmaPackage.eINSTANCE
									.getMethodElement_PresentationName(),
							newContent, -1);
					if (success) {
						ctrl_presentation_name.setText(newContent);
					}
				}
				// clear the selection when the focus of the component is lost 
				if(ctrl_presentation_name.getSelectionCount() > 0){
					ctrl_presentation_name.clearSelection();
				} 
				if (isAutoGenName()) {
					changeElementName();
				}
			}
			
			/* (non-Javadoc)
			 * @see org.eclipse.swt.events.FocusAdapter#focusGained(org.eclipse.swt.events.FocusEvent)
			 */
			public void focusGained(FocusEvent e) {
				((MethodElementEditor) getEditor()).setCurrentFeatureEditor(e.widget, UmaPackage.eINSTANCE.getMethodElement_PresentationName());
				// when user tab to this field, select all text
				ctrl_presentation_name.selectAll();
			}
		});
		
		if (longPresentationNameOn && AuthoringUIPreferences.getEnableUIFields()) {
			ctrl_long_presentation_name.addModifyListener(modelModifyListener);
			ctrl_long_presentation_name.addFocusListener(new FocusAdapter() {
				public void focusLost(FocusEvent e) {
					String oldContent = contentElement.getPresentation().getLongPresentationName();
					if (((MethodElementEditor) getEditor()).mustRestoreValue(
							ctrl_long_presentation_name, oldContent)) {
						return;
					}
					
					String newContent = StrUtil.getPlainText(ctrl_long_presentation_name
							.getText());				
					if (!newContent.equals(oldContent)) {
						boolean success = actionMgr.doAction(IActionManager.SET,
								contentElement.getPresentation(), UmaPackage.eINSTANCE
										.getContentDescription_LongPresentationName(),
								newContent, -1);
						if (success) {
							ctrl_long_presentation_name.setText(newContent);
						}
					}
					// clear the selection when the focus of the component is lost 
					if(ctrl_long_presentation_name.getSelectionCount() > 0){
						ctrl_long_presentation_name.clearSelection();
					}    
				}
				
				/* (non-Javadoc)
				 * @see org.eclipse.swt.events.FocusAdapter#focusGained(org.eclipse.swt.events.FocusEvent)
				 */
				public void focusGained(FocusEvent e) {
					// when user tab to this field, select all text
					ctrl_long_presentation_name.selectAll();
					((MethodElementEditor) getEditor())
					.setCurrentFeatureEditor(e.widget,
							UmaPackage.eINSTANCE
									.getContentDescription_LongPresentationName());
				}
			});
		}

		if (briefDescOn) {
			ctrl_brief_desc.addModifyListener(modelModifyListener);
			ctrl_brief_desc.addFocusListener(new FocusAdapter() {
				public void focusGained(FocusEvent e) {
					((MethodElementEditor) getEditor()).setCurrentFeatureEditor(e.widget,
							UmaPackage.eINSTANCE.getMethodElement_BriefDescription());
				}

				/* (non-Javadoc)
				 * @see org.eclipse.swt.events.FocusAdapter#focusLost(org.eclipse.swt.events.FocusEvent)
				 */
				public void focusLost(FocusEvent e) {
					String oldContent = methodElement.getBriefDescription();
					if (((MethodElementEditor) getEditor()).mustRestoreValue(
							e.widget, oldContent)) {
						return;
					}
					String newContent = ctrl_brief_desc.getText();
					if (!newContent.equals(oldContent)) {
						boolean success = actionMgr.doAction(
								IActionManager.SET, methodElement,
								UmaPackage.eINSTANCE
										.getMethodElement_BriefDescription(),
								newContent, -1);
						if (success) {
							ctrl_brief_desc.setText(newContent);
						}
					}
				}
			});
		}

		if (elementTypeOn) {
			if (methodElement instanceof Guidance) {
				ctrl_type_button.addListener(SWT.Selection, new Listener() {
					public void handleEvent(Event event) {
						final MethodElementEditor editor = (MethodElementEditor) getEditor();
						if (editor.isDirty()) {
							String title = AuthoringUIResources.descriptionTabGuidanceWarningDialog_title; 
							String message = AuthoringUIResources.descriptionTabGuidanceWarningDialog_message1; 
							AuthoringUIPlugin.getDefault().getMsgDialog()
									.displayWarning(title, message);
						} else if (methodElement instanceof Guidance) {
							MethodElementDeleteAction deleteAction = new MethodElementDeleteAction();
							deleteAction.setEditingDomain(LibraryView.getView()
									.getEditingDomain());
							deleteAction
									.selectionChanged(new StructuredSelection(
											methodElement));
							Command cmd = deleteAction
									.createCommand(Collections
											.singleton(methodElement));
							if (cmd instanceof DeleteMethodElementCommand) {
								Guidance newGuidance;
								try {
									newGuidance = ConvertGuidanceType
										.convertGuidance(
												(Guidance) methodElement,
												null,
												(DeleteMethodElementCommand) cmd);
								}
								finally {
									try { cmd.dispose(); } catch(Exception e) {}
								}
								if (newGuidance != null) {
									EditorChooser.getInstance().closeEditor(
											methodElement);
									EditorChooser.getInstance().openEditor(
											newGuidance);
								}
							}
						} else if (editor.isDirty()) {
							String title = AuthoringUIResources.descriptionTabGuidanceWarningDialog_title; 
							String message = AuthoringUIResources.descriptionTabGuidanceWarningDialog_message2; 
							AuthoringUIPlugin.getDefault().getMsgDialog()
									.displayWarning(title, message);
						}
					}
				});
			}
		}
		
		if (publishCategoryOn) {
			ctrl_publish_categories_button.addSelectionListener(new SelectionAdapter() {
				public void widgetSelected(SelectionEvent e) {
					String val = new Boolean(ctrl_publish_categories_button.getSelection()).toString();
					MethodElementProperty prop = TngUtil.getPublishCategoryProperty(methodElement);

					if (prop == null) {
						prop = UmaFactory.eINSTANCE.createMethodElementProperty();
						prop.setName(TngUtil.PUBLISH_CATEGORY_PROPERTY);
						prop.setValue(val);
						actionMgr.doAction(IActionManager.ADD,
										methodElement,
										UmaPackage.eINSTANCE.getMethodElement_MethodElementProperty(),
										prop, -1);
					} else {
						actionMgr.doAction(IActionManager.SET,
										prop,
										UmaPackage.eINSTANCE.getMethodElementProperty_Value(),
										val, -1);
					}
				}
			});
		}
		
		if (externalIdOn && AuthoringUIPreferences.getEnableUIFields()) {
			ctrl_external_id.addModifyListener(contentModifyListener);
			ctrl_external_id.addFocusListener(new FocusAdapter() {
				public void focusGained(FocusEvent e) {
					((MethodElementEditor) getEditor())
							.setCurrentFeatureEditor(e.widget,
									UmaPackage.eINSTANCE
											.getContentDescription_ExternalId());
				}

				public void focusLost(FocusEvent e) {
					String oldContent =  contentElement.getPresentation().getExternalId();
					if (((MethodElementEditor) getEditor()).mustRestoreValue(
							ctrl_external_id, oldContent)) {
						return;
					}
					String newContent = ctrl_external_id.getText();
					if (!newContent.equals(oldContent)) {
						boolean success = actionMgr.doAction(
								IActionManager.SET, contentElement
										.getPresentation(),
								UmaPackage.eINSTANCE
										.getContentDescription_ExternalId(),
								newContent, -1);
						if (success && isVersionSectionOn()) {
							updateChangeDate();
						}
					}
				}
			});
		}
	}

	protected IValidator getNameValidator() {
		return null;
	}

	private void addDetailSectionListeners() {
		if (fullDescOn) {
			ctrl_full_desc.setModalObject(contentElement.getPresentation());
			ctrl_full_desc.setModalObjectFeature(UmaPackage.eINSTANCE
					.getContentDescription_MainDescription());
			ctrl_full_desc.addModifyListener(contentModifyListener);
			ctrl_full_desc.addListener(SWT.Deactivate, new Listener() {
				public void handleEvent(Event e) {
					IMethodRichText control = descExpandFlag ? ctrl_expanded
							: ctrl_full_desc;
					if (debug) {
						System.out
								.println("DescriptionFormPage.ctrl_full_desc.deactivateListener: control=" + control); //$NON-NLS-1$
					}
					if (!control.getModified()) {
						if (debug) {
							System.out
									.println("DescriptionFormPage.ctrl_full_desc.deactivateListener: content not modified, exit"); //$NON-NLS-1$
						}
						return;
					}
					String oldContent = contentElement.getPresentation()
							.getMainDescription();
					if (((MethodElementEditor) getEditor()).mustRestoreValue(
							control, oldContent)) {
						if (debug) {
							System.out
									.println("DescriptionFormPage.ctrl_full_desc.deactivateListener: restored old content, exit"); //$NON-NLS-1$
						}
						return;
					}
					String newContent = control.getText();
					if (!newContent.equals(oldContent)) {
						if (debug) {
							System.out
									.println("DescriptionFormPage.ctrl_full_desc.deactivateListener: saving modified content"); //$NON-NLS-1$
						}
						boolean success = actionMgr
								.doAction(
										IActionManager.SET,
										contentElement.getPresentation(),
										UmaPackage.eINSTANCE
												.getContentDescription_MainDescription(),
										newContent, -1);
						if (debug) {
							System.out
									.println("DescriptionFormPage.ctrl_full_desc.deactivateListener: saved status=" + success); //$NON-NLS-1$
						}
						if (success && isVersionSectionOn()) {
							updateChangeDate();
						}
					}
					if (debug) {
						System.out
								.println("DescriptionFormPage.ctrl_full_desc.deactivateListener: exit"); //$NON-NLS-1$
					}
				}
			});
		}

		if (keyConsiderationOn) {
			ctrl_key.setModalObject(contentElement.getPresentation());
			ctrl_key.setModalObjectFeature(UmaPackage.eINSTANCE
					.getContentDescription_KeyConsiderations());
			ctrl_key.addModifyListener(contentModifyListener);
			ctrl_key.addListener(SWT.Deactivate, new Listener() {
				public void handleEvent(Event e) {
					IMethodRichText control = descExpandFlag ? ctrl_expanded
							: ctrl_key;
					if (debug) {
						System.out
								.println("DescriptionFormPage.ctrl_key.deactivateListener: control=" + control); //$NON-NLS-1$
					}
					if (!control.getModified()) {
						if (debug) {
							System.out
									.println("DescriptionFormPage.ctrl_key.deactivateListener: content not modified, exit"); //$NON-NLS-1$
						}
						return;
					}
					String oldContent = contentElement.getPresentation()
							.getKeyConsiderations();
					if (((MethodElementEditor) getEditor()).mustRestoreValue(
							control, oldContent)) {
						if (debug) {
							System.out
									.println("DescriptionFormPage.ctrl_key.deactivateListener: restored old content, exit"); //$NON-NLS-1$
						}
						return;
					}
					String newContent = control.getText();
					if (!newContent.equals(oldContent)) {
						boolean success = actionMgr
								.doAction(
										IActionManager.SET,
										contentElement.getPresentation(),
										UmaPackage.eINSTANCE
												.getContentDescription_KeyConsiderations(),
										newContent, -1);
						if (debug) {
							System.out
									.println("DescriptionFormPage.ctrl_key.deactivateListener: saved status=" + success); //$NON-NLS-1$
						}
						if (success && isVersionSectionOn()) {
							updateChangeDate();
						}
					}
					if (debug) {
						System.out
								.println("DescriptionFormPage.ctrl_key.deactivateListener: exit"); //$NON-NLS-1$
					}
				}
			});
		}
	}

	/**
	 * Initializes the controls with data from the model.
	 */
	protected void loadData() {
		if (generalSectionOn) {
			loadGeneralSectionData();
		}
		if (detailSectionOn) {
			loadDetailSectionData();
		}
		if (notationSectionOn) {
			loadNotationSectionData();
		}
		if (tailoringSectionOn) {
			loadTailoringSectionData();
		}
		if (versionSectionOn) {
			loadVersionSectionData();
		}
		if (iconSectionOn) {
			loadIconSectionData();
		}
		if (variabilitySectionOn) {
			variabilitySectionData();
		}
		form.getBody().layout(true, true);
	}

	protected void loadGeneralSectionData() {
		String name = methodElement.getName();
		String presentationName = (methodElement).getPresentationName();
		ctrl_name.setText(name == null ? "" : name); //$NON-NLS-1$
		ctrl_presentation_name
				.setText(presentationName == null ? "" : presentationName); //$NON-NLS-1$

		if (longPresentationNameOn && AuthoringUIPreferences.getEnableUIFields()) {
			String longPresentName = contentElement.getPresentation().getLongPresentationName();
			ctrl_long_presentation_name.setText(longPresentName == null ? "" : longPresentName); //$NON-NLS-1$
		}
		if (elementTypeOn) {
			// String type = methodElement.getType().getName();
			String type = LibraryUIText.getUIText(methodElement);
			ctrl_type_label.setText(type == null ? "" : type); //$NON-NLS-1$
		}
		if (briefDescOn) {
			String brief_desc = methodElement.getBriefDescription();
			ctrl_brief_desc.setText(brief_desc == null ? "" : brief_desc); //$NON-NLS-1$
		}
		
		if (externalIdOn && AuthoringUIPreferences.getEnableUIFields()) {
			if (contentElement != null) {
				String external_id = contentElement.getPresentation().getExternalId();
				ctrl_external_id.setText(external_id == null ? "" : external_id); //$NON-NLS-1$
			}
		}
		
		if (publishCategoryOn) {
			MethodElementProperty prop = TngUtil.getPublishCategoryProperty(methodElement);
			if (prop != null) {
				String val = prop.getValue();
				ctrl_publish_categories_button.setSelection((new Boolean(val)).booleanValue());
			}
		}
	}

	private void loadDetailSectionData() {
		if (fullDescOn) {
			String full_desc = (contentElement.getPresentation())
					.getMainDescription();
			ctrl_full_desc.setText(full_desc == null ? "" : full_desc); //$NON-NLS-1$
		}
		if (keyConsiderationOn) {
			String keyConsiderations = (contentElement.getPresentation())
					.getKeyConsiderations();
			ctrl_key
					.setText(keyConsiderations == null ? "" : keyConsiderations); //$NON-NLS-1$
		}
	}
	
	

	private void loadTailoringSectionData() {
	}

	private void loadNotationSectionData() {
	}

	private void variabilitySectionData() {
		VariabilityType variabilityType = contentElement.getVariabilityType();
		List selectionVariabilityList = new ArrayList();
		selectionVariabilityList.add(variabilityType);
		IStructuredSelection newVariabilitySelection = new StructuredSelection(
				selectionVariabilityList);
		viewer_variability.setSelection(newVariabilitySelection, true);
	}

	/**
	 * Toggle Description control to expand and control state.
	 */
	protected void toggle(HyperlinkEvent e) {
		if (ctrl_expanded == null) {
			ctrl_expanded = createRichTextEditor(toolkit, expandedComposite,
					SWT.MULTI | SWT.WRAP | SWT.V_SCROLL, GridData.FILL_BOTH,
					getRichTextEditorHeight(), getRichTextEditorWidth(), 2,
					expandLabel);
			ctrl_expanded.addModifyListener(contentModifyListener);
		}

		if (descExpandFlag) {
			ctrl_expanded.collapse();
			
			expandedComposite.setVisible(false);
			mainComposite.setVisible(true);
			formSection.setClient(mainComposite);
			enableSections(true);
			IMethodRichText richText = getActiveRichTextControl();
			richText.setText(ctrl_expanded.getText());
			richText.setFindReplaceAction(ctrl_expanded.getFindReplaceAction());
			for (Iterator i = richText.getListeners(); i.hasNext();) {
				RichTextListener listener = (RichTextListener) i.next();
				ctrl_expanded.removeListener(listener.getEventType(), listener
						.getListener());
			}
			if (ctrl_expanded.getModified()) {
				((MethodElementEditor) getEditor())
						.saveModifiedRichText(ctrl_expanded);
			}
			richText.setFocus();
			IEditorInput input = getEditorInput();
			if (input instanceof MethodElementEditorInput) {
				((MethodElementEditorInput)input).setModalObject(null);
				((MethodElementEditorInput)input).setModalObjectFeature(null);
			}
		} else {
			mainComposite.setVisible(false);
			expandedComposite.setVisible(true);
			formSection.setClient(expandedComposite);
			enableSections(false);
			expandLabel.setText((String) ((ImageHyperlink) e.getSource())
					.getData("Title")); //$NON-NLS-1$
			IMethodRichText richText = (IMethodRichText) e.getHref();
			ctrl_expanded.setInitialText(richText.getText());
			ctrl_expanded.setModalObject(richText.getModalObject());
			ctrl_expanded.setModalObjectFeature(richText
					.getModalObjectFeature());
			ctrl_expanded.setFindReplaceAction(richText.getFindReplaceAction());
			for (Iterator i = richText.getListeners(); i.hasNext();) {
				RichTextListener listener = (RichTextListener) i.next();
				ctrl_expanded.addListener(listener.getEventType(), listener
						.getListener());
			}
			boolean editable = !TngUtil.isLocked(methodElement);
			ctrl_expanded.setEditable(editable);
			if (editable) {
				ctrl_expanded.setFocus();
			}
			setActiveRichTextControl(richText);
			IEditorInput input = getEditorInput();
			if (input instanceof MethodElementEditorInput) {
				((MethodElementEditorInput)input).setModalObject(richText.getModalObject());
				((MethodElementEditorInput)input).setModalObjectFeature(richText.getModalObjectFeature());
			}
		}
		form.getBody().layout(true, true);
		descExpandFlag = !descExpandFlag;
	}

	/**
	 * Set the active rich text control.
	 */
	private void setActiveRichTextControl(IMethodRichText ctrl) {
		activeControl = ctrl;
	}

	/**
	 * Returns the active rich text control.
	 */
	private IMethodRichText getActiveRichTextControl() {
		return activeControl;
	}

	public void setBriefDescOn(boolean briefDescOn) {
		this.briefDescOn = briefDescOn;
	}
	
	public void setExternalIDOn(boolean exteranlIDOn) {
		this.externalIdOn = exteranlIDOn;
	}
	
	public void setLongPresentationNameOn(boolean longPresentationNameOn) {
		this.longPresentationNameOn = longPresentationNameOn;
	}

	public void setFullDescOn(boolean fullDescOn) {
		this.fullDescOn = fullDescOn;
	}

	public void setKeyConsiderationOn(boolean keyConsiderationOn) {
		this.keyConsiderationOn = keyConsiderationOn;
	}

	/**
	 * @param elementTypeOn
	 *            The elementTypeOn to set.
	 */
	public void setElementTypeOn(boolean elementTypeOn) {
		this.elementTypeOn = elementTypeOn;
	}

	/**
	 * @return Returns the anyAttributeModified.
	 */
	public boolean isAnyAttributeModified() {
		return anyAttributeModified;
	}

	/**
	 * Set this if any attribute is modified. This is required for the change
	 * date field in version section.
	 * 
	 * @param anyAttributeModified
	 *            The anyAttributeModified to set.
	 */
	public void setAnyAttributeModified(boolean anyAttributeModified) {
		this.anyAttributeModified = anyAttributeModified;
	}

	/**
	 * @return Returns the versionSectionOn.
	 */
	public boolean isVersionSectionOn() {
		return versionSectionOn;
	}

	/**
	 * @param versionSectionOn
	 *            The versionSectionOn to set.
	 */
	public void setVersionSectionOn(boolean versionSectionOn) {
		this.versionSectionOn = versionSectionOn;
	}

	/**
	 * Creates the Version Information section.
	 */
	private void createVersionSection(FormToolkit toolkit) {
		versionSection = toolkit.createSection(sectionComposite,
				Section.DESCRIPTION | Section.TWISTIE | Section.EXPANDED
						| Section.TITLE_BAR);
		GridData td = new GridData(GridData.FILL_BOTH);
		versionSection.setLayoutData(td);
		versionSection.setText(AuthoringUIText.VERSION_INFO_SECTION_NAME);
		versionSection.setDescription(getVersionSectionDescription());
		versionSection.setLayout(new GridLayout());

		versionComposite = toolkit.createComposite(versionSection);
		versionComposite.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
		versionComposite.setLayout(new GridLayout(5, false));
		versionSection.setClient(versionComposite);
	}
	
	

	/**
	 * Create the Version section content.
	 */
	protected void createVersionSectionContent() {
		String fillText = (methodUnit.getVersion() == null ? "" : methodUnit.getVersion()); //$NON-NLS-1$
		ctrl_version = createTextEditWithLabel4(toolkit, versionComposite,
				AuthoringUIText.VERSION_TEXT, SWT.DEFAULT, SWT.SINGLE, fillText);

		fillText = methodUnit.getChangeDate() == null ? "" //$NON-NLS-1$
				: DateFormat.getDateInstance(DateFormat.FULL).format(
						methodUnit.getChangeDate());
		ctrl_change_date = createTextEditWithLabel4(toolkit, versionComposite,
				AuthoringUIText.CHANGE_DATE_TEXT, SWT.DEFAULT, SWT.SINGLE, fillText);
		ctrl_change_date.setEditable(false);

		ctrl_change_desc = createTextEditWithLabel5(toolkit, versionComposite,
				AuthoringUIText.CHANGE_DESCRIPTION_TEXT, 40, SWT.MULTI);

		ctrl_authors = createTextEditWithLabel5(toolkit, versionComposite,
				AuthoringUIText.AUTHORS_TEXT, 40, SWT.MULTI);

		label_copyright = createLabel(toolkit, versionComposite,
				AuthoringUIText.COPYRIGHT_TEXT, 2);
		ctrl_copyright = createTable(toolkit, versionComposite, SWT.SINGLE
				| SWT.READ_ONLY, GridData.FILL_HORIZONTAL | GridData.BEGINNING | GridData.FILL_VERTICAL,
				5, 400, 1, 2);

		copyright_viewer = new TableViewer(ctrl_copyright);
		initContentProviderCopyright();
		copyright_viewer.setLabelProvider(copyrightLabelProviderBase);
		copyright_viewer.setInput(methodElement);
		Composite buttonpane = createComposite(toolkit, versionComposite,
				GridData.HORIZONTAL_ALIGN_END, 1, 1, 1);
		{
			GridData gridData = new GridData(GridData.HORIZONTAL_ALIGN_END);
			buttonpane.setLayoutData(gridData);
		}
		copyright_button = toolkit.createButton(buttonpane,
				AuthoringUIText.SELECT_BUTTON_TEXT, SWT.SIMPLE);
		{
			GridData gridData = new GridData(GridData.HORIZONTAL_ALIGN_END);
			gridData.widthHint = BUTTON_WIDTH;
			copyright_button.setLayoutData(gridData);
		}
		copyright_button_deselect = toolkit.createButton(buttonpane,
				AuthoringUIText.DESELECT_BUTTON_TEXT, SWT.SIMPLE);
		{
			GridData gridData = new GridData(GridData.HORIZONTAL_ALIGN_END);
			gridData.widthHint = BUTTON_WIDTH;
			copyright_button_deselect.setLayoutData(gridData);
		}

		setCopyrightButtonDeselect();

		// Create the expanded composite.
		toolkit.paintBordersFor(versionComposite);
		//toolkit.paintBordersFor(buttonpane);
	}

	private void initContentProviderCopyright() {
		copyrightContentProvider = new AdapterFactoryContentProvider(
				TngAdapterFactory.INSTANCE
						.getNavigatorView_ComposedAdapterFactory()) {
			public Object[] getElements(Object object) {
				List list = new ArrayList();
				if (methodUnit.getCopyrightStatement() != null) {
					list.add(methodUnit
							.getCopyrightStatement());
				}
				return list.toArray();
			}

			public void notifyChanged(Notification notification) {
			}
		};
		copyright_viewer.setContentProvider(copyrightContentProvider);
	}

	protected void addVersionSectionListeners() {
		ctrl_version.addModifyListener(contentModifyListener);
		ctrl_version.addFocusListener(new FocusAdapter() {
			public void focusGained(FocusEvent e) {
				((MethodElementEditor) getEditor()).setCurrentFeatureEditor(e.widget,
						UmaPackage.eINSTANCE.getMethodUnit_Version());
			}

			public void focusLost(FocusEvent e) {
				String oldContent = methodUnit
						.getVersion();
				if (((MethodElementEditor) getEditor()).mustRestoreValue(
						e.widget, oldContent)) {
					return;
				}
				String newContent = StrUtil
						.getPlainText(ctrl_version.getText());
				if (!newContent.equals(oldContent)) {
					boolean status = actionMgr.doAction(IActionManager.SET,
							methodUnit,
							UmaPackage.eINSTANCE.getMethodUnit_Version(),
							newContent, -1);
					if (status) {
						updateChangeDate();
					}
				}
			}
		});

		ctrl_authors.addModifyListener(contentModifyListener);
		ctrl_authors.addFocusListener(new FocusAdapter() {
			public void focusGained(FocusEvent e) {
				((MethodElementEditor) getEditor()).setCurrentFeatureEditor(e.widget,
						UmaPackage.eINSTANCE.getMethodUnit_Authors());
			}

			public void focusLost(FocusEvent e) {
				String oldContent = methodUnit
						.getAuthors();
				if (((MethodElementEditor) getEditor()).mustRestoreValue(
						e.widget, oldContent)) {
					return;
				}
				String newContent = StrUtil
						.getPlainText(ctrl_authors.getText());
				if (!newContent.equals(oldContent)) {
					boolean status = actionMgr.doAction(IActionManager.SET,
							methodUnit,
							UmaPackage.eINSTANCE.getMethodUnit_Authors(),
							newContent, -1);
					if (status) {
						updateChangeDate();
					}
				}
			}
		});

		copyright_button.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent e) {
				IFilter filter = new ContentFilter() {
					protected boolean childAccept(Object obj) {
						if (obj instanceof Guidance) {
							return (obj instanceof SupportingMaterial);
						}
						return false;
					}
				};
				List alreadyExsting = new ArrayList();
				if (ctrl_copyright.getItemCount() > 0) {
					TableItem item = ctrl_copyright.getItems()[0];
					if (item.getData() != null)
						alreadyExsting.add(item.getData());
				}
				ItemsFilterDialog fd = new ItemsFilterDialog(PlatformUI
						.getWorkbench().getActiveWorkbenchWindow().getShell(),
						filter, methodElement,
						FilterConstants.SUPPORTING_MATERIALS, alreadyExsting);
				fd.setViewerSelectionSingle(true);
				fd.setBlockOnOpen(true);
				fd.setTitle(FilterConstants.SUPPORTING_MATERIALS);
				fd.open();
				fd.getSelectedItems();
				if (fd.getSelectedItems().size() > 0) {
					boolean status = actionMgr.doAction(IActionManager.SET,
							methodUnit,
							UmaPackage.eINSTANCE
									.getMethodUnit_CopyrightStatement(),
							(SupportingMaterial) fd.getSelectedItems().get(0),
							-1);
					if (!status) {
						return;
					}
				}
				copyright_viewer.refresh();
				setCopyrightButtonDeselect();
			}
		});

		ctrl_change_desc.addModifyListener(contentModifyListener);
		ctrl_change_desc.addFocusListener(new FocusAdapter() {
			public void focusGained(FocusEvent e) {
				((MethodElementEditor) getEditor()).setCurrentFeatureEditor(e.widget,
						UmaPackage.eINSTANCE.getMethodUnit_ChangeDescription());
			}

			public void focusLost(FocusEvent e) {
				String oldContent = methodUnit
						.getChangeDescription();
				if (((MethodElementEditor) getEditor()).mustRestoreValue(
						e.widget, oldContent)) {
					return;
				}
				String newContent = ctrl_change_desc.getText();
				newContent = newContent.replace(StrUtil.LINE_FEED, AuthoringUIResources.ChangeHistoryDialog_delimiter);
				if (!newContent.equals(oldContent)) {
					boolean success = actionMgr.doAction(
							IActionManager.SET, methodUnit, UmaPackage.eINSTANCE
							.getMethodUnit_ChangeDescription(), newContent, -1);
					if (success) {
						updateChangeDate();
					}
				}
			}
		});

		copyright_button_deselect.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent e) {
				boolean status = actionMgr.doAction(IActionManager.SET,
						methodUnit, UmaPackage.eINSTANCE
								.getMethodUnit_CopyrightStatement(), null, -1);
				if (status) {
					copyright_viewer.refresh();
					setCopyrightButtonDeselect();
				}
			}
		});
	}

	/*
	 * update the change date if any attribute is modified.
	 */
	protected void updateChangeDate() {

		Date changeDate = methodUnit.getChangeDate();
		DateFormat df = DateFormat.getDateInstance(DateFormat.FULL);

		String oldContent = ""; //$NON-NLS-1$
		if (changeDate != null) {
			oldContent = df.format(changeDate);
		}

		Date currentDate = new Date();
		String newContent = df.format(currentDate);
		if (!newContent.equals(oldContent)) {
			boolean status = actionMgr.doAction(IActionManager.SET,
					methodUnit, UmaPackage.eINSTANCE
							.getMethodUnit_ChangeDate(), currentDate, -1);
			if (!status) {
				return;
			} else {
				ctrl_change_date.setText(newContent);
			}
		}
	}

	protected void loadVersionSectionData() {

		ctrl_version
				.setText(methodUnit.getVersion() == null ? "" : methodUnit.getVersion()); //$NON-NLS-1$
		ctrl_authors
				.setText(methodUnit.getAuthors() == null ? "" : methodUnit.getAuthors()); //$NON-NLS-1$
		String changeDesc = methodUnit.getChangeDescription() == null ? "" : methodUnit.getChangeDescription(); //$NON-NLS-1$
		changeDesc = changeDesc.replace(AuthoringUIResources.ChangeHistoryDialog_delimiter, StrUtil.LINE_FEED);
		ctrl_change_desc.setText(changeDesc);
		ctrl_change_date
				.setText(methodUnit.getChangeDate() == null ? "" //$NON-NLS-1$
						: DateFormat.getDateInstance(DateFormat.FULL).format(
								methodUnit.getChangeDate()));
	}

	/**
	 * Toggle Description control to expand and control state
	 */
	protected void toggle(HyperlinkEvent e, int id) {
		// TODO- we should combine these methods into one. One way to do it,
		// dispoing
		// ctrl_expanded every time it collapses and creating it when we expand.
		// At present, there is no method to dispose
		toggle(e);
	}

	/**
	 * @return Returns the iconSectionOn.
	 */
	public boolean isIconSectionOn() {
		return iconSectionOn;
	}

	/**
	 * @param iconSectionOn
	 *            The iconSectionOn to set.
	 */
	public void setIconSectionOn(boolean iconSectionOn) {
		this.iconSectionOn = iconSectionOn;
	}

	/**
	 * Creates the Icon section.
	 */
	protected void createIconSection(FormToolkit toolkit) {
		iconSection = toolkit.createSection(sectionComposite,
				Section.DESCRIPTION | Section.TWISTIE | Section.EXPANDED
						| Section.TITLE_BAR);
		GridData td = new GridData(GridData.FILL_BOTH);
		iconSection.setLayoutData(td);
		iconSection.setText(AuthoringUIText.ICON_SECTION_NAME);
		iconSection.setDescription(getIconSectionDescription());
		iconSection.setLayout(new GridLayout());

		iconComposite = toolkit.createComposite(iconSection);
		iconComposite.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
		iconComposite.setLayout(new GridLayout(3, true));
		iconSection.setClient(iconComposite);
	}
	private void createIconSectionContent() {
		Composite shapeIconComposite = createComposite(toolkit, iconComposite,
				1);
		shapeIconComposite.setLayoutData(new GridData());
		shapeIconComposite.setLayout(new GridLayout(2, true));
//		createLabel(
//				toolkit,
//				shapeIconComposite,
//				AuthoringUIResources.DescriptionFormPage_ShapeIconPreview_Label, 2); //$NON-NLS-1$
		// No wrap needed
		createLabelWithNoWrap(
				toolkit,
				shapeIconComposite,
				AuthoringUIResources.DescriptionFormPage_ShapeIconPreview_Label,
				GridData.BEGINNING,
				2); 
		
		pane1 = new Canvas(shapeIconComposite, SWT.BORDER);
		{
			GridData gridData = new GridData(GridData.BEGINNING);

			gridData.heightHint = 60;
			gridData.widthHint = 60;
			gridData.verticalSpan = 1;
			gridData.horizontalSpan = 1;
			pane1.setLayoutData(gridData);
			pane1.setBackground(ColorConstants.lightGray);
		}
		// pane1.setSize(30,30);
		Composite pane2 = createCompositeForButtons(toolkit, shapeIconComposite);
		ctrl_select_shapeIcon_button = toolkit
				.createButton(
						pane2,
						AuthoringUIResources.DescriptionFormPage_ShapeIconPreview_SelectButtonLabel, SWT.NONE); 
		ctrl_clear_shapeIcon_button = toolkit
				.createButton(
						pane2,
						AuthoringUIResources.DescriptionFormPage_ShapeIconPreview_ClearButtonLabel, SWT.NONE); 
		if (contentElement.getShapeicon() == null)
			ctrl_clear_shapeIcon_button.setEnabled(false);
		else
			ctrl_clear_shapeIcon_button.setEnabled(true);

		Composite nodeIconComposite = createComposite(toolkit, iconComposite, 1);
		nodeIconComposite.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
		nodeIconComposite.setLayout(new GridLayout(2, false));
//		createLabel(
//				toolkit,
//				nodeIconComposite,
//				AuthoringUIResources.DescriptionFormPage_NodeIconPreview_Label, 2); //$NON-NLS-1$
		// No wrap need for 
		createLabelWithNoWrap(
				toolkit,
				nodeIconComposite,
				AuthoringUIResources.DescriptionFormPage_NodeIconPreview_Label,
				GridData.BEGINNING,
				2); 
		pane3 = new Canvas(nodeIconComposite, SWT.BORDER);
		{
			GridData gridData = new GridData(GridData.BEGINNING);

			gridData.heightHint = 40;
			gridData.widthHint = 40;
			gridData.verticalSpan = 1;
			gridData.horizontalSpan = 1;
			pane3.setLayoutData(gridData);
			pane3.setBackground(ColorConstants.lightGray);
		}
		Composite pane4 = createCompositeForButtons(toolkit, nodeIconComposite);
		ctrl_select_nodeIcon_button = toolkit
				.createButton(
						pane4,
						AuthoringUIResources.DescriptionFormPage_NodeIconPreview_SelectButtonLabel, SWT.NONE); 
		ctrl_clear_nodeIcon_button = toolkit
				.createButton(
						pane4,
						AuthoringUIResources.DescriptionFormPage_NodeIconPreview_ClearButtonLabel, SWT.NONE); 
		if (contentElement.getNodeicon() == null)
			ctrl_clear_nodeIcon_button.setEnabled(false);
		else
			ctrl_clear_nodeIcon_button.setEnabled(true);
		
		new Label(iconComposite, SWT.NONE);
		shapeIconPath = createLabelWithNoWrap(toolkit,
				iconComposite, "", GridData.BEGINNING, 1); //$NON-NLS-1$
		nodeIconPath = createLabelWithNoWrap(toolkit,
				iconComposite, "", GridData.BEGINNING, 2); //$NON-NLS-1$
//			new Label(nodeIconComposite, SWT.NONE);
//		GridData data = new GridData(GridData.BEGINNING);
//		data.horizontalSpan =2;
//		nodeIconPath.setLayoutData(data);

		toolkit.paintBordersFor(pane1);
		toolkit.paintBordersFor(pane2);
		toolkit.paintBordersFor(pane3);
		toolkit.paintBordersFor(pane4);
	}

	protected void addIconSectionListeners() {

		ctrl_select_shapeIcon_button
				.addSelectionListener(new SelectionAdapter() {
//					File libDirFile = new File(LibraryService.getInstance()
//							.getCurrentMethodLibraryPath());

					public void widgetSelected(SelectionEvent e) {
						java.net.URI shapeIconUri = null;
						FileDialog fileChooser = new FileDialog(Display
								.getCurrent().getActiveShell(), SWT.OPEN);
						fileChooser.setText(AuthoringUIResources.DescriptionFormPage_IconFileChooserDialog_title); 
						fileChooser.setFilterExtensions(imageTypes); 
						fileChooser.setFilterNames(imageNames); 
						String imageFile = null;
						String filename = null;
						while (true) {
							imageFile = fileChooser.open();
							filename = fileChooser.getFileName();
							if (imageFile != null) {
								if (new File(imageFile).exists()) {
//									ImageData imageData = new ImageData(
//											imageFile);
//									if (imageData.width > SHAPEICON_WIDTH_MAX
//											|| imageData.height > SHAPEICON_HEIGHT_MAX) {
//										// msg user - image too big
//										AuthoringUIPlugin
//												.getDefault()
//												.getMsgDialog()
//												.displayError(
//														AuthoringUIResources.forms_DescriptionFormPage_imageTooBigDialog_title, //$NON-NLS-1$ 
//														MessageFormat
//																.format(
//																		AuthoringUIResources.forms_DescriptionFormPage_imageTooBigDialog_template, //$NON-NLS-1$
//																		new Object[] {
//																				imageFile,
//																				new Integer(
//																						SHAPEICON_WIDTH_MAX),
//																				new Integer(
//																						SHAPEICON_HEIGHT_MAX) }));
//									} else {
//										break;
//									}
									break;
								} else {
									// msg user - file doesn't exist
									AuthoringUIPlugin
											.getDefault()
											.getMsgDialog()
											.displayError(
													AuthoringUIResources.forms_DescriptionFormPage_imageNotFoundDialog_title, 
													MessageFormat
															.format(
																	AuthoringUIResources.forms_DescriptionFormPage_imageNotFoundDialog_template, 
																	new Object[] { imageFile }));
								}
							} else {
								return;
							}
						}
						if (imageFile != null && imageFile.length() > 0) {
							try {
								String url = copyResourceToLib(ctrl_select_shapeIcon_button.getShell(), filename,
										fileChooser.getFilterPath(),
										methodElement);
								if (url != null) {
									File file = new File(url);
									shapeIconUri = new URI(NetUtil
											.encodeFileURL(FileUtil
													.getRelativePath(file,
															new File(getPluginPath(methodElement)))));
									if (shapeIconUri != null) {
										boolean status = actionMgr
												.doAction(
														IActionManager.SET,
														methodElement,
														UmaPackage.eINSTANCE
																.getDescribableElement_Shapeicon(),
														shapeIconUri, -1);
										if (!status)
											return;
									}
									shapeImage = new Image(
											Display.getCurrent(), file
													.getAbsolutePath());
									shapeIconPath.setText(NetUtil.decodedFileUrl(shapeIconUri.getPath()));
								}
							} catch (Exception ex) {
								shapeIconUri = null;
								shapeImage = null;
								AuthoringUIPlugin.getDefault().getLogger()
										.logError(ex);
								if (ex instanceof IOException) {
									AuthoringUIPlugin
											.getDefault()
											.getMsgDialog()
											.displayError(
													AuthoringUIResources.err_copying_file_title, 
													AuthoringUIResources.err_copying_file_error, 
													AuthoringUIResources.err_copying_file_reason, 
													ex.getMessage());
								} else {
									AuthoringUIPlugin
											.getDefault()
											.getMsgDialog()
											.displayError(
													AuthoringUIResources.err_processing_file_title, 
													AuthoringUIResources.err_processing_file_description, ex); 
								}
							}
						}
						if (shapeImage != null) {
							pane1.redraw();
							ctrl_clear_shapeIcon_button.setEnabled(true);
						} else {
							ctrl_clear_shapeIcon_button.setEnabled(false);
						}

					}
				});

		ctrl_clear_shapeIcon_button
				.addSelectionListener(new SelectionAdapter() {
					public void widgetSelected(SelectionEvent e) {
						boolean status = actionMgr.doAction(IActionManager.SET,
								methodElement, UmaPackage.eINSTANCE
										.getDescribableElement_Shapeicon(),
								null, -1);
						if (!status)
							return;
						pane1.redraw();
						ctrl_clear_shapeIcon_button.setEnabled(false);
						shapeIconPath.setText(""); //$NON-NLS-1$
					}
				});

		ctrl_select_nodeIcon_button
				.addSelectionListener(new SelectionAdapter() {
//					File libDirFile = new File(LibraryService.getInstance()
//							.getCurrentMethodLibraryPath());

					public void widgetSelected(SelectionEvent e) {
						java.net.URI nodeIconUri = null;
						FileDialog fileChooser = new FileDialog(Display
								.getCurrent().getActiveShell(), SWT.OPEN);
						fileChooser.setText(AuthoringUIResources.DescriptionFormPage_IconFileChooserDialog_title); 
						fileChooser.setFilterExtensions(imageTypes); 
						fileChooser.setFilterNames(imageNames); 
						String imageFile = null;
						String filename = null;
						while (true) {
							imageFile = fileChooser.open();
							filename = fileChooser.getFileName();
							if (imageFile != null) {
								if (new File(imageFile).exists()) {
									ImageData imageData = new ImageData(
											imageFile);
									if (imageData.width > NODEICON_WIDTH_MAX
											|| imageData.height > NODEICON_HEIGHT_MAX) {
										// msg user - image too big
										AuthoringUIPlugin
												.getDefault()
												.getMsgDialog()
												.displayError(
														AuthoringUIResources.forms_DescriptionFormPage_imageTooBigDialog_title, 
														MessageFormat
																.format(
																		AuthoringUIResources.forms_DescriptionFormPage_imageTooBigDialog_template, 
																		new Object[] {
																				imageFile,
																				new Integer(
																						NODEICON_WIDTH_MAX),
																				new Integer(
																						NODEICON_HEIGHT_MAX) }));
									} else {
										break;
									}
								} else {
									// msg user - file doesn't exist
									AuthoringUIPlugin
											.getDefault()
											.getMsgDialog()
											.displayError(
													AuthoringUIResources.forms_DescriptionFormPage_imageNotFoundDialog_title, 
													MessageFormat
															.format(
																	AuthoringUIResources.forms_DescriptionFormPage_imageNotFoundDialog_template, 
																	new Object[] { imageFile }));
								}
							} else {
								return;
							}
						}
						if (imageFile != null && imageFile.length() > 0) {
							try {
								String url = copyResourceToLib(ctrl_select_nodeIcon_button.getShell(), filename,
										fileChooser.getFilterPath(),
										methodElement);
								if (url != null) {
									File file = new File(url);
									nodeIconUri = new URI(NetUtil
											.encodeFileURL(FileUtil
													.getRelativePath(file,
															new File(getPluginPath(methodElement)))));
									if (nodeIconUri != null) {
										boolean status = actionMgr
												.doAction(
														IActionManager.SET,
														methodElement,
														UmaPackage.eINSTANCE
																.getDescribableElement_Nodeicon(),
														nodeIconUri, -1);
										if (!status)
											return;
									}
									nodeImage = new Image(Display.getCurrent(),
											file.getAbsolutePath());
									nodeIconPath.setText(NetUtil.decodedFileUrl(nodeIconUri.getPath()));
								}
							} catch (Exception ex) {
								nodeIconUri = null;
								nodeImage = null;
								AuthoringUIPlugin.getDefault().getLogger()
										.logError(ex);
								if (ex instanceof IOException) {
									AuthoringUIPlugin
											.getDefault()
											.getMsgDialog()
											.displayError(
													AuthoringUIResources.err_copying_file_title, 
													AuthoringUIResources.err_copying_file_error, 
													AuthoringUIResources.err_copying_file_reason, 
													ex.getMessage());

								} else {
									AuthoringUIPlugin
											.getDefault()
											.getMsgDialog()
											.displayError(
													AuthoringUIResources.err_processing_file_title, 
													AuthoringUIResources.err_processing_file_description, ex); 
								}
							}
						}
						if (nodeImage != null) {
							pane3.redraw();
							ctrl_clear_nodeIcon_button.setEnabled(true);
						} else {
							ctrl_clear_nodeIcon_button.setEnabled(false);
						}
					}
				});

		ctrl_clear_nodeIcon_button.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent e) {
				boolean status = actionMgr.doAction(IActionManager.SET,
						methodElement, UmaPackage.eINSTANCE
								.getDescribableElement_Nodeicon(), null, -1);
				if (!status)
					return;
				pane3.redraw();
				ctrl_clear_nodeIcon_button.setEnabled(false);
				nodeIconPath.setText(""); //$NON-NLS-1$
			}
		});
	}

	/**
	 * Copies the selected shapeNodeIcon and nodeIcon to resources folder of
	 * content element. Prompts to overwrite if file already exists.
	 * @param sFileName
	 * @param sFilePath
	 * @param methodElement
	 * @return
	 * @throws IOException
	 */
	protected String copyResourceToLib(Shell shell, String sFileName, String sFilePath,
			MethodElement methodElement) throws IOException {
		File newFile = LibraryUIUtil.copyResourceToLib(shell, new File(sFilePath, sFileName), methodElement);
		if (newFile != null)
			return newFile.getAbsolutePath();
		else 
			return null;
	}

	protected void loadIconSectionData() {
		pane1.addPaintListener(new PaintListener() {
			public void paintControl(PaintEvent e) {
				// paint the grey background
				Rectangle clientRect = pane1.getClientArea();
				e.gc.setClipping(clientRect);
				e.gc.setBackground(Display.getCurrent().getSystemColor(15));
				e.gc.fillRectangle(clientRect);

				java.net.URI uri = contentElement.getShapeicon();
				if (uri != null) {
					String path = NetUtil.decodedFileUrl(contentElement.getShapeicon().getPath());
					if (path != null) {
						try {
							File file = new File(path);
							if (file.exists()) {
							} else {
								if (!file.isAbsolute()) {
									// Check for the uri contains the relative to library.
									MethodPlugin plugin = UmaUtil.getMethodPlugin(methodElement);
									if(path.indexOf(plugin.getName()) > -1){
										path = LibraryService.getInstance()
										.getCurrentMethodLibraryLocation()
										+ File.separator + path;	
									}else{
										path = getPluginPath(methodElement)
										+ File.separator + path;
									}
									
								}
								file = new File(path);
							}
							if (file.exists()) {
								if (shapeImage == null) {
									shapeImage = new Image(
											Display.getCurrent(), path);
								}
								if(contentElement.getShapeicon() != null){
									shapeIconPath.setText(NetUtil.decodedFileUrl(contentElement.getShapeicon().getPath()));
								}
								clientRect = pane1.getClientArea();
								e.gc.setClipping(clientRect);
								e.gc.setBackground(Display.getCurrent()
										.getSystemColor(SWT.COLOR_WHITE));
								e.gc.fillRectangle(clientRect);
								e.gc.drawImage(shapeImage, shapeImage
										.getBounds().x,
										shapeImage.getBounds().y, shapeImage
												.getBounds().width, shapeImage
												.getBounds().height, pane1
												.getClientArea().x, pane1
												.getClientArea().y, pane1
												.getClientArea().width, pane1
												.getClientArea().height);
							} else {
								if (warningCount == 1) {
									warningCount++;
									String msg = AuthoringUIResources.bind(AuthoringUIResources.DescriptionFormPage_LoadShapeIconWarning, (new Object[] { methodElement.getName(), path })); 
									MsgBox.showWarning(msg);
								}

							}
						} catch (Exception ex) {
							AuthoringUIPlugin
									.getDefault()
									.getLogger()
									.logError(
											AuthoringUIResources.bind(AuthoringUIResources.DescriptionFormPage_LoadShapeIconError, (new Object[] { ex.getMessage() }))); 
						}
					}
				}
			}

		});
		pane1.redraw();
		if(contentElement.getShapeicon() != null){
			shapeIconPath.setText(NetUtil.decodedFileUrl(contentElement.getShapeicon().getPath()));
		}
		
		pane3.addPaintListener(new PaintListener() {
			public void paintControl(PaintEvent e) {
				// paint the grey background
				Rectangle clientRect = pane3.getClientArea();
				e.gc.setClipping(clientRect);
				e.gc.setBackground(Display.getCurrent().getSystemColor(15));
				e.gc.fillRectangle(clientRect);

				java.net.URI uri = contentElement.getNodeicon();
				if (uri != null) {
					String path = NetUtil.decodedFileUrl(contentElement.getNodeicon().getPath());
					if (path != null) {
						try {
							File file = new File(path);
							if (file.exists()) {
							} else {
								if (!file.isAbsolute()) {
									MethodPlugin plugin = UmaUtil.getMethodPlugin(methodElement);
									if(path.indexOf(plugin.getName()) > -1){
										path = LibraryService.getInstance()
										.getCurrentMethodLibraryLocation()
										+ File.separator + path;	
									}else{
										path = getPluginPath(methodElement)
										+ File.separator + path;
									}
								}
								file = new File(path);
							}
							if (file.exists()) {
								if (nodeImage == null) {
									nodeImage = new Image(Display.getCurrent(),
											path);
								}
								if(contentElement.getNodeicon() != null){
									nodeIconPath.setText(NetUtil.decodedFileUrl(contentElement.getNodeicon().getPath()));
								}
								clientRect = pane3.getClientArea();
								e.gc.setClipping(clientRect);
								e.gc.setBackground(Display.getCurrent()
										.getSystemColor(SWT.COLOR_WHITE));
								e.gc.fillRectangle(clientRect);
								e.gc.drawImage(nodeImage,
										nodeImage.getBounds().x, nodeImage
												.getBounds().y, nodeImage
												.getBounds().width, nodeImage
												.getBounds().height, pane3
												.getClientArea().x, pane3
												.getClientArea().y, pane3
												.getClientArea().width, pane3
												.getClientArea().height);
							} else {
								if (warningCount == 1) {
									warningCount++;
									String msg = AuthoringUIResources.bind(AuthoringUIResources.DescriptionFormPage_LoadNodeIconWarning, (new Object[] { methodElement.getName(), path })); 
									MsgBox.showWarning(msg);
								}

							}
						} catch (Exception ex) {
							AuthoringUIPlugin
									.getDefault()
									.getLogger()
									.logError(
											AuthoringUIResources.bind(AuthoringUIResources.DescriptionFormPage_LoadNodeIconError, (new Object[] { ex.getMessage() }))); 
						}
					}
				}
			}

		});
		pane3.redraw();
		if(contentElement.getNodeicon() != null){
			nodeIconPath.setText(NetUtil.decodedFileUrl(contentElement.getNodeicon().getPath()));
		}
	}

	
	protected void enableSections(boolean enable) {
		if (generalSectionOn) {
			generalSection.setVisible(enable);
			if (enable) {
				generalSection.setExpanded(generalSectionExpandFlag);
			} else {
				generalSectionExpandFlag = generalSection.isExpanded();
				generalSection.setExpanded(enable);
			}
		}

		if (detailSectionOn) {
			detailSection.setVisible(enable);
			if (enable) {
				detailSection.setExpanded(detailSectionExpandFlag);
			} else {
				detailSectionExpandFlag = detailSection.isExpanded();
				detailSection.setExpanded(enable);
			}
		}
		if (notationSectionOn) {
			notationSection.setVisible(enable);
			if (enable) {
				notationSection.setExpanded(notationSectionExpandFlag);
			} else {
				notationSectionExpandFlag = notationSection.isExpanded();
				notationSection.setExpanded(enable);
			}
		}
		if (tailoringSectionOn) {
			tailoringSection.setVisible(enable);
			if (enable) {
				tailoringSection.setExpanded(tailoringSectionExpandFlag);
			} else {
				tailoringSectionExpandFlag = tailoringSection.isExpanded();
				tailoringSection.setExpanded(enable);
			}
		}
		if (versionSectionOn) {
			versionSection.setVisible(enable);
			if (enable) {
				versionSection.setExpanded(versionSectionExpandFlag);
			} else {
				versionSectionExpandFlag = versionSection.isExpanded();
				versionSection.setExpanded(enable);
			}
		}
		if (iconSectionOn) {
			iconSection.setVisible(enable);
			if (enable) {
				iconSection.setExpanded(iconSectionExpandFlag);
			} else {
				iconSectionExpandFlag = iconSection.isExpanded();
				iconSection.setExpanded(enable);
			}
		}
		if (variabilitySectionOn) {
			variabilitySection.setVisible(enable);
			if (enable) {
				variabilitySection.setExpanded(elementSectionExpandFlag);
			} else {
				elementSectionExpandFlag = variabilitySection.isExpanded();
				variabilitySection.setExpanded(enable);
			}
		}
	}

	/**
	 * @see org.eclipse.ui.forms.editor.FormPage#dispose()
	 */
	public void dispose() {
		if (shapeImage != null) {
			shapeImage.dispose();
		}
		if (nodeImage != null) {
			nodeImage.dispose();
		}
		if (labelProviderVariability != null) {
			labelProviderVariability.dispose();
		}
		if (contentProviderVariability != null) {
			contentProviderVariability.dispose();
		}
		if (labelProviderBase != null) {
			labelProviderBase.dispose();
		}
		if (copyrightLabelProviderBase != null) {
			copyrightLabelProviderBase.dispose();
		}
		
		if (columnProvider != null) {
			columnProvider.dispose();
		}
		if (sectionProviders != null) {
			for (int i = 0; i < sectionProviders.size(); i++) {
				Object provider = sectionProviders.get(i);
				if (provider != null && provider instanceof ISectionProvider) {
					((ISectionProvider) provider).dispose();
				}
			}
		}
		super.dispose();
		
		disposed = true;
	}		

	private void setCopyrightButtonDeselect() {
		if (methodUnit.getCopyrightStatement() != null) {
			copyright_button_deselect
					.setEnabled((methodUnit
							.getCopyrightStatement().getName() == null) ? false
							: true);
		} else
			copyright_button_deselect.setEnabled(false);
		if (TngUtil.isLocked(methodElement))
			copyright_button_deselect.setEnabled(false);
	}

	protected void setContextHelp() {
		if (mainComposite != null) {
			EditorsContextHelper.setHelp(mainComposite.getParent(),
					getContentElement());
		}
		if (expandedComposite != null) {
			PlatformUI.getWorkbench().getHelpSystem().setHelp(
					expandedComposite,
					AuthoringUIHelpContexts.RICH_TEXT_EDITOR_CONTEXT_ID);
		}

	}

	/* (non-Javadoc)
	 * @see org.eclipse.epf.authoring.ui.forms.IRefreshable#refreshName(java.lang.String)
	 */
	public void refreshName(String newName) {
		if (newName != null) {
			if ((ctrl_name != null) && !(ctrl_name.isDisposed())) {
				if (modelModifyListener != null) {				
					ctrl_name.removeModifyListener(modelModifyListener);
					ctrl_name.setText(newName);
					ctrl_name.addModifyListener(modelModifyListener);
				} else {
					ctrl_name.setText(newName);
				}
				setFormTextWithVariableInfo();
			}
		}
	}
	
	public void loadSectionDescription(){
		
	}
	protected String getDetailSectionDescription(){
		if(detailSectionDescription != null){
			return detailSectionDescription;
		}
		return AuthoringUIText.DETAIL_SECTION_DESC;
	}
	protected String getGeneralSectionDescription(){
		if(generalSectionDescription!= null){
			return generalSectionDescription;
		}
		return AuthoringUIText.GENERAL_INFO_SECTION_DESC;
	}
	protected String getTailoringSectionDescription(){
		if(tailoringSectionDescription != null){
			return tailoringSectionDescription;
		}
		return AuthoringUIText.TAILORING_SECTION_DESC;
	}
	protected String getNotationSectionDescription(){
		if(notationSectionDescription != null){
			return notationSectionDescription;
		}
		return AuthoringUIText.NOTATION_SECTION_DESC;
	}
	protected String getVariabilitySectionDescription(){
		if(variabilitySectionDescription != null){
			return variabilitySectionDescription;
		}
		return AuthoringUIText.VARIABILITY_SECTION_DESC;
	}
	
	private String getIconSectionDescription() {
		// TODO Auto-generated method stubs
		if(iconSectionDescription != null){
			return iconSectionDescription;
		}
		return AuthoringUIText.ICON_SECTION_DESC;
	}
	private String getVersionSectionDescription() {
		// TODO Auto-generated method stub
		if(versionSectionDescription != null){
			return versionSectionDescription;
		}
		return AuthoringUIText.VERSION_INFO_SECTION_DESC;
	}

	/** 
	 * Following methods below exposed public in order to allow 
	 * test automation to access the form objects through test objects
	 * of any automation tools.
	 */
	
	/**
	 * Get brief description
	 * @return Returns the ctrl_brief_desc.
	 */
	public Text getCtrl_brief_desc() {
		return ctrl_brief_desc;
	}

	/**
	 * Set brief description
	 * @param ctrl_brief_desc The ctrl_brief_desc to set.
	 */
	public void setCtrl_brief_desc(Text ctrl_brief_desc) {
		this.ctrl_brief_desc = ctrl_brief_desc;
	}

	/**
	 * Get main description
	 * @return Returns the ctrl_full_desc.
	 */
	public IMethodRichText getCtrl_full_desc() {
		return ctrl_full_desc;
	}

	/**
	 * Set main description
	 * @param ctrl_full_desc The ctrl_full_desc to set.
	 */
	public void setCtrl_full_desc(IMethodRichText ctrl_full_desc) {
		this.ctrl_full_desc = ctrl_full_desc;
	}

	/**
	 * Get presentation name
	 * @return Returns the ctrl_presentation_name.
	 */
	public Text getCtrl_presentation_name() {
		return ctrl_presentation_name;
	}

	/**
	 * Set presentation name
	 * @param ctrl_presentation_name The ctrl_presentation_name to set.
	 */
	public void setCtrl_presentation_name(Text ctrl_presentation_name) {
		this.ctrl_presentation_name = ctrl_presentation_name;
	}

	/**
	 * Get expanded rich text control
	 * @return Returns the ctrl_expanded.
	 */
	public IMethodRichTextEditor getCtrl_expanded() {
		return ctrl_expanded;
	}

	/**
	 * Set expanded rich text control
	 * @param ctrl_expanded The ctrl_expanded to set.
	 */
	public void setCtrl_expanded(IMethodRichTextEditor ctrl_expanded) {
		this.ctrl_expanded = ctrl_expanded;
	}

	/**
	 * Get rich text control
	 * @return Returns the ctrl_key.
	 */
	public IMethodRichText getCtrl_key() {
		return ctrl_key;
	}

	/**
	 * Set rich text control
	 * @param ctrl_key The ctrl_key to set.
	 */
	public void setCtrl_key(IMethodRichText ctrl_key) {
		this.ctrl_key = ctrl_key;
	}
	
	public String getPluginPath(MethodElement e){
		MethodPlugin plugin = UmaUtil.getMethodPlugin(e);
		if (plugin != null) {
			return ResourceHelper.getFolderAbsolutePath(plugin);
		}

		return null;
	}

	private String generateName(String presentationName) {
		StringBuffer buf = new StringBuffer();
		for (int i = 0; i < presentationName.length(); i++) {
			char c = presentationName.charAt(i);
			if (c >= 'A' && c <= 'Z') {
				c -= 'A';
				c += 'a'; 
			} else if (c == ' ') {
				c = '_';
			}
			
			boolean toAdd = (c >= '0' && c <= '9') ||
							(c >= 'a' && c <= 'z') ||
							(c == '-' || c == '_' || c== '.');
			if (toAdd) {
				buf.append(c);
			}			
		}
		return buf.toString();
	}
	
	protected void changeElementName() {
		String name = ctrl_name.getText();
		
		if (! name.equals(methodElement.getName())) {
			
			IValidator validator = getNameValidator();
			if(validator == null){
				validator = IValidatorFactory.INSTANCE
					.createNameValidator(
							methodElement,
							TngAdapterFactory.INSTANCE
									.getNavigatorView_ComposedAdapterFactory());
			}
			
			String name0 = name;
			for  (int i = 1; i < 1000; i++) {
				String msg = validator.isValid(name);
				if (msg == null || msg.length() == 0) {
					ctrl_name.setText(name);
					break;
				}
				name = name0 + "_" + i;		//$NON-NLS-1$
			}
			
			if (! name.equals(methodElement.getName())) {
				changeElementName(ctrl_name.getText());	
			}
			
			LibraryUtil.removeNameTrackPresentationNameMark(methodElement);
		}
	
	}

	protected boolean isAutoGenName() {
		return autoGenName;
	}

	protected void setAutoGenName(boolean autoGenName) {
		this.autoGenName = autoGenName;
	}
			
}
