Merge ../org.eclipse.datatools.enablement.oda
diff --git a/plugins/org.eclipse.datatools.connectivity.oda.flatfile.ui/.classpath b/plugins/org.eclipse.datatools.connectivity.oda.flatfile.ui/.classpath
new file mode 100644
index 0000000..751c8f2
--- /dev/null
+++ b/plugins/org.eclipse.datatools.connectivity.oda.flatfile.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.connectivity.oda.flatfile.ui/.gitignore b/plugins/org.eclipse.datatools.connectivity.oda.flatfile.ui/.gitignore
new file mode 100644
index 0000000..4c41f3d
--- /dev/null
+++ b/plugins/org.eclipse.datatools.connectivity.oda.flatfile.ui/.gitignore
@@ -0,0 +1,7 @@
+bin
+download
+*.jar
+*.zip
+plugin_*.properties
+vss*.scc
+build*.xml
diff --git a/plugins/org.eclipse.datatools.connectivity.oda.flatfile.ui/.project b/plugins/org.eclipse.datatools.connectivity.oda.flatfile.ui/.project
new file mode 100644
index 0000000..0a4219b
--- /dev/null
+++ b/plugins/org.eclipse.datatools.connectivity.oda.flatfile.ui/.project
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>org.eclipse.datatools.connectivity.oda.flatfile.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.connectivity.oda.flatfile.ui/META-INF/MANIFEST.MF b/plugins/org.eclipse.datatools.connectivity.oda.flatfile.ui/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..8f871bb
--- /dev/null
+++ b/plugins/org.eclipse.datatools.connectivity.oda.flatfile.ui/META-INF/MANIFEST.MF
@@ -0,0 +1,17 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: %plugin.name
+Bundle-SymbolicName: org.eclipse.datatools.connectivity.oda.flatfile.ui; singleton:=true
+Bundle-Version: 3.3.1.qualifier
+Bundle-RequiredExecutionEnvironment: JavaSE-1.8
+Bundle-Activator: org.eclipse.datatools.connectivity.oda.flatfile.ui.FlatFileUIPlugin
+Bundle-Vendor: Eclipse Data Tools Platform
+Bundle-Localization: plugin
+Export-Package: org.eclipse.datatools.connectivity.oda.flatfile.ui,
+ org.eclipse.datatools.connectivity.oda.flatfile.ui.wizards
+Require-Bundle: org.eclipse.core.runtime,
+ org.eclipse.ui,
+ org.eclipse.datatools.connectivity.oda.design.ui,
+ org.eclipse.datatools.connectivity.oda.flatfile
+Eclipse-LazyStart: true
+Bundle-ActivationPolicy: lazy
diff --git a/plugins/org.eclipse.datatools.connectivity.oda.flatfile.ui/about.html b/plugins/org.eclipse.datatools.connectivity.oda.flatfile.ui/about.html
new file mode 100644
index 0000000..129db9d
--- /dev/null
+++ b/plugins/org.eclipse.datatools.connectivity.oda.flatfile.ui/about.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"/>
+<title>About</title>
+</head>
+<body lang="EN-US">
+<h2>About This Content</h2>
+ 
+<p>June 15, 2009</p>	
+<h3>License</h3>
+
+<p>The Eclipse Foundation makes available all content in this plug-in (&quot;Content&quot;).  Unless otherwise 
+indicated below, the Content is provided to you under the terms and conditions of the
+Eclipse Public License Version 1.0 (&quot;EPL&quot;).  A copy of the EPL is available 
+at <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a>.
+For purposes of the EPL, &quot;Program&quot; will mean the Content.</p>
+
+<p>If you did not receive this Content directly from the Eclipse Foundation, the Content is 
+being redistributed by another party (&quot;Redistributor&quot;) and different terms and conditions may
+apply to your use of any object code in the Content.  Check the Redistributor's license that was 
+provided with the Content.  If no such license exists, contact the Redistributor.  Unless otherwise
+indicated below, the terms and conditions of the EPL still apply to any source code in the Content
+and such source code may be obtained at <a href="http://www.eclipse.org">http://www.eclipse.org</a>.</p>
+
+</body>
+</html>
\ No newline at end of file
diff --git a/plugins/org.eclipse.datatools.connectivity.oda.flatfile.ui/build.properties b/plugins/org.eclipse.datatools.connectivity.oda.flatfile.ui/build.properties
new file mode 100644
index 0000000..75c9ca5
--- /dev/null
+++ b/plugins/org.eclipse.datatools.connectivity.oda.flatfile.ui/build.properties
@@ -0,0 +1,10 @@
+source.. = src/
+output.. = bin/
+bin.includes = plugin.xml,\
+               .,\
+               about.html,\
+               icons/,\
+               META-INF/,\
+               plugin.properties
+download.dir =           ./download/
+src.includes = about.html
diff --git a/plugins/org.eclipse.datatools.connectivity.oda.flatfile.ui/icons/fieldlist.ico b/plugins/org.eclipse.datatools.connectivity.oda.flatfile.ui/icons/fieldlist.ico
new file mode 100644
index 0000000..d1ae146
--- /dev/null
+++ b/plugins/org.eclipse.datatools.connectivity.oda.flatfile.ui/icons/fieldlist.ico
Binary files differ
diff --git a/plugins/org.eclipse.datatools.connectivity.oda.flatfile.ui/icons/file.gif b/plugins/org.eclipse.datatools.connectivity.oda.flatfile.ui/icons/file.gif
new file mode 100644
index 0000000..6b86d07
--- /dev/null
+++ b/plugins/org.eclipse.datatools.connectivity.oda.flatfile.ui/icons/file.gif
Binary files differ
diff --git a/plugins/org.eclipse.datatools.connectivity.oda.flatfile.ui/icons/profile.gif b/plugins/org.eclipse.datatools.connectivity.oda.flatfile.ui/icons/profile.gif
new file mode 100644
index 0000000..6b86d07
--- /dev/null
+++ b/plugins/org.eclipse.datatools.connectivity.oda.flatfile.ui/icons/profile.gif
Binary files differ
diff --git a/plugins/org.eclipse.datatools.connectivity.oda.flatfile.ui/plugin.properties b/plugins/org.eclipse.datatools.connectivity.oda.flatfile.ui/plugin.properties
new file mode 100644
index 0000000..789db5c
--- /dev/null
+++ b/plugins/org.eclipse.datatools.connectivity.oda.flatfile.ui/plugin.properties
@@ -0,0 +1,27 @@
+###############################################################################
+# Copyright (c) 2005, 2007 Actuate Corporation.
+# 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:
+#  Actuate Corporation - initial API and implementation
+#
+###############################################################################
+# Plug-in Profile Configuration
+#
+oda.data.source.id=org.eclipse.datatools.connectivity.oda.flatfile
+#
+###############################################################################
+# NLS messages
+#
+plugin.name=Eclipse Data Tools Platform Flat File ODA Designer
+newwizard.name=Flat File Data Source
+newwizard.description=Create an ODA Flat File connection profile
+wizard.window.title=New Flat File Data Source Profile
+wizard.data.source.page.title=Define Folder or a File URI
+profile.propertypage.name=Flat File Data Source Connection Properties
+wizard.data.set.page.title=Select Columns
+wizard.data.set.title=Select Table
+
diff --git a/plugins/org.eclipse.datatools.connectivity.oda.flatfile.ui/plugin.xml b/plugins/org.eclipse.datatools.connectivity.oda.flatfile.ui/plugin.xml
new file mode 100644
index 0000000..828d538
--- /dev/null
+++ b/plugins/org.eclipse.datatools.connectivity.oda.flatfile.ui/plugin.xml
@@ -0,0 +1,83 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<?eclipse version="3.0"?>
+<!--
+/**
+ *************************************************************************
+ * Copyright (c) 2006, 2008 Actuate Corporation.
+ * 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:
+ *  Actuate Corporation - initial API and implementation
+ *  
+ *************************************************************************
+ *
+ * $Id: plugin.xml,v 1.20 2007/09/12 18:49:39 lzhu Exp $
+ */
+-->
+
+<plugin>
+
+   <extension
+         point="org.eclipse.datatools.connectivity.connectionProfile">
+      <newWizard
+            id="%oda.data.source.id"
+            name="%newwizard.name"
+            class="org.eclipse.datatools.connectivity.oda.design.ui.wizards.NewDataSourceWizard"
+            description="%newwizard.description"
+            icon="icons/fieldlist.ico"
+            profile="%oda.data.source.id"/>
+   </extension>
+   <extension
+         point="org.eclipse.datatools.connectivity.ui.connectionProfileImage">
+      <profileImage
+            profileID="%oda.data.source.id"
+            icon="icons/profile.gif">
+      </profileImage>
+   </extension>
+   <extension
+         point="org.eclipse.ui.propertyPages">
+      <page
+            id="%oda.data.source.id"
+            name="%profile.propertypage.name"
+            class="org.eclipse.datatools.connectivity.oda.flatfile.ui.wizards.FolderPropertyPage">
+         <enabledWhen>
+            <instanceof
+                  value="org.eclipse.datatools.connectivity.IConnectionProfile">
+            </instanceof>
+         </enabledWhen>
+         <filter
+               name="org.eclipse.datatools.profile.property.id"
+               value="%oda.data.source.id"/>
+      </page>
+   </extension>
+   
+   <extension
+         point="org.eclipse.datatools.connectivity.oda.design.ui.dataSource">
+      <dataSourceUI id="%oda.data.source.id">
+         <newDataSourceWizard
+               includesProgressMonitor="false"
+               pageClass="org.eclipse.datatools.connectivity.oda.flatfile.ui.wizards.FolderSelectionWizardPage"
+               pageTitle="%wizard.data.source.page.title"
+               windowTitle="%wizard.window.title"/>
+      </dataSourceUI>
+      <dataSetUI
+            id="org.eclipse.datatools.connectivity.oda.flatfile.dataSet"
+            initialPageId="oda.flatfile.ui.tablePage"
+            supportsInParameters="false"
+            supportsOutParameters="false">
+         <dataSetWizard
+               class="org.eclipse.datatools.connectivity.oda.design.ui.wizards.DataSetWizard"
+               windowTitle="%wizard.data.set.title"/>
+         <dataSetPage
+               displayName="%wizard.data.set.page.title"
+               icon="icons/file.gif"
+               id="oda.flatfile.ui.tablePage"
+               path="/"
+               wizardPageClass="org.eclipse.datatools.connectivity.oda.flatfile.ui.wizards.FileSelectionWizardPage"/>
+      </dataSetUI>
+   </extension>
+
+</plugin>
diff --git a/plugins/org.eclipse.datatools.connectivity.oda.flatfile.ui/src/org/eclipse/datatools/connectivity/oda/flatfile/ui/FlatFileUIPlugin.java b/plugins/org.eclipse.datatools.connectivity.oda.flatfile.ui/src/org/eclipse/datatools/connectivity/oda/flatfile/ui/FlatFileUIPlugin.java
new file mode 100644
index 0000000..16fdf72
--- /dev/null
+++ b/plugins/org.eclipse.datatools.connectivity.oda.flatfile.ui/src/org/eclipse/datatools/connectivity/oda/flatfile/ui/FlatFileUIPlugin.java
@@ -0,0 +1,30 @@
+/*
+ *************************************************************************
+ * Copyright (c) 2005, 2006 Actuate Corporation.
+ * 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:
+ *  Actuate Corporation  - initial API and implementation
+ *  
+ *************************************************************************
+ */
+
+package org.eclipse.datatools.connectivity.oda.flatfile.ui;
+
+import org.eclipse.core.runtime.Plugin;
+import org.osgi.framework.BundleContext;
+
+public class FlatFileUIPlugin extends Plugin
+{
+    public void start( BundleContext context ) throws Exception
+    {
+        super.start( context );
+        if( isDebugging() )
+        {
+            // TODO - set up logger based on debug option
+        }
+    }
+}
diff --git a/plugins/org.eclipse.datatools.connectivity.oda.flatfile.ui/src/org/eclipse/datatools/connectivity/oda/flatfile/ui/i18n/.gitignore b/plugins/org.eclipse.datatools.connectivity.oda.flatfile.ui/src/org/eclipse/datatools/connectivity/oda/flatfile/ui/i18n/.gitignore
new file mode 100644
index 0000000..4ea9b43
--- /dev/null
+++ b/plugins/org.eclipse.datatools.connectivity.oda.flatfile.ui/src/org/eclipse/datatools/connectivity/oda/flatfile/ui/i18n/.gitignore
@@ -0,0 +1 @@
+messages_*.properties
diff --git a/plugins/org.eclipse.datatools.connectivity.oda.flatfile.ui/src/org/eclipse/datatools/connectivity/oda/flatfile/ui/i18n/Messages.java b/plugins/org.eclipse.datatools.connectivity.oda.flatfile.ui/src/org/eclipse/datatools/connectivity/oda/flatfile/ui/i18n/Messages.java
new file mode 100644
index 0000000..37303ad
--- /dev/null
+++ b/plugins/org.eclipse.datatools.connectivity.oda.flatfile.ui/src/org/eclipse/datatools/connectivity/oda/flatfile/ui/i18n/Messages.java
@@ -0,0 +1,48 @@
+/*
+ *************************************************************************
+ * Copyright (c) 2005, 2006 Actuate Corporation.
+ * 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:
+ *  Actuate Corporation  - initial API and implementation
+ *  
+ *************************************************************************
+ */
+
+package org.eclipse.datatools.connectivity.oda.flatfile.ui.i18n;
+
+import java.text.MessageFormat;
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
+
+public class Messages
+{
+    private static final String BUNDLE_NAME = "org.eclipse.datatools.connectivity.oda.flatfile.ui.i18n.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 getFormattedString( String key, Object[] arguments )
+    {
+        return MessageFormat.format( getString( key ), arguments );
+    }
+}
diff --git a/plugins/org.eclipse.datatools.connectivity.oda.flatfile.ui/src/org/eclipse/datatools/connectivity/oda/flatfile/ui/i18n/messages.properties b/plugins/org.eclipse.datatools.connectivity.oda.flatfile.ui/src/org/eclipse/datatools/connectivity/oda/flatfile/ui/i18n/messages.properties
new file mode 100644
index 0000000..926adef
--- /dev/null
+++ b/plugins/org.eclipse.datatools.connectivity.oda.flatfile.ui/src/org/eclipse/datatools/connectivity/oda/flatfile/ui/i18n/messages.properties
@@ -0,0 +1,121 @@
+#
+#************************************************************************
+# Copyright (c) 2006, 2012 Actuate Corporation.
+# 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:
+#  Actuate Corporation - initial API and implementation
+#  
+#************************************************************************
+#
+wizard.title.selectColumns=Select Columns
+wizard.defaultMessage.selectFile=Select the file and the columns for the data set.
+wizard.WizardTitle.DEFAULT_MESSAGE=Select a folder that contains the flat files or enter an URI for the flat file.
+
+FolderSelectionPageHelper.SelectFolderDialog.Title=Select a folder that contains the flat files or enter an URI for the flat file.
+
+label.selectFolder=S&elect home folder: 
+label.fileURI=Enter file &URI:
+lable.fileURI.tooltip=Enter a URI for the file or select a local file. 
+label.selectFile=Select f&ile:
+label.fileFilter=File filte&r:
+label.includeTypeLine=Use second line as &data type indicator.
+label.includeColumnNameLine = Use first line &as column name indicator.
+label.selectCharset=Select &charset:
+label.selectFlatfileStyle=Select flatfile &style:
+label.flatfileComma=CSV
+label.flatfileSemicolon=SSV
+label.flatfilePipe=PSV
+label.flatfileTab=TSV
+label.trailNull=Use trailing nu&ll columns.
+
+button.selectFolder.browse=B&rowse...
+button.selectFileURI.browse=B&rowse...
+button.selectFileURI.menuItem.relativePath=&Relative path
+button.selectFileURI.menuItem.absolutePath=&Absolute path
+button.selectFileURI.browse.tooltips=Select a local file URI.
+button.moveUp=&Up
+button.moveDown=Do&wn
+button.delete=D&elete
+
+editor.title.name=Name
+editor.title.originalName=Original Name
+editor.title.type=Type
+
+
+datatypes.dateTime=Date Time
+datatypes.decimal=Decimal
+datatypes.float=Float
+datatypes.integer=Integer
+datatypes.string=String
+datatypes.date=Date
+datatypes.time=Time
+datatypes.boolean=Boolean
+
+tooltip.flatfilestyle=Move the mouse to each flat file style for more infomation.
+tooltip.csv=Comma-{ , } Seperated Values
+tooltip.ssv=Semicolon-{ ; } Seperated Values
+tooltip.psv=Pipe-{ | } Seperated Values
+tooltip.tsv=Tab-{ Tab } Seperated Values
+tooltip.columnnameline=Please make sure the existence of column names\n in the first row of the selected file.
+tooltip.typeline=Please make sure the existence of data type line\n in the second row of the selected file.
+tooltip.button.add=Add all the selected columns from the left table to the flat file data set.
+tooltip.button.AddAll=Add all the available columns from the left table to the flat file data set.
+tooltip.button.remove=Remove the selected item(s).
+tooltip.button.RemoveAll=Clear all the selected items.
+tooltip.button.up=Move up the selected item.
+tooltip.button.down=Move down the selected item.
+tooltip.button.delete=Delete the selected item.
+tooltip.trailNull=Use trailing null columns when reading lines of data. 
+error.selectFolder=Please select a valid folder.
+error.selectColumns=Please select at least one column for this data set.
+error.emptyPath=Please enter a path.
+error.unexpectedError=An unexpected error happened.
+error.invalidConnectionFilePath=The specified connection profile source path, "{0}", does not exist.
+error.invalidFlatFilePath=Invalid flat file data source path. Please correct the connection profile.
+error.emptyFolderPath=Please select a folder that contains the flat files.
+error.emptyFileURIPath=Please enter the URI or select a source flat file.
+error.errorExist=Error exists in the current page.  Would you like to save it anyway?
+error.noCSVFiles=The folder, "{0}", does not have any specified files in it.
+error.invalidFilePath=The file path is invalid.  Would you like to continue?
+error.emptyFilePath=The file path is empty.  Would you like to continue?
+error.duplicatedNameValueOrEmpty=Duplicated Name Value or Empty
+error.invalidSavedColumnsInfo = Invalid saved Columns Info
+error.invalidColumnName=Invalid Column Name
+error.invalidQureyText=Invalid Query-Text
+error.invalidURIPath=The URI entered is invalid.
+error.URIConnectionFailure=Cannot open connection to the URI resource.
+ 
+
+title.warning=Warning
+warning.fileExtensionInvalid=The selected file might not be a valid flat file.
+confirm.reselectFileFilterTitle=Confirm to select a different file filter.
+confirm.reselectFileFilterMessage=Selecting a different file filter will leave previous operations unsaved.\n\nAre you sure?
+
+confirm.reselectFileNameTitle=Confirm to select a different flat file.
+confirm.reselectFileNameMessage=Do you want to preserve the columns selection the same as the current definition?
+warning.columnNotExist=The selected column "{0}" does not exist!
+
+fileURIChanged.warning.reselectColumnsTitle=File URI in the data source is changed.
+fileURIChanged.warning.reselectColumnsMessage=File URI in the data source is changed!\nPlease select columns again.
+Connection.warning.untested=Please test connection before saving this data source profile.
+Connection.error.invalidPath=No valid flat file locations found.
+Connection.error.invalidHomeFolder=Invalid flat file home folder <{0}>.
+Connection.error.invalidFileURI=Invalid flat file URI path <{0}>.
+
+FileSelectionWizardPage.label.columnName=&Column Name:
+FileSelectionWizardPage.label.originalName=Original Name:
+FileSelectionWizardPage.label.dataType=&Data Type:
+
+FileSelectionWizardPage.MenuItem.remove=Remove
+FileSelectionWizardPage.MenuItem.removeAll=Remove All
+
+FileSelectionWizardPage.error.selectColumn.EmptyName=The column name cannot be empty!
+FileSelectionWizardPage.error.selectColumn.duplicatedFileName=The specified column name is duplicated!
+FileSelectionWizardPage.error.selectColumn.NoColumnSelected=At least one column should be selected.
+FileSelectionWizardPage.error.selectColumn.numberName=Column Name can not be a number.
+
+RelativeFileSelectionDialog.Title.SelectFile=Select File
diff --git a/plugins/org.eclipse.datatools.connectivity.oda.flatfile.ui/src/org/eclipse/datatools/connectivity/oda/flatfile/ui/util/IHelpConstants.java b/plugins/org.eclipse.datatools.connectivity.oda.flatfile.ui/src/org/eclipse/datatools/connectivity/oda/flatfile/ui/util/IHelpConstants.java
new file mode 100644
index 0000000..d819fae
--- /dev/null
+++ b/plugins/org.eclipse.datatools.connectivity.oda.flatfile.ui/src/org/eclipse/datatools/connectivity/oda/flatfile/ui/util/IHelpConstants.java
@@ -0,0 +1,32 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2007 Actuate Corporation.
+ * 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:
+ *  Actuate Corporation - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.datatools.connectivity.oda.flatfile.ui.util;
+
+/**
+ * 
+ */
+
+public interface IHelpConstants
+{
+
+	public static final String PREFIX = "org.eclipse.datatools.oda.cshelp" + "."; //$NON-NLS-1$ //$NON-NLS-2$
+
+	public static final String CONEXT_ID_DATASOURCE_FLATFILE = PREFIX
+			+ "Wizard_FlatfileDatasource_ID";//$NON-NLS-1$
+
+	public static final String CONEXT_ID_DATASET_FLATFILE = PREFIX
+			+ "Dialog_SelectTableColumn_ID";//$NON-NLS-1$
+
+	public static final String CONEXT_ID_COLUMN_EDIT_DIALOG_FLATFILE = PREFIX
+			+ "Dialog_ColumnEditDialog_ID";//$NON-NLS-1$
+
+}
diff --git a/plugins/org.eclipse.datatools.connectivity.oda.flatfile.ui/src/org/eclipse/datatools/connectivity/oda/flatfile/ui/util/Utility.java b/plugins/org.eclipse.datatools.connectivity.oda.flatfile.ui/src/org/eclipse/datatools/connectivity/oda/flatfile/ui/util/Utility.java
new file mode 100644
index 0000000..b9ababf
--- /dev/null
+++ b/plugins/org.eclipse.datatools.connectivity.oda.flatfile.ui/src/org/eclipse/datatools/connectivity/oda/flatfile/ui/util/Utility.java
@@ -0,0 +1,37 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2006 Actuate Corporation.
+ * 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:
+ *  Actuate Corporation - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.datatools.connectivity.oda.flatfile.ui.util;
+
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.ui.PlatformUI;
+
+/**
+ * 
+ */
+
+public class Utility
+{
+
+	/**
+	 * Set context-sensitive help
+	 * 
+	 * @param control
+	 * @param contextId
+	 */
+	public static void setSystemHelp( Control control, String contextId )
+	{
+		PlatformUI.getWorkbench( )
+				.getHelpSystem( )
+				.setHelp( control, contextId );
+	}
+
+}
diff --git a/plugins/org.eclipse.datatools.connectivity.oda.flatfile.ui/src/org/eclipse/datatools/connectivity/oda/flatfile/ui/wizards/FileSelectionWizardPage.java b/plugins/org.eclipse.datatools.connectivity.oda.flatfile.ui/src/org/eclipse/datatools/connectivity/oda/flatfile/ui/wizards/FileSelectionWizardPage.java
new file mode 100644
index 0000000..11d7b1a
--- /dev/null
+++ b/plugins/org.eclipse.datatools.connectivity.oda.flatfile.ui/src/org/eclipse/datatools/connectivity/oda/flatfile/ui/wizards/FileSelectionWizardPage.java
@@ -0,0 +1,2520 @@
+/*
+ *************************************************************************
+ * Copyright (c) 2006, 2011 Actuate Corporation.
+ * 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:
+ *  Actuate Corporation - initial API and implementation
+ *  
+ *************************************************************************
+ */
+
+package org.eclipse.datatools.connectivity.oda.flatfile.ui.wizards;
+
+import java.io.File;
+import java.io.FilenameFilter;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.datatools.connectivity.oda.IConnection;
+import org.eclipse.datatools.connectivity.oda.IDriver;
+import org.eclipse.datatools.connectivity.oda.IQuery;
+import org.eclipse.datatools.connectivity.oda.IResultSetMetaData;
+import org.eclipse.datatools.connectivity.oda.OdaException;
+import org.eclipse.datatools.connectivity.oda.design.DataSetDesign;
+import org.eclipse.datatools.connectivity.oda.design.DataSourceDesign;
+import org.eclipse.datatools.connectivity.oda.design.DesignFactory;
+import org.eclipse.datatools.connectivity.oda.design.Properties;
+import org.eclipse.datatools.connectivity.oda.design.ResultSetColumns;
+import org.eclipse.datatools.connectivity.oda.design.ResultSetDefinition;
+import org.eclipse.datatools.connectivity.oda.design.ui.designsession.DesignSessionUtil;
+import org.eclipse.datatools.connectivity.oda.design.ui.wizards.DataSetWizardPage;
+import org.eclipse.datatools.connectivity.oda.design.util.DesignUtil;
+import org.eclipse.datatools.connectivity.oda.flatfile.CommonConstants;
+import org.eclipse.datatools.connectivity.oda.flatfile.FlatFileDriver;
+import org.eclipse.datatools.connectivity.oda.flatfile.InvalidResourceException;
+import org.eclipse.datatools.connectivity.oda.flatfile.ResourceLocator;
+import org.eclipse.datatools.connectivity.oda.flatfile.ui.i18n.Messages;
+import org.eclipse.datatools.connectivity.oda.flatfile.ui.util.IHelpConstants;
+import org.eclipse.datatools.connectivity.oda.flatfile.ui.util.Utility;
+import org.eclipse.datatools.connectivity.oda.flatfile.util.querytextutil.ColumnsInfoUtil;
+import org.eclipse.datatools.connectivity.oda.flatfile.util.querytextutil.QueryTextUtil;
+import org.eclipse.datatools.connectivity.oda.util.ResourceIdentifiers;
+import org.eclipse.datatools.connectivity.oda.util.manifest.ConnectionProfileProperty;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.jface.dialogs.StatusDialog;
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.jface.viewers.ArrayContentProvider;
+import org.eclipse.jface.viewers.ComboViewer;
+import org.eclipse.jface.viewers.DoubleClickEvent;
+import org.eclipse.jface.viewers.IDoubleClickListener;
+import org.eclipse.jface.viewers.ILabelProviderListener;
+import org.eclipse.jface.viewers.ISelectionChangedListener;
+import org.eclipse.jface.viewers.IStructuredContentProvider;
+import org.eclipse.jface.viewers.ITableLabelProvider;
+import org.eclipse.jface.viewers.LabelProvider;
+import org.eclipse.jface.viewers.SelectionChangedEvent;
+import org.eclipse.jface.viewers.StructuredSelection;
+import org.eclipse.jface.viewers.TableViewer;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.jface.window.Window;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.CCombo;
+import org.eclipse.swt.custom.ScrolledComposite;
+import org.eclipse.swt.events.KeyEvent;
+import org.eclipse.swt.events.KeyListener;
+import org.eclipse.swt.events.MenuAdapter;
+import org.eclipse.swt.events.MenuEvent;
+import org.eclipse.swt.events.ModifyEvent;
+import org.eclipse.swt.events.ModifyListener;
+import org.eclipse.swt.events.MouseAdapter;
+import org.eclipse.swt.events.MouseEvent;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.layout.FillLayout;
+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.Label;
+import org.eclipse.swt.widgets.List;
+import org.eclipse.swt.widgets.Menu;
+import org.eclipse.swt.widgets.MenuItem;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.widgets.TableColumn;
+import org.eclipse.swt.widgets.TableItem;
+import org.eclipse.swt.widgets.Text;
+import org.eclipse.ui.PlatformUI;
+
+/**
+ * Extends the ODA design ui framework to provide a driver-specific custom
+ * editor page to create or edit an ODA data set design instance.
+ */
+public class FileSelectionWizardPage extends DataSetWizardPage
+{
+
+	private static String DEFAULT_MESSAGE = Messages.getString( "wizard.defaultMessage.selectFile" ); //$NON-NLS-1$
+	private static final String ALL_CSV_EXTENSION = "*.csv"; //$NON-NLS-1$
+	private static final String CSV_EXTENSION = ".csv"; //$NON-NLS-1$
+	private static final String ALL_SSV_EXTENSION = "*.ssv"; //$NON-NLS-1$
+	private static final String SSV_EXTENSION = ".ssv"; //$NON-NLS-1$
+	private static final String ALL_TSV_EXTENSION = "*.tsv"; //$NON-NLS-1$
+	private static final String TSV_EXTENSION = ".tsv"; //$NON-NLS-1$
+	private static final String ALL_PSV_EXTENSION = "*.psv"; //$NON-NLS-1$
+	private static final String PSV_EXTENSION = ".psv"; //$NON-NLS-1$
+	private static final String ALL_TXT_EXTENSION = "*.txt"; //$NON-NLS-1$
+	private static final String TXT_EXTENSION = ".txt"; //$NON-NLS-1$
+	private static final String MATCH_ALL_FILES = "*.*"; //$NON-NLS-1$
+
+	private static final String queryTextDelimiter = ":"; //$NON-NLS-1$
+	private static final String columnsInfoStartSymbol = "{"; //$NON-NLS-1$
+	private static final String columnsInfoEndSymbol = "}"; //$NON-NLS-1$
+
+	private static String[] dataTypeDisplayNames = new String[]{
+			Messages.getString( "datatypes.dateTime" ), //$NON-NLS-1$
+			Messages.getString( "datatypes.decimal" ), //$NON-NLS-1$
+			Messages.getString( "datatypes.float" ), //$NON-NLS-1$
+			Messages.getString( "datatypes.integer" ), //$NON-NLS-1$
+			Messages.getString( "datatypes.date" ), //$NON-NLS-1$
+			Messages.getString( "datatypes.time" ), //$NON-NLS-1$
+			Messages.getString( "datatypes.string" ), //$NON-NLS-1$
+			Messages.getString( "datatypes.boolean" ) //$NON-NLS-1$
+	};
+
+	private HashMap<Integer, String> dataTypeDisplayNameMap = new HashMap<Integer, String>( );
+
+	private HashMap<String, String> dataTypeValueMape = new HashMap<String, String>( );
+
+	private HashMap<String, Boolean> flatFileStatusCache = new HashMap<String, Boolean>( );
+
+	private transient ComboViewer fileViewer = null;
+	private transient ComboViewer fileFilter = null;
+	private transient List availableList = null;
+	private transient TableViewer selectedColumnsViewer = null;
+	private transient Button btnAdd, btnAddAll, btnRemove, btnRemoveAll,
+			btnMoveUp, btnMoveDown;
+	private boolean initialized = true;
+
+	private String odaHome;
+	private String fileURI;
+	private String charSet = null;
+	private String inclColumnNameLine;
+	private String flatfileDelimiterType;
+	private String inclTypeLine;
+	private String savedSelectedColumnsInfoString;
+	private String trailNullCols;
+
+	/** store latest selected file */
+	private String selectedFileFilter;
+
+	/** store latest selected file */
+	private Object selectedFile;
+
+	private String nameOfFileWithErrorInLastAccess = null;
+
+	private java.util.List<String[]> originalFileColumnsInfoList = new ArrayList<String[]>( );
+	private java.util.List<String[]> savedSelectedColumnsInfoList = new ArrayList<String[]>( );
+
+	/**
+	 * @param pageName
+	 */
+	public FileSelectionWizardPage( String pageName )
+	{
+		super( pageName );
+		setTitle( pageName );
+		createColumnTypeMap( );
+		setMessage( DEFAULT_MESSAGE );
+
+		setPageComplete( false );
+	}
+
+	/**
+	 * @param pageName
+	 * @param title
+	 * @param titleImage
+	 */
+	public FileSelectionWizardPage( String pageName, String title,
+			ImageDescriptor titleImage )
+	{
+		super( pageName, title, titleImage );
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see
+	 * org.eclipse.datatools.connectivity.oda.design.ui.wizards.DataSetWizardPage
+	 * #createPageCustomControl(org.eclipse.swt.widgets.Composite)
+	 */
+	public void createPageCustomControl( Composite parent )
+	{
+		ScrolledComposite sComposite = new ScrolledComposite( parent,
+				SWT.H_SCROLL | SWT.V_SCROLL );
+		sComposite.setLayout( new FillLayout( ) );
+		sComposite.setLayoutData( new GridData( GridData.FILL_BOTH ) );
+		sComposite.setMinWidth( 560 );
+		sComposite.setExpandHorizontal( true );
+		sComposite.setMinHeight( 300 );
+		sComposite.setExpandVertical( true );
+
+		Composite control = createPageControl( sComposite );
+
+		initializeControl( );
+
+		Point size = control.computeSize( SWT.DEFAULT, SWT.DEFAULT );
+		control.setSize( size.x, size.y );
+
+		sComposite.setContent( control );
+		setControl( sComposite );
+
+		updateButtonStatus( );
+		validatePageStatus( );
+
+		Utility.setSystemHelp( getControl( ),
+				IHelpConstants.CONEXT_ID_DATASET_FLATFILE );
+	}
+
+	/**
+	 * 
+	 * 
+	 */
+	private void createColumnTypeMap( )
+	{
+		dataTypeDisplayNameMap.put( new Integer( 4 ),
+				Messages.getString( "datatypes.integer" ) ); //$NON-NLS-1$
+		dataTypeDisplayNameMap.put( new Integer( 8 ),
+				Messages.getString( "datatypes.float" ) ); //$NON-NLS-1$
+		dataTypeDisplayNameMap.put( new Integer( 12 ),
+				Messages.getString( "datatypes.string" ) ); //$NON-NLS-1$
+		dataTypeDisplayNameMap.put( new Integer( 91 ),
+				Messages.getString( "datatypes.date" ) ); //$NON-NLS-1$
+		dataTypeDisplayNameMap.put( new Integer( 92 ),
+				Messages.getString( "datatypes.time" ) ); //$NON-NLS-1$
+		dataTypeDisplayNameMap.put( new Integer( 93 ),
+				Messages.getString( "datatypes.dateTime" ) ); //$NON-NLS-1$
+		dataTypeDisplayNameMap.put( new Integer( 2 ),
+				Messages.getString( "datatypes.decimal" ) ); //$NON-NLS-1$
+		dataTypeDisplayNameMap.put( new Integer( 16 ),
+				Messages.getString( "datatypes.boolean" ) ); //$NON-NLS-1$
+
+		dataTypeValueMape.put( Messages.getString( "datatypes.integer" ), "INT" ); //$NON-NLS-1$ //$NON-NLS-2$
+		dataTypeValueMape.put( Messages.getString( "datatypes.float" ), //$NON-NLS-1$
+				"DOUBLE" ); //$NON-NLS-1$
+		dataTypeValueMape.put( Messages.getString( "datatypes.string" ), //$NON-NLS-1$
+				"STRING" ); //$NON-NLS-1$
+		dataTypeValueMape.put( Messages.getString( "datatypes.date" ), "DATE" ); //$NON-NLS-1$ //$NON-NLS-2$
+		dataTypeValueMape.put( Messages.getString( "datatypes.time" ), "TIME" ); //$NON-NLS-1$ //$NON-NLS-2$
+		dataTypeValueMape.put( Messages.getString( "datatypes.dateTime" ), //$NON-NLS-1$
+				"TIMESTAMP" ); //$NON-NLS-1$
+		dataTypeValueMape.put( Messages.getString( "datatypes.decimal" ), //$NON-NLS-1$
+				"BIGDECIMAL" ); //$NON-NLS-1$
+		dataTypeValueMape.put( Messages.getString( "datatypes.boolean" ), //$NON-NLS-1$
+				"BOOLEAN" ); //$NON-NLS-1$
+	}
+
+	/**
+	 * 
+	 *
+	 */
+	private void initializeControl( )
+	{
+		/*
+		 * Optionally restores the state of a previous design session. Obtains
+		 * designer state, using getInitializationDesignerState();
+		 */
+
+		DataSetDesign dataSetDesign = getInitializationDesign( );
+		if ( dataSetDesign == null )
+			return; // nothing to initialize
+
+		updateFileFilterComboStatus( dataSetDesign );
+
+		String queryText = dataSetDesign.getQueryText( );
+		if ( queryText == null )
+			return; // nothing to initialize
+
+		updateValuesFromQuery( queryText );
+
+		/*
+		 * Optionally honor the request for an editable or read-only design
+		 * session isSessionEditable();
+		 */
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see
+	 * org.eclipse.datatools.connectivity.oda.design.ui.wizards.DataSetWizardPage
+	 * #collectDataSetDesign(org.eclipse.datatools.connectivity.oda.design.
+	 * DataSetDesign)
+	 */
+	protected DataSetDesign collectDataSetDesign( DataSetDesign design )
+	{
+		// if this page in DataSetEditor hasn't been activated
+		if ( fileViewer == null )
+			return design;
+
+		savePage( design );
+		return design;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see
+	 * org.eclipse.datatools.connectivity.oda.design.internal.ui.DataSetWizardPage
+	 * #collectResponseState()
+	 */
+	protected void collectResponseState( )
+	{
+		super.collectResponseState( );
+		/*
+		 * Optionally assigns custom response state, for inclusion in the ODA
+		 * design session response, using setResponseSessionStatus(
+		 * SessionStatus status ) setResponseDesignerState( DesignerState
+		 * customState );
+		 */
+	}
+
+	/**
+	 * 
+	 * @param parent
+	 * @return
+	 */
+	private Composite createPageControl( Composite parent )
+	{
+
+		Composite mainComposite = new Composite( parent, SWT.NONE );
+		mainComposite.setLayout( new GridLayout( ) );
+		mainComposite.setLayoutData( new GridData( GridData.FILL_BOTH ) );
+
+		createTopComposite( mainComposite );
+
+		Composite composite = new Composite( mainComposite, SWT.NONE );
+		GridLayout layout = new GridLayout( );
+		layout.numColumns = 4;
+		composite.setLayout( layout );
+		composite.setLayoutData( new GridData( GridData.FILL_BOTH ) );
+
+		createLeftComposite( composite );
+
+		createCenterBtnComposite( composite );
+
+		createRightTableComposite( composite );
+
+		createEditBtnGroup( composite );
+
+		loadProperties( );
+		populateFileFilter( );
+		updateFileListAndCharSet( );
+		selectFileChanged( );
+
+		return mainComposite;
+	}
+
+	/**
+	 * Create the top composite of the page
+	 * 
+	 * @param composite
+	 * @param label
+	 */
+	private void createTopComposite( Composite parent )
+	{
+		Composite composite = new Composite( parent, SWT.NONE );
+		GridLayout layout = new GridLayout( );
+		layout.numColumns = 4;
+		composite.setLayout( layout );
+		composite.setLayoutData( new GridData( GridData.FILL_HORIZONTAL ) );
+
+		Label label = new Label( composite, SWT.NONE );
+		label.setText( Messages.getString( "label.selectFile" ) ); //$NON-NLS-1$
+		label.setLayoutData( new GridData( ) );
+
+		fileViewer = new ComboViewer( composite, SWT.BORDER | SWT.READ_ONLY );
+		fileViewer.getControl( )
+				.setLayoutData( new GridData( GridData.FILL_HORIZONTAL ) );
+		fileViewer.setContentProvider( new ArrayContentProvider( ) );
+		fileViewer.getCombo( ).addSelectionListener( new SelectionListener( ){
+
+			public void widgetDefaultSelected( SelectionEvent arg0 )
+			{
+				
+			}
+
+			public void widgetSelected( SelectionEvent arg0 )
+			{
+				selectFileChanged( );
+			}
+			
+		});
+		fileViewer.setLabelProvider( new LabelProvider( ) {
+
+			public String getText( Object element )
+			{
+				if ( element instanceof File )
+					return ( (File) element ).getName( );
+				if ( element instanceof String )
+					return (String) element;
+				return element.toString( );
+			}
+		} );
+
+		label = new Label( composite, SWT.NONE );
+		label.setText( Messages.getString( "label.fileFilter" ) ); //$NON-NLS-1$
+		label.setLayoutData( new GridData( ) );
+
+		fileFilter = new ComboViewer( composite, SWT.READ_ONLY );
+		fileFilter.getControl( )
+				.setLayoutData( new GridData( GridData.FILL_HORIZONTAL ) );
+		fileFilter.addSelectionChangedListener( new ISelectionChangedListener( ) {
+
+			public void selectionChanged( SelectionChangedEvent event )
+			{
+				if ( fileURI != null && fileURI.length( ) > 0 )
+					return;
+
+				String currSelectFilter = fileFilter.getCombo( ).getText( );
+				if ( currSelectFilter.equalsIgnoreCase( selectedFileFilter ) )
+					return;
+
+				if ( !initialized )
+				{
+					selectedFileFilter = currSelectFilter;
+					updateFileListAndCharSet( );
+					initialized = true;
+				}
+				else
+				{
+					if ( currSelectFilter.equals( MATCH_ALL_FILES )
+							|| MessageDialog.openConfirm( fileViewer.getCombo( )
+									.getShell( ),
+									Messages.getString( "confirm.reselectFileFilterTitle" ), //$NON-NLS-1$
+									Messages.getString( "confirm.reselectFileFilterMessage" ) ) ) //$NON-NLS-1$
+					{
+						selectedFileFilter = currSelectFilter;
+						updateFileListAndCharSet( );
+					}
+					else
+					{
+						fileFilter.getCombo( ).setText( selectedFileFilter );
+					}
+				}
+			}
+		} );
+	}
+
+	/**
+	 * Create the left composite of the page
+	 * 
+	 * @param composite
+	 */
+	private void createLeftComposite( Composite composite )
+	{
+		GridData gd = new GridData( GridData.FILL_BOTH );
+		gd.widthHint = 230;
+		gd.heightHint = 300;
+		availableList = new List( composite, SWT.MULTI
+				| SWT.BORDER
+				| SWT.H_SCROLL
+				| SWT.V_SCROLL );
+
+		availableList.setLayoutData( gd );
+		availableList.addSelectionListener( new SelectionAdapter( ) {
+
+			public void widgetSelected( SelectionEvent e )
+			{
+				selectedColumnsViewer.getTable( ).deselectAll( );
+				updateButtonStatus( );
+			}
+		} );
+
+		availableList.addMouseListener( new MouseAdapter( ) {
+
+			public void mouseDoubleClick( MouseEvent e )
+			{
+				addColumns( true );
+
+				updateButtonStatus( );
+				validatePageStatus( );
+			}
+		} );
+	}
+
+	/**
+	 * Create the middle button composite that displays ADD button
+	 * 
+	 * @param composite
+	 * @return
+	 */
+	private void createCenterBtnComposite( Composite composite )
+	{
+		Composite btnComposite = new Composite( composite, SWT.NONE );
+		GridLayout layout = new GridLayout( );
+		layout.verticalSpacing = 5;
+		btnComposite.setLayout( layout );
+
+		GridData gridData = new GridData( );
+		gridData.widthHint = 40;
+		btnAdd = new Button( btnComposite, SWT.NONE );
+		btnAdd.setLayoutData( gridData );
+		btnAdd.setText( ">" ); //$NON-NLS-1$
+		btnAdd.setToolTipText( Messages.getString( "tooltip.button.add" ) ); //$NON-NLS-1$
+
+		btnAdd.addSelectionListener( new SelectionAdapter( ) {
+
+			public void widgetSelected( SelectionEvent e )
+			{
+				addColumns( true );
+
+				updateButtonStatus( );
+				validatePageStatus( );
+			}
+		} );
+
+		gridData = new GridData( );
+		gridData.widthHint = 40;
+		btnAddAll = new Button( btnComposite, SWT.NONE );
+		btnAddAll.setLayoutData( gridData );
+		btnAddAll.setText( ">>" ); //$NON-NLS-1$
+		btnAddAll.setToolTipText( Messages.getString( "tooltip.button.AddAll" ) ); //$NON-NLS-1$
+
+		btnAddAll.addSelectionListener( new SelectionAdapter( ) {
+
+			public void widgetSelected( SelectionEvent e )
+			{
+				addAllAvailableColumns( );
+
+				updateButtonStatus( );
+				validatePageStatus( );
+			}
+		} );
+
+		gridData = new GridData( );
+		gridData.widthHint = 40;
+		btnRemove = new Button( btnComposite, SWT.NONE );
+		btnRemove.setLayoutData( gridData );
+		btnRemove.setText( "<" ); //$NON-NLS-1$
+		btnRemove.setToolTipText( Messages.getString( "tooltip.button.remove" ) ); //$NON-NLS-1$
+
+		btnRemove.addSelectionListener( new SelectionAdapter( ) {
+
+			public void widgetSelected( SelectionEvent e )
+			{
+				removeColumns( );
+				updateButtonStatus( );
+				validatePageStatus( );
+			}
+		} );
+
+		gridData = new GridData( );
+		gridData.widthHint = 40;
+		btnRemoveAll = new Button( btnComposite, SWT.NONE );
+		btnRemoveAll.setLayoutData( gridData );
+		btnRemoveAll.setText( "<<" ); //$NON-NLS-1$
+		btnRemoveAll.setToolTipText( Messages.getString( "tooltip.button.RemoveAll" ) ); //$NON-NLS-1$
+
+		btnRemoveAll.addSelectionListener( new SelectionAdapter( ) {
+
+			public void widgetSelected( SelectionEvent e )
+			{
+				removeAllColumns( );
+				updateButtonStatus( );
+				validatePageStatus( );
+			}
+		} );
+
+	}
+
+	/**
+	 * Create the right composite of the page
+	 * 
+	 * @param composite
+	 * @param btnComposite
+	 */
+	private void createRightTableComposite( Composite composite )
+	{
+		selectedColumnsViewer = new TableViewer( composite, SWT.MULTI
+				| SWT.FULL_SELECTION
+				| SWT.BORDER
+				| SWT.H_SCROLL
+				| SWT.V_SCROLL );
+		selectedColumnsViewer.getTable( ).setHeaderVisible( true );
+		selectedColumnsViewer.getTable( ).setLinesVisible( true );
+		selectedColumnsViewer.getTable( )
+				.setLayoutData( new GridData( GridData.FILL_BOTH ) );
+
+		TableColumn column = new TableColumn( selectedColumnsViewer.getTable( ),
+				SWT.NONE );
+		column.setText( Messages.getString( "editor.title.name" ) ); //$NON-NLS-1$
+		column.setWidth( 100 );
+		column = new TableColumn( selectedColumnsViewer.getTable( ), SWT.NONE );
+		column.setText( Messages.getString( "editor.title.originalName" ) ); //$NON-NLS-1$
+		column.setWidth( 100 );
+		column = new TableColumn( selectedColumnsViewer.getTable( ), SWT.NONE );
+		column.setText( Messages.getString( "editor.title.type" ) ); //$NON-NLS-1$
+		column.setWidth( 100 );
+
+		Menu menu = new Menu( selectedColumnsViewer.getTable( ) );
+		menu.addMenuListener( new MenuAdapter( ) {
+
+			public void menuShown( MenuEvent e )
+			{
+				selectedColumnsViewer.cancelEditing( );
+			}
+		} );
+
+		final MenuItem menuRemove = new MenuItem( menu, SWT.NONE );
+		menuRemove.setText( Messages.getString( "FileSelectionWizardPage.MenuItem.remove" ) ); //$NON-NLS-1$
+		menuRemove.setEnabled( selectedColumnsViewer.getTable( )
+				.getSelectionCount( ) > 0 );
+		menuRemove.addSelectionListener( new SelectionAdapter( ) {
+
+			public void widgetSelected( SelectionEvent e )
+			{
+				removeColumns( );
+				updateButtonStatus( );
+				validatePageStatus( );
+			}
+
+		} );
+		MenuItem menuRemoveAll = new MenuItem( menu, SWT.NONE );
+		menuRemoveAll.setText( Messages.getString( "FileSelectionWizardPage.MenuItem.removeAll" ) ); //$NON-NLS-1$
+		menuRemoveAll.addSelectionListener( new SelectionAdapter( ) {
+
+			public void widgetSelected( SelectionEvent e )
+			{
+				removeAllColumns( );
+				updateButtonStatus( );
+				validatePageStatus( );
+			}
+
+		} );
+
+		selectedColumnsViewer.getTable( ).setMenu( menu );
+
+		selectedColumnsViewer.getTable( )
+				.addSelectionListener( new SelectionAdapter( ) {
+
+					public void widgetSelected( SelectionEvent e )
+					{
+						menuRemove.setEnabled( selectedColumnsViewer.getTable( )
+								.getSelectionCount( ) > 0 );
+
+						availableList.deselectAll( );
+						updateButtonStatus( );
+
+					}
+				} );
+
+		selectedColumnsViewer.addDoubleClickListener( new IDoubleClickListener( ) {
+
+			public void doubleClick( DoubleClickEvent event )
+			{
+				doEdit( );
+			}
+
+		} );
+
+		selectedColumnsViewer.getTable( ).addKeyListener( new KeyListener( ) {
+
+			public void keyPressed( KeyEvent e )
+			{
+				if ( e.keyCode == SWT.DEL )
+				{
+					removeColumns( );
+					updateButtonStatus( );
+					validatePageStatus( );
+				}
+			}
+
+			public void keyReleased( KeyEvent e )
+			{
+
+			}
+		} );
+
+		setColumnsViewerContent( );
+
+		setColumnsViewerLabels( );
+
+	}
+
+	protected void doEdit( )
+	{
+		if ( selectedColumnsViewer.getTable( ).getSelection( ).length > 0 )
+		{
+			ColumnEditDialog editDialog = new ColumnEditDialog( PlatformUI.getWorkbench( )
+					.getDisplay( )
+					.getActiveShell( ) );
+
+			TableItem item = selectedColumnsViewer.getTable( ).getSelection( )[0];
+			editDialog.setInput( item.getText( 0 ),
+					item.getText( 1 ),
+					item.getText( 2 ) );
+
+			if ( editDialog.open( ) == Window.OK )
+			{
+				int index = selectedColumnsViewer.getTable( )
+						.getSelectionIndex( );
+
+				savedSelectedColumnsInfoList.set( index,
+						new String[]{
+								editDialog.getColumnName( ),
+								editDialog.getOriginalName( ),
+								editDialog.getDataType( )
+						} );
+
+				selectedColumnsViewer.refresh( );
+				validatePageStatus( );
+
+			}
+
+		}
+
+	}
+
+	/**
+	 * Create the right button group that displays the UP,DOWN and REMOVE
+	 * buttons
+	 * 
+	 * @param rightComposite
+	 */
+	private void createEditBtnGroup( Composite rightComposite )
+	{
+		Composite btnComposite = new Composite( rightComposite, SWT.NONE );
+		GridLayout layout = new GridLayout( );
+		layout.verticalSpacing = 5;
+		btnComposite.setLayout( layout );
+
+		btnMoveUp = new Button( btnComposite, SWT.NONE );
+		btnMoveUp.setText( Messages.getString( "button.moveUp" ) ); //$NON-NLS-1$
+		btnMoveUp.setToolTipText( Messages.getString( "tooltip.button.up" ) ); //$NON-NLS-1$
+		btnMoveUp.addSelectionListener( new SelectionAdapter( ) {
+
+			public void widgetSelected( SelectionEvent e )
+			{
+				moveUpItem( );
+			}
+		} );
+
+		btnMoveDown = new Button( btnComposite, SWT.NONE );
+		btnMoveDown.setText( Messages.getString( "button.moveDown" ) ); //$NON-NLS-1$
+		btnMoveDown.setToolTipText( Messages.getString( "tooltip.button.down" ) ); //$NON-NLS-1$
+		btnMoveDown.addSelectionListener( new SelectionAdapter( ) {
+
+			public void widgetSelected( SelectionEvent e )
+			{
+				moveDownItem( );
+			}
+		} );
+
+		resetButtonWidth( );
+	}
+
+	private void resetButtonWidth( )
+	{
+		int widthHint = btnMoveUp.computeSize( SWT.DEFAULT, SWT.DEFAULT ).x;
+		widthHint = Math.max( widthHint,
+				btnMoveDown.computeSize( SWT.DEFAULT, SWT.DEFAULT ).x );
+		widthHint = Math.max( widthHint, 52 );
+		GridData btnGd = new GridData( );
+		btnGd.widthHint = widthHint;
+		btnMoveUp.setLayoutData( btnGd );
+		btnMoveDown.setLayoutData( btnGd );
+	}
+
+	/**
+	 * Set the labels of the ColumnsViewer
+	 * 
+	 */
+	private void setColumnsViewerLabels( )
+	{
+		selectedColumnsViewer.setLabelProvider( new ITableLabelProvider( ) {
+
+			public Image getColumnImage( Object element, int columnIndex )
+			{
+				return null;
+			}
+
+			public String getColumnText( Object element, int columnIndex )
+			{
+				return ( (String[]) element )[columnIndex];
+			}
+
+			public void addListener( ILabelProviderListener listener )
+			{
+
+			}
+
+			public void dispose( )
+			{
+
+			}
+
+			public boolean isLabelProperty( Object element, String property )
+			{
+				return false;
+			}
+
+			public void removeListener( ILabelProviderListener listener )
+			{
+
+			}
+
+		} );
+	}
+
+	/**
+	 * Set the content of the ColumnsViewer
+	 * 
+	 */
+	private void setColumnsViewerContent( )
+	{
+		selectedColumnsViewer.setContentProvider( new IStructuredContentProvider( ) {
+
+			@SuppressWarnings("rawtypes")
+			public Object[] getElements( Object inputElement )
+			{
+				if ( inputElement instanceof java.util.List )
+				{
+					return ( (java.util.List) inputElement ).toArray( );
+				}
+
+				return new Object[0];
+			}
+
+			public void dispose( )
+			{
+
+			}
+
+			public void inputChanged( Viewer viewer, Object oldInput,
+					Object newInput )
+			{
+
+			}
+
+		} );
+	}
+
+	/**
+	 * get the count of hte existence of the given column name in the already
+	 * saved selected columns information
+	 * 
+	 * @param columnName
+	 *            given column name
+	 * @return
+	 */
+
+	private int getExistenceCount( String columnName )
+	{
+		int count = 0;
+		java.util.List<String[]> existedColumns = new ArrayList<String[]>( );
+
+		for ( int i = 0; i < savedSelectedColumnsInfoList.size( ); i++ )
+		{
+			if ( columnName.equals( ( (String[]) savedSelectedColumnsInfoList.get( i ) )[1] ) )
+			{
+				count++;
+				existedColumns.add( savedSelectedColumnsInfoList.get( i ) );
+			}
+		}
+
+		for ( int j = 0; j < existedColumns.size( ); j++ )
+		{
+			if ( ( columnName + "_" + count ).equals( ( (String[]) existedColumns.get( j ) )[0] ) ) //$NON-NLS-1$
+			{
+				count++;
+				j = -1;
+			}
+		}
+
+		return count;
+	}
+
+
+	private void updateAvailableColumnsInfo( String fileName )
+	{
+		String[] columnNames = getFileColumnNames( fileName );
+
+		if ( columnNames != null && columnNames.length != 0 )
+		{
+			enableListAndViewer( );
+			availableList.setItems( columnNames );
+			availableList.select( 0 );
+
+			updateButtonStatus( );
+
+			if ( !( fileName.endsWith( CSV_EXTENSION )
+					|| fileName.endsWith( TXT_EXTENSION )
+					|| fileName.endsWith( SSV_EXTENSION )
+					|| fileName.endsWith( TSV_EXTENSION ) || fileName.endsWith( PSV_EXTENSION ) ) )
+			{
+				setMessage( Messages.getString( "warning.fileExtensionInvalid" ), //$NON-NLS-1$
+						WARNING );
+			}
+			else
+				setMessage( DEFAULT_MESSAGE );
+		}
+	}
+
+	private void updateButtonStatus( )
+	{
+		int availableListItemCount = availableList.getItemCount( );
+		int selectedColumnsItemCount = selectedColumnsViewer.getTable( )
+				.getItemCount( );
+
+		if ( availableList.getSelectionCount( ) > 0 )
+		{
+			btnAdd.setEnabled( true );
+			btnRemove.setEnabled( false );
+			btnMoveUp.setEnabled( false );
+			btnMoveDown.setEnabled( false );
+		}
+		else
+		{
+			int count = selectedColumnsViewer.getTable( ).getSelectionCount( );
+
+			if ( count < 1 )
+			{
+				btnAdd.setEnabled( false );
+				btnRemove.setEnabled( false );
+				btnMoveUp.setEnabled( false );
+				btnMoveDown.setEnabled( false );
+			}
+			else if ( count > 1 )
+			{
+				btnAdd.setEnabled( false );
+				btnRemove.setEnabled( true );
+				btnMoveUp.setEnabled( false );
+				btnMoveDown.setEnabled( false );
+			}
+			else
+			{
+				int index = selectedColumnsViewer.getTable( )
+						.getSelectionIndex( );
+				btnAdd.setEnabled( false );
+				btnRemove.setEnabled( true );
+				btnMoveUp.setEnabled( index > 0 );
+				btnMoveDown.setEnabled( index >= 0
+						&& index < ( selectedColumnsItemCount - 1 ) );
+			}
+
+		}
+
+		btnAddAll.setEnabled( availableListItemCount > 0 );
+		btnRemoveAll.setEnabled( selectedColumnsItemCount > 0 );
+	}
+
+	private void updateAvailableListSelection( )
+	{
+		int[] indices = availableList.getSelectionIndices( );
+		availableList.deselectAll( );
+		if ( indices.length > 0 )
+		{
+			int nextIndex = indices[indices.length - 1] + 1;
+			if ( availableList.getItemCount( ) > nextIndex )
+			{
+				availableList.select( nextIndex );
+			}
+			else
+			{
+				availableList.select( availableList.getItemCount( ) - 1 );
+			}
+		}
+	}
+
+	private void updateSelectedItemsSelection( int nextIndex )
+	{
+		int itemCount = selectedColumnsViewer.getTable( ).getItemCount( );
+
+		availableList.deselectAll( );
+		selectedColumnsViewer.getTable( ).deselectAll( );
+
+		if ( itemCount == 0 )
+		{
+			if ( availableList.getItemCount( ) > 0 )
+			{
+				availableList.select( 0 );
+			}
+		}
+		else if ( itemCount > nextIndex )
+		{
+			selectedColumnsViewer.getTable( ).select( nextIndex );
+		}
+		else if ( itemCount > 0 )
+		{
+			selectedColumnsViewer.getTable( ).select( itemCount - 1 );
+		}
+	}
+
+	private boolean validateSelectedFileStatus( )
+	{
+		String fileName = fileViewer.getCombo( ).getText( ).trim( );
+		if ( flatFileStatusCache.containsKey( fileName ) )
+		{
+			return flatFileStatusCache.get( fileName );
+		}
+		return true;
+	}
+
+	private void clearSelectedFileStatus( )
+	{
+		String fileName = fileViewer.getCombo( ).getText( ).trim( );
+		if ( flatFileStatusCache.containsKey( fileName ) )
+		{
+			flatFileStatusCache.remove( fileName );
+		}
+	}
+
+	private void validatePageStatus( )
+	{
+		if ( !validateSelectedFileStatus( ) )
+		{
+			clearSelectedFileStatus( );
+			return;
+		}
+		boolean pageComplete = true;
+		String[] columnNames = availableList.getItems( );
+		for ( int i = 0; i < savedSelectedColumnsInfoList.size( ); i++ )
+		{
+			String columnName = ( (String[]) savedSelectedColumnsInfoList.get( i ) )[0];
+			if ( columnName == null || isNumeric( columnName ) )
+			{
+				setMessage( Messages.getString( "FileSelectionWizardPage.error.selectColumn.numberName" ), //$NON-NLS-1$
+						ERROR );
+				pageComplete = false;
+				break;
+			}
+			String originalName = ( (String[]) savedSelectedColumnsInfoList.get( i ) )[1];
+			boolean columnExists = false;
+			for ( int k = 0; k < columnNames.length; k++ )
+			{
+				if ( ( columnName != null && columnName.equals( columnNames[k] ) )
+						|| ( originalName != null && originalName.equals( columnNames[k] ) ) )
+				{
+					columnExists = true;
+					break;
+				}
+			}
+			if ( !columnExists )
+			{
+				setMessage( Messages.getFormattedString( "warning.columnNotExist", new Object[]{columnName} ), //$NON-NLS-1$
+						ERROR );
+				pageComplete = false;
+				break;
+			}
+		}
+		if ( savedSelectedColumnsInfoList.size( ) <= 0 )
+		{
+			setMessage( Messages.getString( "FileSelectionWizardPage.error.selectColumn.NoColumnSelected" ), //$NON-NLS-1$
+					ERROR );
+			pageComplete = false;
+		}
+
+		if ( pageComplete )
+		{
+			setMessage( DEFAULT_MESSAGE );
+		}
+		setPageComplete( pageComplete );
+	}
+
+	/**
+	 * If text is a decimal presentation of int32 value, then text is index. In
+	 * this case return true and make send out error message. Otherwise return
+	 * false means the column name is right.
+	 */
+	private boolean isNumeric( String text )
+	{
+		long indexTest = indexFromString( text );
+		if ( indexTest >= 0 )
+		{
+			return true;
+		}
+		return false;
+	}
+
+	private long indexFromString( String str )
+	{
+		// The length of the decimal string representation of
+		// Integer.MAX_VALUE, 2147483647
+		final int MAX_VALUE_LENGTH = 10;
+
+		int len = str.length( );
+		if ( len > 0 )
+		{
+			int i = 0;
+			boolean negate = false;
+			int c = str.charAt( 0 );
+			if ( c == '-' )
+			{
+				if ( len > 1 )
+				{
+					c = str.charAt( 1 );
+					i = 1;
+					negate = true;
+				}
+			}
+			c -= '0';
+			if ( 0 <= c
+					&& c <= 9
+					&& len <= ( negate ? MAX_VALUE_LENGTH + 1
+							: MAX_VALUE_LENGTH ) )
+			{
+				// Use negative numbers to accumulate index to handle
+				// Integer.MIN_VALUE that is greater by 1 in absolute value
+				// then Integer.MAX_VALUE
+				int index = -c;
+				int oldIndex = 0;
+				i++;
+				if ( index != 0 )
+				{
+					// Note that 00, 01, 000 etc. are not indexes
+					while ( i != len
+							&& 0 <= ( c = str.charAt( i ) - '0' )
+							&& c <= 9 )
+					{
+						oldIndex = index;
+						index = 10 * index - c;
+						i++;
+					}
+				}
+				// Make sure all characters were consumed and that it
+				// couldn't
+				// have overflowed.
+				if ( i == len
+						&& ( oldIndex > ( Integer.MIN_VALUE / 10 ) || ( oldIndex == ( Integer.MIN_VALUE / 10 ) && c <= ( negate ? -( Integer.MIN_VALUE % 10 )
+								: ( Integer.MAX_VALUE % 10 ) ) ) ) )
+				{
+					return 0xFFFFFFFFL & ( negate ? index : -index );
+				}
+			}
+		}
+		return -1L;
+	}
+
+	/**
+	 * Load the custom properties
+	 */
+	private void loadProperties( )
+	{
+		DataSourceDesign dataSourceDesign = getInitializationDesign( ).getDataSourceDesign( );
+		java.util.Properties dataSourceProps = null;
+		try
+		{
+			dataSourceProps = DesignSessionUtil.getEffectiveDataSourceProperties( dataSourceDesign );
+		}
+		catch ( OdaException e )
+		{
+			this.setMessage( e.getLocalizedMessage( ), ERROR );
+			return;
+		}
+
+		String sourcePath = dataSourceProps.getProperty( ConnectionProfileProperty.PROFILE_STORE_FILE_PATH_PROP_KEY );
+		if ( sourcePath != null )
+		{
+			File cpFile = DesignUtil.convertPathToResourceFile( sourcePath,
+					dataSourceDesign.getHostResourceIdentifiers( ) );
+			if ( cpFile == null )
+			{
+				setMessage( Messages.getFormattedString( "error.invalidConnectionFilePath", new Object[]{sourcePath} ), ERROR ); //$NON-NLS-1$
+				return;
+			}
+		}
+
+		odaHome = dataSourceProps.getProperty( CommonConstants.CONN_HOME_DIR_PROP );
+		if ( odaHome == null )
+			odaHome = "";
+		fileURI = dataSourceProps.getProperty( CommonConstants.CONN_FILE_URI_PROP );
+		charSet = dataSourceProps.getProperty( CommonConstants.CONN_CHARSET_PROP );
+		flatfileDelimiterType = dataSourceProps.getProperty( CommonConstants.CONN_DELIMITER_TYPE );
+		inclColumnNameLine = dataSourceProps.getProperty( CommonConstants.CONN_INCLCOLUMNNAME_PROP );
+		inclTypeLine = dataSourceProps.getProperty( CommonConstants.CONN_INCLTYPELINE_PROP );
+		trailNullCols = dataSourceProps.getProperty( CommonConstants.CONN_TRAILNULLCOLS_PROP );
+
+		verifyFileLocation( );
+	}
+
+	private void verifyFileLocation( )
+	{
+		if ( fileURI != null && fileURI.length( ) > 0 )
+		{
+			try
+			{
+				ResourceLocator.validateFileURI( fileURI,
+						this.getResourceIdentifiers( ) );
+			}
+			catch ( InvalidResourceException ex )
+			{
+				this.setMessage( Messages.getFormattedString( "Connection.error.invalidFileURI", //$NON-NLS-1$
+						new Object[]{
+							fileURI
+						} ),
+						ERROR );
+				fileURI = null;
+			}
+		}
+		else if ( odaHome != null )
+		{
+			try
+			{
+				ResourceLocator.validateHomeFolder( odaHome,
+						this.getResourceIdentifiers( ) );
+			}
+			catch ( InvalidResourceException e )
+			{
+				this.setMessage( Messages.getFormattedString( "Connection.error.invalidHomeFolder", //$NON-NLS-1$
+						new Object[]{
+							odaHome
+						} ),
+						ERROR );
+				odaHome = null;
+			}
+		}
+		else
+		{
+			this.setMessage( Messages.getString( "Connection.error.invalidPath" //$NON-NLS-1$
+			), ERROR );
+			fileURI = null;
+			odaHome = null;
+		}
+	}
+
+	/**
+	 * Update file list in combo viewer
+	 */
+	private void updateFileListAndCharSet( )
+	{
+		if ( fileViewer != null && !fileViewer.getControl( ).isDisposed( ) )
+		{
+			if ( odaHome == null && fileURI == null )
+			{
+				disableAll( );
+				return;
+			}
+
+			ArrayList<Object> allFiles = new ArrayList<Object>( );
+			if ( fileURI == null )
+			{
+				try
+				{
+					File folder = ResourceLocator.getHomeFolderFile( odaHome,
+							this.getResourceIdentifiers( ) );
+					if ( folder.isDirectory( ) && folder.exists( ) )
+					{
+						File[] files = folder.getAbsoluteFile( )
+								.listFiles( new CSVFileFilter( fileFilter.getCombo( )
+										.getText( ) ) );
+
+						allFiles.addAll( Arrays.asList( files ) );
+					}
+				}
+				catch ( InvalidResourceException e )
+				{
+				}
+			}
+			else if ( fileURI != null )
+			{
+				allFiles.add( fileURI );
+			}
+			fileViewer.setInput( allFiles.toArray( ) );
+
+			if ( allFiles.size( ) <= 0 )
+			{
+				setMessage( Messages.getFormattedString( "error.noCSVFiles", //$NON-NLS-1$
+						new Object[]{
+							new File( odaHome ).getAbsolutePath( )
+						} ) );
+				disableAll( );
+			}
+			else
+			{
+				updateFileSelection( );
+				updateButtonStatus( );
+			}
+		}
+	}
+
+	private void updateFileSelection( )
+	{
+		Object[] files = (Object[]) fileViewer.getInput( );
+		if ( files.length > 0 )
+		{
+			enableListAndViewer( );
+			Object toSelectFile = null;
+			if ( selectedFile != null )
+				for ( int i = 0; i < files.length; i++ )
+				{
+					if ( files[i].equals( selectedFile ) )
+					{
+						toSelectFile = selectedFile;
+						break;
+					}
+				}
+			if ( toSelectFile == null )
+				toSelectFile = files[0];
+
+			fileViewer.setSelection( new StructuredSelection( toSelectFile ) );
+			if ( !( nameOfFileWithErrorInLastAccess != null && nameOfFileWithErrorInLastAccess.equals( fileViewer.getCombo( )
+					.getText( ) ) ) )
+				setMessage( DEFAULT_MESSAGE );
+		}
+		else
+		{
+			setMessage( Messages.getFormattedString( "error.noCSVFiles", //$NON-NLS-1$
+					new Object[]{
+						new File( odaHome ).getAbsolutePath( )
+					} ) );
+			disableAll( );
+		}
+	}
+
+	/**
+	 * Returns all the column names found in given flatfile.
+	 * 
+	 * @param file
+	 * @return
+	 */
+	private String[] getFileColumnNames( String file )
+	{
+		java.util.List<String[]> propList = getQueryColumnsInfo( "select * from " + QueryTextUtil.getQuotedName( file ) ); //$NON-NLS-1$
+
+		String[] result;
+		if ( propList != null )
+		{
+			originalFileColumnsInfoList = new ArrayList<String[]>( propList );
+			result = new String[propList.size( )];
+			for ( int i = 0; i < propList.size( ); i++ )
+				result[i] = propList.get( i )[1];
+		}
+		else
+			result = new String[0];
+
+		return result;
+	}
+
+	/**
+	 * 
+	 * @param queryText
+	 * @param file
+	 * @return
+	 */
+	private java.util.List<String[]> getQueryColumnsInfo( String queryText )
+	{
+		IDriver ffDriver = new FlatFileDriver( );
+		IConnection conn = null;
+		java.util.List<String[]> columnList = new ArrayList<String[]>( );
+		try
+		{
+			conn = ffDriver.getConnection( null );
+			IResultSetMetaData metadata = getResultSetMetaData( queryText, conn );
+
+			int columnCount = metadata.getColumnCount( );
+			if ( columnCount == 0 )
+				return new ArrayList<String[]>( );
+
+			for ( int i = 0; i < columnCount; i++ )
+			{
+				String[] result = new String[3];
+				result[0] = metadata.getColumnName( i + 1 );
+
+				result[1] = getOriginalColumnName( result[0],
+						savedSelectedColumnsInfoString,
+						metadata );
+
+				result[2] = getDataTypeDisplayName( new Integer( metadata.getColumnType( i + 1 ) ) );
+				columnList.add( result );
+			}
+			flatFileStatusCache.put( fileViewer.getCombo( ).getText( ).trim( ),
+					true );
+			return columnList;
+		}
+		catch ( OdaException e )
+		{
+			flatFileStatusCache.put( fileViewer.getCombo( ).getText( ).trim( ),
+					false );
+			setMessage( e.getLocalizedMessage( ), ERROR );
+			updateExceptionInfo( );
+			return new ArrayList<String[]>( );
+		}
+		finally
+		{
+			closeConnection( conn );
+		}
+
+	}
+
+	private void updateExceptionInfo( )
+	{
+		nameOfFileWithErrorInLastAccess = fileViewer.getCombo( ).getText( );
+		if ( availableList.getItemCount( ) == 0 )
+			disableAvailableListAndButtons( );
+	}
+
+	private void disableAvailableListAndButtons( )
+	{
+		availableList.setEnabled( false );
+		btnAdd.setEnabled( false );
+		btnAddAll.setEnabled( false );
+		btnRemove.setEnabled( false );
+		btnRemoveAll.setEnabled( false );
+		btnMoveDown.setEnabled( false );
+		btnMoveUp.setEnabled( false );
+	}
+
+	/**
+	 * get the data type display name
+	 * 
+	 * @param type
+	 * @return
+	 */
+	private String getDataTypeDisplayName( Integer type )
+	{
+		if ( dataTypeDisplayNameMap.get( type ) != null )
+			return (String) dataTypeDisplayNameMap.get( type );
+		else
+			return Messages.getString( "datatypes.string" ); //$NON-NLS-1$
+	}
+
+	/**
+	 * 
+	 * @param displayName
+	 * @return
+	 */
+	private String getDataTypeValue( String displayName )
+	{
+		if ( dataTypeValueMape.get( displayName ) != null )
+			return (String) dataTypeValueMape.get( displayName );
+		else
+			return "STRING"; //$NON-NLS-1$
+	}
+
+	/**
+	 * Get the original column name in the flatfile of the given column name
+	 * 
+	 * @param name
+	 * @param columnsInfo
+	 * @param metadata
+	 * @return
+	 */
+	private String getOriginalColumnName( String name, String columnsInfo,
+			IResultSetMetaData metadata )
+	{
+		String originalName = null;
+		if ( columnsInfo.length( ) != 0 )
+		{
+			ColumnsInfoUtil ciu = new ColumnsInfoUtil( columnsInfo );
+			String[] names = ciu.getColumnNames( );
+			for ( int i = 0; i < names.length; i++ )
+			{
+				if ( name.equals( names[i] ) )
+				{
+					originalName = ciu.getOriginalColumnNames( )[i];
+					break;
+				}
+			}
+		}
+
+		// if this name was not selected in the viewer
+		if ( originalName == null )
+		{
+
+			try
+			{
+				for ( int j = 0; j < metadata.getColumnCount( ); j++ )
+				{
+					if ( name.equals( metadata.getColumnName( j + 1 ) ) )
+						originalName = name;
+				}
+			}
+			catch ( OdaException e )
+			{
+				e.printStackTrace( );
+			}
+
+		}
+
+		return originalName;
+	}
+
+	/**
+	 * Attempts to close given ODA connection.
+	 * 
+	 * @param conn
+	 */
+	private void closeConnection( IConnection conn )
+	{
+		try
+		{
+			if ( conn != null )
+				conn.close( );
+		}
+		catch ( OdaException e )
+		{
+			// ignore
+		}
+	}
+
+	/**
+	 * 
+	 * @param queryText
+	 * @param file
+	 * @param conn
+	 * @return
+	 * @throws OdaException
+	 */
+	private IResultSetMetaData getResultSetMetaData( String queryText,
+			IConnection conn ) throws OdaException
+	{
+		java.util.Properties prop = new java.util.Properties( );
+		if ( odaHome != null )
+		{
+			prop.put( CommonConstants.CONN_HOME_DIR_PROP, odaHome );
+		}
+		if ( fileURI != null )
+		{
+			prop.put( CommonConstants.CONN_FILE_URI_PROP, fileURI );
+		}
+		if ( flatfileDelimiterType != null )
+		{
+			prop.put( CommonConstants.CONN_DELIMITER_TYPE,
+					flatfileDelimiterType );
+		}
+		if ( charSet != null )
+		{
+			prop.put( CommonConstants.CONN_CHARSET_PROP, charSet );
+		}
+		if ( inclColumnNameLine != null )
+		{
+			prop.put( CommonConstants.CONN_INCLCOLUMNNAME_PROP,
+					inclColumnNameLine );
+		}
+		if ( inclTypeLine != null )
+		{
+			prop.put( CommonConstants.CONN_INCLTYPELINE_PROP, inclTypeLine );
+		}
+		if ( trailNullCols != null )
+		{
+			prop.put( CommonConstants.CONN_TRAILNULLCOLS_PROP, trailNullCols );
+		}
+
+		savedSelectedColumnsInfoString = ( new QueryTextUtil( queryText ) ).getColumnsInfo( );
+
+		Map<String, Object> appContext = DesignSessionUtil.createResourceIdentifiersContext( getHostResourceIdentifiers( ) );
+		conn.setAppContext( appContext );
+		conn.open( prop );
+
+		IQuery query = conn.newQuery( null );
+		query.setMaxRows( 1 );
+		query.prepare( queryText );
+		query.executeQuery( );
+
+		return query.getMetaData( );
+	}
+
+	private ResourceIdentifiers getResourceIdentifiers( )
+	{
+		return DesignSessionUtil.createRuntimeResourceIdentifiers( getHostResourceIdentifiers( ) );
+	}
+
+	/**
+	 * Enable all control of this page
+	 */
+	private void enableListAndViewer( )
+	{
+		availableList.setEnabled( true );
+		selectedColumnsViewer.getTable( ).setEnabled( true );
+	}
+
+	/**
+	 * Disable all control of this page
+	 */
+	private void disableAll( )
+	{
+		availableList.setEnabled( false );
+		selectedColumnsViewer.getTable( ).setEnabled( false );
+		btnAdd.setEnabled( false );
+		btnRemove.setEnabled( false );
+		btnRemoveAll.setEnabled( false );
+		btnMoveUp.setEnabled( false );
+		btnMoveDown.setEnabled( false );
+		setPageComplete( false );
+	}
+
+	/**
+	 * display the content of the list in the table viewer
+	 * 
+	 * @param list
+	 *            list that contains the dispay content
+	 * @param tViewer
+	 *            the table viewer
+	 */
+	private void setDisplayContent( java.util.List<String[]> list )
+	{
+		selectedColumnsViewer.getTable( ).removeAll( );
+		selectedColumnsViewer.setInput( list );
+		selectedColumnsViewer.getTable( )
+				.select( selectedColumnsViewer.getTable( ).getTopIndex( ) );
+	}
+
+	/**
+	 * get the query text(select clause) of this data set
+	 * 
+	 * @return query
+	 * 
+	 */
+	private String getQuery( )
+	{
+		if ( selectedColumnsViewer.getTable( ).getItemCount( ) == 0 )
+			return ""; //$NON-NLS-1$
+
+		String tableName = null;
+		StringBuffer buf = new StringBuffer( );
+		Object file = ( (StructuredSelection) fileViewer.getSelection( ) ).getFirstElement( );
+		if ( file != null )
+		{
+			if ( file instanceof File )
+				tableName = ( (File) file ).getName( );
+			else if ( file instanceof String )
+				tableName = (String) file;
+		}
+		if ( tableName != null )
+		{
+			tableName = QueryTextUtil.getQuotedName( tableName );
+			if ( availableList.getItemCount( ) == 0 )
+			{
+				buf.append( "select * from " ).append( tableName ); //$NON-NLS-1$
+			}
+			else
+			{
+				buf.append( "select " ); //$NON-NLS-1$
+				String[] columns = new String[selectedColumnsViewer.getTable( )
+						.getItemCount( )];
+				for ( int m = 0; m < columns.length; m++ )
+					columns[m] = selectedColumnsViewer.getTable( )
+							.getItem( m )
+							.getText( 1 );
+
+				for ( int n = 0; n < columns.length; n++ )
+				{
+					StringBuffer sb = new StringBuffer( );
+					char[] columnChars = columns[n].toCharArray( );
+					for ( int i = 0; i < columnChars.length; i++ )
+					{
+						if ( columnChars[i] == '"' )
+							sb.append( "\\\"" ); //$NON-NLS-1$
+						else if ( columnChars[i] == '\\' )
+							sb.append( "\\\\" ); //$NON-NLS-1$
+						else
+							sb.append( columnChars[i] );
+					}
+
+					buf.append( CommonConstants.DELIMITER_DOUBLEQUOTE
+							+ sb.toString( )
+							+ CommonConstants.DELIMITER_DOUBLEQUOTE );
+					if ( n < columns.length - 1 )
+					{
+						buf.append( ", " ); //$NON-NLS-1$
+					}
+				}
+				buf.append( " from " ).append( tableName ); //$NON-NLS-1$
+			}
+		}
+		return buf.toString( );
+	}
+
+	/**
+	 * Update value of query text
+	 * 
+	 * @param queryText
+	 */
+
+	private void updateValuesFromQuery( String queryText )
+	{
+		if ( queryText.length( ) == 0 )
+			return;
+
+		try
+		{
+			String query = ( new QueryTextUtil( queryText ) ).getQuery( );
+			String[] metadata = QueryTextUtil.getQueryMetaData( query );
+
+			// The query must have a table name and columns.
+			if ( metadata != null && metadata[0] != null && metadata[2] != null )
+			{
+				// Now select the table in the list. If it doesn't exists, no
+				// need to process the columns.
+				String f = selectTableFromQuery( metadata[2] );
+				if ( f != null )
+				{
+					updateColumnsFromQuery( queryText, f );
+				}
+			}
+		}
+		catch ( OdaException e )
+		{
+			setMessage( e.getLocalizedMessage( ), ERROR );
+			updateExceptionInfo( );
+		}
+
+	}
+
+	private void updateFileFilterComboStatus( DataSetDesign dataSetDesign )
+	{
+		Properties properties = dataSetDesign.getDataSourceDesign( )
+				.getPublicProperties( );
+		Object value = properties.getProperty( CommonConstants.CONN_HOME_DIR_PROP );
+		if ( value instanceof String )
+		{
+			String folder = (String) value;
+			if ( folder == null || folder.trim( ).length( ) == 0 )
+			{
+				fileFilter.getCombo( ).setEnabled( false );
+			}
+		}
+		else
+		{
+			fileFilter.getCombo( ).setEnabled( false );
+		}
+	}
+
+	/**
+	 * 
+	 * @param queryText
+	 * @param file
+	 */
+	private void updateColumnsFromQuery( String queryText, String file )
+	{
+		availableList.setItems( getFileColumnNames( file ) );
+		selectedColumnsViewer.getTable( ).removeAll( );
+
+		savedSelectedColumnsInfoList.clear( );
+
+		savedSelectedColumnsInfoList = getQueryColumnsInfo( queryText );
+
+		setDisplayContent( savedSelectedColumnsInfoList );
+
+		setPageComplete( true );
+
+		if ( selectedColumnsViewer.getTable( ).getItemCount( ) == 0 )
+		{
+			setPageComplete( false );
+		}
+
+		updateButtonStatus( );
+
+	}
+
+	/**
+	 * @param tableName
+	 * @return File
+	 */
+	private String selectTableFromQuery( String tableName )
+	{
+		String selected = null;
+		if ( fileURI != null && fileURI.length( ) > 0 )
+		{
+			if ( !fileURI.equals( tableName ) )
+			{
+				availableList.removeAll( );
+				nameOfFileWithErrorInLastAccess = null;
+				MessageDialog.openWarning( getShell( ),
+						Messages.getString( "fileURIChanged.warning.reselectColumnsTitle" ), //$NON-NLS-1$
+						Messages.getString( "fileURIChanged.warning.reselectColumnsMessage" ) ); //$NON-NLS-1$
+
+				updateAvailableColumnsInfo( fileURI );
+				selectedColumnsViewer.getTable( ).removeAll( );
+				savedSelectedColumnsInfoList.clear( );
+				fileViewer.setSelection( new StructuredSelection( fileURI ) );
+				setPageComplete( false );
+				setMessage( Messages.getString( "error.selectColumns" ), ERROR ); //$NON-NLS-1$
+			}
+			else
+				selected = tableName;
+		}
+		else
+		{
+			resetInitialized( );
+			fileFilter.setSelection( new StructuredSelection( MATCH_ALL_FILES ) );
+			Object[] files = (Object[]) fileViewer.getInput( );
+			if ( files != null )
+			{
+				for ( int n = 0; n < files.length; n++ )
+				{
+					File f = (File) files[n];
+					if ( f.getName( ).equalsIgnoreCase( tableName ) )
+					{
+						selectedFile = f;
+						resetInitialized( );
+						setFileFilter( tableName );
+						fileViewer.setSelection( new StructuredSelection( files[n] ) );
+						selected = f.getName( );
+						break;
+					}
+				}
+			}
+		}
+		return selected;
+	}
+
+	private void setFileFilter( String table )
+	{
+		String tableName = table.toLowerCase( );
+		if ( tableName.endsWith( CSV_EXTENSION ) )
+			fileFilter.setSelection( new StructuredSelection( ALL_CSV_EXTENSION ) );
+		else if ( tableName.endsWith( TXT_EXTENSION ) )
+			fileFilter.setSelection( new StructuredSelection( ALL_TXT_EXTENSION ) );
+		else if ( tableName.endsWith( SSV_EXTENSION ) )
+			fileFilter.setSelection( new StructuredSelection( ALL_SSV_EXTENSION ) );
+		else if ( tableName.endsWith( TSV_EXTENSION ) )
+			fileFilter.setSelection( new StructuredSelection( ALL_TSV_EXTENSION ) );
+		else if ( tableName.endsWith( PSV_EXTENSION ) )
+			fileFilter.setSelection( new StructuredSelection( ALL_PSV_EXTENSION ) );
+		else
+			fileFilter.setSelection( new StructuredSelection( ALL_PSV_EXTENSION ) );
+	}
+
+	private void resetInitialized( )
+	{
+		this.initialized = false;
+	}
+
+	/**
+	 * Populate file filters for file combo viewer
+	 */
+	private void populateFileFilter( )
+	{
+		if ( fileFilter != null && !fileFilter.getControl( ).isDisposed( ) )
+		{
+			if ( fileFilter.getCombo( ).getSelectionIndex( ) == -1 )
+			{
+				if ( CommonConstants.DELIMITER_COMMA.equalsIgnoreCase( flatfileDelimiterType ) )
+				{
+					fileFilter.add( ALL_CSV_EXTENSION );
+					this.selectedFileFilter = ALL_CSV_EXTENSION;
+				}
+				else if ( CommonConstants.DELIMITER_SEMICOLON.equalsIgnoreCase( flatfileDelimiterType ) )
+				{
+					fileFilter.add( ALL_SSV_EXTENSION );
+					this.selectedFileFilter = ALL_SSV_EXTENSION;
+				}
+				else if ( CommonConstants.DELIMITER_TAB.equalsIgnoreCase( flatfileDelimiterType ) )
+				{
+					fileFilter.add( ALL_TSV_EXTENSION );
+					this.selectedFileFilter = ALL_TSV_EXTENSION;
+				}
+				else if ( CommonConstants.DELIMITER_PIPE.equalsIgnoreCase( flatfileDelimiterType ) )
+				{
+					fileFilter.add( ALL_PSV_EXTENSION );
+					this.selectedFileFilter = ALL_PSV_EXTENSION;
+				}
+				else
+					this.selectedFileFilter = MATCH_ALL_FILES;
+
+				fileFilter.add( ALL_TXT_EXTENSION );
+				fileFilter.add( MATCH_ALL_FILES );
+				fileFilter.getCombo( ).select( 0 );
+			}
+		}
+	}
+
+	private void moveUpItem( )
+	{
+		int count = selectedColumnsViewer.getTable( ).getItemCount( );
+		int index = selectedColumnsViewer.getTable( ).getSelectionIndex( );
+
+		if ( index > 0 && index < count )
+		{
+			if ( !btnMoveDown.isEnabled( ) )
+				btnMoveDown.setEnabled( true );
+
+			String[] columnInfo = savedSelectedColumnsInfoList.get( index );
+			savedSelectedColumnsInfoList.set( index,
+					savedSelectedColumnsInfoList.get( index - 1 ) );
+			savedSelectedColumnsInfoList.set( index - 1, columnInfo );
+			selectedColumnsViewer.refresh( );
+			selectedColumnsViewer.getTable( ).setSelection( index - 1 );
+		}
+
+		if ( index == 1 )
+			btnMoveUp.setEnabled( false );
+	}
+
+	private void moveDownItem( )
+	{
+		int count = selectedColumnsViewer.getTable( ).getItemCount( );
+		int index = selectedColumnsViewer.getTable( ).getSelectionIndex( );
+
+		if ( index > -1 && index < count - 1 )
+		{
+			if ( !btnMoveUp.isEnabled( ) )
+				btnMoveUp.setEnabled( true );
+
+			String[] columnInfo = savedSelectedColumnsInfoList.get( index );
+			savedSelectedColumnsInfoList.set( index,
+					savedSelectedColumnsInfoList.get( index + 1 ) );
+			savedSelectedColumnsInfoList.set( index + 1, columnInfo );
+			selectedColumnsViewer.refresh( );
+			selectedColumnsViewer.getTable( ).setSelection( index + 1 );
+		}
+
+		if ( index == count - 2 )
+			btnMoveDown.setEnabled( false );
+	}
+
+	private void addAllAvailableColumns( )
+	{
+		java.util.List<String[]> addedItems = createAddedColumnsInfo( availableList.getItems( ) );
+		addColumns( addedItems, false );
+	}
+
+	/**
+	 * Add selectd columns
+	 */
+	private void addColumns( boolean updateSelection )
+	{
+		java.util.List<String[]> addedItems = createAddedColumnsInfo( availableList.getSelection( ) );
+		addColumns( addedItems, updateSelection );
+	}
+
+	private void addColumns( java.util.List<String[]> addedItems,
+			boolean updateSelection )
+	{
+		for ( int i = 0; i < addedItems.size( ); i++ )
+		{
+			savedSelectedColumnsInfoList.add( addedItems.get( i ) );
+		}
+
+		setDisplayContent( savedSelectedColumnsInfoList );
+
+		selectedColumnsViewer.getTable( ).deselectAll( );
+		if ( updateSelection )
+			updateAvailableListSelection( );
+	}
+
+	/**
+	 * create a list of the columns info in accordience to the given column
+	 * names
+	 * 
+	 * @param addedColumnNames
+	 * @return
+	 */
+	private java.util.List<String[]> createAddedColumnsInfo(
+			String[] addedColumnNames )
+	{
+		java.util.List<String[]> addedColumnsInfo = new ArrayList<String[]>( );
+		int count = 0;
+
+		for ( int i = 0; i < addedColumnNames.length; i++ )
+		{
+			count = getExistenceCount( addedColumnNames[i] );
+			String[] addedColumns;
+			addedColumns = new String[3];
+			if ( count == 0 )
+				addedColumns[0] = addedColumnNames[i];
+			else
+				addedColumns[0] = addedColumnNames[i] + "_" + count; //$NON-NLS-1$
+
+			addedColumns[1] = addedColumnNames[i];
+			addedColumns[2] = getColumnTypeName( addedColumnNames[i] );
+
+			addedColumnsInfo.add( addedColumns );
+		}
+
+		return addedColumnsInfo;
+	}
+
+	/**
+	 * 
+	 * @param columnName
+	 * @return
+	 */
+	private String getColumnTypeName( String columnName )
+	{
+		for ( int i = 0; i < originalFileColumnsInfoList.size( ); i++ )
+		{
+			if ( columnName.equals( ( (String[]) originalFileColumnsInfoList.get( i ) )[1] ) )
+				return ( (String[]) originalFileColumnsInfoList.get( i ) )[2];
+		}
+		return null;
+	}
+
+	/**
+	 * Remove selected columns
+	 */
+	private void removeColumns( )
+	{
+		TableItem[] tis = selectedColumnsViewer.getTable( ).getSelection( );
+		int index = selectedColumnsViewer.getTable( ).getSelectionIndex( )
+				- selectedColumnsViewer.getTable( ).getSelectionCount( )
+				+ 1;
+		String[] removedColumnInfo = null;
+
+		java.util.List<String[]> removedItems = new ArrayList<String[]>( );
+		for ( int i = 0; i < tis.length; i++ )
+		{
+			removedColumnInfo = new String[3];
+			removedColumnInfo[0] = tis[i].getText( 0 );
+			removedColumnInfo[1] = tis[i].getText( 1 );
+			removedColumnInfo[2] = tis[i].getText( 2 );
+			removedItems.add( removedColumnInfo );
+		}
+
+		removeItemsFromSelectedOnes( removedItems );
+
+		selectedColumnsViewer.refresh( );
+
+		availableList.deselectAll( );
+		updateSelectedItemsSelection( index );
+
+		if ( selectedColumnsViewer.getTable( ).getItemCount( ) == 0 )
+		{
+			setPageComplete( false );
+		}
+	}
+
+	private void removeAllColumns( )
+	{
+		selectedColumnsViewer.getTable( ).removeAll( );
+		savedSelectedColumnsInfoList.clear( );
+
+		selectedColumnsViewer.refresh( );
+
+		updateSelectedItemsSelection( -1 );
+		setPageComplete( false );
+	}
+
+	/**
+	 * remove the given items from the saved selectedComlumnsInfo
+	 * 
+	 * @param removedItemsList
+	 *            list that contains the given elements that are going to be
+	 *            removed
+	 */
+	private void removeItemsFromSelectedOnes(
+			java.util.List<String[]> removedItemsList )
+	{
+		for ( int i = 0; i < removedItemsList.size( ); i++ )
+		{
+			for ( int j = 0; j < savedSelectedColumnsInfoList.size( ); j++ )
+			{
+				if ( ( (String[]) removedItemsList.get( i ) )[0].equals( ( (String[]) savedSelectedColumnsInfoList.get( j ) )[0] )
+						&& ( (String[]) removedItemsList.get( i ) )[1].equals( ( (String[]) savedSelectedColumnsInfoList.get( j ) )[1] )
+						&& ( (String[]) removedItemsList.get( i ) )[2].equals( ( (String[]) savedSelectedColumnsInfoList.get( j ) )[2] ) )
+				{
+					savedSelectedColumnsInfoList.remove( j );
+					break;
+				}
+
+			}
+		}
+
+		validatePageStatus( );
+	}
+
+	/**
+	 * Updates the given dataSetDesign with the query and its metadata defined
+	 * in this page.
+	 * 
+	 * @param dataSetDesign
+	 */
+	private void savePage( DataSetDesign dataSetDesign )
+	{
+		String queryText = getQueryText( );
+		if ( queryText.equals( dataSetDesign.getQueryText( ) ) )
+			return;
+		dataSetDesign.setQueryText( queryText );
+
+		// obtain query's result set metadata, and update
+		// the dataSetDesign with it
+		IConnection conn = null;
+		try
+		{
+			IDriver ffDriver = new FlatFileDriver( );
+			conn = ffDriver.getConnection( null );
+			IResultSetMetaData metadata = getResultSetMetaData( queryText, conn );
+			setResultSetMetaData( dataSetDesign, metadata );
+		}
+		catch ( OdaException e )
+		{
+			// no result set definition available, reset in dataSetDesign
+			dataSetDesign.setResultSets( null );
+		}
+		finally
+		{
+			closeConnection( conn );
+		}
+
+		/*
+		 * See DesignSessionUtil for more convenience methods to define a data
+		 * set design instance.
+		 */
+
+		/*
+		 * Since this flatfile driver does not support query parameters and
+		 * properties, there are no data set parameters and public/private
+		 * properties to specify in the data set design instance
+		 */
+	}
+
+	/**
+	 * Gets the query text
+	 * 
+	 * @return query text
+	 */
+	private String getQueryText( )
+	{
+		String query = getQuery( );
+		String queryText = query.length( ) > 0 ? query
+				+ CommonConstants.DELIMITER_SPACE
+				+ queryTextDelimiter
+				+ CommonConstants.DELIMITER_SPACE
+				+ columnsInfoStartSymbol
+				+ createSelectedColumnsInfoString( )
+				+ columnsInfoEndSymbol : ""; //$NON-NLS-1$
+		return queryText;
+	}
+
+	/**
+	 * create the SelectedColumnsinfo string
+	 * 
+	 * @param dataSetDesign
+	 *            the current dataSetDesign
+	 * @return String that contains the seleced columns infomation
+	 */
+	private String createSelectedColumnsInfoString( )
+	{
+		String prop = ""; //$NON-NLS-1$
+		// If the length is equal to 2 then we have a valid query
+
+		for ( int i = 0; i < savedSelectedColumnsInfoList.size( ); i++ )
+		{
+			char[] columnNameChars = ( (String[]) savedSelectedColumnsInfoList.get( i ) )[0].toCharArray( );
+			StringBuffer columnNameBuf = new StringBuffer( );
+
+			char[] originalColumnNameChars = ( (String[]) savedSelectedColumnsInfoList.get( i ) )[1].toCharArray( );
+			StringBuffer originalColumnNameBuf = new StringBuffer( );
+			for ( int m = 0; m < columnNameChars.length; m++ )
+			{
+				if ( ColumnsInfoUtil.isColumnsInfoKeyWord( columnNameChars[m] ) )
+					columnNameBuf.append( "\\" + columnNameChars[m] ); //$NON-NLS-1$
+				else
+					columnNameBuf.append( columnNameChars[m] );
+
+			}
+
+			prop = prop
+					+ CommonConstants.DELIMITER_DOUBLEQUOTE
+					+ columnNameBuf.toString( )
+					+ CommonConstants.DELIMITER_DOUBLEQUOTE
+					+ CommonConstants.DELIMITER_COMMA_VALUE;
+
+			for ( int m = 0; m < originalColumnNameChars.length; m++ )
+			{
+				if ( ColumnsInfoUtil.isColumnsInfoKeyWord( originalColumnNameChars[m] ) )
+					originalColumnNameBuf.append( "\\" //$NON-NLS-1$
+							+ originalColumnNameChars[m] );
+				else
+					originalColumnNameBuf.append( originalColumnNameChars[m] );
+
+			}
+
+			prop = prop
+					+ CommonConstants.DELIMITER_DOUBLEQUOTE
+					+ originalColumnNameBuf.toString( )
+					+ CommonConstants.DELIMITER_DOUBLEQUOTE
+					+ CommonConstants.DELIMITER_COMMA_VALUE;
+
+			if ( i != savedSelectedColumnsInfoList.size( ) - 1 )
+			{
+				prop = prop
+						+ getDataTypeValue( ( (String[]) savedSelectedColumnsInfoList.get( i ) )[2] )
+						+ CommonConstants.DELIMITER_SEMICOLON_VALUE;
+			}
+			else
+			{
+				prop = prop
+						+ getDataTypeValue( ( (String[]) savedSelectedColumnsInfoList.get( i ) )[2] );
+			}
+
+		}
+
+		savedSelectedColumnsInfoString = prop;
+
+		return savedSelectedColumnsInfoString;
+
+	}
+
+	/**
+	 * 
+	 * @param dataSetDesign
+	 * @param md
+	 * @throws OdaException
+	 */
+	private void setResultSetMetaData( DataSetDesign dataSetDesign,
+			IResultSetMetaData md ) throws OdaException
+	{
+		ResultSetColumns columns = DesignSessionUtil.toResultSetColumnsDesign( md );
+
+		ResultSetDefinition resultSetDefn = DesignFactory.eINSTANCE.createResultSetDefinition( );
+		// flat file does not support result set name
+		resultSetDefn.setResultSetColumns( columns );
+
+		// no exception; go ahead and assign to specified dataSetDesign
+		dataSetDesign.setPrimaryResultSet( resultSetDefn );
+		dataSetDesign.getResultSets( ).setDerivedMetaData( true );
+	}
+
+	class CSVFileFilter implements FilenameFilter
+	{
+
+		private String extension = null;
+
+		CSVFileFilter( String ext )
+		{
+			if ( ALL_CSV_EXTENSION.equalsIgnoreCase( ext ) )
+				extension = CSV_EXTENSION;
+			else if ( ALL_TXT_EXTENSION.equalsIgnoreCase( ext ) )
+				extension = TXT_EXTENSION;
+			else if ( ALL_SSV_EXTENSION.equalsIgnoreCase( ext ) )
+				extension = SSV_EXTENSION;
+			else if ( ALL_TSV_EXTENSION.equalsIgnoreCase( ext ) )
+				extension = TSV_EXTENSION;
+			else if ( ALL_PSV_EXTENSION.equalsIgnoreCase( ext ) )
+				extension = PSV_EXTENSION;
+			else
+				extension = null;
+
+		}
+
+		public boolean accept( File dir, String name )
+		{
+			if ( extension == null )
+			{
+				File file = new File( dir + File.separator + name );
+				if ( file.isFile( ) && !file.isHidden( ) )
+					return true;
+				else
+					return false;
+			}
+			else
+				return name.toLowerCase( ).endsWith( extension );
+		}
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.eclipse.jface.dialogs.DialogPage#setVisible(boolean)
+	 */
+	public void setVisible( boolean visible )
+	{
+		super.setVisible( visible );
+		getControl( ).setFocus( );
+	}
+
+	private void selectFileChanged( )
+	{
+		String file = fileViewer.getCombo( ).getText( ).trim( );
+		if ( file.length( ) == 0 )
+		{
+			return;
+		}
+
+		// File URI mode
+		if ( fileURI != null && fileURI.length( ) > 0 )
+		{
+			if ( file != null ) // Update column info.
+			{
+				updateAvailableColumnsInfo( file );
+				validatePageStatus( );
+			}
+			return;
+		}
+
+		// Home folder mode
+		if ( file.equals( selectedFile ) )
+			return;
+		else
+		{
+			// Not initialized or file selection changed.
+			setPageComplete( false );
+			availableList.removeAll( );
+			nameOfFileWithErrorInLastAccess = null;
+			updateAvailableColumnsInfo( file );
+
+			if ( selectedFile != null ) // File selection changed.
+			{
+				if ( savedSelectedColumnsInfoList.size( ) > 0 )
+				{
+					if ( MessageDialog.openConfirm( getShell( ),
+							Messages.getString( "confirm.reselectFileNameTitle" ), //$NON-NLS-1$
+							Messages.getString( "confirm.reselectFileNameMessage" ) ) ) //$NON-NLS-1$
+					{
+						validatePageStatus( );
+					}
+					else
+					{
+						selectedColumnsViewer.getTable( ).removeAll( );
+						savedSelectedColumnsInfoList.clear( );
+					}
+				}
+			}
+			selectedFile = file;
+		}
+		updateButtonStatus( );
+	}
+
+	private class ColumnEditDialog extends StatusDialog
+	{
+
+		String columnName, columnOriginalName, columnDataType;
+
+		public ColumnEditDialog( Shell parent )
+		{
+			super( parent );
+
+		}
+
+		public void setInput( String columnName, String columnOriginalName,
+				String columnDataType )
+		{
+			this.columnName = columnName;
+			this.columnOriginalName = columnOriginalName;
+			this.columnDataType = columnDataType;
+		}
+
+		protected boolean isResizable( )
+		{
+			return true;
+		}
+
+		public void create( )
+		{
+			super.create( );
+
+			Point pt = getShell( ).computeSize( -1, -1 );
+			pt.x = Math.max( pt.x, 400 );
+			pt.y = Math.max( pt.y, 250 );
+			getShell( ).setSize( pt );
+			getShell( ).setText( getTitle( ) );
+		}
+
+		protected Control createDialogArea( Composite parent )
+		{
+			Composite composite = new Composite( parent, SWT.None );
+
+			GridLayout layout = new GridLayout( );
+			layout.marginLeft = layout.marginTop = layout.marginRight = 20;
+			layout.marginBottom = 5;
+			layout.numColumns = 2;
+			composite.setLayout( layout );
+			GridData data = new GridData( GridData.FILL_BOTH );
+			composite.setLayoutData( data );
+
+			GridData lableData = new GridData( );
+			lableData.widthHint = 100;
+
+			Label columnNameLabel = new Label( composite, SWT.BOLD );
+			columnNameLabel.setLayoutData( lableData );
+			columnNameLabel.setText( Messages.getString( "FileSelectionWizardPage.label.columnName" ) ); //$NON-NLS-1$
+			int width = columnNameLabel.computeSize( -1, -1 ).x;
+			if ( width > lableData.widthHint )
+			{
+				lableData.widthHint = width;
+			}
+			columnNameLabel.setLayoutData( lableData );
+
+			final Text columnNameText = new Text( composite, SWT.BORDER );
+			columnNameText.setLayoutData( new GridData( GridData.FILL_HORIZONTAL ) );
+			columnNameText.setText( this.columnName );
+			columnNameText.addModifyListener( new ModifyListener( ) {
+
+				public void modifyText( ModifyEvent arg0 )
+				{
+					columnName = columnNameText.getText( ).trim( );
+					validate( );
+				}
+
+			} );
+
+			Label originalNameLabel = new Label( composite, SWT.BOLD );
+			originalNameLabel.setText( Messages.getString( "FileSelectionWizardPage.label.originalName" ) ); //$NON-NLS-1$
+			width = originalNameLabel.computeSize( -1, -1 ).x;
+			if ( width > lableData.widthHint )
+			{
+				lableData.widthHint = width;
+			}
+			originalNameLabel.setLayoutData( lableData );
+
+			Text originalNameText = new Text( composite, SWT.BORDER
+					| SWT.READ_ONLY );
+			originalNameText.setLayoutData( new GridData( GridData.FILL_HORIZONTAL ) );
+			originalNameText.setText( this.columnOriginalName );
+
+			Label typeLabel = new Label( composite, SWT.BOLD );
+			typeLabel.setLayoutData( lableData );
+			typeLabel.setText( Messages.getString( "FileSelectionWizardPage.label.dataType" ) ); //$NON-NLS-1$
+
+			final CCombo combo = new CCombo( composite, SWT.READ_ONLY
+					| SWT.BORDER );
+			combo.setLayoutData( new GridData( GridData.FILL_HORIZONTAL ) );
+			combo.setItems( dataTypeDisplayNames );
+			combo.setText( columnDataType );
+			combo.addSelectionListener( new SelectionListener( ) {
+
+				public void widgetDefaultSelected( SelectionEvent arg0 )
+				{
+
+				}
+
+				public void widgetSelected( SelectionEvent arg0 )
+				{
+					columnDataType = combo.getText( );
+				}
+
+			} );
+
+			Utility.setSystemHelp( composite,
+					IHelpConstants.CONEXT_ID_COLUMN_EDIT_DIALOG_FLATFILE );
+
+			return parent;
+		}
+
+		private boolean isDuplicatedName( )
+		{
+			for ( int i = 0; i < savedSelectedColumnsInfoList.size( ); i++ )
+			{
+				if ( this.columnOriginalName != null
+						&& this.columnOriginalName.equals( savedSelectedColumnsInfoList.get( i )[1] ) )
+				{
+					continue;
+				}
+
+				if ( this.columnName.equals( savedSelectedColumnsInfoList.get( i )[0] ) )
+				{
+					return true;
+				}
+			}
+			return false;
+		}
+
+		/**
+		 * Validate the page status
+		 * 
+		 */
+		private void validate( )
+		{
+			Status status;
+			if ( this.columnName.trim( ).length( ) == 0 )
+			{
+				status = getMiscStatus( IStatus.ERROR,
+						Messages.getString( "FileSelectionWizardPage.error.selectColumn.EmptyName" ) ); //$NON-NLS-1$
+			}
+			else if ( isDuplicatedName( ) )
+			{
+				status = getMiscStatus( IStatus.ERROR,
+						Messages.getString( "FileSelectionWizardPage.error.selectColumn.duplicatedFileName" ) ); //$NON-NLS-1$
+			}
+			else if ( isNumeric( this.columnName.trim( ) ) )
+			{
+				status = getMiscStatus( IStatus.ERROR,
+						Messages.getString( "FileSelectionWizardPage.error.selectColumn.numberName" ) ); //$NON-NLS-1$			
+			}
+			else
+			{
+				status = getOKStatus( );
+			}
+			updateStatus( status );
+		}
+
+		private Status getOKStatus( )
+		{
+			return getMiscStatus( IStatus.OK, "" ); //$NON-NLS-1$
+		}
+
+		/**
+		 * 
+		 * @param severity
+		 * @param message
+		 * @return
+		 */
+		private Status getMiscStatus( int severity, String message )
+		{
+			return new Status( severity,
+					PlatformUI.PLUGIN_ID,
+					severity,
+					message,
+					null );
+		}
+
+		public String getColumnName( )
+		{
+			return this.columnName;
+		}
+
+		public String getOriginalName( )
+		{
+			return this.columnOriginalName;
+		}
+
+		public String getDataType( )
+		{
+			return this.columnDataType;
+		}
+
+	}
+
+}
diff --git a/plugins/org.eclipse.datatools.connectivity.oda.flatfile.ui/src/org/eclipse/datatools/connectivity/oda/flatfile/ui/wizards/FolderPropertyPage.java b/plugins/org.eclipse.datatools.connectivity.oda.flatfile.ui/src/org/eclipse/datatools/connectivity/oda/flatfile/ui/wizards/FolderPropertyPage.java
new file mode 100644
index 0000000..ccbfcef
--- /dev/null
+++ b/plugins/org.eclipse.datatools.connectivity.oda.flatfile.ui/src/org/eclipse/datatools/connectivity/oda/flatfile/ui/wizards/FolderPropertyPage.java
@@ -0,0 +1,118 @@
+/*
+ *************************************************************************
+ * Copyright (c) 2005, 2007 Actuate Corporation.
+ * 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:
+ *  Actuate Corporation  - initial API and implementation
+ *  
+ *************************************************************************
+ */
+
+package org.eclipse.datatools.connectivity.oda.flatfile.ui.wizards;
+
+import java.util.Properties;
+
+import org.eclipse.datatools.connectivity.IConnectionProfile;
+import org.eclipse.datatools.connectivity.oda.design.ui.wizards.DataSourceEditorPage;
+import org.eclipse.swt.widgets.Composite;
+
+public class FolderPropertyPage extends DataSourceEditorPage
+{
+
+	private FolderSelectionPageHelper pageHelper;
+
+	public FolderPropertyPage( )
+	{
+		super( );
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see
+	 * org.eclipse.datatools.connectivity.oda.design.ui.wizards.DataSourceEditorPage
+	 * #collectCustomProperties(java.util.Properties)
+	 */
+	public Properties collectCustomProperties( Properties profileProps )
+	{
+		/*
+		 * Optionally assigns a custom designer state, for inclusion in the ODA
+		 * design session response, using setResponseDesignerState(
+		 * DesignerState customState );
+		 */
+
+		if ( pageHelper == null )
+			return profileProps;
+
+		return pageHelper.collectCustomProperties( profileProps );
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see
+	 * org.eclipse.datatools.connectivity.oda.design.ui.wizards.DataSourceEditorPage
+	 * #createAndInitCustomControl(org.eclipse.swt.widgets.Composite,
+	 * java.util.Properties)
+	 */
+	protected void createAndInitCustomControl( Composite parent,
+			Properties profileProps )
+	{
+		if ( pageHelper == null )
+			pageHelper = new FolderSelectionPageHelper( this );
+
+		pageHelper.setResourceIdentifiers( getHostResourceIdentifiers( ) );
+		pageHelper.createCustomControl( parent );
+
+		/*
+		 * Optionally hides the Test Connection button, using
+		 * setPingButtonVisible( false );
+		 */
+
+		/*
+		 * Optionally restores the state of a previous design session. Obtains
+		 * designer state, using getInitializationDesignerState();
+		 */
+
+		pageHelper.initCustomControl( profileProps );
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see
+	 * org.eclipse.datatools.connectivity.oda.design.ui.wizards.DataSourceEditorPage
+	 * #refresh(java.util.Properties)
+	 */
+	protected void refresh( Properties customConnectionProps )
+	{
+		if ( pageHelper != null )
+			pageHelper.initCustomControl( customConnectionProps );
+
+		// enable/disable all controls on page in respect of the editable
+		// session state
+		enableAllControls( getControl( ), isSessionEditable( ) );
+		pageHelper.refreshTypeLineCheckBoxStatus( );
+
+		if ( pageHelper != null && isSessionEditable( ) )
+			pageHelper.resetUIStatus( );
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.eclipse.datatools.connectivity.oda.design.internal.ui.
+	 * DataSourceEditorPageCore
+	 * #createTestConnectionRunnable(org.eclipse.datatools
+	 * .connectivity.IConnectionProfile)
+	 */
+	protected Runnable createTestConnectionRunnable( IConnectionProfile profile )
+	{
+		return pageHelper.createTestConnectionRunnable( profile );
+	}
+
+}
diff --git a/plugins/org.eclipse.datatools.connectivity.oda.flatfile.ui/src/org/eclipse/datatools/connectivity/oda/flatfile/ui/wizards/FolderSelectionPageHelper.java b/plugins/org.eclipse.datatools.connectivity.oda.flatfile.ui/src/org/eclipse/datatools/connectivity/oda/flatfile/ui/wizards/FolderSelectionPageHelper.java
new file mode 100644
index 0000000..bc63c79
--- /dev/null
+++ b/plugins/org.eclipse.datatools.connectivity.oda.flatfile.ui/src/org/eclipse/datatools/connectivity/oda/flatfile/ui/wizards/FolderSelectionPageHelper.java
@@ -0,0 +1,1026 @@
+/*
+ *************************************************************************
+ * Copyright (c) 2005, 2011 Actuate Corporation.
+ * 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:
+ *  Actuate Corporation - initial API and implementation
+ *  
+ *************************************************************************
+ */
+
+package org.eclipse.datatools.connectivity.oda.flatfile.ui.wizards;
+
+import java.io.File;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.nio.charset.Charset;
+import java.util.Properties;
+import java.util.SortedMap;
+
+import org.eclipse.datatools.connectivity.IConnection;
+import org.eclipse.datatools.connectivity.IConnectionProfile;
+import org.eclipse.datatools.connectivity.oda.design.ui.designsession.DesignSessionUtil;
+import org.eclipse.datatools.connectivity.oda.design.ui.nls.TextProcessorWrapper;
+import org.eclipse.datatools.connectivity.oda.flatfile.CommonConstants;
+import org.eclipse.datatools.connectivity.oda.flatfile.InvalidResourceException;
+import org.eclipse.datatools.connectivity.oda.flatfile.ResourceLocator;
+import org.eclipse.datatools.connectivity.oda.flatfile.ui.i18n.Messages;
+import org.eclipse.datatools.connectivity.oda.flatfile.ui.util.IHelpConstants;
+import org.eclipse.datatools.connectivity.oda.flatfile.ui.util.Utility;
+import org.eclipse.datatools.connectivity.oda.util.ResourceIdentifiers;
+import org.eclipse.datatools.connectivity.ui.PingJob;
+import org.eclipse.jface.dialogs.IMessageProvider;
+import org.eclipse.jface.preference.PreferencePage;
+import org.eclipse.jface.window.Window;
+import org.eclipse.jface.wizard.WizardPage;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.ScrolledComposite;
+import org.eclipse.swt.events.ModifyEvent;
+import org.eclipse.swt.events.ModifyListener;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Combo;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.DirectoryDialog;
+import org.eclipse.swt.widgets.FileDialog;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Menu;
+import org.eclipse.swt.widgets.MenuItem;
+import org.eclipse.swt.widgets.Text;
+
+public class FolderSelectionPageHelper
+{
+
+	private WizardPage wizardPage;
+	private PreferencePage propertyPage;
+	private ResourceIdentifiers ri;
+
+	private transient Text folderLocation = null;
+	private transient Text fileURI = null;
+	private transient MenuButton browseLocalFileButton = null;
+	private transient Button typeLineCheckBox = null;
+	private transient MenuButton browseFolderButton = null;
+	private transient Combo charSetSelectionCombo = null;
+	private transient Button columnNameLineCheckBox = null;
+	private transient Combo flatFileStyleCombo = null;
+	private transient Button trailNullColsCheckBox = null;
+	private transient Composite parent = null;
+	private transient Button homeFolderChoice = null;
+	private transient Button fileURIChoice = null;
+	private static final String[] fileExtensions = new String[]{
+			"*.csv", "*.psv", "*.ssv", "*.tsv", "*.txt", "*.*"}; //$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$//$NON-NLS-6$
+
+	private static final String[] flatFileStyles = new String[]{
+			Messages.getString( "label.flatfileComma" ), //$NON-NLS-1$
+			Messages.getString( "label.flatfileSemicolon" ),//$NON-NLS-1$
+			Messages.getString( "label.flatfilePipe" ),//$NON-NLS-1$
+			Messages.getString( "label.flatfileTab" ),//$NON-NLS-1$
+	};
+
+	private SortedMap<String, Charset> charSetMap;
+
+	static final String DEFAULT_MESSAGE = Messages.getString( "FolderSelectionPageHelper.SelectFolderDialog.Title" ); //$NON-NLS-1$
+
+	private static final int CORRECT_FOLDER = InvalidResourceException.CORRECT_RESOURCE;
+	private static final int ERROR_INVALID_PATH = InvalidResourceException.ERROR_INVALID_RESOURCE;
+	private static final String EMPTY_STRING = ""; //$NON-NLS-1$
+
+	private static final Integer SELECT_RELATIVE_PATH = 1;
+	private static final Integer SELECT_ABSOLUTE_PATH = 2;
+
+	private boolean needsCheckURITest = true;
+	private String URIValue = EMPTY_STRING;
+
+	FolderSelectionPageHelper( WizardPage page )
+	{
+		wizardPage = page;
+	}
+
+	FolderSelectionPageHelper( PreferencePage page )
+	{
+		propertyPage = page;
+	}
+
+	/**
+	 * 
+	 * @param parent
+	 */
+	void createCustomControl( Composite parent )
+	{
+		ScrolledComposite sComposite = new ScrolledComposite( parent,
+				SWT.H_SCROLL | SWT.V_SCROLL );
+		sComposite.setLayout( new GridLayout( ) );
+		sComposite.setMinWidth( 550 );
+		sComposite.setExpandHorizontal( true );
+
+		this.parent = parent;
+		Composite content = new Composite( sComposite, SWT.NONE );
+		GridLayout layout = new GridLayout( 3, false );
+		content.setLayout( layout );
+
+		// GridData data;
+		setupFolderLocation( content );
+
+		setupFileURI( content );
+
+		setupCharset( content );
+
+		setupFlatfileStyleList( content );
+
+		setupColumnNameLineCheckBox( content );
+
+		setupTypeLineCheckBox( content );
+
+		setupTrailNullsCheckBox( content );
+
+		Point size = content.computeSize( SWT.DEFAULT, SWT.DEFAULT );
+		content.setSize( size.x, size.y );
+
+		sComposite.setContent( content );
+
+		Utility.setSystemHelp( getControl( ),
+				IHelpConstants.CONEXT_ID_DATASOURCE_FLATFILE );
+	}
+
+	/**
+	 * 
+	 * @return
+	 */
+	String getFolderLocation( )
+	{
+		if ( folderLocation == null )
+			return EMPTY_STRING;
+		return getFolderLocationString( );
+	}
+
+	String getFileURI( )
+	{
+		if ( fileURI == null )
+			return EMPTY_STRING;
+		return getFileURIString( );
+	}
+
+	/**
+	 * 
+	 * @return
+	 */
+	String getWhetherUseFirstLineAsColumnNameLine( )
+	{
+		if ( columnNameLineCheckBox == null
+				|| !columnNameLineCheckBox.getEnabled( ) )
+			return EMPTY_STRING;
+		return columnNameLineCheckBox.getSelection( ) ? CommonConstants.INC_COLUMN_NAME_YES
+				: CommonConstants.INC_COLUMN_NAME_NO;
+	}
+
+	/**
+	 * 
+	 * @return
+	 */
+	String getWhetherUseSecondLineAsTypeLine( )
+	{
+		if ( typeLineCheckBox == null )
+			return EMPTY_STRING;
+		return typeLineCheckBox.getSelection( ) ? CommonConstants.INC_TYPE_LINE_YES
+				: CommonConstants.INC_TYPE_LINE_NO;
+	}
+
+	String getWhetherUseTrailNulls( )
+	{
+		if ( trailNullColsCheckBox == null )
+			return EMPTY_STRING;
+		return trailNullColsCheckBox.getSelection( ) ? CommonConstants.TRAIL_NULL_COLS_YES
+				: CommonConstants.TRAIL_NULL_COLS_NO;
+	}
+
+	/**
+	 * 
+	 * @return
+	 */
+	String getCharSet( )
+	{
+		if ( charSetSelectionCombo == null )
+			return EMPTY_STRING;
+		return charSetSelectionCombo.getItem( charSetSelectionCombo.getSelectionIndex( ) );
+	}
+
+	/**
+	 * 
+	 * @param props
+	 * @return
+	 */
+	Properties collectCustomProperties( Properties props )
+	{
+		if ( props == null )
+			props = new Properties( );
+
+		// set custom driver specific properties
+		if ( homeFolderChoice.getSelection( ) )
+		{
+			props.setProperty( CommonConstants.CONN_HOME_DIR_PROP,
+					getFolderLocation( ).trim( ) );
+			props.remove( CommonConstants.CONN_FILE_URI_PROP );
+		}
+		if ( fileURIChoice.getSelection( ) )
+		{
+			props.setProperty( CommonConstants.CONN_FILE_URI_PROP, getFileURI( ) );
+			props.remove( CommonConstants.CONN_HOME_DIR_PROP );
+		}
+
+		props.setProperty( CommonConstants.CONN_DELIMITER_TYPE,
+				getFlatfileStyle( ) );
+		props.setProperty( CommonConstants.CONN_INCLCOLUMNNAME_PROP,
+				getWhetherUseFirstLineAsColumnNameLine( ) );
+		props.setProperty( CommonConstants.CONN_INCLTYPELINE_PROP,
+				getWhetherUseSecondLineAsTypeLine( ) );
+		props.setProperty( CommonConstants.CONN_CHARSET_PROP, getCharSet( ) );
+		props.setProperty( CommonConstants.CONN_TRAILNULLCOLS_PROP,
+				getWhetherUseTrailNulls( ) );
+
+		return props;
+	}
+
+	/**
+	 * 
+	 * @param profileProps
+	 */
+	void initCustomControl( Properties profileProps )
+	{
+		if ( profileProps == null
+				|| profileProps.isEmpty( )
+				|| folderLocation == null
+				|| fileURI == null )
+			return; // nothing to initialize
+
+		String folderPath = profileProps.getProperty( CommonConstants.CONN_HOME_DIR_PROP );
+		if ( folderPath != null )
+		{
+			setFolderLocationString( folderPath );
+			switchFileSelectionMode( true );
+		}
+
+		String fileURI = profileProps.getProperty( CommonConstants.CONN_FILE_URI_PROP );
+		if ( fileURI != null && fileURI.length( ) != 0 )
+		{
+			setFileURIString( fileURI );
+			switchFileSelectionMode( false );
+		}
+
+		String delimiterType = profileProps.getProperty( CommonConstants.CONN_DELIMITER_TYPE );
+		initFlatfileSytleSelection( delimiterType );
+
+		String hasColumnNameLine = profileProps.getProperty( CommonConstants.CONN_INCLCOLUMNNAME_PROP );
+		if ( hasColumnNameLine == null )
+			hasColumnNameLine = CommonConstants.INC_COLUMN_NAME_YES;
+		if ( hasColumnNameLine.equalsIgnoreCase( CommonConstants.INC_COLUMN_NAME_YES ) )
+		{
+			columnNameLineCheckBox.setSelection( true );
+
+			String useSecondLine = profileProps.getProperty( CommonConstants.CONN_INCLTYPELINE_PROP );
+			if ( useSecondLine == null )
+				useSecondLine = EMPTY_STRING;
+			typeLineCheckBox.setEnabled( true );
+			typeLineCheckBox.setSelection( useSecondLine.equalsIgnoreCase( CommonConstants.INC_TYPE_LINE_YES ) );
+		}
+		else
+		{
+			columnNameLineCheckBox.setSelection( false );
+			typeLineCheckBox.setSelection( false );
+			typeLineCheckBox.setEnabled( false );
+		}
+
+		String trailNullCols = profileProps.getProperty( CommonConstants.CONN_TRAILNULLCOLS_PROP );
+		if ( trailNullCols == null )
+			trailNullCols = CommonConstants.TRAIL_NULL_COLS_NO;
+		if ( trailNullCols.equalsIgnoreCase( CommonConstants.TRAIL_NULL_COLS_YES ) )
+		{
+			trailNullColsCheckBox.setSelection( true );
+		}
+		else
+		{
+			trailNullColsCheckBox.setSelection( false );
+		}
+
+		String charSet = profileProps.getProperty( CommonConstants.CONN_CHARSET_PROP );
+		if ( charSet == null || charSet.trim( ).length( ) == 0 )
+			charSetSelectionCombo.select( 0 );
+		else
+			charSetSelectionCombo.select( charSetSelectionCombo.indexOf( charSet ) );
+		validatePageStatus( );
+	}
+
+	/**
+	 * 
+	 * @return the selected flatfile style
+	 */
+	private String getFlatfileStyle( )
+	{
+		String value = flatFileStyleCombo.getText( );
+		// return value;
+		if ( value.equals( flatFileStyles[0] ) )
+		{
+			return CommonConstants.DELIMITER_COMMA;
+		}
+		else if ( value.equals( flatFileStyles[1] ) )
+		{
+			return CommonConstants.DELIMITER_SEMICOLON;
+		}
+		else if ( value.equals( flatFileStyles[2] ) )
+		{
+			return CommonConstants.DELIMITER_PIPE;
+		}
+		else if ( value.equals( flatFileStyles[3] ) )
+		{
+			return CommonConstants.DELIMITER_TAB;
+		}
+		return CommonConstants.DELIMITER_COMMA;
+	}
+
+	/**
+	 * 
+	 * @param folderPath
+	 */
+	private void setFolderLocationString( String folderPath )
+	{
+		folderLocation.setText( TextProcessorWrapper.process( folderPath ) );
+	}
+
+	private void setFileURIString( String file )
+	{
+		file = convertRelativePath( file );
+		fileURI.setText( TextProcessorWrapper.process( file ) );
+	}
+
+	private String convertRelativePath( String file )
+	{
+		String path = file;
+		if ( file != null && file.length( ) > 0 )
+		{
+			try
+			{
+				new URI( file );
+			}
+			catch ( URISyntaxException e )
+			{
+				// Contains back slash or invalid.
+				try
+				{
+					URI uri = new URI( file.replace( '\\', '/' ) );
+					if ( !uri.isAbsolute( ) )
+						path = uri.toString( );
+				}
+				catch ( URISyntaxException e1 )
+				{
+				}
+			}
+		}
+		return path;
+	}
+
+	/**
+	 * 
+	 * @return
+	 */
+	private String getFolderLocationString( )
+	{
+		return TextProcessorWrapper.deprocess( folderLocation.getText( ) );
+	}
+
+	private String getFileURIString( )
+	{
+		return TextProcessorWrapper.deprocess( convertRelativePath( fileURI.getText( ) ) );
+	}
+
+	/**
+	 * 
+	 * @param delimiterType
+	 */
+	private void initFlatfileSytleSelection( String delimiterType )
+	{
+		if ( CommonConstants.DELIMITER_COMMA.equals( delimiterType ) )
+		{
+			flatFileStyleCombo.select( 0 );
+		}
+		else if ( CommonConstants.DELIMITER_SEMICOLON.equals( delimiterType ) )
+		{
+			flatFileStyleCombo.select( 1 );
+		}
+		else if ( CommonConstants.DELIMITER_PIPE.equals( delimiterType ) )
+		{
+			flatFileStyleCombo.select( 2 );
+		}
+		else if ( CommonConstants.DELIMITER_TAB.equals( delimiterType ) )
+		{
+			flatFileStyleCombo.select( 3 );
+		}
+	}
+
+	/**
+	 * 
+	 * @param composite
+	 */
+	private void setupFolderLocation( Composite composite )
+	{
+		homeFolderChoice = new Button( composite, SWT.RADIO );
+		homeFolderChoice.addSelectionListener( new SelectionListener( ) {
+
+			public void widgetSelected( SelectionEvent e )
+			{
+				switchFileSelectionMode( true );
+				validatePageStatus( );
+			}
+
+			public void widgetDefaultSelected( SelectionEvent e )
+			{
+
+			}
+
+		} );
+		homeFolderChoice.setText( Messages.getString( "label.selectFolder" ) ); //$NON-NLS-1$
+
+		GridData data = new GridData( GridData.FILL_HORIZONTAL );
+		folderLocation = new Text( composite, SWT.BORDER );
+		folderLocation.setLayoutData( data );
+		setPageComplete( false );
+		folderLocation.addModifyListener( new ModifyListener( ) {
+
+			public void modifyText( ModifyEvent e )
+			{
+				validatePageStatus( );
+			}
+
+		} );
+
+		browseFolderButton = new MenuButton( composite, SWT.NONE );
+		browseFolderButton.setText( Messages.getString( "button.selectFileURI.browse" ) ); //$NON-NLS-1$
+		browseFolderButton.setToolTipText( Messages.getString( "button.selectFileURI.browse.tooltips" ) ); //$NON-NLS-1$
+
+		Menu menu = new Menu( composite.getShell( ), SWT.POP_UP );
+		SelectionAdapter action = new SelectionAdapter( ) {
+
+			public void widgetSelected( SelectionEvent e )
+			{
+				if ( e.widget instanceof MenuItem )
+				{
+					MenuItem item = (MenuItem) e.widget;
+					Integer type = (Integer) item.getData( );
+					handleFolderSelection( type );
+				}
+				else if ( e.widget instanceof MenuButton )
+				{
+					if ( ri != null )
+					{
+						handleFolderSelection( SELECT_RELATIVE_PATH );
+					}
+					else
+					{
+						handleFolderSelection( SELECT_ABSOLUTE_PATH );
+					}
+				}
+			}
+		};
+
+		MenuItem item;
+		if ( ri != null )
+		{
+			item = new MenuItem( menu, SWT.PUSH );
+			item.setText( Messages.getString( "button.selectFileURI.menuItem.relativePath" ) ); //$NON-NLS-1$
+			item.setData( SELECT_RELATIVE_PATH );
+			item.addSelectionListener( action );
+		}
+
+		item = new MenuItem( menu, SWT.PUSH );
+		item.setText( Messages.getString( "button.selectFileURI.menuItem.absolutePath" ) ); //$NON-NLS-1$
+		item.setData( SELECT_ABSOLUTE_PATH );
+		item.addSelectionListener( action );
+
+		// Add relative path selection support while having resource identifier
+		browseFolderButton.setDropDownMenu( menu );
+		browseFolderButton.addSelectionListener( action );
+
+		GridData btnData = new GridData( );
+		btnData.widthHint = browseFolderButton.computeSize( -1, -1 ).x;
+		browseFolderButton.setLayoutData( btnData );
+	}
+
+	protected void handleFolderSelection( Integer selectionType )
+	{
+		if ( selectionType == SELECT_RELATIVE_PATH )
+		{
+			RelativeFileSelectionDialog dialog = new RelativeFileSelectionDialog( folderLocation.getShell( ),
+					new File( getResourceFolder( ) ),
+					true );
+			if ( dialog.open( ) == Window.OK )
+			{
+				try
+				{
+					URI uri = dialog.getSelectedURI( );
+					if ( uri != null )
+					{
+						setFolderLocationString( uri.getPath( ) );;
+					}
+				}
+				catch ( URISyntaxException e )
+				{
+				}
+			}
+		}
+		else if ( selectionType == SELECT_ABSOLUTE_PATH )
+		{
+			DirectoryDialog dialog = new DirectoryDialog( folderLocation.getShell( ) );
+			String folderLocationValue = getFolderLocationString( );
+			if ( folderLocationValue != null
+					&& folderLocationValue.trim( ).length( ) > 0 )
+			{
+				dialog.setFilterPath( folderLocationValue );
+			}
+
+			dialog.setMessage( DEFAULT_MESSAGE );
+			String selectedLocation = dialog.open( );
+			if ( selectedLocation != null )
+			{
+				setFolderLocationString( selectedLocation );
+			}
+		}
+	}
+
+	private void setupFileURI( Composite composite )
+	{
+		fileURIChoice = new Button( composite, SWT.RADIO );
+		fileURIChoice.addSelectionListener( new SelectionListener( ) {
+
+			public void widgetSelected( SelectionEvent e )
+			{
+				switchFileSelectionMode( false );
+				needsCheckURITest = true;
+				validatePageStatus( );
+				needsCheckURITest = false;
+			}
+
+			public void widgetDefaultSelected( SelectionEvent e )
+			{
+
+			}
+
+		} );
+		fileURIChoice.setText( Messages.getString( "label.fileURI" ) ); //$NON-NLS-1$
+
+		GridData data = new GridData( GridData.FILL_HORIZONTAL );
+		fileURI = new Text( composite, SWT.BORDER );
+		fileURI.setLayoutData( data );
+		setPageComplete( false );
+		fileURI.setToolTipText( Messages.getString( "lable.fileURI.tooltip" ) ); //$NON-NLS-1$
+		fileURI.addModifyListener( new ModifyListener( ) {
+
+			public void modifyText( ModifyEvent e )
+			{
+				if ( !fileURI.getText( ).trim( ).equals( URIValue ) )
+				{
+					needsCheckURITest = true;
+					validatePageStatus( );
+					needsCheckURITest = false;
+					URIValue = fileURI.getText( ).trim( );
+				}
+			}
+
+		} );
+
+		browseLocalFileButton = new MenuButton( composite, SWT.NONE );
+		browseLocalFileButton.setText( Messages.getString( "button.selectFileURI.browse" ) ); //$NON-NLS-1$
+		browseLocalFileButton.setToolTipText( Messages.getString( "button.selectFileURI.browse.tooltips" ) ); //$NON-NLS-1$
+
+		Menu menu = new Menu( composite.getShell( ), SWT.POP_UP );
+		SelectionAdapter action = new SelectionAdapter( ) {
+
+			public void widgetSelected( SelectionEvent e )
+			{
+				if ( e.widget instanceof MenuItem )
+				{
+					MenuItem item = (MenuItem) e.widget;
+					Integer type = (Integer) item.getData( );
+					handleFileSelection( type );
+				}
+				else if ( e.widget instanceof MenuButton )
+				{
+					if ( ri != null )
+					{
+						handleFileSelection( SELECT_RELATIVE_PATH );
+					}
+					else
+					{
+						handleFileSelection( SELECT_ABSOLUTE_PATH );
+					}
+				}
+			}
+		};
+
+		MenuItem item;
+		if ( ri != null )
+		{
+			item = new MenuItem( menu, SWT.PUSH );
+			item.setText( Messages.getString( "button.selectFileURI.menuItem.relativePath" ) ); //$NON-NLS-1$
+			item.setData( SELECT_RELATIVE_PATH );
+			item.addSelectionListener( action );
+		}
+
+		item = new MenuItem( menu, SWT.PUSH );
+		item.setText( Messages.getString( "button.selectFileURI.menuItem.absolutePath" ) ); //$NON-NLS-1$
+		item.setData( SELECT_ABSOLUTE_PATH );
+		item.addSelectionListener( action );
+
+		// Add relative path selection support while having resource identifier
+		browseLocalFileButton.setDropDownMenu( menu );
+		browseLocalFileButton.addSelectionListener( action );
+
+		GridData btnData = new GridData( );
+		btnData.widthHint = browseLocalFileButton.computeSize( -1, -1 ).x;
+		browseLocalFileButton.setLayoutData( btnData );
+	}
+
+	private void handleFileSelection( int selectionType )
+	{
+		if ( selectionType == SELECT_RELATIVE_PATH )
+		{
+			RelativeFileSelectionDialog dialog = new RelativeFileSelectionDialog( fileURI.getShell( ),
+					new File( getResourceFolder( ) ),
+					false );
+			if ( dialog.open( ) == Window.OK )
+			{
+				try
+				{
+					URI uri = dialog.getSelectedURI( );
+					if ( uri != null )
+					{
+						setFileURIString( uri.getPath( ) );
+					}
+				}
+				catch ( URISyntaxException e )
+				{
+				}
+			}
+		}
+		else if ( selectionType == SELECT_ABSOLUTE_PATH )
+		{
+			FileDialog dialog = new FileDialog( fileURI.getShell( ) );
+			String path = getResourceFolder( );
+			if ( path != null && path.trim( ).length( ) > 0 )
+			{
+				dialog.setFilterPath( path );
+			}
+			dialog.setFilterExtensions( fileExtensions );
+			String filePath = dialog.open( );
+
+			if ( filePath != null )
+			{
+				setFileURIString( filePath );
+			}
+		}
+	}
+
+	private String getResourceFolder( )
+	{
+		if ( ri != null )
+		{
+			if ( ri.getApplResourceBaseURI( ) != null )
+			{
+				return new File( ri.getApplResourceBaseURI( ) ).getAbsolutePath( );
+			}
+		}
+		return null;
+	}
+
+	private void switchFileSelectionMode( boolean homeFolder )
+	{
+		folderLocation.setEnabled( homeFolder );
+		browseFolderButton.setEnabled( homeFolder );
+		homeFolderChoice.setSelection( homeFolder );
+
+		fileURI.setEnabled( !homeFolder );
+		browseLocalFileButton.setEnabled( !homeFolder );
+		fileURIChoice.setSelection( !homeFolder );
+	}
+
+	/**
+	 * 
+	 * @return
+	 */
+	private int verifyFileLocation( )
+	{
+		try
+		{
+			return verifyFileLocation( true );
+		}
+		catch ( InvalidResourceException e )
+		{
+			return ERROR_INVALID_PATH;
+		}
+	}
+
+	private void verfiyFileLocation( ) throws InvalidResourceException
+	{
+		verifyFileLocation( false );
+		setMessage( DEFAULT_MESSAGE, IMessageProvider.NONE );
+	}
+
+	private int verifyFileLocation( boolean supressException )
+			throws InvalidResourceException
+	{
+		String folderLocationValue = getFolderLocationString( ).trim( );
+		String fileURIValue = getFileURIString( ).trim( );
+		// folderLocationValue = folderLocationValue.length( ) > 0 ?
+		// folderLocationValue
+		// : null;
+		fileURIValue = fileURIValue.length( ) > 0 ? fileURIValue : null;
+
+		try
+		{
+			if ( fileURIChoice.getSelection( ) )
+				ResourceLocator.validateFileURI( fileURIValue, ri );
+			else if ( homeFolderChoice.getSelection( ) )
+				ResourceLocator.validateHomeFolder( folderLocationValue, ri );
+		}
+		catch ( InvalidResourceException ex )
+		{
+			setMessage( Messages.getString( "error.invalidFlatFilePath" ), IMessageProvider.ERROR ); //$NON-NLS-1$?
+			setPageComplete( false );
+			if ( wizardPage == null ) // Otherwise, show error.
+			{
+				setPageComplete( true );
+				if ( !supressException )
+				{
+					throw ex;
+				}
+			}
+			if ( supressException )
+			{
+				return ERROR_INVALID_PATH;
+			}
+			else
+			{
+				throw ex;
+			}
+		}
+
+		setPageComplete( true );
+		setMessage( DEFAULT_MESSAGE, IMessageProvider.NONE );
+		return CORRECT_FOLDER;
+	}
+
+	/**
+	 * @param composite
+	 */
+	private void setupCharset( Composite composite )
+	{
+		Label labelCharSet = new Label( composite, SWT.NONE );
+		labelCharSet.setText( Messages.getString( "label.selectCharset" ) ); //$NON-NLS-1$
+
+		charSetSelectionCombo = new Combo( composite, SWT.READ_ONLY );
+
+		GridData data = new GridData( GridData.HORIZONTAL_ALIGN_FILL );
+		data.horizontalSpan = 2;
+		charSetSelectionCombo.setLayoutData( data );
+
+		charSetMap = Charset.availableCharsets( );
+		Object[] charSetsArray = charSetMap.keySet( ).toArray( );
+		for ( int i = 0; i < charSetsArray.length; i++ )
+		{
+			String charSetName = charSetMap.get( charSetsArray[i] ).name( );
+			charSetSelectionCombo.add( charSetName );
+			if ( CommonConstants.CONN_DEFAULT_CHARSET.equalsIgnoreCase( charSetName ) )
+				charSetSelectionCombo.select( i );
+		}
+	}
+
+	/**
+	 * To set up the flatfile styles' list
+	 * 
+	 * @param composite
+	 */
+	private void setupFlatfileStyleList( Composite composite )
+	{
+		Label labelCSVType = new Label( composite, SWT.NONE );
+		labelCSVType.setText( Messages.getString( "label.selectFlatfileStyle" ) ); //$NON-NLS-1$
+
+		flatFileStyleCombo = new Combo( composite, SWT.READ_ONLY );
+		GridData data = new GridData( GridData.HORIZONTAL_ALIGN_FILL );
+		data.horizontalSpan = 2;
+		flatFileStyleCombo.setLayoutData( data );
+
+		for ( int i = 0; i < flatFileStyles.length; i++ )
+		{
+			flatFileStyleCombo.add( flatFileStyles[i] );
+		}
+		flatFileStyleCombo.select( 0 );
+	}
+
+	/**
+	 * 
+	 * @param composite
+	 */
+	private void setupColumnNameLineCheckBox( Composite composite )
+	{
+		Label labelFill = new Label( composite, SWT.NONE );
+		labelFill.setText( "" ); //$NON-NLS-1$
+
+		columnNameLineCheckBox = new Button( composite, SWT.CHECK );
+		columnNameLineCheckBox.setToolTipText( Messages.getString( "tooltip.columnnameline" ) ); //$NON-NLS-1$
+		GridData gd = new GridData( );
+		gd.horizontalSpan = 3;
+		columnNameLineCheckBox.setLayoutData( gd );
+		columnNameLineCheckBox.setText( Messages.getString( "label.includeColumnNameLine" ) ); //$NON-NLS-1$
+		columnNameLineCheckBox.setSelection( true );
+		columnNameLineCheckBox.addSelectionListener( new SelectionAdapter( ) {
+
+			public void widgetSelected( SelectionEvent e )
+			{
+				refreshTypeLineCheckBoxStatus( );
+			}
+		} );
+
+	}
+
+	/**
+	 * @param composite
+	 */
+	private void setupTypeLineCheckBox( Composite composite )
+	{
+		typeLineCheckBox = new Button( composite, SWT.CHECK );
+		typeLineCheckBox.setToolTipText( Messages.getString( "tooltip.typeline" ) ); //$NON-NLS-1$
+		GridData data = new GridData( );
+		data.horizontalSpan = 3;
+		typeLineCheckBox.setLayoutData( data );
+		typeLineCheckBox.setText( Messages.getString( "label.includeTypeLine" ) ); //$NON-NLS-1$
+
+	}
+
+	private void setupTrailNullsCheckBox( Composite composite )
+	{
+		trailNullColsCheckBox = new Button( composite, SWT.CHECK );
+		trailNullColsCheckBox.setToolTipText( Messages.getString( "tooltip.trailNull" ) ); //$NON-NLS-1$
+		GridData data = new GridData( );
+		data.horizontalSpan = 3;
+		trailNullColsCheckBox.setLayoutData( data );
+		trailNullColsCheckBox.setText( Messages.getString( "label.trailNull" ) ); //$NON-NLS-1$
+		trailNullColsCheckBox.setSelection( false );
+		trailNullColsCheckBox.setEnabled( true );
+	}
+
+	/**
+	 * 
+	 * @param complete
+	 */
+	private void setPageComplete( boolean complete )
+	{
+		if ( wizardPage != null )
+			wizardPage.setPageComplete( complete );
+		else if ( propertyPage != null )
+			propertyPage.setValid( complete );
+	}
+
+	/**
+	 * 
+	 * @param newMessage
+	 * @param newType
+	 */
+	private void setMessage( String newMessage, int newType )
+	{
+		if ( wizardPage != null )
+			wizardPage.setMessage( newMessage, newType );
+		else if ( propertyPage != null )
+			propertyPage.setMessage( newMessage, newType );
+	}
+
+	private Control getControl( )
+	{
+		if ( wizardPage != null )
+			return wizardPage.getControl( );
+		if ( propertyPage != null )
+			return propertyPage.getControl( );
+
+		return null;
+	}
+
+	public Runnable createTestConnectionRunnable(
+			final IConnectionProfile profile )
+	{
+		return new Runnable( ) {
+
+			public void run( )
+			{
+				IConnection conn = PingJob.createTestConnection( profile );
+
+				Throwable exception = PingJob.getTestConnectionException( conn );
+
+				if ( exception == null ) // succeed in creating connection
+				{
+					exception = testConnection( );
+				}
+
+				PingJob.PingUIJob.showTestConnectionMessage( parent.getShell( ),
+						exception );
+				if ( conn != null )
+				{
+					conn.close( );
+				}
+			}
+
+			private Throwable testConnection( )
+			{
+				Throwable exception = null;
+				try
+				{
+					verfiyFileLocation( );
+				}
+				catch ( InvalidResourceException ex )
+				{
+					exception = ex;
+				}
+				return exception;
+			}
+		};
+	}
+
+	public void setResourceIdentifiers(
+			org.eclipse.datatools.connectivity.oda.design.ResourceIdentifiers resourceIdentifiers )
+	{
+		if ( resourceIdentifiers != null )
+		{
+			this.ri = DesignSessionUtil.createRuntimeResourceIdentifiers( resourceIdentifiers );
+		}
+	}
+
+	public void resetUIStatus( )
+	{
+		if ( getFileURI( ).length( ) > 0 )
+		{
+			switchFileSelectionMode( false );
+		}
+		else
+		{
+			switchFileSelectionMode( true );
+		}
+	}
+
+	protected void refreshTypeLineCheckBoxStatus( )
+	{
+		if ( columnNameLineCheckBox.getSelection( ) )
+			typeLineCheckBox.setEnabled( columnNameLineCheckBox.isEnabled( ) );
+		else
+		{
+			typeLineCheckBox.setSelection( false );
+			typeLineCheckBox.setEnabled( false );
+		}
+	}
+
+	private void validatePageStatus( )
+	{
+		int status = 1;
+		if ( homeFolderChoice.getSelection( ) )
+		{
+			// if ( getFolderLocationString( ).trim( ).length( ) == 0 )
+			// {
+			//				setMessage( Messages.getString( "error.emptyFolderPath" ), //$NON-NLS-1$?
+			// IMessageProvider.ERROR );
+			// status = -1;
+			// }
+			// else
+			if ( verifyFileLocation( ) == ERROR_INVALID_PATH )
+			{
+				setMessage( Messages.getString( "error.invalidFlatFilePath" ), IMessageProvider.ERROR ); //$NON-NLS-1$?
+				status = -1;
+			}
+		}
+		else if ( fileURIChoice.getSelection( ) )
+		{
+			if ( getFileURIString( ).trim( ).length( ) == 0 )
+			{
+				setMessage( Messages.getString( "error.emptyFileURIPath" ),
+						IMessageProvider.ERROR );
+				status = -1;
+			}
+			else if ( needsCheckURITest )
+			{
+				setMessage( Messages.getString( "Connection.warning.untested" ), IMessageProvider.WARNING ); //$NON-NLS-1$
+				status = 0;
+			}
+		}
+
+		if ( status == 1 )
+		{
+			setMessage( DEFAULT_MESSAGE, IMessageProvider.NONE );
+		}
+
+		setPageComplete( status >= 0 );
+	}
+
+}
diff --git a/plugins/org.eclipse.datatools.connectivity.oda.flatfile.ui/src/org/eclipse/datatools/connectivity/oda/flatfile/ui/wizards/FolderSelectionWizardPage.java b/plugins/org.eclipse.datatools.connectivity.oda.flatfile.ui/src/org/eclipse/datatools/connectivity/oda/flatfile/ui/wizards/FolderSelectionWizardPage.java
new file mode 100644
index 0000000..ce16240
--- /dev/null
+++ b/plugins/org.eclipse.datatools.connectivity.oda.flatfile.ui/src/org/eclipse/datatools/connectivity/oda/flatfile/ui/wizards/FolderSelectionWizardPage.java
@@ -0,0 +1,113 @@
+/*
+ *************************************************************************
+ * Copyright (c) 2005, 2007 Actuate Corporation.
+ * 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:
+ *  Actuate Corporation  - initial API and implementation
+ *  
+ *************************************************************************
+ */
+
+package org.eclipse.datatools.connectivity.oda.flatfile.ui.wizards;
+
+import java.util.Properties;
+
+import org.eclipse.datatools.connectivity.IConnectionProfile;
+import org.eclipse.datatools.connectivity.oda.design.ui.wizards.DataSourceWizardPage;
+import org.eclipse.datatools.connectivity.oda.flatfile.ui.i18n.Messages;
+import org.eclipse.swt.widgets.Composite;
+
+public class FolderSelectionWizardPage extends DataSourceWizardPage
+{
+
+	private FolderSelectionPageHelper pageHelper;
+	private Properties folderProperties;
+
+	public FolderSelectionWizardPage( String pageName )
+	{
+		super( pageName );
+		setMessage( Messages.getString( "wizard.WizardTitle.DEFAULT_MESSAGE" ) );  //$NON-NLS-1$
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.datatools.connectivity.oda.design.ui.wizards.DataSourceWizardPage#createPageCustomControl(org.eclipse.swt.widgets.Composite)
+	 */
+	public void createPageCustomControl( Composite parent )
+	{
+		if ( pageHelper == null )
+			pageHelper = new FolderSelectionPageHelper( this );
+		pageHelper.setResourceIdentifiers( getHostResourceIdentifiers( ) );
+		pageHelper.createCustomControl( parent );
+		pageHelper.initCustomControl( folderProperties ); // in case init was called before create 
+
+		/* 
+		 * Optionally hides the Test Connection button, using
+		 *      setPingButtonVisible( false );  
+		 */
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.datatools.connectivity.oda.design.ui.wizards.DataSourceWizardPage#initPageCustomControl(java.util.Properties)
+	 */
+	public void setInitialProperties( Properties dataSourceProps )
+	{
+		folderProperties = dataSourceProps;
+		if ( pageHelper == null )
+			return; // ignore, wait till createPageCustomControl to initialize
+		pageHelper.initCustomControl( folderProperties );
+	}
+    
+    /*
+     * (non-Javadoc)
+     * @see org.eclipse.datatools.connectivity.oda.design.ui.wizards.DataSourceWizardPage#refresh()
+     */
+    public void refresh()
+    {
+        // enable/disable all controls on page in respect of the editable session state
+        enableAllControls( getControl(), isSessionEditable() );
+        
+        if ( pageHelper != null && isSessionEditable() )
+        	pageHelper.resetUIStatus( );
+    }
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.datatools.connectivity.oda.design.ui.wizards.DataSourceWizardPage#collectCustomProperties()
+	 */
+	public Properties collectCustomProperties( )
+	{
+		/* 
+		 * Optionally assign a custom designer state, for inclusion
+		 * in the ODA design session response, using
+		 * setResponseDesignerState( DesignerState customState ); 
+		 */
+
+		if ( pageHelper != null )
+			return pageHelper.collectCustomProperties( folderProperties );
+
+		return ( folderProperties != null ) ? folderProperties
+				: new Properties( );
+	}
+	
+	/*
+	 * (non-Javadoc)
+	 * @see org.eclipse.jface.dialogs.DialogPage#setVisible(boolean)
+	 */
+	public void setVisible( boolean visible )
+	{
+		super.setVisible( visible );
+		getControl( ).setFocus( );
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.datatools.connectivity.oda.design.internal.ui.DataSourceWizardPageCore#createTestConnectionRunnable(org.eclipse.datatools.connectivity.IConnectionProfile)
+	 */
+	protected Runnable createTestConnectionRunnable( IConnectionProfile profile )
+	{
+		return pageHelper.createTestConnectionRunnable( profile );
+	}
+
+}
diff --git a/plugins/org.eclipse.datatools.connectivity.oda.flatfile.ui/src/org/eclipse/datatools/connectivity/oda/flatfile/ui/wizards/MenuButton.java b/plugins/org.eclipse.datatools.connectivity.oda.flatfile.ui/src/org/eclipse/datatools/connectivity/oda/flatfile/ui/wizards/MenuButton.java
new file mode 100644
index 0000000..b167966
--- /dev/null
+++ b/plugins/org.eclipse.datatools.connectivity.oda.flatfile.ui/src/org/eclipse/datatools/connectivity/oda/flatfile/ui/wizards/MenuButton.java
@@ -0,0 +1,528 @@
+/*******************************************************************************
+ * Copyright (c) 2008 Actuate Corporation.
+ * 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:
+ *  Actuate Corporation  - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.datatools.connectivity.oda.flatfile.ui.wizards;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.PaintEvent;
+import org.eclipse.swt.events.PaintListener;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.Font;
+import org.eclipse.swt.graphics.GC;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.graphics.RGB;
+import org.eclipse.swt.graphics.Rectangle;
+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.Event;
+import org.eclipse.swt.widgets.Listener;
+import org.eclipse.swt.widgets.Menu;
+
+/**
+ * 
+ */
+
+public class MenuButton extends Composite
+{
+
+	private Button button;
+
+	private String text;
+	private Image image;
+
+	public String getText( )
+	{
+		return text;
+	}
+
+	public Image getImage( )
+	{
+		return image;
+	}
+
+	private static final int IMAGE_HEIGHT = 16, IMAGE_WIDTH = 16;
+
+	private static int DRAW_FLAGS = SWT.DRAW_MNEMONIC
+			| SWT.DRAW_TAB
+			| SWT.DRAW_TRANSPARENT
+			| SWT.DRAW_DELIMITER;
+
+	private static final int MARGIN_GAP = 4;
+
+	private static final int TRIANGLE_WIDTH = 5;
+
+	private static final int WIDTH_MORE = 2 * MARGIN_GAP + TRIANGLE_WIDTH + 1;
+
+	public void setText( String text )
+	{
+		this.text = text;
+		button.setText( "" ); //$NON-NLS-1$
+		layoutControl( );
+	}
+
+	public void setToolTipText( String string )
+	{
+		button.setToolTipText( string );
+	}
+
+	private void layoutControl( )
+	{
+		getParent( ).layout( );
+		button.redraw( );
+	}
+
+	private Point defaultSize = new Point( 0, 0 );
+
+	public Point computeSize( int wHint, int hHint, boolean changed )
+	{
+
+		int width;
+		int height;
+
+		Button tmp = new Button( this, button.getStyle( ) );
+		if ( text != null )
+		{
+			tmp.setText( text );
+			height = tmp.computeSize( SWT.DEFAULT, SWT.DEFAULT ).y;
+		}
+		else
+		{
+			tmp.setText( "" ); //$NON-NLS-1$
+			height = tmp.computeSize( SWT.DEFAULT, SWT.DEFAULT ).y;
+		}
+		if ( image != null )
+			tmp.setImage( image );
+		Point size = tmp.computeSize( SWT.DEFAULT, SWT.DEFAULT );
+		tmp.dispose( );
+
+		if ( menu != null )
+		{
+			width = size.x + WIDTH_MORE;
+		}
+		else
+			width = size.x;
+
+		if ( isFixed && image != null )
+		{
+			int imageWidth = image.getImageData( ).width;
+			if ( imageWidth > IMAGE_WIDTH )
+				width -= ( imageWidth - IMAGE_WIDTH );
+
+		}
+		if ( !isFixed )
+			height = size.y;
+		defaultSize = new Point( width, height );
+		if ( wHint != SWT.DEFAULT )
+			width = wHint;
+		if ( hHint != SWT.DEFAULT )
+			height = hHint;
+
+		return new Point( width, height );
+	}
+
+	public void setImage( Image image )
+	{
+		this.image = image;
+		layoutControl( );
+	}
+
+	public void setBackground( Color color )
+	{
+		super.setBackground( color );
+		button.setBackground( color );
+		button.redraw( );
+	}
+
+	public void setForeground( Color color )
+	{
+		super.setBackground( color );
+		button.setForeground( color );
+		button.redraw( );
+	}
+
+	public void setFont( Font font )
+	{
+		super.setFont( font );
+		button.setFont( font );
+		button.redraw( );
+	}
+
+	public void setEnabled( boolean enable )
+	{
+		super.setEnabled( enable );
+		button.setEnabled( enable );
+		button.redraw( );
+	}
+
+	public MenuButton( Composite parent, int style )
+	{
+		this( parent, style, false );
+	}
+
+	private boolean isFixed = true;
+
+	private boolean mouseSelection = false;
+
+	private boolean mouseDown = false;
+
+	public MenuButton( Composite parent, int style, boolean fixed )
+	{
+		super( parent, SWT.DOUBLE_BUFFERED );
+		isFixed = fixed;
+		GridLayout layout = new GridLayout( );
+		layout.marginHeight = layout.marginWidth = 0;
+		this.setLayout( layout );
+
+		button = new Button( this, style | SWT.DOUBLE_BUFFERED ) {
+
+			protected void checkSubclass( )
+			{
+
+			}
+
+			public String getText( )
+			{
+				String text = MenuButton.this.getText( );
+				return text == null ? "" : text;
+			}
+		};
+		GridData gd = new GridData( GridData.FILL_BOTH );
+		button.setLayoutData( gd );
+		button.addPaintListener( new PaintListener( ) {
+
+			public void paintControl( final PaintEvent e )
+			{
+				MenuButton.this.paintControl( e );
+			}
+		} );
+
+		button.addListener( SWT.MouseUp, new Listener( ) {
+
+			public void handleEvent( Event e )
+			{
+				if ( !button.isEnabled( ) || e.button != 1 || !mouseDown )
+					return;
+				mouseDown = false;
+				mouseSelection = true;
+				Rectangle size = button.getBounds( );
+				if ( !size.contains( e.x, e.y ) )
+					return;
+				int left = WIDTH_MORE + MARGIN_GAP - 1;
+				if ( menu == null )
+					left = 0;
+
+				if ( e.x < size.width - left )
+				{
+					if ( listeners == null )
+						return;
+
+					e.widget = MenuButton.this;
+
+					for ( int i = 0; i < listeners.size( ); i++ )
+					{
+						( (SelectionListener) listeners.get( i ) ).widgetSelected( new SelectionEvent( e ) );
+					}
+				}
+				else
+				{
+					if ( menu != null )
+					{
+						menu.setLocation( button.toDisplay( new Point( 0,
+								size.height - 1 ) ) );
+						menu.setVisible( true );
+					}
+				}
+			}
+
+		} );
+
+		button.addListener( SWT.MouseDown, new Listener( ) {
+
+			public void handleEvent( Event e )
+			{
+				if ( !button.isEnabled( ) || e.button != 1 )
+					return;
+				mouseSelection = true;
+				Rectangle size = button.getBounds( );
+				if ( !size.contains( e.x, e.y ) )
+					return;
+				mouseDown = true;
+			}
+
+		} );
+		button.addListener( SWT.KeyUp, new Listener( ) {
+
+			public void handleEvent( Event e )
+			{
+				if ( e.keyCode == SWT.ARROW_DOWN || e.keyCode == SWT.ARROW_UP )
+				{
+					if ( menu != null )
+					{
+						Rectangle size = button.getBounds( );
+						menu.setLocation( button.toDisplay( new Point( 0,
+								size.height - 1 ) ) );
+						menu.setVisible( true );
+					}
+				}
+			}
+
+		} );
+		button.addListener( SWT.Selection, new Listener( ) {
+
+			public void handleEvent( Event e )
+			{
+				if ( mouseSelection == true )
+				{
+					mouseSelection = false;
+					return;
+				}
+
+				if ( listeners == null )
+					return;
+
+				e.widget = MenuButton.this;
+
+				for ( int i = 0; i < listeners.size( ); i++ )
+				{
+					( (SelectionListener) listeners.get( i ) ).widgetSelected( new SelectionEvent( e ) );
+				}
+			}
+
+		} );
+	}
+
+	private Menu menu;
+
+	public void setDropDownMenu( Menu menu )
+	{
+		this.menu = menu;
+	}
+
+	private List listeners;
+
+	public void addSelectionListener( SelectionListener listener )
+	{
+		if ( listeners == null )
+			listeners = new ArrayList( );
+		listeners.add( listener );
+	}
+
+	public void removeSelectionListener( SelectionListener listener )
+	{
+		if ( listeners != null )
+		{
+			listeners.remove( listener );
+			if ( listeners.size( ) == 0 )
+				listeners = null;
+		}
+	}
+
+	protected void paintControl( PaintEvent e )
+	{
+		e.gc.setFont( getFont( ) );
+		Color fg = isEnabled( ) ? getForeground( )
+				: new Color( e.gc.getDevice( ),
+						blend( getBackground( ).getRGB( ),
+								getForeground( ).getRGB( ),
+								70 ) );
+		try
+		{
+			e.gc.setForeground( fg );
+			Color bgColor = e.gc.getBackground( );
+			e.gc.setBackground( e.gc.getForeground( ) );
+			Rectangle size = button.getBounds( );
+
+			if ( menu != null )
+			{
+				Rectangle rect = new Rectangle( size.width - 12,
+						0,
+						TRIANGLE_WIDTH,
+						size.height );
+				drawArrow( e.gc, rect, SWT.DOWN );
+			}
+
+			e.gc.setBackground( bgColor );
+
+			int height = e.gc.textExtent( "", DRAW_FLAGS ).y; //$NON-NLS-1$
+
+			if ( !isFixed && image != null )
+			{
+				int imageHeight = image.getImageData( ).height;
+				if ( height < imageHeight )
+					height = imageHeight;
+			}
+
+			if ( defaultSize.y > size.height )
+			{
+				height = height - ( defaultSize.y - size.height );
+				height = e.gc.textExtent( "", DRAW_FLAGS ).y > height ? e.gc.textExtent( "", //$NON-NLS-1$ //$NON-NLS-2$
+						DRAW_FLAGS ).y
+						: height;
+			}
+
+			int left = WIDTH_MORE + MARGIN_GAP - 1;
+
+			if ( menu == null )
+				left = MARGIN_GAP - 1;
+
+			if ( menu != null )
+			{
+				Color fgColor = e.gc.getForeground( );
+				e.gc.setForeground( getDisplay( ).getSystemColor( SWT.COLOR_WIDGET_NORMAL_SHADOW ) );
+				e.gc.drawLine( size.width - left,
+						( size.height - height ) / 2,
+						size.width - left,
+						( size.height - height ) / 2 + height );
+				e.gc.setForeground( fgColor );
+			}
+
+			if ( text != null && text.trim( ).length( ) > 0 )
+			{
+				int width = e.gc.textExtent( text, DRAW_FLAGS ).x;
+				int fontHeight = e.gc.textExtent( text, DRAW_FLAGS ).y;
+				left += ( MARGIN_GAP + width );
+				e.gc.drawText( text,
+						( size.width - left ) / 2 + MARGIN_GAP,
+						( size.height - fontHeight ) / 2,
+						DRAW_FLAGS | SWT.DRAW_TRANSPARENT );
+			}
+
+			if ( image != null )
+			{
+				int imageWidth = image.getImageData( ).width;
+				int imageHeight = image.getImageData( ).height;
+
+				Image imageTemp = null;
+
+				if ( !isEnabled( ) )
+					imageTemp = new Image( e.gc.getDevice( ),
+							image,
+							SWT.IMAGE_DISABLE );
+
+				if ( isFixed )
+				{
+					imageWidth = imageWidth > IMAGE_WIDTH ? IMAGE_WIDTH
+							: imageWidth;
+					imageHeight = imageHeight > IMAGE_HEIGHT ? IMAGE_HEIGHT
+							: imageHeight;
+				}
+
+				left += ( MARGIN_GAP + imageWidth );
+				if ( !isEnabled( ) )
+				{
+					e.gc.drawImage( imageTemp,
+							0,
+							0,
+							imageTemp.getImageData( ).width,
+							imageTemp.getImageData( ).height,
+							( size.width - left ) / 2 + MARGIN_GAP,
+							Math.round( ( (float) ( size.height - imageHeight ) / 2 ) ),
+							imageWidth,
+							imageHeight );
+
+					imageTemp.dispose( );
+				}
+				else
+				{
+					e.gc.drawImage( image,
+							0,
+							0,
+							image.getImageData( ).width,
+							image.getImageData( ).height,
+							( size.width - left ) / 2 + MARGIN_GAP,
+							Math.round( ( (float) ( size.height - imageHeight ) / 2 ) ),
+							imageWidth,
+							imageHeight );
+				}
+			}
+
+		}
+		finally
+		{
+			if ( !isEnabled( ) && fg != null )
+				fg.dispose( );
+		}
+	}
+
+	public static RGB blend( RGB c1, RGB c2, int ratio )
+	{
+		int r = blend( c1.red, c2.red, ratio );
+		int g = blend( c1.green, c2.green, ratio );
+		int b = blend( c1.blue, c2.blue, ratio );
+		return new RGB( r, g, b );
+	}
+
+	private static int blend( int v1, int v2, int ratio )
+	{
+		int b = ( ratio * v1 + ( 100 - ratio ) * v2 ) / 100;
+		return Math.min( 255, b );
+	}
+
+	public static void drawArrow( GC gc, Rectangle rect, int style )
+	{
+		Point point = new Point( rect.x + ( rect.width / 2 ), rect.y
+				+ ( rect.height / 2 ) );
+		int[] points = null;
+		switch ( style )
+		{
+			case SWT.LEFT :
+				points = new int[]{
+						point.x + 2,
+						point.y - 4,
+						point.x + 2,
+						point.y + 4,
+						point.x - 2,
+						point.y
+				};
+				gc.fillPolygon( points );
+				break;
+
+			/*
+			 * Low efficiency because of Win98 bug.
+			 */
+			case SWT.UP :
+				gc.fillRectangle( new Rectangle( point.x, point.y - 1, 1, 1 ) );
+				gc.fillRectangle( new Rectangle( point.x - 1, point.y, 3, 1 ) );
+				gc.fillRectangle( new Rectangle( point.x - 2, point.y + 1, 5, 1 ) );
+				break;
+
+			case SWT.RIGHT :
+				points = new int[]{
+						point.x - 2,
+						point.y - 4,
+						point.x - 2,
+						point.y + 4,
+						point.x + 2,
+						point.y
+				};
+				gc.fillPolygon( points );
+				break;
+
+			/*
+			 * Low efficiency because of Win98 bug.
+			 */
+			default :
+				gc.fillRectangle( new Rectangle( point.x - 2, point.y - 1, 5, 1 ) );
+				gc.fillRectangle( new Rectangle( point.x - 1, point.y, 3, 1 ) );
+				gc.fillRectangle( new Rectangle( point.x, point.y + 1, 1, 1 ) );
+				break;
+		}
+
+	}
+}
diff --git a/plugins/org.eclipse.datatools.connectivity.oda.flatfile.ui/src/org/eclipse/datatools/connectivity/oda/flatfile/ui/wizards/RelativeFileSelectionDialog.java b/plugins/org.eclipse.datatools.connectivity.oda.flatfile.ui/src/org/eclipse/datatools/connectivity/oda/flatfile/ui/wizards/RelativeFileSelectionDialog.java
new file mode 100644
index 0000000..843ad70
--- /dev/null
+++ b/plugins/org.eclipse.datatools.connectivity.oda.flatfile.ui/src/org/eclipse/datatools/connectivity/oda/flatfile/ui/wizards/RelativeFileSelectionDialog.java
@@ -0,0 +1,324 @@
+/*

+ *************************************************************************

+ * Copyright (c) 2011 Actuate Corporation.

+ * 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:

+ *  Actuate Corporation

+ *  

+ *************************************************************************

+ */

+

+package org.eclipse.datatools.connectivity.oda.flatfile.ui.wizards;

+

+import java.io.File;

+import java.io.FileFilter;

+import java.io.Serializable;

+import java.net.URI;

+import java.net.URISyntaxException;

+import java.util.ArrayList;

+import java.util.Arrays;

+import java.util.Comparator;

+import java.util.List;

+

+import org.eclipse.core.runtime.IStatus;

+import org.eclipse.core.runtime.Status;

+import org.eclipse.datatools.connectivity.oda.flatfile.ui.i18n.Messages;

+import org.eclipse.jface.viewers.ILabelProvider;

+import org.eclipse.jface.viewers.ILabelProviderListener;

+import org.eclipse.jface.viewers.ITreeContentProvider;

+import org.eclipse.jface.viewers.Viewer;

+import org.eclipse.swt.graphics.Image;

+import org.eclipse.swt.widgets.Composite;

+import org.eclipse.swt.widgets.Control;

+import org.eclipse.swt.widgets.Shell;

+import org.eclipse.ui.ISharedImages;

+import org.eclipse.ui.PlatformUI;

+import org.eclipse.ui.dialogs.ElementTreeSelectionDialog;

+import org.eclipse.ui.dialogs.ISelectionStatusValidator;

+

+public class RelativeFileSelectionDialog extends ElementTreeSelectionDialog

+{

+

+	private final static Image IMG_FOLDER = PlatformUI.getWorkbench( )

+			.getSharedImages( )

+			.getImage( ISharedImages.IMG_OBJ_FOLDER );

+

+	private final static Image IMG_FILE = PlatformUI.getWorkbench( )

+			.getSharedImages( )

+			.getImage( ISharedImages.IMG_OBJ_FILE );

+

+	private File rootFolder;

+

+	private static boolean showFolder = false;

+

+	public RelativeFileSelectionDialog( Shell parent, File rootFolder )

+	{

+		super( parent, new LabelProvider( ), new ContentProvider( ) );

+

+		assert rootFolder != null;

+

+		this.setValidator( new SelectionValidator( ) );

+		this.setInput( rootFolder.getAbsolutePath( ) );

+		this.setTitle( Messages.getString( "RelativeFileSelectionDialog.Title.SelectFile" ) ); //$NON-NLS-1$

+		this.rootFolder = rootFolder;

+	}

+

+	public RelativeFileSelectionDialog( Shell parent, File rootFolder,

+			boolean showFolder )

+	{

+		super( parent, new LabelProvider( ), new ContentProvider( ) );

+

+		assert rootFolder != null;

+

+		RelativeFileSelectionDialog.showFolder = showFolder;

+

+		this.setValidator( new SelectionValidator( ) );

+		this.setInput( rootFolder.getAbsolutePath( ) );

+		this.setTitle( Messages.getString( "RelativeFileSelectionDialog.Title.SelectFile" ) ); //$NON-NLS-1$

+		this.rootFolder = rootFolder;

+	}

+

+	public URI getSelectedURI( ) throws URISyntaxException

+	{

+		Object[] selection = getResult( );

+		if ( selection != null && selection.length > 0 )

+		{

+			if ( selection[0] instanceof File )

+			{

+				URI baseURI = rootFolder.toURI( );

+				return baseURI.relativize( ( (File) selection[0] ).toURI( ) );

+			}

+		}

+		return null;

+	}

+

+	/*

+	 * (non-Javadoc)

+	 * 

+	 * @see

+	 * org.eclipse.ui.dialogs.ElementTreeSelectionDialog#createDialogArea(org

+	 * .eclipse.swt.widgets.Composite)

+	 */

+	protected Control createDialogArea( Composite parent )

+	{

+		Control c = super.createDialogArea( parent );

+		this.getTreeViewer( ).expandToLevel( 2 );

+		return c;

+	}

+

+	private static class ContentProvider implements ITreeContentProvider

+	{

+

+		public Object[] getChildren( Object arg0 )

+		{

+			if ( arg0 instanceof File )

+			{

+				File f = (File) arg0;

+				return RelativeFileSelectionDialog.getChildren( f );

+			}

+			return null;

+		}

+

+		public Object getParent( Object arg0 )

+		{

+			return null;

+		}

+

+		public boolean hasChildren( Object arg0 )

+		{

+			if ( arg0 instanceof File )

+			{

+				File f = (File) arg0;

+				return RelativeFileSelectionDialog.getChildren( f ).length > 0;

+			}

+			return false;

+		}

+

+		public Object[] getElements( Object arg0 )

+		{

+			if ( arg0 instanceof String )

+			{

+				return new Object[]{

+					new File( (String) arg0 )

+				};

+			}

+			return null;

+		}

+

+		public void dispose( )

+		{

+

+		}

+

+		public void inputChanged( Viewer arg0, Object arg1, Object arg2 )

+		{

+

+		}

+	}

+

+	private static class LabelProvider implements ILabelProvider

+	{

+

+		public Image getImage( Object arg0 )

+		{

+			if ( arg0 instanceof File )

+			{

+				File f = (File) arg0;

+				if ( f.isFile( ) )

+				{

+					return IMG_FILE;

+				}

+				return IMG_FOLDER;

+			}

+			return null;

+		}

+

+		public String getText( Object arg0 )

+		{

+			if ( arg0 instanceof File )

+			{

+				File f = (File) arg0;

+				if ( f.getName( ).trim( ).equals( "" ) ) //$NON-NLS-1$

+				{

+					// For the case "File("C:\\")"

+					return f.getPath( );

+				}

+				return f.getName( );

+			}

+			return ""; //$NON-NLS-1$

+		}

+

+		public void addListener( ILabelProviderListener arg0 )

+		{

+

+		}

+

+		public void dispose( )

+		{

+

+		}

+

+		public boolean isLabelProperty( Object arg0, String arg1 )

+		{

+			return false;

+		}

+

+		public void removeListener( ILabelProviderListener arg0 )

+		{

+

+		}

+

+	}

+

+	private static class SelectionValidator implements

+			ISelectionStatusValidator

+	{

+

+		public IStatus validate( Object[] selections )

+		{

+			if ( selections != null && selections.length > 0 )

+			{

+				for ( Object o : selections )

+				{

+					if ( o instanceof File )

+					{

+						if ( ( showFolder && ( (File) o ).isDirectory( ) )

+								|| ( !showFolder && ( (File) o ).isFile( ) ) )

+						{

+							return new Status( IStatus.OK,

+									"org.eclipse.datatools.connectivity.oda.flatfile.ui", //$NON-NLS-1$

+									IStatus.OK,

+									"", //$NON-NLS-1$

+									null );

+						}

+					}

+				}

+			}

+			return new Status( IStatus.ERROR,

+					"org.eclipse.datatools.connectivity.oda.flatfile.ui", //$NON-NLS-1$

+					IStatus.ERROR,

+					"", //$NON-NLS-1$

+					null );

+		}

+

+	}

+

+	private static File[] getChildren( File f )

+	{

+		if ( !f.isDirectory( ) )

+		{

+			return new File[0];

+		}

+		File[] result = f.listFiles( new FileFilter( ) {

+

+			public boolean accept( File child )

+			{

+				if ( child.isDirectory( ) )

+				{

+					return true;

+				}

+				if ( !showFolder )

+					return true;

+				else

+					return false;

+			}

+		} );

+		if ( result != null )

+		{

+			Arrays.sort( result, new FileComparator( ) );

+		}

+		return result == null ? new File[0] : result;

+	}

+

+	public String[] getSelectedItems( )

+	{

+		List<String> result = new ArrayList<String>( );

+		Object[] selected = this.getResult( ) == null ? new Object[0]

+				: this.getResult( );

+		for ( Object o : selected )

+		{

+			File f = (File) o;

+			if ( ( showFolder && f.isDirectory( ) )

+					|| ( !showFolder && f.isFile( ) ) )

+			{

+				URI relative = rootFolder.toURI( ).relativize( f.toURI( ) );

+				result.add( relative.getPath( ) );

+			}

+		}

+

+		return result.toArray( new String[0] );

+	}

+

+	public static class FileComparator implements

+			Comparator<File>,

+			Serializable

+	{

+

+		private static final long serialVersionUID = 1L;

+

+		public int compare( File o1, File o2 )

+		{

+			if ( o1.isDirectory( ) && o2.isDirectory( ) )

+			{

+				return o1.getName( ).compareTo( o2.getName( ) );

+			}

+			else if ( o1.isFile( ) && o2.isFile( ) )

+			{

+				return o1.getName( ).compareTo( o2.getName( ) );

+			}

+			else if ( o1.isDirectory( ) && !o2.isDirectory( ) )

+			{

+				return -1;

+			}

+			else

+			{

+				// o1 is not a directory but o2 is a directory

+				return 1;

+			}

+		}

+	}

+}

diff --git a/plugins/org.eclipse.datatools.connectivity.oda.flatfile.ui/src/org/eclipse/datatools/connectivity/oda/flatfile/ui/wizards/package.html b/plugins/org.eclipse.datatools.connectivity.oda.flatfile.ui/src/org/eclipse/datatools/connectivity/oda/flatfile/ui/wizards/package.html
new file mode 100644
index 0000000..9780e02
--- /dev/null
+++ b/plugins/org.eclipse.datatools.connectivity.oda.flatfile.ui/src/org/eclipse/datatools/connectivity/oda/flatfile/ui/wizards/package.html
@@ -0,0 +1,42 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<html>
+<head>
+<!--
+
+ *************************************************************************
+ * Copyright (c) 2004, 2006 Actuate Corporation.
+ * 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:
+ *  Actuate Corporation - initial API and implementation
+ *  
+ *************************************************************************
+
+-->
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+</head>
+<body bgcolor="white">
+
+[<b>Non-API</b>] Flat File Data Source Designer - an ODA designer UI extension.
+<p>
+Note: <i>The implementation classes are <b>not</b> public APIs.  
+<br>Backward compatibility support in future releases is not guaranteed.</i>
+
+<h2>Package Specification</h2>
+The ODA flat file designer serves as an exemplary implementation
+of the ODA designer UI framework and extension points, which  
+integrates with the Data Tools Connection Profile framework.
+<p>It allows an user to create and edit an ODA data set design, 
+which defines a CSV data file location and the slice of data to access
+through its run-time driver. 
+
+<!-- Put @see and @since tags down here. -->
+@see org.eclipse.datatools.connectivity.oda.flatfile
+
+@since 3.0
+
+</body>
+</html>
\ No newline at end of file
diff --git a/plugins/org.eclipse.datatools.connectivity.oda.flatfile/.classpath b/plugins/org.eclipse.datatools.connectivity.oda.flatfile/.classpath
new file mode 100644
index 0000000..065ac06
--- /dev/null
+++ b/plugins/org.eclipse.datatools.connectivity.oda.flatfile/.classpath
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="src" path="src"/>
+	<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
+	<classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/plugins/org.eclipse.datatools.connectivity.oda.flatfile/.gitignore b/plugins/org.eclipse.datatools.connectivity.oda.flatfile/.gitignore
new file mode 100644
index 0000000..50a8888
--- /dev/null
+++ b/plugins/org.eclipse.datatools.connectivity.oda.flatfile/.gitignore
@@ -0,0 +1,9 @@
+bin
+*.jar
+*.zip
+testdatabase
+utestreports
+vss*.scc
+plugin_*.properties
+download
+build*.xml
diff --git a/plugins/org.eclipse.datatools.connectivity.oda.flatfile/.options b/plugins/org.eclipse.datatools.connectivity.oda.flatfile/.options
new file mode 100644
index 0000000..058e97c
--- /dev/null
+++ b/plugins/org.eclipse.datatools.connectivity.oda.flatfile/.options
@@ -0,0 +1,12 @@
+# Debug tracing 
+org.eclipse.datatools.connectivity.oda.flatfile/debug = false
+
+# Debug options for ODA framework's trace logging configuration,  
+# whose values may be passed to the oda IDriver.setLogConfiguration method.
+# This serves as a template only, and is not currently supported by the 
+# oda.flatfile driver.
+
+org.eclipse.datatools.connectivity.oda.flatfile/traceLogging/logLevel = WARNING
+org.eclipse.datatools.connectivity.oda.flatfile/traceLogging/logFormatterClass = 
+org.eclipse.datatools.connectivity.oda.flatfile/traceLogging/logFileNamePrefix = 
+org.eclipse.datatools.connectivity.oda.flatfile/traceLogging/logDirectory = 
diff --git a/plugins/org.eclipse.datatools.connectivity.oda.flatfile/.project b/plugins/org.eclipse.datatools.connectivity.oda.flatfile/.project
new file mode 100644
index 0000000..c35535a
--- /dev/null
+++ b/plugins/org.eclipse.datatools.connectivity.oda.flatfile/.project
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>org.eclipse.datatools.connectivity.oda.flatfile</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>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+		<nature>org.eclipse.pde.PluginNature</nature>
+	</natures>
+</projectDescription>
diff --git a/plugins/org.eclipse.datatools.connectivity.oda.flatfile/META-INF/MANIFEST.MF b/plugins/org.eclipse.datatools.connectivity.oda.flatfile/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..ffcbb64
--- /dev/null
+++ b/plugins/org.eclipse.datatools.connectivity.oda.flatfile/META-INF/MANIFEST.MF
@@ -0,0 +1,17 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: %plugin.name
+Bundle-SymbolicName: org.eclipse.datatools.connectivity.oda.flatfile; singleton:=true
+Bundle-Version: 3.3.1.qualifier
+Bundle-RequiredExecutionEnvironment: JavaSE-1.8
+Bundle-Activator: org.eclipse.datatools.connectivity.oda.flatfile.plugin.FlatfilePlugin
+Bundle-Vendor: Eclipse Data Tools Platform
+Bundle-Localization: plugin
+Export-Package: org.eclipse.datatools.connectivity.oda.flatfile,org.eclipse.datatools.connectivity.oda.flatfile.util;x-friends:="org.eclipse.datatools.connectivity.oda.flatfile.tests",
+ org.eclipse.datatools.connectivity.oda.flatfile.util.querytextutil;x-friends:="org.eclipse.datatools.connectivity.oda.flatfile.ui",
+ org.eclipse.datatools.connectivity.oda.flatfile.plugin
+Require-Bundle: org.eclipse.core.runtime,
+ org.eclipse.datatools.connectivity.oda,
+ org.eclipse.datatools.connectivity.oda.profile;resolution:=optional
+Eclipse-LazyStart: true
+Bundle-ActivationPolicy: lazy
diff --git a/plugins/org.eclipse.datatools.connectivity.oda.flatfile/about.html b/plugins/org.eclipse.datatools.connectivity.oda.flatfile/about.html
new file mode 100644
index 0000000..d0a7cc2
--- /dev/null
+++ b/plugins/org.eclipse.datatools.connectivity.oda.flatfile/about.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"/>
+<title>About</title>
+</head>
+<body lang="EN-US">
+<h2>About This Content</h2>
+ 
+<p>June 15, 2009</p>
+<h3>License</h3>
+
+<p>The Eclipse Foundation makes available all content in this plug-in (&quot;Content&quot;).  Unless otherwise 
+indicated below, the Content is provided to you under the terms and conditions of the
+Eclipse Public License Version 1.0 (&quot;EPL&quot;).  A copy of the EPL is available 
+at <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a>.
+For purposes of the EPL, &quot;Program&quot; will mean the Content.</p>
+
+<p>If you did not receive this Content directly from the Eclipse Foundation, the Content is 
+being redistributed by another party (&quot;Redistributor&quot;) and different terms and conditions may
+apply to your use of any object code in the Content.  Check the Redistributor's license that was 
+provided with the Content.  If no such license exists, contact the Redistributor.  Unless otherwise
+indicated below, the terms and conditions of the EPL still apply to any source code in the Content
+and such source code may be obtained at <a href="http://www.eclipse.org">http://www.eclipse.org</a>.</p>
+
+</body>
+</html>
\ No newline at end of file
diff --git a/plugins/org.eclipse.datatools.connectivity.oda.flatfile/build.properties b/plugins/org.eclipse.datatools.connectivity.oda.flatfile/build.properties
new file mode 100644
index 0000000..142ca56
--- /dev/null
+++ b/plugins/org.eclipse.datatools.connectivity.oda.flatfile/build.properties
@@ -0,0 +1,9 @@
+bin.includes = about.html,\
+               plugin.xml,\
+               META-INF/,\
+               .,\
+               plugin.properties
+download.dir =           ./download/
+source.. = src/
+output.. = bin/
+src.includes = about.html
diff --git a/plugins/org.eclipse.datatools.connectivity.oda.flatfile/plugin.properties b/plugins/org.eclipse.datatools.connectivity.oda.flatfile/plugin.properties
new file mode 100644
index 0000000..a7a2f42
--- /dev/null
+++ b/plugins/org.eclipse.datatools.connectivity.oda.flatfile/plugin.properties
@@ -0,0 +1,45 @@
+###############################################################################
+# Copyright (c) 2004, 2012 Actuate Corporation.
+# 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:
+#  Actuate Corporation  - initial API and implementation
+#
+###############################################################################
+# Plug-in Profile Configuration
+#
+oda.data.source.id=org.eclipse.datatools.connectivity.oda.flatfile
+oda.parent.category.id=org.eclipse.datatools.connectivity.oda.profileCategory
+#
+###############################################################################
+# NLS String
+###############################################################################
+plugin.name=Eclipse Data Tools Platform Flat File ODA Runtime Driver
+datasource.name=Flat File Data Source
+dataset.name=Flat File Data Set
+oda.data.source.category.name=Flat File Data Source
+connection.profile.name=ODA Flat File Data Source Connection Profile
+
+datasource.property.home=Home &Folder
+datasource.property.csvdelimitertype=CSV &Type
+datasource.property.charset=&Character Set
+datasource.property.incltypeline=Use Second Line as &Data Type Indicator
+datasource.property.inclcolumnnameline=Use First Line as Column &Name Indicator
+datasource.property.trailnullcols=Use trailing nu&ll columns
+datasource.property.uri=File U&RI
+
+dataset.property.savedcolumnsinfo=The Information about Each Column
+
+property.value.yes=Yes
+property.value.no=No
+property.value.comma=COMMA
+property.value.semicolon=SEMICOLON
+property.value.pipe=PIPE
+property.value.tab=TAB
+#
+#  Below NLS messages apply to all ODA data sources; should be re-factored
+#
+oda.connection.factory.name=ODA Connection Factory
diff --git a/plugins/org.eclipse.datatools.connectivity.oda.flatfile/plugin.xml b/plugins/org.eclipse.datatools.connectivity.oda.flatfile/plugin.xml
new file mode 100644
index 0000000..13e3405
--- /dev/null
+++ b/plugins/org.eclipse.datatools.connectivity.oda.flatfile/plugin.xml
@@ -0,0 +1,251 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<?eclipse version="3.0"?>
+<!--
+/**
+ *************************************************************************
+ * Copyright (c) 2004, 2007 Actuate Corporation.
+ * 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:
+ *  Actuate Corporation - initial API and implementation
+ *  
+ *************************************************************************
+ *
+ * $Id: plugin.xml,v 1.15 2008/07/01 07:59:43 lzhu Exp $
+ */
+-->
+
+<plugin>
+   <extension
+         point="org.eclipse.datatools.connectivity.oda.dataSource">
+      <dataSource
+            odaVersion="3.1"
+            driverClass="org.eclipse.datatools.connectivity.oda.flatfile.FlatFileDriver"
+            defaultDisplayName="%datasource.name"
+            id="%oda.data.source.id"
+            setThreadContextClassLoader="false">
+         <properties>
+            <property
+                  type="string"
+                  defaultDisplayName="%datasource.property.home"
+                  canInherit="true"
+                  name="HOME"/>
+            <property
+                  allowsEmptyValueAsNull="true"
+                  canInherit="true"
+                  defaultDisplayName="%datasource.property.uri"
+                  isEncryptable="false"
+                  name="URI"
+                  type="string">
+            </property>
+         	<property
+                  defaultDisplayName="%datasource.property.csvdelimitertype"
+                  defaultValue="COMMA"
+                  name="DELIMTYPE"
+                  canInherit="true"
+                  type="choice">
+               <choice
+                     defaultDisplayName="%property.value.comma"
+                     name="COMMA"
+                     value="COMMA"/>
+               <choice
+                     defaultDisplayName="%property.value.semicolon"
+                     name="SEMICOLON"
+                     value="SEMICOLON"/>
+               <choice
+                     defaultDisplayName="%property.value.pipe"
+                     name="PIPE"
+                     value="PIPE"/>
+               <choice
+                     defaultDisplayName="%property.value.tab"
+                     name="TAB"
+                     value="TAB"/>
+            </property>      
+            <property
+                  type="string"
+                  defaultDisplayName="%datasource.property.charset"
+                  canInherit="true"
+                  name="CHARSET"/>
+            <property
+                  defaultDisplayName="%datasource.property.inclcolumnnameline"
+                  defaultValue="YES"
+                  name="INCLCOLUMNNAME"
+                  canInherit="true"
+                  type="choice">
+               <choice
+                     defaultDisplayName="%property.value.yes"
+                     name="YES"
+                     value="YES"/>
+               <choice
+                     defaultDisplayName="%property.value.no"
+                     name="NO"
+                     value="NO"/>
+            </property>         
+            <property
+                  defaultDisplayName="%datasource.property.incltypeline"
+                  defaultValue="YES"
+                  name="INCLTYPELINE"
+                  canInherit="true"
+                  type="choice">
+               <choice
+                     defaultDisplayName="%property.value.yes"
+                     name="YES"
+                     value="YES"/>
+               <choice
+                     defaultDisplayName="%property.value.no"
+                     name="NO"
+                     value="NO"/>
+            </property>   
+            <property
+                  defaultDisplayName="%datasource.property.trailnullcols"
+                  defaultValue="NO"
+                  name="TRAILNULLCOLS"
+                  canInherit="true"
+                  type="choice">
+               <choice
+                     defaultDisplayName="%property.value.yes"
+                     name="YES"
+                     value="YES"/>
+               <choice
+                     defaultDisplayName="%property.value.no"
+                     name="NO"
+                     value="NO"/>
+            </property>          
+         </properties>
+      </dataSource>
+      <dataSet
+            defaultDisplayName="%dataset.name"
+            id="org.eclipse.datatools.connectivity.oda.flatfile.dataSet">
+            <dataTypeMapping
+               nativeDataType="BIT"
+               nativeDataTypeCode="4"
+               odaScalarDataType="Integer"/>
+            <dataTypeMapping
+                  nativeDataType="INT"
+                  nativeDataTypeCode="4"
+                  odaScalarDataType="Integer"/>
+            <dataTypeMapping
+                  nativeDataType="INTEGER"
+                  nativeDataTypeCode="4"
+                  odaScalarDataType="Integer"/>
+            <dataTypeMapping
+               nativeDataType="SMALLINT"
+               nativeDataTypeCode="4"
+               odaScalarDataType="Integer"/>
+            <dataTypeMapping
+               nativeDataType="TINYINT"
+               nativeDataTypeCode="4"
+               odaScalarDataType="Integer"/>      
+         	<dataTypeMapping
+               nativeDataType="FLOAT"
+               nativeDataTypeCode="8"
+               odaScalarDataType="Double"/>
+            <dataTypeMapping
+                  nativeDataType="DOUBLE"
+                  nativeDataTypeCode="8"
+                  odaScalarDataType="Double"/>
+            <dataTypeMapping
+               nativeDataType="REAL"
+               nativeDataTypeCode="8"
+               odaScalarDataType="Double"/>
+            <dataTypeMapping
+               nativeDataType="CHAR"
+               nativeDataTypeCode="12"
+               odaScalarDataType="String"/>
+            <dataTypeMapping
+                  nativeDataType="STRING"
+                  nativeDataTypeCode="12"
+                  odaScalarDataType="String"/>
+            <dataTypeMapping
+               nativeDataType="VARCHAR"
+               nativeDataTypeCode="12"
+               odaScalarDataType="String"/>
+         	<dataTypeMapping
+               nativeDataType="LONGVARCHAR"
+               nativeDataTypeCode="12"
+               odaScalarDataType="String"/>
+            <dataTypeMapping
+                  nativeDataType="DATE"
+                  nativeDataTypeCode="91"
+                  odaScalarDataType="Date"/>
+            <dataTypeMapping
+                  nativeDataType="TIME"
+                  nativeDataTypeCode="92"
+                  odaScalarDataType="Time"/>
+            <dataTypeMapping
+                  nativeDataType="DATETIME"
+                  nativeDataTypeCode="93"
+                  odaScalarDataType="Timestamp"/>
+            <dataTypeMapping
+                  nativeDataType="TIMESTAMP"
+                  nativeDataTypeCode="93"
+                  odaScalarDataType="Timestamp"/>
+            <dataTypeMapping
+                  nativeDataType="BLOB"
+                  nativeDataTypeCode="2004"
+                  odaScalarDataType="String"/>
+            <dataTypeMapping
+                  nativeDataType="CLOB"
+                  nativeDataTypeCode="2005"
+                  odaScalarDataType="String"/>
+            <dataTypeMapping
+                  nativeDataType="ANY"
+                  nativeDataTypeCode="12"
+                  odaScalarDataType="String"/>
+            <dataTypeMapping
+               nativeDataType="BINARY"
+               nativeDataTypeCode="12"
+               odaScalarDataType="String"/>
+			<dataTypeMapping
+               nativeDataType="VARBINARY"
+               nativeDataTypeCode="12"
+               odaScalarDataType="String"/>
+         	<dataTypeMapping
+               nativeDataType="LONGVARBINARY"
+               nativeDataTypeCode="12"
+               odaScalarDataType="String"/>               
+            <dataTypeMapping
+               nativeDataType="BIGINT"
+               nativeDataTypeCode="2"
+               odaScalarDataType="Decimal"/>
+            <dataTypeMapping
+                  nativeDataType="DECIMAL"
+                  nativeDataTypeCode="2"
+                  odaScalarDataType="Decimal"/>
+            <dataTypeMapping
+                  nativeDataType="BIGDECIMAL"
+                  nativeDataTypeCode="2"
+                  odaScalarDataType="Decimal"/>
+            <dataTypeMapping
+               nativeDataType="NUMERIC"
+               nativeDataTypeCode="2"
+               odaScalarDataType="Decimal"/>
+            <dataTypeMapping 
+                  nativeDataType="BOOLEAN"
+                  nativeDataTypeCode="16"
+                  odaScalarDataType="Boolean"/>
+      </dataSet>
+   </extension>
+   
+   <extension
+         point="org.eclipse.datatools.connectivity.connectionProfile">
+      <category
+            id="%oda.data.source.id"
+            name="%oda.data.source.category.name"
+            parentCategory="%oda.parent.category.id"/>
+      <connectionProfile
+            category="%oda.data.source.id"
+            id="%oda.data.source.id"
+            name="%connection.profile.name"
+            pingFactory="org.eclipse.datatools.connectivity.oda.profile.OdaConnectionFactory"/>
+      <connectionFactory
+            id="org.eclipse.datatools.connectivity.oda.IConnection"
+            name="%oda.connection.factory.name"
+            class="org.eclipse.datatools.connectivity.oda.profile.OdaConnectionFactory"
+            profile="%oda.data.source.id"/>
+   </extension>
+   
+</plugin>
diff --git a/plugins/org.eclipse.datatools.connectivity.oda.flatfile/src/org/eclipse/datatools/connectivity/oda/flatfile/.gitignore b/plugins/org.eclipse.datatools.connectivity.oda.flatfile/src/org/eclipse/datatools/connectivity/oda/flatfile/.gitignore
new file mode 100644
index 0000000..93bafad
--- /dev/null
+++ b/plugins/org.eclipse.datatools.connectivity.oda.flatfile/src/org/eclipse/datatools/connectivity/oda/flatfile/.gitignore
@@ -0,0 +1 @@
+vss*.scc
diff --git a/plugins/org.eclipse.datatools.connectivity.oda.flatfile/src/org/eclipse/datatools/connectivity/oda/flatfile/CommonConstants.java b/plugins/org.eclipse.datatools.connectivity.oda.flatfile/src/org/eclipse/datatools/connectivity/oda/flatfile/CommonConstants.java
new file mode 100644
index 0000000..6f289f5
--- /dev/null
+++ b/plugins/org.eclipse.datatools.connectivity.oda.flatfile/src/org/eclipse/datatools/connectivity/oda/flatfile/CommonConstants.java
@@ -0,0 +1,109 @@
+/*
+ *******************************************************************************
+ * Copyright (c) 2004, 2008 Actuate Corporation.
+ * 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:
+ *  Actuate Corporation - initial API and implementation
+ *******************************************************************************
+ */
+
+package org.eclipse.datatools.connectivity.oda.flatfile;
+
+/**
+ * The class that defines package-wide static constants.
+ */
+
+public final class CommonConstants
+{
+
+	public static final String CONN_HOME_DIR_PROP = "HOME"; //$NON-NLS-1$
+	public static final String CONN_FILE_URI_PROP = "URI"; //$NON-NLS-1$
+	public static final String CONN_CHARSET_PROP = "CHARSET"; //$NON-NLS-1$
+	public static final String CONN_INCLCOLUMNNAME_PROP = "INCLCOLUMNNAME"; //$NON-NLS-1$
+	public static final String CONN_INCLTYPELINE_PROP = "INCLTYPELINE"; //$NON-NLS-1$
+	public static final String CONN_DEFAULT_CHARSET = "UTF-8"; //$NON-NLS-1$
+	public static final String CONN_DELIMITER_TYPE = "DELIMTYPE"; //$NON-NLS-1$
+	public static final String CONN_TRAILNULLCOLS_PROP = "TRAILNULLCOLS"; //$NON-NLS-1$
+	public static final String CONN_RESOURCE_IDENTIFIER = "RESOURCE_IDENTIFIER"; //$NON-NLS-1$
+
+	public static final String DELIMITER_COMMA = "COMMA"; //$NON-NLS-1$
+	public static final String DELIMITER_COMMA_VALUE = ","; //$NON-NLS-1$
+	// added for flatfiles seperated by semicolon
+	public static final String DELIMITER_SEMICOLON = "SEMICOLON"; //$NON-NLS-1$
+	public static final String DELIMITER_SEMICOLON_VALUE = ";"; //$NON-NLS-1$
+	public static final String DELIMITER_PIPE = "PIPE"; //$NON-NLS-1$
+	public static final String DELIMITER_PIPE_VALUE = "|"; //$NON-NLS-1$
+	public static final String DELIMITER_TAB = "TAB"; //$NON-NLS-1$
+	public static final String DELIMITER_TAB_VALUE = "\t"; //$NON-NLS-1$
+
+	public static final String DELIMITER_SPACE = " "; //$NON-NLS-1$
+	public static final char DELIMITER_DOUBLEQUOTE = '"'; 
+	public static final String KEYWORD_SELECT = "SELECT"; //$NON-NLS-1$
+	public static final String KEYWORD_FROM = "FROM"; //$NON-NLS-1$
+	public static final String KEYWORD_AS = "AS"; //$NON-NLS-1$
+	public static final String KEYWORD_ASTERISK = "*";//$NON-NLS-1$
+	public static final String DRIVER_NAME = "ODA FLAT FILE DRIVER";//$NON-NLS-1$
+	public static final String PRODUCT_VERSION = "3.0"; //$NON-NLS-1$
+	public static final String INC_COLUMN_NAME_YES = "YES"; //$NON-NLS-1$
+	public static final String INC_COLUMN_NAME_NO = "NO"; //$NON-NLS-1$
+	public static final String INC_TYPE_LINE_YES = "YES"; //$NON-NLS-1$
+	public static final String INC_TYPE_LINE_NO = "NO"; //$NON-NLS-1$
+	public static final String TRAIL_NULL_COLS_YES = "YES";
+	public static final String TRAIL_NULL_COLS_NO = "NO";
+
+	public static final int MaxConnections = 0;
+	public static final int MaxStatements = 0;
+
+	/**
+	 * Private constructor to ensure that the class cannot be instantiated.
+	 */
+	private CommonConstants( )
+	{
+	}
+
+	/**
+	 * Get the delimiter value.
+	 * 
+	 * @param delimiterName
+	 * @return
+	 */
+	public static String getDelimiterValue( String delimiterName )
+	{
+		if ( delimiterName.equalsIgnoreCase( CommonConstants.DELIMITER_COMMA ) )
+			return CommonConstants.DELIMITER_COMMA_VALUE;
+		else if ( delimiterName.equalsIgnoreCase( CommonConstants.DELIMITER_SEMICOLON ) )
+			return CommonConstants.DELIMITER_SEMICOLON_VALUE;
+		else if ( delimiterName.equalsIgnoreCase( CommonConstants.DELIMITER_PIPE ) )
+			return CommonConstants.DELIMITER_PIPE_VALUE;
+		else if ( delimiterName.equalsIgnoreCase( CommonConstants.DELIMITER_TAB ) )
+			return CommonConstants.DELIMITER_TAB_VALUE;
+		else
+			return null;
+
+	}
+	
+	/**
+	 * To see if the delimiter name given is legal or not
+	 * 
+	 * @param delimiterName
+	 * @return
+	 */
+	public static boolean isValidDelimiterName( String delimiterName )
+	{
+		if ( delimiterName.equalsIgnoreCase( CommonConstants.DELIMITER_COMMA ) )
+			return true;
+		else if ( delimiterName.equalsIgnoreCase( CommonConstants.DELIMITER_SEMICOLON ) )
+			return true;
+		else if ( delimiterName.equalsIgnoreCase( CommonConstants.DELIMITER_PIPE ) )
+			return true;
+		else if ( delimiterName.equalsIgnoreCase( CommonConstants.DELIMITER_TAB ) )
+			return true;
+		else
+			return false;
+	}
+	
+}
diff --git a/plugins/org.eclipse.datatools.connectivity.oda.flatfile/src/org/eclipse/datatools/connectivity/oda/flatfile/Connection.java b/plugins/org.eclipse.datatools.connectivity.oda.flatfile/src/org/eclipse/datatools/connectivity/oda/flatfile/Connection.java
new file mode 100644
index 0000000..fa0e66d
--- /dev/null
+++ b/plugins/org.eclipse.datatools.connectivity.oda.flatfile/src/org/eclipse/datatools/connectivity/oda/flatfile/Connection.java
@@ -0,0 +1,324 @@
+/*
+ *******************************************************************************
+ * Copyright (c) 2004, 2009 Actuate Corporation.
+ * 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:
+ *  Actuate Corporation - initial API and implementation
+ *******************************************************************************
+ */
+
+package org.eclipse.datatools.connectivity.oda.flatfile;
+
+import java.util.Map;
+import java.util.Properties;
+
+import org.eclipse.datatools.connectivity.oda.IConnection;
+import org.eclipse.datatools.connectivity.oda.IDataSetMetaData;
+import org.eclipse.datatools.connectivity.oda.IQuery;
+import org.eclipse.datatools.connectivity.oda.OdaException;
+import org.eclipse.datatools.connectivity.oda.flatfile.i18n.Messages;
+import org.eclipse.datatools.connectivity.oda.util.ResourceIdentifiers;
+
+import com.ibm.icu.util.ULocale;
+
+/**
+ * Flat file data provider's implementation of the ODA IConnection interface.
+ */
+
+public class Connection implements IConnection
+{
+
+	private boolean isOpen = false;
+
+	@SuppressWarnings("rawtypes")
+	private Map appContext = null;
+	private char delimiter;
+	private String charSet;
+	private boolean hasColumnNames;
+	private boolean hasTypeLine;
+	private boolean trailNullColumns;
+	private String homeFolder;
+	private String fileURI;
+	private Object ri; // ResourceIdentifiers
+
+	/*
+	 * @see
+	 * org.eclipse.datatools.connectivity.oda.IConnection#open(java.util.Properties
+	 * )
+	 */
+	public void open( Properties connProperties ) throws OdaException
+	{
+		if ( connProperties == null )
+			throw new OdaException( Messages.getString( "connection_CONNECTION_PROPERTIES_MISSING" ) ); //$NON-NLS-1$
+
+		populateFileLocation( connProperties );
+
+		populateDelimiter( connProperties );
+
+		populateInclColumnNames( connProperties );
+
+		populateInclTypeLine( connProperties );
+
+		populateTrailNullCols( connProperties );
+
+		populateCharSet( connProperties );
+
+	}
+
+	/**
+	 * Validate the HOME property exists and has specified an existing
+	 * directory.
+	 * 
+	 * @param connProperties
+	 * @throws OdaException
+	 */
+	private void populateFileLocation( Properties connProperties )
+			throws OdaException
+	{
+		homeFolder = connProperties.getProperty( CommonConstants.CONN_HOME_DIR_PROP );
+
+		if ( homeFolder == null )
+			homeFolder = "";
+		// if ( homeFolder != null && homeFolder.trim( ).length() == 0 )
+		// homeFolder = null;
+
+		fileURI = connProperties.getProperty( CommonConstants.CONN_FILE_URI_PROP );
+		if ( fileURI != null && fileURI.trim( ).length( ) == 0 )
+			fileURI = null;
+
+		if ( homeFolder == null && fileURI == null )
+			throw new OdaException( Messages.getString( "connection_MISSING_FILELOCATION" ) ); //$NON-NLS-1$
+
+		this.isOpen = true;
+	}
+
+	/**
+	 * 
+	 * @param connProperties
+	 * @throws OdaException
+	 */
+	private void populateDelimiter( Properties connProperties )
+			throws OdaException
+	{
+		String delimiterName = connProperties.getProperty( CommonConstants.CONN_DELIMITER_TYPE );
+		if ( delimiterName == null )
+		{
+			delimiterName = CommonConstants.DELIMITER_COMMA;
+			connProperties.setProperty( CommonConstants.CONN_DELIMITER_TYPE,
+					delimiterName );
+		}
+		else
+		{
+			if ( CommonConstants.isValidDelimiterName( delimiterName ) )
+				connProperties.setProperty( CommonConstants.CONN_DELIMITER_TYPE,
+						delimiterName );
+			else
+				throw new OdaException( Messages.getString( "Unsupported_Delimiter" ) ); //$NON-NLS-1$
+		}
+
+		this.delimiter = CommonConstants.getDelimiterValue( delimiterName )
+				.charAt( 0 );
+	}
+
+	private void populateCharSet( Properties connProperties )
+	{
+		this.charSet = connProperties.getProperty( CommonConstants.CONN_CHARSET_PROP );
+	}
+
+	/**
+	 * 
+	 * @param connProperties
+	 */
+	private void populateInclColumnNames( Properties connProperties )
+	{
+		boolean includeColumnNames = true;
+		String inclColumnNames = connProperties.getProperty( CommonConstants.CONN_INCLCOLUMNNAME_PROP );
+		if ( inclColumnNames != null && inclColumnNames.trim( ).length( ) > 0 )
+			includeColumnNames = inclColumnNames.equalsIgnoreCase( CommonConstants.INC_COLUMN_NAME_NO ) ? false
+					: true;
+
+		connProperties.setProperty( CommonConstants.CONN_INCLCOLUMNNAME_PROP,
+				includeColumnNames ? CommonConstants.INC_COLUMN_NAME_YES
+						: CommonConstants.INC_COLUMN_NAME_NO );
+
+		this.hasColumnNames = includeColumnNames;
+	}
+
+	/**
+	 * 
+	 * @param connProperties
+	 */
+	private void populateInclTypeLine( Properties connProperties )
+	{
+		boolean includeTypeLine = true;
+		String inclTypeLine = connProperties.getProperty( CommonConstants.CONN_INCLTYPELINE_PROP );
+		if ( inclTypeLine != null && inclTypeLine.trim( ).length( ) > 0 )
+			includeTypeLine = inclTypeLine.equalsIgnoreCase( CommonConstants.INC_TYPE_LINE_NO ) ? false
+					: true;
+
+		connProperties.setProperty( CommonConstants.CONN_INCLTYPELINE_PROP,
+				includeTypeLine ? CommonConstants.INC_TYPE_LINE_YES
+						: CommonConstants.INC_TYPE_LINE_NO );
+
+		this.hasTypeLine = includeTypeLine;
+	}
+
+	private void populateTrailNullCols( Properties connProperties )
+	{
+		boolean trailNullCols = true;
+		String trailNullColsProp = connProperties.getProperty( CommonConstants.CONN_TRAILNULLCOLS_PROP );
+		if ( trailNullColsProp != null
+				&& trailNullColsProp.trim( ).length( ) > 0 )
+			trailNullCols = trailNullColsProp.equalsIgnoreCase( CommonConstants.TRAIL_NULL_COLS_NO ) ? false
+					: true;
+
+		connProperties.setProperty( CommonConstants.CONN_TRAILNULLCOLS_PROP,
+				trailNullCols ? CommonConstants.TRAIL_NULL_COLS_YES
+						: CommonConstants.TRAIL_NULL_COLS_NO );
+
+		this.trailNullColumns = trailNullCols;
+	}
+
+	/*
+	 * @see
+	 * org.eclipse.datatools.connectivity.oda.IConnection#setAppContext(java
+	 * .lang.Object)
+	 */
+	@SuppressWarnings("rawtypes")
+	public void setAppContext( Object context ) throws OdaException
+	{
+		this.appContext = (Map) context;
+	}
+
+	/*
+	 * @see org.eclipse.datatools.connectivity.oda.IConnection#close()
+	 */
+	public void close( ) throws OdaException
+	{
+		this.isOpen = false;
+	}
+
+	/*
+	 * @see org.eclipse.datatools.connectivity.oda.IConnection#isOpen()
+	 */
+	public boolean isOpen( ) throws OdaException
+	{
+		return this.isOpen;
+	}
+
+	/*
+	 * @see
+	 * org.eclipse.datatools.connectivity.oda.IConnection#getMetaData(java.lang
+	 * .String)
+	 */
+	public IDataSetMetaData getMetaData( String dataSetType )
+			throws OdaException
+	{
+		return new DataSetMetaData( this );
+	}
+
+	/*
+	 * @see
+	 * org.eclipse.datatools.connectivity.oda.IConnection#newQuery(java.lang
+	 * .String)
+	 */
+	public IQuery newQuery( String dataSourceType ) throws OdaException
+	{
+		if ( !isOpen( ) )
+			throw new OdaException( Messages.getString( "common_CONNECTION_HAS_NOT_OPEN" ) ); //$NON-NLS-1$
+
+		return new FlatFileQuery( this );
+	}
+
+	/*
+	 * @see org.eclipse.datatools.connectivity.oda.IConnection#commit()
+	 */
+	public void commit( ) throws OdaException
+	{
+		throw new UnsupportedOperationException( );
+	}
+
+	/*
+	 * @see org.eclipse.datatools.connectivity.oda.IConnection#rollback()
+	 */
+	public void rollback( ) throws OdaException
+	{
+		throw new UnsupportedOperationException( );
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see
+	 * org.eclipse.datatools.connectivity.oda.IConnection#setLocale(com.ibm.
+	 * icu.util.ULocale)
+	 */
+	public void setLocale( ULocale locale ) throws OdaException
+	{
+		throw new UnsupportedOperationException( );
+	}
+
+	/*
+	 * @see org.eclipse.datatools.connectivity.oda.IConnection#getMaxQueries()
+	 */
+	public int getMaxQueries( ) throws OdaException
+	{
+		return CommonConstants.MaxStatements;
+	}
+
+	public char getDelimeter( )
+	{
+		return this.delimiter;
+	}
+
+	public String getCharSet( )
+	{
+		return this.charSet;
+	}
+
+	public boolean hasTypeLine( )
+	{
+		return this.hasTypeLine;
+	}
+
+	public boolean hasColumnNames( )
+	{
+		return this.hasColumnNames;
+	}
+
+	public boolean trailNullColumns( )
+	{
+		return this.trailNullColumns;
+	}
+
+	public String getHomeFolder( )
+	{
+		return this.homeFolder;
+	}
+
+	public String getFileURI( )
+	{
+		return this.fileURI;
+	}
+
+	public ResourceInputStream getInputStream( String tableName )
+			throws OdaException
+	{
+		if ( ri == null && appContext != null )
+		{
+			Object resource = appContext.get( ResourceIdentifiers.ODA_APP_CONTEXT_KEY_CONSUMER_RESOURCE_IDS );
+			if ( resource != null )
+			{
+				ri = resource;
+			}
+		}
+		return ResourceLocator.getResourceInputStream( homeFolder,
+				tableName,
+				fileURI,
+				ri );
+	}
+}
diff --git a/plugins/org.eclipse.datatools.connectivity.oda.flatfile/src/org/eclipse/datatools/connectivity/oda/flatfile/DataSetMetaData.java b/plugins/org.eclipse.datatools.connectivity.oda.flatfile/src/org/eclipse/datatools/connectivity/oda/flatfile/DataSetMetaData.java
new file mode 100644
index 0000000..ed3fe7c
--- /dev/null
+++ b/plugins/org.eclipse.datatools.connectivity.oda.flatfile/src/org/eclipse/datatools/connectivity/oda/flatfile/DataSetMetaData.java
@@ -0,0 +1,149 @@
+/*
+ *******************************************************************************
+ * Copyright (c) 2004, 2006 Actuate Corporation.
+ * 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:
+ *  Actuate Corporation - initial API and implementation
+ *******************************************************************************
+ */
+
+package org.eclipse.datatools.connectivity.oda.flatfile;
+
+import org.eclipse.datatools.connectivity.oda.IConnection;
+import org.eclipse.datatools.connectivity.oda.IDataSetMetaData;
+import org.eclipse.datatools.connectivity.oda.IResultSet;
+import org.eclipse.datatools.connectivity.oda.OdaException;
+import org.eclipse.datatools.connectivity.oda.flatfile.i18n.Messages;
+
+/**
+ * Flat file data provider's implementation of the ODA IDataSetMetaData interface.
+ */
+public class DataSetMetaData implements IDataSetMetaData
+{
+
+	private IConnection connection;
+
+	DataSetMetaData( IConnection conn )
+	{
+		connection = conn;
+	}
+
+	/*
+	 * @see org.eclipse.datatools.connectivity.oda.IDataSetMetaData#getConnection()
+	 */
+	public IConnection getConnection( ) throws OdaException
+	{
+		return connection;
+	}
+
+	/*
+	 * @see org.eclipse.datatools.connectivity.oda.IDataSetMetaData#getDataSourceObjects(java.lang.String,
+	 *      java.lang.String, java.lang.String, java.lang.String)
+	 */
+	public IResultSet getDataSourceObjects( String catalog, String schema,
+			String object, String version ) throws OdaException
+	{
+		throw new UnsupportedOperationException( );
+	}
+
+	/*
+	 * @see org.eclipse.datatools.connectivity.oda.IDataSetMetaData#getDataSourceMajorVersion()
+	 */
+	public int getDataSourceMajorVersion( ) throws OdaException
+	{
+		throw new UnsupportedOperationException( );
+	}
+
+	/*
+	 * @see org.eclipse.datatools.connectivity.oda.IDataSetMetaData#getDataSourceMinorVersion()
+	 */
+	public int getDataSourceMinorVersion( ) throws OdaException
+	{
+		throw new UnsupportedOperationException( );
+	}
+
+	/*
+	 * @see org.eclipse.datatools.connectivity.oda.IDataSetMetaData#getDataSourceProductName()
+	 */
+	public String getDataSourceProductName( ) throws OdaException
+	{
+		return Messages.getString( "dataSetMetaData_PRODUCT_NAME" ); //$NON-NLS-1$
+	}
+
+	/*
+	 * @see org.eclipse.datatools.connectivity.oda.IDataSetMetaData#getDataSourceProductVersion()
+	 */
+	public String getDataSourceProductVersion( ) throws OdaException
+	{
+		return CommonConstants.PRODUCT_VERSION;
+	}
+
+	/*
+	 * @see org.eclipse.datatools.connectivity.oda.IDataSetMetaData#getSQLStateType()
+	 */
+	public int getSQLStateType( ) throws OdaException
+	{
+		throw new UnsupportedOperationException( );
+	}
+
+	/*
+	 * @see org.eclipse.datatools.connectivity.oda.IDataSetMetaData#supportsMultipleOpenResults()
+	 */
+	public boolean supportsMultipleOpenResults( ) throws OdaException
+	{
+		return false;
+	}
+
+	/*
+	 * @see org.eclipse.datatools.connectivity.oda.IDataSetMetaData#supportsMultipleResultSets()
+	 */
+	public boolean supportsMultipleResultSets( ) throws OdaException
+	{
+		return false;
+	}
+
+	/*
+	 * @see org.eclipse.datatools.connectivity.oda.IDataSetMetaData#supportsNamedResultSets()
+	 */
+	public boolean supportsNamedResultSets( ) throws OdaException
+	{
+		return false;
+	}
+
+	/*
+	 * @see org.eclipse.datatools.connectivity.oda.IDataSetMetaData#supportsNamedParameters()
+	 */
+	public boolean supportsNamedParameters( ) throws OdaException
+	{
+		return false;
+	}
+
+	/*
+	 * @see org.eclipse.datatools.connectivity.oda.IDataSetMetaData#supportsInParameters()
+	 */
+	public boolean supportsInParameters( ) throws OdaException
+	{
+		return false;
+	}
+
+	/*
+	 * @see org.eclipse.datatools.connectivity.oda.IDataSetMetaData#supportsOutParameters()
+	 */
+	public boolean supportsOutParameters( ) throws OdaException
+	{
+		return false;
+	}
+
+	/*
+	 * @see org.eclipse.datatools.connectivity.oda.IDataSetMetaData#getSortMode()
+	 */
+	public int getSortMode( )
+	{
+		return sortModeNone;
+	}
+
+}
diff --git a/plugins/org.eclipse.datatools.connectivity.oda.flatfile/src/org/eclipse/datatools/connectivity/oda/flatfile/DataTypes.java b/plugins/org.eclipse.datatools.connectivity.oda.flatfile/src/org/eclipse/datatools/connectivity/oda/flatfile/DataTypes.java
new file mode 100644
index 0000000..6832245
--- /dev/null
+++ b/plugins/org.eclipse.datatools.connectivity.oda.flatfile/src/org/eclipse/datatools/connectivity/oda/flatfile/DataTypes.java
@@ -0,0 +1,107 @@
+/*
+ *******************************************************************************
+ * Copyright (c) 2004, 2007 Actuate Corporation.
+ * 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:
+ *  Actuate Corporation - initial API and implementation
+ *******************************************************************************
+ */
+
+package org.eclipse.datatools.connectivity.oda.flatfile;
+
+import java.sql.Types;
+
+import org.eclipse.datatools.connectivity.oda.OdaException;
+import org.eclipse.datatools.connectivity.oda.flatfile.i18n.Messages;
+import org.eclipse.datatools.connectivity.oda.util.manifest.DataTypeMapping;
+import org.eclipse.datatools.connectivity.oda.util.manifest.ExtensionManifest;
+import org.eclipse.datatools.connectivity.oda.util.manifest.ManifestExplorer;
+
+/**
+ * Defines the data types that are supported by this driver.
+ */
+
+public final class DataTypes
+{
+
+    static final int STRING = Types.VARCHAR;
+    static final int NULL = Types.NULL;
+    static final String NULL_LITERAL = "NULL"; //$NON-NLS-1$
+
+    private static final String FLATFILE_DATA_SOURCE_ID = 
+        "org.eclipse.datatools.connectivity.oda.flatfile"; //$NON-NLS-1$
+
+    /**
+     * Returns the data type code that represents the given type name.
+     * @param typeName a data type name
+     * @return the data type code that represents the given type name
+     * @throws OdaException If the given data type name is invalid
+     */
+    public static int getTypeCode( String typeName ) throws OdaException
+    {
+        if( typeName == null || typeName.trim().length() == 0 )
+            return STRING;      // default data type
+              
+        String preparedTypeName = typeName.trim().toUpperCase();
+        
+        if( preparedTypeName.equals( NULL_LITERAL ))
+            return NULL;
+        
+        // get the data type definition from my plugin manifest for all other types
+        DataTypeMapping typeMapping = getManifest().getDataSetType( null )
+                                        .getDataTypeMapping( preparedTypeName );
+        if( typeMapping != null )
+            return typeMapping.getNativeTypeCode();
+
+        throw new OdaException( Messages
+                .getString( "dataTypes_TYPE_NAME_INVALID" ) + typeName ); //$NON-NLS-1$
+    }
+
+    /**
+     * Evaluates whether the given data type name is a valid type supported by
+     * this driver.
+     * @param typeName	a data type name
+     * @return	true if the given data type name is supported by the driver
+     */
+    public static boolean isValidType( String typeName )
+    {
+        String preparedTypeName = typeName.trim().toUpperCase();
+        
+        if( preparedTypeName.equals( NULL_LITERAL ))
+            return true;
+        
+        // check the data type definition in my plugin manifest for all other types
+        DataTypeMapping typeMapping = null;
+        try
+        {
+            typeMapping = getManifest().getDataSetType( null )
+                                            .getDataTypeMapping( preparedTypeName );
+        }
+        catch( OdaException e )
+        {
+            // ignore
+        }
+        
+        return( typeMapping != null );
+    }
+
+    private DataTypes()
+    {
+    }
+    
+    /**
+     * Returns the object that represents this extension's manifest.
+     * @throws OdaException
+     */
+    static ExtensionManifest getManifest()
+        throws OdaException
+    {
+        return ManifestExplorer.getInstance()
+                .getExtensionManifest( FLATFILE_DATA_SOURCE_ID );
+    }
+
+}
diff --git a/plugins/org.eclipse.datatools.connectivity.oda.flatfile/src/org/eclipse/datatools/connectivity/oda/flatfile/FlatFileDriver.java b/plugins/org.eclipse.datatools.connectivity.oda.flatfile/src/org/eclipse/datatools/connectivity/oda/flatfile/FlatFileDriver.java
new file mode 100644
index 0000000..25781bc
--- /dev/null
+++ b/plugins/org.eclipse.datatools.connectivity.oda.flatfile/src/org/eclipse/datatools/connectivity/oda/flatfile/FlatFileDriver.java
@@ -0,0 +1,60 @@
+/*
+ *******************************************************************************
+ * Copyright (c) 2004, 2005 Actuate Corporation.
+ * 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:
+ *  Actuate Corporation  - initial API and implementation
+ *******************************************************************************
+ */
+
+package org.eclipse.datatools.connectivity.oda.flatfile;
+
+import org.eclipse.datatools.connectivity.oda.IConnection;
+import org.eclipse.datatools.connectivity.oda.IDriver;
+import org.eclipse.datatools.connectivity.oda.LogConfiguration;
+import org.eclipse.datatools.connectivity.oda.OdaException;
+
+/**
+ * Flat file data provider's implementation of the ODA IDriver interface.
+ */
+
+public class FlatFileDriver implements IDriver
+{
+    /*
+     * @see org.eclipse.datatools.connectivity.oda.IDriver#getConnection(java.lang.String)
+     */
+    public IConnection getConnection( String dataSourceId )
+            throws OdaException
+    {
+        return new Connection();
+    }
+
+    /*
+     * @see org.eclipse.datatools.connectivity.oda.IDriver#getMaxConnections()
+     */
+    public int getMaxConnections() throws OdaException
+    {
+        return CommonConstants.MaxConnections;
+    }
+
+    /*
+     * @see org.eclipse.datatools.connectivity.oda.IDriver#setAppContext(java.lang.Object)
+     */
+    public void setAppContext( Object context ) throws OdaException
+    {
+        // do nothing; no support for pass-through application context
+    }
+
+    /*
+     * @see org.eclipse.datatools.connectivity.oda.IDriver#setLogConfiguration(org.eclipse.datatools.connectivity.oda.LogConfiguration)
+     */
+    public void setLogConfiguration( LogConfiguration logConfig )
+            throws OdaException
+    {
+        throw new UnsupportedOperationException();
+    }
+}
\ No newline at end of file
diff --git a/plugins/org.eclipse.datatools.connectivity.oda.flatfile/src/org/eclipse/datatools/connectivity/oda/flatfile/FlatFileQuery.java b/plugins/org.eclipse.datatools.connectivity.oda.flatfile/src/org/eclipse/datatools/connectivity/oda/flatfile/FlatFileQuery.java
new file mode 100644
index 0000000..5be383b
--- /dev/null
+++ b/plugins/org.eclipse.datatools.connectivity.oda.flatfile/src/org/eclipse/datatools/connectivity/oda/flatfile/FlatFileQuery.java
@@ -0,0 +1,1274 @@
+/*
+ *******************************************************************************
+ * Copyright (c) 2004, 2009 Actuate Corporation. 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: Actuate Corporation - initial API and implementation
+ ******************************************************************************
+ */
+
+package org.eclipse.datatools.connectivity.oda.flatfile;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.PushbackInputStream;
+import java.io.Reader;
+import java.math.BigDecimal;
+import java.sql.Date;
+import java.sql.Time;
+import java.sql.Timestamp;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Vector;
+
+import org.eclipse.datatools.connectivity.oda.IConnection;
+import org.eclipse.datatools.connectivity.oda.IParameterMetaData;
+import org.eclipse.datatools.connectivity.oda.IQuery;
+import org.eclipse.datatools.connectivity.oda.IResultSet;
+import org.eclipse.datatools.connectivity.oda.IResultSetMetaData;
+import org.eclipse.datatools.connectivity.oda.OdaException;
+import org.eclipse.datatools.connectivity.oda.SortSpec;
+import org.eclipse.datatools.connectivity.oda.flatfile.i18n.Messages;
+import org.eclipse.datatools.connectivity.oda.flatfile.util.FlatFileDataReader;
+import org.eclipse.datatools.connectivity.oda.flatfile.util.querytextutil.QueryTextUtil;
+import org.eclipse.datatools.connectivity.oda.spec.QuerySpecification;
+
+/**
+ * Flat file data provider's implementation of the ODA IQuery interface. It
+ * supports single result set and no input parameters.
+ */
+public class FlatFileQuery implements IQuery
+{
+
+	public static final int DEFAULT_MAX_ROWS = 1000;
+	private static final String NAME_LITERAL = "NAME"; //$NON-NLS-1$
+	private static final String TYPE_LITERAL = "TYPE"; //$NON-NLS-1$
+
+	// whether the CSV file has the column names
+	private boolean hasColumnNames;
+
+	// Whether to use 2nd line as Type line
+	private boolean hasTypeLine ;
+
+	// The table that the query operates on
+	private String currentTableName = null;
+
+	// The max number of rows that can be read
+	private int maxRows = 0;
+
+	// The Connection instance associated with the Query.
+	private Connection connection = null;
+
+	// The meta data of the query's result set.
+	// It is available only after a query is prepared.
+	private ResultSetMetaData resultSetMetaData = null;
+	
+	private ResultSetMetaDataHelper resultSetMetaDataHelper = null;
+
+	/**
+	 * Constructor
+	 * 
+	 * @param connProperties
+	 * @param host
+	 * @throws OdaException 
+	 */
+	public FlatFileQuery(IConnection host ) throws OdaException
+	{
+		if ( host == null
+				|| ( ((Connection) host).getHomeFolder( ) == null && ((Connection) host).getFileURI( ) == null ) )
+			throw new OdaException( Messages.getString( "common_ARGUMENT_CANNOT_BE_NULL" ) ); //$NON-NLS-1$
+		this.connection = (Connection) host;
+		extractsHasColumnNamesInfo( );
+		extractsHasColumnTypeLineInfo( );
+	}
+	
+	/**
+	 * 
+	 *
+	 */
+	private void extractsHasColumnNamesInfo( )
+	{
+		this.hasColumnNames = connection.hasColumnNames( );
+	}
+	
+	/**
+	 * 
+	 *
+	 */
+	private void extractsHasColumnTypeLineInfo( )
+	{
+		this.hasTypeLine = connection.hasTypeLine( );
+	}
+
+	/*
+	 * @see org.eclipse.datatools.connectivity.oda.IQuery#prepare(java.lang.String)
+	 */
+	public void prepare( String queryText ) throws OdaException
+	{
+		if ( queryText != null )
+		{
+			QueryTextUtil qtu = new QueryTextUtil( queryText );
+			String query = qtu.getQuery( );
+			String colInfo = qtu.getColumnsInfo( );
+			validateOpenConnection( );
+			String formattedQuery = formatQueryText( query );
+			prepareMetaData( formattedQuery, colInfo );
+		}
+		else
+			throw new OdaException( Messages.getString( "common_NULL_QUERY_TEXT" ) ); //$NON-NLS-1$
+	}
+
+	/*
+	 * @see org.eclipse.datatools.connectivity.oda.IQuery#setAppContext(java.lang.Object)
+	 */
+	public void setAppContext( Object context ) throws OdaException
+	{
+		// do nothing; no support for pass-through application context
+	}
+
+	/*
+	 * @see org.eclipse.datatools.connectivity.oda.IQuery#setProperty(java.lang.String,
+	 *      java.lang.String)
+	 */
+	public void setProperty( String name, String value ) throws OdaException
+	{
+		throw new UnsupportedOperationException( );
+	}
+
+	/*
+	 * @see org.eclipse.datatools.connectivity.oda.IQuery#close()
+	 */
+	public void close( ) throws OdaException
+	{
+		currentTableName = null;
+		maxRows = 0;
+		connection = null;
+		resultSetMetaData = null;
+	}
+
+	/*
+	 * @see org.eclipse.datatools.connectivity.oda.IQuery#setMaxRows(int)
+	 */
+	public void setMaxRows( int max ) throws OdaException
+	{
+		this.maxRows = max;
+	}
+
+	/*
+	 * @see org.eclipse.datatools.connectivity.oda.IQuery#getMaxRows()
+	 */
+	public int getMaxRows( ) throws OdaException
+	{
+		return this.maxRows;
+	}
+
+	/*
+	 * @see org.eclipse.datatools.connectivity.oda.IQuery#getMetaData()
+	 */
+	public IResultSetMetaData getMetaData( ) throws OdaException
+	{
+		return this.resultSetMetaData;
+	}
+
+	/*
+	 * @see org.eclipse.datatools.connectivity.oda.IQuery#executeQuery()
+	 */
+	public IResultSet executeQuery( ) throws OdaException
+	{
+		return new ResultSet( new FlatFileDataReader( this.connection,
+				this.currentTableName,
+				this.maxRows,
+				this.resultSetMetaData,
+				this.resultSetMetaDataHelper ),
+				this.resultSetMetaData );
+	}
+	
+	/* (non-Javadoc)
+     * @see org.eclipse.datatools.connectivity.oda.IQuery#cancel()
+     */
+    public void cancel() throws OdaException, UnsupportedOperationException
+    {
+        throw new UnsupportedOperationException( );
+    }
+
+    /*
+	 * @see org.eclipse.datatools.connectivity.oda.IQuery#setInt(java.lang.String,
+	 *      int)
+	 */
+	public void setInt( String parameterName, int value ) throws OdaException
+	{
+		throw new UnsupportedOperationException( );
+	}
+
+	/*
+	 * @see org.eclipse.datatools.connectivity.oda.IQuery#setInt(int, int)
+	 */
+	public void setInt( int parameterId, int value ) throws OdaException
+	{
+		throw new UnsupportedOperationException( );
+	}
+
+	/*
+	 * @see org.eclipse.datatools.connectivity.oda.IQuery#setDouble(java.lang.String,
+	 *      double)
+	 */
+	public void setDouble( String parameterName, double value )
+			throws OdaException
+	{
+		throw new UnsupportedOperationException( );
+	}
+
+	/*
+	 * @see org.eclipse.datatools.connectivity.oda.IQuery#setDouble(int, double)
+	 */
+	public void setDouble( int parameterId, double value ) throws OdaException
+	{
+		throw new UnsupportedOperationException( );
+	}
+
+	/*
+	 * @see org.eclipse.datatools.connectivity.oda.IQuery#setBigDecimal(java.lang.String,
+	 *      java.math.BigDecimal)
+	 */
+	public void setBigDecimal( String parameterName, BigDecimal value )
+			throws OdaException
+	{
+		throw new UnsupportedOperationException( );
+	}
+
+	/*
+	 * @see org.eclipse.datatools.connectivity.oda.IQuery#setBigDecimal(int,
+	 *      java.math.BigDecimal)
+	 */
+	public void setBigDecimal( int parameterId, BigDecimal value )
+			throws OdaException
+	{
+		throw new UnsupportedOperationException( );
+	}
+
+	/*
+	 * @see org.eclipse.datatools.connectivity.oda.IQuery#setString(java.lang.String,
+	 *      java.lang.String)
+	 */
+	public void setString( String parameterName, String value )
+			throws OdaException
+	{
+		throw new UnsupportedOperationException( );
+	}
+
+	/*
+	 * @see org.eclipse.datatools.connectivity.oda.IQuery#setString(int,
+	 *      java.lang.String)
+	 */
+	public void setString( int parameterId, String value ) throws OdaException
+	{
+		throw new UnsupportedOperationException( );
+	}
+
+	/*
+	 * @see org.eclipse.datatools.connectivity.oda.IQuery#setDate(java.lang.String,
+	 *      java.sql.Date)
+	 */
+	public void setDate( String parameterName, Date value ) throws OdaException
+	{
+		throw new UnsupportedOperationException( );
+	}
+
+	/*
+	 * @see org.eclipse.datatools.connectivity.oda.IQuery#setDate(int,
+	 *      java.sql.Date)
+	 */
+	public void setDate( int parameterId, Date value ) throws OdaException
+	{
+		throw new UnsupportedOperationException( );
+	}
+
+	/*
+	 * @see org.eclipse.datatools.connectivity.oda.IQuery#setTime(java.lang.String,
+	 *      java.sql.Time)
+	 */
+	public void setTime( String parameterName, Time value ) throws OdaException
+	{
+		throw new UnsupportedOperationException( );
+	}
+
+	/*
+	 * @see org.eclipse.datatools.connectivity.oda.IQuery#setTime(int,
+	 *      java.sql.Time)
+	 */
+	public void setTime( int parameterId, Time value ) throws OdaException
+	{
+		throw new UnsupportedOperationException( );
+	}
+
+	/*
+	 * @see org.eclipse.datatools.connectivity.oda.IQuery#setTimestamp(java.lang.String,
+	 *      java.sql.Timestamp)
+	 */
+	public void setTimestamp( String parameterName, Timestamp value )
+			throws OdaException
+	{
+		throw new UnsupportedOperationException( );
+	}
+
+	/*
+	 * @see org.eclipse.datatools.connectivity.oda.IQuery#setTimestamp(int,
+	 *      java.sql.Timestamp)
+	 */
+	public void setTimestamp( int parameterId, Timestamp value )
+			throws OdaException
+	{
+		throw new UnsupportedOperationException( );
+	}
+
+    /* (non-Javadoc)
+     * @see org.eclipse.datatools.connectivity.oda.IQuery#setBoolean(java.lang.String, boolean)
+     */
+    public void setBoolean( String parameterName, boolean value )
+            throws OdaException
+    {
+        throw new UnsupportedOperationException();
+    }
+
+    /* (non-Javadoc)
+     * @see org.eclipse.datatools.connectivity.oda.IQuery#setBoolean(int, boolean)
+     */
+    public void setBoolean( int parameterId, boolean value )
+            throws OdaException
+    {
+        throw new UnsupportedOperationException();
+    }
+
+    /* (non-Javadoc)
+     * @see org.eclipse.datatools.connectivity.oda.IQuery#setObject(int, java.lang.Object)
+     */
+    public void setObject( int parameterId, Object value ) throws OdaException
+    {
+        throw new UnsupportedOperationException();
+    }
+
+    /* (non-Javadoc)
+     * @see org.eclipse.datatools.connectivity.oda.IQuery#setObject(java.lang.String, java.lang.Object)
+     */
+    public void setObject( String parameterName, Object value )
+            throws OdaException
+    {
+        throw new UnsupportedOperationException();
+    }
+
+    /* (non-Javadoc)
+     * @see org.eclipse.datatools.connectivity.oda.IQuery#setNull(java.lang.String)
+     */
+    public void setNull( String parameterName ) throws OdaException
+    {
+        throw new UnsupportedOperationException();
+    }
+
+    /* (non-Javadoc)
+     * @see org.eclipse.datatools.connectivity.oda.IQuery#setNull(int)
+     */
+    public void setNull( int parameterId ) throws OdaException
+    {
+        throw new UnsupportedOperationException();
+    }
+
+    /*
+	 * @see org.eclipse.datatools.connectivity.oda.IQuery#findInParameter(java.lang.String)
+	 */
+	public int findInParameter( String parameterName ) throws OdaException
+	{
+		throw new UnsupportedOperationException( );
+	}
+
+	/*
+	 * @see org.eclipse.datatools.connectivity.oda.IQuery#getParameterMetaData()
+	 */
+	public IParameterMetaData getParameterMetaData( ) throws OdaException
+	{
+		throw new UnsupportedOperationException( );
+	}
+
+	/*
+	 * @see org.eclipse.datatools.connectivity.oda.IQuery#clearInParameters()
+	 */
+	public void clearInParameters( ) throws OdaException
+	{
+		throw new UnsupportedOperationException( );
+	}
+
+	/*
+	 * @see org.eclipse.datatools.connectivity.oda.IQuery#setSortSpec(org.eclipse.datatools.connectivity.oda.SortSpec)
+	 */
+	public void setSortSpec( SortSpec sortBy ) throws OdaException
+	{
+		throw new UnsupportedOperationException( );
+	}
+
+	/*
+	 * @see org.eclipse.datatools.connectivity.oda.IQuery#getSortSpec()
+	 */
+	public SortSpec getSortSpec( ) throws OdaException
+	{
+		throw new UnsupportedOperationException( );
+	}
+
+    /* (non-Javadoc)
+     * @see org.eclipse.datatools.connectivity.oda.IQuery#setSpecification(org.eclipse.datatools.connectivity.oda.spec.QuerySpecification)
+     */
+    public void setSpecification( QuerySpecification querySpec )
+            throws OdaException, UnsupportedOperationException
+    {
+        throw new UnsupportedOperationException( );
+    }
+
+    /* (non-Javadoc)
+     * @see org.eclipse.datatools.connectivity.oda.IQuery#getSpecification()
+     */
+    public QuerySpecification getSpecification()
+    {
+        return null;
+    }
+
+    /* (non-Javadoc)
+     * @see org.eclipse.datatools.connectivity.oda.IQuery#getEffectiveQueryText()
+     */
+    public String getEffectiveQueryText()
+    {
+        throw new UnsupportedOperationException();
+    }
+
+    /**
+	 * Validate whether the query's connection is open.
+	 * 
+	 * @throws OdaException
+	 *             if connection is not open yet
+	 */
+	private void validateOpenConnection( ) throws OdaException
+	{
+		if ( connection.isOpen( ) == false )
+			throw new OdaException( Messages.getString( "common_CONNECTION_IS_NOT_OPEN" ) ); //$NON-NLS-1$
+	}
+
+	/**
+	 * Validate whether the given query text is empty.
+	 * 
+	 * @param formattedQuery
+	 *            the trimed query text
+	 * @throws OdaException
+	 *             if the given text is empty
+	 */
+	private void validateNonEmptyQueryText( String formattedQuery )
+			throws OdaException
+	{
+		if ( formattedQuery == null || formattedQuery.length( ) == 0 )
+			throw new OdaException( Messages.getString( "query_COMMAND_IS_EMPTY" ) ); //$NON-NLS-1$
+	}
+
+	/**
+	 * Validate whether the given query segments contains a single table name.
+	 * 
+	 * @param parsedQuerySegments
+	 * @throws OdaException
+	 *             if the given query contains multiple table names
+	 */
+	private void validateSingleTableQuery( String[] parsedQuerySegments )
+			throws OdaException
+	{
+		if ( getPreparedTableNames( parsedQuerySegments ).split( CommonConstants.DELIMITER_COMMA_VALUE ).length != 1 )
+			throw new OdaException( Messages.getString( "query_DO_NOT_SUPPORT_CROSS_TABLE_QUERY" ) ); //$NON-NLS-1$
+	}
+
+	/**
+	 * Return the String that contains column name(s) selected in a query.
+	 * Multiple column names, if any, are separated by comma.
+	 * 
+	 * @param parsedQueryFragments
+	 *            the string array which is generated by the
+	 *            parsePreparedQueryText method
+	 * @return the comma-separated column names selected in a query
+	 */
+	private String getPreparedColumnNames( String[] parsedQueryFragments )
+	{
+		return parsedQueryFragments[0];
+	}
+
+	/**
+	 * Return the String that contains column label(s) selected in a query.
+	 * Multiple column labels, if any, are separated by comma.
+	 * 
+	 * @param parsedQueryFragments
+	 *            the string array which is generated by the
+	 *            parsePreparedQueryText method
+	 * @return the comma-separated column labels selected in a query
+	 */
+	private String getPreparedColumnLabels( String[] parsedQueryFragments )
+	{
+		return parsedQueryFragments[1];
+	}
+
+	/**
+	 * Return the String which contains the identifiers in the FROM clause.
+	 * 
+	 * @param parsedQueryFragments
+	 *            the string array which is generated by the
+	 *            parsePreparedQueryText method
+	 * @return a String that contains table name(s) after the FROM keyword
+	 */
+	private String getPreparedTableNames( String[] parsedQueryFragments )
+	{
+		return parsedQueryFragments[2];
+	}
+
+	/**
+	 * Parse the command by separating keywords and other parts of a SQL SELECT
+	 * query text.
+	 * 
+	 * @param formattedQuery
+	 *            SQL SELECT query: SELECT COLUMNNAME (AS ALIAS)[,COLUMNNAME2
+	 *            (AS ALIAS)] FROM TABLENAME
+	 * @return a String array with first element that holds all the
+	 *         comma-separated column names, the second element that holds all
+	 *         the comma-separated column display labels, and the third element
+	 *         for table name(s) in FROM clause
+	 * @throws OdaException
+	 *             if the given query is not valid.
+	 */
+	private String[] parsePreparedQueryText( String formattedQuery )
+			throws OdaException
+	{
+
+		return QueryTextUtil.getQueryMetaData( formattedQuery );
+	}
+
+	/**
+	 * 
+	 * @param queryColumnNames
+	 * @return
+	 */
+	private Vector<String> getQueryColumnNamesVector( String queryColumnNames )
+	{
+		Vector<String> result = new Vector<String>( );
+		char[] chars = queryColumnNames.toCharArray( );
+		List<Integer> indiceList = new ArrayList<Integer>( );
+		boolean inQuote = false;
+		boolean isEscaped = false;
+		int beginIndex = 0;
+		int endIndex = 0;
+
+		for ( int i = 0; i < chars.length; i++ )
+		{
+			if ( chars[i] == '"' )
+			{
+				if ( !isEscaped )
+					inQuote = !inQuote;
+				else
+					isEscaped = !isEscaped;
+			}
+			else if ( chars[i] == '\\' )
+			{
+				isEscaped = !isEscaped;
+			}
+			else if ( chars[i] == ',' )
+			{
+				if ( inQuote )
+					continue;
+				else
+					indiceList.add( new Integer( i ) );
+			}
+		}
+
+		if ( indiceList.size( ) > 0 )
+		{
+			for ( int j = 0; j < indiceList.size( ); j++ )
+			{
+
+				endIndex = ( (Integer) indiceList.get( j ) ).intValue( );
+
+				result.add( queryColumnNames.substring( beginIndex,
+						endIndex ).trim( ) );
+				beginIndex = endIndex + 1;
+
+				if ( j == indiceList.size( ) - 1 )
+				{
+					result.add( queryColumnNames.substring( beginIndex,
+							queryColumnNames.length( ) ).trim( ) );
+				}
+			}
+		}
+		else
+			result.add( queryColumnNames );
+
+		return result;
+	}
+	
+	/**
+	 * 
+	 * @param queryColumnNames
+	 * @return
+	 */
+	private Vector<String> stripFormatInfoFromQueryColumnNames( Vector<String> queryColumnNames )
+	{
+		Vector<String> columnNames = new Vector<String>( );
+		
+		boolean isEscaped = false;
+		
+		for(int i = 0; i< queryColumnNames.size( ); i++)
+		{
+			StringBuffer sb = new StringBuffer();
+			char[] chars = ((String)queryColumnNames.get( i )).toCharArray( );
+			
+			if(chars[0]!=CommonConstants.DELIMITER_DOUBLEQUOTE)
+			{
+				columnNames.add( queryColumnNames.get( i ) );
+				continue;
+			}
+			
+			for(int j = 0; j <chars.length; j++)
+			{
+				if(chars[j]==CommonConstants.DELIMITER_DOUBLEQUOTE)
+				{
+					if (isEscaped)
+					{
+						sb.append( chars[j] );
+						isEscaped = !isEscaped;
+					}
+				}
+				else if( chars[j] == '\\')
+				{
+					if(isEscaped)
+						sb.append( chars[j] );
+						
+					isEscaped = !isEscaped;
+				}
+				else
+					sb.append( chars[j] );
+			}
+			
+			columnNames.add( sb.toString( ) );
+		}
+		
+		return columnNames;
+	}
+	
+	/**
+	 * 
+	 * @param columnCount
+	 * @return
+	 */
+	private String[] createTempColumnNames( int columnCount )
+	{
+		String[] tempColumnNames = new String[columnCount];
+
+		for ( int i = 0; i < columnCount; i++ )
+		{
+			tempColumnNames[i] = "COLUMN_" + ( i + 1 ); //$NON-NLS-1$
+		}
+
+		return tempColumnNames;
+	}
+
+	/**
+	 * 
+	 * @param columnCount
+	 * @return
+	 */
+	private String[] createTempColumnTypes( int columnCount )
+	{
+		String[] tempColumnTypes = new String[columnCount];
+
+		for ( int i = 0; i < columnCount; i++ )
+		{
+			tempColumnTypes[i] = "STRING"; //$NON-NLS-1$
+		}
+
+		return tempColumnTypes;
+	}
+
+	/**
+	 * Returns a specified array of metadata info
+	 * 
+	 * @param tableName
+	 * @param metaDataType:
+	 *            currently has two values: "NAME" and "TYPE"
+	 * @return String[] an array that holds the specified metadata
+	 * @throws OdaException
+	 */
+	private String[] discoverActualColumnMetaData( String tableName,
+			String metaDataType ) throws OdaException
+	{
+		FlatFileDataReader ffdsr = new FlatFileDataReader( this.connection,
+				tableName,
+				0,
+				null,
+				null );
+		try
+		{
+			if ( !( metaDataType.trim( ).equalsIgnoreCase( NAME_LITERAL ) || metaDataType.trim( )
+					.equalsIgnoreCase( TYPE_LITERAL ) ) )
+				throw new OdaException( Messages.getString( "query_ARGUMENT_ERROR" ) ); //$NON-NLS-1$
+
+			// if want to discover type information then just skip all the empty
+			// lines and the first
+			// line
+			if ( metaDataType.trim( ).equalsIgnoreCase( TYPE_LITERAL ) )
+			{
+				while ( FlatFileDataReader.isEmptyRow( ffdsr.readLine( ) ) )
+					continue;
+			}
+			// Skip all the empty lines until reach the first line
+			List<String> columnNameLine;
+			while ( FlatFileDataReader.isEmptyRow( columnNameLine = ffdsr.readLine( ) ) )
+				continue;
+
+			String[] result = ffdsr.getColumnNameArray( columnNameLine );
+
+
+			if ( metaDataType.trim( ).equalsIgnoreCase( NAME_LITERAL ) )
+				this.validateUniqueName( result );
+			if ( metaDataType.trim( ).equalsIgnoreCase( TYPE_LITERAL ) )
+				validateColumnTypeConsistency( result );
+
+			return trimStringArray( result );
+
+		}
+		finally 
+		{
+			ffdsr.clearBufferedReader( );
+		}
+	}
+
+	/**
+	 * @param result
+	 * @return
+	 */
+	private String[] trimStringArray( String[] array )
+	{
+		String[] result = new String[array.length];
+		for ( int i = 0; i < result.length; i++ )
+			result[i] = array[i].trim( );
+		return result;
+	}
+
+	/**
+	 * Check whether a column name given in query has exactly one occurance in
+	 * actual table
+	 * 
+	 * @param cCN
+	 *            the array of column names in query
+	 * @param aCN
+	 *            the array of column names in actual table
+	 * @throws OdaException
+	 */
+	private void validateColumnName( String[] cCN, String[] aCN )
+			throws OdaException
+	{
+		for ( int i = 0; i < cCN.length; i++ )
+		{
+			if ( this.findOccuranceOfValueInStringArray( cCN[i], aCN ) != 1 )
+			{
+				throw new OdaException( Messages.getString( "query_COMMAND_NOT_VALID" ) ); //$NON-NLS-1$
+			}
+		}
+	}
+
+	/**
+	 * @param cCN
+	 * @return
+	 */
+	private boolean isWildCard( String cCN )
+	{
+		if ( cCN.equalsIgnoreCase( CommonConstants.KEYWORD_ASTERISK ) )
+			return true;
+		return false;
+	}
+
+	/**
+	 * Validate that there are no duplicate column names in a table
+	 * 
+	 * @param aCN
+	 * @throws OdaException
+	 */
+	private void validateUniqueName( String[] aCN ) throws OdaException
+	{
+		for ( int i = 0; i < aCN.length; i++ )
+		{
+			if ( this.findOccuranceOfValueInStringArray( aCN[i], aCN ) > 1 )
+			{
+				throw new OdaException( Messages.getString( "query_SOURCE_DATA_ERROR" ) ); //$NON-NLS-1$
+			}
+		}
+	}
+
+	/**
+	 * Validate whether all column types in source data (line 2) are of valid
+	 * type
+	 * 
+	 * @param aCT
+	 * @throws OdaException
+	 */
+
+	private void validateColumnTypeConsistency( String[] aCT )
+			throws OdaException
+	{
+		if ( !this.hasTypeLine )
+			return;
+		for ( int i = 0; i < aCT.length; i++ )
+		{
+			if ( !DataTypes.isValidType( aCT[i] ) )
+			{
+				throw new OdaException( Messages.getString( "dataTypes_TYPE_NAME_INVALID" ) + aCT[i] ); //$NON-NLS-1$
+			}
+		}
+	}
+
+	/**
+	 * Return the number of occurance of a value in the given array
+	 * 
+	 * @param value
+	 * @param array
+	 * @return
+	 */
+	private int findOccuranceOfValueInStringArray( String value, String[] array )
+	{
+		int count = 0;
+		for ( int i = 0; i < array.length; i++ )
+		{
+			if ( value.trim( ).equalsIgnoreCase( array[i].trim( ) ) )
+				count++;
+		}
+		return count;
+	}
+
+	/**
+	 * Prepare the meta data which will be used in execution of a query text. It
+	 * sets the value of two member variables: resultSetMetaData and
+	 * currentTableName
+	 * 
+	 * @param queryText
+	 * @throws OdaException
+	 */
+	private void prepareMetaData( String query, String savedSelectedColInfo )
+			throws OdaException
+	{
+		validateNonEmptyQueryText( query );
+		
+		String[] queryFragments = parsePreparedQueryText( query );
+		
+		validateSingleTableQuery( queryFragments );
+		
+		// the name of table against which the query will be executed
+		String tableName = getPreparedTableNames( queryFragments );
+
+		FlatFileDataReader ffdsr = new FlatFileDataReader( this.connection , tableName, 0, null, null );
+		
+		// the array that contains the actual column names read from data file
+		String[] allColumnNames = this.hasColumnNames
+				? discoverActualColumnMetaData( tableName, NAME_LITERAL )
+				: createTempColumnNames( ffdsr.getColumnCount( ) );
+
+		// the array that contains the actual data type names read from data
+		// file
+		String[] allColumnTypes;
+		
+		allColumnTypes = this.hasTypeLine
+				? discoverActualColumnMetaData( tableName, TYPE_LITERAL )
+				: createTempColumnTypes( ffdsr.getColumnCount( ) );
+				
+		if ( allColumnNames.length != allColumnTypes.length )
+			throw new OdaException( Messages.getString( "invalid_flatfile_format" ) ); //$NON-NLS-1$
+
+		// the array that contains the column names read from command
+		String[] queryColumnNames = null;
+		String[] queryColumnTypes = null;
+		String[] queryColumnLables = null;
+		// dealing with "*"
+		if ( isWildCard( getPreparedColumnNames( queryFragments ) ) )
+		{
+			queryColumnNames = allColumnNames;
+			queryColumnTypes = allColumnTypes;
+			queryColumnLables = allColumnNames;
+			this.resultSetMetaDataHelper = new ResultSetMetaDataHelper(queryColumnNames,
+					queryColumnTypes,
+					queryColumnLables );
+			this.resultSetMetaData = new ResultSetMetaData( this.resultSetMetaDataHelper );
+		}
+		else
+		{
+			queryColumnNames = FlatFileDataReader.getStringArrayFromList( stripFormatInfoFromQueryColumnNames( getQueryColumnNamesVector( ( getPreparedColumnNames( queryFragments ) ) ) ) );
+			validateColumnName( queryColumnNames, allColumnNames);
+			if ( savedSelectedColInfo == null
+					|| savedSelectedColInfo.length( ) == 0 || hasTypeLine )
+			{				
+				queryColumnTypes = this.hasTypeLine
+						? getQueryColumnTypes( allColumnNames,
+								allColumnTypes,
+								queryColumnNames )
+						: createTempColumnTypes( queryColumnNames.length );
+				queryColumnLables = this.hasColumnNames
+						? getColumnLabels( queryFragments ) : queryColumnNames;
+				if ( queryColumnLables == null )
+					queryColumnLables = queryColumnNames;
+				this.resultSetMetaDataHelper = new ResultSetMetaDataHelper( queryColumnNames,
+						queryColumnTypes,
+						queryColumnLables );
+				this.resultSetMetaData = new ResultSetMetaData( this.resultSetMetaDataHelper );
+			}
+			else
+			{
+				this.resultSetMetaDataHelper = new ResultSetMetaDataHelper( savedSelectedColInfo );
+				this.resultSetMetaData = new ResultSetMetaData( this.resultSetMetaDataHelper );
+
+			}
+
+		}
+
+		this.currentTableName = tableName;
+	}
+	
+	/**
+	 * Returns the array that contains the types of column names read from a
+	 * query text.
+	 * 
+	 * @param allColumnNames
+	 *            The array contains all column names read from file
+	 * @param allColumnTypes
+	 *            The array contains all column types read from file
+	 * @param queryColumnNames
+	 *            The array contains those column names specified in a query
+	 * @return
+	 */
+	private String[] getQueryColumnTypes( String[] allColumnNames,
+			String[] allColumnTypes, String[] queryColumnNames )
+	{
+		if ( !this.hasTypeLine )
+			return null;
+
+		// the array that contains the types of column names read from a query
+		String[] queryColumnTypes = new String[queryColumnNames.length];
+
+		for ( int i = 0; i < queryColumnNames.length; i++ )
+		{
+			for ( int j = 0; j < allColumnNames.length; j++ )
+			{
+				if ( queryColumnNames[i].trim( )
+						.equalsIgnoreCase( allColumnNames[j] ) )
+				{
+					queryColumnTypes[i] = allColumnTypes[j];
+					break;
+				}
+			}
+
+		}
+		return queryColumnTypes;
+	}
+
+	/**
+	 * Returns an array that contains column labels.
+	 * 
+	 * @param queryFragments
+	 * @return a String array that contains column labels
+	 */
+	private String[] getColumnLabels( String[] queryFragments )
+	{
+		String queryColumnLabels = getPreparedColumnLabels( queryFragments );
+		return queryColumnLabels != null
+				? queryColumnLabels.split( CommonConstants.DELIMITER_COMMA_VALUE )
+				: null;
+	}
+
+	/**
+	 * Format the given query text. Eliminates redundant spaces and convert all
+	 * keywords to uppercase.
+	 * 
+	 * @param queryText
+	 * @return
+	 */
+	private String formatQueryText( String queryText )
+	{
+		StringBuffer result = new StringBuffer(); 
+		String[] temp = queryText.trim( )
+				.split( CommonConstants.DELIMITER_SPACE );
+		for ( int i = 0; i < temp.length; i++ )
+		{
+			if ( temp[i].equalsIgnoreCase( CommonConstants.KEYWORD_AS ) )
+				temp[i] = temp[i].toUpperCase( );
+			if ( temp[i].equalsIgnoreCase( CommonConstants.KEYWORD_FROM ) )
+				temp[i] = temp[i].toUpperCase( );
+			if ( temp[i].equalsIgnoreCase( CommonConstants.KEYWORD_SELECT ) )
+				temp[i] = temp[i].toUpperCase( );
+			result.append( temp[i] ).append( CommonConstants.DELIMITER_SPACE );
+		}
+		return result.toString( ).trim( );
+	}
+
+	/**
+	 * CVSBufferReader will buffer the input from the specified file. Read a
+	 * line of text. A line is considered to be terminated by any one of a line
+	 * feed ('\n').
+	 */
+	public static class FlatFileBufferedReader
+	{
+		private Reader reader;
+		private char[] charBuffer; //the buffer saved chars read from file
+		private static int CHARBUFFSIZE = 8192;
+		
+		private char separator;
+		private int endIndex; //the end of the buffer
+		private int currentIndex; //current index in the buffer during parsing a line
+		
+		public FlatFileBufferedReader( InputStream in, String encoding, char seperator ) throws IOException
+		{
+			initReader( in, encoding );
+			this.separator = seperator;
+			endIndex = -1;
+			currentIndex = -1;
+			charBuffer = new char[CHARBUFFSIZE];
+		}
+
+		private void initReader( InputStream in, String encoding ) throws IOException
+		{
+			if ( "UTF-8".equals( encoding ) ) //$NON-NLS-1$
+			{
+				//Currently, only BOM for "UTF-8" is supported
+				PushbackInputStream internalInputStream = new PushbackInputStream( in, 3 );
+				byte bom[] = new byte[3];
+				int len = internalInputStream.read( bom );
+				if ( len == 3 
+						&& bom[0] == (byte)0xEF
+						&& bom[1] == (byte)0xBB
+						&& bom[2] == (byte)0xBF )
+				{
+					//is BOM, first 3 bytes just be skipped
+				}
+				else
+				{
+					//not BOM, back to the start point of <code>in</code
+					if ( len > 0 )
+					{
+						internalInputStream.unread( bom, 0, len );
+					}
+				}
+				reader = new BufferedReader( new InputStreamReader( internalInputStream, encoding) );
+			} 
+			else
+			{
+				reader = new BufferedReader( new InputStreamReader( in, encoding ) );
+			}
+		}
+		
+		/**
+		 * return a line
+		 * the csv format reference: http://www.creativyst.com/Doc/Articles/CSV/CSV01.htm
+		 * @return
+		 * @throws OdaException
+		 * @throws IOException
+		 */
+		public List<String> readLine( ) throws OdaException
+		{
+			int newLineStartIndex = currentIndex + 1;
+			StringBuffer column = new StringBuffer( ); //current parsing column in the line
+			boolean doubleQuoted = false; //is current parsing column double quoted
+			if ( !next( ) ) 
+			{
+				//do not exist more char for read
+				return null;
+			}
+			List<String> result = new ArrayList<String>( );
+			do 
+			{
+				char curChar = getChar( ); 
+					
+				if ( !doubleQuoted )
+				{
+					if ( curChar == separator )
+					{
+						result.add( getColumnValue( column ) ); // this column is parsed
+						column.setLength( 0 ); //prepared for next column
+					}
+					else if ( curChar == '"' )
+					{
+						if ( column.toString( ).trim( ).length( ) > 0 )
+						{
+							//other shown chars exist before the first double quotes
+							throw new OdaException( Messages.getString( "invalid_flatfile_format" ) ); //$NON-NLS-1$
+						}
+						else
+						{
+							doubleQuoted = true;
+							column.setLength( 0 ); //start of this column
+							column.append( '"' );
+						}
+					}
+					else if ( curChar == '\n' )
+					{
+						//Finish this line
+						if ( currentIndex != newLineStartIndex )
+						{
+							result.add( getColumnValue( column ) );
+						}
+						else
+						{
+							//an empty line containing just a "\n"
+						}
+						return result;
+					}
+					else //other char
+					{
+						column.append( curChar );
+					}
+				}
+				else
+				{
+					moveToEndQuotation ( column );
+					moveToEndOfColumn( );
+					doubleQuoted = false;
+				}
+			} while ( next( ) );
+			
+			result.add( getColumnValue( column ) );
+			return result;
+		}
+		
+		private void moveToEndOfColumn( ) throws OdaException
+		{
+			if ( next( ) )
+			{
+				char curChar = getChar( );
+				if ( curChar == separator || curChar == '\n' )
+				{
+					back( );
+					return;
+				}
+				else if ( isAnEmptyChar( curChar ) )
+				{
+					moveToEndOfColumn( );
+				}
+				else
+				{
+					//Other shown chars exists after the double quote which is the flag of end of column
+					throw new OdaException( Messages.getString( "invalid_flatfile_format" ) ); //$NON-NLS-1$
+				}
+			}
+		}
+		
+		private void moveToEndQuotation( StringBuffer column ) throws OdaException
+		{
+			do 
+			{
+				char curChar = getChar( );
+				if ( curChar == '"' )
+				{
+					if ( next( ) )
+					{
+						curChar = getChar( );
+						if ( curChar == '"' )
+						{
+							//transfer '""' to '"'
+							column.append( '"' );
+						} 
+						else
+						{
+							back( );
+							column.append('"');
+							return;
+						}
+					}
+					else
+					{
+						column.append('"');
+						return;
+					}
+						
+				}
+				else
+				{
+					column.append( curChar );
+				}
+			} while (next( )); 
+			//no end quotation is detected
+			throw new OdaException( Messages.getString( "invalid_flatfile_format" ) ); //$NON-NLS-1$
+		}
+		
+		private boolean next( ) throws OdaException
+		{
+			if ( currentIndex < endIndex )
+			{
+				++currentIndex;
+				return true;
+			}
+			else
+			{
+				int len;
+				try
+				{
+					len = reader.read( charBuffer );
+					if ( len <= 0 )
+					{
+						return false; //eof
+					}
+					else
+					{
+						currentIndex = 0;
+						endIndex = len - 1;
+						return true;
+					}
+				}
+				catch ( IOException e )
+				{
+					throw new OdaException( e );
+				}
+			}
+		}
+		
+		private void back( )
+		{
+			if ( currentIndex >= 0 )
+			{
+				currentIndex--;
+			}
+		}
+		
+		private char getChar( )
+		{
+			return charBuffer[currentIndex];
+		}
+		
+		private String getColumnValue( StringBuffer column )
+		{
+			if ( column.length( ) >=  2 
+					&& column.charAt( 0 ) == '"'
+						&& column.charAt( column.length( ) - 1 ) == '"')
+			{
+				//double quoted
+				return column.substring( 1, column.length( ) - 1 );
+			}
+			else
+			{
+				//otherwise, applying trim
+				return column.toString( ).trim( );
+			}
+		}
+		
+		private boolean isAnEmptyChar( char c )
+		{
+			return String.valueOf( c ).trim( ).equals( "" ); //$NON-NLS-1$
+		}
+
+		/**
+		 * Close the reader. This method should be call every time the reader is
+		 * finish reading.
+		 * 
+		 * @throws IOException
+		 */
+		public void close( ) throws IOException
+		{
+			this.charBuffer = null;
+			this.reader.close( );
+		}
+
+	}
+}
diff --git a/plugins/org.eclipse.datatools.connectivity.oda.flatfile/src/org/eclipse/datatools/connectivity/oda/flatfile/InvalidResourceException.java b/plugins/org.eclipse.datatools.connectivity.oda.flatfile/src/org/eclipse/datatools/connectivity/oda/flatfile/InvalidResourceException.java
new file mode 100644
index 0000000..1225e2d
--- /dev/null
+++ b/plugins/org.eclipse.datatools.connectivity.oda.flatfile/src/org/eclipse/datatools/connectivity/oda/flatfile/InvalidResourceException.java
@@ -0,0 +1,38 @@
+/*

+ *************************************************************************

+ * Copyright (c) 2011 Actuate Corporation.

+ * 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:

+ *  Actuate Corporation

+ *  

+ *************************************************************************

+ */

+package org.eclipse.datatools.connectivity.oda.flatfile;

+

+import org.eclipse.datatools.connectivity.oda.OdaException;

+

+

+public class InvalidResourceException extends OdaException

+{

+	public static final int CORRECT_RESOURCE = 0;

+	public static final int ERROR_INVALID_RESOURCE = 1;

+	public static final int ERROR_EMPTY_RESOURCE = 2;

+	

+	private static final long serialVersionUID = 1L;

+	int errorCode = ERROR_EMPTY_RESOURCE;

+	

+	public InvalidResourceException ( int errorCode, String error )

+	{

+		super( error );

+		this.errorCode = errorCode;

+	}

+	

+	public int getErrorCode( )

+	{

+		return this.errorCode;

+	}

+}

diff --git a/plugins/org.eclipse.datatools.connectivity.oda.flatfile/src/org/eclipse/datatools/connectivity/oda/flatfile/ResourceInputStream.java b/plugins/org.eclipse.datatools.connectivity.oda.flatfile/src/org/eclipse/datatools/connectivity/oda/flatfile/ResourceInputStream.java
new file mode 100644
index 0000000..dd1329c
--- /dev/null
+++ b/plugins/org.eclipse.datatools.connectivity.oda.flatfile/src/org/eclipse/datatools/connectivity/oda/flatfile/ResourceInputStream.java
@@ -0,0 +1,68 @@
+/*

+ *************************************************************************

+ * Copyright (c) 2011 Actuate Corporation.

+ * 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:

+ *  Actuate Corporation

+ *  

+ *************************************************************************

+ */

+package org.eclipse.datatools.connectivity.oda.flatfile;

+

+import java.io.IOException;

+import java.io.InputStream;

+

+

+public class ResourceInputStream extends InputStream

+{

+	private InputStream in;

+	private String location;

+	

+	public ResourceInputStream( InputStream in, String location )

+	{

+		this.in = in;

+		this.location = location;

+	}

+	

+	/* (non-Javadoc)

+	 * @see java.io.InputStream#read()

+	 */

+	public int read( ) throws IOException

+	{

+		return in.read( );

+	}

+	

+	public int read( byte[] b ) throws IOException

+	{

+		return in.read( b );

+	}

+

+	public int read( byte[] b, int off, int len ) throws IOException

+	{

+		return in.read( b, off, len );

+	}

+	

+	public long skip( long n ) throws IOException

+	{

+		return in.skip( n );

+	}

+

+	public int available( ) throws IOException

+	{

+		return in.available( );

+	}

+

+	public void close( ) throws IOException

+	{

+		in.close( );

+	}

+

+	public String getLocation( )

+	{

+		return this.location;

+	}

+}

diff --git a/plugins/org.eclipse.datatools.connectivity.oda.flatfile/src/org/eclipse/datatools/connectivity/oda/flatfile/ResourceLocator.java b/plugins/org.eclipse.datatools.connectivity.oda.flatfile/src/org/eclipse/datatools/connectivity/oda/flatfile/ResourceLocator.java
new file mode 100644
index 0000000..c673fdf
--- /dev/null
+++ b/plugins/org.eclipse.datatools.connectivity.oda.flatfile/src/org/eclipse/datatools/connectivity/oda/flatfile/ResourceLocator.java
@@ -0,0 +1,310 @@
+/*

+ *************************************************************************

+ * Copyright (c) 2011 Actuate Corporation.

+ * 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:

+ *  Actuate Corporation

+ *  

+ *************************************************************************

+ */

+

+package org.eclipse.datatools.connectivity.oda.flatfile;

+

+import java.io.File;

+import java.io.FileInputStream;

+import java.io.FileNotFoundException;

+import java.io.IOException;

+import java.io.InputStream;

+import java.net.MalformedURLException;

+import java.net.URI;

+import java.net.URISyntaxException;

+

+import org.eclipse.core.runtime.FileLocator;

+import org.eclipse.datatools.connectivity.oda.flatfile.i18n.Messages;

+import org.eclipse.datatools.connectivity.oda.util.ResourceIdentifiers;

+

+import com.ibm.icu.text.MessageFormat;

+

+public final class ResourceLocator

+{

+

+	public static ResourceInputStream getResourceInputStream(

+			String homeFolder, String table, String fileURI,

+			Object resourceIdentifiers ) throws InvalidResourceException

+	{

+		if ( homeFolder == null && fileURI == null )

+			throw new InvalidResourceException( InvalidResourceException.ERROR_EMPTY_RESOURCE,

+					Messages.getString( "connection_MISSING_FILELLOCATION" ) ); //$NON-NLS-1$

+

+		ResourceInputStream stream = getResourceInputStream( fileURI,

+				resourceIdentifiers );

+		if ( stream != null )

+			return stream;

+

+		if ( homeFolder == null )

+		{

+			throw new InvalidResourceException( InvalidResourceException.ERROR_INVALID_RESOURCE,

+					MessageFormat.format( Messages.getString( "connection_CANNOT_OPEN_FLAT_FILE_URI" ), //$NON-NLS-1$

+							new Object[]{

+								fileURI

+							} ) );

+		}

+

+		stream = getResourceInputStream( homeFolder, table, resourceIdentifiers );

+

+		return stream;

+	}

+

+	public static void validate( String homeFolder, String table,

+			String fileURI, ResourceIdentifiers resourceIdentifiers )

+			throws InvalidResourceException

+	{

+		InputStream in = null;

+		try

+		{

+			in = getResourceInputStream( homeFolder,

+					table,

+					fileURI,

+					resourceIdentifiers );

+		}

+		finally

+		{

+			if ( in != null )

+			{

+				try

+				{

+					in.close( );

+				}

+				catch ( IOException ignore )

+				{

+				}

+			}

+		}

+	}

+

+	public static ResourceInputStream getResourceInputStream(

+			String homeFolder, String table, Object resourceIdentifiers )

+			throws InvalidResourceException

+	{

+		ResourceInputStream stream = null;

+		if ( homeFolder != null )

+		{

+			// Home folder is valid.

+			if ( table == null )

+				return null;

+

+			String filePath = null;

+			

+			if ( homeFolder.trim( ).length( ) == 0 )

+			{

+				filePath = table;

+			}

+			else if ( homeFolder.endsWith( File.separator ) )

+			{

+				filePath = homeFolder + table;				

+			}

+			else

+				filePath = homeFolder + File.separator + table;

+

+			File file;

+			try

+			{

+				file = getResourceFile( filePath, resourceIdentifiers );

+			}

+			catch ( Exception e1 )

+			{

+				throw new InvalidResourceException( InvalidResourceException.ERROR_INVALID_RESOURCE,

+						Messages.getString( "query_invalidTableName" ) //$NON-NLS-1$

+								+ filePath ); 

+			}

+

+			if ( file == null || !file.exists( ) )

+				throw new InvalidResourceException( InvalidResourceException.ERROR_INVALID_RESOURCE,

+						Messages.getString( "query_invalidTableName" ) //$NON-NLS-1$

+								+ filePath );

+			try

+			{

+				stream = new ResourceInputStream( new FileInputStream( file ),

+						file.getAbsolutePath( ) );

+			}

+			catch ( FileNotFoundException e )

+			{

+				throw new InvalidResourceException( InvalidResourceException.ERROR_INVALID_RESOURCE,

+						Messages.getString( "query_invalidTableName" ) //$NON-NLS-1$

+								+ filePath );

+			}

+		}

+

+		return stream;

+	}

+

+	public static File getHomeFolderFile( String homeFolder,

+			Object resourceIdentifiers ) throws InvalidResourceException

+	{

+		if ( homeFolder != null )

+		{

+			try

+			{

+				File homeFile = getResourceFile( homeFolder,

+						resourceIdentifiers );

+				if ( homeFile.exists( ) && homeFile.isDirectory( ) )

+					return homeFile;

+			}

+			catch ( Exception e )

+			{

+				throw new InvalidResourceException( InvalidResourceException.ERROR_INVALID_RESOURCE,

+						MessageFormat.format( Messages.getString( "connection_CANNOT_OPEN_FLAT_FILE_URI" ), //$NON-NLS-1$

+								new Object[]{

+										homeFolder, e

+								} ) );

+			}

+		}

+

+		return null;

+	}

+

+	private static File getResourceFile( String filePath,

+			Object resourceIdentifiers ) throws URISyntaxException,

+			IOException, MalformedURLException

+	{

+		URI uri = null;

+		File file = new File( filePath );

+		if ( file.exists( ) )

+		{

+			if ( file.isAbsolute( ) )

+				return file;

+		}

+

+		try

+		{

+			uri = new URI( filePath );

+		}

+		catch ( URISyntaxException ex )

+		{

+			uri = new URI( null, null, convertURI( filePath ), null );

+		}

+

+		if ( uri.isAbsolute( ) )

+		{

+			; // Already resolved, do nothing.

+		}

+		else if ( !uri.isAbsolute( ) && resourceIdentifiers != null )

+		{

+			URI uriResolved = ResourceIdentifiers.resolveApplResource( resourceIdentifiers,

+					uri );

+			uri = uriResolved == null ? uri : uriResolved;

+		}

+		else

+		{

+			return null;

+		}

+

+		File homeFile = new File( FileLocator.toFileURL( uri.toURL( ) )

+				.toURI( ) );

+		return homeFile;

+	}

+

+	public static ResourceInputStream getResourceInputStream( String fileURI,

+			Object resourceIdentifiers ) throws InvalidResourceException

+	{

+		ResourceInputStream stream = null;

+		if ( fileURI != null )

+		{

+			try

+			{

+				URI uri = null;

+				File file = new File( fileURI );

+				if ( file.exists( ) )

+				{

+					uri = file.toURI( );

+				}

+				else

+				{

+					try

+					{

+						uri = new URI( fileURI );

+					}

+					catch ( URISyntaxException ex )

+					{

+						uri = new URI( null, null, convertURI( fileURI ), null );

+					}

+

+					if ( uri.isAbsolute( ) )

+					{

+						; // Already resolved, do nothing.

+					}

+					else if ( !uri.isAbsolute( ) && resourceIdentifiers != null )

+					{

+						URI uriResolved = ResourceIdentifiers.resolveApplResource( resourceIdentifiers,

+								uri );

+						uri = uriResolved == null ? uri : uriResolved;

+					}

+					else

+					{

+						return null;

+					}

+				}

+				stream = new ResourceInputStream( uri.toURL( ).openStream( ),

+						fileURI );

+			}

+			catch ( Exception e )

+			{

+				throw new InvalidResourceException( InvalidResourceException.ERROR_INVALID_RESOURCE,

+						MessageFormat.format( Messages.getString( "connection_CANNOT_OPEN_FLAT_FILE_URI" ), //$NON-NLS-1$

+								new Object[]{

+										fileURI, e

+								} ) );

+			}

+		}

+

+		return stream;

+	}

+

+	private static String convertURI( String fileURL )

+	{

+		return fileURL.replace( '\\', '/' );

+	}

+

+	public static void validateFileURI( String fileURI, ResourceIdentifiers ri )

+			throws InvalidResourceException

+	{

+		if ( fileURI == null )

+			throw new InvalidResourceException( InvalidResourceException.ERROR_EMPTY_RESOURCE,

+					Messages.getString( "connection_MISSING_FILEURI" ) ); //$NON-NLS-1$

+

+		ResourceInputStream stream = null;

+		try

+		{

+			stream = getResourceInputStream( fileURI, ri );

+		}

+		finally

+		{

+			if ( stream != null )

+				try

+				{

+					stream.close( );

+				}

+				catch ( IOException ignore )

+				{

+				}

+		}

+	}

+

+	public static void validateHomeFolder( String homeFolder,

+			ResourceIdentifiers ri ) throws InvalidResourceException

+	{

+		if ( homeFolder == null )

+			throw new InvalidResourceException( InvalidResourceException.ERROR_EMPTY_RESOURCE,

+					Messages.getString( "connection_MISSING_HOMEFOLDER" ) ); //$NON-NLS-1$

+

+		File file = getHomeFolderFile( homeFolder, ri );

+		if ( file == null || !file.exists( ) || file.isFile( ) )

+			throw new InvalidResourceException( InvalidResourceException.ERROR_INVALID_RESOURCE,

+					Messages.getString( "connection_CANNOT_OPEN_FLAT_FILE_DB_DIR" ) //$NON-NLS-1$

+							+ homeFolder );

+	}

+}

diff --git a/plugins/org.eclipse.datatools.connectivity.oda.flatfile/src/org/eclipse/datatools/connectivity/oda/flatfile/ResultSet.java b/plugins/org.eclipse.datatools.connectivity.oda.flatfile/src/org/eclipse/datatools/connectivity/oda/flatfile/ResultSet.java
new file mode 100644
index 0000000..1873a76
--- /dev/null
+++ b/plugins/org.eclipse.datatools.connectivity.oda.flatfile/src/org/eclipse/datatools/connectivity/oda/flatfile/ResultSet.java
@@ -0,0 +1,600 @@
+/*
+ *******************************************************************************
+ * Copyright (c) 2004, 2009 Actuate Corporation.
+ * 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:
+ *  Actuate Corporation  - initial API and implementation
+ *******************************************************************************
+ */
+
+package org.eclipse.datatools.connectivity.oda.flatfile;
+
+import java.math.BigDecimal;
+import java.sql.Date;
+import java.sql.Time;
+import java.sql.Timestamp;
+import java.text.ParseException;
+import java.util.regex.Pattern;
+
+import org.eclipse.datatools.connectivity.oda.IBlob;
+import org.eclipse.datatools.connectivity.oda.IClob;
+import org.eclipse.datatools.connectivity.oda.IResultSet;
+import org.eclipse.datatools.connectivity.oda.IResultSetMetaData;
+import org.eclipse.datatools.connectivity.oda.OdaException;
+import org.eclipse.datatools.connectivity.oda.flatfile.i18n.Messages;
+import org.eclipse.datatools.connectivity.oda.flatfile.util.DateUtil;
+import org.eclipse.datatools.connectivity.oda.flatfile.util.FlatFileDataReader;
+
+import com.ibm.icu.text.NumberFormat;
+import com.ibm.icu.util.ULocale;
+
+/**
+ * Flat file data provider's implementation of the ODA IResultSet interface.
+ */
+
+public class ResultSet implements IResultSet
+{
+
+    public static final int DEFAULT_MAX_ROWS = 1000;
+    private static final int CURSOR_INITIAL_VALUE = -1;
+    private String[][] sourceData = null;
+    private ResultSetMetaData resultSetMetaData = null;
+    private int maxRows = 0;
+    private int cursor = CURSOR_INITIAL_VALUE;
+    private FlatFileDataReader flatFileDataReader;
+    //Boolean which marks whether it is successful of last call to getXXX();
+    private boolean wasNull = false;
+    //a counter that counts the total number of rows read from the flatfile
+    private int fetchAccumulator = 0;
+   
+    private boolean overFlow = false;
+    private boolean trailNullCols = false;
+    
+    private static ULocale JRE_DEFAULT_LOCALE = ULocale.getDefault( );
+    
+    private static Pattern pattern1 = Pattern.compile( "\\QT\\E" ); //$NON-NLS-1$
+    private static Pattern pattern2 = Pattern.compile( "\\QZ\\E" ); //$NON-NLS-1$
+    
+    /**
+     * Constructor
+     * @param ffr flat file data source reader 
+     * @param rsmd
+     */
+    ResultSet(FlatFileDataReader ffr, ResultSetMetaData rsmd )
+    {
+    	assert ffr != null;
+    	this.flatFileDataReader = ffr;
+    	this.resultSetMetaData = rsmd;
+    	this.maxRows = this.flatFileDataReader.getMaxRowsToRead( this.maxRows );
+    	this.trailNullCols = this.flatFileDataReader.getTrailNullColumns( );
+    }
+
+    /*
+     * @see org.eclipse.datatools.connectivity.oda.IResultSet#getMetaData()
+     */
+    public IResultSetMetaData getMetaData() throws OdaException
+    {
+        return this.resultSetMetaData;
+    }
+
+    /*
+     * @see org.eclipse.datatools.connectivity.oda.IResultSet#close()
+     */
+    public void close() throws OdaException
+    {
+        this.cursor = 0;
+        this.sourceData = null;
+        this.resultSetMetaData = null;
+        this.flatFileDataReader.clearBufferedReader( );
+    }
+
+    /*
+     * @see org.eclipse.datatools.connectivity.oda.IResultSet#setMaxRows(int)
+     */
+    public void setMaxRows( int max ) throws OdaException
+    {
+        this.maxRows = max;
+    }
+
+    /*
+     * @see org.eclipse.datatools.connectivity.oda.IResultSet#next()
+     */
+    public boolean next( ) throws OdaException
+	{	
+    	if ( overFlow ) 
+    	{
+    		return false;
+    	}
+    	//first time to call next
+    	if ( cursor == CURSOR_INITIAL_VALUE )
+		{
+			sourceData = this.flatFileDataReader.getSourceData( );
+		}
+
+		if ( ( this.maxRows <= 0 ? false : fetchAccumulator >= this.maxRows ) )
+		{
+			this.flatFileDataReader.clearBufferedReader( );
+			cursor = CURSOR_INITIAL_VALUE;
+			overFlow = true;
+			return false;
+		}
+
+		if ( cursor == this.sourceData.length-1 )
+		{
+			sourceData = this.flatFileDataReader.getSourceData( );
+
+			cursor = CURSOR_INITIAL_VALUE;
+			
+			if ( sourceData.length == 0 )
+			{
+				this.flatFileDataReader.clearBufferedReader( );
+				overFlow = true;
+				return false;
+			}
+		}
+		
+		fetchAccumulator++;
+		cursor++;
+
+		return true;
+	}
+
+    /*
+	 * @see org.eclipse.datatools.connectivity.oda.IResultSet#getRow()
+	 */
+    public int getRow() throws OdaException
+    {
+        validateCursorState();
+        return this.fetchAccumulator;
+    }
+
+    /*
+     * @see org.eclipse.datatools.connectivity.oda.IResultSet#getString(int)
+     */
+    public String getString( int index ) throws OdaException
+    {
+        validateCursorState();
+        String result = sourceData[cursor][index - 1];
+		if ( ( trailNullCols && result == null ) || result.length( ) == 0 )
+            result = null;
+        this.wasNull = result == null ? true : false;
+        return result;
+    }
+
+    /*
+     * @see org.eclipse.datatools.connectivity.oda.IResultSet#getString(java.lang.String)
+     */
+    public String getString( String columnName ) throws OdaException
+    {
+        validateCursorState();
+        int columnIndex = findColumn( columnName );
+        return getString( columnIndex );
+    }
+
+    /*
+     * @see org.eclipse.datatools.connectivity.oda.IResultSet#getInt(int)
+     */
+    public int getInt( int index ) throws OdaException
+    {
+        return stringToInt( getString( index ) );
+    }
+
+    /*
+     * @see org.eclipse.datatools.connectivity.oda.IResultSet#getInt(java.lang.String)
+     */
+    public int getInt( String columnName ) throws OdaException
+    {
+        return stringToInt( getString( columnName ) );
+    }
+
+    /*
+     * @see org.eclipse.datatools.connectivity.oda.IResultSet#getDouble(int)
+     */
+    public double getDouble( int index ) throws OdaException
+    {
+        return stringToDouble( getString( index ) );
+    }
+
+    /*
+     * @see org.eclipse.datatools.connectivity.oda.IResultSet#getDouble(java.lang.String)
+     */
+    public double getDouble( String columnName ) throws OdaException
+    {
+        return stringToDouble( getString( columnName ) );
+    }
+
+    /*   
+     * @see org.eclipse.datatools.connectivity.oda.IResultSet#getBigDecimal(int)
+     */
+    public BigDecimal getBigDecimal( int index ) throws OdaException
+    {
+        return stringToBigDecimal( getString( index ) );
+    }
+
+    /*
+     * @see org.eclipse.datatools.connectivity.oda.IResultSet#getBigDecimal(java.lang.String)
+     */
+    public BigDecimal getBigDecimal( String columnName ) throws OdaException
+    {
+        return stringToBigDecimal( getString( columnName ) );
+    }
+
+    /*
+     * @see org.eclipse.datatools.connectivity.oda.IResultSet#getDate(int)
+     */
+    public Date getDate( int index ) throws OdaException
+    {
+        return stringToDate( getString( index ) );
+    }
+
+    /*
+     * @see org.eclipse.datatools.connectivity.oda.IResultSet#getDate(java.lang.String)
+     */
+    public Date getDate( String columnName ) throws OdaException
+    {
+        return stringToDate( getString( columnName ) );
+    }
+
+    /*
+     * @see org.eclipse.datatools.connectivity.oda.IResultSet#getTime(int)
+     */
+    public Time getTime( int index ) throws OdaException
+    {
+        return stringToTime( getString( index ) );
+    }
+
+    /*
+     * @see org.eclipse.datatools.connectivity.oda.IResultSet#getTime(java.lang.String)
+     */
+    public Time getTime( String columnName ) throws OdaException
+    {
+        return stringToTime( getString( columnName ) );
+    }
+
+    /*
+     * @see org.eclipse.datatools.connectivity.oda.IResultSet#getTimestamp(int)
+     */
+    public Timestamp getTimestamp( int index ) throws OdaException
+    {
+        return stringToTimestamp( getString( index ) );
+    }
+
+    /*
+     * @see org.eclipse.datatools.connectivity.oda.IResultSet#getTimestamp(java.lang.String)
+     */
+    public Timestamp getTimestamp( String columnName ) throws OdaException
+    {
+        return stringToTimestamp( getString( columnName ) );
+    }
+
+    /*
+     * @see org.eclipse.datatools.connectivity.oda.IResultSet#getBlob(int)
+     */
+    public IBlob getBlob( int index ) throws OdaException
+    {
+        throw new UnsupportedOperationException();
+    }
+
+    /*
+     * @see org.eclipse.datatools.connectivity.oda.IResultSet#getBlob(java.lang.String)
+     */
+    public IBlob getBlob( String columnName ) throws OdaException
+    {
+        throw new UnsupportedOperationException();
+    }
+
+    /*
+     * @see org.eclipse.datatools.connectivity.oda.IResultSet#getClob(int)
+     */
+    public IClob getClob( int index ) throws OdaException
+    {
+        throw new UnsupportedOperationException();
+    }
+
+    /*
+     * @see org.eclipse.datatools.connectivity.oda.IResultSet#getClob(java.lang.String)
+     */
+    public IClob getClob( String columnName ) throws OdaException
+    {
+        throw new UnsupportedOperationException();
+    }
+
+    /* (non-Javadoc)
+     * @see org.eclipse.datatools.connectivity.oda.IResultSet#getBoolean(int)
+     */
+    public boolean getBoolean( int index ) throws OdaException
+    {
+         return stringToBoolean( getString( index ) ).booleanValue( );
+    }
+
+    /* (non-Javadoc)
+     * @see org.eclipse.datatools.connectivity.oda.IResultSet#getBoolean(java.lang.String)
+     */
+    public boolean getBoolean( String columnName ) throws OdaException
+    {
+    	return stringToBoolean( getString( columnName ) ).booleanValue( );
+    }
+
+    /* (non-Javadoc)
+     * @see org.eclipse.datatools.connectivity.oda.IResultSet#getObject(int)
+     */
+    public Object getObject( int index ) throws OdaException
+    {
+        throw new UnsupportedOperationException();
+    }
+
+    /* (non-Javadoc)
+     * @see org.eclipse.datatools.connectivity.oda.IResultSet#getObject(java.lang.String)
+     */
+    public Object getObject( String columnName ) throws OdaException
+    {
+        throw new UnsupportedOperationException();
+    }
+
+    /*
+     * @see org.eclipse.datatools.connectivity.oda.IResultSet#wasNull()
+     */
+    public boolean wasNull() throws OdaException
+    {
+        return this.wasNull;
+    }
+
+    /*
+     * @see org.eclipse.datatools.connectivity.oda.IResultSet#findColumn(java.lang.String)
+     */
+    public int findColumn( String columnName ) throws OdaException
+    {
+    	return resultSetMetaData.findColumn( columnName );
+    }
+
+    /**
+     * Validate whether the cursor has been initialized and at a valid row.
+     * @throws OdaException if the cursor is not initialized
+     */
+    private void validateCursorState() throws OdaException
+    {
+        if( this.cursor < 0 )
+            throw new OdaException( Messages
+                    .getString( "resultSet_CURSOR_HAS_NOT_BEEN_INITIALIZED" ) ); //$NON-NLS-1$
+    }
+
+    /**
+     * Transform a String value to an int value
+     * @param stringValue String value
+     * @return Corresponding int value
+     * @throws ParseException 
+     * @throws OdaException 
+     */
+    private int stringToInt( String stringValue ) throws  OdaException
+    {
+    	if( stringValue != null )
+        {
+            try
+            {
+                return new Integer( stringValue ).intValue();
+            }
+            catch( NumberFormatException e )
+            {
+				try
+				{
+					Number number = NumberFormat.getInstance( JRE_DEFAULT_LOCALE ).parse( stringValue );
+					if ( number != null )
+					{
+						return number.intValue( );
+					}
+				}
+				catch ( ParseException e1 )
+				{
+					throw new OdaException( "Can not convert "+"\""+stringValue+"\""+" to Integer" );
+				}
+            }
+        }
+    	this.wasNull = true;
+        return 0;
+    }
+
+    /**
+     * Transform a String value to a double value
+     * @param stringValue String value
+     * @return Corresponding double value
+     * @throws OdaException 
+     */
+    private double stringToDouble( String stringValue ) throws OdaException
+    {
+    	if( stringValue != null )
+        {
+            try
+            {
+                return new Double( stringValue ).doubleValue();
+            }
+            catch( NumberFormatException e )
+            {
+				try
+				{
+					Number number = NumberFormat.getInstance( JRE_DEFAULT_LOCALE ).parse( stringValue );
+					if ( number != null )
+					{
+						return number.doubleValue( );
+					}
+				}
+				catch ( ParseException e1 )
+				{
+					throw new OdaException( "Can not convert "+"\""+stringValue+"\""+" to a double value" );
+				}
+            }
+        }
+    	this.wasNull = true;
+        return 0;
+    }
+
+    /**
+     * Transform a String value to a big decimal value
+     * @param stringValue String value
+     * @return Corresponding BigDecimal value
+     * @throws OdaException 
+     */
+    private BigDecimal stringToBigDecimal( String stringValue ) throws OdaException
+    {
+    	if( stringValue != null )
+        {
+            try
+            {
+                return new BigDecimal( stringValue );
+            }
+            catch( NumberFormatException e )
+            {
+				try
+				{
+					Number number = NumberFormat.getInstance( JRE_DEFAULT_LOCALE ).parse( stringValue );
+					if ( number != null )
+					{
+						return new BigDecimal( number.toString( ) );
+					}
+				}
+				catch ( ParseException e1 )
+				{
+					throw new OdaException( "Can not convert "+"\""+stringValue+"\""+" to a BigDecimal value" );
+				}
+            }
+        }
+    	this.wasNull = true;
+        return null;
+    }
+
+    /**
+     * Transform a String value to a date value
+     * @param stringValue String value
+     * @return Corresponding date value
+     * @throws OdaException 
+     */
+
+    private Date stringToDate( String stringValue ) throws OdaException
+    {
+    	if ( stringValue != null )
+		{
+			try
+			{
+				return DateUtil.toSqlDate( stringValue );
+			}
+			catch ( OdaException oe )
+			{
+				throw new OdaException( "Can not convert "+"\""+stringValue+"\""+" to a date value" );
+			}
+		}
+		
+		this.wasNull = true;
+        return null;
+    }
+
+    /**
+     * Transform a String value to a Time value
+     * @param stringValue String value
+     * @return Corresponding Time value
+     * @throws OdaException 
+     */
+    private Time stringToTime( String stringValue ) throws OdaException
+    {
+    	if ( stringValue != null )
+		{
+			try
+			{
+				return DateUtil.toSqlTime( stringValue );
+			}
+			catch ( OdaException oe )
+			{
+				throw new OdaException( "Can not convert "+"\""+stringValue+"\""+" to a Time value" );
+			}
+		}
+		this.wasNull = true;
+		return null;
+    }
+
+    /**
+     * Transform a String value to a Timestamp value
+     * @param stringValue String value
+     * @return Corresponding Timestamp value
+     * @throws OdaException 
+     */
+    private Timestamp stringToTimestamp( String stringValue ) throws OdaException
+    {
+    	if( stringValue != null )
+        {
+            try
+            {
+            	String value = pattern1.matcher( stringValue).replaceAll(" "); //$NON-NLS-1$
+            	value = pattern2.split( value )[0];
+            	return Timestamp.valueOf( value );
+			}
+			catch ( IllegalArgumentException e )
+			{
+				try
+				{
+					long timeMills = Long.valueOf( stringValue ).longValue( );
+					return new Timestamp( timeMills );
+				}
+				catch ( NumberFormatException e1 )
+				{
+					try
+					{
+						java.util.Date date = DateUtil.toDate( stringValue );
+						Timestamp timeStamp = new Timestamp( date.getTime( ) );
+						return timeStamp;
+					}
+					catch ( OdaException ex )
+					{
+						throw new OdaException( "Can not convert string "+"\""+stringValue+"\""+" to a Timestamp value" );
+					}
+				}
+			}
+		}
+    	this.wasNull = true;
+        return null;
+    }
+    
+    /**
+	 * Transform a string to boolean value
+	 * @param stringValue
+	 * @return
+     * @throws OdaException 
+	 */
+	private Boolean stringToBoolean( String stringValue ) throws OdaException
+	{
+		if ( stringValue != null )
+		{
+			if ( stringValue.equalsIgnoreCase( "true" ) ) //$NON-NLS-1$
+				return Boolean.TRUE;
+			else if ( stringValue.equalsIgnoreCase( "false" ) ) //$NON-NLS-1$
+				return Boolean.FALSE;
+			else
+			{
+				try
+				{
+					if ( Integer.parseInt( (String) stringValue ) == 0 )
+						return Boolean.FALSE;
+					else
+						return Boolean.TRUE;
+				}
+				catch ( NumberFormatException e )
+				{
+					try
+					{
+						Number number = NumberFormat.getInstance( JRE_DEFAULT_LOCALE ).parse( stringValue );
+						if ( number != null )
+						{
+							return number.intValue( ) == 0 ? Boolean.FALSE : Boolean.TRUE;
+						}
+					}
+					catch ( ParseException e1 )
+					{
+						throw new OdaException( "Can not convert "+"\""+stringValue+"\""+" to boolean value" );						
+					}
+				}
+			}
+		}
+		return Boolean.FALSE;
+	}
+}
\ No newline at end of file
diff --git a/plugins/org.eclipse.datatools.connectivity.oda.flatfile/src/org/eclipse/datatools/connectivity/oda/flatfile/ResultSetMetaData.java b/plugins/org.eclipse.datatools.connectivity.oda.flatfile/src/org/eclipse/datatools/connectivity/oda/flatfile/ResultSetMetaData.java
new file mode 100644
index 0000000..3dc3fab
--- /dev/null
+++ b/plugins/org.eclipse.datatools.connectivity.oda.flatfile/src/org/eclipse/datatools/connectivity/oda/flatfile/ResultSetMetaData.java
@@ -0,0 +1,170 @@
+/*
+ *******************************************************************************
+ * Copyright (c) 2004, 2007 Actuate Corporation.
+ * 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:
+ *  Actuate Corporation - initial API and implementation
+ *******************************************************************************
+ */
+
+package org.eclipse.datatools.connectivity.oda.flatfile;
+
+import java.util.HashMap;
+
+import org.eclipse.datatools.connectivity.oda.IResultSetMetaData;
+import org.eclipse.datatools.connectivity.oda.OdaException;
+import org.eclipse.datatools.connectivity.oda.flatfile.i18n.Messages;
+
+/**
+ * Flat file data provider's implementation of the ODA IResultSetMetaData
+ * interface.
+ */
+
+public class ResultSetMetaData implements IResultSetMetaData
+{
+
+	private String[] columnNames = null;
+	private String[] columnTypeNames = null;
+	private String[] columnLabels = null;
+	
+	private HashMap<String, Integer> columnNameIndexMap = new HashMap<String, Integer>(); 
+
+	/**
+	 * Constructor
+	 * 
+	 * @param rsmdHelper
+	 * @throws OdaException 
+	 */
+	public ResultSetMetaData( ResultSetMetaDataHelper rsmdHelper ) throws OdaException
+	{
+		if( rsmdHelper == null )
+			throw new OdaException( Messages.getString( "common_ARGUMENT_CANNOT_BE_NULL" ) ); //$NON-NLS-1$
+		
+		this.columnNames = rsmdHelper.getColumnNames( );
+		this.columnTypeNames = rsmdHelper.getColumnTypes( );
+		this.columnLabels = rsmdHelper.getColumnLabels( );
+		
+		for (int i = 0; i < columnNames.length; i++)
+		{
+			columnNameIndexMap.put( columnNames[i].toUpperCase( ), Integer.valueOf( i + 1 ) );
+		}
+	}
+
+
+	/*
+	 * @see org.eclipse.datatools.connectivity.oda.IResultSetMetaData#getColumnCount()
+	 */
+	public int getColumnCount( ) throws OdaException
+	{
+		return this.columnNames.length;
+	}
+
+
+	/*
+	 * @see org.eclipse.datatools.connectivity.oda.IResultSetMetaData#getColumnName(int)
+	 */
+	public String getColumnName( int index ) throws OdaException
+	{
+		validateColumnIndex( index );
+		return this.columnNames[index - 1].trim( );
+	}
+
+	/*
+	 * @see org.eclipse.datatools.connectivity.oda.IResultSetMetaData#getColumnLabel(int)
+	 */
+	public String getColumnLabel( int index ) throws OdaException
+	{
+		validateColumnIndex( index );
+		// "null" in lower case represents null label value;
+		if ( this.columnLabels == null
+				|| this.columnLabels[index - 1].equals( "null" ) ) //$NON-NLS-1$
+			return this.getColumnName( index ); // use column name instead
+
+		return this.columnLabels[index - 1].trim( );
+	}
+
+	/*
+	 * @see org.eclipse.datatools.connectivity.oda.IResultSetMetaData#getColumnType(int)
+	 */
+	public int getColumnType( int index ) throws OdaException
+	{
+		validateColumnIndex( index );
+		return ( this.columnTypeNames == null ) ? DataTypes.STRING
+				: DataTypes.getTypeCode( columnTypeNames[index - 1] );
+	}
+
+	/*
+	 * @see org.eclipse.datatools.connectivity.oda.IResultSetMetaData#getColumnTypeName(int)
+	 */
+	public String getColumnTypeName( int index ) throws OdaException
+	{
+		validateColumnIndex( index );
+		return ( this.columnTypeNames == null ) ? DataTypes.NULL_LITERAL :
+				columnTypeNames[index - 1].trim( );
+	}
+
+	/*
+	 * @see org.eclipse.datatools.connectivity.oda.IResultSetMetaData#getColumnDisplayLength(int)
+	 */
+	public int getColumnDisplayLength( int index ) throws OdaException
+	{
+		throw new UnsupportedOperationException( );
+	}
+
+	/*
+	 * @see org.eclipse.datatools.connectivity.oda.IResultSetMetaData#getPrecision(int)
+	 */
+	public int getPrecision( int index ) throws OdaException
+	{
+		return -1;
+	}
+
+	/*
+	 * @see org.eclipse.datatools.connectivity.oda.IResultSetMetaData#getScale(int)
+	 */
+	public int getScale( int index ) throws OdaException
+	{
+		return -1;
+	}
+
+	/*
+	 * @see org.eclipse.datatools.connectivity.oda.IResultSetMetaData#isNullable(int)
+	 */
+	public int isNullable( int index ) throws OdaException
+	{
+		return columnNullableUnknown;
+	}
+
+	/**
+	 * Evaluate whether the value of given column number is valid.
+	 * 
+	 * @param index
+	 *            column number (1-based)
+	 * @throws OdaException
+	 *             if the given index value is invalid
+	 */
+	private void validateColumnIndex( int index ) throws OdaException
+	{
+		if ( index > getColumnCount( ) || index < 1 )
+			throw new OdaException( Messages.getString( "resultSetMetaData_INVALID_COLUMN_INDEX" ) + index ); //$NON-NLS-1$
+	}
+	
+    public int findColumn( String columnName ) throws OdaException
+    {
+        String trimmedColumnName = columnName.trim();
+        Integer index = columnNameIndexMap.get( trimmedColumnName.toUpperCase( ) );
+        if (index == null)
+        {
+        	throw new OdaException( Messages
+                .getString( "resultSet_COLUMN_NOT_FOUND" ) + columnName ); //$NON-NLS-1$
+        }
+        else
+        {
+        	return index.intValue( );
+        }
+    }
+}
diff --git a/plugins/org.eclipse.datatools.connectivity.oda.flatfile/src/org/eclipse/datatools/connectivity/oda/flatfile/ResultSetMetaDataHelper.java b/plugins/org.eclipse.datatools.connectivity.oda.flatfile/src/org/eclipse/datatools/connectivity/oda/flatfile/ResultSetMetaDataHelper.java
new file mode 100644
index 0000000..b590dc7
--- /dev/null
+++ b/plugins/org.eclipse.datatools.connectivity.oda.flatfile/src/org/eclipse/datatools/connectivity/oda/flatfile/ResultSetMetaDataHelper.java
@@ -0,0 +1,154 @@
+
+/*******************************************************************************
+ * Copyright (c) 2004, 2006 Actuate Corporation.
+ * 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:
+ *  Actuate Corporation - initial API and implementation
+ *  
+ *******************************************************************************/
+package org.eclipse.datatools.connectivity.oda.flatfile;
+
+import java.util.HashMap;
+
+import org.eclipse.datatools.connectivity.oda.OdaException;
+import org.eclipse.datatools.connectivity.oda.flatfile.i18n.Messages;
+import org.eclipse.datatools.connectivity.oda.flatfile.util.querytextutil.ColumnsInfoUtil;
+
+/**
+ * A helper class that helps ResultSetMetaData to parse column information and
+ * provide a public access to ResultSet's original column names.
+ */
+
+public class ResultSetMetaDataHelper
+{
+	String savedSelectedColumnsInfoString;
+	String[] columnNames;
+	String[] columnTypes;
+	String[] originalColumnNames;
+	String[] columnLabels;
+	
+	private HashMap<String, Integer> columnNameIndexMap = new HashMap<String, Integer>( );
+	
+	/**
+	 * Constructor
+	 * 
+	 * @param colNames
+	 * @param colTypes
+	 * @param colLabels
+	 * @throws OdaException
+	 */
+	ResultSetMetaDataHelper( String[] colNames, String[] colTypes, String[] colLabels ) throws OdaException
+	{
+		if ( colNames == null )
+			throw new OdaException( Messages.getString( "common_ARGUMENT_CANNOT_BE_NULL" ) ); //$NON-NLS-1$
+
+		this.columnNames = colNames;
+		this.columnTypes = colTypes;
+		this.columnLabels = colLabels;
+		this.originalColumnNames = colNames;
+		trimMetaDataStrings( );
+		initMap( );
+	}
+	
+	/**
+	 * 
+	 * @param savedSelectedColumnsInfoString
+	 */
+	ResultSetMetaDataHelper( String savedSelectedColumnsInfoString )
+	{
+		this.savedSelectedColumnsInfoString = savedSelectedColumnsInfoString;
+		ColumnsInfoUtil ciu = new ColumnsInfoUtil( savedSelectedColumnsInfoString );
+		this.columnNames = ciu.getColumnNames( );
+		this.columnTypes = ciu.getColumnTypeNames( );
+		this.originalColumnNames = ciu.getOriginalColumnNames( );
+		this.columnLabels = this.columnNames;
+		trimMetaDataStrings( );
+		initMap( );
+	}
+	
+	private void initMap( )
+	{
+		for ( int i = 0; i < columnNames.length; i++ )
+		{
+			columnNameIndexMap.put( columnNames[i], Integer.valueOf( i ) );
+		}
+	}
+	
+	/**
+	 * 
+	 *
+	 */
+	private void trimMetaDataStrings( )
+	{
+		assert columnNames.length == columnTypes.length
+				&& columnTypes.length == originalColumnNames.length
+				&& originalColumnNames.length == columnLabels.length;
+
+		for ( int i = 0; i < columnNames.length; i++ )
+		{
+			columnNames[i] = columnNames[i].trim( );
+			columnTypes[i] = columnTypes[i].trim( );
+			columnLabels[i] = columnLabels[i].trim( );
+			originalColumnNames[i] = originalColumnNames[i].trim( );
+		}
+	}
+
+	/**
+	 * 
+	 * @return
+	 */
+	String[] getColumnNames( )
+	{
+		
+		return this.columnNames;
+	}
+
+	/**
+	 * 
+	 * @return
+	 */
+	String[] getColumnTypes( )
+	{
+		return this.columnTypes;
+	}
+
+	/**
+	 * 
+	 * @return
+	 */
+	String[] getColumnLabels( )
+	{
+		return this.columnLabels;
+	}
+
+	/**
+	 * Get the orignal column names
+	 * @return
+	 */
+	public String[] getOriginalColumnNames( )
+	{
+		return this.originalColumnNames;
+	}
+
+	/**
+	 * Get the original column name of the specified column name
+	 * @return
+	 */
+	public String getOriginalColumnName( String columnName )
+	{
+		String originName = null;
+		
+		Integer index = columnNameIndexMap.get( columnName );
+		
+		if ( index != null )
+		{
+			 originName = originalColumnNames[index.intValue( )];
+		}
+		return originName;
+	}
+	
+}
diff --git a/plugins/org.eclipse.datatools.connectivity.oda.flatfile/src/org/eclipse/datatools/connectivity/oda/flatfile/i18n/.gitignore b/plugins/org.eclipse.datatools.connectivity.oda.flatfile/src/org/eclipse/datatools/connectivity/oda/flatfile/i18n/.gitignore
new file mode 100644
index 0000000..f3b89a3
--- /dev/null
+++ b/plugins/org.eclipse.datatools.connectivity.oda.flatfile/src/org/eclipse/datatools/connectivity/oda/flatfile/i18n/.gitignore
@@ -0,0 +1 @@
+messages_*_*.properties
diff --git a/plugins/org.eclipse.datatools.connectivity.oda.flatfile/src/org/eclipse/datatools/connectivity/oda/flatfile/i18n/Messages.java b/plugins/org.eclipse.datatools.connectivity.oda.flatfile/src/org/eclipse/datatools/connectivity/oda/flatfile/i18n/Messages.java
new file mode 100644
index 0000000..a6a63c7
--- /dev/null
+++ b/plugins/org.eclipse.datatools.connectivity.oda.flatfile/src/org/eclipse/datatools/connectivity/oda/flatfile/i18n/Messages.java
@@ -0,0 +1,45 @@
+/*
+ *******************************************************************************
+ * Copyright (c) 2004, 2005 Actuate Corporation.
+ * 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:
+ *  Actuate Corporation  - initial API and implementation
+ *******************************************************************************
+ */
+
+package org.eclipse.datatools.connectivity.oda.flatfile.i18n;
+
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
+
+/**
+ * Resource messages wrapper for the package to obtain localized message text.
+ */
+
+public class Messages
+{
+    private static final String BUNDLE_NAME = "org.eclipse.datatools.connectivity.oda.flatfile.i18n.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 + '!';
+        }
+    }
+}
\ No newline at end of file
diff --git a/plugins/org.eclipse.datatools.connectivity.oda.flatfile/src/org/eclipse/datatools/connectivity/oda/flatfile/i18n/messages.properties b/plugins/org.eclipse.datatools.connectivity.oda.flatfile/src/org/eclipse/datatools/connectivity/oda/flatfile/i18n/messages.properties
new file mode 100644
index 0000000..32a63bf
--- /dev/null
+++ b/plugins/org.eclipse.datatools.connectivity.oda.flatfile/src/org/eclipse/datatools/connectivity/oda/flatfile/i18n/messages.properties
@@ -0,0 +1,58 @@
+#
+#************************************************************************
+# Copyright (c) 2004, 2012 Actuate Corporation.
+# 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:
+#  Actuate Corporation - initial API and implementation
+#  
+#************************************************************************
+#
+# Exception messages for the Oda Flat File Driver
+
+connection_CONNECTION_PROPERTIES_MISSING=Connection properties are missing.
+connection_CANNOT_OPEN_FLAT_FILE_DB_DIR=Cannot open flat file home folder: 
+connection_CANNOT_OPEN_FLAT_FILE_URI=Cannot open flat file from URI <{0}>, because: <{1}>.
+connection_MISSING_FILELOCATION=Missing required connection properties: a valid home folder or the URI for local/remote flat file. 
+connection_MISSING_HOMEFOLDER=Missing required connection properties: Home folder for local flat files 
+connection_MISSING_FILEURI=Missing required connection properties: File URI for remote flat file. 
+
+query_COMMAND_IS_EMPTY=Query command is empty.
+query_DO_NOT_SUPPORT_CROSS_TABLE_QUERY=Cross-table query is not supported.
+query_COMMAND_NOT_VALID=Query command is not valid.
+query_ARGUMENT_ERROR=The argument should be either 'NAME' or 'TYPE'.
+query_IO_EXCEPTION=An I/O Exception occurred when reading the file.
+query_SOURCE_DATA_ERROR=Duplicate column names found in source data.
+query_COLUMN_NAME_ERROR=Column name error
+query_INVALID_FLAT_FILE=The flatfile data source is not valid. Please use trailing null columns to disable column number validation.
+query_text_error=Query-text format error
+resultSet_COLUMN_NOT_FOUND=Column not found:
+resultSet_CURSOR_HAS_NOT_BEEN_INITIALIZED=Cursor has not been initialized yet.
+
+resultSetMetaData_INVALID_COLUMN_INDEX=Invalid column index:
+
+savedSelectedColumnsInfoString_INVALID=Invalid Saved Columns Information
+
+dataTypes_TYPE_NAME_INVALID=Invalid type name:
+
+dataSetMetaData_PRODUCT_NAME=DTP ODA Flat File Data Source Provider
+
+common_ARGUMENT_CANNOT_BE_NULL=Arguments cannot be null.
+common_CONNECTION_HAS_NOT_OPEN=Connection is not open.
+common_CANNOT_FIND_COLUMN=Cannot find any columns.
+common_NULL_QUERY_TEXT = Query text is null
+
+data_read_error=Cannot read data correctly, data source settings probably changed
+
+Invalid_column_name = Invaid column name
+
+invalid_flatfile_format = Invalid flat file format
+
+query_streamClosed=Stream closed
+query_invalidTableName=Invalid table name:
+
+dateUtil.ConvertFails=Convert to date fails. Source:
+dateFormatISO_cannotConvert=Cannot convert the value of {0}.
\ No newline at end of file
diff --git a/plugins/org.eclipse.datatools.connectivity.oda.flatfile/src/org/eclipse/datatools/connectivity/oda/flatfile/package.html b/plugins/org.eclipse.datatools.connectivity.oda.flatfile/src/org/eclipse/datatools/connectivity/oda/flatfile/package.html
new file mode 100644
index 0000000..0d83c23
--- /dev/null
+++ b/plugins/org.eclipse.datatools.connectivity.oda.flatfile/src/org/eclipse/datatools/connectivity/oda/flatfile/package.html
@@ -0,0 +1,148 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<html>
+<head>
+<!--
+
+ *************************************************************************
+ * Copyright (c) 2004, 2006 Actuate Corporation.
+ * 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:
+ *  Actuate Corporation - initial API and implementation
+ *  
+ *************************************************************************
+
+-->
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+</head>
+<body bgcolor="white">
+
+[<b>Non-API</b>] Flat file data source provider - an ODA run-time extension.
+<p>
+Note: <i>The implementation classes are <b>not</b> public APIs.  
+<br>Backward compatibility support in future releases is not guaranteed.</i>
+
+<h2>Package Specification</h2>
+The ODA flat file driver serves as an exemplary implementation
+of the ODA run-time interfaces.  
+It performs basic data source provider functionalities including:
+<p>
+<ul>
+<li>Executes a query on a specific flat file(CSV, SSV, TSV, PSV) using SQL-like query syntax</li>
+<li>Provides the query's result set metadata</li>
+<li>Retrieves the query's result set data from the CSV data file</li>
+</ul>
+<p>
+<h2>Consuming the ODA flat file driver</h2>
+<p>
+<ul>
+<li>Start by creating an IConnection instance by the FlatFileDriver.getConnection method.</li>
+<li>Open the connection using the IConnection.open( Properties prop ) method. 
+The driver-specific connection property names are:
+<ul>
+<li>"HOME" : The directory of the flat file (required property)</li>
+<li>"CHARSET" : The character set for decoding the data file; default value= "UTF-8"</li>
+<li>"INCLCOLUMNNAME": Indicates whether the  flat file contains column name meta-data; valid values= "YES" (default), "NO"</li>
+<li>"INCLTYPELINE" : Indicates whether the flat file contains data type meta-data; valid values= "YES" (default), "NO"</li>
+<li>"DELIMTYPE": Indicates the delimiter type the flat file uses; valid values="COMMA"(default), "SEMICOLON", "TAB", "PIPE"</li>
+</ul>
+<li>Create an IQuery instance by the IConnection.newQuery( String dataSetType ) method.</li>
+<li>Execute the query by the IQuery.executeQuery method, which returns an IResultSet for data retrieval.</li>
+</ul>
+</p>
+
+<h2>Data store format</h2>
+<p>
+The flat file ODA driver expects that both meta-data (including column names 
+and data types) and data are kept in a single flat file.
+The first line of a flat file specifies data column names.
+The second line may optionally specify the column data types. 
+The remaining portion of the file contains data.
+</p>
+<p>
+<h3>Redundant Spaces</h3>
+Redundant spaces are allowed in a flat file, but will be trimmed once processed by the flat file driver.
+</p>
+<h3>Double Quotes</h3>
+Double Quotes can be used in a flat file for the purpose of clarity. 
+The quotes, however, will be trimmed once processed by the driver. 
+That is, a line in flat file like
+<ul>100,"I'm a string","1"</ul>
+is processed to be the same as the following line:
+<ul>100,I'm a string,1</ul>
+
+A comma within a pair of double quotes would not be treated as separator. 
+For example,
+<ul>"I'm, however, a really normal String"</ul>
+contains a single column value.  
+It is not considered the same as the following line:
+<ul>I'm, however, a really normal String</ul>
+because the second case is processed to contain three columnn values, 
+i.e. "I'm", "however", and "a really normal String".
+<p>
+<h3>Null Values</h3>
+Null values are allowed. They are presented as blanks, and are comma-separated from other data. 
+A flat file that contains only one column, and all the data is of null value will be treated as an empty table.
+</p> 
+
+<h2>Data Types</h2>
+
+Flat file driver currently supports the following data types: 
+<br>INT, DOUBLE, STRING, DATE, TIME, TIMESTAMP and BIGDECIMAL. 
+<br>Support for BLOB and CLOB data types will be added in future.
+The driver's data type codes are defined as follows:
+<p>
+<ul>    INT = java.sql.Types.INTEGER;</ul>
+<ul>	DOUBLE = java.sql.Types.DOUBLE;</ul>
+<ul>	STRING = java.sql.Types.VARCHAR;</ul>
+<ul>	DATE = java.sql.Types.DATE;</ul>
+<ul>	TIME = java.sql.Types.TIME;</ul>
+<ul>	TIMESTAMP = java.sql.Types.TIMESTAMP;</ul>
+<ul>	BIGDECIMAL = java.sql.Types.NUMERIC;</ul>
+<ul>	BLOB = java.sql.Types.BLOB;</ul>
+<ul>	CLOB = java.sql.Types.CLOB;</ul>
+</p>
+
+<h2>SQL-like Query Syntax</h2>
+
+The flat file driver supports limited SQL-like query syntax. 
+The supported syntax is:
+<br>(those in square brackets are optional):
+<ul>
+<li><b>SELECT</b> column1 [<b>AS</b> alias1] [,column2 [<b>AS</b> alias2]]... [,columnN [<b>AS</b> aliasN]] <b>FROM</b> tableName</li>
+</ul>
+<ul>
+<li><b>SELECT * FROM</b> tableName</li>
+</ul>
+The query text is case in-sensitive and allows redundant spaces. 
+The flat file driver does not support multiple tables in the FROM clause.  
+For example, a table is named "employee.csv" with columns "Id", "Name" and "HireDate",
+the following queries are valid:
+
+<ul>SELECT Id FROM employee.csv</ul>
+<ul>SELECT Id,Name FROM employee.csv</ul>
+<ul>SELECT Id,Name,HireDate FROM employee.csv</ul>
+
+<ul>SELECT * FROM EMPLOYEE</ul>
+
+<ul>select Id AS PersonnelId, Name AS EmployeeName FROM employee.csv</ul>
+<ul>SELECT Name    AS     EmployeeName ,   Id  , HireDate  FROM employee.csv</ul>
+<ul>SELECT name, name from employee.csv 
+<br>// This command is valid, but would simply return a result set of two columns with same data values.</ul>
+
+However, the following queries are invalid:
+<ul>Id FROM EMPLOYEE.csv  			<br>// missing keyword "SELECT"</ul>
+<ul>Select id       			  <br>// missing keyword "FROM"</ul>
+<ul>SELECT I FROM employee.csv	<br>// invalid column name</ul>
+<br><br>
+<b>Advanced SOL-like query-text is also defined, and it can be used in the dataset design, 
+for detailed information please refer to "<i>org.eclipse.datatolls.connectivity.oda.flatfile.util.querytextutil.package.html</i>"</b>
+<br><br>
+<!-- Put @see and @since tags down here. -->
+@since 3.0
+
+</body>
+</html>
diff --git a/plugins/org.eclipse.datatools.connectivity.oda.flatfile/src/org/eclipse/datatools/connectivity/oda/flatfile/plugin/FlatfilePlugin.java b/plugins/org.eclipse.datatools.connectivity.oda.flatfile/src/org/eclipse/datatools/connectivity/oda/flatfile/plugin/FlatfilePlugin.java
new file mode 100644
index 0000000..dd99317
--- /dev/null
+++ b/plugins/org.eclipse.datatools.connectivity.oda.flatfile/src/org/eclipse/datatools/connectivity/oda/flatfile/plugin/FlatfilePlugin.java
@@ -0,0 +1,32 @@
+/*
+ ******************************************************************************
+ * Copyright (c) 2004, 2006 Actuate Corporation.
+ * 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:
+ *  Actuate Corporation - initial API and implementation
+ *******************************************************************************
+ */
+
+package org.eclipse.datatools.connectivity.oda.flatfile.plugin;
+
+import org.eclipse.core.runtime.Plugin;
+import org.osgi.framework.BundleContext;
+
+/**
+ * Flatfile oda driver plugin runtime implementation.
+ */
+public class FlatfilePlugin extends Plugin
+{
+    public void start( BundleContext context ) throws Exception
+    {
+        super.start( context );
+        if( isDebugging() )
+        {
+            // TODO 
+        }
+    }
+}
diff --git a/plugins/org.eclipse.datatools.connectivity.oda.flatfile/src/org/eclipse/datatools/connectivity/oda/flatfile/util/DateFormatFactory.java b/plugins/org.eclipse.datatools.connectivity.oda.flatfile/src/org/eclipse/datatools/connectivity/oda/flatfile/util/DateFormatFactory.java
new file mode 100644
index 0000000..c4305b6
--- /dev/null
+++ b/plugins/org.eclipse.datatools.connectivity.oda.flatfile/src/org/eclipse/datatools/connectivity/oda/flatfile/util/DateFormatFactory.java
@@ -0,0 +1,281 @@
+/*
+ *************************************************************************
+ * Copyright (c) 2006, 2007 Actuate Corporation.
+ * 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:
+ *  Actuate Corporation - initial API and implementation
+ *  
+ *******************************************************************************/
+
+package org.eclipse.datatools.connectivity.oda.flatfile.util;
+
+import java.util.HashMap;
+
+import com.ibm.icu.text.DateFormat;
+import com.ibm.icu.text.SimpleDateFormat;
+
+import com.ibm.icu.util.ULocale;
+
+/**
+ * Manages per-thread storage of locale-specific DateFormat instances. Use this
+ * factory to obtain DateFormat instances to address two issues: (1) Reduce cost
+ * of on-the-fly construction of DateFormat instances. The factory uses cached
+ * instances whenever possible. (2) MT-safety issue related to use of shared
+ * DateFormat instances across threads
+ */
+public class DateFormatFactory
+{
+
+	private static final int NO_TIME_STYLE = -999;
+
+	// TLS HashMap from locale/style key to DateFormat instance
+	private static ThreadLocal tlsCache = new ThreadLocal( ) {
+
+		protected Object initialValue( )
+		{
+			return new HashMap( );
+		}
+	};
+
+	private static ThreadLocal patternCache = new ThreadLocal( ) {
+		
+		protected Object initialValue( )
+		{
+			HashMap value = new HashMap( );
+			String[] dateFormatPattern = {
+					"yyyy-MM-dd HH:mm:ss.S z", //$NON-NLS-1$
+					"yyyy-MM-dd HH:mm:ss.Sz", //$NON-NLS-1$
+					"yyyy-MM-dd HH:mm:ss.S", //$NON-NLS-1$
+					"yyyy-MM-dd HH:mm:ss z", //$NON-NLS-1$
+					"yyyy-MM-dd HH:mm:ssz", //$NON-NLS-1$
+					"yyyy-MM-dd HH:mm:ss", //$NON-NLS-1$
+					"yyyy-MM-dd HH:mm z", //$NON-NLS-1$
+					"yyyy-MM-dd HH:mmz", //$NON-NLS-1$
+					"yyyy-MM-dd HH:mm", //$NON-NLS-1$
+					"yyyy-MM-dd", //$NON-NLS-1$
+					"yyyy-MM", //$NON-NLS-1$
+					"yyyy", //$NON-NLS-1$
+					"HH:mm:ss.S z", //$NON-NLS-1$
+					"HH:mm:ss.Sz", //$NON-NLS-1$
+					"HH:mm:ss.S", //$NON-NLS-1$
+					"HH:mm:ss z", //$NON-NLS-1$
+					"HH:mm:ssz", //$NON-NLS-1$
+					"HH:mm:ss", //$NON-NLS-1$
+					"HH:mm z", //$NON-NLS-1$
+					"HH:mmz", //$NON-NLS-1$
+					"HH:mm" //$NON-NLS-1$
+			};
+			SimpleDateFormat simpleDateFormatter = null;
+			PatternKey patterKey = null;
+			
+			for ( int i = 0; i < dateFormatPattern.length; i++ )
+			{
+				patterKey = PatternKey.getPatterKey( dateFormatPattern[i] );
+				simpleDateFormatter = new SimpleDateFormat( dateFormatPattern[i] );
+				simpleDateFormatter.setLenient( false );
+				value.put( patterKey, simpleDateFormatter );
+			}
+			return value;
+		}
+	};
+
+	/**
+	 * Gets DateFormat instance allocated to the current thread for the given
+	 * date style, timestyle and locale. Returned instance is safe to use
+	 * 
+	 */
+	public static DateFormat getDateTimeInstance( int dateStyle, int timeStyle,
+			ULocale locale )
+	{
+		assert locale != null;
+
+		// Create key string for cache lookup
+		String keyStr = locale.getName( )
+				+ "/" + Integer.toString( dateStyle ) + "/" //$NON-NLS-1$ //$NON-NLS-2$
+				+ Integer.toString( timeStyle );
+
+		HashMap tlsMap = (HashMap) tlsCache.get( );
+		assert tlsMap != null;
+
+		DateFormat result = (DateFormat) tlsMap.get( keyStr );
+
+		// Create new instance and add to cache if no instance available for
+		// current thread/style/locale combination
+		if ( result == null )
+		{
+			if ( timeStyle == NO_TIME_STYLE )
+				result = DateFormat.getDateInstance( dateStyle,
+						locale.toLocale( ) );
+			else
+				result = DateFormat.getDateTimeInstance( dateStyle,
+						timeStyle,
+						locale.toLocale( ) );
+			result.setLenient( false );
+			tlsMap.put( keyStr, result );
+		}
+
+		return result;
+
+	}
+
+	/**
+	 * Gets DateFormat instance allocated to the current thread for the given
+	 * date style, timestyle and locale. Returned instance is safe to use
+	 * 
+	 */
+	public static DateFormat getDateInstance( int dateStyle, ULocale locale )
+	{
+		return getDateTimeInstance( dateStyle, NO_TIME_STYLE, locale );
+	}
+	
+	/**
+	 * Gets DateFormat instance allocated to the current thread for the given
+	 * pattern. Returned instance is safe to use
+	 * 
+	 */
+	public static SimpleDateFormat getPatternInstance( PatternKey pattern )
+	{
+
+		HashMap patternMap = (HashMap) patternCache.get( );
+		assert patternMap != null;
+
+		return (SimpleDateFormat) patternMap.get( pattern );
+	}
+
+}
+
+/**
+ * A class used as hash key of date format pattern.
+ *
+ */
+class PatternKey
+{
+	private int colonNumber;
+	private int blankNumber;
+	private int hyphenNumber;
+	private int dotNumber;
+	private int timeZomeNumber;
+	
+	/**
+	 * 
+	 * @param source
+	 * @return
+	 */
+	public static PatternKey getPatterKey( String source )
+	{
+		int colonNumber = 0;
+		int blankNumber = 0;
+		int hyphenNumber = 0;
+		int dotNumber = 0;
+		int timeZomeNumber = 0;
+		boolean beLastBlank = false;
+
+		for ( int i = 0; i < source.length( ); i++ )
+		{
+			switch ( source.charAt( i ) )
+			{
+				case ':' :
+				{
+					beLastBlank = false;
+					colonNumber++;
+					break;
+				}
+
+				case ' ' :
+				{
+					if ( !beLastBlank )
+					{
+						blankNumber++;
+					}
+					beLastBlank = true;
+					break;
+				}
+				case '-' :
+				{
+					beLastBlank = false;
+					if ( blankNumber == 0 )
+					{
+						hyphenNumber++;
+					}
+					else
+					{
+						timeZomeNumber++;
+					}
+					break;
+				}
+				case '.' :
+				{
+					beLastBlank = false;
+					dotNumber++;
+					break;
+				}
+				case '+' :
+				case 'z' :
+				case 'Z' :
+				{
+					beLastBlank = false;
+					timeZomeNumber++;
+					break;
+				}
+			}
+			if ( timeZomeNumber > 0 )
+			{
+				break;
+			}
+		}
+
+		if ( hyphenNumber == 0 && colonNumber == 0 && source.length( ) > 4 )
+		{
+			return null;
+		}
+
+		return ( new PatternKey( colonNumber,
+				blankNumber,
+				hyphenNumber,
+				dotNumber,
+				timeZomeNumber ) );
+	}
+
+	PatternKey( int colonNumber, int blankNumber, int hyphenNumber,
+			int dotNumber, int timeZomeNumber )
+	{
+		this.colonNumber = colonNumber;
+		this.blankNumber = blankNumber;
+		this.hyphenNumber = hyphenNumber;
+		this.dotNumber = dotNumber;
+		this.timeZomeNumber = timeZomeNumber;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see java.lang.Object#hashCode()
+	 */
+	public int hashCode( )
+	{
+		return colonNumber
+				* 36 + blankNumber * 12 + hyphenNumber * 4 + dotNumber * 2
+				+ timeZomeNumber;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see java.lang.Object#equals(java.lang.Object)
+	 */
+	public boolean equals( Object key )
+	{
+		if ( key == null )
+			return false;
+		PatternKey patterKey = (PatternKey) key;
+		return patterKey.colonNumber == this.colonNumber
+				|| patterKey.blankNumber == this.blankNumber
+				|| patterKey.hyphenNumber == this.hyphenNumber
+				|| patterKey.dotNumber == this.dotNumber
+				|| patterKey.timeZomeNumber == this.timeZomeNumber;
+	}
+}
diff --git a/plugins/org.eclipse.datatools.connectivity.oda.flatfile/src/org/eclipse/datatools/connectivity/oda/flatfile/util/DateFormatISO8601.java b/plugins/org.eclipse.datatools.connectivity.oda.flatfile/src/org/eclipse/datatools/connectivity/oda/flatfile/util/DateFormatISO8601.java
new file mode 100644
index 0000000..66aa468
--- /dev/null
+++ b/plugins/org.eclipse.datatools.connectivity.oda.flatfile/src/org/eclipse/datatools/connectivity/oda/flatfile/util/DateFormatISO8601.java
@@ -0,0 +1,131 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2007 Actuate Corporation.
+ * 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:
+ *  Actuate Corporation - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.datatools.connectivity.oda.flatfile.util;
+
+import java.text.ParseException;
+import com.ibm.icu.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.regex.Pattern;
+
+import org.eclipse.datatools.connectivity.oda.flatfile.i18n.Messages;
+import org.eclipse.osgi.util.NLS;
+
+
+
+/**
+ * DateFormatISO8601 is a utility class for formatting and parsing dates
+ * according to date format defined by ISO8601.
+ */
+
+public class DateFormatISO8601
+{
+	
+	private static Pattern T_PATTERN = Pattern.compile( "T" );
+	
+	/**
+	 * Parse a date/time string.
+	 * @param source
+	 * @return
+	 * @throws ParseException
+	 */
+	public static Date parse( String source ) throws ParseException,
+			ParseException
+	{
+		if( source == null )
+		{
+			return null;
+		}
+		Date resultDate = null;
+		source = cleanDate( source );
+		Object simpleDateFormatter = DateFormatFactory.getPatternInstance( PatternKey.getPatterKey( source ) );
+		if ( simpleDateFormatter != null )
+		{
+			try
+			{
+				resultDate = ( (SimpleDateFormat) simpleDateFormatter ).parse( source );
+				return resultDate;
+			}
+			catch ( ParseException e1 )
+			{
+			}
+		}
+		throw new ParseException( 
+		        NLS.bind( Messages.getString( "dateFormatISO_cannotConvert" ), source ), //$NON-NLS-1$
+				0 );		
+	}
+	
+	/**
+	 * 
+	 * @param s
+	 * @return
+	 */
+	private static String cleanDate( String s )
+	{
+		s = s.trim( );
+		if ( s.indexOf( 'T' ) < 12 )
+		{
+			s =  T_PATTERN.matcher( s ).replaceFirst( " " );//$NON-NLS-1$ //$NON-NLS-2$
+		}
+		
+//		int zoneIndex = s.indexOf( "GMT" ); //$NON-NLS-1$
+//		if( zoneIndex > 0 )
+//		{
+//			return s.substring( 0, zoneIndex ).trim( );
+//		}
+		int zoneIndex = s.indexOf( 'Z' );
+		if ( zoneIndex == s.length( ) - 1 )
+		{
+			return s.substring( 0, zoneIndex ).trim( );
+		}
+//		zoneIndex = getZoneIndex( s );
+//		if ( zoneIndex > 0 )
+//		{
+//			return s.substring( 0, zoneIndex ).trim( );
+//		}
+		
+		return s;
+	}
+
+	/**
+	 * 
+	 * @param s
+	 * @return
+	 */
+	private static int getZoneIndex( String s )
+	{
+		int index = s.indexOf( '+' );
+		if ( index > 0 )
+		{
+			return index;
+		}
+		
+		index = s.indexOf( '-' ); //first '-'
+		if ( index > 0 )
+		{
+			index = s.indexOf( '-', index + 1 ); //second '-'
+		}
+		else
+		{
+			return index;
+		}
+		if ( index > 0 )
+		{
+			index = s.indexOf( '-', index + 1 ); //third '-'
+		}
+		else
+		{
+			return index;
+		}
+		return index;
+	}	
+
+}
diff --git a/plugins/org.eclipse.datatools.connectivity.oda.flatfile/src/org/eclipse/datatools/connectivity/oda/flatfile/util/DateUtil.java b/plugins/org.eclipse.datatools.connectivity.oda.flatfile/src/org/eclipse/datatools/connectivity/oda/flatfile/util/DateUtil.java
new file mode 100644
index 0000000..26fda20
--- /dev/null
+++ b/plugins/org.eclipse.datatools.connectivity.oda.flatfile/src/org/eclipse/datatools/connectivity/oda/flatfile/util/DateUtil.java
@@ -0,0 +1,445 @@
+
+/*******************************************************************************
+ * Copyright (c) 2004, 2007 Actuate Corporation.
+ * 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:
+ *  Actuate Corporation - initial API and implementation
+ *  
+ *******************************************************************************/
+package org.eclipse.datatools.connectivity.oda.flatfile.util;
+
+import java.sql.Time;
+import java.text.ParseException;
+import java.util.Date;
+import java.util.Locale;
+import java.util.regex.Pattern;
+
+import org.eclipse.datatools.connectivity.oda.OdaException;
+import org.eclipse.datatools.connectivity.oda.flatfile.i18n.Messages;
+
+import com.ibm.icu.text.DateFormat;
+import com.ibm.icu.text.SimpleDateFormat;
+import com.ibm.icu.util.Calendar;
+import com.ibm.icu.util.ULocale;
+
+/**
+ * A utility class. The convert method converts the source object into an Date
+ * object given specified type. If no reasonable conversion can be made, throw a
+ * OdaException.
+ */
+public final class DateUtil
+{
+
+	// Defalult Locale, if we have any problem parse string to date for Locale.getDefault()
+	// we will try to parse it for Locale.US
+	private static ULocale DEFAULT_LOCALE = ULocale.US;
+	private static ULocale JRE_DEFAULT_LOCALE = ULocale.getDefault( );
+	
+	private static SimpleDateFormat MysqlUSDateFormatter = new SimpleDateFormat( "M/d/yyyy HH:mm" );
+
+	// Default Date/Time Style 
+	private static int DEFAULT_DATE_STYLE = DateFormat.MEDIUM;
+	
+	private static Pattern p1 = Pattern.compile( ".*[0-9]+:[0-9]+:[0-9]+.*" );//$NON-NLS-1$
+	private static Pattern p2 = Pattern.compile( ".*[0-9]+:[0-9]+.*" );//$NON-NLS-1$
+	
+	private static DateFormat cachedDateFormat = null;
+	
+	/**
+	 * Number -> Date
+	 * 		new Date((long)Number)
+	 * String -> Date
+	 * 		toDate(String)  
+	 * @param source
+	 * @return
+	 * @throws OdaException
+	 */
+	public static Date toDate( Object source ) throws OdaException
+	{
+		if ( source == null )
+			return null;
+		
+		if ( source instanceof Date )
+		{
+			return new Date( ( (Date) source ).getTime( ) );
+		}
+		else if ( source instanceof String )
+		{
+			return toDate( (String) source );
+		}
+		else
+		{
+			throw new OdaException( Messages.getString( "dateUtil.ConvertFails" ) + source.toString( ) ); //$NON-NLS-1$
+		}
+	}
+    
+    /**
+     * Date -> Time
+     * String -> Time
+     * @param source
+     * @return
+     * @throws OdaException
+     */
+    public static Time toSqlTime( Object source ) throws OdaException
+    {
+        if ( source == null )
+            return null;
+
+        if ( source instanceof Date )
+        {
+       		return toSqlTime( (Date)source);
+        }
+        else if ( source instanceof String )
+        {
+            try
+            {
+                return toSqlTime( toDate((String ) source) );
+            }
+            catch( Exception e )
+            {
+                try
+                {
+                	return toSqlTime( (String)source );
+                }
+                catch ( Exception e1 )
+                {
+                	
+                }
+            }
+        }
+
+        throw new OdaException( Messages.getString( "dateUtil.ConvertFails" ) + source.toString( ) ); //$NON-NLS-1$
+    }
+
+    /**
+     * 
+     * @param date
+     * @return
+     */
+    private static java.sql.Time toSqlTime( Date date )
+    {
+    	Calendar calendar = Calendar.getInstance( );
+		calendar.clear( );
+		calendar.setTimeInMillis( date.getTime( ) );
+		calendar.set( Calendar.YEAR, 1970 );
+		calendar.set( Calendar.MONTH, 0 );
+		calendar.set( Calendar.DAY_OF_MONTH, 1 );
+		calendar.set( Calendar.MILLISECOND, 0 );
+		return new java.sql.Time( calendar.getTimeInMillis( ) );
+    }
+    
+    /**
+     * 
+     * @param value
+     * @return
+     */
+    private static Time toSqlTime( String s )
+    {
+		int hour;
+		int addHour;
+		int minute;
+		int second;
+		int firstColon;
+		int secondColon;
+		int marker;
+		
+		if ( s == null )
+			throw new java.lang.IllegalArgumentException( );
+
+		firstColon = s.indexOf( ':' );
+		secondColon = s.indexOf( ':', firstColon + 1 );
+		for ( marker = secondColon + 1; marker < s.length( ); marker++ )
+		{
+			if ( !isDigitTen( s.charAt( marker ) ) )
+				break;
+		}
+		addHour = 0;
+		String markerValue = null;
+		if ( marker < s.length( ) )
+		{
+			markerValue = s.substring( marker ).trim( );
+			if ( "am".compareToIgnoreCase( markerValue ) == 0 ) //$NON-NLS-1$
+			{
+				addHour = 0;
+			}
+			else if ( "pm".compareToIgnoreCase( markerValue ) == 0 ) //$NON-NLS-1$
+			{
+				addHour = 12;
+			}
+			else
+			{
+				throw new java.lang.IllegalArgumentException( );
+			}
+		}
+		if ( firstColon <= 0  ||
+				secondColon <= 0 || secondColon >= s.length( ) - 1 )
+		{
+			throw new java.lang.IllegalArgumentException( );
+		}
+		hour = Integer.parseInt( s.substring( 0, firstColon ) );
+		if ( hour < 0 ||
+				( hour > 12 && markerValue != null && markerValue.length( ) > 0 ) )
+			throw new java.lang.IllegalArgumentException( );
+		hour += addHour;
+		if( hour > 24 )
+			throw new java.lang.IllegalArgumentException( );
+		minute = Integer.parseInt( s.substring( firstColon + 1, secondColon ) );
+		if( minute < 0 || minute > 60 )
+			throw new java.lang.IllegalArgumentException( );
+		if ( marker < s.length( ) )
+			second = Integer.parseInt( s.substring( secondColon + 1, marker ) );
+		else
+			second = Integer.parseInt( s.substring( secondColon + 1 ) );
+		if( second < 0 || second > 60 )
+			throw new java.lang.IllegalArgumentException( );
+		
+		return toSqlTime( hour, minute, second );
+	}
+    
+    /**
+     * 
+     * @param c
+     * @return
+     */
+    private static boolean isDigitTen( char c )
+	{
+		if ( c <= '9' && c >= '0' )
+			return true;
+		return false;
+	}
+    
+    /**
+     * 
+     * @param hour
+     * @param minute
+     * @param second
+     * @return
+     */
+    private static Time toSqlTime( int hour, int minute, int second )
+    {
+    	Calendar calendar = Calendar.getInstance( );
+		calendar.clear( );
+		calendar.set( Calendar.HOUR_OF_DAY, hour );
+		calendar.set( Calendar.MINUTE, minute );
+		calendar.set( Calendar.SECOND, second );
+		return new java.sql.Time( calendar.getTimeInMillis( ) );
+    }
+    
+    /**
+     * Date -> Time
+     * String -> Time
+     * @param source
+     * @return
+     * @throws OdaException
+     */
+    public static java.sql.Date toSqlDate( Object source ) throws OdaException
+    {
+        if ( source == null )
+            return null;
+
+        if ( source instanceof Date )
+        {
+    		return toSqlDate( (Date)source );
+        }
+        else if ( source instanceof String )
+        {
+            try
+            {
+                return toSqlDate( toDate((String ) source) );
+            }
+            catch( Exception e )
+            {
+                try
+                {
+                	return java.sql.Date.valueOf( (String)source );
+                }
+                catch ( Exception e1 )
+                {
+                	
+                }
+            }
+        }
+
+        throw new OdaException( Messages.getString( "dateUtil.ConvertFails" ) + source.toString( ) ); //$NON-NLS-1$ 
+    }
+    
+    /**
+     * 
+     * @param date
+     * @return
+     */
+    private static java.sql.Date toSqlDate( Date date )
+    {
+    	Calendar calendar = Calendar.getInstance( );
+		calendar.clear( );
+		calendar.setTimeInMillis( date.getTime( ) );
+		calendar.set( Calendar.HOUR_OF_DAY, 0 );
+		calendar.set( Calendar.MINUTE, 0 );
+		calendar.set( Calendar.SECOND, 0 );
+		calendar.set( Calendar.MILLISECOND, 0 );		
+		return new java.sql.Date( calendar.getTimeInMillis( ) );
+    }
+    
+    /**
+	 * A temp solution to the adoption of ICU4J to BIRT. Simply delegate
+	 * toDate( String, Locale) method.
+	 * 
+	 * @param source
+	 *            the String to be convert
+	 * @param locate
+	 * 			  the locate of the string
+	 * @return result Date
+	 */
+	public static Date toDate( String source, Locale locale )
+			throws OdaException
+	{
+		return toDate( source, ULocale.forLocale( locale ) );
+	}
+
+	/**
+	 * convert String with the specified locale to java.util.Date
+	 * 
+	 * @param source
+	 *            the String to be convert
+	 * @param locate
+	 * 			  the locate of the string
+	 * @return result Date
+	 */
+	public static Date toDate( String source, ULocale locale )
+			throws OdaException
+	{
+		if ( source == null )
+			return null;
+
+		DateFormat dateFormat = null;
+		Date resultDate = null;
+		
+		boolean existTime = p1.matcher( source ).matches( )
+				|| p2.matcher( source ).matches( );
+		
+		if ( cachedDateFormat != null )
+		{
+			try
+			{
+				resultDate = cachedDateFormat.parse( source );
+				return resultDate;
+			}
+			catch ( ParseException e1 )
+			{
+				cachedDateFormat = null;
+			}
+		}
+
+		for ( int i = DEFAULT_DATE_STYLE; i <= DateFormat.SHORT; i++ )
+		{
+			for ( int j = DEFAULT_DATE_STYLE; j <= DateFormat.SHORT; j++ )
+			{
+				dateFormat = DateFormatFactory.getDateTimeInstance( i,
+						j,
+						locale );
+				try
+				{
+					resultDate = dateFormat.parse( source );
+					cachedDateFormat = dateFormat;
+					return resultDate;
+				}
+				catch ( ParseException e1 )
+				{
+				}
+			}
+
+			// only Date, no Time
+			if ( !existTime )
+			{
+				dateFormat = DateFormatFactory.getDateInstance( i, locale );
+				try
+				{
+					resultDate = dateFormat.parse( source );
+					return resultDate;
+				}
+				catch ( ParseException e1 )
+				{
+				}
+			}
+		}
+		throw new OdaException( Messages.getString( "dateUtil.ConvertFails" ) + source.toString( ) ); //$NON-NLS-1$
+	}
+
+	/**
+	 * Convert String without specified locale to java.util.Date
+	 * Try to format the given String for JRE default Locale,
+	 * if it fails, try to format the String for Locale.US 
+	 * @param source
+	 *            the String to be convert
+	 * @param locate
+	 * 			  the locate of the string
+	 * @return result Date
+	 */
+	private static Date toDate( String source ) throws OdaException
+	{
+		try
+		{
+			return toDateISO8601( source );
+		}
+		catch ( OdaException e )
+		{
+			try
+			{
+				// format the String for JRE default locale
+				return toDate( source, JRE_DEFAULT_LOCALE );
+			}
+			catch ( OdaException use )
+			{
+				try
+				{
+					// format the String for Locale.US
+					return toDate( source, DEFAULT_LOCALE );
+				}
+				catch ( OdaException de )
+				{
+					return toDateForSpecialFormat( source );
+				}
+			}
+		}
+	}
+
+	private static Date toDateForSpecialFormat( String source ) throws OdaException
+	{
+		try
+		{
+			return MysqlUSDateFormatter.parse( source );
+		}
+		catch ( ParseException e1 )
+		{
+			throw new OdaException( Messages.getString( "dateUtil.ConvertFails" ) + source.toString( ) ); //$NON-NLS-1$
+		}
+	}
+	
+	/**
+	 * convert String with ISO8601 date format to java.util.Date
+	 * 
+	 * @param source
+	 *            the String to be convert
+	 * @param locate
+	 * 			  the locate of the string
+	 * @return result Date
+	 */
+	private static Date toDateISO8601( String source ) throws OdaException
+	{
+		Date resultDate = null;
+
+		try
+		{
+			resultDate = DateFormatISO8601.parse( source );
+			return resultDate;
+		}
+		catch ( ParseException e1 )
+		{
+			throw new OdaException( Messages.getString( "dateUtil.ConvertFails" ) + source.toString( ) ); //$NON-NLS-1$ 
+		}
+	}
+}
diff --git a/plugins/org.eclipse.datatools.connectivity.oda.flatfile/src/org/eclipse/datatools/connectivity/oda/flatfile/util/FlatFileDataReader.java b/plugins/org.eclipse.datatools.connectivity.oda.flatfile/src/org/eclipse/datatools/connectivity/oda/flatfile/util/FlatFileDataReader.java
new file mode 100644
index 0000000..3a9e609
--- /dev/null
+++ b/plugins/org.eclipse.datatools.connectivity.oda.flatfile/src/org/eclipse/datatools/connectivity/oda/flatfile/util/FlatFileDataReader.java
@@ -0,0 +1,474 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2007 Actuate Corporation.
+ * 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:
+ *  Actuate Corporation - initial API and implementation
+ *  
+ *******************************************************************************/
+
+package org.eclipse.datatools.connectivity.oda.flatfile.util;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+
+import org.eclipse.datatools.connectivity.oda.IResultSetMetaData;
+import org.eclipse.datatools.connectivity.oda.OdaException;
+import org.eclipse.datatools.connectivity.oda.flatfile.CommonConstants;
+import org.eclipse.datatools.connectivity.oda.flatfile.Connection;
+import org.eclipse.datatools.connectivity.oda.flatfile.ResourceInputStream;
+import org.eclipse.datatools.connectivity.oda.flatfile.FlatFileQuery.FlatFileBufferedReader;
+import org.eclipse.datatools.connectivity.oda.flatfile.ResultSetMetaDataHelper;
+import org.eclipse.datatools.connectivity.oda.flatfile.i18n.Messages;
+
+/**
+ * FlatFileDataSourceReader is a utility class that help read and parse the raw data from flat file
+ */
+
+public class FlatFileDataReader
+{
+
+	private String currentTableName;
+	private String charSet;
+	private FlatFileBufferedReader flatFileBufferedReader=null;
+	private IResultSetMetaData rsmd;
+	private ResultSetMetaDataHelper rsmdHelper;
+	private int statementMaxRows = 0;
+	private int resultSetMaxRows = 0;
+	private int maxRowsToRead = 0;
+	private String[] originalColumnNames;
+	private boolean isFirstTimeToReadSourceData = true;
+	private boolean isFirstTimeToCallReadLine = true;
+	private int fetchCounter = 0;
+	private int[] selectColumIndexes; 
+	private Connection conn;
+	
+	private List<String> nextDataLine;
+
+	//Max number of rows fetched each time from data source
+	public static final int MAX_ROWS_PER_FETCH = 20000;
+	
+	/**
+	 * Constructor
+	 * 
+	 * @param connProperties Connection properties
+	 * @param currentTableName The current table name of this connection
+	 * @param statementMaxRows	The max number of rows specified in the query
+	 * @param rsmd	ResultSet meta-data
+	 * @param rsmdHelper	ResultSet meta-data helper
+	 * @throws OdaException
+	 */
+	public  FlatFileDataReader( Connection connection,String currentTableName,int statementMaxRows,
+			IResultSetMetaData rsmd, ResultSetMetaDataHelper rsmdHelper ) throws OdaException
+	{
+		this.rsmd = rsmd;
+		this.rsmdHelper = rsmdHelper;
+		this.statementMaxRows = statementMaxRows;
+		this.currentTableName = currentTableName;
+		this.conn = connection;
+		
+		this.charSet = conn.getCharSet( );
+	}
+	
+	private void initNameIndexMap( ) throws OdaException
+	{
+		assert originalColumnNames != null;
+		HashMap<String, Integer> originalColumnNameIndexMap = new HashMap<String, Integer>( ); 
+		for (int i = 0; i < originalColumnNames.length; i++)
+		{
+			originalColumnNameIndexMap.put( originalColumnNames[i].trim( ).toUpperCase( ), 
+					Integer.valueOf( i ) );
+		}
+		selectColumIndexes = new int[rsmd.getColumnCount( )];
+
+		for ( int i = 0; i < rsmd.getColumnCount( ); i++ )
+		{
+			selectColumIndexes[i] = findIndex(rsmdHelper.getOriginalColumnName( rsmd.getColumnName( i + 1 )), originalColumnNameIndexMap);
+		}
+	}
+	
+	public boolean getTrailNullColumns()
+	{
+		return conn.trailNullColumns( );
+	}
+
+	/**
+	 * 
+	 * @return
+	 * @throws OdaException
+	 */
+	public String[][] getSourceData( ) throws OdaException
+	{
+		createBufferedReader( );
+		List<String[]> v = fetchQueriedDataFromFileToList( );
+		return copyDataFromListToTwoDimensionArray( v );
+	}
+	
+	/**
+	 * Read a row from the source data
+	 * @return
+	 * @throws OdaException
+	 * @throws IOException
+	 */
+	public List<String> readLine( ) throws OdaException
+	{
+		if ( isFirstTimeToCallReadLine )
+		{
+			createBufferedReader( );
+			isFirstTimeToCallReadLine = false;
+		}
+
+		return flatFileBufferedReader.readLine( );
+	}
+
+	/**
+	 * 
+	 * @throws OdaException
+	 */
+	private void createBufferedReader( ) throws OdaException
+	{
+		try
+		{
+			if( this.flatFileBufferedReader == null )
+			{
+				examCharset( );
+	
+				this.flatFileBufferedReader = new FlatFileBufferedReader( getInputStream( ),
+						this.charSet, conn.getDelimeter( ));
+			}
+
+		}
+		catch ( IOException e )
+		{
+			throw new OdaException( e.getMessage( ) );
+		}
+	}
+
+	/**
+	 * 
+	 * @param resultSetMaxRows
+	 * @return
+	 */
+	public int getMaxRowsToRead( int resultSetMaxRows )
+	{
+		this.resultSetMaxRows = resultSetMaxRows;
+		return this.maxRowsToRead = ( ( this.statementMaxRows != 0 && this.statementMaxRows < this.resultSetMaxRows ) || this.resultSetMaxRows == 0 )
+				? this.statementMaxRows : this.resultSetMaxRows;
+	}
+	
+	/**
+	 * 
+	 *
+	 */
+	public void clearBufferedReader( )
+	{
+		try
+		{
+			if ( this.flatFileBufferedReader != null )
+				this.flatFileBufferedReader.close( );
+		}
+		catch ( IOException e )
+		{
+			
+		}
+		this.flatFileBufferedReader = null;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * @see java.lang.Object#finalize()
+	 */
+	public void finalize()
+	{
+		this.clearBufferedReader( );
+	}
+
+	/**
+	 * If Charset is not set (that is, of null or empty value), test whether the
+	 * file is encoded with "UTF-16LE" or "UTF-16BE". If neither, then treat
+	 * file as using default "UTF-8"
+	 */
+	private void examCharset( ) throws OdaException, IOException
+	{
+		if ( this.charSet != null && this.charSet.length( ) > 0 )
+			return;
+		
+		InputStream fis = getInputStream( );
+		byte[] byteMarker = new byte[2];
+		fis.read( byteMarker );
+		// file encoded using UTF-16LE sometimes have two bytes prefix
+		// -1, -2
+		// file encoded using UTF-16BE sometimes have two bytes prefix
+		// -2, -1
+		if ( byteMarker[0] == -1 && byteMarker[1] == -2 )
+			this.charSet = "UTF-16LE"; //$NON-NLS-1$
+		else if ( byteMarker[0] == -2 && byteMarker[1] == -1 )
+			this.charSet = "UTF-16BE"; //$NON-NLS-1$
+		else
+			this.charSet = CommonConstants.CONN_DEFAULT_CHARSET;
+		fis.close( );
+	}
+
+	/**
+	 * 
+	 * @param connProperties
+	 * @param tableName
+	 * @return
+	 * @throws OdaException
+	 */
+	public int getColumnCount( ) throws OdaException
+	{
+		int count;
+		ResourceInputStream fis = null;
+		try
+		{
+			examCharset( );
+			fis = getInputStream( );
+			FlatFileBufferedReader br = new FlatFileBufferedReader( fis, this.charSet, conn.getDelimeter( ));
+			List<String> columnLine;
+			while ( isEmptyRow( columnLine = br.readLine( ) ) )
+			{
+				continue;
+			}
+			count = columnLine.size( );
+			br.close( );
+			fis.close( );
+		}
+		catch ( IOException e )
+		{
+			throw new OdaException( Messages.getString( "query_IO_EXCEPTION" ) //$NON-NLS-1$
+					+ fis.getLocation( ) );
+		}
+
+		return count;
+	}
+
+	public ResourceInputStream getInputStream( ) throws OdaException
+	{
+		return conn.getInputStream( this.currentTableName );
+	}
+
+	/**
+	 * See if this row is empty or not
+	 * @param row
+	 * @return
+	 * @throws OdaException
+	 */
+	public static boolean isEmptyRow( List<String> line ) throws OdaException
+	{
+		if ( line == null )
+			throw new OdaException( Messages.getString( "query_INVALID_FLAT_FILE" ) ); //$NON-NLS-1$
+
+		return line.isEmpty( ) || ( line.size( ) == 1 && line.get( 0 ).equals( "" )); //$NON-NLS-1$
+	}
+
+	/**
+	 * 
+	 * @return
+	 * @throws OdaException
+	 */
+	private List<String[]> fetchQueriedDataFromFileToList( ) throws OdaException
+	{
+		List<String[]> result = new ArrayList<String[]>( );
+		if ( isFirstTimeToReadSourceData )
+		{
+			// make a copy of column names if there are
+			if ( conn.hasColumnNames( ) )
+			{
+				List<String> columeNameLine;
+				while ( isEmptyRow( columeNameLine = flatFileBufferedReader.readLine( ) ) )
+				{
+					continue;
+				}
+				this.originalColumnNames = getColumnNameArray( columeNameLine );
+				initNameIndexMap( );
+			}
+
+			// skip Type information. The type information is in the second
+			// line
+			// of file
+			if ( conn.hasTypeLine( ) )
+			{
+				while ( isEmptyRow( flatFileBufferedReader.readLine( ) ) )
+					continue;
+			}
+
+			if ( !conn.hasColumnNames( ) )
+			{
+				while ( isEmptyRow( nextDataLine = flatFileBufferedReader.readLine( ) ) )
+				{
+					continue;
+				}
+				this.originalColumnNames = createTempColumnNames( nextDataLine );
+				initNameIndexMap( );
+			}
+			else
+			{
+				nextDataLine = flatFileBufferedReader.readLine( );
+			}
+			isFirstTimeToReadSourceData = false;
+		}
+
+		// temporary variable which is used to store the data of a row
+		// fetched from a flat file
+
+		int counterLimitPerFetch = fetchCounter + MAX_ROWS_PER_FETCH;
+
+		while ( ( this.maxRowsToRead <= 0 ? true
+				: this.fetchCounter < this.maxRowsToRead )
+				&& this.fetchCounter < counterLimitPerFetch
+				&& nextDataLine != null )
+		{
+			if ( !isEmptyRow( nextDataLine ) )
+			{
+				fetchCounter++;
+				result.add( fetchQueriedDataFromRow( nextDataLine ) );
+			}
+			nextDataLine = flatFileBufferedReader.readLine( );
+		}
+
+		return result;
+	}
+
+	/**
+	 * Extract the column name from the line into the format of string array
+	 * @param line
+	 * @param isFirstLine
+	 * @return
+	 * @throws OdaException
+	 */
+	public String[] getColumnNameArray( List<String> line )
+			throws OdaException
+	{
+		if ( line == null )
+			throw new OdaException( Messages.getString( "common_CANNOT_FIND_COLUMN" ) ); //$NON-NLS-1$
+		return getStringArrayFromList( line );
+	}
+
+	/**
+	 * Put the contants of the list into a string array
+	 * @param list
+	 * @return
+	 */
+	public static String[] getStringArrayFromList( List<String> list )
+	{
+		String[] array = null;
+		if ( list != null )
+		{
+			array = new String[list.size( )];
+			for ( int i = 0; i < list.size( ); i++ )
+				array[i] = (String) list.get( i );
+		}
+		return array;
+	}
+
+	/**
+	 * Feed the row data from a List to a two-dimension array. The string
+	 * value is trimmed before being copied into array.
+	 * 
+	 * @param v
+	 * @return a String two dimension array with each horizontal array contains
+	 *         a row
+	 * @throws OdaException
+	 */
+	private String[][] copyDataFromListToTwoDimensionArray( List<String[]> v )
+			throws OdaException
+	{
+		String[][] rowSet = new String[v.size( )][this.rsmd.getColumnCount( )];
+		for ( int i = 0; i < v.size( ); i++ )
+		{
+			String[] temp = (String[]) v.get( i );
+			for ( int j = 0; j < temp.length; j++ )
+			{
+				if ( temp[j] != null )
+					rowSet[i][j] = temp[j].trim( );
+				else if ( conn.trailNullColumns( ) )
+				{
+					continue;	
+				}
+				else
+				{
+					throw new OdaException( Messages.getString( "data_read_error" ) ); //$NON-NLS-1$
+				}
+			}
+		}
+		return rowSet;
+	}
+
+	/**
+	 * 
+	 * @param columnCount
+	 * @return
+	 * @throws OdaException 
+	 */
+	private String[] createTempColumnNames( List<String> aRow ) throws OdaException
+	{
+		String[] tempColumnNames = new String[aRow.size()];
+
+		for ( int i = 0; i < aRow.size(); i++ )
+		{
+			tempColumnNames[i] = "COLUMN_" + ( i + 1 ); //$NON-NLS-1$
+		}
+
+		return tempColumnNames;
+	}
+
+	/**
+	 * Fetch data from a row.
+	 * 
+	 * @param aRow
+	 *            a row read from table
+	 * @return an array of data values for each specified column names from a
+	 *         row. The "specified column names" are obtained from meta data
+	 * @throws OdaException
+	 */
+	private String[] fetchQueriedDataFromRow( List<String> aRow ) throws OdaException
+	{
+		String[] sArray = new String[rsmd.getColumnCount( )];
+		for ( int i = 0; i < sArray.length; i++ )
+		{
+			int location = selectColumIndexes[i];
+			if ( location != -1 )
+			{
+				if ( location >= aRow.size( ) )
+				{
+					if ( conn.trailNullColumns( ) )
+						sArray[i] = null;
+					else
+						throw new OdaException( Messages.getString( "query_INVALID_FLAT_FILE" ) ); //$NON-NLS-1$
+				}
+				else
+				{
+					sArray[i] = aRow.get( location ).toString( );
+				}
+			}
+		}
+		return sArray;
+	}
+
+	/**
+	 * Return the 0-based position of a value in the given array
+	 * 
+	 * @param value
+	 * @param array
+	 * @return
+	 */
+	private int findIndex( String value, HashMap<String, Integer>  originalColumnNameIndexMap)
+	{
+		Integer index = originalColumnNameIndexMap.get( value.trim( ).toUpperCase( ) );
+		if (index == null)
+		{
+			return -1;
+		}
+		else
+		{
+			return index.intValue( );
+		}
+	}
+}
diff --git a/plugins/org.eclipse.datatools.connectivity.oda.flatfile/src/org/eclipse/datatools/connectivity/oda/flatfile/util/querytextutil/ColumnsInfoUtil.java b/plugins/org.eclipse.datatools.connectivity.oda.flatfile/src/org/eclipse/datatools/connectivity/oda/flatfile/util/querytextutil/ColumnsInfoUtil.java
new file mode 100644
index 0000000..39a66d0
--- /dev/null
+++ b/plugins/org.eclipse.datatools.connectivity.oda.flatfile/src/org/eclipse/datatools/connectivity/oda/flatfile/util/querytextutil/ColumnsInfoUtil.java
@@ -0,0 +1,184 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2007 Actuate Corporation.
+ * 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:
+ *  Actuate Corporation - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.datatools.connectivity.oda.flatfile.util.querytextutil;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Utility class for extracting column names, original column names, and column
+ * types from columns information
+ */
+
+public class ColumnsInfoUtil
+{
+
+    private static String EMPTY_STRING = ""; //$NON-NLS-1$
+    
+    private String[] columnNames;
+    private String[] columnTypeNames;
+    private String[] originalColumnNames;
+	/**
+	 * 
+	 * 
+	 */
+	public ColumnsInfoUtil( String columnsInfo )
+	{
+		assert columnsInfo != null;
+		List columnsInfoVector = getColumnsInfoList( columnsInfo );
+		columnNames = new String[columnsInfoVector.size( )];
+		columnTypeNames = new String[columnsInfoVector.size( )];
+		originalColumnNames = new String[columnsInfoVector.size( )];
+		for (int i = 0; i < columnsInfoVector.size( ); i++)
+		{
+			String[] items = (String[]) columnsInfoVector.get( i );
+			columnNames[i] = items[0];
+			originalColumnNames[i] = items[1];
+			columnTypeNames[i] = items[2];
+		}
+	}
+
+	/**
+	 * Extracts the column names from the columsInfo string
+	 * 
+	 * @param columnsInfo
+	 * @return
+	 */
+	public String[] getColumnNames( )
+	{
+		return columnNames;
+	}
+
+	/**
+	 * Extracts the column type names from the columsInfo string
+	 * 
+	 * @param columnsInfo
+	 * @return
+	 */
+	public String[] getColumnTypeNames( )
+	{
+		return columnTypeNames;
+	}
+
+	/**
+	 * Extracts the original column names from the columsInfo string
+	 * 
+	 * @param columnsInfo
+	 * @return
+	 */
+	public String[] getOriginalColumnNames( )
+	{
+		return originalColumnNames;
+	}
+
+	/**
+	 * 
+	 * @param columnsInfo
+	 * @return
+	 */
+	private static List getColumnsInfoList( String columnsInfo )
+	{
+		List columnsInfoList = new ArrayList( );
+		char[] columnsInfoChars = columnsInfo.toCharArray( );
+		boolean isEscaped = false;
+		String[] columnInfo = {
+		        EMPTY_STRING, EMPTY_STRING, EMPTY_STRING
+		};
+		int index = 0;
+
+		for ( int i = 0; i < columnsInfoChars.length; i++ )
+		{
+			if ( columnsInfoChars[i] == '"'
+					|| columnsInfoChars[i] == '|' || columnsInfoChars[i] == ':'
+					|| columnsInfoChars[i] == '<' || columnsInfoChars[i] == '>'
+					|| columnsInfoChars[i] == '?' || columnsInfoChars[i] == '*'
+					|| columnsInfoChars[i] == '{' || columnsInfoChars[i] == '/' )
+			{
+				if ( isEscaped )
+				{
+					columnInfo[index] = columnInfo[index] + columnsInfoChars[i];
+					isEscaped = !isEscaped;
+				}
+			}
+			else if ( columnsInfoChars[i] == '\\' )
+			{
+				if ( isEscaped )
+				{
+					columnInfo[index] = columnInfo[index] + columnsInfoChars[i];
+					isEscaped = !isEscaped;
+				}
+				else
+					isEscaped = !isEscaped;
+			}
+			else if ( columnsInfoChars[i] == ',' )
+			{
+				if ( isEscaped )
+				{
+					columnInfo[index] = columnInfo[index] + columnsInfoChars[i];
+					isEscaped = !isEscaped;
+				}
+				else
+				{
+					index++;
+				}
+			}
+			else if ( columnsInfoChars[i] == ';'
+					|| i == ( columnsInfoChars.length - 1 ) )
+			{
+				if ( isEscaped )
+				{
+					columnInfo[index] = columnInfo[index] + columnsInfoChars[i];
+					isEscaped = !isEscaped;
+				}
+				else
+				{
+
+					if ( i == ( columnsInfoChars.length - 1 ) )
+					{
+						columnInfo[index] = columnInfo[index]
+								+ columnsInfoChars[i];
+
+						columnsInfoList.add( columnInfo );
+					}
+					else
+					{
+						columnsInfoList.add( columnInfo );
+						index = 0;
+						columnInfo = new String[3];
+						columnInfo[0] = columnInfo[1] = columnInfo[2] = EMPTY_STRING;
+					}
+				}
+			}
+			else
+			{
+				columnInfo[index] = columnInfo[index] + columnsInfoChars[i];
+			}
+		}
+
+		return columnsInfoList;
+	}
+
+	/**
+	 * 
+	 * @param charactor
+	 * @return
+	 */
+	public static boolean isColumnsInfoKeyWord( char charactor )
+	{
+		return ( charactor == '"'
+				|| charactor == ';' || charactor == ',' || charactor == '|'
+				|| charactor == '\\' || charactor == '/' || charactor == '<'
+				|| charactor == '>' || charactor == '*' || charactor == ':'
+				|| charactor == '?' || charactor == '{' );
+	}
+
+}
diff --git a/plugins/org.eclipse.datatools.connectivity.oda.flatfile/src/org/eclipse/datatools/connectivity/oda/flatfile/util/querytextutil/QueryTextUtil.java b/plugins/org.eclipse.datatools.connectivity.oda.flatfile/src/org/eclipse/datatools/connectivity/oda/flatfile/util/querytextutil/QueryTextUtil.java
new file mode 100644
index 0000000..83c07e8
--- /dev/null
+++ b/plugins/org.eclipse.datatools.connectivity.oda.flatfile/src/org/eclipse/datatools/connectivity/oda/flatfile/util/querytextutil/QueryTextUtil.java
@@ -0,0 +1,470 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2007 Actuate Corporation.
+ * 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:
+ *  Actuate Corporation - initial API and implementation
+ *  
+ *******************************************************************************/
+
+package org.eclipse.datatools.connectivity.oda.flatfile.util.querytextutil;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Vector;
+
+import org.eclipse.datatools.connectivity.oda.OdaException;
+import org.eclipse.datatools.connectivity.oda.flatfile.CommonConstants;
+import org.eclipse.datatools.connectivity.oda.flatfile.i18n.Messages;
+import org.eclipse.datatools.connectivity.oda.flatfile.util.FlatFileDataReader;
+
+/**
+ * Utility class for splitting query text into query and columns information
+ */
+
+public class QueryTextUtil
+{
+
+	private static final char QUERY_TEXT_DELIMITER = ':';
+
+	private static final char COLUMNSINFO_BEGIN_DELIMITER = '{';
+	
+	private String query;
+	
+	private String columnsInfo;
+
+	/**
+	 * 
+	 */
+	public QueryTextUtil( String queryText ) throws OdaException
+	{
+		assert queryText != null;
+		String[] splits = splitQueryText( queryText );
+		query = splits[0];
+		columnsInfo = splits[1];
+	}
+
+
+	public String getQuery(  )
+	{
+		return query;
+	}
+
+	public String getColumnsInfo(  )
+	{
+		return columnsInfo;
+	}
+
+	/**
+	 * 
+	 */
+	private String[] splitQueryText( String queryText )
+			throws OdaException
+	{
+		int delimiterIndex = -1;
+		int columnsInfoBeginIndex = -1;
+		
+		String trimmedQueryText = queryText.trim( );
+		
+		String[] splittedQueryText = {
+				"", "" //$NON-NLS-1$ //$NON-NLS-2$
+		};
+		boolean inQuote = false;
+		boolean isEscaped = false;
+		boolean isFrom = false;
+		char[] chars = trimmedQueryText.toCharArray( );
+		
+		for ( int i = 0; i < chars.length; i++ )
+		{
+			if ( !isFrom )
+			{
+				if ( !inQuote
+						&& chars[i] == 'f' && i + 3 < chars.length
+						&& chars[i + 1] == 'r' && chars[i + 2] == 'o'
+						&& chars[i + 3] == 'm' )
+				{
+					isFrom = !isFrom;
+					i = i + 3;
+				}
+				if ( chars[i] == '"' )
+				{
+					if ( !isEscaped )
+						inQuote = !inQuote;
+					else
+						isEscaped = !isEscaped;
+				}
+				else if ( chars[i] == '\\' )
+				{
+					isEscaped = !isEscaped;
+				}
+				else if ( ( !inQuote ) && chars[i] == QUERY_TEXT_DELIMITER )
+					delimiterIndex = i;
+				else if ( ( !inQuote )
+						&& chars[i] == COLUMNSINFO_BEGIN_DELIMITER )
+				{
+					columnsInfoBeginIndex = i;
+					break;
+				}
+
+			}
+			else
+			{
+				if ( chars[i] == '"' )
+				{
+					if ( !isEscaped )
+						inQuote = !inQuote;
+					else
+						isEscaped = !isEscaped;
+				}
+				else if ( ( !inQuote ) && chars[i] == QUERY_TEXT_DELIMITER )
+					delimiterIndex = i;
+				else if ( ( !inQuote )
+						&& chars[i] == COLUMNSINFO_BEGIN_DELIMITER )
+				{
+					columnsInfoBeginIndex = i;
+					break;
+				}
+			}
+
+		}
+
+		if ( inQuote )
+			throw new OdaException( Messages.getString( "query_text_error" ) ); //$NON-NLS-1$
+
+		if ( delimiterIndex != -1
+				&& columnsInfoBeginIndex != -1 )
+		{
+			splittedQueryText[0] = trimmedQueryText.substring( 0, delimiterIndex )
+					.trim( );
+			splittedQueryText[1] = trimmedQueryText.substring( columnsInfoBeginIndex + 1,
+					trimmedQueryText.length( )-1 )
+					.trim( );
+		}
+		else if ( delimiterIndex == -1
+				&& columnsInfoBeginIndex == -1 )
+			splittedQueryText[0] = trimmedQueryText;
+		else
+			throw new OdaException( Messages.getString( "query_text_error" ) ); //$NON-NLS-1$
+
+		return splittedQueryText;
+	}
+	
+	/**
+	 * Strip off keyword "SELECT" from the given query.
+	 * 
+	 * @param formattedQuery
+	 *            a trimed query text; cannot be null.
+	 * @return the given text stripped the SELECT keyword
+	 * @throws OdaException
+	 */
+	protected static String stripSELECTKeyword( String formattedQuery )
+			throws OdaException
+	{
+		// This array stores two values: "SELECT" keyword and other part of a
+		// command
+		String[] array = formattedQuery.split( CommonConstants.DELIMITER_SPACE,
+				2 );
+		if ( array == null
+				|| array.length != 2
+				|| !array[0].trim( )
+						.equalsIgnoreCase( CommonConstants.KEYWORD_SELECT ) )
+			throw new OdaException( Messages.getString( "query_COMMAND_NOT_VALID" ) ); //$NON-NLS-1$
+
+		return array[1];
+	}
+
+	/**
+	 * Split the given query fragments before and after the FROM keyword
+	 * 
+	 * @param query
+	 *            Query text without heading SELECT keyword
+	 * @return A String array with two elements: column names (may include alias
+	 *         with the AS keyword), and table names after the FROM clause.
+	 * @throws OdaException
+	 */
+	protected static String[] stripFROMKeyword( String query )
+			throws OdaException
+	{
+		char[] chars = query.toCharArray( );
+		List<Integer> indiceList = new ArrayList<Integer>( );
+		boolean inQuote = false;
+		boolean isEscaped = false;
+		LookAheadMacher matcher = new LookAheadMacher( "FROM ", " ", true );
+		for ( int i = 0; i < chars.length; i++ )
+		{
+			if ( chars[i] == '"' )
+			{
+				if ( !isEscaped )
+					inQuote = !inQuote;
+				else
+					isEscaped = !isEscaped;
+			}
+			else if ( chars[i] == '\\' )
+			{
+				isEscaped = !isEscaped;
+			}
+			else if (inQuote)
+			{
+				continue;
+			}
+			else
+			{
+				if ( matcher.match( chars, i ) )
+				{
+					indiceList.add( i - 1 );
+				}
+			}
+		}
+
+		String[] result = new String[2];
+		if ( indiceList.size( ) > 0 )
+		{
+			int splitInd = indiceList.get( indiceList.size( ) - 1 );
+			result[0] = query.substring( 0, splitInd );
+			result[1] = getUnQuotedName( query.substring( splitInd
+					+ matcher.getPatternLength( ) ) );
+		}
+		else
+			throw new OdaException( Messages.getString( "query_COMMAND_NOT_VALID" ) ); //$NON-NLS-1$
+
+		return result;
+	}
+
+	public static String getQuotedName( String name )
+	{
+		if ( name == null
+				|| name.trim( ).length( ) == 0
+				|| ( name.charAt( 0 ) == '\"' && name.charAt( name.length( ) - 1 ) == '\"' ) )
+			return name;
+
+		StringBuffer sb = new StringBuffer( "\"" ).append( name ).append( "\"" );
+		return sb.toString( );
+	}
+	
+	public static String getUnQuotedName( String name )
+	{
+		if ( name == null || name.length( ) == 0 )
+			return name;
+
+		int head = 0;
+		int end = name.length( );
+		if ( name.charAt( head ) == '\"' )
+			head++;
+		if ( name.charAt( name.length( ) - 1 ) == '\"' )
+			end--;
+
+		return name.substring( head, end );
+	}
+
+	static class LookAheadMacher
+	{
+
+		private String pattern = "";
+		private String heading = "";
+		private boolean caseInsensitive = false;
+
+		LookAheadMacher( String pattern, String heading,
+				boolean caseInsensitive )
+		{
+			this.pattern = pattern;
+			this.heading = heading;
+			this.caseInsensitive = caseInsensitive;
+		}
+
+		int getPatternLength( )
+		{
+			return pattern.length( ) + heading.length( );
+		}
+
+		boolean match( char[] ch, int ind )
+		{
+			boolean first = false;
+			if ( caseInsensitive )
+			{
+				first = Character.toUpperCase( pattern.charAt( 0 ) ) == Character.toUpperCase( ch[ind] );
+			}
+			else
+			{
+				first = pattern.charAt( 0 ) == ch[ind];
+			}
+			
+			if ( !first )
+				return false;
+			
+			return match(String.valueOf( ch ), ind);
+		}
+
+		boolean match( String toMatch, int start )
+		{
+			if ( toMatch == null
+					|| ( toMatch.length( ) - start ) < pattern.length( ) )
+				return false;
+
+			if ( start < heading.length( ) - 1 )
+				return false;
+
+			String to = toMatch.substring( start - heading.length( ), start );
+			if ( caseInsensitive )
+			{
+				if ( !heading.equalsIgnoreCase( to ) )
+					return false;
+			}
+			else if ( !heading.equals( to ) )
+			{
+				return false;
+			}
+
+			to = toMatch.substring( start, start + pattern.length( ) );
+			if ( to.length( ) != pattern.length( ) )
+				return false;
+
+			if ( caseInsensitive )
+			{
+				if ( !pattern.equalsIgnoreCase( to ) )
+					return false;
+			}
+			else if ( !pattern.equals( to ) )
+			{
+					return false;
+			}
+
+			return true;
+		}
+	}
+	
+	/**
+	 * Split the column name from alias, stripping the "AS" keyword, from given
+	 * query fragments.
+	 * 
+	 * @param querySelectAndFromFragments
+	 * @return a String array with three elements: first element contains column
+	 *         names separated by comma, second element contains column
+	 *         aliases(labels) separated by comma, third element contains the
+	 *         table name(s) in FROM clause
+	 */
+	protected static String[] stripASKeyword( String[] querySelectAndFromFragments )
+	{
+		String[] result = new String[3];
+		// store the table name in given last element as the third element
+		result[2] = querySelectAndFromFragments[1];
+
+		// split the columns specified in the SELECT clause
+		String selectedColumns = querySelectAndFromFragments[0];
+		if ( !isWildCard( selectedColumns ) )
+		{
+			String[] columns = FlatFileDataReader.getStringArrayFromList( getQueryColumnNamesVector( selectedColumns ) );
+
+			for ( int i = 0; i < columns.length; i++ )
+			{
+				String[] columnNameAlias = columns[i].split( CommonConstants.DELIMITER_SPACE
+						+ CommonConstants.KEYWORD_AS
+						+ CommonConstants.DELIMITER_SPACE );
+				if ( columnNameAlias != null )
+				{
+					// append column name to comma-separated column names in
+					// result[0]
+					result[0] = ( i == 0 ? columnNameAlias[0] : result[0]
+							+ CommonConstants.DELIMITER_COMMA_VALUE
+							+ columnNameAlias[0].trim( ) );
+
+					// append column alias, if exists, or null to
+					// comma-separated column aliases in result[1]
+					if ( columnNameAlias.length == 2 )
+						result[1] = ( i == 0 ? columnNameAlias[1] : result[1]
+								+ CommonConstants.DELIMITER_COMMA_VALUE
+								+ columnNameAlias[1].trim( ) );
+					else
+						result[1] = ( i == 0 ? null : result[1]
+								+ CommonConstants.DELIMITER_COMMA_VALUE + null );
+				}
+			}
+		}
+		else
+		{
+			result[0] = CommonConstants.KEYWORD_ASTERISK;
+			result[1] = null;
+		}
+
+		return result;
+	}
+	
+	public static String[] getQueryMetaData(String query) throws OdaException
+	{
+		return stripASKeyword(stripFROMKeyword(stripSELECTKeyword(query)));
+	}
+	
+	/**
+	 * @param cCN
+	 * @return
+	 */
+	static boolean isWildCard( String cCN )
+	{
+		if ( cCN.equalsIgnoreCase( CommonConstants.KEYWORD_ASTERISK ) )
+			return true;
+		return false;
+	}
+
+	/**
+	 * 
+	 * @param queryColumnNames
+	 * @return
+	 */
+	static Vector getQueryColumnNamesVector( String queryColumnNames )
+	{
+		Vector result = new Vector( );
+		char[] chars = queryColumnNames.toCharArray( );
+		List indiceList = new ArrayList( );
+		boolean inQuote = false;
+		boolean isEscaped = false;
+		int beginIndex = 0;
+		int endIndex = 0;
+
+		for ( int i = 0; i < chars.length; i++ )
+		{
+			if ( chars[i] == '"' )
+			{
+				if ( !isEscaped )
+					inQuote = !inQuote;
+				else
+					isEscaped = !isEscaped;
+			}
+			else if ( chars[i] == '\\' )
+			{
+				isEscaped = !isEscaped;
+			}
+			else if ( chars[i] == ',' )
+			{
+				if ( inQuote )
+					continue;
+				else
+					indiceList.add( new Integer( i ) );
+			}
+		}
+
+		if ( indiceList.size( ) > 0 )
+		{
+			for ( int j = 0; j < indiceList.size( ); j++ )
+			{
+
+				endIndex = ( (Integer) indiceList.get( j ) ).intValue( );
+
+				result.add( queryColumnNames.substring( beginIndex,
+						endIndex ).trim( ) );
+				beginIndex = endIndex + 1;
+
+				if ( j == indiceList.size( ) - 1 )
+				{
+					result.add( queryColumnNames.substring( beginIndex,
+							queryColumnNames.length( ) ).trim( ) );
+				}
+			}
+		}
+		else
+			result.add( queryColumnNames );
+
+		return result;
+	}
+}
diff --git a/plugins/org.eclipse.datatools.connectivity.oda.flatfile/src/org/eclipse/datatools/connectivity/oda/flatfile/util/querytextutil/package.html b/plugins/org.eclipse.datatools.connectivity.oda.flatfile/src/org/eclipse/datatools/connectivity/oda/flatfile/util/querytextutil/package.html
new file mode 100644
index 0000000..6820666
--- /dev/null
+++ b/plugins/org.eclipse.datatools.connectivity.oda.flatfile/src/org/eclipse/datatools/connectivity/oda/flatfile/util/querytextutil/package.html
@@ -0,0 +1,51 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<html>
+<head>
+<!--
+
+ *************************************************************************
+ * Copyright (c) 2004, 2006 Actuate Corporation.
+ * 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:
+ *  Actuate Corporation - initial API and implementation
+ *  
+ *************************************************************************
+
+-->
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+</head>
+<body bgcolor="white">
+
+<h2>Package Specification</h2>
+The Query-Text utilities serves as parsers that extract infomation from 
+the saved query-text
+<br>
+<br>The standard format of the query text supported is specified below:
+<p>
+<b>SELECT "</b>originalColumn1<b>"</b> [<b>AS</b> alias1] [<b>,"</b>originalColumn2<b>"</b> [<b>AS</b> alias2]]... [<b>,"</b>originalColumnN<b>"</b> [<b>AS</b> aliasN]] <b>FROM</b> tableName</li> 
+	[ <b>: { "</b>columnName1<b>", "</b>originalColumn1<b>"</b><b> ,</b>DataType [<b>;"</b>columnName2<b>","</b>originalColumn2<b>",</b>DataType]... [<b>;"</b>columnNameN<b>", "</b>originalColumnN<b>",</b>DataType]<b>}</b>]
+<br><br>
+<br>An example of the specification above is shown below:
+<br><br>
+<b>SELECT</b> "A", "B" <b>FROM</b> table : {"a","A",STRING; "b","B",DATE}
+<br>
+<ul>
+<li><i>A</i> and <i>B</i> are the original column names specified in the flatfile or
+	<br>generated by the flatfile driver if there is no column name line in flatfile  </li>
+<br><br>
+<li><i>:</i> in the query-text is the delimiter that seperates the query and the 
+ 	<br>columns information, and this <i>:</i> should never be double quoted or escaped by <i>\</i></li>
+<br><br>
+<li>The string between <i>{</i> and <i>}</i> is the saved columns information.
+	<br>The information of all saved columns is separated by a <i>semicolon</i>, 
+	<br>and the information of each column is separated by a <i>comma</i> 
+	<br><i>i.e.</i><i> a</i> is the defined column name of the original column name <i>A</i>,
+	<br>and they all should be double quoted, <i>STRING</i> is the data type of this column</li>
+<br><br>
+<li><b>NOTE:</b> All the delimiters of the query-text: <i><b>:</b></i> , <i><b>;</b></i> , <i><b>{</b></i> , <i><b>}</b></i> 
+should never be double quoted, unless they are part of the columns information or the query</li>
+</ul>
\ No newline at end of file
diff --git a/plugins/org.eclipse.datatools.enablement.oda.ws.ui/.classpath b/plugins/org.eclipse.datatools.enablement.oda.ws.ui/.classpath
new file mode 100644
index 0000000..751c8f2
--- /dev/null
+++ b/plugins/org.eclipse.datatools.enablement.oda.ws.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.enablement.oda.ws.ui/.project b/plugins/org.eclipse.datatools.enablement.oda.ws.ui/.project
new file mode 100644
index 0000000..7685f1b
--- /dev/null
+++ b/plugins/org.eclipse.datatools.enablement.oda.ws.ui/.project
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>org.eclipse.datatools.enablement.oda.ws.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.enablement.oda.ws.ui/META-INF/MANIFEST.MF b/plugins/org.eclipse.datatools.enablement.oda.ws.ui/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..3c4cca0
--- /dev/null
+++ b/plugins/org.eclipse.datatools.enablement.oda.ws.ui/META-INF/MANIFEST.MF
@@ -0,0 +1,19 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: %plugin.name
+Bundle-SymbolicName: org.eclipse.datatools.enablement.oda.ws.ui; singleton:=true
+Bundle-Version: 1.4.1.qualifier
+Bundle-RequiredExecutionEnvironment: JavaSE-1.8
+Bundle-Activator: org.eclipse.datatools.enablement.oda.ws.ui.Activator
+Bundle-Vendor: Eclipse Data Tools Platform
+Bundle-Localization: plugin
+Require-Bundle: org.eclipse.ui,
+ org.eclipse.core.runtime,
+ org.eclipse.datatools.connectivity.oda.design.ui,
+ org.eclipse.datatools.enablement.oda.ws,
+ org.eclipse.datatools.enablement.oda.xml.ui,
+ javax.wsdl,
+ org.apache.xerces;resolution:=optional,
+ org.eclipse.jface.text
+Eclipse-LazyStart: true
+Bundle-ActivationPolicy: lazy
diff --git a/plugins/org.eclipse.datatools.enablement.oda.ws.ui/about.html b/plugins/org.eclipse.datatools.enablement.oda.ws.ui/about.html
new file mode 100644
index 0000000..129db9d
--- /dev/null
+++ b/plugins/org.eclipse.datatools.enablement.oda.ws.ui/about.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"/>
+<title>About</title>
+</head>
+<body lang="EN-US">
+<h2>About This Content</h2>
+ 
+<p>June 15, 2009</p>	
+<h3>License</h3>
+
+<p>The Eclipse Foundation makes available all content in this plug-in (&quot;Content&quot;).  Unless otherwise 
+indicated below, the Content is provided to you under the terms and conditions of the
+Eclipse Public License Version 1.0 (&quot;EPL&quot;).  A copy of the EPL is available 
+at <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a>.
+For purposes of the EPL, &quot;Program&quot; will mean the Content.</p>
+
+<p>If you did not receive this Content directly from the Eclipse Foundation, the Content is 
+being redistributed by another party (&quot;Redistributor&quot;) and different terms and conditions may
+apply to your use of any object code in the Content.  Check the Redistributor's license that was 
+provided with the Content.  If no such license exists, contact the Redistributor.  Unless otherwise
+indicated below, the terms and conditions of the EPL still apply to any source code in the Content
+and such source code may be obtained at <a href="http://www.eclipse.org">http://www.eclipse.org</a>.</p>
+
+</body>
+</html>
\ No newline at end of file
diff --git a/plugins/org.eclipse.datatools.enablement.oda.ws.ui/build.properties b/plugins/org.eclipse.datatools.enablement.oda.ws.ui/build.properties
new file mode 100644
index 0000000..50805ad
--- /dev/null
+++ b/plugins/org.eclipse.datatools.enablement.oda.ws.ui/build.properties
@@ -0,0 +1,21 @@
+###############################################################################
+# Copyright (c) 2007 Actuate Corporation.
+# 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:
+#  Actuate Corporation - initial API and implementation
+#  
+###############################################################################
+source.. = src/
+output.. = bin/
+bin.includes = plugin.xml,\
+               META-INF/,\
+               .,\
+               plugin.properties,\
+               icons/,\
+               about.html,\
+               about_files/
+src.includes = about.html
diff --git a/plugins/org.eclipse.datatools.enablement.oda.ws.ui/icons/datasetpage.ico b/plugins/org.eclipse.datatools.enablement.oda.ws.ui/icons/datasetpage.ico
new file mode 100644
index 0000000..69f4ae1
--- /dev/null
+++ b/plugins/org.eclipse.datatools.enablement.oda.ws.ui/icons/datasetpage.ico
Binary files differ
diff --git a/plugins/org.eclipse.datatools.enablement.oda.ws.ui/icons/new_oda_dswiz.ico b/plugins/org.eclipse.datatools.enablement.oda.ws.ui/icons/new_oda_dswiz.ico
new file mode 100644
index 0000000..ff770b1
--- /dev/null
+++ b/plugins/org.eclipse.datatools.enablement.oda.ws.ui/icons/new_oda_dswiz.ico
Binary files differ
diff --git a/plugins/org.eclipse.datatools.enablement.oda.ws.ui/icons/operation.gif b/plugins/org.eclipse.datatools.enablement.oda.ws.ui/icons/operation.gif
new file mode 100644
index 0000000..93a714d
--- /dev/null
+++ b/plugins/org.eclipse.datatools.enablement.oda.ws.ui/icons/operation.gif
Binary files differ
diff --git a/plugins/org.eclipse.datatools.enablement.oda.ws.ui/icons/port.gif b/plugins/org.eclipse.datatools.enablement.oda.ws.ui/icons/port.gif
new file mode 100644
index 0000000..e426995
--- /dev/null
+++ b/plugins/org.eclipse.datatools.enablement.oda.ws.ui/icons/port.gif
Binary files differ
diff --git a/plugins/org.eclipse.datatools.enablement.oda.ws.ui/icons/profile.gif b/plugins/org.eclipse.datatools.enablement.oda.ws.ui/icons/profile.gif
new file mode 100644
index 0000000..6b86d07
--- /dev/null
+++ b/plugins/org.eclipse.datatools.enablement.oda.ws.ui/icons/profile.gif
Binary files differ
diff --git a/plugins/org.eclipse.datatools.enablement.oda.ws.ui/icons/service.gif b/plugins/org.eclipse.datatools.enablement.oda.ws.ui/icons/service.gif
new file mode 100644
index 0000000..623e2ba
--- /dev/null
+++ b/plugins/org.eclipse.datatools.enablement.oda.ws.ui/icons/service.gif
Binary files differ
diff --git a/plugins/org.eclipse.datatools.enablement.oda.ws.ui/icons/wsdl.gif b/plugins/org.eclipse.datatools.enablement.oda.ws.ui/icons/wsdl.gif
new file mode 100644
index 0000000..bd7b6d3
--- /dev/null
+++ b/plugins/org.eclipse.datatools.enablement.oda.ws.ui/icons/wsdl.gif
Binary files differ
diff --git a/plugins/org.eclipse.datatools.enablement.oda.ws.ui/plugin.properties b/plugins/org.eclipse.datatools.enablement.oda.ws.ui/plugin.properties
new file mode 100644
index 0000000..19ffe73
--- /dev/null
+++ b/plugins/org.eclipse.datatools.enablement.oda.ws.ui/plugin.properties
@@ -0,0 +1,35 @@
+###############################################################################
+# Copyright (c) 2007 Actuate Corporation.
+# 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:
+#  Actuate Corporation - initial API and implementation
+#
+###############################################################################
+# Plug-in Configuration
+#
+oda.data.source.id=org.eclipse.datatools.enablement.oda.ws
+#
+###############################################################################
+# NLS strings
+#
+plugin.name=Eclipse Data Tools Platform Web Services ODA Designer
+data.source.name=Web Services Data Source
+connection.profile.name=Web Services Data Source Connection Profile
+newwizard.name=Web Services Data Source
+newwizard.description=Create a Web Services data source connection profile
+wizard.window.title=New Web Services Data Source Profile
+wizard.data.source.page.title=Web Services Data Source
+profile.propertypage.name=Web Services Data Source Connection Properties
+wizard.data.set.window.title=New Web Services Data Set
+wizard.data.set.page.title=Query
+
+oda.ws.operation=WSDL Operation
+oda.ws.soapparameters=SOAP Parameters
+oda.ws.soaprequest=SOAP Request
+oda.ws.soapresponse=SOAP Response
+oda.ws.tablemapping=Row Mapping
+oda.ws.columnmapping=Column Mapping
\ No newline at end of file
diff --git a/plugins/org.eclipse.datatools.enablement.oda.ws.ui/plugin.xml b/plugins/org.eclipse.datatools.enablement.oda.ws.ui/plugin.xml
new file mode 100644
index 0000000..3e6b6c7
--- /dev/null
+++ b/plugins/org.eclipse.datatools.enablement.oda.ws.ui/plugin.xml
@@ -0,0 +1,92 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<?eclipse version="3.2"?>
+<plugin>
+   <extension
+         point="org.eclipse.datatools.connectivity.oda.design.ui.dataSource">
+      <dataSourceUI
+            id="%oda.data.source.id">
+         <newDataSourceWizard
+               pageClass="org.eclipse.datatools.enablement.oda.ws.ui.wizards.WebServiceSelectionPage"
+               includesProgressMonitor="false"
+               pageTitle="%wizard.data.source.page.title"
+               windowTitle="%wizard.window.title">
+         </newDataSourceWizard>
+      </dataSourceUI>
+      <dataSetUI
+            supportsOutParameters="false"
+            supportsInParameters="true"
+            initialPageId="org.eclipse.datatools.enablement.oda.ws.ui.OperationPage"
+            id="org.eclipse.datatools.enablement.oda.ws.dataSet">
+         <dataSetWizard
+               class="org.eclipse.datatools.enablement.oda.ws.ui.wizards.SOAPDataSetWizard"
+               windowTitle="%wizard.data.set.window.title">
+         </dataSetWizard>
+         <dataSetPage
+               displayName="%oda.ws.operation"
+               id="org.eclipse.datatools.enablement.oda.ws.ui.OperationPage"
+               wizardPageClass="org.eclipse.datatools.enablement.oda.ws.ui.wizards.OperationPage">
+         </dataSetPage>
+         <dataSetPage
+               displayName="%oda.ws.soapparameters"
+               id="org.eclipse.datatools.enablement.oda.ws.ui.SOAPParametersPage"
+               wizardPageClass="org.eclipse.datatools.enablement.oda.ws.ui.wizards.SOAPParametersPage">
+         </dataSetPage>
+         <dataSetPage
+               displayName="%oda.ws.soaprequest"
+               id="org.eclipse.datatools.enablement.oda.ws.ui.SOAPRequestPage"
+               wizardPageClass="org.eclipse.datatools.enablement.oda.ws.ui.wizards.SOAPRequestPage">
+         </dataSetPage>
+         <dataSetPage
+               displayName="%oda.ws.soapresponse"
+               id="org.eclipse.datatools.enablement.oda.ws.ui.SOAPResponsePage"
+               wizardPageClass="org.eclipse.datatools.enablement.oda.ws.ui.wizards.SOAPResponsePage">
+         </dataSetPage>
+         <dataSetPage
+               displayName="%oda.ws.tablemapping"
+               id="org.eclipse.datatools.enablement.oda.ws.ui.XMLTableMappingPage"
+               wizardPageClass="org.eclipse.datatools.enablement.oda.ws.ui.wizards.XMLTableMappingPage">
+         </dataSetPage>
+         <dataSetPage
+               displayName="%oda.ws.columnmapping"
+               id="org.eclipse.datatools.enablement.oda.ws.ui.XMLColumnMappingPage"
+               wizardPageClass="org.eclipse.datatools.enablement.oda.ws.ui.wizards.XMLColumnMappingPage">
+         </dataSetPage>
+      </dataSetUI>
+   </extension>
+
+   <extension
+         point="org.eclipse.datatools.connectivity.connectionProfile">
+		<newWizard
+            id="%oda.data.source.id"
+            name="%newwizard.name"
+            class="org.eclipse.datatools.connectivity.oda.design.ui.wizards.NewDataSourceWizard"
+            description="%newwizard.description"
+            icon="icons/new_oda_dswiz.ico"
+            profile="%oda.data.source.id"/>
+   </extension>
+   <extension
+         point="org.eclipse.datatools.connectivity.ui.connectionProfileImage">
+      <profileImage
+            profileID="%oda.data.source.id"
+            icon="icons/profile.gif">
+      </profileImage>
+   </extension>
+   <extension
+         point="org.eclipse.ui.propertyPages">
+      <page
+            name="%profile.propertypage.name"
+            class="org.eclipse.datatools.enablement.oda.ws.ui.wizards.WebServicePropertyPage"
+            id="%oda.data.source.id">
+         <enabledWhen>
+            <instanceof
+                  value="org.eclipse.datatools.connectivity.IConnectionProfile">
+            </instanceof>
+         </enabledWhen>
+         <filter
+               name="org.eclipse.datatools.profile.property.id"
+               value="%oda.data.source.id">
+         </filter>
+      </page>
+   </extension>
+
+</plugin>
diff --git a/plugins/org.eclipse.datatools.enablement.oda.ws.ui/src/org/eclipse/datatools/enablement/oda/ws/ui/Activator.java b/plugins/org.eclipse.datatools.enablement.oda.ws.ui/src/org/eclipse/datatools/enablement/oda/ws/ui/Activator.java
new file mode 100644
index 0000000..d27331c
--- /dev/null
+++ b/plugins/org.eclipse.datatools.enablement.oda.ws.ui/src/org/eclipse/datatools/enablement/oda/ws/ui/Activator.java
@@ -0,0 +1,113 @@
+/*
+ ******************************************************************************
+ * Copyright (c) 2007 Actuate Corporation.
+ * 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:
+ *  Actuate Corporation - initial API and implementation
+ *  
+ ******************************************************************************
+ */
+
+package org.eclipse.datatools.enablement.oda.ws.ui;
+
+import java.net.MalformedURLException;
+import java.net.URL;
+
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.ui.plugin.AbstractUIPlugin;
+import org.osgi.framework.BundleContext;
+
+/**
+ * The activator class controls the plug-in life cycle
+ */
+public class Activator extends AbstractUIPlugin {
+
+	// The plug-in ID
+	public static final String PLUGIN_ID = "org.eclipse.datatools.enablement.oda.ws.ui"; //$NON-NLS-1$
+
+	// The shared instance
+	private static Activator plugin;
+	
+	public static final String ICONS_PATH = "icons/";//$NON-NLS-1$
+	public static final String ICON_WSDL = "iconWSDL";//$NON-NLS-1$
+	public static final String ICON_SERVICE = "iconService";//$NON-NLS-1$
+	public static final String ICON_PORT = "iconPort";//$NON-NLS-1$
+	public static final String ICON_OPERATION = "iconOpeartion";//$NON-NLS-1$
+	
+	/**
+	 * The constructor
+	 */
+	public Activator() {
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * @see org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework.BundleContext)
+	 */
+	public void start(BundleContext context) throws Exception {
+		super.start(context);
+		plugin = this;
+		declareImages( );
+	}
+	
+	private void declareImages( )
+	{
+		declareImage( ICON_WSDL, ICONS_PATH + "wsdl.gif" ); //$NON-NLS-1$
+		declareImage( ICON_SERVICE, ICONS_PATH + "service.gif" ); //$NON-NLS-1$
+		declareImage( ICON_PORT, ICONS_PATH + "port.gif" ); //$NON-NLS-1$
+		declareImage( ICON_OPERATION, ICONS_PATH + "operation.gif" );//$NON-NLS-1$
+	}
+
+	private void declareImage( String key, String path )
+	{
+		URL url = null;
+		try
+		{
+			url = new URL( Activator.getDefault( ).getBundle( ).getEntry( "/" ), //$NON-NLS-1$
+					path );
+		}
+		catch ( MalformedURLException e )
+		{
+		}
+		ImageDescriptor desc = ImageDescriptor.createFromURL( url );
+		declareImage( key, desc );
+	}
+
+	private void declareImage( String symbolicName, ImageDescriptor descriptor )
+	{
+		getImageRegistry( ).put( symbolicName, descriptor );
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * @see org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext)
+	 */
+	public void stop(BundleContext context) throws Exception {
+		plugin = null;
+		super.stop(context);
+	}
+
+	/**
+	 * Returns the shared instance
+	 *
+	 * @return the shared instance
+	 */
+	public static Activator getDefault() {
+		return plugin;
+	}
+
+	/**
+	 * Returns an image descriptor for the image file at the given
+	 * plug-in relative path
+	 *
+	 * @param path the path
+	 * @return the image descriptor
+	 */
+	public static ImageDescriptor getImageDescriptor(String path) {
+		return imageDescriptorFromPlugin(PLUGIN_ID, path);
+	}
+}
diff --git a/plugins/org.eclipse.datatools.enablement.oda.ws.ui/src/org/eclipse/datatools/enablement/oda/ws/ui/i18n/Messages.java b/plugins/org.eclipse.datatools.enablement.oda.ws.ui/src/org/eclipse/datatools/enablement/oda/ws/ui/i18n/Messages.java
new file mode 100644
index 0000000..cd3f022
--- /dev/null
+++ b/plugins/org.eclipse.datatools.enablement.oda.ws.ui/src/org/eclipse/datatools/enablement/oda/ws/ui/i18n/Messages.java
@@ -0,0 +1,51 @@
+
+/*******************************************************************************
+ * Copyright (c) 2007 Actuate Corporation.
+ * 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:
+ *  Actuate Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.datatools.enablement.oda.ws.ui.i18n;
+
+import java.text.MessageFormat;
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
+
+/**
+ * 
+ */
+
+public class Messages
+{
+
+	private static final String BUNDLE_NAME = "org.eclipse.datatools.enablement.oda.ws.ui.i18n.messages"; //$NON-NLS-1$
+
+	private static final ResourceBundle RESOURCE_BUNDLE = ResourceBundle.getBundle( BUNDLE_NAME );
+
+	private Messages( )
+	{
+	}
+
+	public static String getString( String key )
+	{
+		// TODO Auto-generated method stub
+		try
+		{
+			return RESOURCE_BUNDLE.getString( key );
+		}
+		catch ( MissingResourceException e )
+		{
+			return '!' + key + '!';
+		}
+	}
+
+	public static String getFormattedString( String key, Object[] arguments )
+	{
+		return MessageFormat.format( getString( key ), arguments );
+	}
+
+}
diff --git a/plugins/org.eclipse.datatools.enablement.oda.ws.ui/src/org/eclipse/datatools/enablement/oda/ws/ui/i18n/messages.properties b/plugins/org.eclipse.datatools.enablement.oda.ws.ui/src/org/eclipse/datatools/enablement/oda/ws/ui/i18n/messages.properties
new file mode 100644
index 0000000..9c4cb9a
--- /dev/null
+++ b/plugins/org.eclipse.datatools.enablement.oda.ws.ui/src/org/eclipse/datatools/enablement/oda/ws/ui/i18n/messages.properties
@@ -0,0 +1,82 @@
+#
+#************************************************************************
+# Copyright (c) 2007 Actuate Corporation.
+# 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:
+#  Actuate Corporation - initial API and implementation
+#  
+#************************************************************************
+#
+# Externalized messages of the Web Services Data Source Designer
+
+#page.type.name
+
+# Common
+
+# WebServiceSelectionPage
+webServiceSelectionPage.message.default=Web Services Data Source
+webServiceSelectionPage.message.error=Specify the SOAP End Point URL or Select a WSDL Descriptor.
+webServiceSelectionPage.group.wsdl=WSDL Descriptor
+webServiceSelectionPage.group.endPoint=&SOAP End Point
+webServiceSelectionPage.group.customClass=&Custom Driver Class
+webServiceSelectionPage.group.classPath=&Driver Class Path
+webServiceSelectionPage.label.wsdl=If the WSDL descriptor of the Web Services is available, enter its URL or browse to its location in the local file system.
+webServiceSelectionPage.label.wsdlURI=&WSDL URL or Location:
+webServiceSelectionPage.label.endPoint=Specify the SOAP End Point URL. You may omit this value if the end point defined in the WSDL is to be used,\nor if you are using a custom connection class that does not require a end point URL.
+webServiceSelectionPage.label.customClass=If connection and query to the Web Services is made through a custom Java class, enter the fully qualified class name here.
+webServiceSelectionPage.label.classPath=A semicolon(;)-separated list of additional JAR files and directories to search for the custom driver class.
+webServiceSelectionPage.button.browse=B&rowse...
+
+# OperationPage
+operationPage.message.default=Select an operation defined in the data source's WSDL descriptor.
+operationPage.message.regenerate.SOAPRequest=Regenerate the SOAP request and reconnect the End Point according to the changed operation.
+operationPage.title.operationChanged=Operation Changed
+operationPage.label.selectOpearation=&Selected Operation
+operationPage.label.document=&Documentation
+
+# SoapParametersPage
+soapParametersPage.message.default=Enter the parameters of chosen WSDL operation.
+soapParametersPage.button.selectAll=&Select All
+soapParametersPage.button.deselectAll=&Deselect All
+soapParametersPage.column.paramName=N&ame
+soapParametersPage.column.dataType=Data &Type
+
+# SoapRequestPage
+soapRequestPage.message.defaultTitle=Edit the SOAP request template of this data set. 
+soapRequestPage.message.regenerateTemplate=This will regenerate the query text template based on the SOAP operation you have selected. It will remove any modifications you have made to the text.\n\nAre you sure?
+soapRequestPage.label.prompt=You may leave the text empty if your custom connection class does not require a query text.
+soapRequestPage.title.regenerateTemplate=Regenerate Template
+soapRequestPage.button.regenerateTemplate=&Regenerate Template
+soapRequestPage.button.insertParameter=&Edit Parameter...
+soapRequestPage.button.clear=&Clear
+soapRequestPage.paramEditDialog.title=Edit parameter property
+
+# ParameterInputDialog
+parameterInputDialog.column.name=&Name
+parameterInputDialog.column.type=Data &Type
+parameterInputDialog.column.defaultValue=Default &Value
+parameterInputDialog.button.edit=&Edit...
+
+# SoapResponsePage
+soapResponsePage.message.default=Edit the SOAP response.
+soapResponsePage.group.schema=Select SOAP Response Schema.
+soapResponsePage.group.xml=Select Sample SOAP response message.
+soapResponsePage.radio.defaultSchema=Use &operation response schema defined in data source WSDL.
+soapResponsePage.radio.reponseSchema=Use schema from &response.
+soapResponsePage.radio.externalSchema=Use external &XML schema file:
+soapResponsePage.radio.endPoint=Query Web Services at SOAP &end point:
+soapResponsePage.radio.externalXML=Use external sample &data file
+soapResponsePage.button.browse1=Bro&wse...
+soapResponsePage.button.browse2=Brow&se...
+soapResponsePage.button.connect=&Connect Now
+
+# XMLTableMappingPage
+
+# XMLColumnMappingPage
+
+# WSConsole
+wsConsole.message.error.cantRetrieveSOAPResponse=SOAP response can't be retrieved, please verify the network or SOAP Response setting.
\ No newline at end of file
diff --git a/plugins/org.eclipse.datatools.enablement.oda.ws.ui/src/org/eclipse/datatools/enablement/oda/ws/ui/util/Constants.java b/plugins/org.eclipse.datatools.enablement.oda.ws.ui/src/org/eclipse/datatools/enablement/oda/ws/ui/util/Constants.java
new file mode 100644
index 0000000..98326ff
--- /dev/null
+++ b/plugins/org.eclipse.datatools.enablement.oda.ws.ui/src/org/eclipse/datatools/enablement/oda/ws/ui/util/Constants.java
@@ -0,0 +1,34 @@
+/*******************************************************************************
+ * Copyright (c) 2007 Actuate Corporation.
+ * 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:
+ *  Actuate Corporation - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.datatools.enablement.oda.ws.ui.util;
+
+/**
+ * 
+ */
+
+public class Constants
+		extends
+			org.eclipse.datatools.enablement.oda.ws.util.Constants
+{
+
+	public static String DELIMITER_OPEARTION = "$-$";//$NON-NLS-1$
+
+	// xml usage
+	public static final String CONST_PROP_FILELIST = org.eclipse.datatools.enablement.oda.xml.Constants.CONST_PROP_FILELIST;
+	public static final String CONST_PROP_SCHEMA_FILELIST = org.eclipse.datatools.enablement.oda.xml.Constants.CONST_PROP_SCHEMA_FILELIST;
+	public static final String CONST_PROP_RELATIONINFORMATION = org.eclipse.datatools.enablement.oda.xml.Constants.CONST_PROP_RELATIONINFORMATION;
+	public static final String CONST_PROP_XPATH = org.eclipse.datatools.enablement.oda.xml.Constants.CONST_PROP_XPATH;
+	public static final String CONST_PROP_TABLE_NAME = org.eclipse.datatools.enablement.oda.xml.Constants.CONST_PROP_TABLE_NAME;
+	public static final String CONST_PROP_MAX_ROW = org.eclipse.datatools.enablement.oda.xml.Constants.CONST_PROP_MAX_ROW;
+	public static final String CONST_PROP_SAMPLE_XML = org.eclipse.datatools.enablement.oda.xml.Constants.CONST_PROP_XML_FILE;
+
+}
diff --git a/plugins/org.eclipse.datatools.enablement.oda.ws.ui/src/org/eclipse/datatools/enablement/oda/ws/ui/util/IHelpConstants.java b/plugins/org.eclipse.datatools.enablement.oda.ws.ui/src/org/eclipse/datatools/enablement/oda/ws/ui/util/IHelpConstants.java
new file mode 100644
index 0000000..33b328d
--- /dev/null
+++ b/plugins/org.eclipse.datatools.enablement.oda.ws.ui/src/org/eclipse/datatools/enablement/oda/ws/ui/util/IHelpConstants.java
@@ -0,0 +1,43 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2008 Actuate Corporation.
+ * 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:
+ *  Actuate Corporation - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.datatools.enablement.oda.ws.ui.util;
+
+/**
+ * 
+ */
+
+public interface IHelpConstants
+{
+
+	public static final String PREFIX = "org.eclipse.datatools.oda.cshelp" + "."; //$NON-NLS-1$ //$NON-NLS-2$
+
+	public static final String CONEXT_ID_WS_OPERATION = PREFIX
+			+ "Wizard_WS_OPERATION_ID";//$NON-NLS-1$
+
+	public static final String CONEXT_ID_WS_SOAP_PARAMETER = PREFIX
+			+ "Wizard_WS_SOAP_PARAMETER_ID";//$NON-NLS-1$
+
+	public static final String CONEXT_ID_WS_SOAP_REQUEST = PREFIX
+			+ "Wizard_WS_SOAP_REQUEST_ID";//$NON-NLS-1$
+
+	public static final String CONEXT_ID_WS_SOAP_RESPONSE = PREFIX
+			+ "Wizard_WS_SOAP_RESPONSE_ID";//$NON-NLS-1$
+
+	public static final String CONEXT_ID_WS_DATASOURCE = PREFIX
+			+ "Wizard_WS_DATASOURCE_ID";//$NON-NLS-1$
+	
+	public static final String CONEXT_ID_WS_SOAP_REQUEST_PARMETER = PREFIX
+			+ "Dialog_SOAP_Request_Parameters_ID";//$NON-NLS-1$
+	
+	public static final String CONEXT_ID_WS_SOAP_REQUEST_PARMETER_PROPERTIES = PREFIX
+			+ "Dialog_SOAP_Request_Parameter_Properties_ID";//$NON-NLS-1$
+}
diff --git a/plugins/org.eclipse.datatools.enablement.oda.ws.ui/src/org/eclipse/datatools/enablement/oda/ws/ui/util/WSConsole.java b/plugins/org.eclipse.datatools.enablement.oda.ws.ui/src/org/eclipse/datatools/enablement/oda/ws/ui/util/WSConsole.java
new file mode 100644
index 0000000..cf4fddf
--- /dev/null
+++ b/plugins/org.eclipse.datatools.enablement.oda.ws.ui/src/org/eclipse/datatools/enablement/oda/ws/ui/util/WSConsole.java
@@ -0,0 +1,824 @@
+/*******************************************************************************
+ * Copyright (c) 2007 Actuate Corporation.
+ * 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:
+ *  Actuate Corporation - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.datatools.enablement.oda.ws.ui.util;
+
+import java.io.BufferedInputStream;
+import java.io.ByteArrayInputStream;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Properties;
+
+import org.eclipse.datatools.connectivity.oda.OdaException;
+import org.eclipse.datatools.connectivity.oda.design.DataSetDesign;
+import org.eclipse.datatools.connectivity.oda.design.DataSetParameters;
+import org.eclipse.datatools.connectivity.oda.design.DataSourceDesign;
+import org.eclipse.datatools.connectivity.oda.design.ParameterDefinition;
+import org.eclipse.datatools.connectivity.oda.design.ui.designsession.DesignSessionUtil;
+import org.eclipse.datatools.enablement.oda.ws.soap.SOAPParameter;
+import org.eclipse.datatools.enablement.oda.ws.soap.SOAPRequest;
+import org.eclipse.datatools.enablement.oda.ws.soap.SOAPResponse;
+import org.eclipse.datatools.enablement.oda.ws.ui.i18n.Messages;
+import org.eclipse.datatools.enablement.oda.ws.util.Java2SOAPManager;
+import org.eclipse.datatools.enablement.oda.ws.util.PropertyValueUtil;
+import org.eclipse.datatools.enablement.oda.ws.util.RawMessageSender;
+import org.eclipse.datatools.enablement.oda.ws.util.WSDLAdvisor;
+import org.eclipse.datatools.enablement.oda.ws.util.WSUtil;
+import org.eclipse.datatools.enablement.oda.xml.ui.utils.XMLRelationInfoUtil;
+import org.eclipse.datatools.enablement.oda.xml.ui.wizards.XMLInformationHolder;
+import org.eclipse.emf.common.util.EList;
+
+/**
+ * A utility class to handle ws design-time model which involves some properties
+ * and util methods.
+ * 
+ * standard case-scenario: initial: design->model->page
+ * intermedial:canLeave/getNextPage(refresh) page->model final:model->design
+ */
+
+public class WSConsole
+{
+
+	private static String XML_TEMP_FILE = "xmlTempFile";// //$NON-NLS-1$
+	private static WSConsole instance;
+
+	private Properties props;
+	private SOAPParameter[] parameters;
+	private boolean isSessionOK = false;
+	private static final int BACKWARD = 0;
+	private static final int FORWARD = 1;
+	
+	private boolean needsRefreshTempFile = false;
+
+	private File templateFile, sampleXMLFile;
+
+	/**
+	 * 
+	 * @return
+	 */
+	public static synchronized WSConsole getInstance( )
+	{
+		if ( instance == null )
+			instance = new WSConsole( );
+
+		return instance;
+	}
+
+	/**
+	 * 
+	 * @param key
+	 * @return
+	 */
+	public String getPropertyValue( String key )
+	{
+		if ( props == null )
+			return null;
+
+		return props.getProperty( key );
+	}
+
+	/**
+	 * 
+	 * @param key
+	 * @param value
+	 */
+	public void setPropertyValue( String key, String value )
+	{
+		if ( props == null )
+			props = new Properties( );;
+
+		if ( value != null )
+			props.setProperty( key, value );
+
+	}
+
+	/**
+	 * 
+	 * @param key
+	 * @return
+	 */
+	public String getXMLPropertyValue( String key )
+	{
+		return XMLInformationHolder.getPropertyValue( key );
+	}
+
+	/**
+	 * 
+	 * @param key
+	 * @param value
+	 */
+	public void setXMLPropertyValue( String key, String value )
+	{
+		XMLInformationHolder.setPropertyValue( key, value );
+	}
+
+	/**
+	 * Populates all the required properties available in dataSetDesign
+	 * 
+	 * @param dataSetDesign
+	 */
+	public void start( DataSetDesign dataSetDesign )
+	{
+		if ( dataSetDesign == null )
+			return;
+
+		startWS( dataSetDesign );
+		startXML( dataSetDesign );
+		isSessionOK = true;
+		needsRefreshTempFile = false;
+	}
+
+	private void startWS( DataSetDesign dataSetDesign )
+	{
+		String queryText = dataSetDesign.getQueryText( );
+		if ( queryText != null && queryText.trim( ).length( ) > 0 )
+		{
+			setPropertyValue( Constants.WS_QUERYTEXT, queryText );
+		}
+		DataSetParameters params = dataSetDesign.getParameters( );
+		if ( params != null )
+		{
+			initSOAPParameters( params );
+		}
+		if ( dataSetDesign.getPublicProperties( ) != null )
+		{
+			String value = dataSetDesign.getPublicProperties( )
+					.getProperty( Constants.XML_FILE_URI );
+			String xmlFileURI = PropertyValueUtil.getQualifiedValueForDataSet( value,
+					Constants.XML_FILE_URI,
+					dataSetDesign.getOdaExtensionDataSetId( ) );
+			setPropertyValue( Constants.XML_FILE_URI, xmlFileURI );
+
+			value = dataSetDesign.getPublicProperties( )
+					.getProperty( Constants.XSD_FILE_URI );
+			String xsdFileURI = PropertyValueUtil.getQualifiedValueForDataSet( value,
+					Constants.XSD_FILE_URI,
+					dataSetDesign.getOdaExtensionDataSetId( ) );
+			setPropertyValue( Constants.XSD_FILE_URI, xsdFileURI );
+		}
+		if ( dataSetDesign.getPrivateProperties( ) != null )
+		{
+			String value = dataSetDesign.getPrivateProperties().getProperty(
+					Constants.XML_FILE_URI);
+			String xmlFileURI = PropertyValueUtil.getQualifiedValueForDataSet(
+					value, Constants.XML_FILE_URI, dataSetDesign
+							.getOdaExtensionDataSetId());
+			if( xmlFileURI != null )
+				setPropertyValue(Constants.XML_FILE_URI, xmlFileURI);
+
+			value = dataSetDesign.getPrivateProperties().getProperty(
+					Constants.XSD_FILE_URI);
+			String xsdFileURI = PropertyValueUtil.getQualifiedValueForDataSet(
+					value, Constants.XSD_FILE_URI, dataSetDesign
+							.getOdaExtensionDataSetId());
+			if( xsdFileURI != null )
+				setPropertyValue(Constants.XSD_FILE_URI, xsdFileURI);
+	
+			value = dataSetDesign.getPrivateProperties( )
+					.getProperty( Constants.OPERATION_TRACE );
+			String operationTrace = PropertyValueUtil.getQualifiedValueForDataSet( value,
+					Constants.OPERATION_TRACE,
+					dataSetDesign.getOdaExtensionDataSetId( ) );
+			setPropertyValue( Constants.OPERATION_TRACE, operationTrace );
+
+			value = dataSetDesign.getPrivateProperties( )
+					.getProperty( Constants.XML_QUERYTEXT );
+			String xmlQueryText = PropertyValueUtil.getQualifiedValueForDataSet( value,
+					Constants.XML_QUERYTEXT,
+					dataSetDesign.getOdaExtensionDataSetId( ) );
+			setPropertyValue( Constants.XML_QUERYTEXT, xmlQueryText );
+		}
+		if ( dataSetDesign.getDataSourceDesign( ) != null )
+		{
+			DataSourceDesign dataSourceDesign = dataSetDesign.getDataSourceDesign( );
+			java.util.Properties props = null;
+			try
+			{
+				props = DesignSessionUtil.getEffectiveDataSourceProperties( dataSourceDesign );
+			}
+			catch ( OdaException e )
+			{
+				props = new java.util.Properties( );
+			}
+
+			String value = props.getProperty( Constants.SOAP_ENDPOINT );
+			String soapEndPoint = PropertyValueUtil.getQualifiedValueForDataSource( value,
+					Constants.SOAP_ENDPOINT );
+			setPropertyValue( Constants.SOAP_ENDPOINT, soapEndPoint );
+
+			value = props.getProperty( Constants.CUSTOM_CONNECTION_CLASS );
+			String customConnectionClass = PropertyValueUtil.getQualifiedValueForDataSource( value,
+					Constants.CUSTOM_CONNECTION_CLASS );
+			setPropertyValue( Constants.CUSTOM_CONNECTION_CLASS,
+						customConnectionClass );
+
+			value = props.getProperty( Constants.CUSTOM_DRIVER_CLASS_PATH );
+			String customDriverPath = PropertyValueUtil.getQualifiedValueForDataSource( value,
+					Constants.CUSTOM_DRIVER_CLASS_PATH );
+			setPropertyValue( Constants.CUSTOM_DRIVER_CLASS_PATH,
+						customDriverPath );
+
+			value = props.getProperty( Constants.CONNECTION_TIMEOUT );
+			String connectionTimeOut = PropertyValueUtil.getQualifiedValueForDataSource( value,
+					Constants.CUSTOM_DRIVER_CLASS_PATH );
+			setPropertyValue( Constants.CONNECTION_TIMEOUT,
+						connectionTimeOut );
+			
+			value = props.getProperty( Constants.WSDL_URI );
+			String wsdlURI = PropertyValueUtil.getQualifiedValueForDataSource( value,
+					Constants.WSDL_URI );
+			setPropertyValue( Constants.WSDL_URI, wsdlURI );
+		}
+	}
+
+	private void startXML( DataSetDesign dataSetDesign )
+	{
+		if ( dataSetDesign.getPrivateProperties( ) != null )
+		{
+			String queryText = dataSetDesign.getPrivateProperties( )
+					.findProperty( Constants.XML_QUERYTEXT )
+					.getValue( );
+
+			if ( queryText != null && queryText.trim( ).length( ) > 0 )
+			{
+				setXMLPropertyValue( Constants.CONST_PROP_RELATIONINFORMATION,
+						queryText );
+				String tableName = XMLRelationInfoUtil.getTableName( queryText );
+				setXMLPropertyValue( Constants.CONST_PROP_TABLE_NAME, tableName );
+
+				String xpath = XMLRelationInfoUtil.getXPathExpression( queryText,
+						tableName );
+				setXMLPropertyValue( Constants.CONST_PROP_XPATH, xpath );
+			}
+		}
+		if ( dataSetDesign.getPublicProperties( ) != null )
+		{
+			String xmlFile = dataSetDesign.getPublicProperties( )
+					.getProperty( Constants.XML_FILE_URI );
+			setXMLPropertyValue( Constants.CONST_PROP_FILELIST, xmlFile == null
+					? WSUtil.EMPTY_STRING : xmlFile );
+
+			String schema = dataSetDesign.getPublicProperties( )
+					.getProperty( Constants.XSD_FILE_URI );
+			setXMLPropertyValue( Constants.CONST_PROP_SCHEMA_FILELIST,
+					schema == null ? WSUtil.EMPTY_STRING : schema );
+		}
+
+		setXMLPropertyValue( Constants.CONST_PROP_MAX_ROW, "-1" ); //$NON-NLS-1$
+	}
+
+	/**
+	 * 
+	 */
+	public void end( )
+	{
+		instance = null;
+	}
+
+	/**
+	 * 
+	 */
+	public void terminateSession( )
+	{
+		isSessionOK = false;
+		props = null;
+		parameters = null;
+		if ( sampleXMLFile != null && !sampleXMLFile.delete( ) )
+		{
+			sampleXMLFile.deleteOnExit( );
+		}
+		if ( templateFile != null && !templateFile.delete( ) )
+		{
+			templateFile.deleteOnExit( );
+		}
+		XMLInformationHolder.destory( );
+	}
+
+	/**
+	 * 
+	 * @return
+	 */
+	public boolean isSessionOK( )
+	{
+		return isSessionOK;
+	}
+
+	/**
+	 * 
+	 * @return
+	 */
+	public SOAPParameter[] getParameters( )
+	{
+		return parameters;
+	}
+
+	/**
+	 * 
+	 * @param soapParameters
+	 */
+	public void setParameters( SOAPParameter[] soapParameters )
+	{
+		this.parameters = soapParameters;
+	}
+
+	/**
+	 * 
+	 * @param soapParameters
+	 */
+	public void updateParameters( SOAPParameter[] soapParameters )
+	{
+		parameters = soapParameters;
+//		if( parameters == null || soapParameters == null || parameters.length == soapParameters.length )
+//		{
+//			parameters = soapParameters;
+//			return;
+//		}
+//		for ( int i = 0; soapParameters != null && i < soapParameters.length; i++ )
+//		{
+//			if ( !WSUtil.isNull( soapParameters[i] ) )
+//			{
+//				int pos = -1;
+//				for ( int j = 0; j < parameters.length; j++ )
+//				{
+//					if ( !WSUtil.isNull( parameters[j].getName( ) )
+//							&& parameters[j].getName( )
+//									.equals( soapParameters[i].getName( ) ) )
+//					{
+//						pos = j;
+//						break;
+//					}
+//				}
+//				if( pos != -1 )
+//				{
+//					parameters[pos].setDefaultValue( soapParameters[i].getDefaultValue( ) );
+//					parameters[pos].setUsed( soapParameters[i].isUsed( ) );
+//				}
+//			}
+//		}
+	}
+	
+	/**
+	 * 
+	 * @return
+	 * @throws OdaException 
+	 */
+	public String getTemplate( ) throws OdaException
+	{
+		WSDLAdvisor wsdlAdvisor = new WSDLAdvisor( );
+		return wsdlAdvisor.getSOAPRequestTemplate( getPropertyValue( Constants.WSDL_URI ),
+				getPropertyValue( Constants.OPERATION_TRACE ) );
+	}
+
+	/**
+	 * 
+	 */
+	public void updateXSDFileURI( )
+	{
+		String xsdFileURI = getPropertyValue( Constants.XSD_FILE_URI );
+		if ( xsdFileURI != null
+				&& !xsdFileURI.equals( getXMLPropertyValue( Constants.CONST_PROP_SCHEMA_FILELIST ) ) )
+			setXMLPropertyValue( Constants.CONST_PROP_SCHEMA_FILELIST,
+					xsdFileURI );
+	}
+
+	/**
+	 * 
+	 * @return
+	 * @throws OdaException
+	 */
+	public void updateXMLFileURI( ) throws OdaException
+	{
+		// Constants.XML_FILE_URI and Constants.CONST_PROP_FILELIST are
+		// initially same, both of which are gotten from design, the difference
+		// is the former will then be accoutable for design while the latter is
+		// for xmlHolder alone
+
+		// check if there is explicit xmlURI
+		String xmlFileURI = getPropertyValue( Constants.XML_FILE_URI );
+		if ( !WSUtil.isNull( xmlFileURI ) )
+		{
+			if ( !xmlFileURI.equals( getXMLPropertyValue( Constants.CONST_PROP_FILELIST ) ) )
+				setXMLPropertyValue( Constants.CONST_PROP_FILELIST, xmlFileURI );
+
+			return;
+		}
+
+		// check if there is implicit xmlURI
+		String xmlTempFileURI = getPropertyValue( Constants.XML_TEMP_FILE_URI );
+		if ( WSUtil.isNull( xmlTempFileURI ) || needsRefreshTempFile )
+		{
+			// there is no xml temp file, create one
+			setXMLPropertyValue( Constants.CONST_PROP_FILELIST,
+					WSUtil.EMPTY_STRING );
+			createXMLTempFileURI( );
+			xmlTempFileURI = getPropertyValue( Constants.XML_TEMP_FILE_URI );
+			needsRefreshTempFile = false;
+		}
+		if ( !WSUtil.isNull( xmlTempFileURI )
+				&& !xmlTempFileURI.equals( getXMLPropertyValue( Constants.CONST_PROP_FILELIST ) ) )
+			setXMLPropertyValue( Constants.CONST_PROP_FILELIST, xmlTempFileURI );
+	}
+
+	/**
+	 * 
+	 * @throws OdaException
+	 */
+	public void createXMLTempFileURI( ) throws OdaException
+	{
+		String fileLocation = getPropertyValue( Constants.XML_TEMP_FILE_URI ) == null
+				? null
+				: getPropertyValue( Constants.XML_TEMP_FILE_URI ).toString( );
+		if ( fileLocation != null && !new File( fileLocation ).delete( ) )
+		{
+			new File( fileLocation ).deleteOnExit( );
+			setPropertyValue( Constants.XML_TEMP_FILE_URI, null );
+		}
+		InputStream stream = null;
+		if( WSUtil.isNull( getPropertyValue( Constants.RESPONSE_SCHEMA ) ) || getPropertyValue( Constants.RESPONSE_SCHEMA ).equals( Constants.FROM_WSDL ) )
+		{
+			stream = getInputStream( true  );
+		}
+		else
+		{
+			stream = getInputStream( false  );
+		}
+		if ( WSUtil.isNull( stream ) )
+			return;
+
+		templateFile = generateTempXMLFile( stream );
+		try
+		{
+			stream.close( );
+		}
+		catch ( IOException e )
+		{
+		}
+		if ( templateFile != null )
+		{
+			String xmlTempFileURI = templateFile.getAbsolutePath( );
+			setPropertyValue( Constants.XML_TEMP_FILE_URI, xmlTempFileURI );
+		}
+	}
+	
+	/**
+	 * 
+	 * @throws OdaException
+	 */
+	public void createSampleXMLFile( ) throws OdaException
+	{
+		String fileLocation = getPropertyValue( Constants.CONST_PROP_SAMPLE_XML ) == null
+				? null
+				: getPropertyValue( Constants.CONST_PROP_SAMPLE_XML ).toString( );
+		if ( fileLocation != null && new File( fileLocation ).delete( ) )
+		{
+			new File( fileLocation ).deleteOnExit( );
+		}
+		setXMLPropertyValue( Constants.CONST_PROP_SAMPLE_XML, "" ); //$NON-NLS-1$
+
+		InputStream stream = getInputStream( false );
+		if ( WSUtil.isNull( stream ) )
+			return;
+		sampleXMLFile = generateTempXMLFile( stream );
+		try
+		{
+			stream.close( );
+		}
+		catch ( IOException e )
+		{
+		}
+		if ( sampleXMLFile != null )
+		{
+			String xmlTempFileURI = sampleXMLFile.getAbsolutePath( );
+			setPropertyValue( Constants.CONST_PROP_SAMPLE_XML, xmlTempFileURI );
+			setXMLPropertyValue( Constants.CONST_PROP_SAMPLE_XML,
+					xmlTempFileURI );
+		}
+	}
+
+	public void setRefreshTempFile( boolean needsRefreshTempFile )
+	{
+		this.needsRefreshTempFile = needsRefreshTempFile;
+	}
+
+	private File generateTempXMLFile( InputStream stream ) throws OdaException
+	{
+
+		File file;
+		try
+		{
+			file = File.createTempFile( XML_TEMP_FILE, null );
+			file.deleteOnExit( );
+			FileOutputStream fos = new FileOutputStream( file );
+			InputStream bis = new BufferedInputStream( stream );
+			int abyte;
+
+			while ( ( abyte = bis.read( ) ) != -1 )
+			{
+				fos.write( abyte );
+			}
+			bis.close( );
+			fos.close( );
+		}
+		catch ( IOException e )
+		{
+			return null;
+		}
+
+		return file;
+	}
+
+	private InputStream getInputStream( boolean fromWSDL ) throws OdaException
+	{
+		if ( !WSUtil.isNull( getPropertyValue( Constants.CUSTOM_CONNECTION_CLASS ) ) )
+		{
+			return byCustom( );
+		}
+		else
+		{
+			SOAPResponse soapResponse = connectNow( fromWSDL );
+			if ( soapResponse == null || soapResponse.getInputStream( ) == null )
+				throw new OdaException( Messages.getString( "wsConsole.message.error.cantRetrieveSOAPResponse" ) ); //$NON-NLS-1$
+
+			return soapResponse.getInputStream( );
+		}
+	}
+
+	private InputStream byCustom( ) throws OdaException
+	{
+		Java2SOAPManager j2s = new Java2SOAPManager( );
+
+		j2s.setConnectionProperties( retrieveConnProperties( ) );
+		j2s.setQueryText( getPropertyValue( Constants.WS_QUERYTEXT ) );
+		if ( !WSUtil.isNull( parameters ) )
+		{
+			Map parameterMap = new HashMap( );
+			for ( int i = 0; i < parameters.length; i++ )
+			{
+				parameterMap.put( parameters[i].getName( ),
+						parameters[i].getDefaultValue( ) );
+			}
+			j2s.setParameterValues( parameterMap );
+		}
+
+		try
+		{
+			j2s.newQuery( getPropertyValue( Constants.CUSTOM_CONNECTION_CLASS ),getPropertyValue( Constants.CUSTOM_DRIVER_CLASS_PATH ) );
+
+			Object o = j2s.executeQuery( );
+			if ( o instanceof InputStream )
+				return (InputStream) o;
+			else if ( o instanceof String )
+				return new ByteArrayInputStream( o.toString( ).getBytes( ) );
+
+			return null;
+		}
+		catch ( Exception e )
+		{
+			throw new OdaException( e );
+		}
+	}
+
+	private Properties retrieveConnProperties( )
+	{
+		Properties p = new Properties( );
+		String value = getPropertyValue( Constants.SOAP_ENDPOINT );
+		if ( value != null )
+			p.put( Constants.SOAP_ENDPOINT, value );
+		value = getPropertyValue( Constants.CUSTOM_CONNECTION_CLASS );
+		if ( value != null )
+			p.put( Constants.CUSTOM_CONNECTION_CLASS, value );
+		value = getPropertyValue( Constants.CUSTOM_DRIVER_CLASS_PATH );
+		if ( value != null )
+			p.put( Constants.CUSTOM_DRIVER_CLASS_PATH, value );
+		value = getPropertyValue( Constants.CONNECTION_TIMEOUT );
+		if ( value != null )
+			p.put( Constants.CONNECTION_TIMEOUT, value );
+
+		return p;
+	}
+
+	private SOAPResponse connectNow( boolean fromWSDL ) throws OdaException
+	{
+		String spec = getPropertyValue( Constants.SOAP_ENDPOINT );
+		// if soapEndPoint is not explicitly specified by the user, try locate
+		// it from the wsdl file
+		if ( WSUtil.isNull( spec ) )
+			spec = WSDLAdvisor.getLocationURI( getPropertyValue( Constants.WSDL_URI ),
+					getPropertyValue( Constants.OPERATION_TRACE ) );
+		String query = getPropertyValue( Constants.WS_QUERYTEXT );
+		if ( WSUtil.isNull( spec ) || WSUtil.isNull( query ) )
+			return null;
+
+		SOAPRequest soapRequest = new SOAPRequest( query );
+		populateSOAPParameterValues( soapRequest, parameters );
+
+		SOAPResponse soapResponse = null;
+		if ( fromWSDL )
+		{
+			WSDLAdvisor wsdlAdvisor = new WSDLAdvisor( );
+			String temlate = wsdlAdvisor.getLocalSOAPResponseTemplate( getPropertyValue( Constants.WSDL_URI ),
+					getPropertyValue( Constants.OPERATION_TRACE ) );
+			soapResponse = new SOAPResponse( new ByteArrayInputStream( temlate.toString( )
+					.getBytes( ) ) );
+		}
+		else
+		{
+			RawMessageSender rawMessageSender = new RawMessageSender( );
+			rawMessageSender.setMessage( soapRequest.toXML( ) );
+			String soapEndPoint = getPropertyValue( Constants.SOAP_ENDPOINT );
+			String wsdlURI = getPropertyValue( Constants.WSDL_URI );
+			String operationTrace = getPropertyValue( Constants.OPERATION_TRACE );
+			String connTimeOut = getPropertyValue( Constants.CONNECTION_TIMEOUT );
+			
+			int connectionTimeout = 0;
+			if ( connTimeOut != null )
+				connectionTimeout = Integer.parseInt( getPropertyValue( Constants.CONNECTION_TIMEOUT ) );
+
+			if ( WSUtil.isNull( soapEndPoint ) )
+				soapEndPoint = WSDLAdvisor.getLocationURI( wsdlURI,
+						operationTrace );
+			rawMessageSender.setSpec( soapEndPoint );
+			rawMessageSender.setSoapAction( WSDLAdvisor.getSOAPActionURI( wsdlURI,
+					operationTrace ) );
+			soapResponse = rawMessageSender.getSOAPResponse( connectionTimeout );
+		}
+		return soapResponse;
+	}
+
+	private void populateSOAPParameterValues( SOAPRequest soapRequest,
+			SOAPParameter[] soapParameters )
+	{
+		if ( WSUtil.isNull( soapRequest ) || WSUtil.isNull( soapParameters ) )
+			return;
+
+		SOAPParameter[] parameters = soapRequest.getParameters( );
+		
+		for ( int i = 0; parameters != null && i < parameters.length; i++ )
+		{
+			if( soapParameters == null || soapParameters.length != parameters.length )
+				return;
+			if ( !WSUtil.isNull( soapParameters[i] ) )
+			{
+				int pos = -1;
+				for ( int j = 0; j < soapParameters.length; j++ )
+				{
+					if ( !WSUtil.isNull( soapParameters[j].getName( ) )
+							&& soapParameters[j].getName( )
+									.equals( parameters[i].getName( ) ) )
+					{
+						pos = j;
+						break;
+					}
+				}
+				if( pos != -1 )
+				{
+					parameters[i].setDefaultValue( soapParameters[pos].getDefaultValue( ) );
+				}
+			}
+		}
+	}
+	
+
+	/**
+	 * 
+	 * @param dataSetParams
+	 */
+	public void initSOAPParameters( DataSetParameters dataSetParams )
+	{
+		EList parameterDefinitions = dataSetParams.getParameterDefinitions( );
+		if ( WSUtil.isNull( parameterDefinitions )
+				|| parameterDefinitions.size( ) == 0 )
+			return;
+
+		parameters = new SOAPParameter[parameterDefinitions.size( )];
+		for ( int i = 0; i < parameterDefinitions.size( ); i++ )
+		{
+			// apply name & defaultValue
+			ParameterDefinition paramDef = (ParameterDefinition) parameterDefinitions.get( i );
+			parameters[i] = new SOAPParameter( i + 1, paramDef.getAttributes( )
+					.getName( ), paramDef.getDefaultScalarValue( ) );
+		}
+
+	}
+
+	/**
+	 * 
+	 * @param parameterDefinitions
+	 */
+	public void merge2ParameterDefinitions( EList parameterDefinitions )
+	{
+		SOAPParameter[] usedParameters = WSUIUtil.getUsedParameter( parameters );
+		if ( !canMerge( usedParameters, parameterDefinitions ) )
+			return;
+
+		for ( int i = 0; i < usedParameters.length; i++ )
+		{
+			// apply name & defaultValue
+			if ( !WSUtil.isNull( usedParameters[i] ) )
+			{
+				ParameterDefinition paramDef = (ParameterDefinition) parameterDefinitions.get( i );
+				paramDef.getAttributes( ).setName( usedParameters[i].getName( ) );
+				paramDef.setDefaultScalarValue( usedParameters[i].getDefaultValue( ) );
+			}
+		}
+	}
+
+	private boolean canMerge( SOAPParameter[] soapParameters,
+			EList parameterDefinitions )
+	{
+		if ( soapParameters == null || parameterDefinitions == null )
+			return false;
+
+		if ( soapParameters.length != parameterDefinitions.size( ) )
+			return false;
+
+		return true;
+	}
+
+	/**
+	 * Convenient method to manipulate query after parameters have been changed
+	 * 
+	 * @param queryText
+	 * @param params
+	 * @return
+	 * @throws OdaException
+	 */
+	public String manipulateTemplate( ) throws OdaException
+	{
+		SOAPRequest soapRequest = new SOAPRequest( getPropertyValue( Constants.WS_QUERYTEXT ) );
+		String[] template = soapRequest.getTemplate( );
+
+		if ( WSUtil.isNull( template ) || WSUtil.isNull( parameters ) )
+			return getTemplate( );
+
+		StringBuffer wsQueryText = new StringBuffer( );
+		// retrieve whole queryText with defaultValue if applicable
+		for ( int i = 0; i < parameters.length; i++ )
+		{
+			wsQueryText.append( template[i] );
+			wsQueryText.append( buildParameter( parameters[i].getName( ) ) );
+		}
+		wsQueryText.append( template[template.length - 1] );
+		
+		// eliminate unused parameters
+		StringBuffer buffer = new StringBuffer( wsQueryText.toString( ) );
+
+		for ( int i = 0; i < parameters.length; i++ )
+		{
+			if ( !parameters[i].isUsed( ) )
+			{
+				int offset = getOffset( wsQueryText.toString( ), parameters[i].getName( ) );
+				int start = getFirstIndex( wsQueryText.toString( ), offset, BACKWARD, '<' );
+				start = getFirstIndex( wsQueryText.toString( ), start, BACKWARD, '\n' );
+				int end = getFirstIndex( wsQueryText.toString( ), offset, FORWARD, '>' );
+				end = getFirstIndex( wsQueryText.toString( ), end, FORWARD, '\n' );
+
+				buffer.delete( start, end );
+				wsQueryText = buffer;
+			}
+		}
+
+		return wsQueryText.toString( );
+	}
+
+	private String buildParameter( String paramName )
+	{
+		return "&?" + paramName + "?&"; //$NON-NLS-1$//$NON-NLS-2$
+	}
+
+	private int getOffset( String queryText, String paramName )
+	{
+		return queryText.indexOf( buildParameter( paramName ) );
+	}
+
+	private int getFirstIndex( String string, int index, int dir, char ch )
+	{
+		while ( string.charAt( index ) != ch )
+		{
+			switch ( dir )
+			{
+				case BACKWARD :
+					index--;
+					break;
+				case FORWARD :
+					index++;
+					break;
+			}
+		}
+
+		return index;
+	}
+
+}
diff --git a/plugins/org.eclipse.datatools.enablement.oda.ws.ui/src/org/eclipse/datatools/enablement/oda/ws/ui/util/WSUIUtil.java b/plugins/org.eclipse.datatools.enablement.oda.ws.ui/src/org/eclipse/datatools/enablement/oda/ws/ui/util/WSUIUtil.java
new file mode 100644
index 0000000..0ca351d
--- /dev/null
+++ b/plugins/org.eclipse.datatools.enablement.oda.ws.ui/src/org/eclipse/datatools/enablement/oda/ws/ui/util/WSUIUtil.java
@@ -0,0 +1,309 @@
+/*******************************************************************************
+ * Copyright (c) 2007 Actuate Corporation.
+ * 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:
+ *  Actuate Corporation - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.datatools.enablement.oda.ws.ui.util;
+
+import java.util.Properties;
+
+import org.eclipse.datatools.connectivity.oda.IConnection;
+import org.eclipse.datatools.connectivity.oda.IDriver;
+import org.eclipse.datatools.connectivity.oda.IParameterMetaData;
+import org.eclipse.datatools.connectivity.oda.IQuery;
+import org.eclipse.datatools.connectivity.oda.IResultSetMetaData;
+import org.eclipse.datatools.connectivity.oda.OdaException;
+import org.eclipse.datatools.connectivity.oda.design.DataSetDesign;
+import org.eclipse.datatools.connectivity.oda.design.DataSetParameters;
+import org.eclipse.datatools.connectivity.oda.design.DesignFactory;
+import org.eclipse.datatools.connectivity.oda.design.ResultSetColumns;
+import org.eclipse.datatools.connectivity.oda.design.ResultSetDefinition;
+import org.eclipse.datatools.connectivity.oda.design.ui.designsession.DesignSessionUtil;
+import org.eclipse.datatools.connectivity.oda.design.util.DesignUtil;
+import org.eclipse.datatools.enablement.oda.ws.impl.Driver;
+import org.eclipse.datatools.enablement.oda.ws.soap.SOAPParameter;
+import org.eclipse.datatools.enablement.oda.ws.util.WSUtil;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.ui.PlatformUI;
+
+/**
+ * 
+ */
+
+public class WSUIUtil
+{
+
+	/**
+	 * Makes sure the public and private properties are not empty
+	 * 
+	 * @param design
+	 */
+	public static void checkExisted( DataSetDesign design )
+	{
+		if ( design.getPublicProperties( ) == null )
+		{
+			try
+			{
+				design.setPublicProperties( DesignSessionUtil.createDataSetPublicProperties( design.getOdaExtensionDataSourceId( ),
+						design.getOdaExtensionDataSetId( ),
+						new Properties( ) ) );
+			}
+			catch ( OdaException e )
+			{
+				e.printStackTrace( );
+			}
+		}
+		if ( design.getPrivateProperties( ) == null )
+		{
+			try
+			{
+				design.setPrivateProperties( DesignSessionUtil.createDataSetNonPublicProperties( design.getOdaExtensionDataSourceId( ),
+						design.getOdaExtensionDataSetId( ),
+						getDataSetInitialPrivateProperties( ) ) );
+			}
+			catch ( OdaException e )
+			{
+				e.printStackTrace( );
+			}
+		}
+	}
+
+	private static Properties getDataSetInitialPrivateProperties( )
+	{
+		Properties props = new Properties( );
+		props.setProperty( Constants.OPERATION_TRACE, WSUtil.EMPTY_STRING );
+		props.setProperty( Constants.XML_QUERYTEXT, WSUtil.EMPTY_STRING );
+
+		return props;
+	}
+
+	/**
+	 * Consumes the driver and updates the dataSetDesign
+	 * 
+	 * @param dataSetDesign
+	 */
+	public static void savePage( DataSetDesign dataSetDesign )
+	{
+		if ( !WSConsole.getInstance( ).isSessionOK( ) )
+			return;
+		
+		IConnection conn = null;
+		try
+		{
+			IDriver driver = new Driver( );
+
+			// obtain and open a live connection
+			conn = driver.getConnection( null );
+			Properties connProps = DesignUtil.convertDataSourceProperties( dataSetDesign.getDataSourceDesign( ) );
+			conn.open( connProps );
+
+			updateDesign( dataSetDesign, conn, dataSetDesign.getQueryText( ) );
+		}
+		catch ( OdaException e )
+		{
+			// not able to get current metadata, reset previous derived metadata
+			dataSetDesign.setResultSets( null );
+			dataSetDesign.setParameters( null );
+
+			e.printStackTrace( );
+		}
+		finally
+		{
+			closeConnection( conn );
+		}
+	}
+
+	/**
+	 * 
+	 * @param parameters
+	 * @return
+	 */
+	public static SOAPParameter[] getUsedParameter( SOAPParameter[] parameters )
+	{
+		int usedNum = 0;
+		if( parameters == null || parameters.length == 0 )
+			return null;
+		for ( int i = 0; i < parameters.length; i++ )
+		{
+			if ( parameters[i].isUsed( ) )
+				usedNum++;
+		}
+		SOAPParameter[] result = new SOAPParameter[usedNum];
+		int resultPtr = 0;
+		for ( int i = 0; i < parameters.length; i++ )
+		{
+			if ( parameters[i].isUsed( ) )
+			{
+				SOAPParameter tParameter = new SOAPParameter( resultPtr + 1,
+						parameters[i].getName( ),
+						parameters[i].getType( ),
+						parameters[i].getDefaultValue( ) );
+				tParameter.setMaxOccurs( parameters[i].getMaxOccurs( ) );
+				tParameter.setMinOccurs( parameters[i].getMinOccurs( ) );
+				tParameter.setUsed( parameters[i].isUsed( ) );
+				result[resultPtr] = tParameter;
+				resultPtr++;
+			}
+		}
+		return result;
+	}
+	
+	/**
+	 * Updates the given dataSetDesign with the queryText and its derived
+	 * metadata obtained from the ODA runtime connection.
+	 */
+	private static void updateDesign( DataSetDesign dataSetDesign,
+			IConnection conn, String queryText ) throws OdaException
+	{
+		IQuery query = conn.newQuery( null );
+		query.prepare( queryText );
+
+		// set soapParameters
+		SOAPParameter[] soapParameters = WSConsole.getInstance( )
+				.getParameters( );
+		soapParameters = getUsedParameter( soapParameters );
+		if ( !WSUtil.isNull( soapParameters ) )
+		{
+			for ( int i = 0; i < soapParameters.length; i++ )
+			{
+				if ( !WSUtil.isNull( soapParameters[i] ) )
+					query.setString( soapParameters[i].getId( ),
+							soapParameters[i].getDefaultValue( ) );
+			}
+		}
+
+		// set xmlQuery note: it was save to design not to model due to
+		// compatibility issue
+		query.setProperty( Constants.XML_QUERYTEXT,
+				dataSetDesign.getPrivateProperties( )
+						.getProperty( Constants.XML_QUERYTEXT ) );
+
+		// set operationTrace: necessary here to get soapAction and, if
+		// applicable, soapEndPoint
+		query.setProperty( Constants.OPERATION_TRACE, WSConsole.getInstance( )
+				.getPropertyValue( Constants.OPERATION_TRACE ) );
+
+		try
+		{
+			IResultSetMetaData md = query.getMetaData( );
+			updateResultSetDesign( md, dataSetDesign );
+		}
+		catch ( OdaException e )
+		{
+			// no result set definition available, reset previous derived
+			// metadata
+			dataSetDesign.setResultSets( null );
+		}
+
+		// proceed to get parameter design definition
+		try
+		{
+			IParameterMetaData paramMd = query.getParameterMetaData( );
+			updateParameterDesign( paramMd, dataSetDesign );
+		}
+		catch ( OdaException ex )
+		{
+			// no parameter definition available, reset previous derived
+			// metadata
+			dataSetDesign.setParameters( null );
+		}
+		query.close( );
+
+		/*
+		 * See DesignSessionUtil for more convenience methods to define a data
+		 * set design instance.
+		 */
+	}
+
+	/**
+	 * Updates the specified data set design's result set definition based on
+	 * the specified runtime metadata.
+	 * 
+	 * @param md
+	 *            runtime result set metadata instance
+	 * @param dataSetDesign
+	 *            data set design instance to update
+	 * @throws OdaException
+	 */
+	private static void updateResultSetDesign( IResultSetMetaData md,
+			DataSetDesign dataSetDesign ) throws OdaException
+	{
+		ResultSetColumns columns = DesignSessionUtil.toResultSetColumnsDesign( md );
+
+		ResultSetDefinition resultSetDefn = DesignFactory.eINSTANCE.createResultSetDefinition( );
+		// resultSetDefn.setName( value ); // result set name
+		resultSetDefn.setResultSetColumns( columns );
+
+		// no exception in conversion; go ahead and assign to specified
+		// dataSetDesign
+		dataSetDesign.setPrimaryResultSet( resultSetDefn );
+		dataSetDesign.getResultSets( ).setDerivedMetaData( true );
+	}
+
+	/**
+	 * Updates the specified data set design's parameter definition based on the
+	 * specified runtime metadata.
+	 * 
+	 * @param paramMd
+	 *            runtime parameter metadata instance
+	 * @param dataSetDesign
+	 *            data set design instance to update
+	 * @throws OdaException
+	 */
+	private static void updateParameterDesign( IParameterMetaData paramMd,
+			DataSetDesign dataSetDesign ) throws OdaException
+	{
+		DataSetParameters paramDesign = DesignSessionUtil.toDataSetParametersDesign( paramMd,
+				DesignSessionUtil.toParameterModeDesign( IParameterMetaData.parameterModeIn ) );
+
+		// no exception in conversion; go ahead and assign to specified
+		// dataSetDesign
+		dataSetDesign.setParameters( paramDesign );
+		if ( WSUtil.isNull( paramDesign ) )
+			return;
+		
+		paramDesign.setDerivedMetaData( true );
+		if ( paramDesign.getParameterDefinitions( ).size( ) > 0 )
+		{
+			WSConsole.getInstance( )
+					.merge2ParameterDefinitions( paramDesign.getParameterDefinitions( ) );
+		}
+
+	}
+
+	/**
+	 * Attempts to close given ODA connection.
+	 */
+	private static void closeConnection( IConnection conn )
+	{
+		try
+		{
+			if ( conn != null && conn.isOpen( ) )
+				conn.close( );
+		}
+		catch ( OdaException e )
+		{
+			// ignore
+			e.printStackTrace( );
+		}
+	}
+	
+	/**
+	 * 
+	 * @param control
+	 * @param contextId
+	 */
+	public static void setSystemHelp( Control control, String contextId )
+	{
+		PlatformUI.getWorkbench( )
+				.getHelpSystem( )
+				.setHelp( control, contextId );
+	}
+
+}
diff --git a/plugins/org.eclipse.datatools.enablement.oda.ws.ui/src/org/eclipse/datatools/enablement/oda/ws/ui/wizards/OperationPage.java b/plugins/org.eclipse.datatools.enablement.oda.ws.ui/src/org/eclipse/datatools/enablement/oda/ws/ui/wizards/OperationPage.java
new file mode 100644
index 0000000..dfddfe4
--- /dev/null
+++ b/plugins/org.eclipse.datatools.enablement.oda.ws.ui/src/org/eclipse/datatools/enablement/oda/ws/ui/wizards/OperationPage.java
@@ -0,0 +1,529 @@
+/*******************************************************************************
+ * Copyright (c) 2007 Actuate Corporation.
+ * 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:
+ *  Actuate Corporation - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.datatools.enablement.oda.ws.ui.wizards;
+
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import javax.wsdl.Definition;
+import javax.wsdl.Operation;
+import javax.wsdl.Port;
+import javax.wsdl.Service;
+import javax.wsdl.WSDLException;
+
+import org.eclipse.datatools.connectivity.oda.OdaException;
+import org.eclipse.datatools.connectivity.oda.design.DataSetDesign;
+import org.eclipse.datatools.connectivity.oda.design.ui.wizards.DataSetWizardPage;
+import org.eclipse.datatools.enablement.oda.ws.ui.Activator;
+import org.eclipse.datatools.enablement.oda.ws.ui.i18n.Messages;
+import org.eclipse.datatools.enablement.oda.ws.ui.util.Constants;
+import org.eclipse.datatools.enablement.oda.ws.ui.util.IHelpConstants;
+import org.eclipse.datatools.enablement.oda.ws.ui.util.WSConsole;
+import org.eclipse.datatools.enablement.oda.ws.ui.util.WSUIUtil;
+import org.eclipse.datatools.enablement.oda.ws.util.WSDLAdvisor;
+import org.eclipse.datatools.enablement.oda.ws.util.WSUtil;
+import org.eclipse.jface.dialogs.IMessageProvider;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.jface.wizard.IWizardPage;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.ScrolledComposite;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.graphics.Font;
+import org.eclipse.swt.graphics.FontData;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Text;
+import org.eclipse.swt.widgets.Tree;
+import org.eclipse.swt.widgets.TreeItem;
+
+/**
+ * 
+ */
+
+public class OperationPage extends DataSetWizardPage
+{
+
+	private transient Tree operationTree;
+	private transient Label operationName;
+	private transient Text operationDescription;
+
+	private String operationTrace = WSUtil.EMPTY_STRING;
+	private String initOperationTrace = WSUtil.EMPTY_STRING;
+	private String wsdlURI = WSUtil.EMPTY_STRING;
+	private String wsQuery = WSUtil.EMPTY_STRING;
+
+	private Image wsdlImage;
+	private Image serviceImage;
+	private Image portImage;
+	private Image operationImage;
+	
+	private boolean selectionChanged = false;
+
+	private static String DEFAULT_MESSAGE = Messages.getString( "operationPage.message.default" );//$NON-NLS-1$
+
+	/**
+	 * 
+	 * @param pageName
+	 */
+	public OperationPage( String pageName )
+	{
+		super( pageName );
+		setMessage( DEFAULT_MESSAGE );
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.eclipse.datatools.connectivity.oda.design.ui.wizards.DataSetWizardPage#createPageCustomControl(org.eclipse.swt.widgets.Composite)
+	 */
+	public void createPageCustomControl( Composite parent )
+	{
+		initialImages( );
+		
+		ScrolledComposite sComposite = new ScrolledComposite( parent, SWT.H_SCROLL | SWT.V_SCROLL );
+		sComposite.setLayout( new GridLayout( ) );
+		sComposite.setLayoutData( new GridData( GridData.FILL_BOTH ) );
+		sComposite.setMinWidth( 600 );
+		sComposite.setExpandHorizontal( true );
+
+		Control control = createPageControl( sComposite );
+		initializeControl( );
+
+		int x = java.awt.Toolkit.getDefaultToolkit( ).getScreenSize( ).width
+				- 800;
+		int y = java.awt.Toolkit.getDefaultToolkit( ).getScreenSize( ).height
+				- 700;
+		if ( getShell( ) != null )
+		{
+			getShell( ).setLocation( x / 2, y / 2 );
+		}
+		else
+		{
+			parent.getShell( ).setLocation( x / 2, y / 2 );
+		}
+		
+		Point size = control.computeSize( SWT.DEFAULT, SWT.DEFAULT );
+		control.setSize( size.x, size.y );
+
+		sComposite.setContent( control );
+		setControl( sComposite );
+
+		WSUIUtil.setSystemHelp( getControl( ), IHelpConstants.CONEXT_ID_WS_OPERATION );
+	}
+
+	private void initialImages( )
+	{
+		wsdlImage = Activator.getDefault( )
+				.getImageRegistry( )
+				.get( Activator.ICON_WSDL );
+		serviceImage = Activator.getDefault( )
+				.getImageRegistry( )
+				.get( Activator.ICON_SERVICE );
+		portImage = Activator.getDefault( )
+				.getImageRegistry( )
+				.get( Activator.ICON_PORT );
+		operationImage = Activator.getDefault( )
+				.getImageRegistry( )
+				.get( Activator.ICON_OPERATION );
+	}
+
+	private Control createPageControl( Composite parent )
+	{
+		Composite composite = new Composite( parent, SWT.NONE );
+		GridLayout layout = new GridLayout( 1, false );
+		layout.verticalSpacing = 30;
+		composite.setLayout( layout );
+		GridData layoutData = new GridData( GridData.HORIZONTAL_ALIGN_FILL
+				| GridData.VERTICAL_ALIGN_FILL );
+		composite.setLayoutData( layoutData );
+
+		setupTreeComposite( composite );
+		setupTextComposite( composite );
+
+		return composite;
+	}
+
+	private void setupTreeComposite( Composite parent )
+	{
+		operationTree = new Tree( parent, SWT.BORDER
+				| SWT.SINGLE | SWT.V_SCROLL | SWT.H_SCROLL );
+		operationTree.setLayout( new GridLayout( ) );
+		GridData layoutData = new GridData( GridData.FILL_BOTH );
+		layoutData.heightHint = 200;
+		operationTree.setLayoutData( layoutData );
+
+		operationTree.addSelectionListener( new SelectionAdapter( ) {
+
+			/*
+			 * (non-Javadoc)
+			 * 
+			 * @see org.eclipse.swt.events.SelectionAdapter#widgetSelected(org.eclipse.swt.events.SelectionEvent)
+			 */
+			public void widgetSelected( SelectionEvent event )
+			{
+				TreeItem item = operationTree.getSelection( )[0];
+
+				if ( item.getData( ) instanceof Operation )
+				{
+					Operation operation = (Operation) item.getData( );
+					operationTrace = toOperationTrace( item );
+					if ( operation.getName( ) != null )
+						operationName.setText( operation.getName( ) );
+					operationDescription.setText( WSDLAdvisor.retrieveDocument( operation ) );
+					setPageComplete( true );
+				}
+				else
+				{
+					operationName.setText( WSUtil.EMPTY_STRING );
+					operationDescription.setText( WSUtil.EMPTY_STRING );
+					setPageComplete( false );
+				}
+				
+				selectionChanged = true;
+			}
+			
+		} );
+	}
+
+	// TODO refine me
+	private String toOperationTrace( TreeItem item )
+	{
+		Service service = (Service) item.getParentItem( )
+				.getParentItem( )
+				.getData( );
+		Port port = (Port) item.getParentItem( ).getData( );
+		Operation operation = (Operation) item.getData( );
+		return service.getQName( ).getLocalPart( )
+				+ Constants.DELIMITER_OPEARTION + port.getName( )
+				+ Constants.DELIMITER_OPEARTION + operation.getName( );
+	}
+
+	private void setupTextComposite( Composite parent )
+	{
+		Composite composite = new Composite( parent, SWT.NONE );
+		GridLayout layout = new GridLayout( 3, false );
+		layout.verticalSpacing = 20;
+		layout.horizontalSpacing = 30;
+		composite.setLayout( layout );
+		GridData layoutData = new GridData( GridData.HORIZONTAL_ALIGN_FILL
+				| GridData.VERTICAL_ALIGN_FILL );
+		composite.setLayoutData( layoutData );
+
+		Label label = new Label( composite, SWT.NONE );
+		layoutData = new GridData( );
+		label.setLayoutData( layoutData );
+		label.setText( Messages.getString( "operationPage.label.selectOpearation" ) );//$NON-NLS-1$
+		if ( label.computeSize( -1, -1 ).x < 100 )
+			layoutData.widthHint = 100;
+
+		operationName = new Label( composite, SWT.BORDER );
+		GridData gd = new GridData( GridData.FILL_HORIZONTAL );
+		gd.horizontalSpan = 2;
+		operationName.setLayoutData( gd );
+
+		Label label2 = new Label( composite, SWT.NONE );
+		GridData data = new GridData( );
+		label2.setLayoutData( data );
+		label2.setText( Messages.getString( "operationPage.label.document" ) ); //$NON-NLS-1$
+		if ( label2.computeSize( -1, -1 ).x < 100 )
+			data.widthHint = 100;
+
+		Composite container = new Composite( composite, SWT.NONE );
+		GridLayout gLayout = new GridLayout( );
+		gLayout.marginWidth = gLayout.marginHeight = 0;
+		container.setLayout( gLayout );
+		layoutData = new GridData( GridData.FILL_BOTH );
+		layoutData.horizontalSpan = 2;
+		container.setLayoutData( layoutData );
+		
+		operationDescription = new Text( container, SWT.BORDER
+				| SWT.WRAP | SWT.V_SCROLL | SWT.H_SCROLL | SWT.READ_ONLY );
+		GridData layoutData2 = new GridData( GridData.FILL_BOTH );
+		layoutData2.heightHint = 60;
+		layoutData2.widthHint = 50;
+		operationDescription.setLayoutData( layoutData2 );
+	}
+
+	/**
+	 * Initializes the page control with the last edited data set design.
+	 */
+	private void initializeControl( )
+	{
+		initWSConsole( );
+		initFromModel( );
+
+		populateTree( );
+		setPageComplete( false );
+	}
+
+	private void initWSConsole( )
+	{
+		if ( !WSConsole.getInstance( ).isSessionOK( ) )
+			WSConsole.getInstance( ).start( getInitializationDesign( ) );
+	}
+
+	private void initFromModel( )
+	{
+		wsdlURI = WSConsole.getInstance( )
+				.getPropertyValue( Constants.WSDL_URI );
+		operationTrace = WSConsole.getInstance( )
+				.getPropertyValue( Constants.OPERATION_TRACE );
+		initOperationTrace = WSConsole.getInstance( )
+				.getPropertyValue( Constants.OPERATION_TRACE );
+	}
+
+	// TODO refine me
+	private void populateTree( )
+	{
+		if ( WSUtil.isNull( wsdlURI ) )
+			return;
+
+		operationTree.removeAll( );
+
+		TreeItem root = new TreeItem( operationTree, SWT.NONE );
+		root.setText( wsdlURI );
+		root.setImage( wsdlImage );
+		Definition definition = null;
+		try
+		{
+			definition = WSDLAdvisor.getDefinition( wsdlURI );
+		}
+		catch ( WSDLException e )
+		{
+			this.setErrorMessage( e.getMessage( ) );
+		}
+		if ( definition == null )
+			return;
+
+		Map services = definition.getServices( );
+		Iterator srcIT = services.keySet( ).iterator( );
+		while ( srcIT.hasNext( ) )
+		{
+			Service service = (Service) services.get( srcIT.next( ) );
+			TreeItem srcTI = populateTreeItem( root,
+					service,
+					service.getQName( ).getLocalPart( ),
+					serviceImage );// TI: treeItem
+			Map ports = service.getPorts( );
+			Iterator prtIT = ports.keySet( ).iterator( );// IT:iterator
+			while ( prtIT.hasNext( ) )
+			{
+				Port port = (Port) ports.get( prtIT.next( ) );
+				TreeItem prtTI = populateTreeItem( srcTI,
+						port,
+						port.getName( ),
+						portImage );
+				List operations = port.getBinding( )
+						.getPortType( )
+						.getOperations( );
+				for ( int i = 0; i < operations.size( ); i++ )
+				{
+					Operation operation = (Operation) operations.get( i );
+					TreeItem treeItem = populateTreeItem( prtTI,
+							operations.get( i ),
+							operation.getName( ),
+							operationImage );
+					if ( !WSUtil.isNull( operationTrace )
+							&& operationTrace.equals( toOperationTrace( treeItem ) ) )
+
+					{
+						highlight( treeItem );
+						if ( operation.getName( ) != null )
+							operationName.setText( operation.getName( ) );
+						operationDescription.setText( WSDLAdvisor.retrieveDocument( operation ) );
+					}
+				}
+			}
+		}
+	}
+
+	// TODO lazy load
+	private TreeItem populateTreeItem( TreeItem parent, Object child,
+			String text, Image image )
+	{
+		TreeItem item = new TreeItem( parent, SWT.NONE );
+		item.setData( child );
+		item.setText( text );
+		item.setImage( image );
+
+		return item;
+	}
+
+	private void highlight( TreeItem treeItem )
+	{
+		if ( WSUtil.isNull( operationTrace ) )
+			return;
+
+		FontData fontData = new FontData( WSUtil.EMPTY_STRING, 8, SWT.BOLD );
+		treeItem.setFont( new Font( null, fontData ) );
+
+		operationTree.setSelection( new TreeItem[]{
+			treeItem
+		} );
+		operationTree.setFocus( );
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.eclipse.datatools.connectivity.oda.design.ui.wizards.DataSetWizardPage#collectDataSetDesign(org.eclipse.datatools.connectivity.oda.design.DataSetDesign)
+	 */
+	protected DataSetDesign collectDataSetDesign( DataSetDesign design )
+	{
+		WSUIUtil.checkExisted( design );
+		savePage( design );
+
+		return design;
+	}
+
+	private void savePage( DataSetDesign design )
+	{
+		if ( !WSConsole.getInstance( ).isSessionOK( ) )
+			return;
+
+		design.getPrivateProperties( ).setProperty( Constants.OPERATION_TRACE,
+				WSConsole.getInstance( )
+						.getPropertyValue( Constants.OPERATION_TRACE ) );
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.eclipse.datatools.connectivity.oda.design.ui.wizards.DataSetWizardPage#refresh(org.eclipse.datatools.connectivity.oda.design.DataSetDesign)
+	 */
+	protected void refresh( DataSetDesign dataSetDesign )
+	{
+		super.refresh( dataSetDesign );
+
+		refresh( );
+	}
+
+	private void refresh( )
+	{
+		initFromModel( );
+		populateTree( );
+
+		setMessage( DEFAULT_MESSAGE );
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.eclipse.datatools.connectivity.oda.design.ui.wizards.DataSetWizardPage#canLeave()
+	 */
+	protected boolean canLeave( )
+	{
+		saveToModle( );
+		try
+		{
+			testDirty( );
+		}
+		catch ( OdaException e )
+		{
+			this.setErrorMessage( e.getMessage( ) );
+		}
+
+		return super.canLeave( );
+	}
+
+	private void testDirty( ) throws OdaException
+	{
+		if ( !WSUtil.isNull( initOperationTrace )
+				&& !initOperationTrace.equals( operationTrace ) )
+			if ( MessageDialog.openQuestion( null,
+					Messages.getString( "operationPage.title.operationChanged" ), Messages.getString( "operationPage.message.regenerate.SOAPRequest" ) ) )//$NON-NLS-1$ //$NON-NLS-2$
+			{
+				regenerateTemplate( );
+				try
+				{
+					WSConsole.getInstance( ).createXMLTempFileURI( );
+				}
+				catch ( OdaException e )
+				{
+					setMessage( e.getMessage( ), IMessageProvider.ERROR );
+				}
+			}
+	}
+
+	private void regenerateTemplate( ) throws OdaException
+	{
+		wsQuery = WSConsole.getInstance( ).getTemplate( );
+		if ( !WSUtil.isNull( wsQuery ) )
+			WSConsole.getInstance( ).setPropertyValue( Constants.WS_QUERYTEXT,
+					wsQuery );
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.eclipse.jface.wizard.WizardPage#canFlipToNextPage()
+	 */
+	public boolean canFlipToNextPage( )
+	{
+		return isPageComplete( );
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.eclipse.jface.wizard.WizardPage#getNextPage()
+	 */
+	public IWizardPage getNextPage( )
+	{
+		saveToModle( );
+
+		IWizardPage page = super.getNextPage( );
+		if ( page instanceof SOAPParametersPage )
+			try
+			{
+				( (SOAPParametersPage) page ).refresh( selectionChanged );
+			}
+			catch ( OdaException e )
+			{
+				this.setErrorMessage( e.getMessage( ) );
+			}
+
+		selectionChanged = false;		
+		return page;
+	}
+
+	private void saveToModle( )
+	{
+		if ( operationTrace != null
+				&& !operationTrace.equals( WSConsole.getInstance( )
+						.getPropertyValue( Constants.OPERATION_TRACE ) ) )
+		{
+			WSConsole.getInstance( )
+					.setPropertyValue( Constants.OPERATION_TRACE,
+							operationTrace );
+			WSConsole.getInstance( ).setRefreshTempFile( true );
+		}
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.eclipse.datatools.connectivity.oda.design.ui.wizards.DataSetWizardPage#cleanup()
+	 */
+	protected void cleanup( )
+	{
+		WSConsole.getInstance( ).terminateSession( );
+	}
+
+}
diff --git a/plugins/org.eclipse.datatools.enablement.oda.ws.ui/src/org/eclipse/datatools/enablement/oda/ws/ui/wizards/SOAPDataSetWizard.java b/plugins/org.eclipse.datatools.enablement.oda.ws.ui/src/org/eclipse/datatools/enablement/oda/ws/ui/wizards/SOAPDataSetWizard.java
new file mode 100644
index 0000000..422aff7
--- /dev/null
+++ b/plugins/org.eclipse.datatools.enablement.oda.ws.ui/src/org/eclipse/datatools/enablement/oda/ws/ui/wizards/SOAPDataSetWizard.java
@@ -0,0 +1,44 @@
+/*
+ *************************************************************************
+ * Copyright (c) 2010 Actuate Corporation.
+ * 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:
+ *  Actuate Corporation - initial API and implementation
+ *  
+ *************************************************************************
+ */
+
+package org.eclipse.datatools.enablement.oda.ws.ui.wizards;
+
+import org.eclipse.datatools.connectivity.oda.design.ui.wizards.DataSetWizard;
+import org.eclipse.jface.wizard.IWizardPage;
+
+/**
+ *  Extended implementation of the ODA Data Set Wizard.
+ */
+public class SOAPDataSetWizard extends DataSetWizard
+{
+
+    public SOAPDataSetWizard()
+    {
+        super();
+    }
+
+    /* (non-Javadoc)
+     * @see org.eclipse.jface.wizard.Wizard#addPage(org.eclipse.jface.wizard.IWizardPage)
+     */
+    @Override
+    public void addPage( IWizardPage page )
+    {
+        // skip the SOAPParametersPage if editing an existing data set design
+        if( page instanceof SOAPParametersPage && ! isCreatingNewDesign() )
+            return;
+        
+        super.addPage( page );
+    }
+
+}
diff --git a/plugins/org.eclipse.datatools.enablement.oda.ws.ui/src/org/eclipse/datatools/enablement/oda/ws/ui/wizards/SOAPParametersPage.java b/plugins/org.eclipse.datatools.enablement.oda.ws.ui/src/org/eclipse/datatools/enablement/oda/ws/ui/wizards/SOAPParametersPage.java
new file mode 100644
index 0000000..14f2b43
--- /dev/null
+++ b/plugins/org.eclipse.datatools.enablement.oda.ws.ui/src/org/eclipse/datatools/enablement/oda/ws/ui/wizards/SOAPParametersPage.java
@@ -0,0 +1,545 @@
+/*******************************************************************************
+ * Copyright (c) 2007 Actuate Corporation.
+ * 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:
+ *  Actuate Corporation - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.datatools.enablement.oda.ws.ui.wizards;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import org.eclipse.datatools.connectivity.oda.OdaException;
+import org.eclipse.datatools.connectivity.oda.design.DataSetDesign;
+import org.eclipse.datatools.connectivity.oda.design.ui.wizards.DataSetWizardPage;
+import org.eclipse.datatools.enablement.oda.ws.soap.SOAPParameter;
+import org.eclipse.datatools.enablement.oda.ws.soap.SOAPRequest;
+import org.eclipse.datatools.enablement.oda.ws.ui.i18n.Messages;
+import org.eclipse.datatools.enablement.oda.ws.ui.util.Constants;
+import org.eclipse.datatools.enablement.oda.ws.ui.util.IHelpConstants;
+import org.eclipse.datatools.enablement.oda.ws.ui.util.WSConsole;
+import org.eclipse.datatools.enablement.oda.ws.ui.util.WSUIUtil;
+import org.eclipse.datatools.enablement.oda.ws.util.WSUtil;
+import org.eclipse.jface.viewers.CellEditor;
+import org.eclipse.jface.viewers.CheckStateChangedEvent;
+import org.eclipse.jface.viewers.CheckboxTableViewer;
+import org.eclipse.jface.viewers.ICheckStateListener;
+import org.eclipse.jface.viewers.ILabelProviderListener;
+import org.eclipse.jface.viewers.IStructuredContentProvider;
+import org.eclipse.jface.viewers.ITableLabelProvider;
+import org.eclipse.jface.viewers.TableLayout;
+import org.eclipse.jface.viewers.TextCellEditor;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.jface.viewers.ViewerSorter;
+import org.eclipse.jface.wizard.IWizardPage;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.ScrolledComposite;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Table;
+import org.eclipse.swt.widgets.TableColumn;
+
+/**
+ * This class is NOT intended to be used in edit mode
+ */
+
+public class SOAPParametersPage extends DataSetWizardPage
+{
+
+	private static final String COLUMN_NAME = Messages.getString( "soapParametersPage.column.paramName" );//$NON-NLS-1$ 
+	private static final String COLUMN_DATATYPE = Messages.getString( "soapParametersPage.column.dataType" );//$NON-NLS-1$ 
+
+	private CheckboxTableViewer viewer;
+	private SOAPRequest soapRequest;
+	private String wsQueryText;
+	
+	private boolean modelChanged;
+
+	private static String DEFAULT_MESSAGE = Messages.getString( "soapParametersPage.message.default" );//$NON-NLS-1$
+
+	/**
+	 * 
+	 * @param pageName
+	 */
+	public SOAPParametersPage( String pageName )
+	{
+		super( pageName );
+		setMessage( DEFAULT_MESSAGE );
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.eclipse.datatools.connectivity.oda.design.ui.wizards.DataSetWizardPage#createPageCustomControl(org.eclipse.swt.widgets.Composite)
+	 */
+	public void createPageCustomControl( Composite parent )
+	{
+		setControl( createPageControl( parent ) );
+		initializeControl( );
+		WSUIUtil.setSystemHelp( getControl( ), IHelpConstants.CONEXT_ID_WS_SOAP_PARAMETER );
+	}
+
+	/**
+	 * Creates custom control for user-defined query text.
+	 */
+	private Control createPageControl( Composite parent )
+	{
+		ScrolledComposite sComposite = new ScrolledComposite( parent, SWT.H_SCROLL | SWT.V_SCROLL );
+		sComposite.setLayout( new GridLayout( ) );
+		sComposite.setLayoutData( new GridData( GridData.FILL_BOTH ) );
+		sComposite.setMinWidth( 600 );
+		sComposite.setExpandHorizontal( true );
+
+		Composite composite = new Composite( sComposite, SWT.NONE );
+		GridLayout layout = new GridLayout( 1, false );
+		layout.verticalSpacing = 20;
+		composite.setLayout( layout );
+		GridData layoutData = new GridData( GridData.FILL_BOTH );
+		composite.setLayoutData( layoutData );
+
+		setupParametersComposite( composite );
+		setupSelectionButtons( composite );
+		
+		Point size = composite.computeSize( SWT.DEFAULT, SWT.DEFAULT );
+		composite.setSize( size.x, size.y );
+
+		sComposite.setContent( composite );
+		setControl( sComposite );
+
+		modelChanged = true;
+		
+		return sComposite;
+	}
+
+	private void setupParametersComposite( Composite parent )
+	{
+		createCheckboxTable( parent );
+		setupEditors( );
+	}
+	
+	/**
+	 * Create the "select all" and "deselect all" buttons
+	 * 
+	 * @param parent
+	 */
+	private void setupSelectionButtons( Composite parent )
+	{
+		GridLayout layout = new GridLayout( );
+		Composite btnComposite = new Composite( parent, SWT.NONE );
+		btnComposite.setLayout( layout );
+		layout.numColumns = 3;
+		btnComposite.setLayoutData( new GridData( GridData.FILL_HORIZONTAL ) );
+
+		Label label = new Label( btnComposite, SWT.NONE );
+		label.setLayoutData( new GridData( GridData.FILL_HORIZONTAL ) );
+
+		Button selectAllBtn = new Button( btnComposite, SWT.NONE );
+		selectAllBtn.setText( Messages.getString( "soapParametersPage.button.selectAll" ) ); //$NON-NLS-1$
+		selectAllBtn.addSelectionListener( new SelectionAdapter( ) {
+
+			public void widgetSelected( SelectionEvent e )
+			{
+				if( viewer.getCheckedElements( ).length < viewer.getTable( ).getItemCount( ) )
+				{
+					viewer.setAllChecked( true );
+					saveToModel( );
+					modelChanged = true;
+				}
+			}
+
+		} );
+
+		Button deselectAllBtn = new Button( btnComposite, SWT.NONE );
+		deselectAllBtn.setText( Messages.getString( "soapParametersPage.button.deselectAll" ) ); //$NON-NLS-1$
+		deselectAllBtn.addSelectionListener( new SelectionAdapter( ) {
+
+			public void widgetSelected( SelectionEvent e )
+			{
+				if ( viewer.getCheckedElements( ).length > 0 )
+				{
+					viewer.setAllChecked( false );
+					saveToModel( );
+					modelChanged = true;
+				}
+			}
+
+		} );
+
+		GridData btnGd = new GridData( GridData.CENTER );
+		btnGd.horizontalIndent = 10;
+		btnGd.widthHint = getMaxWidth( deselectAllBtn,
+				getMaxWidth( selectAllBtn, 100 ) );
+		
+		selectAllBtn.setLayoutData( btnGd );
+		deselectAllBtn.setLayoutData( btnGd );
+
+	}
+	
+	private int getMaxWidth( Button button, int size )
+	{
+		int width = button.computeSize( -1, -1 ).x;
+		return width > size ? width : size;
+	}
+
+	private void createCheckboxTable( Composite parent )
+	{
+		final Table table = new Table( parent, SWT.CHECK
+				| SWT.BORDER | SWT.MULTI | SWT.FULL_SELECTION | SWT.H_SCROLL
+				| SWT.V_SCROLL );
+		TableLayout tableLayout = new TableLayout( );
+		table.setLayout( tableLayout );
+		GridData layouData = new GridData( GridData.FILL_BOTH );
+		layouData.heightHint = 400;
+		table.setLayoutData( layouData );
+
+		table.setHeaderVisible( true );
+		table.setLinesVisible( true );
+
+		TableColumn nameColumn = new TableColumn( table, SWT.NONE );
+		nameColumn.setText( COLUMN_NAME );
+		nameColumn.setWidth( 200 );
+		nameColumn.addSelectionListener( new SelectionAdapter( ) {
+
+			public void widgetSelected( SelectionEvent e )
+			{
+				sortParametersTable( );
+				modelChanged = true;
+			}
+
+		} );
+
+		TableColumn dataTypeColumn = new TableColumn( table, SWT.NONE );
+		dataTypeColumn.setText( COLUMN_DATATYPE );
+		dataTypeColumn.setWidth( 200 );
+
+		createCheckBoxTableViewer( table );
+	}
+
+	private void createCheckBoxTableViewer( final Table table )
+	{
+		viewer = new CheckboxTableViewer( table );
+		viewer.setContentProvider( new IStructuredContentProvider( ) {
+
+			public Object[] getElements( Object inputElement )
+			{
+				if ( inputElement == null
+						|| !( inputElement instanceof SOAPParameter[] ) )
+					return new Object[0];
+
+				return (SOAPParameter[]) inputElement;
+			}
+
+			public void inputChanged( Viewer viewer, Object oldInput,
+					Object newInput )
+			{
+			}
+
+			public void dispose( )
+			{
+			}
+		} );
+		viewer.setLabelProvider( new ITableLabelProvider( ) {
+
+			public Image getColumnImage( Object element, int columnIndex )
+			{
+				return null;
+			}
+
+			public String getColumnText( Object element, int columnIndex )
+			{
+				SOAPParameter param = ( (SOAPParameter) element );
+				String value = WSUtil.EMPTY_STRING;
+				switch ( columnIndex )
+				{
+					case 0 :
+						value = param.getName( );
+						break;
+					case 1 :
+						value = WSUtil.EMPTY_STRING;
+						break;
+					case 2 :
+						value = param.getDefaultValue( );
+						break;
+				}
+
+				return value;
+			}
+
+			public void addListener( ILabelProviderListener listener )
+			{
+			}
+
+			public void dispose( )
+			{
+			}
+
+			public boolean isLabelProperty( Object element, String property )
+			{
+				return false;
+			}
+
+			public void removeListener( ILabelProviderListener listener )
+			{
+			}
+		} );
+		viewer.addCheckStateListener( new ICheckStateListener( ) {
+
+			public void checkStateChanged( CheckStateChangedEvent event )
+			{
+				if ( !event.getChecked( )
+						&& event.getElement( ) instanceof SOAPParameter )
+				{
+					( (SOAPParameter) event.getElement( ) ).setDefaultValue( WSUtil.EMPTY_STRING );
+					viewer.refresh( );
+					saveToModel( );
+				}
+				modelChanged = true;
+			}
+
+		} );
+	}
+	
+	/**
+	 * Lexicographically sort the parameters in the table
+	 * 
+	 */
+	private void sortParametersTable( )
+	{
+		if ( viewer.getTable( ).getSortDirection( ) == SWT.UP )
+		{
+			viewer.setSorter( new ParametersViewerSorter( true ) );
+			viewer.getTable( ).setSortDirection( SWT.DOWN );
+		}
+		else
+		{
+			viewer.setSorter( new ParametersViewerSorter( false ) );
+			viewer.getTable( ).setSortDirection( SWT.UP );
+		}
+	}
+
+	private void setupEditors( )
+	{
+		CellEditor[] editors = new CellEditor[3];
+		for ( int i = 0; i < editors.length; i++ )
+		{
+			editors[i] = new TextCellEditor( viewer.getTable( ), SWT.NONE );
+		}
+
+		viewer.setCellEditors( editors );
+		viewer.setColumnProperties( new String[]{
+				COLUMN_NAME, COLUMN_DATATYPE
+		} );
+
+	}
+
+	/**
+	 * Initializes the page control with the last edited data set design.
+	 */
+	private void initializeControl( )
+	{
+		initWSConsole( );
+		initFromModel( );
+		initViewer( true );
+	}
+
+	private void initWSConsole( )
+	{
+		if ( !WSConsole.getInstance( ).isSessionOK( ) )
+			WSConsole.getInstance( ).start( getInitializationDesign( ) );
+	}
+
+	private void initFromModel( )
+	{
+		wsQueryText = WSConsole.getInstance( )
+				.getPropertyValue( Constants.WS_QUERYTEXT );
+	}
+
+	private void initViewer( boolean refreshParameters )
+	{
+		if ( WSUtil.isNull( wsQueryText ) )
+			return;
+
+		soapRequest = new SOAPRequest( wsQueryText );
+		SOAPParameter[] soapParameters = null;
+		
+		if( refreshParameters || WSConsole.getInstance( ).getParameters( ) == null )
+		{
+			soapParameters = soapRequest.getParameters( );
+		}
+		else
+		{
+			soapParameters = WSConsole.getInstance( ).getParameters( );
+		}
+			
+		if ( !WSUtil.isNull( soapParameters ) )
+		{
+			viewer.setInput( soapParameters );
+			for ( int i = 0; i < soapParameters.length; i++ )
+			{
+				viewer.setChecked( soapParameters[i],
+						soapParameters[i].isUsed( ) );
+			}
+		}
+		else
+		{
+			viewer.setInput( new SOAPParameter[0] );
+		}
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.eclipse.datatools.connectivity.oda.design.ui.wizards.DataSetWizardPage#collectDataSetDesign(org.eclipse.datatools.connectivity.oda.design.DataSetDesign)
+	 */
+	protected DataSetDesign collectDataSetDesign( DataSetDesign design )
+	{
+		savePage( design );
+		return design;
+	}
+
+	private void savePage( DataSetDesign dataSetDesign )
+	{
+		// TODO nothing to save
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.eclipse.jface.wizard.WizardPage#canFlipToNextPage()
+	 */
+	public boolean canFlipToNextPage( )
+	{
+		return isPageComplete( );
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.eclipse.jface.wizard.WizardPage#getNextPage()
+	 */
+	public IWizardPage getNextPage( )
+	{
+
+		IWizardPage page = super.getNextPage( );
+		if ( modelChanged )
+		{
+			saveToModel( );
+			if ( page instanceof SOAPRequestPage )
+			{
+				try
+				{
+					( (SOAPRequestPage) page ).refresh( );
+					modelChanged = false;
+				}
+				catch ( OdaException e )
+				{
+					this.setErrorMessage( e.getMessage( ) );
+				}
+			}
+		}
+
+		return page;
+	}
+
+	private void saveToModel( )
+	{
+		WSConsole.getInstance( ).setPropertyValue( Constants.WS_QUERYTEXT,
+				wsQueryText );
+		WSConsole.getInstance( ).setParameters( getSOAPParameters( ) );
+	}
+
+	private SOAPParameter[] getSOAPParameters( )
+	{
+		SOAPParameter[] targets = soapRequest.getParameters( );
+		if ( WSUtil.isNull( targets ) )
+			return targets;
+
+		Object[] candidates = (Object[]) viewer.getCheckedElements( );
+		List manipulated = getManipulatedIndexList( candidates );
+
+		for ( int i = 0; i < targets.length; i++ )
+		{
+			targets[i].setUsed( manipulated.contains( new Integer( targets[i].getId( ) ) ) );
+		}
+
+		return targets;
+	}
+
+	private List getManipulatedIndexList( Object[] soapParameters )
+	{
+		if ( WSUtil.isNull( soapParameters ) || soapParameters.length == 0 )
+			return Collections.EMPTY_LIST;
+
+		List manipulated = new ArrayList( );
+		for ( int i = 0; i < soapParameters.length; i++ )
+			manipulated.add( new Integer( ( (SOAPParameter) soapParameters[i] ).getId( ) ) );
+
+		return manipulated;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.eclipse.datatools.connectivity.oda.design.ui.wizards.DataSetWizardPage#cleanup()
+	 */
+	protected void cleanup( )
+	{
+		WSConsole.getInstance( ).terminateSession( );
+	}
+
+	void refresh( boolean refreshParameters ) throws OdaException
+	{
+		wsQueryText = WSConsole.getInstance( ).getTemplate( );
+		initViewer( refreshParameters );
+	}
+	
+	private class ParametersViewerSorter extends ViewerSorter
+	{
+		private boolean descent;
+		
+		public ParametersViewerSorter( boolean descent )
+		{
+			this.descent = descent;
+		}
+		
+		public int compare( Viewer viewer, Object o1, Object o2 )
+		{
+			assert !( o1 instanceof SOAPParameter ) || !( o2 instanceof SOAPParameter );
+
+			int result = ( (SOAPParameter) o1 ).getName( )
+					.compareTo( ( (SOAPParameter) o2 ).getName( ) );
+			if ( result == 0 )
+				return 0;
+			
+			if ( result > 0 )
+			{
+				if ( descent )
+					return -1;
+				else
+					return 1;
+			}
+			else
+			{
+				if ( descent )
+					return 1;
+				else
+					return -1;
+			}
+		}
+	}
+
+}
diff --git a/plugins/org.eclipse.datatools.enablement.oda.ws.ui/src/org/eclipse/datatools/enablement/oda/ws/ui/wizards/SOAPRequestPage.java b/plugins/org.eclipse.datatools.enablement.oda.ws.ui/src/org/eclipse/datatools/enablement/oda/ws/ui/wizards/SOAPRequestPage.java
new file mode 100644
index 0000000..2712562
--- /dev/null
+++ b/plugins/org.eclipse.datatools.enablement.oda.ws.ui/src/org/eclipse/datatools/enablement/oda/ws/ui/wizards/SOAPRequestPage.java
@@ -0,0 +1,882 @@
+/*******************************************************************************

+ * Copyright (c) 2007 Actuate Corporation.

+ * 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:

+ *  Actuate Corporation - initial API and implementation

+ *******************************************************************************/

+

+package org.eclipse.datatools.enablement.oda.ws.ui.wizards;

+

+import org.eclipse.core.runtime.IStatus;

+import org.eclipse.core.runtime.Status;

+import org.eclipse.datatools.connectivity.oda.OdaException;

+import org.eclipse.datatools.connectivity.oda.design.DataSetDesign;

+import org.eclipse.datatools.connectivity.oda.design.ui.wizards.DataSetWizardPage;

+import org.eclipse.datatools.enablement.oda.ws.soap.SOAPParameter;

+import org.eclipse.datatools.enablement.oda.ws.soap.SOAPRequest;

+import org.eclipse.datatools.enablement.oda.ws.ui.i18n.Messages;

+import org.eclipse.datatools.enablement.oda.ws.ui.util.Constants;

+import org.eclipse.datatools.enablement.oda.ws.ui.util.IHelpConstants;

+import org.eclipse.datatools.enablement.oda.ws.ui.util.WSConsole;

+import org.eclipse.datatools.enablement.oda.ws.ui.util.WSUIUtil;

+import org.eclipse.datatools.enablement.oda.ws.util.WSUtil;

+import org.eclipse.jface.dialogs.MessageDialog;

+import org.eclipse.jface.dialogs.StatusDialog;

+import org.eclipse.jface.dialogs.TrayDialog;

+import org.eclipse.jface.resource.JFaceResources;

+import org.eclipse.jface.text.Document;

+import org.eclipse.jface.text.ITextOperationTarget;

+import org.eclipse.jface.text.IUndoManager;

+import org.eclipse.jface.text.TextViewerUndoManager;

+import org.eclipse.jface.text.source.SourceViewer;

+import org.eclipse.jface.text.source.SourceViewerConfiguration;

+import org.eclipse.jface.viewers.CellEditor;

+import org.eclipse.jface.viewers.ILabelProviderListener;

+import org.eclipse.jface.viewers.IStructuredContentProvider;

+import org.eclipse.jface.viewers.ITableLabelProvider;

+import org.eclipse.jface.viewers.TableLayout;

+import org.eclipse.jface.viewers.TableViewer;

+import org.eclipse.jface.viewers.TextCellEditor;

+import org.eclipse.jface.viewers.Viewer;

+import org.eclipse.jface.window.Window;

+import org.eclipse.jface.wizard.IWizardPage;

+import org.eclipse.swt.SWT;

+import org.eclipse.swt.custom.ScrolledComposite;

+import org.eclipse.swt.custom.StyledText;

+import org.eclipse.swt.events.KeyAdapter;

+import org.eclipse.swt.events.KeyEvent;

+import org.eclipse.swt.events.ModifyEvent;

+import org.eclipse.swt.events.ModifyListener;

+import org.eclipse.swt.events.MouseAdapter;

+import org.eclipse.swt.events.MouseEvent;

+import org.eclipse.swt.events.SelectionAdapter;

+import org.eclipse.swt.events.SelectionEvent;

+import org.eclipse.swt.graphics.Image;

+import org.eclipse.swt.graphics.Point;

+import org.eclipse.swt.layout.GridData;

+import org.eclipse.swt.layout.GridLayout;

+import org.eclipse.swt.widgets.Button;

+import org.eclipse.swt.widgets.Composite;

+import org.eclipse.swt.widgets.Control;

+import org.eclipse.swt.widgets.Label;

+import org.eclipse.swt.widgets.Table;

+import org.eclipse.swt.widgets.TableColumn;

+import org.eclipse.swt.widgets.Text;

+import org.eclipse.ui.PlatformUI;

+

+/**

+ * 

+ */

+

+public class SOAPRequestPage extends DataSetWizardPage

+{

+

+	// parameters for page, different from soapParameters

+	private SOAPParameter[] parameters;

+	private static String DEFAULT_MESSAGE = Messages.getString( "soapRequestPage.message.defaultTitle" );//$NON-NLS-1$

+	private boolean saved = false;

+	

+	protected final String COLUMN_NAME = Messages.getString( "parameterInputDialog.column.name" );//$NON-NLS-1$ 

+	protected final String COLUMN_DATATYPE = Messages.getString( "parameterInputDialog.column.type" );//$NON-NLS-1$ 

+	protected final String COLUMN_DEFAULTVALUE = Messages.getString( "parameterInputDialog.column.defaultValue" );//$NON-NLS-1$ 

+

+	private Button paramBtn;

+	

+	private SOAPRequest soapRequest;

+	

+	private SourceViewer templateSourceViewer;

+	private StyledText templateText;

+

+	

+	public SOAPRequestPage( String pageName )

+	{

+		super( pageName );

+		setMessage( DEFAULT_MESSAGE );

+	}

+

+	/*

+	 * (non-Javadoc)

+	 * 

+	 * @see org.eclipse.datatools.connectivity.oda.design.ui.wizards.DataSetWizardPage#createPageCustomControl(org.eclipse.swt.widgets.Composite)

+	 */

+	public void createPageCustomControl( Composite parent )

+	{

+		setControl( createPageControl( parent ) );

+		initializeControl( );

+		WSUIUtil.setSystemHelp( getControl( ), IHelpConstants.CONEXT_ID_WS_SOAP_REQUEST );

+	}

+

+	/**

+	 * Creates custom control for user-defined query text.

+	 */

+	private Control createPageControl( Composite parent )

+	{

+		ScrolledComposite sComposite = new ScrolledComposite( parent, SWT.H_SCROLL | SWT.V_SCROLL );

+		sComposite.setLayout( new GridLayout( ) );

+		sComposite.setLayoutData( new GridData( GridData.FILL_BOTH ) );

+		sComposite.setMinWidth( 600 );

+		sComposite.setExpandHorizontal( true );

+

+		Composite composite = new Composite( sComposite, SWT.NONE );

+		GridLayout layout = new GridLayout( 2, false );

+		composite.setLayout( layout );

+		GridData layoutData = new GridData( GridData.FILL_BOTH );

+		composite.setLayoutData( layoutData );

+

+		Label prompt = new Label( composite, SWT.NONE );

+		prompt.setText( Messages.getString( "soapRequestPage.label.prompt" ) ); //$NON-NLS-1$

+		GridData labelGd = new GridData( );

+		labelGd.horizontalSpan = 2;

+		prompt.setLayoutData( labelGd );

+		

+		setupTemplateTextArea( composite );

+		setupButtonComposite( composite );

+

+		Point size = composite.computeSize( SWT.DEFAULT, SWT.DEFAULT );

+		composite.setSize( size.x, size.y );

+

+		sComposite.setContent( composite );

+		setControl( sComposite );

+

+		return sComposite;

+	}

+

+	private void setupTemplateTextArea( Composite parent )

+	{

+		templateSourceViewer = new SourceViewer( parent, null, SWT.BORDER

+				| SWT.LEFT_TO_RIGHT | SWT.MULTI | SWT.V_SCROLL | SWT.H_SCROLL );

+		templateSourceViewer.configure( new SourceViewerConfiguration( ) );

+		templateText = templateSourceViewer.getTextWidget( );

+		GridData layoutData = new GridData( SWT.FILL, SWT.FILL, true, true );

+		layoutData.heightHint = 400;

+		templateText.setLayoutData( layoutData );

+		templateText.setFont(JFaceResources.getFont(JFaceResources.TEXT_FONT ));

+		templateText.addModifyListener( new ModifyListener( ){

+

+			public void modifyText( ModifyEvent arg0 )

+			{

+				validatePageStatus( );				

+			}

+			

+		});

+

+		templateSourceViewer.setDocument( new Document( ) );

+		

+		IUndoManager undoManager = new TextViewerUndoManager( 10 );

+		undoManager.connect( templateSourceViewer );

+		templateSourceViewer.setUndoManager( undoManager );

+

+		templateText.addKeyListener( new KeyAdapter( ) {

+

+			private boolean isRedoKeyPress( KeyEvent e )

+			{

+				return ( ( e.stateMask & SWT.CONTROL ) > 0 )

+						&& ( ( e.keyCode == 'y' ) || ( e.keyCode == 'Y' ) );

+			}

+

+			private boolean isUndoKeyPress( KeyEvent e )

+			{

+				return ( ( e.stateMask & SWT.CONTROL ) > 0 )

+						&& ( ( e.keyCode == 'z' ) || ( e.keyCode == 'Z' ) );

+			}

+

+			public void keyPressed( KeyEvent e )

+			{

+				if ( isUndoKeyPress( e ) )

+				{

+					templateSourceViewer.doOperation( ITextOperationTarget.UNDO );

+					validatePageStatus( );				

+				}

+				else if ( isRedoKeyPress( e ) )

+				{

+					templateSourceViewer.doOperation( ITextOperationTarget.REDO );

+					validatePageStatus( );				

+				}

+			}

+

+		} );

+

+	}

+

+	private void setupButtonComposite( Composite parent )

+	{

+		Composite composite = new Composite( parent, SWT.NONE );

+		composite.setLayout( new GridLayout( 1, false ) );

+		GridData layoutData = new GridData( GridData.HORIZONTAL_ALIGN_FILL

+				| GridData.VERTICAL_ALIGN_FILL );

+		composite.setLayoutData( layoutData );

+

+		Button templateBtn = new Button( composite, SWT.NONE );

+		templateBtn.setText( Messages.getString( "soapRequestPage.button.regenerateTemplate" ) ); //$NON-NLS-1$

+		layoutData = new GridData( );

+		templateBtn.setLayoutData( layoutData );

+		templateBtn.addSelectionListener( new SelectionAdapter( ) {

+

+			public void widgetSelected( SelectionEvent e )

+			{

+				if ( MessageDialog.openConfirm( null,

+						Messages.getString( "soapRequestPage.title.regenerateTemplate" ), //$NON-NLS-1$

+						Messages.getString( "soapRequestPage.message.regenerateTemplate" ) ) )

+					try

+					{

+						regenerateTemplate( );

+					}

+					catch ( OdaException e1 )

+					{

+						setErrorMessage( e1.getMessage( ) );

+					}

+			}

+

+		} );

+

+		int width = getMaxWidth( templateBtn, 60 );

+

+		paramBtn = new Button( composite, SWT.NONE );

+		paramBtn.setText( Messages.getString( "soapRequestPage.button.insertParameter" ) );//$NON-NLS-1$

+		layoutData = new GridData( );

+		layoutData.widthHint = 120;

+		paramBtn.setLayoutData( layoutData );

+		paramBtn.setEnabled( parameters != null && parameters.length > 0 );

+

+		paramBtn.addSelectionListener( new SelectionAdapter( ) {

+

+			/*

+			 * (non-Javadoc)

+			 * 

+			 * @see org.eclipse.swt.events.SelectionAdapter#widgetSelected(org.eclipse.swt.events.SelectionEvent)

+			 */

+			public void widgetSelected( SelectionEvent e )

+			{

+				ParameterInputDialog dlg = new ParameterInputDialog( );

+				if ( dlg.open( ) == Window.OK )

+					parameters = updateSOAPParameters( );

+			}

+

+		} );

+		width = getMaxWidth( paramBtn, width );

+

+		Button clearBtn = new Button( composite, SWT.NONE );

+		clearBtn.setText( Messages.getString( "soapRequestPage.button.clear" ) ); //$NON-NLS-1$

+		layoutData = new GridData( );

+		layoutData.widthHint = 120;

+		clearBtn.setLayoutData( layoutData );

+		clearBtn.addSelectionListener( new SelectionAdapter( ) {

+

+			public void widgetSelected( SelectionEvent e )

+			{

+				templateText.setText( WSUtil.EMPTY_STRING );

+				validatePageStatus( );

+				templateText.setFocus( );

+			}

+

+		} );

+

+		width = getMaxWidth( clearBtn, width );

+		GridData gd = new GridData( );

+		gd.widthHint = width;

+		templateBtn.setLayoutData( gd );

+		paramBtn.setLayoutData( gd );

+		clearBtn.setLayoutData( gd );

+

+	}

+

+	private int getMaxWidth( Button button, int width )

+	{

+		int length = button.computeSize( SWT.DEFAULT, SWT.DEFAULT ).x;

+		return length > width ? length : width;

+	}

+

+	private void regenerateTemplate( ) throws OdaException

+	{

+		templateText.setText( WSConsole.getInstance( ).getTemplate( ) );

+		parameters = WSConsole.getInstance( ).getParameters( );

+		saved = false;

+	}

+

+	/**

+	 * Initializes the page control with the last edited data set design.

+	 */

+	private void initializeControl( )

+	{

+		initWSConsole( );

+		initFromModel( );

+		initParameters( );

+	}

+

+	private void initWSConsole( )

+	{

+		if ( !WSConsole.getInstance( ).isSessionOK( ) )

+			WSConsole.getInstance( ).start( getInitializationDesign( ) );

+	}

+

+	private void initFromModel( )

+	{

+		String wsQueryText = WSConsole.getInstance( )

+				.getPropertyValue( Constants.WS_QUERYTEXT );

+		if ( wsQueryText != null )

+			templateText.setText( wsQueryText );

+		

+		parameters = WSConsole.getInstance( ).getParameters( );

+		initParameters( );

+		saved = false;

+	}

+

+	private void initParameters( )

+	{

+		soapRequest = new SOAPRequest( templateText.getText( ) );

+		mergeParameters( );

+		SOAPParameter[] params = soapRequest.getParameters( );

+		paramBtn.setEnabled( params != null && params.length > 0 );

+	}

+

+	private void mergeParameters( )

+	{

+		SOAPParameter[] soapParameters = soapRequest.getParameters( );

+		for ( int i = 0; parameters != null && i < parameters.length; i++ )

+		{

+			if ( !WSUtil.isNull( parameters[i] ) )

+			{

+				int pos = -1;

+				for ( int j = 0; soapParameters != null

+						&& j < soapParameters.length; j++ )

+				{

+					if ( !WSUtil.isNull( soapParameters[j].getName( ) )

+							&& soapParameters[j].getName( )

+									.equals( parameters[i].getName( ) ) )

+					{

+						pos = j;

+						break;

+					}

+				}

+				if ( pos != -1 )

+					soapParameters[pos].setDefaultValue( parameters[i].getDefaultValue( ) );

+			}

+		}

+	}

+

+	SOAPParameter[] updateSOAPParameters( )

+	{

+		return soapRequest.getParameters( );

+	}

+

+	/*

+	 * (non-Javadoc)

+	 * 

+	 * @see org.eclipse.datatools.connectivity.oda.design.ui.wizards.DataSetWizardPage#collectDataSetDesign(org.eclipse.datatools.connectivity.oda.design.DataSetDesign)

+	 */

+	protected DataSetDesign collectDataSetDesign( DataSetDesign design )

+	{

+		savePage( design );

+		WSUIUtil.savePage( design );

+		return design;

+	}

+

+	/**

+	 * Saves the user-defined value in this page, and updates the specified

+	 * dataSetDesign with the latest design definition.

+	 */

+	private void savePage( DataSetDesign dataSetDesign )

+	{

+		if ( !WSConsole.getInstance( ).isSessionOK( ) )

+			return;

+

+		if ( isControlCreated( ) && !saved )

+			saveToModel( );

+

+		dataSetDesign.setQueryText( WSConsole.getInstance( )

+				.getPropertyValue( Constants.WS_QUERYTEXT ) );

+		// parametes at this point has already be applied to model which will in

+		// turn be applied to dataSetDesign later together with xmlQueryText

+	}

+

+	/*

+	 * (non-Javadoc)

+	 * 

+	 * @see org.eclipse.datatools.connectivity.oda.design.ui.wizards.DataSetWizardPage#refresh(org.eclipse.datatools.connectivity.oda.design.DataSetDesign)

+	 */

+	protected void refresh( DataSetDesign dataSetDesign )

+	{

+		super.refresh( dataSetDesign );

+

+		initFromModel( );

+	}

+

+	void refresh( ) throws OdaException

+	{

+		String value = WSConsole.getInstance( ).manipulateTemplate( );

+		if ( value != null )

+			templateText.setText( value );

+		

+		parameters = WSConsole.getInstance( ).getParameters( );

+		initParameters( );

+		saved = false;

+	}

+

+	/*

+	 * (non-Javadoc)

+	 * 

+	 * @see org.eclipse.jface.wizard.WizardPage#canFlipToNextPage()

+	 */

+	public boolean canFlipToNextPage( )

+	{

+		return isPageComplete( );

+	}

+

+	/*

+	 * (non-Javadoc)

+	 * 

+	 * @see org.eclipse.jface.wizard.WizardPage#getNextPage()

+	 */

+	public IWizardPage getNextPage( )

+	{

+		saveToModel( );

+		return super.getNextPage( );

+	}

+

+	/*

+	 * (non-Javadoc)

+	 * 

+	 * @see org.eclipse.datatools.connectivity.oda.design.ui.wizards.DataSetWizardPage#canLeave()

+	 */

+	protected boolean canLeave( )

+	{

+		saveToModel( );

+		return super.canLeave( );

+	}

+

+	private void saveToModel( )

+	{

+		if( this.templateText == null )

+			return;

+		

+		String templateContent = templateText.getText( ) == null

+				? WSUtil.EMPTY_STRING : templateText.getText( );

+		WSConsole.getInstance( ).setPropertyValue( Constants.WS_QUERYTEXT,

+				templateContent );

+

+		WSConsole.getInstance( ).updateParameters( parameters );

+		saved = true;

+	}

+

+	/*

+	 * (non-Javadoc)

+	 * 

+	 * @see org.eclipse.datatools.connectivity.oda.design.ui.wizards.DataSetWizardPage#cleanup()

+	 */

+	protected void cleanup( )

+	{

+		WSConsole.getInstance( ).terminateSession( );

+	}

+

+	private void validatePageStatus( )

+	{

+		boolean valid = true;

+		if ( templateText.getText( ).trim( ).length( ) == 0 )

+		{

+			valid = false;

+		}

+		setPageComplete( valid );

+	}

+

+	class ParameterInputDialog extends StatusDialog

+	{

+

+		private TableViewer viewer;

+		private Button editBtn;

+		/**

+		 * 

+		 */

+		public ParameterInputDialog( )

+		{

+			super( PlatformUI.getWorkbench( ).getDisplay( ).getActiveShell( ) );

+		}

+

+		/*

+		 * (non-Javadoc)

+		 * 

+		 * @see org.eclipse.jface.dialogs.StatusDialog#create()

+		 */

+		public void create( )

+		{

+			super.create( );

+

+			Point pt = getShell( ).computeSize( -1, -1 );

+			pt.x = Math.max( pt.x, 400 );

+			pt.y = Math.max( pt.y, 200 );

+			getShell( ).setSize( pt );

+			getShell( ).setText( getTitle( ) );

+		}

+

+		/*

+		 * (non-Javadoc)

+		 * 

+		 * @see org.eclipse.jface.dialogs.Dialog#createDialogArea(org.eclipse.swt.widgets.Composite)

+		 */

+		protected Control createDialogArea( Composite parent )

+		{

+			Composite composite = (Composite) super.createDialogArea( parent );

+			GridLayout layout = new GridLayout( 1, false );

+			layout.marginHeight = 10;

+			layout.marginWidth = 10;

+			layout.numColumns = 2;

+			composite.setLayout( layout );

+			composite.setLayout( layout );

+

+			createCustomControls( composite );

+			viewer.setInput( soapRequest.getParameters( ) );

+			WSUIUtil.setSystemHelp( composite, IHelpConstants.CONEXT_ID_WS_SOAP_REQUEST_PARMETER );

+			return composite;

+		}

+

+		private void createCustomControls( Composite parent )

+		{

+			createTableViewer( parent );

+			createBtnComposite( parent );

+		}

+

+		private void createBtnComposite( Composite parent )

+		{

+			editBtn = new Button( parent, SWT.NONE );

+			editBtn.setText( Messages.getString( "parameterInputDialog.button.edit" ) );

+			

+			GridData btnData = new GridData( GridData.VERTICAL_ALIGN_CENTER );

+			btnData.horizontalIndent = 5;

+			editBtn.setLayoutData( btnData );

+			editBtn.setEnabled( viewer.getTable( ).getSelectionCount( ) == 1 );

+			editBtn.addSelectionListener( new SelectionAdapter(){

+				

+				public void widgetSelected( SelectionEvent e )

+				{

+					doEdit( );

+				}

+			});

+		}

+		

+		private void createTableViewer( Composite parent )

+		{

+			final Table table = new Table( parent, SWT.BORDER

+					| SWT.FULL_SELECTION );

+			TableLayout tableLayout = new TableLayout( );

+			table.setLayout( tableLayout );

+			GridData layouData = new GridData( GridData.FILL_BOTH );

+			table.setLayoutData( layouData );

+

+			table.setHeaderVisible( true );

+			table.setLinesVisible( true );

+

+			TableColumn column0 = new TableColumn( table, SWT.NONE );

+			column0.setText( COLUMN_NAME );

+			column0.setWidth( 150 );

+

+			TableColumn column1 = new TableColumn( table, SWT.NONE );

+			column1.setText( COLUMN_DATATYPE );

+			column1.setWidth( 100 );

+

+			TableColumn column2 = new TableColumn( table, SWT.NONE );

+			column2.setText( COLUMN_DEFAULTVALUE );

+			column2.setWidth( 150 );

+

+			viewer = new TableViewer( table );

+			viewer.setContentProvider( new IStructuredContentProvider( ) {

+

+				public Object[] getElements( Object inputElement )

+				{

+					if ( inputElement == null

+							|| !( inputElement instanceof SOAPParameter[] ) )

+						return new Object[0];

+

+					return (SOAPParameter[]) inputElement;

+				}

+

+				public void inputChanged( Viewer viewer, Object oldInput,

+						Object newInput )

+				{

+				}

+

+				public void dispose( )

+				{

+				}

+			} );

+			viewer.setLabelProvider( new ITableLabelProvider( ) {

+

+				public Image getColumnImage( Object element, int columnIndex )

+				{

+					return null;

+				}

+

+				public String getColumnText( Object element, int columnIndex )

+				{

+					SOAPParameter param = ( (SOAPParameter) element );

+					String value = WSUtil.EMPTY_STRING;

+					switch ( columnIndex )

+					{

+						case 0 :

+							value = param.getName( );

+							break;

+						case 1 :

+							value = WSUtil.EMPTY_STRING;

+							break;

+						case 2 :

+							value = param.getDefaultValue( );

+							break;

+					}

+

+					return value;

+				}

+

+				public void addListener( ILabelProviderListener listener )

+				{

+				}

+

+				public void dispose( )

+				{

+				}

+

+				public boolean isLabelProperty( Object element, String property )

+				{

+					return false;

+				}

+

+				public void removeListener( ILabelProviderListener listener )

+				{

+				}

+			} );

+			setupEditors( );

+		}

+

+		private void setupEditors( )

+		{

+			CellEditor[] editors = new CellEditor[3];

+			for ( int i = 0; i < editors.length; i++ )

+			{

+				editors[i] = new TextCellEditor( viewer.getTable( ), SWT.NONE );

+			}

+

+			viewer.setCellEditors( editors );

+			viewer.setColumnProperties( new String[]{

+					COLUMN_NAME, COLUMN_DATATYPE, COLUMN_DEFAULTVALUE

+			} );

+

+			viewer.getTable( ).addSelectionListener( new SelectionAdapter( ) {

+

+				public void widgetSelected( SelectionEvent e )

+				{

+					editBtn.setEnabled( viewer.getTable( ).getSelectionCount( ) == 1 );

+				}

+

+			} );

+			

+			viewer.getTable( ).addMouseListener( new MouseAdapter( ) {

+

+				public void mouseDoubleClick( MouseEvent e )

+				{

+					doEdit( );

+				}

+				

+			} );

+

+		}

+		

+		private void doEdit( )

+		{

+			int index = viewer.getTable( ).getSelectionIndex( );

+			if ( index == -1 )

+				return;

+

+			Object data = viewer.getTable( ).getItem( index ).getData( );

+			if ( data instanceof SOAPParameter )

+			{

+				SOAPParameter soapParameter = (SOAPParameter) data;

+				ParameterEditDialog dialog = new ParameterEditDialog( soapParameter );

+				if ( dialog.open( ) == Window.OK )

+				{

+					soapParameter = dialog.getModifiedSOAPParameter( );

+					viewer.refresh( );

+				}

+			}

+			viewer.getTable( ).setSelection( -1 );

+			editBtn.setEnabled( false );

+		}

+

+	}

+	

+	class ParameterEditDialog extends TrayDialog

+	{

+		final private static String COLON = ":"; //$NON-NLS-1$

+		final private static String EMPTY_STRING = ""; //$NON-NLS-1$

+		private String DEFAULT_TITLE = Messages.getString( "soapRequestPage.paramEditDialog.title" ); //$NON-NLS-1$

+		private String defaultValue;

+		private Text defualtValueText;

+		

+		private  SOAPParameter soapParameter;

+		

+		protected ParameterEditDialog( SOAPParameter soapParameter )

+		{

+			super( PlatformUI.getWorkbench( ).getDisplay( ).getActiveShell( ) );

+

+			this.soapParameter = soapParameter;

+			if ( soapParameter.getDefaultValue( ) == null

+					|| soapParameter.getDefaultValue( ).trim( ).length( ) == 0 )

+			{

+				defaultValue = EMPTY_STRING;

+			}

+			else

+			{

+				defaultValue = soapParameter.getDefaultValue( );

+			}

+		}

+

+		/*

+		 * (non-Javadoc)

+		 * 

+		 * @see org.eclipse.jface.window.Window#create()

+		 */

+		public void create( )

+		{

+			super.create( );

+

+			Point pt = getShell( ).computeSize( -1, -1 );

+			pt.x = Math.max( pt.x, 300 );

+			pt.y = Math.max( pt.y, 200 );

+			getShell( ).setSize( pt );

+			getShell( ).setText( getTitle( ) );

+		}

+

+		protected String getTitle( )

+		{

+			return DEFAULT_TITLE;

+		}

+

+		/*

+		 * (non-Javadoc)

+		 * 

+		 * @see org.eclipse.jface.dialogs.Dialog#createDialogArea(org.eclipse.swt.widgets.Composite)

+		 */

+		protected Control createDialogArea( Composite parent )

+		{

+			Composite composite = new Composite( parent, SWT.NONE );

+			GridLayout layout = new GridLayout( );

+			layout.marginTop = 15;

+			layout.marginRight = 10;

+			layout.marginLeft = 10;

+			layout.marginBottom = 20;

+			layout.numColumns = 2;

+			layout.verticalSpacing = 15;

+			composite.setLayout( layout );

+			composite.setLayoutData( new GridData( GridData.FILL_BOTH ) );

+

+			createCustomControls( composite );

+			

+			WSUIUtil.setSystemHelp( composite, IHelpConstants.CONEXT_ID_WS_SOAP_REQUEST_PARMETER_PROPERTIES );

+			return composite;

+		}

+

+		/**

+		 * Create customized controls

+		 * 

+		 * @param parent

+		 */

+		protected void createCustomControls( Composite parent )

+		{

+			Label columnName = new Label( parent, SWT.NONE );

+			columnName.setText( COLUMN_NAME + COLON );

+

+			GridData textGd = new GridData( GridData.FILL_HORIZONTAL );

+			textGd.widthHint = 180;

+			Text columnNameText = new Text( parent, SWT.BORDER );

+			columnNameText.setText( this.soapParameter.getName( ) );

+			columnNameText.setLayoutData( textGd );

+			columnNameText.setEnabled( false );

+

+			Label columnType = new Label( parent, SWT.NONE );

+			columnType.setText( COLUMN_DATATYPE + COLON );

+

+			Text columnTypeText = new Text( parent, SWT.BORDER );

+			columnTypeText.setText( EMPTY_STRING );

+			columnTypeText.setLayoutData( textGd );

+			columnTypeText.setEnabled( false );

+

+			Label defualtValue = new Label( parent, SWT.NONE );

+			defualtValue.setText( COLUMN_DEFAULTVALUE + COLON );

+

+			defualtValueText = new Text( parent, SWT.BORDER );

+			if ( defaultValue != null )

+			{

+				defualtValueText.setText( defaultValue );

+			}

+			

+			defualtValueText.setLayoutData( textGd );

+			defualtValueText.addModifyListener( new ModifyListener( ) {

+

+				public void modifyText( ModifyEvent e )

+				{

+					defaultValue = defualtValueText.getText( );

+				}

+

+			} );

+			

+			int maxWidth = getMaxWidth( columnName, 100 );

+			maxWidth = getMaxWidth( columnType, maxWidth );

+			maxWidth = getMaxWidth( defualtValue, maxWidth );

+			

+			GridData labelGd = new GridData( );

+			labelGd.widthHint = maxWidth;

+			columnName.setLayoutData( labelGd );

+			columnType.setLayoutData( labelGd );

+			defualtValue.setLayoutData( labelGd );

+			

+		}

+		

+		private int getMaxWidth( Control control, int size )

+		{

+			int width = control.computeSize( -1, -1 ).x;

+			return width > size ? width : size;

+		}

+

+		protected SOAPParameter getModifiedSOAPParameter( )

+		{

+			this.soapParameter.setDefaultValue( defaultValue );

+			return this.soapParameter;

+		}

+

+		/*

+		 * (non-Javadoc)

+		 * 

+		 * @see org.eclipse.jface.dialogs.Dialog#cancelPressed()

+		 */

+		protected void cancelPressed( )

+		{

+			super.cancelPressed( );

+		}

+

+		/**

+		 * 

+		 * @return

+		 */

+		protected Status getOKStatus( )

+		{

+			return getMiscStatus( IStatus.OK, "" ); //$NON-NLS-1$

+		}

+

+		/**

+		 * 

+		 * @param severity

+		 * @param message

+		 * @return

+		 */

+		protected Status getMiscStatus( int severity, String message )

+		{

+			return new Status( severity,

+					PlatformUI.PLUGIN_ID,

+					IStatus.OK,

+					message,

+					null );

+		}

+		

+	}

+

+}

diff --git a/plugins/org.eclipse.datatools.enablement.oda.ws.ui/src/org/eclipse/datatools/enablement/oda/ws/ui/wizards/SOAPResponsePage.java b/plugins/org.eclipse.datatools.enablement.oda.ws.ui/src/org/eclipse/datatools/enablement/oda/ws/ui/wizards/SOAPResponsePage.java
new file mode 100644
index 0000000..1c01636
--- /dev/null
+++ b/plugins/org.eclipse.datatools.enablement.oda.ws.ui/src/org/eclipse/datatools/enablement/oda/ws/ui/wizards/SOAPResponsePage.java
@@ -0,0 +1,688 @@
+/*******************************************************************************
+ * Copyright (c) 2007 Actuate Corporation.
+ * 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:
+ *  Actuate Corporation - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.datatools.enablement.oda.ws.ui.wizards;
+
+import org.eclipse.datatools.connectivity.oda.OdaException;
+import org.eclipse.datatools.connectivity.oda.design.DataSetDesign;
+import org.eclipse.datatools.connectivity.oda.design.ui.wizards.DataSetWizardPage;
+import org.eclipse.datatools.enablement.oda.ws.ui.i18n.Messages;
+import org.eclipse.datatools.enablement.oda.ws.ui.util.Constants;
+import org.eclipse.datatools.enablement.oda.ws.ui.util.IHelpConstants;
+import org.eclipse.datatools.enablement.oda.ws.ui.util.WSConsole;
+import org.eclipse.datatools.enablement.oda.ws.ui.util.WSUIUtil;
+import org.eclipse.datatools.enablement.oda.ws.util.WSUtil;
+import org.eclipse.jface.dialogs.IMessageProvider;
+import org.eclipse.jface.wizard.IWizardPage;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.ScrolledComposite;
+import org.eclipse.swt.events.ModifyEvent;
+import org.eclipse.swt.events.ModifyListener;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.FileDialog;
+import org.eclipse.swt.widgets.Group;
+import org.eclipse.swt.widgets.Text;
+import org.eclipse.ui.PlatformUI;
+
+/**
+ * 
+ */
+
+public class SOAPResponsePage extends DataSetWizardPage
+{
+
+	private transient Button dftXSDRadio;
+	private transient Button resXSDRadio;
+	private transient Button extXSDRadio;
+	private transient Button dftXMLRadio;
+	private transient Button extXMLRadio;
+
+	private Button XSDBrowseBtn, connectBtn, browseXMLBtn;
+
+	private transient Text xmlFileURI;
+	private transient Text xsdFileURI;
+	private transient Text soapEndPoint;
+
+	private boolean saved = false;
+	private boolean initialized = false;
+
+	/**
+	 * 
+	 * @param pageName
+	 */
+	public SOAPResponsePage( String pageName )
+	{
+		super( pageName );
+		setMessage( DEFAULT_MESSAGE );
+	}
+
+	private static String DEFAULT_MESSAGE = Messages.getString( "soapResponsePage.message.default" ); //$NON-NLS-1$
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.eclipse.datatools.connectivity.oda.design.ui.wizards.DataSetWizardPage#createPageCustomControl(org.eclipse.swt.widgets.Composite)
+	 */
+	public void createPageCustomControl( Composite parent )
+	{
+		setControl( createPageControl( parent ) );
+		initializeControl( );
+		WSUIUtil.setSystemHelp( getControl( ), IHelpConstants.CONEXT_ID_WS_SOAP_RESPONSE );
+		initialized = true;
+	}
+
+	private Control createPageControl( Composite parent )
+	{
+		ScrolledComposite sComposite = new ScrolledComposite( parent,
+				SWT.H_SCROLL | SWT.V_SCROLL );
+		sComposite.setLayout( new GridLayout( ) );
+		sComposite.setLayoutData( new GridData( GridData.FILL_BOTH ) );
+		sComposite.setMinWidth( 600 );
+		sComposite.setExpandHorizontal( true );
+
+		Composite composite = new Composite( sComposite, SWT.NONE );
+		GridLayout layout = new GridLayout( 1, false );
+		layout.verticalSpacing = 20;
+		composite.setLayout( layout );
+
+		GridData layoutData = new GridData( GridData.HORIZONTAL_ALIGN_FILL
+				| GridData.VERTICAL_ALIGN_FILL );
+		composite.setLayoutData( layoutData );
+
+		setupXSDGroup( composite );
+		setupXMLGroup( composite );
+
+		Point size = composite.computeSize( SWT.DEFAULT, SWT.DEFAULT );
+		composite.setSize( size.x, size.y );
+
+		sComposite.setContent( composite );
+		setControl( sComposite );
+
+		return sComposite;
+	}
+
+	private void setupXSDGroup( Composite parent )
+	{
+		Group group = new Group( parent, SWT.SHADOW_ETCHED_IN );
+		group.setText( Messages.getString( "soapResponsePage.group.schema" ) );//$NON-NLS-1$
+		group.setLayout( new GridLayout( 3, false ) );
+		GridData layoutData = new GridData( GridData.FILL_HORIZONTAL );
+		group.setLayoutData( layoutData );
+
+		setupDFTXSDRadio( group );
+		setupRESXSDRadio( group );
+		setupEXTXSDRadio( group );
+		
+		initXSDGroupStatus( );
+	}
+	
+	private void initXSDGroupStatus( )
+	{
+		if ( getInitializationDesign( ) == null
+				|| getInitializationDesign( ).getPrivateProperties( ) == null )
+		{
+			setToDefaultXSDSelection( );
+			return;
+		}
+
+		String schema = getInitializationDesign( ).getPrivateProperties( )
+				.getProperty( Constants.RESPONSE_SCHEMA );
+		if ( schema != null )
+		{
+			if ( Constants.FROM_WS_SERVER.equals( schema ) )
+			{
+				resXSDRadio.setSelection( true );
+				WSConsole.getInstance( ).setPropertyValue( Constants.RESPONSE_SCHEMA, Constants.FROM_WS_SERVER );
+			}
+			else if ( Constants.FROM_EXTERNAL_SCHEMA.equals( schema ) )
+			{
+				extXSDRadio.setSelection( true );
+				WSConsole.getInstance( ).setPropertyValue( Constants.RESPONSE_SCHEMA, Constants.FROM_EXTERNAL_SCHEMA );
+			}
+			else
+			{
+				setToDefaultXSDSelection( );
+			}
+		}
+		else
+		{
+			setToDefaultXSDSelection( );
+		}
+		
+		updateXSDGroupControl( );
+
+	}
+
+	private void setToDefaultXSDSelection( )
+	{
+		dftXSDRadio.setSelection( true );
+		updateXSDGroupControl( );
+		WSConsole.getInstance( )
+				.setPropertyValue( Constants.RESPONSE_SCHEMA,
+						Constants.FROM_WSDL );
+	}
+
+	private void setupDFTXSDRadio( Composite parent )
+	{
+		dftXSDRadio = new Button( parent, SWT.RADIO );
+		GridData layoutData = new GridData( );
+		layoutData.horizontalSpan = 3;
+		dftXSDRadio.setLayoutData( layoutData );
+		dftXSDRadio.setText( Messages.getString( "soapResponsePage.radio.defaultSchema" ) );//$NON-NLS-1$
+		
+		dftXSDRadio.addSelectionListener( new SelectionAdapter( ) {
+
+			/*
+			 * (non-Javadoc)
+			 * 
+			 * @see org.eclipse.swt.events.SelectionAdapter#widgetSelected(org.eclipse.swt.events.SelectionEvent)
+			 */
+			public void widgetSelected( SelectionEvent e )
+			{
+				WSConsole.getInstance( ).setPropertyValue( Constants.XML_TEMP_FILE_URI, "" ); //$NON-NLS-1$
+				WSConsole.getInstance( ).setPropertyValue( Constants.RESPONSE_SCHEMA, Constants.FROM_WSDL );
+				updateXSDGroupControl( );
+				updatePageStatus( );
+			}
+
+		} );
+	}
+	
+	private void setupRESXSDRadio( Composite parent )
+	{
+		resXSDRadio = new Button( parent, SWT.RADIO );
+		GridData layoutData = new GridData( );
+		layoutData.horizontalSpan = 3;
+		resXSDRadio.setLayoutData( layoutData );
+		resXSDRadio.setText( Messages.getString( "soapResponsePage.radio.reponseSchema" ) );//$NON-NLS-1$
+		resXSDRadio.addSelectionListener( new SelectionAdapter( ) {
+
+			/*
+			 * (non-Javadoc)
+			 * 
+			 * @see org.eclipse.swt.events.SelectionAdapter#widgetSelected(org.eclipse.swt.events.SelectionEvent)
+			 */
+			public void widgetSelected( SelectionEvent e )
+			{
+				WSConsole.getInstance( ).setPropertyValue( Constants.XML_TEMP_FILE_URI, "" ); //$NON-NLS-1$
+				WSConsole.getInstance( ).setPropertyValue( Constants.RESPONSE_SCHEMA, Constants.FROM_WS_SERVER );
+				updateXSDGroupControl( );
+				updatePageStatus( );
+			}
+
+		} );
+	}
+
+	private void setupEXTXSDRadio( Composite parent )
+	{
+		extXSDRadio = new Button( parent, SWT.RADIO );
+		GridData layoutData = new GridData( );
+		extXSDRadio.setLayoutData( layoutData );
+		extXSDRadio.setText( Messages.getString( "soapResponsePage.radio.externalSchema" ) );//$NON-NLS-1$
+		extXSDRadio.addSelectionListener( new SelectionAdapter( ) {
+
+			/*
+			 * (non-Javadoc)
+			 * 
+			 * @see org.eclipse.swt.events.SelectionAdapter#widgetSelected(org.eclipse.swt.events.SelectionEvent)
+			 */
+			public void widgetSelected( SelectionEvent e )
+			{
+				WSConsole.getInstance( ).setPropertyValue( Constants.RESPONSE_SCHEMA, Constants.FROM_EXTERNAL_SCHEMA );
+				updatePageStatus( );
+			}
+
+		} );
+		xsdFileURI = new Text( parent, SWT.BORDER );
+		layoutData = new GridData( GridData.FILL_HORIZONTAL );
+		xsdFileURI.setLayoutData( layoutData );
+		xsdFileURI.addModifyListener( new ModifyListener( ) {
+
+			public void modifyText( ModifyEvent e )
+			{
+				updatePageStatus( );
+			}
+		} );
+		XSDBrowseBtn = new Button( parent, SWT.NONE );
+		layoutData = new GridData( );
+		XSDBrowseBtn.setLayoutData( layoutData );
+		XSDBrowseBtn.setText( Messages.getString( "soapResponsePage.button.browse1" ) );//$NON-NLS-1$
+		XSDBrowseBtn.addSelectionListener( new SelectionAdapter( ) {
+
+			/*
+			 * (non-Javadoc)
+			 * 
+			 * @see org.eclipse.swt.events.SelectionAdapter#widgetSelected(org.eclipse.swt.events.SelectionEvent)
+			 */
+			public void widgetSelected( SelectionEvent e )
+			{
+				FileDialog dialog = new FileDialog( PlatformUI.getWorkbench( )
+
+				.getDisplay( ).getActiveShell( ), SWT.OPEN );
+				dialog.setFilterExtensions( new String[]{
+						"*.xsd", "*.*" //$NON-NLS-1$//$NON-NLS-2$
+				} );
+				if ( xsdFileURI.getText( ) != null
+						&& xsdFileURI.getText( ).trim( ).length( ) > 0 )
+				{
+					dialog.setFilterPath( xsdFileURI.getText( ) );
+				}
+
+				String selectedLocation = dialog.open( );
+				if ( selectedLocation != null )
+				{
+					xsdFileURI.setText( selectedLocation );
+				}
+				updateXSDGroupControl( );
+			}
+
+		} );
+	}
+	
+	private void updateXSDGroupControl( )
+	{
+		xsdFileURI.setEnabled( extXSDRadio.getSelection( ) );
+		XSDBrowseBtn.setEnabled( extXSDRadio.getSelection( ) );
+	}
+
+	private void setupXMLGroup( Composite parent )
+	{
+		Group group = new Group( parent, SWT.SHADOW_ETCHED_IN );
+		group.setLayout( new GridLayout( 2, false ) );
+		GridData layoutData = new GridData( GridData.FILL_HORIZONTAL );
+		group.setLayoutData( layoutData );
+		group.setText( Messages.getString( "soapResponsePage.group.xml" ) );//$NON-NLS-1$
+
+		setupDFTXMLRadio( group );
+		setupEXTXMLRadio( group );
+		
+		initXMLRadioGroupStatus( );
+	}
+	
+	private void initXMLRadioGroupStatus( )
+	{
+		if ( getInitializationDesign( ) == null
+				|| getInitializationDesign( ).getPrivateProperties( ) == null )
+		{
+			updateSOAPEndPointSelection( true );
+			return;
+		}
+
+		String useSOAPEndPoint = getInitializationDesign( ).getPrivateProperties( )
+				.getProperty( Constants.RESPONSE_USE_SOAPENDPOINT );
+		if ( useSOAPEndPoint != null )
+		{
+			updateSOAPEndPointSelection( Boolean.valueOf( useSOAPEndPoint ) );
+		}
+		else
+		{
+			updateSOAPEndPointSelection( true );
+		}
+
+	}
+
+	private void updateSOAPEndPointSelection( boolean SOAPEndPointSelected )
+	{
+		dftXMLRadio.setSelection( SOAPEndPointSelected );
+		extXMLRadio.setSelection( !SOAPEndPointSelected );
+		WSConsole.getInstance( )
+				.setPropertyValue( Constants.RESPONSE_USE_SOAPENDPOINT,
+						String.valueOf( SOAPEndPointSelected ) );
+	}
+
+	private void setupDFTXMLRadio( Composite parent )
+	{
+		dftXMLRadio = new Button( parent, SWT.RADIO );
+		GridData layoutData = new GridData( );
+		layoutData.horizontalSpan = 2;
+		dftXMLRadio.setLayoutData( layoutData );
+		dftXMLRadio.setText( Messages.getString( "soapResponsePage.radio.endPoint" ) );//$NON-NLS-1$
+
+		dftXMLRadio.addSelectionListener( new SelectionAdapter( ) {
+
+			/*
+			 * (non-Javadoc)
+			 * 
+			 * @see org.eclipse.swt.events.SelectionAdapter#widgetSelected(org.eclipse.swt.events.SelectionEvent)
+			 */
+			public void widgetSelected( SelectionEvent e )
+			{
+				updateXMLControlStatus( );
+			}
+
+		} );
+
+		soapEndPoint = new Text( parent, SWT.BORDER );
+		layoutData = new GridData( GridData.FILL_HORIZONTAL );
+		soapEndPoint.setLayoutData( layoutData );
+
+		connectBtn = new Button( parent, SWT.NONE );
+		layoutData = new GridData( );
+		connectBtn.setLayoutData( layoutData );
+		connectBtn.setText( Messages.getString( "soapResponsePage.button.connect" ) );//$NON-NLS-1$
+		connectBtn.addSelectionListener( new SelectionAdapter( ) {
+
+			/*
+			 * (non-Javadoc)
+			 * 
+			 * @see
+			 * org.eclipse.swt.events.SelectionAdapter#widgetSelected(org.eclipse
+			 * .swt.events.SelectionEvent)
+			 */
+			public void widgetSelected( SelectionEvent e )
+			{
+				try
+				{
+					saveToModel( );
+					WSConsole.getInstance( ).createXMLTempFileURI( );
+					setMessage( DEFAULT_MESSAGE );
+				}
+				catch ( OdaException e1 )
+				{
+					setMessage( e1.getMessage( ), IMessageProvider.ERROR );
+				}
+			}
+		} );
+
+		soapEndPoint.addModifyListener( new ModifyListener( ) {
+
+			public void modifyText( ModifyEvent e )
+			{
+				connectBtn.setEnabled( soapEndPoint.getText( ).trim( ).length( ) > 0 );
+			}
+
+		} );
+
+	}
+
+	private void setupEXTXMLRadio( Composite parent )
+	{
+		GridData layoutData;
+		extXMLRadio = new Button( parent, SWT.RADIO );
+		layoutData = new GridData( );
+		layoutData.horizontalSpan = 2;
+		extXMLRadio.setLayoutData( layoutData );
+		extXMLRadio.setText( Messages.getString( "soapResponsePage.radio.externalXML" ) );//$NON-NLS-1$
+		extXMLRadio.addSelectionListener( new SelectionAdapter( ) {
+
+			/*
+			 * (non-Javadoc)
+			 * 
+			 * @see org.eclipse.swt.events.SelectionAdapter#widgetSelected(org.eclipse.swt.events.SelectionEvent)
+			 */
+			public void widgetSelected( SelectionEvent e )
+			{
+				updateXMLControlStatus( );
+			}
+
+		} );
+
+
+		xmlFileURI = new Text( parent, SWT.BORDER );
+		layoutData = new GridData( GridData.FILL_HORIZONTAL );
+		xmlFileURI.setLayoutData( layoutData );
+
+		browseXMLBtn = new Button( parent, SWT.NONE );
+		layoutData = new GridData( );
+		browseXMLBtn.setLayoutData( layoutData );
+		browseXMLBtn.setText( Messages.getString( "soapResponsePage.button.browse2" ) );//$NON-NLS-1$
+		browseXMLBtn.addSelectionListener( new SelectionAdapter( ) {
+
+			/*
+			 * (non-Javadoc)
+			 * 
+			 * @see org.eclipse.swt.events.SelectionAdapter#widgetSelected(org.eclipse.swt.events.SelectionEvent)
+			 */
+			public void widgetSelected( SelectionEvent e )
+			{
+				FileDialog dialog = new FileDialog( PlatformUI.getWorkbench( )
+						.getDisplay( )
+						.getActiveShell( ), SWT.OPEN );
+				dialog.setFilterExtensions( new String[]{
+						"*.xml", "*.*" //$NON-NLS-1$ //$NON-NLS-2$
+				} );
+				if ( xmlFileURI.getText( ) != null
+						&& xmlFileURI.getText( ).trim( ).length( ) > 0 )
+				{
+					dialog.setFilterPath( xmlFileURI.getText( ) );
+				}
+
+				String selectedLocation = dialog.open( );
+				if ( selectedLocation != null )
+				{
+					xmlFileURI.setText( selectedLocation );
+				}
+			}
+
+		} );
+	}
+	
+	private void updateXMLControlStatus( )
+	{
+		boolean defaultXMLSelection = dftXMLRadio.getSelection( );
+		soapEndPoint.setEnabled( defaultXMLSelection );
+		connectBtn.setEnabled( defaultXMLSelection
+				&