256368 "Multi-page SQL Schema Editor Framework & exemplary implementations for Sybase ASA in enablement project".
diff --git a/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui.pages/.classpath b/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui.pages/.classpath
new file mode 100644
index 0000000..751c8f2
--- /dev/null
+++ b/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui.pages/.classpath
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="src" path="src"/>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
+	<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+	<classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui.pages/.project b/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui.pages/.project
new file mode 100644
index 0000000..e9fb6e8
--- /dev/null
+++ b/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui.pages/.project
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>org.eclipse.datatools.sqltools.schemaobjecteditor.ui.pages</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.pde.ManifestBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.pde.SchemaBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.pde.PluginNature</nature>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+	</natures>
+</projectDescription>
diff --git a/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui.pages/META-INF/MANIFEST.MF b/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui.pages/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..bdeb57e
--- /dev/null
+++ b/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui.pages/META-INF/MANIFEST.MF
@@ -0,0 +1,27 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: %plugin.name
+Bundle-SymbolicName: org.eclipse.datatools.sqltools.schemaobjecteditor.ui.pages;singleton:=true
+Bundle-Version: 1.1.0.qualifier
+Bundle-Activator: org.eclipse.datatools.sqltools.schemaobjecteditor.ui.pages.SOEUIPagePlugin
+Bundle-Vendor: %providerName
+Bundle-Localization: plugin
+Require-Bundle: org.eclipse.core.runtime;bundle-version="[3.2.0,4.0.0)",
+ org.eclipse.core.resources;bundle-version="[3.2.0,4.0.0)",
+ org.eclipse.draw2d;bundle-version="[3.2.0,4.0.0)",
+ org.eclipse.ui;bundle-version="[3.2.0,4.0.0)",
+ org.eclipse.ui.forms;bundle-version="[3.2.0,4.0.0)",
+ org.eclipse.ui.cheatsheets;bundle-version="[3.2.0,4.0.0)",
+ org.eclipse.jface.text;bundle-version="[3.2.0,4.0.0)",
+ org.eclipse.help;bundle-version="[3.2.0,4.0.0)",
+ org.eclipse.help.base;bundle-version="[3.2.0,4.0.0)",
+ org.eclipse.datatools.help;bundle-version="[0.9.0,2.0.0)",
+ org.eclipse.datatools.sqltools.common.ui;bundle-version="[0.9.0,1.5.0)",
+ org.eclipse.datatools.sqltools.sqleditor;bundle-version="[0.9.0,1.5.0)",
+ org.eclipse.datatools.sqltools.editor.core;bundle-version="[0.9.0,1.5.0)",
+ org.eclipse.datatools.sqltools.schemaobjecteditor.ui;bundle-version="[0.9.0,1.5.0)",
+ org.eclipse.datatools.sqltools.schemaobjecteditor;bundle-version="[0.9.0,1.5.0)"
+Eclipse-LazyStart: true
+Export-Package: org.eclipse.datatools.sqltools.schemaobjecteditor.ui.pages,
+ org.eclipse.datatools.sqltools.schemaobjecteditor.ui.pages.ddl,
+ org.eclipse.datatools.sqltools.schemaobjecteditor.ui.pages.intropage
diff --git a/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui.pages/build.properties b/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui.pages/build.properties
new file mode 100644
index 0000000..fb392b8
--- /dev/null
+++ b/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui.pages/build.properties
@@ -0,0 +1,13 @@
+bin.includes = plugin.xml,\
+               .,\
+               plugin.properties,\
+               META-INF/MANIFEST.MF,\
+               icons/,\
+               schema/introductionPage.exsd
+plugin.version = 1.1.0.qualifier
+qualifier=200810071
+jars.compile.order = .
+source.. = src/
+output.. = bin/              
+javacTarget=1.5
+javacSource=1.5
diff --git a/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui.pages/icons/cheatSheet.gif b/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui.pages/icons/cheatSheet.gif
new file mode 100644
index 0000000..322c8cc
--- /dev/null
+++ b/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui.pages/icons/cheatSheet.gif
Binary files differ
diff --git a/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui.pages/icons/help.gif b/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui.pages/icons/help.gif
new file mode 100644
index 0000000..03f656f
--- /dev/null
+++ b/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui.pages/icons/help.gif
Binary files differ
diff --git a/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui.pages/icons/main.gif b/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui.pages/icons/main.gif
new file mode 100644
index 0000000..3ba659c
--- /dev/null
+++ b/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui.pages/icons/main.gif
Binary files differ
diff --git a/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui.pages/icons/saveas_edit.gif b/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui.pages/icons/saveas_edit.gif
new file mode 100644
index 0000000..466bfb1
--- /dev/null
+++ b/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui.pages/icons/saveas_edit.gif
Binary files differ
diff --git a/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui.pages/icons/saveas_wiz.png b/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui.pages/icons/saveas_wiz.png
new file mode 100644
index 0000000..4923d03
--- /dev/null
+++ b/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui.pages/icons/saveas_wiz.png
Binary files differ
diff --git a/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui.pages/icons/start.gif b/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui.pages/icons/start.gif
new file mode 100644
index 0000000..5777119
--- /dev/null
+++ b/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui.pages/icons/start.gif
Binary files differ
diff --git a/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui.pages/plugin.properties b/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui.pages/plugin.properties
new file mode 100644
index 0000000..a1d7183
--- /dev/null
+++ b/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui.pages/plugin.properties
@@ -0,0 +1,5 @@
+Introduction_page_name=Introduction
+DDL_page_name=DDL
+
+plugin.name=Sybase WorkSpace Shcema Object Editor Page
+providerName=Sybase, Inc.
\ No newline at end of file
diff --git a/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui.pages/plugin.xml b/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui.pages/plugin.xml
new file mode 100644
index 0000000..a789608
--- /dev/null
+++ b/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui.pages/plugin.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<?eclipse version="3.2"?>
+<plugin>
+   <extension-point id="introductionPage" name="Introduction Page" schema="schema/introductionPage.exsd"/>
+   <extension
+         point="org.eclipse.datatools.sqltools.schemaobjecteditor.ui.schemaObjectEditor">
+      <EditorPage
+            Class="org.eclipse.datatools.sqltools.schemaobjecteditor.ui.pages.intropage.IntroductionPage"
+            PageId="org.eclipse.datatools.sqltools.schemaobjecteditor.pages.introduction.page"
+            PageName="%Introduction_page_name"
+            Required="false"
+            VisibleByDefault="true"/>
+      <EditorPage
+            Class="org.eclipse.datatools.sqltools.schemaobjecteditor.ui.pages.ddl.DDLPage"
+            PageId="org.eclipse.datatools.sqltools.schemaobjecteditor.pages.ddl"
+            PageName="%DDL_page_name"
+            Required="false"
+            VisibleByDefault="true"/>
+   </extension>
+
+</plugin>
diff --git a/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui.pages/schema/introductionPage.exsd b/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui.pages/schema/introductionPage.exsd
new file mode 100644
index 0000000..2d9bbf1
--- /dev/null
+++ b/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui.pages/schema/introductionPage.exsd
@@ -0,0 +1,152 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!-- Schema file written by PDE -->
+<schema targetNamespace="org.eclipse.datatools.sqltools.schemaobjecteditor" xmlns="http://www.w3.org/2001/XMLSchema">
+<annotation>
+      <appinfo>
+         <meta.schema plugin="org.eclipse.datatools.sqltools.schemaobjecteditor" id="introductionPage" name="Introduction Page"/>
+      </appinfo>
+      <documentation>
+         The introduction is the first page of all schema object editor.
+      </documentation>
+   </annotation>
+
+   <element name="extension">
+      <annotation>
+         <appinfo>
+            <meta.element />
+         </appinfo>
+      </annotation>
+      <complexType>
+         <sequence>
+            <element ref="introPage"/>
+         </sequence>
+         <attribute name="point" type="string" use="required">
+            <annotation>
+               <documentation>
+                  
+               </documentation>
+            </annotation>
+         </attribute>
+         <attribute name="id" type="string">
+            <annotation>
+               <documentation>
+                  
+               </documentation>
+            </annotation>
+         </attribute>
+         <attribute name="name" type="string">
+            <annotation>
+               <documentation>
+                  
+               </documentation>
+               <appinfo>
+                  <meta.attribute translatable="true"/>
+               </appinfo>
+            </annotation>
+         </attribute>
+      </complexType>
+   </element>
+
+   <element name="introPage">
+      <annotation>
+         <appinfo>
+            <meta.element labelAttribute="name"/>
+         </appinfo>
+         <documentation>
+            An introduction page is always put as the first page of one schema object editor to give the user a simple introduction of the editor.
+         </documentation>
+      </annotation>
+      <complexType>
+         <sequence minOccurs="1" maxOccurs="unbounded">
+            <element ref="introElement"/>
+         </sequence>
+         <attribute name="Name" type="string" use="required">
+            <annotation>
+               <documentation>
+                  Name of this page
+               </documentation>
+            </annotation>
+         </attribute>
+         <attribute name="ContextHelpId" type="string">
+            <annotation>
+               <documentation>
+                  Description of the page
+               </documentation>
+            </annotation>
+         </attribute>
+      </complexType>
+   </element>
+
+   <element name="introElement">
+      <annotation>
+         <documentation>
+            An introduction page is consists of multiple introduction pages. Each introduction element occupies one row in the introduction page.
+         </documentation>
+      </annotation>
+      <complexType>
+         <attribute name="icon" type="string">
+            <annotation>
+               <documentation>
+                  The icon should be 72x72 and will appear to the left of the headers, hyperlinks and text
+               </documentation>
+               <appinfo>
+                  <meta.attribute kind="resource"/>
+               </appinfo>
+            </annotation>
+         </attribute>
+         <attribute name="heading" type="string">
+            <annotation>
+               <documentation>
+                  Heading of the element
+               </documentation>
+               <appinfo>
+                  <meta.attribute translatable="true"/>
+               </appinfo>
+            </annotation>
+         </attribute>
+         <attribute name="text" type="string">
+            <annotation>
+               <documentation>
+                  The text to describe the element.
+               </documentation>
+               <appinfo>
+                  <meta.attribute translatable="true"/>
+               </appinfo>
+            </annotation>
+         </attribute>
+         <attribute name="hyperlink" type="string">
+            <annotation>
+               <documentation>
+                  A hyperlinke associated with the element. The hyperlink would normally execute the hyperlinkaction action.
+               </documentation>
+               <appinfo>
+                  <meta.attribute translatable="true"/>
+               </appinfo>
+            </annotation>
+         </attribute>
+         <attribute name="hyperlinkaction" type="string">
+            <annotation>
+               <documentation>
+                  The action will be executed when the hyperlink is selected
+               </documentation>
+               <appinfo>
+                  <meta.attribute kind="java" basedOn="org.eclipse.datatools.sqltools.schemaobjecteditor.ui.pages.intropage.IntroHyperAction:org.eclipse.datatools.sqltools.schemaobjecteditor.ui.pages.intropage.IIntroHyperAction"/>
+               </appinfo>
+            </annotation>
+         </attribute>
+         <attribute name="id" type="string">
+            <annotation>
+               <documentation>
+                  
+               </documentation>
+            </annotation>
+         </attribute>
+      </complexType>
+   </element>
+
+
+
+
+
+
+</schema>
diff --git a/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui.pages/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/pages/LogMessages.properties b/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui.pages/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/pages/LogMessages.properties
new file mode 100644
index 0000000..0002c64
--- /dev/null
+++ b/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui.pages/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/pages/LogMessages.properties
@@ -0,0 +1,2 @@
+IntroductionSection_create_intro_action=Error occurs when creating actions on introduction page
+IntroductionSection_error_read_image=Error occurs when reading images file on introduction page
diff --git a/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui.pages/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/pages/SOEUIPagePlugin.java b/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui.pages/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/pages/SOEUIPagePlugin.java
new file mode 100644
index 0000000..863fa03
--- /dev/null
+++ b/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui.pages/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/pages/SOEUIPagePlugin.java
@@ -0,0 +1,163 @@
+/***********************************************************************************************************************
+ * Copyright (c) 2009 Sybase, Inc. 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: Sybase, Inc. - initial API and implementation
+ **********************************************************************************************************************/
+package org.eclipse.datatools.sqltools.schemaobjecteditor.ui.pages;
+
+import java.util.ResourceBundle;
+
+import org.eclipse.datatools.sqltools.schemaobjecteditor.ui.util.ColorProvider;
+import org.eclipse.datatools.sqltools.schemaobjecteditor.ui.util.ILogger;
+import org.eclipse.datatools.sqltools.schemaobjecteditor.ui.util.StatusLogger;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.IWorkbenchPage;
+import org.eclipse.ui.IWorkbenchWindow;
+import org.eclipse.ui.plugin.AbstractUIPlugin;
+import org.osgi.framework.BundleContext;
+
+/**
+ * The activator class controls the plug-in life cycle
+ */
+public class SOEUIPagePlugin extends AbstractUIPlugin
+{
+    // The plug-in ID
+    public static final String PLUGIN_ID = "org.eclipse.datatools.sqltools.schemaobjecteditor.ui.pages";
+
+    // The shared instance
+    private static SOEUIPagePlugin   plugin;
+
+    private ColorProvider      _colorProvider;
+
+    private ResourceBundle     _bundle   = ResourceBundle
+                                                 .getBundle("org.eclipse.datatools.sqltools.schemaobjecteditor.ui.pages.LogMessages");
+
+    /**
+     * The constructor
+     */
+    public SOEUIPagePlugin()
+    {
+        plugin = this;
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework.BundleContext)
+     */
+    public void start(BundleContext context) throws Exception
+    {
+        super.start(context);
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext)
+     */
+    public void stop(BundleContext context) throws Exception
+    {
+        // release those Color objects
+        if (_colorProvider != null)
+        {
+            _colorProvider.dispose();
+            _colorProvider = null;
+        }
+        plugin = null;
+        super.stop(context);
+    }
+
+    /**
+     * Returns the shared instance
+     * 
+     * @return the shared instance
+     */
+    public static SOEUIPagePlugin getDefault()
+    {
+        return plugin;
+    }
+
+    public ColorProvider getColorProvider()
+    {
+        if (_colorProvider == null)
+        {
+            _colorProvider = new ColorProvider();
+        }
+        return _colorProvider;
+    }
+
+    /**
+     * Returns a logger.
+     * 
+     * @param bundle the bundle used in logger
+     * @return a logger
+     */
+    public static ILogger getLogger(ResourceBundle bundle)
+    {
+        return new StatusLogger(getDefault().getLog(), PLUGIN_ID, bundle == null ? getDefault()._bundle : bundle);
+    }
+
+    /**
+     * Get active workbench page.
+     * <p>
+     * This method acts as a convenience for plug-in implementors.
+     * </P>
+     * 
+     * @return IWorkbenchPage the workbench page for this plug-in
+     */
+    public static IWorkbenchPage getActiveWorkbenchPage()
+    {
+        IWorkbenchPage workbenchPage = getActiveWorkbenchWindow().getActivePage();
+        if (workbenchPage != null)
+        {
+            return workbenchPage;
+        }
+        IWorkbenchPage[] workbenchPages = getActiveWorkbenchWindow().getPages();
+        if (workbenchPages.length > 0)
+        {
+            return workbenchPages[0];
+        }
+        return null;
+    }
+
+    /**
+     * Get active workbench window.
+     * <p>
+     * This method exists as a convenience for plug-in implementors.
+     * </p>
+     * 
+     * @return IWorkbenchWindow the workbench for this plug-in
+     */
+    public static IWorkbenchWindow getActiveWorkbenchWindow()
+    {
+        IWorkbenchWindow window = getDefault().getWorkbench().getActiveWorkbenchWindow();
+        if (window != null)
+        {
+            return window;
+        }
+        IWorkbenchWindow[] windows = getDefault().getWorkbench().getWorkbenchWindows();
+        if (windows.length > 0)
+        {
+            return windows[0];
+        }
+        return null;
+    }
+
+    /**
+     * @return
+     */
+    public static Shell getActiveWorkbenchShell()
+    {
+        IWorkbenchWindow window = getActiveWorkbenchWindow();
+        if (window != null)
+        {
+            return window.getShell();
+        }
+        IWorkbenchWindow[] windows = getDefault().getWorkbench().getWorkbenchWindows();
+        if (windows.length > 0)
+            return windows[0].getShell();
+        return null;
+    }
+}
diff --git a/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui.pages/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/pages/ddl/DDLPage.java b/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui.pages/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/pages/ddl/DDLPage.java
new file mode 100644
index 0000000..f7780e8
--- /dev/null
+++ b/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui.pages/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/pages/ddl/DDLPage.java
@@ -0,0 +1,277 @@
+/***********************************************************************************************************************
+ * Copyright (c) 2009 Sybase, Inc. 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: Sybase, Inc. - initial API and implementation
+ **********************************************************************************************************************/
+package org.eclipse.datatools.sqltools.schemaobjecteditor.ui.pages.ddl;
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+import org.eclipse.datatools.sqltools.common.ui.sqlstatementarea.SQLStatementArea;
+import org.eclipse.datatools.sqltools.schemaobjecteditor.ddl.IDDLProvider;
+import org.eclipse.datatools.sqltools.schemaobjecteditor.ui.ISchemaObjectEditor;
+import org.eclipse.datatools.sqltools.schemaobjecteditor.ui.ISchemaObjectEditorInput;
+import org.eclipse.datatools.sqltools.schemaobjecteditor.ui.ISchemaObjectEditorPage;
+import org.eclipse.datatools.sqltools.schemaobjecteditor.ui.core.SchemaObjectEditorPage;
+import org.eclipse.datatools.sqltools.schemaobjecteditor.ui.internal.ui.SQLSourceViewerService;
+import org.eclipse.datatools.sqltools.schemaobjecteditor.ui.pages.utils.Images;
+import org.eclipse.datatools.sqltools.schemaobjecteditor.ui.util.Util;
+import org.eclipse.jface.action.Action;
+import org.eclipse.jface.action.IAction;
+import org.eclipse.jface.action.IMenuListener;
+import org.eclipse.jface.action.IMenuManager;
+import org.eclipse.jface.action.MenuManager;
+import org.eclipse.jface.action.Separator;
+import org.eclipse.jface.text.ITextOperationTarget;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.KeyAdapter;
+import org.eclipse.swt.events.KeyEvent;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Menu;
+import org.eclipse.ui.IEditorPart;
+import org.eclipse.ui.ISharedImages;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.forms.IManagedForm;
+import org.eclipse.ui.forms.editor.FormEditor;
+import org.eclipse.ui.texteditor.ITextEditorActionConstants;
+import org.eclipse.ui.texteditor.IUpdate;
+
+/**
+ * The DDL page
+ * 
+ * @author Idull
+ */
+public class DDLPage extends SchemaObjectEditorPage implements ISchemaObjectEditorPage
+{
+    private SQLStatementArea _sta;
+    private Map              _actions = new HashMap();
+    private IDDLProvider     _provider;
+    private Color            _bgColor;
+
+    public DDLPage()
+    {
+
+    }
+
+    public DDLPage(FormEditor editor, String id, String title)
+    {
+        super(editor, id, title);
+    }
+
+    public DDLPage(String id, String title)
+    {
+        super(id, title);
+    }
+
+    protected void createFormContent(IManagedForm managedForm)
+    {
+        super.createFormContent(managedForm);
+
+        // set the ddl provider
+        initDDLProvider();
+
+        Composite comp = managedForm.getForm().getBody();
+        GridLayout layout = new GridLayout();
+        layout.marginHeight = 0;
+        layout.marginWidth = 0;
+        comp.setLayout(layout);
+
+        createSQLArea(comp);
+    }
+
+    private void initDDLProvider()
+    {
+        ISchemaObjectEditor editor = (ISchemaObjectEditor) getEditor();
+        IEditorPart part = (IEditorPart) editor;
+        ISchemaObjectEditorInput input = (ISchemaObjectEditorInput) part.getEditorInput();
+        if (input.getEditModelObject().getAdapter(IDDLProvider.class) != null)
+        {
+            _provider = (IDDLProvider) input.getEditModelObject().getAdapter(IDDLProvider.class);
+        }
+    }
+
+    private void initializeActions()
+    {
+        CommonAction action = new CommonAction(_sta.getViewer().getTextOperationTarget(), ITextOperationTarget.COPY,
+                Messages.DDLPage_copy);
+        action.setImageDescriptor(PlatformUI.getWorkbench().getSharedImages().getImageDescriptor(
+                ISharedImages.IMG_TOOL_COPY));
+        _actions.put(ITextEditorActionConstants.COPY, action);
+
+        action = new CommonAction(_sta.getViewer().getTextOperationTarget(), ITextOperationTarget.SELECT_ALL,
+                Messages.DDLPage_selectall);
+        _actions.put(ITextEditorActionConstants.SELECT_ALL, action);
+    }
+
+    private void createSQLArea(Composite comp)
+    {
+        ISchemaObjectEditor editor = (ISchemaObjectEditor) getEditor();
+        String dbType = editor.getEditorDescriptor().getVendorName() + "_" + editor.getEditorDescriptor().getVersion(); //$NON-NLS-1$
+        _sta = new SQLStatementArea(comp, SWT.NONE, new SQLSourceViewerService(), true);
+        String ddlContent = "";
+        if (_provider != null)
+        {
+            ddlContent = _provider.getDDL();
+        }
+        _sta.setInput(ddlContent, dbType);
+        _sta.setEditable(false);
+        _sta.setEnabled(true);
+        _sta.configureViewer(new SQLSourceViewerConfiguration(dbType));
+        _sta.setLayoutData(new GridData(GridData.FILL_BOTH));
+        _bgColor = Util.getBackGroundColor(_sta.getViewer().getControl().getDisplay());
+        if (_bgColor != null)
+        {
+            _sta.getViewer().getTextWidget().setBackground(_bgColor);
+        }
+
+        initializeActions();
+        createContextMenu();
+    }
+
+    private void createContextMenu()
+    {
+        final MenuManager menuMgr = new MenuManager();
+        menuMgr.setRemoveAllWhenShown(true);
+        menuMgr.addMenuListener(new IMenuListener()
+        {
+            public void menuAboutToShow(IMenuManager manager)
+            {
+                // update items' status
+                Iterator iter = _actions.values().iterator();
+                while (iter.hasNext())
+                {
+                    Object obj = iter.next();
+                    if (obj instanceof IUpdate)
+                    {
+                        IUpdate action = (IUpdate) obj;
+                        action.update();
+                    }
+                }
+                menuMgr.add((IAction) _actions.get(ITextEditorActionConstants.COPY));
+                menuMgr.add((IAction) _actions.get(ITextEditorActionConstants.SELECT_ALL));
+                menuMgr.add(new Separator());
+                String ddlContent = "";
+                if (_provider != null)
+                {
+                    ddlContent = _provider.getDDL();
+                }
+
+                SaveAsAction saveAs = new SaveAsAction(ddlContent, (ISchemaObjectEditor) getEditor(),
+                        getDatabaseIdentifier());
+                saveAs.setText(Messages.DDLPage_saveas);
+                saveAs.setImageDescriptor(Images.DESC_SAVEAS_ACTION);
+                saveAs.setEnabled(ddlContent != null && !ddlContent.trim().equals(""));
+                menuMgr.add(saveAs);
+            }
+        });
+        Menu menu = menuMgr.createContextMenu(_sta.getViewer().getTextWidget());
+        _sta.getViewer().getTextWidget().setMenu(menu);
+        _sta.getViewer().getTextWidget().addKeyListener(new KeyAdapter()
+        {
+            public void keyPressed(KeyEvent event)
+            {
+                if (event.keyCode == 'a' && (event.stateMask & SWT.CTRL) != 0)
+                {
+                    CommonAction action = (CommonAction) _actions.get(ITextEditorActionConstants.SELECT_ALL);
+                    if (action != null)
+                    {
+                        action.run();
+                    }
+                }
+            }
+        });
+    }
+
+    /**
+     * Refresh to display to new DDL
+     */
+    public void refresh()
+    {
+        super.refresh();
+        if (!isPageOpened())
+        {
+            return;
+        }
+        initDDLProvider();
+        updateDDL();
+    }
+
+    private void updateDDL()
+    {
+        String ddlContent = "";
+        if (_provider != null)
+        {
+            ddlContent = _provider.getDDL();
+        }
+        ISchemaObjectEditor editor = (ISchemaObjectEditor) getEditor();
+        String dbType = editor.getEditorDescriptor().getVendorName() + "_" + editor.getEditorDescriptor().getVersion(); //$NON-NLS-1$
+        // The SQL statement area may not be created
+        if (_sta != null)
+        {
+            _sta.setInput(ddlContent, dbType);
+        }
+    }
+
+    public void setActive(boolean active)
+    {
+        super.setActive(active);
+        if (active)
+        {
+            updateDDL();
+        }
+    }
+
+    public void dispose()
+    {
+        super.dispose();
+        if (_bgColor != null && !_bgColor.isDisposed())
+        {
+            _bgColor.dispose();
+        }
+    }
+}
+
+class CommonAction extends Action implements IUpdate
+{
+    private int                  _operationCode;
+    private ITextOperationTarget _target;
+
+    /**
+     * 
+     */
+    public CommonAction(ITextOperationTarget target, int operationCode, String itemName)
+    {
+        super();
+        _operationCode = operationCode;
+        _target = target;
+        this.setText(itemName);
+    }
+
+    /**
+     * delegate the call to ITextOperationTarget instance
+     */
+    public void run()
+    {
+        _target.doOperation(_operationCode);
+    }
+
+    public void update()
+    {
+        boolean wasEnabled = isEnabled();
+        boolean isEnabled = (_target != null && _target.canDoOperation(_operationCode));
+        setEnabled(isEnabled);
+
+        if (wasEnabled != isEnabled)
+        {
+            firePropertyChange(ENABLED, wasEnabled ? Boolean.TRUE : Boolean.FALSE, isEnabled ? Boolean.TRUE
+                    : Boolean.FALSE);
+        }
+    }
+}
diff --git a/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui.pages/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/pages/ddl/Messages.java b/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui.pages/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/pages/ddl/Messages.java
new file mode 100644
index 0000000..b9bdffa
--- /dev/null
+++ b/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui.pages/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/pages/ddl/Messages.java
@@ -0,0 +1,28 @@
+/***********************************************************************************************************************
+ * Copyright (c) 2009 Sybase, Inc. 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: Sybase, Inc. - initial API and implementation
+ **********************************************************************************************************************/
+package org.eclipse.datatools.sqltools.schemaobjecteditor.ui.pages.ddl;
+
+import org.eclipse.osgi.util.NLS;
+
+public class Messages extends NLS
+{
+    private static final String BUNDLE_NAME = Messages.class.getPackage().getName() + ".messages"; //$NON-NLS-1$
+    public static String        DDLPage_copy;
+    public static String        DDLPage_selectall;
+    public static String        DDLPage_saveas;
+
+    static
+    {
+        // initialize resource bundle
+        NLS.initializeMessages(BUNDLE_NAME, Messages.class);
+    }
+
+    private Messages()
+    {
+    }
+}
diff --git a/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui.pages/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/pages/ddl/SQLCommentScanner.java b/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui.pages/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/pages/ddl/SQLCommentScanner.java
new file mode 100644
index 0000000..4adf51c
--- /dev/null
+++ b/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui.pages/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/pages/ddl/SQLCommentScanner.java
@@ -0,0 +1,63 @@
+/***********************************************************************************************************************
+ * Copyright (c) 2009 Sybase, Inc. 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: Sybase, Inc. - initial API and implementation
+ **********************************************************************************************************************/
+package org.eclipse.datatools.sqltools.schemaobjecteditor.ui.pages.ddl;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.datatools.sqltools.schemaobjecteditor.ui.pages.SOEUIPagePlugin;
+import org.eclipse.datatools.sqltools.schemaobjecteditor.ui.util.ColorProvider;
+import org.eclipse.datatools.sqltools.sqleditor.internal.sql.AbstractSQLScanner;
+import org.eclipse.datatools.sqltools.sqleditor.internal.sql.ISQLPartitions;
+import org.eclipse.jface.text.TextAttribute;
+import org.eclipse.jface.text.rules.Token;
+
+/**
+ * 
+ * @author Li Huang
+ */
+public class SQLCommentScanner extends AbstractSQLScanner
+{
+
+    ColorProvider _provider = SOEUIPagePlugin.getDefault().getColorProvider();
+    String        _commentKey;
+
+    public SQLCommentScanner(String commentKey)
+    {
+        _commentKey = commentKey;
+        initialize();
+    }
+
+    protected Token getToken()
+    {
+
+        Token token = new Token(null);
+        if (_commentKey.equals(ISQLPartitions.SQL_COMMENT))
+        {
+            token = new Token(new TextAttribute(_provider.getColor(ColorProvider.SINGLE_LINE_COMMENT)));
+        }
+        else if (_commentKey.equals(ISQLPartitions.SQL_MULTILINE_COMMENT))
+        {
+            token = new Token(new TextAttribute(_provider.getColor(ColorProvider.MULTI_LINE_COMMENT)));
+        }
+        return token;
+    }
+
+    /*
+     * @see AbstractSQLScanner#createRules()
+     */
+    protected List createRules()
+    {
+        List list = new ArrayList();
+        Token defaultToken = getToken();
+        setDefaultReturnToken(defaultToken);
+
+        return list;
+    }
+
+}
diff --git a/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui.pages/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/pages/ddl/SQLSourceViewerConfiguration.java b/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui.pages/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/pages/ddl/SQLSourceViewerConfiguration.java
new file mode 100644
index 0000000..3208dc9
--- /dev/null
+++ b/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui.pages/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/pages/ddl/SQLSourceViewerConfiguration.java
@@ -0,0 +1,128 @@
+/***********************************************************************************************************************
+ * Copyright (c) 2009 Sybase, Inc. 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: Sybase, Inc. - initial API and implementation
+ **********************************************************************************************************************/
+package org.eclipse.datatools.sqltools.schemaobjecteditor.ui.pages.ddl;
+
+import org.eclipse.datatools.sqltools.core.SQLToolsFacade;
+import org.eclipse.datatools.sqltools.sqleditor.internal.SQLEditorPlugin;
+import org.eclipse.datatools.sqltools.sqleditor.internal.sql.ISQLPartitions;
+import org.eclipse.datatools.sqltools.sqleditor.internal.sql.SQLCodeScanner;
+import org.eclipse.datatools.sqltools.sqleditor.internal.sql.SQLDoubleClickStrategy;
+import org.eclipse.datatools.sqltools.sqleditor.internal.sql.SQLPartitionScanner;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.ITextDoubleClickStrategy;
+import org.eclipse.jface.text.presentation.IPresentationReconciler;
+import org.eclipse.jface.text.presentation.PresentationReconciler;
+import org.eclipse.jface.text.rules.DefaultDamagerRepairer;
+import org.eclipse.jface.text.rules.ITokenScanner;
+import org.eclipse.jface.text.source.ISourceViewer;
+import org.eclipse.jface.text.source.SourceViewerConfiguration;
+
+/**
+ * This is a common implementation of <code>SourceViewerConfiguration </code> for DMP. This configuraion is used for SQL
+ * Statements preview which supports: <li>Syntax high lighting <li>Double click strategy
+ * <p>
+ * If user wants to support content assistant and autoEditStrategy, user needs to subclass this class with overridding
+ * some motheds or subclass <code>SourceViewerConfiguration </code> directly.
+ * 
+ * @author Shifeng Yu
+ * 
+ */
+public class SQLSourceViewerConfiguration extends SourceViewerConfiguration
+{
+    private ITokenScanner _SQLCodeScanner;
+    private ITokenScanner _SQLStringScanner;
+    private ITokenScanner _multilineCommentScanner;
+    private ITokenScanner _singlelineCommentScanner;
+
+    /**
+     * The SQL identifier which is enclosed in double quotes scanner.
+     */
+    private ITokenScanner _SQLDoubleQuotesIdentifierScanner;
+
+    private String        _dbType = null;
+
+    /**
+     * Instantiates a new SQLSourceViewerConfiguration with the parameter:database type.
+     * 
+     * @param dbType
+     */
+    public SQLSourceViewerConfiguration(String dbType)
+    {
+        this._dbType = dbType;
+        initializeScanners();
+    }
+
+    /**
+     * Initializes the scanners.
+     * 
+     */
+    private void initializeScanners()
+    {
+        _SQLCodeScanner = new SQLCodeScanner(SQLEditorPlugin.getDefault().getSQLColorProvider());
+        ((SQLCodeScanner) _SQLCodeScanner).setSQLSyntax(SQLToolsFacade.getSQLSyntax(this._dbType));
+        _multilineCommentScanner = new SQLCommentScanner(ISQLPartitions.SQL_MULTILINE_COMMENT);
+        _singlelineCommentScanner = new SQLCommentScanner(ISQLPartitions.SQL_COMMENT);
+        _SQLDoubleQuotesIdentifierScanner = new SingleTokenSQLScanner(ISQLPartitions.SQL_DOUBLE_QUOTES_IDENTIFIER);
+        _SQLStringScanner = new SingleTokenSQLScanner(ISQLPartitions.SQL_STRING);
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see
+     * org.eclipse.jface.text.source.SourceViewerConfiguration#getPresentationReconciler(org.eclipse.jface.text.source
+     * .ISourceViewer)
+     */
+    public IPresentationReconciler getPresentationReconciler(ISourceViewer sourceViewer)
+    {
+        PresentationReconciler reconciler = new PresentationReconciler();
+        reconciler.setDocumentPartitioning(ISQLPartitions.SQL_PARTITIONING);
+
+        // rule for default text
+        DefaultDamagerRepairer dr = new DefaultDamagerRepairer(this._SQLCodeScanner);
+        reconciler.setDamager(dr, IDocument.DEFAULT_CONTENT_TYPE);
+        reconciler.setRepairer(dr, IDocument.DEFAULT_CONTENT_TYPE);
+
+        // rule for multiline comments
+        dr = new DefaultDamagerRepairer(this._multilineCommentScanner);
+        reconciler.setDamager(dr, ISQLPartitions.SQL_MULTILINE_COMMENT);
+        reconciler.setRepairer(dr, ISQLPartitions.SQL_MULTILINE_COMMENT);
+
+        // rule for singleline comments
+        dr = new DefaultDamagerRepairer(this._singlelineCommentScanner);
+        reconciler.setDamager(dr, ISQLPartitions.SQL_COMMENT);
+        reconciler.setRepairer(dr, ISQLPartitions.SQL_COMMENT);
+
+        // rule for SQL Strings
+        dr = new DefaultDamagerRepairer(this._SQLStringScanner);
+        reconciler.setDamager(dr, ISQLPartitions.SQL_STRING);
+        reconciler.setRepairer(dr, ISQLPartitions.SQL_STRING);
+
+        // rule for double quoted identifiers
+        dr = new DefaultDamagerRepairer(this._SQLDoubleQuotesIdentifierScanner);
+        reconciler.setDamager(dr, ISQLPartitions.SQL_DOUBLE_QUOTES_IDENTIFIER);
+        reconciler.setRepairer(dr, ISQLPartitions.SQL_DOUBLE_QUOTES_IDENTIFIER);
+
+        dr = new DefaultDamagerRepairer(this._SQLCodeScanner);
+        reconciler.setDamager(dr, SQLPartitionScanner.SQL_CODE);
+        reconciler.setRepairer(dr, SQLPartitionScanner.SQL_CODE);
+        return reconciler;
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see
+     * org.eclipse.jface.text.source.SourceViewerConfiguration#getDoubleClickStrategy(org.eclipse.jface.text.source.
+     * ISourceViewer, java.lang.String)
+     */
+    public ITextDoubleClickStrategy getDoubleClickStrategy(ISourceViewer sourceViewer, String contentType)
+    {
+        return new SQLDoubleClickStrategy();
+    }
+}
diff --git a/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui.pages/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/pages/ddl/SaveAsAction.java b/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui.pages/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/pages/ddl/SaveAsAction.java
new file mode 100644
index 0000000..b4abeea
--- /dev/null
+++ b/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui.pages/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/pages/ddl/SaveAsAction.java
@@ -0,0 +1,64 @@
+/***********************************************************************************************************************
+ * Copyright (c) 2009 Sybase, Inc. 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: Sybase, Inc. - initial API and implementation
+ **********************************************************************************************************************/
+package org.eclipse.datatools.sqltools.schemaobjecteditor.ui.pages.ddl;
+
+import org.eclipse.datatools.sqltools.common.ui.dialog.SaveAsDialog;
+import org.eclipse.datatools.sqltools.core.DatabaseIdentifier;
+import org.eclipse.datatools.sqltools.core.SQLToolsFacade;
+import org.eclipse.datatools.sqltools.editor.core.connection.ISQLEditorConnectionInfo;
+import org.eclipse.datatools.sqltools.schemaobjecteditor.ui.ISchemaObjectEditor;
+import org.eclipse.datatools.sqltools.schemaobjecteditor.ui.ISchemaObjectEditorHandler;
+import org.eclipse.datatools.sqltools.schemaobjecteditor.ui.core.DefaultSchemaObjectEditorHandler;
+import org.eclipse.datatools.sqltools.schemaobjecteditor.ui.pages.SOEUIPagePlugin;
+import org.eclipse.datatools.sqltools.sqleditor.SQLEditor;
+import org.eclipse.datatools.sqltools.sqleditor.SQLEditorConnectionInfo;
+import org.eclipse.jface.action.Action;
+import org.eclipse.ui.IEditorPart;
+
+/**
+ * Save as action in DDL page
+ * 
+ * @author Idull
+ */
+public class SaveAsAction extends Action
+{
+    private ISchemaObjectEditor _editor;
+    private String              _content;
+    private DatabaseIdentifier  _databaseIdentifier;
+
+    public SaveAsAction(String content, ISchemaObjectEditor editor, DatabaseIdentifier databaseIdentifier)
+    {
+        super();
+        _content = content;
+        _editor = editor;
+        _databaseIdentifier = databaseIdentifier;
+    }
+
+    public void run()
+    {
+        SaveAsDialog dlg = new SaveAsDialog(SOEUIPagePlugin.getActiveWorkbenchShell(), _content);
+        dlg.setOriginalName(_editor.getDisplayName() + "_ddl.sql");
+
+        ISchemaObjectEditorHandler handler = _editor.getEditorHandler();
+        if (handler instanceof DefaultSchemaObjectEditorHandler)
+        {
+            boolean isOpen = ((DefaultSchemaObjectEditorHandler) handler).getOpenFileAfterSaveasOption();
+            dlg.setOpenMode(isOpen);
+        }
+        dlg.open();
+        IEditorPart editor = dlg.getEditor();
+        if (editor != null && (editor instanceof SQLEditor))
+        {
+            ISQLEditorConnectionInfo connInfo = new SQLEditorConnectionInfo(SQLToolsFacade
+                    .getConfigurationByProfileName(_databaseIdentifier.getProfileName())
+                    .getDatabaseVendorDefinitionId(), _databaseIdentifier.getProfileName(), _databaseIdentifier
+                    .getDBname(), _databaseIdentifier.getDBname());
+            ((SQLEditor) editor).setConnectionInfo(connInfo);
+        }
+    }
+}
diff --git a/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui.pages/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/pages/ddl/SingleTokenSQLScanner.java b/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui.pages/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/pages/ddl/SingleTokenSQLScanner.java
new file mode 100644
index 0000000..da0e06c
--- /dev/null
+++ b/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui.pages/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/pages/ddl/SingleTokenSQLScanner.java
@@ -0,0 +1,63 @@
+/***********************************************************************************************************************
+ * Copyright (c) 2009 Sybase, Inc. 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: Sybase, Inc. - initial API and implementation
+ **********************************************************************************************************************/
+package org.eclipse.datatools.sqltools.schemaobjecteditor.ui.pages.ddl;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.datatools.sqltools.schemaobjecteditor.ui.pages.SOEUIPagePlugin;
+import org.eclipse.datatools.sqltools.schemaobjecteditor.ui.util.ColorProvider;
+import org.eclipse.datatools.sqltools.sqleditor.internal.sql.AbstractSQLScanner;
+import org.eclipse.datatools.sqltools.sqleditor.internal.sql.ISQLPartitions;
+import org.eclipse.jface.text.TextAttribute;
+import org.eclipse.jface.text.rules.Token;
+
+/**
+ * @author Li Huang
+ * 
+ */
+public class SingleTokenSQLScanner extends AbstractSQLScanner
+{
+
+    ColorProvider _provider = SOEUIPagePlugin.getDefault().getColorProvider();
+    String        _tokenKey;
+
+    public SingleTokenSQLScanner(String tokenKey)
+    {
+        _tokenKey = tokenKey;
+        initialize();
+    }
+
+    protected Token getToken()
+    {
+
+        Token token = new Token(null);
+        if (_tokenKey.equals(ISQLPartitions.SQL_STRING))
+        {
+            token = new Token(new TextAttribute(_provider.getColor(ColorProvider.STRING)));
+        }
+        else if (_tokenKey.equals(ISQLPartitions.SQL_DOUBLE_QUOTES_IDENTIFIER))
+        {
+            token = new Token(new TextAttribute(_provider.getColor(ColorProvider.STRING)));
+        }
+        return token;
+    }
+
+    /*
+     * @see AbstractSQLScanner#createRules()
+     */
+    protected List createRules()
+    {
+        List list = new ArrayList();
+        Token defaultToken = getToken();
+        setDefaultReturnToken(defaultToken);
+
+        return list;
+    }
+
+}
diff --git a/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui.pages/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/pages/ddl/messages.properties b/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui.pages/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/pages/ddl/messages.properties
new file mode 100644
index 0000000..c961698
--- /dev/null
+++ b/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui.pages/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/pages/ddl/messages.properties
@@ -0,0 +1,3 @@
+DDLPage_copy=&Copy
+DDLPage_selectall=Select &All
+DDLPage_saveas=&Save As...
diff --git a/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui.pages/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/pages/intropage/DisplayHelpAction.java b/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui.pages/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/pages/intropage/DisplayHelpAction.java
new file mode 100644
index 0000000..b9ae0fd
--- /dev/null
+++ b/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui.pages/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/pages/intropage/DisplayHelpAction.java
@@ -0,0 +1,90 @@
+/***********************************************************************************************************************
+ * Copyright (c) 2009 Sybase, Inc. 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: Sybase, Inc. - initial API and implementation
+ **********************************************************************************************************************/
+package org.eclipse.datatools.sqltools.schemaobjecteditor.ui.pages.intropage;
+
+import org.eclipse.datatools.help.HelpUtil;
+import org.eclipse.datatools.sqltools.schemaobjecteditor.ui.ISchemaObjectEditorPage;
+import org.eclipse.help.HelpSystem;
+import org.eclipse.help.IContext;
+import org.eclipse.jface.action.Action;
+import org.eclipse.ui.PlatformUI;
+
+/**
+ * 
+ * @author Hui Cao
+ * 
+ */
+public class DisplayHelpAction extends Action implements IIntroHyperAction
+{
+    String _contextHelpId = null;
+    String _pluginId      = null;
+
+    public DisplayHelpAction()
+    {
+
+    }
+
+    public DisplayHelpAction(String text)
+    {
+        super(text);
+
+    }
+
+    public DisplayHelpAction(String text, String contextHelpId)
+    {
+        super(text);
+        _contextHelpId = contextHelpId;
+    }
+
+    private void displayHelp()
+    {
+        String contextId = null;
+        if (_contextHelpId != null && _pluginId != null)
+        {
+            contextId = HelpUtil.getContextId(_contextHelpId, _pluginId);
+        }
+
+        if ((contextId != null) && (contextId.length() > 0))
+        {
+            IContext context = HelpSystem.getContext(contextId);
+
+            if (context == null || (context.getRelatedTopics().length == 0)
+                    || (context.getRelatedTopics()[0].getHref() == null))
+            {
+                PlatformUI.getWorkbench().getHelpSystem().displayHelp();
+            }
+            else if (context.getRelatedTopics().length > 1)
+            {
+                PlatformUI.getWorkbench().getHelpSystem().displayHelp(contextId);
+            }
+            else
+            {
+                PlatformUI.getWorkbench().getHelpSystem().displayHelpResource(context.getRelatedTopics()[0].getHref());
+            }
+        }
+        else
+        {
+            PlatformUI.getWorkbench().getHelpSystem().displayHelp();
+        }
+
+    }
+
+    public void run()
+    {
+        displayHelp();
+    }
+
+    public void setPage(ISchemaObjectEditorPage page)
+    {
+        if (_contextHelpId == null && page instanceof IntroductionPage)
+        {
+            _contextHelpId = ((IntroductionPage) page).getContextHelpId();
+            _pluginId = page.getEditorDescriptor().getPluginId();
+        }
+    }
+}
diff --git a/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui.pages/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/pages/intropage/IIntroHyperAction.java b/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui.pages/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/pages/intropage/IIntroHyperAction.java
new file mode 100644
index 0000000..388cc70
--- /dev/null
+++ b/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui.pages/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/pages/intropage/IIntroHyperAction.java
@@ -0,0 +1,26 @@
+/***********************************************************************************************************************
+ * Copyright (c) 2009 Sybase, Inc. 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: Sybase, Inc. - initial API and implementation
+ **********************************************************************************************************************/
+package org.eclipse.datatools.sqltools.schemaobjecteditor.ui.pages.intropage;
+
+import org.eclipse.datatools.sqltools.schemaobjecteditor.ui.ISchemaObjectEditorPage;
+import org.eclipse.jface.action.IAction;
+
+/**
+ * Will be called to set the page
+ * 
+ * @author Idull
+ */
+public interface IIntroHyperAction extends IAction
+{
+    /**
+     * Sets the page's reference
+     * 
+     * @param page
+     */
+    public void setPage(ISchemaObjectEditorPage page);
+}
diff --git a/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui.pages/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/pages/intropage/ImageContainer.java b/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui.pages/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/pages/intropage/ImageContainer.java
new file mode 100644
index 0000000..302d7ce
--- /dev/null
+++ b/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui.pages/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/pages/intropage/ImageContainer.java
@@ -0,0 +1,86 @@
+/***********************************************************************************************************************
+ * Copyright (c) 2009 Sybase, Inc. 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: Sybase, Inc. - initial API and implementation
+ **********************************************************************************************************************/
+package org.eclipse.datatools.sqltools.schemaobjecteditor.ui.pages.intropage;
+
+import org.eclipse.draw2d.ColorConstants;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.ControlEvent;
+import org.eclipse.swt.events.ControlListener;
+import org.eclipse.swt.events.DisposeEvent;
+import org.eclipse.swt.events.DisposeListener;
+import org.eclipse.swt.events.PaintEvent;
+import org.eclipse.swt.events.PaintListener;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.widgets.Composite;
+
+/**
+ * A composite containing an image
+ * 
+ * @author Idull
+ */
+public class ImageContainer extends Composite
+{
+
+    private Image _image;
+
+    public ImageContainer(Composite parent)
+    {
+        super(parent, SWT.NONE);
+        setBackground(ColorConstants.white);
+
+        addPaintListener(new PaintListener()
+        {
+
+            public void paintControl(PaintEvent e)
+            {
+                if (_image != null)
+                {
+                    e.gc.drawImage(_image, 0, 0);
+                }
+            }
+        });
+
+        addControlListener(new ControlListener()
+        {
+
+            public void controlMoved(ControlEvent e)
+            {
+
+            }
+
+            public void controlResized(ControlEvent e)
+            {
+                if (_image != null)
+                {
+                    setSize(_image.getBounds().width, _image.getBounds().height);
+                }
+            }
+        });
+
+        addDisposeListener(new DisposeListener()
+        {
+
+            public void widgetDisposed(DisposeEvent e)
+            {
+                if (_image != null && !_image.isDisposed())
+                {
+                    _image.dispose();
+                }
+            }
+        });
+    }
+
+    public void setImage(Image image)
+    {
+        _image = image;
+        if (_image != null)
+        {
+            setSize(_image.getBounds().width, _image.getBounds().height);
+        }
+    }
+}
diff --git a/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui.pages/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/pages/intropage/IntroConstants.java b/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui.pages/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/pages/intropage/IntroConstants.java
new file mode 100644
index 0000000..8695407
--- /dev/null
+++ b/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui.pages/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/pages/intropage/IntroConstants.java
@@ -0,0 +1,35 @@
+/***********************************************************************************************************************
+ * Copyright (c) 2009 Sybase, Inc. 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: Sybase, Inc. - initial API and implementation
+ **********************************************************************************************************************/
+package org.eclipse.datatools.sqltools.schemaobjecteditor.ui.pages.intropage;
+
+/**
+ * Constants for introduction page
+ * 
+ * @author Idull
+ */
+public class IntroConstants
+{
+    public static final String EXTENSION_POINT_NAME_INTRO_PAGE                = "introductionPage";
+    public static final String EXTENSION_POINT_INTRO_PAGE                     = "introPage";
+    public static final String EXTENSION_POINT_INTRO_PAGE_NAME                = "Name";
+    public static final String EXTENSION_POINT_INTRO_PAGE_HELPID              = "ContextHelpId";
+    public static final String EXTENSION_POINT_INTRO_ELEMENT                  = "introElement";
+    public static final String EXTENSION_POINT_INTRO_ELEMENT_ICON             = "icon";
+    public static final String EXTENSION_POINT_INTRO_ELEMENT_HEADING          = "heading";
+    public static final String EXTENSION_POINT_INTRO_ELEMENT_TEXT             = "text";
+    public static final String EXTENSION_POINT_INTRO_ELEMENT_ID               = "id";
+    public static final String EXTENSION_POINT_INTRO_ELEMENT_HYPERLINK        = "hyperlink";
+    public static final String EXTENSION_POINT_INTRO_ELEMENT_HYPERLINK_ACTION = "hyperlinkaction";
+    public static final String INTRODUCTION_PAGE_ID                           = "org.eclipse.datatools.sqltools.schemaobjecteditor.pages.introduction.page";
+
+    // default element ids
+    public static final String HELP_ELEMENT_ID                                = "help";
+    public static final String CHEAT_SHEET_ELEMENT_ID                         = "cheatsheet";
+    public static final String START_ELEMENT_ID                               = "start";
+    public static final String DESCRIPTION_ELEMENT_ID                         = "description";
+}
diff --git a/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui.pages/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/pages/intropage/IntroHyperAction.java b/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui.pages/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/pages/intropage/IntroHyperAction.java
new file mode 100644
index 0000000..18c26e2
--- /dev/null
+++ b/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui.pages/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/pages/intropage/IntroHyperAction.java
@@ -0,0 +1,25 @@
+/***********************************************************************************************************************
+ * Copyright (c) 2009 Sybase, Inc. 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: Sybase, Inc. - initial API and implementation
+ **********************************************************************************************************************/
+package org.eclipse.datatools.sqltools.schemaobjecteditor.ui.pages.intropage;
+
+import org.eclipse.datatools.sqltools.schemaobjecteditor.ui.ISchemaObjectEditorPage;
+import org.eclipse.jface.action.Action;
+
+/**
+ * 
+ * @author Idull
+ */
+public class IntroHyperAction extends Action implements IIntroHyperAction
+{
+    protected ISchemaObjectEditorPage _introPage;
+
+    public void setPage(ISchemaObjectEditorPage page)
+    {
+        _introPage = page;
+    }
+}
diff --git a/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui.pages/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/pages/intropage/IntroductionPage.java b/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui.pages/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/pages/intropage/IntroductionPage.java
new file mode 100644
index 0000000..041fb4f
--- /dev/null
+++ b/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui.pages/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/pages/intropage/IntroductionPage.java
@@ -0,0 +1,68 @@
+/***********************************************************************************************************************
+ * Copyright (c) 2009 Sybase, Inc. 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: Sybase, Inc. - initial API and implementation
+ **********************************************************************************************************************/
+package org.eclipse.datatools.sqltools.schemaobjecteditor.ui.pages.intropage;
+
+import org.eclipse.datatools.help.HelpUtil;
+import org.eclipse.datatools.sqltools.schemaobjecteditor.ui.core.SchemaObjectEditorPage;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.forms.IManagedForm;
+import org.eclipse.ui.forms.widgets.TableWrapData;
+import org.eclipse.ui.forms.widgets.TableWrapLayout;
+
+/**
+ * The introduction page
+ * 
+ * @author Idull
+ */
+public class IntroductionPage extends SchemaObjectEditorPage
+{
+    private String _contextHelpId = null;
+
+    protected void createFormContent(IManagedForm managedForm)
+    {
+
+        super.createFormContent(managedForm);
+        Composite comp = managedForm.getForm().getBody();
+        managedForm.getForm().setText(Messages.IntroductionPage_page_title); //$NON-NLS-1$
+        TableWrapLayout layout = new TableWrapLayout();
+        comp.setLayout(layout);
+
+        Composite container = managedForm.getToolkit().createComposite(comp);
+        layout = new TableWrapLayout();
+        container.setLayout(layout);
+        TableWrapData td = new TableWrapData(TableWrapData.FILL_GRAB, TableWrapData.FILL_GRAB);
+        container.setLayoutData(td);
+
+        String pageExtensionId = getPageDescriptor().getPageExtensionId();
+
+        IntroductionSection introSection = new IntroductionSection(pageExtensionId, getEditor().getToolkit(),
+                Messages.IntroductionPage_section_title, container.getDisplay(), SWT.NONE); //$NON-NLS-1$
+        _contextHelpId = introSection.getContextHelpId();
+        introSection.setPage(this);
+        introSection.createControl(container, 1, _contextHelpId);
+        introSection.setPluginId(getEditorDescriptor().getPluginId());
+        if (introSection.getPageName() != null && introSection.getPageName().trim().length() != 0)
+        {
+            managedForm.getForm().setText(introSection.getPageName());
+        }
+    }
+
+    public void createPartControl(Composite parent)
+    {
+        super.createPartControl(parent);
+        PlatformUI.getWorkbench().getHelpSystem().setHelp(parent,
+                HelpUtil.getContextId(_contextHelpId, getEditorDescriptor().getPluginId()));
+    }
+
+    public String getContextHelpId()
+    {
+        return _contextHelpId;
+    }
+}
diff --git a/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui.pages/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/pages/intropage/IntroductionSection.java b/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui.pages/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/pages/intropage/IntroductionSection.java
new file mode 100644
index 0000000..fc96900
--- /dev/null
+++ b/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui.pages/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/pages/intropage/IntroductionSection.java
@@ -0,0 +1,261 @@
+/***********************************************************************************************************************
+ * Copyright (c) 2009 Sybase, Inc. 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: Sybase, Inc. - initial API and implementation
+ **********************************************************************************************************************/
+package org.eclipse.datatools.sqltools.schemaobjecteditor.ui.pages.intropage;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.core.runtime.IExtension;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.datatools.sqltools.schemaobjecteditor.ui.ISchemaObjectEditorPage;
+import org.eclipse.datatools.sqltools.schemaobjecteditor.ui.common.CollapseableSection;
+import org.eclipse.datatools.sqltools.schemaobjecteditor.ui.pages.SOEUIPagePlugin;
+import org.eclipse.datatools.sqltools.schemaobjecteditor.ui.util.ILogger;
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.jface.resource.JFaceResources;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.ui.forms.events.HyperlinkAdapter;
+import org.eclipse.ui.forms.events.HyperlinkEvent;
+import org.eclipse.ui.forms.widgets.FormText;
+import org.eclipse.ui.forms.widgets.FormToolkit;
+import org.eclipse.ui.forms.widgets.Hyperlink;
+import org.eclipse.ui.forms.widgets.TableWrapData;
+import org.eclipse.ui.forms.widgets.TableWrapLayout;
+import org.osgi.framework.Bundle;
+
+/**
+ * The introduction section
+ * 
+ * @author Idull
+ */
+public class IntroductionSection extends CollapseableSection
+{
+    private String                  _pageExtensionId;
+    private String                  _pageName;
+    private ISchemaObjectEditorPage _page;
+    private ILogger                 _log = SOEUIPagePlugin.getLogger(null);
+    private List                    _images;
+
+    public IntroductionSection(String pageExtensionId, FormToolkit toolkit, String title, Display display, int estyle)
+    {
+        super(toolkit, title, display, estyle);
+        this._pageExtensionId = pageExtensionId;
+        IConfigurationElement element = getExtension();
+        if (element != null)
+        {
+            _helpContextId = element.getAttribute(IntroConstants.EXTENSION_POINT_INTRO_PAGE_HELPID);
+        }
+        _images = new ArrayList();
+    }
+
+    public void createSectionContent(Composite parent)
+    {
+        // Set layout and layout data for section
+        getSection().setLayoutData(new TableWrapData(TableWrapData.FILL_GRAB, TableWrapData.FILL_GRAB));
+        getSection().setLayout(new TableWrapLayout());
+        parent.setLayoutData(new TableWrapData(TableWrapData.FILL_GRAB, TableWrapData.FILL_GRAB));
+
+        TableWrapLayout layout = new TableWrapLayout();
+        layout.numColumns = 2;
+        layout.makeColumnsEqualWidth = false;
+        layout.horizontalSpacing = 20;
+        layout.verticalSpacing = 20;
+        parent.setLayout(layout);
+
+        IConfigurationElement element = getExtension();
+        if (element != null)
+        {
+            _helpContextId = element.getAttribute(IntroConstants.EXTENSION_POINT_INTRO_PAGE_HELPID);
+            _pageName = element.getAttribute(IntroConstants.EXTENSION_POINT_INTRO_PAGE_NAME);
+
+            IConfigurationElement[] introElements = element.getChildren(IntroConstants.EXTENSION_POINT_INTRO_ELEMENT);
+            for (int i = 0; i < introElements.length; i++)
+            {
+                String icon = introElements[i].getAttribute(IntroConstants.EXTENSION_POINT_INTRO_ELEMENT_ICON);
+                String id = introElements[i].getAttribute(IntroConstants.EXTENSION_POINT_INTRO_ELEMENT_ID);
+                String heading = introElements[i].getAttribute(IntroConstants.EXTENSION_POINT_INTRO_ELEMENT_HEADING);
+                String text = introElements[i].getAttribute(IntroConstants.EXTENSION_POINT_INTRO_ELEMENT_TEXT);
+                String hyperlink = introElements[i]
+                        .getAttribute(IntroConstants.EXTENSION_POINT_INTRO_ELEMENT_HYPERLINK);
+                String hyperlinkaction = introElements[i]
+                        .getAttribute(IntroConstants.EXTENSION_POINT_INTRO_ELEMENT_HYPERLINK_ACTION);
+                IIntroHyperAction hyperAction = null;
+
+                String pluginNS = introElements[i].getDeclaringExtension().getNamespaceIdentifier();
+                Bundle bundle = Platform.getBundle(pluginNS);
+                Image image = readImage(bundle, icon);
+
+                if (id != null)
+                {
+                    PredefinedIntroSection defSec = (PredefinedIntroSection) PredefinedIntroSection.SECTIONS.get(id);
+                    if (defSec != null)
+                    {
+                        if (image == null && icon == null)
+                        {
+                            image = defSec.getIcon().createImage();
+                        }
+                        if (heading == null)
+                        {
+                            heading = defSec.getHeading();
+                        }
+                        if (text == null)
+                        {
+                            text = defSec.getText();
+                        }
+                        if (hyperlink == null)
+                        {
+                            hyperlink = defSec.getHyperlink();
+                        }
+                        if (hyperlinkaction == null)
+                        {
+                            hyperAction = defSec.getHyperlinkAction();
+                        }
+                    }
+                }
+
+                if (image != null)
+                {
+                    ImageContainer ic = new ImageContainer(parent);
+                    ic.setImage(image);
+                    TableWrapData td = new TableWrapData();
+                    td.rowspan = 2;
+                    ic.setLayoutData(td);
+                    _images.add(image);
+                }
+                else
+                {
+                    // occupy the position
+                    Composite comp = new Composite(parent, SWT.NONE);
+                    TableWrapData td = new TableWrapData();
+                    td.rowspan = 2;
+                    comp.setLayoutData(td);
+                }
+
+                // if heading is specified, we won't display the hyperlink
+                if (heading != null && heading.trim().length() != 0)
+                {
+                    Label head = _toolkit.createLabel(parent, heading);
+                    head.setFont(JFaceResources.getHeaderFont());
+                }
+                else if (hyperlink != null && hyperlink.trim().length() != 0)
+                {
+                    Hyperlink hl = _toolkit.createHyperlink(parent, hyperlink, SWT.NONE);
+
+                    if (hyperAction == null && hyperlinkaction != null)
+                    {
+                        try
+                        {
+                            hyperAction = (IIntroHyperAction) introElements[i]
+                                    .createExecutableExtension(IntroConstants.EXTENSION_POINT_INTRO_ELEMENT_HYPERLINK_ACTION);
+                        }
+                        catch (Exception e)
+                        {
+                            _log.error("IntroductionSection_create_intro_action", e);
+                        }
+                    }
+
+                    if (hyperAction != null)
+                    {
+                        hyperAction.setPage(_page);
+                    }
+                    final IIntroHyperAction hAction = hyperAction;
+                    hl.addHyperlinkListener(new HyperlinkAdapter()
+                    {
+
+                        public void linkActivated(HyperlinkEvent e)
+                        {
+                            if (hAction != null)
+                            {
+                                hAction.run();
+                            }
+                        }
+                    });
+
+                }
+                else
+                {
+                    // occupy the position
+                    _toolkit.createLabel(parent, "");
+                }
+
+                FormText txt = _toolkit.createFormText(parent, false);
+                txt.setText(text == null ? "" : text, false, false);
+            }
+        }
+    }
+
+    private IConfigurationElement getExtension()
+    {
+        if (_pageExtensionId == null || _pageExtensionId.trim().length() == 0)
+        {
+            return null;
+        }
+
+        // Can not fail editor due to introduction page's error
+        IExtension extension = Platform.getExtensionRegistry().getExtension(SOEUIPagePlugin.PLUGIN_ID,
+                IntroConstants.EXTENSION_POINT_NAME_INTRO_PAGE, _pageExtensionId);
+        if (extension == null)
+        {
+            return null;
+        }
+        IConfigurationElement[] elements = extension.getConfigurationElements();
+
+        // There should not be more than one page
+        return elements[0];
+    }
+
+    private Image readImage(Bundle bundle, String iconLoc)
+    {
+        if (bundle == null || iconLoc == null || bundle.getEntry(iconLoc) == null)
+        {
+            return null;
+        }
+        try
+        {
+            ImageDescriptor desp = ImageDescriptor.createFromURL(bundle.getEntry(iconLoc));
+            return desp.createImage();
+        }
+        catch (Exception ex)
+        {
+            _log.error("IntroductionSection_error_read_image", ex);
+            return null;
+        }
+    }
+
+    public String getContextHelpId()
+    {
+        return _helpContextId;
+    }
+
+    public String getPageName()
+    {
+        return _pageName;
+    }
+
+    public void setPage(ISchemaObjectEditorPage _page)
+    {
+        this._page = _page;
+    }
+
+    public void dispose()
+    {
+        super.dispose();
+        Iterator iter = _images.iterator();
+        while (iter.hasNext())
+        {
+            Image i = (Image) iter.next();
+            i.dispose();
+        }
+    }
+}
diff --git a/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui.pages/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/pages/intropage/Messages.java b/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui.pages/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/pages/intropage/Messages.java
new file mode 100644
index 0000000..1cae4b8
--- /dev/null
+++ b/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui.pages/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/pages/intropage/Messages.java
@@ -0,0 +1,53 @@
+/***********************************************************************************************************************
+ * Copyright (c) 2009 Sybase, Inc. 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: Sybase, Inc. - initial API and implementation
+ **********************************************************************************************************************/
+package org.eclipse.datatools.sqltools.schemaobjecteditor.ui.pages.intropage;
+
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
+
+import org.eclipse.osgi.util.NLS;
+
+public class Messages extends NLS
+{
+    private static final String         BUNDLE_NAME     = Messages.class.getPackage().getName() + ".messages"; //$NON-NLS-1$
+
+    private static final ResourceBundle RESOURCE_BUNDLE = ResourceBundle.getBundle(BUNDLE_NAME);
+
+    private Messages()
+    {
+    }
+
+    public static String getString(String key)
+    {
+        try
+        {
+            return RESOURCE_BUNDLE.getString(key);
+        }
+        catch (MissingResourceException e)
+        {
+            return '!' + key + '!';
+        }
+    }
+
+    public static String IntroductionPage_page_title;
+    public static String IntroductionPage_section_title;
+    public static String start;
+    public static String start_desc;
+    public static String cheatsheet;
+    public static String cheatsheet_desc;
+    public static String help;
+    public static String help_desc;
+    public static String default_heading;
+    public static String properites_loading_exception;
+
+    static
+    {
+        NLS.initializeMessages(BUNDLE_NAME, Messages.class);
+    }
+
+}
diff --git a/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui.pages/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/pages/intropage/PredefinedIntroSection.java b/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui.pages/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/pages/intropage/PredefinedIntroSection.java
new file mode 100644
index 0000000..1e40699
--- /dev/null
+++ b/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui.pages/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/pages/intropage/PredefinedIntroSection.java
@@ -0,0 +1,132 @@
+/***********************************************************************************************************************
+ * Copyright (c) 2009 Sybase, Inc. 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: Sybase, Inc. - initial API and implementation
+ **********************************************************************************************************************/
+package org.eclipse.datatools.sqltools.schemaobjecteditor.ui.pages.intropage;
+
+import java.util.HashMap;
+
+import org.eclipse.datatools.sqltools.schemaobjecteditor.ui.pages.utils.Images;
+import org.eclipse.jface.resource.ImageDescriptor;
+
+/**
+ * 
+ * @author Hui Cao
+ * 
+ */
+public class PredefinedIntroSection
+{
+    private String            id              = null;
+    private String            heading         = null;
+    private String            hyperlink       = null;
+    private IIntroHyperAction hyperlinkAction = null;
+    private String            text            = null;
+    private ImageDescriptor   icon            = null;
+
+    public PredefinedIntroSection(String id, String heading, String hyperlink, String text, ImageDescriptor icon,
+            IIntroHyperAction hyperlinkAction)
+    {
+        super();
+        this.id = id;
+        this.heading = heading;
+        this.hyperlink = hyperlink;
+        this.text = text;
+        this.icon = icon;
+        this.hyperlinkAction = hyperlinkAction;
+    }
+
+    public String getId()
+    {
+        return id;
+    }
+
+    public void setId(String id)
+    {
+        this.id = id;
+    }
+
+    public String getHeading()
+    {
+        return heading;
+    }
+
+    public void setHeading(String heading)
+    {
+        this.heading = heading;
+    }
+
+    public String getHyperlink()
+    {
+        return hyperlink;
+    }
+
+    public void setHyperlink(String hyperlink)
+    {
+        this.hyperlink = hyperlink;
+    }
+
+    public String getText()
+    {
+        return text;
+    }
+
+    public void setText(String text)
+    {
+        this.text = text;
+    }
+
+    public ImageDescriptor getIcon()
+    {
+        return icon;
+    }
+
+    public void setIcon(ImageDescriptor icon)
+    {
+        this.icon = icon;
+    }
+
+    public IIntroHyperAction getHyperlinkAction()
+    {
+        if (id.equals(IntroConstants.START_ELEMENT_ID))
+        {
+            hyperlinkAction = new StartEditAction();
+        }
+        else if (id.equals(IntroConstants.HELP_ELEMENT_ID))
+        {
+            hyperlinkAction = new DisplayHelpAction();
+        }
+        return hyperlinkAction;
+    }
+
+    public void setHyperlinkAction(IIntroHyperAction hyperlinkAction)
+    {
+        this.hyperlinkAction = hyperlinkAction;
+    }
+
+    public static final PredefinedIntroSection DESCRIPTION = new PredefinedIntroSection(
+                                                                   IntroConstants.DESCRIPTION_ELEMENT_ID,
+                                                                   Messages.default_heading, null, null,
+                                                                   Images.DESC_MAIN, null);
+
+    public static final PredefinedIntroSection START       = new PredefinedIntroSection(
+                                                                   IntroConstants.START_ELEMENT_ID, null,
+                                                                   Messages.start, Messages.start_desc,
+                                                                   Images.DESC_START, new StartEditAction());
+
+    public static final PredefinedIntroSection HELP        = new PredefinedIntroSection(IntroConstants.HELP_ELEMENT_ID,
+                                                                   null, Messages.help, Messages.help_desc,
+                                                                   Images.DESC_HELP, new DisplayHelpAction());
+
+    public static HashMap                      SECTIONS    = new HashMap();
+
+    static
+    {
+        SECTIONS.put(IntroConstants.DESCRIPTION_ELEMENT_ID, DESCRIPTION);
+        SECTIONS.put(IntroConstants.START_ELEMENT_ID, START);
+        SECTIONS.put(IntroConstants.HELP_ELEMENT_ID, HELP);
+    }
+
+}
diff --git a/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui.pages/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/pages/intropage/StartEditAction.java b/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui.pages/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/pages/intropage/StartEditAction.java
new file mode 100644
index 0000000..c55e70a
--- /dev/null
+++ b/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui.pages/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/pages/intropage/StartEditAction.java
@@ -0,0 +1,41 @@
+/***********************************************************************************************************************
+ * Copyright (c) 2009 Sybase, Inc. 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: Sybase, Inc. - initial API and implementation
+ **********************************************************************************************************************/
+package org.eclipse.datatools.sqltools.schemaobjecteditor.ui.pages.intropage;
+
+import org.eclipse.datatools.sqltools.schemaobjecteditor.ui.core.SchemaObjectEditor;
+
+/**
+ * 
+ * @author Hui Cao
+ * 
+ */
+public class StartEditAction extends IntroHyperAction implements IIntroHyperAction
+{
+    public StartEditAction()
+    {
+
+    }
+
+    public void run()
+    {
+        if (_introPage != null && _introPage.getEditor() != null)
+        {
+            SchemaObjectEditor editor = (SchemaObjectEditor) _introPage.getEditor();
+            int currentInd = editor.getCurrentPageIndex();
+            if (currentInd == 0)
+            {
+                editor.setActivePage(1);
+            }
+            else
+            {
+                editor.setActivePage(0);
+            }
+        }
+        super.run();
+    }
+}
diff --git a/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui.pages/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/pages/intropage/messages.properties b/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui.pages/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/pages/intropage/messages.properties
new file mode 100644
index 0000000..1d70e58
--- /dev/null
+++ b/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui.pages/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/pages/intropage/messages.properties
@@ -0,0 +1,12 @@
+IntroductionPage_page_title=Introduction Page
+IntroductionPage_section_title=Introduction
+
+start=Start
+start_desc=Start to use...
+cheatsheet=Cheat sheet
+cheatsheet_desc=Launch the cheat sheet
+help=Help
+help_desc=Start the help system
+default_heading=This editor allows you to edit the SQL object's definition
+
+properites_loading_exception=Initial properties error
diff --git a/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui.pages/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/pages/utils/Images.java b/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui.pages/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/pages/utils/Images.java
new file mode 100644
index 0000000..f2b678e
--- /dev/null
+++ b/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui.pages/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/pages/utils/Images.java
@@ -0,0 +1,117 @@
+/***********************************************************************************************************************
+ * Copyright (c) 2009 Sybase, Inc. 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: Sybase, Inc. - initial API and implementation
+ **********************************************************************************************************************/
+package org.eclipse.datatools.sqltools.schemaobjecteditor.ui.pages.utils;
+
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.HashMap;
+import java.util.Iterator;
+
+import org.eclipse.datatools.sqltools.schemaobjecteditor.ui.pages.SOEUIPagePlugin;
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.jface.resource.ImageRegistry;
+import org.eclipse.swt.graphics.Image;
+
+/**
+ * Utility class to load images
+ * 
+ * @author Idull
+ */
+public class Images
+{
+    private static final String         NAME_PREFIX        = "org.eclipse.datatools.sqltools.schemaobjecteditor.pages";
+    private static final int            NAME_PREFIX_LENGTH = NAME_PREFIX.length();
+    private static URL                  _baseURL           = null;
+    // The plugin image registry
+    private static ImageRegistry        fgImageRegistry    = null;
+    private static HashMap              fgAvoidSWTErrorMap = new HashMap();
+    static
+    {
+        String pathSuffix = "icons/";
+        _baseURL = SOEUIPagePlugin.getDefault().getBundle().getEntry(pathSuffix);
+    }
+
+    // Save as wizard
+    public static final String          IMG_SAVEAS         = NAME_PREFIX + "saveas_wiz.png";
+    public static final ImageDescriptor DESC_SAVEAS        = createManaged(IMG_SAVEAS);
+
+    // Save as icon
+    public static final String          IMG_SAVEAS_ACTION  = NAME_PREFIX + "saveas_edit.gif";
+    public static final ImageDescriptor DESC_SAVEAS_ACTION = createManaged(IMG_SAVEAS_ACTION);
+
+    // main icon
+    public static final String          IMG_MAIN           = NAME_PREFIX + "main.gif";
+    public static final ImageDescriptor DESC_MAIN          = createManaged(IMG_MAIN);
+
+    // start icon
+    public static final String          IMG_START          = NAME_PREFIX + "start.gif";
+    public static final ImageDescriptor DESC_START         = createManaged(IMG_START);
+
+    // cheatsheet icon
+    public static final String          IMG_CHEATSHEET     = NAME_PREFIX + "cheatSheet.gif";
+    public static final ImageDescriptor DESC_CHEATSHEET    = createManaged(IMG_CHEATSHEET);
+
+    // help icon
+    public static final String          IMG_HELP           = NAME_PREFIX + "help.gif";
+    public static final ImageDescriptor DESC_HELP          = createManaged(IMG_HELP);
+
+    /**
+     * Returns the image managed under the given key in this registry.
+     * 
+     * @param key the image's key
+     * @return the image managed under the given key
+     */
+    public static Image get(String key)
+    {
+        return getImageRegistry().get(key);
+    }
+
+    /**
+     * Helper method to convert HashMap to ImageRegistry
+     * 
+     * @return the image registry
+     */
+    static ImageRegistry getImageRegistry()
+    {
+        if (fgImageRegistry == null)
+        {
+            fgImageRegistry = new ImageRegistry();
+            for (Iterator iter = fgAvoidSWTErrorMap.keySet().iterator(); iter.hasNext();)
+            {
+                String key = (String) iter.next();
+                fgImageRegistry.put(key, (ImageDescriptor) fgAvoidSWTErrorMap.get(key));
+            }
+            fgAvoidSWTErrorMap = null;
+        }
+        return fgImageRegistry;
+    }
+
+    private static ImageDescriptor createManaged(String name)
+    {
+        try
+        {
+            ImageDescriptor result = ImageDescriptor.createFromURL(makeIconFileURL(name.substring(NAME_PREFIX_LENGTH)));
+            fgAvoidSWTErrorMap.put(name, result);
+            return result;
+        }
+        catch (MalformedURLException e)
+        {
+            return ImageDescriptor.getMissingImageDescriptor();
+        }
+
+    }
+
+    private static URL makeIconFileURL(String name) throws MalformedURLException
+    {
+        if (_baseURL == null)
+            throw new MalformedURLException();
+        StringBuffer buffer = new StringBuffer();
+        buffer.append(name);
+        return new URL(_baseURL, buffer.toString());
+    }
+}
diff --git a/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui.pages/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/pages/utils/Messages.java b/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui.pages/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/pages/utils/Messages.java
new file mode 100644
index 0000000..00120ef
--- /dev/null
+++ b/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui.pages/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/pages/utils/Messages.java
@@ -0,0 +1,22 @@
+/***********************************************************************************************************************
+ * Copyright (c) 2009 Sybase, Inc. 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: Sybase, Inc. - initial API and implementation
+ **********************************************************************************************************************/
+package org.eclipse.datatools.sqltools.schemaobjecteditor.ui.pages.utils;
+
+import org.eclipse.osgi.util.NLS;
+
+public class Messages extends NLS
+{
+    private static final String BUNDLE_NAME = Messages.class.getPackage().getName() + ".messages";
+    static
+    {
+        NLS.initializeMessages(BUNDLE_NAME, Messages.class);
+    }
+
+    public static String        StatusLogger_no_bundle;
+    public static String        StatusLogger_possible_args;
+}
diff --git a/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui.pages/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/pages/utils/messages.properties b/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui.pages/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/pages/utils/messages.properties
new file mode 100644
index 0000000..cc1cce6
--- /dev/null
+++ b/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui.pages/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/pages/utils/messages.properties
@@ -0,0 +1,2 @@
+StatusLogger_no_bundle=No resource bundle has been set for the Logger
+StatusLogger_possible_args=\ possible args: {0}, {1}, {2}, {3}
\ No newline at end of file
diff --git a/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui/.classpath b/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui/.classpath
new file mode 100644
index 0000000..751c8f2
--- /dev/null
+++ b/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui/.classpath
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="src" path="src"/>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
+	<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+	<classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui/.project b/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui/.project
new file mode 100644
index 0000000..45f7c21
--- /dev/null
+++ b/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui/.project
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>org.eclipse.datatools.sqltools.schemaobjecteditor.ui</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.pde.ManifestBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.pde.SchemaBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.pde.PluginNature</nature>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+	</natures>
+</projectDescription>
diff --git a/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui/META-INF/MANIFEST.MF b/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..aca3e26
--- /dev/null
+++ b/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui/META-INF/MANIFEST.MF
@@ -0,0 +1,33 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: %plugin.name
+Bundle-SymbolicName: org.eclipse.datatools.sqltools.schemaobjecteditor.ui;singleton:=true
+Bundle-Version: 1.1.0.qualifier
+Bundle-Activator: org.eclipse.datatools.sqltools.schemaobjecteditor.ui.internal.SOEUIPlugin
+Bundle-Vendor: %providerName
+Bundle-Localization: plugin
+Require-Bundle: org.eclipse.core.runtime;bundle-version="[3.2.0,4.0.0)",
+ org.eclipse.core.resources;bundle-version="[3.2.0,4.0.0)",
+ org.eclipse.draw2d;bundle-version="[3.2.0,4.0.0)",
+ org.eclipse.help;bundle-version="[3.2.0,4.0.0)",
+ org.eclipse.ui;bundle-version="[3.2.0,4.0.0)",
+ org.eclipse.ui.ide;bundle-version="[3.2.0,4.0.0)",
+ org.eclipse.ui.navigator;bundle-version="[3.2.0,4.0.0)",
+ org.eclipse.ui.cheatsheets;bundle-version="[3.2.0,4.0.0)",
+ org.eclipse.ui.editors;bundle-version="[3.2.0,4.0.0)",
+ org.eclipse.ui.workbench.texteditor;bundle-version="[3.2.0,4.0.0)",
+ org.eclipse.ui.forms;bundle-version="[3.2.0,4.0.0)",
+ org.eclipse.datatools.connectivity.sqm.core.ui;bundle-version="[0.9.0,1.5.0)",
+ org.eclipse.datatools.sqltools.common.ui;bundle-version="[0.9.0,1.5.0)",
+ org.eclipse.datatools.sqltools.editor.core;bundle-version="[0.9.0,1.5.0)",
+ org.eclipse.datatools.sqltools.sqleditor;bundle-version="[0.9.0,1.5.0)",
+ org.eclipse.datatools.sqltools.schemaobjecteditor;bundle-version="[0.9.0,1.5.0)"
+Eclipse-LazyStart: true
+Export-Package: org.eclipse.datatools.sqltools.schemaobjecteditor.ui,
+ org.eclipse.datatools.sqltools.schemaobjecteditor.ui.action,
+ org.eclipse.datatools.sqltools.schemaobjecteditor.ui.common,
+ org.eclipse.datatools.sqltools.schemaobjecteditor.ui.core,
+ org.eclipse.datatools.sqltools.schemaobjecteditor.ui.extensions,
+ org.eclipse.datatools.sqltools.schemaobjecteditor.ui.internal.ui,
+ org.eclipse.datatools.sqltools.schemaobjecteditor.ui.util
+Bundle-ClassPath: .
diff --git a/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui/build.properties b/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui/build.properties
new file mode 100644
index 0000000..aa489ef
--- /dev/null
+++ b/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui/build.properties
@@ -0,0 +1,13 @@
+bin.includes = plugin.xml,\
+               .,\
+               plugin.properties,\
+               META-INF/MANIFEST.MF,\
+               icons/,\
+               schema/schemaObjectEditor.exsd
+plugin.version = 1.1.0.qualifier
+qualifier=200810071
+jars.compile.order = .
+source.. = src/
+output.. = bin/              
+javacTarget=1.5
+javacSource=1.5
diff --git a/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui/icons/baseeditor.gif b/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui/icons/baseeditor.gif
new file mode 100644
index 0000000..ef7809c
--- /dev/null
+++ b/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui/icons/baseeditor.gif
Binary files differ
diff --git a/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui/icons/help.gif b/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui/icons/help.gif
new file mode 100644
index 0000000..9d70301
--- /dev/null
+++ b/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui/icons/help.gif
Binary files differ
diff --git a/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui/icons/refresh_from_server.gif b/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui/icons/refresh_from_server.gif
new file mode 100644
index 0000000..e383147
--- /dev/null
+++ b/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui/icons/refresh_from_server.gif
Binary files differ
diff --git a/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui/icons/revert_editor.gif b/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui/icons/revert_editor.gif
new file mode 100644
index 0000000..eae118a
--- /dev/null
+++ b/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui/icons/revert_editor.gif
Binary files differ
diff --git a/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui/icons/save_to_database.gif b/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui/icons/save_to_database.gif
new file mode 100644
index 0000000..0f6fc07
--- /dev/null
+++ b/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui/icons/save_to_database.gif
Binary files differ
diff --git a/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui/icons/saveas_wiz.png b/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui/icons/saveas_wiz.png
new file mode 100644
index 0000000..4923d03
--- /dev/null
+++ b/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui/icons/saveas_wiz.png
Binary files differ
diff --git a/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui/plugin.properties b/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui/plugin.properties
new file mode 100644
index 0000000..6c8841f
--- /dev/null
+++ b/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui/plugin.properties
@@ -0,0 +1,7 @@
+SchemaEditor.preference.page.name=Schema Object Editor Configuration
+SchemaEditor.name=Schema Object Editor
+
+plugin.name=Sybase WorkSpace Schema Object Editor Framework
+providerName=Sybase, Inc.
+schemaobjecteditor.command.refreshfromserver = Refresh from Server
+schemaobjecteditor.command.revert = Revert Object
\ No newline at end of file
diff --git a/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui/plugin.xml b/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui/plugin.xml
new file mode 100644
index 0000000..4f39f18
--- /dev/null
+++ b/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui/plugin.xml
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<?eclipse version="3.2"?>
+<plugin>
+   <extension-point id="schemaObjectEditor" name="org.eclipse.datatools.sqltools.schemaObjectEditor" schema="schema/schemaObjectEditor.exsd"/>
+   <extension
+         point="org.eclipse.ui.editors">
+      <editor
+            class="org.eclipse.datatools.sqltools.schemaobjecteditor.ui.core.SchemaObjectEditor"
+            contributorClass="org.eclipse.datatools.sqltools.schemaobjecteditor.ui.internal.core.SchemaObjectEditorActionBarContributor"
+            default="true"
+            icon="icons/baseeditor.gif"
+            id="org.eclipse.datatools.sqltools.schemaobjecteditor.editor"
+            name="%SchemaEditor.name"/>
+   </extension>
+   <extension
+         point="org.eclipse.ui.preferencePages">
+      <page
+            category="org.eclipse.datatools.connectivity.sqm.core.internal.ui.preferences.data"
+            class="org.eclipse.datatools.sqltools.schemaobjecteditor.ui.internal.preference.SchemaObjectEditorPreferencePage"
+            id="org.eclipse.datatools.sqltools.schemaobjecteditor.page1"
+            name="%SchemaEditor.preference.page.name"/>
+   </extension>
+   <extension
+         point="org.eclipse.core.runtime.preferences">
+      <initializer class="org.eclipse.datatools.sqltools.schemaobjecteditor.ui.internal.preference.SchemaObjectEditorPreferenceInitializer"/>
+   </extension>
+   <extension
+         point="org.eclipse.ui.commands">
+      <command
+            defaultHandler="org.eclipse.datatools.sqltools.schemaobjecteditor.ui.action.RefreshSchemaEditorAction"
+            id="refresh.schema.editor.action.id"
+            name="%schemaobjecteditor.command.refreshfromserver">
+      </command>
+      <command
+            defaultHandler="org.eclipse.datatools.sqltools.schemaobjecteditor.ui.action.RevertSchemaEditorAction"
+            id="revert.schema.editor.action.id"
+            name="%schemaobjecteditor.command.revert">
+      </command>
+   </extension>
+</plugin>
diff --git a/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui/schema/schemaObjectEditor.exsd b/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui/schema/schemaObjectEditor.exsd
new file mode 100644
index 0000000..50cee8a
--- /dev/null
+++ b/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui/schema/schemaObjectEditor.exsd
@@ -0,0 +1,362 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!-- Schema file written by PDE -->
+<schema targetNamespace="org.eclipse.datatools.sqltools.schemaobjecteditor" xmlns="http://www.w3.org/2001/XMLSchema">
+<annotation>
+      <appinfo>
+         <meta.schema plugin="org.eclipse.datatools.sqltools.schemaobjecteditor" id="schemaObjectEditor" name="org.eclipse.datatools.sqltools.schemaObjectEditor"/>
+      </appinfo>
+      <documentation>
+         This extension point is used to enable the consumers to define a new multiple pages based database schema object editor.
+      </documentation>
+   </annotation>
+
+   <element name="extension">
+      <annotation>
+         <appinfo>
+            <meta.element />
+         </appinfo>
+      </annotation>
+      <complexType>
+         <sequence>
+            <element ref="SchemaObjectEditor" minOccurs="0" maxOccurs="unbounded"/>
+            <element ref="EditorPage" minOccurs="0" maxOccurs="unbounded"/>
+         </sequence>
+         <attribute name="point" type="string" use="required">
+            <annotation>
+               <documentation>
+                  
+               </documentation>
+            </annotation>
+         </attribute>
+         <attribute name="id" type="string">
+            <annotation>
+               <documentation>
+                  
+               </documentation>
+            </annotation>
+         </attribute>
+         <attribute name="name" type="string">
+            <annotation>
+               <documentation>
+                  
+               </documentation>
+               <appinfo>
+                  <meta.attribute translatable="true"/>
+               </appinfo>
+            </annotation>
+         </attribute>
+      </complexType>
+   </element>
+
+   <element name="SchemaObjectEditor">
+      <annotation>
+         <appinfo>
+            <meta.element labelAttribute="EditorName" icon="Icon"/>
+         </appinfo>
+         <documentation>
+            A schema editor is used to edit a schema object, such as a table, a stored procedure, a view, etc.. 
+It can contain several pages, it&apos;s easy for the consumer to add a page, just add a EditorPage under SchemaObjectEditor node, also, it is the consumer&apos;s responsibility to create the content in a page.
+The schema object editor framework does not define any model for the consumer, so the consumer need to define the model and implement the subject-obsevers mechanism.
+The consumer can define the behaviour of the editor by defining the ConfigurationClass. Also, it can contribute actions via ContributorClass.
+         </documentation>
+      </annotation>
+      <complexType>
+         <sequence>
+            <element ref="EditorPage" minOccurs="0" maxOccurs="unbounded"/>
+            <element ref="ReferencedPage" minOccurs="0" maxOccurs="unbounded"/>
+            <element ref="ReferencedEditor" minOccurs="0" maxOccurs="1"/>
+            <element ref="DefaultPagesOrder" minOccurs="0" maxOccurs="1"/>
+         </sequence>
+         <attribute name="EditorId" type="string" use="required">
+            <annotation>
+               <documentation>
+                  The id of the extended editor
+               </documentation>
+            </annotation>
+         </attribute>
+         <attribute name="EditorName" type="string" use="required">
+            <annotation>
+               <documentation>
+                  The name of an editor, by default, the name of the editor will be displayed as the part name of the editor.
+               </documentation>
+            </annotation>
+         </attribute>
+         <attribute name="VendorName" type="string" use="required">
+            <annotation>
+               <documentation>
+                  The database vendor name for whom the editor is defined. The vendor name and the version will uniquely identify a database product.
+               </documentation>
+            </annotation>
+         </attribute>
+         <attribute name="Version" type="string">
+            <annotation>
+               <documentation>
+                  The database version for which the editor is defined. The vendor name and the version will uniquely identify a database product.
+               </documentation>
+            </annotation>
+         </attribute>
+         <attribute name="ObjectTypeId" type="string" use="required">
+            <annotation>
+               <documentation>
+                  The object type id for which the editor is defined. The consumer can use any form for this attribute, once it defines the id for a specific object, it need to use this id to open the editor.  See SchemaEditorUtils.openEditor()
+               </documentation>
+            </annotation>
+         </attribute>
+         <attribute name="Handler" type="string" use="required">
+            <annotation>
+               <documentation>
+                  Implement this interface to define the behaviour of the editor.
+               </documentation>
+               <appinfo>
+                  <meta.attribute kind="java" basedOn="org.eclipse.datatools.sqltools.schemaobjecteditor.ui.core.DefaultSchemaObjectEditorHandler:org.eclipse.datatools.sqltools.schemaobjecteditor.ui.ISchemaObjectEditorHandler"/>
+               </appinfo>
+            </annotation>
+         </attribute>
+         <attribute name="VisibilityConfigurable" type="boolean">
+            <annotation>
+               <documentation>
+                  If need to let the end-user to set the visibility of pages on preference page, select this attribute to true. If it is false for an editor, then all pages will be shown.
+               </documentation>
+            </annotation>
+         </attribute>
+         <attribute name="Icon" type="string">
+            <annotation>
+               <documentation>
+                  The icon for this editor, if not specified, will use the default icon defined by the extension point.
+               </documentation>
+               <appinfo>
+                  <meta.attribute kind="resource"/>
+               </appinfo>
+            </annotation>
+         </attribute>
+         <attribute name="ContributorClass" type="string">
+            <annotation>
+               <documentation>
+                  Use this to contribute new actions.
+               </documentation>
+               <appinfo>
+                  <meta.attribute kind="java" basedOn="org.eclipse.datatools.sqltools.schemaobjecteditor.ui.core.DefaultSchemaObjectEditorActionBarContributor:org.eclipse.datatools.sqltools.schemaobjecteditor.ui.ISchemaObjectEditorActionBarContributor"/>
+               </appinfo>
+            </annotation>
+         </attribute>
+         <attribute name="MustBeFirstWhenShown" type="string">
+            <annotation>
+               <documentation>
+                  Specify a page which will be always the first page (The end user can not move it down on the page visibility/order preference page). For example, the introduction page of an editor should always be displayed as the first pge.
+               </documentation>
+            </annotation>
+         </attribute>
+         <attribute name="MustBeLastWhenShown" type="string">
+            <annotation>
+               <documentation>
+                  Specify a page which will be always the last page (The end user can not move it up on the page visibility/order preference page). For example, the source code page should be always displayed as the last page.
+               </documentation>
+            </annotation>
+         </attribute>
+         <attribute name="ObjectTypeName" type="string">
+            <annotation>
+               <documentation>
+                  
+               </documentation>
+            </annotation>
+         </attribute>
+      </complexType>
+   </element>
+
+   <element name="EditorPage">
+      <annotation>
+         <appinfo>
+            <meta.element labelAttribute="PageName"/>
+         </appinfo>
+         <documentation>
+            An editor page is contained in a multiple pages editor.
+         </documentation>
+      </annotation>
+      <complexType>
+         <attribute name="PageId" type="string" use="required">
+            <annotation>
+               <documentation>
+                  The id of this page, it SHOULD be unique for its editor.
+               </documentation>
+            </annotation>
+         </attribute>
+         <attribute name="PageName" type="string" use="required">
+            <annotation>
+               <documentation>
+                  The name of this page, it SHOULD be unique for its editor.
+               </documentation>
+            </annotation>
+         </attribute>
+         <attribute name="VisibleByDefault" type="boolean">
+            <annotation>
+               <documentation>
+                  Will be selected to be displayed on the preference page by default if this is configured to be true.
+               </documentation>
+            </annotation>
+         </attribute>
+         <attribute name="Required" type="boolean">
+            <annotation>
+               <documentation>
+                  If this attribute is configured to be true, then this page can not be selected to be unvisible on the preference page.
+               </documentation>
+            </annotation>
+         </attribute>
+         <attribute name="Class" type="string" use="required">
+            <annotation>
+               <documentation>
+                  The form page class.
+               </documentation>
+               <appinfo>
+                  <meta.attribute kind="java" basedOn="org.eclipse.datatools.sqltools.schemaobjecteditor.ui.core.SchemaObjectEditorPage:org.eclipse.datatools.sqltools.schemaobjecteditor.ui.ISchemaObjectEditorPage"/>
+               </appinfo>
+            </annotation>
+         </attribute>
+         <attribute name="ContextHelpId" type="string">
+            <annotation>
+               <documentation>
+                  If a context help id is specified, a small help icon will appear on the top-right corner of this page, if the end user clicks this icon, the related context help page will pop up.
+               </documentation>
+            </annotation>
+         </attribute>
+         <attribute name="ObjectClassType" type="string">
+            <annotation>
+               <documentation>
+                  
+               </documentation>
+            </annotation>
+         </attribute>
+      </complexType>
+   </element>
+
+   <element name="ReferencedPage">
+      <annotation>
+         <appinfo>
+            <meta.element labelAttribute="PageId"/>
+         </appinfo>
+         <documentation>
+            Reference a page defined in other editor. This is to reuse some pages.
+         </documentation>
+      </annotation>
+      <complexType>
+         <attribute name="EditorId" type="string">
+            <annotation>
+               <documentation>
+                  The id of the editor in which the page is contained.
+               </documentation>
+            </annotation>
+         </attribute>
+         <attribute name="PageId" type="string" use="required">
+            <annotation>
+               <documentation>
+                  The id of the referenced page
+               </documentation>
+            </annotation>
+         </attribute>
+         <attribute name="PageExtensionId" type="string">
+            <annotation>
+               <documentation>
+                  This attribute is used in the following scenario: An extension point is defined for one page, this page will be common used by many editors, for example introduction page, the consumer need to extend the introduction page to provide their own introduction information in the extension (Declararively not programmtically), thus we need to know which extension the introduction page is using for a specific editor, use this extension id, the BASE introductin page can generate a introduction page properly.
+               </documentation>
+            </annotation>
+         </attribute>
+      </complexType>
+   </element>
+
+   <element name="Excludes">
+      <annotation>
+         <documentation>
+            When referencing an exsiting editor, all pages in that editor will be added into this editor. To exclude some pages in the referencing editor, using this element.
+         </documentation>
+      </annotation>
+      <complexType>
+         <sequence minOccurs="0" maxOccurs="unbounded">
+            <element ref="ExcludePage"/>
+         </sequence>
+      </complexType>
+   </element>
+
+   <element name="ReferencedEditor">
+      <annotation>
+         <documentation>
+            If a referenced editor is specified, all the attributes will be ignored except DatabaseName, DatabaseVersion, ObjectTypeId and the containing pages.
+A common usage of referenced editor is: For a higer version database, it may reuse the lower version&apos;s editor, but need to add more pages.
+ATTN: The refrenced pages/editors in the referenced editor will not be included.
+         </documentation>
+      </annotation>
+      <complexType>
+         <sequence>
+            <element ref="Excludes" minOccurs="0" maxOccurs="unbounded"/>
+         </sequence>
+         <attribute name="EditorId" type="string">
+            <annotation>
+               <documentation>
+                  The id of the editor to be referenced.
+               </documentation>
+            </annotation>
+         </attribute>
+      </complexType>
+   </element>
+
+   <element name="ExcludePage">
+      <annotation>
+         <appinfo>
+            <meta.element labelAttribute="PageId"/>
+         </appinfo>
+         <documentation>
+            The excluded page in the referenced editor
+         </documentation>
+      </annotation>
+      <complexType>
+         <attribute name="PageId" type="string" use="required">
+            <annotation>
+               <documentation>
+                  The id of the excluded page
+               </documentation>
+            </annotation>
+         </attribute>
+      </complexType>
+   </element>
+
+   <element name="DefaultPagesOrder">
+      <annotation>
+         <documentation>
+            Define the default order of pages which are REQUIRED or visible BY DEFAULT.
+         </documentation>
+      </annotation>
+      <complexType>
+         <sequence minOccurs="0" maxOccurs="unbounded">
+            <element ref="OrderItem"/>
+         </sequence>
+      </complexType>
+   </element>
+
+   <element name="OrderItem">
+      <annotation>
+         <appinfo>
+            <meta.element labelAttribute="PageId"/>
+         </appinfo>
+      </annotation>
+      <complexType>
+         <attribute name="PageId" type="string">
+            <annotation>
+               <documentation>
+                  The page id
+               </documentation>
+            </annotation>
+         </attribute>
+         <attribute name="OrderNum" type="string">
+            <annotation>
+               <documentation>
+                  The order number of the page, the number should be greater than 0, the order number of several pages need not to be continous, for example, if an editor has 3 pages which are REQUIRED or visible BY DEFAULT, the order number can be: 1, 2, 3 respectively, or 1,3,6  etc.
+               </documentation>
+            </annotation>
+         </attribute>
+      </complexType>
+   </element>
+
+
+
+
+
+
+</schema>
diff --git a/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/IDisablementPart.java b/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/IDisablementPart.java
new file mode 100644
index 0000000..b9f1af9
--- /dev/null
+++ b/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/IDisablementPart.java
@@ -0,0 +1,18 @@
+/***********************************************************************************************************************
+ * Copyright (c) 2009 Sybase, Inc. 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: Sybase, Inc. - initial API and implementation
+ **********************************************************************************************************************/
+package org.eclipse.datatools.sqltools.schemaobjecteditor.ui;
+
+/**
+ * Instance of this interface is used to set part control of an editor page enabled or not.
+ * 
+ * @author Idull
+ */
+public interface IDisablementPart
+{
+    public void enable(boolean enabled);
+}
diff --git a/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/IErrorItem.java b/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/IErrorItem.java
new file mode 100644
index 0000000..6987c05
--- /dev/null
+++ b/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/IErrorItem.java
@@ -0,0 +1,43 @@
+/***********************************************************************************************************************
+ * Copyright (c) 2009 Sybase, Inc. 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: Sybase, Inc. - initial API and implementation
+ **********************************************************************************************************************/
+package org.eclipse.datatools.sqltools.schemaobjecteditor.ui;
+
+/**
+ * Instance of this interface is used to describe an error item on an editor page.
+ * 
+ * @author Idull
+ */
+public interface IErrorItem
+{
+    public static final int OK      = 0;
+    public static final int INFO    = 1;
+    public static final int WARNING = 2;
+    public static final int ERROR   = 4;
+    public static final int CANCEL  = 8;
+
+    /**
+     * Returns the source object on which the error occurs. (For future use)
+     * 
+     * @return
+     */
+    public Object getSource();
+
+    /**
+     * Returns the error message
+     * 
+     * @return
+     */
+    public String getMessage();
+
+    /**
+     * Returns the severity. @see Diagnostic
+     * 
+     * @return
+     */
+    public int getSeverity();
+}
diff --git a/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/IResourceChangeEvent.java b/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/IResourceChangeEvent.java
new file mode 100644
index 0000000..3c8e9f8
--- /dev/null
+++ b/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/IResourceChangeEvent.java
@@ -0,0 +1,43 @@
+/***********************************************************************************************************************
+ * Copyright (c) 2009 Sybase, Inc. 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: Sybase, Inc. - initial API and implementation
+ **********************************************************************************************************************/
+package org.eclipse.datatools.sqltools.schemaobjecteditor.ui;
+
+/**
+ * The resource change event
+ * 
+ * @author Idull
+ */
+public interface IResourceChangeEvent
+{
+    public static final int PRE_DELETE  = 0;
+    public static final int POST_DELETE = 1;
+    public static final int PRE_RENAME  = 2;
+    public static final int POST_RENAME = 3;
+    public static final int PRE_CHANGE  = 4;
+    public static final int POST_CHANGE = 5;
+
+    /**
+     * Returns the type of the event
+     * 
+     * @see #PRE_DELETE
+     * @see #POST_DELETE
+     * @see #PRE_RENAME
+     * @see #POST_RENAME
+     * @see #PRE_CHANGE
+     * @see #POST_CHANGE
+     * @return
+     */
+    public int getType();
+
+    /**
+     * Returns the resouce object, which will be useful when the resource is changed.
+     * 
+     * @return
+     */
+    public Object getSource();
+}
diff --git a/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/IResourceChangeHandler.java b/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/IResourceChangeHandler.java
new file mode 100644
index 0000000..3df6a7c
--- /dev/null
+++ b/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/IResourceChangeHandler.java
@@ -0,0 +1,23 @@
+/***********************************************************************************************************************
+ * Copyright (c) 2009 Sybase, Inc. 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: Sybase, Inc. - initial API and implementation
+ **********************************************************************************************************************/
+package org.eclipse.datatools.sqltools.schemaobjecteditor.ui;
+
+/**
+ * A resource change handler is notified to do some cleaning job when the editing resource is changed, renamed or
+ * deleted.
+ * 
+ * @author Idull
+ */
+public interface IResourceChangeHandler
+{
+    /**
+     * The consumer need to call this method when the resouce is changed outside of the schema editor's scope
+     * 
+     */
+    public void resouceChanged(IResourceChangeEvent event);
+}
diff --git a/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/ISchemaObjectEditor.java b/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/ISchemaObjectEditor.java
new file mode 100644
index 0000000..804bf7e
--- /dev/null
+++ b/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/ISchemaObjectEditor.java
@@ -0,0 +1,166 @@
+/***********************************************************************************************************************
+ * Copyright (c) 2009 Sybase, Inc. 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: Sybase, Inc. - initial API and implementation
+ **********************************************************************************************************************/
+package org.eclipse.datatools.sqltools.schemaobjecteditor.ui;
+
+import java.util.Map;
+
+import org.eclipse.datatools.sqltools.schemaobjecteditor.ui.extensions.IEditorDescriptor;
+import org.eclipse.ui.IEditorPart;
+
+/**
+ * Thru this interface, the consumer can get some run-time object of the editor.
+ * 
+ * @author Idull
+ */
+public interface ISchemaObjectEditor extends IResourceChangeHandler, IEditorPart
+{
+
+    /**
+     * Clear the dirty status of the editor
+     * 
+     */
+    public void clearDirty();
+
+    /**
+     * Fires the editor dirty property change event
+     * 
+     */
+    public void fireDirtyPropertyChange();
+
+    /**
+     * Returns the active page
+     * 
+     * @return
+     */
+    public ISchemaObjectEditorPage getActiveEditorPage();
+
+    /**
+     * Returns all the pages currently initialized in this editor
+     * 
+     * @return
+     */
+    public ISchemaObjectEditorPage[] getAllPages();
+
+    /**
+     * Returns the current page's index
+     * 
+     * @return
+     */
+    public int getCurrentPageIndex();
+
+    /**
+     * Returns the application data
+     * 
+     * @return
+     */
+    public Object getData();
+
+    /**
+     * Returns the edit model
+     * 
+     * @return
+     */
+    public Object getEditModel();
+
+    /**
+     * Returns the handler
+     * 
+     * @return
+     */
+    public ISchemaObjectEditorHandler getEditorHandler();
+
+    /**
+     * Returns the page with the given id
+     * 
+     * @param id the id of a page, should be unique for an editor
+     * @return
+     */
+    public ISchemaObjectEditorPage getPageById(String id);
+
+    /**
+     * Returns the page with the given name
+     * 
+     * @param name name of editor pages, we suggest that the name is also unique for an editor, otherwise this method
+     *            will only return the first one
+     * @return
+     */
+    public ISchemaObjectEditorPage getPageByName(String name);
+
+    /**
+     * Returns the <code>IEditorDescriptor</code> instance containing some static information of this editor
+     * 
+     * @return
+     */
+    public IEditorDescriptor getEditorDescriptor();
+
+    /**
+     * Mark the editor as dirty status
+     * 
+     */
+    public void markDirty();
+
+    /**
+     * Sets the application data
+     * 
+     * @param _data
+     */
+    public void setData(Object _data);
+
+    /**
+     * Sets the edit model
+     * 
+     * @param model
+     */
+    public void setEditModel(Object model);
+
+    /**
+     * Sets the part name for the schema object editor
+     * 
+     * @param name
+     */
+    public void setEditorPartName(String name);
+
+    /**
+     * Validates the editor to see if there are errors
+     * 
+     * @return
+     */
+    public Map validate();
+
+    /**
+     * Returns the display name of the current edited object (a meaningful name), this will be used for saving as
+     * purpose.
+     * 
+     * @return
+     */
+    public String getDisplayName();
+
+    /**
+     * Sets sync save mode for the next save process
+     * 
+     */
+    public void setSyncSaveMode();
+
+    /**
+     * Checks if current save mode is sync save
+     */
+    public boolean isSyncSave();
+
+    /**
+     * Sets if the editor needs to be refreshed after it is saved
+     * 
+     * @param needRefresh
+     */
+    public void setNeedRefreshAfterSave(boolean needRefresh);
+
+    /**
+     * 
+     * @return
+     */
+    public boolean needRefreshAfterSave();
+}
diff --git a/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/ISchemaObjectEditorActionBarContributor.java b/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/ISchemaObjectEditorActionBarContributor.java
new file mode 100644
index 0000000..56ab6c9
--- /dev/null
+++ b/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/ISchemaObjectEditorActionBarContributor.java
@@ -0,0 +1,104 @@
+/***********************************************************************************************************************
+ * Copyright (c) 2009 Sybase, Inc. 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: Sybase, Inc. - initial API and implementation
+ **********************************************************************************************************************/
+package org.eclipse.datatools.sqltools.schemaobjecteditor.ui;
+
+import org.eclipse.jface.action.ICoolBarManager;
+import org.eclipse.jface.action.IMenuManager;
+import org.eclipse.jface.action.IStatusLineManager;
+import org.eclipse.jface.action.IToolBarManager;
+import org.eclipse.ui.IActionBars;
+import org.eclipse.ui.IEditorPart;
+import org.eclipse.ui.IWorkbenchPage;
+
+/**
+ * A schema object editor which need to contribute new actions need to implement this interface
+ * 
+ * @author Idull
+ */
+public interface ISchemaObjectEditorActionBarContributor
+{
+    /**
+     * Sets the editor
+     * 
+     * @param editor
+     */
+    public void setEditor(ISchemaObjectEditor editor);
+
+    /**
+     * Contributes actions to cool bar.
+     * 
+     * @param coolBarManager
+     */
+    public void contributeToCoolBar(ICoolBarManager coolBarManager);
+
+    /**
+     * Contributes actions to menu
+     * 
+     * @param menuManager
+     */
+    public void contributeToMenu(IMenuManager menuManager);
+
+    /**
+     * Sets/clears message on status line
+     * 
+     * @param statusLineManager
+     */
+    public void contributeToStatusLine(IStatusLineManager statusLineManager);
+
+    /**
+     * Contribute actions to tool bar
+     * 
+     * @param toolBarManager
+     */
+    public void contributeToToolBar(IToolBarManager toolBarManager);
+
+    /**
+     * This method is called whenever the page changes. Subclasses must implement this method to redirect actions to the
+     * given editor (if not already directed to it).
+     * 
+     * @param activeEditor
+     */
+    public void setActivePage(IEditorPart activeEditor);
+
+    /**
+     * Initializes this contributor, which is expected to add contributions as required to the given action bars and
+     * global action handlers.
+     * <p>
+     * The page is passed to support the use of <code>RetargetAction</code> by the contributor. In this case the init
+     * method implementors should:
+     * </p>
+     * <p>
+     * <ul>
+     * <li>1) set retarget actions as global action handlers</li>
+     * <li>2) add the retarget actions as part listeners</li>
+     * <li>3) get the active part and if not <code>null</code> call partActivated on the retarget actions</li>
+     * </ul>
+     * </p>
+     * <p>
+     * And in the dispose method the retarget actions should be removed as part listeners.
+     * </p>
+     * 
+     * @param bars the action bars
+     * @param page the workbench page for this contributor
+     */
+    public void init(IActionBars bars, IWorkbenchPage page);
+
+    /**
+     * Returns this contributor's action bars.
+     * 
+     * @return the action bars
+     */
+    public IActionBars getActionBars();
+
+    /**
+     * Returns this contributor's workbench page.
+     * 
+     * @return the workbench page
+     */
+    public IWorkbenchPage getPage();
+}
diff --git a/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/ISchemaObjectEditorHandler.java b/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/ISchemaObjectEditorHandler.java
new file mode 100644
index 0000000..12f6080
--- /dev/null
+++ b/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/ISchemaObjectEditorHandler.java
@@ -0,0 +1,136 @@
+/***********************************************************************************************************************
+ * Copyright (c) 2009 Sybase, Inc. 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: Sybase, Inc. - initial API and implementation
+ **********************************************************************************************************************/
+package org.eclipse.datatools.sqltools.schemaobjecteditor.ui;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.datatools.modelbase.sql.schema.SQLObject;
+
+/**
+ * Defines the behaviour of the schema object editor, notice that the name of most of the methods defined in this class
+ * are the same as those in <code>SchemaObjectEditor</code>, the method in <code>SchemaObjectEditor</code> will delegate
+ * the call to the corresponding method in this class.
+ * 
+ * @author Idull
+ */
+public interface ISchemaObjectEditorHandler extends IResourceChangeHandler
+{
+
+    /**
+     * Does something when the editor part is disposing
+     * 
+     */
+    public void dispose();
+
+    /**
+     * Saves the content of the editor part.
+     * 
+     * @param monitor
+     */
+    public void doSave(IProgressMonitor monitor);
+
+    /**
+     * Saves the content of the editor part to another file
+     */
+    public void doSaveAs();
+
+    /**
+     * Generates script for the current editor. This method will be invoked by doSave() to get the script
+     * 
+     * @return
+     */
+    public String generateScript();
+
+    /**
+     * Returns the adapter. This will be called when the <code>super.getAdapter</code> in
+     * <code>SchemaObjectEditor</code> returns null.
+     * 
+     * @param adapter
+     * @return
+     */
+    public Object getAdapter(Class adapter);
+
+    /**
+     * Tests if savesa is allowed for this editor part
+     * 
+     * @return
+     */
+    public boolean isSaveAsAllowed();
+
+    /**
+     * Does something with the editor when the page is changed. This method will be called before all the obsevers of
+     * page change event get notified.
+     * 
+     * @param newPageIndex
+     */
+    public void pageChanged(int newPageIndex);
+
+    /**
+     * Refreshes the model and then refresh the editor
+     * 
+     */
+    public void refreshFromDB(IProgressMonitor monitor);
+
+    /**
+     * Reverts the editor to the original model (no need to refresh the model)
+     * 
+     */
+    public void revert();
+
+    /**
+     * Since the instance of this class will be created using the Eclipse extension API, so that we need to set the
+     * editor to the hanlder for it to use
+     * 
+     * @param editor
+     */
+    public void setEditor(ISchemaObjectEditor editor);
+
+    /**
+     * Returns the display name of the current edited object (a meaningful name), this will be used for saving purpose.
+     * If nothing is returned, the editor part name will be used for saving purpose
+     * 
+     * @return
+     */
+    public String getDisplayName();
+
+    /**
+     * Does some initialization jobs, this will be invoked by the editor after all pages are loaded
+     * 
+     */
+    public void hookInitialization();
+
+    /**
+     * Returns the editor model listeners notifier. The notifier is registered as the listener of the schema object
+     * editor model.
+     * 
+     * @return
+     */
+    public SchemaObjectEditorModelListenersNotifier getNotifier();
+
+    /**
+     * Checks if the editor is in saving process, since the saving process may take time
+     * 
+     * @return <code>true</code> if the editor is in saving process
+     */
+    public boolean inSavingProcess();
+
+    /**
+     * Performs a set focus action in schema editor to the given SQL object.<br>
+     * Generally there're two steps: 1.Focus the page;2.Focus the UI component of the given object in that page.
+     * 
+     * @param object
+     */
+    public void forceFocusObject(SQLObject object);
+
+    /**
+     * existence check for schema object.
+     * 
+     * @param doCheck
+     * @return <code>true</code> if object exists or the doCheck is passed with value false.
+     */
+    public boolean checkSchemaObjectExistence(boolean doCheck);
+}
diff --git a/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/ISchemaObjectEditorInput.java b/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/ISchemaObjectEditorInput.java
new file mode 100644
index 0000000..ffc8b99
--- /dev/null
+++ b/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/ISchemaObjectEditorInput.java
@@ -0,0 +1,43 @@
+/***********************************************************************************************************************
+ * Copyright (c) 2009 Sybase, Inc. 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: Sybase, Inc. - initial API and implementation
+ **********************************************************************************************************************/
+package org.eclipse.datatools.sqltools.schemaobjecteditor.ui;
+
+import org.eclipse.datatools.sqltools.core.DatabaseIdentifier;
+import org.eclipse.datatools.sqltools.schemaobjecteditor.model.ISchemaObjectEditModel;
+import org.eclipse.datatools.sqltools.schemaobjecteditor.ui.extensions.IEditorDescriptor;
+import org.eclipse.ui.IEditorInput;
+
+/**
+ * The editor input for scheme object eidtor.
+ * 
+ * @author Idull
+ */
+public interface ISchemaObjectEditorInput extends IEditorInput
+{
+    /**
+     * Returns the <code>IEditorDescriptor</code> instance which is used to describe some static information of the
+     * schema object editor
+     * 
+     * @return
+     */
+    public IEditorDescriptor getEditorDescriptor();
+
+    /**
+     * Returns the model of the object which is been editing
+     * 
+     * @return
+     */
+    public ISchemaObjectEditModel getEditModelObject();
+
+    /**
+     * Returns the database identifier
+     * 
+     * @return
+     */
+    public DatabaseIdentifier getDatabaseIdentifier();
+}
diff --git a/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/ISchemaObjectEditorPage.java b/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/ISchemaObjectEditorPage.java
new file mode 100644
index 0000000..09822ba
--- /dev/null
+++ b/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/ISchemaObjectEditorPage.java
@@ -0,0 +1,184 @@
+/***********************************************************************************************************************
+ * Copyright (c) 2009 Sybase, Inc. 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: Sybase, Inc. - initial API and implementation
+ **********************************************************************************************************************/
+package org.eclipse.datatools.sqltools.schemaobjecteditor.ui;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.datatools.sqltools.core.DatabaseIdentifier;
+import org.eclipse.datatools.sqltools.schemaobjecteditor.ui.extensions.IEditorDescriptor;
+import org.eclipse.datatools.sqltools.schemaobjecteditor.ui.extensions.IEditorPageDescriptor;
+import org.eclipse.jface.action.IMenuManager;
+import org.eclipse.swt.events.TypedEvent;
+import org.eclipse.ui.forms.editor.FormEditor;
+import org.eclipse.ui.forms.editor.IFormPage;
+
+/**
+ * An instance of this class stands for a run-time editor page of a schema object editor
+ * 
+ * @author Idull
+ */
+public interface ISchemaObjectEditorPage extends IFormPage, IDisablementPart
+{
+    public static final int UNKNOWN_ITEM_TYPE = -1;
+
+    /**
+     * Returns the error message in this page which prevent to flip to other pages
+     * 
+     * @return
+     */
+    public String getErrorMsg();
+
+    /**
+     * Returns the database identifier
+     * 
+     * @return
+     */
+    public DatabaseIdentifier getDatabaseIdentifier();
+
+    /**
+     * Returns an instance of <code>IEditorDescriptor</code> which is used to describe some static information of the
+     * scheme object editor in which this page is contained
+     * 
+     * @return
+     */
+    public IEditorDescriptor getEditorDescriptor();
+
+    /**
+     * Returns an instance of <code>IEditorPageDescriptor</code> which is used to describe some static information of
+     * this page
+     * 
+     * @return
+     */
+    public IEditorPageDescriptor getPageDescriptor();
+
+    /**
+     * Notifies this page that the editor is about to save, subclass should update the model if necessary
+     * 
+     */
+    public boolean aboutToSave(IProgressMonitor monitor);
+
+    /**
+     * Refresh the content of this page to the edit model to synchronize this page with the immutable model. Note: This
+     * is called after save or revert. @see #setActive
+     * 
+     */
+    public void refresh();
+
+    /**
+     * Do something when the model is re-generated, for example, after successfully saving the dirty editor, the edit
+     * model will be re-cloned from the refreshed database model, in this case, page should be refreshed to keep it
+     * synchronized with database
+     * 
+     */
+    public void modelRegenerated();
+
+    /**
+     * Revert this page to the original model
+     * 
+     */
+    public void revert();
+
+    /**
+     * Sets the editor in which this paged is contained, this will be called after the schema object is opened. Subclass
+     * of <code>SchemaObjectPage</code> should not override this method
+     * 
+     * @param editor
+     */
+    public void setEditor(FormEditor editor);
+
+    /**
+     * Sets the id for this page
+     * 
+     * @param id
+     */
+    public void setId(String id);
+
+    /**
+     * Checks if this page is valid
+     * 
+     * @return the error items if this page is not valid, otherwise return <code>null</code>
+     */
+    public IErrorItem[] validate(TypedEvent event);
+
+    /**
+     * Online check if the page is valid
+     * 
+     * @param event
+     * @return the error items if this page is not valid, otherwise return <code>null</code>
+     */
+    public IErrorItem[] validateOnline(TypedEvent event);
+
+    /**
+     * Populates the SQL object using the user's input
+     * 
+     * @param event the edit event which changes the input
+     */
+    public void populateSQLObjects(TypedEvent event);
+
+    /**
+     * Validates the page and show error in problems view accordingly
+     * 
+     * @param event
+     */
+    public void validateAndShowErrors(TypedEvent event);
+
+    /**
+     * Checks if the page is opened (Controls are created)
+     * 
+     * @return
+     */
+    public boolean isPageOpened();
+
+    /**
+     * Sets the title for this page
+     * 
+     * @param title
+     */
+    public void setPartName(String title);
+
+    /**
+     * Sets the editor descriptor for this page
+     * 
+     * @param editor
+     */
+    public void setEditorDescriptor(IEditorDescriptor editor);
+
+    /**
+     * Sets the page descriptor for this page
+     * 
+     * @param page
+     */
+    public void setPageDescriptor(IEditorPageDescriptor page);
+
+    /**
+     * Marks the parent editor as dirty status
+     */
+    public void markDirty();
+
+    /**
+     * Adds menu items for this page
+     * 
+     * @param manager
+     */
+    public void menuAboutToShow(IMenuManager manager);
+
+    /**
+     * Returns the preference pages ids related to this editor page.<br>
+     * The returns preference pages will be displayed if user click "Preferences..." in the editor page's context menu
+     * 
+     * @return
+     */
+    public String[] getPreferencePageIds();
+
+    /**
+     * Sets focus to the pre-defined item
+     * 
+     * @param itemType the type of the item, each page can define its own types
+     * @param item the object of the type, it can be <code>null</code> if the item type provides enough information
+     */
+    public void setFocus(int itemType, Object item);
+}
diff --git a/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/SchemaObjectEditorModelListenersNotifier.java b/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/SchemaObjectEditorModelListenersNotifier.java
new file mode 100644
index 0000000..6851e87
--- /dev/null
+++ b/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/SchemaObjectEditorModelListenersNotifier.java
@@ -0,0 +1,151 @@
+/***********************************************************************************************************************
+ * Copyright (c) 2009 Sybase, Inc. 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: Sybase, Inc. - initial API and implementation
+ **********************************************************************************************************************/
+package org.eclipse.datatools.sqltools.schemaobjecteditor.ui;
+
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.Map;
+
+import org.eclipse.core.runtime.ListenerList;
+import org.eclipse.datatools.sqltools.schemaobjecteditor.model.ISchemaObjectEditModel;
+import org.eclipse.datatools.sqltools.schemaobjecteditor.model.ISchemaObjectEditorModelListener;
+import org.eclipse.datatools.sqltools.schemaobjecteditor.ui.ISchemaObjectEditorInput;
+import org.eclipse.emf.common.notify.Notification;
+import org.eclipse.emf.common.notify.impl.AdapterImpl;
+import org.eclipse.emf.common.util.EList;
+import org.eclipse.emf.ecore.EClass;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.EStructuralFeature;
+
+/**
+ * The notifier for the model change listeners. It is itself a model listener, it accepts all events from the model
+ * object and model's contaiment objects, also from the additional model defined in <code>ISchemaObjectEditModel</code>,
+ * then delegate the events to all the listeners of this notifier.
+ * 
+ * @see ISchemaObjectEditModel
+ * @author Idull
+ */
+public class SchemaObjectEditorModelListenersNotifier extends AdapterImpl
+{
+    private ListenerList _listeners;
+
+    public SchemaObjectEditorModelListenersNotifier()
+    {
+        super();
+        _listeners = new ListenerList();
+    }
+
+    public void addModelListener(ISchemaObjectEditorModelListener listener)
+    {
+        if (listener != null)
+        {
+            _listeners.add(listener);
+        }
+    }
+
+    public void removeModelListener(ISchemaObjectEditorModelListener listener)
+    {
+        if (listener != null)
+        {
+            _listeners.remove(listener);
+        }
+    }
+
+    public void removeAllListeners()
+    {
+        _listeners.clear();
+    }
+
+    private void registerListenerForObject(EObject obj)
+    {
+        if (!obj.eAdapters().contains(this))
+        {
+            obj.eAdapters().add(this);
+        }
+
+        // add listener for containment feature
+        Iterator containments = ((EClass) obj.eClass()).getEAllContainments().iterator();
+        while (containments.hasNext())
+        {
+            Object containmentObj = obj.eGet((EStructuralFeature) containments.next());
+            if (containmentObj instanceof EList)
+            {
+                Iterator iter = ((EList) containmentObj).iterator();
+                while (iter.hasNext())
+                {
+                    registerListenerForObject((EObject) iter.next());
+                }
+            }
+            else if (containmentObj instanceof EObject)
+            {
+                registerListenerForObject((EObject) containmentObj);
+            }
+        }
+    }
+
+    /**
+     * Registers listeners for all SQL objects and their containment features containing in the given editor input
+     * 
+     * @param input the editor input
+     */
+    public void registerListener(ISchemaObjectEditorInput input)
+    {
+        ISchemaObjectEditModel model = input.getEditModelObject();
+        if (model == null)
+        {
+            return;
+        }
+
+        registerListenerForObject(model.getMainSQLObject());
+
+        Map additionalObjs = model.getAdditionalSQLObjects();
+        Iterator iter = additionalObjs.values().iterator();
+        while (iter.hasNext())
+        {
+            Object value = iter.next();
+            if (value instanceof Collection)
+            {
+                Collection col = (Collection) value;
+                if (col == null)
+                {
+                    continue;
+                }
+
+                Iterator colIter = col.iterator();
+                while (colIter.hasNext())
+                {
+                    Object item = colIter.next();
+                    if (item instanceof EObject)
+                    {
+                        registerListenerForObject((EObject) item);
+                    }
+                }
+            }
+            else if (value instanceof EObject)
+            {
+                registerListenerForObject((EObject) value);
+            }
+        }
+    }
+
+    public void notifyChanged(Notification msg)
+    {
+        Object[] listeners = _listeners.getListeners();
+        for (int i = 0; i < listeners.length; i++)
+        {
+            try
+            {
+                ((ISchemaObjectEditorModelListener) listeners[i]).notifyChanged(msg);
+            }
+            catch (Exception e)
+            {
+                // do nothing
+            }
+        }
+    }
+}
diff --git a/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/action/EditSchemaObjectAction.java b/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/action/EditSchemaObjectAction.java
new file mode 100644
index 0000000..4fe1dbf
--- /dev/null
+++ b/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/action/EditSchemaObjectAction.java
@@ -0,0 +1,329 @@
+/***********************************************************************************************************************
+ * Copyright (c) 2009 Sybase, Inc. 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: Sybase, Inc. - initial API and implementation
+ **********************************************************************************************************************/
+package org.eclipse.datatools.sqltools.schemaobjecteditor.ui.action;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.core.runtime.jobs.Job;
+import org.eclipse.datatools.connectivity.sqm.core.containment.ContainmentServiceImpl;
+import org.eclipse.datatools.modelbase.sql.schema.Database;
+import org.eclipse.datatools.modelbase.sql.schema.SQLObject;
+import org.eclipse.datatools.sqltools.core.DatabaseIdentifier;
+import org.eclipse.datatools.sqltools.internal.SQLDevToolsUtil;
+import org.eclipse.datatools.sqltools.schemaobjecteditor.model.ISchemaObjectEditModel;
+import org.eclipse.datatools.sqltools.schemaobjecteditor.ui.core.SchemaObjectEditor;
+import org.eclipse.datatools.sqltools.schemaobjecteditor.ui.internal.SOEUIPlugin;
+import org.eclipse.datatools.sqltools.schemaobjecteditor.ui.util.SchemaObjectEditorUtils;
+import org.eclipse.jface.action.Action;
+import org.eclipse.jface.dialogs.IDialogConstants;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.ui.IEditorPart;
+
+/**
+ * The action to open a schema object editor, given db definition, db object type and a model object. The consumer can
+ * either use this action or re-write a new one if they have extra requirement.
+ * 
+ * @author Idull
+ */
+public class EditSchemaObjectAction extends Action implements IEditSchemaObjectAction
+{
+    class OpenSchemaEditorJob extends Job
+    {
+        public OpenSchemaEditorJob(String name)
+        {
+            super(name);
+        }
+
+        protected IStatus run(IProgressMonitor monitor)
+        {
+            if (monitor == null)
+            {
+                monitor = manager.createProgressGroup();
+            }
+            monitor.beginTask(Messages.EditSchemaObjectAction_open_schema_editor, monitor.UNKNOWN);
+            EditSchemaObjectAction.this.run(monitor);
+            return Status.OK_STATUS;
+        }
+    }
+
+    private ISchemaObjectEditModel _modelObj;
+
+    private String                 _vendorName;
+
+    private String                 _version;
+
+    private String                 _objectTypeId;
+
+    private String                 _editorId;
+
+    private DatabaseIdentifier     _databaseIdentifier;
+
+    private IEditorPart            _part;
+
+    /**
+     * Database name,version,object id, database identifier can be calculated from this object.
+     */
+    protected SQLObject            _sqlObject;
+
+    private String                 _defaultPageId;
+
+    /**
+     * Passes a SQL object, will calculate other necessary information via this object
+     * 
+     * @param obj
+     * @param modelObj
+     */
+    public EditSchemaObjectAction(SQLObject obj, ISchemaObjectEditModel modelObj)
+    {
+        _sqlObject = obj;
+        _modelObj = modelObj;
+    }
+
+    public EditSchemaObjectAction(String vendorName, String version, String objectTypeId,
+            ISchemaObjectEditModel modelObj, DatabaseIdentifier databaseIdentifier)
+    {
+        super();
+        this._vendorName = vendorName;
+        this._version = version;
+        this._objectTypeId = objectTypeId;
+        this._modelObj = modelObj;
+        this._databaseIdentifier = databaseIdentifier;
+    }
+
+    public EditSchemaObjectAction(String vendorName, String version, String objectTypeId, String text, int style,
+            ISchemaObjectEditModel modelObj, DatabaseIdentifier databaseIdentifier)
+    {
+        super(text, style);
+        this._vendorName = vendorName;
+        this._version = version;
+        this._objectTypeId = objectTypeId;
+        this._modelObj = modelObj;
+        this._databaseIdentifier = databaseIdentifier;
+    }
+
+    public EditSchemaObjectAction(String vendorName, String version, String objectTypeId, String text,
+            ISchemaObjectEditModel modelObj)
+    {
+        super(text);
+        this._vendorName = vendorName;
+        this._version = version;
+        this._objectTypeId = objectTypeId;
+        this._modelObj = modelObj;
+    }
+
+    public EditSchemaObjectAction(String vendorName, String version, String objectTypeId, String text,
+            ImageDescriptor image, ISchemaObjectEditModel modelObj)
+    {
+        super(text, image);
+        this._vendorName = vendorName;
+        this._version = version;
+        this._objectTypeId = objectTypeId;
+        this._modelObj = modelObj;
+    }
+
+    public EditSchemaObjectAction()
+    {
+        super();
+    }
+
+    public EditSchemaObjectAction(String text, ImageDescriptor image)
+    {
+        super(text, image);
+    }
+
+    public EditSchemaObjectAction(String text, int style)
+    {
+        super(text, style);
+    }
+
+    public EditSchemaObjectAction(String text)
+    {
+        super(text);
+    }
+
+    public void run()
+    {
+        OpenSchemaEditorJob job = new OpenSchemaEditorJob(Messages.EditSchemaObjectAction_opening);
+        job.setUser(true);
+        job.schedule();
+    }
+
+    public void run(IProgressMonitor monitor)
+    {
+        SOEUIPlugin.getActiveWorkbenchShell().getDisplay().syncExec(new Runnable()
+        {
+            public void run()
+            {
+                checkAndOpenEditor();
+                setActivePage();
+            }
+        });
+    }
+
+    public void checkAndOpenEditor()
+    {
+        if (_modelObj == null)
+        {
+            String[] buttons = new String[]
+            {
+                IDialogConstants.OK_LABEL
+            };
+            MessageDialog d = new MessageDialog(SOEUIPlugin.getActiveWorkbenchShell(),
+                    Messages.EditSchemaObjectAction_error, null, Messages.EditSchemaObjectAction_model_null,
+                    MessageDialog.ERROR, buttons, 0);
+            d.open();
+            return;
+        }
+
+        // open the editor using editor id
+        if (_editorId != null && _editorId.trim().length() != 0)
+        {
+            _part = SchemaObjectEditorUtils.openEditor(_editorId, _modelObj, _databaseIdentifier);
+        }
+
+        if (_vendorName == null || _version == null || _objectTypeId == null || _databaseIdentifier == null)
+        {
+            boolean calculated = false;
+            if (_sqlObject != null)
+            {
+                Object root = ContainmentServiceImpl.INSTANCE.getRootElement(_sqlObject);
+                if (root != null && root instanceof Database)
+                {
+                    calculated = true;
+                    Database db = (Database) root;
+                    if (_vendorName == null)
+                    {
+                        _vendorName = db.getVendor();
+                    }
+                    if (_version == null)
+                    {
+                        _version = db.getVersion();
+                    }
+                    if (_databaseIdentifier == null)
+                    {
+                        SQLDevToolsUtil.getDatabaseIdentifier(_sqlObject);
+                    }
+                    if (_objectTypeId == null)
+                    {
+                        _objectTypeId = _sqlObject.eClass().getEPackage().getName() + "."
+                                + _sqlObject.eClass().getName();
+                    }
+                }
+            }
+            else if (!calculated)
+            {
+                String[] buttons = new String[]
+                {
+                    IDialogConstants.OK_LABEL
+                };
+                MessageDialog d = new MessageDialog(SOEUIPlugin.getActiveWorkbenchShell(),
+                        Messages.EditSchemaObjectAction_error, null, Messages.EditSchemaObjectAction_no_vendor_name,
+                        MessageDialog.ERROR, buttons, 0);
+                d.open();
+                return;
+            }
+        }
+
+        _part = SchemaObjectEditorUtils
+                .openEditor(_vendorName, _version, _objectTypeId, _modelObj, _databaseIdentifier);
+    }
+
+    public String getEditorId()
+    {
+        return _editorId;
+    }
+
+    public void setEditorId(String id)
+    {
+        _editorId = id;
+    }
+
+    public Object getModelObj()
+    {
+        return _modelObj;
+    }
+
+    public void setModelObj(ISchemaObjectEditModel obj)
+    {
+        _modelObj = obj;
+    }
+
+    public String getObjectTypeId()
+    {
+        return _objectTypeId;
+    }
+
+    public void setObjectTypeId(String typeId)
+    {
+        _objectTypeId = typeId;
+    }
+
+    public String getVendorName()
+    {
+        return _vendorName;
+    }
+
+    public void setVendorName(String name)
+    {
+        _vendorName = name;
+    }
+
+    public String getVersion()
+    {
+        return _version;
+    }
+
+    public void setVersion(String _version)
+    {
+        this._version = _version;
+    }
+
+    public IEditorPart getPart()
+    {
+        return _part;
+    }
+
+    public DatabaseIdentifier getDatabaseIdentifier()
+    {
+        return _databaseIdentifier;
+    }
+
+    public void setDatabaseIdentifier(DatabaseIdentifier identifier)
+    {
+        _databaseIdentifier = identifier;
+    }
+
+    public SQLObject getSQLObject()
+    {
+        return _sqlObject;
+    }
+
+    public void setSQLObject(SQLObject object)
+    {
+        _sqlObject = object;
+    }
+
+    public void setDefaultPageId(String defaultPageId)
+    {
+        _defaultPageId = defaultPageId;
+    }
+
+    /**
+     * Set active page
+     */
+    protected void setActivePage()
+    {
+        if (_defaultPageId != null && _part instanceof SchemaObjectEditor)
+        {
+            ((SchemaObjectEditor) _part).setActivePage(_defaultPageId);
+        }
+    }
+
+}
diff --git a/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/action/IEditSchemaObjectAction.java b/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/action/IEditSchemaObjectAction.java
new file mode 100644
index 0000000..a6f91ce
--- /dev/null
+++ b/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/action/IEditSchemaObjectAction.java
@@ -0,0 +1,32 @@
+/***********************************************************************************************************************
+ * Copyright (c) 2009 Sybase, Inc. 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: Sybase, Inc. - initial API and implementation
+ **********************************************************************************************************************/
+package org.eclipse.datatools.sqltools.schemaobjecteditor.ui.action;
+
+import org.eclipse.datatools.modelbase.sql.schema.SQLObject;
+
+/**
+ * Interface for edit schema object action
+ * 
+ * @author Hui Wan
+ */
+public interface IEditSchemaObjectAction
+{
+    /**
+     * Set the object to be opened
+     * 
+     * @param object Object
+     */
+    public void setSQLObject(SQLObject object);
+
+    /**
+     * Set the default page ID
+     * 
+     * @param defaultPageId Default page Id
+     */
+    public void setDefaultPageId(String defaultPageId);
+}
diff --git a/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/action/Messages.java b/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/action/Messages.java
new file mode 100644
index 0000000..a00a773
--- /dev/null
+++ b/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/action/Messages.java
@@ -0,0 +1,30 @@
+/***********************************************************************************************************************
+ * Copyright (c) 2009 Sybase, Inc. 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: Sybase, Inc. - initial API and implementation
+ **********************************************************************************************************************/
+package org.eclipse.datatools.sqltools.schemaobjecteditor.ui.action;
+
+import org.eclipse.osgi.util.NLS;
+
+public class Messages extends NLS
+{
+    private static final String BUNDLE_NAME = Messages.class.getPackage().getName() + ".messages";
+    static
+    {
+        NLS.initializeMessages(BUNDLE_NAME, Messages.class);
+    }
+    public static String        EditSchemaObjectAction_error;
+    public static String        EditSchemaObjectAction_model_null;
+    public static String        EditSchemaObjectAction_no_vendor_name;
+    public static String        EditSchemaObjectAction_open_schema_editor;
+    public static String        EditSchemaObjectAction_opening;
+    public static String        RefreshSchemaEditorAction_question;
+    public static String        RefreshSchemaEditorAction_referesh_editor;
+    public static String        RefreshSchemaEditorAction_refresh_from_server;
+    public static String        RefreshSchemaEditorAction_refresh_job;
+    public static String        RefreshSchemaEditorAction_sync_with_db;
+    public static String        RevertSchemaEditorAction_revert;
+}
diff --git a/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/action/RefreshSchemaEditorAction.java b/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/action/RefreshSchemaEditorAction.java
new file mode 100644
index 0000000..ad3f91d
--- /dev/null
+++ b/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/action/RefreshSchemaEditorAction.java
@@ -0,0 +1,127 @@
+/***********************************************************************************************************************
+ * Copyright (c) 2009 Sybase, Inc. 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: Sybase, Inc. - initial API and implementation
+ **********************************************************************************************************************/
+package org.eclipse.datatools.sqltools.schemaobjecteditor.ui.action;
+
+import org.eclipse.core.commands.ExecutionEvent;
+import org.eclipse.core.commands.ExecutionException;
+import org.eclipse.core.commands.IHandler;
+import org.eclipse.core.commands.IHandlerListener;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.core.runtime.jobs.Job;
+import org.eclipse.datatools.sqltools.schemaobjecteditor.ui.ISchemaObjectEditor;
+import org.eclipse.datatools.sqltools.schemaobjecteditor.ui.ISchemaObjectEditorHandler;
+import org.eclipse.datatools.sqltools.schemaobjecteditor.ui.internal.SOEUIPlugin;
+import org.eclipse.datatools.sqltools.schemaobjecteditor.ui.util.Images;
+import org.eclipse.jface.action.Action;
+import org.eclipse.jface.dialogs.IDialogConstants;
+import org.eclipse.jface.dialogs.MessageDialog;
+
+/**
+ * Action to refresh the schema editor
+ * 
+ * @author Idull
+ */
+public class RefreshSchemaEditorAction extends Action implements IHandler
+{
+    protected ISchemaObjectEditor _editor;
+
+    public RefreshSchemaEditorAction()
+    {
+        super();
+        setText(Messages.RefreshSchemaEditorAction_refresh_from_server);
+        setImageDescriptor(Images.DESC_REFRESH);
+    }
+
+    public void run()
+    {
+        if (_editor == null)
+        {
+            return;
+        }
+        if (_editor.isDirty())
+        {
+            String[] buttons = new String[]
+            {
+                IDialogConstants.YES_LABEL, IDialogConstants.NO_LABEL
+            };
+            MessageDialog d = new MessageDialog(SOEUIPlugin.getActiveWorkbenchShell(),
+                    Messages.RefreshSchemaEditorAction_referesh_editor, null,
+                    Messages.RefreshSchemaEditorAction_question, MessageDialog.QUESTION, buttons, 0);
+            int result = d.open();
+            switch (result)
+            {
+                case IDialogConstants.CANCEL_ID:
+                    return;
+                default:
+                    break;
+            }
+        }
+        ISchemaObjectEditorHandler handler = _editor.getEditorHandler();
+        RefreshSchemaEditorJob refreshJob = new RefreshSchemaEditorJob(Messages.RefreshSchemaEditorAction_refresh_job,
+                handler);
+        refreshJob.setUser(true);
+        refreshJob.schedule();
+    }
+
+    public void setEditor(ISchemaObjectEditor _editor)
+    {
+        this._editor = _editor;
+    }
+
+    public static class RefreshSchemaEditorJob extends Job
+    {
+        ISchemaObjectEditorHandler _handler;
+
+        public RefreshSchemaEditorJob(String name, ISchemaObjectEditorHandler handler)
+        {
+            super(name);
+            _handler = handler;
+        }
+
+        protected IStatus run(IProgressMonitor monitor)
+        {
+            if (monitor == null)
+            {
+                monitor = manager.createProgressGroup();
+            }
+            if (_handler == null)
+            {
+                return Status.OK_STATUS;
+            }
+            monitor.beginTask(Messages.RefreshSchemaEditorAction_sync_with_db, monitor.UNKNOWN);
+            _handler.refreshFromDB(monitor);
+            return Status.OK_STATUS;
+        }
+    }
+
+    /*
+     * Since this class will be casted in HandlerProxy.loadHandler(), it should implements IHandler. The four methods
+     * blow are the implementation of IHandler's.
+     */
+    public void addHandlerListener(IHandlerListener handlerListener)
+    {
+
+    }
+
+    public void dispose()
+    {
+
+    }
+
+    public Object execute(ExecutionEvent event) throws ExecutionException
+    {
+        return null;
+    }
+
+    public void removeHandlerListener(IHandlerListener handlerListener)
+    {
+
+    }
+}
diff --git a/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/action/RevertSchemaEditorAction.java b/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/action/RevertSchemaEditorAction.java
new file mode 100644
index 0000000..a04dcb8
--- /dev/null
+++ b/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/action/RevertSchemaEditorAction.java
@@ -0,0 +1,95 @@
+/***********************************************************************************************************************
+ * Copyright (c) 2009 Sybase, Inc. 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: Sybase, Inc. - initial API and implementation
+ **********************************************************************************************************************/
+package org.eclipse.datatools.sqltools.schemaobjecteditor.ui.action;
+
+import org.eclipse.core.commands.ExecutionEvent;
+import org.eclipse.core.commands.ExecutionException;
+import org.eclipse.core.commands.IHandler;
+import org.eclipse.core.commands.IHandlerListener;
+import org.eclipse.datatools.sqltools.schemaobjecteditor.ui.ISchemaObjectEditor;
+import org.eclipse.datatools.sqltools.schemaobjecteditor.ui.ISchemaObjectEditorHandler;
+import org.eclipse.datatools.sqltools.schemaobjecteditor.ui.util.Images;
+import org.eclipse.jface.action.Action;
+import org.eclipse.ui.IEditorPart;
+import org.eclipse.ui.IPropertyListener;
+
+/**
+ * Reverts the editor to the begining status
+ * 
+ * @author Idull
+ */
+public class RevertSchemaEditorAction extends Action implements IPropertyListener, IHandler
+{
+    protected ISchemaObjectEditor _editor;
+
+    public RevertSchemaEditorAction()
+    {
+        super();
+        setText(Messages.RevertSchemaEditorAction_revert);
+        setImageDescriptor(Images.DESC_REVERT);
+    }
+
+    public void run()
+    {
+        if (_editor == null)
+        {
+            return;
+        }
+        ISchemaObjectEditorHandler handler = _editor.getEditorHandler();
+        if (handler == null)
+        {
+            return;
+        }
+        handler.revert();
+    }
+
+    public void setEditor(ISchemaObjectEditor editor)
+    {
+        this._editor = editor;
+    }
+
+    public void propertyChanged(Object source, int propId)
+    {
+        if (source != _editor || propId != IEditorPart.PROP_DIRTY)
+        {
+            return;
+        }
+        if (_editor.isDirty())
+        {
+            setEnabled(true);
+        }
+        else
+        {
+            setEnabled(false);
+        }
+    }
+
+    /*
+     * Since this class will be casted in HandlerProxy.loadHandler(), it should implements IHandler. The four methods
+     * blow are the implementation of IHandler's.
+     */
+    public void addHandlerListener(IHandlerListener handlerListener)
+    {
+
+    }
+
+    public void dispose()
+    {
+
+    }
+
+    public Object execute(ExecutionEvent event) throws ExecutionException
+    {
+        return null;
+    }
+
+    public void removeHandlerListener(IHandlerListener handlerListener)
+    {
+
+    }
+}
diff --git a/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/action/messages.properties b/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/action/messages.properties
new file mode 100644
index 0000000..dc75277
--- /dev/null
+++ b/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/action/messages.properties
@@ -0,0 +1,11 @@
+EditSchemaObjectAction_error=Error
+EditSchemaObjectAction_opening=Opening
+EditSchemaObjectAction_model_null=The model object is null
+EditSchemaObjectAction_no_vendor_name=Either vendor name, or object type id, or database identifier is null
+EditSchemaObjectAction_open_schema_editor=Opening schema editor...
+RefreshSchemaEditorAction_refresh_from_server=Refresh from Server
+RefreshSchemaEditorAction_referesh_editor=Refresh from Server
+RefreshSchemaEditorAction_question=The object has been modified. Refresh it anyway?
+RefreshSchemaEditorAction_refresh_job=Refresh
+RefreshSchemaEditorAction_sync_with_db=Synchronizing with database
+RevertSchemaEditorAction_revert=Revert Object
diff --git a/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/common/CollapseableSection.java b/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/common/CollapseableSection.java
new file mode 100644
index 0000000..8076e8f
--- /dev/null
+++ b/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/common/CollapseableSection.java
@@ -0,0 +1,246 @@
+/***********************************************************************************************************************
+ * Copyright (c) 2009 Sybase, Inc. 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: Sybase, Inc. - initial API and implementation
+ **********************************************************************************************************************/
+package org.eclipse.datatools.sqltools.schemaobjecteditor.ui.common;
+
+import org.eclipse.datatools.help.HelpUtil;
+import org.eclipse.datatools.sqltools.schemaobjecteditor.ui.util.Images;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.forms.AbstractFormPart;
+import org.eclipse.ui.forms.FormColors;
+import org.eclipse.ui.forms.events.ExpansionAdapter;
+import org.eclipse.ui.forms.events.ExpansionEvent;
+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;
+
+/**
+ * A common used section in multiple forms based editor. Which will set the SEPARATOR color to use to BORDER color,
+ * because in Eclipse 3.1, the SEAPARTOR color looks bad. Also, the help context id can be set to this section (A small
+ * help icon will be add to the section, if end-user clicks the icon, help page will be displayed).
+ * 
+ * @author Idull
+ */
+public abstract class CollapseableSection extends AbstractFormPart
+{
+    protected boolean     _isWhiteBackgroud;
+    protected FormToolkit _toolkit;
+    protected Section     _sec;
+    protected String      _title;
+    protected Display     _display;
+    protected int         _estyle;
+    protected String      _helpContextId;
+    private Composite     _content;
+    protected String      _pluginId;
+
+    /**
+     * Constructs a collapseable section
+     * 
+     * @param toolkit the form toolkit
+     * @param title the title of the section
+     * @param display the <code>Display</code> instance
+     * @param isCollapseable whether the section is collapseable
+     * @param isCollapsed the initial status
+     */
+    public CollapseableSection(FormToolkit toolkit, String title, Display display, boolean isCollapseable,
+            boolean isCollapsed, int estyle)
+    {
+        this._toolkit = toolkit;
+        this._title = title;
+        _display = display;
+        _estyle = estyle;
+        // justify the SEPARTOR color for Eclipse 3.1
+        _isWhiteBackgroud = toolkit.getColors().getBackground().equals(_display.getSystemColor(SWT.COLOR_WHITE));
+        if (_isWhiteBackgroud)
+        {
+            _estyle |= Section.TITLE_BAR;
+        }
+        else
+        {
+            FormColors colors = toolkit.getColors();
+            if (colors.getBorderColor() != null)
+            {
+                colors.createColor(FormColors.SEPARATOR, colors.getBorderColor().getRGB());
+            }
+        }
+        if (isCollapseable)
+        {
+            _estyle |= Section.FOCUS_TITLE | Section.TWISTIE;
+        }
+        _estyle |= isCollapsed ? Section.COMPACT : Section.EXPANDED;
+    }
+
+    public CollapseableSection(FormToolkit toolkit, String title, Display display, boolean isCollapsed, int estyle)
+    {
+        this(toolkit, title, display, true, isCollapsed, estyle);
+    }
+
+    public CollapseableSection(FormToolkit toolkit, String title, Display display, int estyle)
+    {
+        this(toolkit, title, display, false, false, estyle);
+    }
+
+    /**
+     * User of this class need to call this method to create this section
+     * 
+     * @param parent the parent in which this section is created
+     * @param horizontalSpan the horizontal span
+     * @param helpContextId the id of the context help
+     * @return the section instance
+     */
+    public Control createControl(Composite parent, int horizontalSpan, String helpContextId)
+    {
+        _helpContextId = helpContextId;
+        _sec = _toolkit.createSection(parent, _estyle);
+        hookListeners();
+        _sec.setText(_title);
+        if (!_isWhiteBackgroud)
+        {
+            _toolkit.createCompositeSeparator(_sec);
+        }
+
+        _content = _toolkit.createComposite(_sec, SWT.NULL);
+        _content.setBackground(parent.getBackground());
+
+        createSectionContent(_content);
+
+        if (_helpContextId != null)
+        {
+            ImageHyperlink helplink = new ImageHyperlink(_sec, SWT.NONE);
+            _toolkit.adapt(helplink, false, false);
+            helplink.setImage(Images.get(Images.IMG_HELP));
+            helplink.setToolTipText("Help");
+            helplink.addHyperlinkListener(new HyperlinkAdapter()
+            {
+                public void linkActivated(HyperlinkEvent e)
+                {
+                    displayHelp(_helpContextId);
+                }
+            });
+            _sec.setTextClient(helplink);
+
+        }
+        _sec.setClient(_content);
+        Object data = _sec.getLayoutData();
+        if (data != null)
+        {
+            if (data instanceof GridData)
+            {
+                GridData gd = (GridData) data;
+                gd.horizontalSpan = horizontalSpan;
+                _sec.setLayoutData(gd);
+            }
+            else if (data instanceof TableWrapData)
+            {
+                TableWrapData td = (TableWrapData) data;
+                td.colspan = horizontalSpan;
+                _sec.setLayoutData(td);
+            }
+        }
+        return _sec;
+    }
+
+    private void displayHelp(String contextHelpId)
+    {
+        String contextId = HelpUtil.getContextId(contextHelpId, _pluginId);
+        if ((contextId != null) && (contextId.length() > 0))
+        {
+            PlatformUI.getWorkbench().getHelpSystem().displayHelp(contextId);
+        }
+        else
+        {
+            PlatformUI.getWorkbench().getHelpSystem().displayHelp();
+        }
+    }
+
+    /**
+     * Creates the section content, subclass should implement this method to create controls in the contect
+     * 
+     * @param parent the section content composite
+     */
+    protected abstract void createSectionContent(Composite parent);
+
+    /**
+     * Returns the section instance
+     * 
+     * @return the section instance
+     */
+    public Section getSection()
+    {
+        return _sec;
+    }
+
+    /**
+     * Returns the section content composite
+     * 
+     * @return the section content composite
+     */
+    public Composite getSectionContent()
+    {
+        return _content;
+    }
+
+    /**
+     * Adds listeners to the underlying widget.
+     */
+    protected void hookListeners()
+
+    {
+        if ((_sec.getExpansionStyle() & Section.TWISTIE) != 0 || (_sec.getExpansionStyle() & Section.TREE_NODE) != 0)
+        {
+            _sec.addExpansionListener(new ExpansionAdapter()
+            {
+                public void expansionStateChanging(ExpansionEvent e)
+
+                {
+                    CollapseableSection.this.expansionStateChanging(e.getState());
+                }
+
+                public void expansionStateChanged(ExpansionEvent e)
+                {
+                    CollapseableSection.this.expansionStateChanged(e.getState());
+                }
+            });
+        }
+    }
+
+    /**
+     * The section is about to expand or collapse.
+     * 
+     * @param expanding <code>true</code> for expansion, <code>false</code> for collapse.
+     */
+    protected void expansionStateChanging(boolean expanding)
+    {
+
+    }
+
+    /**
+     * The section has expanded or collapsed.
+     * 
+     * @param expanded <code>true</code> for expansion, <code>false</code> for collapse.
+     */
+    protected void expansionStateChanged(boolean expanded)
+    {
+        if (getManagedForm() != null)
+        {
+            getManagedForm().getForm().reflow(false);
+        }
+    }
+
+    public void setPluginId(String id)
+    {
+        _pluginId = id;
+    }
+}
diff --git a/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/common/CompositeEditSection.java b/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/common/CompositeEditSection.java
new file mode 100644
index 0000000..4feb8c4
--- /dev/null
+++ b/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/common/CompositeEditSection.java
@@ -0,0 +1,202 @@
+/***********************************************************************************************************************
+ * Copyright (c) 2009 Sybase, Inc. 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: Sybase, Inc. - initial API and implementation
+ **********************************************************************************************************************/
+package org.eclipse.datatools.sqltools.schemaobjecteditor.ui.common;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.ui.forms.widgets.FormToolkit;
+import org.eclipse.ui.forms.widgets.Section;
+
+/**
+ * A composite edit section, with a main control area and a button list. <br>
+ * User of this class can create any widgets on the main control area, for example, viewer.
+ * 
+ * @author Idull
+ */
+public class CompositeEditSection extends CollapseableSection
+{
+    protected Button[]      _buttons;
+    protected Composite     _left;
+    protected Composite     _buttonComp;
+    protected String[]      _buttonTexts;
+    protected String        _despText;
+    private int             _buttonWidth;
+    public static final int BUTTON_WIDTH = 80;
+
+    /**
+     * Constructs a composite edit section
+     * 
+     * @param toolkit the form toolkit
+     * @param title the title of this section
+     * @param display the <code>Display</code> instance
+     * @param isCollapseable whether the section is collapseable or not
+     * @param isCollapsed the initial collapse status of the section
+     * @param estyle the style of the section
+     * @param buttonTexts the button texts
+     * @param buttonWidth the button width
+     */
+    public CompositeEditSection(FormToolkit toolkit, String title, Display display, boolean isCollapseable,
+            boolean isCollapsed, int estyle, String[] buttonTexts, int buttonWidth)
+    {
+        super(toolkit, title, display, isCollapseable, isCollapsed, estyle);
+        _buttonTexts = buttonTexts;
+        _buttonWidth = buttonWidth;
+    }
+
+    /**
+     * Constructs a composite edit section
+     * 
+     * @param toolkit the form toolkit
+     * @param title the title of this section
+     * @param display the <code>Display</code> instance
+     * @param isCollapseable whether the section is collapseable or not
+     * @param isCollapsed the initial collapse status of the section
+     * @param estyle the style of the section
+     * @param buttonTexts the button texts
+     * @param buttonWidth the button width
+     * @param despText the description text of the section
+     */
+    public CompositeEditSection(FormToolkit toolkit, String title, Display display, boolean isCollapseable,
+            boolean isCollapsed, int estyle, String[] buttonTexts, int buttonWidth, String despText)
+    {
+        this(toolkit, title, display, isCollapseable, isCollapsed, estyle
+                | ((despText != null && !despText.trim().equals("")) ? Section.DESCRIPTION : SWT.NONE), buttonTexts,
+                buttonWidth);
+        _despText = despText;
+    }
+
+    protected void createSectionContent(Composite parent)
+    {
+        Assert.isNotNull(_buttonTexts);
+
+        // Set layout for section
+        getSection().setLayout(new GridLayout());
+
+        GridLayout layout = new GridLayout();
+        layout.numColumns = 2;
+        layout.marginTop = 2;
+        layout.marginBottom = 2;
+        parent.setLayout(layout);
+        parent.setLayoutData(new GridData(GridData.FILL_BOTH));
+
+        if (_despText != null && !_despText.trim().equals(""))
+        {
+            getSection().setDescription(_despText);
+        }
+        _left = _toolkit.createComposite(parent, SWT.NONE);
+        layout = new GridLayout();
+        layout.marginHeight = 2;
+        layout.marginWidth = 1;
+        _left.setLayout(layout);
+        _left.setLayoutData(new GridData(GridData.FILL_BOTH));
+
+        _buttonComp = _toolkit.createComposite(parent);
+
+        layout = new GridLayout();
+        layout.marginWidth = 0;
+        layout.marginHeight = 0;
+        _buttonComp.setLayout(layout);
+        _buttonComp.setLayoutData(new GridData(GridData.FILL_VERTICAL));
+
+        if (_buttonWidth < 0)
+        {
+            _buttonWidth = BUTTON_WIDTH;
+        }
+        List buttons = new ArrayList();
+        for (int i = 0; i < _buttonTexts.length; i++)
+        {
+            if (_buttonTexts[i] == null)
+            {
+                continue;
+            }
+            Button b = _toolkit.createButton(_buttonComp, "", SWT.NONE);
+            b.setText(_buttonTexts[i]);
+            GridData gd = new GridData();
+            gd.widthHint = _buttonWidth;
+            b.setLayoutData(gd);
+            b.setData(new Integer(i));
+            b.addSelectionListener(new SelectionListener()
+            {
+                public void widgetDefaultSelected(SelectionEvent e)
+                {
+                    buttonSelected(e, ((Integer) e.widget.getData()).intValue());
+                }
+
+                public void widgetSelected(SelectionEvent e)
+                {
+                    buttonSelected(e, ((Integer) e.widget.getData()).intValue());
+                }
+            });
+            buttons.add(b);
+        }
+
+        Composite blankComp = _toolkit.createComposite(_buttonComp, SWT.NONE);
+        blankComp.setLayoutData(new GridData(GridData.FILL_BOTH));
+        _toolkit.paintBordersFor(parent);
+        _buttons = (Button[]) buttons.toArray(new Button[buttons.size()]);
+    }
+
+    public Composite getLeftComposite()
+    {
+        return _left;
+    }
+
+    /**
+     * Returns the button list
+     * 
+     * @return
+     */
+    public Button[] getButtons()
+    {
+        return _buttons;
+    }
+
+    public Composite getButtonComp()
+    {
+        return _buttonComp;
+    }
+
+    public void enableButton(boolean enable, int buttonIndex)
+    {
+        if (_buttons == null || buttonIndex < 0 || buttonIndex > _buttons.length - 1)
+        {
+            return;
+        }
+        _buttons[buttonIndex].setEnabled(enable);
+    }
+
+    public boolean isButtonEnabled(boolean enable, int buttonIndex)
+    {
+        if (_buttons == null || buttonIndex < 0 || buttonIndex > _buttons.length - 1)
+        {
+            return false;
+        }
+        return _buttons[buttonIndex].isEnabled();
+    }
+
+    /**
+     * Will be called when the button is selected
+     * 
+     * @param e the selection event
+     * @param buttonIndex the index of the button
+     */
+    protected void buttonSelected(SelectionEvent e, int buttonIndex)
+    {
+
+    }
+}
diff --git a/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/common/TextFormEntry.java b/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/common/TextFormEntry.java
new file mode 100644
index 0000000..53ca98b
--- /dev/null
+++ b/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/common/TextFormEntry.java
@@ -0,0 +1,176 @@
+/***********************************************************************************************************************
+ * Copyright (c) 2009 Sybase, Inc. 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: Sybase, Inc. - initial API and implementation
+ **********************************************************************************************************************/
+package org.eclipse.datatools.sqltools.schemaobjecteditor.ui.common;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Layout;
+import org.eclipse.swt.widgets.Text;
+import org.eclipse.ui.forms.FormColors;
+import org.eclipse.ui.forms.widgets.FormToolkit;
+import org.eclipse.ui.forms.widgets.TableWrapData;
+import org.eclipse.ui.forms.widgets.TableWrapLayout;
+
+/**
+ * A text form entry used in form page
+ * 
+ * @author Idull
+ */
+public class TextFormEntry
+{
+    private Control     _nameLabel;
+    private Text        _text;
+    private Button      _button;
+    private FormToolkit _toolkit;
+    private int         _colSpan;
+
+    public TextFormEntry(Composite parent, FormToolkit toolkit, int textStyle, String labelText, String buttonText,
+            int colSpan)
+    {
+        _toolkit = toolkit;
+        _colSpan = colSpan;
+        createControl(parent, toolkit, textStyle, labelText, buttonText);
+    }
+
+    private void createControl(Composite parent, FormToolkit toolkit, int textStyle, String labelText, String buttonText)
+    {
+        _nameLabel = _toolkit.createLabel(parent, labelText);
+        _nameLabel.setForeground(toolkit.getColors().getColor(FormColors.TITLE));
+        _text = _toolkit.createText(parent, "", textStyle);
+        boolean buttonCreated = false;
+        if (buttonText != null && buttonText.trim().length() != 0)
+        {
+            _button = _toolkit.createButton(parent, buttonText, SWT.NONE);
+            buttonCreated = true;
+        }
+
+        Layout layout = parent.getLayout();
+        if (layout instanceof GridLayout)
+        {
+            GridLayout parentLayout = (GridLayout) layout;
+            // numColumns should be greater than or equals to 2
+            int numColumns = parentLayout.numColumns;
+            if (numColumns < 2)
+            {
+                // how to?
+                return;
+            }
+            if (!buttonCreated)
+            {
+                int numSpan = numColumns;
+                if (_colSpan < numColumns && !(_colSpan < 2))
+                {
+                    numSpan = _colSpan;
+                }
+                int textSpan = numSpan - 1;
+                GridData gd = new GridData();
+                _nameLabel.setLayoutData(gd);
+
+                gd = new GridData(GridData.FILL_HORIZONTAL);
+                gd.horizontalSpan = textSpan;
+                _text.setLayoutData(gd);
+            }
+            else
+            {
+                if (numColumns < 3)
+                {
+                    // how to?
+                    return;
+                }
+                int numSpan = numColumns;
+                if (_colSpan < numColumns && !(_colSpan < 3))
+                {
+                    numSpan = _colSpan;
+                }
+                int textSpan = numSpan - 2;
+                GridData gd = new GridData();
+                _nameLabel.setLayoutData(gd);
+
+                gd = new GridData(GridData.FILL_HORIZONTAL);
+                gd.horizontalSpan = textSpan;
+                _text.setLayoutData(gd);
+
+                gd = new GridData();
+                _button.setLayoutData(gd);
+            }
+        }
+        else if (layout instanceof TableWrapLayout)
+        {
+            TableWrapLayout parentLayout = (TableWrapLayout) layout;
+            // numColumns should be greater than or equals to 2
+            int numColumns = parentLayout.numColumns;
+            if (numColumns < 2)
+            {
+                // how to?
+                return;
+            }
+            if (!buttonCreated)
+            {
+                int numSpan = numColumns;
+                if (_colSpan < numColumns && !(_colSpan < 2))
+                {
+                    numSpan = _colSpan;
+                }
+                int textSpan = numSpan - 1;
+                TableWrapData td = new TableWrapData();
+                td.valign = TableWrapData.MIDDLE;
+                _nameLabel.setLayoutData(td);
+
+                td = new TableWrapData(TableWrapData.FILL_GRAB);
+                td.colspan = textSpan;
+                td.valign = TableWrapData.MIDDLE;
+                _text.setLayoutData(td);
+            }
+            else
+            {
+                if (numColumns < 3)
+                {
+                    // how to?
+                    return;
+                }
+                int numSpan = numColumns;
+                if (_colSpan < numColumns && !(_colSpan < 3))
+                {
+                    numSpan = _colSpan;
+                }
+                int textSpan = numSpan - 2;
+                TableWrapData td = new TableWrapData();
+                td.valign = TableWrapData.MIDDLE;
+                _nameLabel.setLayoutData(td);
+
+                td = new TableWrapData(TableWrapData.FILL_GRAB);
+                td.colspan = textSpan;
+                td.valign = TableWrapData.MIDDLE;
+                _text.setLayoutData(td);
+
+                td = new TableWrapData();
+                _button.setLayoutData(td);
+            }
+        }
+        _toolkit.paintBordersFor(parent);
+    }
+
+    public Button getButton()
+    {
+        return _button;
+    }
+
+    public Control getNameLabel()
+    {
+        return _nameLabel;
+    }
+
+    public Text getText()
+    {
+        return _text;
+    }
+}
diff --git a/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/core/Constants.java b/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/core/Constants.java
new file mode 100644
index 0000000..771b111
--- /dev/null
+++ b/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/core/Constants.java
@@ -0,0 +1,28 @@
+/***********************************************************************************************************************
+ * Copyright (c) 2009 Sybase, Inc. 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: Sybase, Inc. - initial API and implementation
+ **********************************************************************************************************************/
+package org.eclipse.datatools.sqltools.schemaobjecteditor.ui.core;
+
+/**
+ * Constants for consumers
+ * 
+ * @author Idull
+ */
+public class Constants
+{
+    public static final String SCHEMA_EDITOR_ID         = org.eclipse.datatools.sqltools.schemaobjecteditor.ui.internal.Constants.SCHEMA_EDITOR_ID;
+    public static final String SCHEMA_EDITOR_NESTED_ID  = org.eclipse.datatools.sqltools.schemaobjecteditor.ui.internal.Constants.SCHEMA_EDITOR_NESTED_ID;
+
+    public static final String REFRESH_EDITOR_ACTION_ID = "refresh.schema.editor.action.id";
+    public static final String REVERT_EDITOR_ACTION_ID  = "revert.schema.editor.action.id";
+    public static final String PROBLEMS_VIEW_ID         = "org.eclipse.ui.views.ProblemView";
+
+    public static final String REFRESH_REVERT_GROUP     = "refresh.revert.action.group";
+    public static final String SAVE_PREFERENCE_GROUP    = "sav.preference.action.group";
+
+    public static final String PREFERENCE_PAGE_ID       = "org.eclipse.datatools.sqltools.schemaobjecteditor.page1";
+}
diff --git a/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/core/DefaultSchemaObjectEditorActionBarContributor.java b/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/core/DefaultSchemaObjectEditorActionBarContributor.java
new file mode 100644
index 0000000..2511f39
--- /dev/null
+++ b/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/core/DefaultSchemaObjectEditorActionBarContributor.java
@@ -0,0 +1,95 @@
+/***********************************************************************************************************************
+ * Copyright (c) 2009 Sybase, Inc. 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: Sybase, Inc. - initial API and implementation
+ **********************************************************************************************************************/
+package org.eclipse.datatools.sqltools.schemaobjecteditor.ui.core;
+
+import org.eclipse.datatools.sqltools.schemaobjecteditor.ui.ISchemaObjectEditor;
+import org.eclipse.datatools.sqltools.schemaobjecteditor.ui.ISchemaObjectEditorActionBarContributor;
+import org.eclipse.jface.action.ICoolBarManager;
+import org.eclipse.jface.action.IMenuManager;
+import org.eclipse.jface.action.IStatusLineManager;
+import org.eclipse.jface.action.IToolBarManager;
+import org.eclipse.ui.IActionBars;
+import org.eclipse.ui.IEditorPart;
+import org.eclipse.ui.IWorkbenchPage;
+
+/**
+ * Consumers should extend this class instead of implementing <code>ISchemaObjectEditorActionBarContributor</code>
+ * 
+ * @author Idull
+ */
+public class DefaultSchemaObjectEditorActionBarContributor implements ISchemaObjectEditorActionBarContributor
+{
+    protected ISchemaObjectEditor _editor;
+    /**
+     * The action bars; <code>null</code> until <code>init</code> is called.
+     */
+    private IActionBars           bars;
+
+    /**
+     * The workbench page; <code>null</code> until <code>init</code> is called.
+     */
+    private IWorkbenchPage        page;
+
+    public void setEditor(ISchemaObjectEditor editor)
+    {
+        _editor = editor;
+    }
+
+    public void contributeToCoolBar(ICoolBarManager coolBarManager)
+    {
+
+    }
+
+    public void contributeToMenu(IMenuManager menuManager)
+    {
+
+    }
+
+    public void contributeToStatusLine(IStatusLineManager statusLineManager)
+    {
+
+    }
+
+    public void contributeToToolBar(IToolBarManager toolBarManager)
+    {
+
+    }
+
+    public void setActivePage(IEditorPart activeEditor)
+    {
+
+    }
+
+    public void init(IActionBars bars, IWorkbenchPage page)
+    {
+        this.page = page;
+        this.bars = bars;
+        // TODO reference EditorActionBarContributor.init implementation
+    }
+
+    /**
+     * Returns this contributor's action bars.
+     * 
+     * @return the action bars
+     */
+    public IActionBars getActionBars()
+    {
+        return bars;
+    }
+
+    /**
+     * Returns this contributor's workbench page.
+     * 
+     * @return the workbench page
+     */
+    public IWorkbenchPage getPage()
+    {
+        return page;
+    }
+
+}
diff --git a/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/core/DefaultSchemaObjectEditorHandler.java b/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/core/DefaultSchemaObjectEditorHandler.java
new file mode 100644
index 0000000..3449327
--- /dev/null
+++ b/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/core/DefaultSchemaObjectEditorHandler.java
@@ -0,0 +1,647 @@
+/***********************************************************************************************************************
+ * Copyright (c) 2009 Sybase, Inc. 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: Sybase, Inc. - initial API and implementation
+ **********************************************************************************************************************/
+package org.eclipse.datatools.sqltools.schemaobjecteditor.ui.core;
+
+import java.util.Map;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.MultiStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.datatools.connectivity.sqm.core.containment.ContainmentServiceImpl;
+import org.eclipse.datatools.connectivity.sqm.core.definition.DatabaseDefinition;
+import org.eclipse.datatools.connectivity.sqm.internal.core.definition.DatabaseDefinitionRegistryImpl;
+import org.eclipse.datatools.modelbase.sql.routines.Routine;
+import org.eclipse.datatools.modelbase.sql.schema.Database;
+import org.eclipse.datatools.modelbase.sql.schema.SQLObject;
+import org.eclipse.datatools.modelbase.sql.tables.Table;
+import org.eclipse.datatools.sqltools.common.ui.dialog.SaveAsDialog;
+import org.eclipse.datatools.sqltools.core.DatabaseIdentifier;
+import org.eclipse.datatools.sqltools.core.SQLToolsFacade;
+import org.eclipse.datatools.sqltools.editor.core.connection.ISQLEditorConnectionInfo;
+import org.eclipse.datatools.sqltools.schemaobjecteditor.model.AbstractSchemaObjectEditModel;
+import org.eclipse.datatools.sqltools.schemaobjecteditor.model.ISchemaObjectEditModel;
+import org.eclipse.datatools.sqltools.schemaobjecteditor.model.ISchemaObjectImmutableModel;
+import org.eclipse.datatools.sqltools.schemaobjecteditor.ui.IErrorItem;
+import org.eclipse.datatools.sqltools.schemaobjecteditor.ui.IResourceChangeEvent;
+import org.eclipse.datatools.sqltools.schemaobjecteditor.ui.ISchemaObjectEditor;
+import org.eclipse.datatools.sqltools.schemaobjecteditor.ui.ISchemaObjectEditorHandler;
+import org.eclipse.datatools.sqltools.schemaobjecteditor.ui.ISchemaObjectEditorInput;
+import org.eclipse.datatools.sqltools.schemaobjecteditor.ui.ISchemaObjectEditorPage;
+import org.eclipse.datatools.sqltools.schemaobjecteditor.ui.SchemaObjectEditorModelListenersNotifier;
+import org.eclipse.datatools.sqltools.schemaobjecteditor.ui.extensions.IEditorPageDescriptor;
+import org.eclipse.datatools.sqltools.schemaobjecteditor.ui.internal.SOEUIPlugin;
+import org.eclipse.datatools.sqltools.schemaobjecteditor.ui.internal.Constants;
+import org.eclipse.datatools.sqltools.schemaobjecteditor.ui.internal.core.ScriptsExecutionRunnable;
+import org.eclipse.datatools.sqltools.schemaobjecteditor.ui.internal.ui.SavePreviewDialog;
+import org.eclipse.datatools.sqltools.schemaobjecteditor.ui.util.SQLUtil;
+import org.eclipse.datatools.sqltools.schemaobjecteditor.ui.util.SchemaObjectEditorUtils;
+import org.eclipse.datatools.sqltools.sql.util.ModelUtil;
+import org.eclipse.datatools.sqltools.sqleditor.SQLEditor;
+import org.eclipse.datatools.sqltools.sqleditor.SQLEditorConnectionInfo;
+import org.eclipse.jface.dialogs.ErrorDialog;
+import org.eclipse.jface.dialogs.IDialogConstants;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.ui.IEditorPart;
+import org.eclipse.ui.IWorkbenchPage;
+
+/**
+ * Instead of implementing the <code>ISchemaEditorConfiguration</code> from scratch, the consumer should extend this
+ * class, and rewrite some methods.
+ * 
+ * @author Idull
+ */
+public class DefaultSchemaObjectEditorHandler implements ISchemaObjectEditorHandler
+{
+    protected ISchemaObjectEditor                      _editor;
+    protected SchemaObjectEditorModelListenersNotifier _notifier;
+    protected boolean                                  _inSavingProcess = false;
+
+    /**
+     * Constructs a multiple status based on the error map
+     * 
+     * @param pageErrors
+     * @return
+     */
+    protected IStatus constructStatus(Map pageErrors)
+    {
+        if (_editor == null)
+        {
+            return null;
+        }
+
+        MultiStatus errorStatus = new MultiStatus(SOEUIPlugin.PLUGIN_ID, 1,
+                Messages.DefaultSchemaObjectEditorHandler_validation_fail, null);
+        ISchemaObjectEditorPage[] pages = _editor.getAllPages();
+        for (int i = 0; i < pages.length; i++)
+        {
+            if (pages[i] != null)
+            {
+                MultiStatus pageStatus = new MultiStatus(SOEUIPlugin.PLUGIN_ID, 1,
+                        Messages.DefaultSchemaObjectEditorHandler_page + pages[i].getPageDescriptor().getPageName(),
+                        null);
+                IErrorItem[] items = (IErrorItem[]) pageErrors.get(pages[i]);
+                if (items == null)
+                {
+                    continue;
+                }
+                for (int j = 0; j < items.length; j++)
+                {
+                    if (items[j] != null)
+                    {
+                        IStatus status = new Status(IStatus.ERROR, SOEUIPlugin.PLUGIN_ID, 1, items[j].getMessage(), null);
+                        pageStatus.add(status);
+                    }
+                }
+                errorStatus.add(pageStatus);
+            }
+        }
+        return errorStatus;
+    }
+
+    public void dispose()
+    {
+        if (getEditorInput() != null)
+        {
+            getEditorInput().getEditModelObject().stopLogging();
+        }
+    }
+
+    public void doSave(IProgressMonitor monitor)
+    {
+        if (_editor == null)
+        {
+            return;
+        }
+
+        _inSavingProcess = true;
+        Map pageErrors = _editor.validate();
+        if (!hasError(pageErrors))
+        {
+            IPreferenceStore store = SOEUIPlugin.getDefault().getPreferenceStore();
+            boolean showPreview = store.getBoolean(Constants.PREFERENCE_ALWAYS_SHOW_PREVIEW);
+            String scripts = generateScript();
+
+            if (showPreview && scripts.length() != 0)
+            {
+                ISchemaObjectEditorInput input = (ISchemaObjectEditorInput) ((IEditorPart) _editor).getEditorInput();
+                SavePreviewDialog dlg = new SavePreviewDialog(SOEUIPlugin.getActiveWorkbenchShell(), scripts, input
+                        .getDatabaseIdentifier(), _editor, _editor.isSyncSave(), monitor, getGroupExecDisplayString(),
+                        _editor.getEditorDescriptor().getEditorName());
+                dlg.open();
+            }
+            // execute the scripts if the preview dialog does not pop up
+            else
+            {
+                ISchemaObjectEditorInput input = (ISchemaObjectEditorInput) ((IEditorPart) _editor).getEditorInput();
+                ScriptsExecutionRunnable scriptsRunnable = new ScriptsExecutionRunnable(scripts, input
+                        .getDatabaseIdentifier(), new SQLExecutionJobListener(_editor, monitor), _editor.isSyncSave(),
+                        monitor, getGroupExecDisplayString(), _editor.getEditorDescriptor().getEditorName());
+                scriptsRunnable.run();
+            }
+        }
+        else
+        {
+            IStatus status = constructStatus(pageErrors);
+            ErrorDialog dlg = new ErrorDialog(SOEUIPlugin.getActiveWorkbenchShell(),
+                    Messages.DefaultSchemaObjectEditorHandler_validation_problem,
+                    Messages.DefaultSchemaObjectEditorHandler_existing_errors, status, IStatus.ERROR);
+            dlg.open();
+        }
+        _inSavingProcess = false;
+    }
+
+    /**
+     * Does nothing
+     */
+    public void doSaveAs()
+    {
+
+    }
+
+    public String generateScript()
+    {
+        return getEditorInput().getEditModelObject().getDeltaDDL();
+    }
+
+    public Object getAdapter(Class adapter)
+    {
+        return null;
+    }
+
+    /**
+     * Scans the error map to see if there are real errors
+     * 
+     * @param pageErrors
+     * @return
+     */
+    protected boolean hasError(Map pageErrors)
+    {
+        if (pageErrors == null || pageErrors.keySet().size() == 0 || _editor == null)
+        {
+            return false;
+        }
+        ISchemaObjectEditorPage[] pages = _editor.getAllPages();
+        for (int i = 0; i < pages.length; i++)
+        {
+            if (pages[i] != null)
+            {
+                IErrorItem[] items = (IErrorItem[]) pageErrors.get(pages[i]);
+                if (items != null && items.length > 0)
+                {
+                    for (int j = 0; j < items.length; j++)
+                    {
+                        if (items[j].getSeverity() == IErrorItem.ERROR || items[j].getSeverity() == IErrorItem.INFO)
+                        {
+                            return true;
+                        }
+                    }
+                }
+            }
+        }
+        return false;
+    }
+
+    public boolean isSaveAsAllowed()
+    {
+        return false;
+    }
+
+    public void pageChanged(int newPageIndex)
+    {
+        // Do not refresh page here. Pages only need to handle setActive
+    }
+
+    protected boolean isEditorDisposed()
+    {
+        IEditorPart part = SOEUIPlugin.getActiveWorkbenchPage().findEditor(_editor.getEditorInput());
+        if (part == null)
+        {
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * SubClass should override this method to refresh the model first, then refresh each page
+     */
+    public void refreshFromDB(IProgressMonitor monitor)
+    {
+        if (_editor == null)
+        {
+            return;
+        }
+
+        // Set the dirty status first to disable the "Save" button
+        SOEUIPlugin.getActiveWorkbenchShell().getDisplay().syncExec(new Runnable()
+        {
+            public void run()
+            {
+                _editor.clearDirty();
+            }
+        });
+
+        if (monitor != null)
+        {
+            if (isEditorDisposed())
+            {
+                monitor.beginTask(Messages.DefaultSchemaObjectEditorHandler_refreshing, monitor.UNKNOWN);
+            }
+            else
+            {
+                monitor.beginTask(Messages.DefaultSchemaObjectEditorHandler_refreshing_schema_editor, monitor.UNKNOWN);
+            }
+            monitor.subTask(Messages.DefaultSchemaObjectEditorHandler_subtask_name);
+        }
+
+        // change for cr544833-1, we also need refresh database when the editor part is disposed.
+        // if (!isEditorDisposed())
+        {
+            // Refresh the edit model
+            int theStatus = -1;
+            SQLObject sqlObject = getEditorInput().getEditModelObject().getMainSQLObject();
+            if (sqlObject == null)
+            {
+                theStatus = ISchemaObjectEditModel.FATAL_ERROR_MAIN_OBJ_LOST;
+            }
+            else
+            {
+                theStatus = getEditorInput().getEditModelObject().refreshFromDB();
+            }
+            final int status = theStatus;
+
+            SOEUIPlugin.getActiveWorkbenchShell().getDisplay().syncExec(new Runnable()
+            {
+                public void run()
+                {
+                    if (status == ISchemaObjectEditModel.FATAL_ERROR_MAIN_OBJ_LOST)
+                    {
+                        // Change for CR472677-1
+                        promptSaveAndCloseEditor();
+                    }
+                }
+
+            });
+
+            // Won't register listeners and refresh page if editor is already closed
+            if (status != ISchemaObjectEditModel.FATAL_ERROR_MAIN_OBJ_LOST)
+            {
+                // re-register all the listeners
+                if (_notifier == null)
+                {
+                    _notifier = getNotifier();
+                }
+                _notifier.registerListener(getEditorInput());
+
+                final ISchemaObjectEditorPage[] pages = _editor.getAllPages();
+                SOEUIPlugin.getActiveWorkbenchShell().getDisplay().syncExec(new Runnable()
+                {
+                    public void run()
+                    {
+                        for (int i = 0; i < pages.length; i++)
+                        {
+                            if (pages[i] != null)
+                            {
+                                try
+                                {
+                                    pages[i].modelRegenerated();
+                                }
+                                catch (Exception ex)
+                                {
+
+                                }
+                            }
+                        }
+                        _editor.setEditorPartName(SQLUtil.unquote(getEditorInput().getName()));
+                        SchemaObjectEditorUtils.expandNode(getEditorInput().getEditModelObject()
+                                .getSchemaObjectImmutableModel().getMainSQLObject());
+                    }
+                });
+            }
+        }
+        if (monitor != null)
+        {
+            monitor.done();
+        }
+    }
+
+    /**
+     * If the model object is lost, prompt the user to save the DDL, and close the editor.
+     */
+    private void promptSaveAndCloseEditor()
+    {
+        MessageDialog dialog = new MessageDialog(SOEUIPlugin.getActiveWorkbenchShell(),
+                Messages.MainSQLObjectLostPromoptSavingTitle, null, Messages.MainSQLObjectLostPromoptSavingMessage,
+                MessageDialog.QUESTION, new String[]
+                {
+                    IDialogConstants.YES_LABEL, IDialogConstants.NO_LABEL
+                }, 0);
+        if (dialog.open() == IDialogConstants.OK_ID)
+        {
+            ISchemaObjectEditModel schemaObjectEditModel = getEditorInput().getEditModelObject();
+            String ddl = null;
+            if (schemaObjectEditModel instanceof AbstractSchemaObjectEditModel)
+            {
+                ddl = ((AbstractSchemaObjectEditModel) schemaObjectEditModel).getBackupedDDL();
+            }
+
+            final SaveAsDialog dia = new SaveAsDialog(SOEUIPlugin.getActiveWorkbenchShell(), ddl);
+            dia.setOriginalName(_editor.getDisplayName() + "_ddl.sql");
+            dia.setOpenMode(getOpenFileAfterSaveasOption());
+            dia.open();
+            IEditorPart editor = dia.getEditor();
+            if (editor != null && (editor instanceof SQLEditor))
+            {
+                ISchemaObjectEditorInput input = (ISchemaObjectEditorInput) _editor.getEditorInput();
+                DatabaseIdentifier databaseIdentifier = input.getDatabaseIdentifier();
+                ISQLEditorConnectionInfo connInfo = new SQLEditorConnectionInfo(SQLToolsFacade
+                        .getConfigurationByProfileName(databaseIdentifier.getProfileName())
+                        .getDatabaseVendorDefinitionId(), databaseIdentifier.getProfileName(), databaseIdentifier
+                        .getDBname(), databaseIdentifier.getDBname());
+                ((SQLEditor) editor).setConnectionInfo(connInfo);
+            }
+        }
+
+        final IWorkbenchPage workPage = SOEUIPlugin.getActiveWorkbenchPage();
+        workPage.closeEditor((IEditorPart) _editor, false);
+    }
+
+    public void resouceChanged(IResourceChangeEvent event)
+    {
+
+    }
+
+    public void revert()
+    {
+        if (_editor == null)
+        {
+            return;
+        }
+
+        // Check Model Existence before real revert object.
+        ISchemaObjectEditModel model = getEditorInput().getEditModelObject();
+        if (!model.checkModelExistence())
+        {
+            promptObjectLost(model);
+            promptSaveAndCloseEditor();
+            return;
+        }
+
+        // Revert the edit model
+        getEditorInput().getEditModelObject().revert();
+        // re-register all the listeners
+        if (_notifier == null)
+        {
+            _notifier = getNotifier();
+        }
+        _notifier.registerListener(getEditorInput());
+        ISchemaObjectEditorPage[] pages = _editor.getAllPages();
+        for (int i = 0; i < pages.length; i++)
+        {
+            if (pages[i] != null)
+            {
+                try
+                {
+                    pages[i].revert();
+                }
+                catch (Exception e)
+                {
+
+                }
+            }
+        }
+        _editor.clearDirty();
+    }
+
+    public void setEditor(ISchemaObjectEditor editor)
+    {
+        this._editor = editor;
+        editor.setEditorPartName(SQLUtil.unquote(getEditorInput().getName()));
+    }
+
+    public String getDisplayName()
+    {
+        return Messages.SavePreviewDialog_noname_sql;
+    }
+
+    public ISchemaObjectEditorInput getEditorInput()
+    {
+        if (_editor == null)
+        {
+            return null;
+        }
+        ISchemaObjectEditorInput input = (ISchemaObjectEditorInput) ((IEditorPart) _editor).getEditorInput();
+        return input;
+    }
+
+    public void hookInitialization()
+    {
+
+    }
+
+    /**
+     * Returns the editor model listeners notifier. The notifier is registered as the listener of the schema object
+     * editor model.
+     * 
+     * @return
+     */
+    public synchronized SchemaObjectEditorModelListenersNotifier getNotifier()
+    {
+        if (_notifier == null)
+        {
+            _notifier = new SchemaObjectEditorModelListenersNotifier();
+            _notifier.registerListener(getEditorInput());
+        }
+        return _notifier;
+    }
+
+    public boolean inSavingProcess()
+    {
+        return _inSavingProcess;
+    }
+
+    public String getGroupExecDisplayString()
+    {
+        return Messages.DefaultSchemaObjectEditorHandler_modifying
+                + " " + _editor.getEditorDescriptor().getObjectTypeName() + ": " + getQualifiedObjectName(); //$NON-NLS-2$ //$NON-NLS-3$
+    }
+
+    protected String getQualifiedObjectName()
+    {
+        ISchemaObjectImmutableModel immutableModel = getEditorInput().getEditModelObject()
+                .getSchemaObjectImmutableModel();
+        StringBuffer sb = new StringBuffer(""); //$NON-NLS-1$
+        Object root = ContainmentServiceImpl.INSTANCE.getRootElement(immutableModel.getMainSQLObject());
+        if (root != null && root instanceof Database)
+        {
+            Database db = (Database) root;
+            DatabaseDefinition dbDefinition = DatabaseDefinitionRegistryImpl.INSTANCE.getDefinition(db);
+            sb.append(ModelUtil.getDatabaseName(immutableModel.getMainSQLObject())).append("."); //$NON-NLS-1$
+
+            String schemaName = new String();
+            SQLObject sqlObject = immutableModel.getMainSQLObject();
+            if (sqlObject instanceof Table)
+            {
+                schemaName = ((Table) sqlObject).getSchema().getName();
+            }
+            else if (sqlObject instanceof Routine)
+            {
+                schemaName = ((Routine) sqlObject).getSchema().getName();
+            }
+            sb.append(schemaName);
+        }
+        sb.append(immutableModel.getMainSQLObject().getName());
+        return sb.toString();
+    }
+
+    public boolean getOpenFileAfterSaveasOption()
+    {
+        IPreferenceStore store = SOEUIPlugin.getDefault().getPreferenceStore();
+        boolean isOpenFile = store
+                .getBoolean(org.eclipse.datatools.sqltools.schemaobjecteditor.ui.internal.Constants.PREFERENCE_OPEN_FILE_AFTER_SAVEAS);
+
+        return isOpenFile;
+    }
+
+    /**
+     * Should be invoked in UI thread
+     */
+    public void forceFocusObject(SQLObject object)
+    {
+        SOEUIPlugin.getActiveWorkbenchPage().activate(_editor);
+        ISchemaObjectEditorPage[] pages = _editor.getAllPages();
+        for (int i = 0; i < pages.length; i++)
+        {
+            if (pages[i] == null)
+            {
+                continue;
+            }
+            IEditorPageDescriptor pageDesp = pages[i].getPageDescriptor();
+            try
+            {
+                Class c = null;
+                try
+                {
+                    c = Class.forName(pageDesp.getObjectClassType());
+                }
+                catch (Exception e)
+                {
+                }
+                if (c != null && c.isInstance(object))
+                {
+                    ((SchemaObjectEditor) _editor).setActivePage(pages[i].getPageDescriptor().getPageId());
+                    pages[i].setFocus(ISchemaObjectEditorPage.UNKNOWN_ITEM_TYPE, object);
+                    return;
+                }
+            }
+            catch (Exception e)
+            {
+                // do nothing
+            }
+        }
+    }
+
+    /**
+     * Do check based on the parameter doCheck.
+     * 
+     * @param doCheck
+     * @return
+     * @author sul
+     */
+    public boolean checkSchemaObjectExistence(boolean doCheck)
+    {
+        if (!doCheck)
+        {
+            return true;
+        }
+
+        ISchemaObjectEditModel editModel = getEditorInput().getEditModelObject();
+
+        if (!editModel.checkModelExistence())
+        {
+            promptObjectLost(editModel);
+            
+            MessageDialog dialog = new MessageDialog(SOEUIPlugin.getActiveWorkbenchShell(),
+                    Messages.MainSQLObjectLostPromoptSavingTitle, null, Messages.MainSQLObjectLostPromoptSavingMessage,
+                    MessageDialog.QUESTION, new String[]
+                    {
+                        IDialogConstants.YES_LABEL, IDialogConstants.NO_LABEL
+                    }, 0);
+
+            ISchemaObjectEditModel schemaObjectEditModel = getEditorInput().getEditModelObject();
+            String ddl = null;
+            if (schemaObjectEditModel instanceof AbstractSchemaObjectEditModel)
+            {
+                ddl = ((AbstractSchemaObjectEditModel) schemaObjectEditModel).getBackupedDDL();
+            }
+            // if ddl is not null, prompt to save it.
+            if (ddl != null && dialog.open() == IDialogConstants.OK_ID)
+            {
+                final SaveAsDialog dia = new SaveAsDialog(SOEUIPlugin.getActiveWorkbenchShell(), ddl);
+                dia.setOriginalName(_editor.getDisplayName() + "_ddl.sql");
+                dia.setOpenMode(getOpenFileAfterSaveasOption());
+                //
+                SOEUIPlugin.getActiveWorkbenchShell().getDisplay().asyncExec(new Runnable()
+                {
+                    public void run()
+                    {
+                        dia.open();
+                        IEditorPart editor = dia.getEditor();
+                        if (editor != null && (editor instanceof SQLEditor))
+                        {
+                            ISchemaObjectEditorInput input = (ISchemaObjectEditorInput) _editor.getEditorInput();
+                            DatabaseIdentifier databaseIdentifier = input.getDatabaseIdentifier();
+                            ISQLEditorConnectionInfo connInfo = new SQLEditorConnectionInfo(SQLToolsFacade
+                                    .getConfigurationByProfileName(databaseIdentifier.getProfileName())
+                                    .getDatabaseVendorDefinitionId(), databaseIdentifier.getProfileName(),
+                                    databaseIdentifier.getDBname(), databaseIdentifier.getDBname());
+                            ((SQLEditor) editor).setConnectionInfo(connInfo);
+                        }
+                    }
+                });
+
+            }
+
+            final IWorkbenchPage workPage = SOEUIPlugin.getActiveWorkbenchPage();
+
+            SOEUIPlugin.getActiveWorkbenchShell().getDisplay().asyncExec(new Runnable()
+            {
+                public void run()
+                {
+                    workPage.closeEditor((IEditorPart) _editor, false);
+                }
+            });
+
+            return false;
+        }
+        return true;
+
+    }
+
+    private void promptObjectLost(final ISchemaObjectEditModel editModel)
+    {
+        SOEUIPlugin.getActiveWorkbenchShell().getDisplay().syncExec(new Runnable()
+        {
+            public void run()
+            {
+                String[] buttons = new String[]
+                {
+                    IDialogConstants.OK_LABEL
+                };
+                MessageDialog d = new MessageDialog(SOEUIPlugin.getActiveWorkbenchShell(),
+                        Messages.AbstractSchemaObjectEditModel_fatal_error, null, Messages.bind(
+                                Messages.AbstractSchemaObjectEditModel_main_object_lost, editModel.getMainSQLObject()
+                                        .getName()), MessageDialog.ERROR, buttons, 0);
+                d.open();
+                return;
+            }
+        });
+    }
+
+}
diff --git a/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/core/ErrorItem.java b/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/core/ErrorItem.java
new file mode 100644
index 0000000..4412fcb
--- /dev/null
+++ b/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/core/ErrorItem.java
@@ -0,0 +1,54 @@
+/***********************************************************************************************************************
+ * Copyright (c) 2009 Sybase, Inc. 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: Sybase, Inc. - initial API and implementation
+ **********************************************************************************************************************/
+package org.eclipse.datatools.sqltools.schemaobjecteditor.ui.core;
+
+import org.eclipse.datatools.sqltools.schemaobjecteditor.ui.IErrorItem;
+
+/**
+ * 
+ * @author Idull
+ */
+public class ErrorItem implements IErrorItem
+{
+    private Object _source;
+    private String _message;
+    public int     _severity = ERROR;
+
+    public ErrorItem(Object source, String message)
+    {
+        this(source, message, ERROR);
+    }
+
+    public ErrorItem(Object source, String message, int severity)
+    {
+        super();
+        this._source = source;
+        this._message = message;
+        this._severity = severity;
+    }
+
+    public String getMessage()
+    {
+        return _message;
+    }
+
+    public Object getSource()
+    {
+        return _source;
+    }
+
+    public int getSeverity()
+    {
+        return _severity;
+    }
+
+    public void setSeverity(int severity)
+    {
+        this._severity = severity;
+    }
+}
diff --git a/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/core/Messages.java b/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/core/Messages.java
new file mode 100644
index 0000000..1cf8bc6
--- /dev/null
+++ b/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/core/Messages.java
@@ -0,0 +1,55 @@
+/***********************************************************************************************************************
+ * Copyright (c) 2009 Sybase, Inc. 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: Sybase, Inc. - initial API and implementation
+ **********************************************************************************************************************/
+package org.eclipse.datatools.sqltools.schemaobjecteditor.ui.core;
+
+import org.eclipse.osgi.util.NLS;
+
+public class Messages extends NLS
+{
+    private static final String BUNDLE_NAME = Messages.class.getPackage().getName() + ".messages";
+    static
+    {
+        NLS.initializeMessages(BUNDLE_NAME, Messages.class);
+    }
+    public static String        DefaultSchemaObjectEditorHandler_existing_errors;
+    public static String        DefaultSchemaObjectEditorHandler_modifying;
+    public static String        DefaultSchemaObjectEditorHandler_page;
+    public static String        DefaultSchemaObjectEditorHandler_refreshing;
+    public static String        DefaultSchemaObjectEditorHandler_refreshing_schema_editor;
+    public static String        DefaultSchemaObjectEditorHandler_subtask_name;
+    public static String        DefaultSchemaObjectEditorHandler_validation_fail;
+    public static String        DefaultSchemaObjectEditorHandler_validation_problem;
+    public static String        ErrorPage_error;
+    public static String        ErrorPage_error_msg;
+    public static String        SavePreviewDialog_cancel;
+    public static String        SavePreviewDialog_copy;
+    public static String        SavePreviewDialog_execute;
+    public static String        SavePreviewDialog_execution_failed_msg;
+    public static String        SavePreviewDialog_noname_sql;
+    public static String        SavePreviewDialog_not_show_again;
+    public static String        SavePreviewDialog_preview;
+    public static String        SavePreviewDialog_problem;
+    public static String        SavePreviewDialog_save_as;
+    public static String        SavePreviewDialog_select_all;
+    public static String        SchemaObjectEditor_error;
+    public static String        SchemaObjectEditor_error_id;
+    public static String        SchemaObjectEditor_no_handler;
+    public static String        SchemaObjectEditor_no_page;
+    public static String        SchemaObjectEditor_preferences;
+    public static String        SchemaObjectEditor_save_to_server;
+    public static String        SchemaObjectEditorInput_name;
+    public static String        SchemaObjectEditorPage_help_name;
+    public static String        SchemaObjectEditorPage_help_tip;
+    public static String        SchemaObjectEditor_pagechange_error;
+    public static String        SQLExecutionJobListener_refreshing;
+    public static String        MainSQLObjectLostPromoptSavingTitle;
+    public static String        MainSQLObjectLostPromoptSavingMessage;
+
+    public static String        AbstractSchemaObjectEditModel_fatal_error;
+    public static String        AbstractSchemaObjectEditModel_main_object_lost;
+}
diff --git a/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/core/NestedEditorPage.java b/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/core/NestedEditorPage.java
new file mode 100644
index 0000000..a1be744
--- /dev/null
+++ b/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/core/NestedEditorPage.java
@@ -0,0 +1,99 @@
+/***********************************************************************************************************************
+ * Copyright (c) 2009 Sybase, Inc. 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: Sybase, Inc. - initial API and implementation
+ **********************************************************************************************************************/
+package org.eclipse.datatools.sqltools.schemaobjecteditor.ui.core;
+
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.ui.IEditorInput;
+import org.eclipse.ui.IEditorPart;
+import org.eclipse.ui.IEditorSite;
+import org.eclipse.ui.PartInitException;
+import org.eclipse.ui.forms.IManagedForm;
+import org.eclipse.ui.forms.editor.FormEditor;
+
+/**
+ * A schema object editor page whose content is a nested editor
+ * 
+ * @author Idull
+ */
+public abstract class NestedEditorPage extends SchemaObjectEditorPage
+{
+    protected Control _control = null;
+    
+    public NestedEditorPage()
+    {
+        super();
+    }
+
+    public NestedEditorPage(FormEditor editor, String id, String title)
+    {
+        super(editor, id, title);
+    }
+
+    public NestedEditorPage(String id, String title)
+    {
+        super(id, title);
+    }
+
+    protected void createFormContent(IManagedForm managedForm)
+    {
+        //do nothing as we're using the nested editor's control
+    }
+
+    
+    public Control getPartControl()
+    {
+        return _control;
+    }
+    
+    public void setPartControl(Control control)
+    {
+        _control = control;
+    }
+    /**
+     * Subclass should implement this method to reutrn the editor part in this page
+     * 
+     * @return
+     */
+    public abstract IEditorPart getNestedEditor();
+
+    /**
+     * Subclass should implement this method to reutrn the editor input for the nested editor
+     * 
+     * @return
+     */
+    public abstract IEditorInput getNestedEditorInput();
+    
+    public void init(IEditorSite site, IEditorInput input) throws PartInitException
+    {
+        super.init(site, input);
+        getNestedEditor().init(site, input);
+    }
+    
+    
+    public boolean isEditor()
+    {
+        return true;
+    }
+    
+    
+    public boolean isDirty()
+    {
+        IEditorPart editor = getNestedEditor();
+        return (editor != null && editor.isDirty());
+    }
+    
+    /**
+     * Notifies this page that a page switch event has occurred. This is to workaround the problem that in FormEditor's
+     * pageChange implementation, setActive(true) is called before setActive(false).
+     * 
+     */
+    public void aboutToLeave()
+    {
+        //by default do nothing
+    }
+}
diff --git a/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/core/RefreshEditModelJob.java b/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/core/RefreshEditModelJob.java
new file mode 100644
index 0000000..7b14576
--- /dev/null
+++ b/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/core/RefreshEditModelJob.java
@@ -0,0 +1,43 @@
+/***********************************************************************************************************************
+ * Copyright (c) 2009 Sybase, Inc. 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: Sybase, Inc. - initial API and implementation
+ **********************************************************************************************************************/
+package org.eclipse.datatools.sqltools.schemaobjecteditor.ui.core;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.core.runtime.jobs.Job;
+import org.eclipse.datatools.sqltools.schemaobjecteditor.ui.ISchemaObjectEditorHandler;
+
+/**
+ * To refresh the edit model and re-display them in the schema object editor. It will delegate to
+ * <code>ISchemaObjectEditorHandler</code> to do the real job.
+ * 
+ * @author Idull
+ */
+public class RefreshEditModelJob extends Job
+{
+    ISchemaObjectEditorHandler _handler;
+
+    public RefreshEditModelJob(String name, ISchemaObjectEditorHandler handler)
+    {
+        super(name);
+        _handler = handler;
+    }
+
+    protected IStatus run(IProgressMonitor monitor)
+    {
+        if (monitor == null)
+        {
+            monitor = manager.createProgressGroup();
+        }
+        monitor.beginTask("", monitor.UNKNOWN);
+        _handler.refreshFromDB(monitor);
+        monitor.done();
+        return Status.OK_STATUS;
+    }
+}
diff --git a/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/core/ResourceChangeEvent.java b/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/core/ResourceChangeEvent.java
new file mode 100644
index 0000000..687336a
--- /dev/null
+++ b/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/core/ResourceChangeEvent.java
@@ -0,0 +1,38 @@
+/***********************************************************************************************************************
+ * Copyright (c) 2009 Sybase, Inc. 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: Sybase, Inc. - initial API and implementation
+ **********************************************************************************************************************/
+package org.eclipse.datatools.sqltools.schemaobjecteditor.ui.core;
+
+import org.eclipse.datatools.sqltools.schemaobjecteditor.ui.IResourceChangeEvent;
+
+/**
+ * 
+ * @author Idull
+ */
+public class ResourceChangeEvent implements IResourceChangeEvent
+{
+    private Object _source;
+    private int    _type;
+
+    public ResourceChangeEvent(Object _source, int _type)
+    {
+        super();
+        this._source = _source;
+        this._type = _type;
+    }
+
+    public Object getSource()
+    {
+        return _source;
+    }
+
+    public int getType()
+    {
+        return _type;
+    }
+
+}
diff --git a/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/core/SQLExecutionJobListener.java b/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/core/SQLExecutionJobListener.java
new file mode 100644
index 0000000..66c5069
--- /dev/null
+++ b/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/core/SQLExecutionJobListener.java
@@ -0,0 +1,160 @@
+/***********************************************************************************************************************
+ * Copyright (c) 2009 Sybase, Inc. 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: Sybase, Inc. - initial API and implementation
+ **********************************************************************************************************************/
+package org.eclipse.datatools.sqltools.schemaobjecteditor.ui.core;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.jobs.IJobChangeEvent;
+import org.eclipse.core.runtime.jobs.IJobChangeListener;
+import org.eclipse.core.runtime.jobs.JobChangeAdapter;
+import org.eclipse.datatools.sqltools.schemaobjecteditor.ui.ISchemaObjectEditor;
+import org.eclipse.datatools.sqltools.schemaobjecteditor.ui.ISchemaObjectEditorHandler;
+import org.eclipse.datatools.sqltools.schemaobjecteditor.ui.ISchemaObjectEditorInput;
+import org.eclipse.datatools.sqltools.schemaobjecteditor.ui.internal.SOEUIPlugin;
+import org.eclipse.jface.dialogs.IDialogConstants;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.ui.IEditorPart;
+
+/**
+ * When the delta ddl scripts are successfully executed against the database, need to perform the following operations:
+ * <ul>
+ * <li>1.Refresh the edit model from the database and re-clone it;
+ * <li>2.Re-register the model listener for all the re-cloned SQL objects;
+ * <li>3.Refresh all the editor pages based on the refreshed SQL objects.
+ * </ul>
+ * All these jobs will be delegated to <code>ISchemaObjectEditorHandler</code>.
+ * 
+ * @author Idull
+ */
+public class SQLExecutionJobListener implements IJobChangeListener
+{
+    private ISchemaObjectEditor _editor;
+    private IProgressMonitor    _monitor;
+
+    public SQLExecutionJobListener(ISchemaObjectEditor editor, IProgressMonitor monitor)
+    {
+        super();
+        _editor = editor;
+        _monitor = monitor;
+    }
+
+    public void aboutToRun(IJobChangeEvent event)
+    {
+
+    }
+
+    public void awake(IJobChangeEvent event)
+    {
+
+    }
+
+    public void done(IJobChangeEvent event)
+    {
+        if (_editor == null)
+        {
+            SOEUIPlugin.getActiveWorkbenchShell().getDisplay().syncExec(new Runnable()
+            {
+                public void run()
+                {
+                    if (_monitor != null)
+                    {
+                        _monitor.setCanceled(true);
+                    }
+                }
+            });
+
+            return;
+        }
+
+        if (event.getResult().isOK())
+        {
+            final ISchemaObjectEditorInput input = (ISchemaObjectEditorInput) _editor.getEditorInput();
+            input.getEditModelObject().stopLogging();
+
+            // Check if the editor is disposed
+            // [544833-1] we also need to refresh database while use close dirty editor part and save the edit result at
+            // the same time
+            IEditorPart part = SOEUIPlugin.getActiveWorkbenchPage().findEditor(_editor.getEditorInput());
+            if (part != null)
+            {
+                SOEUIPlugin.getActiveWorkbenchShell().getDisplay().syncExec(new Runnable()
+                {
+                    public void run()
+                    {
+                        _editor.setEditorPartName(input.getEditModelObject().getMainSQLObject().getName());
+                    }
+                });
+            }
+
+            ISchemaObjectEditorHandler handler = _editor.getEditorHandler();
+            if (handler != null && _editor.needRefreshAfterSave())
+            {
+                // Set the name of the immutable model to make it consistent with edit model
+                RefreshEditModelJob refreshJob = new RefreshEditModelJob(Messages.SQLExecutionJobListener_refreshing,
+                        handler);
+                refreshJob.setUser(true);
+                refreshJob.schedule();
+                refreshJob.addJobChangeListener(new JobChangeAdapter()
+                {
+                    public void done(IJobChangeEvent event)
+                    {
+                        super.done(event);
+                        SOEUIPlugin.getActiveWorkbenchShell().getDisplay().syncExec(new Runnable()
+                        {
+                            public void run()
+                            {
+                                if (_monitor != null)
+                                {
+                                    _monitor.done();
+                                }
+                            }
+                        });
+
+                    }
+                });
+            }
+
+        }
+        // not all the scripts are successfully executed
+        else
+        {
+            SOEUIPlugin.getActiveWorkbenchShell().getDisplay().syncExec(new Runnable()
+            {
+                public void run()
+                {
+                    String[] buttons = new String[]
+                    {
+                        IDialogConstants.YES_LABEL
+                    };
+                    MessageDialog d = new MessageDialog(SOEUIPlugin.getActiveWorkbenchShell(),
+                            Messages.SavePreviewDialog_problem, null, Messages.SavePreviewDialog_execution_failed_msg,
+                            MessageDialog.ERROR, buttons, 0);
+                    d.open();
+                    if (_monitor != null)
+                    {
+                        _monitor.setCanceled(true);
+                    }
+                }
+            });
+        }
+    }
+
+    public void running(IJobChangeEvent event)
+    {
+
+    }
+
+    public void scheduled(IJobChangeEvent event)
+    {
+
+    }
+
+    public void sleeping(IJobChangeEvent event)
+    {
+
+    }
+}
diff --git a/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/core/SchemaObjectEditor.java b/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/core/SchemaObjectEditor.java
new file mode 100644
index 0000000..72974c8
--- /dev/null
+++ b/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/core/SchemaObjectEditor.java
@@ -0,0 +1,875 @@
+/***********************************************************************************************************************
+ * Copyright (c) 2009 Sybase, Inc. 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: Sybase, Inc. - initial API and implementation
+ **********************************************************************************************************************/
+package org.eclipse.datatools.sqltools.schemaobjecteditor.ui.core;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.SafeRunner;
+import org.eclipse.datatools.sqltools.schemaobjecteditor.ui.IErrorItem;
+import org.eclipse.datatools.sqltools.schemaobjecteditor.ui.IResourceChangeEvent;
+import org.eclipse.datatools.sqltools.schemaobjecteditor.ui.ISchemaObjectEditor;
+import org.eclipse.datatools.sqltools.schemaobjecteditor.ui.ISchemaObjectEditorHandler;
+import org.eclipse.datatools.sqltools.schemaobjecteditor.ui.ISchemaObjectEditorInput;
+import org.eclipse.datatools.sqltools.schemaobjecteditor.ui.ISchemaObjectEditorPage;
+import org.eclipse.datatools.sqltools.schemaobjecteditor.ui.extensions.IEditorDescriptor;
+import org.eclipse.datatools.sqltools.schemaobjecteditor.ui.extensions.IEditorPageDescriptor;
+import org.eclipse.datatools.sqltools.schemaobjecteditor.ui.internal.SOEUIPlugin;
+import org.eclipse.datatools.sqltools.schemaobjecteditor.ui.internal.core.ErrorPage;
+import org.eclipse.datatools.sqltools.schemaobjecteditor.ui.util.ILogger;
+import org.eclipse.datatools.sqltools.schemaobjecteditor.ui.util.Images;
+import org.eclipse.jface.action.Action;
+import org.eclipse.jface.action.ActionContributionItem;
+import org.eclipse.jface.action.IAction;
+import org.eclipse.jface.action.IContributionItem;
+import org.eclipse.jface.action.IMenuListener;
+import org.eclipse.jface.action.IMenuManager;
+import org.eclipse.jface.action.MenuManager;
+import org.eclipse.jface.action.Separator;
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.jface.util.SafeRunnable;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.layout.FillLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Menu;
+import org.eclipse.ui.IEditorInput;
+import org.eclipse.ui.IEditorPart;
+import org.eclipse.ui.IEditorSite;
+import org.eclipse.ui.IPartListener;
+import org.eclipse.ui.IPartService;
+import org.eclipse.ui.IPropertyListener;
+import org.eclipse.ui.IWorkbenchPage;
+import org.eclipse.ui.IWorkbenchPart;
+import org.eclipse.ui.PartInitException;
+import org.eclipse.ui.dialogs.PreferencesUtil;
+import org.eclipse.ui.forms.editor.FormEditor;
+import org.eclipse.ui.forms.editor.IFormPage;
+import org.eclipse.ui.part.IWorkbenchPartOrientation;
+import org.eclipse.ui.part.MultiPageEditorPart;
+import org.eclipse.ui.part.MultiPageEditorSite;
+import org.eclipse.ui.views.contentoutline.IContentOutlinePage;
+
+/**
+ * The base editor, which is responsible for loading the pages defined by the consumers according to the end-user's
+ * setting (visibility & order). Through this class, consumer can get the run-time page and static page instance.
+ * <p>
+ * To define the run-time behaviour of the multi-page eidtor, the consumer need to extend
+ * <code>DefaultSchemaObjectEditorHandler</code> and set it in the extension accordingly.
+ * <p>
+ * The editor input of this base editor is defined as <code>SchemeObjectEditorInput</code>, which contains a model
+ * object, the consumer can use that field to store the domain model, for example the Table object.
+ * <p>
+ * Some methods defined in the parent classes are overrided to emplify the visibility since the consumer can not extend
+ * and override this class.
+ * 
+ * @author Idull
+ */
+public class SchemaObjectEditor extends FormEditor implements ISchemaObjectEditor
+{
+    /**
+     * The consumer can store application data in this field
+     */
+    public Object                      _data;
+    private boolean                    _dirty                = false;
+    /**
+     * The edit model of this editor, this is always a "dirty" one compared with the orginal model
+     */
+    public Object                      _editModel;
+    private IEditorDescriptor          _exEditor;
+    private ISchemaObjectEditorHandler _handler;
+    private ILogger                    _logger               = SOEUIPlugin.getLogger(null);
+
+    private Map                        _nameToPages          = new HashMap();
+    private Map                        _idToPages            = new HashMap();
+    private List                       _ids                  = new ArrayList();
+    private List                       _editorPages;
+    private boolean                    _syncSave             = false;
+    private boolean                    _needRefreshAfterSave = true;
+
+    private ActivationListener         _activationListener   = null;
+    // Edit Model may not be available when editor is closed, part listener will set this flag.
+    private boolean                    _isEditModelAvailable = true;
+
+    public SchemaObjectEditor()
+    {
+        _editorPages = new ArrayList();
+    }
+
+    protected void createPages()
+    {
+        super.createPages();
+
+        MenuManager manager = new MenuManager();
+        manager.setRemoveAllWhenShown(true);
+        manager.addMenuListener(new IMenuListener()
+        {
+            public void menuAboutToShow(IMenuManager manager)
+            {
+                final ISchemaObjectEditorPage page = getActiveEditorPage();
+
+                manager.add(new Separator(Constants.REFRESH_REVERT_GROUP));
+                IContributionItem item = ((IEditorPart) SchemaObjectEditor.this).getEditorSite().getActionBars()
+                        .getToolBarManager().find(Constants.REVERT_EDITOR_ACTION_ID);
+                if (item != null && item instanceof ActionContributionItem)
+                {
+                    manager.appendToGroup(Constants.REFRESH_REVERT_GROUP, ((ActionContributionItem) item).getAction());
+                }
+
+                item = ((IEditorPart) SchemaObjectEditor.this).getEditorSite().getActionBars().getToolBarManager()
+                        .find(Constants.REFRESH_EDITOR_ACTION_ID);
+                if (item != null && item instanceof ActionContributionItem)
+                {
+                    manager.appendToGroup(Constants.REFRESH_REVERT_GROUP, ((ActionContributionItem) item).getAction());
+                }
+                manager.add(new Separator(Constants.SAVE_PREFERENCE_GROUP));
+                IAction prefAction = new Action()
+                {
+                    public void run()
+                    {
+                        String[] subPages = page.getPreferencePageIds();
+                        int pageNum = subPages == null ? 0 : subPages.length;
+                        String[] preferencePages = new String[1 + pageNum];
+                        preferencePages[0] = Constants.PREFERENCE_PAGE_ID;
+                        for (int i = 0; i < pageNum; i++)
+                        {
+                            preferencePages[i + 1] = subPages[i];
+                        }
+
+                        PreferencesUtil.createPreferenceDialogOn(null, preferencePages[0], preferencePages, null)
+                                .open();
+                    }
+                };
+                prefAction.setText(Messages.SchemaObjectEditor_preferences);
+                manager.add(prefAction);
+
+                IAction saveAction = new Action()
+                {
+                    public void run()
+                    {
+                        SOEUIPlugin.getActiveWorkbenchPage().saveEditor((IEditorPart) SchemaObjectEditor.this, false);
+                    }
+                };
+                saveAction.setText(Messages.SchemaObjectEditor_save_to_server);
+                saveAction.setImageDescriptor(Images.DESC_SAVE_TO_DB);
+                saveAction.setEnabled(SchemaObjectEditor.this.isDirty());
+
+                manager.appendToGroup(Constants.SAVE_PREFERENCE_GROUP, saveAction);
+
+                if (page != null)
+                {
+                    page.menuAboutToShow(manager);
+                }
+            }
+        });
+        Menu menu = manager.createContextMenu(getContainer());
+        getContainer().setMenu(menu);
+
+        _activationListener = new ActivationListener(getEditorSite().getWorkbenchWindow().getPartService());
+
+        // Open Problems view
+        try
+        {
+            SOEUIPlugin.getActiveWorkbenchPage().showView(Constants.PROBLEMS_VIEW_ID, null, IWorkbenchPage.VIEW_VISIBLE);
+        }
+        catch (Exception e)
+        {
+            _logger.error("SchemaObjectEditorUtils_error_open_problemview", e); //$NON-NLS-1$
+        }
+    }
+
+    protected void addPages()
+    {
+        if (_exEditor == null || _exEditor.getPageDescriptors() == null || _exEditor.getPageDescriptors().length == 0)
+        {
+            setupErrorPage(new ErrorPage(Messages.SchemaObjectEditor_no_page), _exEditor);
+            return;
+        }
+        if (_exEditor.getHandler() == null)
+        {
+            setupErrorPage(new ErrorPage(Messages.SchemaObjectEditor_no_handler), _exEditor);
+            return;
+        }
+
+        // set the editor
+        _handler.setEditor(this);
+
+        IEditorPageDescriptor[] pages = _exEditor.getSortedPages();
+        for (int i = 0; i < pages.length; i++)
+        {
+            setupPage(pages[i], _exEditor);
+        }
+        _handler.hookInitialization();
+    }
+
+    public void clearDirty()
+    {
+        _dirty = false;
+        Iterator pageIter = _editorPages.iterator();
+        while (pageIter.hasNext())
+        {
+            Object obj = pageIter.next();
+            if (obj instanceof ISchemaObjectEditorPage)
+            {
+                ISchemaObjectEditorPage page = (ISchemaObjectEditorPage) obj;
+                if (page.getManagedForm() != null)
+                {
+                    page.getManagedForm().commit(true);
+                }
+            }
+        }
+        fireDirtyPropertyChange();
+    }
+
+    public void dispose()
+    {
+        for (int i = pages.size() - 1; i >= 0; i--)
+        {
+            Object page = pages.get(i);
+            if (page instanceof NestedEditorPage)
+            {
+                disposePart(((NestedEditorPage) page).getNestedEditor());
+                pages.remove(i);
+            }
+        }
+
+        super.dispose();
+        if (_handler != null)
+        {
+            _handler.dispose();
+        }
+        // cannot dispose the icon because it could be used by another editor instance
+        // if (_exEditor.getIcon() != null)
+        // {
+        // _exEditor.getIcon().dispose();
+        // }
+    }
+
+    private boolean aboutToSave(IProgressMonitor monitor)
+    {
+        boolean goon = true;
+        for (Iterator iter = pages.iterator(); iter.hasNext();)
+        {
+            Object next = iter.next();
+            if (next instanceof SchemaObjectEditorPage)
+            {
+                goon = ((SchemaObjectEditorPage) next).aboutToSave(monitor);
+                if (!goon)
+                {
+                    break;
+                }
+            }
+        }
+        return goon;
+    }
+
+    public void doSave(IProgressMonitor monitor)
+    {
+        boolean goon = aboutToSave(monitor);
+        if (goon)
+        {
+            if (_handler != null)
+            {
+                _handler.doSave(monitor);
+
+                // By default, the object is saved asynchronizely
+                _syncSave = false;
+            }
+        }
+    }
+
+    public void doSaveAs()
+    {
+        if (_handler != null)
+        {
+            _handler.doSaveAs();
+        }
+    }
+
+    /**
+     * A short-cut method
+     */
+    public void fireDirtyPropertyChange()
+    {
+        firePropertyChange(IEditorPart.PROP_DIRTY);
+    }
+
+    public void fireSchemaEditorProperChanged(final int propertyId)
+    {
+        super.firePropertyChange(propertyId);
+    }
+
+    /**
+     * Returns the active page instance
+     */
+    public ISchemaObjectEditorPage getActiveEditorPage()
+    {
+        return (ISchemaObjectEditorPage) getActivePageInstance();
+    }
+
+    public Object getAdapter(Class adapter)
+    {
+        Object result = super.getAdapter(adapter);
+        if (result != null && !IContentOutlinePage.class.equals(adapter))
+        {
+            return result;
+        }
+        if (_handler != null)
+        {
+            return _handler.getAdapter(adapter);
+        }
+        return null;
+    }
+
+    /**
+     * Returns all pages loaded
+     */
+    public ISchemaObjectEditorPage[] getAllPages()
+    {
+        // Sometimes there is null page (?)
+        ArrayList ps = new ArrayList();
+        Iterator iter = _editorPages.iterator();
+        while (iter.hasNext())
+        {
+            Object obj = iter.next();
+            if (obj != null)
+            {
+                ps.add(obj);
+            }
+        }
+        return (ISchemaObjectEditorPage[]) ps.toArray(new ISchemaObjectEditorPage[_editorPages.size()]);
+    }
+
+    public int getCurrentPageIndex()
+    {
+        return getCurrentPage();
+    }
+
+    public Object getData()
+    {
+        return _data;
+    }
+
+    public Object getEditModel()
+    {
+        return _editModel;
+    }
+
+    public Composite getEditorContainer()
+    {
+        return super.getContainer();
+    }
+
+    public ISchemaObjectEditorHandler getEditorHandler()
+    {
+        return _handler;
+    }
+
+    public Control getEditorPageControl(int pageIndex)
+    {
+        return super.getControl(pageIndex);
+    }
+
+    public int getEditorPageCount()
+    {
+        return super.getPageCount();
+    }
+
+    /**
+     * Returns the page by id
+     */
+    public ISchemaObjectEditorPage getPageById(String id)
+    {
+        return (ISchemaObjectEditorPage) _idToPages.get(id);
+    }
+
+    /**
+     * Returns the page by name
+     */
+    public ISchemaObjectEditorPage getPageByName(String name)
+    {
+        return (ISchemaObjectEditorPage) _nameToPages.get(name);
+    }
+
+    /**
+     * Returns the static editor instance
+     */
+    public IEditorDescriptor getEditorDescriptor()
+    {
+        return _exEditor;
+    }
+
+    public void init(IEditorSite site, IEditorInput input) throws PartInitException
+    {
+        super.init(site, input);
+        if (input instanceof ISchemaObjectEditorInput)
+        {
+            ISchemaObjectEditorInput in = (ISchemaObjectEditorInput) input;
+            _exEditor = in.getEditorDescriptor();
+            _handler = in.getEditorDescriptor().getHandler();
+
+            if (_exEditor != null && _exEditor.getEditorName() != null && _exEditor.getEditorName().length() != 0)
+            {
+                setPartName(_exEditor.getEditorName());
+            }
+            if (_exEditor != null && _exEditor.getIcon() != null)
+            {
+                setTitleImage(_exEditor.getIcon());
+            }
+        }
+        else
+        {
+            _logger.error("SchemaObjectEditor_not_proper_iput"); //$NON-NLS-1$
+            return;
+        }
+    }
+
+    public boolean isDirty()
+    {
+        if (_dirty)
+        {
+            return _dirty;
+        }
+        return super.isDirty();
+    }
+
+    public boolean isSaveAsAllowed()
+    {
+        if (_handler != null)
+        {
+            return _handler.isSaveAsAllowed();
+        }
+        return false;
+    }
+
+    public void markDirty()
+    {
+        _dirty = true;
+        fireDirtyPropertyChange();
+    }
+
+    /**
+     * Delegate the call to consumer's code when the page is changed
+     */
+    protected void pageChange(int newPageIndex)
+    {
+        if (!_isEditModelAvailable || !_handler.checkSchemaObjectExistence(true))
+        {
+            return;
+        }
+
+        int oldPage = getCurrentPage();
+        if (oldPage != -1 && _editorPages.size() > oldPage
+                && _editorPages.get(oldPage) instanceof ISchemaObjectEditorPage && oldPage != newPageIndex)
+        {
+            // Check the old page
+            ISchemaObjectEditorPage oldFormPage = (ISchemaObjectEditorPage) _editorPages.get(oldPage);
+            // do not popup the error dialog here. let the page to handle it in canLeaveThePage()
+            // if (oldFormPage.canLeaveThePage() == false)
+            // {
+            // String[] buttons = new String[]
+            // {
+            // IDialogConstants.OK_LABEL
+            // }
+            // ;
+            // MessageDialog d = new MessageDialog(getSite().getShell(), Messages.SchemaObjectEditor_error, null,
+            // oldFormPage.getErrorMsg() == null ? Messages.SchemaObjectEditor_pagechange_error :
+            // oldFormPage.getErrorMsg(), MessageDialog.ERROR,
+            // buttons, 0);
+            // d.open();
+            // setActivePage(oldPage);
+            // return;
+            // }
+            if (oldFormPage instanceof NestedEditorPage)
+            {
+                ((NestedEditorPage) oldFormPage).aboutToLeave();
+            }
+        }
+
+        // Do something when the page changed
+        if (_handler != null)
+        {
+            _handler.pageChanged(newPageIndex);
+        }
+        super.pageChange(newPageIndex);
+    }
+
+    public void resouceChanged(IResourceChangeEvent event)
+    {
+        _handler.resouceChanged(event);
+    }
+
+    public void setData(Object _data)
+    {
+        this._data = _data;
+    }
+
+    public void setEditModel(Object model)
+    {
+        _editModel = model;
+    }
+
+    public void setEditorPageImage(int pageIndex, Image image)
+    {
+        super.setPageImage(pageIndex, image);
+    }
+
+    public void setEditorPageText(int pageIndex, String text)
+    {
+        super.setPageText(pageIndex, text);
+    }
+
+    public void setEditorPartName(final String name)
+    {
+        if (name != null && name.length() != 0)
+        {
+            getSite().getShell().getDisplay().asyncExec(new Runnable()
+            {
+                public void run()
+                {
+                    SchemaObjectEditor.super.setPartName(name);
+                };
+            });
+        }
+    }
+
+    /**
+     * Creates and adds a new page containing the given editor to this multi-page editor. The page is added at the given
+     * index. This also hooks a property change listener on the nested editor.
+     * 
+     * @param index the index at which to add the page (0-based)
+     * @param editor the nested editor
+     * @param input the input for the nested editor
+     * @exception PartInitException if a new page could not be created
+     * 
+     * @see MultiPageEditorPart#handlePropertyChange(int) the handler for property change events from the nested editor
+     */
+    public void addPage(int index, NestedEditorPage page) throws PartInitException
+    {
+        IEditorPart editor = page.getNestedEditor();
+        IEditorInput input = page.getNestedEditorInput();
+        IEditorSite site = createSite(editor);
+        // call init first so that if an exception is thrown, we have created no
+        // new widgets
+        // The page is responsible for calling IEditorPart.init
+        page.init(site, input);
+        Composite parent2 = new Composite(getContainer(), getOrientation(editor));
+        parent2.setLayout(new FillLayout());
+        editor.createPartControl(parent2);
+        page.setPartControl(parent2);
+        editor.addPropertyListener(new IPropertyListener()
+        {
+            public void propertyChanged(Object source, int propertyId)
+            {
+                SchemaObjectEditor.this.handlePropertyChange(propertyId);
+            }
+        });
+        // create item for page only after createPartControl has succeeded
+        addPage(index, parent2);
+        // remember the editor as data on the item's control
+        parent2.setData(editor);
+
+        configurePage(index, page);
+    }
+
+    protected IEditorSite createSite(IEditorPart editor)
+    {
+        if (editor.getEditorSite() != null)
+        {
+            return editor.getEditorSite();
+        }
+        else
+        {
+            return new MultiPageEditorSite(this, editor)
+            {
+                public String getId()
+                {
+                    return Constants.SCHEMA_EDITOR_NESTED_ID;
+                }
+            };
+        }
+    }
+
+    /**
+     * Get the orientation of the editor.
+     * 
+     * @param editor
+     * @return int the orientation flag
+     * @see SWT#RIGHT_TO_LEFT
+     * @see SWT#LEFT_TO_RIGHT
+     * @see SWT#NONE
+     */
+    private int getOrientation(IEditorPart editor)
+    {
+        if (editor instanceof IWorkbenchPartOrientation)
+        {
+            return ((IWorkbenchPartOrientation) editor).getOrientation();
+        }
+        return getOrientation();
+    }
+
+    /**
+     * Sets up an error page to report the error message
+     * 
+     * @param page
+     * @param editor
+     */
+    private void setupErrorPage(ISchemaObjectEditorPage page, IEditorDescriptor editor)
+    {
+        try
+        {
+            page.setId(Messages.SchemaObjectEditor_error_id);
+            page.setEditor(this);
+            page.setEditorDescriptor(_exEditor);
+            page.setPartName(Messages.SchemaObjectEditor_error);
+            addPage(page);
+        }
+        catch (Exception e)
+        {
+            _logger.error("SchemaObjectEditor_error_set_errorpage", e); //$NON-NLS-1$
+        }
+    }
+
+    /**
+     * Sets up a page defined by consumer
+     * 
+     * @param p
+     * @param editor
+     */
+    private void setupPage(IEditorPageDescriptor p, IEditorDescriptor editor)
+    {
+        if (!p.isSelectedToShow())
+        {
+            return;
+        }
+        try
+        {
+            ISchemaObjectEditorPage page = (ISchemaObjectEditorPage) p.getPageClass();
+            page.setId(p.getPageId());
+            page.setEditor(this);
+            page.setEditorDescriptor(_exEditor);
+            page.setPageDescriptor(p);
+            page.setPartName(p.getPageName());
+
+            // The id or name should be unique
+            _nameToPages.put(p.getPageName(), page);
+            _idToPages.put(p.getPageId(), page);
+            _ids.add(p.getPageId());
+
+            // If the page is a nested editor, should add it as an editor
+            if (page instanceof NestedEditorPage)
+            {
+                NestedEditorPage editorPage = (NestedEditorPage) page;
+                addPage(getPageCount(), editorPage);
+                // setPageText(getPageCount() - 1, editorPage.getTitle());
+            }
+            else
+            {
+                addPage(page);
+            }
+            _editorPages.add(page);
+        }
+        catch (Exception e)
+        {
+            _logger.error("SchemaObjectEditor_error_setup_page", e); //$NON-NLS-1$
+        }
+    }
+
+    public Map validate()
+    {
+        Map pageErrors = new HashMap();
+        ISchemaObjectEditorPage[] pages = getAllPages();
+        for (int i = 0; i < pages.length; i++)
+        {
+            if (pages[i] != null)
+            {
+                IErrorItem[] items = pages[i].validateOnline(null);
+                if (items != null && items.length != 0)
+                {
+                    pageErrors.put(pages[i], items);
+                }
+            }
+        }
+        return pageErrors;
+    }
+
+    /**
+     * Tries to return a meaningful name
+     */
+    public String getDisplayName()
+    {
+        if (_handler != null && _handler.getDisplayName() != null
+                && !_handler.getDisplayName().equals(Messages.SavePreviewDialog_noname_sql))
+        {
+            return _handler.getDisplayName();
+        }
+        String partName = getPartName();
+        if (partName != null && !partName.equals("") && partName.indexOf('\\') < 0 && partName.indexOf('/') < 0 //$NON-NLS-1$
+                && partName.indexOf(':') < 0 && partName.indexOf('*') < 0 && partName.indexOf('?') < 0
+                && partName.indexOf('\"') < 0 && partName.indexOf('<') < 0 && partName.indexOf('>') < 0
+                && partName.indexOf('|') < 0)
+        {
+            return partName;
+        }
+        return Messages.SavePreviewDialog_noname_sql;
+    }
+
+    public IFormPage setActivePage(String pageId)
+    {
+        IFormPage page = super.setActivePage(pageId);
+        if (page != null)
+        {
+            return page;
+        }
+
+        int i = 0;
+        Iterator idsIter = _ids.iterator();
+        while (idsIter.hasNext())
+        {
+            String id = (String) idsIter.next();
+            if (id.equals(pageId))
+            {
+                setActivePage(i);
+                return (IFormPage) _idToPages.get(id);
+            }
+            i++;
+        }
+
+        return null;
+    }
+
+    /**
+     * Widen the visibility
+     */
+    public void setActivePage(int pageIndex)
+    {
+        super.setActivePage(pageIndex);
+    }
+
+    /**
+     * Disposes the given part and its site.
+     * 
+     * @param part The part to dispose; must not be <code>null</code>.
+     */
+    private void disposePart(final IWorkbenchPart part)
+    {
+        SafeRunner.run(new SafeRunnable()
+        {
+            public void run()
+            {
+                if (part.getSite() instanceof MultiPageEditorSite)
+                {
+                    MultiPageEditorSite partSite = (MultiPageEditorSite) part.getSite();
+                    partSite.dispose();
+                }
+                part.dispose();
+            }
+
+            public void handleException(Throwable e)
+            {
+                // Exception has already being logged by Core. Do nothing.
+            }
+        });
+    }
+
+    /**
+     * Returns the editor for the given page index. The page index must be valid.
+     * 
+     * @param pageIndex the index of the page
+     * @return the editor for the specified page, or <code>null</code> if the specified page was not created with
+     *         <code>addPage(IEditorPart,IEditorInput)</code>
+     */
+    protected IEditorPart getEditor(int pageIndex)
+    {
+        IEditorPart editor = super.getEditor(pageIndex);
+        if (editor != null)
+        {
+            return editor;
+        }
+        Control control = getControl(pageIndex);
+        if (control != null && control.getData() instanceof IEditorPart)
+        {
+            return (IEditorPart) control.getData();
+        }
+
+        return null;
+    }
+
+    public void setSyncSaveMode()
+    {
+        _syncSave = true;
+    }
+
+    public boolean isSyncSave()
+    {
+        return _syncSave;
+    }
+
+    public boolean needRefreshAfterSave()
+    {
+        return _needRefreshAfterSave;
+    }
+
+    public void setNeedRefreshAfterSave(boolean needRefresh)
+    {
+        _needRefreshAfterSave = needRefresh;
+    }
+
+    class ActivationListener implements IPartListener
+    {
+        IPartService part;
+
+        public ActivationListener(IPartService part)
+        {
+            this.part = part;
+            part.addPartListener(this);
+        }
+
+        public void partActivated(IWorkbenchPart part)
+        {
+            if (part == SchemaObjectEditor.this)
+            {
+                IPreferenceStore store = SOEUIPlugin.getDefault().getPreferenceStore();
+                boolean isNeedCheck = store
+                        .getBoolean(org.eclipse.datatools.sqltools.schemaobjecteditor.ui.internal.Constants.PREFERENCE_CHECK_EXISTENCE);
+                if (!_handler.checkSchemaObjectExistence(isNeedCheck))
+                {
+                    SchemaObjectEditor.this._isEditModelAvailable = false;
+                    this.part.removePartListener(this);
+                }
+            }
+
+        }
+
+        public void partBroughtToTop(IWorkbenchPart part)
+        {
+        }
+
+        public void partClosed(IWorkbenchPart part)
+        {
+            if (part == SchemaObjectEditor.this)
+            {
+                this.part.removePartListener(this);
+            }
+        }
+
+        public void partDeactivated(IWorkbenchPart part)
+        {
+        }
+
+        public void partOpened(IWorkbenchPart part)
+        {
+        }
+    }
+
+}
diff --git a/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/core/SchemaObjectEditorInput.java b/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/core/SchemaObjectEditorInput.java
new file mode 100644
index 0000000..5a9e255
--- /dev/null
+++ b/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/core/SchemaObjectEditorInput.java
@@ -0,0 +1,115 @@
+/***********************************************************************************************************************
+ * Copyright (c) 2009 Sybase, Inc. 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: Sybase, Inc. - initial API and implementation
+ **********************************************************************************************************************/
+package org.eclipse.datatools.sqltools.schemaobjecteditor.ui.core;
+
+import org.eclipse.datatools.connectivity.IConnectionProfile;
+import org.eclipse.datatools.sqltools.core.DatabaseIdentifier;
+import org.eclipse.datatools.sqltools.core.profile.NoSuchProfileException;
+import org.eclipse.datatools.sqltools.core.profile.ProfileUtil;
+import org.eclipse.datatools.sqltools.schemaobjecteditor.model.ISchemaObjectEditModel;
+import org.eclipse.datatools.sqltools.schemaobjecteditor.model.ISchemaObjectImmutableModel;
+import org.eclipse.datatools.sqltools.schemaobjecteditor.ui.ISchemaObjectEditorInput;
+import org.eclipse.datatools.sqltools.schemaobjecteditor.ui.extensions.IEditorDescriptor;
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.ui.IPersistableElement;
+
+/**
+ * The editor input for schema object editor.
+ * 
+ * @author Idull
+ */
+public class SchemaObjectEditorInput implements ISchemaObjectEditorInput
+{
+    IEditorDescriptor      _editor;
+    ISchemaObjectEditModel _modelObject;
+    DatabaseIdentifier     _databaseIdentifier;
+
+    public SchemaObjectEditorInput(IEditorDescriptor editor, ISchemaObjectEditModel modelObject,
+            DatabaseIdentifier identifier)
+    {
+        this._editor = editor;
+        this._modelObject = modelObject;
+        this._databaseIdentifier = identifier;
+    }
+
+    public IEditorDescriptor getEditorDescriptor()
+    {
+        return _editor;
+    }
+
+    public boolean exists()
+    {
+        return false;
+    }
+
+    public ImageDescriptor getImageDescriptor()
+    {
+        return null;
+    }
+
+    public String getName()
+    {
+        if (_modelObject.getMainSQLObject() != null && _modelObject.getMainSQLObject().getName() != null)
+        {
+            return _modelObject.getMainSQLObject().getName();
+        }
+        return Messages.SchemaObjectEditorInput_name;
+    }
+
+    public IPersistableElement getPersistable()
+    {
+        return null;
+    }
+
+    public String getToolTipText()
+    {
+        if (_modelObject != null && _modelObject.getEditorTooltipText() != null)
+        {
+            return _modelObject.getEditorTooltipText();
+        }
+        return Messages.SchemaObjectEditorInput_name;
+    }
+
+    public Object getAdapter(Class adapter)
+    {
+        if (adapter == IConnectionProfile.class)
+        {
+            try
+            {
+                return ProfileUtil.getProfile(_databaseIdentifier.getProfileName());
+            }
+            catch (NoSuchProfileException e)
+            {
+                return null;
+            }
+        }
+
+        return null;
+    }
+
+    public ISchemaObjectEditModel getEditModelObject()
+    {
+        return _modelObject;
+    }
+
+    public DatabaseIdentifier getDatabaseIdentifier()
+    {
+        return _databaseIdentifier;
+    }
+
+    public boolean equals(Object obj)
+    {
+        if (!(obj instanceof ISchemaObjectEditorInput))
+        {
+            return false;
+        }
+        ISchemaObjectEditorInput input = (ISchemaObjectEditorInput) obj;
+        ISchemaObjectImmutableModel originalModel = input.getEditModelObject().getSchemaObjectImmutableModel();
+        return originalModel.equals(this.getEditModelObject().getSchemaObjectImmutableModel());
+    }
+}
diff --git a/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/core/SchemaObjectEditorPage.java b/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/core/SchemaObjectEditorPage.java
new file mode 100644
index 0000000..ebfe4c6
--- /dev/null
+++ b/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/core/SchemaObjectEditorPage.java
@@ -0,0 +1,730 @@
+/***********************************************************************************************************************
+ * Copyright (c) 2009 Sybase, Inc. 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: Sybase, Inc. - initial API and implementation
+ **********************************************************************************************************************/
+package org.eclipse.datatools.sqltools.schemaobjecteditor.ui.core;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.core.resources.IMarker;
+import org.eclipse.core.resources.IWorkspace;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.datatools.help.HelpUtil;
+import org.eclipse.datatools.modelbase.sql.schema.SQLObject;
+import org.eclipse.datatools.sqltools.common.ui.helpsystem.CommonContextProvider;
+import org.eclipse.datatools.sqltools.common.ui.helpsystem.HelpSystemEditorPart;
+import org.eclipse.datatools.sqltools.core.DatabaseIdentifier;
+import org.eclipse.datatools.sqltools.core.modelvalidity.SQLModelValidationDelegate;
+import org.eclipse.datatools.sqltools.schemaobjecteditor.ui.IErrorItem;
+import org.eclipse.datatools.sqltools.schemaobjecteditor.ui.ISchemaObjectEditor;
+import org.eclipse.datatools.sqltools.schemaobjecteditor.ui.ISchemaObjectEditorInput;
+import org.eclipse.datatools.sqltools.schemaobjecteditor.ui.ISchemaObjectEditorPage;
+import org.eclipse.datatools.sqltools.schemaobjecteditor.ui.extensions.IEditorDescriptor;
+import org.eclipse.datatools.sqltools.schemaobjecteditor.ui.extensions.IEditorPageDescriptor;
+import org.eclipse.datatools.sqltools.schemaobjecteditor.ui.internal.SOEUIPlugin;
+import org.eclipse.datatools.sqltools.schemaobjecteditor.ui.util.ILogger;
+import org.eclipse.datatools.sqltools.schemaobjecteditor.ui.util.Images;
+import org.eclipse.emf.common.util.BasicDiagnostic;
+import org.eclipse.emf.common.util.Diagnostic;
+import org.eclipse.emf.common.util.DiagnosticChain;
+import org.eclipse.jface.action.Action;
+import org.eclipse.jface.action.IMenuManager;
+import org.eclipse.jface.action.IToolBarManager;
+import org.eclipse.swt.custom.BusyIndicator;
+import org.eclipse.swt.events.TypedEvent;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.ui.IEditorInput;
+import org.eclipse.ui.IEditorPart;
+import org.eclipse.ui.IEditorSite;
+import org.eclipse.ui.PartInitException;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.forms.IManagedForm;
+import org.eclipse.ui.forms.ManagedForm;
+import org.eclipse.ui.forms.editor.FormEditor;
+import org.eclipse.ui.forms.widgets.ScrolledForm;
+import org.eclipse.ui.part.WorkbenchPart;
+
+/**
+ * Copied from <code>FormPage</code> since some fields are private and can not be set. To add a page to an editor, the
+ * consumer need to extend this class to create the controls in the page.
+ * 
+ * @author Idull
+ * 
+ */
+public class SchemaObjectEditorPage extends HelpSystemEditorPart implements ISchemaObjectEditorPage
+{
+    protected ILogger             _logger       = SOEUIPlugin.getLogger(null);
+    private FormEditor            _editor;
+    private PageForm              _mform;
+    private int                   _index;
+    private String                _id;
+    protected String              _errorMsg;
+    private IEditorDescriptor     _editorDescriptor;
+    private IEditorPageDescriptor _pageDescriptor;
+    protected DiagnosticChain     _diagnostics;
+    protected List                _remembersMarkers;
+    protected boolean             _pageOpened   = false;
+    protected boolean             _isOnlineMode = false;
+
+    public static class PageForm extends ManagedForm
+    {
+        public PageForm(SchemaObjectEditorPage page, ScrolledForm form)
+        {
+            super(page.getEditor().getToolkit(), form);
+            setContainer(page);
+        }
+
+        public SchemaObjectEditorPage getPage()
+        {
+            return (SchemaObjectEditorPage) getContainer();
+        }
+
+        public void dirtyStateChanged()
+        {
+            getPage().getEditor().editorDirtyStateChanged();
+        }
+
+        public void staleStateChanged()
+        {
+            if (getPage().isActive())
+            {
+                refresh();
+            }
+        }
+    }
+
+    public SchemaObjectEditorPage()
+    {
+
+    }
+
+    /**
+     * A constructor that creates the page and initializes it with the editor.
+     * 
+     * @param editor the parent editor
+     * @param id the unique identifier
+     * @param title the page title
+     */
+    public SchemaObjectEditorPage(FormEditor editor, String id, String title)
+    {
+        this(id, title);
+        initialize(editor);
+    }
+
+    /**
+     * The constructor. The parent editor need to be passed in the <code>initialize</code> method if this constructor is
+     * used.
+     * 
+     * @param id a unique page identifier
+     * @param title a user-friendly page title
+     */
+    public SchemaObjectEditorPage(String id, String title)
+    {
+        this._id = id;
+        setPartName(title);
+    }
+
+    /**
+     * Initializes the form page.
+     * 
+     * @see IEditorPart#init
+     */
+    public void init(IEditorSite site, IEditorInput input) throws PartInitException
+    {
+        setSite(site);
+        setInput(input);
+    }
+
+    /**
+     * Primes the form page with the parent editor instance.
+     * 
+     * @param editor the parent editor
+     */
+    public void initialize(FormEditor editor)
+    {
+        this._editor = editor;
+    }
+
+    /**
+     * Returns the parent editor.
+     * 
+     * @return parent editor instance
+     */
+    public FormEditor getEditor()
+    {
+        return _editor;
+    }
+
+    /**
+     * Returns the managed form owned by this page.
+     * 
+     * @return the managed form
+     */
+    public IManagedForm getManagedForm()
+    {
+        return _mform;
+    }
+
+    /**
+     * Implements the required method by refreshing the form when set active. Subclasses must call super when overriding
+     * this method.
+     */
+    public void setActive(boolean active)
+    {
+        if (active)
+        {
+            // We are switching to this page - refresh it
+            // if needed.
+            _mform.refresh();
+        }
+        else
+        {
+            removeRememberedMarkers();
+        }
+    }
+
+    /**
+     * Tests if the page is active by asking the parent editor if this page is the currently active page.
+     * 
+     * @return <code>true</code> if the page is currently active, <code>false</code> otherwise.
+     */
+    public boolean isActive()
+    {
+        return this.equals(_editor.getActivePageInstance());
+    }
+
+    /**
+     * Creates the part control by creating the managed form using the parent editor's toolkit. Subclasses should
+     * override <code>createFormContent(IManagedForm)</code> to populate the form with content.
+     * 
+     * @param parent the page parent composite
+     */
+    public void createPartControl(Composite parent)
+    {
+        ScrolledForm form = _editor.getToolkit().createScrolledForm(parent);
+        _mform = createManagedForm(form);
+        BusyIndicator.showWhile(parent.getDisplay(), new Runnable()
+        {
+            public void run()
+            {
+                createFormContent(_mform);
+            }
+        });
+
+        _contextProvider = new CommonContextProvider(getEditorDescriptor().getPluginId());
+        parent.getShell().setData(HelpUtil.CONTEXT_PROVIDER_KEY, this);
+        HelpUtil.setHelp(parent, HelpUtil.getContextId(_pageDescriptor.getContextHelpId(), getEditorDescriptor()
+                .getPluginId()));
+    }
+
+    protected PageForm createManagedForm(ScrolledForm form)
+    {
+        return new PageForm(this, form);
+    }
+
+    /**
+     * Subclasses should override this method to create content in the form hosted in this page.
+     * 
+     * @param managedForm the form hosted in this page.
+     */
+    protected void createFormContent(IManagedForm managedForm)
+    {
+        _pageOpened = true;
+        // Add help action to the form tool bar if needed
+        if (_pageDescriptor != null && _pageDescriptor.getContextHelpId() != null
+                && _pageDescriptor.getContextHelpId().trim().length() != 0)
+        {
+            IToolBarManager toolBar = managedForm.getForm().getToolBarManager();
+            Action help = new Action(Messages.SchemaObjectEditorPage_help_name)
+            {
+                public void run()
+                {
+                    displayHelp(_pageDescriptor.getContextHelpId());
+                }
+            };
+            help.setImageDescriptor(Images.DESC_HELP);
+            help.setToolTipText(Messages.SchemaObjectEditorPage_help_tip);
+            toolBar.add(help);
+            managedForm.getForm().updateToolBar();
+        }
+
+        // 3.3 API
+        managedForm.getToolkit().decorateFormHeading(managedForm.getForm().getForm());
+    }
+
+    private void displayHelp(String contextHelpId)
+    {
+        String contextId = HelpUtil.getContextId(contextHelpId, getEditorDescriptor().getPluginId());
+        if ((contextId != null) && (contextId.length() > 0))
+        {
+            PlatformUI.getWorkbench().getHelpSystem().displayHelp(contextId);
+        }
+        else
+        {
+            PlatformUI.getWorkbench().getHelpSystem().displayHelp();
+        }
+    }
+
+    /**
+     * Returns the form page control.
+     * 
+     * @return managed form's control
+     */
+    public Control getPartControl()
+    {
+        return _mform != null ? _mform.getForm() : null;
+    }
+
+    /**
+     * Disposes the managed form.
+     */
+    public void dispose()
+    {
+        if (_mform != null)
+        {
+            _mform.dispose();
+        }
+
+        // remove all the markers when the page is disposed
+        removeRememberedMarkers();
+    }
+
+    /**
+     * Returns the unique identifier that can be used to reference this page.
+     * 
+     * @return the unique page identifier
+     */
+    public String getId()
+    {
+        return _id;
+    }
+
+    /**
+     * Returns <code>null</code>- form page has no title image. Subclasses may override.
+     * 
+     * @return <code>null</code>
+     */
+    public Image getTitleImage()
+    {
+        return null;
+    }
+
+    /**
+     * Sets the focus by delegating to the managed form.
+     */
+    public void setFocus()
+    {
+        if (_mform != null)
+        {
+            _mform.setFocus();
+        }
+    }
+
+    /**
+     * @see org.eclipse.ui.ISaveablePart#doSave(org.eclipse.core.runtime.IProgressMonitor)
+     */
+    public void doSave(IProgressMonitor monitor)
+    {
+        if (_mform != null)
+        {
+            _mform.commit(true);
+        }
+    }
+
+    /**
+     * @see org.eclipse.ui.ISaveablePart#doSaveAs()
+     */
+    public void doSaveAs()
+    {
+    }
+
+    /**
+     * @see org.eclipse.ui.ISaveablePart#isSaveAsAllowed()
+     */
+    public boolean isSaveAsAllowed()
+    {
+        return false;
+    }
+
+    /**
+     * Implemented by testing if the managed form is dirty.
+     * 
+     * @return <code>true</code> if the managed form is dirty, <code>false</code> otherwise.
+     * 
+     * @see org.eclipse.ui.ISaveablePart#isDirty()
+     */
+    public boolean isDirty()
+    {
+        return _mform != null ? _mform.isDirty() : false;
+    }
+
+    /**
+     * Preserves the page index.
+     * 
+     * @param index the assigned page index
+     */
+    public void setIndex(int index)
+    {
+        this._index = index;
+    }
+
+    /**
+     * Returns the saved page index.
+     * 
+     * @return the page index
+     */
+    public int getIndex()
+    {
+        return _index;
+    }
+
+    /**
+     * Form pages are not editors.
+     * 
+     * @return <code>false</code>
+     */
+    public boolean isEditor()
+    {
+        return false;
+    }
+
+    /**
+     * Attempts to select and reveal the given object by passing the request to the managed form.
+     * 
+     * @param object the object to select and reveal in the page if possible.
+     * @return <code>true</code> if the page has been successfully selected and revealed by one of the managed form
+     *         parts, <code>false</code> otherwise.
+     */
+    public boolean selectReveal(Object object)
+    {
+        if (_mform != null)
+        {
+            return _mform.setInput(object);
+        }
+        return false;
+    }
+
+    /**
+     * By default, editor will be allowed to flip the page.
+     * 
+     * @return <code>true</code>
+     */
+    public boolean canLeaveThePage()
+    {
+        return true;
+    }
+
+    public void setEditor(FormEditor editor)
+    {
+        this._editor = editor;
+    }
+
+    public void setId(String id)
+    {
+        this._id = id;
+    }
+
+    public void setPartName(String title)
+    {
+        super.setPartName(title);
+    }
+
+    public String getErrorMsg()
+    {
+        return _errorMsg;
+    }
+
+    public IEditorDescriptor getEditorDescriptor()
+    {
+        return _editorDescriptor;
+    }
+
+    public IEditorPageDescriptor getPageDescriptor()
+    {
+        return _pageDescriptor;
+    }
+
+    public void setEditorDescriptor(IEditorDescriptor editor)
+    {
+        _editorDescriptor = editor;
+    }
+
+    public void setPageDescriptor(IEditorPageDescriptor page)
+    {
+        _pageDescriptor = page;
+    }
+
+    /**
+     * Sub class should override this method to refresh the page according to the model and if this page is not opened,
+     * should not refresh it
+     */
+    public void refresh()
+    {
+        removeRememberedMarkers();
+    }
+
+    public void revert()
+    {
+        refresh();
+    }
+
+    /**
+     * Returns the database identifier
+     * 
+     * @return
+     */
+    public DatabaseIdentifier getDatabaseIdentifier()
+    {
+        ISchemaObjectEditorInput input = (ISchemaObjectEditorInput) getEditor().getEditorInput();
+        return input.getDatabaseIdentifier();
+    }
+
+    /**
+     * Mark the dirty status
+     * 
+     */
+    public void markDirty()
+    {
+        ISchemaObjectEditor editor = (ISchemaObjectEditor) getEditor();
+        editor.markDirty();
+    }
+
+    /**
+     * The default implementation of this method validate all the objects belong to this page and return the error items
+     * 
+     * @param event
+     */
+    public IErrorItem[] validate(TypedEvent event)
+    {
+        List errors = new ArrayList();
+        _diagnostics = getDiagnosticChain(event);
+
+        boolean isValid = ((BasicDiagnostic) _diagnostics).getChildren().size() == 0;
+
+        SQLObject[] objs = getSQLObjects();
+        if (objs == null)
+        {
+            return new IErrorItem[0];
+        }
+
+        // Check each object given in the context
+        for (int i = 0; i < objs.length; i++)
+        {
+            isValid &= SQLModelValidationDelegate.getInstance().validate(objs[i], _diagnostics,
+                    buildValidationContext(event), buildSharedParams(event));
+        }
+
+        if (!isValid)
+        {
+            if (((Diagnostic) _diagnostics).getChildren().size() > 0)
+            {
+                Iterator iter = ((Diagnostic) _diagnostics).getChildren().iterator();
+                while (iter.hasNext())
+                {
+                    Diagnostic d = (Diagnostic) iter.next();
+                    errors.add(new ErrorItem(null, d.getMessage(), d.getSeverity()));
+                }
+            }
+        }
+
+        IErrorItem[] items = (IErrorItem[]) errors.toArray(new IErrorItem[errors.size()]);
+        return items;
+    }
+
+    protected Map buildValidationContext(TypedEvent e)
+    {
+        Map context = new HashMap();
+        return context;
+    }
+
+    protected Map buildSharedParams(TypedEvent e)
+    {
+        Map context = new HashMap();
+        return context;
+    }
+
+    protected Map buildSharedParams()
+    {
+        return buildSharedParams(null);
+    }
+
+    /**
+     * Sub class should override this method to populate the SQL objects belong to this page
+     * 
+     * @param event
+     */
+    public void populateSQLObjects(TypedEvent event)
+    {
+
+    }
+
+    /**
+     * Validates this page and show errors accordingly
+     * 
+     * @param event
+     */
+    public void validateAndShowErrors(TypedEvent event)
+    {
+        IErrorItem[] errors = validate(event);
+        showErrorItems(errors);
+    }
+
+    /**
+     * Sub class should override this method to return the SQL objects belong to this page
+     * 
+     * @return
+     */
+    protected SQLObject[] getSQLObjects()
+    {
+        return new SQLObject[0];
+    }
+
+    /**
+     * Shows the validation errors.<br>
+     * Since multiple threads can concurrently show error items, to prevent duplicate error items, this method should be
+     * executed synchronized.
+     * 
+     * @param items
+     */
+    protected synchronized void showErrorItems(IErrorItem[] items)
+    {
+        if (Thread.interrupted())
+        {
+            return;
+        }
+        ISchemaObjectEditor editor = (ISchemaObjectEditor) getEditor();
+        removeRememberedMarkers();
+
+        if (items == null)
+        {
+            return;
+        }
+
+        IWorkspace workspace = ResourcesPlugin.getWorkspace();
+        IMarker marker = null;
+        try
+        {
+            for (int i = 0; i < items.length; i++)
+            {
+                int severity = items[i].getSeverity();
+                if (severity == Diagnostic.WARNING)
+                {
+                    severity = IMarker.SEVERITY_WARNING;
+                }
+                else if (severity == Diagnostic.INFO)
+                {
+                    severity = IMarker.SEVERITY_INFO;
+                }
+                else
+                {
+                    severity = IMarker.SEVERITY_ERROR;
+                }
+                marker = workspace.getRoot().createMarker(IMarker.PROBLEM);
+                marker.setAttribute(IMarker.MESSAGE, items[i].getMessage());
+                marker.setAttribute(IMarker.USER_EDITABLE, Boolean.FALSE);
+                marker.setAttribute(IMarker.SEVERITY, severity);
+                marker.setAttribute(IMarker.PRIORITY, IMarker.PRIORITY_HIGH);
+                marker.setAttribute(IMarker.TRANSIENT, Boolean.TRUE);
+                marker.setAttribute(IMarker.LOCATION, ((WorkbenchPart) editor).getPartName() + ": "
+                        + getPageDescriptor().getPageName());
+                _remembersMarkers.add(marker);
+            }
+        }
+        catch (Exception e)
+        {
+            _logger.error("SchemaObjectEditorPage_marker_creation_error", e);
+        }
+    }
+
+    protected void removeRememberedMarkers()
+    {
+        if (_remembersMarkers == null)
+        {
+            _remembersMarkers = new ArrayList();
+        }
+        Iterator iter = _remembersMarkers.iterator();
+        while (iter.hasNext())
+        {
+            IMarker marker = (IMarker) iter.next();
+            try
+            {
+                marker.delete();
+            }
+            catch (CoreException cex)
+            {
+                _logger.error("SchemaObjectEditorPage_marker_remove_error", cex);
+            }
+        }
+        _remembersMarkers.clear();
+    }
+
+    /**
+     * Sub class can override this method to put some diagnostics into the chain before validating the model
+     * 
+     * @return
+     */
+    protected DiagnosticChain getDiagnosticChain(TypedEvent event)
+    {
+        return new BasicDiagnostic();
+    }
+
+    public boolean isPageOpened()
+    {
+        return _pageOpened;
+    }
+
+    public void modelRegenerated()
+    {
+        refresh();
+    }
+
+    public boolean aboutToSave(IProgressMonitor monitor)
+    {
+        return true;
+    }
+
+    public IErrorItem[] validateOnline(TypedEvent event)
+    {
+        _isOnlineMode = true;
+        IErrorItem[] errors = validate(event);
+        _isOnlineMode = false;
+        return errors;
+    }
+
+    public void menuAboutToShow(IMenuManager manager)
+    {
+
+    }
+
+    public String[] getPreferencePageIds()
+    {
+        return null;
+    }
+
+    /**
+     * The default implementation sets the current page active
+     */
+    public void setFocus(int itemType, Object item)
+    {
+        if (getPageDescriptor().getPageId() != null)
+        {
+            getEditor().setActivePage(getPageDescriptor().getPageId());
+        }
+    }
+
+    public void enable(boolean enabled)
+    {
+
+    }
+}
diff --git a/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/core/messages.properties b/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/core/messages.properties
new file mode 100644
index 0000000..35b4682
--- /dev/null
+++ b/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/core/messages.properties
@@ -0,0 +1,36 @@
+SchemaObjectEditorPage_help_name=help
+SchemaObjectEditorPage_help_tip=Help
+SchemaObjectEditorInput_name=Schema Editor Input
+SchemaObjectEditor_error_id=error
+SchemaObjectEditor_error=Error
+SchemaObjectEditor_no_page=No page defined/selected for the editor, if you see this error, an internal error occurred.
+SchemaObjectEditor_no_handler=No editor handler defined for the editor, if you see this error message, an internal error occurred
+SchemaObjectEditor_preferences=&Preferences...
+SchemaObjectEditor_pagechange_error=Cannot change page because of error in the previous page
+SchemaObjectEditor_save_to_server=&Save to Server
+ErrorPage_error_msg=Error Message
+ErrorPage_error=Error
+SavePreviewDialog_problem=Problem Occurred
+SavePreviewDialog_execution_failed_msg=Error occurred when executing one or more generated SQL statements, the editor will not be refreshed. Refer to the SQL Results view for error information
+SavePreviewDialog_copy=&Copy
+SavePreviewDialog_preview=Preview Changes
+SavePreviewDialog_not_show_again=&Do not show this dialog again
+SavePreviewDialog_noname_sql=noname
+SavePreviewDialog_execute=&Save
+SavePreviewDialog_save_as=Save &As...
+SavePreviewDialog_select_all=&Select All
+SavePreviewDialog_cancel=&Cancel
+DefaultSchemaObjectEditorHandler_validation_problem=Validation Problem
+DefaultSchemaObjectEditorHandler_refreshing_schema_editor=Synchronizing the editor with database
+DefaultSchemaObjectEditorHandler_existing_errors=There exists errors
+DefaultSchemaObjectEditorHandler_validation_fail=Validation failed, correct them before saving to the database
+DefaultSchemaObjectEditorHandler_subtask_name=Retrieving database objects
+DefaultSchemaObjectEditorHandler_refreshing=Refreshing database object...
+DefaultSchemaObjectEditorHandler_modifying=Modifying
+DefaultSchemaObjectEditorHandler_page=Page: 
+SQLExecutionJobListener_refreshing=Synchronizing
+MainSQLObjectLostPromoptSavingTitle=Save DDL
+MainSQLObjectLostPromoptSavingMessage = The database object was lost. Do you want to save the DDL?
+
+AbstractSchemaObjectEditModel_fatal_error=Fatal Error
+AbstractSchemaObjectEditModel_main_object_lost=The database object \"{0}\" cannot be found in the database, either because it is removed or the current connection is lost. The editor should be closed.
\ No newline at end of file
diff --git a/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/extensions/IEditorDescriptor.java b/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/extensions/IEditorDescriptor.java
new file mode 100644
index 0000000..654594d
--- /dev/null
+++ b/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/extensions/IEditorDescriptor.java
@@ -0,0 +1,199 @@
+/***********************************************************************************************************************
+ * Copyright (c) 2009 Sybase, Inc. 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: Sybase, Inc. - initial API and implementation
+ **********************************************************************************************************************/
+package org.eclipse.datatools.sqltools.schemaobjecteditor.ui.extensions;
+
+import java.util.Map;
+
+import org.eclipse.datatools.sqltools.schemaobjecteditor.ui.ISchemaObjectEditorActionBarContributor;
+import org.eclipse.datatools.sqltools.schemaobjecteditor.ui.ISchemaObjectEditorHandler;
+import org.eclipse.swt.graphics.Image;
+
+/**
+ * Containing some static information of an schema object editor
+ * 
+ * @author Idull
+ */
+public interface IEditorDescriptor
+{
+    /**
+     * Returns the editor name
+     * 
+     * @return
+     */
+    public String getEditorName();
+
+    /**
+     * Returns the editor id
+     * 
+     * @return
+     */
+    public String getEditorId();
+
+    /**
+     * Returns the vendor name
+     * 
+     * @return
+     */
+    public String getVendorName();
+
+    /**
+     * Returns the product version for which this editor is defined
+     * 
+     * @return
+     */
+    public String getVersion();
+
+    /**
+     * Returns the db object type id for which this editor is defined
+     * 
+     * @return
+     */
+    public String getSchemaObjectType();
+
+    /**
+     * Returns the pages list of this editor
+     * 
+     * @return
+     */
+    public IEditorPageDescriptor[] getPageDescriptors();
+
+    /**
+     * Sets the pages of this editor, should NOT called by consumer
+     * 
+     * @param pages
+     */
+    public void setPageDescriptors(IEditorPageDescriptor[] pages);
+
+    /**
+     * Returns the handler for this editor
+     * 
+     * @return
+     */
+    public ISchemaObjectEditorHandler getHandler();
+
+    /**
+     * Sets the handler, should NOT called by consumer
+     * 
+     * @param handler
+     */
+    public void setHandler(ISchemaObjectEditorHandler handler);
+
+    /**
+     * Returns the icon for this editor, can be <code>null</code>
+     * 
+     * @return
+     */
+    public Image getIcon();
+
+    /**
+     * Checks if the visibility of pages of this editor can be set by end user
+     * 
+     * @return
+     */
+    public boolean isVisibilityConfigurable();
+
+    /**
+     * Returns the action bar contributor, can be <code>null</code>
+     * 
+     * @return
+     */
+    public ISchemaObjectEditorActionBarContributor getActionContributor();
+
+    /**
+     * Sets the action bar contributor, should NOT called by consumer
+     * 
+     * @param contributor
+     */
+    public void setActionContributor(ISchemaObjectEditorActionBarContributor contributor);
+
+    /**
+     * Returns the default order of the pages. ATTN: The contents of the map may be removed outside of this class
+     * 
+     * @return
+     */
+    public Map getDefaultPagesOrder();
+
+    /**
+     * Returns the pages of this editor with the order set by end-user
+     * 
+     * @return
+     */
+    public IEditorPageDescriptor[] getSortedPages();
+
+    /**
+     * Returns the pages of this editor with default order
+     * 
+     * @return
+     */
+    public IEditorPageDescriptor[] getDefaultSortedPages();
+
+    /**
+     * Returns the visible pages of this editor with the order set by end-user
+     * 
+     * @return
+     */
+    public IEditorPageDescriptor[] getVisibleSortedPages();
+
+    /**
+     * Returns the visible pages of this editor with default order
+     * 
+     * @return
+     */
+    public IEditorPageDescriptor[] getVisibleSortedPagesDefault();
+
+    /**
+     * Returns the page which is specified as the first page when it's visible
+     * 
+     * @return the first page
+     */
+    public IEditorPageDescriptor getMandatoryFirstPage();
+
+    /**
+     * Returns the page which is specified as the last page when it's visible
+     * 
+     * @return the last page
+     */
+    public IEditorPageDescriptor getMandatoryLastPage();
+
+    /**
+     * 
+     * @param mandatoryFirstPage
+     */
+    public void setMandatoryFirstPage(IEditorPageDescriptor mandatoryFirstPage);
+
+    /**
+     * 
+     * @param mandatoryLastPage
+     */
+    public void setMandatoryLastPage(IEditorPageDescriptor mandatoryLastPage);
+
+    /**
+     * Returns the object type name
+     * 
+     * @return
+     */
+    public String getObjectTypeName();
+
+    /**
+     * 
+     * @param objTypeName
+     */
+    public void setObjectTypeName(String objTypeName);
+
+    /**
+     * Returns the plugin id which this editors belongs to
+     * 
+     * @return
+     */
+    public String getPluginId();
+
+    /**
+     * Sets the plugin id
+     */
+    public void setPluginId(String pluginId);
+}
diff --git a/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/extensions/IEditorPageDescriptor.java b/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/extensions/IEditorPageDescriptor.java
new file mode 100644
index 0000000..3f02041
--- /dev/null
+++ b/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/extensions/IEditorPageDescriptor.java
@@ -0,0 +1,102 @@
+/***********************************************************************************************************************
+ * Copyright (c) 2009 Sybase, Inc. 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: Sybase, Inc. - initial API and implementation
+ **********************************************************************************************************************/
+package org.eclipse.datatools.sqltools.schemaobjecteditor.ui.extensions;
+
+import org.eclipse.datatools.sqltools.schemaobjecteditor.ui.ISchemaObjectEditorPage;
+
+/**
+ * Containing some static information of an editor page
+ * 
+ * @author Idull
+ */
+public interface IEditorPageDescriptor
+{
+    /**
+     * Returns the page id
+     * 
+     * @return
+     */
+    public String getPageId();
+
+    /**
+     * Returns the page name
+     * 
+     * @return
+     */
+    public String getPageName();
+
+    /**
+     * Returns the id of the editor in which this page is contained
+     * 
+     * @return
+     */
+    public String getEditorId();
+
+    /**
+     * Checks if this page is required (Must be visible)
+     * 
+     * @return
+     */
+    public boolean isRequired();
+
+    /**
+     * Checks if the page is visible by default
+     * 
+     * @return
+     */
+    public boolean isVisibleByDefault();
+
+    /**
+     * Checks if this page is visible or not
+     * 
+     * @return
+     */
+    public boolean isSelectedToShow();
+
+    /**
+     * Returns the page instance
+     * 
+     * @return
+     */
+    public ISchemaObjectEditorPage getPageClass();
+
+    /**
+     * Returns the page extension id defined in the extension, can be <code>null</code>
+     * 
+     * @return
+     */
+    public String getPageExtensionId();
+
+    /**
+     * Returns the instance of the editor in which this page is contained
+     * 
+     * @return
+     */
+    public IEditorDescriptor getEditor();
+
+    /**
+     * Returns the context help id
+     * 
+     * @return
+     */
+    public String getContextHelpId();
+
+    /**
+     * Returns the object class type for which the page is designed
+     * 
+     * @return
+     */
+    public String getObjectClassType();
+
+    /**
+     * Checks if the page is selected to be visible
+     * 
+     * @return
+     */
+    public boolean isVisible();
+}
diff --git a/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/internal/Constants.java b/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/internal/Constants.java
new file mode 100644
index 0000000..70216bb
--- /dev/null
+++ b/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/internal/Constants.java
@@ -0,0 +1,63 @@
+/***********************************************************************************************************************
+ * Copyright (c) 2009 Sybase, Inc. 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: Sybase, Inc. - initial API and implementation
+ **********************************************************************************************************************/
+package org.eclipse.datatools.sqltools.schemaobjecteditor.ui.internal;
+
+/**
+ * Constants
+ * 
+ * @author Idull
+ */
+public class Constants
+{
+    public static final String PLUGIN_ID                                            = "org.eclipse.datatools.sqltools.schemaobjecteditor.ui";
+    public static final String EXTENSION_POINT_ID                                   = "schemaObjectEditor";
+    public static final String EXTENSION_POINT_EDITOR_ID                            = "EditorId";
+    public static final String EXTENSION_POINT_EDITOR_NAME                          = "EditorName";
+    public static final String EXTENSION_POINT_EDITOR_VENDOR_NAME                   = "VendorName";
+    public static final String EXTENSION_POINT_EDITOR_DB_VERSION                    = "Version";
+    public static final String EXTENSION_POINT_EDITOR_OBJECT_TYPE_ID                = "ObjectTypeId";
+    public static final String EXTENSION_POINT_EDITOR_HANDLER                       = "Handler";
+    public static final String EXTENSION_POINT_EDITOR_GENERATE_PREF_GROUP           = "VisibilityConfigurable";
+    public static final String EXTENSION_POINT_EDITOR_CONTRIBUTOR_CLASS             = "ContributorClass";
+    public static final String EXTENSION_POINT_EDITOR_ICON                          = "Icon";
+    public static final String EXTENSION_POINT_EDITOR_MANDATORYFRISTPAGE            = "MustBeFirstWhenShown";
+    public static final String EXTENSION_POINT_EDITOR_MANDATORYLASTPAGE             = "MustBeLastWhenShown";
+    public static final String EXTENSION_POINT_EDITOR_OBJECT_TYPE_NAME              = "ObjectTypeName";
+
+    public static final String EXTENSION_POINT_PAGE                                 = "EditorPage";
+    public static final String EXTENSION_POINT_PAGE_HELPID                          = "ContextHelpId";
+    public static final String EXTENSION_POINT_REFERENCED_PAGE                      = "ReferencedPage";
+    public static final String EXTENSION_POINT_PAGE_ID                              = "PageId";
+    public static final String EXTENSION_POINT_PAGE_NAME                            = "PageName";
+    public static final String EXTENSION_POINT_PAGE_VISIBLE_BYDEFAULT               = "VisibleByDefault";
+    public static final String EXTENSION_POINT_PAGE_CLASS                           = "Class";
+    public static final String EXTENSION_POINT_PAGE_IS_REQUIRED                     = "Required";
+    public static final String EXTENSION_POINT_PAGE_EXTENSION_ID                    = "PageExtensionId";
+    public static final String EXTENSION_POINT_PAGE_OBJECT_CLASS_TYPE               = "ObjectClassType";
+
+    public static final String SCHEMA_EDITOR_ID                                     = "org.eclipse.datatools.sqltools.schemaobjecteditor.editor";
+    public static final String SCHEMA_EDITOR_NESTED_ID                              = "org.eclipse.datatools.sqltools.schemaobjecteditor.nested.editor";
+    public static final String EXTENSION_POINT_EDITOR_REFERENCED_EDITOR             = "ReferencedEditor";
+    public static final String EXTENSION_POINT_EDITOR_REFERENCED_EDITOR_EXCLUDES    = "Excludes";
+    public static final String EXTENSION_POINT_EDITOR_REFERENCED_EDITOR_EXCLUDEPAGE = "ExcludePage";
+    public static final String EXTENSION_POINT_EDITOR_DEFAULT_ORDER                 = "DefaultPagesOrder";
+    public static final String EXTENSION_POINT_EDITOR_ORDER_ITEM                    = "OrderItem";
+    public static final String EXTENSION_POINT_EDITOR_ORDER_NUM                     = "OrderNum";
+
+    public static final String EDITOR_PAGE_VISIABILITY                              = "SchemaObjectEditor.visiability";
+    public static final String EDITOR_PAGE_ORDER                                    = "SchemaObjectEditor.pageOrder";
+
+    public static final String PREFERENCE_PREVIOUS_DB_DEFINITION                    = "SchemaObjectEditorPreferencePage.previous.configured.dbdefinition";
+    public static final String PREFERENCE_PREVIOUS_EDIOR_NAME                       = "SchemaObjectEditorPreferencePage.previous.configured.editor";
+
+    public static final String PREFERENCE_ALWAYS_SHOW_PREVIEW                       = "SchemaObjectEditorPreferencePage.show.preview.dialog";
+    public static final String PREFERENCE_USE_LATEST_VERSION                        = "SchemaObjectEditorPreferencePage.use.latest.version";
+
+    public static final String PREFERENCE_CHECK_EXISTENCE                           = "SchemaObjectEditorPreferencePage.check.existence";
+    public static final String PREFERENCE_OPEN_FILE_AFTER_SAVEAS                    = "SchemaObjectEditorPreferencePage.open.file.after.saveas";
+}
diff --git a/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/internal/ISchemaObjectEditorExtensionsRegistryReader.java b/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/internal/ISchemaObjectEditorExtensionsRegistryReader.java
new file mode 100644
index 0000000..1939068
--- /dev/null
+++ b/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/internal/ISchemaObjectEditorExtensionsRegistryReader.java
@@ -0,0 +1,20 @@
+/***********************************************************************************************************************
+ * Copyright (c) 2009 Sybase, Inc. 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: Sybase, Inc. - initial API and implementation
+ **********************************************************************************************************************/
+package org.eclipse.datatools.sqltools.schemaobjecteditor.ui.internal;
+
+import org.eclipse.datatools.sqltools.schemaobjecteditor.ui.extensions.IEditorDescriptor;
+
+/**
+ * The schema object editor extensions' registry reader
+ * 
+ * @author Idull
+ */
+public interface ISchemaObjectEditorExtensionsRegistryReader
+{
+    public IEditorDescriptor[] getEditorDescriptors();
+}
diff --git a/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/internal/LogMessages.properties b/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/internal/LogMessages.properties
new file mode 100644
index 0000000..28e6f47
--- /dev/null
+++ b/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/internal/LogMessages.properties
@@ -0,0 +1,13 @@
+EditorPage_error_create_class=Error occurs when instantiating the editor page class
+ExtendedEditor_error_create_handler=Error occurs when instantiating the editor handler class
+ExtendedEditor_error_create_contributor=Error occurs when instantiating the editor action contributor class
+SchemaObjectEditor_not_proper_iput=Improper editor input
+SchemaObjectEditor_error_setup_page=Error occurs when setting up editor pages
+SchemaObjectEditorExtensionsRegistryReader_error_reading_page=Error occurs when reading the editor page information from the extensions registry
+SchemaObjectEditorExtensionsRegistryReader_error_reading_editor=Error occurs when reading the editor information from the extensions registry
+SchemaObjectEditorExtensionsRegistryRead_error_read_image=Error occurs when reading the editor icon
+SchemaObjectEditor_error_set_errorpage=Error occurs when setting up the error page in the schema object editor
+SaveAsDialog_open_error=Error occurs when opening the saved file
+ScriptsExecutionRunnable_error_execution=Error occurs when executing the generated SQL scripts
+SchemaObjectEditorPage_marker_creation_error=Error occurs when creating markers in Problems view
+SchemaObjectEditorPage_marker_remove_error=Error occurs when removing markers from Problems view
diff --git a/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/internal/Messages.java b/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/internal/Messages.java
new file mode 100644
index 0000000..f978e94
--- /dev/null
+++ b/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/internal/Messages.java
@@ -0,0 +1,29 @@
+/***********************************************************************************************************************
+ * Copyright (c) 2009 Sybase, Inc. 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: Sybase, Inc. - initial API and implementation
+ **********************************************************************************************************************/
+package org.eclipse.datatools.sqltools.schemaobjecteditor.ui.internal;
+
+import org.eclipse.osgi.util.NLS;
+
+public class Messages extends NLS
+{
+    private static final String BUNDLE_NAME = Messages.class.getPackage().getName() + ".messages"; //$NON-NLS-1$
+
+    private Messages()
+    {
+    }
+
+    static
+    {
+        NLS.initializeMessages(BUNDLE_NAME, Messages.class);
+    }
+
+    public static String SchemaEditorsHandler_dirty_editor;
+    public static String SchemaEditorsHandler_dirty_editor_found;
+    public static String SchemaEditorsHandler_save_disconnect;
+    public static String SchemaEditorsHandler_select_to_save;
+}
diff --git a/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/internal/SOEUIPlugin.java b/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/internal/SOEUIPlugin.java
new file mode 100644
index 0000000..bb77f5d
--- /dev/null
+++ b/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/internal/SOEUIPlugin.java
@@ -0,0 +1,167 @@
+/***********************************************************************************************************************
+ * Copyright (c) 2009 Sybase, Inc. 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: Sybase, Inc. - initial API and implementation
+ **********************************************************************************************************************/
+package org.eclipse.datatools.sqltools.schemaobjecteditor.ui.internal;
+
+import java.util.ResourceBundle;
+
+import org.eclipse.datatools.sqltools.core.profile.SQLToolsProfileListenersManager;
+import org.eclipse.datatools.sqltools.editor.core.connection.SQLToolsConnectListenersManager;
+import org.eclipse.datatools.sqltools.schemaobjecteditor.ui.util.ColorProvider;
+import org.eclipse.datatools.sqltools.schemaobjecteditor.ui.util.ILogger;
+import org.eclipse.datatools.sqltools.schemaobjecteditor.ui.util.StatusLogger;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.IWorkbenchPage;
+import org.eclipse.ui.IWorkbenchWindow;
+import org.eclipse.ui.plugin.AbstractUIPlugin;
+import org.osgi.framework.BundleContext;
+
+/**
+ * The activator class controls the plug-in life cycle
+ */
+public class SOEUIPlugin extends AbstractUIPlugin
+{
+
+    private ResourceBundle     _bundle   = ResourceBundle
+                                                 .getBundle("org.eclipse.datatools.sqltools.schemaobjecteditor.ui.internal.LogMessages");
+    // The plug-in ID
+    public static final String PLUGIN_ID = "org.eclipse.datatools.sqltools.schemaobjecteditor.ui";
+
+    // The shared instance
+    private static SOEUIPlugin   plugin;
+    private ColorProvider      _colorProvider;
+
+    /**
+     * The constructor
+     */
+    public SOEUIPlugin()
+    {
+        plugin = this;
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework.BundleContext)
+     */
+    public void start(BundleContext context) throws Exception
+    {
+        super.start(context);
+        SchemaEditorsHandler handler = new SchemaEditorsHandler();
+        SQLToolsConnectListenersManager.getInstance().addConnectListener(handler);
+        SQLToolsProfileListenersManager.getInstance().addProfileListener(handler);
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext)
+     */
+    public void stop(BundleContext context) throws Exception
+    {
+        // release those Color objects
+        if (_colorProvider != null)
+        {
+            _colorProvider.dispose();
+            _colorProvider = null;
+        }
+        plugin = null;
+        super.stop(context);
+    }
+
+    /**
+     * Returns the shared instance
+     * 
+     * @return the shared instance
+     */
+    public static SOEUIPlugin getDefault()
+    {
+        return plugin;
+    }
+
+    /**
+     * Get active workbench page.
+     * <p>
+     * This method acts as a convenience for plug-in implementors.
+     * </P>
+     * 
+     * @return IWorkbenchPage the workbench page for this plug-in
+     */
+    public static IWorkbenchPage getActiveWorkbenchPage()
+    {
+        IWorkbenchPage workbenchPage = getActiveWorkbenchWindow().getActivePage();
+        if (workbenchPage != null)
+        {
+            return workbenchPage;
+        }
+        IWorkbenchPage[] workbenchPages = getActiveWorkbenchWindow().getPages();
+        if (workbenchPages.length > 0)
+        {
+            return workbenchPages[0];
+        }
+        return null;
+    }
+
+    /**
+     * Get active workbench window.
+     * <p>
+     * This method exists as a convenience for plug-in implementors.
+     * </p>
+     * 
+     * @return IWorkbenchWindow the workbench for this plug-in
+     */
+    public static IWorkbenchWindow getActiveWorkbenchWindow()
+    {
+        IWorkbenchWindow window = getDefault().getWorkbench().getActiveWorkbenchWindow();
+        if (window != null)
+        {
+            return window;
+        }
+        IWorkbenchWindow[] windows = getDefault().getWorkbench().getWorkbenchWindows();
+        if (windows.length > 0)
+        {
+            return windows[0];
+        }
+        return null;
+    }
+
+    /**
+     * @return
+     */
+    public static Shell getActiveWorkbenchShell()
+    {
+        IWorkbenchWindow window = getActiveWorkbenchWindow();
+        if (window != null)
+        {
+            return window.getShell();
+        }
+        IWorkbenchWindow[] windows = getDefault().getWorkbench().getWorkbenchWindows();
+        if (windows.length > 0)
+            return windows[0].getShell();
+        return null;
+    }
+
+    /**
+     * Returns a logger.
+     * 
+     * @param bundle the bundle used in logger
+     * @return a logger
+     */
+    public static ILogger getLogger(ResourceBundle bundle)
+    {
+        return new StatusLogger(getDefault().getLog(), PLUGIN_ID, bundle == null ? getDefault()._bundle : bundle);
+    }
+
+    public ColorProvider getColorProvider()
+    {
+        if (_colorProvider == null)
+        {
+            _colorProvider = new ColorProvider();
+        }
+        return _colorProvider;
+    }
+}
diff --git a/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/internal/SchemaEditorsHandler.java b/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/internal/SchemaEditorsHandler.java
new file mode 100644
index 0000000..19cf63a
--- /dev/null
+++ b/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/internal/SchemaEditorsHandler.java
@@ -0,0 +1,197 @@
+/***********************************************************************************************************************
+ * Copyright (c) 2009 Sybase, Inc. 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: Sybase, Inc. - initial API and implementation
+ **********************************************************************************************************************/
+package org.eclipse.datatools.sqltools.schemaobjecteditor.ui.internal;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import org.eclipse.datatools.connectivity.ConnectEvent;
+import org.eclipse.datatools.connectivity.IConnectionProfile;
+import org.eclipse.datatools.sqltools.core.profile.ConnectProfile;
+import org.eclipse.datatools.sqltools.core.profile.ISQLToolsProfileListener;
+import org.eclipse.datatools.sqltools.editor.core.connection.ISQLToolsConnectListener;
+import org.eclipse.datatools.sqltools.schemaobjecteditor.ui.ISchemaObjectEditor;
+import org.eclipse.datatools.sqltools.schemaobjecteditor.ui.ISchemaObjectEditorInput;
+import org.eclipse.jface.viewers.ILabelProvider;
+import org.eclipse.jface.viewers.IStructuredContentProvider;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.IEditorPart;
+import org.eclipse.ui.IEditorReference;
+import org.eclipse.ui.IWorkbenchPage;
+import org.eclipse.ui.dialogs.ListSelectionDialog;
+import org.eclipse.ui.model.AdaptableList;
+import org.eclipse.ui.model.WorkbenchContentProvider;
+import org.eclipse.ui.model.WorkbenchPartLabelProvider;
+
+/**
+ * Connect listener for schema object editors
+ * 
+ * @author Idull
+ */
+public class SchemaEditorsHandler implements ISQLToolsConnectListener, ISQLToolsProfileListener
+{
+    int _saveResult;
+
+    public void aboutToClose(ConnectEvent event)
+    {
+
+    }
+
+    public void closeConnection(ConnectEvent event)
+    {
+        if (SOEUIPlugin.getDefault() == null)
+        {
+            return;
+        }
+        IEditorReference[] editorRefs = SOEUIPlugin.getActiveWorkbenchPage().getEditorReferences();
+        List openedClearEditors = new ArrayList();
+        for (int i = 0; i < editorRefs.length; i++)
+        {
+            IEditorPart part = editorRefs[i].getEditor(false);
+            if (part instanceof ISchemaObjectEditor)
+            {
+                ISchemaObjectEditor editor = (ISchemaObjectEditor) part;
+                ISchemaObjectEditorInput input = (ISchemaObjectEditorInput) editor.getEditorInput();
+                if (event.getConnectionProfile().getName().equals(input.getDatabaseIdentifier().getProfileName()))
+                {
+                    openedClearEditors.add(part);
+                }
+            }
+        }
+        Iterator iter = openedClearEditors.iterator();
+        while (iter.hasNext())
+        {
+            final IEditorPart p = (IEditorPart) iter.next();
+            SOEUIPlugin.getActiveWorkbenchShell().getDisplay().syncExec(new Runnable()
+            {
+                public void run()
+                {
+                    SOEUIPlugin.getActiveWorkbenchPage().closeEditor(p, false);
+                }
+            });
+        }
+    }
+
+    public boolean okToClose(ConnectEvent event)
+    {
+        final List editors = new ArrayList();
+        IEditorReference[] editorRefs = SOEUIPlugin.getActiveWorkbenchPage().getEditorReferences();
+        for (int i = 0; i < editorRefs.length; i++)
+        {
+            final IEditorPart part = editorRefs[i].getEditor(false);
+            if (part instanceof ISchemaObjectEditor)
+            {
+                ISchemaObjectEditor editor = (ISchemaObjectEditor) part;
+                ISchemaObjectEditorInput input = (ISchemaObjectEditorInput) editor.getEditorInput();
+                if (!event.getConnectionProfile().getName().equals(input.getDatabaseIdentifier().getProfileName()))
+                {
+                    continue;
+                }
+                SOEUIPlugin.getActiveWorkbenchShell().getDisplay().syncExec(new Runnable()
+                {
+                    public void run()
+                    {
+                        // isDirty() should be called in UI thread
+                        if (part.isDirty())
+                        {
+                            editors.add(part);
+                        }
+                    }
+                });
+            }
+        }
+
+        // Save dirty editors
+        if (editors.size() > 0)
+        {
+
+            SOEUIPlugin.getActiveWorkbenchShell().getDisplay().syncExec(new Runnable()
+            {
+                public void run()
+                {
+                    SaveDirtyEditorsSelectionDialog dlg = new SaveDirtyEditorsSelectionDialog(SOEUIPlugin
+                            .getActiveWorkbenchShell(), new AdaptableList(editors), new WorkbenchContentProvider(),
+                            new WorkbenchPartLabelProvider(), Messages.SchemaEditorsHandler_select_to_save);
+                    dlg.setInitialElementSelections(editors);
+                    _saveResult = dlg.open();
+                }
+            });
+
+            // dont disconnect if cancelled or saving failed
+            return _saveResult == 1 ? false : true;
+        }
+        return true;
+    }
+
+    public void profileConnected(ConnectEvent event)
+    {
+
+    }
+
+    public void profileAdded(IConnectionProfile profile)
+    {
+
+    }
+
+    public void profileChanged(IConnectionProfile profile, String oldName, String oldDesc, Boolean oldAutoConnect,
+            boolean onlyNameChanged, ConnectProfile oldProfile)
+    {
+
+    }
+
+    public void profileDeleted(IConnectionProfile profile)
+    {
+
+    }
+
+    /**
+     * Selection dialog to save dirty editors
+     * 
+     * @author Idull
+     */
+    class SaveDirtyEditorsSelectionDialog extends ListSelectionDialog
+    {
+        public SaveDirtyEditorsSelectionDialog(Shell parentShell, Object input,
+                IStructuredContentProvider contentProvider, ILabelProvider labelProvider, String message)
+        {
+            super(parentShell, input, contentProvider, labelProvider, message);
+            setTitle(Messages.SchemaEditorsHandler_save_disconnect);
+        }
+
+        protected void okPressed()
+        {
+            super.okPressed();
+            Object[] selectedItems = getResult();
+            if (selectedItems != null)
+            {
+                for (int i = 0; i < selectedItems.length; i++)
+                {
+                    if (selectedItems[i] == null || !(selectedItems[i] instanceof ISchemaObjectEditor))
+                    {
+                        continue;
+                    }
+                    ISchemaObjectEditor editor = (ISchemaObjectEditor) selectedItems[i];
+                    editor.setSyncSaveMode();
+                    editor.setNeedRefreshAfterSave(false);
+                    IWorkbenchPage page = SOEUIPlugin.getActiveWorkbenchPage();
+                    boolean succeeded = page.saveEditor(editor, false);
+                    if (!succeeded)
+                    {
+                        setReturnCode(CANCEL);
+                    }
+                    else
+                    {
+                        // Close the editor if saving succeeds
+                        page.closeEditor(editor, false);
+                    }
+                }
+            }
+        }
+    }
+}
diff --git a/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/internal/SchemaObjectEditorExtensionsRegistryReader.java b/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/internal/SchemaObjectEditorExtensionsRegistryReader.java
new file mode 100644
index 0000000..06134f8
--- /dev/null
+++ b/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/internal/SchemaObjectEditorExtensionsRegistryReader.java
@@ -0,0 +1,460 @@
+/***********************************************************************************************************************
+ * Copyright (c) 2009 Sybase, Inc. 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: Sybase, Inc. - initial API and implementation
+ **********************************************************************************************************************/
+package org.eclipse.datatools.sqltools.schemaobjecteditor.ui.internal;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.core.runtime.IExtension;
+import org.eclipse.core.runtime.IExtensionPoint;
+import org.eclipse.core.runtime.IExtensionRegistry;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.datatools.sqltools.schemaobjecteditor.ui.ISchemaObjectEditorActionBarContributor;
+import org.eclipse.datatools.sqltools.schemaobjecteditor.ui.ISchemaObjectEditorHandler;
+import org.eclipse.datatools.sqltools.schemaobjecteditor.ui.ISchemaObjectEditorPage;
+import org.eclipse.datatools.sqltools.schemaobjecteditor.ui.extensions.IEditorDescriptor;
+import org.eclipse.datatools.sqltools.schemaobjecteditor.ui.extensions.IEditorPageDescriptor;
+import org.eclipse.datatools.sqltools.schemaobjecteditor.ui.internal.core.EditorDescriptor;
+import org.eclipse.datatools.sqltools.schemaobjecteditor.ui.internal.core.EditorPageDescriptor;
+import org.eclipse.datatools.sqltools.schemaobjecteditor.ui.util.ILogger;
+import org.eclipse.datatools.sqltools.schemaobjecteditor.ui.util.Images;
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.swt.graphics.Image;
+import org.osgi.framework.Bundle;
+
+/**
+ * The registry reader
+ * 
+ * @author Idull
+ */
+public class SchemaObjectEditorExtensionsRegistryReader implements ISchemaObjectEditorExtensionsRegistryReader
+{
+    private List                                              _editors;
+    private static SchemaObjectEditorExtensionsRegistryReader _instance;
+    private ILogger                                           _logger = SOEUIPlugin.getLogger(null);
+
+    private SchemaObjectEditorExtensionsRegistryReader()
+    {
+
+    }
+
+    Image _image = null;
+
+    public static synchronized SchemaObjectEditorExtensionsRegistryReader getInstance()
+    {
+        if (_instance == null)
+        {
+            _instance = new SchemaObjectEditorExtensionsRegistryReader();
+        }
+        return _instance;
+    }
+
+    public IEditorDescriptor[] getEditorDescriptors()
+    {
+        if (_editors == null)
+        {
+            init();
+        }
+        return _editors == null ? new IEditorDescriptor[0] : (IEditorDescriptor[]) _editors
+                .toArray(new IEditorDescriptor[_editors.size()]);
+    }
+
+    private void init()
+    {
+        _editors = new ArrayList();
+        IExtensionRegistry registry = Platform.getExtensionRegistry();
+        IExtensionPoint point = registry.getExtensionPoint(Constants.PLUGIN_ID, Constants.EXTENSION_POINT_ID);
+        if (point != null)
+        {
+            IExtension[] extensions = point.getExtensions();
+            if (extensions != null)
+            {
+                for (int i = 0; i < extensions.length; i++)
+                {
+                    IConfigurationElement[] elements = extensions[i].getConfigurationElements();
+                    IEditorDescriptor editor = null;
+                    for (int j = 0; j < elements.length; j++)
+                    {
+                        if (elements[j].getName().equals(Constants.EXTENSION_POINT_PAGE))
+                        {
+                            continue;
+                        }
+                        String editorId = elements[j].getAttribute(Constants.EXTENSION_POINT_EDITOR_ID);
+                        String editorName = elements[j].getAttribute(Constants.EXTENSION_POINT_EDITOR_NAME);
+                        String objectType = elements[j].getAttribute(Constants.EXTENSION_POINT_EDITOR_OBJECT_TYPE_ID);
+                        String vendorName = elements[j].getAttribute(Constants.EXTENSION_POINT_EDITOR_VENDOR_NAME);
+                        String version = elements[j].getAttribute(Constants.EXTENSION_POINT_EDITOR_DB_VERSION);
+                        String iconLoc = elements[j].getAttribute(Constants.EXTENSION_POINT_EDITOR_ICON);
+                        String objectTypeName = elements[j]
+                                .getAttribute(Constants.EXTENSION_POINT_EDITOR_OBJECT_TYPE_NAME);
+                        String pluginNamespace = extensions[i].getNamespaceIdentifier();
+                        Bundle bundle = Platform.getBundle(pluginNamespace);
+                        Image icon = readImage(bundle, iconLoc);
+                        String needGenPrefGrpString = elements[j]
+                                .getAttribute(Constants.EXTENSION_POINT_EDITOR_GENERATE_PREF_GROUP);
+
+                        // true by default
+                        boolean needGenPrefGrp = true;
+                        if (needGenPrefGrpString != null)
+                        {
+                            needGenPrefGrp = needGenPrefGrpString.equals("true");
+                        }
+                        editor = new EditorDescriptor(editorId, editorName, vendorName, version, objectType, icon,
+                                needGenPrefGrp);
+                        editor.setPluginId(elements[j].getDeclaringExtension().getNamespaceIdentifier());
+                        editor.setObjectTypeName(objectTypeName);
+                        String mandatoryFirstPage = "";
+                        String mandatoryLastPage = "";
+                        try
+                        {
+                            ISchemaObjectEditorHandler handler = (ISchemaObjectEditorHandler) elements[j]
+                                    .createExecutableExtension(Constants.EXTENSION_POINT_EDITOR_HANDLER);
+                            ISchemaObjectEditorActionBarContributor contributor = null;
+
+                            // The contributor class can be left empty
+                            try
+                            {
+                                contributor = (ISchemaObjectEditorActionBarContributor) elements[j]
+                                        .createExecutableExtension(Constants.EXTENSION_POINT_EDITOR_CONTRIBUTOR_CLASS);
+
+                            }
+                            catch (Exception e)
+                            {
+                                // ignore
+                            }
+
+                            mandatoryFirstPage = elements[j]
+                                    .getAttribute(Constants.EXTENSION_POINT_EDITOR_MANDATORYFRISTPAGE);
+                            mandatoryLastPage = elements[j]
+                                    .getAttribute(Constants.EXTENSION_POINT_EDITOR_MANDATORYLASTPAGE);
+
+                            editor.setHandler(handler);
+                            editor.setActionContributor(contributor);
+                            ((EditorDescriptor) editor).setConfigElement(elements[j]);
+                            ((EditorDescriptor) editor).setContributorElement(elements[j]);
+                        }
+                        catch (Exception e)
+                        {
+                            _logger.error("SchemaObjectEditorExtensionRegistryReader_error_reading_editor", e);
+                        }
+                        List pages = new ArrayList();
+
+                        // Read the referenced editor(s)
+                        IConfigurationElement[] referencedEditors = elements[j]
+                                .getChildren(Constants.EXTENSION_POINT_EDITOR_REFERENCED_EDITOR);
+
+                        for (int k = 0; k < referencedEditors.length; k++)
+                        {
+                            List excludePages = new ArrayList();
+                            String id = referencedEditors[k].getAttribute(Constants.EXTENSION_POINT_EDITOR_ID);
+
+                            IConfigurationElement[] excludes = referencedEditors[k]
+                                    .getChildren(Constants.EXTENSION_POINT_EDITOR_REFERENCED_EDITOR_EXCLUDES);
+                            if (excludes != null && excludes.length > 0)
+                            {
+                                IConfigurationElement[] excludeElements = excludes[0]
+                                        .getChildren(Constants.EXTENSION_POINT_EDITOR_REFERENCED_EDITOR_EXCLUDEPAGE);
+                                for (int kk = 0; kk < excludeElements.length; kk++)
+                                {
+                                    String excludeId = excludeElements[kk]
+                                            .getAttribute(Constants.EXTENSION_POINT_PAGE_ID);
+                                    excludePages.add(excludeId);
+                                }
+                            }
+                            IEditorPageDescriptor[] selectedPages = resolveReferenceEditor(id, editor, extensions,
+                                    excludePages);
+                            for (int kk = 0; kk < selectedPages.length; kk++)
+                            {
+                                pages.add(selectedPages[kk]);
+                            }
+                        }
+
+                        // Read self-defined editor pages
+                        IConfigurationElement[] declaredPages = elements[j].getChildren(Constants.EXTENSION_POINT_PAGE);
+                        for (int k = 0; k < declaredPages.length; k++)
+                        {
+                            IEditorPageDescriptor page = readPage(declaredPages[k], editor);
+                            if (page != null)
+                            {
+                                pages.add(page);
+                            }
+                        }
+
+                        // Read referenced pages
+                        IConfigurationElement[] referencedPages = elements[j]
+                                .getChildren(Constants.EXTENSION_POINT_REFERENCED_PAGE);
+                        for (int k = 0; k < referencedPages.length; k++)
+                        {
+                            try
+                            {
+                                String eId = referencedPages[k].getAttribute(Constants.EXTENSION_POINT_EDITOR_ID);
+                                String pId = referencedPages[k].getAttribute(Constants.EXTENSION_POINT_PAGE_ID);
+                                String pageExtensionId = referencedPages[k]
+                                        .getAttribute(Constants.EXTENSION_POINT_PAGE_EXTENSION_ID);
+                                IEditorPageDescriptor page = resolveReferencedPage(eId, pId, extensions, editor);
+                                ((EditorPageDescriptor) page).setPageExtensionId(pageExtensionId);
+                                if (page != null)
+                                {
+                                    pages.add(page);
+                                }
+
+                            }
+                            catch (Exception e)
+                            {
+                                System.out.println(e.getMessage());
+                            }
+                        }
+
+                        editor.setPageDescriptors((IEditorPageDescriptor[]) pages
+                                .toArray(new IEditorPageDescriptor[pages.size()]));
+
+                        // set the mandatory first/last page for the editor
+                        if (mandatoryFirstPage != null && !mandatoryFirstPage.trim().equals(""))
+                        {
+                            IEditorPageDescriptor[] p = editor.getPageDescriptors();
+                            for (int l = 0; l < p.length; l++)
+                            {
+                                if (p[l].getPageId().equals(mandatoryFirstPage.trim()))
+                                {
+                                    editor.setMandatoryFirstPage(p[l]);
+                                }
+                            }
+                        }
+
+                        if (mandatoryLastPage != null && !mandatoryLastPage.trim().equals(""))
+                        {
+                            IEditorPageDescriptor[] p = editor.getPageDescriptors();
+                            for (int l = 0; l < p.length; l++)
+                            {
+                                if (p[l].getPageId().equals(mandatoryLastPage.trim()))
+                                {
+                                    editor.setMandatoryLastPage(p[l]);
+                                }
+                            }
+                        }
+
+                        IConfigurationElement[] orders = elements[j]
+                                .getChildren(Constants.EXTENSION_POINT_EDITOR_DEFAULT_ORDER);
+                        if (orders != null && orders.length > 0)
+                        {
+                            IConfigurationElement[] orderItems = orders[0]
+                                    .getChildren(Constants.EXTENSION_POINT_EDITOR_ORDER_ITEM);
+                            for (int kk = 0; kk < orderItems.length; kk++)
+                            {
+                                String pId = orderItems[kk].getAttribute(Constants.EXTENSION_POINT_PAGE_ID);
+                                String orderNum = orderItems[kk]
+                                        .getAttribute(Constants.EXTENSION_POINT_EDITOR_ORDER_NUM);
+                                int order = -1;
+                                try
+                                {
+                                    order = Integer.parseInt(orderNum);
+                                    if (order < 1)
+                                    {
+                                        continue;
+                                    }
+                                }
+                                catch (Exception e)
+                                {
+                                    continue;
+                                }
+                                IEditorPageDescriptor page = getPageById(pages, pId);
+                                if (page != null)
+                                {
+                                    editor.getDefaultPagesOrder().put(page, new Integer(order));
+                                }
+                            }
+                        }
+                        _editors.add(editor);
+                    }
+                }
+            }
+        }
+    }
+
+    private IEditorPageDescriptor getPageById(List pages, String pId)
+    {
+        Iterator iter = pages.iterator();
+        while (iter.hasNext())
+        {
+            IEditorPageDescriptor page = (IEditorPageDescriptor) iter.next();
+            if (page.getPageId().equals(pId))
+            {
+                return page;
+            }
+        }
+        return null;
+    }
+
+    private IEditorPageDescriptor resolveReferencedPage(String editorId, String pageId, IExtension[] extensions,
+            IEditorDescriptor editor)
+    {
+        for (int i = 0; i < extensions.length; i++)
+        {
+            IConfigurationElement[] elements = extensions[i].getConfigurationElements();
+            for (int j = 0; j < elements.length; j++)
+            {
+                // is a standalone editor page
+                if (elements[j].getName().equals(Constants.EXTENSION_POINT_PAGE))
+                {
+                    // if the editor id is empty, it references a standalone
+                    // page
+                    if (editorId == null || editorId.trim().length() == 0)
+                    {
+                        String pId = elements[j].getAttribute(Constants.EXTENSION_POINT_PAGE_ID);
+                        if (pId.equals(pageId))
+                        {
+                            IEditorPageDescriptor page = readPage(elements[j], editor);
+                            return page;
+                        }
+                        else
+                        {
+                            continue;
+                        }
+                    }
+                    else
+                    {
+                        continue;
+                    }
+                }
+
+                // match the editor id
+                String eId = elements[j].getAttribute(Constants.EXTENSION_POINT_EDITOR_ID);
+                if (!eId.equals(editorId))
+                {
+                    continue;
+                }
+                IConfigurationElement[] pages = elements[j].getChildren(Constants.EXTENSION_POINT_PAGE);
+                for (int k = 0; k < pages.length; k++)
+                {
+                    // match the page id
+                    String pId = pages[k].getAttribute(Constants.EXTENSION_POINT_PAGE_ID);
+                    if (!pId.equals(pageId))
+                    {
+                        continue;
+                    }
+                    IEditorPageDescriptor page = readPage(pages[k], editor);
+                    return page;
+                }
+            }
+        }
+        return null;
+    }
+
+    private IEditorPageDescriptor readPage(IConfigurationElement element, IEditorDescriptor editor)
+    {
+        IEditorPageDescriptor page = null;
+        String pageId = element.getAttribute(Constants.EXTENSION_POINT_PAGE_ID);
+        String pageName = element.getAttribute(Constants.EXTENSION_POINT_PAGE_NAME);
+        String requiredStr = element.getAttribute(Constants.EXTENSION_POINT_PAGE_IS_REQUIRED);
+        String visibleByDefaultStr = element.getAttribute(Constants.EXTENSION_POINT_PAGE_VISIBLE_BYDEFAULT);
+        String contextHelpId = element.getAttribute(Constants.EXTENSION_POINT_PAGE_HELPID);
+        String objectClassType = element.getAttribute(Constants.EXTENSION_POINT_PAGE_OBJECT_CLASS_TYPE);
+
+        ISchemaObjectEditorPage pageClass = null;
+        try
+        {
+            pageClass = (ISchemaObjectEditorPage) element
+                    .createExecutableExtension(Constants.EXTENSION_POINT_PAGE_CLASS);
+            boolean isRequired = false;
+            if (requiredStr != null)
+            {
+                isRequired = requiredStr.equals("true");
+            }
+            boolean isVisibleByDefault = false;
+            if (visibleByDefaultStr != null)
+            {
+                isVisibleByDefault = visibleByDefaultStr.equals("true");
+            }
+            page = new EditorPageDescriptor(editor.getEditorId(), pageId, pageName, isRequired, isVisibleByDefault,
+                    pageClass, editor, element, null, contextHelpId, objectClassType);
+            return page;
+        }
+        catch (Exception e)
+        {
+            _logger.error("SchemaObjectEditorExtensionRegistryReader_error_reading_page", e);
+            return null;
+        }
+    }
+
+    private IEditorPageDescriptor[] resolveReferenceEditor(String editorId, IEditorDescriptor editor,
+            IExtension[] extensions, List excludes)
+    {
+        List selectedPages = new ArrayList();
+        for (int i = 0; i < extensions.length; i++)
+        {
+            IConfigurationElement[] elements = extensions[i].getConfigurationElements();
+            for (int j = 0; j < elements.length; j++)
+            {
+                // is a standalone editor page
+                if (elements[j].getName().equals(Constants.EXTENSION_POINT_PAGE))
+                {
+                    continue;
+                }
+
+                // match the editor id
+                String eId = elements[j].getAttribute(Constants.EXTENSION_POINT_EDITOR_ID);
+                if (!eId.equals(editorId))
+                {
+                    continue;
+                }
+                IConfigurationElement[] pages = elements[j].getChildren(Constants.EXTENSION_POINT_PAGE);
+                for (int k = 0; k < pages.length; k++)
+                {
+                    String pageId = pages[k].getAttribute(Constants.EXTENSION_POINT_PAGE_ID);
+                    if (excludes.contains(pageId))
+                    {
+                        continue;
+                    }
+                    IEditorPageDescriptor page = readPage(pages[k], editor);
+                    if (page != null)
+                    {
+                        selectedPages.add(page);
+                    }
+                }
+            }
+        }
+        return (IEditorPageDescriptor[]) selectedPages.toArray(new IEditorPageDescriptor[selectedPages.size()]);
+    }
+
+    private Image readImage(final Bundle bundle, final String iconLoc)
+    {
+        // CR:471496-1DBGR: Failed to load source when debugging last launch configuration (F11)
+        SOEUIPlugin.getActiveWorkbenchShell().getDisplay().syncExec(new Runnable()
+        {
+
+            public void run()
+            {
+                if (bundle == null || iconLoc == null || bundle.getEntry(iconLoc) == null)
+                {
+                    _image = null;
+                    return;
+                }
+                String key = bundle.getBundleId() + "_" + iconLoc;
+                Image img = Images.getImageRegistry().get(key);
+                if (img == null)
+                {
+                    try
+                    {
+                        ImageDescriptor desp = ImageDescriptor.createFromURL(bundle.getEntry(iconLoc));
+                        Images.getImageRegistry().put(key, desp);
+                    }
+                    catch (Exception ex)
+                    {
+                        _logger.error("SchemaObjectEditorExtensionsRegistryRead_error_read_image", ex);
+                        _image = null;
+                        return;
+                    }
+                }
+                _image = Images.getImageRegistry().get(key);
+            }
+        });
+        return _image;
+    }
+}
diff --git a/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/internal/core/EditorDescriptor.java b/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/internal/core/EditorDescriptor.java
new file mode 100644
index 0000000..17582d8
--- /dev/null
+++ b/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/internal/core/EditorDescriptor.java
@@ -0,0 +1,352 @@
+/***********************************************************************************************************************
+ * Copyright (c) 2009 Sybase, Inc. 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: Sybase, Inc. - initial API and implementation
+ **********************************************************************************************************************/
+package org.eclipse.datatools.sqltools.schemaobjecteditor.ui.internal.core;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.datatools.sqltools.schemaobjecteditor.ui.ISchemaObjectEditorActionBarContributor;
+import org.eclipse.datatools.sqltools.schemaobjecteditor.ui.ISchemaObjectEditorHandler;
+import org.eclipse.datatools.sqltools.schemaobjecteditor.ui.extensions.IEditorDescriptor;
+import org.eclipse.datatools.sqltools.schemaobjecteditor.ui.extensions.IEditorPageDescriptor;
+import org.eclipse.datatools.sqltools.schemaobjecteditor.ui.internal.SOEUIPlugin;
+import org.eclipse.datatools.sqltools.schemaobjecteditor.ui.internal.Constants;
+import org.eclipse.datatools.sqltools.schemaobjecteditor.ui.util.ILogger;
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.swt.graphics.Image;
+
+/**
+ * An instance of this class stands for a specific schema object editor, which contains some static information of this
+ * editor: name, icon, pages, etc.
+ * 
+ * @author Idull
+ */
+public class EditorDescriptor implements IEditorDescriptor
+{
+    private IConfigurationElement                   _configElement;
+
+    private ISchemaObjectEditorActionBarContributor _contributor;
+
+    private IConfigurationElement                   _contributorElement;
+
+    private Map                                     _defaultPagesOrder;
+
+    private String                                  _editorId;
+
+    private String                                  _editorName;
+
+    private ISchemaObjectEditorHandler              _handler;
+
+    private Image                                   _icon;
+
+    private boolean                                 _isVisibilityConfigurable;
+
+    private ILogger                                 _logger = SOEUIPlugin.getLogger(null);
+
+    private IEditorPageDescriptor                   _mandatoryFirstPage;
+
+    private IEditorPageDescriptor                   _mandatoryLastPage;
+
+    private String                                  _objectType;
+
+    private IEditorPageDescriptor[]                 _pages;
+
+    private IPreferenceStore                        _store;
+
+    private String                                  _vendorName;
+
+    private String                                  _version;
+
+    private String                                  _objTypeName;
+
+    private String                                  _pluginId;
+
+    public EditorDescriptor(String id, String name, String dbName, String dbVersion, String type, Image icon,
+            boolean genPreference)
+    {
+        this(id, name, dbName, dbVersion, type, icon, genPreference, null, null, null, null, null);
+    }
+
+    public EditorDescriptor(String id, String name, String dbName, String dbVersion, String type, Image icon,
+            boolean genPreference, IEditorPageDescriptor[] _pages, ISchemaObjectEditorHandler configuration,
+            ISchemaObjectEditorActionBarContributor contributor, IConfigurationElement configElement,
+            IConfigurationElement contributorElement)
+    {
+        super();
+        _defaultPagesOrder = new HashMap();
+        _editorId = id;
+        _editorName = name;
+        _vendorName = dbName;
+        _version = dbVersion;
+        _objectType = type;
+        _icon = icon;
+        _isVisibilityConfigurable = genPreference;
+        this._pages = _pages;
+        this._handler = configuration;
+        this._contributor = contributor;
+        _configElement = configElement;
+        _contributorElement = contributorElement;
+        _store = SOEUIPlugin.getDefault().getPreferenceStore();
+    }
+
+    public ISchemaObjectEditorActionBarContributor getActionContributor()
+    {
+
+        try
+        {
+            if (_contributor == null)
+            {
+                _contributor = (ISchemaObjectEditorActionBarContributor) _contributorElement
+                        .createExecutableExtension(Constants.EXTENSION_POINT_EDITOR_CONTRIBUTOR_CLASS);
+            }
+        }
+        catch (Exception e)
+        {
+        }
+        return _contributor;
+    }
+
+    public Map getDefaultPagesOrder()
+    {
+        return _defaultPagesOrder;
+    }
+
+    public IEditorPageDescriptor[] getDefaultSortedPages()
+    {
+        List sortedPages = new ArrayList();
+
+        HashMap orders = (HashMap) getDefaultPagesOrder();
+
+        HashMap clonedOrder = (HashMap) orders.clone();
+        IEditorPageDescriptor ePage = getNextPage(clonedOrder);
+        while (ePage != null)
+        {
+            sortedPages.add(ePage);
+            ePage = getNextPage(clonedOrder);
+        }
+
+        for (int i = 0; i < _pages.length; i++)
+        {
+            if (!getDefaultPagesOrder().keySet().contains(_pages[i]))
+            {
+                sortedPages.add(_pages[i]);
+            }
+        }
+
+        return (IEditorPageDescriptor[]) sortedPages.toArray(new IEditorPageDescriptor[sortedPages.size()]);
+    }
+
+    public String getEditorId()
+    {
+        return _editorId;
+    }
+
+    public String getEditorName()
+    {
+        return _editorName;
+    }
+
+    public ISchemaObjectEditorHandler getHandler()
+    {
+        ISchemaObjectEditorHandler config = _handler;
+        try
+        {
+            _handler = (ISchemaObjectEditorHandler) _configElement
+                    .createExecutableExtension(Constants.EXTENSION_POINT_EDITOR_HANDLER);
+        }
+        catch (Exception e)
+        {
+            _logger.error("ExtendedEditor_error_create_handler", e);
+        }
+        return config;
+    }
+
+    public Image getIcon()
+    {
+        return _icon;
+    }
+
+    public IEditorPageDescriptor getMandatoryFirstPage()
+    {
+        return _mandatoryFirstPage;
+    }
+
+    public IEditorPageDescriptor getMandatoryLastPage()
+    {
+        return _mandatoryLastPage;
+    }
+
+    /**
+     * Returns the next page given the orders of pages. The order number can be 0 or greater than 0. If it's 0, that
+     * means it's unordered
+     * 
+     * @param orders
+     * @return the next page with the minumum order number (greater than 0)
+     */
+    private IEditorPageDescriptor getNextPage(Map orders)
+    {
+        if (orders != null && orders.size() > 0)
+        {
+            IEditorPageDescriptor page = null;
+            IEditorPageDescriptor firstPage = null;
+            int minNumber = -1;
+            Iterator iter = orders.keySet().iterator();
+            if (iter.hasNext())
+            {
+                firstPage = (IEditorPageDescriptor) iter.next();
+                int number = ((Integer) orders.get(firstPage)).intValue();
+                if (number > 0)
+                {
+                    minNumber = number;
+                    page = firstPage;
+                }
+            }
+
+            while (iter.hasNext())
+            {
+                IEditorPageDescriptor tmp = (IEditorPageDescriptor) iter.next();
+                int number = ((Integer) orders.get(tmp)).intValue();
+                if (number > 0 && (number < minNumber || minNumber == -1))
+                {
+                    minNumber = number;
+                    page = tmp;
+                }
+            }
+            if (page != null)
+            {
+                orders.remove(page);
+            }
+            else
+            {
+                // all pages are unsorted, return the first one
+                orders.remove(firstPage);
+                return firstPage;
+            }
+            return page;
+        }
+        return null;
+    }
+
+    public IEditorPageDescriptor[] getPageDescriptors()
+    {
+        return _pages;
+    }
+
+    public String getSchemaObjectType()
+    {
+        return _objectType;
+    }
+
+    public IEditorPageDescriptor[] getSortedPages()
+    {
+        IEditorPageDescriptor[] pages = getPageDescriptors();
+        List sortedPages = new ArrayList();
+
+        HashMap orders = new HashMap();
+        for (int i = 0; i < pages.length; i++)
+        {
+            String key = Constants.EDITOR_PAGE_ORDER + pages[i].getEditorId() + pages[i].getPageId();
+            int orderNum = _store.getInt(key);
+            orders.put(pages[i], new Integer(orderNum));
+        }
+
+        IEditorPageDescriptor ePage = getNextPage(orders);
+        while (ePage != null)
+        {
+            sortedPages.add(ePage);
+            ePage = getNextPage(orders);
+        }
+
+        return (IEditorPageDescriptor[]) sortedPages.toArray(new IEditorPageDescriptor[sortedPages.size()]);
+    }
+
+    public String getVendorName()
+    {
+        return _vendorName;
+    }
+
+    public String getVersion()
+    {
+        return _version;
+    }
+
+    public IEditorPageDescriptor[] getVisibleSortedPages()
+    {
+        return null;
+    }
+
+    public IEditorPageDescriptor[] getVisibleSortedPagesDefault()
+    {
+        return null;
+    }
+
+    public boolean isVisibilityConfigurable()
+    {
+        return _isVisibilityConfigurable;
+    }
+
+    public void setActionContributor(ISchemaObjectEditorActionBarContributor contributor)
+    {
+        this._contributor = contributor;
+
+    }
+
+    public void setConfigElement(IConfigurationElement element)
+    {
+        _configElement = element;
+    }
+
+    public void setContributorElement(IConfigurationElement element)
+    {
+        _contributorElement = element;
+    }
+
+    public void setHandler(ISchemaObjectEditorHandler handler)
+    {
+        this._handler = handler;
+    }
+
+    public void setMandatoryFirstPage(IEditorPageDescriptor mandatoryFirstPage)
+    {
+        _mandatoryFirstPage = mandatoryFirstPage;
+    }
+
+    public void setMandatoryLastPage(IEditorPageDescriptor mandatoryLastPage)
+    {
+        _mandatoryLastPage = mandatoryLastPage;
+    }
+
+    public void setPageDescriptors(IEditorPageDescriptor[] pages)
+    {
+        _pages = pages;
+    }
+
+    public String getObjectTypeName()
+    {
+        return _objTypeName == null ? "" : _objTypeName;
+    }
+
+    public void setObjectTypeName(String objTypeName)
+    {
+        _objTypeName = objTypeName;
+    }
+
+    public String getPluginId()
+    {
+        return _pluginId;
+    }
+
+    public void setPluginId(String pluginId)
+    {
+        _pluginId = pluginId;
+    }
+}
diff --git a/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/internal/core/EditorPageDescriptor.java b/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/internal/core/EditorPageDescriptor.java
new file mode 100644
index 0000000..5d313b4
--- /dev/null
+++ b/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/internal/core/EditorPageDescriptor.java
@@ -0,0 +1,141 @@
+/***********************************************************************************************************************
+ * Copyright (c) 2009 Sybase, Inc. 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: Sybase, Inc. - initial API and implementation
+ **********************************************************************************************************************/
+package org.eclipse.datatools.sqltools.schemaobjecteditor.ui.internal.core;
+
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.datatools.sqltools.schemaobjecteditor.ui.ISchemaObjectEditorPage;
+import org.eclipse.datatools.sqltools.schemaobjecteditor.ui.extensions.IEditorDescriptor;
+import org.eclipse.datatools.sqltools.schemaobjecteditor.ui.extensions.IEditorPageDescriptor;
+import org.eclipse.datatools.sqltools.schemaobjecteditor.ui.internal.SOEUIPlugin;
+import org.eclipse.datatools.sqltools.schemaobjecteditor.ui.internal.Constants;
+import org.eclipse.datatools.sqltools.schemaobjecteditor.ui.util.ILogger;
+import org.eclipse.jface.preference.IPreferenceStore;
+
+/**
+ * An instance of this class describe some static information of a page in a specific schema object editor.
+ * 
+ * @author Idull
+ */
+public class EditorPageDescriptor implements IEditorPageDescriptor
+{
+    private String                  _contextHelpId;
+    private IEditorDescriptor       _editor;
+    private String                  _editorId;
+    private ILogger                 _logger = SOEUIPlugin.getLogger(null);
+    private boolean                 _mustBeShown;
+    private ISchemaObjectEditorPage _page;
+    private IConfigurationElement   _pageClassElement;
+    private String                  _pageExtensionId;
+    private String                  _pageId;
+    private String                  _pageName;
+    private boolean                 _showByDefault;
+    private String                  _objectClassType;
+
+    public EditorPageDescriptor(String editorId, String pageId, String pageName, boolean beShown,
+            boolean showByDefault, ISchemaObjectEditorPage page, IEditorDescriptor editor,
+            IConfigurationElement pageClassElement, String pageExtensionId, String contextHelpId, String objectClassType)
+    {
+        super();
+        _editorId = editorId;
+        _pageId = pageId;
+        _pageName = pageName;
+        _mustBeShown = beShown;
+        _showByDefault = showByDefault;
+        _page = page;
+        _editor = editor;
+        _pageClassElement = pageClassElement;
+        _pageExtensionId = pageExtensionId;
+        _contextHelpId = contextHelpId;
+        _objectClassType = objectClassType;
+    }
+
+    public String getContextHelpId()
+    {
+        return _contextHelpId;
+    }
+
+    public IEditorDescriptor getEditor()
+    {
+        return _editor;
+    }
+
+    public String getEditorId()
+    {
+        return _editorId;
+    }
+
+    public ISchemaObjectEditorPage getPageClass()
+    {
+        ISchemaObjectEditorPage page = _page;
+        try
+        {
+            _page = (ISchemaObjectEditorPage) _pageClassElement
+                    .createExecutableExtension(Constants.EXTENSION_POINT_PAGE_CLASS);
+        }
+        catch (Exception e)
+        {
+            _logger.error("EditorPage_error_create_class", e);
+        }
+        return page;
+    }
+
+    public String getPageExtensionId()
+    {
+        return _pageExtensionId;
+    }
+
+    public String getPageId()
+    {
+        return _pageId;
+    }
+
+    public String getPageName()
+    {
+        return _pageName;
+    }
+
+    public boolean isRequired()
+    {
+        return _mustBeShown;
+    }
+
+    public boolean isSelectedToShow()
+    {
+        // show all pages if no preference group generated
+        if (_mustBeShown || !_editor.isVisibilityConfigurable())
+        {
+            return true;
+        }
+        IPreferenceStore store = SOEUIPlugin.getDefault().getPreferenceStore();
+        String preferenceName = Constants.EDITOR_PAGE_VISIABILITY + getEditorId() + getPageId();
+        return store.getBoolean(preferenceName);
+    }
+
+    public boolean isVisibleByDefault()
+    {
+        return _showByDefault;
+    }
+
+    public void setPageExtensionId(String pageExtensionId)
+    {
+        this._pageExtensionId = pageExtensionId;
+    }
+
+    public String getObjectClassType()
+    {
+        return _objectClassType;
+    }
+
+    public boolean isVisible()
+    {
+        IPreferenceStore store = SOEUIPlugin.getDefault().getPreferenceStore();
+        String key = Constants.EDITOR_PAGE_VISIABILITY + getEditorId() + getPageId();
+        return store.getBoolean(key);
+    }
+
+}
diff --git a/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/internal/core/ErrorPage.java b/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/internal/core/ErrorPage.java
new file mode 100644
index 0000000..e9c8ea3
--- /dev/null
+++ b/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/internal/core/ErrorPage.java
@@ -0,0 +1,73 @@
+/***********************************************************************************************************************
+ * Copyright (c) 2009 Sybase, Inc. 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: Sybase, Inc. - initial API and implementation
+ **********************************************************************************************************************/
+package org.eclipse.datatools.sqltools.schemaobjecteditor.ui.internal.core;
+
+import org.eclipse.datatools.sqltools.schemaobjecteditor.ui.common.CollapseableSection;
+import org.eclipse.datatools.sqltools.schemaobjecteditor.ui.core.Messages;
+import org.eclipse.datatools.sqltools.schemaobjecteditor.ui.core.SchemaObjectEditorPage;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Layout;
+import org.eclipse.ui.forms.IManagedForm;
+import org.eclipse.ui.forms.widgets.FormText;
+import org.eclipse.ui.forms.widgets.FormToolkit;
+import org.eclipse.ui.forms.widgets.TableWrapData;
+import org.eclipse.ui.forms.widgets.TableWrapLayout;
+
+/**
+ * A page internally used to display some information to the end-user
+ * 
+ * @author Idull
+ */
+public class ErrorPage extends SchemaObjectEditorPage
+{
+
+    private String _errorMsg;
+
+    public ErrorPage(String msg)
+    {
+        _errorMsg = msg == null ? "" : msg;
+    }
+
+    protected void createFormContent(IManagedForm managedForm)
+    {
+        super.createFormContent(managedForm);
+        managedForm.getForm().setText(Messages.ErrorPage_error_msg);
+        Composite comp = managedForm.getForm().getBody();
+        Layout layout = new GridLayout();
+        comp.setLayout(layout);
+
+        Composite container = managedForm.getToolkit().createComposite(comp);
+        layout = new GridLayout();
+        container.setLayout(layout);
+        GridData gd = new GridData(GridData.FILL_BOTH);
+        container.setLayoutData(gd);
+
+        CollapseableSection errorSection = new CollapseableSection(getEditor().getToolkit(), Messages.ErrorPage_error,
+                container.getDisplay(), SWT.NONE)
+        {
+            public void createSectionContent(Composite parent)
+            {
+                getSection().setLayoutData(new GridData(GridData.FILL_BOTH));
+                getSection().setLayout(new TableWrapLayout());
+
+                parent.setLayoutData(new TableWrapData(TableWrapData.FILL_GRAB));
+                FormToolkit toolkit = getEditor().getToolkit();
+                TableWrapLayout layout = new TableWrapLayout();
+                layout.makeColumnsEqualWidth = false;
+                parent.setLayout(layout);
+
+                FormText text = toolkit.createFormText(parent, false);
+                text.setText(_errorMsg, false, false);
+            }
+        };
+        errorSection.createControl(container, 1, null);
+    }
+}
diff --git a/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/internal/core/Messages.java b/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/internal/core/Messages.java
new file mode 100644
index 0000000..ec5be1b
--- /dev/null
+++ b/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/internal/core/Messages.java
@@ -0,0 +1,21 @@
+/***********************************************************************************************************************
+ * Copyright (c) 2009 Sybase, Inc. 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: Sybase, Inc. - initial API and implementation
+ **********************************************************************************************************************/
+package org.eclipse.datatools.sqltools.schemaobjecteditor.ui.internal.core;
+
+import org.eclipse.osgi.util.NLS;
+
+public class Messages extends NLS
+{
+    private static final String BUNDLE_NAME = Messages.class.getPackage().getName() + ".messages";
+    static
+    {
+        NLS.initializeMessages(BUNDLE_NAME, Messages.class);
+    }
+    public static String        SchemaObjectEditorActionBarContributor_refresh_from_server;
+    public static String        SchemaObjectEditorActionBarContributor_revert;
+}
diff --git a/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/internal/core/SchemaObjectEditorActionBarContributor.java b/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/internal/core/SchemaObjectEditorActionBarContributor.java
new file mode 100644
index 0000000..9ed7184
--- /dev/null
+++ b/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/internal/core/SchemaObjectEditorActionBarContributor.java
@@ -0,0 +1,169 @@
+/***********************************************************************************************************************
+ * Copyright (c) 2009 Sybase, Inc. 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: Sybase, Inc. - initial API and implementation
+ **********************************************************************************************************************/
+package org.eclipse.datatools.sqltools.schemaobjecteditor.ui.internal.core;
+
+import org.eclipse.datatools.sqltools.schemaobjecteditor.ui.ISchemaObjectEditor;
+import org.eclipse.datatools.sqltools.schemaobjecteditor.ui.ISchemaObjectEditorActionBarContributor;
+import org.eclipse.datatools.sqltools.schemaobjecteditor.ui.action.RefreshSchemaEditorAction;
+import org.eclipse.datatools.sqltools.schemaobjecteditor.ui.action.RevertSchemaEditorAction;
+import org.eclipse.datatools.sqltools.schemaobjecteditor.ui.core.Constants;
+import org.eclipse.datatools.sqltools.schemaobjecteditor.ui.extensions.IEditorDescriptor;
+import org.eclipse.datatools.sqltools.schemaobjecteditor.ui.util.Images;
+import org.eclipse.jface.action.ICoolBarManager;
+import org.eclipse.jface.action.IMenuManager;
+import org.eclipse.jface.action.IStatusLineManager;
+import org.eclipse.jface.action.IToolBarManager;
+import org.eclipse.ui.IEditorPart;
+import org.eclipse.ui.actions.RetargetAction;
+import org.eclipse.ui.part.MultiPageEditorActionBarContributor;
+
+/**
+ * The action bar contributor
+ * 
+ * @author Idull
+ */
+public class SchemaObjectEditorActionBarContributor extends MultiPageEditorActionBarContributor
+{
+    ISchemaObjectEditor                     _editor;
+    IEditorDescriptor                       _exEditor;
+    ISchemaObjectEditorActionBarContributor _contributor;
+
+    IToolBarManager                         _toolManager;
+    ICoolBarManager                         _coolManager;
+    IMenuManager                            _menuManager;
+    IStatusLineManager                      _statusManager;
+    RetargetAction                          _refreshEditorRetargetAction;
+    RetargetAction                          _revertEditorRetargetAction;
+
+    RefreshSchemaEditorAction               _refreshEditorAction;
+    RevertSchemaEditorAction                _revertEditorAction;
+
+    public SchemaObjectEditorActionBarContributor()
+    {
+        _refreshEditorRetargetAction = new RetargetAction(Constants.REFRESH_EDITOR_ACTION_ID,
+                Messages.SchemaObjectEditorActionBarContributor_refresh_from_server);
+        _refreshEditorRetargetAction.setActionDefinitionId(Constants.REFRESH_EDITOR_ACTION_ID);
+        _refreshEditorRetargetAction.setImageDescriptor(Images.DESC_REFRESH);
+
+        _revertEditorRetargetAction = new RetargetAction(Constants.REVERT_EDITOR_ACTION_ID,
+                Messages.SchemaObjectEditorActionBarContributor_revert);
+        _revertEditorRetargetAction.setActionDefinitionId(Constants.REVERT_EDITOR_ACTION_ID);
+        _revertEditorRetargetAction.setImageDescriptor(Images.DESC_REVERT);
+    }
+
+    protected void createRetargetActions()
+    {
+
+    }
+
+    public void contributeToCoolBar(ICoolBarManager coolBarManager)
+    {
+        super.contributeToCoolBar(coolBarManager);
+        _coolManager = coolBarManager;
+    }
+
+    public void contributeToMenu(IMenuManager menuManager)
+    {
+        super.contributeToMenu(menuManager);
+        _menuManager = menuManager;
+    }
+
+    public void contributeToStatusLine(IStatusLineManager statusLineManager)
+    {
+        super.contributeToStatusLine(statusLineManager);
+        _statusManager = statusLineManager;
+    }
+
+    public void contributeToToolBar(IToolBarManager toolBarManager)
+    {
+        super.contributeToToolBar(toolBarManager);
+        _toolManager = toolBarManager;
+    }
+
+    public void setActiveEditor(IEditorPart targetEditor)
+    {
+        _toolManager.removeAll();
+        _coolManager.removeAll();
+        _menuManager.removeAll();
+        _statusManager.removeAll();
+        if (targetEditor instanceof ISchemaObjectEditor)
+        {
+            ISchemaObjectEditor editor = (ISchemaObjectEditor) targetEditor;
+            setEditor(editor);
+
+            _toolManager.add(_refreshEditorRetargetAction);
+            _toolManager.add(_revertEditorRetargetAction);
+
+            // Add the default actions for all editors
+            _refreshEditorAction = new RefreshSchemaEditorAction();
+            _refreshEditorAction.setEditor(editor);
+            targetEditor.getEditorSite().getActionBars().setGlobalActionHandler(Constants.REFRESH_EDITOR_ACTION_ID,
+                    _refreshEditorAction);
+            _refreshEditorRetargetAction.partActivated(targetEditor);
+
+            _revertEditorAction = new RevertSchemaEditorAction();
+            _revertEditorAction.setEnabled(editor.isDirty());
+            editor.addPropertyListener(_revertEditorAction);
+            _revertEditorAction.setEditor(editor);
+            targetEditor.getEditorSite().getActionBars().setGlobalActionHandler(Constants.REVERT_EDITOR_ACTION_ID,
+                    _revertEditorAction);
+            _revertEditorRetargetAction.partActivated(targetEditor);
+
+            targetEditor.getEditorSite().getActionBars().updateActionBars();
+            _exEditor = editor.getEditorDescriptor();
+            if (_exEditor != null)
+            {
+                _contributor = _exEditor.getActionContributor();
+            }
+
+            if (_exEditor != null && _contributor != null)
+            {
+                // can do _contributor.init in this.init because _exEditor was null
+                if (_contributor.getActionBars() == null)
+                {
+                    _contributor.init(this.getActionBars(), this.getPage());
+                    _contributor.setEditor(_editor);
+                }
+                else
+                {
+                    _contributor.setEditor(_editor);
+                    _contributor.contributeToMenu(_menuManager);
+                    _contributor.contributeToCoolBar(_coolManager);
+                    _contributor.contributeToToolBar(_toolManager);
+                    _contributor.contributeToStatusLine(_statusManager);
+                }
+            }
+        }
+        _toolManager.update(true);
+        _menuManager.update(true);
+        // Set wrapped EditorMenuManagers contained in _menuManager visible
+        _menuManager.setVisible(true);
+        _coolManager.update(true);
+        _statusManager.update(true);
+        super.setActiveEditor(targetEditor);
+    }
+
+    public ISchemaObjectEditor getEditor()
+    {
+        return _editor;
+    }
+
+    public void setEditor(ISchemaObjectEditor editor)
+    {
+        _editor = editor;
+    }
+
+    public void setActivePage(IEditorPart activeEditor)
+    {
+        if (_exEditor != null && _exEditor.getActionContributor() != null)
+        {
+            _exEditor.getActionContributor().setActivePage(activeEditor);
+        }
+    }
+
+}
diff --git a/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/internal/core/ScriptsExecutionRunnable.java b/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/internal/core/ScriptsExecutionRunnable.java
new file mode 100644
index 0000000..fe8e634
--- /dev/null
+++ b/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/internal/core/ScriptsExecutionRunnable.java
@@ -0,0 +1,135 @@
+/***********************************************************************************************************************
+ * Copyright (c) 2009 Sybase, Inc. 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: Sybase, Inc. - initial API and implementation
+ **********************************************************************************************************************/
+package org.eclipse.datatools.sqltools.schemaobjecteditor.ui.internal.core;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.jobs.IJobChangeEvent;
+import org.eclipse.core.runtime.jobs.IJobChangeListener;
+import org.eclipse.datatools.sqltools.core.DatabaseIdentifier;
+import org.eclipse.datatools.sqltools.core.SQLDevToolsConfiguration;
+import org.eclipse.datatools.sqltools.core.SQLToolsFacade;
+import org.eclipse.datatools.sqltools.core.services.SQLService;
+import org.eclipse.datatools.sqltools.schemaobjecteditor.ui.internal.SOEUIPlugin;
+import org.eclipse.datatools.sqltools.schemaobjecteditor.ui.util.ILogger;
+import org.eclipse.datatools.sqltools.sqleditor.result.GroupSQLResultRunnable;
+
+/**
+ * Execute the generated scripts in the schema object editor
+ * 
+ * @author Idull
+ */
+public class ScriptsExecutionRunnable implements Runnable
+{
+    private String             _scripts;
+    private DatabaseIdentifier _databaseIdentifier;
+    private ILogger            _log                     = SOEUIPlugin.getLogger(null);
+    private IJobChangeListener _jobListener;
+    private boolean            _syncExec;
+    private IProgressMonitor   _monitor;
+    private String             _groupExecutionDspString = "Group execution";
+    private String             _consumerName            = "Schema object editor";
+
+    public ScriptsExecutionRunnable(String scripts, DatabaseIdentifier databaseIdentifier, IJobChangeListener listener,
+            boolean syncExec, IProgressMonitor monitor)
+    {
+        _scripts = scripts;
+        _databaseIdentifier = databaseIdentifier;
+        _jobListener = listener;
+        _syncExec = syncExec;
+        _monitor = monitor;
+    }
+
+    public ScriptsExecutionRunnable(String scripts, DatabaseIdentifier databaseIdentifier, IJobChangeListener listener,
+            boolean syncExec, IProgressMonitor monitor, String groupExecutionDspString, String consumerName)
+    {
+        _scripts = scripts;
+        _databaseIdentifier = databaseIdentifier;
+        _jobListener = listener;
+        _syncExec = syncExec;
+        _monitor = monitor;
+        _groupExecutionDspString = groupExecutionDspString;
+        _consumerName = consumerName;
+    }
+
+    public void run()
+    {
+        try
+        {
+            SQLDevToolsConfiguration f = SQLToolsFacade.getConfigurationByProfileName(_databaseIdentifier
+                    .getProfileName());
+
+            String[] groups = new String[]
+            {
+                _scripts
+            };
+            SQLService sqlService = f.getSQLService();
+            if (sqlService != null)
+            {
+                groups = sqlService.splitSQL(_scripts);
+            }
+            GroupSQLResultRunnable job = new GroupSQLResultRunnable(null, groups, null, null, _databaseIdentifier,
+                    false, null, _groupExecutionDspString, _consumerName);
+            if (_jobListener != null)
+            {
+                job.addJobChangeListener(_jobListener);
+            }
+            job.addJobChangeListener(new IJobChangeListener()
+            {
+                public void aboutToRun(IJobChangeEvent event)
+                {
+
+                }
+
+                public void awake(IJobChangeEvent event)
+                {
+
+                }
+
+                public void done(final IJobChangeEvent event)
+                {
+                    SOEUIPlugin.getActiveWorkbenchShell().getDisplay().syncExec(new Runnable()
+                    {
+                        public void run()
+                        {
+                            if (!event.getResult().isOK())
+                            {
+                                _monitor.setCanceled(true);
+                            }
+                        }
+                    });
+                }
+
+                public void running(IJobChangeEvent event)
+                {
+
+                }
+
+                public void scheduled(IJobChangeEvent event)
+                {
+
+                }
+
+                public void sleeping(IJobChangeEvent event)
+                {
+
+                }
+            });
+            job.setUser(true);
+            job.schedule();
+            if (_syncExec)
+            {
+                job.join();
+            }
+        }
+        catch (Exception ex)
+        {
+            _log.error("ScriptsExecutionRunnable_error_execution", ex);
+        }
+
+    }
+}
diff --git a/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/internal/core/messages.properties b/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/internal/core/messages.properties
new file mode 100644
index 0000000..18e5b72
--- /dev/null
+++ b/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/internal/core/messages.properties
@@ -0,0 +1,2 @@
+SchemaObjectEditorActionBarContributor_refresh_from_server=Refresh from Server
+SchemaObjectEditorActionBarContributor_revert=Revert Object
diff --git a/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/internal/messages.properties b/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/internal/messages.properties
new file mode 100644
index 0000000..e9b677e
--- /dev/null
+++ b/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/internal/messages.properties
@@ -0,0 +1,4 @@
+SchemaEditorsHandler_dirty_editor=Dirty Editor
+SchemaEditorsHandler_save_disconnect=Save and Disconnect
+SchemaEditorsHandler_dirty_editor_found=There are dirty schema object editors opened
+SchemaEditorsHandler_select_to_save=Select editors to save:
\ No newline at end of file
diff --git a/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/internal/preference/Messages.java b/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/internal/preference/Messages.java
new file mode 100644
index 0000000..ead1bbe
--- /dev/null
+++ b/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/internal/preference/Messages.java
@@ -0,0 +1,48 @@
+/***********************************************************************************************************************
+ * Copyright (c) 2009 Sybase, Inc. 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: Sybase, Inc. - initial API and implementation
+ **********************************************************************************************************************/
+package org.eclipse.datatools.sqltools.schemaobjecteditor.ui.internal.preference;
+
+import org.eclipse.osgi.util.NLS;
+
+public class Messages extends NLS
+{
+    private static final String BUNDLE_NAME = Messages.class.getPackage().getName() + ".messages";
+    static
+    {
+        NLS.initializeMessages(BUNDLE_NAME, Messages.class);
+    }
+    public static String        SchemaObjectEditorPreferencePage_add;
+    public static String        SchemaObjectEditorPreferencePage_add_all;
+    public static String        SchemaObjectEditorPreferencePage_always_show_preview;
+    public static String        SchemaObjectEditorPreferencePage_available_editors;
+    public static String        SchemaObjectEditorPreferencePage_available_pages;
+    public static String        SchemaObjectEditorPreferencePage_can_not_down;
+    public static String        SchemaObjectEditorPreferencePage_can_not_remove;
+    public static String        SchemaObjectEditorPreferencePage_can_not_up;
+    public static String        SchemaObjectEditorPreferencePage_databaseType;
+    public static String        SchemaObjectEditorPreferencePage_editors;
+    public static String        SchemaObjectEditorPreferencePage_erroe;
+    public static String        SchemaObjectEditorPreferencePage_error;
+    public static String        SchemaObjectEditorPreferencePage_latest_version_open_tooltip;
+    public static String        SchemaObjectEditorPreferencePage_move_down;
+    public static String        SchemaObjectEditorPreferencePage_move_up;
+    public static String        SchemaObjectEditorPreferencePage_must_be_first;
+    public static String        SchemaObjectEditorPreferencePage_must_be_last;
+    public static String        SchemaObjectEditorPreferencePage_no_page;
+    public static String        SchemaObjectEditorPreferencePage_pagesSetting;
+    public static String        SchemaObjectEditorPreferencePage_question;
+    public static String        SchemaObjectEditorPreferencePage_remove;
+    public static String        SchemaObjectEditorPreferencePage_remove_all;
+    public static String        SchemaObjectEditorPreferencePage_save_modification;
+    public static String        SchemaObjectEditorPreferencePage_selected_pages;
+    public static String        SchemaObjectEditorPreferencePage_use_latest_version_to_open;
+    public static String        SchemaObjectEditorPreferencePage_check_existence_when_activated;
+    public static String        SchemaObjectEditorPreferencePage_check_existence_when_activated_tooltip;
+    public static String        SchemaObjectEditorPreferencePage_open_file_after_saveas;
+    public static String        SchemaObjectEditorPreferencePage_open_file_after_saveas_tooltip;
+}
diff --git a/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/internal/preference/SchemaObjectEditorPreferenceInitializer.java b/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/internal/preference/SchemaObjectEditorPreferenceInitializer.java
new file mode 100644
index 0000000..cfbd8d5
--- /dev/null
+++ b/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/internal/preference/SchemaObjectEditorPreferenceInitializer.java
@@ -0,0 +1,67 @@
+/***********************************************************************************************************************
+ * Copyright (c) 2009 Sybase, Inc. 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: Sybase, Inc. - initial API and implementation
+ **********************************************************************************************************************/
+package org.eclipse.datatools.sqltools.schemaobjecteditor.ui.internal.preference;
+
+import org.eclipse.core.runtime.preferences.AbstractPreferenceInitializer;
+import org.eclipse.datatools.sqltools.schemaobjecteditor.ui.extensions.IEditorDescriptor;
+import org.eclipse.datatools.sqltools.schemaobjecteditor.ui.extensions.IEditorPageDescriptor;
+import org.eclipse.datatools.sqltools.schemaobjecteditor.ui.internal.SOEUIPlugin;
+import org.eclipse.datatools.sqltools.schemaobjecteditor.ui.internal.Constants;
+import org.eclipse.datatools.sqltools.schemaobjecteditor.ui.internal.ISchemaObjectEditorExtensionsRegistryReader;
+import org.eclipse.datatools.sqltools.schemaobjecteditor.ui.internal.SchemaObjectEditorExtensionsRegistryReader;
+import org.eclipse.jface.preference.IPreferenceStore;
+
+/**
+ * The preference initializer for schema object editors
+ * 
+ * @author Idull
+ */
+public class SchemaObjectEditorPreferenceInitializer extends AbstractPreferenceInitializer
+{
+
+    public SchemaObjectEditorPreferenceInitializer()
+    {
+
+    }
+
+    public void initializeDefaultPreferences()
+    {
+        IPreferenceStore store = SOEUIPlugin.getDefault().getPreferenceStore();
+        store.setDefault(Constants.PREFERENCE_ALWAYS_SHOW_PREVIEW, true);
+        store.setDefault(Constants.PREFERENCE_USE_LATEST_VERSION, true);
+        store.setDefault(Constants.PREFERENCE_CHECK_EXISTENCE, false);
+        store.setDefault(Constants.PREFERENCE_OPEN_FILE_AFTER_SAVEAS, true);
+
+        ISchemaObjectEditorExtensionsRegistryReader reader = SchemaObjectEditorExtensionsRegistryReader.getInstance();
+        IEditorDescriptor[] editors = reader.getEditorDescriptors();
+
+        if (editors != null)
+        {
+            for (int i = 0; i < editors.length; i++)
+            {
+                IEditorPageDescriptor[] pages = editors[i].getPageDescriptors();
+                for (int j = 0; j < pages.length; j++)
+                {
+                    String prefName = Constants.EDITOR_PAGE_VISIABILITY + editors[i].getEditorId()
+                            + pages[j].getPageId();
+                    store.setDefault(prefName, pages[j].isVisibleByDefault() || pages[j].isRequired()
+                            || !pages[j].getEditor().isVisibilityConfigurable());
+
+                    Integer order = (Integer) editors[i].getDefaultPagesOrder().get(pages[j]);
+                    if (order != null)
+                    {
+                        String orderPrefName = Constants.EDITOR_PAGE_ORDER + pages[j].getEditorId()
+                                + pages[j].getPageId();
+                        store.setDefault(orderPrefName, order.intValue());
+                    }
+                }
+            }
+        }
+    }
+
+}
diff --git a/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/internal/preference/SchemaObjectEditorPreferencePage.java b/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/internal/preference/SchemaObjectEditorPreferencePage.java
new file mode 100644
index 0000000..4696b47
--- /dev/null
+++ b/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/internal/preference/SchemaObjectEditorPreferencePage.java
@@ -0,0 +1,1043 @@
+/***********************************************************************************************************************
+ * Copyright (c) 2009 Sybase, Inc. 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: Sybase, Inc. - initial API and implementation
+ **********************************************************************************************************************/
+package org.eclipse.datatools.sqltools.schemaobjecteditor.ui.internal.preference;
+
+import java.text.Collator;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.Iterator;
+import java.util.Locale;
+import java.util.Map;
+
+import org.eclipse.datatools.sqltools.schemaobjecteditor.ui.extensions.IEditorDescriptor;
+import org.eclipse.datatools.sqltools.schemaobjecteditor.ui.extensions.IEditorPageDescriptor;
+import org.eclipse.datatools.sqltools.schemaobjecteditor.ui.internal.SOEUIPlugin;
+import org.eclipse.datatools.sqltools.schemaobjecteditor.ui.internal.Constants;
+import org.eclipse.datatools.sqltools.schemaobjecteditor.ui.util.SchemaObjectEditorUtils;
+import org.eclipse.jface.dialogs.DialogPage;
+import org.eclipse.jface.dialogs.IDialogConstants;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.jface.preference.PreferencePage;
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Combo;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Event;
+import org.eclipse.swt.widgets.Group;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.List;
+import org.eclipse.ui.IWorkbench;
+import org.eclipse.ui.IWorkbenchPreferencePage;
+
+/**
+ * The preference page to set the visibility and order of pages for editors.
+ * 
+ * @author Idull
+ */
+public class SchemaObjectEditorPreferencePage extends PreferencePage implements IWorkbenchPreferencePage
+{
+    IPreferenceStore _store       = SOEUIPlugin.getDefault().getPreferenceStore();
+    Composite        _parent;
+    Combo            _dbType;
+    Combo            _editorName;
+    List             _displayedPages;
+    List             _hiddenPages;
+    Button           _rightOne;
+    Button           _rightAll;
+    Button           _leftOne;
+    Button           _leftAll;
+    Button           _upMove;
+    Button           _downMove;
+    Button           _alwaysShowPreview;
+    Button           _promptIfNoExactEditorFound;
+    Button           _checkWhenActivated;
+    Button           _openFileAfterSaveas;
+
+    boolean          _dirty;
+    static final int BUTTON_WIDTH = 80;
+
+    public SchemaObjectEditorPreferencePage()
+    {
+    }
+
+    public SchemaObjectEditorPreferencePage(String title)
+    {
+        super(title);
+    }
+
+    public SchemaObjectEditorPreferencePage(String title, ImageDescriptor image)
+    {
+        super(title, image);
+    }
+
+    protected Control createContents(Composite parent)
+    {
+        _parent = parent;
+        GridLayout layout = new GridLayout();
+        parent.setLayout(layout);
+
+        Composite container = new Composite(parent, SWT.NONE);
+        layout = new GridLayout();
+        container.setLayout(layout);
+        GridData gd = new GridData(GridData.FILL_BOTH);
+        container.setLayoutData(gd);
+
+        Group editorsComp = new Group(container, SWT.NONE);
+        gd = new GridData(GridData.FILL_HORIZONTAL);
+        layout = new GridLayout();
+        layout.numColumns = 4;
+        layout.makeColumnsEqualWidth = true;
+        editorsComp.setLayout(layout);
+        editorsComp.setText(Messages.SchemaObjectEditorPreferencePage_available_editors);
+        editorsComp.setLayoutData(gd);
+
+        Composite dbdefsComp = new Composite(editorsComp, SWT.NONE);
+        layout = new GridLayout();
+        layout.numColumns = 2;
+        dbdefsComp.setLayout(layout);
+        gd = new GridData(GridData.FILL_BOTH);
+        gd.horizontalSpan = 2;
+        dbdefsComp.setLayoutData(gd);
+
+        Label dbTypeLabel = new Label(dbdefsComp, SWT.NONE);
+        dbTypeLabel.setText(Messages.SchemaObjectEditorPreferencePage_databaseType);
+
+        _dbType = new Combo(dbdefsComp, SWT.READ_ONLY);
+        gd = new GridData(GridData.FILL_HORIZONTAL);
+        gd.minimumWidth = 130;
+        _dbType.setLayoutData(gd);
+
+        Composite edComp = new Composite(editorsComp, SWT.NONE);
+        layout = new GridLayout();
+        layout.numColumns = 2;
+        edComp.setLayout(layout);
+        gd = new GridData(GridData.FILL_BOTH);
+        gd.horizontalSpan = 2;
+        edComp.setLayoutData(gd);
+
+        Label editorTypeLabel = new Label(edComp, SWT.NONE);
+        editorTypeLabel.setText(Messages.SchemaObjectEditorPreferencePage_editors);
+
+        _editorName = new Combo(edComp, SWT.READ_ONLY);
+        gd = new GridData(GridData.FILL_HORIZONTAL);
+        gd.minimumWidth = 130;
+        _editorName.setLayoutData(gd);
+
+        Group pagesComp = new Group(container, SWT.NONE);
+        gd = new GridData(GridData.FILL_BOTH);
+        layout = new GridLayout();
+        layout.numColumns = 3;
+        pagesComp.setLayout(layout);
+        pagesComp.setLayoutData(gd);
+        pagesComp.setText(Messages.SchemaObjectEditorPreferencePage_pagesSetting);
+
+        Composite selectedComposite = new Composite(pagesComp, SWT.NONE);
+        gd = new GridData(GridData.FILL_BOTH);
+        selectedComposite.setLayoutData(gd);
+        layout = new GridLayout();
+        selectedComposite.setLayout(layout);
+
+        Label selectedPages = new Label(selectedComposite, SWT.NONE);
+        selectedPages.setText(Messages.SchemaObjectEditorPreferencePage_selected_pages);
+        gd = new GridData();
+        gd.horizontalAlignment = GridData.HORIZONTAL_ALIGN_BEGINNING;
+        selectedPages.setLayoutData(gd);
+
+        _displayedPages = new List(selectedComposite, SWT.BORDER | SWT.MULTI);
+        gd = new GridData(GridData.FILL_BOTH);
+        _displayedPages.setLayoutData(gd);
+
+        Composite buttonsComp = new Composite(pagesComp, SWT.NONE);
+        gd = new GridData(GridData.FILL_VERTICAL);
+        buttonsComp.setLayoutData(gd);
+        layout = new GridLayout();
+        buttonsComp.setLayout(layout);
+
+        new Label(buttonsComp, SWT.NONE);
+        _rightOne = new Button(buttonsComp, SWT.NONE | SWT.LEFT);
+        gd = new GridData();
+        gd.verticalAlignment = GridData.VERTICAL_ALIGN_CENTER;
+        gd.widthHint = BUTTON_WIDTH;
+        _rightOne.setLayoutData(gd);
+        _rightOne.setText(Messages.SchemaObjectEditorPreferencePage_remove);
+        _rightOne.addSelectionListener(new SelectionListener()
+        {
+
+            public void widgetDefaultSelected(SelectionEvent e)
+            {
+
+            }
+
+            public void widgetSelected(SelectionEvent e)
+            {
+                String[] selectedItems = _displayedPages.getSelection();
+                boolean isSucceeded = false;
+                int movedNum = 0;
+                for (int i = 0; i < selectedItems.length; i++)
+                {
+                    String name = selectedItems[i];
+                    Object data = _displayedPages.getData(name);
+                    IEditorPageDescriptor page = (IEditorPageDescriptor) data;
+                    if (page.isRequired())
+                    {
+                        continue;
+                    }
+                    _hiddenPages.add(name);
+                    _hiddenPages.setData(name, data);
+                    _displayedPages.remove(name);
+                    isSucceeded = true;
+                    movedNum++;
+                }
+                setOrClearErrorMsg();
+
+                if (!isSucceeded)
+                {
+                    String[] buttons = new String[]
+                    {
+                        IDialogConstants.OK_LABEL
+                    };
+                    MessageDialog d = new MessageDialog(_parent.getShell(),
+                            Messages.SchemaObjectEditorPreferencePage_error, null,
+                            Messages.SchemaObjectEditorPreferencePage_can_not_remove, MessageDialog.ERROR, buttons, 0);
+                    d.open();
+                }
+                else
+                {
+                    _dirty = true;
+                    int[] indecies = new int[movedNum];
+                    for (int i = 0; i < movedNum; i++)
+                    {
+                        indecies[i] = _hiddenPages.getItemCount() - 1 - i;
+                    }
+                    _hiddenPages.setSelection(indecies);
+                }
+                setButtonStatus();
+            }
+        });
+
+        _rightAll = new Button(buttonsComp, SWT.NONE | SWT.LEFT);
+        gd = new GridData();
+        gd.verticalAlignment = GridData.VERTICAL_ALIGN_CENTER;
+        gd.widthHint = BUTTON_WIDTH;
+        _rightAll.setLayoutData(gd);
+        _rightAll.setText(Messages.SchemaObjectEditorPreferencePage_remove_all);
+        _rightAll.addSelectionListener(new SelectionListener()
+        {
+
+            public void widgetDefaultSelected(SelectionEvent e)
+            {
+
+            }
+
+            public void widgetSelected(SelectionEvent e)
+            {
+                String[] selectedItems = _displayedPages.getItems();
+                boolean isSucceeded = false;
+                for (int i = 0; i < selectedItems.length; i++)
+                {
+                    String name = selectedItems[i];
+                    Object data = _displayedPages.getData(name);
+                    IEditorPageDescriptor page = (IEditorPageDescriptor) data;
+                    if (page.isRequired())
+                    {
+                        continue;
+                    }
+                    _hiddenPages.add(name);
+                    _hiddenPages.setData(name, data);
+                    _displayedPages.remove(name);
+                    isSucceeded = true;
+                }
+                setOrClearErrorMsg();
+                setButtonStatus();
+                if (!isSucceeded)
+                {
+                    String[] buttons = new String[]
+                    {
+                        IDialogConstants.OK_LABEL
+                    };
+                    MessageDialog d = new MessageDialog(_parent.getShell(),
+                            Messages.SchemaObjectEditorPreferencePage_erroe, null,
+                            Messages.SchemaObjectEditorPreferencePage_can_not_remove, MessageDialog.ERROR, buttons, 0);
+                    d.open();
+                }
+                else
+                {
+                    _dirty = true;
+                }
+            }
+        });
+
+        _leftOne = new Button(buttonsComp, SWT.NONE | SWT.LEFT);
+        gd = new GridData();
+        gd.verticalAlignment = GridData.VERTICAL_ALIGN_CENTER;
+        gd.widthHint = BUTTON_WIDTH;
+        _leftOne.setLayoutData(gd);
+        _leftOne.setText(Messages.SchemaObjectEditorPreferencePage_add);
+        _leftOne.addSelectionListener(new SelectionListener()
+        {
+
+            public void widgetDefaultSelected(SelectionEvent e)
+            {
+
+            }
+
+            public void widgetSelected(SelectionEvent e)
+            {
+                String[] selectedItems = _hiddenPages.getSelection();
+                int movedNum = 0;
+                for (int i = 0; i < selectedItems.length; i++)
+                {
+                    String name = selectedItems[i];
+                    Object data = _hiddenPages.getData(name);
+                    IEditorDescriptor editor = (IEditorDescriptor) _editorName.getData(_editorName.getText());
+                    IEditorPageDescriptor page = (IEditorPageDescriptor) data;
+                    boolean isPageMandatoryFirstOne = editor.getMandatoryFirstPage() != null
+                            && editor.getMandatoryFirstPage().getPageId().equals(page.getPageId());
+                    boolean isPageMandatoryLastOne = editor.getMandatoryLastPage() != null
+                            && editor.getMandatoryLastPage().getPageId().equals(page.getPageId());
+
+                    if (isPageMandatoryFirstOne)
+                    {
+                        _displayedPages.add(name, 0);
+                        _displayedPages.setData(name, data);
+                    }
+                    else if (isPageMandatoryLastOne)
+                    {
+                        _displayedPages.add(name, _displayedPages.getItemCount());
+                        _displayedPages.setData(name, data);
+                    }
+                    else
+                    {
+                        // Check if the last visible page is a mandatory page
+                        if (_displayedPages.getItemCount() > 0)
+                        {
+                            String displayedLastOne = _displayedPages.getItem(_displayedPages.getItemCount() - 1);
+                            IEditorPageDescriptor displayedLast = (IEditorPageDescriptor) _displayedPages
+                                    .getData(displayedLastOne);
+                            boolean isLastPageMandatory = editor.getMandatoryLastPage() != null
+                                    && editor.getMandatoryLastPage().getPageId().equals(displayedLast.getPageId());
+                            if (isLastPageMandatory)
+                            {
+                                _displayedPages.add(name, _displayedPages.getItemCount() - 1);
+                                _displayedPages.setData(name, data);
+                            }
+                            else
+                            {
+                                _displayedPages.add(name);
+                                _displayedPages.setData(name, data);
+                            }
+                        }
+                        else
+                        {
+                            _displayedPages.add(name);
+                            _displayedPages.setData(name, data);
+                        }
+                    }
+                    _hiddenPages.remove(name);
+                    movedNum++;
+                }
+                setOrClearErrorMsg();
+                if (movedNum > 0)
+                {
+                    _dirty = true;
+                }
+                int[] indecies = new int[movedNum];
+                for (int i = 0; i < movedNum; i++)
+                {
+                    indecies[i] = _displayedPages.getItemCount() - 1 - i;
+                }
+                _displayedPages.setSelection(indecies);
+                setButtonStatus();
+            }
+        });
+        _leftAll = new Button(buttonsComp, SWT.NONE | SWT.LEFT);
+        gd = new GridData();
+        gd.verticalAlignment = GridData.VERTICAL_ALIGN_CENTER;
+        gd.widthHint = BUTTON_WIDTH;
+        _leftAll.setLayoutData(gd);
+        _leftAll.setText(Messages.SchemaObjectEditorPreferencePage_add_all);
+        _leftAll.addSelectionListener(new SelectionListener()
+        {
+
+            public void widgetDefaultSelected(SelectionEvent e)
+            {
+
+            }
+
+            public void widgetSelected(SelectionEvent e)
+            {
+                String[] selectedItems = _hiddenPages.getItems();
+                for (int i = 0; i < selectedItems.length; i++)
+                {
+                    _dirty = true;
+                    String name = selectedItems[i];
+                    Object data = _hiddenPages.getData(name);
+
+                    IEditorDescriptor editor = (IEditorDescriptor) _editorName.getData(_editorName.getText());
+                    IEditorPageDescriptor page = (IEditorPageDescriptor) data;
+                    boolean isPageMandatoryFirstOne = editor.getMandatoryFirstPage() != null
+                            && editor.getMandatoryFirstPage().getPageId().equals(page.getPageId());
+                    boolean isPageMandatoryLastOne = editor.getMandatoryLastPage() != null
+                            && editor.getMandatoryLastPage().getPageId().equals(page.getPageId());
+
+                    if (isPageMandatoryFirstOne)
+                    {
+                        _displayedPages.add(name, 0);
+                        _displayedPages.setData(name, data);
+                    }
+                    else if (isPageMandatoryLastOne)
+                    {
+                        _displayedPages.add(name, _displayedPages.getItemCount());
+                        _displayedPages.setData(name, data);
+                    }
+                    else
+                    {
+                        // Check if the last visible page is a mandatory page
+                        if (_displayedPages.getItemCount() > 0)
+                        {
+                            String displayedLastOne = _displayedPages.getItem(_displayedPages.getItemCount() - 1);
+                            IEditorPageDescriptor displayedLast = (IEditorPageDescriptor) _displayedPages
+                                    .getData(displayedLastOne);
+                            boolean isLastPageMandatory = editor.getMandatoryLastPage() != null
+                                    && editor.getMandatoryLastPage().getPageId().equals(displayedLast.getPageId());
+                            if (isLastPageMandatory)
+                            {
+                                _displayedPages.add(name, _displayedPages.getItemCount() - 1);
+                                _displayedPages.setData(name, data);
+                            }
+                            else
+                            {
+                                _displayedPages.add(name);
+                                _displayedPages.setData(name, data);
+                            }
+                        }
+                        else
+                        {
+                            _displayedPages.add(name);
+                            _displayedPages.setData(name, data);
+                        }
+                    }
+                    _hiddenPages.remove(name);
+                }
+                setOrClearErrorMsg();
+                setButtonStatus();
+            }
+        });
+
+        _upMove = new Button(buttonsComp, SWT.NONE | SWT.LEFT);
+        gd = new GridData();
+        gd.verticalAlignment = GridData.VERTICAL_ALIGN_CENTER;
+        gd.widthHint = BUTTON_WIDTH;
+        _upMove.setLayoutData(gd);
+        _upMove.setText(Messages.SchemaObjectEditorPreferencePage_move_up);
+        _upMove.addSelectionListener(new SelectionListener()
+        {
+
+            public void widgetDefaultSelected(SelectionEvent e)
+            {
+
+            }
+
+            public void widgetSelected(SelectionEvent e)
+            {
+                moveItem(_displayedPages, true);
+            }
+        });
+
+        _downMove = new Button(buttonsComp, SWT.NONE | SWT.LEFT);
+        gd = new GridData();
+        gd.verticalAlignment = GridData.VERTICAL_ALIGN_CENTER;
+        gd.widthHint = BUTTON_WIDTH;
+        _downMove.setLayoutData(gd);
+        _downMove.setText(Messages.SchemaObjectEditorPreferencePage_move_down);
+        _downMove.addSelectionListener(new SelectionListener()
+        {
+
+            public void widgetDefaultSelected(SelectionEvent e)
+            {
+
+            }
+
+            public void widgetSelected(SelectionEvent e)
+            {
+                moveItem(_displayedPages, false);
+            }
+        });
+
+        Composite availableComp = new Composite(pagesComp, SWT.NONE);
+        gd = new GridData(GridData.FILL_BOTH);
+        availableComp.setLayoutData(gd);
+        layout = new GridLayout();
+        availableComp.setLayout(layout);
+
+        Label availablePages = new Label(availableComp, SWT.NONE);
+        availablePages.setText(Messages.SchemaObjectEditorPreferencePage_available_pages);
+        gd = new GridData();
+        gd.horizontalAlignment = GridData.HORIZONTAL_ALIGN_BEGINNING;
+        availablePages.setLayoutData(gd);
+
+        _hiddenPages = new List(availableComp, SWT.BORDER | SWT.MULTI);
+        gd = new GridData(GridData.FILL_BOTH);
+        _hiddenPages.setLayoutData(gd);
+
+        final Map editorsMap = SchemaObjectEditorUtils.getEditorsCatalogedByDBDefinition();
+
+        // Sort the dbdefinitions
+        java.util.List keys = new ArrayList();
+        Iterator iter = editorsMap.keySet().iterator();
+        while (iter.hasNext())
+        {
+            String dbdefi = (String) iter.next();
+            keys.add(dbdefi);
+        }
+        Collections.sort(keys);
+        iter = keys.iterator();
+        while (iter.hasNext())
+        {
+            String dbdefi = (String) iter.next();
+            _dbType.add(dbdefi);
+        }
+        _dbType.setFocus();
+
+        _dbType.addSelectionListener(new SelectionListener()
+        {
+
+            public void widgetDefaultSelected(SelectionEvent e)
+            {
+                // do nothing
+
+            }
+
+            public void widgetSelected(SelectionEvent e)
+            {
+                String dbdefi = _dbType.getText();
+                if (dbdefi != null && dbdefi.trim().length() != 0)
+                {
+                    _editorName.removeAll();
+                    java.util.List editors = (java.util.List) editorsMap.get(dbdefi);
+                    if (editors != null)
+                    {
+                        Collections.sort(editors, new EditorComparator());
+                        Iterator iter = editors.iterator();
+                        while (iter.hasNext())
+                        {
+                            IEditorDescriptor editor = (IEditorDescriptor) iter.next();
+                            _editorName.add(editor.getEditorName());
+                            _editorName.setData(editor.getEditorName(), editor);
+                        }
+                    }
+                    if (_editorName.getItemCount() > 0)
+                    {
+                        _editorName.select(0);
+                        _editorName.notifyListeners(SWT.Selection, new Event());
+                    }
+                }
+            }
+        });
+
+        _editorName.addSelectionListener(new SelectionListener()
+        {
+
+            public void widgetDefaultSelected(SelectionEvent e)
+            {
+
+            }
+
+            public void widgetSelected(SelectionEvent e)
+            {
+                String name = _editorName.getText();
+                if (_dirty && isValid())
+                {
+                    String[] buttons = new String[]
+                    {
+                        IDialogConstants.YES_LABEL, IDialogConstants.NO_LABEL
+                    };
+                    MessageDialog d = new MessageDialog(_parent.getShell(),
+                            Messages.SchemaObjectEditorPreferencePage_question, null,
+                            Messages.SchemaObjectEditorPreferencePage_save_modification, MessageDialog.QUESTION,
+                            buttons, 0);
+                    int result = d.open();
+                    switch (result)
+                    {
+                        case 0:
+                            savePreferences();
+                            break;
+                        case 1:
+                            break;
+                        default:
+                            break;
+                    }
+                }
+                _dirty = false;
+
+                if (name != null && name.trim().length() != 0)
+                {
+                    _displayedPages.removeAll();
+                    _hiddenPages.removeAll();
+                    IEditorDescriptor editor = (IEditorDescriptor) _editorName.getData(name);
+                    if (editor != null)
+                    {
+                        IEditorPageDescriptor[] pages = editor.getPageDescriptors();
+                        for (int i = 0; i < pages.length; i++)
+                        {
+                            if (!_store.getBoolean(Constants.EDITOR_PAGE_VISIABILITY + pages[i].getEditorId()
+                                    + pages[i].getPageId()))
+                            {
+                                _hiddenPages.add(pages[i].getPageName());
+                                _hiddenPages.setData(pages[i].getPageName(), pages[i]);
+                            }
+                        }
+
+                        IEditorPageDescriptor[] sortedPages = editor.getSortedPages();
+                        for (int j = 0; j < sortedPages.length; j++)
+                        {
+                            if (sortedPages[j].isSelectedToShow())
+                            {
+                                _displayedPages.add(sortedPages[j].getPageName());
+                                _displayedPages.setData(sortedPages[j].getPageName(), sortedPages[j]);
+                            }
+                        }
+                    }
+                    setOrClearErrorMsg();
+                    setButtonStatus();
+                }
+            }
+        });
+
+        String preDBdef = _store.getString(Constants.PREFERENCE_PREVIOUS_DB_DEFINITION);
+        String preEditor = _store.getString(Constants.PREFERENCE_PREVIOUS_EDIOR_NAME);
+        if (preDBdef != null)
+        {
+            int index = _dbType.indexOf(preDBdef);
+            if (index != -1)
+            {
+                _dbType.select(index);
+                _dbType.notifyListeners(SWT.Selection, new Event());
+            }
+        }
+        if (preEditor != null)
+        {
+            int index = _editorName.indexOf(preEditor);
+            if (index != -1)
+            {
+                _editorName.select(index);
+                _editorName.notifyListeners(SWT.Selection, new Event());
+            }
+        }
+
+        _displayedPages.addSelectionListener(new SelectionListener()
+        {
+
+            public void widgetDefaultSelected(SelectionEvent e)
+            {
+
+            }
+
+            public void widgetSelected(SelectionEvent e)
+            {
+                setButtonStatus();
+            }
+        });
+        _hiddenPages.addSelectionListener(new SelectionListener()
+        {
+
+            public void widgetDefaultSelected(SelectionEvent e)
+            {
+
+            }
+
+            public void widgetSelected(SelectionEvent e)
+            {
+                setButtonStatus();
+            }
+        });
+        setButtonStatus();
+        _alwaysShowPreview = new Button(container, SWT.CHECK);
+        _alwaysShowPreview.setText(Messages.SchemaObjectEditorPreferencePage_always_show_preview);
+        _alwaysShowPreview.setSelection(_store.getBoolean(Constants.PREFERENCE_ALWAYS_SHOW_PREVIEW));
+        _promptIfNoExactEditorFound = new Button(container, SWT.CHECK);
+        _promptIfNoExactEditorFound.setText(Messages.SchemaObjectEditorPreferencePage_use_latest_version_to_open);
+        _promptIfNoExactEditorFound
+                .setToolTipText(Messages.SchemaObjectEditorPreferencePage_latest_version_open_tooltip);
+        _promptIfNoExactEditorFound.setSelection(_store.getBoolean(Constants.PREFERENCE_USE_LATEST_VERSION));
+
+        // add by sul - CR470356-2
+        _checkWhenActivated = new Button(container, SWT.CHECK);
+        _checkWhenActivated.setText(Messages.SchemaObjectEditorPreferencePage_check_existence_when_activated);
+        _checkWhenActivated.setSelection(_store.getBoolean(Constants.PREFERENCE_CHECK_EXISTENCE));
+        _checkWhenActivated
+                .setToolTipText(Messages.SchemaObjectEditorPreferencePage_check_existence_when_activated_tooltip);
+        // add end
+
+        // add by sul - CR497357-1
+        _openFileAfterSaveas = new Button(container, SWT.CHECK);
+        _openFileAfterSaveas.setText(Messages.SchemaObjectEditorPreferencePage_open_file_after_saveas);
+        _openFileAfterSaveas.setSelection(_store.getBoolean(Constants.PREFERENCE_OPEN_FILE_AFTER_SAVEAS));
+        _openFileAfterSaveas.setToolTipText(Messages.SchemaObjectEditorPreferencePage_open_file_after_saveas_tooltip);
+        // add end
+
+        return container;
+    }
+
+    private void setButtonStatus()
+    {
+        if (_displayedPages.getSelectionCount() > 0)
+        {
+            _rightOne.setEnabled(true);
+            if (_displayedPages.getSelectionCount() == 1 && _displayedPages.getSelectionIndex() != 0)
+            {
+                _upMove.setEnabled(true);
+            }
+            else
+            {
+                _upMove.setEnabled(false);
+            }
+
+            if (_displayedPages.getSelectionCount() == 1
+                    && _displayedPages.getSelectionIndex() != _displayedPages.getItemCount() - 1)
+            {
+                _downMove.setEnabled(true);
+            }
+            else
+            {
+                _downMove.setEnabled(false);
+            }
+        }
+        else
+        {
+            _rightOne.setEnabled(false);
+            _upMove.setEnabled(false);
+            _downMove.setEnabled(false);
+        }
+
+        if (_displayedPages.getItemCount() > 0)
+        {
+            _rightAll.setEnabled(true);
+        }
+        else
+        {
+            _rightAll.setEnabled(false);
+        }
+
+        if (_hiddenPages.getSelectionCount() > 0)
+        {
+            _leftOne.setEnabled(true);
+        }
+        else
+        {
+            _leftOne.setEnabled(false);
+        }
+
+        if (_hiddenPages.getItemCount() > 0)
+        {
+            _leftAll.setEnabled(true);
+        }
+        else
+        {
+            _leftAll.setEnabled(false);
+        }
+
+    }
+
+    public void init(IWorkbench workbench)
+    {
+
+    }
+
+    private void setOrClearErrorMsg()
+    {
+        if (_displayedPages.getItemCount() == 0)
+        {
+            setMessage(Messages.SchemaObjectEditorPreferencePage_no_page, DialogPage.ERROR);
+            setValid(false);
+            updateApplyButton();
+        }
+        else
+        {
+            setMessage(null);
+            setValid(true);
+            updateApplyButton();
+        }
+    }
+
+    protected void performApply()
+    {
+        /*
+         * boolean alwaysShowPreview = _alwaysShowPreview.getSelection(); boolean promptIfNoExactEditorFound =
+         * _promptIfNoExactEditorFound.getSelection(); boolean checkWhenActivated = _checkWhenActivated.getSelection();
+         * _store.setValue(Constants.PREFERENCE_ALWAYS_SHOW_PREVIEW, alwaysShowPreview);
+         * _store.setValue(Constants.PREFERENCE_USE_LATEST_VERSION, promptIfNoExactEditorFound);
+         * _store.setValue(Constants.PREFERENCE_CHECK_EXISTENCE, checkWhenActivated);
+         */
+        savePreferences();
+        super.performApply();
+    }
+
+    protected void performDefaults()
+    {
+        boolean alwaysShowPreview = _store.getDefaultBoolean(Constants.PREFERENCE_ALWAYS_SHOW_PREVIEW);
+        _alwaysShowPreview.setSelection(alwaysShowPreview);
+
+        boolean promptIfNoExactEditorFound = _store.getDefaultBoolean(Constants.PREFERENCE_USE_LATEST_VERSION);
+        _promptIfNoExactEditorFound.setSelection(promptIfNoExactEditorFound);
+
+        boolean checkWhenActivated = _store.getDefaultBoolean(Constants.PREFERENCE_CHECK_EXISTENCE);
+        _checkWhenActivated.setSelection(checkWhenActivated);
+
+        boolean openFileAfterSaveas = _store.getDefaultBoolean(Constants.PREFERENCE_OPEN_FILE_AFTER_SAVEAS);
+        _openFileAfterSaveas.setSelection(openFileAfterSaveas);
+
+        loadDefault();
+        super.performDefaults();
+    }
+
+    public boolean performOk()
+    {
+        savePreferences();
+        savePreConfiguredItem();
+        return super.performOk();
+    }
+
+    private void loadDefault()
+    {
+        String dbdef = _dbType.getText();
+        if (dbdef != null && dbdef.trim().length() != 0)
+        {
+            String editorName = _editorName.getText();
+            if (editorName != null && editorName.trim().length() != 0)
+            {
+                Object obj = _editorName.getData(editorName);
+                if (obj != null)
+                {
+                    IEditorDescriptor editor = (IEditorDescriptor) obj;
+                    _displayedPages.removeAll();
+                    _hiddenPages.removeAll();
+
+                    IEditorPageDescriptor[] pages = editor.getDefaultSortedPages();
+                    for (int i = 0; i < pages.length; i++)
+                    {
+                        if (pages[i].isRequired() || pages[i].isVisibleByDefault())
+                        {
+                            _displayedPages.add(pages[i].getPageName());
+                            _displayedPages.setData(pages[i].getPageName(), pages[i]);
+                        }
+                        else
+                        {
+                            _hiddenPages.add(pages[i].getPageName());
+                            _hiddenPages.setData(pages[i].getPageName(), pages[i]);
+                        }
+                    }
+                }
+            }
+        }
+        setOrClearErrorMsg();
+        setButtonStatus();
+        _dirty = false;
+    }
+
+    private void savePreferences()
+    {
+        boolean alwaysShowPreview = _alwaysShowPreview.getSelection();
+        boolean promptIfNoExactEditorFound = _promptIfNoExactEditorFound.getSelection();
+        boolean checkWhenActivated = _checkWhenActivated.getSelection();
+        boolean openFileAfterSaveas = _openFileAfterSaveas.getSelection();
+        _store.setValue(Constants.PREFERENCE_ALWAYS_SHOW_PREVIEW, alwaysShowPreview);
+        _store.setValue(Constants.PREFERENCE_USE_LATEST_VERSION, promptIfNoExactEditorFound);
+        _store.setValue(Constants.PREFERENCE_CHECK_EXISTENCE, checkWhenActivated);
+        _store.setValue(Constants.PREFERENCE_OPEN_FILE_AFTER_SAVEAS, openFileAfterSaveas);
+
+        String[] displayItems = _displayedPages.getItems();
+        int num = 1;
+        for (int i = 0; i < displayItems.length; i++)
+        {
+            String item = displayItems[i];
+            IEditorPageDescriptor page = (IEditorPageDescriptor) _displayedPages.getData(item);
+            if (page != null)
+            {
+                _store.setValue(Constants.EDITOR_PAGE_VISIABILITY + page.getEditorId() + page.getPageId(), true);
+                _store.setValue(Constants.EDITOR_PAGE_ORDER + page.getEditorId() + page.getPageId(), num++);
+            }
+        }
+
+        String[] hiddenItems = _hiddenPages.getItems();
+        for (int i = 0; i < hiddenItems.length; i++)
+        {
+            String item = hiddenItems[i];
+            IEditorPageDescriptor page = (IEditorPageDescriptor) _hiddenPages.getData(item);
+            if (page != null)
+            {
+                _store.setValue(Constants.EDITOR_PAGE_VISIABILITY + page.getEditorId() + page.getPageId(), false);
+            }
+        }
+        _dirty = false;
+    }
+
+    private void moveItem(List list, boolean upDirection)
+    {
+        if (list.getItemCount() == 0)
+        {
+            // no item
+        }
+        else if (list.getSelectionCount() == 0)
+        {
+            // no selection
+        }
+        else if (list.getSelectionCount() > 1)
+        {
+            // multiple selections
+        }
+        else if (list.getSelectionIndex() == 0 && upDirection)
+        {
+            // can not move the top one up
+        }
+        else if (list.getSelectionIndex() == list.getItemCount() - 1 && !upDirection)
+        {
+            // can not move the lowest one down
+        }
+        else
+        {
+            int selectionIndex = list.getSelectionIndex();
+            String selectionItem = list.getItem(selectionIndex);
+            IEditorDescriptor editor = (IEditorDescriptor) _editorName.getData(_editorName.getText());
+
+            String firstItem = list.getItem(0);
+            String lastItem = list.getItem(list.getItemCount() - 1);
+
+            IEditorPageDescriptor firstPage = (IEditorPageDescriptor) _displayedPages.getData(firstItem);
+            IEditorPageDescriptor lastPage = (IEditorPageDescriptor) _displayedPages.getData(lastItem);
+
+            boolean isFirstPageMandatory = editor.getMandatoryFirstPage() != null
+                    && editor.getMandatoryFirstPage().getPageId().equals(firstPage.getPageId());
+            boolean isLastPageMandatory = editor.getMandatoryLastPage() != null
+                    && editor.getMandatoryLastPage().getPageId().equals(lastPage.getPageId());
+
+            // can not move the mandatory first page
+            if (!upDirection && selectionIndex == 0 && isFirstPageMandatory)
+            {
+                String[] buttons = new String[]
+                {
+                    IDialogConstants.OK_LABEL
+                };
+                MessageDialog d = new MessageDialog(_parent.getShell(), "Error", null, //$NON-NLS-1$
+                        Messages.SchemaObjectEditorPreferencePage_must_be_first, MessageDialog.ERROR, buttons, 0);
+                d.open();
+                return;
+            }
+
+            // can not move the mandatory last page
+            if (upDirection && selectionIndex == list.getItemCount() - 1 && isLastPageMandatory)
+            {
+                String[] buttons = new String[]
+                {
+                    IDialogConstants.OK_LABEL
+                };
+                MessageDialog d = new MessageDialog(_parent.getShell(), "Error", null, //$NON-NLS-1$
+                        Messages.SchemaObjectEditorPreferencePage_must_be_last, MessageDialog.ERROR, buttons, 0);
+                d.open();
+                return;
+            }
+
+            // move the second page to the first one
+            if (upDirection && selectionIndex == 1 && isFirstPageMandatory)
+            {
+                String[] buttons = new String[]
+                {
+                    IDialogConstants.OK_LABEL
+                };
+                MessageDialog d = new MessageDialog(_parent.getShell(), "Error", null, //$NON-NLS-1$
+                        Messages.SchemaObjectEditorPreferencePage_can_not_up, MessageDialog.ERROR, buttons, 0);
+                d.open();
+                return;
+            }
+
+            // move the last but one page to the last one
+            if (!upDirection && selectionIndex == list.getItemCount() - 2 && isLastPageMandatory)
+            {
+                String[] buttons = new String[]
+                {
+                    IDialogConstants.OK_LABEL
+                };
+                MessageDialog d = new MessageDialog(_parent.getShell(),
+                        "Error", null, Messages.SchemaObjectEditorPreferencePage_can_not_down, //$NON-NLS-1$
+                        MessageDialog.ERROR, buttons, 0);
+                d.open();
+                return;
+            }
+
+            _dirty = true;
+            if (upDirection)
+            {
+                list.add(selectionItem, selectionIndex - 1);
+                list.remove(selectionIndex + 1);
+                list.select(selectionIndex - 1);
+            }
+            else
+            {
+                list.add(selectionItem, selectionIndex + 2);
+                list.remove(selectionIndex);
+                list.select(selectionIndex + 1);
+            }
+            setButtonStatus();
+        }
+    }
+
+    public boolean performCancel()
+    {
+        savePreConfiguredItem();
+        return super.performCancel();
+    }
+
+    private void savePreConfiguredItem()
+    {
+        String dbdef = _dbType.getText();
+        String editor = _editorName.getText();
+        if (dbdef != null && dbdef.trim().length() != 0)
+        {
+            _store.setValue(Constants.PREFERENCE_PREVIOUS_DB_DEFINITION, dbdef);
+        }
+        if (editor != null && editor.trim().length() != 0)
+        {
+            _store.setValue(Constants.PREFERENCE_PREVIOUS_EDIOR_NAME, editor);
+        }
+    }
+}
+
+class EditorComparator implements Comparator
+{
+    public int compare(Object arg0, Object arg1)
+    {
+        Locale locale = Locale.getDefault();
+        if (!(arg0 instanceof IEditorDescriptor))
+        {
+            return -1;
+        }
+        if (!(arg1 instanceof IEditorDescriptor))
+        {
+            return 1;
+        }
+        IEditorDescriptor editor1 = (IEditorDescriptor) arg0;
+        IEditorDescriptor editor2 = (IEditorDescriptor) arg1;
+        Collator col = Collator.getInstance(locale);
+        try
+        {
+            return col.compare(editor1.getEditorName(), editor2.getEditorName());
+        }
+        catch (Exception e)
+        {
+            return 0;
+        }
+    }
+}
diff --git a/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/internal/preference/messages.properties b/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/internal/preference/messages.properties
new file mode 100644
index 0000000..aa4c9fc
--- /dev/null
+++ b/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/internal/preference/messages.properties
@@ -0,0 +1,29 @@
+SchemaObjectEditorPreferencePage_available_editors=Available Editors
+SchemaObjectEditorPreferencePage_databaseType=Database type:
+SchemaObjectEditorPreferencePage_editors=Editor:
+SchemaObjectEditorPreferencePage_pagesSetting=Pages Setting
+SchemaObjectEditorPreferencePage_selected_pages=Selected pages:
+SchemaObjectEditorPreferencePage_remove=&Remove>>
+SchemaObjectEditorPreferencePage_error=Error
+SchemaObjectEditorPreferencePage_can_not_remove=Cannot remove the required item(s)
+SchemaObjectEditorPreferencePage_remove_all=R&emove All>>
+SchemaObjectEditorPreferencePage_erroe=Error
+SchemaObjectEditorPreferencePage_add=<<&Add
+SchemaObjectEditorPreferencePage_add_all=<<Add A&ll
+SchemaObjectEditorPreferencePage_move_up=Move &Up
+SchemaObjectEditorPreferencePage_move_down=Move &Down
+SchemaObjectEditorPreferencePage_available_pages=Available pages:
+SchemaObjectEditorPreferencePage_question=Question
+SchemaObjectEditorPreferencePage_save_modification=Save the modification?
+SchemaObjectEditorPreferencePage_no_page=Cannot edit without pages
+SchemaObjectEditorPreferencePage_always_show_preview=&Always show the preview dialog when saving the editor
+SchemaObjectEditorPreferencePage_use_latest_version_to_open=&Use the editor of the latest version without prompt
+SchemaObjectEditorPreferencePage_latest_version_open_tooltip=If no exact editor defined matches the database's version, will use the editor of the latest version to open the database object
+SchemaObjectEditorPreferencePage_must_be_last=The selected page must be the last page
+SchemaObjectEditorPreferencePage_must_be_first=The selected page must be the first page
+SchemaObjectEditorPreferencePage_can_not_up=Cannot move up
+SchemaObjectEditorPreferencePage_can_not_down=Cannot move down
+SchemaObjectEditorPreferencePage_check_existence_when_activated=Check schema object existence when editor activated
+SchemaObjectEditorPreferencePage_check_existence_when_activated_tooltip=Do existence check when an schema object editor is activated
+SchemaObjectEditorPreferencePage_open_file_after_saveas=open file after source saved as file
+SchemaObjectEditorPreferencePage_open_file_after_saveas_tooltip=open a sql editor after source saved as a file
\ No newline at end of file
diff --git a/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/internal/ui/ContainerContentProvider.java b/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/internal/ui/ContainerContentProvider.java
new file mode 100644
index 0000000..51a53c5
--- /dev/null
+++ b/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/internal/ui/ContainerContentProvider.java
@@ -0,0 +1,142 @@
+/***********************************************************************************************************************
+ * Copyright (c) 2009 Sybase, Inc. 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: Sybase, Inc. - initial API and implementation
+ **********************************************************************************************************************/
+package org.eclipse.datatools.sqltools.schemaobjecteditor.ui.internal.ui;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.core.resources.IContainer;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IWorkspace;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.jface.viewers.ITreeContentProvider;
+import org.eclipse.jface.viewers.Viewer;
+
+/**
+ * Provides content for a tree viewer that shows only containers.
+ * <p>
+ * This class is copied from <code>org.eclipse.ui.internal.ide.misc.ContainerContentProvider</code>.
+ * 
+ */
+public class ContainerContentProvider implements ITreeContentProvider
+{
+    private boolean showClosedProjects = true;
+
+    /**
+     * Creates a new ContainerContentProvider.
+     */
+    public ContainerContentProvider()
+    {
+    }
+
+    /**
+     * The visual part that is using this content provider is about to be disposed. Deallocate all allocated SWT
+     * resources.
+     */
+    public void dispose()
+    {
+    }
+
+    /*
+     * @see org.eclipse.jface.viewers.ITreeContentProvider#getChildren(java.lang.Object)
+     */
+    public Object[] getChildren(Object element)
+    {
+        if (element instanceof IWorkspace)
+        {
+            // check if closed projects should be shown
+            IProject[] allProjects = ((IWorkspace) element).getRoot().getProjects();
+            if (showClosedProjects)
+            {
+                return allProjects;
+            }
+
+            ArrayList accessibleProjects = new ArrayList();
+            for (int i = 0; i < allProjects.length; i++)
+            {
+                if (allProjects[i].isOpen())
+                {
+                    accessibleProjects.add(allProjects[i]);
+                }
+            }
+            return accessibleProjects.toArray();
+        }
+        else if (element instanceof IContainer)
+        {
+            IContainer container = (IContainer) element;
+            if (container.isAccessible())
+            {
+                try
+                {
+                    List children = new ArrayList();
+                    IResource[] members = container.members();
+                    for (int i = 0; i < members.length; i++)
+                    {
+                        if (members[i].getType() != IResource.FILE)
+                        {
+                            children.add(members[i]);
+                        }
+                    }
+                    return children.toArray();
+                }
+                catch (CoreException e)
+                {
+                    // this should never happen because we call #isAccessible before invoking #members
+                }
+            }
+        }
+        return new Object[0];
+    }
+
+    /*
+     * @see org.eclipse.jface.viewers.IStructuredContentProvider#getElements(java.lang.Object)
+     */
+    public Object[] getElements(Object element)
+    {
+        return getChildren(element);
+    }
+
+    /*
+     * @see org.eclipse.jface.viewers.ITreeContentProvider#getParent(java.lang.Object)
+     */
+    public Object getParent(Object element)
+    {
+        if (element instanceof IResource)
+        {
+            return ((IResource) element).getParent();
+        }
+        return null;
+    }
+
+    /*
+     * @see org.eclipse.jface.viewers.ITreeContentProvider#hasChildren(java.lang.Object)
+     */
+    public boolean hasChildren(Object element)
+    {
+        return getChildren(element).length > 0;
+    }
+
+    /*
+     * @see org.eclipse.jface.viewers.IContentProvider#inputChanged
+     */
+    public void inputChanged(Viewer viewer, Object oldInput, Object newInput)
+    {
+    }
+
+    /**
+     * Specify whether or not to show closed projects in the tree viewer. Default is to show closed projects.
+     * 
+     * @param show boolean if false, do not show closed projects in the tree
+     */
+    public void showClosedProjects(boolean show)
+    {
+        showClosedProjects = show;
+    }
+
+}
diff --git a/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/internal/ui/ContainerSelectionGroup.java b/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/internal/ui/ContainerSelectionGroup.java
new file mode 100644
index 0000000..ca6d469
--- /dev/null
+++ b/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/internal/ui/ContainerSelectionGroup.java
@@ -0,0 +1,341 @@
+/***********************************************************************************************************************
+ * Copyright (c) 2009 Sybase, Inc. 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: Sybase, Inc. - initial API and implementation
+ **********************************************************************************************************************/
+package org.eclipse.datatools.sqltools.schemaobjecteditor.ui.internal.ui;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.core.resources.IContainer;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.jface.dialogs.Dialog;
+import org.eclipse.jface.viewers.DoubleClickEvent;
+import org.eclipse.jface.viewers.IDoubleClickListener;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.ISelectionChangedListener;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.SelectionChangedEvent;
+import org.eclipse.jface.viewers.StructuredSelection;
+import org.eclipse.jface.viewers.TreeViewer;
+import org.eclipse.jface.viewers.ViewerSorter;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Event;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Listener;
+import org.eclipse.swt.widgets.Text;
+import org.eclipse.ui.model.WorkbenchLabelProvider;
+import org.eclipse.ui.part.DrillDownComposite;
+
+/**
+ * Workbench-level composite for choosing a container.
+ * <p>
+ * This class is copied from <code>org.eclipse.ui.internal.ide.misc.ContainerSelectionGroup</code>, adding a "Create
+ * Project" button to allow user to create project on this UI section.
+ * 
+ * @author Dafan Yang
+ */
+public class ContainerSelectionGroup extends Composite
+{
+    // The listener to notify of events
+    private Listener            listener;
+
+    // Enable user to type in new container name
+    private boolean             allowNewContainerName        = true;
+
+    // show all projects by default
+    private boolean             showClosedProjects           = true;
+
+    // Last selection made by user
+    private IContainer          selectedContainer;
+
+    // handle on parts
+    private Text                containerNameField;
+
+    TreeViewer                  treeViewer;
+
+    // the message to display at the top of this dialog
+    private static final String DEFAULT_MSG_NEW_ALLOWED      = Messages.ContainerSelectionGroup_message;
+
+    private static final String DEFAULT_MSG_SELECT_ONLY      = Messages.ContainerSelectionGroup_folder_select; //$NON-NLS-1$
+
+    // sizing constants
+    private static final int    SIZING_SELECTION_PANE_WIDTH  = 320;
+
+    private static final int    SIZING_SELECTION_PANE_HEIGHT = 300;
+
+    /**
+     * Creates a new instance of the widget.
+     * 
+     * @param parent The parent widget of the group.
+     * @param listener A listener to forward events to. Can be null if no listener is required.
+     * @param allowNewContainerName Enable the user to type in a new container name instead of just selecting from the
+     *            existing ones.
+     */
+    public ContainerSelectionGroup(Composite parent, Listener listener, boolean allowNewContainerName)
+    {
+        this(parent, listener, allowNewContainerName, null);
+    }
+
+    /**
+     * Creates a new instance of the widget.
+     * 
+     * @param parent The parent widget of the group.
+     * @param listener A listener to forward events to. Can be null if no listener is required.
+     * @param allowNewContainerName Enable the user to type in a new container name instead of just selecting from the
+     *            existing ones.
+     * @param message The text to present to the user.
+     */
+    public ContainerSelectionGroup(Composite parent, Listener listener, boolean allowNewContainerName, String message)
+    {
+        this(parent, listener, allowNewContainerName, message, true);
+    }
+
+    /**
+     * Creates a new instance of the widget.
+     * 
+     * @param parent The parent widget of the group.
+     * @param listener A listener to forward events to. Can be null if no listener is required.
+     * @param allowNewContainerName Enable the user to type in a new container name instead of just selecting from the
+     *            existing ones.
+     * @param message The text to present to the user.
+     * @param showClosedProjects Whether or not to show closed projects.
+     */
+    public ContainerSelectionGroup(Composite parent, Listener listener, boolean allowNewContainerName, String message,
+            boolean showClosedProjects)
+    {
+        this(parent, listener, allowNewContainerName, message, showClosedProjects, SIZING_SELECTION_PANE_HEIGHT);
+    }
+
+    /**
+     * Creates a new instance of the widget.
+     * 
+     * @param parent The parent widget of the group.
+     * @param listener A listener to forward events to. Can be null if no listener is required.
+     * @param allowNewContainerName Enable the user to type in a new container name instead of just selecting from the
+     *            existing ones.
+     * @param message The text to present to the user.
+     * @param showClosedProjects Whether or not to show closed projects.
+     * @param heightHint height hint for the drill down composite
+     */
+    public ContainerSelectionGroup(Composite parent, Listener listener, boolean allowNewContainerName, String message,
+            boolean showClosedProjects, int heightHint)
+    {
+        super(parent, SWT.NONE);
+        this.listener = listener;
+        this.allowNewContainerName = allowNewContainerName;
+        this.showClosedProjects = showClosedProjects;
+        if (message != null)
+        {
+            createContents(message, heightHint);
+        }
+        else if (allowNewContainerName)
+        {
+            createContents(DEFAULT_MSG_NEW_ALLOWED, heightHint);
+        }
+        else
+        {
+            createContents(DEFAULT_MSG_SELECT_ONLY, heightHint);
+        }
+    }
+
+    /**
+     * The container selection has changed in the tree view. Update the container name field value and notify all
+     * listeners.
+     */
+    public void containerSelectionChanged(IContainer container)
+    {
+        selectedContainer = container;
+
+        if (allowNewContainerName)
+        {
+            if (container == null)
+            {
+                containerNameField.setText("");//$NON-NLS-1$
+            }
+            else
+            {
+                containerNameField.setText(container.getFullPath().makeRelative().toString());
+            }
+        }
+
+        // fire an event so the parent can update its controls
+        if (listener != null)
+        {
+            Event changeEvent = new Event();
+            changeEvent.type = SWT.Selection;
+            changeEvent.widget = this;
+            listener.handleEvent(changeEvent);
+        }
+    }
+
+    /**
+     * Creates the contents of the composite.
+     */
+    public void createContents(String message)
+    {
+        createContents(message, SIZING_SELECTION_PANE_HEIGHT);
+    }
+
+    /**
+     * Creates the contents of the composite.
+     * 
+     * @param heightHint height hint for the drill down composite
+     */
+    public void createContents(String message, int heightHint)
+    {
+        GridLayout layout = new GridLayout();
+        layout.marginWidth = 0;
+        setLayout(layout);
+        setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
+
+        Label label = new Label(this, SWT.WRAP);
+        label.setText(message);
+        label.setFont(this.getFont());
+
+        if (allowNewContainerName)
+        {
+            containerNameField = new Text(this, SWT.SINGLE | SWT.BORDER);
+            containerNameField.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+            containerNameField.addListener(SWT.Modify, listener);
+            containerNameField.setFont(this.getFont());
+        }
+        else
+        {
+            // filler...
+            new Label(this, SWT.NONE);
+        }
+
+        createTreeViewer(heightHint);
+        Dialog.applyDialogFont(this);
+    }
+
+    /**
+     * Returns a new drill down viewer for this dialog.
+     * 
+     * @param heightHint height hint for the drill down composite
+     * @return a new drill down viewer
+     */
+    protected void createTreeViewer(int heightHint)
+    {
+        // Create drill down.
+        DrillDownComposite drillDown = new DrillDownComposite(this, SWT.BORDER);
+        GridData spec = new GridData(SWT.FILL, SWT.FILL, true, true);
+        spec.widthHint = SIZING_SELECTION_PANE_WIDTH;
+        spec.heightHint = heightHint;
+        drillDown.setLayoutData(spec);
+
+        // Create tree viewer inside drill down.
+        treeViewer = new TreeViewer(drillDown, SWT.NONE);
+        drillDown.setChildTree(treeViewer);
+        ContainerContentProvider cp = new ContainerContentProvider();
+        cp.showClosedProjects(showClosedProjects);
+        treeViewer.setContentProvider(cp);
+        treeViewer.setLabelProvider(WorkbenchLabelProvider.getDecoratingWorkbenchLabelProvider());
+        treeViewer.setSorter(new ViewerSorter());
+        treeViewer.addSelectionChangedListener(new ISelectionChangedListener()
+        {
+            public void selectionChanged(SelectionChangedEvent event)
+            {
+                IStructuredSelection selection = (IStructuredSelection) event.getSelection();
+                containerSelectionChanged((IContainer) selection.getFirstElement()); // allow null
+            }
+        });
+        treeViewer.addDoubleClickListener(new IDoubleClickListener()
+        {
+            public void doubleClick(DoubleClickEvent event)
+            {
+                ISelection selection = event.getSelection();
+                if (selection instanceof IStructuredSelection)
+                {
+                    Object item = ((IStructuredSelection) selection).getFirstElement();
+                    if (treeViewer.getExpandedState(item))
+                    {
+                        treeViewer.collapseToLevel(item, 1);
+                    }
+                    else
+                    {
+                        treeViewer.expandToLevel(item, 1);
+                    }
+                }
+            }
+        });
+
+        // This has to be done after the viewer has been laid out
+        treeViewer.setInput(ResourcesPlugin.getWorkspace());
+    }
+
+    /**
+     * Returns the currently entered container name. Null if the field is empty. Note that the container may not exist
+     * yet if the user entered a new container name in the field.
+     */
+    public IPath getContainerFullPath()
+    {
+        if (allowNewContainerName)
+        {
+            String pathName = containerNameField.getText();
+            if (pathName == null || pathName.length() < 1)
+            {
+                return null;
+            }
+            else
+            {
+                // The user may not have made this absolute so do it for them
+                return (new Path(pathName)).makeAbsolute();
+            }
+        }
+        else
+        {
+            if (selectedContainer == null)
+            {
+                return null;
+            }
+            else
+            {
+                return selectedContainer.getFullPath();
+            }
+        }
+    }
+
+    /**
+     * Gives focus to one of the widgets in the group, as determined by the group.
+     */
+    public void setInitialFocus()
+    {
+        if (allowNewContainerName)
+        {
+            containerNameField.setFocus();
+        }
+        else
+        {
+            treeViewer.getTree().setFocus();
+        }
+    }
+
+    /**
+     * Sets the selected existing container.
+     */
+    public void setSelectedContainer(IContainer container)
+    {
+        selectedContainer = container;
+
+        // expand to and select the specified container
+        List itemsToExpand = new ArrayList();
+        IContainer parent = container.getParent();
+        while (parent != null)
+        {
+            itemsToExpand.add(0, parent);
+            parent = parent.getParent();
+        }
+        treeViewer.setExpandedElements(itemsToExpand.toArray());
+        treeViewer.setSelection(new StructuredSelection(container), true);
+    }
+}
diff --git a/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/internal/ui/Messages.java b/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/internal/ui/Messages.java
new file mode 100644
index 0000000..dc39d16
--- /dev/null
+++ b/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/internal/ui/Messages.java
@@ -0,0 +1,74 @@
+/***********************************************************************************************************************
+ * Copyright (c) 2009 Sybase, Inc. 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: Sybase, Inc. - initial API and implementation
+ **********************************************************************************************************************/
+package org.eclipse.datatools.sqltools.schemaobjecteditor.ui.internal.ui;
+
+import java.lang.reflect.Field;
+
+import org.eclipse.osgi.util.NLS;
+
+public final class Messages extends NLS
+{
+
+    private static final String BUNDLE_NAME = Messages.class.getPackage().getName() + ".messages"; //$NON-NLS-1$
+
+    private Messages()
+    {
+        // Do not instantiate
+    }
+
+    public static String ResourceAndContainerGroup_folder_empty;
+    public static String ResourceAndContainerGroup_project_noexist;
+    public static String ResourceAndContainerGroup_file_exists;
+    public static String ResourceAndContainerGroup_name_exists;
+    public static String ResourceAndContainerGroup_name_empty;
+    public static String ResourceAndContainerGroup_invalid_name;
+    public static String ContainerSelectionGroup_message;
+    public static String ContainerSelectionGroup_folder_select;
+    public static String SaveAsDialog_error;
+    public static String SaveAsDialog_error_msg;
+    public static String SaveAsDialog_message;
+    public static String SaveAsDialog_title;
+    public static String SaveAsDialog_filetype_label;
+    public static String SaveAsDialog_overwrite;
+    public static String SaveAsDialog_question;
+    public static String SaveAsDialog_filename;
+    public static String SaveAsDialog_export_error;
+
+    static
+    {
+        NLS.initializeMessages(BUNDLE_NAME, Messages.class);
+    }
+
+    /**
+     * Gets a resource string by field name. This is useful when the field name is constructed ad hoc.
+     * 
+     * @param fieldName
+     * @return
+     */
+    public static String getString(String fieldName)
+    {
+        Class c = Messages.class;
+        Field[] fields = c.getDeclaredFields();
+        for (int i = 0; i < fields.length; i++)
+        {
+            if (fields[i].getName().equals(fieldName))
+            {
+                try
+                {
+                    return (String) fields[i].get(null);
+                }
+                catch (Exception ex)
+                {
+                    return "!" + fieldName + "!";
+                }
+            }
+        }
+        return "!" + fieldName + "!";
+    }
+
+}
diff --git a/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/internal/ui/ResourceAndContainerGroup.java b/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/internal/ui/ResourceAndContainerGroup.java
new file mode 100644
index 0000000..06e4b84
--- /dev/null
+++ b/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/internal/ui/ResourceAndContainerGroup.java
@@ -0,0 +1,444 @@
+/***********************************************************************************************************************
+ * Copyright (c) 2009 Sybase, Inc. 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: Sybase, Inc. - initial API and implementation
+ **********************************************************************************************************************/
+package org.eclipse.datatools.sqltools.schemaobjecteditor.ui.internal.ui;
+
+import org.eclipse.core.resources.IContainer;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IWorkspace;
+import org.eclipse.core.resources.IWorkspaceRoot;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Font;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Event;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Listener;
+import org.eclipse.swt.widgets.Text;
+
+/**
+ * Workbench-level composite for resource and container specification by the user. Services such as field validation are
+ * performed by the group. The group can be configured to accept existing resources, or only new resources.
+ * <p>
+ * This class is copied from <code>org.eclipse.ui.internal.ide.misc.ResourceAndContainerGroup</code> since it is an
+ * internal class, the <code>createExtraContents</code> method is added to allow subclasses to create extra contents.
+ * 
+ * @author Dafan Yang
+ */
+public class ResourceAndContainerGroup implements Listener
+{
+    // problem identifiers
+    public static final int         PROBLEM_NONE                        = 0;
+
+    public static final int         PROBLEM_RESOURCE_EMPTY              = 1;
+
+    public static final int         PROBLEM_RESOURCE_EXIST              = 2;
+
+    public static final int         PROBLEM_RESOURCE_CONTAINS_SEPARATOR = 3;
+
+    public static final int         PROBLEM_PATH_INVALID                = 4;
+
+    public static final int         PROBLEM_CONTAINER_EMPTY             = 5;
+
+    public static final int         PROBLEM_PROJECT_DOES_NOT_EXIST      = 6;
+
+    public static final int         PROBLEM_NAME_INVALID                = 7;
+
+    public static final int         PROBLEM_PATH_OCCUPIED               = 8;
+
+    // the client to notify of changes
+    private Listener                client;
+
+    // whether to allow existing resources
+    private boolean                 allowExistingResources              = false;
+
+    // resource type (file, folder, project)
+    private String                  resourceType                        = "resource";
+
+    // show closed projects in the tree, by default
+    private boolean                 showClosedProjects                  = true;
+
+    // problem indicator
+    private String                  problemMessage                      = "";          //$NON-NLS-1$
+
+    private int                     problemType                         = PROBLEM_NONE;
+
+    // widgets
+    private ContainerSelectionGroup containerGroup;
+
+    private Text                    resourceNameField;
+
+    // constants
+    private static final int        SIZING_TEXT_FIELD_WIDTH             = 250;
+
+    protected Listener              _listener;
+
+    /**
+     * Create an instance of the group to allow the user to enter/select a container and specify a resource name.
+     * 
+     * @param parent composite widget to parent the group
+     * @param client object interested in changes to the group's fields value
+     * @param resourceFieldLabel label to use in front of the resource name field
+     * @param resourceType one word, in lowercase, to describe the resource to the user (file, folder, project)
+     */
+    public ResourceAndContainerGroup(Composite parent, Listener client, String resourceFieldLabel, String resourceType,
+            Listener listener)
+    {
+        this(parent, client, resourceFieldLabel, resourceType, true, listener);
+    }
+
+    /**
+     * Create an instance of the group to allow the user to enter/select a container and specify a resource name.
+     * 
+     * @param parent composite widget to parent the group
+     * @param client object interested in changes to the group's fields value
+     * @param resourceFieldLabel label to use in front of the resource name field
+     * @param resourceType one word, in lowercase, to describe the resource to the user (file, folder, project)
+     * @param showClosedProjects whether or not to show closed projects
+     */
+    public ResourceAndContainerGroup(Composite parent, Listener client, String resourceFieldLabel, String resourceType,
+            boolean showClosedProjects, Listener listener)
+    {
+        this(parent, client, resourceFieldLabel, resourceType, showClosedProjects, SWT.DEFAULT, listener);
+    }
+
+    /**
+     * Create an instance of the group to allow the user to enter/select a container and specify a resource name.
+     * 
+     * @param parent composite widget to parent the group
+     * @param client object interested in changes to the group's fields value
+     * @param resourceFieldLabel label to use in front of the resource name field
+     * @param resourceType one word, in lowercase, to describe the resource to the user (file, folder, project)
+     * @param showClosedProjects whether or not to show closed projects
+     * @param heightHint height hint for the container selection widget group
+     */
+    public ResourceAndContainerGroup(Composite parent, Listener client, String resourceFieldLabel, String resourceType,
+            boolean showClosedProjects, int heightHint, Listener listener)
+    {
+        super();
+        this.resourceType = resourceType;
+        this.showClosedProjects = showClosedProjects;
+        this._listener = listener;
+        createContents(parent, resourceFieldLabel, heightHint);
+        this.client = client;
+    }
+
+    /**
+     * Returns a boolean indicating whether all controls in this group contain valid values.
+     * 
+     * @return boolean
+     */
+    public boolean areAllValuesValid()
+    {
+        return problemType == PROBLEM_NONE;
+    }
+
+    /**
+     * Creates this object's visual components.
+     * 
+     * @param parent org.eclipse.swt.widgets.Composite
+     * @param heightHint height hint for the container selection widget group
+     */
+    protected void createContents(Composite parent, String resourceLabelString, int heightHint)
+    {
+
+        Font font = parent.getFont();
+        // server name group
+        Composite composite = new Composite(parent, SWT.NONE);
+        GridLayout layout = new GridLayout();
+        layout.marginWidth = 0;
+        layout.marginHeight = 0;
+        composite.setLayout(layout);
+        composite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
+        composite.setFont(font);
+
+        // container group
+        if (heightHint == SWT.DEFAULT)
+        {
+            containerGroup = new ContainerSelectionGroup(composite, this, true, null, showClosedProjects);
+        }
+        else
+        {
+            containerGroup = new ContainerSelectionGroup(composite, this, true, null, showClosedProjects, heightHint);
+        }
+
+        // resource name group
+        Composite nameGroup = new Composite(composite, SWT.NONE);
+        layout = new GridLayout();
+        layout.numColumns = 2;
+        layout.marginWidth = 0;
+        nameGroup.setLayout(layout);
+        nameGroup.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_FILL | GridData.GRAB_HORIZONTAL));
+        nameGroup.setFont(font);
+
+        Label label = new Label(nameGroup, SWT.NONE);
+        label.setText(resourceLabelString);
+        label.setFont(font);
+
+        // resource name entry field
+        resourceNameField = new Text(nameGroup, SWT.BORDER);
+        resourceNameField.addListener(SWT.Modify, this);
+        GridData data = new GridData(GridData.HORIZONTAL_ALIGN_FILL | GridData.GRAB_HORIZONTAL);
+        data.widthHint = SIZING_TEXT_FIELD_WIDTH;
+        resourceNameField.setLayoutData(data);
+        resourceNameField.setFont(font);
+
+        // creates extra contents
+        createExtraContents(composite, layout, font, data);
+
+        validateControls();
+    }
+
+    /**
+     * Returns the path of the currently selected container or null if no container has been selected. Note that the
+     * container may not exist yet if the user entered a new container name in the field.
+     */
+    public IPath getContainerFullPath()
+    {
+        return containerGroup.getContainerFullPath();
+    }
+
+    /**
+     * Returns an error message indicating the current problem with the value of a control in the group, or an empty
+     * message if all controls in the group contain valid values.
+     * 
+     * @return java.lang.String
+     */
+    public String getProblemMessage()
+    {
+        return problemMessage;
+    }
+
+    /**
+     * Returns the type of problem with the value of a control in the group.
+     * 
+     * @return one of the PROBLEM_* constants
+     */
+    public int getProblemType()
+    {
+        return problemType;
+    }
+
+    /**
+     * Returns a string that is the path of the currently selected container. Returns an empty string if no container
+     * has been selected.
+     */
+    public String getResource()
+    {
+        return resourceNameField.getText();
+    }
+
+    /**
+     * Handles events for all controls in the group.
+     * 
+     * @param e org.eclipse.swt.widgets.Event
+     */
+    public void handleEvent(Event e)
+    {
+        validateControls();
+        if (client != null)
+        {
+            client.handleEvent(e);
+        }
+    }
+
+    /**
+     * Sets the flag indicating whether existing resources are permitted.
+     */
+    public void setAllowExistingResources(boolean value)
+    {
+        allowExistingResources = value;
+    }
+
+    /**
+     * Sets the value of this page's container.
+     * 
+     * @param path Full path to the container.
+     */
+    public void setContainerFullPath(IPath path)
+    {
+        IResource initial = ResourcesPlugin.getWorkspace().getRoot().findMember(path);
+        if (initial != null)
+        {
+            if (!(initial instanceof IContainer))
+            {
+                initial = initial.getParent();
+            }
+            containerGroup.setSelectedContainer((IContainer) initial);
+        }
+        validateControls();
+    }
+
+    /**
+     * Gives focus to the resource name field and selects its contents
+     */
+    public void setFocus()
+    {
+        // select the whole resource name.
+        resourceNameField.setSelection(0, resourceNameField.getText().length());
+        resourceNameField.setFocus();
+    }
+
+    /**
+     * Sets the value of this page's resource name.
+     * 
+     * @param value new value
+     */
+    public void setResource(String value)
+    {
+        resourceNameField.setText(value);
+        validateControls();
+    }
+
+    /**
+     * Returns a <code>boolean</code> indicating whether a container name represents a valid container resource in the
+     * workbench. An error message is stored for future reference if the name does not represent a valid container.
+     * 
+     * @return <code>boolean</code> indicating validity of the container name
+     */
+    protected boolean validateContainer()
+    {
+        IPath path = containerGroup.getContainerFullPath();
+        if (path == null)
+        {
+            problemType = PROBLEM_CONTAINER_EMPTY;
+            problemMessage = Messages.ResourceAndContainerGroup_folder_empty;
+            return false;
+        }
+        IWorkspace workspace = ResourcesPlugin.getWorkspace();
+        String projectName = path.segment(0);
+        if (projectName == null || !workspace.getRoot().getProject(projectName).exists())
+        {
+            problemType = PROBLEM_PROJECT_DOES_NOT_EXIST;
+            problemMessage = Messages.ResourceAndContainerGroup_project_noexist; //$NON-NLS-1$
+            return false;
+        }
+        // path is invalid if any prefix is occupied by a file
+        IWorkspaceRoot root = workspace.getRoot();
+        while (path.segmentCount() > 1)
+        {
+            if (root.getFile(path).exists())
+            {
+                problemType = PROBLEM_PATH_OCCUPIED;
+                problemMessage = NLS.bind(Messages.ResourceAndContainerGroup_file_exists, new Object[]
+                {
+                    path.makeRelative() //$NON-NLS-1$
+                            .toOSString()
+                });
+                return false;
+            }
+            path = path.removeLastSegments(1);
+        }
+        return true;
+    }
+
+    /**
+     * Validates the values for each of the group's controls. If an invalid value is found then a descriptive error
+     * message is stored for later reference. Returns a boolean indicating the validity of all of the controls in the
+     * group.
+     */
+    protected boolean validateControls()
+    {
+        // don't attempt to validate controls until they have been created
+        if (containerGroup == null)
+        {
+            return false;
+        }
+        problemType = PROBLEM_NONE;
+        problemMessage = "";//$NON-NLS-1$
+
+        if (!validateContainer() || !validateResourceName())
+        {
+            return false;
+        }
+
+        IPath path = containerGroup.getContainerFullPath().append(resourceNameField.getText());
+        return validateFullResourcePath(path);
+    }
+
+    /**
+     * Returns a <code>boolean</code> indicating whether the specified resource path represents a valid new resource in
+     * the workbench. An error message is stored for future reference if the path does not represent a valid new
+     * resource path.
+     * 
+     * @param resourcePath the path to validate
+     * @return <code>boolean</code> indicating validity of the resource path
+     */
+    protected boolean validateFullResourcePath(IPath resourcePath)
+    {
+        IWorkspace workspace = ResourcesPlugin.getWorkspace();
+
+        IStatus result = workspace.validatePath(resourcePath.toString(), IResource.FOLDER);
+        if (!result.isOK())
+        {
+            problemType = PROBLEM_PATH_INVALID;
+            problemMessage = result.getMessage();
+            return false;
+        }
+
+        if (!allowExistingResources
+                && (workspace.getRoot().getFolder(resourcePath).exists() || workspace.getRoot().getFile(resourcePath)
+                        .exists()))
+        {
+            problemType = PROBLEM_RESOURCE_EXIST;
+            problemMessage = Messages.ResourceAndContainerGroup_name_exists;
+            return false;
+        }
+        return true;
+    }
+
+    /**
+     * Returns a <code>boolean</code> indicating whether the resource name rep- resents a valid resource name in the
+     * workbench. An error message is stored for future reference if the name does not represent a valid resource name.
+     * 
+     * @return <code>boolean</code> indicating validity of the resource name
+     */
+    protected boolean validateResourceName()
+    {
+        String resourceName = resourceNameField.getText();
+
+        if (resourceName.equals("")) //$NON-NLS-1$
+        {
+            problemType = PROBLEM_RESOURCE_EMPTY;
+            problemMessage = NLS.bind(Messages.ResourceAndContainerGroup_name_empty, new Object[]
+            {
+                resourceType
+            }); //$NON-NLS-1$
+            return false;
+        }
+
+        if (!(new Path("")).isValidPath(resourceName)) //$NON-NLS-1$
+        {
+            problemType = PROBLEM_NAME_INVALID;
+            problemMessage = NLS.bind(Messages.ResourceAndContainerGroup_invalid_name, new Object[]
+            {
+                resourceName
+            }); //$NON-NLS-1$
+            return false;
+        }
+        return true;
+    }
+
+    /**
+     * Creates extra contents in the container selection group.
+     * 
+     * @param comp the Composite
+     * @param layout
+     * @param font font of this dialog
+     * @param data layout data
+     */
+    protected void createExtraContents(Composite comp, GridLayout layout, Font font, GridData data)
+    {
+
+    }
+}
diff --git a/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/internal/ui/SQLCommentScanner.java b/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/internal/ui/SQLCommentScanner.java
new file mode 100644
index 0000000..063f666
--- /dev/null
+++ b/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/internal/ui/SQLCommentScanner.java
@@ -0,0 +1,63 @@
+/***********************************************************************************************************************
+ * Copyright (c) 2009 Sybase, Inc. 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: Sybase, Inc. - initial API and implementation
+ **********************************************************************************************************************/
+package org.eclipse.datatools.sqltools.schemaobjecteditor.ui.internal.ui;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.datatools.sqltools.schemaobjecteditor.ui.internal.SOEUIPlugin;
+import org.eclipse.datatools.sqltools.schemaobjecteditor.ui.util.ColorProvider;
+import org.eclipse.datatools.sqltools.sqleditor.internal.sql.AbstractSQLScanner;
+import org.eclipse.datatools.sqltools.sqleditor.internal.sql.ISQLPartitions;
+import org.eclipse.jface.text.TextAttribute;
+import org.eclipse.jface.text.rules.Token;
+
+/**
+ * 
+ * @author Li Huang
+ */
+public class SQLCommentScanner extends AbstractSQLScanner
+{
+
+    ColorProvider _provider = SOEUIPlugin.getDefault().getColorProvider();
+    String        _commentKey;
+
+    public SQLCommentScanner(String commentKey)
+    {
+        _commentKey = commentKey;
+        initialize();
+    }
+
+    protected Token getToken()
+    {
+
+        Token token = new Token(null);
+        if (_commentKey.equals(ISQLPartitions.SQL_COMMENT))
+        {
+            token = new Token(new TextAttribute(_provider.getColor(ColorProvider.SINGLE_LINE_COMMENT)));
+        }
+        else if (_commentKey.equals(ISQLPartitions.SQL_MULTILINE_COMMENT))
+        {
+            token = new Token(new TextAttribute(_provider.getColor(ColorProvider.MULTI_LINE_COMMENT)));
+        }
+        return token;
+    }
+
+    /*
+     * @see AbstractSQLScanner#createRules()
+     */
+    protected List createRules()
+    {
+        List list = new ArrayList();
+        Token defaultToken = getToken();
+        setDefaultReturnToken(defaultToken);
+
+        return list;
+    }
+
+}
diff --git a/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/internal/ui/SQLSourceViewerConfiguration.java b/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/internal/ui/SQLSourceViewerConfiguration.java
new file mode 100644
index 0000000..0bea136
--- /dev/null
+++ b/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/internal/ui/SQLSourceViewerConfiguration.java
@@ -0,0 +1,128 @@
+/***********************************************************************************************************************
+ * Copyright (c) 2009 Sybase, Inc. 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: Sybase, Inc. - initial API and implementation
+ **********************************************************************************************************************/
+package org.eclipse.datatools.sqltools.schemaobjecteditor.ui.internal.ui;
+
+import org.eclipse.datatools.sqltools.core.SQLToolsFacade;
+import org.eclipse.datatools.sqltools.sqleditor.internal.SQLEditorPlugin;
+import org.eclipse.datatools.sqltools.sqleditor.internal.sql.ISQLPartitions;
+import org.eclipse.datatools.sqltools.sqleditor.internal.sql.SQLCodeScanner;
+import org.eclipse.datatools.sqltools.sqleditor.internal.sql.SQLDoubleClickStrategy;
+import org.eclipse.datatools.sqltools.sqleditor.internal.sql.SQLPartitionScanner;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.ITextDoubleClickStrategy;
+import org.eclipse.jface.text.presentation.IPresentationReconciler;
+import org.eclipse.jface.text.presentation.PresentationReconciler;
+import org.eclipse.jface.text.rules.DefaultDamagerRepairer;
+import org.eclipse.jface.text.rules.ITokenScanner;
+import org.eclipse.jface.text.source.ISourceViewer;
+import org.eclipse.jface.text.source.SourceViewerConfiguration;
+
+/**
+ * This is a common implementation of <code>SourceViewerConfiguration </code> for DMP. This configuraion is used for SQL
+ * Statements preview which supports: <li>Syntax high lighting <li>Double click strategy
+ * <p>
+ * If user wants to support content assistant and autoEditStrategy, user needs to subclass this class with overridding
+ * some motheds or subclass <code>SourceViewerConfiguration </code> directly.
+ * 
+ * @author Shifeng Yu
+ * 
+ */
+public class SQLSourceViewerConfiguration extends SourceViewerConfiguration
+{
+    private ITokenScanner _SQLCodeScanner;
+    private ITokenScanner _SQLStringScanner;
+    private ITokenScanner _multilineCommentScanner;
+    private ITokenScanner _singlelineCommentScanner;
+
+    /**
+     * The SQL identifier which is enclosed in double quotes scanner.
+     */
+    private ITokenScanner _SQLDoubleQuotesIdentifierScanner;
+
+    private String        _dbType = null;
+
+    /**
+     * Instantiates a new SQLSourceViewerConfiguration with the parameter:database type.
+     * 
+     * @param dbType
+     */
+    public SQLSourceViewerConfiguration(String dbType)
+    {
+        this._dbType = dbType;
+        initializeScanners();
+    }
+
+    /**
+     * Initializes the scanners.
+     * 
+     */
+    private void initializeScanners()
+    {
+        _SQLCodeScanner = new SQLCodeScanner(SQLEditorPlugin.getDefault().getSQLColorProvider());
+        ((SQLCodeScanner) _SQLCodeScanner).setSQLSyntax(SQLToolsFacade.getSQLSyntax(this._dbType));
+        _multilineCommentScanner = new SQLCommentScanner(ISQLPartitions.SQL_MULTILINE_COMMENT);
+        _singlelineCommentScanner = new SQLCommentScanner(ISQLPartitions.SQL_COMMENT);
+        _SQLDoubleQuotesIdentifierScanner = new SingleTokenSQLScanner(ISQLPartitions.SQL_DOUBLE_QUOTES_IDENTIFIER);
+        _SQLStringScanner = new SingleTokenSQLScanner(ISQLPartitions.SQL_STRING);
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see
+     * org.eclipse.jface.text.source.SourceViewerConfiguration#getPresentationReconciler(org.eclipse.jface.text.source
+     * .ISourceViewer)
+     */
+    public IPresentationReconciler getPresentationReconciler(ISourceViewer sourceViewer)
+    {
+        PresentationReconciler reconciler = new PresentationReconciler();
+        reconciler.setDocumentPartitioning(ISQLPartitions.SQL_PARTITIONING);
+
+        // rule for default text
+        DefaultDamagerRepairer dr = new DefaultDamagerRepairer(this._SQLCodeScanner);
+        reconciler.setDamager(dr, IDocument.DEFAULT_CONTENT_TYPE);
+        reconciler.setRepairer(dr, IDocument.DEFAULT_CONTENT_TYPE);
+
+        // rule for multiline comments
+        dr = new DefaultDamagerRepairer(this._multilineCommentScanner);
+        reconciler.setDamager(dr, ISQLPartitions.SQL_MULTILINE_COMMENT);
+        reconciler.setRepairer(dr, ISQLPartitions.SQL_MULTILINE_COMMENT);
+
+        // rule for singleline comments
+        dr = new DefaultDamagerRepairer(this._singlelineCommentScanner);
+        reconciler.setDamager(dr, ISQLPartitions.SQL_COMMENT);
+        reconciler.setRepairer(dr, ISQLPartitions.SQL_COMMENT);
+
+        // rule for SQL Strings
+        dr = new DefaultDamagerRepairer(this._SQLStringScanner);
+        reconciler.setDamager(dr, ISQLPartitions.SQL_STRING);
+        reconciler.setRepairer(dr, ISQLPartitions.SQL_STRING);
+
+        // rule for double quoted identifiers
+        dr = new DefaultDamagerRepairer(this._SQLDoubleQuotesIdentifierScanner);
+        reconciler.setDamager(dr, ISQLPartitions.SQL_DOUBLE_QUOTES_IDENTIFIER);
+        reconciler.setRepairer(dr, ISQLPartitions.SQL_DOUBLE_QUOTES_IDENTIFIER);
+
+        dr = new DefaultDamagerRepairer(this._SQLCodeScanner);
+        reconciler.setDamager(dr, SQLPartitionScanner.SQL_CODE);
+        reconciler.setRepairer(dr, SQLPartitionScanner.SQL_CODE);
+        return reconciler;
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see
+     * org.eclipse.jface.text.source.SourceViewerConfiguration#getDoubleClickStrategy(org.eclipse.jface.text.source.
+     * ISourceViewer, java.lang.String)
+     */
+    public ITextDoubleClickStrategy getDoubleClickStrategy(ISourceViewer sourceViewer, String contentType)
+    {
+        return new SQLDoubleClickStrategy();
+    }
+}
diff --git a/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/internal/ui/SQLSourceViewerService.java b/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/internal/ui/SQLSourceViewerService.java
new file mode 100644
index 0000000..b78a8a3
--- /dev/null
+++ b/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/internal/ui/SQLSourceViewerService.java
@@ -0,0 +1,53 @@
+/***********************************************************************************************************************
+ * Copyright (c) 2009 Sybase, Inc. 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: Sybase, Inc. - initial API and implementation
+ **********************************************************************************************************************/
+package org.eclipse.datatools.sqltools.schemaobjecteditor.ui.internal.ui;
+
+import org.eclipse.datatools.sqltools.common.ui.sqlstatementarea.ISQLSourceViewerService;
+import org.eclipse.datatools.sqltools.core.SQLToolsFacade;
+import org.eclipse.datatools.sqltools.sqleditor.internal.sql.ISQLPartitions;
+import org.eclipse.datatools.sqltools.sqleditor.internal.sql.SQLPartitionScanner;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.IDocumentExtension3;
+import org.eclipse.jface.text.rules.FastPartitioner;
+
+/**
+ * This is a common implementation of <code>ISQLSourceViewerService </code> . In this implementation, the document is
+ * divided into following partitions: <li>SQL code <li>SQL single line comment <li>SQL muli-line comment <li>SQL String
+ * <li>SQL double quoted identifier
+ * <p>
+ * If user wants to support other partitions, user needs to subclass <code>ISQLSourceViewerService</code> directly and
+ * implement the method: setUpDocument().
+ * 
+ * @author Shi-feng Yu
+ */
+public class SQLSourceViewerService implements ISQLSourceViewerService
+{
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see testDDLPage.actions.ISQLSourceViewerService#setUpDocument(org.eclipse.jface.text.IDocument,
+     * java.lang.String)
+     */
+    public void setUpDocument(IDocument document, String dbType)
+    {
+        SQLPartitionScanner _sqlPartitionSanner = new SQLPartitionScanner(SQLToolsFacade.getSQLSyntax(dbType));
+        if (document instanceof IDocumentExtension3)
+        {
+            IDocumentExtension3 extension3 = (IDocumentExtension3) document;
+            FastPartitioner _partitioner = new FastPartitioner(_sqlPartitionSanner, new String[]
+            {
+                SQLPartitionScanner.SQL_CODE, SQLPartitionScanner.SQL_COMMENT,
+                SQLPartitionScanner.SQL_MULTILINE_COMMENT, SQLPartitionScanner.SQL_STRING,
+                SQLPartitionScanner.SQL_DOUBLE_QUOTES_IDENTIFIER
+            });
+            _partitioner.connect(document);
+            extension3.setDocumentPartitioner(ISQLPartitions.SQL_PARTITIONING, _partitioner);
+        }
+    }
+}
diff --git a/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/internal/ui/SaveAsDialog.java b/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/internal/ui/SaveAsDialog.java
new file mode 100644
index 0000000..ebd6452
--- /dev/null
+++ b/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/internal/ui/SaveAsDialog.java
@@ -0,0 +1,365 @@
+/***********************************************************************************************************************
+ * Copyright (c) 2009 Sybase, Inc. 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: Sybase, Inc. - initial API and implementation
+ **********************************************************************************************************************/
+package org.eclipse.datatools.sqltools.schemaobjecteditor.ui.internal.ui;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStreamWriter;
+import java.io.PrintWriter;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.datatools.sqltools.schemaobjecteditor.ui.internal.SOEUIPlugin;
+import org.eclipse.datatools.sqltools.schemaobjecteditor.ui.util.ILogger;
+import org.eclipse.datatools.sqltools.schemaobjecteditor.ui.util.Images;
+import org.eclipse.jface.dialogs.ErrorDialog;
+import org.eclipse.jface.dialogs.IDialogConstants;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.jface.dialogs.TitleAreaDialog;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Event;
+import org.eclipse.swt.widgets.Listener;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.IWorkbenchPage;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.ide.IDE;
+
+/**
+ * An UI class that is used to save the result set or all result sets in a result instance into an Eclipse project file
+ * 
+ * @author Idull
+ */
+public class SaveAsDialog extends TitleAreaDialog
+{
+    private static ILogger            _log           = SOEUIPlugin.getLogger(null);
+    private IFile                     _originalFile  = null;
+    private String                    _originalName  = null;
+    private IPath                     _result;
+
+    private ResourceAndContainerGroup _resourceGroup;
+    private Button                    _okButton;
+    private String                    _content;
+    private static final String       ENCODING       = "UTF-8";
+    /**
+     * Image for title area
+     */
+    private Image                     _dlgTitleImage = null;
+
+    private boolean                   _first         = true;
+    private Listener                  _listener      = new Listener()
+                                                     {
+                                                         public void handleEvent(Event event)
+                                                         {
+                                                             if (_resourceGroup != null)
+                                                             {
+                                                                 boolean valid = _resourceGroup.validateContainer();
+                                                                 if (!valid)
+                                                                 {
+                                                                     SaveAsDialog.this
+                                                                             .getButton(IDialogConstants.OK_ID)
+                                                                             .setEnabled(false);
+                                                                 }
+                                                                 else
+                                                                 {
+                                                                     SaveAsDialog.this.setMessage(null);
+                                                                     SaveAsDialog.this
+                                                                             .getButton(IDialogConstants.OK_ID)
+                                                                             .setEnabled(true);
+                                                                 }
+                                                             }
+                                                         }
+                                                     };
+
+    /**
+     * Creates a new Save As dialog (Used to save a result set object)
+     * 
+     * @param parentShell the parent shell
+     */
+    public SaveAsDialog(Shell parentShell, String content)
+    {
+        super(parentShell);
+        this._content = content;
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see org.eclipse.jface.window.Window#configureShell(org.eclipse.swt.widgets.Shell)
+     */
+    protected void configureShell(Shell shell)
+    {
+        super.configureShell(shell);
+        shell.setText(Messages.SaveAsDialog_title);
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see org.eclipse.jface.window.Window#createContents(org.eclipse.swt.widgets.Composite)
+     */
+    protected Control createContents(Composite parent)
+    {
+        Control contents = super.createContents(parent);
+
+        initializeControls();
+        validatePage();
+        _resourceGroup.setFocus();
+
+        setTitle(Messages.SaveAsDialog_title);
+        setMessage(Messages.SaveAsDialog_message);
+        _dlgTitleImage = Images.get(Images.IMG_SAVEAS);
+        setTitleImage(_dlgTitleImage);
+        _first = false;
+
+        return contents;
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see org.eclipse.jface.dialogs.Dialog#createButtonsForButtonBar(org.eclipse.swt.widgets.Composite)
+     */
+    protected void createButtonsForButtonBar(Composite parent)
+    {
+        _okButton = createButton(parent, IDialogConstants.OK_ID, IDialogConstants.OK_LABEL, true);
+        createButton(parent, IDialogConstants.CANCEL_ID, IDialogConstants.CANCEL_LABEL, false);
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see org.eclipse.jface.dialogs.Dialog#createDialogArea(org.eclipse.swt.widgets.Composite)
+     */
+    protected Control createDialogArea(Composite parent)
+    {
+        // top level composite
+        Composite parentComposite = (Composite) super.createDialogArea(parent);
+
+        // create a composite with standard margins and spacing
+        Composite composite = new Composite(parentComposite, SWT.NONE);
+        GridLayout layout = new GridLayout();
+        layout.marginHeight = convertVerticalDLUsToPixels(IDialogConstants.VERTICAL_MARGIN);
+        layout.marginWidth = convertHorizontalDLUsToPixels(IDialogConstants.HORIZONTAL_MARGIN);
+        layout.verticalSpacing = convertVerticalDLUsToPixels(IDialogConstants.VERTICAL_SPACING);
+        layout.horizontalSpacing = convertHorizontalDLUsToPixels(IDialogConstants.HORIZONTAL_SPACING);
+        composite.setLayout(layout);
+        composite.setLayoutData(new GridData(GridData.FILL_BOTH));
+        composite.setFont(parentComposite.getFont());
+
+        Listener listener = new Listener()
+        {
+            public void handleEvent(Event event)
+            {
+                setDialogComplete(validatePage());
+            }
+        };
+        _resourceGroup = new ResourceAndContainerGroup(composite, listener, "", "file", _listener); //$NON-NLS-1$ //$NON-NLS-2$
+        _resourceGroup.setAllowExistingResources(true);
+
+        return parentComposite;
+    }
+
+    /**
+     * Returns the full path entered by the user.
+     * <p>
+     * Note that the file and container might not exist and would need to be created. See the <code>IFile.create</code>
+     * method and the <code>ContainerGenerator</code> class.
+     * </p>
+     * 
+     * @return the path, or <code>null</code> if Cancel was pressed
+     */
+    public IPath getResult()
+    {
+        return _result;
+    }
+
+    /**
+     * Initializes the controls of this dialog.
+     */
+    private void initializeControls()
+    {
+        if (_originalFile != null)
+        {
+            _resourceGroup.setContainerFullPath(_originalFile.getParent().getFullPath());
+            _resourceGroup.setResource(_originalFile.getName());
+        }
+        else if (_originalName != null)
+        {
+            _resourceGroup.setResource(_originalName);
+        }
+
+        setDialogComplete(validatePage());
+    }
+
+    /*
+     * (non-Javadoc) Method declared on Dialog.
+     */
+    protected void okPressed()
+    {
+        String filename = _resourceGroup.getResource();
+        IPath path = _resourceGroup.getContainerFullPath().append(filename);
+
+        // If the path already exists then confirm overwrite.
+        IFile file = ResourcesPlugin.getWorkspace().getRoot().getFile(path);
+
+        if (file.exists())
+        {
+            String[] buttons = new String[]
+            {
+                IDialogConstants.YES_LABEL, IDialogConstants.NO_LABEL, IDialogConstants.CANCEL_LABEL
+            };
+            String question = NLS.bind(Messages.SaveAsDialog_overwrite, new Object[]
+            {
+                path.toOSString()
+            });
+            MessageDialog d = new MessageDialog(getShell(), Messages.SaveAsDialog_question, null, question,
+                    MessageDialog.QUESTION, buttons, 0);
+            int overwrite = d.open();
+            switch (overwrite)
+            {
+                case 0: // Yes
+                    break;
+                case 1: // No
+                    return;
+                case 2: // Cancel
+                default:
+                    cancelPressed();
+                    return;
+            }
+        }
+
+        // Store path and close.
+        _result = path;
+
+        try
+        {
+            String resource = _resourceGroup.getContainerFullPath().toString();
+            if (ResourcesPlugin.getWorkspace().getRoot().findMember(resource) != null)
+            {
+
+                String fullpath = ResourcesPlugin.getWorkspace().getRoot().findMember(resource).getLocation()
+                        .toOSString()
+                        + File.separator + filename;
+                PrintWriter output = new PrintWriter(new OutputStreamWriter(new FileOutputStream(fullpath), ENCODING)); //$NON-NLS-1$
+                if (_content != null)
+                {
+                    output.write(_content);
+                }
+                if (output != null)
+                {
+                    output.close();
+                }
+                try
+                {
+                    if (file != null && file.getProject() != null)
+                    {
+                        file.getProject().refreshLocal(IResource.DEPTH_INFINITE, null);
+                        // set the correct charset for this file
+                        file.setCharset(ENCODING, new NullProgressMonitor()); //$NON-NLS-1$
+
+                        IWorkbenchPage page = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage();
+                        IDE.openEditor(page, file, true);
+                    }
+
+                }
+                catch (CoreException e)
+                {
+                    _log.error("SaveAsDialog_open_error", e); //$NON-NLS-1$
+                }
+            }
+        }
+        catch (IOException ex)
+        {
+            ErrorDialog.openError(getShell(), Messages.SaveAsDialog_error, Messages.SaveAsDialog_error_msg, new Status(
+                    IStatus.ERROR, SOEUIPlugin.PLUGIN_ID, 0, ex.getMessage(), ex));
+        }
+        close();
+    }
+
+    /**
+     * Sets the completion state of this dialog and adjusts the enable state of the Ok button accordingly.
+     * 
+     * @param value <code>true</code> if this dialog is compelete, and <code>false</code> otherwise
+     */
+    protected void setDialogComplete(boolean value)
+    {
+        _okButton.setEnabled(value);
+    }
+
+    /**
+     * Sets the original file to use.
+     * 
+     * @param originalFile the original file
+     */
+    public void setOriginalFile(IFile originalFile)
+    {
+        this._originalFile = originalFile;
+    }
+
+    /**
+     * Set the original file name to use. Used instead of <code>setOriginalFile</code> when the original resource is not
+     * an IFile. Must be called before <code>create</code>.
+     * 
+     * @param originalName default file name
+     */
+    public void setOriginalName(String originalName)
+    {
+        this._originalName = originalName;
+    }
+
+    /**
+     * Returns whether this page's visual components all contain valid values.
+     * 
+     * @return <code>true</code> if valid, and <code>false</code> otherwise
+     */
+    private boolean validatePage()
+    {
+        setErrorMessage(null);
+        setMessage(Messages.SaveAsDialog_message);
+
+        if (!_resourceGroup.areAllValuesValid())
+        {
+            if (_resourceGroup.getProblemType() == ResourceAndContainerGroup.PROBLEM_RESOURCE_EMPTY
+                    || _resourceGroup.getProblemType() == ResourceAndContainerGroup.PROBLEM_CONTAINER_EMPTY)
+            {
+                // according to eclipse ui guideline, we shall start a wizard/dialog with a prompt, not an error
+                // because he/she hasn't done anything yet.
+                if (_first)
+                {
+                    setMessage(_resourceGroup.getProblemMessage());
+                    setErrorMessage(null);
+                }
+                else
+                {
+                    setErrorMessage(_resourceGroup.getProblemMessage());
+                }
+            }
+            else
+            {
+                setErrorMessage(_resourceGroup.getProblemMessage());
+            }
+            return false;
+        }
+
+        return true;
+    }
+}
diff --git a/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/internal/ui/SavePreviewDialog.java b/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/internal/ui/SavePreviewDialog.java
new file mode 100644
index 0000000..3eb4601
--- /dev/null
+++ b/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/internal/ui/SavePreviewDialog.java
@@ -0,0 +1,323 @@
+/***********************************************************************************************************************
+ * Copyright (c) 2009 Sybase, Inc. 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: Sybase, Inc. - initial API and implementation
+ **********************************************************************************************************************/
+package org.eclipse.datatools.sqltools.schemaobjecteditor.ui.internal.ui;
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.datatools.sqltools.common.ui.dialog.SaveAsDialog;
+import org.eclipse.datatools.sqltools.common.ui.sqlstatementarea.SQLStatementArea;
+import org.eclipse.datatools.sqltools.core.DatabaseIdentifier;
+import org.eclipse.datatools.sqltools.core.SQLToolsFacade;
+import org.eclipse.datatools.sqltools.editor.core.connection.ISQLEditorConnectionInfo;
+import org.eclipse.datatools.sqltools.schemaobjecteditor.ui.ISchemaObjectEditor;
+import org.eclipse.datatools.sqltools.schemaobjecteditor.ui.core.Messages;
+import org.eclipse.datatools.sqltools.schemaobjecteditor.ui.core.SQLExecutionJobListener;
+import org.eclipse.datatools.sqltools.schemaobjecteditor.ui.internal.SOEUIPlugin;
+import org.eclipse.datatools.sqltools.schemaobjecteditor.ui.internal.Constants;
+import org.eclipse.datatools.sqltools.schemaobjecteditor.ui.internal.core.ScriptsExecutionRunnable;
+import org.eclipse.datatools.sqltools.sqleditor.SQLEditor;
+import org.eclipse.datatools.sqltools.sqleditor.SQLEditorConnectionInfo;
+import org.eclipse.jface.action.Action;
+import org.eclipse.jface.action.IAction;
+import org.eclipse.jface.action.IMenuListener;
+import org.eclipse.jface.action.IMenuManager;
+import org.eclipse.jface.action.MenuManager;
+import org.eclipse.jface.dialogs.Dialog;
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.jface.text.ITextOperationTarget;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Menu;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.IEditorPart;
+import org.eclipse.ui.ISharedImages;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.texteditor.ITextEditorActionConstants;
+import org.eclipse.ui.texteditor.IUpdate;
+
+/**
+ * The preview dialog when saving the editor
+ * 
+ * @author Idull
+ */
+public class SavePreviewDialog extends Dialog
+{
+    private Button              _notShowAgain;
+    private Button              _execute;
+    private Button              _saveAs;
+    private Button              _cancel;
+    private String              _scripts;
+    private DatabaseIdentifier  _databaseIdentifier;
+    private ISchemaObjectEditor _editor;
+    private SQLStatementArea    _sta;
+    private Map                 _actions   = new HashMap();
+    IPreferenceStore            _store     = SOEUIPlugin.getDefault().getPreferenceStore();
+    private boolean             _syncSave;
+    private IProgressMonitor    _monitor;
+    private boolean             _executing = false;
+    private String              _groupExecutionDspString;
+    private String              _consumerName;
+
+    /**
+     * Constructor
+     * 
+     * @param parentShell the parent shell
+     */
+    public SavePreviewDialog(Shell parentShell, String scripts, DatabaseIdentifier databaseIdentifier,
+            ISchemaObjectEditor editor, boolean syncSave, IProgressMonitor monitor, String groupExecutionDspString,
+            String consumerName)
+    {
+        super(parentShell);
+        setShellStyle(getShellStyle() | SWT.RESIZE);
+        _scripts = scripts;
+        _databaseIdentifier = databaseIdentifier;
+        _editor = editor;
+        _syncSave = syncSave;
+        _monitor = monitor;
+        _groupExecutionDspString = groupExecutionDspString;
+        _consumerName = consumerName;
+    }
+
+    private void initializeActions()
+    {
+        CommonAction action = new CommonAction(_sta.getViewer().getTextOperationTarget(), ITextOperationTarget.COPY,
+                Messages.SavePreviewDialog_copy);
+        action.setImageDescriptor(PlatformUI.getWorkbench().getSharedImages().getImageDescriptor(
+                ISharedImages.IMG_TOOL_COPY));
+        _actions.put(ITextEditorActionConstants.COPY, action);
+
+        action = new CommonAction(_sta.getViewer().getTextOperationTarget(), ITextOperationTarget.SELECT_ALL,
+                Messages.SavePreviewDialog_select_all);
+        _actions.put(ITextEditorActionConstants.SELECT_ALL, action);
+    }
+
+    protected void configureShell(Shell newShell)
+    {
+        super.configureShell(newShell);
+        newShell.setText(Messages.SavePreviewDialog_preview);
+    }
+
+    protected Control createContents(Composite parent)
+    {
+        parent.setLayout(new GridLayout());
+
+        Composite outter = new Composite(parent, SWT.NONE);
+        outter.setLayoutData(new GridData(GridData.FILL_BOTH));
+        GridLayout layout = new GridLayout();
+        layout.marginHeight = 0;
+        layout.marginWidth = 0;
+        layout.numColumns = 1;
+        outter.setLayout(layout);
+
+        Composite top = new Composite(outter, SWT.NONE);
+        top.setLayout(new GridLayout());
+        GridData gd = new GridData(GridData.FILL_BOTH);
+        top.setLayoutData(gd);
+        createSQLArea(top);
+
+        Composite bottom = new Composite(outter, SWT.NONE);
+        layout = new GridLayout();
+        layout.numColumns = 4;
+        bottom.setLayout(layout);
+        bottom.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+
+        _notShowAgain = new Button(bottom, SWT.CHECK);
+        _notShowAgain.setText(Messages.SavePreviewDialog_not_show_again);
+        gd = new GridData();
+        gd.grabExcessHorizontalSpace = true;
+        gd.widthHint = 400;
+        _notShowAgain.setLayoutData(gd);
+        _notShowAgain.addSelectionListener(new SelectionListener()
+        {
+            public void widgetDefaultSelected(SelectionEvent e)
+            {
+
+            }
+
+            public void widgetSelected(SelectionEvent e)
+            {
+                _store.setValue(Constants.PREFERENCE_ALWAYS_SHOW_PREVIEW, !_notShowAgain.getSelection());
+            }
+        });
+
+        _execute = new Button(bottom, SWT.NONE);
+        _execute.setText(Messages.SavePreviewDialog_execute);
+        _execute.setLayoutData(new GridData());
+        _execute.addSelectionListener(new SelectionListener()
+        {
+            public void widgetDefaultSelected(SelectionEvent e)
+            {
+
+            }
+
+            public void widgetSelected(SelectionEvent e)
+            {
+                ScriptsExecutionRunnable scriptsRunnable = new ScriptsExecutionRunnable(_scripts, _databaseIdentifier,
+                        new SQLExecutionJobListener(_editor, _monitor), _syncSave, _monitor, _groupExecutionDspString,
+                        _consumerName);
+                scriptsRunnable.run();
+                _executing = true;
+                SavePreviewDialog.this.close();
+            }
+        });
+
+        _saveAs = new Button(bottom, SWT.NONE);
+        _saveAs.setText(Messages.SavePreviewDialog_save_as);
+        _saveAs.setLayoutData(new GridData());
+        _saveAs.addSelectionListener(new SelectionListener()
+        {
+
+            public void widgetDefaultSelected(SelectionEvent e)
+            {
+
+            }
+
+            public void widgetSelected(SelectionEvent e)
+            {
+                SaveAsDialog dlg = new SaveAsDialog(SOEUIPlugin.getActiveWorkbenchShell(), _scripts);
+
+                IPreferenceStore store = SOEUIPlugin.getDefault().getPreferenceStore();
+                boolean isOpen = store
+                        .getBoolean(org.eclipse.datatools.sqltools.schemaobjecteditor.ui.internal.Constants.PREFERENCE_OPEN_FILE_AFTER_SAVEAS);
+
+                dlg.setOriginalName(_editor.getDisplayName() + "_edit.sql");
+                dlg.setOpenMode(isOpen);
+                dlg.open();
+                IEditorPart editor = dlg.getEditor();
+                if (editor != null && (editor instanceof SQLEditor))
+                {
+                    ISQLEditorConnectionInfo connInfo = new SQLEditorConnectionInfo(SQLToolsFacade
+                            .getConfigurationByProfileName(_databaseIdentifier.getProfileName())
+                            .getDatabaseVendorDefinitionId(), _databaseIdentifier.getProfileName(), _databaseIdentifier
+                            .getDBname(), _databaseIdentifier.getDBname());
+                    ((SQLEditor) editor).setConnectionInfo(connInfo);
+                }
+                SavePreviewDialog.this.close();
+            }
+        });
+
+        _cancel = new Button(bottom, SWT.NONE);
+        _cancel.setText(Messages.SavePreviewDialog_cancel);
+        _cancel.setLayoutData(new GridData());
+        _cancel.addSelectionListener(new SelectionListener()
+        {
+
+            public void widgetDefaultSelected(SelectionEvent e)
+            {
+
+            }
+
+            public void widgetSelected(SelectionEvent e)
+            {
+                SavePreviewDialog.this.close();
+            }
+        });
+
+        boolean dontShowPreview = !_store.getBoolean(Constants.PREFERENCE_ALWAYS_SHOW_PREVIEW);
+        _notShowAgain.setSelection(dontShowPreview);
+        return outter;
+    }
+
+    private void createSQLArea(Composite comp)
+    {
+        String dbType = _editor.getEditorDescriptor().getVendorName()
+                + "_" + _editor.getEditorDescriptor().getVersion(); //$NON-NLS-1$
+        _sta = new SQLStatementArea(comp, SWT.BORDER, new SQLSourceViewerService(), true);
+        _sta.setInput(_scripts, dbType);
+        _sta.setEditable(false);
+        _sta.setEnabled(true);
+        _sta.configureViewer(new SQLSourceViewerConfiguration(dbType));
+        _sta.setLayoutData(new GridData(GridData.FILL_BOTH));
+        initializeActions();
+        createContextMenu();
+    }
+
+    private void createContextMenu()
+    {
+        final MenuManager menuMgr = new MenuManager();
+        menuMgr.setRemoveAllWhenShown(true);
+        menuMgr.addMenuListener(new IMenuListener()
+        {
+            public void menuAboutToShow(IMenuManager manager)
+            {
+                // update items' status
+                Iterator iter = _actions.values().iterator();
+                while (iter.hasNext())
+                {
+                    Object obj = iter.next();
+                    if (obj instanceof IUpdate)
+                    {
+                        IUpdate action = (IUpdate) obj;
+                        action.update();
+                    }
+                }
+                menuMgr.add((IAction) _actions.get(ITextEditorActionConstants.COPY));
+                menuMgr.add((IAction) _actions.get(ITextEditorActionConstants.SELECT_ALL));
+            }
+        });
+        Menu menu = menuMgr.createContextMenu(_sta.getViewer().getTextWidget());
+        _sta.getViewer().getTextWidget().setMenu(menu);
+    }
+
+    public boolean close()
+    {
+        if (!_executing && _monitor != null)
+        {
+            _monitor.setCanceled(true);
+        }
+        return super.close();
+    }
+}
+
+class CommonAction extends Action implements IUpdate
+{
+    private int                  _operationCode;
+    private ITextOperationTarget _target;
+
+    /**
+     * 
+     */
+    public CommonAction(ITextOperationTarget target, int operationCode, String itemName)
+    {
+        super();
+        _operationCode = operationCode;
+        _target = target;
+        this.setText(itemName);
+    }
+
+    /**
+     * delegate the call to ITextOperationTarget instance
+     */
+    public void run()
+    {
+        _target.doOperation(_operationCode);
+    }
+
+    public void update()
+    {
+        boolean wasEnabled = isEnabled();
+        boolean isEnabled = (_target != null && _target.canDoOperation(_operationCode));
+        setEnabled(isEnabled);
+
+        if (wasEnabled != isEnabled)
+        {
+            firePropertyChange(ENABLED, wasEnabled ? Boolean.TRUE : Boolean.FALSE, isEnabled ? Boolean.TRUE
+                    : Boolean.FALSE);
+        }
+    }
+
+}
diff --git a/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/internal/ui/SingleTokenSQLScanner.java b/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/internal/ui/SingleTokenSQLScanner.java
new file mode 100644
index 0000000..24dc887
--- /dev/null
+++ b/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/internal/ui/SingleTokenSQLScanner.java
@@ -0,0 +1,63 @@
+/***********************************************************************************************************************
+ * Copyright (c) 2009 Sybase, Inc. 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: Sybase, Inc. - initial API and implementation
+ **********************************************************************************************************************/
+package org.eclipse.datatools.sqltools.schemaobjecteditor.ui.internal.ui;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.datatools.sqltools.schemaobjecteditor.ui.internal.SOEUIPlugin;
+import org.eclipse.datatools.sqltools.schemaobjecteditor.ui.util.ColorProvider;
+import org.eclipse.datatools.sqltools.sqleditor.internal.sql.AbstractSQLScanner;
+import org.eclipse.datatools.sqltools.sqleditor.internal.sql.ISQLPartitions;
+import org.eclipse.jface.text.TextAttribute;
+import org.eclipse.jface.text.rules.Token;
+
+/**
+ * @author Li Huang
+ * 
+ */
+public class SingleTokenSQLScanner extends AbstractSQLScanner
+{
+
+    ColorProvider _provider = SOEUIPlugin.getDefault().getColorProvider();
+    String        _tokenKey;
+
+    public SingleTokenSQLScanner(String tokenKey)
+    {
+        _tokenKey = tokenKey;
+        initialize();
+    }
+
+    protected Token getToken()
+    {
+
+        Token token = new Token(null);
+        if (_tokenKey.equals(ISQLPartitions.SQL_STRING))
+        {
+            token = new Token(new TextAttribute(_provider.getColor(ColorProvider.STRING)));
+        }
+        else if (_tokenKey.equals(ISQLPartitions.SQL_DOUBLE_QUOTES_IDENTIFIER))
+        {
+            token = new Token(new TextAttribute(_provider.getColor(ColorProvider.STRING)));
+        }
+        return token;
+    }
+
+    /*
+     * @see AbstractSQLScanner#createRules()
+     */
+    protected List createRules()
+    {
+        List list = new ArrayList();
+        Token defaultToken = getToken();
+        setDefaultReturnToken(defaultToken);
+
+        return list;
+    }
+
+}
diff --git a/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/internal/ui/messages.properties b/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/internal/ui/messages.properties
new file mode 100644
index 0000000..7596983
--- /dev/null
+++ b/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/internal/ui/messages.properties
@@ -0,0 +1,17 @@
+ResourceAndContainerGroup_folder_empty=The folder is empty.
+ResourceAndContainerGroup_project_noexist=The specified project does not exist.
+ResourceAndContainerGroup_file_exists=A file already exists at that location: {0}
+ResourceAndContainerGroup_name_exists=The same name already exists.
+ResourceAndContainerGroup_name_empty=The ''{0}'' name is empty.
+ResourceAndContainerGroup_invalid_name=''{0}'' is not a valid file name.
+ContainerSelectionGroup_message=&Enter or select the parent folder:
+ContainerSelectionGroup_folder_select=Select the folder:
+SaveAsDialog_filetype_label=&File type:
+SaveAsDialog_overwrite=The file ''{0}'' already exists. Do you want to replace the existing file?
+SaveAsDialog_question=Question
+SaveAsDialog_filename=&File name:
+SaveAsDialog_export_error=Export Error
+SaveAsDialog_title=Save As
+SaveAsDialog_message=Save as a SQL file
+SaveAsDialog_error=Error
+SaveAsDialog_error_msg=Error occurs when trying to save the scripts as a file
diff --git a/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/util/ColorProvider.java b/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/util/ColorProvider.java
new file mode 100644
index 0000000..5e61405
--- /dev/null
+++ b/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/util/ColorProvider.java
@@ -0,0 +1,66 @@
+package org.eclipse.datatools.sqltools.schemaobjecteditor.ui.util;
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.RGB;
+import org.eclipse.swt.widgets.Display;
+
+/**
+ * Colors used in the SQL editor
+ */
+public class ColorProvider
+{
+    public static final RGB BACKGROUND          = new RGB(255, 255, 255);
+
+    public static final RGB MULTI_LINE_COMMENT  = new RGB(64, 128, 128);
+
+    public static final RGB SINGLE_LINE_COMMENT = new RGB(64, 128, 128);
+
+    public static final RGB DEFAULT             = new RGB(0, 0, 0);
+
+    public static final RGB KEYWORD             = new RGB(127, 0, 85);
+
+    public static final RGB TYPE                = new RGB(64, 0, 200);
+
+    public static final RGB STRING              = new RGB(0, 0, 255);
+
+    public static final RGB SQL_CODE_DEFAULT    = new RGB(63, 95, 191);
+
+    public static final RGB SQL_CODE_KEYWORD    = new RGB(100, 100, 100);
+
+    public static final RGB SQL_CODE_TAG        = new RGB(127, 159, 191);
+
+    protected Map           fColorTable         = new HashMap(10);
+
+    /**
+     * Method disposes of the colors.
+     */
+    public void dispose()
+    {
+        Iterator e = fColorTable.values().iterator();
+        while (e.hasNext())
+        ((Color) e.next()).dispose();
+    }
+
+    /**
+     * A getter method that returns a color.
+     * 
+     * @param rgb
+     * @return Color
+     */
+    public Color getColor(RGB rgb)
+    {
+        Color color = (Color) fColorTable.get(rgb);
+
+        if (color == null)
+        {
+            color = new Color(Display.getCurrent(), rgb);
+            fColorTable.put(rgb, color);
+        }
+
+        return color;
+    }
+}
diff --git a/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/util/ILogger.java b/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/util/ILogger.java
new file mode 100644
index 0000000..0793c16
--- /dev/null
+++ b/plugins/org.eclipse.datatools.sqltools.schemaobjecteditor.ui/src/org/eclipse/datatools/sqltools/schemaobjecteditor/ui/util/ILogger.java
@@ -0,0 +1,419 @@
+/*******************************************************************************
+ * Copyright (c) 2005 Sybase, Inc.
+ * 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:
+ *    Sybase, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.datatools.sqltools.schemaobjecteditor.ui.util;
+
+/**
+ * Interface for logger
+ * 
+ * @author Li Huang
+ */
+public interface ILogger
+{
+    public abstract void fatal(Object message);
+
+    /**
+     * This method should NOT be used since it doesn't use the resource bundle to localize the message. It is provided
+     * here as a case when a resource bundle can't be used.
+     */
+    public abstract void fatal(Object message, Throwable tt);
+
+    /**
+     * For fatal logging with no arguments
+     */
+    public abstract void fatal(String key);
+
+    /**
+     * For fatal logging with no arguments but a stack trace
+     */
+    public abstract void fatal(String key, Throwable tt);
+
+    /**
+     * For fatal logging with one argument
+     */
+    public abstract void fatal(String key, Object arg0);
+
+    /**
+     * For fatal logging with one argument and a stack trace
+     */
+    public abstract void fatal(String key, Object arg0, Throwable tt);
+
+    /**
+     * For fatal logging with 2 arguments
+     */
+    public abstract void fatal(String key, Object arg0, Object arg1);
+
+    /**
+     * For fatal logging with 2 arguments and a stack trace
+     */
+    public abstract void fatal(String key, Object arg0, Object arg1, Throwable tt);
+
+    /**
+     * For fatal logging with 3 arguments
+     */
+    public abstract void fatal(String key, Object arg0, Object arg1, Object arg2);
+
+    /**
+     * For fatal logging with 3 arguments and a stack trace
+     */
+    public abstract void fatal(String key, Object arg0, Object arg1, Object arg2, Throwable tt);
+
+    /**
+     * For fatal logging with 4 arguments
+     */
+    public abstract void fatal(String key, Object arg0, Object arg1, Object arg2, Object arg3);
+
+    /**
+     * For fatal logging with 4 arguments and a stack trace
+     */
+    public abstract void fatal(String key, Object arg0, Object arg1, Object arg2, Object arg3, Throwable tt);
+
+    /**
+     * For fatal logging with 5 arguments
+     */
+    public abstract void fatal(String key, Object arg0, Object arg1, Object arg2, Object arg3, Object arg4);
+
+    /**
+     * For fatal logging with 5 arguments and a stack trace
+     */
+    public abstract void fatal(String key, Object arg0, Object arg1, Object arg2, Object arg3, Object arg4, Throwable tt);
+
+    /**
+     * For fatal logging methods where the number of args is greater than the methods provided.
+     */
+    public abstract void fatal(String key, Object[] args);
+
+    /**
+     * For fatal logging methods where the number of args is greater than the methods provided.
+     */
+    public abstract void fatal(String key, Object[] args, Throwable tt);
+
+    public abstract void error(Object message);
+
+    /**
+     * This method should NOT be used since it doesn't use the resource bundle to localize the message. It is provided
+     * here as a case when a resource bundle can't be used.
+     */
+    public abstract void error(Object message, Throwable tt);
+
+    /**
+     * For error logging with no arguments
+     */
+    public abstract void error(String key);
+
+    /**
+     * For error logging with no arguments but a stack trace
+     */
+    public abstract void error(String key, Throwable tt);
+
+    /**
+     * For error logging with one argument
+     */
+    public abstract void error(String key, Object arg0);
+
+    /**
+     * For error logging with one argument and a stack trace
+     */
+    public abstract void error(String key, Object arg0, Throwable tt);
+
+    /**
+     * For error logging with 2 arguments
+     */
+    public abstract void error(String key, Object arg0, Object arg1);
+
+    /**
+     * For error logging with 2 arguments and a stack trace
+     */
+    public abstract void error(String key, Object arg0, Object arg1, Throwable tt);
+
+    /**
+     * For error logging with 3 arguments
+     */
+    public abstract void error(String key, Object arg0, Object arg1, Object arg2);
+
+    /**
+     * For error logging with 3 arguments and a stack trace
+     */
+    public abstract void error(String key, Object arg0, Object arg1, Object arg2, Throwable tt);
+
+    /**
+     * For error logging with 4 arguments
+     */
+    public abstract void error(String key, Object arg0, Object arg1, Object arg2, Object arg3);
+
+    /**
+     * For error logging with 4 arguments and a stack trace
+     */
+    public abstract void error(String key, Object arg0, Object arg1, Object arg2, Object arg3, Throwable tt);
+
+    /**
+     * For error logging with 5 arguments
+     */
+    public abstract void error(String key, Object arg0, Object arg1, Object arg2, Object arg3, Object arg4);
+
+    /**
+     * For error logging with 5 arguments and a stack trace
+     */
+    public abstract void error(String key, Object arg0, Object arg1, Object arg2, Object arg3, Object arg4, Throwable tt);
+
+    /**
+     * For error logging methods where the number of args is greater than the methods provided.
+     */
+    public abstract void error(String key, Object[] args);
+
+    /**
+     * For error logging methods where the number of args is greater than the methods provided.
+     */
+    public abstract void error(String key, Object[] args, Throwable tt);
+
+    pub